docs: def walk_mapsources(mapsources, root=""):
      """
      recursively walk through foldernames of mapsources.
  
      Like os.walk, only for a list of mapsources.
  
      Args:
          mapsources (list of MapSource):
  
      Yields:
          (root, foldernames, maps)
  
      >>> mapsources = load_maps("test/mapsources")
      >>> pprint([x for x in walk_mapsources(mapsources.values())])
      [('',
        ['asia', 'europe'],
        [<MapSource: osm1 (root 1), n_layers: 1, min_zoom:5, max_zoom:18>,
         <MapSource: osm10 (root 2), n_layers: 1, min_zoom:5, max_zoom:18>]),
       ('/asia',
        [],
        [<MapSource: osm6 (asia), n_layers: 1, min_zoom:5, max_zoom:18>]),
       ('/europe',
        ['france', 'germany', 'switzerland'],
        [<MapSource: osm4 (eruope 1), n_layers: 1, min_zoom:1, max_zoom:18>]),
       ('/europe/france',
        [],
        [<MapSource: osm2 (europe/france 1), n_layers: 1, min_zoom:5, max_zoom:18>,
         <MapSource: osm3 (europe/france 2), n_layers: 1, min_zoom:1, max_zoom:18>,
         <MapSource: osm5 (europe/france 3), n_layers: 1, min_zoom:5, max_zoom:18>]),
       ('/europe/germany',
        [],
        [<MapSource: osm7 (europe/germany 1), n_layers: 1, min_zoom:5, max_zoom:18>,
         <MapSource: osm8 (europe/germany 2), n_layers: 1, min_zoom:5, max_zoom:18>]),
       ('/europe/switzerland',
        [],
        [<MapSource: osm9 (europe/switzerland), n_layers: 1, min_zoom:5, max_zoom:18>])]
  
      """
      def get_first_folder(path):
          """
          Get the first folder in a path
          > get_first_folder("europe/switzerland/bs")
          europe
          """
          path = path[len(root):]
          path = path.lstrip(F_SEP)
          return path.split(F_SEP)[0]
  
      path_tuples = sorted(((get_first_folder(m.folder), m) for m in mapsources), key=lambda x: x[0])
      groups = {k: [x for x in g] for k, g in itertools.groupby(path_tuples, lambda x: x[0])}
      folders = sorted([x for x in groups.keys() if x != ""])
      mapsources = sorted([t[1] for t in groups.get("", [])], key=lambda x: x.id)
      yield (root, folders, mapsources)
      for fd in folders:
          yield from walk_mapsources([t[1] for t in groups[fd]], F_SEP.join([root, fd]))