module Mischief.Materials.Sprite where

import Mischief.Materials
import Mischief.Materials.Time (TimeMaterial, getTime)
import Mischief.Render.Camera (CameraMatrices (CameraMatrices), Matrices (..))
import Mischief.Render.Core (DefaultSampler (..))
import Mischief.Render.Image
import Mischief.Render.Sprite.Common
import Prelude ()

data SpriteData f = SpriteData
  { forall f.
SpriteData f -> Field f (Vec 3 (Expr ('Primitive 'TFloat)))
coords :: Field f (Vec 3 Float),
    forall f.
SpriteData f -> Field f (Vec 2 (Expr ('Primitive 'TFloat)))
size :: Field f (Vec 2 Float),
    forall f.
SpriteData f -> Field f (Vec 4 (Expr ('Primitive 'TFloat)))
slice :: Field f (Vec 4 Float),
    forall f. SpriteData f -> Field f (Vec 2 Int)
flip :: Field f (Vec 2 Int),
    forall f. SpriteData f -> Field f (Mat 3 3)
rotation :: Field f (Mat 3 3)
  }
  deriving stock ((forall x. SpriteData f -> Rep (SpriteData f) x)
-> (forall x. Rep (SpriteData f) x -> SpriteData f)
-> Generic (SpriteData f)
forall x. Rep (SpriteData f) x -> SpriteData f
forall x. SpriteData f -> Rep (SpriteData f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (SpriteData f) x -> SpriteData f
forall f x. SpriteData f -> Rep (SpriteData f) x
$cfrom :: forall f x. SpriteData f -> Rep (SpriteData f) x
from :: forall x. SpriteData f -> Rep (SpriteData f) x
$cto :: forall f x. Rep (SpriteData f) x -> SpriteData f
to :: forall x. Rep (SpriteData f) x -> SpriteData f
Generic)
  deriving anyclass (Int
[(Text, Text)]
Integer -> SpriteData GPU
SpriteData CPU -> Ptr Word8 -> IO Int
(Integer -> SpriteData GPU)
-> [(Text, Text)]
-> Int
-> (SpriteData CPU -> Ptr Word8 -> IO Int)
-> Bufferable SpriteData
forall (a :: * -> *).
(Integer -> a GPU)
-> [(Text, Text)]
-> Int
-> (a CPU -> Ptr Word8 -> IO Int)
-> Bufferable a
$cdummyBuffer :: Integer -> SpriteData GPU
dummyBuffer :: Integer -> SpriteData GPU
$cgetFields :: [(Text, Text)]
getFields :: [(Text, Text)]
$cgetSize :: Int
getSize :: Int
$cputBytes :: SpriteData CPU -> Ptr Word8 -> IO Int
putBytes :: SpriteData CPU -> Ptr Word8 -> IO Int
Bufferable)

newtype VertexInput f = VertexInput (BuiltIn f "vertex_index" Uint)
  deriving stock ((forall x. VertexInput f -> Rep (VertexInput f) x)
-> (forall x. Rep (VertexInput f) x -> VertexInput f)
-> Generic (VertexInput f)
forall x. Rep (VertexInput f) x -> VertexInput f
forall x. VertexInput f -> Rep (VertexInput f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (VertexInput f) x -> VertexInput f
forall f x. VertexInput f -> Rep (VertexInput f) x
$cfrom :: forall f x. VertexInput f -> Rep (VertexInput f) x
from :: forall x. VertexInput f -> Rep (VertexInput f) x
$cto :: forall f x. Rep (VertexInput f) x -> VertexInput f
to :: forall x. Rep (VertexInput f) x -> VertexInput f
Generic)
  deriving anyclass (Typeable (VertexInput GPU)
Params
ParamDefinition
VertexInput GPU
Typeable (VertexInput GPU) =>
Params
-> ParamDefinition
-> VertexInput GPU
-> (VertexInput GPU -> Values)
-> ShaderParam VertexInput
VertexInput GPU -> Values
forall (a :: * -> *).
Typeable (a GPU) =>
Params
-> ParamDefinition -> a GPU -> (a GPU -> Values) -> ShaderParam a
$ccollectParams :: Params
collectParams :: Params
$cparamDefinition :: ParamDefinition
paramDefinition :: ParamDefinition
$cdummyParam :: VertexInput GPU
dummyParam :: VertexInput GPU
$ccollectValues :: VertexInput GPU -> Values
collectValues :: VertexInput GPU -> Values
ShaderParam)

data VertexOutput f = VertexOutput
  { forall f.
VertexOutput f
-> BuiltIn f "position" (Vec 4 (Expr ('Primitive 'TFloat)))
pos :: BuiltIn f "position" (Vec 4 Float),
    forall f.
VertexOutput f -> Location f 0 (Vec 2 (Expr ('Primitive 'TFloat)))
uv :: Location f 0 (Vec 2 Float)
  }
  deriving ((forall x. VertexOutput f -> Rep (VertexOutput f) x)
-> (forall x. Rep (VertexOutput f) x -> VertexOutput f)
-> Generic (VertexOutput f)
forall x. Rep (VertexOutput f) x -> VertexOutput f
forall x. VertexOutput f -> Rep (VertexOutput f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (VertexOutput f) x -> VertexOutput f
forall f x. VertexOutput f -> Rep (VertexOutput f) x
$cfrom :: forall f x. VertexOutput f -> Rep (VertexOutput f) x
from :: forall x. VertexOutput f -> Rep (VertexOutput f) x
$cto :: forall f x. Rep (VertexOutput f) x -> VertexOutput f
to :: forall x. Rep (VertexOutput f) x -> VertexOutput f
Generic, Typeable (VertexOutput GPU)
Params
ParamDefinition
VertexOutput GPU
Typeable (VertexOutput GPU) =>
Params
-> ParamDefinition
-> VertexOutput GPU
-> (VertexOutput GPU -> Values)
-> ShaderParam VertexOutput
VertexOutput GPU -> Values
forall (a :: * -> *).
Typeable (a GPU) =>
Params
-> ParamDefinition -> a GPU -> (a GPU -> Values) -> ShaderParam a
$ccollectParams :: Params
collectParams :: Params
$cparamDefinition :: ParamDefinition
paramDefinition :: ParamDefinition
$cdummyParam :: VertexOutput GPU
dummyParam :: VertexOutput GPU
$ccollectValues :: VertexOutput GPU -> Values
collectValues :: VertexOutput GPU -> Values
ShaderParam)

data Bindings f = Bindings
  { forall f. Bindings f -> Uniform f (Matrices f)
matrices :: Uniform f (Matrices f),
    forall f. Bindings f -> Uniform f (SpriteData f)
sprite :: Uniform f (SpriteData f),
    forall f. Bindings f -> Binding f Texture
texture :: Binding f Texture,
    forall f. Bindings f -> Binding f Sampler
sampler :: Binding f Sampler
  }
  deriving ((forall x. Bindings f -> Rep (Bindings f) x)
-> (forall x. Rep (Bindings f) x -> Bindings f)
-> Generic (Bindings f)
forall x. Rep (Bindings f) x -> Bindings f
forall x. Bindings f -> Rep (Bindings f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (Bindings f) x -> Bindings f
forall f x. Bindings f -> Rep (Bindings f) x
$cfrom :: forall f x. Bindings f -> Rep (Bindings f) x
from :: forall x. Bindings f -> Rep (Bindings f) x
$cto :: forall f x. Rep (Bindings f) x -> Bindings f
to :: forall x. Rep (Bindings f) x -> Bindings f
Generic, Typeable Bindings
Typeable Bindings =>
(Natural -> Proxy (Bindings Internal) -> (Bindings, Natural))
-> (Natural
    -> Proxy (Bindings Internal)
    -> ([WGPUBindGroupLayoutEntry], Natural))
-> (Natural -> Bindings CPU -> ([WGPUBindGroupEntry], Natural))
-> (Natural -> (Bindings GPU, Natural))
-> Bindable Bindings
Natural -> (Bindings GPU, Natural)
Natural
-> Proxy (Bindings Internal)
-> ([WGPUBindGroupLayoutEntry], Natural)
Natural -> Proxy (Bindings Internal) -> (Bindings, Natural)
Natural -> Bindings CPU -> ([WGPUBindGroupEntry], Natural)
forall (a :: * -> *).
Typeable a =>
(Natural -> Proxy (a Internal) -> (Bindings, Natural))
-> (Natural
    -> Proxy (a Internal) -> ([WGPUBindGroupLayoutEntry], Natural))
-> (Natural -> a CPU -> ([WGPUBindGroupEntry], Natural))
-> (Natural -> (a GPU, Natural))
-> Bindable a
$ccollectBindings :: Natural -> Proxy (Bindings Internal) -> (Bindings, Natural)
collectBindings :: Natural -> Proxy (Bindings Internal) -> (Bindings, Natural)
$ccollectLayouts :: Natural
-> Proxy (Bindings Internal)
-> ([WGPUBindGroupLayoutEntry], Natural)
collectLayouts :: Natural
-> Proxy (Bindings Internal)
-> ([WGPUBindGroupLayoutEntry], Natural)
$ccollectEntries :: Natural -> Bindings CPU -> ([WGPUBindGroupEntry], Natural)
collectEntries :: Natural -> Bindings CPU -> ([WGPUBindGroupEntry], Natural)
$cdummyBinding :: Natural -> (Bindings GPU, Natural)
dummyBinding :: Natural -> (Bindings GPU, Natural)
Bindable)

data SpriteMaterial

instance Material SpriteMaterial where
  type VI SpriteMaterial = VertexInput
  type VO SpriteMaterial = VertexOutput
  type B SpriteMaterial = Bindings

  vertex :: VertexInput GPU -> Shader SpriteMaterial (VertexOutput GPU)
  vertex :: VertexInput GPU -> Shader SpriteMaterial (VertexOutput GPU)
vertex (VertexInput BuiltIn GPU "vertex_index" (Expr ('Primitive 'TUInt))
index) = do
    b <- Shader SpriteMaterial (B SpriteMaterial GPU)
Shader SpriteMaterial (Bindings GPU)
forall a. Material a => Shader a (B a GPU)
bindings

    positions <- var $ array @(Vec2 Float) [vec2 (-1) (-1), vec2 1 (-1), vec2 1 1, vec2 (-1) (-1), vec2 1 1, vec2 (-1) 1]
    uvs <- var $ array @(Vec2 Float) [vec2 0 1, vec2 1 1, vec2 1 0, vec2 0 1, vec2 1 0, vec2 0 0]

    pos <- var $ (positions !! index) * b.sprite.size * diag 0.5
    pos <- var $ b.sprite.rotation !*^ (pos +: 0)
    pos <- var $ pos + b.sprite.coords
    pos <- var $ b.matrices.projection !*^ (b.matrices.view !*^ (pos +: 1))

    pure
      VertexOutput
        { pos = vec3 pos.x pos.y pos.z +: 1,
          uv = uvs !! index
        }

  fragment :: VertexOutput GPU -> Shader SpriteMaterial (Vec 4 Float)
  fragment :: VertexOutput GPU
-> Shader SpriteMaterial (Vec 4 (Expr ('Primitive 'TFloat)))
fragment VertexOutput {Location GPU 0 (Vec 2 (Expr ('Primitive 'TFloat)))
uv :: forall f.
VertexOutput f -> Location f 0 (Vec 2 (Expr ('Primitive 'TFloat)))
uv :: Location GPU 0 (Vec 2 (Expr ('Primitive 'TFloat)))
uv} = Vec 2 (Expr ('Primitive 'TFloat))
-> Shader SpriteMaterial (Vec 4 (Expr ('Primitive 'TFloat)))
sampleSprite Vec 2 (Expr ('Primitive 'TFloat))
Location GPU 0 (Vec 2 (Expr ('Primitive 'TFloat)))
uv

  fetch :: FetchBindings (B SpriteMaterial)
fetch =
    (CameraEntity -> Query System (Buffer Matrices, Sampler))
-> (CameraEntity -> Query System (Buffer SpriteData, TextureView))
-> ((Buffer Matrices, Sampler)
    -> (Buffer SpriteData, TextureView) -> Bindings CPU)
-> FetchBindings Bindings
forall x y (b :: * -> *).
Bindable b =>
(CameraEntity -> Query System x)
-> (CameraEntity -> Query System y)
-> (x -> y -> b CPU)
-> FetchBindings b
FetchBindings
      ( \CameraEntity
camera -> do
          (DefaultSampler sampler) <- forall c (m :: * -> *) w.
(MonadSystem w m, Component c) =>
Query m c
qres @DefaultSampler
          CameraMatrices matrices <- qget camera [qd|CameraMatrices|]
          pure (matrices, sampler)
      )
      ( \CameraEntity
sprite -> do
          (Sprite {image}, buffer) <- CameraEntity
-> (C Sprite, C (Buffer SpriteData))
-> Query System (Sprite, Buffer SpriteData)
forall w (m :: * -> *) qd out.
(MonadSystem w m, Queryable qd out) =>
CameraEntity -> qd -> Query m out
qget CameraEntity
sprite [qd|Sprite, (Buffer SpriteData)|]
          ImageTextureView texture <- qget image [qd|ImageTextureView|]
          pure (buffer, texture)
      )
      (\(Buffer Matrices
matrices, Sampler
sampler) (Buffer SpriteData
buffer, TextureView
texture) -> Bindings {Buffer Matrices
Uniform CPU (Matrices CPU)
matrices :: Uniform CPU (Matrices CPU)
matrices :: Buffer Matrices
matrices, Sampler
Binding CPU Sampler
sampler :: Binding CPU Sampler
sampler :: Sampler
sampler, sprite :: Uniform CPU (SpriteData CPU)
sprite = Buffer SpriteData
Uniform CPU (SpriteData CPU)
buffer, TextureView
Binding CPU Texture
texture :: Binding CPU Texture
texture :: TextureView
texture})

sampleSprite :: Vec 2 Float -> Shader SpriteMaterial (Vec 4 Float)
sampleSprite :: Vec 2 (Expr ('Primitive 'TFloat))
-> Shader SpriteMaterial (Vec 4 (Expr ('Primitive 'TFloat)))
sampleSprite Vec 2 (Expr ('Primitive 'TFloat))
uv = do
  b <- Shader SpriteMaterial (B SpriteMaterial GPU)
Shader SpriteMaterial (Bindings GPU)
forall a. Material a => Shader a (B a GPU)
bindings
  let uv_flipped :: Vec 2 Float = abs $ cast b.sprite.flip - uv
  let uv = Expr ('VectorType 2 'TFloat)
Vec 2 (Expr ('Primitive 'TFloat))
uv_flipped Expr ('VectorType 2 'TFloat)
-> Expr ('VectorType 2 'TFloat) -> Expr ('VectorType 2 'TFloat)
forall (a :: Types). Num a => Expr a -> Expr a -> Expr a
* Expr
  ('Primitive (DesugarPrimitiveExpr (Expr ('Primitive 'TFloat))))
-> Expr
     ('Primitive (DesugarPrimitiveExpr (Expr ('Primitive 'TFloat))))
-> Vec 2 (Expr ('Primitive 'TFloat))
forall a.
(Expr ('Primitive (DesugarPrimitiveExpr a)) ~ a,
 SingI (DesugarPrimitiveExpr a),
 PrintVecElements 2 (DesugarPrimitiveExpr a)) =>
Expr ('Primitive (DesugarPrimitiveExpr a))
-> Expr ('Primitive (DesugarPrimitiveExpr a)) -> Vec 2 a
vec2 Bindings GPU
b.sprite.slice.z Bindings GPU
b.sprite.slice.w Expr ('VectorType 2 'TFloat)
-> Expr ('VectorType 2 'TFloat) -> Expr ('VectorType 2 'TFloat)
forall (a :: Types). Num a => Expr a -> Expr a -> Expr a
+ Bindings GPU
b.sprite.slice.xy
  pure $ sample b.texture b.sampler uv

newtype SomeColor f = SomeColor {forall f.
SomeColor f -> Field f (Vec 3 (Expr ('Primitive 'TFloat)))
color :: Field f (Vec 3 Float)}
  deriving stock ((forall x. SomeColor f -> Rep (SomeColor f) x)
-> (forall x. Rep (SomeColor f) x -> SomeColor f)
-> Generic (SomeColor f)
forall x. Rep (SomeColor f) x -> SomeColor f
forall x. SomeColor f -> Rep (SomeColor f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (SomeColor f) x -> SomeColor f
forall f x. SomeColor f -> Rep (SomeColor f) x
$cfrom :: forall f x. SomeColor f -> Rep (SomeColor f) x
from :: forall x. SomeColor f -> Rep (SomeColor f) x
$cto :: forall f x. Rep (SomeColor f) x -> SomeColor f
to :: forall x. Rep (SomeColor f) x -> SomeColor f
Generic)
  deriving anyclass (Int
[(Text, Text)]
Integer -> SomeColor GPU
SomeColor CPU -> Ptr Word8 -> IO Int
(Integer -> SomeColor GPU)
-> [(Text, Text)]
-> Int
-> (SomeColor CPU -> Ptr Word8 -> IO Int)
-> Bufferable SomeColor
forall (a :: * -> *).
(Integer -> a GPU)
-> [(Text, Text)]
-> Int
-> (a CPU -> Ptr Word8 -> IO Int)
-> Bufferable a
$cdummyBuffer :: Integer -> SomeColor GPU
dummyBuffer :: Integer -> SomeColor GPU
$cgetFields :: [(Text, Text)]
getFields :: [(Text, Text)]
$cgetSize :: Int
getSize :: Int
$cputBytes :: SomeColor CPU -> Ptr Word8 -> IO Int
putBytes :: SomeColor CPU -> Ptr Word8 -> IO Int
Bufferable)

newtype CustomBindings f = CustomBindings (Uniform f (SomeColor f))
  deriving stock ((forall x. CustomBindings f -> Rep (CustomBindings f) x)
-> (forall x. Rep (CustomBindings f) x -> CustomBindings f)
-> Generic (CustomBindings f)
forall x. Rep (CustomBindings f) x -> CustomBindings f
forall x. CustomBindings f -> Rep (CustomBindings f) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall f x. Rep (CustomBindings f) x -> CustomBindings f
forall f x. CustomBindings f -> Rep (CustomBindings f) x
$cfrom :: forall f x. CustomBindings f -> Rep (CustomBindings f) x
from :: forall x. CustomBindings f -> Rep (CustomBindings f) x
$cto :: forall f x. Rep (CustomBindings f) x -> CustomBindings f
to :: forall x. Rep (CustomBindings f) x -> CustomBindings f
Generic)
  deriving anyclass (Typeable CustomBindings
Typeable CustomBindings =>
(Natural -> Proxy (CustomBindings Internal) -> (Bindings, Natural))
-> (Natural
    -> Proxy (CustomBindings Internal)
    -> ([WGPUBindGroupLayoutEntry], Natural))
-> (Natural
    -> CustomBindings CPU -> ([WGPUBindGroupEntry], Natural))
-> (Natural -> (CustomBindings GPU, Natural))
-> Bindable CustomBindings
Natural -> (CustomBindings GPU, Natural)
Natural
-> Proxy (CustomBindings Internal)
-> ([WGPUBindGroupLayoutEntry], Natural)
Natural -> Proxy (CustomBindings Internal) -> (Bindings, Natural)
Natural -> CustomBindings CPU -> ([WGPUBindGroupEntry], Natural)
forall (a :: * -> *).
Typeable a =>
(Natural -> Proxy (a Internal) -> (Bindings, Natural))
-> (Natural
    -> Proxy (a Internal) -> ([WGPUBindGroupLayoutEntry], Natural))
-> (Natural -> a CPU -> ([WGPUBindGroupEntry], Natural))
-> (Natural -> (a GPU, Natural))
-> Bindable a
$ccollectBindings :: Natural -> Proxy (CustomBindings Internal) -> (Bindings, Natural)
collectBindings :: Natural -> Proxy (CustomBindings Internal) -> (Bindings, Natural)
$ccollectLayouts :: Natural
-> Proxy (CustomBindings Internal)
-> ([WGPUBindGroupLayoutEntry], Natural)
collectLayouts :: Natural
-> Proxy (CustomBindings Internal)
-> ([WGPUBindGroupLayoutEntry], Natural)
$ccollectEntries :: Natural -> CustomBindings CPU -> ([WGPUBindGroupEntry], Natural)
collectEntries :: Natural -> CustomBindings CPU -> ([WGPUBindGroupEntry], Natural)
$cdummyBinding :: Natural -> (CustomBindings GPU, Natural)
dummyBinding :: Natural -> (CustomBindings GPU, Natural)
Bindable)

data CustomMat

instance Material CustomMat where
  type VI CustomMat = VI SpriteMaterial
  type VO CustomMat = VO SpriteMaterial

  type B CustomMat = CustomBindings

  type Extends CustomMat = '[SpriteMaterial, TimeMaterial]

  vertex :: VI CustomMat GPU -> Shader CustomMat (VO CustomMat GPU)
vertex = Shader SpriteMaterial (VertexOutput GPU)
-> Shader CustomMat (VertexOutput GPU)
forall a b c. ExtensionOf b a => Shader a c -> Shader b c
liftExt (Shader SpriteMaterial (VertexOutput GPU)
 -> Shader CustomMat (VertexOutput GPU))
-> (VertexInput GPU -> Shader SpriteMaterial (VertexOutput GPU))
-> VertexInput GPU
-> Shader CustomMat (VertexOutput GPU)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Material a => VI a GPU -> Shader a (VO a GPU)
vertex @SpriteMaterial

  fragment :: VO CustomMat GPU -> Shader CustomMat (Vec 4 Float)
  fragment :: VO CustomMat GPU
-> Shader CustomMat (Vec 4 (Expr ('Primitive 'TFloat)))
fragment VO CustomMat GPU
vo = do
    color <- Shader SpriteMaterial (Vec 4 (Expr ('Primitive 'TFloat)))
-> Shader CustomMat (Vec 4 (Expr ('Primitive 'TFloat)))
forall a b c. ExtensionOf b a => Shader a c -> Shader b c
liftExt (Shader SpriteMaterial (Vec 4 (Expr ('Primitive 'TFloat)))
 -> Shader CustomMat (Vec 4 (Expr ('Primitive 'TFloat))))
-> Shader SpriteMaterial (Vec 4 (Expr ('Primitive 'TFloat)))
-> Shader CustomMat (Vec 4 (Expr ('Primitive 'TFloat)))
forall a b. (a -> b) -> a -> b
$ forall a.
Material a =>
VO a GPU -> Shader a (Vec 4 (Expr ('Primitive 'TFloat)))
fragment @SpriteMaterial VO CustomMat GPU
VO SpriteMaterial GPU
vo
    time <- liftExt getTime
    (CustomBindings (SomeColor c)) <- bindings
    pure $ color * (c ^* cos time +: 1)

  fetch :: FetchBindings (B CustomMat)
fetch =
    FetchBindings
      { camera :: CameraEntity -> Query System ()
camera = Query System () -> CameraEntity -> Query System ()
forall a b. a -> b -> a
const (Query System () -> CameraEntity -> Query System ())
-> Query System () -> CameraEntity -> Query System ()
forall a b. (a -> b) -> a -> b
$ () -> Query System ()
forall a. a -> Query System a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
        mesh :: CameraEntity -> Query System (Buffer SomeColor)
mesh = \CameraEntity
sprite -> CameraEntity
-> C (Buffer SomeColor) -> Query System (Buffer SomeColor)
forall w (m :: * -> *) qd out.
(MonadSystem w m, Queryable qd out) =>
CameraEntity -> qd -> Query m out
qget CameraEntity
sprite [qd|(Buffer SomeColor)|],
        result :: () -> Buffer SomeColor -> CustomBindings CPU
result = (Buffer SomeColor -> CustomBindings CPU)
-> () -> Buffer SomeColor -> CustomBindings CPU
forall a b. a -> b -> a
const Buffer SomeColor -> CustomBindings CPU
Uniform CPU (SomeColor CPU) -> CustomBindings CPU
forall f. Uniform f (SomeColor f) -> CustomBindings f
CustomBindings
      }