    {-# LANGUAGE CPP   #-}
    {-# LANGUAGE RankNTypes   #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE DeriveGeneric #-}

    -- | lenses to access sheets, cells and values of 'Xlsx'
    module Codec.Xlsx.Lens
      ( ixSheet
      , atSheet
      , ixCell
      , ixCellRC
      , ixCellXY
      , atCell
      , atCellRC
      , atCellXY
      , cellValueAt
      , cellValueAtRC
      , cellValueAtXY
      ) where

    import Codec.Xlsx.Types
    #ifdef USE_MICROLENS
    import Lens.Micro
    import Lens.Micro.Internal
    import Lens.Micro.GHC ()
    #else
    import Control.Lens
    #endif
    import Data.Function (on)
    import Data.List (deleteBy)
    import Data.Text
    import Data.Tuple (swap)
    import GHC.Generics (Generic)

    newtype SheetList = SheetList{ SheetList -> [(Text, Worksheet)]
    unSheetList :: [(Text, Worksheet)] }
        deriving (SheetList -> SheetList -> Bool
    (SheetList -> SheetList -> Bool)
    -> (SheetList -> SheetList -> Bool) -> Eq SheetList
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SheetList -> SheetList -> Bool
    == :: SheetList -> SheetList -> Bool
    $c/= :: SheetList -> SheetList -> Bool
    /= :: SheetList -> SheetList -> Bool
    Eq, Int -> SheetList -> ShowS
    [SheetList] -> ShowS
    SheetList -> String
    (Int -> SheetList -> ShowS)
    -> (SheetList -> String)
    -> ([SheetList] -> ShowS)
    -> Show SheetList
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SheetList -> ShowS
    showsPrec :: Int -> SheetList -> ShowS
    $cshow :: SheetList -> String
    show :: SheetList -> String
    $cshowList :: [SheetList] -> ShowS
    showList :: [SheetList] -> ShowS
    Show, (forall x. SheetList -> Rep SheetList x)
    -> (forall x. Rep SheetList x -> SheetList) -> Generic SheetList
    forall x. Rep SheetList x -> SheetList
    forall x. SheetList -> Rep SheetList x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. SheetList -> Rep SheetList x
    from :: forall x. SheetList -> Rep SheetList x
    $cto :: forall x. Rep SheetList x -> SheetList
    to :: forall x. Rep SheetList x -> SheetList
    Generic)

    type instance IxValue (SheetList) = Worksheet
    type instance Index (SheetList) = Text

    instance Ixed SheetList where
        ix :: Index SheetList -> Traversal' SheetList (IxValue SheetList)
    ix Index SheetList
    k IxValue SheetList -> f (IxValue SheetList)
    f sl :: SheetList
    sl@(SheetList [(Text, Worksheet)]
    l) = case Text -> [(Text, Worksheet)] -> Maybe Worksheet
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    Index SheetList
    k [(Text, Worksheet)]
    l of
            Just Worksheet
    v  -> IxValue SheetList -> f (IxValue SheetList)
    f IxValue SheetList
    Worksheet
    v f Worksheet -> (Worksheet -> SheetList) -> f SheetList
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \Worksheet
    v' -> [(Text, Worksheet)] -> SheetList
    SheetList (Text -> Worksheet -> [(Text, Worksheet)] -> [(Text, Worksheet)]
    forall k v. Eq k => k -> v -> [(k, v)] -> [(k, v)]
    upsert Text
    Index SheetList
    k Worksheet
    v' [(Text, Worksheet)]
    l)
            Maybe Worksheet
    Nothing -> SheetList -> f SheetList
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure SheetList
    sl
        {-# INLINE ix #-}

    instance At SheetList where
      at :: Index SheetList -> Lens' SheetList (Maybe (IxValue SheetList))
    at Index SheetList
    k Maybe (IxValue SheetList) -> f (Maybe (IxValue SheetList))
    f (SheetList [(Text, Worksheet)]
    l) = Maybe (IxValue SheetList) -> f (Maybe (IxValue SheetList))
    f Maybe (IxValue SheetList)
    Maybe Worksheet
    mv f (Maybe Worksheet)
    -> (Maybe Worksheet -> SheetList) -> f SheetList
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \Maybe Worksheet
    r -> case Maybe Worksheet
    r of
          Maybe Worksheet
    Nothing -> [(Text, Worksheet)] -> SheetList
    SheetList ([(Text, Worksheet)] -> SheetList)
    -> [(Text, Worksheet)] -> SheetList
    forall a b. (a -> b) -> a -> b
    $ [(Text, Worksheet)]
    -> (Worksheet -> [(Text, Worksheet)])
    -> Maybe Worksheet
    -> [(Text, Worksheet)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [(Text, Worksheet)]
    l (\Worksheet
    v -> ((Text, Worksheet) -> (Text, Worksheet) -> Bool)
    -> (Text, Worksheet) -> [(Text, Worksheet)] -> [(Text, Worksheet)]
    forall a. (a -> a -> Bool) -> a -> [a] -> [a]
    deleteBy (Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) (Text -> Text -> Bool)
    -> ((Text, Worksheet) -> Text)
    -> (Text, Worksheet)
    -> (Text, Worksheet)
    -> Bool
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` (Text, Worksheet) -> Text
    forall a b. (a, b) -> a
    fst) (Text
    Index SheetList
    k,Worksheet
    v) [(Text, Worksheet)]
    l) Maybe Worksheet
    mv
          Just Worksheet
    v' -> [(Text, Worksheet)] -> SheetList
    SheetList ([(Text, Worksheet)] -> SheetList)
    -> [(Text, Worksheet)] -> SheetList
    forall a b. (a -> b) -> a -> b
    $ Text -> Worksheet -> [(Text, Worksheet)] -> [(Text, Worksheet)]
    forall k v. Eq k => k -> v -> [(k, v)] -> [(k, v)]
    upsert Text
    Index SheetList
    k Worksheet
    v' [(Text, Worksheet)]
    l
        where
          mv :: Maybe Worksheet
    mv = Text -> [(Text, Worksheet)] -> Maybe Worksheet
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    Index SheetList
    k [(Text, Worksheet)]
    l
      {-# INLINE at #-}

    upsert :: (Eq k) => k -> v -> [(k,v)] -> [(k,v)]
    upsert :: forall k v. Eq k => k -> v -> [(k, v)] -> [(k, v)]
    upsert k
    k v
    v [] = [(k
    k,v
    v)]
    upsert k
    k v
    v ((k
    k1,v
    v1):[(k, v)]
    r) =
        if k
    k k -> k -> Bool
    forall a. Eq a => a -> a -> Bool
    == k
    k1
        then (k
    k,v
    v)(k, v) -> [(k, v)] -> [(k, v)]
    forall a. a -> [a] -> [a]
    :[(k, v)]
    r
        else (k
    k1,v
    v1)(k, v) -> [(k, v)] -> [(k, v)]
    forall a. a -> [a] -> [a]
    :k -> v -> [(k, v)] -> [(k, v)]
    forall k v. Eq k => k -> v -> [(k, v)] -> [(k, v)]
    upsert k
    k v
    v [(k, v)]
    r

    -- | lens giving access to a worksheet from 'Xlsx' object
    -- by its name
    ixSheet :: Text -> Traversal' Xlsx Worksheet
    ixSheet :: Text -> Traversal' Xlsx Worksheet
    ixSheet Text
    s = ([(Text, Worksheet)] -> f [(Text, Worksheet)]) -> Xlsx -> f Xlsx
    Lens' Xlsx [(Text, Worksheet)]
    xlSheets (([(Text, Worksheet)] -> f [(Text, Worksheet)]) -> Xlsx -> f Xlsx)
    -> ((Worksheet -> f Worksheet)
        -> [(Text, Worksheet)] -> f [(Text, Worksheet)])
    -> (Worksheet -> f Worksheet)
    -> Xlsx
    -> f Xlsx
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . \Worksheet -> f Worksheet
    f -> (SheetList -> [(Text, Worksheet)])
    -> f SheetList -> f [(Text, Worksheet)]
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap SheetList -> [(Text, Worksheet)]
    unSheetList (f SheetList -> f [(Text, Worksheet)])
    -> ([(Text, Worksheet)] -> f SheetList)
    -> [(Text, Worksheet)]
    -> f [(Text, Worksheet)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Index SheetList -> Traversal' SheetList (IxValue SheetList)
    forall m. Ixed m => Index m -> Traversal' m (IxValue m)
    ix Text
    Index SheetList
    s IxValue SheetList -> f (IxValue SheetList)
    Worksheet -> f Worksheet
    f (SheetList -> f SheetList)
    -> ([(Text, Worksheet)] -> SheetList)
    -> [(Text, Worksheet)]
    -> f SheetList
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Text, Worksheet)] -> SheetList
    SheetList

    -- | 'Control.Lens.At' variant of 'ixSheet' lens
    --
    -- /Note:/ if there is no such sheet in this workbook then new sheet will be
    -- added as the last one to the sheet list
    atSheet :: Text -> Lens' Xlsx (Maybe Worksheet)
    atSheet :: Text -> Lens' Xlsx (Maybe Worksheet)
    atSheet Text
    s = ([(Text, Worksheet)] -> f [(Text, Worksheet)]) -> Xlsx -> f Xlsx
    Lens' Xlsx [(Text, Worksheet)]
    xlSheets (([(Text, Worksheet)] -> f [(Text, Worksheet)]) -> Xlsx -> f Xlsx)
    -> ((Maybe Worksheet -> f (Maybe Worksheet))
        -> [(Text, Worksheet)] -> f [(Text, Worksheet)])
    -> (Maybe Worksheet -> f (Maybe Worksheet))
    -> Xlsx
    -> f Xlsx
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . \Maybe Worksheet -> f (Maybe Worksheet)
    f -> (SheetList -> [(Text, Worksheet)])
    -> f SheetList -> f [(Text, Worksheet)]
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap SheetList -> [(Text, Worksheet)]
    unSheetList (f SheetList -> f [(Text, Worksheet)])
    -> ([(Text, Worksheet)] -> f SheetList)
    -> [(Text, Worksheet)]
    -> f [(Text, Worksheet)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Index SheetList -> Lens' SheetList (Maybe (IxValue SheetList))
    forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
    at Text
    Index SheetList
    s Maybe (IxValue SheetList) -> f (Maybe (IxValue SheetList))
    Maybe Worksheet -> f (Maybe Worksheet)
    f (SheetList -> f SheetList)
    -> ([(Text, Worksheet)] -> SheetList)
    -> [(Text, Worksheet)]
    -> f SheetList
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Text, Worksheet)] -> SheetList
    SheetList

    -- | lens giving access to a cell in some worksheet
    -- by its position, by default row+column index is used
    -- so this lens is a synonym of 'ixCellRC'
    ixCell :: (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    ixCell :: (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    ixCell = (RowIndex, ColumnIndex)
    -> (Cell -> f Cell) -> Worksheet -> f Worksheet
    (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    ixCellRC

    -- | lens to access cell in a worksheet
    ixCellRC :: (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    ixCellRC :: (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    ixCellRC (RowIndex, ColumnIndex)
    i = (CellMap -> f CellMap) -> Worksheet -> f Worksheet
    Lens' Worksheet CellMap
    wsCells ((CellMap -> f CellMap) -> Worksheet -> f Worksheet)
    -> ((Cell -> f Cell) -> CellMap -> f CellMap)
    -> (Cell -> f Cell)
    -> Worksheet
    -> f Worksheet
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Index CellMap -> Traversal' CellMap (IxValue CellMap)
    forall m. Ixed m => Index m -> Traversal' m (IxValue m)
    ix (RowIndex, ColumnIndex)
    Index CellMap
    i

    -- | lens to access cell in a worksheet using more traditional
    -- x+y coordinates
    ixCellXY :: (ColumnIndex, RowIndex) -> Traversal' Worksheet Cell
    ixCellXY :: (ColumnIndex, RowIndex) -> Traversal' Worksheet Cell
    ixCellXY (ColumnIndex, RowIndex)
    i = (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    ixCellRC ((RowIndex, ColumnIndex) -> Traversal' Worksheet Cell)
    -> (RowIndex, ColumnIndex) -> Traversal' Worksheet Cell
    forall a b. (a -> b) -> a -> b
    $ (ColumnIndex, RowIndex) -> (RowIndex, ColumnIndex)
    forall a b. (a, b) -> (b, a)
    swap (ColumnIndex, RowIndex)
    i

    -- | accessor that can read, write or delete cell in a worksheet
    -- synonym of 'atCellRC' so uses row+column index
    atCell :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCell :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCell = (RowIndex, ColumnIndex)
    -> (Maybe Cell -> f (Maybe Cell)) -> Worksheet -> f Worksheet
    (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCellRC

    -- | lens to read, write or delete cell in a worksheet
    atCellRC :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCellRC :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCellRC (RowIndex, ColumnIndex)
    i = (CellMap -> f CellMap) -> Worksheet -> f Worksheet
    Lens' Worksheet CellMap
    wsCells ((CellMap -> f CellMap) -> Worksheet -> f Worksheet)
    -> ((Maybe Cell -> f (Maybe Cell)) -> CellMap -> f CellMap)
    -> (Maybe Cell -> f (Maybe Cell))
    -> Worksheet
    -> f Worksheet
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Index CellMap -> Lens' CellMap (Maybe (IxValue CellMap))
    forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
    at (RowIndex, ColumnIndex)
    Index CellMap
    i

    -- | lens to read, write or delete cell in a worksheet
    -- using more traditional x+y or row+column index
    atCellXY :: (ColumnIndex, RowIndex) -> Lens' Worksheet (Maybe Cell)
    atCellXY :: (ColumnIndex, RowIndex) -> Lens' Worksheet (Maybe Cell)
    atCellXY (ColumnIndex, RowIndex)
    i = (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCellRC ((RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell))
    -> (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    forall a b. (a -> b) -> a -> b
    $ (ColumnIndex, RowIndex) -> (RowIndex, ColumnIndex)
    forall a b. (a, b) -> (b, a)
    swap (ColumnIndex, RowIndex)
    i

    -- | lens to read, write or delete cell value in a worksheet
    -- with row+column coordinates, synonym for 'cellValueRC'
    cellValueAt :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAt :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAt = (RowIndex, ColumnIndex)
    -> (Maybe CellValue -> f (Maybe CellValue))
    -> Worksheet
    -> f Worksheet
    (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAtRC

    -- | lens to read, write or delete cell value in a worksheet
    -- using row+column coordinates of that cell
    cellValueAtRC :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAtRC :: (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAtRC (RowIndex, ColumnIndex)
    i = (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe Cell)
    atCell (RowIndex, ColumnIndex)
    i ((Maybe Cell -> f (Maybe Cell)) -> Worksheet -> f Worksheet)
    -> ((Maybe CellValue -> f (Maybe CellValue))
        -> Maybe Cell -> f (Maybe Cell))
    -> (Maybe CellValue -> f (Maybe CellValue))
    -> Worksheet
    -> f Worksheet
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Cell -> Iso' (Maybe Cell) Cell
    forall a. Eq a => a -> Iso' (Maybe a) a
    non Cell
    forall a. Default a => a
    def ((Cell -> f Cell) -> Maybe Cell -> f (Maybe Cell))
    -> ((Maybe CellValue -> f (Maybe CellValue)) -> Cell -> f Cell)
    -> (Maybe CellValue -> f (Maybe CellValue))
    -> Maybe Cell
    -> f (Maybe Cell)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Maybe CellValue -> f (Maybe CellValue)) -> Cell -> f Cell
    Lens' Cell (Maybe CellValue)
    cellValue

    -- | lens to read, write or delete cell value in a worksheet
    -- using traditional x+y coordinates
    cellValueAtXY :: (ColumnIndex, RowIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAtXY :: (ColumnIndex, RowIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAtXY (ColumnIndex, RowIndex)
    i = (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    cellValueAtRC ((RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue))
    -> (RowIndex, ColumnIndex) -> Lens' Worksheet (Maybe CellValue)
    forall a b. (a -> b) -> a -> b
    $ (ColumnIndex, RowIndex) -> (RowIndex, ColumnIndex)
    forall a b. (a, b) -> (b, a)
    swap (ColumnIndex, RowIndex)
    i