You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2015/07/16 09:08:51 UTC

[09/51] [partial] karaf-decanter git commit: [KARAF-3849] Add karaf kibana dashboard

http://git-wip-us.apache.org/repos/asf/karaf-decanter/blob/a24aae9b/kibana/src/main/resources/vendor/elasticjs/elastic.js
----------------------------------------------------------------------
diff --git a/kibana/src/main/resources/vendor/elasticjs/elastic.js b/kibana/src/main/resources/vendor/elasticjs/elastic.js
new file mode 100644
index 0000000..a782673
--- /dev/null
+++ b/kibana/src/main/resources/vendor/elasticjs/elastic.js
@@ -0,0 +1,17775 @@
+/*! elastic.js - v1.1.1 - 2014-03-21
+ * https://github.com/fullscale/elastic.js
+ * Copyright (c) 2014 FullScale Labs, LLC; Licensed MIT */
+
+/**
+ @namespace
+ @name ejs
+ @desc All elastic.js modules are organized under the ejs namespace.
+ */
+(function () {
+  'use strict';
+
+  var
+
+    // save reference to global object
+    // `window` in browser
+    // `exports` on server
+    root = this,
+
+    // save the previous version of ejs
+    _ejs = root && root.ejs,
+
+    // from underscore.js, used in utils
+    ArrayProto = Array.prototype,
+    ObjProto = Object.prototype,
+    slice = ArrayProto.slice,
+    toString = ObjProto.toString,
+    hasOwnProp = ObjProto.hasOwnProperty,
+    nativeForEach = ArrayProto.forEach,
+    nativeIsArray = Array.isArray,
+    nativeIndexOf = ArrayProto.indexOf,
+    breaker = {},
+    has,
+    each,
+    extend,
+    indexOf,
+    isArray,
+    isObject,
+    isString,
+    isNumber,
+    isBoolean,
+    isFunction,
+    isEJSObject, // checks if valid ejs object
+    isQuery, // checks valid ejs Query object
+    isRescore, // checks valid ejs Rescore object
+    isFilter, // checks valid ejs Filter object
+    isFacet, // checks valid ejs Facet object
+    isAggregation, // checks valid ejs Aggregation object
+    isScriptField, // checks valid ejs ScriptField object
+    isGeoPoint, // checks valid ejs GeoPoint object
+    isIndexedShape, // checks valid ejs IndexedShape object
+    isShape, // checks valid ejs Shape object
+    isSort, // checks valid ejs Sort object
+    isHighlight, // checks valid ejs Highlight object
+    isSuggest, // checks valid ejs Suggest object
+    isGenerator, // checks valid ejs Generator object
+    isScoreFunction, // checks valid ejs ScoreFunction object
+
+    // create ejs object
+    ejs;
+
+  if (typeof exports !== 'undefined') {
+    ejs = exports;
+  } else {
+    ejs = root.ejs = {};
+  }
+
+  /* Utility methods, most of which are pulled from underscore.js. */
+
+  // Shortcut function for checking if an object has a given property directly
+  // on itself (in other words, not on a prototype).
+  has = function (obj, key) {
+    return hasOwnProp.call(obj, key);
+  };
+
+  // The cornerstone, an `each` implementation, aka `forEach`.
+  // Handles objects with the built-in `forEach`, arrays, and raw objects.
+  // Delegates to **ECMAScript 5**'s native `forEach` if available.
+  each = function (obj, iterator, context) {
+    if (obj == null) {
+      return;
+    }
+    if (nativeForEach && obj.forEach === nativeForEach) {
+      obj.forEach(iterator, context);
+    } else if (obj.length === +obj.length) {
+      for (var i = 0, l = obj.length; i < l; i++) {
+        if (iterator.call(context, obj[i], i, obj) === breaker) {
+          return;
+        }
+      }
+    } else {
+      for (var key in obj) {
+        if (has(obj, key)) {
+          if (iterator.call(context, obj[key], key, obj) === breaker) {
+            return;
+          }
+        }
+      }
+    }
+  };
+
+  // Extend a given object with all the properties in passed-in object(s).
+  extend = function (obj) {
+    each(slice.call(arguments, 1), function (source) {
+      for (var prop in source) {
+        obj[prop] = source[prop];
+      }
+    });
+    return obj;
+  };
+
+  // Returns the index at which value can be found in the array, or -1 if
+  // value is not present in the array.
+  indexOf = function (array, item) {
+    if (array == null) {
+      return -1;
+    }
+
+    var i = 0, l = array.length;
+    if (nativeIndexOf && array.indexOf === nativeIndexOf) {
+      return array.indexOf(item);
+    }
+
+    for (; i < l; i++) {
+      if (array[i] === item) {
+        return i;
+
+      }
+    }
+
+    return -1;
+  };
+
+  // Is a given value an array?
+  // Delegates to ECMA5's native Array.isArray
+  // switched to ===, not sure why underscore used ==
+  isArray = nativeIsArray || function (obj) {
+    return toString.call(obj) === '[object Array]';
+  };
+
+  // Is a given variable an object?
+  isObject = function (obj) {
+    return obj === Object(obj);
+  };
+
+  // switched to ===, not sure why underscore used ==
+  isString = function (obj) {
+    return toString.call(obj) === '[object String]';
+  };
+
+  // switched to ===, not sure why underscore used ==
+  isNumber = function (obj) {
+    return toString.call(obj) === '[object Number]';
+  };
+
+  isBoolean = function(obj) {
+    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+  };
+
+  // switched to ===, not sure why underscore used ==
+  if (typeof (/./) !== 'function') {
+    isFunction = function (obj) {
+      return typeof obj === 'function';
+    };
+  } else {
+    isFunction = function (obj) {
+      return toString.call(obj) === '[object Function]';
+    };
+  }
+
+  // Is a given value an ejs object?
+  // Yes if object and has "_type", "toJSON", and "toString" properties
+  isEJSObject = function (obj) {
+    return (isObject(obj) &&
+      has(obj, '_type') &&
+      has(obj, 'toJSON'));
+  };
+
+  isQuery = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'query');
+  };
+
+  isRescore = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'rescore');
+  };
+
+  isFilter = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'filter');
+  };
+
+  isFacet = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'facet');
+  };
+
+  isAggregation = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'aggregation');
+  };
+
+  isScriptField = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'script field');
+  };
+
+  isGeoPoint = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'geo point');
+  };
+
+  isIndexedShape = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'indexed shape');
+  };
+
+  isShape = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'shape');
+  };
+
+  isSort = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'sort');
+  };
+
+  isHighlight = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'highlight');
+  };
+
+  isSuggest = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'suggest');
+  };
+
+  isGenerator = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'generator');
+  };
+
+  isScoreFunction = function (obj) {
+    return (isEJSObject(obj) && obj._type() === 'score function');
+  };
+
+  /**
+    @mixin
+    <p>The AggregationMixin provides support for common options used across
+    various <code>Aggregation</code> implementations.  This object should not be
+    used directly.</p>
+
+    @name ejs.AggregationMixin
+    */
+  ejs.AggregationMixin = function (name) {
+
+    var aggs = {};
+    aggs[name] = {};
+
+    return {
+
+      /**
+      Add a nesated aggregation.  This method can be called multiple times
+      in order to set multiple nested aggregations what will be executed
+      at the same time as the parent aggregation.
+
+      @member ejs.AggregationMixin
+      @param {Aggregation} agg Any valid <code>Aggregation</code> object.
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      aggregation: function(agg) {
+        if (agg == null) {
+          return aggs[name].aggs;
+        }
+
+        if (aggs[name].aggs == null) {
+          aggs[name].aggs = {};
+        }
+
+        if (!isAggregation(agg)) {
+          throw new TypeError('Argument must be an Aggregation');
+        }
+
+        extend(aggs[name].aggs, agg.toJSON());
+
+        return this;
+      },
+
+      /**
+      Add a nesated aggregation.  This method can be called multiple times
+      in order to set multiple nested aggregations what will be executed
+      at the same time as the parent aggregation.  Alias for the
+      aggregation method.
+
+      @member ejs.AggregationMixin
+      @param {Aggregation} agg Any valid <code>Aggregation</code> object.
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      agg: function(agg) {
+        return this.aggregation(agg);
+      },
+
+      /**
+            The type of ejs object.  For internal use only.
+
+            @member ejs.AggregationMixin
+            @returns {String} the type of object
+            */
+      _type: function () {
+        return 'aggregation';
+      },
+
+      /**
+            <p>Retrieves the internal <code>agg</code> object. This is typically used by
+               internal API functions so use with caution.</p>
+
+            @member ejs.AggregationMixin
+            @returns {String} returns this object's internal object.
+            */
+      toJSON: function () {
+        return aggs;
+      }
+
+    };
+  };
+
+  /**
+    @mixin
+    <p>The DirectSettingsMixin provides support for common options used across 
+    various <code>Suggester</code> implementations.  This object should not be 
+    used directly.</p>
+
+    @name ejs.DirectSettingsMixin
+  
+    @param {String} settings The object to set the options on.
+    */
+  ejs.DirectSettingsMixin = function (settings) {
+
+    return {
+        
+      /**
+            <p>Sets the accuracy.  How similar the suggested terms at least 
+            need to be compared to the original suggest text.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Double} a A positive double value between 0 and 1.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      accuracy: function (a) {
+        if (a == null) {
+          return settings.accuracy;
+        }
+  
+        settings.accuracy = a;
+        return this;
+      },
+    
+      /**
+            <p>Sets the suggest mode.  Valid values are:</p>
+
+            <dl>
+              <dd><code>missing</code> - Only suggest terms in the suggest text that aren't in the index</dd>
+              <dd><code>popular</code> - Only suggest suggestions that occur in more docs then the original suggest text term</dd>
+              <dd><code>always</code> - Suggest any matching suggestions based on terms in the suggest text</dd> 
+            </dl>
+
+            @member ejs.DirectSettingsMixin
+            @param {String} m The mode of missing, popular, or always.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      suggestMode: function (m) {
+        if (m == null) {
+          return settings.suggest_mode;
+        }
+  
+        m = m.toLowerCase();
+        if (m === 'missing' || m === 'popular' || m === 'always') {
+          settings.suggest_mode = m;
+        }
+      
+        return this;
+      },
+    
+      /**
+            <p>Sets the sort mode.  Valid values are:</p>
+
+            <dl>
+              <dd><code>score</code> - Sort by score first, then document frequency, and then the term itself</dd>
+              <dd><code>frequency</code> - Sort by document frequency first, then simlarity score and then the term itself</dd>
+            </dl>
+
+            @member ejs.DirectSettingsMixin
+            @param {String} s The score type of score or frequency.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      sort: function (s) {
+        if (s == null) {
+          return settings.sort;
+        }
+  
+        s = s.toLowerCase();
+        if (s === 'score' || s === 'frequency') {
+          settings.sort = s;
+        }
+      
+        return this;
+      },
+    
+      /**
+            <p>Sets what string distance implementation to use for comparing 
+            how similar suggested terms are.  Valid values are:</p>
+
+            <dl>
+              <dd><code>internal</code> - based on damerau_levenshtein but but highly optimized for comparing string distance for terms inside the index</dd>
+              <dd><code>damerau_levenshtein</code> - String distance algorithm based on Damerau-Levenshtein algorithm</dd>
+              <dd><code>levenstein</code> - String distance algorithm based on Levenstein edit distance algorithm</dd>
+              <dd><code>jarowinkler</code> - String distance algorithm based on Jaro-Winkler algorithm</dd>
+              <dd><code>ngram</code> - String distance algorithm based on character n-grams</dd>
+            </dl>
+
+            @member ejs.DirectSettingsMixin
+            @param {String} s The string distance algorithm name.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      stringDistance: function (s) {
+        if (s == null) {
+          return settings.string_distance;
+        }
+  
+        s = s.toLowerCase();
+        if (s === 'internal' || s === 'damerau_levenshtein' || 
+            s === 'levenstein' || s === 'jarowinkler' || s === 'ngram') {
+          settings.string_distance = s;
+        }
+      
+        return this;
+      },
+    
+      /**
+            <p>Sets the maximum edit distance candidate suggestions can have 
+            in order to be considered as a suggestion.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Integer} max An integer value greater than 0.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      maxEdits: function (max) {
+        if (max == null) {
+          return settings.max_edits;
+        }
+  
+        settings.max_edits = max;
+        return this;
+      },
+    
+      /**
+            <p>The factor that is used to multiply with the size in order 
+            to inspect more candidate suggestions.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Integer} max A positive integer value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      maxInspections: function (max) {
+        if (max == null) {
+          return settings.max_inspections;
+        }
+  
+        settings.max_inspections = max;
+        return this;
+      },
+    
+      /**
+            <p>Sets a maximum threshold in number of documents a suggest text 
+            token can exist in order to be corrected.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Double} max A positive double value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      maxTermFreq: function (max) {
+        if (max == null) {
+          return settings.max_term_freq;
+        }
+  
+        settings.max_term_freq = max;
+        return this;
+      },
+    
+      /**
+            <p>Sets the number of minimal prefix characters that must match in 
+            order be a candidate suggestion.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Integer} len A positive integer value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      prefixLen: function (len) {
+        if (len == null) {
+          return settings.prefix_len;
+        }
+  
+        settings.prefix_len = len;
+        return this;
+      },
+    
+      /**
+            <p>Sets the minimum length a suggest text term must have in order 
+            to be corrected.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Integer} len A positive integer value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      minWordLen: function (len) {
+        if (len == null) {
+          return settings.min_word_len;
+        }
+  
+        settings.min_word_len = len;
+        return this;
+      },
+    
+      /**
+            <p>Sets a minimal threshold of the number of documents a suggested 
+            term should appear in.</p>
+
+            @member ejs.DirectSettingsMixin
+            @param {Double} min A positive double value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      minDocFreq: function (min) {
+        if (min == null) {
+          return settings.min_doc_freq;
+        }
+  
+        settings.min_doc_freq = min;
+        return this;
+      }
+      
+    };
+  };
+
+  /**
+    @mixin
+    <p>The FacetMixin provides support for common options used across 
+    various <code>Facet</code> implementations.  This object should not be 
+    used directly.</p>
+
+    @name ejs.FacetMixin
+    */
+  ejs.FacetMixin = function (name) {
+
+    var facet = {};
+    facet[name] = {};
+    
+    return {
+    
+      /**
+            <p>Allows you to reduce the documents used for computing facet results.</p>
+
+            @member ejs.FacetMixin
+            @param {Object} oFilter A valid <code>Filter</code> object.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      facetFilter: function (oFilter) {
+        if (oFilter == null) {
+          return facet[name].facet_filter;
+        }
+      
+        if (!isFilter(oFilter)) {
+          throw new TypeError('Argument must be a Filter');
+        }
+        
+        facet[name].facet_filter = oFilter.toJSON();
+        return this;
+      },
+
+      /**
+            <p>Computes values across the entire index</p>
+
+            @member ejs.FacetMixin
+            @param {Boolean} trueFalse Calculate facet counts globally or not.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      global: function (trueFalse) {
+        if (trueFalse == null) {
+          return facet[name].global;
+        }
+        
+        facet[name].global = trueFalse;
+        return this;
+      },
+      
+      /**
+            <p>Sets the mode the facet will use.<p>
+            
+            <dl>
+                <dd><code>collector</code></dd>
+                <dd><code>post</code></dd>
+            <dl>
+            
+            @member ejs.FacetMixin
+            @param {String} m The mode: collector or post.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      mode: function (m) {
+        if (m == null) {
+          return facet[name].mode;
+        }
+      
+        m = m.toLowerCase();
+        if (m === 'collector' || m === 'post') {
+          facet[name].mode = m;
+        }
+        
+        return this;
+      },
+      
+      /**
+            <p>Enables caching of the <code>facetFilter</code></p>
+
+            @member ejs.FacetMixin
+            @param {Boolean} trueFalse If the facetFilter should be cached or not
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      cacheFilter: function (trueFalse) {
+        if (trueFalse == null) {
+          return facet[name].cache_filter;
+        }
+        
+        facet[name].cache_filter = trueFalse;
+        return this;
+      },
+      
+      /**
+            <p>Computes values across the the specified scope</p>
+
+            @deprecated since elasticsearch 0.90
+            @member ejs.FacetMixin
+            @param {String} scope The scope name to calculate facet counts with.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      scope: function (scope) {
+        return this;
+      },
+      
+      /**
+            <p>Sets the path to the nested document if faceting against a
+            nested field.</p>
+
+            @member ejs.FacetMixin
+            @param {String} path The nested path
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      nested: function (path) {
+        if (path == null) {
+          return facet[name].nested;
+        }
+        
+        facet[name].nested = path;
+        return this;
+      },
+
+      /**
+            The type of ejs object.  For internal use only.
+            
+            @member ejs.FacetMixin
+            @returns {String} the type of object
+            */
+      _type: function () {
+        return 'facet';
+      },
+      
+      /**
+            <p>Retrieves the internal <code>facet</code> object. This is typically used by
+               internal API functions so use with caution.</p>
+
+            @member ejs.FacetMixin
+            @returns {String} returns this object's internal <code>facet</code> property.
+            */
+      toJSON: function () {
+        return facet;
+      }
+      
+    };
+  };
+
+  /**
+    @mixin
+    <p>The FilterMixin provides support for common options used across 
+    various <code>Filter</code> implementations.  This object should not be 
+    used directly.</p>
+
+    @name ejs.FilterMixin
+    */
+  ejs.FilterMixin = function (type) {
+
+    var filter = {};
+    filter[type] = {};
+
+    return {
+
+      /**
+            Sets the filter name.
+
+            @member ejs.FilterMixin
+            @param {String} name A name for the filter.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      name: function (name) {
+        if (name == null) {
+          return filter[type]._name;
+        }
+
+        filter[type]._name = name;
+        return this;
+      },
+
+      /**
+            Enable or disable caching of the filter
+
+            @member ejs.FilterMixin
+            @param {Boolean} trueFalse True to cache the filter, false otherwise.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      cache: function (trueFalse) {
+        if (trueFalse == null) {
+          return filter[type]._cache;
+        }
+
+        filter[type]._cache = trueFalse;
+        return this;
+      },
+
+      /**
+            Sets the cache key.
+
+            @member ejs.FilterMixin
+            @param {String} key the cache key as a string.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      cacheKey: function (key) {
+        if (key == null) {
+          return filter[type]._cache_key;
+        }
+
+        filter[type]._cache_key = key;
+        return this;
+      },
+
+      /**
+            The type of ejs object.  For internal use only.
+          
+            @member ejs.FilterMixin
+            @returns {String} the type of object
+            */
+      _type: function () {
+        return 'filter';
+      },
+    
+      /**
+             Returns the filter object.
+
+             @member ejs.FilterMixin
+             @returns {Object} filter object
+             */
+      toJSON: function () {
+        return filter;
+      }
+    
+    };
+  };
+
+  /**
+    @mixin
+    <p>The MetricsAggregationMixin provides support for common options used across
+    various metrics <code>Aggregation</code> implementations.  This object should
+    not be used directly.</p>
+
+    @name ejs.MetricsAggregationMixin
+    @ejs aggregation
+    @borrows ejs.AggregationMixin._type as _type
+    @borrows ejs.AggregationMixin.toJSON as toJSON
+
+    */
+  ejs.MetricsAggregationMixin = function (name, type) {
+
+    var
+      _common = ejs.AggregationMixin(name),
+      agg = _common.toJSON();
+
+    // remove ability for sub-aggregations since metrics aggregations dont
+    // support them.
+    delete _common.aggregation;
+    delete _common.agg;
+
+    agg[name][type] = {};
+
+    return extend(_common, {
+
+      /**
+      <p>Sets the field to operate on.</p>
+
+      @member ejs.MetricsAggregationMixin
+      @param {String} field a valid field name..
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      field: function (field) {
+        if (field == null) {
+          return agg[name][type].field;
+        }
+
+        agg[name][type].field = field;
+        return this;
+      },
+
+      /**
+      Allows you generate or modify the terms/values using a script.
+
+      @member ejs.MetricsAggregationMixin
+      @param {String} scriptCode A valid script string to execute.
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      script: function (scriptCode) {
+        if (scriptCode == null) {
+          return agg[name][type].script;
+        }
+
+        agg[name][type].script = scriptCode;
+        return this;
+      },
+
+      /**
+      The script language being used.
+
+      @member ejs.MetricsAggregationMixin
+      @param {String} language The language of the script.
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      lang: function (language) {
+        if (language == null) {
+          return agg[name][type].lang;
+        }
+
+        agg[name][type].lang = language;
+        return this;
+      },
+
+      /**
+      Set to true to assume script values are sorted.
+
+      @member ejs.MetricsAggregationMixin
+      @param {Boolean} trueFalse assume sorted values or not
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      scriptValuesSorted: function (trueFalse) {
+        if (trueFalse == null) {
+          return agg[name][type].script_values_sorted;
+        }
+
+        agg[name][type].script_values_sorted = trueFalse;
+        return this;
+      },
+
+      /**
+      Sets parameters that will be applied to the script.  Overwrites
+      any existing params.
+
+      @member ejs.MetricsAggregationMixin
+      @param {Object} p An object where the keys are the parameter name and
+        values are the parameter value.
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      params: function (p) {
+        if (p == null) {
+          return agg[name][type].params;
+        }
+
+        agg[name][type].params = p;
+        return this;
+      }
+
+    });
+  };
+
+  /**
+    @mixin
+    <p>The QueryMixin provides support for common options used across 
+    various <code>Query</code> implementations.  This object should not be 
+    used directly.</p>
+
+    @name ejs.QueryMixin
+    */
+  ejs.QueryMixin = function (type) {
+
+    var query = {};
+    query[type] = {};
+
+    return {
+
+      /**
+            Sets the boost value for documents matching the <code>Query</code>.
+
+            @member ejs.QueryMixin
+            @param {Double} boost A positive <code>double</code> value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      boost: function (boost) {
+        if (boost == null) {
+          return query[type].boost;
+        }
+
+        query[type].boost = boost;
+        return this;
+      },
+    
+      /**
+            The type of ejs object.  For internal use only.
+          
+            @member ejs.QueryMixin
+            @returns {String} the type of object
+            */
+      _type: function () {
+        return 'query';
+      },
+    
+      /**
+            Retrieves the internal <code>query</code> object. This is typically used by
+            internal API functions so use with caution.
+
+            @member ejs.QueryMixin
+            @returns {String} returns this object's internal <code>query</code> property.
+            */
+      toJSON: function () {
+        return query;
+      }
+  
+    };
+  };
+
+  /**
+    @mixin
+    <p>The ScoreFunctionMixin provides support for common options used across
+    various <code>ScoreFunction</code> implementations.  This object should not be
+    used directly.</p>
+
+    @name ejs.ScoreFunctionMixin
+    */
+  ejs.ScoreFunctionMixin = function (name) {
+
+    var func = {};
+    func[name] = {};
+
+    return {
+
+      /**
+      Adds a filter whose matching documents will have the score function applied.
+
+      @member ejs.ScoreFunctionMixin
+      @param {Filter} oFilter Any valid <code>Filter</code> object.
+      @returns {Object} returns <code>this</code> so that calls can be chained.
+      */
+      filter: function(oFilter) {
+        if (oFilter == null) {
+          return func.filter;
+        }
+
+        if (!isFilter(oFilter)) {
+          throw new TypeError('Argument must be a Filter');
+        }
+
+        func.filter = oFilter.toJSON();
+        return this;
+      },
+
+      /**
+      The type of ejs object.  For internal use only.
+
+      @member ejs.ScoreFunctionMixin
+      @returns {String} the type of object
+      */
+      _type: function () {
+        return 'score function';
+      },
+
+      /**
+      <p>Retrieves the internal <code>agg</code> object. This is typically used by
+         internal API functions so use with caution.</p>
+
+      @member ejs.ScoreFunctionMixin
+      @returns {String} returns this object's internal object.
+      */
+      toJSON: function () {
+        return func;
+      }
+
+    };
+  };
+
+  /**
+    @mixin
+    <p>The SuggestContextMixin provides support for suggest context settings 
+    across various <code>Suggester</code> implementations.  This object should not be 
+    used directly.</p>
+
+    @name ejs.SuggestContextMixin
+  
+    @param {String} settings The object to set the options on.
+    */
+  ejs.SuggestContextMixin = function (settings) {
+
+    return {
+    
+      /**
+            <p>Sets analyzer used to analyze the suggest text.</p>
+
+            @member ejs.SuggestContextMixin
+            @param {String} analyzer A valid analyzer name.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      analyzer: function (analyzer) {
+        if (analyzer == null) {
+          return settings.analyzer;
+        }
+  
+        settings.analyzer = analyzer;
+        return this;
+      },
+    
+      /**
+            <p>Sets the field used to generate suggestions from.</p>
+
+            @member ejs.SuggestContextMixin
+            @param {String} field A valid field name.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      field: function (field) {
+        if (field == null) {
+          return settings.field;
+        }
+  
+        settings.field = field;
+        return this;
+      },
+    
+      /**
+            <p>Sets the number of suggestions returned for each token.</p>
+
+            @member ejs.SuggestContextMixin
+            @param {Integer} s A positive integer value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      size: function (s) {
+        if (s == null) {
+          return settings.size;
+        }
+  
+        settings.size = s;
+        return this;
+      },
+    
+      /**
+            <p>Sets the maximum number of suggestions to be retrieved from 
+            each individual shard.</p>
+
+            @member ejs.SuggestContextMixin
+            @param {Integer} s A positive integer value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      shardSize: function (s) {
+        if (s == null) {
+          return settings.shard_size;
+        }
+  
+        settings.shard_size = s;
+        return this;
+      }
+      
+    };
+  };
+
+  /**
+    @mixin
+    <p>The SuggesterMixin provides support for the base setting of all suggesters. 
+    This object should not be used directly.</p>
+
+    @name ejs.SuggesterMixin
+  
+    @param {String} name The name of the suggester.
+    */
+  ejs.SuggesterMixin = function (name) {
+  
+    var suggest = {};
+    suggest[name] = {};
+
+    return {
+  
+      /**
+            <p>Sets the text to get suggestions for.  If not set, the global
+            suggestion text will be used.</p>
+
+            @member ejs.SuggesterMixin
+            @param {String} txt A string to get suggestions for.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      text: function (txt) {
+        if (txt == null) {
+          return suggest[name].text;
+        }
+  
+        suggest[name].text = txt;
+        return this;
+      },
+  
+      /**
+            The type of ejs object.  For internal use only.
+        
+            @member ejs.SuggesterMixin
+            @returns {String} the type of object
+            */
+      _type: function () {
+        return 'suggest';
+      },
+  
+      /**
+            <p>Retrieves the internal <code>suggest</code> object. This is typically used by
+               internal API functions so use with caution.</p>
+
+            @member ejs.SuggesterMixin
+            @returns {String} returns this object's internal <code>suggest</code> property.
+            */
+      toJSON: function () {
+        return suggest;
+      }
+    
+    };
+  };
+
+  /**
+    @class
+    <p>The DateHistogram facet works with time-based values by building a histogram across time
+       intervals of the <code>value</code> field. Each value is <em>rounded</em> into an interval (or
+       placed in a bucket), and statistics are provided per interval/bucket (count and total).</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.DateHistogramFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+  
+    @desc
+    <p>A facet which returns the N most frequent terms within a collection
+       or set of collections.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.DateHistogramFacet = function (name) {
+
+    var  
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    facet[name].date_histogram = {};
+
+    return extend(_common, {
+
+      /**
+            Sets the field to be used to construct the this facet.
+
+            @member ejs.DateHistogramFacet
+            @param {String} fieldName The field name whose data will be used to construct the facet.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      field: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].date_histogram.field;
+        }
+      
+        facet[name].date_histogram.field = fieldName;
+        return this;
+      },
+
+      /**
+            Allows you to specify a different key field to be used to group intervals.
+
+            @member ejs.DateHistogramFacet
+            @param {String} fieldName The name of the field to be used.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      keyField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].date_histogram.key_field;
+        }
+      
+        facet[name].date_histogram.key_field = fieldName;
+        return this;
+      },
+      
+      /**
+            Allows you to specify a different value field to aggrerate over.
+
+            @member ejs.DateHistogramFacet
+            @param {String} fieldName The name of the field to be used.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].date_histogram.value_field;
+        }
+      
+        facet[name].date_histogram.value_field = fieldName;
+        return this;
+      },
+      
+      /**
+            Sets the bucket interval used to calculate the distribution.
+
+            @member ejs.DateHistogramFacet
+            @param {String} timeInterval The bucket interval. Valid values are <code>year, month, week, day, hour,</code> and <code>minute</code>.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      interval: function (timeInterval) {
+        if (timeInterval == null) {
+          return facet[name].date_histogram.interval;
+        }
+      
+        facet[name].date_histogram.interval = timeInterval;
+        return this;
+      },
+
+      /**
+            <p>By default, time values are stored in UTC format.<p> 
+
+            <p>This method allows users to set a time zone value that is then used 
+            to compute intervals before rounding on the interval value. Equalivent to 
+            <coe>preZone</code>.  Use <code>preZone</code> if possible. The 
+            value is an offset from UTC.<p>
+            
+            <p>For example, to use EST you would set the value to <code>-5</code>.</p>
+
+            @member ejs.DateHistogramFacet
+            @param {Integer} tz An offset value from UTC.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      timeZone: function (tz) {
+        if (tz == null) {
+          return facet[name].date_histogram.time_zone;
+        }
+      
+        facet[name].date_histogram.time_zone = tz;
+        return this;
+      },
+
+      /**
+            <p>By default, time values are stored in UTC format.<p> 
+
+            <p>This method allows users to set a time zone value that is then used to 
+            compute intervals before rounding on the interval value.  The value is an 
+            offset from UTC.<p>
+            
+            <p>For example, to use EST you would set the value to <code>-5</code>.</p>
+
+            @member ejs.DateHistogramFacet
+            @param {Integer} tz An offset value from UTC.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      preZone: function (tz) {
+        if (tz == null) {
+          return facet[name].date_histogram.pre_zone;
+        }
+      
+        facet[name].date_histogram.pre_zone = tz;
+        return this;
+      },
+      
+      /**
+            <p>Enables large date interval conversions (day and up).</p>  
+
+            <p>Set to true to enable and then set the <code>interval</code> to an 
+            interval greater than a day.</p>
+            
+            @member ejs.DateHistogramFacet
+            @param {Boolean} trueFalse A valid boolean value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      preZoneAdjustLargeInterval: function (trueFalse) {
+        if (trueFalse == null) {
+          return facet[name].date_histogram.pre_zone_adjust_large_interval;
+        }
+      
+        facet[name].date_histogram.pre_zone_adjust_large_interval = trueFalse;
+        return this;
+      },
+      
+      /**
+            <p>By default, time values are stored in UTC format.<p> 
+
+            <p>This method allows users to set a time zone value that is then used to compute 
+            intervals after rounding on the interval value.  The value is an offset from UTC.  
+            The tz offset value is simply added to the resulting bucket's date value.<p>
+            
+            <p>For example, to use EST you would set the value to <code>-5</code>.</p>
+
+            @member ejs.DateHistogramFacet
+            @param {Integer} tz An offset value from UTC.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      postZone: function (tz) {
+        if (tz == null) {
+          return facet[name].date_histogram.post_zone;
+        }
+      
+        facet[name].date_histogram.post_zone = tz;
+        return this;
+      },
+
+      /**
+            Set's a specific pre-rounding offset.  Format is 1d, 1h, etc.
+
+            @member ejs.DateHistogramFacet
+            @param {String} offset The offset as a string (1d, 1h, etc)
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      preOffset: function (offset) {
+        if (offset == null) {
+          return facet[name].date_histogram.pre_offset;
+        }
+      
+        facet[name].date_histogram.pre_offset = offset;
+        return this;
+      },
+      
+      /**
+            Set's a specific post-rounding offset.  Format is 1d, 1h, etc.
+
+            @member ejs.DateHistogramFacet
+            @param {String} offset The offset as a string (1d, 1h, etc)
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      postOffset: function (offset) {
+        if (offset == null) {
+          return facet[name].date_histogram.post_offset;
+        }
+      
+        facet[name].date_histogram.post_offset = offset;
+        return this;
+      },
+      
+      /**
+            <p>The date histogram works on numeric values (since time is stored 
+            in milliseconds since the epoch in UTC).<p> 
+
+            <p>But, sometimes, systems will store a different resolution (like seconds since UTC) 
+            in a numeric field. The factor parameter can be used to change the value in the field 
+            to milliseconds to actual do the relevant rounding, and then be applied again to get to 
+            the original unit.</p>
+
+            <p>For example, when storing in a numeric field seconds resolution, 
+            the factor can be set to 1000.<p>
+
+            @member ejs.DateHistogramFacet
+            @param {Integer} f The conversion factor.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      factor: function (f) {
+        if (f == null) {
+          return facet[name].date_histogram.factor;
+        }
+      
+        facet[name].date_histogram.factor = f;
+        return this;
+      },
+      
+      /**
+            Allows you modify the <code>value</code> field using a script. The modified value
+            is then used to compute the statistical data.
+
+            @member ejs.DateHistogramFacet
+            @param {String} scriptCode A valid script string to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueScript: function (scriptCode) {
+        if (scriptCode == null) {
+          return facet[name].date_histogram.value_script;
+        }
+      
+        facet[name].date_histogram.value_script = scriptCode;
+        return this;
+      },
+
+      /**
+            <p>Sets the type of ordering that will be performed on the date
+            buckets.  Valid values are:<p>
+            
+            <dl>
+                <dd><code>time</code> - the default, sort by the buckets start time in milliseconds.</dd>
+                <dd><code>count</code> - sort by the number of items in the bucket</dd>
+                <dd><code>total</code> - sort by the sum/total of the items in the bucket</dd>
+            <dl>
+            
+            @member ejs.DateHistogramFacet
+            @param {String} o The ordering method: time, count, or total.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      order: function (o) {
+        if (o == null) {
+          return facet[name].date_histogram.order;
+        }
+      
+        o = o.toLowerCase();
+        if (o === 'time' || o === 'count' || o === 'total') {
+          facet[name].date_histogram.order = o;
+        }
+        
+        return this;
+      },
+      
+      /**
+            The script language being used. Currently supported values are
+            <code>javascript</code>, <code>groovy</code>, and <code>mvel</code>.
+
+            @member ejs.DateHistogramFacet
+            @param {String} language The language of the script.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      lang: function (language) {
+        if (language == null) {
+          return facet[name].date_histogram.lang;
+        }
+      
+        facet[name].date_histogram.lang = language;
+        return this;
+      },
+
+      /**
+            Sets parameters that will be applied to the script.  Overwrites 
+            any existing params.
+
+            @member ejs.DateHistogramFacet
+            @param {Object} p An object where the keys are the parameter name and 
+              values are the parameter value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      params: function (p) {
+        if (p == null) {
+          return facet[name].date_histogram.params;
+        }
+    
+        facet[name].date_histogram.params = p;
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>The FilterFacet allows you to specify any valid <code>Filter</code> and
+    have the number of matching hits returned as the value.</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.FilterFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet that return a count of the hits matching the given filter.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.FilterFacet = function (name) {
+
+    var
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    return extend(_common, {
+
+      /**
+            <p>Sets the filter to be used for this facet.</p>
+
+            @member ejs.FilterFacet
+            @param {Object} oFilter A valid <code>Query</code> object.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      filter: function (oFilter) {
+        if (oFilter == null) {
+          return facet[name].filter;
+        }
+      
+        if (!isFilter(oFilter)) {
+          throw new TypeError('Argument must be a Filter');
+        }
+        
+        facet[name].filter = oFilter.toJSON();
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>The geoDistanceFacet facet provides information over a range of distances from a
+    provided point. This includes the number of hits that fall within each range,
+    along with aggregate information (like total).</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.GeoDistanceFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet which provides information over a range of distances from a provided point.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.GeoDistanceFacet = function (name) {
+
+    var
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON(),
+      point = ejs.GeoPoint([0, 0]),
+      field = 'location';
+
+    facet[name].geo_distance = {
+      location: point.toJSON(),
+      ranges: []
+    };
+
+    return extend(_common, {
+
+      /**
+            Sets the document field containing the geo-coordinate to be used 
+            to calculate the distance.  Defaults to "location".
+
+            @member ejs.GeoDistanceFacet
+            @param {String} fieldName The field name whose data will be used to construct the facet.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      field: function (fieldName) {
+        var oldValue = facet[name].geo_distance[field];
+        
+        if (fieldName == null) {
+          return field;
+        }
+
+        delete facet[name].geo_distance[field];
+        field = fieldName;
+        facet[name].geo_distance[fieldName] = oldValue;
+        
+        return this;
+      },
+
+      /**
+            Sets the point of origin from where distances will be measured.
+
+            @member ejs.GeoDistanceFacet
+            @param {GeoPoint} p A valid GeoPoint object
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      point: function (p) {
+        if (p == null) {
+          return point;
+        }
+      
+        if (!isGeoPoint(p)) {
+          throw new TypeError('Argument must be a GeoPoint');
+        }
+        
+        point = p;
+        facet[name].geo_distance[field] = p.toJSON();
+        return this;
+      },
+
+      /**
+            Adds a new bounded range.
+
+            @member ejs.GeoDistanceFacet
+            @param {Number} from The lower bound of the range
+            @param {Number} to The upper bound of the range
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      addRange: function (from, to) {
+        if (arguments.length === 0) {
+          return facet[name].geo_distance.ranges;
+        }
+      
+        facet[name].geo_distance.ranges.push({
+          from: from,
+          to: to
+        });
+        
+        return this;
+      },
+
+      /**
+            Adds a new unbounded lower limit.
+
+            @member ejs.GeoDistanceFacet
+            @param {Number} from The lower limit of the unbounded range
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      addUnboundedFrom: function (from) {
+        if (from == null) {
+          return facet[name].geo_distance.ranges;
+        }
+      
+        facet[name].geo_distance.ranges.push({
+          from: from
+        });
+        
+        return this;
+      },
+
+      /**
+            Adds a new unbounded upper limit.
+
+            @member ejs.GeoDistanceFacet
+            @param {Number} to The upper limit of the unbounded range
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      addUnboundedTo: function (to) {
+        if (to == null) {
+          return facet[name].geo_distance.ranges;
+        }
+      
+        facet[name].geo_distance.ranges.push({
+          to: to
+        });
+        
+        return this;
+      },
+
+      /**
+             Sets the distance unit.  Valid values are "mi" for miles or "km"
+             for kilometers. Defaults to "km".
+
+             @member ejs.GeoDistanceFacet
+             @param {Number} unit the unit of distance measure.
+             @returns {Object} returns <code>this</code> so that calls can be chained.
+             */
+      unit: function (unit) {
+        if (unit == null) {
+          return facet[name].geo_distance.unit;
+        }
+      
+        unit = unit.toLowerCase();
+        if (unit === 'mi' || unit === 'km') {
+          facet[name].geo_distance.unit = unit;
+        }
+        
+        return this;
+      },
+      
+      /**
+            How to compute the distance. Can either be arc (better precision) 
+            or plane (faster). Defaults to arc.
+
+            @member ejs.GeoDistanceFacet
+            @param {String} type The execution type as a string.  
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      distanceType: function (type) {
+        if (type == null) {
+          return facet[name].geo_distance.distance_type;
+        }
+
+        type = type.toLowerCase();
+        if (type === 'arc' || type === 'plane') {
+          facet[name].geo_distance.distance_type = type;
+        }
+        
+        return this;
+      },
+
+      /**
+            If the lat/long points should be normalized to lie within their
+            respective normalized ranges.
+            
+            Normalized ranges are:
+            lon = -180 (exclusive) to 180 (inclusive) range
+            lat = -90 to 90 (both inclusive) range
+
+            @member ejs.GeoDistanceFacet
+            @param {String} trueFalse True if the coordinates should be normalized. False otherwise.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      normalize: function (trueFalse) {
+        if (trueFalse == null) {
+          return facet[name].geo_distance.normalize;
+        }
+
+        facet[name].geo_distance.normalize = trueFalse;
+        return this;
+      },
+      
+      /**
+            Allows you to specify a different value field to aggrerate over.
+
+            @member ejs.GeoDistanceFacet
+            @param {String} fieldName The name of the field to be used.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].geo_distance.value_field;
+        }
+      
+        facet[name].geo_distance.value_field = fieldName;
+        return this;
+      },
+      
+      /**
+            Allows you modify the <code>value</code> field using a script. The modified value
+            is then used to compute the statistical data.
+
+            @member ejs.GeoDistanceFacet
+            @param {String} scriptCode A valid script string to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueScript: function (scriptCode) {
+        if (scriptCode == null) {
+          return facet[name].geo_distance.value_script;
+        }
+      
+        facet[name].geo_distance.value_script = scriptCode;
+        return this;
+      },
+      
+      /**
+            The script language being used. Currently supported values are
+            <code>javascript</code>, <code>groovy</code>, and <code>mvel</code>.
+
+            @member ejs.GeoDistanceFacet
+            @param {String} language The language of the script.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      lang: function (language) {
+        if (language == null) {
+          return facet[name].geo_distance.lang;
+        }
+      
+        facet[name].geo_distance.lang = language;
+        return this;
+      },
+      
+      /**
+            Sets parameters that will be applied to the script.  Overwrites 
+            any existing params.
+
+            @member ejs.GeoDistanceFacet
+            @param {Object} p An object where the keys are the parameter name and 
+              values are the parameter value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      params: function (p) {
+        if (p == null) {
+          return facet[name].geo_distance.params;
+        }
+    
+        facet[name].geo_distance.params = p;
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>The histogram facet works with numeric data by building a histogram across intervals
+       of the field values. Each value is <em>rounded</em> into an interval (or placed in a
+       bucket), and statistics are provided per interval/bucket (count and total).</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.HistogramFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet which returns the N most frequent terms within a collection
+       or set of collections.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.HistogramFacet = function (name) {
+
+    var 
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    facet[name].histogram = {};
+
+    return extend(_common, {
+
+      /**
+            Sets the field to be used to construct the this facet.
+
+            @member ejs.HistogramFacet
+            @param {String} fieldName The field name whose data will be used to construct the facet.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      field: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].histogram.field;
+        }
+      
+        facet[name].histogram.field = fieldName;
+        return this;
+      },
+
+      /**
+            Sets the bucket interval used to calculate the distribution.
+
+            @member ejs.HistogramFacet
+            @param {Number} numericInterval The bucket interval in which to group values.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      interval: function (numericInterval) {
+        if (numericInterval == null) {
+          return facet[name].histogram.interval;
+        }
+      
+        facet[name].histogram.interval = numericInterval;
+        return this;
+      },
+
+      /**
+            Sets the bucket interval used to calculate the distribution based
+            on a time value such as "1d", "1w", etc.
+
+            @member ejs.HistogramFacet
+            @param {Number} timeInterval The bucket interval in which to group values.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      timeInterval: function (timeInterval) {
+        if (timeInterval == null) {
+          return facet[name].histogram.time_interval;
+        }
+      
+        facet[name].histogram.time_interval = timeInterval;
+        return this;
+      },
+
+      /**
+            Sets the "from", "start", or lower bounds bucket.  For example if 
+            you have a value of 1023, an interval of 100, and a from value of 
+            1500, it will be placed into the 1500 bucket vs. the normal bucket 
+            of 1000.
+
+            @member ejs.HistogramFacet
+            @param {Number} from the lower bounds bucket value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      from: function (from) {
+        if (from == null) {
+          return facet[name].histogram.from;
+        }
+      
+        facet[name].histogram.from = from;
+        return this;
+      },
+
+      /**
+            Sets the "to", "end", or upper bounds bucket.  For example if 
+            you have a value of 1023, an interval of 100, and a to value of 
+            900, it will be placed into the 900 bucket vs. the normal bucket 
+            of 1000.
+
+            @member ejs.HistogramFacet
+            @param {Number} to the upper bounds bucket value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      to: function (to) {
+        if (to == null) {
+          return facet[name].histogram.to;
+        }
+      
+        facet[name].histogram.to = to;
+        return this;
+      },
+                  
+      /**
+            Allows you to specify a different value field to aggrerate over.
+
+            @member ejs.HistogramFacet
+            @param {String} fieldName The name of the field to be used.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].histogram.value_field;
+        }
+      
+        facet[name].histogram.value_field = fieldName;
+        return this;
+      },
+
+      /**
+            Allows you to specify a different key field to be used to group intervals.
+
+            @member ejs.HistogramFacet
+            @param {String} fieldName The name of the field to be used.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      keyField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].histogram.key_field;
+        }
+      
+        facet[name].histogram.key_field = fieldName;
+        return this;
+      },
+
+      /**
+            Allows you modify the <code>value</code> field using a script. The modified value
+            is then used to compute the statistical data.
+
+            @member ejs.HistogramFacet
+            @param {String} scriptCode A valid script string to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueScript: function (scriptCode) {
+        if (scriptCode == null) {
+          return facet[name].histogram.value_script;
+        }
+      
+        facet[name].histogram.value_script = scriptCode;
+        return this;
+      },
+
+      /**
+            Allows you modify the <code>key</code> field using a script. The modified value
+            is then used to generate the interval.
+
+            @member ejs.HistogramFacet
+            @param {String} scriptCode A valid script string to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      keyScript: function (scriptCode) {
+        if (scriptCode == null) {
+          return facet[name].histogram.key_script;
+        }
+      
+        facet[name].histogram.key_script = scriptCode;
+        return this;
+      },
+
+      /**
+            The script language being used. Currently supported values are
+            <code>javascript</code>, <code>groovy</code>, and <code>mvel</code>.
+
+            @member ejs.HistogramFacet
+            @param {String} language The language of the script.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      lang: function (language) {
+        if (language == null) {
+          return facet[name].histogram.lang;
+        }
+      
+        facet[name].histogram.lang = language;
+        return this;
+      },
+
+      /**
+            Sets parameters that will be applied to the script.  Overwrites 
+            any existing params.
+
+            @member ejs.HistogramFacet
+            @param {Object} p An object where the keys are the parameter name and 
+              values are the parameter value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      params: function (p) {
+        if (p == null) {
+          return facet[name].histogram.params;
+        }
+    
+        facet[name].histogram.params = p;
+        return this;
+      },
+      
+      /**
+            Sets the type of ordering that will be performed on the date
+            buckets.  Valid values are:
+            
+            key - the default, sort by the bucket's key value
+            count - sort by the number of items in the bucket
+            total - sort by the sum/total of the items in the bucket
+            
+            @member ejs.HistogramFacet
+            @param {String} o The ordering method: key, count, or total.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      order: function (o) {
+        if (o == null) {
+          return facet[name].histogram.order;
+        }
+      
+        o = o.toLowerCase();
+        if (o === 'key' || o === 'count' || o === 'total') {
+          facet[name].histogram.order = o;
+        }
+        
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>The QueryFacet facet allows you to specify any valid <code>Query</code> and
+    have the number of matching hits returned as the value.</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.QueryFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet that return a count of the hits matching the given query.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.QueryFacet = function (name) {
+
+    var 
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    return extend(_common, {
+
+      /**
+            <p>Sets the query to be used for this facet.</p>
+
+            @member ejs.QueryFacet
+            @param {Object} oQuery A valid <code>Query</code> object.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      query: function (oQuery) {
+        if (oQuery == null) {
+          return facet[name].query;
+        }
+      
+        if (!isQuery(oQuery)) {
+          throw new TypeError('Argument must be a Query');
+        }
+        
+        facet[name].query = oQuery.toJSON();
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>A RangeFacet allows you to specify a set of ranges and get both the number of docs (count) that
+       fall within each range, and aggregated data based on the field, or another specified field.</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.RangeFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet which provides information over a range of numeric intervals.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.RangeFacet = function (name) {
+
+    var 
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    facet[name].range = {
+      ranges: []
+    };
+
+    return extend(_common, {
+
+      /**
+            Sets the document field to be used for the facet.
+
+            @member ejs.RangeFacet
+            @param {String} fieldName The field name whose data will be used to compute the interval.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      field: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].range.field;
+        }
+      
+        facet[name].range.field = fieldName;
+        return this;
+      },
+
+      /**
+            Allows you to specify an alternate key field to be used to compute the interval.
+
+            @member ejs.RangeFacet
+            @param {String} fieldName The field name whose data will be used to compute the interval.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      keyField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].range.key_field;
+        }
+      
+        facet[name].range.key_field = fieldName;
+        return this;
+      },
+
+      /**
+            Allows you to specify an alternate value field to be used to compute statistical information.
+
+            @member ejs.RangeFacet
+            @param {String} fieldName The field name whose data will be used to compute statistics.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].range.value_field;
+        }
+      
+        facet[name].range.value_field = fieldName;
+        return this;
+      },
+
+      /**
+            Allows you modify the <code>value</code> field using a script. The modified value
+            is then used to compute the statistical data.
+
+            @member ejs.RangeFacet
+            @param {String} scriptCode A valid script string to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueScript: function (scriptCode) {
+        if (scriptCode == null) {
+          return facet[name].range.value_script;
+        }
+      
+        facet[name].range.value_script = scriptCode;
+        return this;
+      },
+
+      /**
+            Allows you modify the <code>key</code> field using a script. The modified value
+            is then used to generate the interval.
+
+            @member ejs.RangeFacet
+            @param {String} scriptCode A valid script string to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      keyScript: function (scriptCode) {
+        if (scriptCode == null) {
+          return facet[name].range.key_script;
+        }
+      
+        facet[name].range.key_script = scriptCode;
+        return this;
+      },
+
+      /**
+            The script language being used. Currently supported values are
+            <code>javascript</code>, <code>groovy</code>, and <code>mvel</code>.
+
+            @member ejs.RangeFacet
+            @param {String} language The language of the script.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      lang: function (language) {
+        if (language == null) {
+          return facet[name].range.lang;
+        }
+      
+        facet[name].range.lang = language;
+        return this;
+      },
+
+      /**
+            Sets parameters that will be applied to the script.  Overwrites 
+            any existing params.
+
+            @member ejs.RangeFacet
+            @param {Object} p An object where the keys are the parameter name and 
+              values are the parameter value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      params: function (p) {
+        if (p == null) {
+          return facet[name].range.params;
+        }
+    
+        facet[name].range.params = p;
+        return this;
+      },
+      
+      /**
+            Adds a new bounded range.
+
+            @member ejs.RangeFacet
+            @param {Number} from The lower bound of the range (can also be <code>Date</code>).
+            @param {Number} to The upper bound of the range (can also be <code>Date</code>).
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      addRange: function (from, to) {
+        if (arguments.length === 0) {
+          return facet[name].range.ranges;
+        }
+      
+        facet[name].range.ranges.push({
+          from: from,
+          to: to
+        });
+        
+        return this;
+      },
+
+      /**
+            Adds a new unbounded lower limit.
+
+            @member ejs.RangeFacet
+            @param {Number} from The lower limit of the unbounded range (can also be <code>Date</code>).
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      addUnboundedFrom: function (from) {
+        if (from == null) {
+          return facet[name].range.ranges;
+        }
+      
+        facet[name].range.ranges.push({
+          from: from
+        });
+        
+        return this;
+      },
+
+      /**
+            Adds a new unbounded upper limit.
+
+            @member ejs.RangeFacet
+            @param {Number} to The upper limit of the unbounded range (can also be <code>Date</code>).
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      addUnboundedTo: function (to) {
+        if (to == null) {
+          return facet[name].range.ranges;
+        }
+      
+        facet[name].range.ranges.push({
+          to: to
+        });
+        
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>A statistical facet allows you to compute statistical data over a numeric fields. Statistical data includes
+    the count, total, sum of squares, mean (average), minimum, maximum, variance, and standard deviation.</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.StatisticalFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet which returns statistical information about a numeric field</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.StatisticalFacet = function (name) {
+
+    var 
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    facet[name].statistical = {};
+
+    return extend(_common, {
+
+      /**
+            Sets the field to be used to construct the this facet.
+
+            @member ejs.StatisticalFacet
+            @param {String} fieldName The field name whose data will be used to construct the facet.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      field: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].statistical.field;
+        }
+      
+        facet[name].statistical.field = fieldName;
+        return this;
+      },
+
+      /**
+            Aggregate statistical info across a set of fields.
+
+            @member ejs.StatisticalFacet
+            @param {Array} aFieldName An array of field names.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      fields: function (fields) {
+        if (fields == null) {
+          return facet[name].statistical.fields;
+        }
+      
+        if (!isArray(fields)) {
+          throw new TypeError('Argument must be an array');
+        }
+        
+        facet[name].statistical.fields = fields;
+        return this;
+      },
+
+      /**
+            Define a script to evaluate of which the result will be used to generate
+            the statistical information.
+
+            @member ejs.StatisticalFacet
+            @param {String} code The script code to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      script: function (code) {
+        if (code == null) {
+          return facet[name].statistical.script;
+        }
+      
+        facet[name].statistical.script = code;
+        return this;
+      },
+
+      /**
+            The script language being used. Currently supported values are
+            <code>javascript</code>, <code>groovy</code>, and <code>mvel</code>.
+
+            @member ejs.StatisticalFacet
+            @param {String} language The language of the script.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      lang: function (language) {
+        if (language == null) {
+          return facet[name].statistical.lang;
+        }
+      
+        facet[name].statistical.lang = language;
+        return this;
+      },
+
+      /**
+            Allows you to set script parameters to be used during the execution of the script.
+
+            @member ejs.StatisticalFacet
+            @param {Object} oParams An object containing key/value pairs representing param name/value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      params: function (oParams) {
+        if (oParams == null) {
+          return facet[name].statistical.params;
+        }
+      
+        facet[name].statistical.params = oParams;
+        return this;
+      }
+      
+    });
+  };
+
+  /**
+    @class
+    <p>A termsStatsFacet allows you to compute statistics over an aggregate key (term). Essentially this
+    facet provides the functionality of what is often refered to as a <em>pivot table</em>.</p>
+
+    <p>Facets are similar to SQL <code>GROUP BY</code> statements but perform much
+       better. You can also construct several <em>"groups"</em> at once by simply
+       specifying multiple facets.</p>
+
+    <div class="alert-message block-message info">
+        <p>
+            <strong>Tip: </strong>
+            For more information on faceted navigation, see
+            <a href="http://en.wikipedia.org/wiki/Faceted_classification">this</a>
+            Wikipedia article on Faceted Classification.
+        </p>
+    </div>
+
+    @name ejs.TermStatsFacet
+    @ejs facet
+    @borrows ejs.FacetMixin.facetFilter as facetFilter
+    @borrows ejs.FacetMixin.global as global
+    @borrows ejs.FacetMixin.mode as mode
+    @borrows ejs.FacetMixin.cacheFilter as cacheFilter
+    @borrows ejs.FacetMixin.scope as scope
+    @borrows ejs.FacetMixin.nested as nested
+    @borrows ejs.FacetMixin._type as _type
+    @borrows ejs.FacetMixin.toJSON as toJSON
+
+    @desc
+    <p>A facet which computes statistical data based on an aggregate key.</p>
+
+    @param {String} name The name which be used to refer to this facet. For instance,
+        the facet itself might utilize a field named <code>doc_authors</code>. Setting
+        <code>name</code> to <code>Authors</code> would allow you to refer to the
+        facet by that name, possibly simplifying some of the display logic.
+
+    */
+  ejs.TermStatsFacet = function (name) {
+
+    var 
+      _common = ejs.FacetMixin(name),
+      facet = _common.toJSON();
+
+    facet[name].terms_stats = {};
+
+    return extend(_common, {
+
+      /**
+            Sets the field for which statistical information will be generated.
+
+            @member ejs.TermStatsFacet
+            @param {String} fieldName The field name whose data will be used to construct the facet.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].terms_stats.value_field;
+        }
+      
+        facet[name].terms_stats.value_field = fieldName;
+        return this;
+      },
+
+      /**
+            Sets the field which will be used to pivot on (group-by).
+
+            @member ejs.TermStatsFacet
+            @param {String} fieldName The field name whose data will be used to construct the facet.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      keyField: function (fieldName) {
+        if (fieldName == null) {
+          return facet[name].terms_stats.key_field;
+        }
+      
+        facet[name].terms_stats.key_field = fieldName;
+        return this;
+      },
+
+      /**
+            Sets a script that will provide the terms for a given document.
+
+            @member ejs.TermStatsFacet
+            @param {String} script The script code.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      scriptField: function (script) {
+        if (script == null) {
+          return facet[name].terms_stats.script_field;
+        }
+      
+        facet[name].terms_stats.script_field = script;
+        return this;
+      },
+      
+      /**
+            Define a script to evaluate of which the result will be used to generate
+            the statistical information.
+
+            @member ejs.TermStatsFacet
+            @param {String} code The script code to execute.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      valueScript: function (code) {
+        if (code == null) {
+          return facet[name].terms_stats.value_script;
+        }
+      
+        facet[name].terms_stats.value_script = code;
+        return this;
+      },
+
+      /**
+            <p>Allows you to return all terms, even if the frequency count is 0. This should not be
+               used on fields that contain a large number of unique terms because it could cause
+               <em>out-of-memory</em> errors.</p>
+
+            @member ejs.TermStatsFacet
+            @param {String} trueFalse <code>true</code> or <code>false</code>
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      allTerms: function (trueFalse) {
+        if (trueFalse == null) {
+          return facet[name].terms_stats.all_terms;
+        }
+      
+        facet[name].terms_stats.all_terms = trueFalse;
+        return this;
+      },
+      
+      /**
+            The script language being used. Currently supported values are
+            <code>javascript</code>, <code>groovy</code>, and <code>mvel</code>.
+
+            @member ejs.TermStatsFacet
+            @param {String} language The language of the script.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      lang: function (language) {
+        if (language == null) {
+          return facet[name].terms_stats.lang;
+        }
+      
+        facet[name].terms_stats.lang = language;
+        return this;
+      },
+
+      /**
+            Allows you to set script parameters to be used during the execution of the script.
+
+            @member ejs.TermStatsFacet
+            @param {Object} oParams An object containing key/value pairs representing param name/value.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      params: function (oParams) {
+        if (oParams == null) {
+          return facet[name].terms_stats.params;
+        }
+      
+        facet[name].terms_stats.params = oParams;
+        return this;
+      },
+
+      /**
+            Sets the number of facet entries that will be returned for this facet. For instance, you
+            might ask for only the top 5 aggregate keys although there might be hundreds of
+            unique keys. <strong>Higher settings could cause memory strain</strong>.
+
+            @member ejs.TermStatsFacet
+            @param {Integer} facetSize The numer of facet entries to be returned.
+            @returns {Object} returns <code>this</code> so that calls can be chained.
+            */
+      size: function (facetSize) {
+        if (facetSize == null) {
+          return facet[name].terms_stats.size;
+        }
+      
+        facet[name].terms_stats.size = facetSize;
+        return this;
+      },
+
+      /**
+            Sets the type of ordering that will be performed on the date
+            buckets.  Valid values are:
+            
+            count - default, sort by the number of items in the bucket
+            term - sort by term value.
+    

<TRUNCATED>