docs: def _sprite_map(g, **kwargs):
      """
      Generates a sprite map from the files matching the glob pattern.
      Uses the keyword-style arguments passed in to control the placement.
      """
      g = StringValue(g).value
  
      if not Image:
          raise Exception("Images manipulation require PIL")
  
      if g in sprite_maps:
          sprite_maps[glob]['*'] = datetime.datetime.now()
      elif '..' not in g:  # Protect against going to prohibited places...
          vertical = (kwargs.get('direction', 'vertical') == 'vertical')
          offset_x = NumberValue(kwargs.get('offset_x', 0))
          offset_y = NumberValue(kwargs.get('offset_y', 0))
          repeat = StringValue(kwargs.get('repeat', 'no-repeat'))
          position = NumberValue(kwargs.get('position', 0))
          dst_color = kwargs.get('dst_color')
          src_color = kwargs.get('src_color')
          if position and position > -1 and position < 1:
              position.units = {'%': _units_weights.get('%', 1), '_': '%'}
          spacing = kwargs.get('spacing', 0)
          if isinstance(spacing, ListValue):
              spacing = [int(NumberValue(v).value) for n, v in spacing.items()]
          else:
              spacing = [int(NumberValue(spacing).value)]
          spacing = (spacing * 4)[:4]
  
          if callable(STATIC_ROOT):
              rfiles = files = sorted(STATIC_ROOT(g))
          else:
              glob_path = os.path.join(STATIC_ROOT, g)
              files = glob.glob(glob_path)
              files = sorted((f, None) for f in files)
              rfiles = [(f[len(STATIC_ROOT):], s) for f, s in files]
  
          if not files:
              log.error("Nothing found at '%s'", glob_path)
              return StringValue(None)
  
          times = []
          for file, storage in files:
              try:
                  d_obj = storage.modified_time(file)
                  times.append(int(time.mktime(d_obj.timetuple())))
              except:
                  times.append(int(os.path.getmtime(file)))
  
          map_name = os.path.normpath(
              os.path.dirname(g)).replace('\\', '_').replace('/', '_')
          key = list(zip(*files)[0]) + times + [repr(kwargs)]
          key = map_name + '-' + base64.urlsafe_b64encode(
              hashlib.md5(repr(key)).digest()).rstrip('=').replace('-', '_')
          asset_file = key + '.png'
          asset_path = os.path.join(ASSETS_ROOT, asset_file)
  
          if os.path.exists(asset_path + '.cache'):
              asset, map, sizes = pickle.load(open(asset_path + '.cache'))
              sprite_maps[asset] = map
          else:
              images = tuple(Image.open(storage.open(file)) if storage is not None else Image.open(file) for file, storage in files)
              names = tuple(os.path.splitext(
                  os.path.basename(file))[0] for file, storage in files)
              positions = []
              spacings = []
              tot_spacings = []
              for name in names:
                  name = name.replace('-', '_')
                  _position = kwargs.get(name + '_position')
                  if _position is None:
                      _position = position
                  else:
                      _position = NumberValue(_position)
                      if _position and _position > -1 and _position < 1:
                          _position.units = {'%':
                                             _units_weights.get('%', 1), '_': '%'}
                  positions.append(_position)
                  _spacing = kwargs.get(name + '_spacing')
                  if _spacing is None:
                      _spacing = spacing
                  else:
                      if isinstance(_spacing, ListValue):
                          _spacing = [int(NumberValue(
                              v).value) for n, v in _spacing.items()]
                      else:
                          _spacing = [int(NumberValue(_spacing).value)]
                      _spacing = (_spacing * 4)[:4]
                  spacings.append(_spacing)
                  if _position and _position.unit != '%':
                      if vertical:
                          if _position > 0:
                              tot_spacings.append((_spacing[0], _spacing[
                                  1], _spacing[2], _spacing[3] + _position))
                      else:
                          if _position > 0:
                              tot_spacings.append((_spacing[0] + _position,
                                                   _spacing[1], _spacing[2], _spacing[3]))
                  else:
                      tot_spacings.append(_spacing)
              sizes = tuple(image.size for image in images)
  
              _spacings = zip(*tot_spacings)
              if vertical:
                  width = max(
                      zip(*sizes)[0]) + max(_spacings[1]) + max(_spacings[3])
                  height = sum(
                      zip(*sizes)[1]) + sum(_spacings[0]) + sum(_spacings[2])
              else:
                  width = sum(
                      zip(*sizes)[0]) + sum(_spacings[1]) + sum(_spacings[3])
                  height = max(
                      zip(*sizes)[1]) + max(_spacings[0]) + max(_spacings[2])
  
              new_image = Image.new(
                  mode='RGBA',
                  size=(width, height),
                  color=(0, 0, 0, 0)
              )
  
              offsets_x = []
              offsets_y = []
              offset = 0
              for i, image in enumerate(images):
                  spacing = spacings[i]
                  position = positions[i]
                  if vertical:
                      if position and position.unit == '%':
                          x = width * position.value - \
                              (spacing[3] + sizes[i][1] + spacing[1])
                      elif position.value < 0:
                          x = width + position.value - \
                              (spacing[3] + sizes[i][1] + spacing[1])
                      else:
                          x = position.value
                      offset += spacing[0]
                      new_image.paste(image, (int(x + spacing[3]), offset))
                      offsets_x.append(x)
                      offsets_y.append(offset - spacing[0])
                      offset += sizes[i][1] + spacing[2]
                  else:
                      if position and position.unit == '%':
                          y = height * position.value - \
                              (spacing[0] + sizes[i][1] + spacing[2])
                      elif position.value < 0:
                          y = height + position.value - \
                              (spacing[0] + sizes[i][1] + spacing[2])
                      else:
                          y = position.value
                      offset += spacing[3]
                      new_image.paste(image, (offset, int(y + spacing[0])))
                      offsets_x.append(offset - spacing[3])
                      offsets_y.append(y)
                      offset += sizes[i][0] + spacing[1]
  
              if dst_color:
                  src_color = ColorValue(
                      src_color).value[:3] if src_color else (0, 0, 0)
                  dst_color = list(ColorValue(dst_color).value[:3])
                  pixdata = new_image.load()
                  for y in xrange(new_image.size[1]):
                      for x in xrange(new_image.size[0]):
                          if pixdata[x, y][:3] == src_color:
                              pixdata[x,
                                      y] = tuple(dst_color + [pixdata[x, y][3]])
  
              try:
                  new_image.save(asset_path)
              except IOError:
                  log.exception("Error while saving image")
              filetime = int(time.mktime(datetime.datetime.now().timetuple()))
  
              url = '%s%s?_=%s' % (ASSETS_URL, asset_file, filetime)
              asset = 'url("%s") %s' % (escape(url), repeat)
              # Use the sorted list to remove older elements (keep only 500
              # objects):
              if len(sprite_maps) > 1000:
                  for a in sorted(sprite_maps, key=lambda a: sprite_maps[a]['*'], reverse=True)[500:]:
                      del sprite_maps[a]
              # Add the new object:
              map = dict(zip(names, zip(sizes, rfiles, offsets_x, offsets_y)))
              map['*'] = datetime.datetime.now()
              map['*f*'] = asset_file
              map['*k*'] = key
              map['*n*'] = map_name
              map['*t*'] = filetime
              pickle.dump((asset, map, zip(files, sizes)), open(
                  asset_path + '.cache', 'w'))
              sprite_maps[asset] = map
          for file, size in sizes:
              sprite_images[file] = size
      ret = StringValue(asset)
      return ret