src/layout.js
function toSurround(description) {
  if (!Array.isArray(description)) {
    description = [layered(description)];
  }

  var positions = extractSurroundPositions(description);
  var top = positions.top;
  var right = positions.right;
  var bottom = positions.bottom;
  var left = positions.left;
  var middle = positions.middle;

  var container = {_id: '_container'};
  var topEdge = top[top.length - 1] && constraint.eq(top[top.length - 1], 'bottom') || 0;
  var rightEdge = right[0] && constraint.eq(right[0], 'left') || constraint.eq(container, 'right');
  var bottomEdge = bottom[0] && constraint.eq(bottom[0], 'top') || constraint.eq(container, 'bottom');
  var leftEdge = left[left.length - 1] && constraint.eq(left[left.length - 1], 'right') || 0;

  top = top.map(function(item, i, items) {
    var layout = {
      _position: 'top',
      top: items[i - 1] && constraint.eq(items[i - 1], 'bottom') || 0,
      left: leftEdge,
      right: rightEdge,
      width: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  right = right.map(function(item, i, items) {
    var layout = {
      _position: 'right',
      right: items[i + 1] && constraint.eq(items[i + 1], 'left') || constraint.eq(container, 'right'),
      top: topEdge,
      bottom: bottomEdge,
      height: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  bottom = bottom.map(function(item, i, items) {
    var layout = {
      _position: 'bottom',
      bottom: items[i + 1] && constraint.eq(items[i + 1], 'top') || constraint.eq(container, 'bottom'),
      left: leftEdge,
      right: rightEdge,
      width: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  left = left.map(function(item, i, items) {
    var layout = {
      _position: 'left',
      left: items[i - 1] && constraint.eq(items[i - 1], 'right') || 0,
      top: topEdge,
      bottom: bottomEdge,
      height: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  middle = middle.map(function(item) {
    var layout = {
      _position: 'middle',
      top: topEdge,
      right: rightEdge,
      bottom: bottomEdge,
      left: leftEdge,
      width: constraint.flex(),
      height: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });

  var allItems = top.concat(left).concat(middle).concat(right).concat(bottom);
  var byId = {};
  var ordered = [];
  allItems.forEach(function(item) {
    byId[item._id] = item;
    ordered.push(item._id);
  });

  return {byId: byId, ordered: ordered};
}
function toSurround(description) {
  if (!Array.isArray(description)) {
    description = [layered(description)];
  }

  var positions = extractSurroundPositions(description);
  var top = positions.top;
  var right = positions.right;
  var bottom = positions.bottom;
  var left = positions.left;
  var middle = positions.middle;

  var container = {_id: '_container'};
  var topEdge = top[top.length - 1] && constraint.eq(top[top.length - 1], 'bottom') || 0;
  var rightEdge = right[0] && constraint.eq(right[0], 'left') || constraint.eq(container, 'right');
  var bottomEdge = bottom[0] && constraint.eq(bottom[0], 'top') || constraint.eq(container, 'bottom');
  var leftEdge = left[left.length - 1] && constraint.eq(left[left.length - 1], 'right') || 0;

  top = top.map(function(item, i, items) {
    var layout = {
      _position: 'top',
      top: items[i - 1] && constraint.eq(items[i - 1], 'bottom') || 0,
      left: leftEdge,
      right: rightEdge,
      width: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  right = right.map(function(item, i, items) {
    var layout = {
      _position: 'right',
      right: items[i + 1] && constraint.eq(items[i + 1], 'left') || constraint.eq(container, 'right'),
      top: topEdge,
      bottom: bottomEdge,
      height: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  bottom = bottom.map(function(item, i, items) {
    var layout = {
      _position: 'bottom',
      bottom: items[i + 1] && constraint.eq(items[i + 1], 'top') || constraint.eq(container, 'bottom'),
      left: leftEdge,
      right: rightEdge,
      width: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  left = left.map(function(item, i, items) {
    var layout = {
      _position: 'left',
      left: items[i - 1] && constraint.eq(items[i - 1], 'right') || 0,
      top: topEdge,
      bottom: bottomEdge,
      height: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });
  middle = middle.map(function(item) {
    var layout = {
      _position: 'middle',
      top: topEdge,
      right: rightEdge,
      bottom: bottomEdge,
      left: leftEdge,
      width: constraint.flex(),
      height: constraint.flex()
    };

    item = assign({}, item);
    item.props = assign(layout, item.props);
    return item;
  });

  var allItems = top.concat(left).concat(middle).concat(right).concat(bottom);
  var byId = {};
  var ordered = [];
  allItems.forEach(function(item) {
    byId[item._id] = item;
    ordered.push(item._id);
  });

  return {byId: byId, ordered: ordered};
}
Placeholder until formal constraints/layouts are added