Merge pull request #1271 from android/dt/remove-feature-dep

Remove the search module's dependency on other feature modules
pull/1288/head
Don Turner 9 months ago committed by GitHub
commit 0584f191bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,5 +1,5 @@
/* /*
* Copyright 2022 The Android Open Source Project * Copyright 2024 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.google.samples.apps.nowinandroid.feature.interests package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -38,7 +38,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.DynamicA
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.feature.interests.R.string import com.google.samples.apps.nowinandroid.core.ui.R.string
@Composable @Composable
fun InterestsItem( fun InterestsItem(
@ -70,7 +70,7 @@ fun InterestsItem(
Icon( Icon(
imageVector = NiaIcons.Add, imageVector = NiaIcons.Add,
contentDescription = stringResource( contentDescription = stringResource(
id = string.feature_interests_card_follow_button_content_desc, id = string.core_ui_interests_card_follow_button_content_desc,
), ),
) )
}, },
@ -78,7 +78,7 @@ fun InterestsItem(
Icon( Icon(
imageVector = NiaIcons.Check, imageVector = NiaIcons.Check,
contentDescription = stringResource( contentDescription = stringResource(
id = string.feature_interests_card_unfollow_button_content_desc, id = string.core_ui_interests_card_unfollow_button_content_desc,
), ),
) )
}, },

@ -26,4 +26,7 @@
<string name="core_ui_topic_chip_content_description_when_followed">%1$s is followed</string> <string name="core_ui_topic_chip_content_description_when_followed">%1$s is followed</string>
<string name="core_ui_topic_chip_content_description_when_not_followed">%1$s is not followed</string> <string name="core_ui_topic_chip_content_description_when_not_followed">%1$s is not followed</string>
<string name="core_ui_interests_card_follow_button_content_desc">Follow interest</string>
<string name="core_ui_interests_card_unfollow_button_content_desc">Unfollow interest</string>
</resources> </resources>

@ -4,478 +4,460 @@
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <!-- Generated by graphviz version 9.0.0 (20230911.1827)
--> -->
<!-- Title: G Pages: 1 --> <!-- Title: G Pages: 1 -->
<svg width="1219pt" height="476pt" <svg width="1178pt" height="404pt"
viewBox="0.00 0.00 1219.00 476.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> viewBox="0.00 0.00 1178.13 404.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 472)"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 400)">
<title>G</title> <title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-472 1215,-472 1215,4 -4,4"/> <polygon fill="white" stroke="none" points="-4,4 -4,-400 1174.13,-400 1174.13,4 -4,4"/>
<!-- :app --> <!-- :app -->
<g id="node1" class="node"> <g id="node1" class="node">
<title>:app</title> <title>:app</title>
<ellipse fill="none" stroke="black" cx="678" cy="-450" rx="27" ry="18"/> <ellipse fill="none" stroke="black" cx="626.13" cy="-378" rx="27" ry="18"/>
<text text-anchor="middle" x="678" y="-444.95" font-family="Times,serif" font-size="14.00">:app</text> <text text-anchor="middle" x="626.13" y="-372.95" font-family="Times,serif" font-size="14.00">:app</text>
</g> </g>
<!-- :feature:interests --> <!-- :feature:interests -->
<g id="node2" class="node"> <g id="node2" class="node">
<title>:feature:interests</title> <title>:feature:interests</title>
<ellipse fill="none" stroke="black" cx="921" cy="-306" rx="72.34" ry="18"/> <ellipse fill="none" stroke="black" cx="289.13" cy="-306" rx="72.34" ry="18"/>
<text text-anchor="middle" x="921" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:interests</text> <text text-anchor="middle" x="289.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:interests</text>
</g> </g>
<!-- :app&#45;&gt;:feature:interests --> <!-- :app&#45;&gt;:feature:interests -->
<g id="edge1" class="edge"> <g id="edge1" class="edge">
<title>:app&#45;&gt;:feature:interests</title> <title>:app&#45;&gt;:feature:interests</title>
<path fill="none" stroke="black" d="M697.89,-437.38C738.48,-413.66 831.44,-359.33 883.66,-328.82"/> <path fill="none" stroke="red" stroke-width="2" d="M600.52,-371.68C548.58,-360.89 429.43,-336.14 354.49,-320.58"/>
<polygon fill="black" stroke="black" points="885.35,-331.88 892.22,-323.82 881.82,-325.84 885.35,-331.88"/> <polygon fill="red" stroke="red" stroke-width="2" points="356.78,-317.48 346.28,-318.87 355.36,-324.33 356.78,-317.48"/>
</g> </g>
<!-- :feature:foryou --> <!-- :feature:foryou -->
<g id="node3" class="node"> <g id="node3" class="node">
<title>:feature:foryou</title> <title>:feature:foryou</title>
<ellipse fill="none" stroke="black" cx="764" cy="-306" rx="66.19" ry="18"/> <ellipse fill="none" stroke="black" cx="132.13" cy="-306" rx="66.19" ry="18"/>
<text text-anchor="middle" x="764" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:foryou</text> <text text-anchor="middle" x="132.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:foryou</text>
</g> </g>
<!-- :app&#45;&gt;:feature:foryou --> <!-- :app&#45;&gt;:feature:foryou -->
<g id="edge2" class="edge"> <g id="edge2" class="edge">
<title>:app&#45;&gt;:feature:foryou</title> <title>:app&#45;&gt;:feature:foryou</title>
<path fill="none" stroke="black" d="M687.7,-432.99C702.32,-408.85 730.16,-362.87 747.87,-333.63"/> <path fill="none" stroke="black" d="M599.59,-374.51C533.28,-368.1 355.12,-349.7 208.13,-324 202.83,-323.07 197.34,-322.02 191.85,-320.91"/>
<polygon fill="black" stroke="black" points="750.7,-335.72 752.89,-325.35 744.71,-332.09 750.7,-335.72"/> <polygon fill="black" stroke="black" points="192.63,-317.5 182.12,-318.88 191.19,-324.35 192.63,-317.5"/>
</g> </g>
<!-- :feature:bookmarks --> <!-- :feature:bookmarks -->
<g id="node4" class="node"> <g id="node4" class="node">
<title>:feature:bookmarks</title> <title>:feature:bookmarks</title>
<ellipse fill="none" stroke="black" cx="483" cy="-306" rx="83.08" ry="18"/> <ellipse fill="none" stroke="black" cx="787.13" cy="-306" rx="83.08" ry="18"/>
<text text-anchor="middle" x="483" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text> <text text-anchor="middle" x="787.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text>
</g> </g>
<!-- :app&#45;&gt;:feature:bookmarks --> <!-- :app&#45;&gt;:feature:bookmarks -->
<g id="edge3" class="edge"> <g id="edge3" class="edge">
<title>:app&#45;&gt;:feature:bookmarks</title> <title>:app&#45;&gt;:feature:bookmarks</title>
<path fill="none" stroke="black" d="M650.97,-447.86C614.3,-444.86 549.02,-434.12 511,-396 495.08,-380.05 488.2,-355.15 485.23,-335.74"/> <path fill="none" stroke="black" d="M648.51,-367.27C672.32,-356.92 710.64,-340.25 740.97,-327.07"/>
<polygon fill="black" stroke="black" points="488.72,-335.49 484.02,-325.99 481.78,-336.35 488.72,-335.49"/> <polygon fill="black" stroke="black" points="742.16,-330.37 749.93,-323.17 739.37,-323.95 742.16,-330.37"/>
</g> </g>
<!-- :feature:topic --> <!-- :feature:topic -->
<g id="node5" class="node"> <g id="node5" class="node">
<title>:feature:topic</title> <title>:feature:topic</title>
<ellipse fill="none" stroke="black" cx="164" cy="-306" rx="60.05" ry="18"/> <ellipse fill="none" stroke="black" cx="626.13" cy="-306" rx="60.05" ry="18"/>
<text text-anchor="middle" x="164" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:topic</text> <text text-anchor="middle" x="626.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:topic</text>
</g> </g>
<!-- :app&#45;&gt;:feature:topic --> <!-- :app&#45;&gt;:feature:topic -->
<g id="edge4" class="edge"> <g id="edge4" class="edge">
<title>:app&#45;&gt;:feature:topic</title> <title>:app&#45;&gt;:feature:topic</title>
<path fill="none" stroke="black" d="M651.8,-445.32C602.92,-438.15 494.73,-420.79 406,-396 335.4,-376.28 256.11,-345.37 208.13,-325.66"/> <path fill="none" stroke="black" d="M626.13,-359.7C626.13,-352.41 626.13,-343.73 626.13,-335.54"/>
<polygon fill="black" stroke="black" points="209.48,-322.43 198.9,-321.85 206.81,-328.9 209.48,-322.43"/> <polygon fill="black" stroke="black" points="629.63,-335.62 626.13,-325.62 622.63,-335.62 629.63,-335.62"/>
</g> </g>
<!-- :feature:search --> <!-- :feature:search -->
<g id="node6" class="node"> <g id="node6" class="node">
<title>:feature:search</title> <title>:feature:search</title>
<ellipse fill="none" stroke="black" cx="585" cy="-378" rx="65.17" ry="18"/> <ellipse fill="none" stroke="black" cx="445.13" cy="-306" rx="65.17" ry="18"/>
<text text-anchor="middle" x="585" y="-372.95" font-family="Times,serif" font-size="14.00">:feature:search</text> <text text-anchor="middle" x="445.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:search</text>
</g> </g>
<!-- :app&#45;&gt;:feature:search --> <!-- :app&#45;&gt;:feature:search -->
<g id="edge5" class="edge"> <g id="edge5" class="edge">
<title>:app&#45;&gt;:feature:search</title> <title>:app&#45;&gt;:feature:search</title>
<path fill="none" stroke="red" stroke-width="2" d="M660.51,-435.83C647.87,-426.32 630.48,-413.23 615.57,-402.01"/> <path fill="none" stroke="black" d="M603.2,-368.13C575.53,-357.43 528.27,-339.16 492.62,-325.37"/>
<polygon fill="red" stroke="red" stroke-width="2" points="619.18,-400.35 609.09,-397.13 614.97,-405.94 619.18,-400.35"/> <polygon fill="black" stroke="black" points="493.96,-322.13 483.37,-321.79 491.44,-328.66 493.96,-322.13"/>
</g> </g>
<!-- :feature:settings --> <!-- :feature:settings -->
<g id="node7" class="node"> <g id="node7" class="node">
<title>:feature:settings</title> <title>:feature:settings</title>
<ellipse fill="none" stroke="black" cx="312" cy="-306" rx="69.78" ry="18"/> <ellipse fill="none" stroke="black" cx="958.13" cy="-306" rx="69.78" ry="18"/>
<text text-anchor="middle" x="312" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:settings</text> <text text-anchor="middle" x="958.13" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:settings</text>
</g> </g>
<!-- :app&#45;&gt;:feature:settings --> <!-- :app&#45;&gt;:feature:settings -->
<g id="edge6" class="edge"> <g id="edge6" class="edge">
<title>:app&#45;&gt;:feature:settings</title> <title>:app&#45;&gt;:feature:settings</title>
<path fill="none" stroke="black" d="M652.28,-443.52C615.27,-435.25 545.15,-418.17 488,-396 438.32,-376.72 383.99,-347.99 349.03,-328.42"/> <path fill="none" stroke="black" d="M651.63,-371.7C697.28,-362.22 795.94,-341.66 879.13,-324 884.26,-322.91 889.58,-321.78 894.92,-320.63"/>
<polygon fill="black" stroke="black" points="351.02,-325.52 340.59,-323.66 347.58,-331.62 351.02,-325.52"/> <polygon fill="black" stroke="black" points="895.34,-324.12 904.39,-318.6 893.88,-317.28 895.34,-324.12"/>
</g> </g>
<!-- :core:common --> <!-- :core:common -->
<g id="node8" class="node"> <g id="node8" class="node">
<title>:core:common</title> <title>:core:common</title>
<ellipse fill="none" stroke="black" cx="395" cy="-18" rx="65.17" ry="18"/> <ellipse fill="none" stroke="black" cx="760.13" cy="-18" rx="65.17" ry="18"/>
<text text-anchor="middle" x="395" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <text text-anchor="middle" x="760.13" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text>
</g> </g>
<!-- :app&#45;&gt;:core:common --> <!-- :app&#45;&gt;:core:common -->
<g id="edge7" class="edge"> <g id="edge7" class="edge">
<title>:app&#45;&gt;:core:common</title> <title>:app&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M650.58,-449.21C523.74,-449.46 0,-442.3 0,-307 0,-307 0,-307 0,-161 0,-125.6 227.6,-62.12 337.27,-33.59"/> <path fill="none" stroke="black" d="M653.52,-377.16C744.97,-377.21 1038.43,-373.43 1116.13,-324 1155.16,-299.17 1170.13,-281.27 1170.13,-235 1170.13,-235 1170.13,-235 1170.13,-161 1170.13,-114.96 1155.63,-97.23 1117.13,-72 1064.1,-37.25 896.54,-47.11 834.13,-36 829.18,-35.12 824.06,-34.12 818.93,-33.06"/>
<polygon fill="black" stroke="black" points="337.87,-37.05 346.67,-31.16 336.11,-30.27 337.87,-37.05"/> <polygon fill="black" stroke="black" points="819.74,-29.66 809.23,-30.99 818.28,-36.51 819.74,-29.66"/>
</g> </g>
<!-- :core:ui --> <!-- :core:ui -->
<g id="node9" class="node"> <g id="node9" class="node">
<title>:core:ui</title> <title>:core:ui</title>
<ellipse fill="none" stroke="black" cx="561" cy="-234" rx="39.07" ry="18"/> <ellipse fill="none" stroke="black" cx="530.13" cy="-234" rx="39.07" ry="18"/>
<text text-anchor="middle" x="561" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <text text-anchor="middle" x="530.13" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text>
</g> </g>
<!-- :app&#45;&gt;:core:ui --> <!-- :app&#45;&gt;:core:ui -->
<g id="edge8" class="edge"> <g id="edge8" class="edge">
<title>:app&#45;&gt;:core:ui</title> <title>:app&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M676.62,-431.53C674.63,-413.03 669.91,-383.33 659,-360 640.58,-320.63 607.68,-282.34 585.13,-258.74"/> <path fill="none" stroke="black" d="M605.49,-365.91C590.07,-356.62 569.59,-342.01 557.13,-324 544.69,-306.03 537.86,-282.18 534.18,-263.69"/>
<polygon fill="black" stroke="black" points="587.87,-256.54 578.38,-251.82 582.85,-261.42 587.87,-256.54"/> <polygon fill="black" stroke="black" points="537.64,-263.17 532.45,-253.93 530.75,-264.38 537.64,-263.17"/>
</g> </g>
<!-- :core:designsystem --> <!-- :core:designsystem -->
<g id="node10" class="node"> <g id="node10" class="node">
<title>:core:designsystem</title> <title>:core:designsystem</title>
<ellipse fill="none" stroke="black" cx="343" cy="-162" rx="82.06" ry="18"/> <ellipse fill="none" stroke="black" cx="749.13" cy="-162" rx="82.06" ry="18"/>
<text text-anchor="middle" x="343" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <text text-anchor="middle" x="749.13" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
</g> </g>
<!-- :app&#45;&gt;:core:designsystem --> <!-- :app&#45;&gt;:core:designsystem -->
<g id="edge9" class="edge"> <g id="edge9" class="edge">
<title>:app&#45;&gt;:core:designsystem</title> <title>:app&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M650.87,-447.97C542.86,-443.2 145.91,-419.33 77,-324 56.94,-296.24 98.11,-219.46 102,-216 125.29,-195.3 199.91,-181.02 260.01,-172.54"/> <path fill="none" stroke="black" d="M653.33,-375.54C740.95,-370.56 1011.68,-352.94 1037.13,-324 1047.69,-311.98 1045.9,-301.38 1037.13,-288 1023.35,-267 880.1,-211.43 800.97,-181.97"/>
<polygon fill="black" stroke="black" points="260.12,-176.05 269.55,-171.23 259.17,-169.12 260.12,-176.05"/> <polygon fill="black" stroke="black" points="802.26,-178.71 791.67,-178.52 799.82,-185.28 802.26,-178.71"/>
</g> </g>
<!-- :core:data --> <!-- :core:data -->
<g id="node11" class="node"> <g id="node11" class="node">
<title>:core:data</title> <title>:core:data</title>
<ellipse fill="none" stroke="black" cx="663" cy="-162" rx="47.26" ry="18"/> <ellipse fill="none" stroke="black" cx="564.13" cy="-162" rx="47.26" ry="18"/>
<text text-anchor="middle" x="663" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <text text-anchor="middle" x="564.13" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text>
</g> </g>
<!-- :app&#45;&gt;:core:data --> <!-- :app&#45;&gt;:core:data -->
<g id="edge10" class="edge"> <g id="edge10" class="edge">
<title>:app&#45;&gt;:core:data</title> <title>:app&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M705.27,-448.51C790.66,-445.54 1045.6,-425.22 1019,-288 1012.44,-254.13 1016.95,-237.54 990,-216 949.55,-183.67 804.19,-170.6 721.54,-165.69"/> <path fill="none" stroke="black" d="M598.83,-376.56C490.37,-374.55 94,-364.47 57.13,-324 -72.66,-181.56 345.93,-164.36 505.2,-162.87"/>
<polygon fill="black" stroke="black" points="721.76,-162.2 711.58,-165.12 721.36,-169.18 721.76,-162.2"/> <polygon fill="black" stroke="black" points="505.17,-166.37 515.14,-162.79 505.12,-159.37 505.17,-166.37"/>
</g> </g>
<!-- :core:model --> <!-- :core:model -->
<g id="node12" class="node"> <g id="node12" class="node">
<title>:core:model</title> <title>:core:model</title>
<ellipse fill="none" stroke="black" cx="663" cy="-18" rx="55.45" ry="18"/> <ellipse fill="none" stroke="black" cx="391.13" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="663" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <text text-anchor="middle" x="391.13" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g> </g>
<!-- :app&#45;&gt;:core:model --> <!-- :app&#45;&gt;:core:model -->
<g id="edge11" class="edge"> <g id="edge11" class="edge">
<title>:app&#45;&gt;:core:model</title> <title>:app&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M705.36,-448.53C792.7,-446.64 1063.54,-437.47 1139,-396 1183.59,-371.49 1211,-357.88 1211,-307 1211,-307 1211,-307 1211,-161 1211,-62.5 875.03,-31.19 729.22,-22.24"/> <path fill="none" stroke="black" d="M599.09,-376.3C488.77,-373.19 76.42,-359.31 31.13,-324 -1.91,-298.24 0.13,-276.89 0.13,-235 0.13,-235 0.13,-235 0.13,-161 0.13,-91.6 220.52,-46.37 330.37,-28.13"/>
<polygon fill="black" stroke="black" points="729.5,-18.75 719.31,-21.65 729.09,-25.74 729.5,-18.75"/> <polygon fill="black" stroke="black" points="330.81,-31.61 340.11,-26.54 329.68,-24.7 330.81,-31.61"/>
</g> </g>
<!-- :core:analytics --> <!-- :core:analytics -->
<g id="node13" class="node"> <g id="node13" class="node">
<title>:core:analytics</title> <title>:core:analytics</title>
<ellipse fill="none" stroke="black" cx="969" cy="-90" rx="64.66" ry="18"/> <ellipse fill="none" stroke="black" cx="1043.13" cy="-90" rx="64.66" ry="18"/>
<text text-anchor="middle" x="969" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <text text-anchor="middle" x="1043.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text>
</g> </g>
<!-- :app&#45;&gt;:core:analytics --> <!-- :app&#45;&gt;:core:analytics -->
<g id="edge12" class="edge"> <g id="edge12" class="edge">
<title>:app&#45;&gt;:core:analytics</title> <title>:app&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M705.11,-448.1C786.71,-445.01 1028.68,-432.87 1097,-396 1142.77,-371.29 1173,-359.02 1173,-307 1173,-307 1173,-307 1173,-233 1173,-162.11 1089,-123.73 1028.8,-105.32"/> <path fill="none" stroke="black" d="M653.6,-377.55C742.51,-378.76 1020.63,-378.07 1088.13,-324 1126.58,-293.2 1125.57,-263.67 1113.13,-216 1103.47,-178.98 1080.15,-141.32 1063.07,-117.16"/>
<polygon fill="black" stroke="black" points="1029.9,-102 1019.32,-102.54 1027.93,-108.72 1029.9,-102"/> <polygon fill="black" stroke="black" points="1066,-115.25 1057.3,-109.2 1060.33,-119.35 1066,-115.25"/>
</g> </g>
<!-- :sync:work --> <!-- :sync:work -->
<g id="node14" class="node"> <g id="node14" class="node">
<title>:sync:work</title> <title>:sync:work</title>
<ellipse fill="none" stroke="black" cx="1093" cy="-234" rx="51.86" ry="18"/> <ellipse fill="none" stroke="black" cx="1052.13" cy="-234" rx="51.86" ry="18"/>
<text text-anchor="middle" x="1093" y="-228.95" font-family="Times,serif" font-size="14.00">:sync:work</text> <text text-anchor="middle" x="1052.13" y="-228.95" font-family="Times,serif" font-size="14.00">:sync:work</text>
</g> </g>
<!-- :app&#45;&gt;:sync:work --> <!-- :app&#45;&gt;:sync:work -->
<g id="edge13" class="edge"> <g id="edge13" class="edge">
<title>:app&#45;&gt;:sync:work</title> <title>:app&#45;&gt;:sync:work</title>
<path fill="none" stroke="black" d="M705.28,-449.47C786.05,-450.25 1021.58,-447.93 1073,-396 1107.37,-361.3 1104.35,-299.74 1098.83,-263.63"/> <path fill="none" stroke="black" d="M653.22,-375.82C745.34,-371.53 1042.3,-355.35 1070.13,-324 1085.05,-307.19 1077.76,-281.49 1068.38,-262.03"/>
<polygon fill="black" stroke="black" points="1102.31,-263.19 1097.17,-253.93 1095.41,-264.37 1102.31,-263.19"/> <polygon fill="black" stroke="black" points="1071.54,-260.51 1063.78,-253.29 1065.34,-263.77 1071.54,-260.51"/>
</g> </g>
<!-- :feature:interests&#45;&gt;:core:ui --> <!-- :feature:interests&#45;&gt;:core:ui -->
<g id="edge14" class="edge"> <g id="edge14" class="edge">
<title>:feature:interests&#45;&gt;:core:ui</title> <title>:feature:interests&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M867.21,-293.72C857.81,-291.79 848.13,-289.82 839,-288 757.8,-271.84 663.04,-253.99 607.76,-243.68"/> <path fill="none" stroke="black" d="M335.02,-291.67C378.65,-279 443.79,-260.08 486.61,-247.64"/>
<polygon fill="black" stroke="black" points="608.54,-240.26 598.07,-241.87 607.26,-247.14 608.54,-240.26"/> <polygon fill="black" stroke="black" points="487.45,-251.04 496.07,-244.89 485.49,-244.32 487.45,-251.04"/>
</g> </g>
<!-- :feature:interests&#45;&gt;:core:designsystem --> <!-- :feature:interests&#45;&gt;:core:designsystem -->
<g id="edge15" class="edge"> <g id="edge15" class="edge">
<title>:feature:interests&#45;&gt;:core:designsystem</title> <title>:feature:interests&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M876.99,-291.3C843.88,-280.86 797.45,-265.96 757,-252 713.14,-236.86 703.85,-227.89 659,-216 581.14,-195.36 490.25,-181.11 425.99,-172.63"/> <path fill="none" stroke="black" d="M320.56,-289.4C366.58,-266.76 450.28,-226.34 482.13,-216 543.5,-196.07 615.36,-182.32 669.06,-173.83"/>
<polygon fill="black" stroke="black" points="426.58,-169.18 416.22,-171.36 425.68,-176.12 426.58,-169.18"/> <polygon fill="black" stroke="black" points="669.39,-177.32 678.73,-172.33 668.32,-170.41 669.39,-177.32"/>
</g> </g>
<!-- :feature:interests&#45;&gt;:core:data --> <!-- :feature:interests&#45;&gt;:core:data -->
<g id="edge16" class="edge"> <g id="edge16" class="edge">
<title>:feature:interests&#45;&gt;:core:data</title> <title>:feature:interests&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M892.4,-289.26C845.15,-263.25 750.85,-211.35 699.08,-182.86"/> <path fill="none" stroke="black" d="M308.22,-288.26C331.27,-268.74 371.86,-236.53 411.13,-216 444.18,-198.71 484.08,-185.11 514.85,-176.01"/>
<polygon fill="black" stroke="black" points="700.79,-179.81 690.34,-178.05 697.42,-185.94 700.79,-179.81"/> <polygon fill="black" stroke="black" points="515.65,-179.42 524.28,-173.28 513.7,-172.7 515.65,-179.42"/>
</g> </g>
<!-- :core:domain --> <!-- :core:domain -->
<g id="node15" class="node"> <g id="node15" class="node">
<title>:core:domain</title> <title>:core:domain</title>
<ellipse fill="none" stroke="black" cx="921" cy="-234" rx="60.05" ry="18"/> <ellipse fill="none" stroke="black" cx="261.13" cy="-234" rx="60.05" ry="18"/>
<text text-anchor="middle" x="921" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> <text text-anchor="middle" x="261.13" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text>
</g> </g>
<!-- :feature:interests&#45;&gt;:core:domain --> <!-- :feature:interests&#45;&gt;:core:domain -->
<g id="edge17" class="edge"> <g id="edge17" class="edge">
<title>:feature:interests&#45;&gt;:core:domain</title> <title>:feature:interests&#45;&gt;:core:domain</title>
<path fill="none" stroke="black" d="M921,-287.7C921,-280.41 921,-271.73 921,-263.54"/> <path fill="none" stroke="red" stroke-width="2" d="M282.21,-287.7C279.19,-280.15 275.57,-271.12 272.2,-262.68"/>
<polygon fill="black" stroke="black" points="924.5,-263.62 921,-253.62 917.5,-263.62 924.5,-263.62"/> <polygon fill="red" stroke="red" stroke-width="2" points="276.06,-262.9 269.09,-254.91 269.56,-265.5 276.06,-262.9"/>
</g> </g>
<!-- :feature:foryou&#45;&gt;:core:ui --> <!-- :feature:foryou&#45;&gt;:core:ui -->
<g id="edge37" class="edge"> <g id="edge37" class="edge">
<title>:feature:foryou&#45;&gt;:core:ui</title> <title>:feature:foryou&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M724.38,-291.34C689.14,-279.19 637.81,-261.49 602.12,-249.18"/> <path fill="none" stroke="black" d="M181.1,-293.62C190.07,-291.65 199.37,-289.7 208.13,-288 304.99,-269.21 419.09,-251.46 482.14,-242.03"/>
<polygon fill="black" stroke="black" points="603.61,-245.99 593.02,-246.04 601.33,-252.61 603.61,-245.99"/> <polygon fill="black" stroke="black" points="482.43,-245.52 491.81,-240.59 481.4,-238.6 482.43,-245.52"/>
</g> </g>
<!-- :feature:foryou&#45;&gt;:core:designsystem --> <!-- :feature:foryou&#45;&gt;:core:designsystem -->
<g id="edge38" class="edge"> <g id="edge38" class="edge">
<title>:feature:foryou&#45;&gt;:core:designsystem</title> <title>:feature:foryou&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M741.28,-288.77C712.07,-268.68 659.12,-234.8 609,-216 549.83,-193.8 479.6,-180.31 426.16,-172.5"/> <path fill="none" stroke="black" d="M180.42,-293.47C229.84,-281.43 303.12,-262.8 330.13,-252 361.15,-239.59 364.45,-226.64 396.13,-216 421.45,-207.49 572.8,-186.4 668.92,-173.54"/>
<polygon fill="black" stroke="black" points="426.91,-169.07 416.52,-171.13 425.93,-176 426.91,-169.07"/> <polygon fill="black" stroke="black" points="669.12,-177.04 678.56,-172.25 668.19,-170.1 669.12,-177.04"/>
</g> </g>
<!-- :feature:foryou&#45;&gt;:core:data --> <!-- :feature:foryou&#45;&gt;:core:data -->
<g id="edge39" class="edge"> <g id="edge39" class="edge">
<title>:feature:foryou&#45;&gt;:core:data</title> <title>:feature:foryou&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M751.82,-287.87C734.28,-263.22 701.79,-217.54 681.35,-188.79"/> <path fill="none" stroke="black" d="M138.65,-287.67C147.42,-266.94 165.12,-232.91 192.13,-216 243.29,-183.95 414.92,-170.54 506.08,-165.57"/>
<polygon fill="black" stroke="black" points="684.44,-187.1 675.79,-180.98 678.73,-191.16 684.44,-187.1"/> <polygon fill="black" stroke="black" points="506.01,-169.08 515.81,-165.06 505.64,-162.09 506.01,-169.08"/>
</g> </g>
<!-- :feature:foryou&#45;&gt;:core:domain --> <!-- :feature:foryou&#45;&gt;:core:domain -->
<g id="edge40" class="edge"> <g id="edge40" class="edge">
<title>:feature:foryou&#45;&gt;:core:domain</title> <title>:feature:foryou&#45;&gt;:core:domain</title>
<path fill="none" stroke="red" stroke-width="2" d="M797.3,-290.15C820.84,-279.66 852.63,-265.48 878.08,-254.14"/> <path fill="none" stroke="black" d="M160.76,-289.46C179.09,-279.52 203.09,-266.5 223.02,-255.68"/>
<polygon fill="red" stroke="red" stroke-width="2" points="878.09,-257.97 885.79,-250.7 875.24,-251.57 878.09,-257.97"/> <polygon fill="black" stroke="black" points="224.57,-258.82 231.69,-250.97 221.23,-252.67 224.57,-258.82"/>
</g> </g>
<!-- :feature:bookmarks&#45;&gt;:core:ui --> <!-- :feature:bookmarks&#45;&gt;:core:ui -->
<g id="edge41" class="edge"> <g id="edge41" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:ui</title> <title>:feature:bookmarks&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M501.88,-288.05C511.91,-279.05 524.39,-267.85 535.3,-258.07"/> <path fill="none" stroke="black" d="M736.66,-291.25C689.36,-278.37 619.35,-259.3 574.23,-247.01"/>
<polygon fill="black" stroke="black" points="537.39,-260.89 542.5,-251.6 532.72,-255.68 537.39,-260.89"/> <polygon fill="black" stroke="black" points="575.36,-243.69 564.79,-244.44 573.52,-250.45 575.36,-243.69"/>
</g> </g>
<!-- :feature:bookmarks&#45;&gt;:core:designsystem --> <!-- :feature:bookmarks&#45;&gt;:core:designsystem -->
<g id="edge42" class="edge"> <g id="edge42" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:designsystem</title> <title>:feature:bookmarks&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M466.39,-288.15C441.87,-263.28 395.82,-216.57 367.44,-187.79"/> <path fill="none" stroke="black" d="M782.47,-287.59C776.02,-263.5 764.31,-219.75 756.63,-191.03"/>
<polygon fill="black" stroke="black" points="370.16,-185.57 360.65,-180.9 365.18,-190.48 370.16,-185.57"/> <polygon fill="black" stroke="black" points="760.06,-190.33 754.1,-181.57 753.3,-192.14 760.06,-190.33"/>
</g> </g>
<!-- :feature:bookmarks&#45;&gt;:core:data --> <!-- :feature:bookmarks&#45;&gt;:core:data -->
<g id="edge43" class="edge"> <g id="edge43" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:data</title> <title>:feature:bookmarks&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M484.38,-287.6C486.86,-267.74 493.77,-235.51 513,-216 537.95,-190.68 575.72,-177.43 607.12,-170.5"/> <path fill="none" stroke="black" d="M758.5,-288.7C740.69,-278.43 717.39,-264.73 697.13,-252 661.72,-229.75 621.97,-202.9 595.23,-184.55"/>
<polygon fill="black" stroke="black" points="607.77,-173.94 616.88,-168.53 606.39,-167.08 607.77,-173.94"/> <polygon fill="black" stroke="black" points="597.46,-181.84 587.24,-179.05 593.49,-187.6 597.46,-181.84"/>
</g> </g>
<!-- :feature:topic&#45;&gt;:core:ui --> <!-- :feature:topic&#45;&gt;:core:ui -->
<g id="edge44" class="edge"> <g id="edge44" class="edge">
<title>:feature:topic&#45;&gt;:core:ui</title> <title>:feature:topic&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M208.42,-293.49C216.57,-291.54 225.02,-289.62 233,-288 331.71,-267.9 448.38,-250.56 512.57,-241.57"/> <path fill="none" stroke="black" d="M604.34,-289.12C591,-279.39 573.76,-266.82 559.26,-256.24"/>
<polygon fill="black" stroke="black" points="513.01,-245.04 522.43,-240.2 512.04,-238.11 513.01,-245.04"/> <polygon fill="black" stroke="black" points="561.55,-253.58 551.41,-250.52 557.43,-259.24 561.55,-253.58"/>
</g> </g>
<!-- :feature:topic&#45;&gt;:core:designsystem --> <!-- :feature:topic&#45;&gt;:core:designsystem -->
<g id="edge45" class="edge"> <g id="edge45" class="edge">
<title>:feature:topic&#45;&gt;:core:designsystem</title> <title>:feature:topic&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M177.25,-288.11C192.79,-269.03 220,-237.8 248,-216 263.55,-203.89 282.2,-192.85 298.85,-184.02"/> <path fill="none" stroke="black" d="M640.72,-288.15C662.17,-263.39 702.37,-216.97 727.33,-188.16"/>
<polygon fill="black" stroke="black" points="300.29,-187.21 307.57,-179.51 297.08,-180.99 300.29,-187.21"/> <polygon fill="black" stroke="black" points="729.66,-190.82 733.56,-180.97 724.37,-186.24 729.66,-190.82"/>
</g> </g>
<!-- :feature:topic&#45;&gt;:core:data --> <!-- :feature:topic&#45;&gt;:core:data -->
<g id="edge46" class="edge"> <g id="edge46" class="edge">
<title>:feature:topic&#45;&gt;:core:data</title> <title>:feature:topic&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M198.28,-290.94C245.52,-271.95 333.61,-237.97 411,-216 478.37,-196.88 557.65,-181.31 609.04,-172.11"/> <path fill="none" stroke="black" d="M618.65,-287.87C608.08,-263.67 588.67,-219.21 576.09,-190.39"/>
<polygon fill="black" stroke="black" points="609.48,-175.59 618.71,-170.4 608.26,-168.7 609.48,-175.59"/> <polygon fill="black" stroke="black" points="579.45,-189.34 572.24,-181.58 573.03,-192.14 579.45,-189.34"/>
</g>
<!-- :feature:search&#45;&gt;:feature:interests -->
<g id="edge53" class="edge">
<title>:feature:search&#45;&gt;:feature:interests</title>
<path fill="none" stroke="black" d="M636.03,-366.37C694.74,-354.14 791.29,-334.02 855.5,-320.65"/>
<polygon fill="black" stroke="black" points="856.14,-324.09 865.22,-318.62 854.71,-317.23 856.14,-324.09"/>
</g>
<!-- :feature:search&#45;&gt;:feature:foryou -->
<g id="edge52" class="edge">
<title>:feature:search&#45;&gt;:feature:foryou</title>
<path fill="none" stroke="red" stroke-width="2" d="M621.66,-362.67C649.17,-351.91 687.06,-337.09 716.83,-325.45"/>
<polygon fill="red" stroke="red" stroke-width="2" points="716.54,-329.32 724.57,-322.42 713.99,-322.8 716.54,-329.32"/>
</g>
<!-- :feature:search&#45;&gt;:feature:bookmarks -->
<g id="edge51" class="edge">
<title>:feature:search&#45;&gt;:feature:bookmarks</title>
<path fill="none" stroke="black" d="M561.34,-360.76C548.02,-351.62 531.16,-340.05 516.5,-329.99"/>
<polygon fill="black" stroke="black" points="518.71,-327.26 508.49,-324.49 514.75,-333.03 518.71,-327.26"/>
</g> </g>
<!-- :feature:search&#45;&gt;:core:ui --> <!-- :feature:search&#45;&gt;:core:ui -->
<g id="edge47" class="edge"> <g id="edge47" class="edge">
<title>:feature:search&#45;&gt;:core:ui</title> <title>:feature:search&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M583.82,-359.83C582.41,-341.82 579.64,-312.76 575,-288 573.47,-279.83 571.35,-271.06 569.23,-263.06"/> <path fill="none" stroke="black" d="M465.27,-288.41C476.46,-279.2 490.54,-267.6 502.72,-257.57"/>
<polygon fill="black" stroke="black" points="572.63,-262.2 566.59,-253.5 565.88,-264.07 572.63,-262.2"/> <polygon fill="black" stroke="black" points="504.92,-260.29 510.41,-251.24 500.47,-254.89 504.92,-260.29"/>
</g> </g>
<!-- :feature:search&#45;&gt;:core:designsystem --> <!-- :feature:search&#45;&gt;:core:designsystem -->
<g id="edge48" class="edge"> <g id="edge48" class="edge">
<title>:feature:search&#45;&gt;:core:designsystem</title> <title>:feature:search&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M520.52,-374.73C393.97,-369.62 122.94,-355.12 95,-324 32.8,-254.71 183.23,-202.79 276.21,-178.4"/> <path fill="none" stroke="black" d="M483.1,-291.03C509.94,-280.88 546.6,-266.44 578.13,-252 624.31,-230.84 675.85,-203.48 710.15,-184.72"/>
<polygon fill="black" stroke="black" points="276.97,-181.82 285.78,-175.94 275.23,-175.04 276.97,-181.82"/> <polygon fill="black" stroke="black" points="711.82,-187.8 718.89,-179.91 708.44,-181.66 711.82,-187.8"/>
</g> </g>
<!-- :feature:search&#45;&gt;:core:data --> <!-- :feature:search&#45;&gt;:core:data -->
<g id="edge49" class="edge"> <g id="edge49" class="edge">
<title>:feature:search&#45;&gt;:core:data</title> <title>:feature:search&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M591.25,-359.85C604.69,-322.99 636.42,-235.92 652.81,-190.96"/> <path fill="none" stroke="black" d="M449.03,-287.64C454.05,-268.42 464.33,-237.33 482.13,-216 493.69,-202.15 509.81,-190.65 524.7,-181.95"/>
<polygon fill="black" stroke="black" points="656.06,-192.25 656.2,-181.65 649.49,-189.85 656.06,-192.25"/> <polygon fill="black" stroke="black" points="526.38,-185.02 533.42,-177.11 522.98,-178.9 526.38,-185.02"/>
</g> </g>
<!-- :feature:search&#45;&gt;:core:domain --> <!-- :feature:search&#45;&gt;:core:domain -->
<g id="edge50" class="edge"> <g id="edge50" class="edge">
<title>:feature:search&#45;&gt;:core:domain</title> <title>:feature:search&#45;&gt;:core:domain</title>
<path fill="none" stroke="black" d="M648.41,-373.49C759.33,-366.69 979.03,-350.08 1002,-324 1012.58,-311.99 1009.61,-302.07 1002,-288 994.22,-273.61 980.64,-262.5 966.8,-254.25"/> <path fill="none" stroke="black" d="M407.89,-290.83C379.05,-279.86 338.93,-264.6 307.92,-252.8"/>
<polygon fill="black" stroke="black" points="968.53,-251.21 958.08,-249.48 965.17,-257.35 968.53,-251.21"/> <polygon fill="black" stroke="black" points="309.37,-249.61 298.78,-249.32 306.88,-256.15 309.37,-249.61"/>
</g> </g>
<!-- :feature:settings&#45;&gt;:core:ui --> <!-- :feature:settings&#45;&gt;:core:ui -->
<g id="edge54" class="edge"> <g id="edge51" class="edge">
<title>:feature:settings&#45;&gt;:core:ui</title> <title>:feature:settings&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M357.96,-292.08C403.46,-279.29 472.62,-259.84 517.32,-247.28"/> <path fill="none" stroke="black" d="M906.8,-293.48C897.6,-291.55 888.1,-289.64 879.13,-288 772.28,-268.41 646.09,-250.54 578.56,-241.4"/>
<polygon fill="black" stroke="black" points="518.26,-250.65 526.94,-244.57 516.37,-243.91 518.26,-250.65"/> <polygon fill="black" stroke="black" points="579.32,-237.97 568.94,-240.1 578.38,-244.91 579.32,-237.97"/>
</g> </g>
<!-- :feature:settings&#45;&gt;:core:designsystem --> <!-- :feature:settings&#45;&gt;:core:designsystem -->
<g id="edge55" class="edge"> <g id="edge52" class="edge">
<title>:feature:settings&#45;&gt;:core:designsystem</title> <title>:feature:settings&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M315.8,-287.59C321.06,-263.5 330.61,-219.75 336.88,-191.03"/> <path fill="none" stroke="black" d="M934.15,-288.71C896.95,-263.43 825.2,-214.68 782.81,-185.88"/>
<polygon fill="black" stroke="black" points="340.23,-192.11 338.94,-181.59 333.39,-190.61 340.23,-192.11"/> <polygon fill="black" stroke="black" points="784.96,-183.11 774.72,-180.39 781.02,-188.9 784.96,-183.11"/>
</g> </g>
<!-- :feature:settings&#45;&gt;:core:data --> <!-- :feature:settings&#45;&gt;:core:data -->
<g id="edge56" class="edge"> <g id="edge53" class="edge">
<title>:feature:settings&#45;&gt;:core:data</title> <title>:feature:settings&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M339.82,-289.14C374.12,-270.04 434.56,-237.8 489,-216 530,-199.59 578.14,-185.29 613.38,-175.69"/> <path fill="none" stroke="black" d="M918.54,-290.73C844.61,-264.09 686.03,-206.93 608.56,-179.01"/>
<polygon fill="black" stroke="black" points="614.13,-179.11 622.88,-173.14 612.31,-172.35 614.13,-179.11"/> <polygon fill="black" stroke="black" points="609.75,-175.72 599.16,-175.63 607.38,-182.31 609.75,-175.72"/>
</g> </g>
<!-- :core:ui&#45;&gt;:core:designsystem --> <!-- :core:ui&#45;&gt;:core:designsystem -->
<g id="edge19" class="edge"> <g id="edge19" class="edge">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:ui&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M529.77,-222.97C495.61,-212 440.21,-194.21 398.6,-180.85"/> <path fill="none" stroke="black" d="M561.51,-222.93C568.62,-220.65 576.13,-218.24 583.13,-216 619.89,-204.24 661.23,-191.03 693.47,-180.75"/>
<polygon fill="black" stroke="black" points="399.83,-177.57 389.24,-177.85 397.69,-184.24 399.83,-177.57"/> <polygon fill="black" stroke="black" points="694.13,-184.21 702.59,-177.84 692,-177.55 694.13,-184.21"/>
</g> </g>
<!-- :core:ui&#45;&gt;:core:model --> <!-- :core:ui&#45;&gt;:core:model -->
<g id="edge20" class="edge"> <g id="edge20" class="edge">
<title>:core:ui&#45;&gt;:core:model</title> <title>:core:ui&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M557.92,-215.93C553.23,-184.72 547.6,-117.48 576,-72 585.53,-56.74 601.22,-45.24 616.67,-36.92"/> <path fill="none" stroke="black" d="M496.49,-224.51C447.08,-210.02 356.59,-175.34 318.13,-108 310.19,-94.11 310.86,-86.25 318.13,-72 325.1,-58.32 337.43,-47.35 350,-39.02"/>
<polygon fill="black" stroke="black" points="617.99,-40.18 625.37,-32.58 614.86,-33.91 617.99,-40.18"/> <polygon fill="black" stroke="black" points="351.58,-42.15 358.28,-33.95 347.93,-36.18 351.58,-42.15"/>
</g> </g>
<!-- :core:ui&#45;&gt;:core:analytics --> <!-- :core:ui&#45;&gt;:core:analytics -->
<g id="edge18" class="edge"> <g id="edge18" class="edge">
<title>:core:ui&#45;&gt;:core:analytics</title> <title>:core:ui&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M592.24,-222.71C624.15,-212.15 675.11,-195.17 719,-180 789.18,-155.74 870.09,-126.75 920.39,-108.6"/> <path fill="none" stroke="black" d="M555.54,-220.04C574.11,-210.1 599.56,-195.49 620.13,-180 638.71,-166.01 637.05,-153.85 658.13,-144 782.97,-85.63 830.22,-130.89 966.13,-108 972.03,-107.01 978.17,-105.85 984.28,-104.63"/>
<polygon fill="black" stroke="black" points="921.32,-111.99 929.53,-105.3 918.94,-105.41 921.32,-111.99"/> <polygon fill="black" stroke="black" points="984.65,-108.13 993.73,-102.67 983.23,-101.27 984.65,-108.13"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:common --> <!-- :core:data&#45;&gt;:core:common -->
<g id="edge21" class="edge"> <g id="edge21" class="edge">
<title>:core:data&#45;&gt;:core:common</title> <title>:core:data&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M617.4,-156.79C512.12,-146.87 260.13,-121.78 248,-108 216.8,-72.57 280.34,-46.93 333.42,-32.52"/> <path fill="none" stroke="black" d="M601.15,-150.4C609.05,-148.22 617.35,-145.99 625.13,-144 693.65,-126.5 736.14,-163.38 780.13,-108 794.09,-90.42 786.46,-65.02 776.87,-45.85"/>
<polygon fill="black" stroke="black" points="334.29,-35.91 343.08,-30 332.52,-29.14 334.29,-35.91"/> <polygon fill="black" stroke="black" points="780.04,-44.37 772.18,-37.26 773.9,-47.72 780.04,-44.37"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:analytics --> <!-- :core:data&#45;&gt;:core:analytics -->
<g id="edge25" class="edge"> <g id="edge25" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:core:data&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M703.01,-151.97C749.43,-141.47 828.28,-123.59 896,-108 900.49,-106.97 905.14,-105.89 909.82,-104.81"/> <path fill="none" stroke="black" d="M600.02,-149.93C608.21,-147.7 616.92,-145.57 625.13,-144 774.83,-115.44 815.71,-132.47 966.13,-108 972.04,-107.04 978.18,-105.91 984.3,-104.7"/>
<polygon fill="black" stroke="black" points="910.28,-108.29 919.24,-102.62 908.7,-101.48 910.28,-108.29"/> <polygon fill="black" stroke="black" points="984.66,-108.2 993.75,-102.75 983.25,-101.34 984.66,-108.2"/>
</g> </g>
<!-- :core:database --> <!-- :core:database -->
<g id="node16" class="node"> <g id="node16" class="node">
<title>:core:database</title> <title>:core:database</title>
<ellipse fill="none" stroke="black" cx="823" cy="-90" rx="63.63" ry="18"/> <ellipse fill="none" stroke="black" cx="391.13" cy="-90" rx="63.63" ry="18"/>
<text text-anchor="middle" x="823" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <text text-anchor="middle" x="391.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:database --> <!-- :core:data&#45;&gt;:core:database -->
<g id="edge22" class="edge"> <g id="edge22" class="edge">
<title>:core:data&#45;&gt;:core:database</title> <title>:core:data&#45;&gt;:core:database</title>
<path fill="none" stroke="red" stroke-width="2" d="M693.09,-147.83C717.31,-137.24 751.68,-122.2 778.99,-110.26"/> <path fill="none" stroke="red" stroke-width="2" d="M532.8,-148.32C506.06,-137.5 467.25,-121.8 437,-109.56"/>
<polygon fill="red" stroke="red" stroke-width="2" points="778.91,-114.11 786.67,-106.89 776.11,-107.7 778.91,-114.11"/> <polygon fill="red" stroke="red" stroke-width="2" points="440.09,-107.03 429.5,-106.53 437.46,-113.52 440.09,-107.03"/>
</g> </g>
<!-- :core:datastore --> <!-- :core:datastore -->
<g id="node17" class="node"> <g id="node17" class="node">
<title>:core:datastore</title> <title>:core:datastore</title>
<ellipse fill="none" stroke="black" cx="322" cy="-90" rx="65.17" ry="18"/> <ellipse fill="none" stroke="black" cx="892.13" cy="-90" rx="65.17" ry="18"/>
<text text-anchor="middle" x="322" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <text text-anchor="middle" x="892.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <!-- :core:data&#45;&gt;:core:datastore -->
<g id="edge23" class="edge"> <g id="edge23" class="edge">
<title>:core:data&#45;&gt;:core:datastore</title> <title>:core:data&#45;&gt;:core:datastore</title>
<path fill="none" stroke="black" d="M621.3,-153.12C568.69,-143.09 475.48,-125.01 396,-108 391.36,-107.01 386.56,-105.96 381.74,-104.89"/> <path fill="none" stroke="black" d="M600.77,-150.26C608.77,-148.06 617.21,-145.86 625.13,-144 707.95,-124.56 729.76,-124.95 813.13,-108 819.06,-106.79 825.23,-105.51 831.4,-104.21"/>
<polygon fill="black" stroke="black" points="382.52,-101.47 371.99,-102.7 380.98,-108.3 382.52,-101.47"/> <polygon fill="black" stroke="black" points="831.9,-107.69 840.95,-102.19 830.45,-100.84 831.9,-107.69"/>
</g> </g>
<!-- :core:network --> <!-- :core:network -->
<g id="node18" class="node"> <g id="node18" class="node">
<title>:core:network</title> <title>:core:network</title>
<ellipse fill="none" stroke="black" cx="467" cy="-90" rx="62.1" ry="18"/> <ellipse fill="none" stroke="black" cx="709.13" cy="-90" rx="62.1" ry="18"/>
<text text-anchor="middle" x="467" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <text text-anchor="middle" x="709.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:network --> <!-- :core:data&#45;&gt;:core:network -->
<g id="edge24" class="edge"> <g id="edge24" class="edge">
<title>:core:data&#45;&gt;:core:network</title> <title>:core:data&#45;&gt;:core:network</title>
<path fill="none" stroke="black" d="M629.31,-148.97C597.96,-137.77 550.9,-120.97 515.52,-108.33"/> <path fill="none" stroke="black" d="M592.43,-147.34C613.89,-136.97 643.72,-122.58 667.85,-110.93"/>
<polygon fill="black" stroke="black" points="516.96,-105.13 506.36,-105.06 514.61,-111.72 516.96,-105.13"/> <polygon fill="black" stroke="black" points="669.29,-114.12 676.77,-106.62 666.25,-107.82 669.29,-114.12"/>
</g> </g>
<!-- :core:notifications --> <!-- :core:notifications -->
<g id="node19" class="node"> <g id="node19" class="node">
<title>:core:notifications</title> <title>:core:notifications</title>
<ellipse fill="none" stroke="black" cx="663" cy="-90" rx="77.97" ry="18"/> <ellipse fill="none" stroke="black" cx="551.13" cy="-90" rx="77.97" ry="18"/>
<text text-anchor="middle" x="663" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <text text-anchor="middle" x="551.13" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:notifications --> <!-- :core:data&#45;&gt;:core:notifications -->
<g id="edge26" class="edge"> <g id="edge26" class="edge">
<title>:core:data&#45;&gt;:core:notifications</title> <title>:core:data&#45;&gt;:core:notifications</title>
<path fill="none" stroke="black" d="M663,-143.7C663,-136.41 663,-127.73 663,-119.54"/> <path fill="none" stroke="black" d="M560.91,-143.7C559.54,-136.32 557.91,-127.52 556.37,-119.25"/>
<polygon fill="black" stroke="black" points="666.5,-119.62 663,-109.62 659.5,-119.62 666.5,-119.62"/> <polygon fill="black" stroke="black" points="559.85,-118.79 554.58,-109.59 552.96,-120.06 559.85,-118.79"/>
</g> </g>
<!-- :sync:work&#45;&gt;:core:data --> <!-- :sync:work&#45;&gt;:core:data -->
<g id="edge58" class="edge"> <g id="edge55" class="edge">
<title>:sync:work&#45;&gt;:core:data</title> <title>:sync:work&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M1053.37,-222.06C1044.72,-219.87 1035.58,-217.73 1027,-216 918.84,-194.26 790.89,-177.73 719.12,-169.27"/> <path fill="none" stroke="black" d="M1003.5,-227.18C929,-218.09 782.21,-199.56 658.13,-180 644.69,-177.88 630.21,-175.38 616.74,-172.95"/>
<polygon fill="black" stroke="black" points="719.94,-165.84 709.6,-168.16 719.13,-172.8 719.94,-165.84"/> <polygon fill="black" stroke="black" points="617.66,-169.56 607.19,-171.21 616.4,-176.44 617.66,-169.56"/>
</g> </g>
<!-- :sync:work&#45;&gt;:core:analytics --> <!-- :sync:work&#45;&gt;:core:analytics -->
<g id="edge57" class="edge"> <g id="edge54" class="edge">
<title>:sync:work&#45;&gt;:core:analytics</title> <title>:sync:work&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M1078.53,-216.43C1057,-191.77 1016.33,-145.2 991.07,-116.27"/> <path fill="none" stroke="black" d="M1051.02,-215.59C1049.5,-191.61 1046.75,-148.14 1044.93,-119.42"/>
<polygon fill="black" stroke="black" points="993.97,-114.27 984.75,-109.04 988.7,-118.88 993.97,-114.27"/> <polygon fill="black" stroke="black" points="1048.43,-119.38 1044.31,-109.62 1041.45,-119.82 1048.43,-119.38"/>
</g> </g>
<!-- :core:domain&#45;&gt;:core:data --> <!-- :core:domain&#45;&gt;:core:data -->
<g id="edge35" class="edge"> <g id="edge35" class="edge">
<title>:core:domain&#45;&gt;:core:data</title> <title>:core:domain&#45;&gt;:core:data</title>
<path fill="none" stroke="red" stroke-width="2" d="M877.53,-221.2C831.66,-208.76 759.53,-189.19 711.76,-176.23"/> <path fill="none" stroke="red" stroke-width="2" d="M307.48,-222.29C363.12,-209.44 456.09,-187.96 513.55,-174.68"/>
<polygon fill="red" stroke="red" stroke-width="2" points="714.26,-173.28 703.69,-174.04 712.42,-180.04 714.26,-173.28"/> <polygon fill="red" stroke="red" stroke-width="2" points="512.64,-178.49 521.6,-172.83 511.06,-171.67 512.64,-178.49"/>
</g> </g>
<!-- :core:domain&#45;&gt;:core:model --> <!-- :core:domain&#45;&gt;:core:model -->
<g id="edge36" class="edge"> <g id="edge36" class="edge">
<title>:core:domain&#45;&gt;:core:model</title> <title>:core:domain&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M947.98,-217.6C996,-188.3 1087.32,-122.93 1043,-72 1003.2,-26.26 827.85,-18.77 729.86,-18.26"/> <path fill="none" stroke="black" d="M258.85,-215.58C255.67,-183.81 253.43,-115.69 285.13,-72 297.97,-54.29 318.43,-42.15 337.96,-34.01"/>
<polygon fill="black" stroke="black" points="730.12,-14.76 720.11,-18.24 730.1,-21.76 730.12,-14.76"/> <polygon fill="black" stroke="black" points="339.18,-37.29 347.25,-30.43 336.66,-30.76 339.18,-37.29"/>
</g> </g>
<!-- :core:database&#45;&gt;:core:model --> <!-- :core:database&#45;&gt;:core:model -->
<g id="edge27" class="edge"> <g id="edge27" class="edge">
<title>:core:database&#45;&gt;:core:model</title> <title>:core:database&#45;&gt;:core:model</title>
<path fill="none" stroke="red" stroke-width="2" d="M789.46,-74.33C765.06,-63.65 731.83,-49.11 705.55,-37.62"/> <path fill="none" stroke="red" stroke-width="2" d="M391.13,-71.7C391.13,-64.41 391.13,-55.73 391.13,-47.54"/>
<polygon fill="red" stroke="red" stroke-width="2" points="708.47,-35.07 697.91,-34.27 705.66,-41.49 708.47,-35.07"/> <polygon fill="red" stroke="red" stroke-width="2" points="394.63,-49.13 391.13,-39.13 387.63,-49.13 394.63,-49.13"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <!-- :core:datastore&#45;&gt;:core:common -->
<g id="edge30" class="edge"> <g id="edge30" class="edge">
<title>:core:datastore&#45;&gt;:core:common</title> <title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M339.3,-72.41C348.33,-63.76 359.54,-53 369.54,-43.42"/> <path fill="none" stroke="black" d="M862.83,-73.46C844.12,-63.54 819.63,-50.56 799.26,-39.75"/>
<polygon fill="black" stroke="black" points="371.68,-46.21 376.48,-36.76 366.84,-41.16 371.68,-46.21"/> <polygon fill="black" stroke="black" points="801.15,-36.79 790.68,-35.2 797.87,-42.98 801.15,-36.79"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:model --> <!-- :core:datastore&#45;&gt;:core:model -->
<g id="edge29" class="edge"> <g id="edge29" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:datastore&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M370.52,-77.64C379,-75.71 387.75,-73.77 396,-72 467.83,-56.62 550.87,-40.38 605.03,-29.99"/> <path fill="none" stroke="black" d="M836.32,-80.36C818.39,-77.63 798.43,-74.64 780.13,-72 664.78,-55.39 530,-37.33 453.19,-27.16"/>
<polygon fill="black" stroke="black" points="605.48,-33.47 614.64,-28.15 604.16,-26.59 605.48,-33.47"/> <polygon fill="black" stroke="black" points="453.7,-23.7 443.33,-25.86 452.78,-30.64 453.7,-23.7"/>
</g> </g>
<!-- :core:datastore&#45;proto --> <!-- :core:datastore&#45;proto -->
<g id="node20" class="node"> <g id="node20" class="node">
<title>:core:datastore&#45;proto</title> <title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="224" cy="-18" rx="87.69" ry="18"/> <ellipse fill="none" stroke="black" cx="931.13" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="224" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> <text text-anchor="middle" x="931.13" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto --> <!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge28" class="edge"> <g id="edge28" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title> <title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M299.27,-72.76C286.59,-63.71 270.58,-52.27 256.59,-42.28"/> <path fill="none" stroke="black" d="M901.57,-72.05C905.91,-64.26 911.17,-54.82 916.04,-46.08"/>
<polygon fill="black" stroke="black" points="258.69,-39.48 248.52,-36.51 254.62,-45.17 258.69,-39.48"/> <polygon fill="black" stroke="black" points="918.96,-48.04 920.77,-37.6 912.84,-44.63 918.96,-48.04"/>
</g> </g>
<!-- :core:network&#45;&gt;:core:common --> <!-- :core:network&#45;&gt;:core:common -->
<g id="edge31" class="edge"> <g id="edge31" class="edge">
<title>:core:network&#45;&gt;:core:common</title> <title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M449.94,-72.41C440.97,-63.69 429.81,-52.85 419.9,-43.21"/> <path fill="none" stroke="black" d="M721.47,-72.05C727.42,-63.89 734.69,-53.91 741.31,-44.82"/>
<polygon fill="black" stroke="black" points="422.64,-40.99 413.03,-36.53 417.76,-46.01 422.64,-40.99"/> <polygon fill="black" stroke="black" points="743.94,-47.16 747,-37.01 738.29,-43.03 743.94,-47.16"/>
</g> </g>
<!-- :core:network&#45;&gt;:core:model --> <!-- :core:network&#45;&gt;:core:model -->
<g id="edge32" class="edge"> <g id="edge32" class="edge">
<title>:core:network&#45;&gt;:core:model</title> <title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M504.79,-75.5C536.51,-64.17 581.97,-47.94 616.03,-35.78"/> <path fill="none" stroke="black" d="M662.57,-77.69C654.43,-75.76 646.04,-73.8 638.13,-72 573.05,-57.23 498.08,-41.3 447.97,-30.8"/>
<polygon fill="black" stroke="black" points="616.98,-39.15 625.23,-32.49 614.63,-32.56 616.98,-39.15"/> <polygon fill="black" stroke="black" points="448.71,-27.38 438.2,-28.76 447.28,-34.23 448.71,-27.38"/>
</g> </g>
<!-- :core:notifications&#45;&gt;:core:common --> <!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge34" class="edge"> <g id="edge34" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title> <title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M612.59,-75.83C566.97,-63.92 499.83,-46.38 452.21,-33.94"/> <path fill="none" stroke="black" d="M594.18,-74.58C627.64,-63.37 674.14,-47.8 709.41,-35.99"/>
<polygon fill="black" stroke="black" points="453.18,-30.58 442.62,-31.44 451.41,-37.35 453.18,-30.58"/> <polygon fill="black" stroke="black" points="710.16,-39.43 718.53,-32.93 707.94,-32.79 710.16,-39.43"/>
</g> </g>
<!-- :core:notifications&#45;&gt;:core:model --> <!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge33" class="edge"> <g id="edge33" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title> <title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M663,-71.7C663,-64.41 663,-55.73 663,-47.54"/> <path fill="none" stroke="black" d="M516.01,-73.64C491.68,-62.99 459.15,-48.76 433.39,-37.49"/>
<polygon fill="black" stroke="black" points="666.5,-47.62 663,-37.62 659.5,-47.62 666.5,-47.62"/> <polygon fill="black" stroke="black" points="435.12,-34.43 424.55,-33.62 432.31,-40.84 435.12,-34.43"/>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

@ -4,328 +4,226 @@
<!-- Generated by graphviz version 9.0.0 (20230911.1827) <!-- Generated by graphviz version 9.0.0 (20230911.1827)
--> -->
<!-- Title: G Pages: 1 --> <!-- Title: G Pages: 1 -->
<svg width="1034pt" height="404pt" <svg width="1073pt" height="332pt"
viewBox="0.00 0.00 1033.76 404.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> viewBox="0.00 0.00 1072.75 332.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 400)"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 328)">
<title>G</title> <title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-400 1029.76,-400 1029.76,4 -4,4"/> <polygon fill="white" stroke="none" points="-4,4 -4,-328 1068.75,-328 1068.75,4 -4,4"/>
<!-- :feature:search --> <!-- :feature:search -->
<g id="node1" class="node"> <g id="node1" class="node">
<title>:feature:search</title> <title>:feature:search</title>
<ellipse fill="none" stroke="black" cx="278.07" cy="-378" rx="65.17" ry="18"/> <ellipse fill="none" stroke="black" cx="250.06" cy="-306" rx="65.17" ry="18"/>
<text text-anchor="middle" x="278.07" y="-372.95" font-family="Times,serif" font-size="14.00">:feature:search</text> <text text-anchor="middle" x="250.06" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:search</text>
</g> </g>
<!-- :core:ui --> <!-- :core:ui -->
<g id="node2" class="node"> <g id="node2" class="node">
<title>:core:ui</title> <title>:core:ui</title>
<ellipse fill="none" stroke="black" cx="111.07" cy="-234" rx="39.07" ry="18"/> <ellipse fill="none" stroke="black" cx="192.06" cy="-234" rx="39.07" ry="18"/>
<text text-anchor="middle" x="111.07" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text> <text text-anchor="middle" x="192.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:ui</text>
</g> </g>
<!-- :feature:search&#45;&gt;:core:ui --> <!-- :feature:search&#45;&gt;:core:ui -->
<g id="edge1" class="edge"> <g id="edge1" class="edge">
<title>:feature:search&#45;&gt;:core:ui</title> <title>:feature:search&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M215.02,-373.03C146.44,-367.24 43.34,-353.74 19.07,-324 8.95,-311.6 11.06,-301.85 19.07,-288 29.76,-269.5 49.63,-256.89 68.17,-248.63"/> <path fill="none" stroke="black" d="M236.02,-288.05C229.08,-279.68 220.57,-269.4 212.89,-260.13"/>
<polygon fill="black" stroke="black" points="69.24,-251.97 77.16,-244.94 66.58,-245.5 69.24,-251.97"/> <polygon fill="black" stroke="black" points="215.61,-257.94 206.54,-252.47 210.22,-262.41 215.61,-257.94"/>
</g> </g>
<!-- :core:designsystem --> <!-- :core:designsystem -->
<g id="node3" class="node"> <g id="node3" class="node">
<title>:core:designsystem</title> <title>:core:designsystem</title>
<ellipse fill="none" stroke="black" cx="200.07" cy="-162" rx="82.06" ry="18"/> <ellipse fill="none" stroke="black" cx="82.06" cy="-162" rx="82.06" ry="18"/>
<text text-anchor="middle" x="200.07" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text> <text text-anchor="middle" x="82.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:designsystem</text>
</g> </g>
<!-- :feature:search&#45;&gt;:core:designsystem --> <!-- :feature:search&#45;&gt;:core:designsystem -->
<g id="edge2" class="edge"> <g id="edge2" class="edge">
<title>:feature:search&#45;&gt;:core:designsystem</title> <title>:feature:search&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M214.52,-373.54C143.34,-368.18 34.58,-355.02 9.07,-324 -25.99,-281.35 57.01,-220.59 63.07,-216 84.59,-199.7 111.73,-187.82 136.17,-179.49"/> <path fill="none" stroke="black" d="M211.24,-291.1C189.86,-282.17 163.75,-269.02 144.06,-252 123.99,-234.64 107.23,-209.43 96.22,-190.27"/>
<polygon fill="black" stroke="black" points="136.95,-182.92 145.37,-176.49 134.78,-176.26 136.95,-182.92"/> <polygon fill="black" stroke="black" points="99.35,-188.7 91.44,-181.66 93.23,-192.1 99.35,-188.7"/>
</g> </g>
<!-- :core:data --> <!-- :core:data -->
<g id="node4" class="node"> <g id="node4" class="node">
<title>:core:data</title> <title>:core:data</title>
<ellipse fill="none" stroke="black" cx="517.07" cy="-162" rx="47.26" ry="18"/> <ellipse fill="none" stroke="black" cx="568.06" cy="-162" rx="47.26" ry="18"/>
<text text-anchor="middle" x="517.07" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text> <text text-anchor="middle" x="568.06" y="-156.95" font-family="Times,serif" font-size="14.00">:core:data</text>
</g> </g>
<!-- :feature:search&#45;&gt;:core:data --> <!-- :feature:search&#45;&gt;:core:data -->
<g id="edge3" class="edge"> <g id="edge3" class="edge">
<title>:feature:search&#45;&gt;:core:data</title> <title>:feature:search&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M341.07,-372.8C408.59,-366.84 509.31,-353.2 533.07,-324 563.94,-286.05 545.4,-225.23 530.4,-190.21"/> <path fill="none" stroke="black" d="M286.11,-290.58C311.86,-280.16 347.25,-265.59 378.06,-252 430.92,-228.69 491.2,-200.11 529.43,-181.73"/>
<polygon fill="black" stroke="black" points="533.63,-188.87 526.34,-181.19 527.25,-191.75 533.63,-188.87"/> <polygon fill="black" stroke="black" points="530.74,-184.98 538.23,-177.48 527.71,-178.67 530.74,-184.98"/>
</g> </g>
<!-- :core:domain --> <!-- :core:domain -->
<g id="node5" class="node"> <g id="node5" class="node">
<title>:core:domain</title> <title>:core:domain</title>
<ellipse fill="none" stroke="black" cx="429.07" cy="-234" rx="60.05" ry="18"/> <ellipse fill="none" stroke="black" cx="309.06" cy="-234" rx="60.05" ry="18"/>
<text text-anchor="middle" x="429.07" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text> <text text-anchor="middle" x="309.06" y="-228.95" font-family="Times,serif" font-size="14.00">:core:domain</text>
</g> </g>
<!-- :feature:search&#45;&gt;:core:domain --> <!-- :feature:search&#45;&gt;:core:domain -->
<g id="edge4" class="edge"> <g id="edge4" class="edge">
<title>:feature:search&#45;&gt;:core:domain</title> <title>:feature:search&#45;&gt;:core:domain</title>
<path fill="none" stroke="black" d="M339.78,-371.88C402.79,-365.22 494.35,-351.08 516.07,-324 526.08,-311.52 523.91,-301.95 516.07,-288 507.47,-272.69 492.46,-261.29 477.31,-253.06"/> <path fill="none" stroke="red" stroke-width="2" d="M264.34,-288.05C271.3,-279.8 279.81,-269.7 287.54,-260.54"/>
<polygon fill="black" stroke="black" points="479.25,-250.12 468.74,-248.78 476.12,-256.38 479.25,-250.12"/> <polygon fill="red" stroke="red" stroke-width="2" points="289.19,-264.01 292.96,-254.1 283.84,-259.49 289.19,-264.01"/>
</g>
<!-- :feature:bookmarks -->
<g id="node6" class="node">
<title>:feature:bookmarks</title>
<ellipse fill="none" stroke="black" cx="111.07" cy="-306" rx="83.08" ry="18"/>
<text text-anchor="middle" x="111.07" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:bookmarks</text>
</g>
<!-- :feature:search&#45;&gt;:feature:bookmarks -->
<g id="edge5" class="edge">
<title>:feature:search&#45;&gt;:feature:bookmarks</title>
<path fill="none" stroke="black" d="M243.47,-362.5C218.84,-352.17 185.45,-338.18 158.36,-326.82"/>
<polygon fill="black" stroke="black" points="159.92,-323.68 149.34,-323.04 157.21,-330.14 159.92,-323.68"/>
</g>
<!-- :feature:foryou -->
<g id="node7" class="node">
<title>:feature:foryou</title>
<ellipse fill="none" stroke="black" cx="278.07" cy="-306" rx="66.19" ry="18"/>
<text text-anchor="middle" x="278.07" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:foryou</text>
</g>
<!-- :feature:search&#45;&gt;:feature:foryou -->
<g id="edge6" class="edge">
<title>:feature:search&#45;&gt;:feature:foryou</title>
<path fill="none" stroke="red" stroke-width="2" d="M278.07,-359.7C278.07,-352.41 278.07,-343.73 278.07,-335.54"/>
<polygon fill="red" stroke="red" stroke-width="2" points="281.57,-337.13 278.07,-327.13 274.57,-337.13 281.57,-337.13"/>
</g>
<!-- :feature:interests -->
<g id="node8" class="node">
<title>:feature:interests</title>
<ellipse fill="none" stroke="black" cx="435.07" cy="-306" rx="72.34" ry="18"/>
<text text-anchor="middle" x="435.07" y="-300.95" font-family="Times,serif" font-size="14.00">:feature:interests</text>
</g>
<!-- :feature:search&#45;&gt;:feature:interests -->
<g id="edge7" class="edge">
<title>:feature:search&#45;&gt;:feature:interests</title>
<path fill="none" stroke="black" d="M311.36,-362.15C334.36,-351.9 365.21,-338.15 390.35,-326.94"/>
<polygon fill="black" stroke="black" points="391.65,-330.19 399.35,-322.92 388.8,-323.8 391.65,-330.19"/>
</g> </g>
<!-- :core:ui&#45;&gt;:core:designsystem --> <!-- :core:ui&#45;&gt;:core:designsystem -->
<g id="edge9" class="edge"> <g id="edge6" class="edge">
<title>:core:ui&#45;&gt;:core:designsystem</title> <title>:core:ui&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M129.94,-218.15C141.55,-209.02 156.69,-197.12 169.93,-186.71"/> <path fill="none" stroke="black" d="M169.8,-218.83C154.65,-209.19 134.29,-196.24 117,-185.23"/>
<polygon fill="black" stroke="black" points="171.84,-189.66 177.53,-180.72 167.51,-184.16 171.84,-189.66"/> <polygon fill="black" stroke="black" points="119.35,-182.58 109.04,-180.17 115.59,-188.49 119.35,-182.58"/>
</g> </g>
<!-- :core:analytics --> <!-- :core:analytics -->
<g id="node9" class="node"> <g id="node6" class="node">
<title>:core:analytics</title> <title>:core:analytics</title>
<ellipse fill="none" stroke="black" cx="291.07" cy="-90" rx="64.66" ry="18"/> <ellipse fill="none" stroke="black" cx="342.06" cy="-90" rx="64.66" ry="18"/>
<text text-anchor="middle" x="291.07" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text> <text text-anchor="middle" x="342.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:analytics</text>
</g> </g>
<!-- :core:ui&#45;&gt;:core:analytics --> <!-- :core:ui&#45;&gt;:core:analytics -->
<g id="edge8" class="edge"> <g id="edge5" class="edge">
<title>:core:ui&#45;&gt;:core:analytics</title> <title>:core:ui&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M105,-216.04C99.22,-196.61 93.49,-164.77 109.07,-144 123.26,-125.09 178.83,-110.72 224.88,-101.74"/> <path fill="none" stroke="black" d="M208.69,-217.26C234.76,-192.58 285.48,-144.57 316.3,-115.38"/>
<polygon fill="black" stroke="black" points="225.38,-105.21 234.56,-99.91 224.08,-98.33 225.38,-105.21"/> <polygon fill="black" stroke="black" points="318.48,-118.14 323.33,-108.73 313.67,-113.06 318.48,-118.14"/>
</g> </g>
<!-- :core:model --> <!-- :core:model -->
<g id="node10" class="node"> <g id="node7" class="node">
<title>:core:model</title> <title>:core:model</title>
<ellipse fill="none" stroke="black" cx="517.07" cy="-18" rx="55.45" ry="18"/> <ellipse fill="none" stroke="black" cx="568.06" cy="-18" rx="55.45" ry="18"/>
<text text-anchor="middle" x="517.07" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text> <text text-anchor="middle" x="568.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:model</text>
</g> </g>
<!-- :core:ui&#45;&gt;:core:model --> <!-- :core:ui&#45;&gt;:core:model -->
<g id="edge10" class="edge"> <g id="edge7" class="edge">
<title>:core:ui&#45;&gt;:core:model</title> <title>:core:ui&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M101.91,-216.22C93.05,-197.52 82.63,-166.9 95.07,-144 123.14,-92.33 151.29,-93.38 206.07,-72 286.93,-40.44 386.87,-27.64 451.27,-22.47"/> <path fill="none" stroke="black" d="M192.94,-215.73C195.65,-182.32 206.61,-108.88 251.06,-72 288.33,-41.08 420.81,-27.72 502.24,-22.33"/>
<polygon fill="black" stroke="black" points="451.26,-25.98 460.96,-21.74 450.73,-19 451.26,-25.98"/> <polygon fill="black" stroke="black" points="502.11,-25.84 511.87,-21.71 501.66,-18.86 502.11,-25.84"/>
</g> </g>
<!-- :core:data&#45;&gt;:core:analytics --> <!-- :core:data&#45;&gt;:core:analytics -->
<g id="edge15" class="edge"> <g id="edge12" class="edge">
<title>:core:data&#45;&gt;:core:analytics</title> <title>:core:data&#45;&gt;:core:analytics</title>
<path fill="none" stroke="black" d="M481.26,-149.91C444.35,-138.48 386.41,-120.53 344.17,-107.45"/> <path fill="none" stroke="black" d="M532.25,-149.91C495.35,-138.48 437.4,-120.53 395.16,-107.45"/>
<polygon fill="black" stroke="black" points="345.28,-104.13 334.7,-104.51 343.21,-110.81 345.28,-104.13"/> <polygon fill="black" stroke="black" points="396.27,-104.13 385.69,-104.51 394.2,-110.81 396.27,-104.13"/>
</g> </g>
<!-- :core:common --> <!-- :core:common -->
<g id="node11" class="node"> <g id="node8" class="node">
<title>:core:common</title> <title>:core:common</title>
<ellipse fill="none" stroke="black" cx="761.07" cy="-18" rx="65.17" ry="18"/> <ellipse fill="none" stroke="black" cx="806.06" cy="-18" rx="65.17" ry="18"/>
<text text-anchor="middle" x="761.07" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text> <text text-anchor="middle" x="806.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:common</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:common --> <!-- :core:data&#45;&gt;:core:common -->
<g id="edge11" class="edge"> <g id="edge8" class="edge">
<title>:core:data&#45;&gt;:core:common</title> <title>:core:data&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M564.54,-160.03C642.71,-157.31 793.18,-147.01 826.07,-108 836.38,-95.77 832.93,-86.45 826.07,-72 820.22,-59.69 809.96,-49.3 799.3,-41.07"/> <path fill="none" stroke="black" d="M614.84,-159.04C725.87,-153.9 998.07,-138.31 1025.06,-108 1035.7,-96.05 1034.95,-84.57 1025.06,-72 1023.79,-70.39 929.84,-48.06 865.42,-32.9"/>
<polygon fill="black" stroke="black" points="801.34,-38.22 791.16,-35.27 797.28,-43.92 801.34,-38.22"/> <polygon fill="black" stroke="black" points="866.57,-29.58 856.03,-30.7 864.97,-36.39 866.57,-29.58"/>
</g> </g>
<!-- :core:database --> <!-- :core:database -->
<g id="node12" class="node"> <g id="node9" class="node">
<title>:core:database</title> <title>:core:database</title>
<ellipse fill="none" stroke="black" cx="437.07" cy="-90" rx="63.63" ry="18"/> <ellipse fill="none" stroke="black" cx="488.06" cy="-90" rx="63.63" ry="18"/>
<text text-anchor="middle" x="437.07" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text> <text text-anchor="middle" x="488.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:database</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:database --> <!-- :core:data&#45;&gt;:core:database -->
<g id="edge12" class="edge"> <g id="edge9" class="edge">
<title>:core:data&#45;&gt;:core:database</title> <title>:core:data&#45;&gt;:core:database</title>
<path fill="none" stroke="red" stroke-width="2" d="M498.92,-145.12C488.7,-136.18 475.75,-124.85 464.34,-114.86"/> <path fill="none" stroke="red" stroke-width="2" d="M549.91,-145.12C539.69,-136.18 526.74,-124.85 515.33,-114.86"/>
<polygon fill="red" stroke="red" stroke-width="2" points="468.09,-113.5 458.26,-109.54 463.48,-118.76 468.09,-113.5"/> <polygon fill="red" stroke="red" stroke-width="2" points="519.08,-113.5 509.25,-109.54 514.48,-118.76 519.08,-113.5"/>
</g> </g>
<!-- :core:datastore --> <!-- :core:datastore -->
<g id="node13" class="node"> <g id="node10" class="node">
<title>:core:datastore</title> <title>:core:datastore</title>
<ellipse fill="none" stroke="black" cx="938.07" cy="-90" rx="65.17" ry="18"/> <ellipse fill="none" stroke="black" cx="951.06" cy="-90" rx="65.17" ry="18"/>
<text text-anchor="middle" x="938.07" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text> <text text-anchor="middle" x="951.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:datastore</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:datastore --> <!-- :core:data&#45;&gt;:core:datastore -->
<g id="edge13" class="edge"> <g id="edge10" class="edge">
<title>:core:data&#45;&gt;:core:datastore</title> <title>:core:data&#45;&gt;:core:datastore</title>
<path fill="none" stroke="black" d="M561.21,-155C626.5,-145.93 752.57,-127.69 859.07,-108 865.1,-106.88 871.38,-105.65 877.65,-104.38"/> <path fill="none" stroke="black" d="M611.44,-154.34C671.36,-144.97 782.73,-126.91 877.06,-108 881.92,-107.03 886.94,-105.97 891.98,-104.88"/>
<polygon fill="black" stroke="black" points="878.29,-107.82 887.37,-102.36 876.87,-100.97 878.29,-107.82"/> <polygon fill="black" stroke="black" points="892.49,-108.35 901.5,-102.78 890.98,-101.52 892.49,-108.35"/>
</g> </g>
<!-- :core:network --> <!-- :core:network -->
<g id="node14" class="node"> <g id="node11" class="node">
<title>:core:network</title> <title>:core:network</title>
<ellipse fill="none" stroke="black" cx="755.07" cy="-90" rx="62.1" ry="18"/> <ellipse fill="none" stroke="black" cx="806.06" cy="-90" rx="62.1" ry="18"/>
<text text-anchor="middle" x="755.07" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text> <text text-anchor="middle" x="806.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:network</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:network --> <!-- :core:data&#45;&gt;:core:network -->
<g id="edge14" class="edge"> <g id="edge11" class="edge">
<title>:core:data&#45;&gt;:core:network</title> <title>:core:data&#45;&gt;:core:network</title>
<path fill="none" stroke="black" d="M553.73,-150.22C593.28,-138.58 656.63,-119.95 701.7,-106.7"/> <path fill="none" stroke="black" d="M604.73,-150.22C644.27,-138.58 707.62,-119.95 752.69,-106.7"/>
<polygon fill="black" stroke="black" points="702.68,-110.06 711.28,-103.88 700.7,-103.34 702.68,-110.06"/> <polygon fill="black" stroke="black" points="753.67,-110.06 762.27,-103.88 751.69,-103.34 753.67,-110.06"/>
</g> </g>
<!-- :core:notifications --> <!-- :core:notifications -->
<g id="node15" class="node"> <g id="node12" class="node">
<title>:core:notifications</title> <title>:core:notifications</title>
<ellipse fill="none" stroke="black" cx="597.07" cy="-90" rx="77.97" ry="18"/> <ellipse fill="none" stroke="black" cx="648.06" cy="-90" rx="77.97" ry="18"/>
<text text-anchor="middle" x="597.07" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text> <text text-anchor="middle" x="648.06" y="-84.95" font-family="Times,serif" font-size="14.00">:core:notifications</text>
</g> </g>
<!-- :core:data&#45;&gt;:core:notifications --> <!-- :core:data&#45;&gt;:core:notifications -->
<g id="edge16" class="edge"> <g id="edge13" class="edge">
<title>:core:data&#45;&gt;:core:notifications</title> <title>:core:data&#45;&gt;:core:notifications</title>
<path fill="none" stroke="black" d="M535.22,-145.12C545.26,-136.33 557.95,-125.23 569.22,-115.37"/> <path fill="none" stroke="black" d="M586.21,-145.12C596.25,-136.33 608.94,-125.23 620.21,-115.37"/>
<polygon fill="black" stroke="black" points="571.51,-118.01 576.73,-108.79 566.9,-112.75 571.51,-118.01"/> <polygon fill="black" stroke="black" points="622.5,-118.01 627.72,-108.79 617.89,-112.75 622.5,-118.01"/>
</g> </g>
<!-- :core:domain&#45;&gt;:core:data --> <!-- :core:domain&#45;&gt;:core:data -->
<g id="edge25" class="edge"> <g id="edge22" class="edge">
<title>:core:domain&#45;&gt;:core:data</title> <title>:core:domain&#45;&gt;:core:data</title>
<path fill="none" stroke="red" stroke-width="2" d="M449.48,-216.76C461.08,-207.53 475.79,-195.83 488.53,-185.7"/> <path fill="none" stroke="red" stroke-width="2" d="M352.7,-221.2C398.75,-208.76 471.15,-189.19 519.11,-176.23"/>
<polygon fill="red" stroke="red" stroke-width="2" points="489.36,-189.51 495.01,-180.55 485,-184.04 489.36,-189.51"/> <polygon fill="red" stroke="red" stroke-width="2" points="518.48,-180.02 527.22,-174.04 516.66,-173.27 518.48,-180.02"/>
</g> </g>
<!-- :core:domain&#45;&gt;:core:model --> <!-- :core:domain&#45;&gt;:core:model -->
<g id="edge26" class="edge"> <g id="edge23" class="edge">
<title>:core:domain&#45;&gt;:core:model</title> <title>:core:domain&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M406.15,-217.01C379.19,-198.48 332.8,-167.5 291.07,-144 259.2,-126.06 236.47,-139.01 217.07,-108 208.58,-94.44 206.79,-84.26 217.07,-72 246.27,-37.19 371.39,-25.23 450.53,-21.13"/> <path fill="none" stroke="black" d="M296.33,-216.3C273.75,-184.5 232.28,-114.65 268.06,-72 297.26,-37.19 422.38,-25.23 501.52,-21.13"/>
<polygon fill="black" stroke="black" points="450.53,-24.64 460.35,-20.66 450.19,-17.64 450.53,-24.64"/> <polygon fill="black" stroke="black" points="501.52,-24.64 511.34,-20.66 501.18,-17.64 501.52,-24.64"/>
</g>
<!-- :feature:bookmarks&#45;&gt;:core:ui -->
<g id="edge27" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M111.07,-287.7C111.07,-280.41 111.07,-271.73 111.07,-263.54"/>
<polygon fill="black" stroke="black" points="114.57,-263.62 111.07,-253.62 107.57,-263.62 114.57,-263.62"/>
</g>
<!-- :feature:bookmarks&#45;&gt;:core:designsystem -->
<g id="edge28" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M128.96,-287.98C138.68,-278.09 150.45,-265.05 159.07,-252 171.8,-232.72 182.57,-208.85 189.86,-190.68"/>
<polygon fill="black" stroke="black" points="193.03,-192.2 193.4,-181.61 186.51,-189.66 193.03,-192.2"/>
</g>
<!-- :feature:bookmarks&#45;&gt;:core:data -->
<g id="edge29" class="edge">
<title>:feature:bookmarks&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M143.65,-289.12C183.77,-270 254.3,-237.74 317.07,-216 366.71,-198.81 424.91,-183.96 465.68,-174.39"/>
<polygon fill="black" stroke="black" points="466.27,-177.85 475.22,-172.18 464.69,-171.03 466.27,-177.85"/>
</g>
<!-- :feature:foryou&#45;&gt;:core:ui -->
<g id="edge30" class="edge">
<title>:feature:foryou&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M243.06,-290.33C215.75,-278.88 177.85,-262.99 149.67,-251.18"/>
<polygon fill="black" stroke="black" points="151.36,-248.09 140.78,-247.45 148.65,-254.55 151.36,-248.09"/>
</g>
<!-- :feature:foryou&#45;&gt;:core:designsystem -->
<g id="edge31" class="edge">
<title>:feature:foryou&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M268.66,-287.87C255.31,-263.56 230.73,-218.82 214.91,-190.01"/>
<polygon fill="black" stroke="black" points="218.12,-188.6 210.24,-181.52 211.99,-191.97 218.12,-188.6"/>
</g>
<!-- :feature:foryou&#45;&gt;:core:data -->
<g id="edge32" class="edge">
<title>:feature:foryou&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M289.73,-287.85C304.09,-267.93 330.29,-235.34 360.07,-216 391.9,-195.33 432.63,-181.89 464.62,-173.71"/>
<polygon fill="black" stroke="black" points="465.2,-177.18 474.08,-171.4 463.53,-170.38 465.2,-177.18"/>
</g>
<!-- :feature:foryou&#45;&gt;:core:domain -->
<g id="edge33" class="edge">
<title>:feature:foryou&#45;&gt;:core:domain</title>
<path fill="none" stroke="red" stroke-width="2" d="M310.46,-289.98C332.88,-279.59 362.93,-265.66 387.17,-254.42"/>
<polygon fill="red" stroke="red" stroke-width="2" points="387.16,-258.29 394.76,-250.91 384.21,-251.94 387.16,-258.29"/>
</g>
<!-- :feature:interests&#45;&gt;:core:ui -->
<g id="edge34" class="edge">
<title>:feature:interests&#45;&gt;:core:ui</title>
<path fill="none" stroke="black" d="M381.93,-293.52C319.19,-279.96 215.9,-257.65 156.65,-244.85"/>
<polygon fill="black" stroke="black" points="157.76,-241.51 147.25,-242.82 156.28,-248.35 157.76,-241.51"/>
</g>
<!-- :feature:interests&#45;&gt;:core:designsystem -->
<g id="edge35" class="edge">
<title>:feature:interests&#45;&gt;:core:designsystem</title>
<path fill="none" stroke="black" d="M408.57,-288.99C366.54,-263.59 284.5,-214.02 236.82,-185.21"/>
<polygon fill="black" stroke="black" points="238.86,-182.35 228.49,-180.17 235.24,-188.34 238.86,-182.35"/>
</g>
<!-- :feature:interests&#45;&gt;:core:data -->
<g id="edge36" class="edge">
<title>:feature:interests&#45;&gt;:core:data</title>
<path fill="none" stroke="black" d="M461.4,-288.93C474.36,-279.69 489.09,-266.95 498.07,-252 509.03,-233.75 513.71,-210.07 515.69,-191.72"/>
<polygon fill="black" stroke="black" points="519.18,-192.04 516.53,-181.78 512.21,-191.45 519.18,-192.04"/>
</g>
<!-- :feature:interests&#45;&gt;:core:domain -->
<g id="edge37" class="edge">
<title>:feature:interests&#45;&gt;:core:domain</title>
<path fill="none" stroke="black" d="M433.59,-287.7C432.96,-280.41 432.22,-271.73 431.51,-263.54"/>
<polygon fill="black" stroke="black" points="435.01,-263.28 430.66,-253.61 428.03,-263.87 435.01,-263.28"/>
</g> </g>
<!-- :core:database&#45;&gt;:core:model --> <!-- :core:database&#45;&gt;:core:model -->
<g id="edge17" class="edge"> <g id="edge14" class="edge">
<title>:core:database&#45;&gt;:core:model</title> <title>:core:database&#45;&gt;:core:model</title>
<path fill="none" stroke="red" stroke-width="2" d="M456.03,-72.41C466.16,-63.54 478.82,-52.47 489.97,-42.71"/> <path fill="none" stroke="red" stroke-width="2" d="M507.02,-72.41C517.15,-63.54 529.81,-52.47 540.96,-42.71"/>
<polygon fill="red" stroke="red" stroke-width="2" points="491.02,-46.44 496.24,-37.22 486.41,-41.17 491.02,-46.44"/> <polygon fill="red" stroke="red" stroke-width="2" points="542.01,-46.44 547.23,-37.22 537.4,-41.17 542.01,-46.44"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:model --> <!-- :core:datastore&#45;&gt;:core:model -->
<g id="edge19" class="edge"> <g id="edge16" class="edge">
<title>:core:datastore&#45;&gt;:core:model</title> <title>:core:datastore&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M883.46,-79.92C804.42,-66.78 658.64,-42.54 576.82,-28.93"/> <path fill="none" stroke="black" d="M902.98,-77.54C894.37,-75.61 885.46,-73.68 877.06,-72 791.15,-54.78 691.1,-38.26 628.66,-28.37"/>
<polygon fill="black" stroke="black" points="577.64,-25.52 567.2,-27.34 576.49,-32.43 577.64,-25.52"/> <polygon fill="black" stroke="black" points="629.37,-24.94 618.95,-26.83 628.28,-31.85 629.37,-24.94"/>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:common --> <!-- :core:datastore&#45;&gt;:core:common -->
<g id="edge20" class="edge"> <g id="edge17" class="edge">
<title>:core:datastore&#45;&gt;:core:common</title> <title>:core:datastore&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M901.82,-74.67C874.62,-63.91 837.15,-49.09 807.72,-37.45"/> <path fill="none" stroke="black" d="M919.6,-73.81C898.51,-63.63 870.51,-50.11 847.59,-39.05"/>
<polygon fill="black" stroke="black" points="809.26,-34.29 798.67,-33.87 806.69,-40.8 809.26,-34.29"/> <polygon fill="black" stroke="black" points="849.35,-36.01 838.82,-34.82 846.31,-42.32 849.35,-36.01"/>
</g> </g>
<!-- :core:datastore&#45;proto --> <!-- :core:datastore&#45;proto -->
<g id="node16" class="node"> <g id="node13" class="node">
<title>:core:datastore&#45;proto</title> <title>:core:datastore&#45;proto</title>
<ellipse fill="none" stroke="black" cx="938.07" cy="-18" rx="87.69" ry="18"/> <ellipse fill="none" stroke="black" cx="977.06" cy="-18" rx="87.69" ry="18"/>
<text text-anchor="middle" x="938.07" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text> <text text-anchor="middle" x="977.06" y="-12.95" font-family="Times,serif" font-size="14.00">:core:datastore&#45;proto</text>
</g> </g>
<!-- :core:datastore&#45;&gt;:core:datastore&#45;proto --> <!-- :core:datastore&#45;&gt;:core:datastore&#45;proto -->
<g id="edge18" class="edge"> <g id="edge15" class="edge">
<title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title> <title>:core:datastore&#45;&gt;:core:datastore&#45;proto</title>
<path fill="none" stroke="black" d="M938.07,-71.7C938.07,-64.41 938.07,-55.73 938.07,-47.54"/> <path fill="none" stroke="black" d="M957.49,-71.7C960.29,-64.15 963.64,-55.12 966.78,-46.68"/>
<polygon fill="black" stroke="black" points="941.57,-47.62 938.07,-37.62 934.57,-47.62 941.57,-47.62"/> <polygon fill="black" stroke="black" points="969.98,-48.12 970.18,-37.52 963.42,-45.68 969.98,-48.12"/>
</g> </g>
<!-- :core:network&#45;&gt;:core:model --> <!-- :core:network&#45;&gt;:core:model -->
<g id="edge22" class="edge"> <g id="edge19" class="edge">
<title>:core:network&#45;&gt;:core:model</title> <title>:core:network&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M712.52,-76.49C672.05,-64.58 611.13,-46.67 568.08,-34"/> <path fill="none" stroke="black" d="M763.51,-76.49C723.04,-64.58 662.12,-46.67 619.07,-34"/>
<polygon fill="black" stroke="black" points="569.3,-30.71 558.72,-31.25 567.33,-37.43 569.3,-30.71"/> <polygon fill="black" stroke="black" points="620.29,-30.71 609.71,-31.25 618.32,-37.43 620.29,-30.71"/>
</g> </g>
<!-- :core:network&#45;&gt;:core:common --> <!-- :core:network&#45;&gt;:core:common -->
<g id="edge21" class="edge"> <g id="edge18" class="edge">
<title>:core:network&#45;&gt;:core:common</title> <title>:core:network&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M756.55,-71.7C757.18,-64.41 757.92,-55.73 758.62,-47.54"/> <path fill="none" stroke="black" d="M806.06,-71.7C806.06,-64.41 806.06,-55.73 806.06,-47.54"/>
<polygon fill="black" stroke="black" points="762.11,-47.87 759.47,-37.61 755.13,-47.28 762.11,-47.87"/> <polygon fill="black" stroke="black" points="809.56,-47.62 806.06,-37.62 802.56,-47.62 809.56,-47.62"/>
</g> </g>
<!-- :core:notifications&#45;&gt;:core:model --> <!-- :core:notifications&#45;&gt;:core:model -->
<g id="edge23" class="edge"> <g id="edge20" class="edge">
<title>:core:notifications&#45;&gt;:core:model</title> <title>:core:notifications&#45;&gt;:core:model</title>
<path fill="none" stroke="black" d="M578.11,-72.41C567.97,-63.54 555.32,-52.47 544.16,-42.71"/> <path fill="none" stroke="black" d="M629.1,-72.41C618.97,-63.54 606.31,-52.47 595.15,-42.71"/>
<polygon fill="black" stroke="black" points="546.59,-40.18 536.75,-36.23 541.98,-45.44 546.59,-40.18"/> <polygon fill="black" stroke="black" points="597.58,-40.18 587.75,-36.23 592.97,-45.44 597.58,-40.18"/>
</g> </g>
<!-- :core:notifications&#45;&gt;:core:common --> <!-- :core:notifications&#45;&gt;:core:common -->
<g id="edge24" class="edge"> <g id="edge21" class="edge">
<title>:core:notifications&#45;&gt;:core:common</title> <title>:core:notifications&#45;&gt;:core:common</title>
<path fill="none" stroke="black" d="M633.06,-73.64C657.51,-63.2 690.02,-49.33 716.16,-38.17"/> <path fill="none" stroke="black" d="M683.13,-73.46C706.43,-63.14 737.22,-49.5 762.16,-38.45"/>
<polygon fill="black" stroke="black" points="717.35,-41.47 725.17,-34.32 714.6,-35.03 717.35,-41.47"/> <polygon fill="black" stroke="black" points="763.34,-41.76 771.06,-34.51 760.5,-35.36 763.34,-41.76"/>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@ -36,6 +36,7 @@ import com.google.samples.apps.nowinandroid.core.testing.util.TestSyncManager
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.LINKED_NEWS_RESOURCE_ID import com.google.samples.apps.nowinandroid.feature.foryou.navigation.LINKED_NEWS_RESOURCE_ID
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.advanceUntilIdle
@ -70,6 +71,7 @@ class ForYouViewModelTest {
topicsRepository = topicsRepository, topicsRepository = topicsRepository,
userDataRepository = userDataRepository, userDataRepository = userDataRepository,
) )
private val savedStateHandle = SavedStateHandle() private val savedStateHandle = SavedStateHandle()
private lateinit var viewModel: ForYouViewModel private lateinit var viewModel: ForYouViewModel
@ -504,6 +506,24 @@ class ForYouViewModelTest {
collectJob.cancel() collectJob.cancel()
} }
@Test
fun whenUpdateNewsResourceSavedIsCalled_bookmarkStateIsUpdated() = runTest {
val newsResourceId = "123"
viewModel.updateNewsResourceSaved(newsResourceId, true)
assertEquals(
expected = setOf(newsResourceId),
actual = userDataRepository.userData.first().bookmarkedNewsResources,
)
viewModel.updateNewsResourceSaved(newsResourceId, false)
assertEquals(
expected = emptySet(),
actual = userDataRepository.userData.first().bookmarkedNewsResources,
)
}
} }
private val sampleTopics = listOf( private val sampleTopics = listOf(

@ -27,10 +27,11 @@ import androidx.compose.ui.test.onNodeWithText
import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData
import com.google.samples.apps.nowinandroid.feature.interests.InterestsScreen import com.google.samples.apps.nowinandroid.feature.interests.InterestsScreen
import com.google.samples.apps.nowinandroid.feature.interests.InterestsUiState import com.google.samples.apps.nowinandroid.feature.interests.InterestsUiState
import com.google.samples.apps.nowinandroid.feature.interests.R
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import com.google.samples.apps.nowinandroid.core.ui.R as CoreUiR
import com.google.samples.apps.nowinandroid.feature.interests.R as InterestsR
/** /**
* UI test for checking the correct behaviour of the Interests screen; * UI test for checking the correct behaviour of the Interests screen;
@ -50,12 +51,12 @@ class InterestsScreenTest {
@Before @Before
fun setup() { fun setup() {
composeTestRule.activity.apply { composeTestRule.activity.apply {
interestsLoading = getString(R.string.feature_interests_loading) interestsLoading = getString(InterestsR.string.feature_interests_loading)
interestsEmptyHeader = getString(R.string.feature_interests_empty_header) interestsEmptyHeader = getString(InterestsR.string.feature_interests_empty_header)
interestsTopicCardFollowButton = interestsTopicCardFollowButton =
getString(R.string.feature_interests_card_follow_button_content_desc) getString(CoreUiR.string.core_ui_interests_card_follow_button_content_desc)
interestsTopicCardUnfollowButton = interestsTopicCardUnfollowButton =
getString(R.string.feature_interests_card_unfollow_button_content_desc) getString(CoreUiR.string.core_ui_interests_card_unfollow_button_content_desc)
} }
} }

@ -39,6 +39,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollba
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.rememberDraggableScroller import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.rememberDraggableScroller
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.ui.InterestsItem
@Composable @Composable
fun TopicsTabContent( fun TopicsTabContent(

@ -18,6 +18,4 @@
<string name="feature_interests_title">Interests</string> <string name="feature_interests_title">Interests</string>
<string name="feature_interests_loading">Loading data</string> <string name="feature_interests_loading">Loading data</string>
<string name="feature_interests_empty_header">"No available data"</string> <string name="feature_interests_empty_header">"No available data"</string>
<string name="feature_interests_card_follow_button_content_desc">Follow interest</string>
<string name="feature_interests_card_unfollow_button_content_desc">Unfollow interest</string>
</resources> </resources>

@ -27,9 +27,7 @@ android {
dependencies { dependencies {
implementation(projects.core.data) implementation(projects.core.data)
implementation(projects.core.domain) implementation(projects.core.domain)
implementation(projects.feature.bookmarks) implementation(projects.core.ui)
implementation(projects.feature.foryou)
implementation(projects.feature.interests)
testImplementation(projects.core.testing) testImplementation(projects.core.testing)

@ -35,10 +35,10 @@ import com.google.samples.apps.nowinandroid.core.model.data.UserData
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData
import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData
import com.google.samples.apps.nowinandroid.core.ui.R.string
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import com.google.samples.apps.nowinandroid.feature.interests.R as interestsR
/** /**
* UI test for checking the correct behaviour of the Search screen. * UI test for checking the correct behaviour of the Search screen.
@ -73,9 +73,9 @@ class SearchScreenTest {
clearSearchContentDesc = getString(R.string.feature_search_clear_search_text_content_desc) clearSearchContentDesc = getString(R.string.feature_search_clear_search_text_content_desc)
clearRecentSearchesContentDesc = getString(R.string.feature_search_clear_recent_searches_content_desc) clearRecentSearchesContentDesc = getString(R.string.feature_search_clear_recent_searches_content_desc)
followButtonContentDesc = followButtonContentDesc =
getString(interestsR.string.feature_interests_card_follow_button_content_desc) getString(string.core_ui_interests_card_follow_button_content_desc)
unfollowButtonContentDesc = unfollowButtonContentDesc =
getString(interestsR.string.feature_interests_card_unfollow_button_content_desc) getString(string.core_ui_interests_card_unfollow_button_content_desc)
topicsString = getString(R.string.feature_search_topics) topicsString = getString(R.string.feature_search_topics)
updatesString = getString(R.string.feature_search_updates) updatesString = getString(R.string.feature_search_updates)
tryAnotherSearchString = getString(R.string.feature_search_try_another_search) + tryAnotherSearchString = getString(R.string.feature_search_try_another_search) +

@ -88,14 +88,11 @@ import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.InterestsItem
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success
import com.google.samples.apps.nowinandroid.core.ui.R.string import com.google.samples.apps.nowinandroid.core.ui.R.string
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
import com.google.samples.apps.nowinandroid.core.ui.newsFeed import com.google.samples.apps.nowinandroid.core.ui.newsFeed
import com.google.samples.apps.nowinandroid.feature.bookmarks.BookmarksViewModel
import com.google.samples.apps.nowinandroid.feature.foryou.ForYouViewModel
import com.google.samples.apps.nowinandroid.feature.interests.InterestsItem
import com.google.samples.apps.nowinandroid.feature.interests.InterestsViewModel
import com.google.samples.apps.nowinandroid.feature.search.R as searchR import com.google.samples.apps.nowinandroid.feature.search.R as searchR
@Composable @Composable
@ -104,10 +101,7 @@ internal fun SearchRoute(
onInterestsClick: () -> Unit, onInterestsClick: () -> Unit,
onTopicClick: (String) -> Unit, onTopicClick: (String) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
bookmarksViewModel: BookmarksViewModel = hiltViewModel(),
interestsViewModel: InterestsViewModel = hiltViewModel(),
searchViewModel: SearchViewModel = hiltViewModel(), searchViewModel: SearchViewModel = hiltViewModel(),
forYouViewModel: ForYouViewModel = hiltViewModel(),
) { ) {
val recentSearchQueriesUiState by searchViewModel.recentSearchQueriesUiState.collectAsStateWithLifecycle() val recentSearchQueriesUiState by searchViewModel.recentSearchQueriesUiState.collectAsStateWithLifecycle()
val searchResultUiState by searchViewModel.searchResultUiState.collectAsStateWithLifecycle() val searchResultUiState by searchViewModel.searchResultUiState.collectAsStateWithLifecycle()
@ -120,9 +114,9 @@ internal fun SearchRoute(
onSearchQueryChanged = searchViewModel::onSearchQueryChanged, onSearchQueryChanged = searchViewModel::onSearchQueryChanged,
onSearchTriggered = searchViewModel::onSearchTriggered, onSearchTriggered = searchViewModel::onSearchTriggered,
onClearRecentSearches = searchViewModel::clearRecentSearches, onClearRecentSearches = searchViewModel::clearRecentSearches,
onNewsResourcesCheckedChanged = forYouViewModel::updateNewsResourceSaved, onNewsResourcesCheckedChanged = searchViewModel::setNewsResourceBookmarked,
onNewsResourceViewed = { bookmarksViewModel.setNewsResourceViewed(it, true) }, onNewsResourceViewed = { searchViewModel.setNewsResourceViewed(it, true) },
onFollowButtonClick = interestsViewModel::followTopic, onFollowButtonClick = searchViewModel::followTopic,
onBackClick = onBackClick, onBackClick = onBackClick,
onInterestsClick = onInterestsClick, onInterestsClick = onInterestsClick,
onTopicClick = onTopicClick, onTopicClick = onTopicClick,

@ -23,6 +23,7 @@ import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsCountUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsCountUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase
@ -44,6 +45,7 @@ class SearchViewModel @Inject constructor(
getSearchContentsCountUseCase: GetSearchContentsCountUseCase, getSearchContentsCountUseCase: GetSearchContentsCountUseCase,
recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase, recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase,
private val recentSearchRepository: RecentSearchRepository, private val recentSearchRepository: RecentSearchRepository,
private val userDataRepository: UserDataRepository,
private val savedStateHandle: SavedStateHandle, private val savedStateHandle: SavedStateHandle,
private val analyticsHelper: AnalyticsHelper, private val analyticsHelper: AnalyticsHelper,
) : ViewModel() { ) : ViewModel() {
@ -111,6 +113,24 @@ class SearchViewModel @Inject constructor(
recentSearchRepository.clearRecentSearches() recentSearchRepository.clearRecentSearches()
} }
} }
fun setNewsResourceBookmarked(newsResourceId: String, isChecked: Boolean) {
viewModelScope.launch {
userDataRepository.updateNewsResourceBookmark(newsResourceId, isChecked)
}
}
fun followTopic(followedTopicId: String, followed: Boolean) {
viewModelScope.launch {
userDataRepository.setTopicIdFollowed(followedTopicId, followed)
}
}
fun setNewsResourceViewed(newsResourceId: String, viewed: Boolean) {
viewModelScope.launch {
userDataRepository.setNewsResourceViewed(newsResourceId, viewed)
}
}
} }
private fun AnalyticsHelper.logEventSearchTriggered(query: String) = private fun AnalyticsHelper.logEventSearchTriggered(query: String) =

@ -33,6 +33,7 @@ import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.E
import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.Loading import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.Loading
import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.SearchNotReady import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.SearchNotReady
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
@ -60,6 +61,7 @@ class SearchViewModelTest {
private val recentSearchRepository = TestRecentSearchRepository() private val recentSearchRepository = TestRecentSearchRepository()
private val getRecentQueryUseCase = GetRecentSearchQueriesUseCase(recentSearchRepository) private val getRecentQueryUseCase = GetRecentSearchQueriesUseCase(recentSearchRepository)
private val getSearchContentsCountUseCase = GetSearchContentsCountUseCase(searchContentsRepository) private val getSearchContentsCountUseCase = GetSearchContentsCountUseCase(searchContentsRepository)
private lateinit var viewModel: SearchViewModel private lateinit var viewModel: SearchViewModel
@Before @Before
@ -70,6 +72,7 @@ class SearchViewModelTest {
recentSearchQueriesUseCase = getRecentQueryUseCase, recentSearchQueriesUseCase = getRecentQueryUseCase,
savedStateHandle = SavedStateHandle(), savedStateHandle = SavedStateHandle(),
recentSearchRepository = recentSearchRepository, recentSearchRepository = recentSearchRepository,
userDataRepository = userDataRepository,
analyticsHelper = NoOpAnalyticsHelper(), analyticsHelper = NoOpAnalyticsHelper(),
) )
userDataRepository.setUserData(emptyUserData) userDataRepository.setUserData(emptyUserData)
@ -128,4 +131,22 @@ class SearchViewModelTest {
collectJob.cancel() collectJob.cancel()
} }
@Test
fun whenToggleNewsResourceSavedIsCalled_bookmarkStateIsUpdated() = runTest {
val newsResourceId = "123"
viewModel.setNewsResourceBookmarked(newsResourceId, true)
assertEquals(
expected = setOf(newsResourceId),
actual = userDataRepository.userData.first().bookmarkedNewsResources,
)
viewModel.setNewsResourceBookmarked(newsResourceId, false)
assertEquals(
expected = emptySet(),
actual = userDataRepository.userData.first().bookmarkedNewsResources,
)
}
} }

Loading…
Cancel
Save