Loosen stac search to generalise out of pilot

This should allow us to recognise files in other campaigns.
Make graph tests a bit more convenient to write
Test the python-graph notion of neighbors
Introduce flat graph representation

The flat representation does not rely on the notion of a
hypergraph and instead represents CDUs as nodes that
point to their contents. I'm not sure why exactly I think
this will be useful, but it's worth exploring.

In the interest of sharing useful functions between the two
graph representations, I've split things apart a bit so that we have

  AttrsMixin - common node/edge attributes like 'is_cdu'
  |
  +-- HypergraphBase -+-- Graph
  |                   |
  |                   +-- FakeGraph (for testing)
  |
  +-- (DigraphBase)--+--- FlatGraph

DigraphBase doesn't actually exist but it probably should
Simplify class hierarchy for educe.graph

Much of the complexity was from me trying to avoid the __init__ function
of Graph for testing.  So I just turned that init into a factory method
instead.
glozz-graph --split

Split the graph into connnected components
(mostly a way of seeing how you might use some of
graph lib functionality)