From 67b553688da393909a66a7221c150cef885238ee Mon Sep 17 00:00:00 2001 From: Yuuuu <1569752928@qq.com> Date: Wed, 18 Mar 2026 22:24:47 +0800 Subject: [PATCH] Refactor AI PMO services and harden ingress error handling --- .openclaw/pmflow-routing-rules.json | 10 + .tmp/feishu_case1_v4.html | 1 + .tmp/feishu_case1_v4.png | Bin 0 -> 30141 bytes .tmp/feishu_case2_fail.html | 26 ++ .tmp/feishu_case2_fail.png | Bin 0 -> 39141 bytes .tmp/feishu_case2_v4.html | 25 ++ .tmp/feishu_case2_v4.png | Bin 0 -> 119958 bytes .tmp/p0_feishu_reply_validation.png | Bin 0 -> 79410 bytes .tmp/p1_real_validate.py | 313 +++++++++++++++++ .tmp/p1_real_validate_v4.py | 330 ++++++++++++++++++ .tmp/real_feishu_case_1.png | Bin 0 -> 73021 bytes .tmp/real_feishu_case_2.png | Bin 0 -> 168006 bytes .tmp/real_feishu_case_3.png | Bin 0 -> 66560 bytes .tmp/real_feishu_case_4.png | Bin 0 -> 69579 bytes .tmp/real_feishu_case_5.png | Bin 0 -> 75757 bytes .tmp/run_feishu_case.py | 291 +++++++++++++++ AGENTS.md | 1 + CLAUDE.md | 146 ++++---- backend/.openclaw/pmflow-routing-rules.json | 10 + ...d_ai_orchestration_ingress_async_fields.py | 165 +++++++++ backend/app/api/ai_pmo_api/shared.py | 4 +- backend/app/api/ai_steward_api/shared.py | 8 +- backend/app/api/feishu_api/config_routes.py | 4 +- .../api/feishu_api/long_connection_routes.py | 2 +- backend/app/api/feishu_api/message_routes.py | 2 +- backend/app/api/feishu_api/test_routes.py | 4 +- backend/app/api/knowledge_graph.py | 2 +- .../app/api/model_capability_api/shared.py | 6 +- backend/app/api/model_routing.py | 2 +- backend/app/api/projects_api/__init__.py | 4 +- backend/app/api/projects_api/helpers.py | 3 +- backend/app/api/projects_api/shared.py | 2 +- backend/app/api/prompt_profiles.py | 2 +- backend/app/api/rag_api/shared.py | 2 +- backend/app/api/scheduler.py | 4 +- backend/app/api/signals_api/ingest_fetch.py | 8 +- backend/app/api/skill_tags_api/routes.py | 2 +- .../app/api/sstc_api/charters_ai_alignment.py | 4 +- .../api/sstc_api/charters_detail_update.py | 23 +- .../app/api/sstc_api/releases_list_create.py | 38 +- backend/app/api/sstc_api/shared.py | 4 +- .../app/api/sstc_api/tasks_ai_breakdown.py | 40 ++- backend/app/api/tasks.py | 2 +- backend/app/api/users_api/shared.py | 2 +- backend/app/api/webhooks.py | 2 +- backend/app/api/wecom_api/config.py | 2 +- backend/app/api/wecom_api/messaging.py | 2 +- backend/app/api/wecom_api/webhook.py | 2 +- backend/app/config/ai_prompts.py | 6 + .../app/config/ai_prompts_catalog/__init__.py | 12 + .../app/config/ai_prompts_catalog/part_01.py | 8 + .../app/config/ai_prompts_catalog/part_02.py | 32 +- .../app/config/ai_prompts_catalog/part_03.py | 4 +- .../ai_prompts_catalog/part_scenes_01.py | 22 ++ .../ai_prompts_catalog/part_scenes_02.py | 27 ++ .../ai_prompts_catalog/part_scenes_03.py | 23 ++ .../ai_prompts_catalog/part_scenes_04.py | 21 ++ .../ai_prompts_catalog/part_scenes_05.py | 21 ++ .../ai_prompts_catalog/part_scenes_06.py | 24 ++ .../app/core/startup/ai_pmo_ingress_async.py | 30 ++ backend/app/core/startup/feishu_outbox.py | 2 +- .../app/core/startup/world_model_warmup.py | 2 +- backend/app/main.py | 10 +- backend/app/models/ai_orchestration_run.py | 24 +- .../mixin_answer_entry.py | 37 +- .../mixin_answer_retrieval.py | 9 +- .../mixin_deep_guard_answer.py | 189 +++++++++- .../mixin_deep_guard_rules.py | 9 +- .../adaptive_rag_service/mixin_ingest.py | 17 +- .../adaptive_rag_service/shared_imports.py | 15 +- .../adaptive_rag_service/shared_part_02.py | 3 + .../adaptive_rag_service/shared_utils.py | 2 + .../ai_orchestration_run/ingress_worker.py | 265 ++++++++++++++ .../services/ai_orchestration_run/service.py | 324 ++++++++++++++++- backend/app/services/ai_pmo/__init__.py | 1 + .../{ => ai_pmo}/ai_pmo_cadence/__init__.py | 0 .../ai_pmo_cadence/mixin_builders.py | 0 .../ai_pmo_cadence/mixin_program_view.py | 0 .../ai_pmo_cadence/mixin_queries_a.py | 0 .../ai_pmo_cadence/mixin_queries_b.py | 0 .../ai_pmo_cadence/mixin_snapshots.py | 0 .../{ => ai_pmo}/ai_pmo_cadence/service.py | 0 .../{ => ai_pmo}/ai_pmo_cadence/shared.py | 4 +- .../{ => ai_pmo}/ai_pmo_decision/__init__.py | 0 .../{ => ai_pmo}/ai_pmo_decision/engine.py | 0 .../{ => ai_pmo}/ai_pmo_decision/policy.py | 31 +- .../{ => ai_pmo}/ai_pmo_decision/shared.py | 0 .../ai_pmo_decision/simulation.py | 0 .../{ => ai_pmo}/ai_pmo_decision/strategic.py | 0 .../{ => ai_pmo}/ai_pmo_decision/tactical.py | 0 .../{ => ai_pmo}/ai_pmo_intent/__init__.py | 0 .../ai_pmo_intent/intent_resolver.py | 3 +- .../{ => ai_pmo}/ai_pmo_intent/models.py | 4 + .../ai_pmo_intent/route_resolver.py | 81 ++--- .../{ => ai_pmo}/ai_pmo_intent/shared.py | 5 +- .../{ => ai_pmo}/ai_pmo_kernel/__init__.py | 9 +- .../ai_pmo_kernel/ai_agent_kernel.py | 0 .../ai_pmo_kernel/ai_pmo_domain_workflow.py | 2 +- .../ai_pmo_kernel/ai_pmo_kernel_runtime.py | 11 +- .../ai_pmo_kernel/ai_pmo_reply_renderer.py | 0 .../ai_pmo_kernel/ai_pmo_review_service.py | 2 +- .../ai_pmo_kernel/ai_pmo_typed_executor.py | 0 .../ai_pmo_typed_executor_common.py | 20 +- .../ai_pmo_typed_executor_mixins_parse.py | 0 .../ai_pmo_kernel/ai_pmo_workflow_runtime.py | 4 +- .../ai_pmo_kernel/compositions/__init__.py | 15 + .../ai_pmo_kernel/compositions/closure.py} | 6 +- .../ai_pmo_kernel/compositions/followup.py | 23 ++ .../ai_pmo_kernel/compositions/ingress.py} | 6 +- .../ai_pmo_kernel/compositions/intent.py} | 6 +- .../compositions/world_model.py} | 8 +- .../ai_pmo/ai_pmo_kernel/mixins/__init__.py | 1 + .../ai_pmo_kernel/mixins/closure/__init__.py | 1 + .../ai_pmo_kernel_mixins_closure_data.py | 2 +- .../ai_pmo_kernel_mixins_closure_helpers.py | 2 +- .../ai_pmo_kernel_mixins_closure_payload.py | 2 +- .../ai_pmo_kernel/mixins/followup/__init__.py | 1 + ...o_kernel_mixins_followup_project_signal.py | 0 ..._mixins_followup_project_signal_actions.py | 2 +- ...l_mixins_followup_project_signal_resume.py | 2 +- .../ai_pmo_kernel_mixins_followup_records.py | 2 +- .../ai_pmo_kernel_mixins_followup_routing.py | 2 +- ...pmo_kernel_mixins_followup_verification.py | 2 +- .../ai_pmo_kernel/mixins/ingress/__init__.py | 1 + .../ai_pmo_kernel_mixins_ingress_render.py | 13 +- .../ai_pmo_kernel_mixins_ingress_storage.py | 2 +- .../ai_pmo_kernel/mixins/intent/__init__.py | 1 + .../ai_pmo_kernel_mixins_intent_llm.py | 86 +++-- .../ai_pmo_kernel_mixins_intent_resolve.py | 51 +++ .../ai_pmo_kernel_mixins_intent_rules.py | 112 +++++- .../mixins/world_model/__init__.py | 1 + ...i_pmo_kernel_mixins_world_model_session.py | 2 +- .../ai_pmo_kernel_common_core/__init__.py | 0 .../ai_pmo_kernel_common_core/constants.py | 6 +- .../ai_pmo_kernel_common_core/env.py | 4 +- .../ai_pmo_kernel_common_core/helpers.py | 3 + .../ai_pmo_kernel_common_core/imports.py | 24 +- .../ai_pmo_kernel_ingress_flow/__init__.py | 0 .../ai_pmo_kernel_ingress_flow/mixin_auto.py | 49 +++ .../ai_pmo_kernel_ingress_flow/mixin_entry.py | 118 ++++++- .../mixin_prepare_manual.py | 0 .../ai_pmo_kernel_ingress_flow/service.py | 0 .../ai_pmo_kernel_ingress_flow/shared.py | 2 + .../__init__.py | 0 .../mixin_basics.py | 0 .../mixin_project.py | 0 .../service.py | 0 .../shared.py | 3 + .../__init__.py | 0 .../mixin_builder.py | 0 .../mixin_cache.py | 0 .../mixin_project.py | 0 .../ai_pmo_kernel_world_model_core/service.py | 0 .../ai_pmo_kernel_world_model_core/shared.py | 3 + .../__init__.py | 0 .../mixin_analysis.py | 0 .../mixin_context.py | 0 .../mixin_discover.py | 0 .../service.py | 0 .../ai_pmo_typed_executor_discovery/shared.py | 0 .../ai_pmo_typed_executor_execute/__init__.py | 0 .../mixin_execute_query_project.py | 1 + .../mixin_execute_signal_create.py | 0 .../mixin_execute_signal_source.py | 0 .../mixin_helpers.py | 3 +- .../ai_pmo_typed_executor_execute/service.py | 0 .../ai_pmo_typed_executor_execute/shared.py | 0 .../ai_pmo_kernel_mixins_followup.py | 19 - .../ai_pmo_kernel_mixins_intent_resolve.py | 66 ---- .../ai_service_core/mixin_business_tasks.py | 70 +++- .../services/context_cache_service/shared.py | 2 + backend/app/services/integrations/__init__.py | 1 + .../feishu_integration_service/__init__.py | 0 .../mixin_config.py | 3 +- .../mixin_message_payload.py | 11 +- .../mixin_receive.py | 10 +- .../mixin_receive_routing.py | 0 .../mixin_reply_guard.py | 0 .../mixin_reply_llm_core.py | 36 +- .../mixin_reply_outbox.py | 3 +- .../mixin_reply_templates.py | 0 .../mixin_sender_resolution.py | 0 .../feishu_integration_service/mixin_trace.py | 0 .../mixin_transport.py | 0 .../feishu_integration_service/service.py | 0 .../feishu_integration_service/shared.py | 15 +- .../feishu_long_connection_core/__init__.py | 0 .../feishu_long_connection_core/manager.py | 0 .../mixin_lifecycle.py | 0 .../mixin_lifecycle_connection.py | 0 .../mixin_lifecycle_control.py | 0 .../mixin_runtime.py | 0 .../feishu_long_connection_core/registry.py | 0 .../feishu_long_connection_core/shared.py | 6 +- .../feishu_outbox/__init__.py | 0 .../feishu_outbox/service.py | 2 +- .../feishu_signal_pipeline/__init__.py | 0 .../mixin_command_commit_project.py | 0 .../mixin_command_commit_task.py | 0 .../mixin_command_exec_core.py | 0 .../mixin_context_prefill_a.py | 0 .../mixin_context_prefill_b.py | 0 .../feishu_signal_pipeline/mixin_core_base.py | 0 .../mixin_extraction.py | 0 .../mixin_followup_a.py | 0 .../mixin_followup_b.py | 0 .../mixin_gate_dispatch.py | 14 +- .../mixin_gate_project.py | 0 .../feishu_signal_pipeline/mixin_gate_task.py | 0 .../mixin_intent_gate_core.py | 0 .../mixin_intent_support.py | 0 .../mixin_item_finalize_routing.py | 0 .../mixin_item_processing.py | 0 .../mixin_lookup_and_block.py | 0 .../mixin_message_utils_a.py | 0 .../mixin_message_utils_b.py | 0 .../mixin_persistence_lookup.py | 0 .../mixin_process_message_core.py | 0 .../mixin_process_message_default.py | 103 ++++-- .../mixin_process_message_helpers_a.py | 0 .../mixin_process_message_helpers_b.py | 0 .../mixin_queue_confirm_undo.py | 0 .../mixin_queue_read_write.py | 0 .../mixin_routing_notify.py | 0 .../mixin_serialization.py | 0 .../mixin_task_command_queue.py | 0 .../feishu_signal_pipeline/service.py | 0 .../feishu_signal_pipeline/shared.py | 0 .../feishu_signal_pipeline/shared_core.py | 31 +- .../shared_schema_utils.py | 0 .../integration_core/__init__.py | 0 .../integration_core/lark_service.py | 0 .../integration_core/mixin_clients.py | 0 .../integration_core/mixin_health.py | 0 .../integration_core/mixin_lifecycle.py | 0 .../integration_core/mixin_sync.py | 4 +- .../integration_core/plane_service.py | 0 .../integration_core/registry.py | 0 .../integration_core/schemas.py | 0 .../integration_core/service.py | 0 .../integration_core/shared.py | 2 +- .../{ => integrations}/wecom/__init__.py | 0 .../{ => integrations}/wecom/service.py | 4 +- .../llm_service/mixin_cache_circuit.py | 3 +- .../services/llm_service/mixin_chat_openai.py | 103 +++--- .../mixin_generate_db_structured.py | 129 ++++++- .../llm_service/mixin_guardrails_prompt.py | 40 ++- .../llm_service/mixin_openclaw_routing.py | 5 +- .../mixin_structured_candidates.py | 120 ++++++- .../mixin_structured_extract_object.py | 101 ++++-- .../llm_service/mixin_structured_parse.py | 21 +- .../llm_service/mixin_tier_escalation.py | 49 ++- backend/app/services/llm_service/shared.py | 4 + .../services/llm_service/shared_part_01.py | 5 +- .../services/llm_service/shared_part_02.py | 4 + backend/app/services/model/__init__.py | 1 + .../{ => model}/model_capability/__init__.py | 0 .../cost_optimization_service.py | 2 +- .../model_capability/mixin_cost_tracking.py | 2 +- .../model_capability/mixin_gap_queries.py | 0 .../model_capability/mixin_validation.py | 0 .../model_lifecycle_service.py | 2 +- .../{ => model}/model_capability/service.py | 0 .../{ => model}/model_capability/shared.py | 6 +- .../model_context_bundle/__init__.py | 0 .../model_context_bundle/mixin_build.py | 2 +- .../model_context_bundle/mixin_core.py | 0 .../model_context_bundle/mixin_verify.py | 0 .../model_context_bundle/service.py | 0 .../model_context_bundle/shared.py | 6 +- .../{ => model}/model_routing/__init__.py | 0 .../{ => model}/model_routing/service.py | 4 +- .../{ => model}/prompt_profile/__init__.py | 0 .../{ => model}/prompt_profile/service.py | 6 +- .../project_knowledge_graph_service/shared.py | 4 +- .../scheduler_center_core/ai_pmo_cadence.py | 15 +- .../scheduler_center_core/knowledge_graph.py | 9 +- .../services/scheduler_center_core/shared.py | 2 +- backend/app/services/signal/__init__.py | 1 + .../signal_capture_service/__init__.py | 0 .../external_fetcher.py | 0 .../signal_capture_service/impact_analyzer.py | 0 .../mixin_analysis_normalize.py | 5 +- .../mixin_capture_entry.py | 305 ++++++++++++++++ .../mixin_capture_legacy.py | 0 .../mixin_external_sources.py | 0 .../mixin_new_project.py | 0 .../mixin_pipeline_cache.py | 0 .../mixin_source_analyzers.py | 2 +- .../mixin_task_orchestration_main.py | 0 .../mixin_task_orchestration_skill.py | 0 .../mixin_task_orchestration_team.py | 0 .../signal_capture_service/service.py | 0 .../signal_capture_service/shared.py | 28 +- .../{ => signal}/signal_planner/__init__.py | 0 .../signal_planner/mixin_analyze.py | 0 .../signal_planner/mixin_loaders.py | 0 .../signal_planner/mixin_prompt.py | 0 .../signal_planner/mixin_utils.py | 0 .../{ => signal}/signal_planner/service.py | 0 .../{ => signal}/signal_planner/shared.py | 16 +- .../signal_strategic_analysis_service.py | 4 +- .../signal_source_orchestration/__init__.py | 0 .../mixin_entry_orchestrate.py | 0 .../mixin_entry_terminal_a.py | 0 .../mixin_entry_terminal_b.py | 0 .../mixin_execute_isolation.py | 0 .../mixin_lookup_parse.py | 0 .../mixin_planning_locator_roles.py | 0 .../mixin_planning_onboard.py | 0 .../mixin_registry_execute.py | 0 .../mixin_result_resolution.py | 0 .../mixin_result_run_updates.py | 0 .../mixin_worker_prompt_persist.py | 0 .../signal_source_orchestration/service.py | 0 .../signal_source_orchestration/shared.py | 15 +- .../signal_source_repair/__init__.py | 0 .../signal_source_repair/errors.py | 0 .../signal_source_repair/mixin_capture.py | 0 .../signal_source_repair/mixin_data_access.py | 0 .../signal_source_repair/mixin_persist.py | 0 .../signal_source_repair/mixin_repair.py | 0 .../signal_source_repair/mixin_utils.py | 0 .../signal_source_repair/service.py | 0 .../signal_source_repair/shared.py | 10 +- .../{ => signal}/symbol_index/__init__.py | 0 .../symbol_index/mixin_parse_python.py | 0 .../symbol_index/mixin_parse_typescript.py | 0 .../symbol_index/mixin_query_overview.py | 0 .../symbol_index/mixin_serialize.py | 0 .../symbol_index/mixin_sync_core.py | 0 .../{ => signal}/symbol_index/service.py | 0 .../{ => signal}/symbol_index/shared.py | 4 +- .../mixin_capture_entry.py | 173 --------- backend/app/services/skill/shared.py | 3 +- backend/app/services/sstc/charter_data.py | 13 +- backend/app/services/sstc/shared.py | 6 +- .../sstc_service_core/mixin_build_views.py | 2 +- .../sstc_service_core/mixin_fetch_core.py | 2 +- .../app/services/sstc_service_core/service.py | 9 + .../app/services/sstc_service_core/shared.py | 3 + .../sstc_service_core/shared_helpers.py | 3 + backend/app/services/task_brief/__init__.py | 8 +- .../services/task_persistence_core/persist.py | 2 +- .../workload/workload_alert_service.py | 6 +- backend/scripts/p1_real_validate.py | 313 +++++++++++++++++ backend/tmp_p1_real_validate_v4.py | 330 ++++++++++++++++++ backend/tmp_run_feishu_case.py | 291 +++++++++++++++ docker-compose.dev.yml | 24 ++ docker-compose.yml | 24 ++ frontend/src/api/sstc.ts | 4 + .../components/sstc/SSTCCharterStagePanel.tsx | 113 +++++- .../sstc/SSTCExecutionBoardPanel.tsx | 95 ++++- .../sstc/SSTCReleaseCreateDialog.tsx | 44 ++- .../components/sstc/SSTCReleaseStagePanel.tsx | 1 + .../src/components/sstc/SSTCWorkspace.tsx | 7 + .../sstc/useSSTCWorkspaceOrchestration.ts | 179 +++++++++- .../pages/project-board/ProjectBoardPage.tsx | 1 + frontend/tsconfig.tsbuildinfo | 2 +- 359 files changed, 5574 insertions(+), 904 deletions(-) create mode 100644 .tmp/feishu_case1_v4.html create mode 100644 .tmp/feishu_case1_v4.png create mode 100644 .tmp/feishu_case2_fail.html create mode 100644 .tmp/feishu_case2_fail.png create mode 100644 .tmp/feishu_case2_v4.html create mode 100644 .tmp/feishu_case2_v4.png create mode 100644 .tmp/p0_feishu_reply_validation.png create mode 100644 .tmp/p1_real_validate.py create mode 100644 .tmp/p1_real_validate_v4.py create mode 100644 .tmp/real_feishu_case_1.png create mode 100644 .tmp/real_feishu_case_2.png create mode 100644 .tmp/real_feishu_case_3.png create mode 100644 .tmp/real_feishu_case_4.png create mode 100644 .tmp/real_feishu_case_5.png create mode 100644 .tmp/run_feishu_case.py create mode 100644 backend/alembic/versions/20260316_add_ai_orchestration_ingress_async_fields.py create mode 100644 backend/app/config/ai_prompts_catalog/part_scenes_01.py create mode 100644 backend/app/config/ai_prompts_catalog/part_scenes_02.py create mode 100644 backend/app/config/ai_prompts_catalog/part_scenes_03.py create mode 100644 backend/app/config/ai_prompts_catalog/part_scenes_04.py create mode 100644 backend/app/config/ai_prompts_catalog/part_scenes_05.py create mode 100644 backend/app/config/ai_prompts_catalog/part_scenes_06.py create mode 100644 backend/app/core/startup/ai_pmo_ingress_async.py create mode 100644 backend/app/services/ai_orchestration_run/ingress_worker.py create mode 100644 backend/app/services/ai_pmo/__init__.py rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/mixin_builders.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/mixin_program_view.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/mixin_queries_a.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/mixin_queries_b.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/mixin_snapshots.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/service.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_cadence/shared.py (93%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/engine.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/policy.py (79%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/shared.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/simulation.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/strategic.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_decision/tactical.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_intent/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_intent/intent_resolver.py (99%) rename backend/app/services/{ => ai_pmo}/ai_pmo_intent/models.py (88%) rename backend/app/services/{ => ai_pmo}/ai_pmo_intent/route_resolver.py (68%) rename backend/app/services/{ => ai_pmo}/ai_pmo_intent/shared.py (97%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/__init__.py (68%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_agent_kernel.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_domain_workflow.py (98%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_kernel_runtime.py (86%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_reply_renderer.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_review_service.py (98%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_typed_executor.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_typed_executor_common.py (82%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_typed_executor_mixins_parse.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel/ai_pmo_workflow_runtime.py (98%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/compositions/__init__.py rename backend/app/services/{ai_pmo_kernel/ai_pmo_kernel_mixins_closure.py => ai_pmo/ai_pmo_kernel/compositions/closure.py} (51%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/compositions/followup.py rename backend/app/services/{ai_pmo_kernel/ai_pmo_kernel_mixins_ingress.py => ai_pmo/ai_pmo_kernel/compositions/ingress.py} (52%) rename backend/app/services/{ai_pmo_kernel/ai_pmo_kernel_mixins_intent.py => ai_pmo/ai_pmo_kernel/compositions/intent.py} (52%) rename backend/app/services/{ai_pmo_kernel/ai_pmo_kernel_mixins_world_model.py => ai_pmo/ai_pmo_kernel/compositions/world_model.py} (53%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/__init__.py create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/closure/__init__.py rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/closure}/ai_pmo_kernel_mixins_closure_data.py (99%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/closure}/ai_pmo_kernel_mixins_closure_helpers.py (98%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/closure}/ai_pmo_kernel_mixins_closure_payload.py (99%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/followup/__init__.py rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/followup}/ai_pmo_kernel_mixins_followup_project_signal.py (100%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/followup}/ai_pmo_kernel_mixins_followup_project_signal_actions.py (99%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/followup}/ai_pmo_kernel_mixins_followup_project_signal_resume.py (99%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/followup}/ai_pmo_kernel_mixins_followup_records.py (98%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/followup}/ai_pmo_kernel_mixins_followup_routing.py (99%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/followup}/ai_pmo_kernel_mixins_followup_verification.py (99%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/ingress/__init__.py rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/ingress}/ai_pmo_kernel_mixins_ingress_render.py (93%) rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/ingress}/ai_pmo_kernel_mixins_ingress_storage.py (99%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/intent/__init__.py rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/intent}/ai_pmo_kernel_mixins_intent_llm.py (79%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/intent/ai_pmo_kernel_mixins_intent_resolve.py rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/intent}/ai_pmo_kernel_mixins_intent_rules.py (71%) create mode 100644 backend/app/services/ai_pmo/ai_pmo_kernel/mixins/world_model/__init__.py rename backend/app/services/{ai_pmo_kernel => ai_pmo/ai_pmo_kernel/mixins/world_model}/ai_pmo_kernel_mixins_world_model_session.py (98%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_common_core/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_common_core/constants.py (94%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_common_core/env.py (95%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_common_core/helpers.py (97%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_common_core/imports.py (84%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_ingress_flow/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_ingress_flow/mixin_auto.py (79%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_ingress_flow/mixin_entry.py (73%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_ingress_flow/mixin_prepare_manual.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_ingress_flow/service.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_ingress_flow/shared.py (78%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_aggregates/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_aggregates/mixin_basics.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_aggregates/mixin_project.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_aggregates/service.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_aggregates/shared.py (79%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_core/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_core/mixin_builder.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_core/mixin_cache.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_core/mixin_project.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_core/service.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_kernel_world_model_core/shared.py (78%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_discovery/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_discovery/mixin_analysis.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_discovery/mixin_context.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_discovery/mixin_discover.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_discovery/service.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_discovery/shared.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/__init__.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/mixin_execute_query_project.py (97%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/mixin_execute_signal_create.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/mixin_execute_signal_source.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/mixin_helpers.py (98%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/service.py (100%) rename backend/app/services/{ => ai_pmo}/ai_pmo_typed_executor_execute/shared.py (100%) delete mode 100644 backend/app/services/ai_pmo_kernel/ai_pmo_kernel_mixins_followup.py delete mode 100644 backend/app/services/ai_pmo_kernel/ai_pmo_kernel_mixins_intent_resolve.py create mode 100644 backend/app/services/integrations/__init__.py rename backend/app/services/{ => integrations}/feishu_integration_service/__init__.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_config.py (98%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_message_payload.py (96%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_receive.py (96%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_receive_routing.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_reply_guard.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_reply_llm_core.py (88%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_reply_outbox.py (99%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_reply_templates.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_sender_resolution.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_trace.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/mixin_transport.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/service.py (100%) rename backend/app/services/{ => integrations}/feishu_integration_service/shared.py (72%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/__init__.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/manager.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/mixin_lifecycle.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/mixin_lifecycle_connection.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/mixin_lifecycle_control.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/mixin_runtime.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/registry.py (100%) rename backend/app/services/{ => integrations}/feishu_long_connection_core/shared.py (88%) rename backend/app/services/{ => integrations}/feishu_outbox/__init__.py (100%) rename backend/app/services/{ => integrations}/feishu_outbox/service.py (98%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/__init__.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_command_commit_project.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_command_commit_task.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_command_exec_core.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_context_prefill_a.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_context_prefill_b.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_core_base.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_extraction.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_followup_a.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_followup_b.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_gate_dispatch.py (94%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_gate_project.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_gate_task.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_intent_gate_core.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_intent_support.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_item_finalize_routing.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_item_processing.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_lookup_and_block.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_message_utils_a.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_message_utils_b.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_persistence_lookup.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_process_message_core.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_process_message_default.py (78%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_process_message_helpers_a.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_process_message_helpers_b.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_queue_confirm_undo.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_queue_read_write.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_routing_notify.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_serialization.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/mixin_task_command_queue.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/service.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/shared.py (100%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/shared_core.py (91%) rename backend/app/services/{ => integrations}/feishu_signal_pipeline/shared_schema_utils.py (100%) rename backend/app/services/{ => integrations}/integration_core/__init__.py (100%) rename backend/app/services/{ => integrations}/integration_core/lark_service.py (100%) rename backend/app/services/{ => integrations}/integration_core/mixin_clients.py (100%) rename backend/app/services/{ => integrations}/integration_core/mixin_health.py (100%) rename backend/app/services/{ => integrations}/integration_core/mixin_lifecycle.py (100%) rename backend/app/services/{ => integrations}/integration_core/mixin_sync.py (98%) rename backend/app/services/{ => integrations}/integration_core/plane_service.py (100%) rename backend/app/services/{ => integrations}/integration_core/registry.py (100%) rename backend/app/services/{ => integrations}/integration_core/schemas.py (100%) rename backend/app/services/{ => integrations}/integration_core/service.py (100%) rename backend/app/services/{ => integrations}/integration_core/shared.py (92%) rename backend/app/services/{ => integrations}/wecom/__init__.py (100%) rename backend/app/services/{ => integrations}/wecom/service.py (98%) create mode 100644 backend/app/services/model/__init__.py rename backend/app/services/{ => model}/model_capability/__init__.py (100%) rename backend/app/services/{ => model}/model_capability/cost_optimization_service.py (98%) rename backend/app/services/{ => model}/model_capability/mixin_cost_tracking.py (99%) rename backend/app/services/{ => model}/model_capability/mixin_gap_queries.py (100%) rename backend/app/services/{ => model}/model_capability/mixin_validation.py (100%) rename backend/app/services/{ => model}/model_capability/model_lifecycle_service.py (99%) rename backend/app/services/{ => model}/model_capability/service.py (100%) rename backend/app/services/{ => model}/model_capability/shared.py (83%) rename backend/app/services/{ => model}/model_context_bundle/__init__.py (100%) rename backend/app/services/{ => model}/model_context_bundle/mixin_build.py (98%) rename backend/app/services/{ => model}/model_context_bundle/mixin_core.py (100%) rename backend/app/services/{ => model}/model_context_bundle/mixin_verify.py (100%) rename backend/app/services/{ => model}/model_context_bundle/service.py (100%) rename backend/app/services/{ => model}/model_context_bundle/shared.py (90%) rename backend/app/services/{ => model}/model_routing/__init__.py (100%) rename backend/app/services/{ => model}/model_routing/service.py (99%) rename backend/app/services/{ => model}/prompt_profile/__init__.py (100%) rename backend/app/services/{ => model}/prompt_profile/service.py (98%) create mode 100644 backend/app/services/signal/__init__.py rename backend/app/services/{ => signal}/signal_capture_service/__init__.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/external_fetcher.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/impact_analyzer.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_analysis_normalize.py (98%) create mode 100644 backend/app/services/signal/signal_capture_service/mixin_capture_entry.py rename backend/app/services/{ => signal}/signal_capture_service/mixin_capture_legacy.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_external_sources.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_new_project.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_pipeline_cache.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_source_analyzers.py (99%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_task_orchestration_main.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_task_orchestration_skill.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/mixin_task_orchestration_team.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/service.py (100%) rename backend/app/services/{ => signal}/signal_capture_service/shared.py (85%) rename backend/app/services/{ => signal}/signal_planner/__init__.py (100%) rename backend/app/services/{ => signal}/signal_planner/mixin_analyze.py (100%) rename backend/app/services/{ => signal}/signal_planner/mixin_loaders.py (100%) rename backend/app/services/{ => signal}/signal_planner/mixin_prompt.py (100%) rename backend/app/services/{ => signal}/signal_planner/mixin_utils.py (100%) rename backend/app/services/{ => signal}/signal_planner/service.py (100%) rename backend/app/services/{ => signal}/signal_planner/shared.py (74%) rename backend/app/services/{ => signal}/signal_planner/signal_strategic_analysis_service.py (97%) rename backend/app/services/{ => signal}/signal_source_orchestration/__init__.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_entry_orchestrate.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_entry_terminal_a.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_entry_terminal_b.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_execute_isolation.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_lookup_parse.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_planning_locator_roles.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_planning_onboard.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_registry_execute.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_result_resolution.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_result_run_updates.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/mixin_worker_prompt_persist.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/service.py (100%) rename backend/app/services/{ => signal}/signal_source_orchestration/shared.py (82%) rename backend/app/services/{ => signal}/signal_source_repair/__init__.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/errors.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/mixin_capture.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/mixin_data_access.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/mixin_persist.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/mixin_repair.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/mixin_utils.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/service.py (100%) rename backend/app/services/{ => signal}/signal_source_repair/shared.py (70%) rename backend/app/services/{ => signal}/symbol_index/__init__.py (100%) rename backend/app/services/{ => signal}/symbol_index/mixin_parse_python.py (100%) rename backend/app/services/{ => signal}/symbol_index/mixin_parse_typescript.py (100%) rename backend/app/services/{ => signal}/symbol_index/mixin_query_overview.py (100%) rename backend/app/services/{ => signal}/symbol_index/mixin_serialize.py (100%) rename backend/app/services/{ => signal}/symbol_index/mixin_sync_core.py (100%) rename backend/app/services/{ => signal}/symbol_index/service.py (100%) rename backend/app/services/{ => signal}/symbol_index/shared.py (91%) delete mode 100644 backend/app/services/signal_capture_service/mixin_capture_entry.py create mode 100644 backend/scripts/p1_real_validate.py create mode 100644 backend/tmp_p1_real_validate_v4.py create mode 100644 backend/tmp_run_feishu_case.py diff --git a/.openclaw/pmflow-routing-rules.json b/.openclaw/pmflow-routing-rules.json index 0818c1d1..cd365b48 100644 --- a/.openclaw/pmflow-routing-rules.json +++ b/.openclaw/pmflow-routing-rules.json @@ -29,6 +29,16 @@ "api_env": "OPENAI_API_KEY", "function_exact": "classify_intent_complex" }, + { + "name": "engine_low_intent_kernel_exact", + "enabled": true, + "priority": 310, + "tier": "low", + "provider": "glm", + "model": "GLM-4.7", + "api_env": "GLM_API_KEY", + "function_exact": "classify_intent_ai_pmo_kernel" + }, { "name": "engine_low_execute_glm_flash", "enabled": true, diff --git a/.tmp/feishu_case1_v4.html b/.tmp/feishu_case1_v4.html new file mode 100644 index 00000000..35bf9db7 --- /dev/null +++ b/.tmp/feishu_case1_v4.html @@ -0,0 +1 @@ +
杨宇当前负载为 199.17%。根据系统快照,他身兼多职(FE, BOSS, AI, BE, ADMIN),负责 4 个项目,负载已严重超载,建议尽快进行任务调配。
(b()*YUb>0Ksn$3xA7|$}l&}Cb0e@U4S#z zh%Kf{N9ELKG8BPCd^Vt9xoZ12pUr9c{ZX{*jzAV(N~cze{z$jz*GCD43@rM!^Aj6E zM6dwziW$ydR)d+j3Q0B}#!3xh8`4x7ZgC`Ob+^Ht(|@GXtz7p#ow4ML7*PYjQOkeA zq3>rlNR0NAl?B>mCc%#`PWNDZCvir8)^%AA^WySTA&Ue`0BOljOG#CX+^0fbbUJPt zHJ>VcsR|*$h97n@vLcQnM=ugAQ`rnYuOoUMnol#GR?Bkpm6f`|pFevRaYm2#biBsr zWK(>Mqvc>bxRoc$-;?Zto0~=5Uh%Rw4gfi}6XiK>r_H#+b~q2n5LiSkmDAX&_$lM` z#=xSx>gX{!??nYQBQG`?IevqXD8HO7&?>Ni{eJD~d)BIQKLrzzecYS6wlTQShu#Ks=;Hn*o?mr>%j6+1AI_hNZq^a&LIt zE4{Yg;J$}+-5O2vyXd5P1yb_fL`9yff&A8^R+ijUh(oWfd 6n(Hmc%cA> zh>yWEF*RjAo$>E!mW^RR0JJ>Wf$63Gd5j?`^<61UFE$8|Hqn)hr)(D7(b>Tg5tH_Z z_BT0laooOH)6V^ZxoHs`mVI (4Sx>?MxqMGXicG?U6r$H0XF=E--MsrQPhtKM4fjG7#@@EZ0G zS;3L$X#&Ir-@wzL!c@&>w8~bi!Ds>2c*FP6&?0sY+0G4C_ovfcz?k=BG*OZ{ab)|@ zgmyXfNIb^T8B1>%`C+>DBUq%9 CanXW5Z{pq!1DAhH<;b=(5{mJ zDR3SPrPcVF1~3hFv0hEzv|zi%WJY|U>&5YgAdxo2Sa)LDea<(w;hBWI{0|v>{6`aH zUp!pBjq{QAkMN1(L!_hmdJ{O-P-8|l( Ah?RnP&TTu|LyuWG%@&J8 zH7r+F_oQ7v76pJcE*an73Zlpa4ofeDW?-o1fV1sXB_p6r69Aed1qM?R@YAIB6zk5y zJ( &Xe55fiJ$7k X9FAVTccN}Zu zTB _N*U3lx;@-V>^&DP+@=x`T}Z6 ztC(Etg|dkvw1&@Qz7`OecB+w4A^hnfPEV=qViMqevYqhm&o6Wgj3gX2K|p}}Wo`I9 zLeD|;V|M3ME7C04LtZ)n%CdUGBNYGWRjO|U3BW#FV;VZUmm-({ux4gvK6fvSq*}Ri zRi8r{y!2>BEyc?%0JLHoNJ(I`ZacX=fa?ykRI9c<)X=5hdDS0kcapw>#QQnMO)TsO zuhXdJF6U01k+uV1v9f`{*=1*P xuyoQ#4C- z>1l`V+j?~Te67d|Y&uXUyXDln)DThc7C3=o)~$3*{94^i87?q{^!3gw)ex{I8SYpq zf+5+RHBC$&`E2t$%cx*ZoKlSrt|ypSwNDIog2#{sz47F@0cy<&A~t3t9_I)1X~r3F zqa 3ta39?pTb4(@Yrl;YvOSB?15_c&%&1iD z6jR~(^XKvdrUuwJmG9jg4(Gq(CgNS@<}^J3q!zebkyo*uB-?NMni&fgMA=?JG3qYQ z6|UT+zP?BR*ZZjlr|8YfC}Tii;Q^$?E%Z9~1(!|qhO357KNc(eC&+vel+rdm-g}6= z#Pf8~ukcA1D+Bd3o{!<13(jkO8bX;8&B)t6T;Zz^(iVx~sj}=Z*>?2tIj!(?#`=&Z zMJ^jd77Gevv;j^}hlgdm61*?;>s@3-gDhPD25R@mB1-&}Wjj_1#GL^aA%Fqb(x47C zbk-B)D+f#My}w2cc%x%&00K(&ozvbm8{kYGdYzG__4#|}Ad|ahCN$ RZzoQG zmg0*hV&^Da1Dfs8r_jD&8ZKy2qcj*>37cR8Db^Airdg_QT|I 4`2>V)*z%$ftHQ?ZGsD zK|W?8hovH;xr?UJ+Bq=H(pTa!Bi_4p?ds+Thr>;?!A!~AExas%(sHBzf{QbLS8+8M zfuLj4JYp{hE`KhlQD!1JlB0pG={o7elRWssTgbHS2f$%up>^otWgr|il+OU41MHM8 zi};;mI(G=SSeN&KW4Y}Z3v<#0|0H{`fczNwWHvzfD(~1$TK++7MANGYG zZ3T8w?)qO zI=?QlHB02TE~( MxRKTtIWOe+CE1dlDERd`fTm#zBbJhu_BI^Ls<{D_Lx6UmjZHM@&D)ab z6`|nmDQ+O&qS3Ee-m9HZ7X;u_|MupZQKPWZW`u!5l}k^fwY{$3jpZ5{CdnOFTuU2! zueKB#9DDuaU hkf8ZyRwuw7Hq>6Tr-_i#f#AH)1C$IJ2{D^?w z5})W#R+?T`HcS4P1c&uE?<++&M@wv-qH5;+ytl{88gDL&beu-&H82#7SzpWO);X;J z_@-ZNr^C-P=x_*!M7$wT!yUU%_oDuE*1L*uQUO!wII>|6IR%%M`B{gy93f3UQEi`e zGJhv~ZVXYIizjj0vl9msHh?>Kv*esivM510Nj{gwlkdvaqHijX!e=&2DC#jtfZkra zOTMK^dgr w+8%`3oze5wtN=+acI^zPRAf1TH=HKk{KlYAZ!=D0 zKR-XGS1k*F+U@I@xGJ!!(>;?f8)8tZ&+AQsNRa}nShIwjR~C?d6B^hjhSxhLfXyuK zT1WQwZM%u+l9fcy$}w8~t1h!Bcr0`2Kf%2ccDc}hKX|{c*fu*lTMK4*BCc_BCl~f# z#sJ&_0`fXwz!kQ2DSWOMS4aI^1Ay%g@8o3E=lqFi!4_ZbNf-vI5?(Q#%z+(jAxUvN zi3EwT17d(hq#6ST+u)rTt+2w)#3au(L kKxG>%Rs=0CbL2PF$ibrH3KZ8kxB{dtxkblCmL^Y1&@{Azwdy1 z9=&< Zb1GqY@(jwBvf_z9Wr0l;7Mbb~(0&!6ttD(fv&7eHV#1>%tZ6qZ zK)OH^iNqo2kK&i+#`?qoG%VsVqLl5K1}#@Pjfw^kT|v1(zwYJQFO$|_AYHK-A+Pe% z{MdVmfe54u2sX$h`Lm^kunh>8OksW_5V|RR_J0G`?xb*S6c7;Lx8w%6CeS|Ke8fl& zAWPA&b^Lv7u=q9dzW@C~Zh+<`GNdj~c4EBFb_ V#Z5X9;oE{4B@)!Ww0E6}%)~SLJzdlt18=@W-kVx=9iJqO= z d>=jfA1hWL)QFa*6L?O! z(-H>>v+B;HDj6=Opk@(l%Bjb1cest24W2e8Rw*T)if#sW<~OU(Na|2hp6Z+HSQdlH zY?&y)&Kb{TWy0a0&?XEh5mgANm$jiJX)_BG_iXC&0MqfdcxcG;9i_nKoU&Y_Dk?AE z1DN&o)s?FCjZjN_`<8E%U8Li|qNM%Hyjoi7=hLdQJO1}yf#TjUrudY^14CG7SeRlG zcgbqO=N5hzCMKqL@5bvV00N9|q?=axLJ07|IU%Nb 1ud*A8r1Y6g+I5yV6)G|G%} 0$BV63&h~RRYuPdt zvwoK`0LpoU%{83PS6Uy dalA0iV&dht~l24aC%llc%}0idGFhI@0QY_yTd(#Y0T<$ zMx(_#0P3&svI8gs(9KBGN_SjUJMPPOk^Js`vN2t`N@ J^BL_#sMAd(TKo zFFR?~{H{?oKm&xI8qP&G0=b&<`T{}mGWj*o7@Sv`97YPQi!>D?lbu?FjoQPmGaVQ1 zcRkBhye@>^#xZCzB`rr!((g42(=agTTE~^gw}v!Mm751%7q m7miu08M30ZZ<0#7=Jifkc z)Gu4Kx99 JuwROj {w(^nb+bIs++i=#*cjwF#W+@1^QZRoX8A{l~IqrxX6E16#Iq)ie&?0Ar9w?0s2 7wC(-QA)E||Lj9gXTk$;Z(Vxge@`mkRe5fVKr@7@e_=#nlK(gTo&=6d z=l-e^{kmkS!o<9YKpe7>0?3GDuf}T_{7`W?7kdxc5bHUjWyGwa{mb(xY%q& IiKF3&nr-=bS5 zlF?z*e5M||FgcD QIS*)j}FIUJ;S^4(!pFpLLK4dUJ1Faot?Dq_GSxgX~yMA z OF~Iu)z9c{{^-O76YGVTuA9 zbVF+9UD5k53&gc9*Js?lZM7RvsIi8G5c4lzIV}2KzI^s 6Zm>zpl0p eP9K&Fut{%PNDXQ@sh*)GoKE;qZqP_Z} z)qY`El7MHm&CCM~WGt&uD$m@@La(LHs5}hp3+))e-hu1AcD~--%J*x1{`qaQ8O=*D z 71vfM1xz&qbKXG$LpP*N3nXl-z6X!!Rw#y!9d(S-n;!g9NZIM22`hJ3ZH@7 zP#(j-3|D7MHVOsuq6E6kGI@$hK1aPuxo(0cEtay3$6+w!#noc#Tp^8}&99|41&vX_ zds9$(^zGrdL)K+gRB v^baPR-7!d6nqlt6{0R z%<1?6l0yoLNys70l0;2q<0u(>U|kfE`Ugrv30K{$TLgyi8?RF!IN}nsPg H-gAJltiw& 5>N8I(m Okz{`y%S<*?^@>KMwg$AQAnJIklP4bbo@jD zq?9^r)*UNJ9C+=x)+fmKoHJcxcro P9dfJXNB zB8~0{%Jw_`?FuScbf*fTk2|g5fa z+h*4NhN>RmZPeHMeH)oJH`85eB^ zDmnu~)X+0Uz-mZk+4nLrBLI}l0D_n4Ht;M}&4Cl2_i!j}ayDcpG&MD~Fg_wo6Css4OlhE5qi}v6ae7gJV^nQN&s?$DM3P3U#L~*Ao6^Esx0cG^JE~lwJ+dL> zTW{H$$P2v@z$Ej#uvP$?8y>533g3v}?7{Z}SG`@Sr@9j@jHRz+B3d~5E7`O>;UMPC zG@SC<_Y~_?tQ$ADF?Yu>mVDMI8f6f!UrVi5)HB5T!1^OalkOXX_P_|s(%*s#EJB}> z0osFL$V`2=gMUW4LXm!>pM6PrbpW?N_mc1F$Wii55iFMOF$sH%UFZw4gcCJPu5AJ8 z*RPHD=T$(d8&qEYI0dR1%B^Sh0ytAqHMT89(T4O5tjrHC6_94wAHq>J9IZV-@NI4% z=>D3hAgZxC_}LkBJW1hqrUOISz+Cnas7E+g%AQ6gx+C0n<0euJ7=vbjcxkxgG)v)v z0wu@*EP2%Gi3QLKvre;A%zyqF=-&By2SjgiflAAhR(M)C% cr(w zmv3!iy3`{{ol2vaY&^%6YdstgOiIEHzZ}uRVBplLvI!k+J^GRkC@-+1EtosUOnN|o zAqkgF=JmEM%#}+toV)M)vn8CD?*x3#^j6z=KsEA2SFGQA!eg?+vXSN__`TWTvW_gH z{1=O@fsCpfd{@-&wS&BTvCI~bhxbshL;Q-jn9^Xibc(ezJa*7{a&-BAF>1nhMzk7O z^v_VWAJsrTeH5S|pcBblcKa6PCSaz@cW~KH!e5I^g;EIjEK?fFS%qnsQ?Fu@`P+I$ z0bxK7JpHrVU_hY=_?lsjYI%M6hI{}8U=lbmg1lX7;Jx!$F;&36er>?|DuhV9x8v8Z z?^J8Kc&mkqNya0jxWEs`05e-`2^!9l#w~XUP|XP@VAky@Ex6E*00 _qg4>Rr6vo<)#a}?p z%>IIs2Z0S$9UB2Ib)5%r*g=uSp#EfDONJ9rCr}-ae#aBhLbhcSaa?EwHE6UMnRMH^ zaUbac2~q9p0HmHBO=e82?O2IaK#N0|_1pl=7j9_8Wj2hIiyvR^tcYp!kfg%=acr4b zKaPb*L^PK!O4d#GcBI6+z223y$6_!SIGav)Y-lgSNld)?_+T*2(4-M=KefwY@nZz3 ztZT`qR5m^Hn~*`h37!%rb@_AnHNtU$ClHr{W9ES;bH*Dv1vsEa&J}A04f+$Y*4zI! zNv5rDJ*+*)j{tRj=cP7#AnU%pez*SZYNtkP$a5RuHG|rxg$#2PP&>A`KzzENkd>|~ zAT5r~MN-dgTzM`MgT^y)R)B3zfBp>N(}E~=0I^4gz*U1j=Dyubz1m)_!;I9Hm$k9q z)d3OnNRHfsT$~>;0$gUxNJe{SI8AGb%nlDFQhScF>C2!_N3%DB%{?XlU%tJy?%w zK3ZcPYXPauuPb`O!Yq-~nn8<&=i_3JcwpEjGk!b#VzbGNNNM4VO$7y1Ky>1F7+FK( zg-sbT1sR#3-FP0!(o$7x2$4!xI?s@8I2nINjhfYBWseY*;l~oW7zP5)8sAGCdIQiR zh%5c$#abm>iS5LpBAzYtu@tE9r13f%j}#J=;M@LPcR*0Rc{7Bh+o+l24kzI%)2WaG zG*IJvx^SMOWmhyWqh|5$P) p)kJ4_Js4RkF2zStuPoNf2@%~UEeqG|DMQi z9l&H*Dcf7B`0#t|;xr?0mkXD}5=Ya->UP6Xb)U^9no)eZ$~OFDZ?%`7GYWYB-31f) zS+q*^4HL!yPmV@zygj=*+KAn9$~IAy8wZfr$hYe6_UOS e;EQ{e zd6!XrsK@;0M}>Q# v>*kH& zwJn%-nb@wyvr w17JDpnlwD*Ue7*v*5Jwqzsq=bD;6xzFvCn2*|`egUaKcXfXL zhYXAJVkkrozDVM+kz>g@ NPpb`eCvY46x3i-YtyuttM8Lx`y3B?crPDs znBKpydVG{Io@3HFwauc1okMVWO5t^T%_AT^>#Q^b(7W&P;5%n*tty+CRL@nJ3N$Pt zznOXzCEugcQah5%3s#vlAp;SS 0~<@soHg 6E8NC;B0`&+ReD9%F_ldnw91-cgebMaNo| zgR`MThml8cmu?KQ6HG?Xt!#4-Z9mOze>`ED+#uuL`yZOLA~q_%LLVJW>L6p09%hkh zUMhlb|NSrA<`F*jOMbUE2M-ku@~O@VgW{+<3Ci%E>WPSmIPM!ERn^_E&zAa$n4MDA zw3Y`et;PGb&>uY-H*ifB@;&)WzbE7nHLV;}BZBFS*F7WfTh<{VD#oL=q_H%FxifTw zY6Wj9l=UX6lFVt^aZrI+Gehh=%7 $B*5Wl1$35u+b267A1TYtIwc(LYKd3O|L;y& zIQVnK6(22VdPEbDLhi6058c3ASA1Vr>R?w)=l!3PK#u&IGqBvj%ShMM^>ef 1eN{vksbSP#XFxS2~`@A=QWGlsw?7;4!MGp(_&bYn(m&DSOu*`*Ah02qCk}ba#%Q zlj_^*3u= w25k zh-Qr5Zm7<=Y5A}%vk(d2dpuhH98Jre&9t3BFi3#c7AoYkE>g~#eAD{S9(!xjS~6ED zC4SqiJ&c_EO0f}(NbGJF1MODD`VXZkGg_Zw8Wz3ot1&Kw*^E$;_O7j$e@^mZm@IX2 zDmGR_rOiw=yLop~Ai~SV@Tj{>2MbBBUYk#TQ|EjcA09}~R}0-s74A>vEn)lpJHciY z>Abn!dUJC#S~Wa1qn0PTQaIA4lpyFjRJ+t3?xpY(bdjdQP`Ll>J5*~TB~oXvXRXH$ z>OQ9V9G~Z9jY1~YE<1q24p6 zAvptnazP@z7ccHgS64GQ$<;QowbgO|wffr;qFL(ydT>RlkMz;`+)BhjM9643v{i7l z*3acVUkav7yyb7*XQ5XSQn;M?yw0;@1dLjOK4 ^ppmf4wx=lu*U z+}s~sB8wA-X~I3A>1%phbC+8hasn$4LX!|2X5WZst4ybG=a|z3e37oqEQav?O*w<; zl6NaK&&dc-y+e|zron`)#+gx6I}?blzD;wyaMpOrj-!msq7;n2hdBzicdmPO3YtW3 zL@yd|oZ99;z#H6jEH=^(Y?KzdG#VaCuB7t!n|9H$uLtLd4-Nlu4qYhT01F` z%_6s+@cOOAG3VuORlt5Lr*ZY*% V}eT`oZlh-?^9S+1ejr5o`Tv-sP?0hLi+6 zJvwJ8mJI bV-}WR lP^@ri#W~5-o-U=4RKgBdxnK(%a1hX~QUnu_)|O*(urY zkUmR$YP6wSgGVS^o8|J=F^wo;ilQCsH}M*b$XmOfKp4uGpBiSs2|1Z}zerdJQ!=nF zJKVjbAb{RTN~)jo*x0oJ@hbGCP`19mY}$`o_P4Jb&m+-y(maL41Ag3vz)!b?AY@U9 z)`{eF)r6mWSVi`47R<{hz@>8K(q^CNE582+t3f@(%n 9my0 z!pB9v@@A&mTx~L)aY4m#wMU~+lczaxyFgPxc20Bmd>6swu9m1}=)(g2{3VEVRlgpe zgn)R1tNaLy6}3KMIh(v;kmk9$EU9Ih++d^m{%FjCi&p6+G{bocWeZJdIKzNKZ`}ia z uGEW4*DTh6!p*Wo_$Zrkh6t~E+^cNYDzV!H9) zQVPGkK9AbrOL^y4{C;pTO) zosQS+_6DdvBxbB2O>*4(OZyS~P6y9(I6nv%MT>d{9unnnqxP(=E}qsksx0wx cXHK{${{ec8p8@Zel|d{UNipqN_}|wlPPY9mat;ySGk#&-v}jt88cFD^Mi7KFhUv zlftB42br wxB4@_5H8mR*37R+Z-%`n6 fOT z2jaE~3|2VIoi=WLa@(6!*$X?IE50f*D_}o)Z%#*nOOctkO^W7O@A%s6deX>fhogy{ z &xx3TO6u)S_g?PEVfPWlp= zy-(x3lOkk|_2tN&ge?0QnavlM7KgM;*O$)~?N@t0N~$wcKnwem_ELF$3(bcwE3fnV z43in%Q|UPfdy={9=86P`UR=d~p>0UIQ%KNmZSL$(p6e= 7+x!MTz_3Xqv lrh4E&AqBg3^kxHZp|KZsEN3dAMx| zzN;&7mQ{fg%)u+ SGx>Y=M>5z`5%%KGk%eHFLa{B|hyDHU-}i@VVmNTy!$^>e zfe@+iOR?AQ wjkK^y4^P@nX+4n=A=&WNzJ^_$nv1pFenDT5B;=h51br$;qAU`} z$6w&3xNKj2$s`2L0o}e+tAHL`^`T=D28RW+7iika_bhzHNVT~wzROkfjeq*@@AvPU zH7H^z`ETtVv97K!H23P!o7aNap_UQX7+(h}-BDtpEim264`DVp*t_=2rhRkJioZ{? z8@ilo_Qo3_;bYO)vm^qR3+`i+O6`bK;j<-oBSy7-l1A5~Hs&OrN}tRU!PT$0?Kl)% zvpCX+tE|eIX4d_U#S`TTQ&dK2kvU!Jg+2|$Hz2x08V?G&O^ZfL(Un_{+NSn;les5$ zZAZ^6CNiA}80cB7r;GgwKP;ZH#a`N^_ 2WSuzC9XQaBKPJF*zK+ZA`-aiuk|`S2_+9>CUN&qCk+I5)C1@AcV9 zIig-t&h-8e*fFZUx;1`(VjVokgL-Ia94|-iW)+lN2r@TUb4m&wEpeOrQ&+L=J@G=w zA$qCV7n=g}F)sxv-Vzs5 Z+hrWI=7td**N(?l)y!ostIasTNG|cGI7UV@*A3j-JqQ0aO%c7BdbDCjt znYg~HWgt4Ia<4e|JE%o>9B*D*q-oW=`kbKWsJPGg!e)<`jK2!M {!zFi$B(edKzAMUYQuWbtn&o?%?`Rrz5%*;IA0?zwoJ1FP`mRfv#< z_eswN1yb(@#61j;X~#SeBUc#I6AxCXwk$e~ehq{mE~t=Dg_D=OzDD)zkj`*DH;U6M z+mm(EQS6W(Ki1FG< gN?Pd?!XcZ!y}aP!+RaDU9bAP%i+R-i zcs=3O{a@-TFjr*9GB*&$8KvI5N-3NUJ?-LE%d1sjEId);;z{Y&M{eLnN7e@(r2RGC znf4gW)wwEXsIHKH#OPkih8iu6!{A+a-@H+<=3V;bW7r%Xq#P|drv{)A_YuPLu;ruL zmV JBHK+I_D%!tg5MGmE_)Jsu28CoYSR^;N&}#>cf`Y#=K6Zg&`8 zW<1Btc@Fx{C*TL+&X)a5XEwRl>Yv5@ZT}W8p$=d2I!_psk%)>~myl*nXD`ff-KC^# ztAp@BY$31ZeE`#YLcfL1&&!L?dYYd6fiR!;1~F(LulpKE;D;AUx^Un@j5o@e**<1n z&R9Li!mumRTcFRjIGt7(O=y<51t#<>3HuabC$-6PIBhS3Qfl$pLK6R8eI9_jzGuH1 z@Px>?I%YOl!HRu?@&h;r$>o&LkwKAEIjwf3FuIfHJm#-~_(BJgD145sSJ=_JH1aFY zri`lXCpZD;_-HD0aTA9Pq-&2{gQ81Pt{an8F^w_r)9uOSn|ce)pgql_m1JuBR6i+b z&|D3$?T!8?X_$y@)5j LRntj@*PoJJs%h{S (=u-GwWAc9l+1A=pZ&D z+cyB3A+j`Qcrg6tQHO^yh3f@E*K^Ez$VIIFYK`j5KzE+nxoL^>(nqH;%v!%& tjqjxZ4HMXEJ_npBJu8B6rU=F*TjMeJ6si5b!z$ i%Iit5AiWYh46;yX4xl}Z#GBy2Ao0Czb^KnOpTt>#h N!P2OXi`fBblHGt1vEbel=m0&@HL z`hxg`)3Vjzri}BJ(NsR}oR-tVMDu%n{pn9gL?xGe=0^q4e+R! `nPoanE+H{RVn;YUA?xVc;Zu;w|&CYr50Un1~hLFCeAKjzOx@;`ltZ=^?z;n zs}cIQ|Em;t5U3VlDjh5cSd#z6*KaJ}wcFmmE~)kSci8R!q-0F{5D)99l>IBsFc$n% z_=WCMQWzNUJTJGbe3SXFsG_O*OdVYXjfZUTvE$K7msxAe;QrmK8EV2X(-^)KzQUZ( z1w2z#GUKJ@`}n)eHci6dQ}_?&E3T(0Xa!=P(AeYAjgbFCxQU{n6=8S{z9BcLuj#0} zCGn5eF8J1~s{H(d`+31B3_kbYQ{N-}q@G3b3y4vaYsKkkjN-bC2I&M%JB#2*$L7UF zgA5so$|7i#7_SxNel`o}nseQ-l!sy}_XX+^{V5s$?}v(hzA3$Yy4ERX1xBIn26jH& z#|I|>fEVZgjrW+$YkvR!Bj`t1=$%CV{_fo=pGcSX)`(uLrwQ4A2sjo6KMFK=X0!Oy zWEiX5-1D=3@PIuV>+nd<^k1os=JkS;oxYDpbWwf+?>n-4m_G~ev@e$hRWlcPeMhNQ znwx(gR20zACezWb=|$@BGu~MGjLL5?qZKsw-~Y)MozzkfZSGJ2*ZwK1{#X68TB{;~ z5ZL?mPAPj9!G?LuVJUBUcew)jyImR&tI)FVgZ0z+79eT99IOWROf%d)K%0B-(ZQPa z=E3KLo5HtTzz)am{QZJAbl6It{)*hqG(-%RSwGnLN(^?@L ez(1w!y0>c4$_U)l?Bj>+A0_)D&^3mrlfboFugOmR+z9i;c2koZnPjj=S zd>Y~N=a~!n`T1q0!n_|BYh4XSL61f+kC7fUkXnvVDe)cKL?;e~5U1~C91t#2DdU*+ z>U}TW?wkTm6&nb&jcJSFU?%)5HP<%~2UM?q63>DWWbi_lg+G#Dj%+ML{1Tg#$Fe)t z9=w!-wefiI`jqF`%UD}m`|E`}HE(}Rk>6unTr5o4B+$eULnc;$_ijjqlK(1A`4hr( z*%+~H7A|yQm6SK>75XDQ99kwF4n||BFAqVU!nvNmrcJe5;w{(ek4xJ+^f^CV* vc&95ptMw0p5Nwmj^X68@wol=7>`k-bSO)@=I7DcT?j&Z58U;CYwtaS znrz#3VH@%&DmFyAjoze7S5T1NL25*#Hz7cP5U`;SAVsRw&^tjo36Mya8X!REz4zV& z--T=5we~x+|E&GZp1poN{BSaJkGb!h*Lk1US&rkl)^=?>#u!QaKVDBYG8r~$6ejxE z5;3*VsdnRv04mNMK!aHZU}C^eEV96RjC~;I)XQF*2;i08Tq^2S(acmI*MlJ1psfvo zbX4&Y#I%3}MG2B6G6;|h_-o0p(f Z*sU5P^{ThODK8tmpaC7#= fU?oC)G^-CN-tItI1PT7UWwr?NU@ zOyeVPy2>MGJZOm;5Y2N2!+Fzt-O7&Li+oN1nI;gxwgAd)&J^5lm1qJK4?GF!l!yEK zu81T CA0XF3 zlqW~mW=L}=n7=g7=GOJ=kKKR64~X+s{N~NwTjO74Wo3!ECdL`6 z!^!pj45H3`r|I?k+d!z~n7ua-5(VnoM@WBv|E+bI`UeMuUmwXfnS3fsF1oEA7kO;T zw-o^>JKbLUAT5v&G0f6T18ZnhYJ`6F>Fd_wU`FjO1L=sA7yA}aKmeju#lvM|!4`E* zcZA^yTR;13YjhQ0lLD=rn6I2Z2lJ?kl~QC+jB1RaMvmxoKvs2i^^F@hRx2f61C<_6 z#l=^Z&;1gA-Q#|>yCQkJ*GkLk*04s=Om+n4fB5mKKOo->St950^ZL@#jfQ^t$J;~< zY$RIJa0fm5|cXLL+p4pa2(oKAN9487zkhVAS49l=P29AN0?RSle zEb>0@xpVe(1AKpC;!^=H80i4%E!OUBvo`jOkbw}Ls@jFlG*81>{ACVy=EFGkRsdEW zu**aM=ol~ L7fHWcm KckjMRe%=Jg z$=(}HKY-U8tlXQ~mG&O3fKgH}ojT6TOMiY+&1XNq)#2Eih=ZLLr1U6=XF0 _(EY^RTTt=tY3jGpPu*F zoO0Tp9Vqmj&AFZR<3m#I7uf2E84%dHtm1ua?ux@A1PkUNy_?>$nqV}> k QlfYsNScfkS*pddB7Y7A3JFF> z#0 8i`!d0@RZxvxbA5ML&*%*!KuSJ40h~uClB17y zwsw~NpxgP2l~lBz1(tY|eiRFTDG*e0?8k7gySE@>8A STftk=qhwL>l#K!MKfj9|9E_J=HH;G+t_1byIr< zleBDF80{uaW&pI?-QLLGe$2umccL22&kV5o=gWrOVj1G=8X5rP-ubG;+OJQbsyNL! z&KSLLId`O0SHHhdu>I?-UWFfctLH}R1ETJ5>jI50F93ZhO$k$p6&7+hdOa+@+6wli zuh*8%%q9mUNyUVriOI>` QFbDq9v zahS;jg_}XC`__=C-kP9CS1NjQ=1({A9Tl)`usR4?)&wk gw2@&JWIR54bJ>axfd>U<>cE(1+d>pgn0V!W$UAwbb}mFJOg*3P`$u zkyb}!TP)y~?S9!EEwhPO?5zZ)9zlW|hGYj#y;4g6-~{{L0gz=`8bT9R-t;!@LuUbg zEBgcKa2GJ~92Te{R(l;uAbbEChKKX)dR(~zA>Blw?Z9=h*xh39cjrTzF3Y{`D9Dl} zr(V`gdU}bszsJhRD|>SLABM50i6RbMHsu+4;D+<$OkQ(-tVnucyXPws9w4D3kw_^i zDS$!r3Q(GyCZ&AllD@W9!2uJ?ZFR(+H`})V8dIToep>`*ROD=(-y~3d+D30ugAx49 zZ?}W3tRWv`yVG?)L8e^_{#J74i8z8M)#`&0aVyj;gJ-Jsj+Y8=w6u>&@X9a%do2q- z1EeEq8u3z%6mki9Mp5T-?WUXl(!vfyeJPCr=SRF*KZ$$z1q3Yi=H*yF)kuBWxzLjx zGY_yq;Q4$9n z?iYhtoUTG^$X@h%`~mkTn)V2R!$ziHz%u+4JWoU&a>G`P>I0~j2ey4Fzg!cbzHV(j z+fK3>8A1cylUl$MmB>KiUMD@E!t)hb;%$gK>>2yPGy $x4(f}yLosvD0i~Gd^XDg$u|kHWb=&(O z(gW(p3d$2!-`Ge*X*Jq9faGqWdp N*f7J3>E`GR52<~B*WgG zX;!!CF0ak~$o=5K#6&%X>LyqaB_LlS^b;h|myp3~0BThfkK_bAG?1>Wt%6b^_2MZn zu8d1;fA$G%XK6tw2jnv{lOUIW??VkP33U)JopBU(p0OL)GX0a`gOcUc9nOrM|8Et4 ze?aud-rkokMg6IV@BFEUDSovz%w8_vKX;yFHaYR{7yj_Q=Lr|(8XNS%{eE%(ff?L+ z9~*dDS@Wk-`Ufi|j{m_L(41CaI?uY#y( %AkTRC^sFX`qapr0M*iP|{3zNp`|3vjnBZo7h!WlHL}@a% zs0Z3p-|#W)RRE5%2XHB0ox@)3I^IQ}u9T*qe+ {ozudUb%(wZ| z+ue)EI=$qd2ugh5XQ}=jKQq4>IRO>d_l7Tg)u^6<5*&!Ao}y9?$@iT81D5h<@&6N+ z!pkovY<~~&7_?BwBLC%Me_RPzKu{D|_!oEjDPHB&k#0@?YNJMmjQwjJ@BgdJ{{OGW zI>vN=Vy!x)1ot+_)$&Wti|xlt`1o1kQRrsE;r3d$h|-((1n%ziD#`Wfy(f##Hw6?X zR~^$7Qa I7crbcCVJ09AO4;mIkz|HtO0nX>WMe0{P7AdAE-el5=MS`x-r0Her3J)_ zd^sxJ=_Up|yvFbs4`MK>3HgFiG}lNrY})P}1XH 4Wy=u@9sKChBQb&MK?7YP~}dAdu72o z+lQCF4nlm`r*>U?GFo*_icZ2PCu?g%gH(ASsuG(wd8>4Dp}VrTq^o|8ml<7MDROwV z 4SD2$~99@S`fE>1@#fuke zXNQ&yF!XY}yy+bJ0iAUoC9)xs9`s7T^3tB_q|p*mFSl uJtXsb;tD#Zp5S|h