align = (options, ...geometries) => {
  const defaults = {
    modes: ['center', 'center', 'min'],
    relativeTo: [0, 0, 0],
    grouped: false
  }
  options = Object.assign({}, defaults, options)

  options = validateOptions(options)
  let { modes, relativeTo, grouped } = options
  geometries = flatten(geometries)
  if (geometries.length === 0) throw new Error('align(): No geometries were provided to act upon')

  if (relativeTo.filter((val) => val == null).length) {
    const bounds = measureAggregateBoundingBox(geometries)
    relativeTo = populateRelativeToFromBounds(relativeTo, modes, bounds)
  }
  if (grouped) {
    geometries = alignGeometries(geometries, modes, relativeTo)
  } else {
    geometries = geometries.map((geometry) => alignGeometries(geometry, modes, relativeTo))
  }
  return geometries.length === 1 ? geometries[0] : geometries
}
Align the boundaries of the given geometries using the given options.
@param {Object} options - options for aligning
@param {Array} [options.modes = ['center', 'center', 'min']] - the point on the geometries to align to for each axis. Valid options are "center", "max", "min", and "none".
@param {Array} [options.relativeTo = [0,0,0]] - The point one each axis on which to align the geometries upon.  If the value is null, then the corresponding value from the group's bounding box is used.
@param {Boolean} [options.grouped = false] - if true, transform all geometries by the same amount, maintaining the relative positions to each other.
@param {...Object} geometries - the geometries to align
@return {Object|Array} the aligned geometry, or a list of aligned geometries
@alias module:modeling/transforms.align

@example
let alignedGeometries = align({modes: ['min', 'center', 'none'], relativeTo: [10, null, 10], grouped: true }, geometries)