module Emanote.Model.Graph where

import Commonmark.Extensions.WikiLink qualified as WL
import Data.IxSet.Typed ((@+), (@=))
import Data.IxSet.Typed qualified as Ix
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Data.Tree (Forest, Tree (Node))
import Emanote.Model.Calendar qualified as Calendar
import Emanote.Model.Link.Rel qualified as Rel
import Emanote.Model.Link.Resolve qualified as Resolve
import Emanote.Model.Meta (lookupRouteMeta)
import Emanote.Model.Note qualified as MN
import Emanote.Model.Type (Model, modelRels, resolveLmlRoute)
import Emanote.Route qualified as R
import Emanote.Route.ModelRoute (ModelRoute)
import Optics.Operators as Lens ((^.))
import Relude hiding (empty)
import Text.Pandoc.Definition qualified as B

-- TODO: Do breadth-first instead of depth-first
modelFolgezettelAncestorTree :: ModelRoute -> Model -> Forest R.LMLRoute
modelFolgezettelAncestorTree :: ModelRoute -> Model -> Forest LMLRoute
modelFolgezettelAncestorTree ModelRoute
r0 Model
model =
  (Forest LMLRoute, Set ModelRoute) -> Forest LMLRoute
forall a b. (a, b) -> a
fst ((Forest LMLRoute, Set ModelRoute) -> Forest LMLRoute)
-> (Forest LMLRoute, Set ModelRoute) -> Forest LMLRoute
forall a b. (a -> b) -> a -> b
$ Set ModelRoute
-> State (Set ModelRoute) (Forest LMLRoute)
-> (Forest LMLRoute, Set ModelRoute)
forall s a. s -> State s a -> (a, s)
usingState Set ModelRoute
forall a. Monoid a => a
mempty (State (Set ModelRoute) (Forest LMLRoute)
 -> (Forest LMLRoute, Set ModelRoute))
-> State (Set ModelRoute) (Forest LMLRoute)
-> (Forest LMLRoute, Set ModelRoute)
forall a b. (a -> b) -> a -> b
$ ModelRoute -> State (Set ModelRoute) (Forest LMLRoute)
forall (m :: Type -> Type).
MonadState (Set ModelRoute) m =>
ModelRoute -> m (Forest LMLRoute)
go ModelRoute
r0
  where
    go :: MonadState (Set ModelRoute) m => ModelRoute -> m (Forest R.LMLRoute)
    go :: forall (m :: Type -> Type).
MonadState (Set ModelRoute) m =>
ModelRoute -> m (Forest LMLRoute)
go ModelRoute
r = do
      let folgezettelBacklinks :: [LMLRoute]
folgezettelBacklinks =
            ModelRoute -> Model -> [Rel]
backlinkRels ModelRoute
r Model
model
              [Rel] -> ([Rel] -> [Rel]) -> [Rel]
forall a b. a -> (a -> b) -> b
& (Rel -> Bool) -> [Rel] -> [Rel]
forall a. (a -> Bool) -> [a] -> [a]
filter (UnresolvedRelTarget -> Bool
isFolgezettel (UnresolvedRelTarget -> Bool)
-> (Rel -> UnresolvedRelTarget) -> Rel -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rel
-> Optic' A_Lens ('[] @Type) Rel UnresolvedRelTarget
-> UnresolvedRelTarget
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Rel UnresolvedRelTarget
Rel.relTo))
              [Rel] -> (Rel -> LMLRoute) -> [LMLRoute]
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> (Rel -> Optic' A_Lens ('[] @Type) Rel LMLRoute -> LMLRoute
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Rel LMLRoute
Rel.relFrom)
          -- Handle reverse folgezettel links here
          folgezettelFrontlinks :: [LMLRoute]
folgezettelFrontlinks =
            ModelRoute -> Model -> [Rel]
frontlinkRels ModelRoute
r Model
model
              [Rel] -> ([Rel] -> [LMLRoute]) -> [LMLRoute]
forall a b. a -> (a -> b) -> b
& (Rel -> Maybe LMLRoute) -> [Rel] -> [LMLRoute]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (WikiLink -> Maybe LMLRoute
lookupWikiLink (WikiLink -> Maybe LMLRoute)
-> (Rel -> Maybe WikiLink) -> Rel -> Maybe LMLRoute
forall (m :: Type -> Type) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< UnresolvedRelTarget -> Maybe WikiLink
selectReverseFolgezettel (UnresolvedRelTarget -> Maybe WikiLink)
-> (Rel -> UnresolvedRelTarget) -> Rel -> Maybe WikiLink
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rel
-> Optic' A_Lens ('[] @Type) Rel UnresolvedRelTarget
-> UnresolvedRelTarget
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Rel UnresolvedRelTarget
Rel.relTo))
          -- Folders are automatically made a folgezettel
          folgezettelFolder :: [LMLRoute]
folgezettelFolder =
            Maybe LMLRoute -> [LMLRoute]
forall a. Maybe a -> [a]
maybeToList (Maybe LMLRoute -> [LMLRoute]) -> Maybe LMLRoute -> [LMLRoute]
forall a b. (a -> b) -> a -> b
$ do
              LMLRoute
lmlR <- Either LMLRoute StaticFileRoute -> Maybe LMLRoute
forall l r. Either l r -> Maybe l
leftToMaybe (ModelRoute -> Either LMLRoute StaticFileRoute
R.modelRouteCase ModelRoute
r)
              Bool -> Maybe ()
forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Bool -> NonEmpty Text -> LMLRoute -> Model -> Bool
forall a (f :: Type -> Type).
FromJSON a =>
a -> NonEmpty Text -> LMLRoute -> ModelT f -> a
lookupRouteMeta Bool
True (Text
"emanote" Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text
"folder-folgezettel"]) LMLRoute
lmlR Model
model
              Model -> LMLRoute -> Maybe LMLRoute
parentLmlRoute Model
model LMLRoute
lmlR
          folgezettelParents :: [LMLRoute]
folgezettelParents =
            [[LMLRoute]] -> [LMLRoute]
forall a. Monoid a => [a] -> a
mconcat
              [ [LMLRoute]
folgezettelBacklinks,
                [LMLRoute]
folgezettelFrontlinks,
                [LMLRoute]
folgezettelFolder
              ]
      ([Maybe (Tree LMLRoute)] -> Forest LMLRoute)
-> m [Maybe (Tree LMLRoute)] -> m (Forest LMLRoute)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap [Maybe (Tree LMLRoute)] -> Forest LMLRoute
forall a. [Maybe a] -> [a]
catMaybes (m [Maybe (Tree LMLRoute)] -> m (Forest LMLRoute))
-> ((LMLRoute -> m (Maybe (Tree LMLRoute)))
    -> m [Maybe (Tree LMLRoute)])
-> (LMLRoute -> m (Maybe (Tree LMLRoute)))
-> m (Forest LMLRoute)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [LMLRoute]
-> (LMLRoute -> m (Maybe (Tree LMLRoute)))
-> m [Maybe (Tree LMLRoute)]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [LMLRoute]
folgezettelParents ((LMLRoute -> m (Maybe (Tree LMLRoute))) -> m (Forest LMLRoute))
-> (LMLRoute -> m (Maybe (Tree LMLRoute))) -> m (Forest LMLRoute)
forall a b. (a -> b) -> a -> b
$ \LMLRoute
parentR -> do
        let parentModelR :: ModelRoute
parentModelR = LMLRoute -> ModelRoute
R.ModelRoute_LML LMLRoute
parentR
        (Set ModelRoute -> Bool) -> m Bool
forall s (m :: Type -> Type) a. MonadState s m => (s -> a) -> m a
gets (ModelRoute
parentModelR ModelRoute -> Set ModelRoute -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member`) m Bool
-> (Bool -> m (Maybe (Tree LMLRoute))) -> m (Maybe (Tree LMLRoute))
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
          Bool
True -> Maybe (Tree LMLRoute) -> m (Maybe (Tree LMLRoute))
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Maybe (Tree LMLRoute)
forall a. Maybe a
Nothing
          Bool
False -> do
            (Set ModelRoute -> Set ModelRoute) -> m ()
forall s (m :: Type -> Type). MonadState s m => (s -> s) -> m ()
modify ((Set ModelRoute -> Set ModelRoute) -> m ())
-> (Set ModelRoute -> Set ModelRoute) -> m ()
forall a b. (a -> b) -> a -> b
$ ModelRoute -> Set ModelRoute -> Set ModelRoute
forall a. Ord a => a -> Set a -> Set a
Set.insert ModelRoute
parentModelR
            Forest LMLRoute
sub <- ModelRoute -> m (Forest LMLRoute)
forall (m :: Type -> Type).
MonadState (Set ModelRoute) m =>
ModelRoute -> m (Forest LMLRoute)
go ModelRoute
parentModelR
            Maybe (Tree LMLRoute) -> m (Maybe (Tree LMLRoute))
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Maybe (Tree LMLRoute) -> m (Maybe (Tree LMLRoute)))
-> Maybe (Tree LMLRoute) -> m (Maybe (Tree LMLRoute))
forall a b. (a -> b) -> a -> b
$ Tree LMLRoute -> Maybe (Tree LMLRoute)
forall a. a -> Maybe a
Just (Tree LMLRoute -> Maybe (Tree LMLRoute))
-> Tree LMLRoute -> Maybe (Tree LMLRoute)
forall a b. (a -> b) -> a -> b
$ LMLRoute -> Forest LMLRoute -> Tree LMLRoute
forall a. a -> [Tree a] -> Tree a
Node LMLRoute
parentR Forest LMLRoute
sub
    isFolgezettel :: UnresolvedRelTarget -> Bool
isFolgezettel = \case
      Rel.URTWikiLink (WikiLinkType
WL.WikiLinkBranch, WikiLink
_wl) ->
        Bool
True
      UnresolvedRelTarget
_ ->
        Bool
False
    selectReverseFolgezettel :: Rel.UnresolvedRelTarget -> Maybe WL.WikiLink
    selectReverseFolgezettel :: UnresolvedRelTarget -> Maybe WikiLink
selectReverseFolgezettel = \case
      Rel.URTWikiLink (WikiLinkType
WL.WikiLinkTag, WikiLink
wl) -> WikiLink -> Maybe WikiLink
forall a. a -> Maybe a
Just WikiLink
wl
      UnresolvedRelTarget
_ -> Maybe WikiLink
forall a. Maybe a
Nothing
    lookupWikiLink :: WL.WikiLink -> Maybe R.LMLRoute
    lookupWikiLink :: WikiLink -> Maybe LMLRoute
lookupWikiLink WikiLink
wl = do
      Note
note <- Either Note StaticFile -> Maybe Note
forall l r. Either l r -> Maybe l
leftToMaybe (Either Note StaticFile -> Maybe Note)
-> (ResolvedRelTarget (Either Note StaticFile)
    -> Maybe (Either Note StaticFile))
-> ResolvedRelTarget (Either Note StaticFile)
-> Maybe Note
forall (m :: Type -> Type) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ResolvedRelTarget (Either Note StaticFile)
-> Maybe (Either Note StaticFile)
forall a. ResolvedRelTarget a -> Maybe a
getFound (ResolvedRelTarget (Either Note StaticFile) -> Maybe Note)
-> ResolvedRelTarget (Either Note StaticFile) -> Maybe Note
forall a b. (a -> b) -> a -> b
$ Model -> WikiLink -> ResolvedRelTarget (Either Note StaticFile)
Resolve.resolveWikiLinkMustExist Model
model WikiLink
wl
      LMLRoute -> Maybe LMLRoute
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (LMLRoute -> Maybe LMLRoute) -> LMLRoute -> Maybe LMLRoute
forall a b. (a -> b) -> a -> b
$ Note
note Note -> Optic' A_Lens ('[] @Type) Note LMLRoute -> LMLRoute
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Note LMLRoute
MN.noteRoute
    getFound :: Rel.ResolvedRelTarget a -> Maybe a
    getFound :: forall a. ResolvedRelTarget a -> Maybe a
getFound = \case
      Rel.RRTFound a
x -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
      ResolvedRelTarget a
_ -> Maybe a
forall a. Maybe a
Nothing

-- | Return the route to parent folder (unless indexRoute is passed).
--
--  This will return the existing note (.org or .md) if possible. Otherwise
--  fallback to .md even if missing.
parentLmlRoute :: Model -> R.LMLRoute -> Maybe R.LMLRoute
parentLmlRoute :: Model -> LMLRoute -> Maybe LMLRoute
parentLmlRoute Model
model LMLRoute
r = do
  R @() 'Folder
pr <- do
    let lmlR :: Either (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
lmlR = LMLRoute
-> Either
     (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
R.lmlRouteCase LMLRoute
r
    -- Root index do not have a parent folder.
    Bool -> Maybe ()
forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Either (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
lmlR Either (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
-> Either
     (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
-> Bool
forall a. Eq a => a -> a -> Bool
/= R @SourceExt ('LMLType 'Md)
-> Either
     (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
forall a b. a -> Either a b
Left R @SourceExt ('LMLType 'Md)
forall {a} (ext :: FileType a). R @a ext
R.indexRoute Bool -> Bool -> Bool
&& Either (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
lmlR Either (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
-> Either
     (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
-> Bool
forall a. Eq a => a -> a -> Bool
/= R @SourceExt ('LMLType 'Org)
-> Either
     (R @SourceExt ('LMLType 'Md)) (R @SourceExt ('LMLType 'Org))
forall a b. b -> Either a b
Right R @SourceExt ('LMLType 'Org)
forall {a} (ext :: FileType a). R @a ext
R.indexRoute
    -- Consider the index route as parent folder for all
    -- top-level notes.
    R @() 'Folder -> Maybe (R @() 'Folder)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (R @() 'Folder -> Maybe (R @() 'Folder))
-> R @() 'Folder -> Maybe (R @() 'Folder)
forall a b. (a -> b) -> a -> b
$ R @() 'Folder -> Maybe (R @() 'Folder) -> R @() 'Folder
forall a. a -> Maybe a -> a
fromMaybe R @() 'Folder
forall {a} (ext :: FileType a). R @a ext
R.indexRoute (Maybe (R @() 'Folder) -> R @() 'Folder)
-> Maybe (R @() 'Folder) -> R @() 'Folder
forall a b. (a -> b) -> a -> b
$ (forall (lmlType :: LML).
 HasExt @SourceExt ('LMLType lmlType) =>
 R @SourceExt ('LMLType lmlType) -> Maybe (R @() 'Folder))
-> LMLRoute -> Maybe (R @() 'Folder)
forall r.
(forall (lmlType :: LML).
 HasExt @SourceExt ('LMLType lmlType) =>
 R @SourceExt ('LMLType lmlType) -> r)
-> LMLRoute -> r
R.withLmlRoute forall {a} (ext :: FileType a). R @a ext -> Maybe (R @() 'Folder)
forall (lmlType :: LML).
HasExt @SourceExt ('LMLType lmlType) =>
R @SourceExt ('LMLType lmlType) -> Maybe (R @() 'Folder)
R.routeParent LMLRoute
r
  LMLRoute -> Maybe LMLRoute
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (LMLRoute -> Maybe LMLRoute) -> LMLRoute -> Maybe LMLRoute
forall a b. (a -> b) -> a -> b
$ Model -> R @SourceExt ('LMLType (Any @LML)) -> LMLRoute
forall (lmlType :: LML) (f :: Type -> Type).
ModelT f -> R @SourceExt ('LMLType lmlType) -> LMLRoute
resolveLmlRoute Model
model (R @SourceExt ('LMLType (Any @LML)) -> LMLRoute)
-> (R @() 'Folder -> R @SourceExt ('LMLType (Any @LML)))
-> R @() 'Folder
-> LMLRoute
forall b c a. (b -> c) -> (a -> b) -> a -> c
. R @() 'Folder -> R @SourceExt ('LMLType (Any @LML))
coerce (R @() 'Folder -> LMLRoute) -> R @() 'Folder -> LMLRoute
forall a b. (a -> b) -> a -> b
$ R @() 'Folder
pr

modelLookupBacklinks :: ModelRoute -> Model -> [(R.LMLRoute, NonEmpty [B.Block])]
modelLookupBacklinks :: ModelRoute -> Model -> [(LMLRoute, NonEmpty [Block])]
modelLookupBacklinks ModelRoute
r Model
model =
  ((LMLRoute, NonEmpty [Block]) -> Down Title)
-> [(LMLRoute, NonEmpty [Block])] -> [(LMLRoute, NonEmpty [Block])]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Model -> LMLRoute -> Down Title
Calendar.backlinkSortKey Model
model (LMLRoute -> Down Title)
-> ((LMLRoute, NonEmpty [Block]) -> LMLRoute)
-> (LMLRoute, NonEmpty [Block])
-> Down Title
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LMLRoute, NonEmpty [Block]) -> LMLRoute
forall a b. (a, b) -> a
fst) ([(LMLRoute, NonEmpty [Block])] -> [(LMLRoute, NonEmpty [Block])])
-> [(LMLRoute, NonEmpty [Block])] -> [(LMLRoute, NonEmpty [Block])]
forall a b. (a -> b) -> a -> b
$
    [(LMLRoute, [Block])] -> [(LMLRoute, NonEmpty [Block])]
forall a b. Ord a => [(a, b)] -> [(a, NonEmpty b)]
groupNE ([(LMLRoute, [Block])] -> [(LMLRoute, NonEmpty [Block])])
-> [(LMLRoute, [Block])] -> [(LMLRoute, NonEmpty [Block])]
forall a b. (a -> b) -> a -> b
$
      ModelRoute -> Model -> [Rel]
backlinkRels ModelRoute
r Model
model [Rel] -> (Rel -> (LMLRoute, [Block])) -> [(LMLRoute, [Block])]
forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> \Rel
rel ->
        (Rel
rel Rel -> Optic' A_Lens ('[] @Type) Rel LMLRoute -> LMLRoute
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Rel LMLRoute
Rel.relFrom, Rel
rel Rel -> Optic' A_Lens ('[] @Type) Rel [Block] -> [Block]
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Rel [Block]
Rel.relCtx)
  where
    groupNE :: forall a b. Ord a => [(a, b)] -> [(a, NonEmpty b)]
    groupNE :: forall a b. Ord a => [(a, b)] -> [(a, NonEmpty b)]
groupNE =
      Map a (NonEmpty b) -> [(a, NonEmpty b)]
forall k a. Map k a -> [(k, a)]
Map.toList (Map a (NonEmpty b) -> [(a, NonEmpty b)])
-> ([(a, b)] -> Map a (NonEmpty b))
-> [(a, b)]
-> [(a, NonEmpty b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map a (NonEmpty b) -> (a, b) -> Map a (NonEmpty b))
-> Map a (NonEmpty b) -> [(a, b)] -> Map a (NonEmpty b)
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Map a (NonEmpty b) -> (a, b) -> Map a (NonEmpty b)
f Map a (NonEmpty b)
forall k a. Map k a
Map.empty
      where
        f :: Map a (NonEmpty b) -> (a, b) -> Map a (NonEmpty b)
        f :: Map a (NonEmpty b) -> (a, b) -> Map a (NonEmpty b)
f Map a (NonEmpty b)
m (a
x, b
y) =
          case a -> Map a (NonEmpty b) -> Maybe (NonEmpty b)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup a
x Map a (NonEmpty b)
m of
            Maybe (NonEmpty b)
Nothing -> a -> NonEmpty b -> Map a (NonEmpty b) -> Map a (NonEmpty b)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
x (OneItem (NonEmpty b) -> NonEmpty b
forall x. One x => OneItem x -> x
one b
OneItem (NonEmpty b)
y) Map a (NonEmpty b)
m
            Just NonEmpty b
ys -> a -> NonEmpty b -> Map a (NonEmpty b) -> Map a (NonEmpty b)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert a
x (NonEmpty b
ys NonEmpty b -> NonEmpty b -> NonEmpty b
forall a. Semigroup a => a -> a -> a
<> OneItem (NonEmpty b) -> NonEmpty b
forall x. One x => OneItem x -> x
one b
OneItem (NonEmpty b)
y) Map a (NonEmpty b)
m

backlinkRels :: ModelRoute -> Model -> [Rel.Rel]
backlinkRels :: ModelRoute -> Model -> [Rel]
backlinkRels ModelRoute
r Model
model =
  let allPossibleLinks :: [UnresolvedRelTarget]
allPossibleLinks = ModelRoute -> [UnresolvedRelTarget]
Rel.unresolvedRelsTo ModelRoute
r
   in IxSet RelIxs Rel -> [Rel]
forall (ixs :: [Type]) a. IxSet ixs a -> [a]
Ix.toList (IxSet RelIxs Rel -> [Rel]) -> IxSet RelIxs Rel -> [Rel]
forall a b. (a -> b) -> a -> b
$ (Model
model Model
-> Optic' A_Lens ('[] @Type) Model (IxSet RelIxs Rel)
-> IxSet RelIxs Rel
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Model (IxSet RelIxs Rel)
forall (encF :: Type -> Type).
Lens' (ModelT encF) (IxSet RelIxs Rel)
modelRels) IxSet RelIxs Rel -> [UnresolvedRelTarget] -> IxSet RelIxs Rel
forall (ixs :: [Type]) a ix.
(Indexable ixs a, IsIndexOf ix ixs) =>
IxSet ixs a -> [ix] -> IxSet ixs a
@+ [UnresolvedRelTarget]
allPossibleLinks

frontlinkRels :: ModelRoute -> Model -> [Rel.Rel]
frontlinkRels :: ModelRoute -> Model -> [Rel]
frontlinkRels ModelRoute
r Model
model =
  Maybe [Rel] -> [Rel]
forall m. Monoid m => Maybe m -> m
maybeToMonoid (Maybe [Rel] -> [Rel]) -> Maybe [Rel] -> [Rel]
forall a b. (a -> b) -> a -> b
$ do
    LMLRoute
lmlR <- Either LMLRoute StaticFileRoute -> Maybe LMLRoute
forall l r. Either l r -> Maybe l
leftToMaybe (Either LMLRoute StaticFileRoute -> Maybe LMLRoute)
-> Either LMLRoute StaticFileRoute -> Maybe LMLRoute
forall a b. (a -> b) -> a -> b
$ ModelRoute -> Either LMLRoute StaticFileRoute
R.modelRouteCase ModelRoute
r
    [Rel] -> Maybe [Rel]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ([Rel] -> Maybe [Rel]) -> [Rel] -> Maybe [Rel]
forall a b. (a -> b) -> a -> b
$ IxSet RelIxs Rel -> [Rel]
forall (ixs :: [Type]) a. IxSet ixs a -> [a]
Ix.toList (IxSet RelIxs Rel -> [Rel]) -> IxSet RelIxs Rel -> [Rel]
forall a b. (a -> b) -> a -> b
$ (Model
model Model
-> Optic' A_Lens ('[] @Type) Model (IxSet RelIxs Rel)
-> IxSet RelIxs Rel
forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens ('[] @Type) Model (IxSet RelIxs Rel)
forall (encF :: Type -> Type).
Lens' (ModelT encF) (IxSet RelIxs Rel)
modelRels) IxSet RelIxs Rel -> LMLRoute -> IxSet RelIxs Rel
forall (ixs :: [Type]) a ix.
(Indexable ixs a, IsIndexOf ix ixs) =>
IxSet ixs a -> ix -> IxSet ixs a
@= LMLRoute
lmlR