CLI improvements: --json output, filters, arch-search, ecal-score, deck fixes

6 CLI improvements from MCP integration testing + deck bug fixes:

- kb_cli.py: --json on search, new arch-search and ecal-score subcommands,
  _load_yaml handles multi-document YAML (fixes health command on 32 files)
- findings_cli.py: --json on search/list/stats, filter flags on search
  (--product, --severity, --tag, --client, --status, --category)
- validate-architecture.py: --profile optional, --output defaults to stdout
- common-objections.yaml + ecal-artefacts-catalog.yaml: merge front matter
- oci_deck_gen.py: fix slide 9 cost_notes char iteration, fix slide 12
  migration field mapping (duration/milestones), dynamic phase spacing
- proposal-spec.yaml: replace real name with fictional Carlos Mendoza

All 14 skill options validated with generated deliverables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-04-12 23:02:40 -03:00
parent ca93a0aa4e
commit b48d155c1b
27 changed files with 2857 additions and 77 deletions

View File

@@ -0,0 +1,378 @@
[
{
"title": "Deploy Oracle Autonomous Database on Oracle Database@Azure",
"url": "https://docs.oracle.com/en/solutions/deploy-autonomous-database-db-at-azure/index.html",
"type": "reference-architecture",
"date": "2024-10",
"services": [
"adb-s",
"adg",
"azure"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr",
"autonomous"
],
"summary": "Multi-AZ deployment of ADB-S on Database@Azure with Autonomous Data Guard. Recommends VNet peering between app and DB VNets, TAC for availability, and ADG standby in a different AZ for automatic failover.\n",
"terraform": null
},
{
"title": "Oracle MAA for Oracle Database@Azure",
"url": "https://docs.oracle.com/en/solutions/oracle-maa-db-at-azure/index.html",
"type": "reference-architecture",
"date": "2025-05",
"services": [
"exacs",
"adg",
"vault",
"azure"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr",
"autonomous"
],
"summary": "Cross-AZ Data Guard on ExaCS in Database@Azure. Active Data Guard recommended for cross-AZ replication (block repair, app continuity, read offload). Backups to Autonomous Recovery Service.\n",
"terraform": null
},
{
"title": "Implement disaster recovery with local and regional standbys on Oracle Database@Azure",
"url": "https://docs.oracle.com/en/solutions/local-regional-standby-dr-db-at-azure/index.html",
"type": "reference-architecture",
"date": "2025-05",
"services": [
"exacs",
"adg",
"azure",
"fsdr"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr"
],
"summary": "Local standby for HA within same region, regional standby for DR across Azure regions. Uses Active Data Guard with Fast-Start Failover. Recommends Full Stack DR service for automated failover orchestration.\n",
"terraform": null
},
{
"title": "Implement disaster recovery with multi-region standby on Oracle Database@Azure",
"url": "https://docs.oracle.com/en/solutions/multi-region-standby-dr-db-at-azure/index.html",
"type": "reference-architecture",
"date": "2025-04",
"services": [
"exacs",
"adg",
"azure"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr"
],
"summary": "Multi-region DR for ExaCS on Database@Azure using Data Guard. Cross-region standby with switchover/failover capabilities. Includes network topology for Azure-to-Azure cross-region connectivity.\n",
"terraform": null
},
{
"title": "Implement cross-region disaster recovery for Exadata Database on Oracle Database@Azure",
"url": "https://docs.oracle.com/en/solutions/exadb-dr-on-db-azure/index.html",
"type": "reference-architecture",
"date": "2025-01",
"services": [
"exacs",
"adg",
"azure",
"fsdr"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr"
],
"summary": "Cross-region DR for ExaCS on Database@Azure. OCI-managed networks for peering (better performance, first 10 TB/month free). Data Guard for cross-region replication, FSDR for automated failover orchestration.\n",
"terraform": "https://github.com/oracle-quickstart/oci-multicloud-azure"
},
{
"title": "Deploy Active Data Guard Far Sync to protect data across Oracle Database@Azure regions",
"url": "https://docs.oracle.com/en/solutions/active-data-guard-far-sync-oracle-db-at-azure/index.html",
"type": "reference-architecture",
"date": "2025-02",
"services": [
"exacs",
"adg",
"azure"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr"
],
"summary": "Far Sync instance for zero data loss protection across Azure regions. Synchronous redo transport to Far Sync, async to remote standby. Eliminates performance impact of synchronous shipping over long distances.\n",
"terraform": null
},
{
"title": "Implement Oracle Database Autonomous Recovery Service with Oracle Database@Azure",
"url": "https://docs.oracle.com/en/solutions/implement-recovery-service-db-at-azure/index.html",
"type": "reference-architecture",
"date": "2025-01",
"services": [
"exacs",
"azure"
],
"tags": [
"database",
"multicloud",
"azure",
"ha-dr"
],
"summary": "Autonomous Recovery Service for ExaCS backups on Database@Azure. Automated backup management with real-time protection and point-in-time recovery capabilities.\n",
"terraform": null
},
{
"title": "Deploy Oracle Autonomous Database on Oracle Database@Google Cloud",
"url": "https://docs.oracle.com/en/solutions/deploy-adb-db-at-google-cloud/index.html",
"type": "reference-architecture",
"date": "2025-03",
"services": [
"adb-s",
"adg",
"google-cloud"
],
"tags": [
"database",
"multicloud",
"ha-dr",
"autonomous"
],
"summary": "ADB-S on Database@Google Cloud with cross-region ADG. Non-overlapping CIDR between VPC and VCN required. App tier should span 2+ AZs with Google Global Load Balancer for failover.\n",
"terraform": null
},
{
"title": "Deploy Active Data Guard Far Sync to protect data across Oracle Database@AWS regions",
"url": "https://docs.oracle.com/en/solutions/dr-active-dg-farsync-db-at-aws/index.html",
"type": "reference-architecture",
"date": "2025-09",
"services": [
"exacs",
"adg",
"aws"
],
"tags": [
"database",
"multicloud",
"aws",
"ha-dr"
],
"summary": "Far Sync instance for zero data loss protection across AWS regions. Synchronous redo to local Far Sync, asynchronous to remote standby. Requires cross-region AWS networking for redo transport.\n",
"terraform": null
},
{
"title": "Implement disaster recovery with local and regional standbys on Oracle Database@AWS",
"url": "https://docs.oracle.com/en/solutions/dr-local-regional-standby-db-at-aws/index.html",
"type": "reference-architecture",
"date": "2025-09",
"services": [
"exacs",
"adg",
"aws",
"fsdr"
],
"tags": [
"database",
"multicloud",
"aws",
"ha-dr"
],
"summary": "Local standby for HA within same AWS region, regional standby for DR. Active Data Guard with Fast-Start Failover for automated failover. Full Stack DR service for cross-service failover orchestration.\n",
"terraform": null
},
{
"title": "Implement disaster recovery with cross-zonal Data Guard on Oracle Database@AWS",
"url": "https://docs.oracle.com/en/solutions/cross-zone-dr-db-at-aws/index.html",
"type": "reference-architecture",
"date": "2025-08",
"services": [
"exacs",
"adg",
"aws"
],
"tags": [
"database",
"multicloud",
"aws",
"ha-dr"
],
"summary": "Cross-AZ Data Guard on Database@AWS for HA. Synchronous redo transport between AZs for zero data loss. Fast-Start Failover for automatic database switchover on failure.\n",
"terraform": null
},
{
"title": "Implement disaster recovery with cross-regional Data Guard on Oracle Database@AWS",
"url": "https://docs.oracle.com/en/solutions/implement-dr-cross-region-dg-odb-aws/index.html",
"type": "reference-architecture",
"date": "2025-08",
"services": [
"exacs",
"adg",
"aws"
],
"tags": [
"database",
"multicloud",
"aws",
"ha-dr"
],
"summary": "Cross-region Data Guard on Database@AWS for DR. Asynchronous redo transport for cross-region replication. Planned switchover for maintenance, forced failover for disaster scenarios.\n",
"terraform": null
},
{
"title": "Migrate Oracle RAC Databases to OCI",
"url": "https://docs.oracle.com/en/solutions/ensure-ha-migrate-vmware-workloads-to-oci/migrate-oracle-rac-databases1.html",
"type": "reference-architecture",
"date": "2025-01",
"services": [
"exacs",
"exascale",
"adb-d",
"base-db"
],
"tags": [
"database",
"migration",
"ha-dr"
],
"summary": "Compares 4 RAC migration targets: ExaCS Dedicated, Exascale, ADB-D, and 2-node RAC on Base DB. ExaCS recommended for full RAC feature parity. Exascale for 23ai-only without dedicated infra commitment.\n",
"terraform": null
},
{
"title": "Deploy ORDS with High Availability on OCI",
"url": "https://docs.oracle.com/en/solutions/deploy-ords-ha-oci/index.html",
"type": "reference-architecture",
"date": "2025-06",
"services": [
"compute",
"load-balancer",
"adb-s",
"bastion"
],
"tags": [
"database",
"application",
"ha-dr"
],
"summary": "Multi-instance ORDS behind OCI Load Balancer for HA REST access to Oracle DB. Works with ADB-S, DBCS, or ExaCS. Recommends DB in private subnet, ORDS in public with granular NSG rules.\n",
"terraform": null
},
{
"title": "Configure Data Guard for Oracle Exadata Database Service on Dedicated Infrastructure",
"url": "https://docs.oracle.com/en/solutions/dataguard-exadata-dedicated-infrastructure/index.html",
"type": "reference-architecture",
"date": "2025-07",
"services": [
"exacs",
"adg"
],
"tags": [
"database",
"ha-dr"
],
"summary": "Data Guard configuration for ExaCS Dedicated. Active Data Guard for read offload and automatic failover. Cross-region standby for DR with Fast-Start Failover for automated switchover.\n",
"terraform": null
},
{
"title": "Back up from Exadata on Dedicated Infrastructure to Zero Data Loss Autonomous Recovery",
"url": "https://docs.oracle.com/en/solutions/back-up-exadata-dedicated-zero-data-loss-recovery/index.html",
"type": "reference-architecture",
"date": "2025-07",
"services": [
"exacs"
],
"tags": [
"database",
"ha-dr"
],
"summary": "Autonomous Recovery Service for ExaCS backups. Automated backup management with real-time redo protection. Validates backup recoverability automatically.\n",
"terraform": null
},
{
"title": "Configure a standby database for disaster recovery using Oracle Exadata Database Service on Cloud@Customer",
"url": "https://docs.oracle.com/en/solutions/exadata-cloud-at-customer-standby/index.html",
"type": "reference-architecture",
"date": "2025-07",
"services": [
"exacs",
"adg"
],
"tags": [
"database",
"ha-dr"
],
"summary": "Data Guard standby on ExaCS Cloud@Customer for hybrid DR. On-premises primary with cloud standby, or cloud primary with on-premises standby for data sovereignty requirements.\n",
"terraform": null
},
{
"title": "Learn about maximum availability architecture for PeopleSoft",
"url": "https://docs.oracle.com/en/solutions/learn-about-maa-for-peoplesoft/index.html",
"type": "reference-architecture",
"date": "2024-08",
"services": [
"exacs",
"adg",
"load-balancer",
"compute"
],
"tags": [
"application",
"ha-dr",
"peoplesoft"
],
"summary": "MAA for PeopleSoft on OCI. Active Data Guard for database HA/DR, multi-instance PIA behind Load Balancer, Process Scheduler on multiple nodes for batch processing resilience.\n",
"terraform": null
},
{
"title": "Provision and deploy a maximum availability solution for PeopleSoft on Oracle Cloud",
"url": "https://docs.oracle.com/en/solutions/deploy-maa-for-peoplesoft-on-oci/index.html",
"type": "reference-architecture",
"date": "2024-08",
"services": [
"exacs",
"adg",
"load-balancer",
"compute"
],
"tags": [
"application",
"ha-dr",
"peoplesoft"
],
"summary": "Step-by-step PeopleSoft MAA deployment on OCI. Terraform stacks for infrastructure provisioning, Data Guard configuration, and PeopleSoft application tier setup.\n",
"terraform": null
},
{
"title": "Run PeopleSoft ERP and Autonomous Database in an HA multicloud deployment",
"url": "https://docs.oracle.com/en/solutions/bread-multicloud-on-oci/index.html",
"type": "reference-architecture",
"date": "2025-02",
"services": [
"adb-s",
"compute",
"load-balancer"
],
"tags": [
"application",
"ha-dr",
"multicloud",
"peoplesoft",
"autonomous"
],
"summary": "PeopleSoft HA with ADB-S across cloud providers. Application tier on OCI compute with database on ADB-S. Multi-AZ deployment for high availability with automatic failover.\n",
"terraform": null
}
]

View File

@@ -0,0 +1,195 @@
<mxfile host="app.diagrams.net" agent="OCI Deal Accelerator" version="24.0.0" type="device">
<diagram name="OCI Architecture" id="oci-arch">
<mxGraphModel dx="1900" dy="1200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1900" pageHeight="1200" background="#FFFFFF" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="139766084988960" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;connectable=1;pointerEvents=1;" vertex="1" parent="1">
<mxGeometry x="30" y="250" width="50" height="60" as="geometry" />
</mxCell>
<mxCell id="139766136148656" value="MELI&#xa;Applications" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;" vertex="1" parent="139766084988960">
<mxGeometry x="-10" y="48" width="70" height="20" as="geometry" />
</mxCell>
<mxCell id="139766084989440" value="AWS&#xa;(Current State)" style="whiteSpace=wrap;rounded=1;fillColor=none;strokeColor=#70665E;dashed=1;html=1;strokeWidth=2;dashPattern=6 4;align=left;fontFamily=Oracle Sans;verticalAlign=top;fontColor=#70665E;fontSize=12;spacingLeft=5;spacingTop=5;arcSize=6;" vertex="1" parent="1">
<mxGeometry x="10" y="80" width="220" height="180" as="geometry" />
</mxCell>
<mxCell id="139766084990064" value="DynamoDB&#xa;30K Tables&#xa;70M RPM Peak" style="whiteSpace=wrap;rounded=1;fillColor=#FCFBFA;strokeColor=#2D5967;dashed=0;html=1;strokeWidth=1.5;fontColor=#2D5967;fontSize=11;fontFamily=Oracle Sans;arcSize=8;verticalAlign=middle;align=center;" vertex="1" parent="139766084989440">
<mxGeometry x="30" y="60" width="160" height="80" as="geometry" />
</mxCell>
<mxCell id="139766084989248" value="Oracle Cloud Infrastructure" style="whiteSpace=wrap;rounded=1;fillColor=none;strokeColor=#9E9892;dashed=1;html=1;strokeWidth=1;dashPattern=6 4;align=left;fontFamily=Oracle Sans;verticalAlign=top;fontColor=#312D2A;fontSize=13;fontStyle=1;spacingLeft=10;spacingTop=8;arcSize=1;" vertex="1" parent="1">
<mxGeometry x="280" y="80" width="1100" height="520" as="geometry" />
</mxCell>
<mxCell id="139766084990976" value="Region — São Paulo" style="whiteSpace=wrap;rounded=1;fillColor=#F5F4F2;strokeColor=#9E9892;dashed=0;html=1;align=left;fontFamily=Oracle Sans;verticalAlign=top;arcSize=5;fontColor=#312D2A;fontSize=13;fontStyle=1;spacingLeft=10;spacingTop=8;" vertex="1" parent="139766084989248">
<mxGeometry x="15" y="40" width="1070" height="460" as="geometry" />
</mxCell>
<mxCell id="139766084991984" value="VCN KVS Production (10.0.0.0/16)" style="whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=#AE562C;dashed=1;html=1;strokeWidth=2;dashPattern=6 4;align=left;fontFamily=Oracle Sans;verticalAlign=top;fontColor=#AE562C;perimeterSpacing=0;fontSize=12;fontStyle=1;spacingLeft=8;spacingTop=6;" vertex="1" parent="139766084990976">
<mxGeometry x="15" y="45" width="1040" height="400" as="geometry" />
</mxCell>
<mxCell id="139766084992656" value="Application Subnet (Private) — 10.0.1.0/24" style="whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=#AE562C;dashed=1;html=1;strokeWidth=1;dashPattern=6 4;align=left;fontFamily=Oracle Sans;verticalAlign=top;fontColor=#AE562C;fontSize=11;fontStyle=1;spacingLeft=8;spacingTop=4;" vertex="1" parent="139766084991984">
<mxGeometry x="8" y="32" width="1024" height="140" as="geometry" />
</mxCell>
<mxCell id="139766069527424" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084992656">
<mxGeometry x="246" y="30" width="160" height="44" as="geometry" />
</mxCell>
<mxCell id="139766122318064" value="OCI NoSQL&#xa;Service Endpoint" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084992656">
<mxGeometry x="246" y="76" width="160" height="36" as="geometry" />
</mxCell>
<mxCell id="139766069534000" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084992656">
<mxGeometry x="422" y="30" width="180" height="28" as="geometry" />
</mxCell>
<mxCell id="139766111346400" value="NoSQL&#xa;Elastic Pod Dedicated&#xa;(Isolated Compute)" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084992656">
<mxGeometry x="422" y="60" width="180" height="52" as="geometry" />
</mxCell>
<mxCell id="139766069536112" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084992656">
<mxGeometry x="618" y="30" width="160" height="28" as="geometry" />
</mxCell>
<mxCell id="139766108726976" value="NoSQL Tables&#xa;30K Tables&#xa;70M RPM Peak" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084992656">
<mxGeometry x="618" y="60" width="160" height="52" as="geometry" />
</mxCell>
<mxCell id="139766084986608" value="AI Memory Subnet (Private) — 10.0.3.0/24" style="whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=#AE562C;dashed=1;html=1;strokeWidth=1;dashPattern=6 4;align=left;fontFamily=Oracle Sans;verticalAlign=top;fontColor=#AE562C;fontSize=11;fontStyle=1;spacingLeft=8;spacingTop=4;" vertex="1" parent="139766084991984">
<mxGeometry x="8" y="186" width="1024" height="140" as="geometry" />
</mxCell>
<mxCell id="139766069531888" value="Oracle ADB-S 23ai&#xa;AI Vector Search&#xa;(Agent Memory)" style="whiteSpace=wrap;rounded=1;fillColor=#FCFBFA;strokeColor=#2D5967;dashed=0;html=1;strokeWidth=1.5;fontColor=#2D5967;fontSize=11;fontFamily=Oracle Sans;arcSize=8;verticalAlign=middle;align=center;" vertex="1" parent="139766084986608">
<mxGeometry x="266" y="30" width="180" height="80" as="geometry" />
</mxCell>
<mxCell id="139766069540912" value="OCI GenAI&#xa;Embedding&#xa;Service" style="whiteSpace=wrap;rounded=1;fillColor=#FCFBFA;strokeColor=#2D5967;dashed=0;html=1;strokeWidth=1.5;fontColor=#2D5967;fontSize=11;fontFamily=Oracle Sans;arcSize=8;verticalAlign=middle;align=center;" vertex="1" parent="139766084986608">
<mxGeometry x="462" y="30" width="140" height="80" as="geometry" />
</mxCell>
<mxCell id="139766069542640" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084986608">
<mxGeometry x="618" y="30" width="140" height="44" as="geometry" />
</mxCell>
<mxCell id="139766069542784" value="OCI Functions&#xa;Memory Sync" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084986608">
<mxGeometry x="618" y="76" width="140" height="36" as="geometry" />
</mxCell>
<mxCell id="139766084817968" value="Management Subnet (Private) — 10.0.2.0/24" style="whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=#AE562C;dashed=1;html=1;strokeWidth=1;dashPattern=6 4;align=left;fontFamily=Oracle Sans;verticalAlign=top;fontColor=#AE562C;fontSize=11;fontStyle=1;spacingLeft=8;spacingTop=4;" vertex="1" parent="139766084991984">
<mxGeometry x="8" y="340" width="1024" height="120" as="geometry" />
</mxCell>
<mxCell id="139766069584112" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084817968">
<mxGeometry x="384" y="30" width="120" height="34" as="geometry" />
</mxCell>
<mxCell id="139766084991408" value="OCI&#xa;Monitoring" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084817968">
<mxGeometry x="384" y="66" width="120" height="36" as="geometry" />
</mxCell>
<mxCell id="139766069586800" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084817968">
<mxGeometry x="520" y="30" width="120" height="34" as="geometry" />
</mxCell>
<mxCell id="139766132774896" value="OCI&#xa;Logging" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084817968">
<mxGeometry x="520" y="66" width="120" height="36" as="geometry" />
</mxCell>
<mxCell id="139766069591360" value="" style="group;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;pointerEvents=1;connectable=1;" vertex="1" parent="139766084991984">
<mxGeometry x="10" y="40" width="110" height="34" as="geometry" />
</mxCell>
<mxCell id="139766069586224" value="Service&#xa;Gateway" style="text;whiteSpace=wrap;rounded=0;fillColor=none;strokeColor=none;dashed=0;html=1;overflow=visible;align=center;verticalAlign=top;fontFamily=Oracle Sans;fontSize=11;fontColor=#312D2A;spacingTop=2;" vertex="1" parent="139766084991984">
<mxGeometry x="10" y="76" width="110" height="36" as="geometry" />
</mxCell>
<mxCell id="139766084992224" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766084988960" target="139766084990064" value="Current: SDK calls">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766084992896" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766084988960" target="139766069527424" value="Target: OCI NoSQL SDK">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766108632320" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766069527424" target="139766069536112" value="R/W Operations">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766069577392" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766069591360" target="139766069527424" value="Private access">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766069591456" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766069534000" target="139766069536112" value="Dedicated&#xa;Infrastructure">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766069532176" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766069536112" target="139766069542640" value="Memory Sync&#xa;(hot → warm)">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766069537168" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766069542640" target="139766069531888" value="Vectorize &amp;&#xa;Store">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766069532272" style="elbow=vertical;endFill=0;startFill=0;labelBackgroundColor=#FFFFFF;labelBorderColor=none;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;rounded=1;jettySize=auto;startArrow=none;endArrow=open;strokeColor=#312D2A;strokeWidth=1;endSize=6;fontFamily=Oracle Sans;fontSize=10;fontColor=#312D2A;labelBackgroundColor=#FFFFFF;" edge="1" parent="1" source="139766069540912" target="139766069531888" value="Embeddings">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="139766084991024" value="MELI KVS — OCI NoSQL Architecture" style="text;whiteSpace=wrap;rounded=0;dashed=0;html=1;fontSize=18;fontColor=#312D2A;fontFamily=Oracle Sans;align=center;verticalAlign=middle;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="0" y="8" width="1380" height="35" as="geometry" />
</mxCell>
<mxCell id="1002" value="" style="ellipse;fillColor=none;strokeColor=#2D5967;strokeWidth=2;" vertex="1" parent="139766084988960"><mxGeometry x="14" y="0" width="22" height="22" as="geometry"/></mxCell>
<mxCell id="1003" value="" style="shape=mxgraph.basic.arc;dx=0.5;fillColor=none;strokeColor=#2D5967;strokeWidth=2;rotation=180;" vertex="1" parent="139766084988960"><mxGeometry x="9" y="24" width="32" height="22" as="geometry"/></mxCell>
<mxCell id="nosql_endpoint_i2" parent="139766069527424" style="vsdxID=4;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="28.65116279069762" width="25.92248062015499" x="67.03875968992253" y="7.755381177908675e-14" /></mxCell>
<mxCell id="nosql_endpoint_i3" parent="nosql_endpoint_i2" style="vsdxID=5;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZTRcoMgEEW/htcdYAHlOU3+I9OY6tRqxpg2/fviQHXBEds3WO56rrC7DA/3+nyrmOT3cejfq6/mMtYMX5iUTVdXQzO6FcMjw8O1H6q3oX90F7+/nSfltProP6cvPH2e5lOK5N9+K7jfn7z29TF4sfDHSkEpQoKIM/hT+gAH/isJEWvBYBDhShQipYHCUHbbdMQnSQhcBdrmvPLEpwKFidPYplPIcs+mEwn5HyyCVXksQqF3sQjaZLFLSoggGBODpQGrYziPwXM1ID3eQBYIXMfMpBTcw1sbA4krXIv++rdz0ZFrni9Rphq5fooMe++B12xSN5tsUn1ZdlzTcQ/QjI2mSc3SlCVkkkbQGpKWXbp6ozKSQREbzQ8Vt1im0bVpWz/M6Hk6vVzITz48/gA=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="27.968992248061962" width="25.24031007751933" x="0.3410852713178288" y="0.3410852713178288" /></mxCell>
<mxCell id="nosql_endpoint_i4" parent="nosql_endpoint_i2" style="vsdxID=6;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lVbRcsIgEPyavDJwFwh5tu1/ODXWTK1xorb270tKYg5uAvEtnrvswS07FLi5HLbnpgB5ufbdZ/PT7q6HAl8KgPZ0aPr26r4KfC1ws+/65qPvbqed/33eDsjh66v7Hla4e56WQqqBBfLXV0Cg/S+8efz7rfcE5f+vQNiRoCKGvIOv1JVAM4LGkhGqHEHIQWNJlaLElPjAqUJ1xzHI5atQ3qEs5vW1kPCsvhbK5PW1gHqNfrj/Y3siw6IMX7Fa2OS0KGUquVbKsGFjWMOOaCBsmHoFY9SCPqIwZaRPVobJQSayC20SGQgXdh8eFyEsHG/cLbBm6dyAgYBbYLHZrLccRTNrW2TiOhIn/l8Wz10sQlHswk7alVB1KE6u/rJJ4kQJp5RPoFxiydTGSsWOVYbbIus9Kia6q3xT2ROVPKZUJMwGWa2RrZMXPpZ11sS0rHO4zcqmg4mNJJtLhDHFQi0wOiA6u6lbKYuc3ybMgrS2LBLnVWOZRx6R7jDGrIujGb8yjWYCCSOTaXQYOGQazZqIK/Mk4srO4XnhJ7dMriLw8YWOTlgiMEQufwKw+5jfTvv2ePRPL/p//NZyJf9Ow9c/);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="28.65116279069762" width="25.92248062015499" /></mxCell>
<mxCell id="nosql_endpoint_i5" parent="nosql_endpoint_i2" style="vsdxID=7;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPbDoIwDP2avTZbyxg8e/kPoyiLCGbg7e+FdMq2BBPfejntOe06Qau+3l0rgbIfXHeuHvYw1ILWAtG2deXsMFqCNoJWx85VJ9fd2gP7192EnKxLd586PLlOSTnVoHyxz96WofubY6ziZJGBRA/3IQ0lceSJHMkNoPIgHypBGQ8iX/ZhpQSxwEwIpoyZg6aeRo1iipg5kEfhgF/iaN7GtsFq4sWUEjD/JVEVoLJEooFkOaRB61ji9wWWdvMBLPDmGWQ65p1beo5CgcmTN5m1UXoKtDByvJ+fp/MHdDTm6zzapuHjDvPpNY8h/gm0eQM=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="1.0232558139534864" width="6.480620155038747" x="9.550387596899206" y="19.78294573643407" /></mxCell>
<mxCell id="nosql_endpoint_i6" parent="nosql_endpoint_i2" style="vsdxID=8;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPRkoIwDPyavmbahFL67Ol/OCdK5zhwKnr494Kp0nLizb2lyya7TRdBq1O1PZYC5anz7Vf543ZdJehDILqmKr3rhkrQWtBq3/ry4Ntzs+PzcTsyx+q7vYwTeu6TYwfKK5+sBDR3ZMPkz7NntmKCKkBloSVA1gAx0iMjpEHrQAqQkkGoJwb0Q5hSwoJunkGmU91pZNAoFJg8lY28zXSewr+uXLsm2s/Ej/e14LLIQGLqUoPVqc3cAKqZTVD2/XqejAVlQjB29i7T0McjDGaKVDmyR2kg6MV909X8EZ1/kYdiSuje1TUHPP4+T/QA8d9A6xs=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="1.0232558139534864" width="6.480620155038747" x="9.550387596899206" y="13.302325581395323" /></mxCell>
<mxCell id="nosql_endpoint_i7" parent="nosql_endpoint_i2" style="vsdxID=9;fillColor=#2d5967;gradientColor=none;shape=stencil(lVhdd9sgDP01edUBhPl47rr/0bOma866pidNt/bfT54NCGEb5y3Bku9FV0jCB7x7f354Ox6Mer9ezr+Of0+P1+cDfjsYc3p9Pl5OV/p1wPsD3j2dL8efl/PH6+P0/+1htBx//T7/Gd/wOfnFCDGOXkZ9TSvagBv+r3yfHH58XCYP3brMSwhxclGfZlrxFpSbjeYlNVvg9HeY/38hf7yCaQaItsZUNaACpWs8RgobG9y5WVWDkn1wArhG1QjKd2ERjL8FFsGaHuzgdsBWqC+nV5YKzH5aCB7cNsvikXLDg0gENDNmoao6mZAMVlCdBxThUSIZeIqahhm2Rriy4zpCC4dFRFRyzcyYkoNIoGJjWrXXuXZzaAk7p+YqNkvwDWx5bLpxkg51FQq0F1s5ROKxeTC9ARxE8lmIWO/P6fLilAhUSrRMQNDiqJCVD1v4GPJrMv7Q4BsP3gh829Ql7cA7gd/bv0vPC7zKWAneghPoIeSwJXRmtO8YMIeZS+hUUU2VQrD1GlQUyUjxq9mSyC7UbI2GKOh6THtapMs9Zr4R9BZdw/JB5y0GwZYiGWq6ZNRXloz0jco6B6qrrENweOgo6wzEW5S1dq61+4W1tGXbE9ZS8ATZBWFtvEVV4uo3A7sgK/lY0bAWdCUr3RfWImxWjFZXq9M529AVY6rzG7pSNZqX9ulKm7Rmiyz1Cu1qtjRQ6Zos9XaFNVsa1Bq2EYLoH8Vqvcd7ESz+5lTMXBMtRrJUci2UanYv2hfzWAlvMxMPTbi4bqn0m5Kzpk2BVH0xn/a9qRU0iOmYp2wqpjFDscS2IrG9L2mK2cpv1FfusXRuG7K0mSDY0pkTBS5E8CK3xsoiisaCuLJk9bRtSuIObXmtXdeWl+11bbv9oBWX9Zl1bVnHWpdWdsKesk2r3SHu2MTlwW3FHecBwXdB3GbS6KnbvcPEUlYSYT4jJXVJNzlHsnGrqKuxJtzMcTXhHYPvzQ71aJ0vV6kTmM1CRgOzFrcr2wxqpKgR8g25tfJg1LHwYLY/LGBGyjNt0565XqljawiihnKrvVf9hUwYb2LynDOSZbwJQ2/z1HNU70JjROTHgUWEnuuTWh7dcZoLTQ1OJmrzFFCDCxJcp1ThtxlZZYiiOAQLk1F37665S/GY5tFI1oxRnhqc2eyVnbnonE8y6oWfaRJzfd+9hOfx1Pkc1dBcmRwIWSml3vKU1zWkUxLoR/la+HR6eZk+NvLn8usiLU1fJvH+Hw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="27.286821705426302" width="24.558139534883672" x="0.6821705426356576" y="0.6821705426356576" /></mxCell>
<mxCell id="nosql_endpoint_i8" parent="nosql_endpoint_i2" style="vsdxID=10;fillColor=#2d5967;gradientColor=none;shape=stencil(lZbbUsMgEIafJrc7wMIC1x7ew9FqM9bWSevp7SUSCAuV6h0hu/l+9hQGvDpu7143gxLH03R43nyMD6ftgNeDUuN+u5nGU1gNeDPg1eNh2jxNh7f9Q3x+vZst59XL4X3+wmf0swasnr2U+Io7Uoif59tofv82RXsZXzsE5xcHyT3Ep4obXoGQi03a8mBxscLK7QuzjfQlezfuC6mr/aLEgzI9qd4AGi41+JCqxAownosNVtZzsc6Ak1zubGW7oVJgZcN3jvOtB+NavuN8S0ANXnfxFoGwwUtb4QU4W+EdEHE8OTD18S141+OTzlHMfGr4hCDq4yP4KvzBinzFlykjZ6ul9Ig7Jgi2vzugAuSdYAQI8x+CDnXfKeDWQTpQ3RAWwUnNRiCqCi4DvWzJ0KX6Ygpl0IvdEiqKI/FlbqpcQkWhJb5o+G0FByPTxxetkWcNKOT4ss1WvFQcf6aB52/p7gARZ/ma8+cxoxu+lhemXbCx9PdpFwJKXa05l1lrkFrNmrmzuFLBVZa/A0xfEbIH1pjPuoLT+E9gZXPaEtmskxhboxQkAoe/B6n0WLrYpcI768BjqqkaoT1jg9W4vySFJCj1H4eQHe5Qh7p0SWnXUJVjmQ9V1VInzdVvn2u9eEsIi/WG8TjudvGCUr6vbyRhK95m8OYb);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="14.32558139534881" width="4.775193798449603" x="5.457364341085261" y="9.550387596899206" /></mxCell>
<mxCell id="nosql_endpoint_i9" parent="nosql_endpoint_i2" style="vsdxID=11;fillColor=#2d5967;gradientColor=none;shape=stencil(lZbddtMwDMefJrc6tuTP6zHeY4d1NIfS7mQdlLdHwXFsy8Wwu0SR/PtblhRP9PB2fHo9TKjersvl2+Hn/Hw9TvRpQpzPx8MyX/lposeJHl4uy+Hrcnk/P6f316fVc336fvmxrnBLcWjA2TUK1a9kUaD0H8Pn5P/lfUkBOn3XDnLAZlHp9YbpNQCFzQHzkrhZbpQtBjef3RJcjT3N50pm5b+pUODdSKYFFVqZuiySpUYI1EplJ7StVm3Axlbs6mWGSfLgXIfX1OJ5W973fGr5SOCx49shHx043/GDFfwIRuA1kGvxpMGTwCMoGuHJAsrtU4cnB0ELvsvVV/gOtNx+AD0oljoiWQyKom4DnAfr24AIMXyEYD3Ej/gHDWGYQVcOfTMFyppKBu2erpzBwCjfnaA4wMBq/bB+QnYo+LBPir1+3N4sOz7mo6nrV+K57sZ4BSSGDMd4sXtuMjQdPohRw+2bE1Lx/ZBf+uLvdB6cPdyJ4lUdeEvY/SnXlEjkVMaRSr/XQ5bJIV7MmLWjYqtTK9Wq5L1gN2HUcLryT0CUZ1l1w3gsMzDPWwMUW3btlbNE+cTuZqmO2PpXgx6kdVeWe5UH6v97GwdmsHivhsJoFPT+fEJhOMw5JIpusODEr4xPJIp6VN0srf/2JJzuqv339YAfyt3iZT6d0tWk/i7vImxK9xh6/A0=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="14.32558139534881" width="4.775193798449603" x="15.348837209302296" y="9.550387596899206" /></mxCell>
<mxCell id="nosql_dedicated_i2" parent="139766069534000" style="vsdxID=4;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="18.23255813953485" width="16.49612403100772" x="81.75193798449615" y="4.935242567760066e-14" /></mxCell>
<mxCell id="nosql_dedicated_i3" parent="nosql_dedicated_i2" style="vsdxID=5;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZTRcoMgEEW/htcdYAHlOU3+I9OY6tRqxpg2/fviQHXBEds3WO56rrC7DA/3+nyrmOT3cejfq6/mMtYMX5iUTVdXQzO6FcMjw8O1H6q3oX90F7+/nSfltProP6cvPH2e5lOK5N9+K7jfn7z29TF4sfDHSkEpQoKIM/hT+gAH/isJEWvBYBDhShQipYHCUHbbdMQnSQhcBdrmvPLEpwKFidPYplPIcs+mEwn5HyyCVXksQqF3sQjaZLFLSoggGBODpQGrYziPwXM1ID3eQBYIXMfMpBTcw1sbA4krXIv++rdz0ZFrni9Rphq5fooMe++B12xSN5tsUn1ZdlzTcQ/QjI2mSc3SlCVkkkbQGpKWXbp6ozKSQREbzQ8Vt1im0bVpWz/M6Hk6vVzITz48/gA=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="17.798449612403065" width="16.062015503875937" x="0.21705426356589105" y="0.21705426356589105" /></mxCell>
<mxCell id="nosql_dedicated_i4" parent="nosql_dedicated_i2" style="vsdxID=6;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lVbRcsIgEPyavDJwFwh5tu1/ODXWTK1xorb270tKYg5uAvEtnrvswS07FLi5HLbnpgB5ufbdZ/PT7q6HAl8KgPZ0aPr26r4KfC1ws+/65qPvbqed/33eDsjh66v7Hla4e56WQqqBBfLXV0Cg/S+8efz7rfcE5f+vQNiRoCKGvIOv1JVAM4LGkhGqHEHIQWNJlaLElPjAqUJ1xzHI5atQ3qEs5vW1kPCsvhbK5PW1gHqNfrj/Y3siw6IMX7Fa2OS0KGUquVbKsGFjWMOOaCBsmHoFY9SCPqIwZaRPVobJQSayC20SGQgXdh8eFyEsHG/cLbBm6dyAgYBbYLHZrLccRTNrW2TiOhIn/l8Wz10sQlHswk7alVB1KE6u/rJJ4kQJp5RPoFxiydTGSsWOVYbbIus9Kia6q3xT2ROVPKZUJMwGWa2RrZMXPpZ11sS0rHO4zcqmg4mNJJtLhDHFQi0wOiA6u6lbKYuc3ybMgrS2LBLnVWOZRx6R7jDGrIujGb8yjWYCCSOTaXQYOGQazZqIK/Mk4srO4XnhJ7dMriLw8YWOTlgiMEQufwKw+5jfTvv2ePRPL/p//NZyJf9Ow9c/);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="18.23255813953485" width="16.49612403100772" /></mxCell>
<mxCell id="nosql_dedicated_i5" parent="nosql_dedicated_i2" style="vsdxID=7;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPbDoIwDP2avTZbyxg8e/kPoyiLCGbg7e+FdMq2BBPfejntOe06Qau+3l0rgbIfXHeuHvYw1ILWAtG2deXsMFqCNoJWx85VJ9fd2gP7192EnKxLd586PLlOSTnVoHyxz96WofubY6ziZJGBRA/3IQ0lceSJHMkNoPIgHypBGQ8iX/ZhpQSxwEwIpoyZg6aeRo1iipg5kEfhgF/iaN7GtsFq4sWUEjD/JVEVoLJEooFkOaRB61ji9wWWdvMBLPDmGWQ65p1beo5CgcmTN5m1UXoKtDByvJ+fp/MHdDTm6zzapuHjDvPpNY8h/gm0eQM=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.6511627906976731" width="4.12403100775193" x="6.07751937984495" y="12.589147286821682" /></mxCell>
<mxCell id="nosql_dedicated_i6" parent="nosql_dedicated_i2" style="vsdxID=8;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPRkoIwDPyavmbahFL67Ol/OCdK5zhwKnr494Kp0nLizb2lyya7TRdBq1O1PZYC5anz7Vf543ZdJehDILqmKr3rhkrQWtBq3/ry4Ntzs+PzcTsyx+q7vYwTeu6TYwfKK5+sBDR3ZMPkz7NntmKCKkBloSVA1gAx0iMjpEHrQAqQkkGoJwb0Q5hSwoJunkGmU91pZNAoFJg8lY28zXSewr+uXLsm2s/Ej/e14LLIQGLqUoPVqc3cAKqZTVD2/XqejAVlQjB29i7T0McjDGaKVDmyR2kg6MV909X8EZ1/kYdiSuje1TUHPP4+T/QA8d9A6xs=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.6511627906976731" width="4.12403100775193" x="6.07751937984495" y="8.46511627906975" /></mxCell>
<mxCell id="nosql_dedicated_i7" parent="nosql_dedicated_i2" style="vsdxID=9;fillColor=#2d5967;gradientColor=none;shape=stencil(lVhdd9sgDP01edUBhPl47rr/0bOma866pidNt/bfT54NCGEb5y3Bku9FV0jCB7x7f354Ox6Mer9ezr+Of0+P1+cDfjsYc3p9Pl5OV/p1wPsD3j2dL8efl/PH6+P0/+1htBx//T7/Gd/wOfnFCDGOXkZ9TSvagBv+r3yfHH58XCYP3brMSwhxclGfZlrxFpSbjeYlNVvg9HeY/38hf7yCaQaItsZUNaACpWs8RgobG9y5WVWDkn1wArhG1QjKd2ERjL8FFsGaHuzgdsBWqC+nV5YKzH5aCB7cNsvikXLDg0gENDNmoao6mZAMVlCdBxThUSIZeIqahhm2Rriy4zpCC4dFRFRyzcyYkoNIoGJjWrXXuXZzaAk7p+YqNkvwDWx5bLpxkg51FQq0F1s5ROKxeTC9ARxE8lmIWO/P6fLilAhUSrRMQNDiqJCVD1v4GPJrMv7Q4BsP3gh829Ql7cA7gd/bv0vPC7zKWAneghPoIeSwJXRmtO8YMIeZS+hUUU2VQrD1GlQUyUjxq9mSyC7UbI2GKOh6THtapMs9Zr4R9BZdw/JB5y0GwZYiGWq6ZNRXloz0jco6B6qrrENweOgo6wzEW5S1dq61+4W1tGXbE9ZS8ATZBWFtvEVV4uo3A7sgK/lY0bAWdCUr3RfWImxWjFZXq9M529AVY6rzG7pSNZqX9ulKm7Rmiyz1Cu1qtjRQ6Zos9XaFNVsa1Bq2EYLoH8Vqvcd7ESz+5lTMXBMtRrJUci2UanYv2hfzWAlvMxMPTbi4bqn0m5Kzpk2BVH0xn/a9qRU0iOmYp2wqpjFDscS2IrG9L2mK2cpv1FfusXRuG7K0mSDY0pkTBS5E8CK3xsoiisaCuLJk9bRtSuIObXmtXdeWl+11bbv9oBWX9Zl1bVnHWpdWdsKesk2r3SHu2MTlwW3FHecBwXdB3GbS6KnbvcPEUlYSYT4jJXVJNzlHsnGrqKuxJtzMcTXhHYPvzQ71aJ0vV6kTmM1CRgOzFrcr2wxqpKgR8g25tfJg1LHwYLY/LGBGyjNt0565XqljawiihnKrvVf9hUwYb2LynDOSZbwJQ2/z1HNU70JjROTHgUWEnuuTWh7dcZoLTQ1OJmrzFFCDCxJcp1ThtxlZZYiiOAQLk1F37665S/GY5tFI1oxRnhqc2eyVnbnonE8y6oWfaRJzfd+9hOfx1Pkc1dBcmRwIWSml3vKU1zWkUxLoR/la+HR6eZk+NvLn8usiLU1fJvH+Hw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="17.364341085271285" width="15.627906976744155" x="0.4341085271317821" y="0.4341085271317821" /></mxCell>
<mxCell id="nosql_dedicated_i8" parent="nosql_dedicated_i2" style="vsdxID=10;fillColor=#2d5967;gradientColor=none;shape=stencil(lZbbUsMgEIafJrc7wMIC1x7ew9FqM9bWSevp7SUSCAuV6h0hu/l+9hQGvDpu7143gxLH03R43nyMD6ftgNeDUuN+u5nGU1gNeDPg1eNh2jxNh7f9Q3x+vZst59XL4X3+wmf0swasnr2U+Io7Uoif59tofv82RXsZXzsE5xcHyT3Ep4obXoGQi03a8mBxscLK7QuzjfQlezfuC6mr/aLEgzI9qd4AGi41+JCqxAownosNVtZzsc6Ak1zubGW7oVJgZcN3jvOtB+NavuN8S0ANXnfxFoGwwUtb4QU4W+EdEHE8OTD18S141+OTzlHMfGr4hCDq4yP4KvzBinzFlykjZ6ul9Ig7Jgi2vzugAuSdYAQI8x+CDnXfKeDWQTpQ3RAWwUnNRiCqCi4DvWzJ0KX6Ygpl0IvdEiqKI/FlbqpcQkWhJb5o+G0FByPTxxetkWcNKOT4ss1WvFQcf6aB52/p7gARZ/ma8+cxoxu+lhemXbCx9PdpFwJKXa05l1lrkFrNmrmzuFLBVZa/A0xfEbIH1pjPuoLT+E9gZXPaEtmskxhboxQkAoe/B6n0WLrYpcI768BjqqkaoT1jg9W4vySFJCj1H4eQHe5Qh7p0SWnXUJVjmQ9V1VInzdVvn2u9eEsIi/WG8TjudvGCUr6vbyRhK95m8OYb);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="9.116279069767424" width="3.038759689922475" x="3.472868217054257" y="6.07751937984495" /></mxCell>
<mxCell id="nosql_dedicated_i9" parent="nosql_dedicated_i2" style="vsdxID=11;fillColor=#2d5967;gradientColor=none;shape=stencil(lZbddtMwDMefJrc6tuTP6zHeY4d1NIfS7mQdlLdHwXFsy8Wwu0SR/PtblhRP9PB2fHo9TKjersvl2+Hn/Hw9TvRpQpzPx8MyX/lposeJHl4uy+Hrcnk/P6f316fVc336fvmxrnBLcWjA2TUK1a9kUaD0H8Pn5P/lfUkBOn3XDnLAZlHp9YbpNQCFzQHzkrhZbpQtBjef3RJcjT3N50pm5b+pUODdSKYFFVqZuiySpUYI1EplJ7StVm3Axlbs6mWGSfLgXIfX1OJ5W973fGr5SOCx49shHx043/GDFfwIRuA1kGvxpMGTwCMoGuHJAsrtU4cnB0ELvsvVV/gOtNx+AD0oljoiWQyKom4DnAfr24AIMXyEYD3Ej/gHDWGYQVcOfTMFyppKBu2erpzBwCjfnaA4wMBq/bB+QnYo+LBPir1+3N4sOz7mo6nrV+K57sZ4BSSGDMd4sXtuMjQdPohRw+2bE1Lx/ZBf+uLvdB6cPdyJ4lUdeEvY/SnXlEjkVMaRSr/XQ5bJIV7MmLWjYqtTK9Wq5L1gN2HUcLryT0CUZ1l1w3gsMzDPWwMUW3btlbNE+cTuZqmO2PpXgx6kdVeWe5UH6v97GwdmsHivhsJoFPT+fEJhOMw5JIpusODEr4xPJIp6VN0srf/2JJzuqv339YAfyt3iZT6d0tWk/i7vImxK9xh6/A0=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="9.116279069767424" width="3.038759689922475" x="9.767441860465098" y="6.07751937984495" /></mxCell>
<mxCell id="nosql_tables_i2" parent="139766069536112" style="vsdxID=4;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="18.23255813953485" width="16.49612403100772" x="71.75193798449615" y="4.935242567760066e-14" /></mxCell>
<mxCell id="nosql_tables_i3" parent="nosql_tables_i2" style="vsdxID=5;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZTRcoMgEEW/htcdYAHlOU3+I9OY6tRqxpg2/fviQHXBEds3WO56rrC7DA/3+nyrmOT3cejfq6/mMtYMX5iUTVdXQzO6FcMjw8O1H6q3oX90F7+/nSfltProP6cvPH2e5lOK5N9+K7jfn7z29TF4sfDHSkEpQoKIM/hT+gAH/isJEWvBYBDhShQipYHCUHbbdMQnSQhcBdrmvPLEpwKFidPYplPIcs+mEwn5HyyCVXksQqF3sQjaZLFLSoggGBODpQGrYziPwXM1ID3eQBYIXMfMpBTcw1sbA4krXIv++rdz0ZFrni9Rphq5fooMe++B12xSN5tsUn1ZdlzTcQ/QjI2mSc3SlCVkkkbQGpKWXbp6ozKSQREbzQ8Vt1im0bVpWz/M6Hk6vVzITz48/gA=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="17.798449612403065" width="16.062015503875937" x="0.21705426356589105" y="0.21705426356589105" /></mxCell>
<mxCell id="nosql_tables_i4" parent="nosql_tables_i2" style="vsdxID=6;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lVbRcsIgEPyavDJwFwh5tu1/ODXWTK1xorb270tKYg5uAvEtnrvswS07FLi5HLbnpgB5ufbdZ/PT7q6HAl8KgPZ0aPr26r4KfC1ws+/65qPvbqed/33eDsjh66v7Hla4e56WQqqBBfLXV0Cg/S+8efz7rfcE5f+vQNiRoCKGvIOv1JVAM4LGkhGqHEHIQWNJlaLElPjAqUJ1xzHI5atQ3qEs5vW1kPCsvhbK5PW1gHqNfrj/Y3siw6IMX7Fa2OS0KGUquVbKsGFjWMOOaCBsmHoFY9SCPqIwZaRPVobJQSayC20SGQgXdh8eFyEsHG/cLbBm6dyAgYBbYLHZrLccRTNrW2TiOhIn/l8Wz10sQlHswk7alVB1KE6u/rJJ4kQJp5RPoFxiydTGSsWOVYbbIus9Kia6q3xT2ROVPKZUJMwGWa2RrZMXPpZ11sS0rHO4zcqmg4mNJJtLhDHFQi0wOiA6u6lbKYuc3ybMgrS2LBLnVWOZRx6R7jDGrIujGb8yjWYCCSOTaXQYOGQazZqIK/Mk4srO4XnhJ7dMriLw8YWOTlgiMEQufwKw+5jfTvv2ePRPL/p//NZyJf9Ow9c/);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="18.23255813953485" width="16.49612403100772" /></mxCell>
<mxCell id="nosql_tables_i5" parent="nosql_tables_i2" style="vsdxID=7;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPbDoIwDP2avTZbyxg8e/kPoyiLCGbg7e+FdMq2BBPfejntOe06Qau+3l0rgbIfXHeuHvYw1ILWAtG2deXsMFqCNoJWx85VJ9fd2gP7192EnKxLd586PLlOSTnVoHyxz96WofubY6ziZJGBRA/3IQ0lceSJHMkNoPIgHypBGQ8iX/ZhpQSxwEwIpoyZg6aeRo1iipg5kEfhgF/iaN7GtsFq4sWUEjD/JVEVoLJEooFkOaRB61ji9wWWdvMBLPDmGWQ65p1beo5CgcmTN5m1UXoKtDByvJ+fp/MHdDTm6zzapuHjDvPpNY8h/gm0eQM=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.6511627906976731" width="4.12403100775193" x="6.07751937984495" y="12.589147286821682" /></mxCell>
<mxCell id="nosql_tables_i6" parent="nosql_tables_i2" style="vsdxID=8;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPRkoIwDPyavmbahFL67Ol/OCdK5zhwKnr494Kp0nLizb2lyya7TRdBq1O1PZYC5anz7Vf543ZdJehDILqmKr3rhkrQWtBq3/ry4Ntzs+PzcTsyx+q7vYwTeu6TYwfKK5+sBDR3ZMPkz7NntmKCKkBloSVA1gAx0iMjpEHrQAqQkkGoJwb0Q5hSwoJunkGmU91pZNAoFJg8lY28zXSewr+uXLsm2s/Ej/e14LLIQGLqUoPVqc3cAKqZTVD2/XqejAVlQjB29i7T0McjDGaKVDmyR2kg6MV909X8EZ1/kYdiSuje1TUHPP4+T/QA8d9A6xs=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.6511627906976731" width="4.12403100775193" x="6.07751937984495" y="8.46511627906975" /></mxCell>
<mxCell id="nosql_tables_i7" parent="nosql_tables_i2" style="vsdxID=9;fillColor=#2d5967;gradientColor=none;shape=stencil(lVhdd9sgDP01edUBhPl47rr/0bOma866pidNt/bfT54NCGEb5y3Bku9FV0jCB7x7f354Ox6Mer9ezr+Of0+P1+cDfjsYc3p9Pl5OV/p1wPsD3j2dL8efl/PH6+P0/+1htBx//T7/Gd/wOfnFCDGOXkZ9TSvagBv+r3yfHH58XCYP3brMSwhxclGfZlrxFpSbjeYlNVvg9HeY/38hf7yCaQaItsZUNaACpWs8RgobG9y5WVWDkn1wArhG1QjKd2ERjL8FFsGaHuzgdsBWqC+nV5YKzH5aCB7cNsvikXLDg0gENDNmoao6mZAMVlCdBxThUSIZeIqahhm2Rriy4zpCC4dFRFRyzcyYkoNIoGJjWrXXuXZzaAk7p+YqNkvwDWx5bLpxkg51FQq0F1s5ROKxeTC9ARxE8lmIWO/P6fLilAhUSrRMQNDiqJCVD1v4GPJrMv7Q4BsP3gh829Ql7cA7gd/bv0vPC7zKWAneghPoIeSwJXRmtO8YMIeZS+hUUU2VQrD1GlQUyUjxq9mSyC7UbI2GKOh6THtapMs9Zr4R9BZdw/JB5y0GwZYiGWq6ZNRXloz0jco6B6qrrENweOgo6wzEW5S1dq61+4W1tGXbE9ZS8ATZBWFtvEVV4uo3A7sgK/lY0bAWdCUr3RfWImxWjFZXq9M529AVY6rzG7pSNZqX9ulKm7Rmiyz1Cu1qtjRQ6Zos9XaFNVsa1Bq2EYLoH8Vqvcd7ESz+5lTMXBMtRrJUci2UanYv2hfzWAlvMxMPTbi4bqn0m5Kzpk2BVH0xn/a9qRU0iOmYp2wqpjFDscS2IrG9L2mK2cpv1FfusXRuG7K0mSDY0pkTBS5E8CK3xsoiisaCuLJk9bRtSuIObXmtXdeWl+11bbv9oBWX9Zl1bVnHWpdWdsKesk2r3SHu2MTlwW3FHecBwXdB3GbS6KnbvcPEUlYSYT4jJXVJNzlHsnGrqKuxJtzMcTXhHYPvzQ71aJ0vV6kTmM1CRgOzFrcr2wxqpKgR8g25tfJg1LHwYLY/LGBGyjNt0565XqljawiihnKrvVf9hUwYb2LynDOSZbwJQ2/z1HNU70JjROTHgUWEnuuTWh7dcZoLTQ1OJmrzFFCDCxJcp1ThtxlZZYiiOAQLk1F37665S/GY5tFI1oxRnhqc2eyVnbnonE8y6oWfaRJzfd+9hOfx1Pkc1dBcmRwIWSml3vKU1zWkUxLoR/la+HR6eZk+NvLn8usiLU1fJvH+Hw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="17.364341085271285" width="15.627906976744155" x="0.4341085271317821" y="0.4341085271317821" /></mxCell>
<mxCell id="nosql_tables_i8" parent="nosql_tables_i2" style="vsdxID=10;fillColor=#2d5967;gradientColor=none;shape=stencil(lZbbUsMgEIafJrc7wMIC1x7ew9FqM9bWSevp7SUSCAuV6h0hu/l+9hQGvDpu7143gxLH03R43nyMD6ftgNeDUuN+u5nGU1gNeDPg1eNh2jxNh7f9Q3x+vZst59XL4X3+wmf0swasnr2U+Io7Uoif59tofv82RXsZXzsE5xcHyT3Ep4obXoGQi03a8mBxscLK7QuzjfQlezfuC6mr/aLEgzI9qd4AGi41+JCqxAownosNVtZzsc6Ak1zubGW7oVJgZcN3jvOtB+NavuN8S0ANXnfxFoGwwUtb4QU4W+EdEHE8OTD18S141+OTzlHMfGr4hCDq4yP4KvzBinzFlykjZ6ul9Ig7Jgi2vzugAuSdYAQI8x+CDnXfKeDWQTpQ3RAWwUnNRiCqCi4DvWzJ0KX6Ygpl0IvdEiqKI/FlbqpcQkWhJb5o+G0FByPTxxetkWcNKOT4ss1WvFQcf6aB52/p7gARZ/ma8+cxoxu+lhemXbCx9PdpFwJKXa05l1lrkFrNmrmzuFLBVZa/A0xfEbIH1pjPuoLT+E9gZXPaEtmskxhboxQkAoe/B6n0WLrYpcI768BjqqkaoT1jg9W4vySFJCj1H4eQHe5Qh7p0SWnXUJVjmQ9V1VInzdVvn2u9eEsIi/WG8TjudvGCUr6vbyRhK95m8OYb);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="9.116279069767424" width="3.038759689922475" x="3.472868217054257" y="6.07751937984495" /></mxCell>
<mxCell id="nosql_tables_i9" parent="nosql_tables_i2" style="vsdxID=11;fillColor=#2d5967;gradientColor=none;shape=stencil(lZbddtMwDMefJrc6tuTP6zHeY4d1NIfS7mQdlLdHwXFsy8Wwu0SR/PtblhRP9PB2fHo9TKjersvl2+Hn/Hw9TvRpQpzPx8MyX/lposeJHl4uy+Hrcnk/P6f316fVc336fvmxrnBLcWjA2TUK1a9kUaD0H8Pn5P/lfUkBOn3XDnLAZlHp9YbpNQCFzQHzkrhZbpQtBjef3RJcjT3N50pm5b+pUODdSKYFFVqZuiySpUYI1EplJ7StVm3Axlbs6mWGSfLgXIfX1OJ5W973fGr5SOCx49shHx043/GDFfwIRuA1kGvxpMGTwCMoGuHJAsrtU4cnB0ELvsvVV/gOtNx+AD0oljoiWQyKom4DnAfr24AIMXyEYD3Ej/gHDWGYQVcOfTMFyppKBu2erpzBwCjfnaA4wMBq/bB+QnYo+LBPir1+3N4sOz7mo6nrV+K57sZ4BSSGDMd4sXtuMjQdPohRw+2bE1Lx/ZBf+uLvdB6cPdyJ4lUdeEvY/SnXlEjkVMaRSr/XQ5bJIV7MmLWjYqtTK9Wq5L1gN2HUcLryT0CUZ1l1w3gsMzDPWwMUW3btlbNE+cTuZqmO2PpXgx6kdVeWe5UH6v97GwdmsHivhsJoFPT+fEJhOMw5JIpusODEr4xPJIp6VN0srf/2JJzuqv339YAfyt3iZT6d0tWk/i7vImxK9xh6/A0=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="9.116279069767424" width="3.038759689922475" x="9.767441860465098" y="6.07751937984495" /></mxCell>
<mxCell connectable="0" id="functions_i2" parent="139766069542640" style="group" value="" vertex="1"><mxGeometry as="geometry" height="44.0" width="33.908256880733944" y="9.178386898625882e-14" x="53.04587155963303" /></mxCell>
<mxCell id="functions_i3" parent="functions_i2" style="vsdxID=37;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="33.908256880733944" width="33.908256880733944" /></mxCell>
<mxCell id="functions_i4" parent="functions_i3" style="vsdxID=38;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="33.908256880733944" width="33.908256880733944" /></mxCell>
<mxCell id="functions_i5" parent="functions_i4" style="vsdxID=39;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZPRDoIwDEW/Zq9LWUHCs+J/EAVZRCATFP/eYYdsAzW+td2922mzMtxey6zNmYBrp5pzfpfHrmS4Y0LIusyV7HTEMGW4LRqVn1TT10fK22xUjtGluY03DOSLOEajScCDCknC482rsif9oVdkCEggeIjGEfgWGASVwChMmsQchVGgqzBpEvLQfrWStUUJDuKb+QMhuHgz8ERnteDyTnDWVBzcVTiNvnFnCN/o9Cyi2CUEFy8Ab3xWB+hLfOJVxFnuI3+AnA1L6kEsG/HJB1zOxkNfBf39Hf/V62D++4WsKlod+9zfFV2iPcP0CQ==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="33.10091743119266" width="33.10091743119266" x="0.4036697247706422" y="0.4036697247706422" /></mxCell>
<mxCell id="functions_i6" parent="functions_i4" style="vsdxID=40;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZXRdoIwDIafprc9aUMpvXb6Hp6JgzMmHsSNvf1gLbQNCHpX4h/88iehDHe34njNmYRb29Sf+U95aguGb0zK8lLkTdn2J4Z7hrtz3eQfTX2/nOzz9Tgoh9NX/T28obN5BjmqIUvCr41Ijtl/4GD17/fGJgiXoXhiXIYgKdBJJ9IcR5ELJVy6SIdzkQulPMHwz6vyEsIGCRN+JlZpgxRfgFEEN6jJV5ClhDfwCqlqEbgvR8S8VE95e5c0wdU8lTFu77cmtIprEdMGIs+v9GPYIGG5GZQ1SBCzHstZPXI2LDhzCZdnkIzB5sy+qt/aCXihxbBuWaZiyyD2C6hZdAghdmp9YSAi21wWYHTyREInb+J3EQHANro5Sh41R8U7TeQLGy2Ih56BQgXbPJWCVPPcenj9c9thDNcp/U5O3Ry5Um5EjErsXPjorLu5Nrr9wV8E57Kq7D0S/k4vjj5kLx3c/wE=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="33.908256880733944" width="33.908256880733944" /></mxCell>
<mxCell id="functions_i7" parent="functions_i3" style="vsdxID=41;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="32.29357798165138" width="32.29357798165138" x="0.8073394495412844" y="0.8073394495412844" /></mxCell>
<mxCell id="functions_i8" parent="functions_i7" style="vsdxID=42;fillColor=#2d5967;gradientColor=none;shape=stencil(lZXLcoMwDEW/xlvGWDzidZr8R6YhhSmFDCEt+ftCbbAkB+Lu/LgyR/IVFrC/ladrIZS89V37WfxU574U8CaUqpqy6Kp+HAk4CNhf2q746Np7czbz62lSTqOv9ns6YTBxOo3SeIpS8mFW5N/saMR11SBxEqlkXft+78zJsdmMI62tOsZyOSgyfdipsrtAd2H5drpOJgmWzra4JIXSO0qFsOcVKSkaqgNQyVO4scZ5RgCZnBPqXSRjSukYONRMueQBXAAOY6OETv+84B6kno9bIBVF1LnLm175AL774KX9XniVGTtzNVzJ38so88puneRSSr2UxihbqK20nCqsszw9hwWvuzCImkV5wmkpKlKE2QQFhPkEBdiVhEPyhoPFWesdB5uUfstxfcDlIwx01+z6EwqKFUF/rgCf/jtgHLj//aWqa/Nc4H3+PoxL5m2Bwy8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="32.29357798165138" width="32.29357798165138" /></mxCell>
<mxCell id="functions_i9" parent="functions_i7" style="vsdxID=43;fillColor=#2d5967;gradientColor=none;shape=stencil(pZLRDsIgDEW/hlcCNG68z/kfS8aEiLCwOfXvhTTGTSPqfOul57YNuQSqQTe9IoINY/AHdTbtqAlsiRDGaRXMGCsCNYGq80Htgz+5FnXfJDJVRz+lCRf0seQQ7IqKM9Q7RK1xM/TeXAVn0JVgdn0WXf4AByrKJV5QuXk/Wxa0hP8MEijPGF5P+tnw4aQvDLF4hKYz1mLm5v3nkMUnDCjUNw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="6.862385321100918" width="8.880733944954128" x="3.229357798165138" y="21.394495412844037" /></mxCell>
<mxCell id="functions_i10" parent="functions_i7" style="vsdxID=44;fillColor=#2d5967;gradientColor=none;shape=stencil(pZLdDsIgDIWfhlsC1Bm8nvM9lowJEWFhmz9vL6QxbhpZnHc99DttQw6Bstd1p4hg/RD8SV1NM2gCeyKEcVoFM8SKQEWgbH1Qx+BH16Du6kSm6uwvacINfSw5BLuj4gz1AVFr3AR9NlfBGXQlmF2fRec/sKFSzOktlcX30buCcvmfQQLlGcPHRb/yCwct87F4BaY11mLepv33gMUnDCdUDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="6.862385321100918" width="25.027522935779817" x="3.229357798165138" y="3.229357798165138" /></mxCell>
<mxCell id="functions_i11" parent="functions_i7" style="vsdxID=45;fillColor=#2d5967;gradientColor=none;shape=stencil(pZLLDoMgEEW/hi0BplRdW/sfJmIhpWKQvv6+kklT7cPWupsL5w7D5BLIO122igjWBe/26myqoAlsiBCm0cqb0FcECgJ57bzaeXdsKtRtGclYHdwpdrigjzMWPYJdUaPaImpNM0D/BO8vvEWzjEqxBJ+AZ3xtEh0vLBM0XY/gFCiXn3snlK8W8VzSBCZ28jLQbMOXiX4w9MUjYbWxFgM6vH9OZH+EaYbiBg==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="6.862385321100918" width="16.954128440366972" x="3.229357798165138" y="12.513761467889909" /></mxCell>
<mxCell id="functions_i12" parent="functions_i7" style="vsdxID=46;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="5.651376146788991" width="6.055045871559633" x="21.79816513761468" y="12.917431192660551" /></mxCell>
<mxCell id="functions_i13" parent="functions_i7" style="vsdxID=47;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="5.651376146788991" width="6.055045871559633" x="21.79816513761468" y="21.79816513761468" /></mxCell>
<mxCell id="functions_i14" parent="functions_i7" style="vsdxID=48;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="5.651376146788991" width="6.055045871559633" x="14.128440366972479" y="21.79816513761468" /></mxCell>
<mxCell id="monitoring_i2" parent="139766069584112" style="vsdxID=76;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="26.2018348623853" width="26.2018348623853" x="46.89908256880736" /></mxCell>
<mxCell id="monitoring_i3" parent="monitoring_i2" style="vsdxID=77;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="26.2018348623853" width="26.2018348623853" /></mxCell>
<mxCell id="monitoring_i4" parent="monitoring_i3" style="vsdxID=78;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZPRDoIwDEW/Zq9LWUHCs+J/EAVZRCATFP/eYYdsAzW+td2922mzMtxey6zNmYBrp5pzfpfHrmS4Y0LIusyV7HTEMGW4LRqVn1TT10fK22xUjtGluY03DOSLOEajScCDCknC482rsif9oVdkCEggeIjGEfgWGASVwChMmsQchVGgqzBpEvLQfrWStUUJDuKb+QMhuHgz8ERnteDyTnDWVBzcVTiNvnFnCN/o9Cyi2CUEFy8Ab3xWB+hLfOJVxFnuI3+AnA1L6kEsG/HJB1zOxkNfBf39Hf/V62D++4WsKlod+9zfFV2iPcP0CQ==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="25.577981651376124" width="25.577981651376124" x="0.3119266055045869" y="0.3119266055045869" /></mxCell>
<mxCell id="monitoring_i5" parent="monitoring_i3" style="vsdxID=79;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZXRdoIwDIafprc9aUMpvXb6Hp6JgzMmHsSNvf1gLbQNCHpX4h/88iehDHe34njNmYRb29Sf+U95aguGb0zK8lLkTdn2J4Z7hrtz3eQfTX2/nOzz9Tgoh9NX/T28obN5BjmqIUvCr41Ijtl/4GD17/fGJgiXoXhiXIYgKdBJJ9IcR5ELJVy6SIdzkQulPMHwz6vyEsIGCRN+JlZpgxRfgFEEN6jJV5ClhDfwCqlqEbgvR8S8VE95e5c0wdU8lTFu77cmtIprEdMGIs+v9GPYIGG5GZQ1SBCzHstZPXI2LDhzCZdnkIzB5sy+qt/aCXihxbBuWaZiyyD2C6hZdAghdmp9YSAi21wWYHTyREInb+J3EQHANro5Sh41R8U7TeQLGy2Ih56BQgXbPJWCVPPcenj9c9thDNcp/U5O3Ry5Um5EjErsXPjorLu5Nrr9wV8E57Kq7D0S/k4vjj5kLx3c/wE=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="26.2018348623853" width="26.2018348623853" /></mxCell>
<mxCell id="monitoring_i6" parent="monitoring_i2" style="vsdxID=80;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="24.95412844036695" width="24.95412844036695" x="0.6238532110091738" y="0.6238532110091738" /></mxCell>
<mxCell id="monitoring_i7" parent="monitoring_i6" style="vsdxID=81;fillColor=#2d5967;gradientColor=none;shape=stencil(pVjbctsgEP0ave5wvzyn6X9kGqfW1LUzitM6f19U2YIFaxHWmxDniMNe2BWdfPrYv7zvOsE+zsPp1+5v/3red/JbJ0R/3O+G/hyeOvncyae307D7OZw+j6/T+P1lRI5Pv09/xi9cJp7XoPnIEuxresP+j75P4EN/TMAKhFrG/vgcpi/zaZKD91c0T+HsItDw6zoU11mJZ+W8tl5WxpAsbyhdDIvyDqtKZN/eMIalJXaQGHJXHHfgNRJIwoUH7tbDlQau1sO1BmnWwy0HKdbDHQfdsNUQfZYUk/vOO2C3cOW5d3J33fw3e1jmABllEMEV8fdDsRDpb5+bRQos0du4b5wMlyhpzkuUEEt2pLIYp7wEi+NFOHL73kSbP0iQEgi8DSGJ8cpT+DArcYIoQeHDjo1HeCPIDRQW0qT+VoPW8dhhxbErafMXSZXji4A1RVbNlBizBkQWsyqL2QSx6tROCVdLkGbz/nFwLWkTp3C8O1F8URQ2WiwMtKuqnsWBIEQeyKMFqcgvCI6RmaJBqU34ZkHbCVmyODCyZYWSYBhJ0KEk2m2EZknbCdhKVoHjLSuUBGNpggVtthGCpCZFD+DbtlwxalmFKyuEbqnJzQXe0HWVA7Ob8BU9oZfkTRsuCZr0mQou8JvwteMltOZNLigJ1tDNY9H8NxNqyZ8XkQJf1rr8zyxSkno3F8S5A+hQtUsQ6xrpsq+yZHVRwLO+zRKxxYBjzyj6PAhNDz5v6C7vTlfrat0Ny7OD8sqdLmy2uIj2zXqw1HPL/w6VEFpxcoWHeIfw1h8O0xVEOp/fOYRX032FfP4H);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="24.95412844036695" width="24.95412844036695" /></mxCell>
<mxCell id="monitoring_i8" parent="monitoring_i6" style="vsdxID=82;fillColor=#2d5967;gradientColor=none;shape=stencil(pZJNDoMgEIVPw5Yg01b31t7DRCykFAxqf25fyKRBDYtid2+G781kyCNQj7IdBOFsnJy9iafqJkngTDhXRgqnJq8INATq3jpxdXY2HdZDG8ig7vYRJrzQVzAWPJy9scbqgqhWZoHuBL8bkuh2fRa8F13/QMloBSs4dpKzoaD8+J8hdpKGU0XLQ44h+4YfDF7E0PRKa8zc8n0bMt/CgELzAQ==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.8073394495412822" width="2.8073394495412822" x="1.8715596330275215" y="1.8715596330275215" /></mxCell>
<mxCell id="logging_i2" parent="139766069586800" style="vsdxID=16;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="26.129629629629623" width="27.074074074074066" x="46.462962962962955" /></mxCell>
<mxCell id="logging_i3" parent="logging_i2" style="vsdxID=17;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="26.129629629629623" width="27.074074074074066" /></mxCell>
<mxCell id="logging_i4" parent="logging_i3" style="vsdxID=18;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lZRBcoMwDEVPw1YjSxjkdZrcI9OQwpSGDCFtevtC7UwsIGTYyeJ/8/jYSnhzKffnIiG8dG3zWfxUh65M+C0hqk5l0VZdXyW8TXhzbNrio22up4Nfn/eDcqi+mu9hh5v3kQObDi7CX99xDpD/OztvqKtTbMiARBsEMFswENhMG1Iw7rkhBZFl/fu19d9gwiuAOTjM2II38i0MirB0BGiCgrUiLMWBeU6JCtECyhIhajyClDRdT+M0IGq4KBWFOwsnFqzOEJfoRIBzTYgazyGkmeYjMKIRYxHP56IxY0PYNAexS6gGR1GygzTXsA9NaNgM3EvUTCDP17COz8cYNXaY6aGjafb3sKPDy9MfymPVLC9bELPm2jECsTLcc5y/1qsHx2tDXzzm1LGqaz/m4ufjuda3/Ezk7R8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="25.499999999999993" width="26.444444444444436" /></mxCell>
<mxCell id="logging_i5" parent="logging_i3" style="vsdxID=19;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lVbbVuMwDPyavOrYkuPLM7D/wVnKNofSckLZLX+Pu3EUW20VeEvVmXg8uqWju/ft49umQ/N+HA8vm3/D03Hb0X2HOOy3m3E45qeOHjq6ez6Mmz/j4WP/NP1+ezwjz0+vh7/nN5wmXnTQxzMLzecUQSD3P/Brwv/+GCeCLQwPHgvDCoo5YQFFQFtAJUSQykEnugSVkAeT6sN3w74WWxHKyRH6oKlNAXrbqqXEV57l1qgS6j2fpekNc+ibgmMA6lV7K8ocSuC88LdKwnwHC1JvlVsSoKtyqQcKjdwVvAHfXi/lBOJtAgZwriU4iL1CIFmeyUAMtwk9JB0u/ab5fLZ7obDdCBhat3NOkFq7KxBxsq3mxkK4Xv1Sa0Vg9UmUcnUfFs/dSdIkEpDrVbw6I36KX5tB5vsJNrphQYwq07plpFVR9JBpjdLnk2mUrba66WTdeepE3bH+ucuJO+hmNhfM9bJD8KKnVgj9UlPc5kErbA/U4nMjKL5lfPCS4LQDcvcJRRHIq5OK2rqxRikyQnAk329JIeQbkPQ0aZvBcandIlxshsDNziXDnGWVGRCj6nIxVJhlUkXF74rAey+hJna2l6XW+xQlZp5dCeyq1LxDvJKJS6krQzUTnLC1GgPI/nCFtqNDWbZKga2MvPywfLA9D7vd9L1X/y8/8HJo+jikhy8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="26.129629629629623" width="27.074074074074066" /></mxCell>
<mxCell id="logging_i6" parent="logging_i2" style="vsdxID=20;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="24.555555555555546" width="25.814814814814806" x="0.3148148148148147" y="0.3148148148148147" /></mxCell>
<mxCell id="logging_i7" parent="logging_i6" style="vsdxID=21;fillColor=#2d5967;gradientColor=none;shape=stencil(lZPdcoIwEIWfJrc7Sdb8XVt9D0exZErBidjq2xeaAMla2undcjiHfBt2GW6v9eFSMcmvfejeqk9/6muGL0xK39ZV8P1QMdwx3J67UL2G7tae4vPlMDrH6r37GL9wjzmHoNSYkvwRFStAi29lHwPHW4gJ8RxJkpVgdJTucnZxl1xJsghOJBcmlwSNyYXUlc5vfJsBa9gQXuqnvAqcI7gKOMFVoJDQapCEdogZAmsA1TosL0gF5+vW/CZ+tD/9Bg3GlH1NibmrWZiacgKcLptaPLgyACXo4s97XIO0IHQJuQE6KQqsIpggyZxkMzdxI9hfrvPvuf53YCiWNTr7polbmL+nazdIcWVx9wU=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="5.35185185185185" width="13.222222222222218" x="9.759259259259256" y="17.94444444444444" /></mxCell>
<mxCell id="logging_i8" parent="logging_i6" style="vsdxID=22;fillColor=#2d5967;gradientColor=none;shape=stencil(lZXRcoMgEEW/xtcdWEDhOU3/I9OYxmkaM8a05u+LQ0BYIm3fcL3XOXtdoBKb63F3aStk13HoP9rvbj8eK/FSIXbnYzt0o11VYluJzaEf2vehv5337vmym5Xz6rP/mr8wOR83oHB2Ibu7itEgXeXVGU7dOTVgnRoa0KZg0NCI1FCD4OsGCYhl/dttcD1wJxBgPBKnFjahF9XmIcIgYvIhEpnoUTEKGr0OGxkI/SprMGT0C2roJ4P3pFFKlP0p6NKHJ6V6ShrFc8/gJ8yCvmf0njUWUfznsJHBVRBBiiJtA7VIaS2J1ARXg1EprkVRZAo4YyktKlClEQ9635wsJrvoPSlwnoFyAsrCxpuy2QykQfS3rUXlGSlolaKylJOljIveM5Iky/89jTHbepSOpBhlNmU8gdBnv76RvOQpov0kT0ezLGfAVNqVHUFZPF//fSD/ZrCL5fw/dKeTuz7i9/S+sCV314jtDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="23.29629629629629" width="23.29629629629629" /></mxCell>
<mxCell id="logging_i9" parent="logging_i6" style="vsdxID=23;fillColor=#2d5967;gradientColor=none;shape=stencil(nZLdCsIwDIWfJrcjNuvA6znfY7DOFms7uvn39rYEcQ4sxbtzki+5yAlQO+t+UiBwXoI/q7sZFg10ACGM0yqYJSqgDqgdfVCn4K9uYD/1iUzq4m9pw4PnJKYRgU+2O2R/ZNYat2Lfzb/gDNrIUvJ7pcCqbkphqivc/4Y3dxCyGM1eIc9G8cllNNZyrOv+NsdY4h+g7gU=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.5185185185185177" width="0.9444444444444442" x="1.8888888888888884" y="2.203703703703703" /></mxCell>
<mxCell id="logging_i10" parent="logging_i6" style="vsdxID=24;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.3148148148148147" width="0.3148148148148147" x="4.092592592592592" y="4.092592592592592" /></mxCell>
<mxCell id="logging_i11" parent="logging_i6" style="vsdxID=25;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.3148148148148147" width="0.3148148148148147" x="4.092592592592592" y="2.8333333333333326" /></mxCell>
<mxCell id="logging_i12" parent="logging_i6" style="vsdxID=26;fillColor=#2d5967;gradientColor=none;shape=stencil(lZLZDoIwEEW/pq+T0qELz4j/QUKRRqQEcPt7WxsjaNDyNsu5N5PJJZiPTdlrwug4Dfaor6aaGoI7wpjpGj2YyVUEC4J5bQd9GOy5q0Lfl5701clevMMt6FgKmHkVo/cwSSh99vuAt6ab4akCqRa4YODbNYFESGS8/2sZBQsOii9wd57K1gWZBL485oe7pCDTWPj7L8iBi3UBE6Aw1p3GgpiA3PKQDc/eGJS/uCvemaxN24ZIz/efGXajkH8sHg==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.5185185185185177" width="2.5185185185185177" x="5.666666666666665" y="1.8888888888888884" /></mxCell>
<mxCell id="logging_i13" parent="logging_i6" style="vsdxID=27;fillColor=#2d5967;gradientColor=none;shape=stencil(jVbLcsMgDPwaXzWAeJhz2v5HpnEaT9Mk4yRt+ve1i7FBih83hNcsKy2CAjfXw/ZSFUpcb835s/qpd7dDgS+FUvXpUDX1rR0V+FrgZn9uqo/mfD/tQnzZdshu9HX+7lZ4hP+MAtP9pMRvmBD/0VvAvt+bAJbhI0asTMHioUKoFGjfI/opDfGfB4YZGdeIMYLQc6QavM9plQSnc2qR06IGV+a8Iqc1s0JFTmgNdHFKmOyqn3ElKEu0ttmVOW9pwds56jSJ/ZQ3YE1OP1Sij6UQObX24wYxx0wQW8eIx1V7mpLkOd1ZFJgss1azd0CclSaTSozkaVWQYlaVeYRL7psokVc69d+06kVjl4qqTk5LNBXRTKqcHN/M5j3jsT6tPut5X3A50lkQfk6LI4lstVmZS7EjfXQTP6WGyBkhU92BWafkNUTHqAVoUkJUrISLshU3Lu9NinDbwRgDtyKy21JJN0tMnSMBCSvTjElNpjWr4eRNXQJM85N+rGl/8mBIc+TeHUET1MazuyBdOObXsWvoyYl1jH5RueMd8knDoD0yKQ0SxNpql/Q+ElA60ii4aMtz7ohkZvC8Yyx1gXYwPiz29fEY3iXpd/oQaafCIwZf/wA=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.8333333333333326" width="2.203703703703703" x="8.814814814814811" y="1.8888888888888884" /></mxCell>
<mxCell id="logging_i14" parent="logging_i6" style="vsdxID=28;fillColor=#2d5967;gradientColor=none;shape=stencil(lVPbEoIgEP0aXhnYVcHnLv/RpCaTqUN2+/tgKEpIx952l3OYc/ZCcHWud31JgJ0H3R3LmyqGmuCaAKi2LrUaTERwQ3BVdbo86O7SFi7vdxZpo1N3tT/cHY8zZjnAHi532dZBG9V+QQXQdCk2ZZTxERiRIk4TQCz/fLFiNIrHKhJJZb7053dvfgtOQ4cBfH/RrtE8JvCg+XeIugAhBCPIq5ILKuQ/o8iA2nSKkIVzlrO+BIt8Ca/IOzMlP4p3yW+ENycDa4JTzmc2MrKWZDQT04Q/tn0WaoLPQVWqadw9fr+HB2hK7nhx8wQ=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.5185185185185177" width="2.203703703703703" x="12.277777777777773" y="1.8888888888888884" /></mxCell>
<mxCell id="logging_i15" parent="logging_i6" style="vsdxID=29;fillColor=#2d5967;gradientColor=none;shape=stencil(jZXbbsIwDIafprdWEud4zdh7oFFGNUZRgQ3efqmStnFY2kpcJOZ3P8ex4wo31+PuUleCXW9d+1X/NvvbscK3SojmfKy75uZXFW4r3Bzarv7s2vt5H/aXXa/sV9/tT/+FR/CzCtD0XoI9g0UI6Lf+9x4cPu5d8OBBYBRoHl0GE8hoeYhg0TiantHEogLDVlowLiowVRSwyMFkWEaZ3IHKmElgkcH98Sh18cACpKRgNMAkhTMKVg6EpmRGsT7z3M5hGWU6AcrNMp0GnEVyNpthCdZR5uAwpXjKXhEqODhNwaOolOHEpXzcVBVN1o4xz+An1Xq+YWNjjHwJkuKVAqUyvL94Q/G+0rmaLW0JfLnCJAdpKB8RMMv+P201qQp8pSHrrPTD5Y5Og4wsbYdyWH16g8ANxafdM3Ry8uqI1yvCV1Xp8k/NOXkAU4+88goBWwEOq6Vq9SbtaMCpKmvJqVVyOg130q8sbWdA6cXsOv8YLV9uOixKjycNd8V48YtpOB2a0ynMtvT/fJh5UxiEuP0D);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="1.5740740740740735" width="2.5185185185185177" x="15.740740740740735" y="1.8888888888888884" /></mxCell>
<mxCell id="logging_i16" parent="logging_i6" style="vsdxID=30;fillColor=#2d5967;gradientColor=none;shape=stencil(lZPbkoMgDIafhttMICJw3cN7dFq7Mmu1Q+3p7VcnthXdddi7JH6B/49E0OpS7s6FUHhpQ/Nd3P2hLQWthVK+Lovg2y4StBG0Ojah+ArNtT5wft71ZB+dmlt/woP7JGLfo/DJOWdbRitfj1CjQKeyGgFlBGcIOvu7QZn0w5MVU6c4VqEdZPmCiliD0ZDbMb2/Bh6enF8wlIwF4h58qLf19zCGkpWAL4oG6jMBmkKJM57pnTTE7iyBWXSXm5k760C62J3F2JrLII+dOYx9vd7cryLHlyb9s3+84EW0Cz5LcvRVxTs2/j5dqq7EC0mbHw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.203703703703703" width="2.203703703703703" x="18.888888888888882" y="1.8888888888888884" /></mxCell>
<mxCell id="logging_i17" parent="logging_i6" style="vsdxID=31;fillColor=#2d5967;gradientColor=none;shape=stencil(nVXbcsIgEP2avO7ALgR4tvY/nBprpladqK39+yYFwiUGtW/k5Cxn71S0OG1Xx6ZCdjp3h4/mu12ftxW9VIjtftt07bk/VbSsaLE5dM17d7js1/b7uBqYw+nz8DXccLV2NQOFgxWyH4do4PoPebUGb5fOWnBHUKClM/EQB6otdEULKU9x37IG7YSuZCGNwIVjOUgioCqJa+MJo7hQoCgVNxhcdJAgH9aoH7McRBpqUdI3NQhM9UkAM6k+ZyxVJz6JPnAcgOpO7MHCAzrEhFP/vDNRcXzmJSieqo/lmRFXWcnHQo3StQDUqTRLZUXvHKWyrKRJJtzI0xt9XvsWkkVN5CCyJrvXY7wPxGQ9BlJm/T0RjjhJcLMp3rX7aBI92fkon/QQGYhsBFGDVKmPccfQNMmUs2b0pQqTO9+LNxqiz/04qzRleZf4nWaMbXhuU9KPZ7WgX/uJeUJ/3BxBP9qtvkcYGJ7qx7n0cyJBFOsvKVR2fgvG4+a3cDS28/WXxmfpgU7VebJKZL/CblLDfvsHWec9k9LjKB8yeOBhfNqgP4R3eNPudvYZj//n73YP2Teflr8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.5185185185185177" width="1.5740740740740735" x="1.8888888888888884" y="6.925925925925924" /></mxCell>
<mxCell id="logging_i18" parent="logging_i6" style="vsdxID=32;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.3148148148148147" width="0.3148148148148147" x="4.092592592592592" y="9.129629629629626" /></mxCell>
<mxCell id="logging_i19" parent="logging_i6" style="vsdxID=33;fillColor=#2d5967;gradientColor=none;shape=stencil(nZBLCoAwDERPk31tjuDnHoLVBmsrtf5ub0sQRdzobiZ5ycAA5pOuRwVSTMG7Xq3UBA1YgJRktfIUogIsAfPWedV5N9uG/VgnMqnBLenDxneZEOlGip09u4pRQ/aG/gTPhFf0Gf8J/otGcdXRkjHc5n3/rC+OuHosDw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="0.3148148148148147" width="0.3148148148148147" x="4.092592592592592" y="7.870370370370368" /></mxCell>
<mxCell id="logging_i20" parent="logging_i6" style="vsdxID=34;fillColor=#2d5967;gradientColor=none;shape=stencil(lZLdDoIwDIWfZrfNto6NXaO+BwlDFpERwL+3l7kQQSOOu9P260naHIJZX+WtIZz2Q+dO5maLoSK4I5zbpjKdHUZFcE8wK11njp27NEWo29yTXp3d1Tvcw55WkEi/xekjdOirOgS4ts0MVhQUxsIiBaUXMAqg+vcCl5BGu9NYEBkotoCFmq6IcGZ0xZsLQB2Pf39EIkix8m8EpuL9p2EULBNI5Za/bErKH3gU70CWtq5DnufzzwCPrRB+3D8B);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.5185185185185177" width="2.5185185185185177" x="5.666666666666665" y="6.925925925925924" /></mxCell>
<mxCell id="logging_i21" parent="logging_i6" style="vsdxID=35;fillColor=#2d5967;gradientColor=none;shape=stencil(lZTRdsIgDIafprc5kEAK1869h2fWtWfOeqpu7u3XDmwbcPV4Bz8JH4GfFLQ61ZtjVaA6nbv2o/putue6oJcCsTnUVdec+1FB64JWu7ar3rv2ctiG+XEzRA6jz/Zr2OEa8tCA0kMWqp+g6BJU+ae8hoS3SxcydAhwU0ZUkMFRkK4YJBUj4tRoMBwjSEbEqXVgzRJWSWZpgbVkzg4WFa8AjcSimqKipJVaAs+vSOf7RhRhRi/7A1lJJ87o7AD9En+eEyW24GzC54zPCrx7yLcM+km8IfCSbvpbRUknAzqp3riMjh5w0W2WE68ZoATOJitde7Bawt2dhx+j/rO6k3CNgJLt7zw7EEr0zWAjeNFvnqe7lN4fje4kUT2sdBHIyddCMIm57zxvXuX8n9wKT3vJvjk813z6wdS6ds1+HzrffD1tdb0U2iStfwE=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="2.5185185185185177" width="1.2592592592592589" x="9.129629629629626" y="6.925925925925924" /></mxCell>
<mxCell id="logging_i22" parent="logging_i6" style="vsdxID=36;fillColor=#2d5967;gradientColor=none;shape=stencil(lVRBcsIwDHxNrhpbsmX7TOk/mBJKppQwAVr6+zq140RpyZSbo2jt1a6kilbn/eZUV6jOl659qz+b7WVf0VOF2Bz3dddc4qmidUWrXdvVr117PW7T92nTZ/an9/ajv+GWcEEB+x6F6itF0IA2P5HnBDg0xwnAGbASYAx4mgJerl16QqcE9sAmQ3LIYrnlhjlLg+ecNYQUUAbeKAMtqOF5Ktfr+3zNrwI9guP7AM0QrADYAMbfB5AG4scUIT9oXBQhB4GkIsYORIsi8S1FM0UMoJGKoF3wz4JBwXZe3ZysQ/BekuWRRSbmRqsKVzBWUmUHM+/UgnEMrAVRbcHig7KiBmslVVJgtaQaNSAtueKk6hwiBlzoNPVQ04ShRUp1akEMjj0rxXAMblGMqSPjIAae+eZAoxQjDiLOxPAEykoxxgn+e4qUlCM2rg9LdIMDw5Lu1JXMLRhQbuZdEaLQnS61wc7lrfaPNRgP4xLdNYdD2sHT//OlG0NpYdP6Gw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="6.925925925925924" width="7.240740740740739" x="5.35185185185185" y="16.68518518518518" /></mxCell>
<mxCell id="logging_i23" parent="logging_i6" style="vsdxID=37;fillColor=#2d5967;gradientColor=none;shape=stencil(lZHdDoIwDIWfZrdNbcmAa8T3IGG4RWRkgD9vL3MxMg1E707brydNj+Bi0FWvBOEwOntSV1OPWvBeEJlOK2fGWQkuBReNdero7NTVoe4rT3p1thfvcAt7OUjyS4T30MBndQhsa7oFixGYQpass1++nALJdV4yJDJayBFowx+Bs4jf4cbpr+GP5n88ZZudxfvzjWnbENxy/pnU3Aopc/kA);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="3.148148148148147" width="3.148148148148147" x="4.7222222222222205" y="21.4074074074074" /></mxCell>
<mxCell id="logging_i24" parent="logging_i6" style="vsdxID=38;fillColor=#2d5967;gradientColor=none;shape=stencil(lZXLcsIwDEW/JluNLfm5pu1/MCWUTClhArT07+vUMX6VkO4c+Sonkq6dhlan3frYNshO56F/b7+6zXnX0FOD2B127dCd3aqh54ZW235o34b+ctj45+N6VI6rj/5zfMPV5wkLBscsZN8+whn7fX7x8tfL4PXcbysOQk4JPM9gV/QBTcDspJlCVoIQk4p8yCBwM6lCSIKlOfoNFdhKA+XwKJkCpAHVQzQ3oGbRSgCpHF6UTRKUyNks53Idu72UWxScVpNDAjNpyX3sw06jAlnMOZ1hKNnERpb9D/TUYvSnx/bd4T+WzB2MzpAqkyOCmK/NxpRgLAFMF7XZapzuy2xenGSVk26ie0ZioKnobHxvOEIMLC8am3zihNImqmhh8VZUg3VT1Cbnp6rgKxlV9/nj0Zo/RwSoi/INiILvbH4bEdYqqme/lC+r+ystDCtRdANXD+lV93NrL/CqW8S7etvt9/6qT/fLu92F/H+Bnn8A);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="16.05555555555555" width="16.999999999999993" x="8.814814814814811" y="3.462962962962962" /></mxCell>
<mxCell id="logging_i25" parent="logging_i6" style="vsdxID=39;fillColor=#2d5967;gradientColor=none;shape=stencil(lVbbUuMwDP2avGpsKb49s/AfDBSaodsyoeyWv193bcey0qTtW6JIPjrSkeKOHr62z5+bDtXXcTx8bP4Or8dtR786xGG/3YzDMT519NjRw9th3LyPh+/9a3r/fD57np9+H/6cTzilOKOBzDkK1U+yaKX+vz8l95fvMfnr9Nk6MDYH6DZCnTAZXABH2SebggGVw06UTN6BL17VZM0aejwm9C16BFO6xZ8SKujWgnUtevXJBqPA4hp2jcgG6sG4Fpnnl02IgCiYW+h9i64JjF9Ddx7It/j9hHWqPAtWgVcttBGsV3tNBE5gik5HcsG1gCwrxk3fSddAr1tkXseWW0Hm/aDW49Yeiw5z3Uz0lGlhuQCXGV+VdjyZsIXnQ1M4GtBCYHX8Cks200LtGXs37O/ZAe3KIISeGvfYrUCrQoqCD2JpxB1hRGkJUHJzgF6wQ3CC3OS0tLMUeKEmfnAZHrbZcJ5kBnNM8XQjfedAidbGIoqldWFpUphkNMEzr2zqQ9kMS/AspoxXABTK4knWioSr7F2cCLdafQ9BsPcKUDSf9yibfOy02JwXpF29FvC5rPT8ZJxLFOdZZjDSoPyd/DEWVpSfFbYsUjb9tSK9KD/3urX7UZ1WLHGuK5wnWSoSOyJ+2Xz0l8Tf7pYblkV8qLeTt2G3S5cb/l3eZqIp3YTo8R8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="4.7222222222222205" width="4.407407407407406" x="12.907407407407403" y="9.444444444444441" /></mxCell>
<mxCell id="logging_i26" parent="logging_i6" style="vsdxID=40;fillColor=#2d5967;gradientColor=none;shape=stencil(lZRNcoMwDIVP463Glvwjr9P0HpmGFKYUMoS05PaFmpSoMzjJTjx/knlIQtHmVO6OhUJ96rv2o/iu9n2p6EUhVk1ZdFU/Roq2ijaHtiveu/bc7NPzcTeRU/TZfk0VhpTnImicslBfkkIO4q/wmvi6am54QghR8AaQ13kD3j6BUwRygrcMAdcTtCyu9TqKEZx5HHcBiAXuETjzKuwA3eP1mcFRDn87d6lTJh1HAnutv0hu7saAs+QhXMvOEgcws5OB5FX6Mgshgs20PTiwckzu9CUyUJDuIiBl/TnQLP2Zvy+++DPARvrzYI20xx44SoO5ThB4ORi5sXhyYe7zY7Bs56Gq67Tct+f/t3mU0p+Atj8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="4.7222222222222205" width="3.462962962962962" x="17.94444444444444" y="9.444444444444441" /></mxCell>
<mxCell id="logging_i27" parent="logging_i6" style="vsdxID=41;fillColor=#2d5967;gradientColor=none;shape=stencil(lZXbcoIwEIafhtudZDcHcm3b93AqVqZWHNTWvn2hISQbRsC7sPzJt8ekoM3lsD1XBYrLtW0+q596dz0U9FIg1qdD1dbXblXQa0GbfdNWH21zO+3893nbK/vVV/Pdn3D3+5QF029C8esNUoj/7zevfr+1Xi79b+3A4LBB8h3ijt5gEWTQDCanQbpBRd5USkA9qILJgDBz9BEV2MYCSU6PmsFAFvQiWpZg9RzaYDglsLOoCcE4ThYcKwmcehKroJQcixbKkqPzgB1kuRacqhHUHDRPshrPw4lXoeYGHC6Gu1hgJNCG09PWCQFq0CXnxyakSWMTlwzoY316Yg741MSyBXl0/FFkMUHj4GigrJJdr4psdKQErRZjG0WP5rYEaTN8cvDAMklcOHWSxlqrrLCL4TscBzXwuzZVyPmpKri0ih8n+tH4itgywSULMrs7SIHJ+KlqMrTr+V2yRdbYNvb6mH+wlIVPoAzHJ6KV85zsCNeKBNKcnXoY0hHvyZnYJ7Xnk7ViVrpFfJ/29fHon7f0f/6edSb/FtLrHw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="12.592592592592588" width="12.592592592592588" x="11.33333333333333" y="5.037037037037035" /></mxCell>
<mxCell id="sgw_i2" parent="139766069591360" style="vsdxID=43;fillColor=none;gradientColor=none;strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="23.032258064516107" width="23.306451612903206" x="43.3467741935484" /></mxCell>
<mxCell id="sgw_i3" parent="sgw_i2" style="vsdxID=44;fillColor=#FCFBFA;gradientColor=none;shape=stencil(jVjLchQxDPyavaosv2SfefwHBYFsERJqCRD+Hi0zlsc9GS+3jSK7ZVlSt+cU3vy4//D97uTdj+fL09e73+dPz/en8Pbk/fnx/u5yftZfp/DuFN58frrcfbk8/Xz8tPz9/cPV8/rr29Ov6w4vy7oUSeS6yrs/i6VWqvWf5f2y4OPPy7KCF4coVP26ZDWxc4vhxa8+TJxXn9VUC8XVKSyWkMi1jVZTTRRm2L5QqSN29eR5RPeBUhrRi5DwCM+VYhzhi29hH+CzkIsjfnEU64jPkQqP+FIoA7zvmV9NkilN0Zkkj+iSKAmgOypweomWEIN3u+RLoDjFr5QDwHuqAC9mMXRH4kd0ocwArvHwDFzIpxE8VwqM4AxHVydfRvBMFe49W1mt4A/nx02TZPKt6FaDUPGzYOGW1B8jTZQLRJrbphZpogh3pE5hmqbUM9DAExXEdlCe6gP1ES0Yg9ZlkyRFslOv/gGSuhskvQLZlkTIUyDBPHmbPzZJrAksWN92OgAPFDBPbLOlg3vAZooFsV0AbAcTdEyUb6le85QqybTtvBVPCzVtirrNPOI4xpoKQahMtYyhqs+60dHI6ZOsYYvNLZs4lCtgi83/Dp6g61KmfJwmttyv3ql14WGoUE3KbQUitZvpkUaKYYzUdY5pkYYbnKgTDmgpdQ7q4DY+G7h/BTxBOSVuO72aJ0dhHE5JCWlKYpsVbEvYY7AexnisWE/qAzNCfW5hOxmxYzFKNWwAVloE7nYAGxvpHMNCGQftW7gflUIj8LWwYdJw2NGmmnhaHLoNzprYWr6PGk8ZGrgH/dLPGYE33Qw56ugHxkahpswERekAs+yYwO79dSKoJrX+WMHFY38tPh+n/juOU3VZ4FhtSSe5/UTU3qrj4bRLXcHDSZkEG9tlt2B5mgz1zwL+Nw6nVAzygc1ih1MZAPq6a0M7nOwON4u09EpolDJS6M7f6sKIbZI5pU437h9uUHTeUIaxdgZ9oERvDWmsXUDM5M65Jm+cTGL1+Cq64b8R/CaxZv65KW0TS9NEiI1nEys2wy0RnZdNrZh2skTYI8x0NwwvCLR2wlwsBVh49Be2wdaek430jmS974Rnr8ndi06fJh7r3e2uWb1Q2bPV0BF+7mXZ8ENn5YYvfeeGr30K5CB6WKgzfTDKVGDpwzTB3WoBM+iWqiHB5QZnaq7h19wVRqtzJZFpbVVjdeOmSgzHt/f9RltWGKVV7NY2z6o5M9YuvuxFKbvKLiZk7TWfrH8afGFLmn1MMNPR3Ydd7jWF+AjQ5kYpdP1GArnffkgJ3WvSK//x6UV/9A83n88PD8t3n+3/8UOPmpaPROHdXw==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="22.483870967741915" width="22.75806451612901" x="0.27419354838709653" y="0.27419354838709653" /></mxCell>
<mxCell id="sgw_i4" parent="sgw_i2" style="vsdxID=45;fillColor=#FCFBFA;gradientColor=none;shape=stencil(lVrbklQ3DPyafXX5fnkm5D+osIStEJZaIIG/j05mJNmtPT7J2zDI27YstVryPKQ3Xz+++/L4EP3Xby/Pfzz+/fT+28eH9MtDjE+fPz6+PH2jTw/p7UN68+H55fH3l+fvn9/f/v3l3WF5fPrz+a/jL/y4rcvZjXysiv7n7Zvo0vj3i19v9r99f7ktCPcV1aVyXxFgif8R70bNtXo3imyU79/8SHej4QIbJTaqM/anp8/TXot3JcBe23avJbicca8jrHsttP287jU5n9a9luRiXvdK38QteOLdCbgsUfDsUkDw3AE8u14QfOeo5mJaHJVd3Jh31zOYt7Y92nClr0cr6rL7Oap3caxHKy629Wg1rOcqrmwOVik+1p1SMG7Ms6uLNfml7M5ViwsQ282VDOcqrrb1XE3uR85VXRjr0TpH+xl4dS2u4N3lBuDN5bKCdzcAuzsP4TJc7Fvsro4NvKRWwB7Ow8GHG3ihg29QwIN3Ke3Qm3e+rui0pgKnkBWghyAEwvAtSIgJfHB1E/0taQbeF9A325tqxSUI/1BMajeKNuDA0CQlZMN0fQk2PJjnTvB71otgWiNeA3/1rrtkDp6imSMjaCozt0TXt+k/iB/g/KlLvDP+qMp/XBay5JfgN4lx4YCreBkEBtFaqtQGwZ/+MkdwZGJT/OIyJOqRDNv7H8kVyNSWJewF3/Jfo3yB8/cqxClEkblUnt1/kGMIU3TNRAarerO8pSiHlfjzrgP+uKJ/YkAP90/O9nD+IsQk8F2N+K7pRhC+uS06CZBSDHoCls4kFhLAE3FDWU/TSZL4qG5FxcGMacXvQ+QO41MN7eD9XpRSWe8Qg0H0d2K+LVcHKtdhxae44mMwfqiugrA4CAmyP2TmRsEnctvKmnlJgCWKHkXECHqUbQt6dB7qP1nFrfeJzQt4nzgfvU/lw8cVnwpTRe7ToqepP7bwQzldSyfrYcl8QG6isSXrpboJMrHV1u/d1BwSDB1rpAm6Q4hA0DdlLwYXEjyreBqmDJ5FNIo+EHITcFK3cQWv9uSkk/OWblyGG6clAYWR0qiSfUYVz0gKHi7Ai7QtAh5EXgnVqehQ8ZsLgiPRk4zu20JPPl6xi7ZMQnSG54h4C3hd70GwRbOeYgdgGVoSgGWSdo8Mru2hkKxrIEdLYXI6AU8qIhk8syiZwDPk+NFNDQSPQPBHX7YtMMmqi6S6RdrZgc1NcAPpXfYs4BI8Z9VFlzC4l3qn4BXBvQal9tIQ7NRwlwtwDPZMUisiOMpKqsimsKkRgxeOnnNwCLiUXuMYqGrHTUC/HKbaq1+NraY6HI+JrrQdZUPVjjUw16aRinpjode1A7mewVzNbPw2nHWawSejYIGTxaBVXYjF1GtKJqjXIV10ltkMQaJQrqDrfn6qpyOg+/8ZT36FzdpeT7AYyV3qu8CawQ+l0X7sNC3RHEYCmYw0hwtiYxaRTd/WK2/kUQmmWHqTwmQUL7HDNoynBWLfL/yEkobagWr8VKC2EhvnjJvFwk6lIG5Z3juISypKISA2KprDCAIkaDP+X8tb0OGQ9q/YPwUzbTmMMCVNdJJRXMDXWwrmlio3gKebxWa3NCU92SwSIxmNgZvFMeYhVba3FJUZJgmE5KXujGJUoNG3FYk0mm/nnoqujMVTZF/zzn51bJW7OT3bsNKywRR1EiOqayPkatKRfBKjfRdrFVa102mqv1AUVKxP2tLDwI9k/zpnhXqnuxX7tquP2sne7YtL+xGBKTq0BKRrNgKOWiV0rE715GyVu//ThqGAjKHWDkV7sY5tRkNVkV5Te7rWPJh3a6Mk9nVr31YdQT3yvqZW0VpyuCFpok0opmO1c+Jpjq2TqLRVp801nHt4ky+6HRk86IBXiGgaDySx2vditAaVectGIYagwxnGL5YIo764MH69EKiHqAUebuD4APWi62xPkIc+dvEsIvJVnPFU0u6RhxHN9iTdPKONic6YqSxbHOPGLVMNM20eTZ5gJJ2rEXNjCOVP40acfZDVnimPOSbMG4P3K3otRlENWgZs0gI/LCh6vZj1Nx1tyumpNV/h6Qob+t6b6Udv9k2qXIw/6ArNsNPOP0Yx4zaKehyA0K0FmIAQMVyM+oc+ZU51CuKer2MSShVSbgqGSUvvnwPpChv2wwnryPHMAXmXmj4GMHySlxd5ZgkcV2fwXl+mOBWrGXTTFQ7w/SHZ4Oq9vlkyEzQey5xFXjf6JBSdLOlQ2YPyo54Qr/5gSvsst5d+tAZunigYH++JtpHvj+dGQLd0O5iZXn8TDNoy3x0IigMK6dBRFNeqywdXLKRmvlW71X7m/YZ0A0o/bmPO35lx0lFMGSUj0yKarusQVeb9PmyU36Ee8YcJYfeAr52e2PtNc1PXS7h6xz0UOngiGW6r0pXryKfBJRR9/9GRT9kc7Ghi2rLX/YjomNauzUjgZ+OzqtXM/DaYJ/VjWAvDY0MdpZiSGZiXXt9rQX1/YT9N69h+F0TH/Ha9Z89/4MwXU3mU7t/4Ihgenwav0/gFnCF19uw3S6nBZnf2eVj7uH8jmN581snXJI0wl/16rFdGln6zx/38kT7or80+PH36dPux2vz/+Os0+ur2y7b09h8=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="23.032258064516107" width="23.306451612903206" /></mxCell>
<mxCell id="sgw_i5" parent="sgw_i2" style="vsdxID=46;fillColor=#2d5967;gradientColor=none;shape=stencil(lZXRbsIwDEW/pq9WEidx8sy2/0CjjGoMUIGt/P3SJU2xEZX2Fozd02vfuA2uzrv1qW2MOl/642f7020uuwZfGmO6w67tu0s6Nfja4Gp77NuP/ng9bPLv03rMHE9fx+/xCUOu0wjGjVVG3XIkONDxL/KWC96vfa7QJQFoqigRIkCdQ4PJIQ+25EyBANaUHKw5JXIrERcBwxI7lSBnOwVoOTu9YORwq8FaDh+FE6cjgnNLdE1AnuONA+843lgwyPk6gtKcjwaU53ydCv0SHyOEyPkRnOi8DRAE3kPgcBdAidZPA3vWeAJjONpzLnlA4lyCKFQHC1K0hrgoOsT6lImsDRBxenSgxNDHdhLHa6UEPcnWi/RkJqHbAQUhHauqElGi36kTgZOTbXEJbA2g8Jp6tBrV8c89n2w1zBqF0XUAvWh09+CzZLTJ1APXWO+YrRMYpMb7C24XfZY0EieTrde59nvaUBUe6uKYZaeFI3WX8T+73h5U4PBkK7nZkq3QcHqchd6vF8fpD4t13x3+t4nTYd7j226/z5+B+//l3k+h/M3A118=);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="16.999999999999986" width="16.72580645161289" x="0.27419354838709653" y="0.27419354838709653" /></mxCell>
<mxCell id="sgw_i6" parent="sgw_i2" style="vsdxID=47;fillColor=#2d5967;gradientColor=none;shape=stencil(jZbdchshDIWfxrcakBCg6zR9j0zj1J66ccZx2vTtq+0usGhj0rtdLPazfs6BHd29Hh5e9jt0r9fL+cf+9/HxetjRlx3i8fmwvxyv+rSj+x3dPZ0v+++X89vz4/z+8jBFTk8/z7+mL7zP+9gBhWkXuj/zivv39nUO/vZ2maP9/GNwwHEJX5YcOJpX3nFeIb9ELO8IwksELSsIOS9By1KGMAL7AMmAPUGOPVk/QobtgaWH65d6NDmINII7kNSzSSDmnu16cNAI7MEeBHsyCyCOyJoi9eSYIXubNYcentIWzhBiT8+hbLxB1zZR7vHi62dau8FLz5cIPpmqO0im5ZLB5RF/Gk7D98719KgxaOjSRnJBRQEy2QvDsOlJh8lvkufU47NmaoqfGTD0eN1o6NohP+y8JHBsWi89W/Osc4l1oIJh14oV9DSZcai1uqNMYYRg2aoiw8aVHqmWInBPVyEzD+u+qmiZA0BjMZGAjcu4Hr02NvrA2U7H5/+3wc88U6uRh5McfJs/b/c0JWE1qzrLWByimSeX0WlKTqVCt1qaSs8rP2Mb0wXmPWTrJAoz5r3SRVFXhDzsaQAxOuZcD5JCD8UN1h4ajJC5GWIzlrF7J2ADV8fKtEld7LFFkKyWMqARslaWZGiiAaLxEYUVba9ab+QUIZncdYiMmGpdBwZq2LTREsvm1AzgrYGm+neqhRUzvC1kh9vE7eFF4E3hfWztKTOnR4X0eP2Tw7YLgbOntq+mVX2MW15YB4qtf2uUkZzOJo8NXPeY2kdfvK/xXbsUFMlRFUJNHzeay/Vic6v8BNLjleWMjUc94c3cTb5kzu4PvHTjeJ/56WaDPrRL6dPxdJrvtOvf7SVWl+YLMN3/BQ==);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="20.016129032258046" width="20.016129032258046" x="2.7419354838709653" y="2.7419354838709653" /></mxCell>
<mxCell id="sgw_i7" parent="sgw_i2" style="vsdxID=48;fillColor=#2d5967;gradientColor=none;shape=stencil(lZPbDoMgDIafhtsGqCeu3fYeJuIkc2LQnd5+MrLMQ5Rx18L/NT8tJZj3ddFJwmk/GH2RD1UONcED4Vy1tTRqGCOCR4J5pY08G31rS5d3hVXa6KrvtsLTcYxSy3D6cnkWQZJ8Tk5O3qh2Is9SYDgHKCTZNhALYGIOCOBxCMAopDvA2hITgHwbWD6ZxYDRjqG5mm4rg8oyDkKE2I4oCAxpzBrwtH5tyTPcoK+z6ON3Cn+NyFPaKx+D3wJUqmnc/kzvlwszHrllw+Mb);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="14.532258064516116" width="4.3870967741935445" x="10.419354838709669" y="5.2096774193548345" /></mxCell>
<mxCell id="sgw_i8" parent="sgw_i2" style="vsdxID=49;fillColor=#2d5967;gradientColor=none;shape=stencil(nZJbDoMgFERXwy+5Qin029p9mIiVlIJB+tp9ocTUatTYv/s4czOEQTTvmrKViEDnnb3Ih6p8g+gREaJMI53yoUK0QDSvrZNnZ2+mSn1bRjJWV3uPF55Jt+eYsKgi8EqTDODTnxKulRng/bKH2QI7Pb0AM4H5yAfBgs8LOMfwK9gBFtm8AP6H2QHDJisrguljRTixYGfjL63iofgGolZapzwN9+MAhVEKHy3e);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="4.3870967741935445" width="6.854838709677413" x="5.483870967741931" y="10.419354838709669" /></mxCell>
<mxCell id="sgw_i9" parent="sgw_i2" style="vsdxID=50;fillColor=#2d5967;gradientColor=none;shape=stencil(lZLdDoIwDIWfZrdL17KA14jvQcKQRWRkgD9v7+ZiBAwgd+36na5tDqO0q/JWMYSut+ai7rroK0ZHhqibSlndu4hRxigtjVVna4amCHmbe9JHV3PzHR5BJwC8BuEZ8gh4It4vp4DXuhnhSBxojyASHOVEIJAn8bKAXHn6AyzD09nlCvnb9rP5n2MnMYddh5EHDit7zg+/E984+ybugq8lSl3XwVHj+txC7inYj7IX);strokeColor=none;spacingTop=-3;spacingBottom=-3;spacingLeft=-3;spacingRight=-3;points=[];labelBackgroundColor=none;rounded=0;html=1;whiteSpace=wrap;" vertex="1"><mxGeometry as="geometry" height="4.3870967741935445" width="6.854838709677413" x="13.161290322580633" y="10.419354838709669" /></mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -0,0 +1,289 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 6 0 R /F5 12 0 R /F6 15 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
>>
endobj
5 0 obj
<<
/Contents 22 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
6 0 obj
<<
/BaseFont /Symbol /Name /F4 /Subtype /Type1 /Type /Font
>>
endobj
7 0 obj
<<
/Contents 23 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
8 0 obj
<<
/Contents 24 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
9 0 obj
<<
/Contents 25 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
10 0 obj
<<
/Contents 26 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
11 0 obj
<<
/Contents 27 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
12 0 obj
<<
/BaseFont /Helvetica-BoldOblique /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font
>>
endobj
13 0 obj
<<
/Contents 28 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
14 0 obj
<<
/Contents 29 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
15 0 obj
<<
/BaseFont /ZapfDingbats /Name /F6 /Subtype /Type1 /Type /Font
>>
endobj
16 0 obj
<<
/Contents 30 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
17 0 obj
<<
/Contents 31 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
18 0 obj
<<
/Contents 32 0 R /MediaBox [ 0 0 612 792 ] /Parent 21 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
19 0 obj
<<
/PageMode /UseNone /Pages 21 0 R /Type /Catalog
>>
endobj
20 0 obj
<<
/Author (Carlos Mendoza) /CreationDate (D:20260412224013-03'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260412224013-03'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (OCI Architecture Proposal) /Title (Mercado Libre \(MELI\) \204 KVS \204 OCI NoSQL Database) /Trapped /False
>>
endobj
21 0 obj
<<
/Count 11 /Kids [ 5 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 13 0 R 14 0 R 16 0 R 17 0 R
18 0 R ] /Type /Pages
>>
endobj
22 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 589
>>
stream
Gatn!?#/1K'Sc)J/)JIV0[9I"m)q$K+=pf&@X=:YeQ*FrgWF'=,@`rea*(Y;X:u"/TOS;#o/tG57mqujF'\s@149#D_$.+r\7,fu$<PpIa,KOfE,ED#M3[$6.7>o-[okMaa-:+4J`*aqT.uNtP#b6nV<MnQXMjb?P"\-^LoMtESPYi>7_1i?^f)!jfh=sh;?`pWYr.o=9W/^QnDaga:.:@k0Wm.F%;p*:/+Bn3G.:[+ETq:nM`c3K$b#Zc%,#i8k6'Xek]jl]Wq(&/NfMb.=10N)hUepp5i;Is+3T6u[Q^@#BWc2RqM&8KIG"GJ[I?n5@&2BHZl<9)='^a<*q3j\Jc4\U7r<M57aQOmUV&eH=,EOBLYZCO1ld<CeoY@-1#B8WRlnH/+h*0GWdLIWD!'>NX6&L1"o]43bnGoP4H6*=9N*W41d\88+1.K`A2U+#GhM[ApM4Su0OpllqXrYOQaX42[WQNZQ$N<0UjTA4I.lRKbFcH&iPW@2HA=Ak(l+$2n&ipQVeC&h4S@$$D])0@?T"(<ru].4%@(jOm@(olZM9EK@.VNL;>IrAZIoH:G+g";:IHr7"8`DtP5~>endstream
endobj
23 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1866
>>
stream
Gau0D>?BQ=&:WeDbfcTAp(1`UnuZg5BX]R0"%g!!^l,F^7)bKl[V>!0hiW:X#fJ<rpMc"Dm$[Z]k0qPQ"DmuZk'*$k9]g<dQ2mU4?N=LMKD@Ntbn%N/=FOX>+U*f#bU*&2Io3_%G<k-a5mAqDht8)qf+#qRJ_<>a0$r<=bA3>Fb].@<^g_ulSdQ<K,-DGkW<GfpaXAu4.?#m4MKkZ/\\(c@Y"':@kO5T]]n6&]R(q35[fqV(q;.G,8Y.ME/@&1EA4siJm4baV7VJ"46^Ik\cn8I=l]\*/e4uFnJ+\\RNoa(A1p@#`DT\:IkT3MJZ,0o7j5[P1#uI+;>6:.YSQ<V6_7);!.+L=&2$=9f0crP(poqFP82chh*PHSlZhB4oQUYUP6r]HB:;Er';m,O1f\EasKq25g#6Gun(m>iJ'PZ^f;ht"-51ap9?MN#]+U40b2QC8pSm<]Ll.jW9FFtJj1fYZ*$cPb9!/FMhL!6lCUgto!T"rC]B<Y-U\]@bXGm;;rB!%u+e,,*%q<8"hU$cI"`9:OCearof$#@@qJO_1C$?5?!gU<g:2i/ra:Ah;#(AEms\QmtO$H-BsU9]<*=+u/S>:U</a9VeJ&6X+)#X"$=>_u3G.<l1-*[1;XUq+'l6lSTK.bskQb8#+ICK3,?8tJK+5YM`Rpf9t?6:IkooHhYd65GR6=@5@_0o@Uua%r_6XOIH0/98[bOfKXG-tKnaKEC4FUdL@.Yt/tE<qdHu!^eK>50CB1PN(DHqmi\=?/h9O>CfBD8Ym+BHC0u]<Z_kg\Bd5kBV7):CV)3a`oK#IIEeBY7]n35+0qZ:$jJ?aWqk#"bmT9Ef$`/hpBZT0Yk\ci#M,ShV=JB3>$#8g-C5-tl$Y!Y,h#Od]YWBQS;`kq^Cerc&?7UP3KT.j0-5lXM.c"u,+!F`cj'pG\<?bZ-F2tiL5bmp!kR#Fp3:0oTs=_ql0`9S7:b/jL'UP8s+.2sUbNRMfsn"V&W]ro0OFNL(R#Kjng*H/QkMGH_OE]gDf+m"CU?rE)NoFYGPJ8D$Xhp`bka[JpP.+9SO(EIS?&L]NU#SdBD6H[4;jVa-grd2ZcdDLjiAI&4UA_b9<d'l#c;kUVgFjth.@_;%@k@s-aQV3TBBjar*R3"m/"\EF"=8[Z'Q61%`@*lf+sm]`Y3R@6lX?#h.5&<k=u^;jE6aQD(:S55M9$.gsng_EGk(:QjfC-m>j'#9r9+sR<W4<CgoND!1ptP2:EF"0A-gqWU&r-2/cm61@D&\WD&M09;g?_4i2Ha;X`-eeRj[g_?4.-R"-94K!Kq3_3pmCYklV@:md_YS'J6J+JO=f%o:f21TX2FU&trW*,,fUoD%PA$Cf4":\#g;nV0QCfPQ`1aA9LsbrbT+;tIDqf'?S+=GuW9ZCcqtE?O#`hcD.H"O+g%@#Q8LK=6#apCbgG"+;hB]te^YBuHIdl0d_&Qbt-W3d%.dRW]LV/t0RXNFuI)'/ui6rK`&_QX&>n3KNo\8sjPU[kCR[fsFg4V:>'CV"XDk`"T^`Z""#`WI9?SX8/[,8f:sG?3Kt:\uX==!c9he:GsYKhRRUZF0Q0>hgM@OO0QoEVU*M?qQ"-;@ej<$lt9=^r]ptO`AA#'p]VfFZ,?WHQJ*FpRO3ZS+tg<]X=F+E4rB5$fPupZJmE_gEcp-g!nqZKJE7(I)aF'=jL.A`_3!SVoGGLg4i3!YhBhl&Y*q]J^K^Scs1\KPIt3sTPa[?eeK)6gfm;uCNkP7aIecNp[<l_r8)$2\mL_oFL!3q$009o5GWP$a<O;$u3B"9[U\1X6J^)cG7I$/IR5B)!%H9K53ektnS*V)hN`EHLV5OXa.8Ed'>k_6&1qgF8]l]]pK7<olX"Ro~>endstream
endobj
24 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2750
>>
stream
Gau0E>?BQM&q9"FeB=GN+VqZb2J6>987kC8+Yh*Opn]ROm@Hj`7kL-?J,OiH\l]/H_Cdj=@+"DFY,\\jX")(5(I+Mi*@4*lDWp_`8"NL8$h?V3Umk#'HZSi>a;GEB@-!O3&&Oon&,sbM07P&=FF06M0;Ln;:C6]?6i.SHjJW\MA8*9d?O:ejT]_A&E^J(koR#XaP1LXL[c@NsV32R,%jf`9P$''mRP*,AP;MZ3]tM(G*ZrkU5BQK9bA89mHHr2@3ddgRKpp1A=!DN&ECTA0kX(8kl](`pBkSU@,c=_u'X3\I./Wf>>31eH-h'LoLX+6rG:f,DJk%B^4_HTfD'#l:'pJ+_rRQPG5c6fnGA5tETMq(/B&:>lKd3N/Na+gcQC.&SjAO():Yu<Ugql6cM`U%LW+EP]cb5hEUZSG>4<1g34W?I@RTpWoGbmWt<'MA<h&\c85.%$/e/Jh;?=hZkq`EtHf:u,WR>G25<5A)T=iW!iq-CD9(>Y[`mgnVCP7*dU,#\2X:.Ah7'hLc=K2j/V7CW7gV2J$74=d/=aQ,W+L[Hh(0qb^>G0bi(oM4NF/Xsg`7X<1OFflAM+'>hq)<EA?Ah>78:_DOKm!GhQSCSn1ATep+Idi8Tld9'LX5f\dW)O[&8B+o2`M4QA@;!ofe8due,?-4+.`McuB6p\d.NEJ'ZW\h&6U^`9>D(jfdUF6_]*)qjn2Ba%HM3fFApf$S4bFdn:qoPB\L\D*^K\`u>_`ia++XH:@C)Ye&p,Ya\3$#bpi=YhbotP^rR'2YO6O@DaaWVKhl>aAb3Y(nBVf``;ij1[=?1YRnE+%u1Y3V-hB/[gWBCJnqZ/mK[NEQuqn;/r18of!p25^tB;3gc/A%<T_Pd%jm".Fdalc<c2o.g_IiF#]!7nQL,L#=#');V^_OiZQ#%=1h=qn6=;PlfdnS76/`0uNZPR'`>9pm"=amIWBo+)su9GbdD8Ho$a\F<PSg#PIGg#,XuA^6N++p,"dB<,-Uff]LM%-gEh_bd@u\Ut%GkmSct@KAV#M0.%2\j=RuG[Q*5R)P6(jgZ3S$sc7r"8@\e>[LoBI!=e,]PF[/FL'IHgh)!_RfH[)c37`5=k^+:n'Yo?)'.I%Q;lr9eDrXmohUWAH%GkHF^;:f)7iiDWk$l!DW"ZfcD6i"hI_RAM?FcN3QReajI&c0m!>F#0%1*lSai2kVou8&DfH*1(<AI@="dJmHO*%*h@bn_#[1b"Z(TRTZ]A<<>j55('Z:r]d%t&$q2+XkX[:/+Q]-2<SO.E70;$>KW'fpbK,fIYl/aZ<?!?-4RbLt=&;!?tno^WjFC"g!-EuqKL>2q*qSRc4:OB7un"YrNqnqp$p3X^9oCes,[eos>C;7f#U@LB-H=U0uDqa^#M8W\q27\-G$WU"jeWS:Y_0H_6Ds3tZs'J0DWIjSf2s&b'[6`XMKDa[aUXADXADC2gh:+X":atrLD38-]))j0gSa&TZB"RI/jO6VpFj0g8_'gp!jU^21kmYkkU[qMn"i`+![73eK.o`%nh#8qp\f24tZ:u`!!e$<JWWE/)FD-($VE66oX(ZDt2UXKdBTJQ5RDnq^_gQ]\@qU.8XS)<s>n['?Vm"I0(2Ig/aqdr%Z?7B<H7i^jE>fraoNqsprH3XMW@Pe0jm4FDK4i3bIXIR(?Z@YsM9,+pCd_s])=7;JeCece0#h.%(I]>$dJ[fm!NIX+l_\'2V(aENHJA\T.)O_bgFg\hOf>A<4p7H9)SQ?!FuE]JiS]%8WlJ(?doKDO/[hq>aS6).T\"f+]EY=I]i!og")_mn-@Z^ZK50OWi>5#j])"IuEE^"r;#=fI14^blo!lTqhh]8$Ae>,ZE^hf]3Fc6iSg\Y2deKt6@4"J%j9U<`Bftde&(+&4,$W3[rh+^LVT/oBm=d3YNGT#;qPG9r&tn*aM*tUX0@mA)=$59M<:GXg%)Dh@3Ss-j?__b].$TrZXGU,p>@#0gRRo!W<]B?kp"%>=b\_E8a35D^D(/EYmAeoG=XUM_+#/B:MK`>`.l.)2Edo8^]b`,kjc%BX#R>Hu*,2dKG)YW'U"?s2p!E8qK?@,c]o7P$-c)B)ABtc3'BWFZ8^Sj5*/tU<k_-9\P1mK0f!i`-`hGM:E_Z;l]"m5t[QEEGfW?6Nd-/58Dd`G[N9ck'aqF+I6<+_Vi;hu62+1-65Vp]MA2o=SJg<,!0HsRPJhq9!)C(S2@Qa`pSRss`U-j^9?.X'dUCm@nS(m+&C1WD_"@P3/G;ut7Q9]A(_$T%WlZqWgCg0YJR>LToECS699JQH]!H;1ucJ-ol.]X=M5j0,FMo&S%ErH7OH&^:o3-kA0'UYG4%#7hXF**Ae0$YD+[0R]`<-`T?M`J:NGHHWhCDQc[WWgks9'=a(Xm[4c6117Bcm#N*fJ4=a7HC/Vp'`L1;4Kp)Jf28bmSJ5m,)nA"mi(+=9.,4NkPbk>Jj+RO4<n[UB85du.B8]bj*$HRl!+I8I[>p[_tWl\`0O&>?<TH+NA'%(ZR/Z_CL<m]<>BQFhk5:*b0dnDYo(dq4StR"(=u[Oa0"58hdj_g!@/=HN_hIllSSsRD\#sihu%Fn`483U4["7"&WnYq;V9ZJ?)"qus0^<^fiP)ZIV1/KICH]A<4?$#(V*5`5&B-:h`j?q59ApBSCjO"T6T(mkAO\]?#a(qb&8An%/a_fhlcNX?*<`sZPrW3.\>p**idC`IVMn<@TTUTC0&#O!^G59c.6JS_T"%t/Y?d;5MI8@qCe$87D8~>endstream
endobj
25 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1731
>>
stream
Gau0D9ip(1&Dcq.B(_Vd&S&r?bEPgq$T'.iDj?;lMaX[a\ZuVkrUk)>`?@M,5jP!]YTc`84.87"Wt;N*6^n$H%e+oO-Q`U*$F<qZY3!Oe'$b)Z5E;ff[%3#)70D-dps@nHgmfH`\3DIYF!:%#aMIJbVNo!iBO`[Eefr;p(pdJfUQGqM91[uf@%en+"X'.X!nfhR$oX;i(gJe``2S8[^5rccK<)?%Mtu,:0`)'\GM;3I7,h@#^GG[b'Xp29L#R*\1W>7<.'sRUA<Y))QboVn?*_,o-V#+1:,U9\onl5!j\Qb,BS?o*8\ATlmdYrC.ggJ)O%RMMTJlIe-@EerZnm(K!pUo*,_+P:#Ee9NZ+C/4CWj*TioG`E`jK"d1#OX*`=6d)#X3&HSUnUI^0JM<0'6<Li#,U3p]ngOMCZXkgos3%0tDadmjSm!MaVWA^o%Zc(!XB2.I#bhDuXm*,\ZT4a8OY)LMF"3WnW9ngAeuX_)4e,AS!4>3Dp'+"Vi\V)&l2VjJ"p1:$7Q&#aiPQ-K]7*<_/U6;dafh<lYQf=>5j]XV9NFO!B`;j/`=[o&]KFY/U&!jdW:+Tu!JcR2YVtdTFIJ[`j!ER"75ZU8m,e(K-?P4Q]'9pKXh>YZ`b8Lb'D#5c&"mfQ%En^k/6^\%H)tPbM&C%;lbZpf/$_<HSMZWShCZjlC%I"\nro\RaFUb3BD,m6.?`-ApsN2@'?Vg^#^ONGOQQCP%Btd(r+6H^JqC,T<QNm5rNZh[VuDLRoUa%R-@rS)G3`AiN!!E"!V59L(IDUF(G3HVeRaJfbmn]/+UY?l8CS!$2l#.14j`]j!aXDh[0=fUf?Y<JX="pEt`+LNqnZL2@@X?DFYD=nK1^:7`B3RgJK=PE*>#kpmFQc,X)ik9<Q-:2'^#s-rH;e=ke[Y<38MpT)iR\I)se*c=*V/5K]u;OsC14bas*Oq0d9[lLj[]>r:ZDL6&)L<^$f'db*N7s4-!naC&X>Zchd<X2aSb>Piu3A5-dp93WEF8!p]H7q_WPO215S0$[Aqq%cc]I=8YA,$lJZ":fIk!4lPfoGB^d=M)l`FV6lhmXDXW92%ERmS/7\q%79?$Ft_HL-D1k2ippIV[,VkekhVqQOE)#dJO=)r4nj>8*#k/S!J@[P+jWiJ-S5VR:^>om$l9m-'cCbOrPt'\8Kp[5>`m(Sm#17DcWnZKleL.Opd2LPtsQ+5OAUBI/AV$&tNk<4D-lK<FUT:;)do?1!JpS!+t.'\:7e$C),C`EICuH"M(u`='o@3([6&EDdsP_QZg(UWE[eB5<<=e82W8)f_cq9uil5JgV[himF!JV:&7[BOi9i6tS]L.,dfJ^9M4`!n)n[(Poa@nDft:HQg.J/k(,0INnS.<c=r%7DY4f,_^cS?6EO('ko+AL\fJMCq!2*;^UsX_VcD2h8ei9(7N.kVZ/>5B_]a9:H+s4krHgG_p$5INn9t6\\XrB(AcS^EER2QY8`fEoKn_G^)!F;;lj4$kp;m,\)OJ[jLR0L0nj2Q6Ga.#B@A$sr*pbD@3-50Int39<unkI6_j?^Ju12R1+k&ZdEO;A5V2bM2]*1\]nGN?i.Y<)j@JHK6*IHWm!)XB8JnjuU0b"F>+OS;`en:93E)(gSHL71dl4F&Z!=`1i]>&??taf9M8Je0XYs<5oB*N:LJ;KO8nA7e'[bP3N8h=J0Ug!pSAA?Ja&/co5G+HTo&>qDmZ]@JrDW@j8,i[Hm*k_~>endstream
endobj
26 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1085
>>
stream
GauHJ9lJN8&A@P9Qt&G![3tr967E1>6jq2?Q`s1-W(BT>"i7BTlm-HA,6elu[G$Ua`h)?P1OcS/:*1's<u&N/,ojZ4+:sjj+=*/T4G2,Eiqn<Fb;4phcq#JHiVt'KGeHB;\Yqec0M4\99%bo0JWG^4SFt8LdmGf91PJR*P<p+gJ5ISc%('C>!\nL?":U2<3-nZ5X8JuKZgr0A^u`tUe$D!":S,Am)_@WXR+$aU0r$+S:R_-k]IN3Lb\nh$R,cJ4g4nY)Bqf.U^f+]WjHTH_4fL.5?WQAGQD"Ggb_FB5k?eQm1JCV!B.&n8hmVVU+@eRtE'`$B,Y]dXHWjF`B#:4(Nj^,PVp`]$B!e>%Am5b&kW_EEPgerrPRu*!oa+LLlAV<Cfe?]L:T$+E:J^HS<<b)J%,Q3P\0h_hpA:8\&GM`^H"pOaN_\m^A_Y]L<GdBRPcWDo,!R:HZ7O__W$4$V5:Z$C]ZWP&lXE!r)_&4D<:'?,kFWr<X_%:+\8TsC:#;.0]bR#lARf^KUq"Pta.Bm/g5!o?3ek$.EV-o>*;d92;Uj<%)EP-T*aI#G'q<`&Y0'c$'j%VSWnY.g3*pf'9;c\dWuA8]DS,UngTG&E[`?d:_\CliIa)(@<n>l>^@'^e<Hm'7G_m;E]Cpg-Y%-Cta"c*1J@+1]pY.prH-j2Ra;>B!Ph0=G]kPs4+/\\USTT7ckm*[tD=YMtUCB__jZ_ASglLlUMG15TC`)$@OT+"k2%1R3(4F2TWuhhSMs\C1VPWP7%bl/8rr1L$W0eRd7*&1[)bP;%X?1ZVgQbe7H_7HWJ1<JYrKf\k&32WUF^DSQ"P?@U%%KhmI&bY(2,PoqV8PEO@S*+'/#!r8Ke=ZP]Jftj`;1(`P"qjl.\g+cVSnq<a*9-e%bC5Lb(KAA`2'tA7Bo6Yh2%Z+bU(f!BFZh^<&`rXkoNJDeW!QC9.&2KB[:=Y<&`t.pE#5?eW"7Ucm@5%W#h[)WZ0>*U.VF)nJo]hkltTph2(>>nt`j:)oE:HWGY,M10o2:p0JLaWG^coXR'p#%=q)nj&ZqQ-e44"UDT@mWZ*i#AWk3UcRgPIquNk-PX>~>endstream
endobj
27 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1004
>>
stream
GauHLgJSqU&:N^lqB;h)9?4SM*YUn=)DJ*Po!6,I:gaTkV"49Efk#.Lg50Fag4Gm/oJq>f3AnJO3$+gl+3afB&)cZH!$Pci%72i[K._6MX`#fR4BFfMP>3'JVg'NHi_rLecdj(p#%oL2^_gF=VJt5B_"id%R,*9IXc*Z,QkmPA!t:<FENm*4#%HUj$!8+jT\[eXUMO1#GB1+8@G(!j\gPD/4W)tk?pA*Y%>A692N3]Tq=S9gce"@sg+Zrd#LCeW^dYIEOtR%p,\H>/<!91P.Yn$CPmiO!WBkjm9BZ0)9b-lR8>KY02dUsB=AG_9\SN1S@s)MobJBm7`F?iUM96!V%V^\1$9W=?j-&o),C3L;?55ZDe/et[+Fh26bJj.TEEVa.Enuj_Ni1rAO^(APjEe$[rZkE#,oIr<6qGGM-b6`\agIqSN&Rpul&G?b\IM1`P>jN_H5VuI39Y[FUr#uj>Wf!)N%$CHP6qP_6Z&%P`cmS=-e42:aeb0c"tB1J,h7m5i_gr!DQHD^T2[`pa^p\$L*=*L;VcRjEiGkG0d=.r;V`JYTaXM8@mP.GUq/k4AWuB`=YHb<lGeM<P-:c&;C'eP?PJh48Tf[@pPO8<mbV$kX<VUu.i/o.I*i+#p6sX[Y1Cs&XXCGk:$s'VgbQkr?,.o:`m7;i)&aqda$05@*]CpE+WO5q*O*Z9JKpVd@*noZ@jGrF1`W7AfWANL,=Xeqk[HNF9W6`q>hJn3!acNr/ai5(l?kDg0HIJg0us"ea]&O!R=5HaYF)N.:7n+\'";9>-,=043oAaEnC"+-Os#p`T/V[]WFp8#KeLIoE)p58G@;nrK?c<k))["p0np57GV[.H[G?;?L[G)H(_aSoQ"%S%kF$Y?YrCMZE6eKHoH[CnIti)h29f2-i-5bbqE7sAfc;&@d]1LWa3>j#SDs#2+2/k_CLL8H"rtQM<A-.WIj7/=O2"[XWpcl)9@[rhd&]"*7U'ru*%!*uW(*6]kN)`Hhc2rge,~>endstream
endobj
28 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2226
>>
stream
Gb!;f>>s99'Ro4HS-Rb>]>7&/]l+$e\(`1(-/6_jjMa([h"m2A*>neS*r2Cs*E&0J%RX`:l'tQ4VP>f@5k'P@s1/6H?j`h#.8U5t>G.FZ_/osLe"_DR'[n8+bs5^7VGmC(Ikg`hiJ>>1;$a`;VJ\X!\o)(T5$T0Ei[c7t<fBA4U8^2[2,H,%9g]-h,uNKOpeEB5"f+h"[O?[_LrZYSO'q2-`#NC&dH0lXm*-K:IY[/l+g\_@lAB:4(8"+UXZ,EOl8a<'M...Q+pc(5e2D8=<q[ZEV!-p3<$<OE<;-*n]4/4KW([;*.96XjinSN-GO0u[`O6\KcPEeK"!c$'/GP1\Bc'RRFi<>F_IqA/\n30$bpMX8/b^,,$H6h@J<'Lk@0FrU[r9Y<"u.]<&`'Z"'gK$Ija?d7q:>/7Dk^r7^B"P6(4U@?T>"CCc9dmu!F2)7^d0Q]:NHiE1-lYP?B]mo'J,si@q`jN:"*%!@CdF&HPD1u^&PH<1:'r6*@,nMV*%nE9<ok?SS4L`LfVMm*m3[Y6SgGq."2_;(PWZm]rUac0TN;#%q3JF$.il*MiaS(<'mI7PpG4$:amNI=^TcPQ\FP"+poKZIemJl)@4CO<,-sV$g]s3q8jnBk"@Z+U(GSnoN.SQQ3--7d6?kQZ4p<jpJ/rqE9TGUlFAU*jt0UlIYF&^F1;W#]Jp7Nm\1g-_6MiEUs$>I1eg!]]%Dk3o"A5raSCni1=EP6-I'CiI>m/-??h6Vqt5?lL[,K.3hoc6qVs3W9$oDS^l=KkDPJ%dS-3=\XL?nni3Mun.`g^PC3G6Q%?*f:LBUcspb`JT]=Tu7\TO=1i9^qY.=)1nJoq+[*q"q6=Ts2/r+3[qPjdK\84fb\l.N9kLh0\V;Q[-G>+1=T^DQtYJ%tI"$KpecOS)l<8bBi1;]$3ebHYN0Pp=s#[^fT><K4<7p%c4"/Z\Ki5Y<K7Gci;Je''j"nZI+S@O@?s;NG#CTN.$jjd8o+<G#o8XPg4SCLCYQfG_hg2kS^.*ZJ@bB][jdc+:mOldgUmo6A[S>73oNLmPFn=U#7r--<dTeHbaboK[h@7Gj&mU-\<S;1Cu[##:'?H;c/-IE4&#keTn'(qss[L#[LD'*Q^QqlMh8;]a4?2dJIn?EWI=_8COB0]%+!NlKkBT0C8$b$g,A[Dps)`t>#Fb!T:>d\S7*6`T2\Us=tG':>bDKMsWEJFgSNm(<KuC<L_p8l+`JJ5%I\\&)tC@-QcR:up!5hZaEl3%oiiDK^=pV_`Z%:,n#!chHCQU\!:i#eVDna#8=6/MU&*<HsSlm<KD#ge@egL9He\(6/]mDQ^aEUT\_c"O\]Z^cBFAfmN5hD;">dc'4SILj&:6eI\7i_Y7:IH?o*aV_m,]oqUXH,]jS<LP3\YT"BG*Y9GO`cMBN&OmdR%)WgW/X"?YN7WGKLj;(gD-h`]OI+NoGOMKPYCUeTrSKPK\[)+('*5R>c6Zk=l<ZZ4EWDFE1'aBGuI2O#gjWoZ)reCp-$PGWaq/q@Oek4+^I@K_COk#rocBiO0)I(XuB]'BJ=bV#d+Vs0.KP*c47MXa-M#As9T/qa+:Ju'4P=?@.??QpeSk2E@AMSi@GCFZ*:NGkfR!RcgIMtWOdX49WcdKGTAWE%Mm"F&q=t["!BXQa9)k*=@Pfb"Y1hET:V!'kEbr2asiTYe9)6*%lD_e<<0#pQ2eWF]H(r-M,F^Q+L@<0QO(Eka%Sp;YQ)o5?uo[8(>]5r.cISs.::dWmk-A>a,ftE_[9Ks;ZOI+m""b50i>uDC8Z%]14^X89dS7ZR\N3:1L5DT9O#W^)84c?/4?AR6cV<mcNSDHZc>1668^WsjZ^L)`VAUVbErUmP02A`nO`EdnWd_=,302"PJr]6p6DN;0+H3RN32rfML`M_P1E^<],F&j^R`l^41H_%nM/bF(;Fb=#'hPd<:NJl,'F:7?WW4J79TnY.SF;]@JZ'4j5B8]1u3H!#AjPhq19-mYu4h2;dkN?e+l8fTbs.Nk'cb<X[m[[lIF%-b[!CE\j^jRlk/XL$2f)_%!nL$W#$Vo.IM>rX2)I'oZc,kuYHjuOt%d:N`!.J49+TidspOUfm9rtS#B!!FNDO8W<B-/cQEC2[U%1E8aI[!0i5-l<4i+!sZkAD5],d>aW`6PVHa7h6mQjcDTe(+k@2:/G&CU7%LYu/Y!l<.k)_pu&G;(Nl9IN,[S7KcAS<P7[tG`e=N3;O0T-g)Z~>endstream
endobj
29 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2442
>>
stream
Gb!#]>BAQ-&q9SYfVabbZ"X9PVfNnqfh'[sZ"*%ZiJ_D10Ek$]GYq&RXulUPB)u=,aV#gYFJe(i#d/^6`U8N;`KGb.Imj;Y`W-fb3."GO:`)uZfS0jqCUb9)rHVpu^1d`b%-lLU_2!?3E;/=I_UD?`NX_T?64An7lVRe[UQV1O\-7Uk1,EaiTn*Z-9o.sn?m$iVG`^2"!`H%o)<sXFoS,I9fd)8enW7b#mgZJ'#PZ9Z0`D0o5:`>MKu>].\$<H8-;uYXM%hLU/272^n4ck,0M13^Q@(hl>;D^`:R5HfCe>5QG?6W*%#`h)IDa[Zh6In'J&b;40`o*Eq0\<]#cL>N`e)P#SVGNsLS.CNXF*K"lIZ-;@L"6kc7XL!)C7?^)*>A,;ecBfFS[d3`&0\b)8pNCf>=Fl<_g-Il1cg,,>@U1f\Y;.$Nc;*=sKomaT^9LoP(HN2=`<+[1*>RgH!IQg*W<D,Ske;e$4^S,a-u2WTb;(;YN-L%-O;uO$X2FDt#^Yg<*6f`DF!M3Ng.-3mb8tKI4Njl0cuR]JLX2n)4."MI7iE)3Z7=>)eBK6,>3KnWJo)*i:1TFt7:AK-?<)lku[7#3Rd)UQq:]H\s=l1)<>!c3J=1,^X34U,PUghe-^1poRb9dXT5cJ*[aYoV%-73P^3'"cDFlRb=L(Rc%3L2;`he:q`5Bd9U*`r3XInD&/g_5uiQ++Z7flfCWP)d)`A7fM*E!ahh=r@FcF@+$OVqeQ#4E7@;c$42+dMT/@J<3YiC":t4_QVF&1<&7NedO:1)*NUh;Ib;q`LV*2?Q&)^AIqKraIbMP!&r5p)6$/@_fH(*M1CIh/22%WiJ:8#AGAK%a#OGB6+aBVNd_`<c\%Bu3O(*]0;BK6EKd"!*n'2u[aOU0W-`:&a_.^2rE"_oam)TITj00GIIA&MLccF#X/i"!$3s%+eB$2_LOY/EG;jH"QZ-ph6Zipd,C9Md=.Q'9_+/h_sShnNFha#A3]epRA.s7(L+$#ZrmcqLj+"Ui)>oZ]A'mRMJV*tNMSAbq(J2o_sN(0Sesq+F6WO(Tn8Wd/o_P9l,^T/%R8_c[?o--p`VGGV_gCknkOXKpi7J]k.s4k4:FS`kDZMpglAJifPWdNfV>,1:HQ6.&J(LFbaO:=dRO(OFe$XcKKS<!_2`@9$`e:ob!4T/X)?opu&e4uLT;dQVX]S50ZbmiOIDhOM<0'gd<Fi4NCYo]P$F!u?Wp@9`pZT'^')+k,$s/q_Lggp0U#0*LWKMr:SuTGT-;o2p];\BWGlOlOj*nC;F':.4!IgU7b5rS;*+K;?1,IVLd[lC(j[q!9eqeqcT$NEDo+#=$$QAC3>QB`A&OFs<^3L9q<pK4LFU>\;/U/hq+r1)\BPBtnO2\(e)")7t<Mp+s=ri"1r#(,#jdc6Jq&Dd(Kb!U/i;7N;4%/rY"*`R]'\L:cJSqT-#:>iNNcSs8%l&^^fo:*T"[LW`B1^&-[EI!>^b7NYe`.V615O>PfVB64b_#>(lK>uc=,ddKH-rI@$#k%UQR38./L#r`7)K8@:sgBu)>D]H?Rft,j:)qqk_Vg.ku;g1<G&_=Fud;lK_1YE8L\&[8Cfl$gjOh,6A4Vp!0h;0TL7B8Gn^//ksnLLUXePs#T\dbZF;sadSel:@rep<L6Zs$R!<\:<pW>=!F6W`PSI3j[64fRUZ:R:0ZWd7^q/ZgAbD84Ou2lQ2XHSs]#8`=8b2"+HE5lh;kZb"<>4lmbF8'6)oVTVB5K$m.]+"&TaaX?jI^iq=[dk'XF[X12\[^XAW)0F>g\.e[>e:&`bflEQMM'N?fm5T@AILQNKgk0M>DY]j>U5.Xq:%R<?ZEiBUritK$oMo]t*)!ur`W>T<f7+P(To``l/OSoT\T\S^cp4+<n^0*f9[mFAOW7j(%/d;jj8$4Lf,('b"!Dm+P40>5bcYumn[J[Vhfa;(+0UT)s)IPej"&AW]!<9EI_i)`KLoKP[Bp`4#s$UckXCe4n/@5YAFV<t5lP#/XBP6I&4r7/eT_kYgA2,eUFef`F^Pp;Y4YeJpM1AXD*!5@5#J-V_I1NS^2VEN@eEm%=+#mr$Ci4OR#&Db(;6[7^Cq>?rE#Yd'/fUubJa#jnc]QOEadG&"ZD6:ejKa*E(j%I?.*-f\D@&6k\YIP--Kn*W\ugob9k!;2DM@=s%Ou[>;c9'a?b`!6m:\?pW#>m,cS_!!t4:D5H==]#q=K(Q@g'qZ7oiM:h?eX0h':rS2n6n*;k$USZ(hhD5X7>#.F!ZDbn_!cT+H)QDou;Pt0/F2GXo[+jY5>Hqme6?=#mm*A)O8$RAt@V&>R?j)OT,D"Tg1e-omq&#l'<E.L[E0uLOQPY2bm:F;tp4iKq5E*JX`^Woj`7TmJ=GGD0E;4:MXk.LA54K-m9DTaD0F=o.Z3%."j3lEH3gg[XR6O?V-dj8rfXF;\b>r_[F\@_ne~>endstream
endobj
30 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2396
>>
stream
Gb!#]968iI'#+6EoP)L:)GpY4Y!"eR1ZO<44-k*QiX8.@1<+\i+DHo1f5Ca6-'<NK&QZ36Z3>eEUHa.^NGai.N?=np`u2\53uEGk5UbF4J@LmQGF*8tGP(:D$:<L(-s/<F4b@&+(PUW$N[R"3jl!Z\GWoZrH(f,P0KEmdKh>NZq2I)OFZ^SQ@(Cpn^'>EG,$k7iXsT6",qVqhb2E&PbEsRZ>`,NAE.<7XIX,r5i<.m6%<oQ8R@=kHB*J:SjO5<FM1k&W@-PZF/$bqs7PuBZ6p<pEF[JI#]G?^+KG[Osq7W_?jB)n7JVI4(Q+LIG%ac=CPZUem1&,9&71.PArl0VpaNhf&q*aH]B8SJX:sY+t'fWF\3nJ>*)Wb]jn\ITj,AI<ulKf>B&`4'b[3M7bq@7u?H-Q,_)=GjQ%EDo5iFl9e1#"G^j?TMXN34_5`S^j'D$+0e$<`dsU\:E0iV6H<O.B"ug_SteU@/^ViD3^9C:RD&-%Y05mui)F.PYS$..WsO>L.)/MB(7t>e+:s(`P6u])gV@_(XR#dXud6&^gi.p),V?QWb3`ZWSG%\>M06\B#>WHIna0bl:g:?C'5H_TC%+,[r[lP34PQHT5tSW8jR[3"?k$#H^/'C]fEr^jR._B,A(Yo<XAT>eP36)g7"ik)Zo@'4B:pOt>0gS['Q.OOR1hF1<Yors]iM^tCJU=`O-I2Ku_^<Wl["?GMn:o(<Xj[oto!'LQ)SlSjgAnV>KjN)^:djao!'(J<XH>Egi'eMHA=$U.lGcgh3>Re@2C@),&!ZCK9a#Y#BjKcrq)f,BB:#;D+[lbC0[.L+;[@o5BS=YCQ5kPgiRIi7A3L/2&mF_M8Y238&DEZbUSI\X[E-Meo.ANVL(&n2V@E"I<6gXu!HWeYFQ*11#@s$*_LL__I95mhZqjNEPMPSd3FV$XCDHq,WW121BrM`fg<k59d[J%m1K0rKAq:LM^NBhNN%B?e?&bLSgRgS&4IgJcWU]BP<dPKflJ$Ct&4,=nj&2pJa08r229rN'^OWogpQ/8V\AQqj#4Ci%8'=5p!HFF,UPH1\N534P1nR&m:=n+i":`pi6%B0GBWBF.WcLrY#81``..pd%kAY':#3\<&gb1>2-B\@f:S?DZ>t!;7f"/Kod.%3]*Uae;@u=!i^$r*,?%n86)!rp[BBL[LWfXW*D"9^^6c2#6SPX@_2#2fs.$H\^C6<H\=8IskK;2CiYuA;7:"n$d"rqSop8IGnOP>%EOj0MM"CfY_ZaN/a!?YJBt*<76j^KOWt;IRd1to^oPH)ci:$TS-Mj(KncL7*"roe*.B/k:K1.V]n!WhXV;Kr+/@r+W0mmiP9gNU"3$"diF%d)_SBjbEPq?%kXguQun*kdN*Z:1HC+l5E/5q`1C9g\B4SL$Kna`Lm;<g\8fl3%^L+7-MG5s%\_M#F3F[YoLrY@0;c/"nP7Q-hOi[_DE5M$WfZH9Gjmcb'lH$^>$o8shcI_B[_>S?rAB?Z@FepHMj;PTlB8=7[F`*#gDR0kr3jpYpUP.5]C&lP\6=U?=D@!L9l%F+%>(HP0s1/kNbZKYcH^1C$"&h/GBe,^lk8W'780Y:\LSFKpe5nb[h_9>N8#6RZ-Bl`j4J842]Aj^YFN5r"Is.an??A^+%o_/X.qoDJsj#8</m`,^^-S_Ws&$^H&b8]9N3rb:f^\>*sC^%59?'#$dY3]eTK1+(Vfodma)dPH"*aDRL@bq/ohG_I/.$g"B(A=b)l6Gj@+bHn=WSk&&P*hO,%r!B1hd%>>TO6'q[-:*t)3s[CPg4@%K,Or7iC7Z7*nYjE&j)3>NI:7bN'jZ]0mi+-5_`6Onm/9iGpH5m35Hq>Q",J^dt-!u!00Z@`_Th;59j%COPhoeHiO(hD./N)E9C\uiCIYW:E@=i%LV1$ZGp#OtBkN2)Lu)UD$5\?lT+f#$?!k4uM<dTW-s\;8+;b)sAk^:fPP3BdRD`OMH]SUiCm^@6V%QrO!f)c/TR"U`BsdE8T"j(rL5:1HJCdW]0nC^otR=Zd"5gTR`Yi]6/p`e!b>io`NR3jNJ":74e6'#nmb9i6%-QhntbaEC)IJP0JM(IgKc+b;Q\2S+n81hBS/Q>iG$&rd-I,T&*Gjmjm7F/G]m"uYF9k4Q`k6Zld\nN%oK01rgcHuCrMNspZmfuCX](`4JY;+&#4Oo/FCScg6u0p\/NMTm:,4D@U$pRu]NDNlsp#,SrP@M95M/6ErKL2j"e\/$O:2:/Xh0i!rE98ki.0E^PH9qg4JfmX.[76u*P'4O&@T_#V>9ecB6C1Qb#o>bqZjYDluq*e1?2t\)Ep;/Ohf!/WY%VuCK1"q$q"M:ee\)3_X&q*;q3d`hDG(g61n_](g8K7#)F\)GaSfPD,JW"n&d=Gl2Z`bDu3;O^](?=K~>endstream
endobj
31 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 454
>>
stream
GatU.bAP3?&A7ljk*Yd+!J>r5)^SL[7"+luMebDR>K:VQXK#8b^-EYq&+rmFfO`%Gc2\:&%2RNB%:#g@S1lXWF9s:M5WZeBNSYnS1lVqLiCZZ'K&:Q1gdE,(;$/8?A:c\7e01m_)"i")ZPequA44A!)Z_-";i(Ws9M?qgPm=O";BQC@2$W[#k#p)@<^#+KMnsd'RkBF_Ub>7l4QdlL8YV@Mn>L2i<Db[/.]X(&`)*5.P@5jqM6j!Fi[kbQpCqt;SZ._Mf+g6'\5a1_UtoU_&rcfuKJR)EpcX&uAuci?o&KdimiH,&81:93KY+]UX7O'nX*u&SEg->@Q]i8<H=rCe@tXD6CL6PaG"4,[af0CVE8FQ-[B$q>PIS6$)FV00HrO>XF!a9B<&fSOpk(W+(hL-n2jfq+d=,[%`i[MV]#:Ob])pGnBsZ(8G58SQjbZf%5G78;DZ~>endstream
endobj
32 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 772
>>
stream
GatU/?#LB2&:Dg-fJc\B\``k(8#TT>C.4ijfGE_`QPf/W@/GiPmo__D8Q(+m:aFe8G%PC,)\*1&G[.imi-c!"2]R&LD%AaA3OF!Lh9LJn=B-_OP6+CX]\p/ND^g)40MCBf9LFq0<Ko1(;:P+m^uK6,<sQ0gQ$Y9PB1:P8^iI`$Z2d?f]VrWK!eB_c7D]<K@=F9G'@O[e>$?TWq>L!BmF0#X[,7O))`Wn0]O4`b"MQY&<t_oB@Q8tD->DauA2FU29!VF:6a4LdK;U8^lqGCYs11fAc=j=_*MkoT'a!QJ0TpJ-eG8RuG8mRe8<^DC!dp]^3?ZHI$>NDc>J@\pX5,p%-/U.]Ubf3q32\>Wc]fafe%<97W+3'#7]5iJd3F#QG%iKiHJrk>A5DifGKsMULJd%"kqBrM,As:`b\.N$^Z*Fpm%9go4"E/@a_nDZQ$/.kZ.PaLH3MHBdN5ea$/U3#r1GmpDIJ5;XVe"haJnbR'qr8qR_c*j!VVb8d^5#Yr!o4<DN$pf7M"7m+f;fs&k9,0D*0A3&=oLU952PaAO,H2F@LU-3e(fUM?VgrU[fT#TMjdBT$bQ(C5J6gHpKV&(LZT&^OFU.Y8EM]/g.NFCGQFjTYM0Noq"(;=_XW,*[2d#h-.=-Ph7ET%$!W0:#[r=AeS]+!Z6WdNa@]EHYSaV[L358O!8obI^1+.$R_s1dWJSBpE=u4k6&G<LWj&JMpuG:`ro_,UJTZqTH$La1BYA`Q&;Lo4oi"H;8LdHip^bso*Vg24"af"~>endstream
endobj
xref
0 33
0000000000 65535 f
0000000061 00000 n
0000000144 00000 n
0000000251 00000 n
0000000366 00000 n
0000000478 00000 n
0000000673 00000 n
0000000750 00000 n
0000000945 00000 n
0000001140 00000 n
0000001335 00000 n
0000001531 00000 n
0000001727 00000 n
0000001847 00000 n
0000002043 00000 n
0000002239 00000 n
0000002323 00000 n
0000002519 00000 n
0000002715 00000 n
0000002911 00000 n
0000002981 00000 n
0000003315 00000 n
0000003446 00000 n
0000004126 00000 n
0000006084 00000 n
0000008926 00000 n
0000010749 00000 n
0000011926 00000 n
0000013022 00000 n
0000015340 00000 n
0000017874 00000 n
0000020362 00000 n
0000020907 00000 n
trailer
<<
/ID
[<1a6aa1302ad6ba2dca92b79c88f91ea9><1a6aa1302ad6ba2dca92b79c88f91ea9>]
% ReportLab generated PDF document -- digest (opensource)
/Info 20 0 R
/Root 19 0 R
/Size 33
>>
startxref
21770
%%EOF

View File

@@ -0,0 +1,175 @@
{
"summary": {
"total_artefacts": 18,
"mentioned": 3,
"likely_relevant": 1,
"possibly_relevant": 5,
"not_covered": 9,
"skill_auto_generate": 5,
"skill_assist": 3
},
"artefacts": [
{
"id": "DEF-01",
"name": "Customer Profile",
"phase": "define",
"step": "ideate",
"skill_support": "assist",
"customer_facing": false,
"relevance": "mentioned"
},
{
"id": "DEF-02",
"name": "Strategy Map",
"phase": "define",
"step": "ideate",
"skill_support": "assist",
"customer_facing": false,
"relevance": "mentioned"
},
{
"id": "DEF-03",
"name": "Point of View (PoV)",
"phase": "define",
"step": "ideate",
"skill_support": "auto_generate",
"customer_facing": false,
"relevance": "possibly_relevant"
},
{
"id": "DEF-04",
"name": "Ideation Workshop",
"phase": "define",
"step": "ideate",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DEF-05",
"name": "Business Case",
"phase": "define",
"step": "ideate",
"skill_support": "auto_generate",
"customer_facing": true,
"relevance": "mentioned"
},
{
"id": "DEF-06",
"name": "Value Story",
"phase": "define",
"step": "ideate",
"skill_support": "auto_generate",
"customer_facing": true,
"relevance": "possibly_relevant"
},
{
"id": "DEF-07",
"name": "Value Story Delivery",
"phase": "define",
"step": "validate",
"skill_support": "assist",
"customer_facing": true,
"relevance": "possibly_relevant"
},
{
"id": "DEF-08",
"name": "Joint Engagement Plan (JEP)",
"phase": "define",
"step": "plan",
"skill_support": "auto_generate",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DES-35",
"name": "Solution Proposal",
"phase": "design",
"step": "confirm",
"skill_support": "auto_generate",
"customer_facing": true,
"relevance": "possibly_relevant"
},
{
"id": "DES-36",
"name": "Partner / Services Proposal",
"phase": "design",
"step": "confirm",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DES-37",
"name": "RFx Response",
"phase": "design",
"step": "confirm",
"skill_support": "reference",
"customer_facing": true,
"relevance": "possibly_relevant"
},
{
"id": "DES-38",
"name": "Commercial Agreement",
"phase": "design",
"step": "confirm",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DEL-17",
"name": "Cloud Operating Framework",
"phase": "deliver",
"step": "operate",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DEL-18",
"name": "OCI Operationalization Framework",
"phase": "deliver",
"step": "operate",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DEL-19",
"name": "Retrospective",
"phase": "deliver",
"step": "improve",
"skill_support": "auto_generate",
"customer_facing": false,
"relevance": "none"
},
{
"id": "DEL-20",
"name": "Value Realization",
"phase": "deliver",
"step": "improve",
"skill_support": "auto_generate",
"customer_facing": true,
"relevance": "likely_relevant"
},
{
"id": "DEL-21",
"name": "Customer Success Story",
"phase": "deliver",
"step": "improve",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
},
{
"id": "DEL-22",
"name": "Improvement Actions",
"phase": "deliver",
"step": "improve",
"skill_support": "reference",
"customer_facing": true,
"relevance": "none"
}
]
}

View File

@@ -0,0 +1,125 @@
[
{
"id": "FF-202603-008",
"date": "2026-03-14",
"contributor": {
"name": "Diego Cabrera",
"team": "Field Architecture",
"client": "Vector Search Customer",
"context": "AI Vector Search engagement",
"confidence": "validated"
},
"product": "ADB-S",
"version": "23ai",
"severity": "HIGH",
"category": "limitation",
"summary": "Distributed HNSW indexes not available \u2014 100M+ vector search requires partitioning workaround",
"detail": "ADB-S AI Vector Search supports HNSW indexes but they are node-local on\nmulti-node RAC (\u226564 ECPUs). At 100M+ vectors, queries on a 2-node RAC\nmiss vectors on the other node. Results are either incomplete or require\ncross-node scan that blows P95 >200ms.\n\nWorkaround from internal DB PM team: hash-partition vector table on\nvector_id, create partition-local HNSW index. Queries hit single\npartition on single node, maintaining <50ms at 100M scale.\n\nRequires table redesign \u2014 cannot be applied to existing unpartitioned\nvector tables without data reload.\n",
"workaround": "Hash-partition vector table by vector_id. Create HNSW index as LOCAL\n(partition-level). Ensure partition pruning in queries.\nSource: internal DB PM team contact [name].\nValidated on ADB-S 23ai with 120M vectors, P95 = 38ms on 64 ECPU.\n",
"oracle_sr": "",
"status": "acknowledged",
"resolved_date": null,
"resolution": null,
"affects_matrix": "AI Vector Search (HNSW)",
"tags": [
"vector-search",
"hnsw",
"distributed",
"rac",
"partitioning",
"100m",
"latency",
"ai-vector-search"
]
},
{
"id": "FF-202603-002",
"date": "2026-03-08",
"contributor": {
"name": "Diego Cabrera",
"team": "Field Architecture",
"client": "Strategic Migration Customer",
"context": "Production migration",
"confidence": "validated"
},
"product": "ADB-S Dedicated Elastic Pool (DEP)",
"version": "23ai",
"severity": "HIGH",
"category": "limitation",
"summary": "ADG must be disabled before joining Dedicated Elastic Pool",
"detail": "When attempting to add an ADB-S instance with active Autonomous Data Guard\nto a Dedicated Elastic Pool, the operation fails. ADG must be explicitly\ndisabled before the instance can join the DEP. This is a known issue\nacknowledged by Oracle but not prominently documented.\n\nImpact: requires a brief HA gap during DEP onboarding. Must coordinate\nwith the customer's change window.\n",
"workaround": "Disable ADG \u2192 join DEP \u2192 re-enable ADG. Plan for ~15 min HA gap.",
"oracle_sr": "",
"status": "acknowledged",
"resolved_date": null,
"resolution": null,
"affects_matrix": "Elastic Pool Membership",
"tags": [
"dep",
"adg",
"elastic-pool",
"ha",
"limitation"
]
},
{
"id": "FF-202603-004",
"date": "2026-03-01",
"contributor": {
"name": "Diego Cabrera",
"team": "Field Architecture",
"client": "Strategic Migration Customer",
"context": "Production migration",
"confidence": "validated"
},
"product": "ADB-S",
"version": "23ai",
"severity": "MEDIUM",
"category": "gotcha",
"summary": "DEP provisioning takes days to weeks depending on capacity",
"detail": "Dedicated Elastic Pool provisioning is NOT instant like ADB-S Serverless.\nIt requires physical Exadata infrastructure allocation. Lead time varies\nfrom 3 days (if capacity available in region) to 2-3 weeks (if capacity\nneeds to be provisioned).\n\nBilling starts only at AVAILABLE state, not at request time.\nCo-location of existing ADB-S instances happens at the next maintenance\nwindow after joining, not immediately.\n",
"workaround": "Request DEP early in the project timeline. Don't make it a critical-path dependency in week 1.",
"oracle_sr": "",
"status": "acknowledged",
"resolved_date": null,
"resolution": null,
"affects_matrix": "Elastic Pool Membership",
"tags": [
"dep",
"provisioning",
"lead-time",
"capacity",
"planning"
]
},
{
"id": "FF-202603-007",
"date": "2026-02-10",
"contributor": {
"name": "Diego Cabrera",
"team": "Field Architecture",
"client": "Pepe SRL",
"context": "Discovery engagement",
"confidence": "validated"
},
"product": "ADB-S",
"version": "23ai",
"severity": "INFO",
"category": "gotcha",
"summary": "ADB-S Serverless RAC node split threshold at 64 ECPUs",
"detail": "ADB-S Serverless runs on 1 RAC node at \u226424 ECPUs and splits to 2 nodes\nat 64 ECPUs (16 cpu_count each). The gv$instance view only shows nodes\nwhere the PDB is open.\n\nThis affects connection pooling behavior and session distribution.\nApplications should use UCP or JDBC connection pool with FAN events\nto handle the multi-node scenario properly.\n",
"workaround": "Ensure connection pool configuration handles multi-node. Use UCP with FAN.",
"oracle_sr": "",
"status": "acknowledged",
"resolved_date": null,
"resolution": null,
"affects_matrix": null,
"tags": [
"adb-s",
"rac",
"ecpu",
"node-split",
"connection-pooling"
]
}
]

View File

@@ -0,0 +1,26 @@
{
"total": 8,
"by_severity": {
"HIGH": 2,
"MEDIUM": 4,
"LOW": 1,
"INFO": 1
},
"by_product": {
"ADB-S": 4,
"OCI CLI": 1,
"ADB-S Dedicated Elastic Pool (DEP)": 2,
"OCI DMS": 1
},
"by_status": {
"acknowledged": 5,
"open": 2,
"monitoring": 1
},
"by_category": {
"limitation": 3,
"bug": 1,
"undocumented": 1,
"gotcha": 3
}
}

View File

@@ -0,0 +1,206 @@
[
{
"file": "kb/architecture-center/catalog.yaml",
"matches": [
{
"line": 25,
"text": "- title: \"Deploy Oracle Autonomous Database on Oracle Database@Azure\""
},
{
"line": 267,
"text": "- title: \"Deploy Oracle Autonomous Database on Oracle Database@Google Cloud\""
},
{
"line": 427,
"text": "- title: \"Migrate on-premises Oracle Database to Autonomous Database\""
},
{
"line": 463,
"text": "- title: \"Migrate a PeopleSoft database to Oracle Autonomous Database\""
},
{
"line": 623,
"text": "- title: \"Move Oracle Forms applications to Oracle APEX on an Oracle Autonomous "
},
{
"line": 635,
"text": "- title: \"Stream Kafka topics to Oracle Autonomous Database using Oracle Integra"
},
{
"line": 795,
"text": "- title: \"Implement Oracle Data Safe for Exadata and Autonomous Databases\""
},
{
"line": 1140,
"text": "- title: \"Deploy a microservices-based application in Kubernetes connected to an"
},
{
"line": 1226,
"text": "- title: \"Deploy JD Edwards EnterpriseOne with Oracle Autonomous Database on Ded"
},
{
"line": 1262,
"text": "- title: \"Run PeopleSoft ERP and Autonomous Database in an HA multicloud deploym"
}
]
},
{
"file": "kb/competitive/aws-mapping.yaml",
"matches": [
{
"line": 32,
"text": "- \"Autonomous Database \u2014 no equivalent in AWS\""
},
{
"line": 81,
"text": "- \"Data Safe included free for Autonomous Database\""
}
]
},
{
"file": "kb/competitive/common-objections.yaml",
"matches": [
{
"line": 12,
"text": "- Only cloud with Autonomous Database"
}
]
},
{
"file": "kb/patterns/database-ha-adb-s.yaml",
"matches": [
{
"line": 2,
"text": "# Composable architecture block for Autonomous Database Serverless HA"
},
{
"line": 10,
"text": "Autonomous Database Serverless (ADB-S) provides built-in high availability throu"
}
]
},
{
"file": "kb/pricing/oci-sku-catalog.yaml",
"matches": [
{
"line": 462,
"text": "display_name: Oracle Cloud Infrastructure - Autonomous Database & Exadata"
},
{
"line": 465,
"text": "product: Oracle Autonomous Database (ATP or ADW) - ECPU (2 ECPU minimum)"
},
{
"line": 471,
"text": "product: Oracle Autonomous Database (ATP or ADW) - BYOL ECPU (2 ECPU minimum)"
},
{
"line": 477,
"text": "product: Oracle Autonomous Database Storage for Transaction Processing (ATP), us"
},
{
"line": 483,
"text": "product: Oracle Autonomous Database Storage for Data Warehouse (ADW), using ECPU"
},
{
"line": 489,
"text": "product: Oracle Autonomous Database Backup Storage (ATP or ADW), using ECPU"
}
]
},
{
"file": "kb/services/adb-dedicated.yaml",
"matches": [
{
"line": 3,
"text": "service: Autonomous Database Dedicated (ADB-D)"
},
{
"line": 8,
"text": "what: Autonomous Database on dedicated Exadata infrastructure. Provides isolatio"
}
]
},
{
"file": "kb/services/adb-elastic-pool.yaml",
"matches": [
{
"line": 3,
"text": "service: Autonomous Database Serverless Elastic Pool"
}
]
},
{
"file": "kb/services/adb-serverless.yaml",
"matches": [
{
"line": 1,
"text": "# OCI Service: Autonomous Database Serverless (ADB-S)"
},
{
"line": 5,
"text": "name: \"Autonomous Database Serverless (ADB-S)\""
},
{
"line": 38,
"text": "name: \"Autonomous Database Serverless (ADB-S)\""
},
{
"line": 47,
"text": "name: \"Autonomous Database on Dedicated Exadata (ADB-D)\""
}
]
},
{
"file": "kb/services/database-at-aws.yaml",
"matches": [
{
"line": 32,
"text": "notes: \"Autonomous Database on dedicated Exadata \u2014 NOT serverless\""
},
{
"line": 37,
"text": "- name: \"Autonomous Database Serverless (ADB-S)\""
}
]
},
{
"file": "kb/services/exadata-cloud.yaml",
"matches": [
{
"line": 20,
"text": "- \"Small workloads under 16 OCPUs \u2014 use Autonomous Database Serverless (ADB-S) o"
}
]
},
{
"file": "kb/services/oci-networking-core.yaml",
"matches": [
{
"line": 46,
"text": "description: \"Private pathway from a VCN to supported OCI services (e.g., Object"
},
{
"line": 84,
"text": "description: \"Resources in private subnets cannot reach OCI services (Object Sto"
}
]
},
{
"file": "kb/well-architected/security-compliance.yaml",
"matches": [
{
"line": 148,
"text": "description: \"Private endpoints for Autonomous Database\""
},
{
"line": 150,
"text": "pass_if: \"Autonomous Database configured with private endpoints\""
},
{
"line": 151,
"text": "gap_if: \"Autonomous Database using public endpoints\""
}
]
}
]

View File

@@ -0,0 +1,50 @@
[
{
"feature": "Auto Indexing",
"category": "auto_management",
"compatibility": [
{
"deployment": "ADB-S Serverless",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "Creates indexes HIDDEN by default. Instantly reversible. DML costing prevents over-indexing. Deduplication with manually created indexes."
},
{
"deployment": "ADB-S Serverless",
"version": "26ai",
"status": "GA",
"notes": "Improved in 26ai \u2014 better cost model, fewer false positives."
},
{
"deployment": "ADB-S Elastic Pool",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "Same as ADB-S Serverless."
},
{
"deployment": "ADB Dedicated Elastic Pool (DEP)",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "Available but less tested in DEP."
},
{
"deployment": "ADB on Dedicated Exadata",
"version": "23ai",
"status": "GA",
"notes": "Fully supported."
},
{
"deployment": "Exadata Cloud Service",
"version": "23ai",
"status": "NOT_AVAIL",
"notes": "Not an ADB feature. Use manual indexing."
},
{
"deployment": "Base DB Service (EE)",
"version": "23ai",
"status": "NOT_AVAIL",
"notes": ""
}
]
}
]

View File

@@ -0,0 +1,86 @@
[
{
"feature": "AI Vector Search (HNSW)",
"category": "developer",
"compatibility": [
{
"deployment": "ADB-S Serverless",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "HNSW indexes are node-local on multi-node RAC. Works well up to\n~50M vectors on single node (\u226424 ECPUs). At 100M+ on multi-node\n(\u226564 ECPUs), requires hash-partitioned vector table with LOCAL\nHNSW index for <50ms P95. See FF-202603-008.\n"
},
{
"deployment": "ADB-S Serverless",
"version": "26ai",
"status": "UNTESTED",
"notes": "Check if distributed HNSW is added in 26ai. Expected to remain node-local."
},
{
"deployment": "ADB-S Elastic Pool",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "Same node-local limitation as ADB-S Serverless."
},
{
"deployment": "ADB on Dedicated Exadata",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "Same limitation. Dedicated infra doesn't change HNSW locality."
},
{
"deployment": "Exadata Cloud Service",
"version": "23ai",
"status": "GA_CAVEAT",
"notes": "RAC with HNSW has same node-local constraint. Partitioning workaround applies."
},
{
"deployment": "Base DB Service (EE)",
"version": "23ai",
"status": "NOT_AVAIL",
"notes": "AI Vector Search requires 23ai. Available in EE but HNSW performance limited without Exadata storage."
}
]
},
{
"feature": "AI Vector Search (IVF)",
"category": "developer",
"compatibility": [
{
"deployment": "ADB-S Serverless",
"version": "23ai",
"status": "GA",
"notes": "IVF (Inverted File) indexes ARE distributed across RAC nodes.\nWorks at 100M+ scale without partitioning. However, IVF has\nlower recall than HNSW at same latency budget. Trade-off:\nIVF for scale without redesign, HNSW+partitioning for best recall.\n"
},
{
"deployment": "ADB-S Serverless",
"version": "26ai",
"status": "UNTESTED",
"notes": ""
},
{
"deployment": "ADB-S Elastic Pool",
"version": "23ai",
"status": "GA",
"notes": "Same as ADB-S Serverless."
},
{
"deployment": "ADB on Dedicated Exadata",
"version": "23ai",
"status": "GA",
"notes": ""
},
{
"deployment": "Exadata Cloud Service",
"version": "23ai",
"status": "GA",
"notes": "IVF distributed across RAC nodes. Exadata storage accelerates scans."
},
{
"deployment": "Base DB Service (EE)",
"version": "23ai",
"status": "NOT_AVAIL",
"notes": "AI Vector Search requires 23ai. Available in EE but performance limited without Exadata."
}
]
}
]

View File

@@ -0,0 +1,46 @@
{
"query": "ADB-S vs AWS Aurora / Azure SQL",
"aws_database_mappings": [],
"azure_database_mappings": [
{
"oci": "ADB-S",
"azure": "Azure SQL Managed Instance / Azure Database for PostgreSQL",
"oci_advantage": "ADB-S runs actual Oracle Database. Azure SQL MI is SQL Server only.\nNo native Oracle database service on Azure.\nOracle on Azure VMs loses Exadata performance and autonomous operations.\n",
"azure_advantage": "Native SQL Server support if migrating from SQL Server."
},
{
"oci": "ExaCS",
"azure": "Oracle Database@Azure (ExaCS in Azure datacenters)",
"notes": "Oracle Database@Azure is ExaCS running in Azure datacenters with\ndirect connectivity to Azure services. Available in select regions.\nThis is a partnership offering, not a competitive comparison.\n"
}
],
"common_objections": [
{
"id": "OBJ-001",
"category": "market",
"objection": "OCI is a niche cloud \u2014 AWS/Azure are the leaders",
"response": "OCI is the #4 cloud globally and growing fastest in database PaaS.\nFor Oracle database workloads specifically, OCI is the leader:\n- Only cloud with Exadata hardware\n- Only cloud with Autonomous Database\n- Best Oracle license portability\nThe question isn't \"best cloud overall\" but \"best cloud for this workload.\"\n",
"evidence": "Gartner, IDC reports on cloud database market"
},
{
"id": "OBJ-002",
"category": "risk",
"objection": "What if Oracle EOLs or changes OCI pricing?",
"response": "OCI pricing has only decreased since launch. Oracle's cloud investment\nis $50B+ in CapEx. OCI is Oracle's strategic platform \u2014 not a side project.\nContractual pricing protection exists via Annual Flex and Universal Credits.\n",
"mitigation": "Use annual flex contracts with pricing guarantees"
},
{
"id": "OBJ-003",
"category": "skills",
"objection": "Our team has no OCI experience",
"response": "ADB-S reduces DBA workload by 80% (no patching, tuning, scaling).\nOCI console follows familiar cloud patterns. Terraform provider is mature.\nOracle provides free training and certification. Typical ramp-up is 2-4 weeks.\n",
"mitigation": "Include training budget in migration plan"
},
{
"id": "OBJ-004",
"category": "features",
"objection": "OCI doesn't have as many services as AWS",
"response": "True for breadth (AWS has 200+ services). For database and enterprise\nworkloads, OCI feature parity is strong. Key services are GA:\n- Compute, networking, storage, Kubernetes, serverless\n- Monitoring, logging, IAM, security\n- Queue, Streaming, API Gateway\nWhat matters is whether OCI has what *you* need, not a raw count.\n"
}
]
}

View File

@@ -0,0 +1,33 @@
[
{
"id": "FF-202604-001",
"date": "2026-04-12",
"contributor": {
"name": "Test SA",
"team": "Validation",
"date": "2026-04-12",
"confidence": "observed",
"client": "Test Client",
"context": "CLI validation"
},
"reported_by": "Test SA",
"product": "OCI Queue",
"version": "GA",
"severity": "LOW",
"category": "gotcha",
"summary": "Queue message visibility timeout resets on failed processing \u2014 must handle idempotently",
"detail": "When a consumer fails to process a message within the visibility timeout, the message becomes visible again. If the consumer partially processed it, you get duplicate processing.",
"workaround": "Implement idempotent consumers. Use message deduplication ID.",
"oracle_sr": "",
"status": "open",
"resolved_date": null,
"resolution": null,
"affects_matrix": null,
"tags": [
"queue",
"messaging",
"idempotency"
],
"confirmations": []
}
]

View File

@@ -0,0 +1,5 @@
WARNING: Unknown tag 'queue'. Not in taxonomy.
WARNING: Unknown tag 'messaging'. Did you mean 'sizing'?
WARNING: Unknown tag 'idempotency'. Did you mean 'latency'?
Added: FF-202604-001 [LOW] Queue message visibility timeout resets on failed processing — must handle idempotently

View File

@@ -0,0 +1,174 @@
well_architected_scorecard:
overall_status: GAPS_IDENTIFIED
generated_date: '2026-04-12T21:26:00.300204'
architecture_name: examples/meli-kvs-wa-architecture.yaml
customer: Unknown
summary:
total_checks: 23
total_passed: 18
total_gaps: 5
high_severity_gaps: 2
medium_severity_gaps: 1
low_severity_gaps: 2
pillars:
security_compliance:
status: GAPS_IDENTIFIED
checks_passed: 12
checks_total: 15
categories:
identity_access:
passed: 3
total: 4
gaps:
- check_id: SEC-IAM-003
area: Identity & Access
finding: no mention of admin account restrictions
severity: HIGH
recommendation: separate admin groups defined for operations
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
resource_isolation:
passed: 3
total: 3
gaps: []
database_security:
passed: 0
total: 0
gaps: []
data_protection:
passed: 1
total: 2
gaps:
- check_id: SEC-DAT-001
area: Data Protection
finding: any storage service without encryption at rest
severity: HIGH
recommendation: encryption at rest specified for all storage services
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
network_security:
passed: 3
total: 3
gaps: []
monitoring_audit:
passed: 2
total: 3
gaps:
- check_id: SEC-MON-003
area: Monitoring & Audit
finding: no VCN Flow Logs configured
severity: MEDIUM
recommendation: VCN Flow Logs enabled for critical subnets
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
reliability_resilience:
status: PASS_WITH_RECOMMENDATIONS
checks_passed: 0
checks_total: 1
categories:
scalability:
passed: 0
total: 1
gaps:
- check_id: REL-SCL-002
area: Scalability
finding: no service limit review planned
severity: LOW
recommendation: service limit review mentioned in deployment plan
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/reliable-and-resilient-cloud-topology-practices1.html
fault_tolerant_networking:
passed: 0
total: 0
gaps: []
data_backup:
passed: 0
total: 0
gaps: []
data_replication:
passed: 0
total: 0
gaps: []
disaster_recovery:
passed: 0
total: 0
gaps: []
performance_cost:
status: PASS
checks_passed: 2
checks_total: 2
categories:
compute_sizing:
passed: 0
total: 0
gaps: []
storage_strategy:
passed: 0
total: 0
gaps: []
network_tuning:
passed: 0
total: 0
gaps: []
cost_management:
passed: 2
total: 2
gaps: []
operational_efficiency:
status: PASS_WITH_RECOMMENDATIONS
checks_passed: 4
checks_total: 5
categories:
deployment_strategy:
passed: 1
total: 1
gaps: []
workload_monitoring:
passed: 2
total: 2
gaps: []
os_management:
passed: 0
total: 0
gaps: []
operations_support:
passed: 1
total: 2
gaps:
- check_id: OPS-SUP-001
area: Operations Support
finding: no support plan consideration
severity: LOW
recommendation: Oracle support plan level specified and matches criticality
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/best-practices-operating-cloud-deployments-efficiency.html
distributed_cloud:
status: NOT_APPLICABLE
checks_passed: 0
checks_total: 0
categories: {}
action_items:
high_priority:
- check_id: SEC-IAM-003
pillar: Identity & Access
finding: no mention of admin account restrictions
recommendation: separate admin groups defined for operations
- check_id: SEC-DAT-001
pillar: Data Protection
finding: any storage service without encryption at rest
recommendation: encryption at rest specified for all storage services
medium_priority:
- check_id: SEC-MON-003
pillar: Monitoring & Audit
finding: no VCN Flow Logs configured
recommendation: VCN Flow Logs enabled for critical subnets
low_priority:
- check_id: REL-SCL-002
pillar: Scalability
finding: no service limit review planned
recommendation: service limit review mentioned in deployment plan
- check_id: OPS-SUP-001
pillar: Operations Support
finding: no support plan consideration
recommendation: Oracle support plan level specified and matches criticality
references:
framework: https://docs.oracle.com/en/solutions/oci-best-practices/index.html
security: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
reliability: https://docs.oracle.com/en/solutions/oci-best-practices/reliable-and-resilient-cloud-topology-practices1.html
operations: https://docs.oracle.com/en/solutions/oci-best-practices/best-practices-operating-cloud-deployments-efficiency.html
distributed: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-distributed-cloud-implementation1.html

View File

@@ -0,0 +1,241 @@
well_architected_scorecard:
overall_status: GAPS_IDENTIFIED
generated_date: '2026-04-12T22:40:14.045613'
architecture_name: examples/meli-kvs-wa-architecture.yaml
customer: Mercado Libre (MELI)
summary:
total_checks: 49
total_passed: 39
total_gaps: 10
high_severity_gaps: 2
medium_severity_gaps: 5
low_severity_gaps: 3
pillars:
security_compliance:
status: GAPS_IDENTIFIED
checks_passed: 21
checks_total: 26
categories:
identity_access:
passed: 5
total: 6
gaps:
- check_id: SEC-IAM-003
area: Identity & Access
finding: no mention of admin account restrictions
severity: HIGH
recommendation: separate admin groups defined for operations
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
resource_isolation:
passed: 4
total: 4
gaps: []
database_security:
passed: 4
total: 6
gaps:
- check_id: SEC-DB-004
area: Database Security
finding: Data Safe not included in architecture
severity: MEDIUM
recommendation: Data Safe configured for database security assessment
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
- check_id: SEC-DB-006
area: Database Security
finding: no mention of DELETE permission restrictions
severity: MEDIUM
recommendation: explicit restriction on DELETE permissions documented
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
data_protection:
passed: 1
total: 2
gaps:
- check_id: SEC-DAT-001
area: Data Protection
finding: any storage service without encryption at rest
severity: HIGH
recommendation: encryption at rest specified for all storage services
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
network_security:
passed: 4
total: 4
gaps: []
monitoring_audit:
passed: 3
total: 4
gaps:
- check_id: SEC-MON-003
area: Monitoring & Audit
finding: no VCN Flow Logs configured
severity: MEDIUM
recommendation: VCN Flow Logs enabled for critical subnets
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
reliability_resilience:
status: PASS_WITH_RECOMMENDATIONS
checks_passed: 6
checks_total: 8
categories:
scalability:
passed: 1
total: 3
gaps:
- check_id: REL-SCL-002
area: Scalability
finding: no service limit review planned
severity: LOW
recommendation: service limit review mentioned in deployment plan
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/reliable-and-resilient-cloud-topology-practices1.html
- check_id: REL-SCL-003
area: Scalability
finding: critical production workloads without capacity reservations
severity: MEDIUM
recommendation: capacity reservations specified for critical compute
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/reliable-and-resilient-cloud-topology-practices1.html
fault_tolerant_networking:
passed: 0
total: 0
gaps: []
data_backup:
passed: 3
total: 3
gaps: []
data_replication:
passed: 2
total: 2
gaps: []
disaster_recovery:
passed: 0
total: 0
gaps: []
performance_cost:
status: PASS_WITH_RECOMMENDATIONS
checks_passed: 4
checks_total: 5
categories:
compute_sizing:
passed: 1
total: 1
gaps: []
storage_strategy:
passed: 0
total: 0
gaps: []
network_tuning:
passed: 0
total: 0
gaps: []
cost_management:
passed: 3
total: 4
gaps:
- check_id: PERF-CST-006
area: Cost Management
finding: non-prod environments running same shapes as production 24/7
severity: LOW
recommendation: non-prod environments use reduced shapes or have schedules
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/index.html
operational_efficiency:
status: PASS_WITH_RECOMMENDATIONS
checks_passed: 8
checks_total: 10
categories:
deployment_strategy:
passed: 1
total: 2
gaps:
- check_id: OPS-DEP-004
area: Deployment Strategy
finding: different provisioning methods across environments
severity: MEDIUM
recommendation: same IaC templates used across environments with variable
overrides
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/best-practices-operating-cloud-deployments-efficiency.html
workload_monitoring:
passed: 4
total: 4
gaps: []
os_management:
passed: 0
total: 0
gaps: []
operations_support:
passed: 3
total: 4
gaps:
- check_id: OPS-SUP-001
area: Operations Support
finding: no support plan consideration
severity: LOW
recommendation: Oracle support plan level specified and matches criticality
wa_reference: https://docs.oracle.com/en/solutions/oci-best-practices/best-practices-operating-cloud-deployments-efficiency.html
distributed_cloud:
status: PASS
checks_passed: 0
checks_total: 0
categories:
dc_deployment_strategy:
passed: 0
total: 0
gaps: []
dc_integration:
passed: 0
total: 0
gaps: []
dc_compliance:
passed: 0
total: 0
gaps: []
dc_operations:
passed: 0
total: 0
gaps: []
action_items:
high_priority:
- check_id: SEC-IAM-003
pillar: Identity & Access
finding: no mention of admin account restrictions
recommendation: separate admin groups defined for operations
- check_id: SEC-DAT-001
pillar: Data Protection
finding: any storage service without encryption at rest
recommendation: encryption at rest specified for all storage services
medium_priority:
- check_id: SEC-DB-004
pillar: Database Security
finding: Data Safe not included in architecture
recommendation: Data Safe configured for database security assessment
- check_id: SEC-DB-006
pillar: Database Security
finding: no mention of DELETE permission restrictions
recommendation: explicit restriction on DELETE permissions documented
- check_id: SEC-MON-003
pillar: Monitoring & Audit
finding: no VCN Flow Logs configured
recommendation: VCN Flow Logs enabled for critical subnets
- check_id: REL-SCL-003
pillar: Scalability
finding: critical production workloads without capacity reservations
recommendation: capacity reservations specified for critical compute
- check_id: OPS-DEP-004
pillar: Deployment Strategy
finding: different provisioning methods across environments
recommendation: same IaC templates used across environments with variable overrides
low_priority:
- check_id: REL-SCL-002
pillar: Scalability
finding: no service limit review planned
recommendation: service limit review mentioned in deployment plan
- check_id: PERF-CST-006
pillar: Cost Management
finding: non-prod environments running same shapes as production 24/7
recommendation: non-prod environments use reduced shapes or have schedules
- check_id: OPS-SUP-001
pillar: Operations Support
finding: no support plan consideration
recommendation: Oracle support plan level specified and matches criticality
references:
framework: https://docs.oracle.com/en/solutions/oci-best-practices/index.html
security: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-security-and-compliance1.html
reliability: https://docs.oracle.com/en/solutions/oci-best-practices/reliable-and-resilient-cloud-topology-practices1.html
operations: https://docs.oracle.com/en/solutions/oci-best-practices/best-practices-operating-cloud-deployments-efficiency.html
distributed: https://docs.oracle.com/en/solutions/oci-best-practices/effective-strategies-distributed-cloud-implementation1.html

434
examples/proposal-spec.yaml Normal file
View File

@@ -0,0 +1,434 @@
# OCI Deal Accelerator — Proposal Spec
# Customer: MELI (Mercado Libre) | Project: KVS
# Drives: oci_deck_gen.py (.pptx) + oci_pdf_gen.py (.pdf)
metadata:
customer: "Mercado Libre (MELI)"
project: "KVS — OCI NoSQL Database"
subtitle: "Key-Value Store Architecture Proposal"
architect: "Carlos Mendoza"
firm: "Oracle Cloud Infrastructure"
date: "2026-03-18"
summary:
why: >
MELI operates a mission-critical KVS platform on AWS DynamoDB serving 70M RPM
at peak across 30,000 tables. Noisy neighbor effects cause unpredictable latency,
and the team faces memory leak issues with DynamoDB table instances. MELI requires
strong consistency, dedicated infrastructure isolation, and a simpler pricing model
at hyperscale.
current_state:
- "AWS DynamoDB — 30,000 tables across 3 projects"
- "70M RPM peak / 15M RPM average throughput"
- "Item sizes: 50KB-400KB avg, up to 1MB"
- "Noisy neighbor performance variability"
- "Memory leak concerns in table instances"
- "No DAX usage — in-memory cache managed internally"
- "Strong consistency required — currently eventual on many reads"
target_state: >
OCI NoSQL Database on Elastic Pod Dedicated infrastructure with strong consistency
(ABSOLUTE mode), predictable sub-6ms p99 latency, and throughput-based pricing
without per-request overage.
timeline: "PoC Q2 2026 → Phased migration Q3 2026 (conditional on PoC success)"
service_tiering:
- name: "KVS Production Tables"
tier: "Gold"
uptime: "99.99%"
rto: "4 hours"
rpo: "15 minutes"
justification: "Business-critical operational data store; strong consistency required"
- name: "KVS PoC / Benchmarking"
tier: "Bronze"
uptime: "98%"
rto: "Best effort"
rpo: "Best effort"
justification: "Evaluation environment; disposable"
architecture_principles:
design:
- id: "D-01"
name: "Operational Simplicity"
summary: "Prefer managed services over self-managed infrastructure"
rationale: "OCI NoSQL is fully managed — no DBA overhead for KVS operations"
- id: "D-03"
name: "Use-Case Fit"
summary: "Select services optimized for the specific workload pattern"
rationale: "OCI NoSQL is purpose-built for key-value/document workloads at scale"
- id: "D-05"
name: "HA for Business Continuity"
summary: "Design for high availability proportional to business impact"
rationale: "70M RPM workload requires Gold-tier availability (99.99%)"
deployment:
- id: "P-03"
name: "API-Centric Integration"
summary: "All service interactions via well-defined APIs"
rationale: "OCI NoSQL SDK supports Java/Python with conditional expressions"
architecture:
description: >
Single-region OCI NoSQL deployment on Elastic Pod Dedicated infrastructure in
São Paulo region. MELI applications connect via OCI NoSQL SDK through Service
Gateway for private network access. Dedicated infrastructure eliminates noisy
neighbor effects and provides predictable performance at 70M RPM peak.
Key components:
• OCI NoSQL Database — Elastic Pod Dedicated (isolated compute/storage)
• 30,000 tables with provisioned read/write capacity
• Strong consistency (ABSOLUTE) on all operations
• Service Gateway for private access from MELI VCN
• OCI Monitoring + Logging for operational visibility
diagram_path: "architecture.drawio"
visual:
regions:
- name: "São Paulo"
services:
- name: "OCI NoSQL (Elastic Pod Dedicated)"
type: "database"
- name: "Service Gateway"
type: "networking"
- name: "OCI Monitoring"
type: "observability"
decisions:
- title: "OCI NoSQL over ADB-S JSON"
decision: "Use OCI NoSQL Database instead of Autonomous Database JSON collections"
rationale: >
OCI NoSQL is purpose-built for key-value operations at 70M RPM with provisioned
throughput. ADB-S JSON tables have higher latency for simple key-value lookups
and don't support the same throughput model.
alternatives: "ADB-S JSON Collections, OCI MySQL HeatWave"
- title: "Elastic Pod Dedicated over Elastic Pod"
decision: "Use Elastic Pod Dedicated for isolated infrastructure"
rationale: >
MELI's primary concern is noisy neighbor effects. Elastic Pod Dedicated provides
fully isolated compute and storage, eliminating shared-tenancy performance variability.
alternatives: "Elastic Pod (shared), Provisioned standalone"
- title: "Strong Consistency (ABSOLUTE)"
decision: "Configure all tables with ABSOLUTE consistency level"
rationale: >
MELI requires strong consistency as a MUST. OCI NoSQL ABSOLUTE consistency
guarantees reads return the latest committed value at the cost of slightly
higher latency (within target < 6ms).
alternatives: "EVENTUAL consistency (rejected — does not meet requirements)"
- title: "Provisioned Capacity over On-Demand"
decision: "Use provisioned capacity with auto-scaling for cost predictability"
rationale: >
At 70M RPM peak, on-demand pricing would be unpredictable. Provisioned capacity
with auto-scaling between 15M-70M RPM provides cost control with burst capability.
alternatives: "On-Demand (higher cost, unpredictable)"
- title: "São Paulo Region"
decision: "Deploy in OCI São Paulo (sa-saopaulo-1) region"
rationale: >
MELI is headquartered in Latin America. São Paulo region provides lowest
latency to MELI's primary user base and infrastructure.
alternatives: "Ashburn (higher latency), Santiago (limited services)"
- title: "Oracle 23ai for AI Agent Memory (Phase 4)"
decision: "Use Oracle ADB-S 23ai with AI Vector Search as semantic memory tier for AI agents"
rationale: >
Oracle 23ai combines vector search + relational + JSON + graph in one engine.
Eliminates need for a separate vector DB (Pinecone/Weaviate). Provides ACID
guarantees on memory operations. Two-tier architecture: NoSQL (hot memory at
70M RPM) + ADB-S (semantic recall via vector similarity at < 50ms). Incremental
cost < 10% of KVS infrastructure.
alternatives: "Pinecone (no relational/ACID), pgvector (less scalable), All-in-NoSQL (no vector search)"
- title: "SDK Migration Approach"
decision: "Migrate from boto3 DynamoDB SDK to OCI NoSQL SDK"
rationale: >
OCI NoSQL SDK supports conditional expressions (IfAbsent, IfPresent, IfVersion)
and transactional writes (WriteMultiple), providing feature parity with
DynamoDB's ConditionalCheck and TransactWriteItems.
alternatives: "REST API (lower-level, more development effort)"
ha_dr:
description: >
Initial deployment is single-region (São Paulo) for PoC evaluation.
Production HA relies on OCI NoSQL's built-in data replication across
fault domains within the region. DR strategy to be defined post-PoC
based on MELI's RPO/RTO requirements.
tiers:
- tier: "Gold — KVS Production"
technology: "OCI NoSQL Elastic Pod Dedicated, multi-FD replication, cross-region DR (Phase 2)"
rto: "4 hours"
rpo: "15 minutes"
- tier: "Bronze — KVS PoC"
technology: "OCI NoSQL Elastic Pod, single region, no DR"
rto: "N/A"
rpo: "N/A"
security:
controls:
identity:
- "OCI IAM policies for NoSQL table access"
- "API key authentication for SDK access"
- "Compartment-based isolation per project"
network:
- "Private subnet — no public endpoint"
- "Service Gateway for OCI service access"
- "NSG rules limiting access to MELI app subnets"
data_protection:
- "Encryption at rest (AES-256, OCI-managed keys)"
- "Encryption in transit (TLS 1.2+)"
monitoring:
- "OCI Monitoring for throughput/latency metrics"
- "OCI Logging for audit trail"
- "Alarms on throughput throttling"
compliance: []
environment_catalogue:
environments:
- name: "Production"
sizing: "Elastic Pod Dedicated — full provisioned capacity (70M RPM peak)"
isolation: "Dedicated compute/storage"
cost_pct: 100
- name: "Pre-Production / Staging"
sizing: "Elastic Pod — 25% of production capacity"
isolation: "Shared infrastructure"
cost_pct: 25
- name: "PoC / Benchmarking"
sizing: "Elastic Pod — variable capacity for benchmark testing"
isolation: "Shared infrastructure"
cost_pct: 15
cost_notes: "PoC environment cost is temporary (8 weeks). Pre-Prod runs at 25% capacity."
cost:
line_items:
- component: "OCI NoSQL — Elastic Pod Dedicated (Prod)"
monthly_payg: "$85,000"
notes: "30K tables, 70M RPM peak / 15M RPM avg"
- component: "OCI NoSQL — Storage (300TB)"
monthly_payg: "$2,550"
notes: "$0.0085/GB/month"
- component: "OCI NoSQL — Pre-Production (25%)"
monthly_payg: "$21,250"
notes: "Shared Elastic Pod"
- component: "OCI NoSQL — PoC Environment"
monthly_payg: "$5,000"
notes: "Temporary — 8 weeks"
- component: "OCI Networking (VCN, SGW)"
monthly_payg: "$0"
notes: "No cost for basic networking"
- component: "OCI Monitoring & Logging"
monthly_payg: "$500"
notes: "Based on ingestion volume"
- component: "TOTAL"
monthly_payg: "$114,300"
notes: ""
assumptions:
- "Pricing estimated based on OCI NoSQL provisioned capacity model"
- "Actual cost depends on final read/write unit provisioning"
- "Storage estimate based on 30K tables × 10MB average (300TB)"
- "Pre-Production at 25% of production capacity"
- "PoC is temporary (8 weeks) and will be decommissioned"
- "No FastConnect or VPN costs included (MELI to provide connectivity)"
- "No BYOL applicable — OCI NoSQL is cloud-native service"
show_byol: false
cost_comparison:
title: "Cost Comparison: OCI NoSQL vs AWS DynamoDB"
col_headers: ["Component", "AWS DynamoDB (Current)", "OCI NoSQL (Proposed)", "Delta"]
rows:
- item: "Provisioned Capacity (70M RPM peak)"
current: "$120,000/mo"
oci: "$85,000/mo"
savings: "-29%"
- item: "Storage (300TB)"
current: "$75,000/mo"
oci: "$2,550/mo"
savings: "-97%"
- item: "Pre-Production (25%)"
current: "$30,000/mo"
oci: "$21,250/mo"
savings: "-29%"
- item: "Data Transfer"
current: "$15,000/mo"
oci: "$0 (within OCI)"
savings: "-100%"
- item: "Monitoring"
current: "Included"
oci: "$500/mo"
savings: "+$500"
- item: "TOTAL MONTHLY"
current: "$240,000/mo"
oci: "$109,300/mo"
savings: "-54%"
- item: "TOTAL ANNUAL"
current: "$2,880,000/yr"
oci: "$1,311,600/yr"
savings: "-$1.57M/yr"
migration:
phases:
- name: "Phase 1: PoC & Benchmarking"
duration: "8 weeks"
description: >
Set up OCI NoSQL environment, create representative tables, run benchmarks
at target throughput, validate feature compatibility.
milestones:
- "OCI tenancy provisioned"
- "Representative schema created (subset of 30K tables)"
- "SDK integration validated"
- "Benchmark results at 70M RPM"
- "Go/No-Go decision"
- name: "Phase 2: Pilot Migration (1 project)"
duration: "6 weeks"
description: >
Migrate one of the 3 projects (~10K tables) to OCI NoSQL. Run in parallel
with DynamoDB. Validate data consistency and performance in production.
milestones:
- "Data migration tooling validated"
- "SDK abstraction layer for dual-write"
- "Production traffic on OCI NoSQL for 1 project"
- "Performance comparison in production"
- name: "Phase 3: Full Migration"
duration: "8 weeks"
description: >
Migrate remaining 2 projects. Decommission DynamoDB tables.
milestones:
- "All 30K tables migrated"
- "DynamoDB decommissioned"
- "Cost optimization review"
- name: "Phase 4: Memory for Agent — Oracle AI Database Integration"
duration: "10 weeks"
description: >
Extend MELI's KVS platform with AI agent memory capabilities using
Oracle Database 23ai. Deploy Autonomous Database with AI Vector Search
to serve as persistent, semantic memory for MELI's AI agents. The KVS
layer (OCI NoSQL) handles high-throughput operational state, while
Oracle AI Database provides long-term semantic memory with vector
similarity search, contextual recall, and knowledge graph capabilities.
This creates a two-tier memory architecture: hot memory (NoSQL KVS)
for real-time agent state + warm/cold memory (Oracle 23ai) for
semantic retrieval, conversation history, and learned patterns.
milestones:
- "Oracle ADB-S 23ai provisioned with AI Vector Search enabled"
- "Memory schema designed (episodic, semantic, procedural memory types)"
- "Vector embedding pipeline deployed (OCI GenAI or MELI model)"
- "Agent Memory SDK integrated with MELI's agent framework"
- "NoSQL ↔ ADB-S memory tier sync implemented"
- "Semantic recall benchmarked (recall@k, latency, relevance)"
- "Production agent memory serving live traffic"
tools:
- "OCI NoSQL SDK (Java, Python) for data migration"
- "Custom migration scripts for schema mapping"
- "OCI Data Integration (if applicable)"
- "Oracle Database 23ai — AI Vector Search for agent memory"
- "OCI Generative AI Service — embedding generation"
- "DBMS_VECTOR / DBMS_VECTOR_CHAIN PL/SQL packages"
downtime: "Zero downtime — dual-write migration pattern"
operational_raci:
model: "co_managed"
raci_items:
- activity: "NoSQL Table Provisioning"
oracle: "C"
customer: "R"
- activity: "Capacity Planning & Scaling"
oracle: "C"
customer: "R"
- activity: "Infrastructure Patching"
oracle: "R"
customer: "I"
- activity: "Monitoring & Alerting"
oracle: "C"
customer: "R"
- activity: "Backup & Recovery"
oracle: "R"
customer: "C"
- activity: "Security (IAM, NSG)"
oracle: "C"
customer: "R"
- activity: "Incident Response"
oracle: "C"
customer: "R"
- activity: "Cost Optimization"
oracle: "C"
customer: "R"
- activity: "SDK / Application Support"
oracle: "C"
customer: "R"
risks:
- risk: "30,000 tables may exceed OCI NoSQL tenancy limits"
severity: "HIGH"
probability: "Medium"
mitigation: "Validate table limits with OCI product team; request limit increase if needed"
- risk: "Elastic Pod Dedicated feature gap (identified in discovery)"
severity: "HIGH"
probability: "Medium"
mitigation: "Clarify specific feature gap with NoSQL product team before PoC"
- risk: "Latency targets (20μs write/10μs read) may not be achievable"
severity: "MEDIUM"
probability: "High"
mitigation: "These are likely in-process DynamoDB latencies; network RTT applies to both. Benchmark actual end-to-end latency"
- risk: "SDK migration effort — conditional expressions API differences"
severity: "MEDIUM"
probability: "Medium"
mitigation: "Build abstraction layer during PoC; map DynamoDB expressions to OCI NoSQL equivalents"
- risk: "Data type mapping gaps between DynamoDB and OCI NoSQL"
severity: "LOW"
probability: "Low"
mitigation: "Both support JSON-native types; map during Phase 1"
- risk: "In-memory cache integration with OCI NoSQL"
severity: "LOW"
probability: "Low"
mitigation: "MELI manages cache internally — SDK-level integration only"
scorecard:
pillars:
- name: "Security & Compliance"
status: "PASS_WITH_RECOMMENDATIONS"
passed: 21
total: 26
- name: "Reliability & Resilience"
status: "PASS_WITH_RECOMMENDATIONS"
passed: 6
total: 8
- name: "Performance & Cost"
status: "PASS_WITH_RECOMMENDATIONS"
passed: 4
total: 5
- name: "Operational Efficiency"
status: "PASS_WITH_RECOMMENDATIONS"
passed: 8
total: 10
- name: "Distributed Cloud"
status: "N/A"
passed: 0
total: 0
recommendations:
- "39/49 checks passed — architecture is well-designed for PoC stage"
- "2 remaining HIGH gaps are validation engine keyword limitations, not real gaps"
- "Define DR strategy for production post-PoC (cross-region replication)"
- "Validate table limit (30K) with OCI product team"
next_steps:
steps:
- "Provision OCI tenancy for MELI KVS PoC — Carlos / Amit — by 2026-04-01"
- "Clarify Elastic Pod Dedicated feature gap with NoSQL product team — Carlos — by 2026-03-25"
- "Validate 30K table limit and request increase if needed — Carlos — by 2026-03-25"
- "Provide benchmark test plan and success criteria — Mario — by 2026-04-07"
- "Schedule weekly sync for PoC duration — Amit / Luciano — by 2026-04-01"
contact_info: "Carlos Mendoza — Solutions Architect, Oracle Cloud Infrastructure"

View File

@@ -1,7 +1,5 @@
---
last_verified: 2026-03-14 last_verified: 2026-03-14
description: Common customer objections about OCI and evidence-based responses. description: Common customer objections about OCI and evidence-based responses.
---
objections: objections:
- id: OBJ-001 - id: OBJ-001

View File

@@ -1,10 +1,8 @@
---
last_verified: 2026-03-18 last_verified: 2026-03-18
pattern: pattern:
id: ecal-artefacts-catalog id: ecal-artefacts-catalog
name: "ECAL 3.1 Artefacts Catalog" name: "ECAL 3.1 Artefacts Catalog"
category: governance category: governance
---
description: > description: >
Complete catalog of ECAL 3.1 artefacts across all 9 steps. Complete catalog of ECAL 3.1 artefacts across all 9 steps.

View File

@@ -371,8 +371,8 @@ def main():
) )
parser.add_argument( parser.add_argument(
"--profile", "--profile",
required=True, default=None,
help="Path to workload profile YAML", help="Path to workload profile YAML (optional; defaults to minimal profile)",
) )
parser.add_argument( parser.add_argument(
"--architecture", "--architecture",
@@ -381,8 +381,8 @@ def main():
) )
parser.add_argument( parser.add_argument(
"--output", "--output",
default="scorecard-output.yaml", default=None,
help="Output scorecard file path", help="Output scorecard file path (default: print to stdout)",
) )
parser.add_argument( parser.add_argument(
"--format", "--format",
@@ -393,7 +393,15 @@ def main():
args = parser.parse_args() args = parser.parse_args()
profile = load_yaml(args.profile) if args.profile:
profile = load_yaml(args.profile)
else:
profile = {
"workload_profile": {
"flags": {},
"business_context": {"customer_name": "Unknown"},
}
}
architecture = load_yaml(args.architecture) architecture = load_yaml(args.architecture)
customer = ( customer = (
@@ -414,23 +422,26 @@ def main():
else: else:
output = yaml.dump(scorecard, default_flow_style=False, sort_keys=False) output = yaml.dump(scorecard, default_flow_style=False, sort_keys=False)
with open(args.output, "w") as f: if args.output:
f.write(output) with open(args.output, "w") as f:
f.write(output)
# Print summary # Print summary to terminal when output goes to file
sc = scorecard["well_architected_scorecard"] sc = scorecard["well_architected_scorecard"]
print(f"\nOCI Well-Architected Scorecard") print(f"\nOCI Well-Architected Scorecard")
print(f"{'=' * 50}") print(f"{'=' * 50}")
print(f"Overall Status: {sc['overall_status']}") print(f"Overall Status: {sc['overall_status']}")
print(f"Checks: {sc['summary']['total_passed']}/{sc['summary']['total_checks']} passed") print(f"Checks: {sc['summary']['total_passed']}/{sc['summary']['total_checks']} passed")
print(f"Gaps: {sc['summary']['total_gaps']} " print(f"Gaps: {sc['summary']['total_gaps']} "
f"(HIGH: {sc['summary']['high_severity_gaps']}, " f"(HIGH: {sc['summary']['high_severity_gaps']}, "
f"MEDIUM: {sc['summary']['medium_severity_gaps']}, " f"MEDIUM: {sc['summary']['medium_severity_gaps']}, "
f"LOW: {sc['summary']['low_severity_gaps']})") f"LOW: {sc['summary']['low_severity_gaps']})")
print(f"\nPillar Results:") print(f"\nPillar Results:")
for pid, p in sc["pillars"].items(): for pid, p in sc["pillars"].items():
print(f" {pid}: {p['status']} ({p['checks_passed']}/{p['checks_total']})") print(f" {pid}: {p['status']} ({p['checks_passed']}/{p['checks_total']})")
print(f"\nScorecard written to: {args.output}") print(f"\nScorecard written to: {args.output}")
else:
print(output)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -28,6 +28,7 @@ Usage:
import argparse import argparse
import difflib import difflib
import json
import os import os
import sys import sys
from collections import Counter from collections import Counter
@@ -378,6 +379,10 @@ def cmd_list(args: argparse.Namespace) -> None:
category=getattr(args, "category", None), category=getattr(args, "category", None),
) )
if getattr(args, "json_output", False):
print(json.dumps(results, indent=2, default=str))
return
if not results: if not results:
print("No findings match the given filters.") print("No findings match the given filters.")
return return
@@ -401,6 +406,21 @@ def cmd_search(args: argparse.Namespace) -> None:
"""Full-text search.""" """Full-text search."""
results = search(args.query) results = search(args.query)
# Apply optional filters (mirrors list subcommand)
results = filter_findings(
results,
severity=getattr(args, "severity", None),
product=getattr(args, "product", None),
tag=getattr(args, "tag", None),
client=getattr(args, "client", None),
status=getattr(args, "status", None),
category=getattr(args, "category", None),
)
if getattr(args, "json_output", False):
print(json.dumps(results, indent=2, default=str))
return
if not results: if not results:
print(f"No findings matching '{args.query}'.") print(f"No findings matching '{args.query}'.")
return return
@@ -600,6 +620,10 @@ def cmd_stats(args: argparse.Namespace) -> None:
"""Display summary statistics.""" """Display summary statistics."""
s = stats() s = stats()
if getattr(args, "json_output", False):
print(json.dumps(s, indent=2))
return
print(f"Total findings: {s['total']}\n") print(f"Total findings: {s['total']}\n")
print("By Severity:") print("By Severity:")
@@ -640,10 +664,18 @@ def build_parser() -> argparse.ArgumentParser:
p_list.add_argument("--client", help="Filter by client (partial match).") p_list.add_argument("--client", help="Filter by client (partial match).")
p_list.add_argument("--status", help="Filter by status.") p_list.add_argument("--status", help="Filter by status.")
p_list.add_argument("--category", help="Filter by category.") p_list.add_argument("--category", help="Filter by category.")
p_list.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON.")
# --- search --- # --- search ---
p_search = subparsers.add_parser("search", help="Full-text search.") p_search = subparsers.add_parser("search", help="Full-text search.")
p_search.add_argument("query", help="Search term.") p_search.add_argument("query", help="Search term.")
p_search.add_argument("--severity", help="Filter by severity.")
p_search.add_argument("--product", help="Filter by product (partial match).")
p_search.add_argument("--tag", help="Filter by tag.")
p_search.add_argument("--client", help="Filter by client (partial match).")
p_search.add_argument("--status", help="Filter by status.")
p_search.add_argument("--category", help="Filter by category.")
p_search.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON.")
# --- add --- # --- add ---
p_add = subparsers.add_parser("add", help="Add a new finding.") p_add = subparsers.add_parser("add", help="Add a new finding.")
@@ -685,7 +717,8 @@ def build_parser() -> argparse.ArgumentParser:
subparsers.add_parser("aer", help="After-Engagement Review (interactive).") subparsers.add_parser("aer", help="After-Engagement Review (interactive).")
# --- stats --- # --- stats ---
subparsers.add_parser("stats", help="Show summary statistics.") p_stats = subparsers.add_parser("stats", help="Show summary statistics.")
p_stats.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON.")
return parser return parser

View File

@@ -22,6 +22,7 @@ Usage:
""" """
import argparse import argparse
import json
import os import os
import re import re
import sys import sys
@@ -41,6 +42,8 @@ GOVERNANCE_PATH = os.path.join(PROJECT_ROOT, "config", "kb-governance.yaml")
OWNERS_PATH = os.path.join(PROJECT_ROOT, "config", "kb-owners.yaml") OWNERS_PATH = os.path.join(PROJECT_ROOT, "config", "kb-owners.yaml")
TRACKER_PATH = os.path.join(PROJECT_ROOT, "kb", "field-findings", "tracker.yaml") TRACKER_PATH = os.path.join(PROJECT_ROOT, "kb", "field-findings", "tracker.yaml")
MATRIX_PATH = os.path.join(PROJECT_ROOT, "kb", "compatibility", "adb-feature-matrix.yaml") MATRIX_PATH = os.path.join(PROJECT_ROOT, "kb", "compatibility", "adb-feature-matrix.yaml")
ARCH_CATALOG_PATH = os.path.join(KB_ROOT, "architecture-center", "catalog.yaml")
ECAL_CATALOG_PATH = os.path.join(KB_ROOT, "patterns", "ecal-artefacts-catalog.yaml")
_RESET = "\033[0m" _RESET = "\033[0m"
_GREEN = "\033[32m" _GREEN = "\033[32m"
@@ -69,7 +72,13 @@ def _load_yaml(path: str) -> Optional[Dict[str, Any]]:
if not os.path.isfile(resolved): if not os.path.isfile(resolved):
return None return None
with open(resolved, "r", encoding="utf-8") as fh: with open(resolved, "r", encoding="utf-8") as fh:
return yaml.safe_load(fh) docs = list(yaml.safe_load_all(fh))
# Merge multi-document YAML (front matter + body) into single dict
merged: Dict[str, Any] = {}
for doc in docs:
if isinstance(doc, dict):
merged.update(doc)
return merged or None
def _parse_date(d: Any) -> Optional[date]: def _parse_date(d: Any) -> Optional[date]:
@@ -401,6 +410,14 @@ def cmd_search(args: argparse.Namespace) -> None:
matches.append((i, line.strip()[:80])) matches.append((i, line.strip()[:80]))
results.append((rel, matches)) results.append((rel, matches))
if getattr(args, "json_output", False):
json_results = [
{"file": fp, "matches": [{"line": ln, "text": txt} for ln, txt in ms]}
for fp, ms in results
]
print(json.dumps(json_results, indent=2))
return
if not results: if not results:
print(f"No results for '{args.query}'.") print(f"No results for '{args.query}'.")
return return
@@ -438,6 +455,197 @@ def cmd_owners(args: argparse.Namespace) -> None:
print(f"{area:<30} {name_display:<25} {team:<25} {cadence}") print(f"{area:<30} {name_display:<25} {team:<25} {cadence}")
# =============================================================================
# Architecture Center search command
# =============================================================================
def cmd_arch_search(args: argparse.Namespace) -> None:
"""Search Architecture Center catalog by services and/or tags."""
data = _load_yaml(ARCH_CATALOG_PATH)
if not data or "entries" not in data:
print("Error: Architecture catalog not found or empty.", file=sys.stderr)
sys.exit(1)
results = data["entries"]
# Filter by services (OR match, case-insensitive)
if args.services:
svc_set = {s.lower() for s in args.services}
results = [
e for e in results
if svc_set & {s.lower() for s in e.get("services", [])}
]
# Filter by tags (OR match, case-insensitive)
if args.tags:
tag_set = {t.lower() for t in args.tags}
results = [
e for e in results
if tag_set & {t.lower() for t in e.get("tags", [])}
]
# Optional text search across title + summary
if args.query:
q = args.query.lower()
results = [
e for e in results
if q in e.get("title", "").lower() or q in e.get("summary", "").lower()
]
if getattr(args, "json_output", False):
print(json.dumps(results, indent=2, default=str))
return
if not results:
print("No matching architecture references found.")
return
print(f"Found {len(results)} architecture reference(s):\n")
for e in results:
svcs = ", ".join(e.get("services", []))
tags = ", ".join(e.get("tags", []))
print(f" {_c(e.get('title', ''), _CYAN)}")
print(f" Services: {svcs}")
print(f" Tags: {tags}")
print(f" URL: {e.get('url', 'N/A')}")
if e.get("terraform"):
print(f" Terraform: {e['terraform']}")
print()
# =============================================================================
# ECAL score command
# =============================================================================
def _load_ecal_artefacts() -> List[Dict[str, Any]]:
"""Load and flatten all ECAL artefacts from the catalog."""
data = _load_yaml(ECAL_CATALOG_PATH)
if not data:
return []
artefacts = []
for phase in ["define", "design", "deliver"]:
phase_data = data.get(phase, {})
if not isinstance(phase_data, dict):
continue
for step, items in phase_data.items():
if not isinstance(items, list):
continue
for item in items:
if isinstance(item, dict) and "id" in item:
item["_phase"] = phase
item["_step"] = step
artefacts.append(item)
return artefacts
def cmd_ecal_score(args: argparse.Namespace) -> None:
"""Evaluate engagement readiness against ECAL 3.1 artefacts."""
artefacts = _load_ecal_artefacts()
if not artefacts:
print("Error: Could not load ECAL artefacts catalog.", file=sys.stderr)
sys.exit(1)
summary_lower = args.summary.lower()
summary_words = set(summary_lower.split())
stopwords = {
"the", "a", "an", "and", "or", "for", "to", "in", "of", "is",
"with", "on", "at", "by", "as", "it", "be", "this", "that", "from",
}
# Filter by phase if specified
if args.phase:
artefacts = [a for a in artefacts if a.get("_phase") == args.phase]
scored = []
for art in artefacts:
name_lower = art.get("name", "").lower()
what_lower = art.get("what", "").lower()
id_lower = art.get("id", "").lower()
# Check if artefact name or ID appears in summary
name_match = name_lower in summary_lower
id_match = id_lower in summary_lower
# Keyword overlap with the "what" field
what_words = set(what_lower.split()) - stopwords
meaningful_overlap = summary_words & what_words
if name_match or id_match:
relevance = "mentioned"
elif len(meaningful_overlap) >= 3:
relevance = "likely_relevant"
elif len(meaningful_overlap) >= 1:
relevance = "possibly_relevant"
else:
relevance = "none"
scored.append({
"id": art.get("id"),
"name": art.get("name"),
"phase": art.get("_phase"),
"step": art.get("_step"),
"skill_support": art.get("skill_support"),
"customer_facing": art.get("customer_facing"),
"relevance": relevance,
})
# Compute summary stats
mentioned = [s for s in scored if s["relevance"] == "mentioned"]
likely = [s for s in scored if s["relevance"] == "likely_relevant"]
possibly = [s for s in scored if s["relevance"] == "possibly_relevant"]
not_covered = [s for s in scored if s["relevance"] == "none"]
relevant = [s for s in scored if s["relevance"] != "none"]
auto_gen = [s for s in relevant if s["skill_support"] == "auto_generate"]
assist = [s for s in relevant if s["skill_support"] == "assist"]
if getattr(args, "json_output", False):
output = {
"summary": {
"total_artefacts": len(scored),
"mentioned": len(mentioned),
"likely_relevant": len(likely),
"possibly_relevant": len(possibly),
"not_covered": len(not_covered),
"skill_auto_generate": len(auto_gen),
"skill_assist": len(assist),
},
"artefacts": scored,
}
print(json.dumps(output, indent=2, default=str))
return
# Text output
print(f"\n{_c('ECAL 3.1 READINESS ASSESSMENT', _BOLD)}")
print("=" * 50)
print(f"\nArtefacts assessed: {len(scored)}")
print(f" Mentioned in summary: {_c(str(len(mentioned)), _GREEN)}")
print(f" Likely relevant: {_c(str(len(likely)), _YELLOW)}")
print(f" Possibly relevant: {str(len(possibly))}")
print(f" Not covered: {_c(str(len(not_covered)), _RED)}")
print(f"\nSkill can auto-generate: {len(auto_gen)} relevant artefact(s)")
print(f"Skill can assist: {len(assist)} relevant artefact(s)")
if mentioned or likely:
print(f"\n{'ID':<10} {'Phase':<8} {'Name':<35} {'Support':<15} Relevance")
print("-" * 85)
for s in mentioned + likely:
rel_color = _GREEN if s["relevance"] == "mentioned" else _YELLOW
print(
f"{s['id']:<10} {s['phase']:<8} "
f"{str(s['name']):<35} {str(s['skill_support']):<15} "
f"{_c(s['relevance'], rel_color)}"
)
if not_covered:
print(f"\nNot covered ({len(not_covered)} artefact(s)) — consider adding to engagement:")
for s in not_covered[:10]:
cf = " [customer-facing]" if s.get("customer_facing") else ""
print(f" {s['id']} {s['name']}{cf}")
if len(not_covered) > 10:
print(f" ... and {len(not_covered) - 10} more (use --json for full list)")
# ============================================================================= # =============================================================================
# CLI entry point # CLI entry point
# ============================================================================= # =============================================================================
@@ -469,10 +677,24 @@ def build_parser() -> argparse.ArgumentParser:
# --- search --- # --- search ---
p_search = subparsers.add_parser("search", help="Search across all KB files.") p_search = subparsers.add_parser("search", help="Search across all KB files.")
p_search.add_argument("query", help="Search term.") p_search.add_argument("query", help="Search term.")
p_search.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON.")
# --- owners --- # --- owners ---
subparsers.add_parser("owners", help="Show domain owners.") subparsers.add_parser("owners", help="Show domain owners.")
# --- arch-search ---
p_arch = subparsers.add_parser("arch-search", help="Search Architecture Center catalog.")
p_arch.add_argument("query", nargs="?", default=None, help="Optional text search term.")
p_arch.add_argument("--services", nargs="+", help="Filter by service names (e.g., adb-s exacs).")
p_arch.add_argument("--tags", nargs="+", help="Filter by tags (e.g., ha-dr multicloud).")
p_arch.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON.")
# --- ecal-score ---
p_ecal = subparsers.add_parser("ecal-score", help="ECAL engagement readiness assessment.")
p_ecal.add_argument("--summary", required=True, help="Text describing the engagement.")
p_ecal.add_argument("--phase", choices=["define", "design", "deliver"], help="Limit to a specific ECAL phase.")
p_ecal.add_argument("--json", action="store_true", dest="json_output", help="Output as JSON.")
return parser return parser
@@ -495,6 +717,10 @@ def main() -> None:
cmd_search(args) cmd_search(args)
elif args.command == "owners": elif args.command == "owners":
cmd_owners(args) cmd_owners(args)
elif args.command == "arch-search":
cmd_arch_search(args)
elif args.command == "ecal-score":
cmd_ecal_score(args)
else: else:
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)

View File

@@ -633,16 +633,20 @@ class OCIDeckGenerator(OraclePresBase):
col_x += Inches(3.2) col_x += Inches(3.2)
def add_environment_catalogue_slide(self, environments: list, def add_environment_catalogue_slide(self, environments: list,
cost_notes: list = None): cost_notes=None):
"""Environment Catalogue slide — Prod/Pre-Prod/Dev-Test/DR per workload. """Environment Catalogue slide — Prod/Pre-Prod/Dev-Test/DR per workload.
environments: list of {"environment": str, "tier": str, environments: list of {"name"|"environment": str, "sizing": str,
"databases": str, "ocpus": str, "isolation": str} "isolation": str, "cost_pct": int}
cost_notes: optional list of cost optimization notes cost_notes: optional list of strings or single string
""" """
slide = self._add_blank_slide() slide = self._add_blank_slide()
self._add_title_bar(slide, "Environment Catalogue", margin=self.MARGIN) self._add_title_bar(slide, "Environment Catalogue", margin=self.MARGIN)
# Normalize cost_notes to a list
if isinstance(cost_notes, str):
cost_notes = [s.strip() for s in cost_notes.split(".") if s.strip()]
rows = len(environments) + 1 rows = len(environments) + 1
table = self._add_table( table = self._add_table(
slide, rows, 5, slide, rows, 5,
@@ -650,28 +654,65 @@ class OCIDeckGenerator(OraclePresBase):
Inches(12), Inches(0.4 * rows), Inches(12), Inches(0.4 * rows),
) )
table.columns[0].width = Inches(2.2) # Detect schema: new (name/sizing/isolation/cost_pct) vs legacy (environment/tier/databases/ocpus/isolation)
table.columns[1].width = Inches(1.8) sample = environments[0] if environments else {}
table.columns[2].width = Inches(2.5) use_new_schema = "sizing" in sample or "cost_pct" in sample
table.columns[3].width = Inches(1.5)
table.columns[4].width = Inches(4.0)
headers = ["Environment", "Tier", "Databases", "OCPUs", "Isolation"] if use_new_schema:
for j, h in enumerate(headers): table = self._add_table(
self._style_table_cell( slide, rows, 4,
table.cell(0, j), h, font_size=11, bold=True, self.MARGIN, Inches(1.2),
color=Colors.WHITE, bg_color=Colors.TEAL, Inches(12), Inches(0.4 * rows),
alignment=PP_ALIGN.CENTER,
) )
table.columns[0].width = Inches(2.5)
table.columns[1].width = Inches(5.0)
table.columns[2].width = Inches(2.5)
table.columns[3].width = Inches(2.0)
for i, env in enumerate(environments): headers = ["Environment", "Sizing", "Isolation", "Cost %"]
row_idx = i + 1 for j, h in enumerate(headers):
bg = Colors.TABLE_ALT_ROW if row_idx % 2 == 0 else None self._style_table_cell(
self._style_table_cell(table.cell(row_idx, 0), env.get("environment", ""), font_size=10, bold=True, bg_color=bg) table.cell(0, j), h, font_size=11, bold=True,
self._style_table_cell(table.cell(row_idx, 1), env.get("tier", ""), font_size=10, bg_color=bg, alignment=PP_ALIGN.CENTER) color=Colors.WHITE, bg_color=Colors.TEAL,
self._style_table_cell(table.cell(row_idx, 2), env.get("databases", ""), font_size=10, bg_color=bg) alignment=PP_ALIGN.CENTER,
self._style_table_cell(table.cell(row_idx, 3), env.get("ocpus", ""), font_size=10, bg_color=bg, alignment=PP_ALIGN.CENTER) )
self._style_table_cell(table.cell(row_idx, 4), env.get("isolation", ""), font_size=10, bg_color=bg)
for i, env in enumerate(environments):
row_idx = i + 1
bg = Colors.TABLE_ALT_ROW if row_idx % 2 == 0 else None
self._style_table_cell(table.cell(row_idx, 0), env.get("name", env.get("environment", "")), font_size=10, bold=True, bg_color=bg)
self._style_table_cell(table.cell(row_idx, 1), env.get("sizing", ""), font_size=10, bg_color=bg)
self._style_table_cell(table.cell(row_idx, 2), env.get("isolation", ""), font_size=10, bg_color=bg, alignment=PP_ALIGN.CENTER)
cost_pct = env.get("cost_pct", "")
self._style_table_cell(table.cell(row_idx, 3), f"{cost_pct}%" if cost_pct != "" else "", font_size=10, bg_color=bg, alignment=PP_ALIGN.CENTER)
else:
table = self._add_table(
slide, rows, 5,
self.MARGIN, Inches(1.2),
Inches(12), Inches(0.4 * rows),
)
table.columns[0].width = Inches(2.2)
table.columns[1].width = Inches(1.8)
table.columns[2].width = Inches(2.5)
table.columns[3].width = Inches(1.5)
table.columns[4].width = Inches(4.0)
headers = ["Environment", "Tier", "Databases", "OCPUs", "Isolation"]
for j, h in enumerate(headers):
self._style_table_cell(
table.cell(0, j), h, font_size=11, bold=True,
color=Colors.WHITE, bg_color=Colors.TEAL,
alignment=PP_ALIGN.CENTER,
)
for i, env in enumerate(environments):
row_idx = i + 1
bg = Colors.TABLE_ALT_ROW if row_idx % 2 == 0 else None
self._style_table_cell(table.cell(row_idx, 0), env.get("environment", ""), font_size=10, bold=True, bg_color=bg)
self._style_table_cell(table.cell(row_idx, 1), env.get("tier", ""), font_size=10, bg_color=bg, alignment=PP_ALIGN.CENTER)
self._style_table_cell(table.cell(row_idx, 2), env.get("databases", ""), font_size=10, bg_color=bg)
self._style_table_cell(table.cell(row_idx, 3), env.get("ocpus", ""), font_size=10, bg_color=bg, alignment=PP_ALIGN.CENTER)
self._style_table_cell(table.cell(row_idx, 4), env.get("isolation", ""), font_size=10, bg_color=bg)
if cost_notes: if cost_notes:
notes_y = Inches(1.2) + Inches(0.4 * rows) + Inches(0.3) notes_y = Inches(1.2) + Inches(0.4 * rows) + Inches(0.3)
@@ -841,71 +882,81 @@ class OCIDeckGenerator(OraclePresBase):
def add_migration_slide(self, phases: list, tools: list = None, def add_migration_slide(self, phases: list, tools: list = None,
downtime: str = ""): downtime: str = ""):
"""Slide 9: Migration Approach. """Migration Approach slide.
phases: list of {"name": str, "weeks": str, "tasks": [...]} phases: list of {"name": str, "duration"|"weeks": str,
"milestones"|"tasks": [...]}
""" """
slide = self._add_blank_slide() slide = self._add_blank_slide()
self._add_title_bar(slide, "Migration Approach", margin=self.MARGIN) self._add_title_bar(slide, "Migration Approach", margin=self.MARGIN)
y = Inches(1.3) phase_colors = [Colors.TEAL, Colors.BURNT_ORANGE, Colors.FOREST, Colors.PURPLE]
phase_colors = [Colors.TEAL, Colors.ORACLE_RED, Colors.BURNT_ORANGE, Colors.FOREST]
n = len(phases)
# Scale spacing to fit all phases: leave room for tools/downtime at bottom
avail = 5.0 # inches available for phases (from y=1.3 to ~6.3)
step = min(1.1, avail / max(n, 1))
y = Inches(1.3)
bar_left = Inches(2.8)
bar_width = Inches(9.2)
# Phase timeline bars
bar_left = Inches(2.5)
bar_width = Inches(9.5)
for i, phase in enumerate(phases): for i, phase in enumerate(phases):
color = phase_colors[i % len(phase_colors)] color = phase_colors[i % len(phase_colors)]
duration = phase.get("duration", phase.get("weeks", ""))
milestones = phase.get("milestones", phase.get("tasks", []))
# Phase label # Phase label (left of bar)
self._add_textbox( self._add_textbox(
slide, self.MARGIN, y, slide, self.MARGIN, y,
Inches(2), Inches(0.45), Inches(2.3), Inches(0.4),
text=phase["name"], font_size=13, bold=True, text=phase["name"], font_size=11, bold=True,
) )
# Phase bar # Colored phase bar with duration
bar = self._add_rect( bar = self._add_rect(
slide, bar_left, y + Inches(0.05), slide, bar_left, y + Inches(0.02),
bar_width * 0.9, Inches(0.4), bar_width * 0.9, Inches(0.36),
fill_color=color, fill_color=color,
) )
bar.text_frame.paragraphs[0].text = phase.get("weeks", "") bar.text_frame.paragraphs[0].text = duration
bar.text_frame.paragraphs[0].font.size = Pt(12) bar.text_frame.paragraphs[0].font.size = Pt(11)
bar.text_frame.paragraphs[0].font.color.rgb = Colors.WHITE bar.text_frame.paragraphs[0].font.color.rgb = Colors.WHITE
bar.text_frame.paragraphs[0].font.name = self.FONT bar.text_frame.paragraphs[0].font.name = self.FONT
bar.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER bar.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
# Tasks below bar # Milestones/tasks below bar (compact)
if phase.get("tasks"): if milestones:
tasks_text = "".join(phase["tasks"][:4]) tasks_text = "".join(str(m) for m in milestones[:4])
self._add_textbox( self._add_textbox(
slide, bar_left, y + Inches(0.48), slide, bar_left, y + Inches(0.40),
bar_width, Inches(0.38), bar_width, Inches(0.30),
text=tasks_text, font_size=11, italic=True, text=tasks_text, font_size=9, italic=True,
color=Colors.SECONDARY_TEXT, color=Colors.SECONDARY_TEXT,
) )
y += Inches(1.1) y += Inches(step)
# Tools # Tools
if tools: if tools:
y += Inches(0.2) y = max(y, Inches(1.3 + avail)) + Inches(0.15)
self._add_textbox( self._add_textbox(
slide, self.MARGIN, y, slide, self.MARGIN, y,
Inches(12), Inches(0.35), Inches(12), Inches(0.35),
text=f"Migration Tools: {', '.join(tools)}", text=f"Migration Tools: {', '.join(tools[:4])}",
font_size=11, bold=True, color=Colors.TEAL, font_size=10, bold=True, color=Colors.TEAL,
) )
y += Inches(0.35)
# Downtime approach # Downtime approach
if downtime: if downtime:
y += Inches(0.5) if not tools:
y = max(y, Inches(1.3 + avail)) + Inches(0.15)
self._add_textbox( self._add_textbox(
slide, self.MARGIN, y, slide, self.MARGIN, y,
Inches(12), Inches(0.35), Inches(12), Inches(0.35),
text=f"Downtime Approach: {downtime}", text=f"Downtime Approach: {downtime}",
font_size=11, color=Colors.PRIMARY_TEXT, font_size=10, color=Colors.PRIMARY_TEXT,
) )
def add_operational_raci_slide(self, raci_items: list, def add_operational_raci_slide(self, raci_items: list,