mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 09:37:23 +00:00
1 line
87 KiB
XML
1 line
87 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" data-diagram-type="CLASS" height="1466px" preserveAspectRatio="none" style="width:5567px;height:1466px;background:#FAFCF9;" version="1.1" viewBox="0 0 5567 1466" width="5567px" zoomAndPan="magnify"><?plantuml 1.2026.3?><defs/><g><rect fill="#FAFCF9" height="1466" style="stroke:none;stroke-width:1;" width="5567" x="0" y="0"/><g class="title" data-source-line="25"><text fill="#28342A" font-family="'Volkhov'" font-size="20" font-weight="700" lengthAdjust="spacing" textLength="443.18" x="2558.5157" y="29.42">The Biergarten Data Pipeline - Class Diagram</text></g><!--class BiergartenPipelineOrchestrator--><g class="entity" data-qualified-name="BiergartenPipelineOrchestrator" data-source-line="27" id="ent0002"><rect fill="#FAFCF9" height="281.192" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="441.7737" x="3151.45" y="53.8"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="441.7737" x="3151.45" y="53.8"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="441.7737" x="3151.45" y="79.528"/><rect fill="none" height="281.192" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="441.7737" x="3151.45" y="53.8"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="201.9644" x="3271.3547" y="72.688">BiergartenPipelineOrchestrator</text><line style="stroke:#547461;stroke-width:0.5;" x1="3152.45" x2="3592.2237" y1="82.028" y2="82.028"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="93.642"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="223.0099" x="3170.45" y="99.916">logger_ : std::shared_ptr<ILogger></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="111.87"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="366.6779" x="3170.45" y="118.144">context_service_ : std::unique_ptr<IEnrichmentService></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="130.098"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="294.8859" x="3170.45" y="136.372">generator_ : std::unique_ptr<DataGenerator></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="148.326"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="284.2809" x="3170.45" y="154.6">exporter_ : std::unique_ptr<IExportService></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="166.554"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="415.2299" x="3170.45" y="172.828">curated_data_service_ : std::unique_ptr<ICuratedDataService></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="184.782"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="276.4022" x="3170.45" y="191.056">application_options_ : ApplicationOptions</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="203.01"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="343.9246" x="3170.45" y="209.284">generated_breweries_ : std::vector<BreweryRecord></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="221.238"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="291.2669" x="3170.45" y="227.512">generated_users_ : std::vector<UserRecord></text><line style="stroke:#547461;stroke-width:0.5;" x1="3152.45" x2="3592.2237" y1="235.852" y2="235.852"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3162.45" cy="250.466" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="73.5806" x="3170.45" y="253.74">Run() : bool</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="265.694"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="332.658" x="3170.45" y="271.968">QueryCitiesWithCountries() : std::vector<Location></text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="283.922"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="416.7737" x="3170.45" y="290.196">GenerateBreweries(cities : std::span<const EnrichedCity>) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="302.15"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="389.4247" x="3170.45" y="308.424">GenerateUsers(cities : std::span<const EnrichedCity>) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3159.45" y="320.378"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="118.9687" x="3170.45" y="326.652">LogResults() : void</text></g><!--class LogLevel--><g class="entity" data-qualified-name="LogLevel" data-source-line="43" id="ent0003"><rect fill="#FAFCF9" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="97.144" x="2432.77" y="1288.95"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="97.144" x="2432.77" y="1288.95"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="97.144" x="2432.77" y="1332.906"/><rect fill="none" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="97.144" x="2432.77" y="1288.95"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="95.144" x="2433.77" y="1307.838">«enumeration»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="57.2636" x="2452.7102" y="1326.066">LogLevel</text><line style="stroke:#547461;stroke-width:0.5;" x1="2433.77" x2="2528.914" y1="1335.406" y2="1335.406"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="42.1925" x="2438.77" y="1353.294">Debug</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="24.3636" x="2438.77" y="1371.522">Info</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.3736" x="2438.77" y="1389.75">Warn</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="31.7487" x="2438.77" y="1407.978">Error</text><line style="stroke:#547461;stroke-width:0.5;" x1="2433.77" x2="2528.914" y1="1416.318" y2="1416.318"/></g><!--class PipelinePhase--><g class="entity" data-qualified-name="PipelinePhase" data-source-line="50" id="ent0004"><rect fill="#FAFCF9" height="190.052" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="193.3283" x="2578.68" y="1261.61"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="193.3283" x="2578.68" y="1261.61"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="193.3283" x="2578.68" y="1305.566"/><rect fill="none" height="190.052" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="193.3283" x="2578.68" y="1261.61"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="95.144" x="2627.7721" y="1280.498">«enumeration»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="89.4356" x="2630.6264" y="1298.726">PipelinePhase</text><line style="stroke:#547461;stroke-width:0.5;" x1="2579.68" x2="2771.0083" y1="1308.066" y2="1308.066"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="48.6816" x="2584.68" y="1325.954">Startup</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="101.8642" x="2584.68" y="1344.182">UserGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="181.3283" x="2584.68" y="1362.41">BreweryAndBeerGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="125.0097" x="2584.68" y="1380.638">CheckinGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="113.1377" x="2584.68" y="1398.866">RatingGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="113.5472" x="2584.68" y="1417.094">FollowGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="64.3931" x="2584.68" y="1435.322">Teardown</text><line style="stroke:#547461;stroke-width:0.5;" x1="2579.68" x2="2771.0083" y1="1443.662" y2="1443.662"/></g><!--class LogDTO--><g class="entity" data-qualified-name="LogDTO" data-source-line="60" id="ent0005"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="164.1286" x="2363.28" y="1055.35"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="164.1286" x="2363.28" y="1055.35"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="164.1286" x="2363.28" y="1081.078"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="164.1286" x="2363.28" y="1055.35"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="51.8139" x="2419.4373" y="1074.238">LogDTO</text><line style="stroke:#547461;stroke-width:0.5;" x1="2364.28" x2="2526.4086" y1="1083.578" y2="1083.578"/><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2374.28" cy="1098.192" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="97.0657" x="2382.28" y="1101.466">level : LogLevel</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2374.28" cy="1116.42" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="139.1286" x="2382.28" y="1119.694">phase : PipelinePhase</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2374.28" cy="1134.648" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="131.9748" x="2382.28" y="1137.922">message : std::string</text><line style="stroke:#547461;stroke-width:0.5;" x1="2364.28" x2="2526.4086" y1="1146.262" y2="1146.262"/></g><!--class LogEntry--><g class="entity" data-qualified-name="LogEntry" data-source-line="66" id="ent0006"><rect fill="#FAFCF9" height="153.596" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="353.9828" x="2562.35" y="1028.01"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="353.9828" x="2562.35" y="1028.01"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="353.9828" x="2562.35" y="1053.738"/><rect fill="none" height="153.596" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="353.9828" x="2562.35" y="1028.01"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="57.8762" x="2710.4033" y="1046.898">LogEntry</text><line style="stroke:#547461;stroke-width:0.5;" x1="2563.35" x2="2915.3328" y1="1056.238" y2="1056.238"/><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2573.35" cy="1070.852" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="328.9828" x="2581.35" y="1074.126">timestamp : std::chrono::system_clock::time_point</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2573.35" cy="1089.08" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="179.2073" x="2581.35" y="1092.354">origin : std::source_location</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2573.35" cy="1107.308" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="162.4842" x="2581.35" y="1110.582">thread_id : std::thread::id</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2573.35" cy="1125.536" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="97.0657" x="2581.35" y="1128.81">level : LogLevel</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2573.35" cy="1143.764" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="139.1286" x="2581.35" y="1147.038">phase : PipelinePhase</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="2573.35" cy="1161.992" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="131.9748" x="2581.35" y="1165.266">message : std::string</text><line style="stroke:#547461;stroke-width:0.5;" x1="2563.35" x2="2915.3328" y1="1173.606" y2="1173.606"/></g><!--class ILogger--><g class="entity" data-qualified-name="ILogger" data-source-line="75" id="ent0007"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="218.438" x="2729.12" y="433.22"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="218.438" x="2729.12" y="433.22"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="218.438" x="2729.12" y="477.176"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="218.438" x="2729.12" y="433.22"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="2802.765" y="452.108">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="47.684" x="2814.497" y="470.336">ILogger</text><line style="stroke:#547461;stroke-width:0.5;" x1="2730.12" x2="2946.558" y1="479.676" y2="479.676"/><line style="stroke:#547461;stroke-width:0.5;" x1="2730.12" x2="2946.558" y1="487.676" y2="487.676"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2740.12" cy="502.29" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="186.0882" x="2748.12" y="505.564">Log(payload : LogDTO) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2737.12" y="517.518"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="193.438" x="2748.12" y="523.792">DoLog(entry : LogEntry) : void</text></g><!--class LogProducer--><g class="entity" data-qualified-name="LogProducer" data-source-line="80" id="ent0008"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="290.0167" x="2354.33" y="748.85"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="290.0167" x="2354.33" y="748.85"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="290.0167" x="2354.33" y="774.578"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="290.0167" x="2354.33" y="748.85"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="83.0307" x="2457.823" y="767.738">LogProducer</text><line style="stroke:#547461;stroke-width:0.5;" x1="2355.33" x2="2643.3467" y1="777.078" y2="777.078"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2362.33" y="788.692"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="265.0167" x="2373.33" y="794.966">channel_ : BoundedChannel<LogEntry>&</text><line style="stroke:#547461;stroke-width:0.5;" x1="2355.33" x2="2643.3467" y1="803.306" y2="803.306"/><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2362.33" y="814.92"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="192.5179" x="2373.33" y="821.194">DoLog(entry : LogEntry) : void</text></g><!--class LogDispatcher--><g class="entity" data-qualified-name="LogDispatcher" data-source-line="85" id="ent0009"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="329.9764" x="2679.35" y="739.73"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="329.9764" x="2679.35" y="739.73"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="329.9764" x="2679.35" y="765.458"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="329.9764" x="2679.35" y="739.73"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="94.5561" x="2797.0601" y="758.618">LogDispatcher</text><line style="stroke:#547461;stroke-width:0.5;" x1="2680.35" x2="3008.3264" y1="767.958" y2="767.958"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2687.35" y="779.572"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="265.0167" x="2698.35" y="785.846">channel_ : BoundedChannel<LogEntry>&</text><line style="stroke:#547461;stroke-width:0.5;" x1="2680.35" x2="3008.3264" y1="794.186" y2="794.186"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2690.35" cy="808.8" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="72.8876" x="2698.35" y="812.074">Run() : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2687.35" y="824.028"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="304.9764" x="2698.35" y="830.302">ToSpdlogLevel(level) : spdlog::level::level_enum</text></g><!--class IEnrichmentService--><g class="entity" data-qualified-name="IEnrichmentService" data-source-line="91" id="ent0010"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="3182.67" y="442.34"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="3182.67" y="442.34"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="3182.67" y="486.296"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="3182.67" y="442.34"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="3336.7611" y="461.228">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="125.692" x="3309.4891" y="479.456">IEnrichmentService</text><line style="stroke:#547461;stroke-width:0.5;" x1="3183.67" x2="3561.0002" y1="488.796" y2="488.796"/><line style="stroke:#547461;stroke-width:0.5;" x1="3183.67" x2="3561.0002" y1="496.796" y2="496.796"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3193.67" cy="511.41" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="354.3302" x="3201.67" y="514.684">GetLocationContext(loc : const Location&) : std::string</text></g><!--class MockEnrichmentService--><g class="entity" data-qualified-name="MockEnrichmentService" data-source-line="95" id="ent0011"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="3044.67" y="757.96"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="3044.67" y="757.96"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="3044.67" y="783.688"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="3044.67" y="757.96"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="157.5527" x="3155.5588" y="776.848">MockEnrichmentService</text><line style="stroke:#547461;stroke-width:0.5;" x1="3045.67" x2="3423.0002" y1="786.188" y2="786.188"/><line style="stroke:#547461;stroke-width:0.5;" x1="3045.67" x2="3423.0002" y1="794.188" y2="794.188"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3055.67" cy="808.802" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="354.3302" x="3063.67" y="812.076">GetLocationContext(loc : const Location&) : std::string</text></g><!--class WikipediaEnrichmentService--><g class="entity" data-qualified-name="WikipediaEnrichmentService" data-source-line="99" id="ent0012"><rect fill="#FAFCF9" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="422.6147" x="3459.03" y="730.62"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="422.6147" x="3459.03" y="730.62"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="422.6147" x="3459.03" y="756.348"/><rect fill="none" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="422.6147" x="3459.03" y="730.62"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="186.1932" x="3577.2407" y="749.508">WikipediaEnrichmentService</text><line style="stroke:#547461;stroke-width:0.5;" x1="3460.03" x2="3880.6447" y1="758.848" y2="758.848"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3467.03" y="770.462"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="238.9101" x="3478.03" y="776.736">client_ : std::unique_ptr<WebClient></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3467.03" y="788.69"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="397.6147" x="3478.03" y="794.964">extract_cache_ : std::unordered_map<std::string, std::string></text><line style="stroke:#547461;stroke-width:0.5;" x1="3460.03" x2="3880.6447" y1="803.304" y2="803.304"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3470.03" cy="817.918" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="354.3302" x="3478.03" y="821.192">GetLocationContext(loc : const Location&) : std::string</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3467.03" y="833.146"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="318.5638" x="3478.03" y="839.42">FetchExtract(query : std::string_view) : std::string</text></g><!--class WebClient--><g class="entity" data-qualified-name="WebClient" data-source-line="106" id="ent0013"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="3502.82" y="1055.35"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="3502.82" y="1055.35"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="3502.82" y="1099.306"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="3502.82" y="1055.35"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="3634.7631" y="1074.238">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="68.222" x="3636.2261" y="1092.466">WebClient</text><line style="stroke:#547461;stroke-width:0.5;" x1="3503.82" x2="3836.8542" y1="1101.806" y2="1101.806"/><line style="stroke:#547461;stroke-width:0.5;" x1="3503.82" x2="3836.8542" y1="1109.806" y2="1109.806"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3513.82" cy="1124.42" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.8552" x="3521.82" y="1127.694">Get(url : const std::string&) : std::string</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3513.82" cy="1142.648" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="310.0342" x="3521.82" y="1145.922">UrlEncode(value : const std::string&) : std::string</text></g><!--class HttpWebClient--><g class="entity" data-qualified-name="HttpWebClient" data-source-line="111" id="ent0014"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="3502.82" y="1316.29"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="3502.82" y="1316.29"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="3502.82" y="1342.018"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="3502.82" y="1316.29"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="97.5276" x="3621.5733" y="1335.178">HttpWebClient</text><line style="stroke:#547461;stroke-width:0.5;" x1="3503.82" x2="3836.8542" y1="1344.518" y2="1344.518"/><line style="stroke:#547461;stroke-width:0.5;" x1="3503.82" x2="3836.8542" y1="1352.518" y2="1352.518"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3513.82" cy="1367.132" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.8552" x="3521.82" y="1370.406">Get(url : const std::string&) : std::string</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3513.82" cy="1385.36" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="310.0342" x="3521.82" y="1388.634">UrlEncode(value : const std::string&) : std::string</text></g><!--class DataGenerator--><g class="entity" data-qualified-name="DataGenerator" data-source-line="116" id="ent0015"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="717.8332" x="3916.42" y="433.22"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="717.8332" x="3916.42" y="433.22"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="717.8332" x="3916.42" y="477.176"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="717.8332" x="3916.42" y="433.22"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="4239.7626" y="452.108">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="97.062" x="4226.8056" y="470.336">DataGenerator</text><line style="stroke:#547461;stroke-width:0.5;" x1="3917.42" x2="4633.2532" y1="479.676" y2="479.676"/><line style="stroke:#547461;stroke-width:0.5;" x1="3917.42" x2="4633.2532" y1="487.676" y2="487.676"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3927.42" cy="502.29" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="628.8885" x="3935.42" y="505.564">GenerateBrewery(location : const Location&, region_context : const std::string&) : BreweryResult</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3927.42" cy="520.518" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="692.8332" x="3935.42" y="523.792">GenerateUser(city : const EnrichedCity&, persona : const UserPersona&, name : const Name&) : UserResult</text></g><!--class MockGenerator--><g class="entity" data-qualified-name="MockGenerator" data-source-line="121" id="ent0016"><rect fill="#FAFCF9" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="717.8332" x="3916.42" y="730.62"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="717.8332" x="3916.42" y="730.62"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="717.8332" x="3916.42" y="756.348"/><rect fill="none" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="717.8332" x="3916.42" y="730.62"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="101.4686" x="4224.6023" y="749.508">MockGenerator</text><line style="stroke:#547461;stroke-width:0.5;" x1="3917.42" x2="4633.2532" y1="758.848" y2="758.848"/><line style="stroke:#547461;stroke-width:0.5;" x1="3917.42" x2="4633.2532" y1="766.848" y2="766.848"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3927.42" cy="781.462" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="628.8885" x="3935.42" y="784.736">GenerateBrewery(location : const Location&, region_context : const std::string&) : BreweryResult</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="3927.42" cy="799.69" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="692.8332" x="3935.42" y="802.964">GenerateUser(city : const EnrichedCity&, persona : const UserPersona&, name : const Name&) : UserResult</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3924.42" y="814.918"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="349.5106" x="3935.42" y="821.192">DeterministicHash(location : const Location&) : size_t</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="3924.42" y="833.146"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="692.5602" x="3935.42" y="839.42">DeterministicHash(location : const Location&, persona : const UserPersona&, name : const Name&) : size_t</text></g><!--class LlamaGenerator--><g class="entity" data-qualified-name="LlamaGenerator" data-source-line="128" id="ent0017"><rect fill="#FAFCF9" height="226.508" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="397.138" x="4668.77" y="675.93"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="397.138" x="4668.77" y="675.93"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="397.138" x="4668.77" y="701.658"/><rect fill="none" height="226.508" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="397.138" x="4668.77" y="675.93"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="104.5242" x="4815.0769" y="694.818">LlamaGenerator</text><line style="stroke:#547461;stroke-width:0.5;" x1="4669.77" x2="5064.908" y1="704.158" y2="704.158"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="715.772"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="145.1239" x="4687.77" y="722.046">model_ : ModelHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="734"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="167.0061" x="4687.77" y="740.274">context_ : ContextHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="752.228"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="372.138" x="4687.77" y="758.502">prompt_formatter_ : std::unique_ptr<IPromptFormatter></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="770.456"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="365.4283" x="4687.77" y="776.73">prompt_directory_ : std::unique_ptr<IPromptDirectory></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="788.684"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="123.1442" x="4687.77" y="794.958">rng_ : std::mt19937</text><line style="stroke:#547461;stroke-width:0.5;" x1="4669.77" x2="5064.908" y1="803.298" y2="803.298"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4679.77" cy="817.912" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="236.0966" x="4687.77" y="821.186">GenerateBrewery(...) : BreweryResult</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4679.77" cy="836.14" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="188.4403" x="4687.77" y="839.414">GenerateUser(...) : UserResult</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="851.368"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="285.3309" x="4687.77" y="857.642">Load(model_path : const std::string&) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="869.596"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="122.0454" x="4687.77" y="875.87">Infer(...) : std::string</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4676.77" y="887.824"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="190.817" x="4687.77" y="894.098">InferFormatted(...) : std::string</text></g><!--class IPromptFormatter--><g class="entity" data-qualified-name="IPromptFormatter" data-source-line="141" id="ent0018"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="4185.26" y="1064.47"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="4185.26" y="1064.47"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="4185.26" y="1108.426"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="4185.26" y="1064.47"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="4439.7663" y="1083.358">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="116.48" x="4417.1003" y="1101.586">IPromptFormatter</text><line style="stroke:#547461;stroke-width:0.5;" x1="4186.26" x2="4764.4205" y1="1110.926" y2="1110.926"/><line style="stroke:#547461;stroke-width:0.5;" x1="4186.26" x2="4764.4205" y1="1118.926" y2="1118.926"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4196.26" cy="1133.54" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="555.1605" x="4204.26" y="1136.814">Format(system_prompt : std::string_view, user_prompt : std::string_view) : std::string</text></g><!--class Gemma4JinjaPromptFormatter--><g class="entity" data-qualified-name="Gemma4JinjaPromptFormatter" data-source-line="145" id="ent0019"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="4174.26" y="1325.41"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="4174.26" y="1325.41"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="4174.26" y="1351.138"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="4174.26" y="1325.41"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="202.5557" x="4363.0624" y="1344.298">Gemma4JinjaPromptFormatter</text><line style="stroke:#547461;stroke-width:0.5;" x1="4175.26" x2="4753.4205" y1="1353.638" y2="1353.638"/><line style="stroke:#547461;stroke-width:0.5;" x1="4175.26" x2="4753.4205" y1="1361.638" y2="1361.638"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4185.26" cy="1376.252" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="555.1605" x="4193.26" y="1379.526">Format(system_prompt : std::string_view, user_prompt : std::string_view) : std::string</text></g><!--class IPromptDirectory--><g class="entity" data-qualified-name="IPromptDirectory" data-source-line="149" id="ent0020"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="277.1055" x="4822.79" y="1064.47"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="277.1055" x="4822.79" y="1064.47"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="277.1055" x="4822.79" y="1108.426"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="277.1055" x="4822.79" y="1064.47"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="4925.7688" y="1083.358">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="112.49" x="4905.0978" y="1101.586">IPromptDirectory</text><line style="stroke:#547461;stroke-width:0.5;" x1="4823.79" x2="5098.8955" y1="1110.926" y2="1110.926"/><line style="stroke:#547461;stroke-width:0.5;" x1="4823.79" x2="5098.8955" y1="1118.926" y2="1118.926"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4833.79" cy="1133.54" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="252.1055" x="4841.79" y="1136.814">Load(key : std::string_view) : std::string</text></g><!--class PromptDirectory--><g class="entity" data-qualified-name="PromptDirectory" data-source-line="153" id="ent0021"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="366.6985" x="4788.99" y="1307.18"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="366.6985" x="4788.99" y="1307.18"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="366.6985" x="4788.99" y="1332.908"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="366.6985" x="4788.99" y="1307.18"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="109.2106" x="4917.7339" y="1326.068">PromptDirectory</text><line style="stroke:#547461;stroke-width:0.5;" x1="4789.99" x2="5154.6885" y1="1335.408" y2="1335.408"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4796.99" y="1347.022"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="224.5147" x="4807.99" y="1353.296">prompt_dir_ : std::filesystem::path</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="4796.99" y="1365.25"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="341.6985" x="4807.99" y="1371.524">cache_ : std::unordered_map<std::string, std::string></text><line style="stroke:#547461;stroke-width:0.5;" x1="4789.99" x2="5154.6885" y1="1379.864" y2="1379.864"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4799.99" cy="1394.478" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="252.1055" x="4807.99" y="1397.752">Load(key : std::string_view) : std::string</text></g><!--class ICuratedDataService--><g class="entity" data-qualified-name="ICuratedDataService" data-source-line="159" id="ent0022"><rect fill="#FAFCF9" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="818.679" x="1191" y="415"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="818.679" x="1191" y="415"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="818.679" x="1191" y="458.956"/><rect fill="none" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="818.679" x="1191" y="415"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="1564.7655" y="433.888">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="135.254" x="1532.7125" y="452.116">ICuratedDataService</text><line style="stroke:#547461;stroke-width:0.5;" x1="1192" x2="2008.679" y1="461.456" y2="461.456"/><line style="stroke:#547461;stroke-width:0.5;" x1="1192" x2="2008.679" y1="469.456" y2="469.456"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="484.07" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="547.9401" x="1210" y="487.344">LoadLocations(filepath : const std::filesystem::path&) : const std::vector<Location>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="502.298" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="568.8176" x="1210" y="505.572">LoadPersonas(filepath : const std::filesystem::path&) : const std::vector<UserPersona>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="520.526" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="793.679" x="1210" y="523.8">LoadForenamesByCountry(filepath : const std::filesystem::path&) : const std::unordered_map<std::string, forename_list>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="538.754" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="780.106" x="1210" y="542.028">LoadSurnamesByCountry(filepath : const std::filesystem::path&) : const std::unordered_map<std::string, surname_list>&</text></g><!--class JsonLoader--><g class="entity" data-qualified-name="JsonLoader" data-source-line="166" id="ent0023"><rect fill="#FAFCF9" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="818.679" x="7" y="721.5"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="818.679" x="7" y="721.5"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="818.679" x="7" y="747.228"/><rect fill="none" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="818.679" x="7" y="721.5"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="75.5861" x="378.5465" y="740.388">JsonLoader</text><line style="stroke:#547461;stroke-width:0.5;" x1="8" x2="824.679" y1="749.728" y2="749.728"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="15" y="761.342"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="98.7701" x="26" y="767.616">cache_ : cache</text><line style="stroke:#547461;stroke-width:0.5;" x1="8" x2="824.679" y1="775.956" y2="775.956"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="18" cy="790.57" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="547.9401" x="26" y="793.844">LoadLocations(filepath : const std::filesystem::path&) : const std::vector<Location>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="18" cy="808.798" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="568.8176" x="26" y="812.072">LoadPersonas(filepath : const std::filesystem::path&) : const std::vector<UserPersona>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="18" cy="827.026" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="793.679" x="26" y="830.3">LoadForenamesByCountry(filepath : const std::filesystem::path&) : const std::unordered_map<std::string, forename_list>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="18" cy="845.254" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="780.106" x="26" y="848.528">LoadSurnamesByCountry(filepath : const std::filesystem::path&) : const std::unordered_map<std::string, surname_list>&</text></g><g class="entity" data-qualified-name="GMN24" data-source-line="175" id="ent0025"><path d="M860.96,747.73 L860.96,830.642 L1155.7268,830.642 L1155.7268,757.73 L1145.7268,747.73 L860.96,747.73" fill="#EAF0E8" style="stroke:#547461;stroke-width:0.5;"/><path d="M1145.7268,747.73 L1145.7268,757.73 L1155.7268,757.73 L1145.7268,747.73" fill="#EAF0E8" style="stroke:#547461;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="273.7668" x="866.96" y="766.618">Each Load* method memoizes its result in</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="238.2" x="866.96" y="784.846">cache_ on first call; later calls on the</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="253.0399" x="866.96" y="803.074">same instance return the cached value</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="124.3658" x="866.96" y="821.302">without re-parsing.</text></g><!--class MockCuratedDataService--><g class="entity" data-qualified-name="MockCuratedDataService" data-source-line="181" id="ent0027"><rect fill="#FAFCF9" height="190.052" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="818.679" x="1191" y="694.16"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="818.679" x="1191" y="694.16"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="818.679" x="1191" y="719.888"/><rect fill="none" height="190.052" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="818.679" x="1191" y="694.16"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="166.5267" x="1517.0762" y="713.048">MockCuratedDataService</text><line style="stroke:#547461;stroke-width:0.5;" x1="1192" x2="2008.679" y1="722.388" y2="722.388"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1199" y="734.002"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="219.8879" x="1210" y="740.276">locations_ : std::vector<Location></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1199" y="752.23"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="245.6619" x="1210" y="758.504">personas_ : std::vector<UserPersona></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1199" y="770.458"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="483.921" x="1210" y="776.732">forenames_by_country_ : std::unordered_map<std::string, forename_list></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1199" y="788.686"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="471.993" x="1210" y="794.96">surnames_by_country_ : std::unordered_map<std::string, surname_list></text><line style="stroke:#547461;stroke-width:0.5;" x1="1192" x2="2008.679" y1="803.3" y2="803.3"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="817.914" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="547.9401" x="1210" y="821.188">LoadLocations(filepath : const std::filesystem::path&) : const std::vector<Location>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="836.142" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="568.8176" x="1210" y="839.416">LoadPersonas(filepath : const std::filesystem::path&) : const std::vector<UserPersona>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="854.37" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="793.679" x="1210" y="857.644">LoadForenamesByCountry(filepath : const std::filesystem::path&) : const std::unordered_map<std::string, forename_list>&</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1202" cy="872.598" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="780.106" x="1210" y="875.872">LoadSurnamesByCountry(filepath : const std::filesystem::path&) : const std::unordered_map<std::string, surname_list>&</text></g><g class="entity" data-qualified-name="GMN28" data-source-line="193" id="ent0029"><path d="M2045.09,756.85 L2045.09,821.534 L2319.5812,821.534 L2319.5812,766.85 L2309.5812,756.85 L2045.09,756.85" fill="#EAF0E8" style="stroke:#547461;stroke-width:0.5;"/><path d="M2309.5812,756.85 L2309.5812,766.85 L2319.5812,766.85 L2309.5812,756.85" fill="#EAF0E8" style="stroke:#547461;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="241.9063" x="2051.09" y="775.738">Fixed 4-location / 3-persona dataset</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="253.4912" x="2051.09" y="793.966">(US, DE, FR, BE) used in --mocked runs;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="202.8184" x="2051.09" y="812.194">filepath arguments are ignored.</text></g><!--class IExportService--><g class="entity" data-qualified-name="IExportService" data-source-line="198" id="ent0031"><rect fill="#FAFCF9" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="415.1177" x="4813.78" y="415"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="415.1177" x="4813.78" y="415"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="415.1177" x="4813.78" y="458.956"/><rect fill="none" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="415.1177" x="4813.78" y="415"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="4985.7649" y="433.888">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="93.786" x="4974.4459" y="452.116">IExportService</text><line style="stroke:#547461;stroke-width:0.5;" x1="4814.78" x2="5227.8977" y1="461.456" y2="461.456"/><line style="stroke:#547461;stroke-width:0.5;" x1="4814.78" x2="5227.8977" y1="469.456" y2="469.456"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4824.78" cy="484.07" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="100.4677" x="4832.78" y="487.344">Initialize() : void</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4824.78" cy="502.298" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="390.1177" x="4832.78" y="505.572">ProcessRecord(brewery : const BreweryRecord&) : uint64_t</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4824.78" cy="520.526" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="340.981" x="4832.78" y="523.8">ProcessRecord(user : const UserRecord&) : uint64_t</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="4824.78" cy="538.754" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="95.8547" x="4832.78" y="542.028">Finalize() : void</text></g><!--class SqliteExportService--><g class="entity" data-qualified-name="SqliteExportService" data-source-line="205" id="ent0032"><rect fill="#FAFCF9" height="317.648" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="451.7415" x="5100.47" y="630.36"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="451.7415" x="5100.47" y="630.36"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="451.7415" x="5100.47" y="656.088"/><rect fill="none" height="317.648" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="451.7415" x="5100.47" y="630.36"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="127.3512" x="5262.6651" y="649.248">SqliteExportService</text><line style="stroke:#547461;stroke-width:0.5;" x1="5101.47" x2="5551.2115" y1="658.588" y2="658.588"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="670.202"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="387.0232" x="5119.47" y="676.476">date_time_provider_ : std::unique_ptr<IDateTimeProvider></text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="688.43"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="215.2222" x="5119.47" y="694.704">run_timestamp_utc_ : std::string</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="706.658"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.0218" x="5119.47" y="712.932">database_path_ : std::filesystem::path</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="724.886"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="233.4325" x="5119.47" y="731.16">db_handle_ : SqliteDatabaseHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="743.114"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="308.1823" x="5119.47" y="749.388">insert_location_stmt_ : SqliteStatementHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="761.342"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="309.4563" x="5119.47" y="767.616">insert_brewery_stmt_ : SqliteStatementHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="779.57"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="284.1477" x="5119.47" y="785.844">insert_user_stmt_ : SqliteStatementHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="797.798"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="164.4616" x="5119.47" y="804.072">transaction_open_ : bool</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="816.026"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="426.7415" x="5119.47" y="822.3">location_cache_ : std::unordered_map<std::string, sqlite3_int64></text><line style="stroke:#547461;stroke-width:0.5;" x1="5101.47" x2="5551.2115" y1="830.64" y2="830.64"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="5111.47" cy="845.254" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="100.4677" x="5119.47" y="848.528">Initialize() : void</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="5111.47" cy="863.482" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="390.1177" x="5119.47" y="866.756">ProcessRecord(brewery : const BreweryRecord&) : uint64_t</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="5111.47" cy="881.71" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="340.981" x="5119.47" y="884.984">ProcessRecord(user : const UserRecord&) : uint64_t</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="5111.47" cy="899.938" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="95.8547" x="5119.47" y="903.212">Finalize() : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="915.166"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="152.6842" x="5119.47" y="921.44">InitializeSchema() : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="5108.47" y="933.394"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="396.5051" x="5119.47" y="939.668">ResolveLocationId(location : const Location&) : sqlite3_int64</text></g><!--class IDateTimeProvider--><g class="entity" data-qualified-name="IDateTimeProvider" data-source-line="223" id="ent0033"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="5211.71" y="1064.47"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="5211.71" y="1064.47"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="5211.71" y="1108.426"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="5211.71" y="1064.47"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="5290.7697" y="1083.358">«interface»</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="120.176" x="5266.2557" y="1101.586">IDateTimeProvider</text><line style="stroke:#547461;stroke-width:0.5;" x1="5212.71" x2="5439.9773" y1="1110.926" y2="1110.926"/><line style="stroke:#547461;stroke-width:0.5;" x1="5212.71" x2="5439.9773" y1="1118.926" y2="1118.926"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="5222.71" cy="1133.54" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="204.2673" x="5230.71" y="1136.814">GetUtcTimestamp() : std::string</text></g><!--class SystemDateTimeProvider--><g class="entity" data-qualified-name="SystemDateTimeProvider" data-source-line="227" id="ent0034"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="5211.71" y="1325.41"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="5211.71" y="1325.41"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="5211.71" y="1351.138"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="5211.71" y="1325.41"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="165.4241" x="5243.6316" y="1344.298">SystemDateTimeProvider</text><line style="stroke:#547461;stroke-width:0.5;" x1="5212.71" x2="5439.9773" y1="1353.638" y2="1353.638"/><line style="stroke:#547461;stroke-width:0.5;" x1="5212.71" x2="5439.9773" y1="1361.638" y2="1361.638"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="5222.71" cy="1376.252" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="204.2673" x="5230.71" y="1379.526">GetUtcTimestamp() : std::string</text></g><!--link JsonLoader to GMN24--><g class="link" data-entity-1="ent0023" data-entity-2="ent0025" data-link-type="association" data-source-line="175" id="lnk26"><path d="M825.94,789.19 C837.46,789.19 848.98,789.19 860.5,789.19" fill="none" id="JsonLoader-GMN24" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/></g><!--link MockCuratedDataService to GMN28--><g class="link" data-entity-1="ent0027" data-entity-2="ent0029" data-link-type="association" data-source-line="193" id="lnk30"><path d="M2010.13,789.19 C2021.67,789.19 2033.22,789.19 2044.77,789.19" fill="none" id="MockCuratedDataService-GMN28" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/></g><!--reverse link BiergartenPipelineOrchestrator to ILogger--><g class="link" data-entity-1="ent0002" data-entity-2="ent0007" data-link-type="composition" data-source-line="232" id="lnk35"><path codeLine="232" d="M3140.7135,319.5791 C3062.9535,361.2591 2990.41,400.15 2929.39,432.87" fill="none" id="BiergartenPipelineOrchestrator-backto-ILogger" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="3151.29,313.91,3144.1121,313.219,3140.7135,319.5791,3147.8915,320.27,3151.29,313.91" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="3042.81" y="379.888">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to IEnrichmentService--><g class="link" data-entity-1="ent0002" data-entity-2="ent0010" data-link-type="composition" data-source-line="233" id="lnk36"><path codeLine="233" d="M3372.34,347.19 C3372.34,386.36 3372.34,413.87 3372.34,441.97" fill="none" id="BiergartenPipelineOrchestrator-backto-IEnrichmentService" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="3372.34,335.19,3368.34,341.19,3372.34,347.19,3376.34,341.19,3372.34,335.19" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="3373.34" y="379.888">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to DataGenerator--><g class="link" data-entity-1="ent0002" data-entity-2="ent0015" data-link-type="composition" data-source-line="234" id="lnk37"><path codeLine="234" d="M3604.9688,269.1468 C3768.6588,321.0468 3976.08,386.8 4121.17,432.8" fill="none" id="BiergartenPipelineOrchestrator-backto-DataGenerator" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="3593.53,265.52,3598.0405,271.1463,3604.9688,269.1468,3600.4583,263.5205,3593.53,265.52" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="3958.48" y="379.888">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to IExportService--><g class="link" data-entity-1="ent0002" data-entity-2="ent0031" data-link-type="composition" data-source-line="235" id="lnk38"><path codeLine="235" d="M3605.511,234.8369 C3860.591,278.1069 4280.51,349.75 4651.34,415 C4703.89,424.24 4760.61,434.38 4813.48,443.91" fill="none" id="BiergartenPipelineOrchestrator-backto-IExportService" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="3593.68,232.83,3598.9265,237.7771,3605.511,234.8369,3600.2645,229.8898,3593.68,232.83" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="4478.49" y="379.888">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to ICuratedDataService--><g class="link" data-entity-1="ent0002" data-entity-2="ent0022" data-link-type="composition" data-source-line="236" id="lnk39"><path codeLine="236" d="M3139.2036,233.064 C2854.2436,279.104 2365.33,358.09 2010.01,415.49" fill="none" id="BiergartenPipelineOrchestrator-backto-ICuratedDataService" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="3151.05,231.15,3144.4888,228.1582,3139.2036,233.064,3145.7648,236.0558,3151.05,231.15" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="2276.51" y="379.888">owns</text></g><!--reverse link LogEntry to LogLevel--><g class="link" data-entity-1="ent0006" data-entity-2="ent0003" data-link-type="composition" data-source-line="238" id="lnk40"><path codeLine="238" d="M2638.2971,1189.6554 C2609.9171,1214.2854 2588.16,1234.41 2561.34,1261.61 C2550.81,1272.29 2540.05,1284.16 2529.98,1295.77" fill="none" id="LogEntry-backto-LogLevel" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2647.36,1181.79,2640.2068,1182.7017,2638.2971,1189.6554,2645.4503,1188.7436,2647.36,1181.79" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link LogEntry to PipelinePhase--><g class="link" data-entity-1="ent0006" data-entity-2="ent0004" data-link-type="composition" data-source-line="239" id="lnk41"><path codeLine="239" d="M2716.8999,1193.4041 C2710.4599,1218.5241 2706.2,1235.16 2699.46,1261.48" fill="none" id="LogEntry-backto-PipelinePhase" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2719.88,1181.78,2714.5153,1186.5987,2716.8999,1193.4041,2722.2647,1188.5854,2719.88,1181.78" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link LogDTO to LogLevel--><g class="link" data-entity-1="ent0005" data-entity-2="ent0003" data-link-type="composition" data-source-line="240" id="lnk42"><path codeLine="240" d="M2454.0801,1166.4475 C2459.5801,1204.6475 2465.59,1246.33 2471.67,1288.57" fill="none" id="LogDTO-backto-LogLevel" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2452.37,1154.57,2449.2659,1161.0788,2454.0801,1166.4475,2457.1842,1159.9387,2452.37,1154.57" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link LogDTO to PipelinePhase--><g class="link" data-entity-1="ent0005" data-entity-2="ent0004" data-link-type="composition" data-source-line="241" id="lnk43"><path codeLine="241" d="M2498.3571,1163.3989 C2526.2671,1193.7189 2554.96,1224.88 2588.41,1261.21" fill="none" id="LogDTO-backto-PipelinePhase" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2490.23,1154.57,2491.3506,1161.6935,2498.3571,1163.3989,2497.2365,1156.2754,2490.23,1154.57" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link ILogger to LogProducer--><g class="link" data-entity-1="ent0007" data-entity-2="ent0008" data-link-type="extension" data-source-line="242" id="lnk44"><path codeLine="242" d="M2763.5756,543.8721 C2729.2356,571.9021 2699.77,596.73 2662.34,630.36 C2618.98,669.33 2571.27,715.99 2538.74,748.43" fill="none" id="ILogger-backto-LogProducer" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="2777.52,532.49,2759.7815,539.224,2767.3696,548.5203,2777.52,532.49" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="2720.38" y="595.248">implements</text></g><!--link LogProducer to LogEntry--><g class="link" data-entity-1="ent0008" data-entity-2="ent0006" data-link-type="dependency" data-source-line="243" id="lnk45"><path codeLine="243" d="M2529.74,829.91 C2567.64,879.44 2629.6035,960.4152 2677.3435,1022.7952" fill="none" id="LogProducer-to-LogEntry" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#628A5B" points="2680.99,1027.56,2678.6967,1017.9819,2677.9512,1023.5894,2672.3437,1022.8439,2680.99,1027.56" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="36.2985" x="2655.86" y="992.898">emits</text></g><!--link LogDispatcher to LogEntry--><g class="link" data-entity-1="ent0009" data-entity-2="ent0006" data-link-type="dependency" data-source-line="244" id="lnk46"><path codeLine="244" d="M2828.05,838.85 C2811.17,889.26 2786.4649,963.0504 2766.7849,1021.8304" fill="none" id="LogDispatcher-to-LogEntry" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#628A5B" points="2764.88,1027.52,2771.5304,1020.2556,2766.4674,1022.7787,2763.9443,1017.7157,2764.88,1027.52" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="66.857" x="2780.35" y="992.898">consumes</text></g><!--reverse link IEnrichmentService to WikipediaEnrichmentService--><g class="link" data-entity-1="ent0010" data-entity-2="ent0012" data-link-type="extension" data-source-line="246" id="lnk47"><path codeLine="246" d="M3423.8893,536.355 C3475.4793,589.075 3554.24,669.56 3613.53,730.13" fill="none" id="IEnrichmentService-backto-WikipediaEnrichmentService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="3411.3,523.49,3419.601,540.5515,3428.1777,532.1586,3411.3,523.49" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="3486.88" y="595.248">implements</text></g><!--reverse link IEnrichmentService to MockEnrichmentService--><g class="link" data-entity-1="ent0010" data-entity-2="ent0011" data-link-type="extension" data-source-line="247" id="lnk48"><path codeLine="247" d="M3346.8694,539.8847 C3318.9594,601.4647 3273.35,702.11 3248.22,757.57" fill="none" id="IEnrichmentService-backto-MockEnrichmentService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="3354.3,523.49,3341.4045,537.4078,3352.3343,542.3616,3354.3,523.49" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="3328.7" y="595.248">implements</text></g><!--reverse link WikipediaEnrichmentService to WebClient--><g class="link" data-entity-1="ent0012" data-entity-2="ent0013" data-link-type="composition" data-source-line="248" id="lnk49"><path codeLine="248" d="M3670.34,860.08 C3670.34,919.55 3670.34,999.1 3670.34,1055.01" fill="none" id="WikipediaEnrichmentService-backto-WebClient" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="3670.34,848.08,3666.34,854.08,3670.34,860.08,3674.34,854.08,3670.34,848.08" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="3671.34" y="992.898">owns</text></g><!--reverse link WebClient to HttpWebClient--><g class="link" data-entity-1="ent0013" data-entity-2="ent0014" data-link-type="extension" data-source-line="250" id="lnk50"><path codeLine="250" d="M3670.34,1172.57 C3670.34,1219.72 3670.34,1272.26 3670.34,1316.04" fill="none" id="WebClient-backto-HttpWebClient" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="3670.34,1154.57,3664.34,1172.57,3676.34,1172.57,3670.34,1154.57" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="3671.34" y="1226.498">implements</text></g><!--reverse link DataGenerator to MockGenerator--><g class="link" data-entity-1="ent0015" data-entity-2="ent0016" data-link-type="extension" data-source-line="252" id="lnk51"><path codeLine="252" d="M4275.34,550.6 C4275.34,604.49 4275.34,673.06 4275.34,730.28" fill="none" id="DataGenerator-backto-MockGenerator" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="4275.34,532.6,4269.34,550.6,4281.34,550.6,4275.34,532.6" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="4276.34" y="595.248">implements</text></g><!--reverse link DataGenerator to LlamaGenerator--><g class="link" data-entity-1="ent0015" data-entity-2="ent0017" data-link-type="extension" data-source-line="253" id="lnk52"><path codeLine="253" d="M4443.6006,538.6541 C4513.8506,563.8841 4580.37,591.46 4651.34,630.36 C4675.57,643.65 4700.21,659.28 4723.75,675.46" fill="none" id="DataGenerator-backto-LlamaGenerator" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="4426.66,532.57,4441.5725,544.301,4445.6286,533.0073,4426.66,532.57" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="4583.43" y="595.248">implements</text></g><!--reverse link LlamaGenerator to IPromptFormatter--><g class="link" data-entity-1="ent0017" data-entity-2="ent0018" data-link-type="composition" data-source-line="255" id="lnk53"><path codeLine="255" d="M4717.2794,910.2462 C4646.7894,966.6362 4575.28,1023.86 4524.74,1064.29" fill="none" id="LlamaGenerator-backto-IPromptFormatter" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="4726.65,902.75,4719.466,903.3746,4717.2794,910.2462,4724.4634,909.6216,4726.65,902.75" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="30.044" x="4625.7" y="992.898">uses</text></g><!--reverse link LlamaGenerator to IPromptDirectory--><g class="link" data-entity-1="ent0017" data-entity-2="ent0020" data-link-type="composition" data-source-line="256" id="lnk54"><path codeLine="256" d="M4904.4552,914.0248 C4921.3652,970.4448 4937.34,1023.74 4949.48,1064.23" fill="none" id="LlamaGenerator-backto-IPromptDirectory" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="4901.01,902.53,4898.901,909.4258,4904.4552,914.0248,4906.5642,907.129,4901.01,902.53" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="30.044" x="4929.25" y="992.898">uses</text></g><!--reverse link IPromptFormatter to Gemma4JinjaPromptFormatter--><g class="link" data-entity-1="ent0018" data-entity-2="ent0019" data-link-type="extension" data-source-line="258" id="lnk55"><path codeLine="258" d="M4472.8078,1163.3826 C4470.6078,1213.3226 4467.66,1280.14 4465.68,1325.27" fill="none" id="IPromptFormatter-backto-Gemma4JinjaPromptFormatter" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="4473.6,1145.4,4466.8136,1163.1185,4478.802,1163.6466,4473.6,1145.4" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="4471.5" y="1226.498">implements</text></g><!--reverse link IPromptDirectory to PromptDirectory--><g class="link" data-entity-1="ent0020" data-entity-2="ent0021" data-link-type="extension" data-source-line="259" id="lnk56"><path codeLine="259" d="M4963.8733,1163.3825 C4965.8033,1207.1325 4968.11,1259.65 4970.19,1306.8" fill="none" id="IPromptDirectory-backto-PromptDirectory" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="4963.08,1145.4,4957.8791,1163.6469,4969.8675,1163.1181,4963.08,1145.4" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="4967.84" y="1226.498">implements</text></g><!--reverse link ICuratedDataService to JsonLoader--><g class="link" data-entity-1="ent0022" data-entity-2="ent0023" data-link-type="extension" data-source-line="261" id="lnk57"><path codeLine="261" d="M1173.2063,553.832 C1059.7663,575.732 954.86,599.17 843.34,630.36 C754.38,655.24 657.65,690.3 578.78,721.06" fill="none" id="ICuratedDataService-backto-JsonLoader" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1190.88,550.42,1172.069,547.9407,1174.3437,559.7232,1190.88,550.42" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1028.93" y="595.248">implements</text></g><!--reverse link ICuratedDataService to MockCuratedDataService--><g class="link" data-entity-1="ent0022" data-entity-2="ent0027" data-link-type="extension" data-source-line="262" id="lnk58"><path codeLine="262" d="M1600.34,568.51 C1600.34,610.52 1600.34,647.37 1600.34,693.8" fill="none" id="ICuratedDataService-backto-MockCuratedDataService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1600.34,550.51,1594.34,568.51,1606.34,568.51,1600.34,550.51" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1601.34" y="595.248">implements</text></g><!--reverse link IExportService to SqliteExportService--><g class="link" data-entity-1="ent0031" data-entity-2="ent0032" data-link-type="extension" data-source-line="264" id="lnk59"><path codeLine="264" d="M5101.0086,563.2272 C5124.7686,586.9472 5139.89,602.04 5168.01,630.12" fill="none" id="IExportService-backto-SqliteExportService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="5088.27,550.51,5096.7696,567.4734,5105.2477,558.981,5088.27,550.51" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="5138.55" y="595.248">implements</text></g><!--reverse link SqliteExportService to IDateTimeProvider--><g class="link" data-entity-1="ent0032" data-entity-2="ent0033" data-link-type="composition" data-source-line="265" id="lnk60"><path codeLine="265" d="M5326.34,960.38 C5326.34,1003.46 5326.34,1034.4 5326.34,1064.2" fill="none" id="SqliteExportService-backto-IDateTimeProvider" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="5326.34,948.38,5322.34,954.38,5326.34,960.38,5330.34,954.38,5326.34,948.38" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="5327.34" y="992.898">owns</text></g><!--reverse link IDateTimeProvider to SystemDateTimeProvider--><g class="link" data-entity-1="ent0033" data-entity-2="ent0034" data-link-type="extension" data-source-line="266" id="lnk61"><path codeLine="266" d="M5326.34,1163.4 C5326.34,1213.34 5326.34,1280.14 5326.34,1325.27" fill="none" id="IDateTimeProvider-backto-SystemDateTimeProvider" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="5326.34,1145.4,5320.34,1163.4,5332.34,1163.4,5326.34,1145.4" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="5327.34" y="1226.498">implements</text></g><?plantuml-src xHdRSjksybrVWScPIPNQSfl4JHFLendBaf9qaiR7SauUEH2vbb2300E0SjIS_7iN04aH5AdOwMKcdRv86kpzWjt5IbypaL55KwBDXWD-AXQRFEKzNK4IkA8vDpCfp2yq1N9lyfhCgT3tsd7cx3SW3uzhGCCCXotv_oI_NidrlJOCH_pe-nfeGUFhfPAvICuabuhyPtOwEvizQvTTe3nw-lZuqMaR_ow4KwNaJG5yykZfwG_ZNWqQSwer-TWZPDoX3I4lW2QWTk3JqzdtqwUMKYg45wS_7Fzu_EGXdhR89MHNqKzrROGqqAxCPuIrydMk8PSh86C6QacL0K4cr51opZBWJ00Pa3FdW0cZIrIWr_F-sEANc6zKl09C8MfGXjLmGBXSBa55P8YfbGo7UaKL955crCdBLmuqScWngWOVJAH1hLaC5NuksFiSFFvKO6wkKi0iyLYUT0a2dCGs8cl8ynB1uyE7JABIgbs60mRyuno9KUS4MUtLxymZMf410vfbdCNKC2aYcTalRUbFjyTl_6dT71IuK703Ye6kfAqXHZDEnWwmkO0OmpngKEMeuWx5MppSeX-GYrpq7o3EGahkwF-R8yCpPb3QEsPMPvXKnefsM7LEhwHNsOijN0lZKjL-x7XKuSweEC7OQaDyz2118PkHvRgMB0cOM2M_Y04cqWLeB05UNNV-gSnI1Bw2DN1oSW8YJwqag_x8vUS45laIlr-AAubVxwWI-3N5Iwcs7ChiFbzH3QrivWQlGPxXBsj3OG-2xKtqiJeLoHWQeBCLn7YfWxCB_26MmT5CSYvlWgDBe2gHDyBL1QFos5Wp9vTld3O7X3k3XvNjxZ1pwWz3Snma1Qtf4YgVO-J5CkGznNJO5DmDGm93qwmaY5TA2ec46sqWZM8ku-lXqA95cMJ2E2gfs9A9IeRC5LuZNcIJvxjIM4CZbfH8_c0uT67-ywn2ZK1TqHX8KO8mfjLP4T43AwMVqGsNDF4oqRr1rdsa2rlgOlE9JAJ51kUZOUMkrbmyLpB9OoZBOxoYGW2tztLi2pccjpyvARcCxZl4EuYOCBmr1g_A7OLioq9buwMSPmal_Drt0N05mHqEX-wW-8hijMYuTwTYjthwEPYogfpvDj37l40n_jwNiFiFTaFfRNwD-ROhwazY_evTOsebZBPBGEzoXcTj7U4TBCuSi6myBbsYc69iQlYkLsFbJcbsKbFXiAxFw0yPOwNF05DYwbNelxVbFaIArWnk7koxBPKvNL7ivufNojJOjEXpGDugFXMnJA2_fZo7Mz5LGNbXJBPLvszLOEkFOBRey4czFMxwPRdRZTWXKR2q0q8n27LgK_L-s-y28RRrsEwvgMZh7HCbPDXUfQ0Ls1AS-pE42ZkRbo0xg3jnVd1mieBhjhNx7sYfgxU0mKoPODgm-0NLgpqckIp1XqjqTz8lqxKGjYtwdAOq3Cc0f9ZQhkQ_jZzUK95m26Pj11LLf0RCb4mp4rr9bLBJDIMVEwHPYJEgKoPCkKbniuToKk9uIeNLfqHEpSDdpnx_s9fKHqT7jqYC0giHprVOn_lU9TWSLvrPLxK-70ctp9h5r05B-vCshB0HDXpMMYmyj5yCKTwRBINwaDW9lnlUMJEVGvhIuv-P-9KsrVch5TZnH9K07QCNnkeQDdUnhidtOoCdgmIxOXoyYSEXpGH_9Rwu9TzDrveZTb-BdRueguNkM-LtqxTfaala6hpvTBjVSIuApHzaN2jPDTwOJc3Bbnvl_7DoyuLIzeJZgf0HSIosDTdpNFtLehKNKKgk4l5dT8DLOJjzbxdbVlmRrAyhg6xPXa_NbI7ogXPSkoR0U3h5liMtfbd91BzIYQrP4sOqZZcs-H1c7xT53k04SCKKwX5JpdyYdDhYQtzh2p8kExJj-0oLfG9BWWA3AbcGvv4GDwmYtWr3aRb1Z456bKRrZteW4hSTh4zgBNMctCmL2HZjNV4KyqdhIgdC3uTOXar7YmqETov2jocfORWTgo8CT-KKHE_VY_OrNxJspBNRCFO1By7ne1gfloEF1-KCRLUq6kp0rtyxFoIJwI6PNHoIyVI1dLaIl5PaC4YHDVvMkT0_8MPb6bNBtBxkDVx26xX4vI6ftwdwOgE-9cxjsoy5Cunoh0RrZSg1dLDYqDelO_j-nRjznmIRNUVE75a_EOvC2x4Tmu9dGnVPZ8c69bMtch_dp41eZYyFw4jyOxWTdf9hbdGy1J0wS8bOvmLICT7d8ghMX55kugXbYBRHMc2yt42-VpvB5j7AlL4icjTvKb3NtYvODK6PQgaOQPEQBS7SeAesmBiKHHXkJ-0cuCzZ6qM5fd6n-GSHrLVkbPgt7pwTeCUHY-teAqWp_rGgDPoZcIaDeVX2atmDPN5zcNpkcLrtGMEYRgPYrvhghOalozpiTpuevYu7TtZUciitPEwsvrZ4E9h9VGzQiKnZoPe0PaC28jwWVtu5bo6zp_oVzkrWK2siXqJU27qhYjsrvUs9mmtNNOG61UKEX2tJIa7Tg_w5i8ZLVm31QVWdGF6NI1EzF0kHgxy2_dzq5EpfXuIb6NStM_VgWAEZqVQVaI61b7c4slgzWMBp6LiCsjAs6RU2zooR0pswwDituG7f7X7MAzkjQkdtsjhNYWXNhm7hNcCZMcfKJw4QUWjsOv4LScy0NRuqDnb3s-Zr7jJjXg10xUqkPwmcUxObOIHs5XgMUbTMtP3MjxybgxqTGo5T11q3VaDSOrgnX6rzFw1gGt1ktAc8HPwqb5ydgBsC1h9-1m00?></g></svg> |