text: /*!
   * contentstack-express
   * Copyright (c) Contentstack
   * MIT Licensed
   */
  
  'use strict';
  
  var isArray;
  /**
   * Strip leading and trailing whitespace from a string.
   * @param  {string} input
   * @return {string}       Stripped input.
   */
  exports.strip = function(input) {
    return input.replace(/^\s+|\s+$/g, '');
  };
  /**
   * Test if a string starts with a given prefix.
   * @param  {string} str    String to test against.
   * @param  {string} prefix Prefix to check for.
   * @return {boolean}
   */
  exports.startsWith = function(str, prefix) {
    return str.indexOf(prefix) === 0;
  };
  /**
   * Test if a string ends with a given suffix.
   * @param  {string} str    String to test against.
   * @param  {string} suffix Suffix to check for.
   * @return {boolean}
   */
  exports.endsWith = function(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
  };
  /**
   * Iterate over an array or object.
   * @param  {array|object} obj Enumerable object.
   * @param  {Function}     fn  Callback function executed for each item.
   * @return {array|object}     The original input object.
   */
  exports.each = function(obj, fn) {
    var i, l;
    if (isArray(obj)) {
      i = 0;
      l = obj.length;
      for (i; i < l; i += 1) {
        if (fn(obj[i], i, obj) === false) {
          break;
        }
      }
    } else {
      for (i in obj) {
        if (obj.hasOwnProperty(i)) {
          if (fn(obj[i], i, obj) === false) {
            break;
          }
        }
      }
    }
    return obj;
  };
  /**
   * Test if an object is an Array.
   * @param {object} obj
   * @return {boolean}
   */
  exports.isArray = isArray = (Array.hasOwnProperty('isArray')) ? Array.isArray : function(obj) {
    return (obj) ? (typeof obj === 'object' && Object.prototype.toString.call(obj).indexOf() !== -1) : false;
  };
  /**
   * Test if an item in an enumerable matches your conditions.
   * @param  {array|object}   obj   Enumerable object.
   * @param  {Function}       fn    Executed for each item. Return true if your condition is met.
   * @return {boolean}
   */
  exports.some = function(obj, fn) {
    var i = 0,
      result,
      l;
    if (isArray(obj)) {
      l = obj.length;
      for (i; i < l; i += 1) {
        result = fn(obj[i], i, obj);
        if (result) {
          break;
        }
      }
    } else {
      exports.each(obj, function(value, index) {
        result = fn(value, index, obj);
        return !(result);
      });
    }
    return !!result;
  };
  /**
   * Return a new enumerable, mapped by a given iteration function.
   * @param  {object}   obj Enumerable object.
   * @param  {Function} fn  Executed for each item. Return the item to replace the original item with.
   * @return {object}       New mapped object.
   */
  exports.map = function(obj, fn) {
    var i = 0,
      result = [],
      l;
    if (isArray(obj)) {
      l = obj.length;
      for (i; i < l; i += 1) {
        result[i] = fn(obj[i], i);
      }
    } else {
      for (i in obj) {
        if (obj.hasOwnProperty(i)) {
          result[i] = fn(obj[i], i);
        }
      }
    }
    return result;
  };
  /**
   * Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.
   * @param {...object} arguments
   * @return {object}
   */
  exports.extend = function() {
    var args = arguments,
      target = args[0],
      objs = (args.length > 1) ? Array.prototype.slice.call(args, 1) : [],
      i = 0,
      l = objs.length,
      key,
      obj;
    for (i; i < l; i += 1) {
      obj = objs[i] || {};
      for (key in obj) {
        if (obj.hasOwnProperty(key)) {
          target[key] = obj[key];
        }
      }
    }
    return target;
  };
  /**
   * Get all of the keys on an object.
   * @param  {object} obj
   * @return {array}
   */
  exports.keys = function(obj) {
    if (!obj) {
      return [];
    }
    if (Object.keys) {
      return Object.keys(obj);
    }
    return exports.map(obj, function(v, k) {
      return k;
    });
  };
  /**
   * Throw an error with possible line number and source file.
   * @param  {string} message Error message
   * @param  {number} [line]  Line number in template.
   * @param  {string} [file]  Template file the error occured in.
   * @throws {Error} No seriously, the point is to throw an error.
   */
  exports.throwError = function(message, line, file) {
    if (line) {
      message += ' on line ' + line;
    }
    if (file) {
      message += ' in file ' + file;
    }
    throw new Error(message + '.');
  };