docs: def sortLocations(locations):
      """ Sort the locations by ranking:
              1.  all on-axis points
              2.  all off-axis points which project onto on-axis points
                  these would be involved in master to master interpolations
                  necessary for patching. Projecting off-axis masters have
                  at least one coordinate in common with an on-axis master.
              3.  non-projecting off-axis points, 'wild' off axis points
                  These would be involved in projecting limits and need to be patched.
      """
      onAxis = []
      onAxisValues = {}
      offAxis = []
      offAxis_projecting = []
      offAxis_wild = []
      # first get the on-axis points
      for l in locations:
          if l.isOrigin():
              continue
          if l.isOnAxis():
              onAxis.append(l)
              for axis in l.keys():
                  if axis not in onAxisValues:
                      onAxisValues[axis] = []
                  onAxisValues[axis].append(l[axis])
          else:
              offAxis.append(l)
      for l in offAxis:
          ok = False
          for axis in l.keys():
              if axis not in onAxisValues:
                  continue
              if l[axis] in onAxisValues[axis]:
                  ok = True
          if ok:
              offAxis_projecting.append(l)
          else:
              offAxis_wild.append(l)
      return onAxis, offAxis_projecting, offAxis_wild