diff --git a/LICENCE b/LICENCE
new file mode 100644
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,31 @@
+Copyright (c) 2017-2019, Commonwealth Scientific and Industrial Research Organisation
+Copyright (c) 2019-2021, Tony Morris
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of QFPL nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/aviation-weight-balance.cabal b/aviation-weight-balance.cabal
new file mode 100644
--- /dev/null
+++ b/aviation-weight-balance.cabal
@@ -0,0 +1,53 @@
+name:               aviation-weight-balance
+version:            0.0.2
+license:            BSD3
+license-file:       LICENCE
+author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>, Joshua Morris <ɯoɔ˙lᴉɐɯƃ@llǝʞsɐɥ+sᴉɹɹoɯuɥoɾɐnɥsoɾ>
+maintainer:         Tony Morris, Joshua Morris
+copyright:          Copyright (c) 2019-2021, Tony Morris
+synopsis:           Weight and Balance structures used in aviation.
+category:           Aviation
+description:
+  Weight and Balance used in aviation.
+
+homepage:           https://gitlab.com/tonymorris/aviation-weight-balance
+bug-reports:        https://gitlab.com/tonymorris/aviation-weight-balance/issues
+cabal-version:      >= 1.10
+build-type:         Simple
+extra-source-files: changelog
+
+source-repository   head
+  type:             git
+  location:         git@gitlab.com:tonymorris/aviation-weight-balance.git
+
+library
+  default-language:
+                    Haskell2010
+
+  build-depends:
+                    base >= 4.8 && < 5
+                    , lens >= 4.15 && < 5
+                    , aviation-units >= 0.0.2 && < 1
+
+  if impl(ghc < 8)
+    build-depends:
+      semigroups >= 0.9 && < 0.19
+
+  ghc-options:
+                    -Wall
+
+  hs-source-dirs:
+                    src
+
+  exposed-modules:
+                    Data.Aviation.WB
+                    Data.Aviation.WB.Arm
+                    Data.Aviation.WB.Arm.Arm
+                    Data.Aviation.WB.Arm.ArmRange
+                    Data.Aviation.WB.Arm.ArmRangeLower
+                    Data.Aviation.WB.Arm.ArmStatic
+                    Data.Aviation.WB.Arm.ArmRangeUpper
+                    Data.Aviation.WB.Avgas100LL
+                    Data.Aviation.WB.Moment
+                    Data.Aviation.WB.Volume
+                    Data.Aviation.WB.Weight
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,7 @@
+0.0.2
+
+* Update GHC
+
+0.0.1
+
+* Initial release
diff --git a/src/Data/Aviation/WB.hs b/src/Data/Aviation/WB.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Data.Aviation.WB(
+  module A
+) where
+
+import Data.Aviation.WB.Arm as A
+import Data.Aviation.WB.Avgas100LL as A
+import Data.Aviation.WB.Moment as A
+import Data.Aviation.WB.Volume as A
+import Data.Aviation.WB.Weight as A
diff --git a/src/Data/Aviation/WB/Arm.hs b/src/Data/Aviation/WB/Arm.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Arm.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Data.Aviation.WB.Arm(
+  module A
+) where
+
+import Data.Aviation.WB.Arm.Arm as A
+import Data.Aviation.WB.Arm.ArmRange as A
+import Data.Aviation.WB.Arm.ArmRangeLower as A
+import Data.Aviation.WB.Arm.ArmStatic as A
+import Data.Aviation.WB.Arm.ArmRangeUpper as A
diff --git a/src/Data/Aviation/WB/Arm/Arm.hs b/src/Data/Aviation/WB/Arm/Arm.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Arm/Arm.hs
@@ -0,0 +1,116 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Arm.Arm(
+  Arm(..)
+, staticArm
+, rangeArm
+, HasArm(..)
+, HasArms(..)
+, SetArm(..)
+, HasArm0(..)
+) where
+
+import Control.Category((.))
+import Control.Lens(Lens', Traversal', Setter', lens, makeClassy)
+import Data.Aviation.WB.Arm.ArmRangeLower(HasArmRangeLowers(armRangeLowers), SetArmRangeLower(setArmRangeLower))
+import Data.Aviation.WB.Arm.ArmRange(ArmRange, HasArmRanges(armRanges), SetArmRange(setArmRange), HasArmRange0(armRange0))
+import Data.Aviation.WB.Arm.ArmStatic(ArmStatic, HasArmStatic(armStatic), HasArmStatics(armStatics), SetArmStatic(setArmStatic))
+import Data.Aviation.WB.Arm.ArmRangeUpper(HasArmRangeUppers(armRangeUppers), SetArmRangeUpper(setArmRangeUpper))
+import Data.Functor((<$>))
+import Data.Traversable(traverse)
+import Data.Eq(Eq)
+import Data.Maybe(Maybe(Nothing, Just))
+import Data.Ord(Ord)
+import Prelude(Show)
+    
+data Arm =
+  Arm
+    ArmStatic
+    (Maybe ArmRange)
+  deriving (Eq, Ord, Show)
+
+makeClassy ''Arm
+
+staticArm ::
+  ArmStatic
+  -> Arm
+staticArm x =
+  Arm x Nothing
+
+rangeArm ::
+  ArmStatic
+  -> ArmRange
+  -> Arm
+rangeArm x =
+  Arm x . Just
+
+class HasArms a where
+  arms ::
+    Traversal'
+      a
+      Arm
+
+instance HasArms Arm where
+  arms =
+    arm
+
+class SetArm a where
+  setArm ::
+    Setter'
+      a
+      Arm
+
+instance SetArm Arm where
+  setArm =
+    arm
+
+instance HasArmStatic Arm where
+  armStatic =
+    lens
+      (\(Arm s _) -> s)
+      (\(Arm _ r) s -> Arm s r)
+
+instance HasArmStatics Arm where
+  armStatics =
+    armStatic
+    
+instance HasArmRanges Arm where
+  armRanges f (Arm s r) =
+    Arm s <$> traverse f r
+
+instance SetArmRange Arm where
+  setArmRange =
+    armRanges
+
+instance SetArmStatic Arm where
+  setArmStatic =
+    armStatic . setArmStatic
+
+instance HasArmRangeLowers Arm where
+  armRangeLowers =
+    armRanges . armRangeLowers
+
+instance HasArmRangeUppers Arm where
+  armRangeUppers =
+    armRanges . armRangeUppers
+
+instance SetArmRangeLower Arm where
+  setArmRangeLower =
+    setArmRange . setArmRangeLower
+
+instance SetArmRangeUpper Arm where
+  setArmRangeUpper =
+    setArmRange . setArmRangeUpper
+
+class HasArm0 a where
+  arm0 ::
+    Lens'
+      a
+      (Maybe Arm)
+
+instance HasArmRange0 Arm where
+  armRange0 =
+    lens
+      (\(Arm _ r) -> r)
+      (\(Arm s _) r -> Arm s r)
diff --git a/src/Data/Aviation/WB/Arm/ArmRange.hs b/src/Data/Aviation/WB/Arm/ArmRange.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Arm/ArmRange.hs
@@ -0,0 +1,90 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Arm.ArmRange(
+  ArmRange(..)
+, HasArmRange(..)
+, HasArmRanges(..)
+, SetArmRange(..)
+, HasArmRange0(..)
+, (.->.)
+) where
+
+import Control.Lens(Lens', Traversal', Setter', lens, makeClassy)
+import Data.Aviation.WB.Arm.ArmRangeLower(ArmRangeLower, HasArmRangeLower(armRangeLower), HasArmRangeLowers(armRangeLowers), SetArmRangeLower(setArmRangeLower))
+import Data.Aviation.WB.Arm.ArmRangeUpper(ArmRangeUpper, HasArmRangeUpper(armRangeUpper), HasArmRangeUppers(armRangeUppers), SetArmRangeUpper(setArmRangeUpper))
+import Data.Eq(Eq)
+import Data.Maybe(Maybe)
+import Data.Ord(Ord)
+import Prelude(Show)
+
+data ArmRange =
+  ArmRange
+    ArmRangeLower
+    ArmRangeUpper
+  deriving (Eq, Ord, Show)
+
+makeClassy ''ArmRange
+
+(.->.) ::
+  ArmRangeLower
+  -> ArmRangeUpper
+  -> ArmRange
+(.->.) =
+  ArmRange
+
+infixl 2 .->. 
+
+class HasArmRanges a where
+  armRanges ::
+    Traversal'
+      a
+      ArmRange
+
+instance HasArmRanges ArmRange where
+  armRanges =
+    armRange
+
+class SetArmRange a where
+  setArmRange ::
+    Setter'
+      a
+      ArmRange
+
+instance SetArmRange ArmRange where
+  setArmRange =
+    armRange
+
+instance HasArmRangeLower ArmRange where
+  armRangeLower =
+    lens
+      (\(ArmRange lower _) -> lower)
+      (\(ArmRange _ upper) lower -> ArmRange lower upper)
+
+instance HasArmRangeUpper ArmRange where
+  armRangeUpper =
+    lens
+      (\(ArmRange _ upper) -> upper)
+      (\(ArmRange lower _) upper -> ArmRange lower upper)
+
+instance HasArmRangeLowers ArmRange where
+  armRangeLowers =
+    armRangeLower
+    
+instance HasArmRangeUppers ArmRange where
+  armRangeUppers =
+    armRangeUpper
+
+instance SetArmRangeLower ArmRange where
+  setArmRangeLower =
+    armRangeLower
+    
+instance SetArmRangeUpper ArmRange where
+  setArmRangeUpper =
+    armRangeUpper
+
+class HasArmRange0 a where
+  armRange0 ::
+    Lens'
+      a
+      (Maybe ArmRange)
diff --git a/src/Data/Aviation/WB/Arm/ArmRangeLower.hs b/src/Data/Aviation/WB/Arm/ArmRangeLower.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Arm/ArmRangeLower.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Arm.ArmRangeLower(
+  ArmRangeLower
+, HasArmRangeLower(..)
+, HasArmRangeLowers(..)
+, SetArmRangeLower(..)
+, HasArmRangeLower0(..)
+) where
+
+import Control.Category((.))
+import Control.Lens(Lens', Traversal', Setter', makeClassy, iso)
+import Data.Aviation.Units(Inches(inches), Centimetres(centimetres), Thouinches(thouinches))
+import Data.Eq(Eq)
+import Data.Maybe(Maybe)
+import Data.Monoid(Monoid(mempty, mappend))
+import Data.Ord(Ord)
+import Data.Ratio((%))
+import Data.Semigroup(Semigroup((<>)))
+import Numeric.Lens(dividing, multiplying)
+import Prelude(Show, Rational, (+))
+
+newtype ArmRangeLower =
+  ArmRangeLower
+    Rational
+  deriving (Eq, Ord, Show)
+
+makeClassy ''ArmRangeLower
+
+class HasArmRangeLowers a where
+  armRangeLowers ::
+    Traversal'
+      a
+      ArmRangeLower
+
+instance HasArmRangeLowers ArmRangeLower where
+  armRangeLowers =
+    armRangeLower
+
+class SetArmRangeLower a where
+  setArmRangeLower ::
+    Setter'
+      a
+      ArmRangeLower
+
+instance SetArmRangeLower ArmRangeLower where
+  setArmRangeLower =
+    armRangeLower
+
+class HasArmRangeLower0 a where
+  armRangeLower0 ::
+    Lens'
+      a
+      (Maybe ArmRangeLower)
+
+instance Inches ArmRangeLower where
+  inches =
+    iso
+      ArmRangeLower
+      (\(ArmRangeLower x) -> x)
+
+instance Thouinches ArmRangeLower where
+  thouinches =
+    multiplying 1000 . inches
+
+instance Centimetres ArmRangeLower where
+  centimetres =
+    dividing (254 % 100) . inches
+
+instance Semigroup ArmRangeLower where
+  (<>) =
+    mappend
+
+instance Monoid ArmRangeLower where
+  mempty =
+    ArmRangeLower 0
+  ArmRangeLower w1 `mappend` ArmRangeLower w2 =
+    ArmRangeLower (w1 + w2)
diff --git a/src/Data/Aviation/WB/Arm/ArmRangeUpper.hs b/src/Data/Aviation/WB/Arm/ArmRangeUpper.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Arm/ArmRangeUpper.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Arm.ArmRangeUpper(
+  ArmRangeUpper
+, HasArmRangeUpper(..)
+, HasArmRangeUppers(..)
+, SetArmRangeUpper(..)
+, HasArmRangeUpper0(..)
+) where
+
+import Control.Category((.))
+import Control.Lens(Lens', Traversal', Setter', makeClassy, iso)
+import Data.Aviation.Units(Inches(inches), Centimetres(centimetres), Thouinches(thouinches))
+import Data.Eq(Eq)
+import Data.Maybe(Maybe)
+import Data.Monoid(Monoid(mempty, mappend))
+import Data.Ord(Ord)
+import Data.Ratio((%))
+import Data.Semigroup(Semigroup((<>)))
+import Numeric.Lens(dividing, multiplying)
+import Prelude(Show, Rational, (+))
+
+newtype ArmRangeUpper =
+  ArmRangeUpper
+    Rational
+  deriving (Eq, Ord, Show)
+
+makeClassy ''ArmRangeUpper
+
+class HasArmRangeUppers a where
+  armRangeUppers ::
+    Traversal'
+      a
+      ArmRangeUpper
+
+instance HasArmRangeUppers ArmRangeUpper where
+  armRangeUppers =
+    armRangeUpper
+
+class SetArmRangeUpper a where
+  setArmRangeUpper ::
+    Setter'
+      a
+      ArmRangeUpper
+
+instance SetArmRangeUpper ArmRangeUpper where
+  setArmRangeUpper =
+    armRangeUpper
+
+class HasArmRangeUpper0 a where
+  armRangeUpper0 ::
+    Lens'
+      a
+      (Maybe ArmRangeUpper)
+
+instance Inches ArmRangeUpper where
+  inches =
+    iso
+      ArmRangeUpper
+      (\(ArmRangeUpper x) -> x)
+
+instance Thouinches ArmRangeUpper where
+  thouinches =
+    multiplying 1000 . inches
+
+instance Centimetres ArmRangeUpper where
+  centimetres =
+    dividing (254 % 100) . inches
+    
+instance Semigroup ArmRangeUpper where
+  (<>) =
+    mappend
+
+instance Monoid ArmRangeUpper where
+  mempty =
+    ArmRangeUpper 0
+  ArmRangeUpper w1 `mappend` ArmRangeUpper w2 =
+    ArmRangeUpper (w1 + w2)
diff --git a/src/Data/Aviation/WB/Arm/ArmStatic.hs b/src/Data/Aviation/WB/Arm/ArmStatic.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Arm/ArmStatic.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Arm.ArmStatic(
+  ArmStatic
+, HasArmStatic(..)
+, HasArmStatics(..)
+, SetArmStatic(..)
+, HasArmStatic0(..)
+) where
+
+import Control.Category((.))
+import Control.Lens(Lens', Traversal', Setter', makeClassy, iso)
+import Data.Aviation.Units(Inches(inches), Centimetres(centimetres), Thouinches(thouinches))
+import Data.Eq(Eq)
+import Data.Maybe(Maybe)
+import Data.Monoid(Monoid(mempty, mappend))
+import Data.Ord(Ord)
+import Data.Ratio((%))
+import Data.Semigroup(Semigroup((<>)))
+import Numeric.Lens(dividing, multiplying)
+import Prelude(Show, Rational, (+))
+
+newtype ArmStatic =
+  ArmStatic
+    Rational
+  deriving (Eq, Ord, Show)
+
+makeClassy ''ArmStatic
+
+class HasArmStatics a where
+  armStatics ::
+    Traversal'
+      a
+      ArmStatic
+
+instance HasArmStatics ArmStatic where
+  armStatics =
+    armStatic
+
+class SetArmStatic a where
+  setArmStatic ::
+    Setter'
+      a
+      ArmStatic
+
+instance SetArmStatic ArmStatic where
+  setArmStatic =
+    armStatic
+
+class HasArmStatic0 a where
+  armStatic0 ::
+    Lens'
+      a
+      (Maybe ArmStatic)
+
+instance Inches ArmStatic where
+  inches =
+    iso
+      ArmStatic
+      (\(ArmStatic x) -> x)
+
+instance Thouinches ArmStatic where
+  thouinches =
+    multiplying 1000 . inches
+
+instance Centimetres ArmStatic where
+  centimetres =
+    dividing (254 % 100) . inches
+
+instance Semigroup ArmStatic where
+  (<>) =
+    mappend
+
+instance Monoid ArmStatic where
+  mempty =
+    ArmStatic 0
+  ArmStatic w1 `mappend` ArmStatic w2 =
+    ArmStatic (w1 + w2)
diff --git a/src/Data/Aviation/WB/Avgas100LL.hs b/src/Data/Aviation/WB/Avgas100LL.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Avgas100LL.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FunctionalDependencies #-}
+
+module Data.Aviation.WB.Avgas100LL(
+  Avgas100LL(..)
+) where
+
+import Control.Category((.))
+import Control.Lens(Iso', from)
+import Data.Aviation.Units.USGallons(usgallons)
+import Data.Aviation.Units.Pounds(pounds)
+import Data.Aviation.WB.Weight(Weight)
+import Data.Aviation.WB.Volume(Volume)
+import Numeric.Lens(multiplying)
+
+class Avgas100LL a b | a -> b, b -> a where
+  avgas100LL ::
+    Iso' a b
+
+instance Avgas100LL Volume Weight where
+  avgas100LL =
+    from usgallons . multiplying 6 . pounds
+
+instance Avgas100LL Weight Volume where
+  avgas100LL =
+    from avgas100LL
diff --git a/src/Data/Aviation/WB/Moment.hs b/src/Data/Aviation/WB/Moment.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Moment.hs
@@ -0,0 +1,138 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE RankNTypes #-}
+
+module Data.Aviation.WB.Moment(
+  Moment(..)
+, HasMoment(..)
+, HasMoments(..)
+, SetMoment(..)
+, HasMoment0(..)
+, totalMoment
+, totalMoments
+, totalMoment''
+, totalWeights
+, momentX
+) where
+
+import Control.Applicative(Applicative((<*>)))
+import Control.Category((.))
+import Control.Lens(Lens', Traversal', Setter', Iso', lens, makeClassy, view, re)
+import Data.Aviation.WB.Arm.ArmStatic(ArmStatic, HasArmStatic(armStatic), HasArmStatics(armStatics), SetArmStatic(setArmStatic))
+import Data.Aviation.WB.Weight(Weight, HasWeight(weight), HasWeights(weights), SetWeight(setWeight))
+import Data.Eq(Eq)
+import Data.Foldable(Foldable, foldl, foldMap)
+import Data.Functor((<$>))
+import Data.Maybe(Maybe)
+import Data.Ord(Ord)
+import Prelude(Show, (*), (+), Rational)
+
+data Moment =
+  Moment
+    Weight
+    ArmStatic
+  deriving (Eq, Ord, Show)
+
+makeClassy ''Moment
+
+class HasMoments a where
+  moments ::
+    Traversal'
+      a
+      Moment
+
+instance HasMoments Moment where
+  moments =
+    moment
+
+class SetMoment a where
+  setMoment ::
+    Setter'
+      a
+      Moment
+
+instance SetMoment Moment where
+  setMoment =
+    moment
+
+class HasMoment0 a where
+  moment0 ::
+    Lens'
+      a
+      (Maybe Moment)
+
+instance HasWeight Moment where
+  weight =
+    lens
+      (\(Moment w _) -> w)
+      (\(Moment _ a) w -> Moment w a)
+
+instance HasWeights Moment where
+  weights =
+    weight
+
+instance SetWeight Moment where
+  setWeight =
+    weight
+
+instance HasArmStatic Moment where
+  armStatic =
+    lens
+      (\(Moment _ a) -> a)
+      (\(Moment w _) a -> Moment w a)
+
+instance HasArmStatics Moment where
+  armStatics =
+    armStatic
+
+instance SetArmStatic Moment where
+  setArmStatic =
+    armStatic
+
+totalMoment ::
+  HasMoment moment =>
+  Iso' Rational Weight
+  -> Iso' Rational ArmStatic
+  -> moment
+  -> Rational
+totalMoment w a m =
+  let r = view (moment . weight . re w) m
+      s = view (moment . armStatic . re a) m
+  in  r * s
+  
+totalMoments ::
+  (HasMoment moment, Foldable f) =>
+  Iso' Rational Weight
+  -> Iso' Rational ArmStatic
+  -> f moment
+  -> Rational
+totalMoments w a =
+  foldl (\x y -> x + totalMoment w a y) 0
+
+
+totalMoment'' ::
+  (HasMoment moment, Foldable f) =>
+  Iso' Rational Weight
+  -> Iso' Rational ArmStatic
+  -> f moment
+  -> Moment
+totalMoment'' w a m =
+  let (mw, ma) = foldl (\(w', a') n ->  let w'' = view (moment . weight . re w) n
+                                            a'' = view (moment . armStatic . re a) n
+                                        in  (w' + w'', a' + w'' * a'')) (0, 0) m
+  in  Moment (view w mw) (view a ma)
+
+totalWeights ::
+  (HasMoment moment, Foldable f) =>
+  f moment
+  -> Weight
+totalWeights =
+  foldMap (view (moment . weight))
+    
+momentX :: 
+  (HasWeight w, HasArmStatic s, Applicative f) =>
+  f w
+  -> f s
+  -> f Moment
+momentX wt b =
+  (\w -> Moment (view weight w) . view armStatic) <$> wt <*> b
diff --git a/src/Data/Aviation/WB/Volume.hs b/src/Data/Aviation/WB/Volume.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Volume.hs
@@ -0,0 +1,105 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Volume(
+  Volume
+, HasVolume(..)
+, HasVolumes(..)
+, SetVolume(..)
+, HasVolume0(..)
+, usgallonsV
+, litresV
+, imperialgallonsV
+) where
+
+import Control.Category((.))
+import Control.Lens(makeClassy, Traversal', Setter', Lens', Iso', iso)
+import Data.Aviation.Units.ImperialGallons(ImperialGallons(imperialgallons))
+import Data.Aviation.Units.USGallons(USGallons(usgallons))
+import Data.Aviation.Units.Litres(Litres(litres))
+import Data.Eq(Eq)
+import Data.Maybe(Maybe)
+import Data.Monoid(Monoid(mempty, mappend))
+import Data.Ord(Ord)
+import Data.Ratio((%))
+import Data.Semigroup(Semigroup((<>)))
+import Numeric.Lens(multiplying, dividing)
+import Prelude(Show, Rational, (+), (*))
+
+newtype Volume =
+  Volume
+    Rational
+  deriving (Eq, Ord, Show)
+
+makeClassy ''Volume
+
+class HasVolumes a where
+  volumes ::
+    Traversal'
+      a
+      Volume
+
+instance HasVolumes Volume where
+  volumes =
+    volume
+
+class SetVolume a where
+  setVolume ::
+    Setter'
+      a
+      Volume
+
+instance SetVolume Volume where
+  setVolume =
+    volume
+
+class HasVolume0 a where
+  volume0 ::
+    Lens'
+      a
+      (Maybe Volume)
+
+instance Semigroup Volume where
+  (<>) =
+    mappend
+
+instance Monoid Volume where
+  mempty =
+    Volume 0
+  Volume w1 `mappend` Volume w2 =
+    Volume (w1 + w2)
+
+instance USGallons Volume where
+  usgallons =
+    iso
+      Volume
+      (\(Volume x) -> x)
+
+instance Litres Volume where
+  litres =
+    dividing ((254 * 254 * 254 * 231) % 1000000000) . usgallons
+
+instance ImperialGallons Volume where
+  imperialgallons =
+    multiplying (454609 % 100000) . litres
+
+usgallonsV ::
+  Iso'
+    Rational
+    Volume
+usgallonsV =
+  usgallons
+
+litresV ::
+  Iso'
+    Rational
+    Volume
+litresV =
+  litres
+
+imperialgallonsV ::
+  Iso'
+    Rational
+    Volume
+imperialgallonsV =
+  imperialgallons
diff --git a/src/Data/Aviation/WB/Weight.hs b/src/Data/Aviation/WB/Weight.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aviation/WB/Weight.hs
@@ -0,0 +1,91 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Data.Aviation.WB.Weight(
+  Weight
+, HasWeight(..)
+, HasWeights(..)
+, SetWeight(..)
+, HasWeight0(..)
+, kilogramsW
+, poundsW
+) where
+
+import Control.Category((.))
+import Control.Lens(Iso', iso, Lens', Traversal', Setter', makeClassy, iso)
+import Data.Aviation.Units(Kilograms(kilograms), Pounds(pounds))
+import Data.Eq(Eq)
+import Data.Maybe(Maybe)
+import Data.Monoid(Monoid(mempty, mappend))
+import Data.Ord(Ord)
+import Data.Ratio((%))
+import Data.Semigroup(Semigroup((<>)))
+import Numeric.Lens(multiplying)
+import Prelude(Show, Rational, (+))
+
+newtype Weight =
+  Weight
+    Rational
+  deriving (Eq, Ord, Show)
+
+makeClassy ''Weight
+
+class HasWeights a where
+  weights ::
+    Traversal'
+      a
+      Weight
+
+instance HasWeights Weight where
+  weights =
+    weight
+
+class SetWeight a where
+  setWeight ::
+    Setter'
+      a
+      Weight
+
+instance SetWeight Weight where
+  setWeight =
+    weight
+
+class HasWeight0 a where
+  weight0 ::
+    Lens'
+      a
+      (Maybe Weight)
+
+instance Semigroup Weight where
+  (<>) =
+    mappend
+
+instance Monoid Weight where
+  mempty =
+    Weight 0
+  Weight w1 `mappend` Weight w2 =
+    Weight (w1 + w2)
+
+instance Kilograms Weight where
+  kilograms =
+    multiplying (22046226218 % 10000000000) . pounds
+
+instance Pounds Weight where
+  pounds =
+    iso
+      Weight
+      (\(Weight x) -> x)
+
+kilogramsW ::
+  Iso'
+    Rational
+    Weight
+kilogramsW =
+  kilograms
+  
+poundsW ::
+  Iso'
+    Rational
+    Weight
+poundsW =
+  pounds
