whole_func_string: function ListLayout(context, options) {
  
          // Local data
          var size = context.size;
          var direction = context.direction;
          var alignment = context.alignment;
          var revDirection = direction ? 0 : 1;
          var offset;
          var margins = LayoutUtility.normalizeMargins(options.margins);
          var spacing = options.spacing || 0;
          var node;
          var nodeSize;
          var itemSize;
          var getItemSize;
          var lastSectionBeforeVisibleCell;
          var lastSectionBeforeVisibleCellOffset;
          var lastSectionBeforeVisibleCellLength;
          var lastSectionBeforeVisibleCellScrollLength;
          var lastSectionBeforeVisibleCellTopReached;
          var firstVisibleCell;
          var lastNode;
          var lastCellOffsetInFirstVisibleSection;
          var isSectionCallback = options.isSectionCallback;
          var bound;
  
          //
          // Sanity checks
          //
          if (spacing && typeof spacing !== 'number') {
              console.log('Famous-flex warning: ListLayout was initialized with a non-numeric spacing option. ' + // eslint-disable-line no-console
                  'The CollectionLayout supports an array spacing argument, but the ListLayout does not.');
          }
  
          //
          // Reset size & translation
          //
          set.size[0] = size[0];
          set.size[1] = size[1];
          set.size[revDirection] -= (margins[1 - revDirection] + margins[3 - revDirection]);
          set.translate[0] = 0;
          set.translate[1] = 0;
          set.translate[2] = 0;
          set.translate[revDirection] = margins[direction ? 3 : 0];
  
          //
          // Determine item-size or use true=size
          //
          if ((options.itemSize === true) || !options.hasOwnProperty('itemSize')) {
              itemSize = true;
          }
          else if (options.itemSize instanceof Function) {
              getItemSize = options.itemSize;
          }
          else {
              itemSize = (options.itemSize === undefined) ? size[direction] : options.itemSize;
          }
  
          //
          // Determine leading/trailing margins
          //
          margin[0] = margins[direction ? 0 : 3];
          margin[1] = -margins[direction ? 2 : 1];
  
          //
          // Process all next nodes
          //
          offset = context.scrollOffset + margin[alignment];
          bound = context.scrollEnd + margin[alignment];
          while (offset < (bound + spacing)) {
              lastNode = node;
              node = context.next();
              if (!node) {
                  break;
              }
  
              //
              // Get node size
              //
              nodeSize = getItemSize ? getItemSize(node.renderNode, context.size) : itemSize;
              nodeSize = (nodeSize === true) ? context.resolveSize(node, size)[direction] : nodeSize;
  
              //
              // Position node
              //
              set.size[direction] = nodeSize;
              set.translate[direction] = offset + (alignment ? spacing : 0);
              set.scrollLength = nodeSize + spacing;
              context.set(node, set);
              offset += set.scrollLength;
  
              //
              // Keep track of the last section before the first visible cell
              //
              if (isSectionCallback && isSectionCallback(node.renderNode)) {
                  if ((set.translate[direction] <= margin[0]) && !lastSectionBeforeVisibleCellTopReached) {
                      lastSectionBeforeVisibleCellTopReached = true;
                      set.translate[direction] = margin[0];
                      context.set(node, set);
                  }
                  if (!firstVisibleCell) {
                      lastSectionBeforeVisibleCell = node;
                      lastSectionBeforeVisibleCellOffset = offset - nodeSize;
                      lastSectionBeforeVisibleCellLength = nodeSize;
                      lastSectionBeforeVisibleCellScrollLength = nodeSize;
                  }
                  else if (lastCellOffsetInFirstVisibleSection === undefined) {
                      lastCellOffsetInFirstVisibleSection = offset - nodeSize;
                  }
              }
              else if (!firstVisibleCell && (offset >= 0)) {
                  firstVisibleCell = node;
              }
          }
          if (lastNode && !node && !alignment) {
              set.scrollLength = nodeSize + margin[0] + -margin[1];
              context.set(lastNode, set);
          }
  
          //
          // Process previous nodes
          //
          lastNode = undefined;
          node = undefined;
          offset = context.scrollOffset + margin[alignment];
          bound = context.scrollStart + margin[alignment];
          while (offset > (bound - spacing)) {
              lastNode = node;
              node = context.prev();
              if (!node) {
                  break;
              }
  
              //
              // Get node size
              //
              nodeSize = getItemSize ? getItemSize(node.renderNode, context.size) : itemSize;
              nodeSize = (nodeSize === true) ? context.resolveSize(node, size)[direction] : nodeSize;
  
              //
              // Position node
              //
              set.scrollLength = nodeSize + spacing;
              offset -= set.scrollLength;
              set.size[direction] = nodeSize;
              set.translate[direction] = offset + (alignment ? spacing : 0);
              context.set(node, set);
  
              //
              // Keep track of the last section before the first visible cell
              //
              if (isSectionCallback && isSectionCallback(node.renderNode)) {
                  if ((set.translate[direction] <= margin[0]) && !lastSectionBeforeVisibleCellTopReached) {
                      lastSectionBeforeVisibleCellTopReached = true;
                      set.translate[direction] = margin[0];
                      context.set(node, set);
                  }
                  if (!lastSectionBeforeVisibleCell) {
                      lastSectionBeforeVisibleCell = node;
                      lastSectionBeforeVisibleCellOffset = offset;
                      lastSectionBeforeVisibleCellLength = nodeSize;
                      lastSectionBeforeVisibleCellScrollLength = set.scrollLength;
                  }
              }
              else if ((offset + nodeSize) >= 0) {
                  firstVisibleCell = node;
                  if (lastSectionBeforeVisibleCell) {
                      lastCellOffsetInFirstVisibleSection = offset + nodeSize;
                  }
                  lastSectionBeforeVisibleCell = undefined;
              }
          }
          if (lastNode && !node && alignment) {
              set.scrollLength = nodeSize + margin[0] + -margin[1];
              context.set(lastNode, set);
              if (lastSectionBeforeVisibleCell === lastNode) {
                  lastSectionBeforeVisibleCellScrollLength = set.scrollLength;
              }
          }
  
          //
          // When no first section is in the scrollable range, then
          // look back further in search for that section
          //
          if (isSectionCallback && !lastSectionBeforeVisibleCell) {
              node = context.prev();
              while (node) {
                  if (isSectionCallback(node.renderNode)) {
                      lastSectionBeforeVisibleCell = node;
                      nodeSize = options.itemSize || context.resolveSize(node, size)[direction];
                      lastSectionBeforeVisibleCellOffset = offset - nodeSize;
                      lastSectionBeforeVisibleCellLength = nodeSize;
                      lastSectionBeforeVisibleCellScrollLength = undefined;
                      break;
                  }
                  else {
                      node = context.prev();
                  }
              }
          }
  
          //
          // Reposition "last section before first visible cell" to the top of the layout
          //
          if (lastSectionBeforeVisibleCell) {
              var correctedOffset = Math.max(margin[0], lastSectionBeforeVisibleCellOffset);
              if ((lastCellOffsetInFirstVisibleSection !== undefined) &&
                  (lastSectionBeforeVisibleCellLength > (lastCellOffsetInFirstVisibleSection - margin[0]))) {
                  correctedOffset = ((lastCellOffsetInFirstVisibleSection - lastSectionBeforeVisibleCellLength));
              }
              set.size[direction] = lastSectionBeforeVisibleCellLength;
              set.translate[direction] = correctedOffset;
              set.scrollLength = lastSectionBeforeVisibleCellScrollLength;
              context.set(lastSectionBeforeVisibleCell, set);
          }
      }
func_code_string: function ListLayout(context, options) {
  
          // Local data
          var size = context.size;
          var direction = context.direction;
          var alignment = context.alignment;
          var revDirection = direction ? 0 : 1;
          var offset;
          var margins = LayoutUtility.normalizeMargins(options.margins);
          var spacing = options.spacing || 0;
          var node;
          var nodeSize;
          var itemSize;
          var getItemSize;
          var lastSectionBeforeVisibleCell;
          var lastSectionBeforeVisibleCellOffset;
          var lastSectionBeforeVisibleCellLength;
          var lastSectionBeforeVisibleCellScrollLength;
          var lastSectionBeforeVisibleCellTopReached;
          var firstVisibleCell;
          var lastNode;
          var lastCellOffsetInFirstVisibleSection;
          var isSectionCallback = options.isSectionCallback;
          var bound;
  
          //
          // Sanity checks
          //
          if (spacing && typeof spacing !== 'number') {
              console.log('Famous-flex warning: ListLayout was initialized with a non-numeric spacing option. ' + // eslint-disable-line no-console
                  'The CollectionLayout supports an array spacing argument, but the ListLayout does not.');
          }
  
          //
          // Reset size & translation
          //
          set.size[0] = size[0];
          set.size[1] = size[1];
          set.size[revDirection] -= (margins[1 - revDirection] + margins[3 - revDirection]);
          set.translate[0] = 0;
          set.translate[1] = 0;
          set.translate[2] = 0;
          set.translate[revDirection] = margins[direction ? 3 : 0];
  
          //
          // Determine item-size or use true=size
          //
          if ((options.itemSize === true) || !options.hasOwnProperty('itemSize')) {
              itemSize = true;
          }
          else if (options.itemSize instanceof Function) {
              getItemSize = options.itemSize;
          }
          else {
              itemSize = (options.itemSize === undefined) ? size[direction] : options.itemSize;
          }
  
          //
          // Determine leading/trailing margins
          //
          margin[0] = margins[direction ? 0 : 3];
          margin[1] = -margins[direction ? 2 : 1];
  
          //
          // Process all next nodes
          //
          offset = context.scrollOffset + margin[alignment];
          bound = context.scrollEnd + margin[alignment];
          while (offset < (bound + spacing)) {
              lastNode = node;
              node = context.next();
              if (!node) {
                  break;
              }
  
              //
              // Get node size
              //
              nodeSize = getItemSize ? getItemSize(node.renderNode, context.size) : itemSize;
              nodeSize = (nodeSize === true) ? context.resolveSize(node, size)[direction] : nodeSize;
  
              //
              // Position node
              //
              set.size[direction] = nodeSize;
              set.translate[direction] = offset + (alignment ? spacing : 0);
              set.scrollLength = nodeSize + spacing;
              context.set(node, set);
              offset += set.scrollLength;
  
              //
              // Keep track of the last section before the first visible cell
              //
              if (isSectionCallback && isSectionCallback(node.renderNode)) {
                  if ((set.translate[direction] <= margin[0]) && !lastSectionBeforeVisibleCellTopReached) {
                      lastSectionBeforeVisibleCellTopReached = true;
                      set.translate[direction] = margin[0];
                      context.set(node, set);
                  }
                  if (!firstVisibleCell) {
                      lastSectionBeforeVisibleCell = node;
                      lastSectionBeforeVisibleCellOffset = offset - nodeSize;
                      lastSectionBeforeVisibleCellLength = nodeSize;
                      lastSectionBeforeVisibleCellScrollLength = nodeSize;
                  }
                  else if (lastCellOffsetInFirstVisibleSection === undefined) {
                      lastCellOffsetInFirstVisibleSection = offset - nodeSize;
                  }
              }
              else if (!firstVisibleCell && (offset >= 0)) {
                  firstVisibleCell = node;
              }
          }
          if (lastNode && !node && !alignment) {
              set.scrollLength = nodeSize + margin[0] + -margin[1];
              context.set(lastNode, set);
          }
  
          //
          // Process previous nodes
          //
          lastNode = undefined;
          node = undefined;
          offset = context.scrollOffset + margin[alignment];
          bound = context.scrollStart + margin[alignment];
          while (offset > (bound - spacing)) {
              lastNode = node;
              node = context.prev();
              if (!node) {
                  break;
              }
  
              //
              // Get node size
              //
              nodeSize = getItemSize ? getItemSize(node.renderNode, context.size) : itemSize;
              nodeSize = (nodeSize === true) ? context.resolveSize(node, size)[direction] : nodeSize;
  
              //
              // Position node
              //
              set.scrollLength = nodeSize + spacing;
              offset -= set.scrollLength;
              set.size[direction] = nodeSize;
              set.translate[direction] = offset + (alignment ? spacing : 0);
              context.set(node, set);
  
              //
              // Keep track of the last section before the first visible cell
              //
              if (isSectionCallback && isSectionCallback(node.renderNode)) {
                  if ((set.translate[direction] <= margin[0]) && !lastSectionBeforeVisibleCellTopReached) {
                      lastSectionBeforeVisibleCellTopReached = true;
                      set.translate[direction] = margin[0];
                      context.set(node, set);
                  }
                  if (!lastSectionBeforeVisibleCell) {
                      lastSectionBeforeVisibleCell = node;
                      lastSectionBeforeVisibleCellOffset = offset;
                      lastSectionBeforeVisibleCellLength = nodeSize;
                      lastSectionBeforeVisibleCellScrollLength = set.scrollLength;
                  }
              }
              else if ((offset + nodeSize) >= 0) {
                  firstVisibleCell = node;
                  if (lastSectionBeforeVisibleCell) {
                      lastCellOffsetInFirstVisibleSection = offset + nodeSize;
                  }
                  lastSectionBeforeVisibleCell = undefined;
              }
          }
          if (lastNode && !node && alignment) {
              set.scrollLength = nodeSize + margin[0] + -margin[1];
              context.set(lastNode, set);
              if (lastSectionBeforeVisibleCell === lastNode) {
                  lastSectionBeforeVisibleCellScrollLength = set.scrollLength;
              }
          }
  
          //
          // When no first section is in the scrollable range, then
          // look back further in search for that section
          //
          if (isSectionCallback && !lastSectionBeforeVisibleCell) {
              node = context.prev();
              while (node) {
                  if (isSectionCallback(node.renderNode)) {
                      lastSectionBeforeVisibleCell = node;
                      nodeSize = options.itemSize || context.resolveSize(node, size)[direction];
                      lastSectionBeforeVisibleCellOffset = offset - nodeSize;
                      lastSectionBeforeVisibleCellLength = nodeSize;
                      lastSectionBeforeVisibleCellScrollLength = undefined;
                      break;
                  }
                  else {
                      node = context.prev();
                  }
              }
          }
  
          //
          // Reposition "last section before first visible cell" to the top of the layout
          //
          if (lastSectionBeforeVisibleCell) {
              var correctedOffset = Math.max(margin[0], lastSectionBeforeVisibleCellOffset);
              if ((lastCellOffsetInFirstVisibleSection !== undefined) &&
                  (lastSectionBeforeVisibleCellLength > (lastCellOffsetInFirstVisibleSection - margin[0]))) {
                  correctedOffset = ((lastCellOffsetInFirstVisibleSection - lastSectionBeforeVisibleCellLength));
              }
              set.size[direction] = lastSectionBeforeVisibleCellLength;
              set.translate[direction] = correctedOffset;
              set.scrollLength = lastSectionBeforeVisibleCellScrollLength;
              context.set(lastSectionBeforeVisibleCell, set);
          }
      }
func_documentation_string: Layout function