PageSourceSearch

https://3seaseurope.com/wp-content/plugins/wp-online-users-stats/public/js/jquery.dataTables.js?ver=1790649471

js 3seaseurope.com collected 2026-10-02 04:52:20 UTC 448,547 bytes, 15,307 lines download raw bytes

1/*! DataTables 1.10.13
2 * ©2008-2016 SpryMedia Ltd - datatables.net/license
3 */
4
5/**
6 * @summary     DataTables
7 * @description Paginate, search and order HTML tables
8 * @version     1.10.13
9 * @file        jquery.dataTables.js
10 * @author      SpryMedia Ltd
11 * @contact     www.datatables.net
12 * @copyright   Copyright 2008-2016 SpryMedia Ltd.
13 *
14 * This source file is free software, available under the following license:
15 *   MIT license - http://datatables.net/license
16 *
17 * This source file is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20 *
21 * For details please refer to: http://www.datatables.net
22 */
23
24/*jslint evil: true, undef: true, browser: true */
25/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
26
27(function( factory ) {
28	"use strict";
29
30	if ( typeof define === 'function' && define.amd ) {
31		// AMD
32		define( ['jquery'], function ( $ ) {
33			return factory( $, window, document );
34		} );
35	}
36	else if ( typeof exports === 'object' ) {
37		// CommonJS
38		module.exports = function (root, $) {
39			if ( ! root ) {
40				// CommonJS environments without a window global must pass a
41				// root. This will give an error otherwise
42				root = window;
43			}
44
45			if ( ! $ ) {
46				$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
47					require('jquery') :
48					require('jquery')( root );
49			}
50
51			return factory( $, root, root.document );
52		};
53	}
54	else {
55		// Browser
56		factory( jQuery, window, document );
57	}
58}
59(function( $, window, document, undefined ) {
60	"use strict";
61
62	/**
63	 * DataTables is a plug-in for the jQuery Javascript library. It is a highly
64	 * flexible tool, based upon the foundations of progressive enhancement,
65	 * which will add advanced interaction controls to any HTML table. For a
66	 * full list of features please refer to
67	 * [DataTables.net](href="http://datatables.net).
68	 *
69	 * Note that the `DataTable` object is not a global variable but is aliased
70	 * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
71	 * be  accessed.
72	 *
73	 *  @class
74	 *  @param {object} [init={}] Configuration object for DataTables. Options
75	 *    are defined by {@link DataTable.defaults}
76	 *  @requires jQuery 1.7+
77	 *
78	 *  @example
79	 *    // Basic initialisation
80	 *    $(document).ready( function {
81	 *      $('#example').dataTable();
82	 *    } );
83	 *
84	 *  @example
85	 *    // Initialisation with configuration options - in this case, disable
86	 *    // pagination and sorting.
87	 *    $(document).ready( function {
88	 *      $('#example').dataTable( {
89	 *        "paginate": false,
90	 *        "sort": false
91	 *      } );
92	 *    } );
93	 */
94	var DataTable = function ( options )
95	{
vendor: 6,636 bytes, lines 95-254
95
96		/**
97		 * Perform a jQuery selector action on the table's TR elements (from the tbody) and
98		 * return the resulting jQuery object.
99		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
100		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
101		 *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
102		 *    criterion ("applied") or all TR elements (i.e. no filter).
103		 *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
104		 *    Can be either 'current', whereby the current sorting of the table is used, or
105		 *    'original' whereby the original order the data was read into the table is used.
106		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
107		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
108		 *    'current' and filter is 'applied', regardless of what they might be given as.
109		 *  @returns {object} jQuery object, filtered by the given selector.
110		 *  @dtopt API
111		 *  @deprecated Since v1.10
112		 *
113		 *  @example
114		 *    $(document).ready(function() {
115		 *      var oTable = $('#example').dataTable();
116		 *
117		 *      // Highlight every second row
118		 *      oTable.$('tr:odd').css('backgroundColor', 'blue');
119		 *    } );
120		 *
121		 *  @example
122		 *    $(document).ready(function() {
123		 *      var oTable = $('#example').dataTable();
124		 *
125		 *      // Filter to rows with 'Webkit' in them, add a background colour and then
126		 *      // remove the filter, thus highlighting the 'Webkit' rows only.
127		 *      oTable.fnFilter('Webkit');
128		 *      oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
129		 *      oTable.fnFilter('');
130		 *    } );
131		 */
132		this.$ = function ( sSelector, oOpts )
133		{
134			return this.api(true).$( sSelector, oOpts );
135		};
136		
137		
138		/**
139		 * Almost identical to $ in operation, but in this case returns the data for the matched
140		 * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
141		 * rather than any descendants, so the data can be obtained for the row/cell. If matching
142		 * rows are found, the data returned is the original data array/object that was used to
143		 * create the row (or a generated array if from a DOM source).
144		 *
145		 * This method is often useful in-combination with $ where both functions are given the
146		 * same parameters and the array indexes will match identically.
147		 *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
148		 *  @param {object} [oOpts] Optional parameters for modifying the rows to be included
149		 *  @param {string} [oOpts.filter=none] Select elements that meet the current filter
150		 *    criterion ("applied") or all elements (i.e. no filter).
151		 *  @param {string} [oOpts.order=current] Order of the data in the processed array.
152		 *    Can be either 'current', whereby the current sorting of the table is used, or
153		 *    'original' whereby the original order the data was read into the table is used.
154		 *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
155		 *    ("current") or not ("all"). If 'current' is given, then order is assumed to be
156		 *    'current' and filter is 'applied', regardless of what they might be given as.
157		 *  @returns {array} Data for the matched elements. If any elements, as a result of the
158		 *    selector, were not TR, TD or TH elements in the DataTable, they will have a null
159		 *    entry in the array.
160		 *  @dtopt API
161		 *  @deprecated Since v1.10
162		 *
163		 *  @example
164		 *    $(document).ready(function() {
165		 *      var oTable = $('#example').dataTable();
166		 *
167		 *      // Get the data from the first row in the table
168		 *      var data = oTable._('tr:first');
169		 *
170		 *      // Do something useful with the data
171		 *      alert( "First cell is: "+data[0] );
172		 *    } );
173		 *
174		 *  @example
175		 *    $(document).ready(function() {
176		 *      var oTable = $('#example').dataTable();
177		 *
178		 *      // Filter to 'Webkit' and get all data for
179		 *      oTable.fnFilter('Webkit');
180		 *      var data = oTable._('tr', {"search": "applied"});
181		 *
182		 *      // Do something with the data
183		 *      alert( data.length+" rows matched the search" );
184		 *    } );
185		 */
186		this._ = function ( sSelector, oOpts )
187		{
188			return this.api(true).rows( sSelector, oOpts ).data();
189		};
190		
191		
192		/**
193		 * Create a DataTables Api instance, with the currently selected tables for
194		 * the Api's context.
195		 * @param {boolean} [traditional=false] Set the API instance's context to be
196		 *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was
197		 *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),
198		 *   or if all tables captured in the jQuery object should be used.
199		 * @return {DataTables.Api}
200		 */
201		this.api = function ( traditional )
202		{
203			return traditional ?
204				new _Api(
205					_fnSettingsFromNode( this[ _ext.iApiIndex ] )
206				) :
207				new _Api( this );
208		};
209		
210		
211		/**
212		 * Add a single new row or multiple rows of data to the table. Please note
213		 * that this is suitable for client-side processing only - if you are using
214		 * server-side processing (i.e. "bServerSide": true), then to add data, you
215		 * must add it to the data source, i.e. the server-side, through an Ajax call.
216		 *  @param {array|object} data The data to be added to the table. This can be:
217		 *    <ul>
218		 *      <li>1D array of data - add a single row with the data provided</li>
219		 *      <li>2D array of arrays - add multiple rows in a single call</li>
220		 *      <li>object - data object when using <i>mData</i></li>
221		 *      <li>array of objects - multiple data objects when using <i>mData</i></li>
222		 *    </ul>
223		 *  @param {bool} [redraw=true] redraw the table or not
224		 *  @returns {array} An array of integers, representing the list of indexes in
225		 *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
226		 *    the table.
227		 *  @dtopt API
228		 *  @deprecated Since v1.10
229		 *
230		 *  @example
231		 *    // Global var for counter
232		 *    var giCount = 2;
233		 *
234		 *    $(document).ready(function() {
235		 *      $('#example').dataTable();
236		 *    } );
237		 *
238		 *    function fnClickAddRow() {
239		 *      $('#example').dataTable().fnAddData( [
240		 *        giCount+".1",
241		 *        giCount+".2",
242		 *        giCount+".3",
243		 *        giCount+".4" ]
244		 *      );
245		 *
246		 *      giCount++;
247		 *    }
248		 */
249		this.fnAddData = function( data, redraw )
250		{
251			var api = this.api( true );
252		
253			/* Check if we want to add multiple rows or not */
254			var rows = 
254$.isArray(data) && ( $
vendor: 18,409 bytes, lines 254-850
254.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
255				api.rows.add( data ) :
256				api.row.add( data );
257		
258			if ( redraw === undefined || redraw ) {
259				api.draw();
260			}
261		
262			return rows.flatten().toArray();
263		};
264		
265		
266		/**
267		 * This function will make DataTables recalculate the column sizes, based on the data
268		 * contained in the table and the sizes applied to the columns (in the DOM, CSS or
269		 * through the sWidth parameter). This can be useful when the width of the table's
270		 * parent element changes (for example a window resize).
271		 *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
272		 *  @dtopt API
273		 *  @deprecated Since v1.10
274		 *
275		 *  @example
276		 *    $(document).ready(function() {
277		 *      var oTable = $('#example').dataTable( {
278		 *        "sScrollY": "200px",
279		 *        "bPaginate": false
280		 *      } );
281		 *
282		 *      $(window).on('resize', function () {
283		 *        oTable.fnAdjustColumnSizing();
284		 *      } );
285		 *    } );
286		 */
287		this.fnAdjustColumnSizing = function ( bRedraw )
288		{
289			var api = this.api( true ).columns.adjust();
290			var settings = api.settings()[0];
291			var scroll = settings.oScroll;
292		
293			if ( bRedraw === undefined || bRedraw ) {
294				api.draw( false );
295			}
296			else if ( scroll.sX !== "" || scroll.sY !== "" ) {
297				/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
298				_fnScrollDraw( settings );
299			}
300		};
301		
302		
303		/**
304		 * Quickly and simply clear a table
305		 *  @param {bool} [bRedraw=true] redraw the table or not
306		 *  @dtopt API
307		 *  @deprecated Since v1.10
308		 *
309		 *  @example
310		 *    $(document).ready(function() {
311		 *      var oTable = $('#example').dataTable();
312		 *
313		 *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
314		 *      oTable.fnClearTable();
315		 *    } );
316		 */
317		this.fnClearTable = function( bRedraw )
318		{
319			var api = this.api( true ).clear();
320		
321			if ( bRedraw === undefined || bRedraw ) {
322				api.draw();
323			}
324		};
325		
326		
327		/**
328		 * The exact opposite of 'opening' a row, this function will close any rows which
329		 * are currently 'open'.
330		 *  @param {node} nTr the table row to 'close'
331		 *  @returns {int} 0 on success, or 1 if failed (can't find the row)
332		 *  @dtopt API
333		 *  @deprecated Since v1.10
334		 *
335		 *  @example
336		 *    $(document).ready(function() {
337		 *      var oTable;
338		 *
339		 *      // 'open' an information row when a row is clicked on
340		 *      $('#example tbody tr').click( function () {
341		 *        if ( oTable.fnIsOpen(this) ) {
342		 *          oTable.fnClose( this );
343		 *        } else {
344		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
345		 *        }
346		 *      } );
347		 *
348		 *      oTable = $('#example').dataTable();
349		 *    } );
350		 */
351		this.fnClose = function( nTr )
352		{
353			this.api( true ).row( nTr ).child.hide();
354		};
355		
356		
357		/**
358		 * Remove a row for the table
359		 *  @param {mixed} target The index of the row from aoData to be deleted, or
360		 *    the TR element you want to delete
361		 *  @param {function|null} [callBack] Callback function
362		 *  @param {bool} [redraw=true] Redraw the table or not
363		 *  @returns {array} The row that was deleted
364		 *  @dtopt API
365		 *  @deprecated Since v1.10
366		 *
367		 *  @example
368		 *    $(document).ready(function() {
369		 *      var oTable = $('#example').dataTable();
370		 *
371		 *      // Immediately remove the first row
372		 *      oTable.fnDeleteRow( 0 );
373		 *    } );
374		 */
375		this.fnDeleteRow = function( target, callback, redraw )
376		{
377			var api = this.api( true );
378			var rows = api.rows( target );
379			var settings = rows.settings()[0];
380			var data = settings.aoData[ rows[0][0] ];
381		
382			rows.remove();
383		
384			if ( callback ) {
385				callback.call( this, settings, data );
386			}
387		
388			if ( redraw === undefined || redraw ) {
389				api.draw();
390			}
391		
392			return data;
393		};
394		
395		
396		/**
397		 * Restore the table to it's original state in the DOM by removing all of DataTables
398		 * enhancements, alterations to the DOM structure of the table and event listeners.
399		 *  @param {boolean} [remove=false] Completely remove the table from the DOM
400		 *  @dtopt API
401		 *  @deprecated Since v1.10
402		 *
403		 *  @example
404		 *    $(document).ready(function() {
405		 *      // This example is fairly pointless in reality, but shows how fnDestroy can be used
406		 *      var oTable = $('#example').dataTable();
407		 *      oTable.fnDestroy();
408		 *    } );
409		 */
410		this.fnDestroy = function ( remove )
411		{
412			this.api( true ).destroy( remove );
413		};
414		
415		
416		/**
417		 * Redraw the table
418		 *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
419		 *  @dtopt API
420		 *  @deprecated Since v1.10
421		 *
422		 *  @example
423		 *    $(document).ready(function() {
424		 *      var oTable = $('#example').dataTable();
425		 *
426		 *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
427		 *      oTable.fnDraw();
428		 *    } );
429		 */
430		this.fnDraw = function( complete )
431		{
432			// Note that this isn't an exact match to the old call to _fnDraw - it takes
433			// into account the new data, but can hold position.
434			this.api( true ).draw( complete );
435		};
436		
437		
438		/**
439		 * Filter the input based on data
440		 *  @param {string} sInput String to filter the table on
441		 *  @param {int|null} [iColumn] Column to limit filtering to
442		 *  @param {bool} [bRegex=false] Treat as regular expression or not
443		 *  @param {bool} [bSmart=true] Perform smart filtering or not
444		 *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
445		 *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
446		 *  @dtopt API
447		 *  @deprecated Since v1.10
448		 *
449		 *  @example
450		 *    $(document).ready(function() {
451		 *      var oTable = $('#example').dataTable();
452		 *
453		 *      // Sometime later - filter...
454		 *      oTable.fnFilter( 'test string' );
455		 *    } );
456		 */
457		this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
458		{
459			var api = this.api( true );
460		
461			if ( iColumn === null || iColumn === undefined ) {
462				api.search( sInput, bRegex, bSmart, bCaseInsensitive );
463			}
464			else {
465				api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
466			}
467		
468			api.draw();
469		};
470		
471		
472		/**
473		 * Get the data for the whole table, an individual row or an individual cell based on the
474		 * provided parameters.
475		 *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
476		 *    a TR node then the data source for the whole row will be returned. If given as a
477		 *    TD/TH cell node then iCol will be automatically calculated and the data for the
478		 *    cell returned. If given as an integer, then this is treated as the aoData internal
479		 *    data index for the row (see fnGetPosition) and the data for that row used.
480		 *  @param {int} [col] Optional column index that you want the data of.
481		 *  @returns {array|object|string} If mRow is undefined, then the data for all rows is
482		 *    returned. If mRow is defined, just data for that row, and is iCol is
483		 *    defined, only data for the designated cell is returned.
484		 *  @dtopt API
485		 *  @deprecated Since v1.10
486		 *
487		 *  @example
488		 *    // Row data
489		 *    $(document).ready(function() {
490		 *      oTable = $('#example').dataTable();
491		 *
492		 *      oTable.$('tr').click( function () {
493		 *        var data = oTable.fnGetData( this );
494		 *        // ... do something with the array / object of data for the row
495		 *      } );
496		 *    } );
497		 *
498		 *  @example
499		 *    // Individual cell data
500		 *    $(document).ready(function() {
501		 *      oTable = $('#example').dataTable();
502		 *
503		 *      oTable.$('td').click( function () {
504		 *        var sData = oTable.fnGetData( this );
505		 *        alert( 'The cell clicked on had the value of '+sData );
506		 *      } );
507		 *    } );
508		 */
509		this.fnGetData = function( src, col )
510		{
511			var api = this.api( true );
512		
513			if ( src !== undefined ) {
514				var type = src.nodeName ? src.nodeName.toLowerCase() : '';
515		
516				return col !== undefined || type == 'td' || type == 'th' ?
517					api.cell( src, col ).data() :
518					api.row( src ).data() || null;
519			}
520		
521			return api.data().toArray();
522		};
523		
524		
525		/**
526		 * Get an array of the TR nodes that are used in the table's body. Note that you will
527		 * typically want to use the '$' API method in preference to this as it is more
528		 * flexible.
529		 *  @param {int} [iRow] Optional row index for the TR element you want
530		 *  @returns {array|node} If iRow is undefined, returns an array of all TR elements
531		 *    in the table's body, or iRow is defined, just the TR element requested.
532		 *  @dtopt API
533		 *  @deprecated Since v1.10
534		 *
535		 *  @example
536		 *    $(document).ready(function() {
537		 *      var oTable = $('#example').dataTable();
538		 *
539		 *      // Get the nodes from the table
540		 *      var nNodes = oTable.fnGetNodes( );
541		 *    } );
542		 */
543		this.fnGetNodes = function( iRow )
544		{
545			var api = this.api( true );
546		
547			return iRow !== undefined ?
548				api.row( iRow ).node() :
549				api.rows().nodes().flatten().toArray();
550		};
551		
552		
553		/**
554		 * Get the array indexes of a particular cell from it's DOM element
555		 * and column index including hidden columns
556		 *  @param {node} node this can either be a TR, TD or TH in the table's body
557		 *  @returns {int} If nNode is given as a TR, then a single index is returned, or
558		 *    if given as a cell, an array of [row index, column index (visible),
559		 *    column index (all)] is given.
560		 *  @dtopt API
561		 *  @deprecated Since v1.10
562		 *
563		 *  @example
564		 *    $(document).ready(function() {
565		 *      $('#example tbody td').click( function () {
566		 *        // Get the position of the current data from the node
567		 *        var aPos = oTable.fnGetPosition( this );
568		 *
569		 *        // Get the data array for this row
570		 *        var aData = oTable.fnGetData( aPos[0] );
571		 *
572		 *        // Update the data array and return the value
573		 *        aData[ aPos[1] ] = 'clicked';
574		 *        this.innerHTML = 'clicked';
575		 *      } );
576		 *
577		 *      // Init DataTables
578		 *      oTable = $('#example').dataTable();
579		 *    } );
580		 */
581		this.fnGetPosition = function( node )
582		{
583			var api = this.api( true );
584			var nodeName = node.nodeName.toUpperCase();
585		
586			if ( nodeName == 'TR' ) {
587				return api.row( node ).index();
588			}
589			else if ( nodeName == 'TD' || nodeName == 'TH' ) {
590				var cell = api.cell( node ).index();
591		
592				return [
593					cell.row,
594					cell.columnVisible,
595					cell.column
596				];
597			}
598			return null;
599		};
600		
601		
602		/**
603		 * Check to see if a row is 'open' or not.
604		 *  @param {node} nTr the table row to check
605		 *  @returns {boolean} true if the row is currently open, false otherwise
606		 *  @dtopt API
607		 *  @deprecated Since v1.10
608		 *
609		 *  @example
610		 *    $(document).ready(function() {
611		 *      var oTable;
612		 *
613		 *      // 'open' an information row when a row is clicked on
614		 *      $('#example tbody tr').click( function () {
615		 *        if ( oTable.fnIsOpen(this) ) {
616		 *          oTable.fnClose( this );
617		 *        } else {
618		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
619		 *        }
620		 *      } );
621		 *
622		 *      oTable = $('#example').dataTable();
623		 *    } );
624		 */
625		this.fnIsOpen = function( nTr )
626		{
627			return this.api( true ).row( nTr ).child.isShown();
628		};
629		
630		
631		/**
632		 * This function will place a new row directly after a row which is currently
633		 * on display on the page, with the HTML contents that is passed into the
634		 * function. This can be used, for example, to ask for confirmation that a
635		 * particular record should be deleted.
636		 *  @param {node} nTr The table row to 'open'
637		 *  @param {string|node|jQuery} mHtml The HTML to put into the row
638		 *  @param {string} sClass Class to give the new TD cell
639		 *  @returns {node} The row opened. Note that if the table row passed in as the
640		 *    first parameter, is not found in the table, this method will silently
641		 *    return.
642		 *  @dtopt API
643		 *  @deprecated Since v1.10
644		 *
645		 *  @example
646		 *    $(document).ready(function() {
647		 *      var oTable;
648		 *
649		 *      // 'open' an information row when a row is clicked on
650		 *      $('#example tbody tr').click( function () {
651		 *        if ( oTable.fnIsOpen(this) ) {
652		 *          oTable.fnClose( this );
653		 *        } else {
654		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
655		 *        }
656		 *      } );
657		 *
658		 *      oTable = $('#example').dataTable();
659		 *    } );
660		 */
661		this.fnOpen = function( nTr, mHtml, sClass )
662		{
663			return this.api( true )
664				.row( nTr )
665				.child( mHtml, sClass )
666				.show()
667				.child()[0];
668		};
669		
670		
671		/**
672		 * Change the pagination - provides the internal logic for pagination in a simple API
673		 * function. With this function you can have a DataTables table go to the next,
674		 * previous, first or last pages.
675		 *  @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
676		 *    or page number to jump to (integer), note that page 0 is the first page.
677		 *  @param {bool} [bRedraw=true] Redraw the table or not
678		 *  @dtopt API
679		 *  @deprecated Since v1.10
680		 *
681		 *  @example
682		 *    $(document).ready(function() {
683		 *      var oTable = $('#example').dataTable();
684		 *      oTable.fnPageChange( 'next' );
685		 *    } );
686		 */
687		this.fnPageChange = function ( mAction, bRedraw )
688		{
689			var api = this.api( true ).page( mAction );
690		
691			if ( bRedraw === undefined || bRedraw ) {
692				api.draw(false);
693			}
694		};
695		
696		
697		/**
698		 * Show a particular column
699		 *  @param {int} iCol The column whose display should be changed
700		 *  @param {bool} bShow Show (true) or hide (false) the column
701		 *  @param {bool} [bRedraw=true] Redraw the table or not
702		 *  @dtopt API
703		 *  @deprecated Since v1.10
704		 *
705		 *  @example
706		 *    $(document).ready(function() {
707		 *      var oTable = $('#example').dataTable();
708		 *
709		 *      // Hide the second column after initialisation
710		 *      oTable.fnSetColumnVis( 1, false );
711		 *    } );
712		 */
713		this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
714		{
715			var api = this.api( true ).column( iCol ).visible( bShow );
716		
717			if ( bRedraw === undefined || bRedraw ) {
718				api.columns.adjust().draw();
719			}
720		};
721		
722		
723		/**
724		 * Get the settings for a particular table for external manipulation
725		 *  @returns {object} DataTables settings object. See
726		 *    {@link DataTable.models.oSettings}
727		 *  @dtopt API
728		 *  @deprecated Since v1.10
729		 *
730		 *  @example
731		 *    $(document).ready(function() {
732		 *      var oTable = $('#example').dataTable();
733		 *      var oSettings = oTable.fnSettings();
734		 *
735		 *      // Show an example parameter from the settings
736		 *      alert( oSettings._iDisplayStart );
737		 *    } );
738		 */
739		this.fnSettings = function()
740		{
741			return _fnSettingsFromNode( this[_ext.iApiIndex] );
742		};
743		
744		
745		/**
746		 * Sort the table by a particular column
747		 *  @param {int} iCol the data index to sort on. Note that this will not match the
748		 *    'display index' if you have hidden data entries
749		 *  @dtopt API
750		 *  @deprecated Since v1.10
751		 *
752		 *  @example
753		 *    $(document).ready(function() {
754		 *      var oTable = $('#example').dataTable();
755		 *
756		 *      // Sort immediately with columns 0 and 1
757		 *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
758		 *    } );
759		 */
760		this.fnSort = function( aaSort )
761		{
762			this.api( true ).order( aaSort ).draw();
763		};
764		
765		
766		/**
767		 * Attach a sort listener to an element for a given column
768		 *  @param {node} nNode the element to attach the sort listener to
769		 *  @param {int} iColumn the column that a click on this node will sort on
770		 *  @param {function} [fnCallback] callback function when sort is run
771		 *  @dtopt API
772		 *  @deprecated Since v1.10
773		 *
774		 *  @example
775		 *    $(document).ready(function() {
776		 *      var oTable = $('#example').dataTable();
777		 *
778		 *      // Sort on column 1, when 'sorter' is clicked on
779		 *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
780		 *    } );
781		 */
782		this.fnSortListener = function( nNode, iColumn, fnCallback )
783		{
784			this.api( true ).order.listener( nNode, iColumn, fnCallback );
785		};
786		
787		
788		/**
789		 * Update a table cell or row - this method will accept either a single value to
790		 * update the cell with, an array of values with one element for each column or
791		 * an object in the same format as the original data source. The function is
792		 * self-referencing in order to make the multi column updates easier.
793		 *  @param {object|array|string} mData Data to update the cell/row with
794		 *  @param {node|int} mRow TR element you want to update or the aoData index
795		 *  @param {int} [iColumn] The column to update, give as null or undefined to
796		 *    update a whole row.
797		 *  @param {bool} [bRedraw=true] Redraw the table or not
798		 *  @param {bool} [bAction=true] Perform pre-draw actions or not
799		 *  @returns {int} 0 on success, 1 on error
800		 *  @dtopt API
801		 *  @deprecated Since v1.10
802		 *
803		 *  @example
804		 *    $(document).ready(function() {
805		 *      var oTable = $('#example').dataTable();
806		 *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
807		 *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
808		 *    } );
809		 */
810		this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
811		{
812			var api = this.api( true );
813		
814			if ( iColumn === undefined || iColumn === null ) {
815				api.row( mRow ).data( mData );
816			}
817			else {
818				api.cell( mRow, iColumn ).data( mData );
819			}
820		
821			if ( bAction === undefined || bAction ) {
822				api.columns.adjust();
823			}
824		
825			if ( bRedraw === undefined || bRedraw ) {
826				api.draw();
827			}
828			return 0;
829		};
830		
831		
832		/**
833		 * Provide a common method for plug-ins to check the version of DataTables being used, in order
834		 * to ensure compatibility.
835		 *  @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
836		 *    formats "X" and "X.Y" are also acceptable.
837		 *  @returns {boolean} true if this version of DataTables is greater or equal to the required
838		 *    version, or false if this version of DataTales is not suitable
839		 *  @method
840		 *  @dtopt API
841		 *  @deprecated Since v1.10
842		 *
843		 *  @example
844		 *    $(document).ready(function() {
845		 *      var oTable = $('#example').dataTable();
846		 *      alert( oTable.fnVersionCheck( '1.9.0' ) );
847		 *    } );
848		 */
849		this.fnVersionCheck = _ext.fnVersionCheck;
850		
vendor: 57,432 bytes, lines 851-2849
851
852		var _that = this;
853		var emptyInit = options === undefined;
854		var len = this.length;
855
856		if ( emptyInit ) {
857			options = {};
858		}
859
860		this.oApi = this.internal = _ext.internal;
861
862		// Extend with old style plug-in API methods
863		for ( var fn in DataTable.ext.internal ) {
864			if ( fn ) {
865				this[fn] = _fnExternApiFunc(fn);
866			}
867		}
868
869		this.each(function() {
870			// For each initialisation we want to give it a clean initialisation
871			// object that can be bashed around
872			var o = {};
873			var oInit = len > 1 ? // optimisation for single table case
874				_fnExtend( o, options, true ) :
875				options;
876
877			/*global oInit,_that,emptyInit*/
878			var i=0, iLen, j, jLen, k, kLen;
879			var sId = this.getAttribute( 'id' );
880			var bInitHandedOff = false;
881			var defaults = DataTable.defaults;
882			var $this = $(this);
883			
884			
885			/* Sanity check */
886			if ( this.nodeName.toLowerCase() != 'table' )
887			{
888				_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
889				return;
890			}
891			
892			/* Backwards compatibility for the defaults */
893			_fnCompatOpts( defaults );
894			_fnCompatCols( defaults.column );
895			
896			/* Convert the camel-case defaults to Hungarian */
897			_fnCamelToHungarian( defaults, defaults, true );
898			_fnCamelToHungarian( defaults.column, defaults.column, true );
899			
900			/* Setting up the initialisation object */
901			_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
902			
903			
904			
905			/* Check to see if we are re-initialising a table */
906			var allSettings = DataTable.settings;
907			for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
908			{
909				var s = allSettings[i];
910			
911				/* Base check on table node */
912				if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
913				{
914					var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
915					var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
916			
917					if ( emptyInit || bRetrieve )
918					{
919						return s.oInstance;
920					}
921					else if ( bDestroy )
922					{
923						s.oInstance.fnDestroy();
924						break;
925					}
926					else
927					{
928						_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
929						return;
930					}
931				}
932			
933				/* If the element we are initialising has the same ID as a table which was previously
934				 * initialised, but the table nodes don't match (from before) then we destroy the old
935				 * instance by simply deleting it. This is under the assumption that the table has been
936				 * destroyed by other methods. Anyone using non-id selectors will need to do this manually
937				 */
938				if ( s.sTableId == this.id )
939				{
940					allSettings.splice( i, 1 );
941					break;
942				}
943			}
944			
945			/* Ensure the table has an ID - required for accessibility */
946			if ( sId === null || sId === "" )
947			{
948				sId = "DataTables_Table_"+(DataTable.ext._unique++);
949				this.id = sId;
950			}
951			
952			/* Create the settings object for this table and set some of the default parameters */
953			var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
954				"sDestroyWidth": $this[0].style.width,
955				"sInstance":     sId,
956				"sTableId":      sId
957			} );
958			oSettings.nTable = this;
959			oSettings.oApi   = _that.internal;
960			oSettings.oInit  = oInit;
961			
962			allSettings.push( oSettings );
963			
964			// Need to add the instance after the instance after the settings object has been added
965			// to the settings array, so we can self reference the table instance if more than one
966			oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
967			
968			// Backwards compatibility, before we apply all the defaults
969			_fnCompatOpts( oInit );
970			
971			if ( oInit.oLanguage )
972			{
973				_fnLanguageCompat( oInit.oLanguage );
974			}
975			
976			// If the length menu is given, but the init display length is not, use the length menu
977			if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
978			{
979				oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
980					oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
981			}
982			
983			// Apply the defaults and init options to make a single init object will all
984			// options defined from defaults and instance options.
985			oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
986			
987			
988			// Map the initialisation options onto the settings object
989			_fnMap( oSettings.oFeatures, oInit, [
990				"bPaginate",
991				"bLengthChange",
992				"bFilter",
993				"bSort",
994				"bSortMulti",
995				"bInfo",
996				"bProcessing",
997				"bAutoWidth",
998				"bSortClasses",
999				"bServerSide",
1000				"bDeferRender"
1001			] );
1002			_fnMap( oSettings, oInit, [
1003				"asStripeClasses",
1004				"ajax",
1005				"fnServerData",
1006				"fnFormatNumber",
1007				"sServerMethod",
1008				"aaSorting",
1009				"aaSortingFixed",
1010				"aLengthMenu",
1011				"sPaginationType",
1012				"sAjaxSource",
1013				"sAjaxDataProp",
1014				"iStateDuration",
1015				"sDom",
1016				"bSortCellsTop",
1017				"iTabIndex",
1018				"fnStateLoadCallback",
1019				"fnStateSaveCallback",
1020				"renderer",
1021				"searchDelay",
1022				"rowId",
1023				[ "iCookieDuration", "iStateDuration" ], // backwards compat
1024				[ "oSearch", "oPreviousSearch" ],
1025				[ "aoSearchCols", "aoPreSearchCols" ],
1026				[ "iDisplayLength", "_iDisplayLength" ],
1027				[ "bJQueryUI", "bJUI" ]
1028			] );
1029			_fnMap( oSettings.oScroll, oInit, [
1030				[ "sScrollX", "sX" ],
1031				[ "sScrollXInner", "sXInner" ],
1032				[ "sScrollY", "sY" ],
1033				[ "bScrollCollapse", "bCollapse" ]
1034			] );
1035			_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
1036			
1037			/* Callback functions which are array driven */
1038			_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );
1039			_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );
1040			_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );
1041			_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );
1042			_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );
1043			_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );
1044			_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );
1045			_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );
1046			_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );
1047			_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );
1048			_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );
1049			
1050			oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
1051			
1052			/* Browser support detection */
1053			_fnBrowserDetect( oSettings );
1054			
1055			var oClasses = oSettings.oClasses;
1056			
1057			// @todo Remove in 1.11
1058			if ( oInit.bJQueryUI )
1059			{
1060				/* Use the JUI classes object for display. You could clone the oStdClasses object if
1061				 * you want to have multiple tables with multiple independent classes
1062				 */
1063				$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
1064			
1065				if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
1066				{
1067					/* Set the DOM to use a layout suitable for jQuery UI's theming */
1068					oSettings.sDom = '<"H"lfr>t<"F"ip>';
1069				}
1070			
1071				if ( ! oSettings.renderer ) {
1072					oSettings.renderer = 'jqueryui';
1073				}
1074				else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
1075					oSettings.renderer.header = 'jqueryui';
1076				}
1077			}
1078			else
1079			{
1080				$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
1081			}
1082			$this.addClass( oClasses.sTable );
1083			
1084			
1085			if ( oSettings.iInitDisplayStart === undefined )
1086			{
1087				/* Display start point, taking into account the save saving */
1088				oSettings.iInitDisplayStart = oInit.iDisplayStart;
1089				oSettings._iDisplayStart = oInit.iDisplayStart;
1090			}
1091			
1092			if ( oInit.iDeferLoading !== null )
1093			{
1094				oSettings.bDeferLoading = true;
1095				var tmp = $.isArray( oInit.iDeferLoading );
1096				oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
1097				oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
1098			}
1099			
1100			/* Language definitions */
1101			var oLanguage = oSettings.oLanguage;
1102			$.extend( true, oLanguage, oInit.oLanguage );
1103			
1104			if ( oLanguage.sUrl )
1105			{
1106				/* Get the language definitions from a file - because this Ajax call makes the language
1107				 * get async to the remainder of this function we use bInitHandedOff to indicate that
1108				 * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
1109				 */
1110				$.ajax( {
1111					dataType: 'json',
1112					url: oLanguage.sUrl,
1113					success: function ( json ) {
1114						_fnLanguageCompat( json );
1115						_fnCamelToHungarian( defaults.oLanguage, json );
1116						$.extend( true, oLanguage, json );
1117						_fnInitialise( oSettings );
1118					},
1119					error: function () {
1120						// Error occurred loading language file, continue on as best we can
1121						_fnInitialise( oSettings );
1122					}
1123				} );
1124				bInitHandedOff = true;
1125			}
1126			
1127			/*
1128			 * Stripes
1129			 */
1130			if ( oInit.asStripeClasses === null )
1131			{
1132				oSettings.asStripeClasses =[
1133					oClasses.sStripeOdd,
1134					oClasses.sStripeEven
1135				];
1136			}
1137			
1138			/* Remove row stripe classes if they are already on the table row */
1139			var stripeClasses = oSettings.asStripeClasses;
1140			var rowOne = $this.children('tbody').find('tr').eq(0);
1141			if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
1142				return rowOne.hasClass(el);
1143			} ) ) !== -1 ) {
1144				$('tbody tr', this).removeClass( stripeClasses.join(' ') );
1145				oSettings.asDestroyStripes = stripeClasses.slice();
1146			}
1147			
1148			/*
1149			 * Columns
1150			 * See if we should load columns automatically or use defined ones
1151			 */
1152			var anThs = [];
1153			var aoColumnsInit;
1154			var nThead = this.getElementsByTagName('thead');
1155			if ( nThead.length !== 0 )
1156			{
1157				_fnDetectHeader( oSettings.aoHeader, nThead[0] );
1158				anThs = _fnGetUniqueThs( oSettings );
1159			}
1160			
1161			/* If not given a column array, generate one with nulls */
1162			if ( oInit.aoColumns === null )
1163			{
1164				aoColumnsInit = [];
1165				for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
1166				{
1167					aoColumnsInit.push( null );
1168				}
1169			}
1170			else
1171			{
1172				aoColumnsInit = oInit.aoColumns;
1173			}
1174			
1175			/* Add the columns */
1176			for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
1177			{
1178				_fnAddColumn( oSettings, anThs ? anThs[i] : null );
1179			}
1180			
1181			/* Apply the column definitions */
1182			_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
1183				_fnColumnOptions( oSettings, iCol, oDef );
1184			} );
1185			
1186			/* HTML5 attribute detection - build an mData object automatically if the
1187			 * attributes are found
1188			 */
1189			if ( rowOne.length ) {
1190				var a = function ( cell, name ) {
1191					return cell.getAttribute( 'data-'+name ) !== null ? name : null;
1192				};
1193			
1194				$( rowOne[0] ).children('th, td').each( function (i, cell) {
1195					var col = oSettings.aoColumns[i];
1196			
1197					if ( col.mData === i ) {
1198						var sort = a( cell, 'sort' ) || a( cell, 'order' );
1199						var filter = a( cell, 'filter' ) || a( cell, 'search' );
1200			
1201						if ( sort !== null || filter !== null ) {
1202							col.mData = {
1203								_:      i+'.display',
1204								sort:   sort !== null   ? i+'.@data-'+sort   : undefined,
1205								type:   sort !== null   ? i+'.@data-'+sort   : undefined,
1206								filter: filter !== null ? i+'.@data-'+filter : undefined
1207							};
1208			
1209							_fnColumnOptions( oSettings, i );
1210						}
1211					}
1212				} );
1213			}
1214			
1215			var features = oSettings.oFeatures;
1216			var loadedInit = function () {
1217				/*
1218				 * Sorting
1219				 * @todo For modularisation (1.11) this needs to do into a sort start up handler
1220				 */
1221			
1222				// If aaSorting is not defined, then we use the first indicator in asSorting
1223				// in case that has been altered, so the default sort reflects that option
1224				if ( oInit.aaSorting === undefined ) {
1225					var sorting = oSettings.aaSorting;
1226					for ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {
1227						sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1228					}
1229				}
1230			
1231				/* Do a first pass on the sorting classes (allows any size changes to be taken into
1232				 * account, and also will apply sorting disabled classes if disabled
1233				 */
1234				_fnSortingClasses( oSettings );
1235			
1236				if ( features.bSort ) {
1237					_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1238						if ( oSettings.bSorted ) {
1239							var aSort = _fnSortFlatten( oSettings );
1240							var sortedColumns = {};
1241			
1242							$.each( aSort, function (i, val) {
1243								sortedColumns[ val.src ] = val.dir;
1244							} );
1245			
1246							_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
1247							_fnSortAria( oSettings );
1248						}
1249					} );
1250				}
1251			
1252				_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
1253					if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
1254						_fnSortingClasses( oSettings );
1255					}
1256				}, 'sc' );
1257			
1258			
1259				/*
1260				 * Final init
1261				 * Cache the header, body and footer as required, creating them if needed
1262				 */
1263			
1264				// Work around for Webkit bug 83867 - store the caption-side before removing from doc
1265				var captions = $this.children('caption').each( function () {
1266					this._captionSide = $(this).css('caption-side');
1267				} );
1268			
1269				var thead = $this.children('thead');
1270				if ( thead.length === 0 ) {
1271					thead = $('<thead/>').appendTo($this);
1272				}
1273				oSettings.nTHead = thead[0];
1274			
1275				var tbody = $this.children('tbody');
1276				if ( tbody.length === 0 ) {
1277					tbody = $('<tbody/>').appendTo($this);
1278				}
1279				oSettings.nTBody = tbody[0];
1280			
1281				var tfoot = $this.children('tfoot');
1282				if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") ) {
1283					// If we are a scrolling table, and no footer has been given, then we need to create
1284					// a tfoot element for the caption element to be appended to
1285					tfoot = $('<tfoot/>').appendTo($this);
1286				}
1287			
1288				if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
1289					$this.addClass( oClasses.sNoFooter );
1290				}
1291				else if ( tfoot.length > 0 ) {
1292					oSettings.nTFoot = tfoot[0];
1293					_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
1294				}
1295			
1296				/* Check if there is data passing into the constructor */
1297				if ( oInit.aaData ) {
1298					for ( i=0 ; i<oInit.aaData.length ; i++ ) {
1299						_fnAddData( oSettings, oInit.aaData[ i ] );
1300					}
1301				}
1302				else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {
1303					/* Grab the data from the page - only do this when deferred loading or no Ajax
1304					 * source since there is no point in reading the DOM data if we are then going
1305					 * to replace it with Ajax data
1306					 */
1307					_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
1308				}
1309			
1310				/* Copy the data index array */
1311				oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1312			
1313				/* Initialisation complete - table can be drawn */
1314				oSettings.bInitialised = true;
1315			
1316				/* Check if we need to initialise the table (it might not have been handed off to the
1317				 * language processor)
1318				 */
1319				if ( bInitHandedOff === false ) {
1320					_fnInitialise( oSettings );
1321				}
1322			};
1323			
1324			/* Must be done after everything which can be overridden by the state saving! */
1325			if ( oInit.bStateSave )
1326			{
1327				features.bStateSave = true;
1328				_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
1329				_fnLoadState( oSettings, oInit, loadedInit );
1330			}
1331			else {
1332				loadedInit();
1333			}
1334			
1335		} );
1336		_that = null;
1337		return this;
1338	};
1339
1340	
1341	/*
1342	 * It is useful to have variables which are scoped locally so only the
1343	 * DataTables functions can access them and they don't leak into global space.
1344	 * At the same time these functions are often useful over multiple files in the
1345	 * core and API, so we list, or at least document, all variables which are used
1346	 * by DataTables as private variables here. This also ensures that there is no
1347	 * clashing of variable names and that they can easily referenced for reuse.
1348	 */
1349	
1350	
1351	// Defined else where
1352	//  _selector_run
1353	//  _selector_opts
1354	//  _selector_first
1355	//  _selector_row_indexes
1356	
1357	var _ext; // DataTable.ext
1358	var _Api; // DataTable.Api
1359	var _api_register; // DataTable.Api.register
1360	var _api_registerPlural; // DataTable.Api.registerPlural
1361	
1362	var _re_dic = {};
1363	var _re_new_lines = /[\r\n]/g;
1364	var _re_html = /<.*?>/g;
1365	
1366	// This is not strict ISO8601 - Date.parse() is quite lax, although
1367	// implementations differ between browsers.
1368	var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
1369	
1370	// Escape regular expression special characters
1371	var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
1372	
1373	// http://en.wikipedia.org/wiki/Foreign_exchange_market
1374	// - \u20BD - Russian ruble.
1375	// - \u20a9 - South Korean Won
1376	// - \u20BA - Turkish Lira
1377	// - \u20B9 - Indian Rupee
1378	// - R - Brazil (R$) and South Africa
1379	// - fr - Swiss Franc
1380	// - kr - Swedish krona, Norwegian krone and Danish krone
1381	// - \u2009 is thin space and \u202F is narrow no-break space, both used in many
1382	//   standards as thousands separators.
1383	var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
1384	
1385	
1386	var _empty = function ( d ) {
1387		return !d || d === true || d === '-' ? true : false;
1388	};
1389	
1390	
1391	var _intVal = function ( s ) {
1392		var integer = parseInt( s, 10 );
1393		return !isNaN(integer) && isFinite(s) ? integer : null;
1394	};
1395	
1396	// Convert from a formatted number with characters other than `.` as the
1397	// decimal place, to a Javascript number
1398	var _numToDecimal = function ( num, decimalPoint ) {
1399		// Cache created regular expressions for speed as this function is called often
1400		if ( ! _re_dic[ decimalPoint ] ) {
1401			_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
1402		}
1403		return typeof num === 'string' && decimalPoint !== '.' ?
1404			num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
1405			num;
1406	};
1407	
1408	
1409	var _isNumber = function ( d, decimalPoint, formatted ) {
1410		var strType = typeof d === 'string';
1411	
1412		// If empty return immediately so there must be a number if it is a
1413		// formatted string (this stops the string "k", or "kr", etc being detected
1414		// as a formatted number for currency
1415		if ( _empty( d ) ) {
1416			return true;
1417		}
1418	
1419		if ( decimalPoint && strType ) {
1420			d = _numToDecimal( d, decimalPoint );
1421		}
1422	
1423		if ( formatted && strType ) {
1424			d = d.replace( _re_formatted_numeric, '' );
1425		}
1426	
1427		return !isNaN( parseFloat(d) ) && isFinite( d );
1428	};
1429	
1430	
1431	// A string without HTML in it can be considered to be HTML still
1432	var _isHtml = function ( d ) {
1433		return _empty( d ) || typeof d === 'string';
1434	};
1435	
1436	
1437	var _htmlNumeric = function ( d, decimalPoint, formatted ) {
1438		if ( _empty( d ) ) {
1439			return true;
1440		}
1441	
1442		var html = _isHtml( d );
1443		return ! html ?
1444			null :
1445			_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
1446				true :
1447				null;
1448	};
1449	
1450	
1451	var _pluck = function ( a, prop, prop2 ) {
1452		var out = [];
1453		var i=0, ien=a.length;
1454	
1455		// Could have the test in the loop for slightly smaller code, but speed
1456		// is essential here
1457		if ( prop2 !== undefined ) {
1458			for ( ; i<ien ; i++ ) {
1459				if ( a[i] && a[i][ prop ] ) {
1460					out.push( a[i][ prop ][ prop2 ] );
1461				}
1462			}
1463		}
1464		else {
1465			for ( ; i<ien ; i++ ) {
1466				if ( a[i] ) {
1467					out.push( a[i][ prop ] );
1468				}
1469			}
1470		}
1471	
1472		return out;
1473	};
1474	
1475	
1476	// Basically the same as _pluck, but rather than looping over `a` we use `order`
1477	// as the indexes to pick from `a`
1478	var _pluck_order = function ( a, order, prop, prop2 )
1479	{
1480		var out = [];
1481		var i=0, ien=order.length;
1482	
1483		// Could have the test in the loop for slightly smaller code, but speed
1484		// is essential here
1485		if ( prop2 !== undefined ) {
1486			for ( ; i<ien ; i++ ) {
1487				if ( a[ order[i] ][ prop ] ) {
1488					out.push( a[ order[i] ][ prop ][ prop2 ] );
1489				}
1490			}
1491		}
1492		else {
1493			for ( ; i<ien ; i++ ) {
1494				out.push( a[ order[i] ][ prop ] );
1495			}
1496		}
1497	
1498		return out;
1499	};
1500	
1501	
1502	var _range = function ( len, start )
1503	{
1504		var out = [];
1505		var end;
1506	
1507		if ( start === undefined ) {
1508			start = 0;
1509			end = len;
1510		}
1511		else {
1512			end = start;
1513			start = len;
1514		}
1515	
1516		for ( var i=start ; i<end ; i++ ) {
1517			out.push( i );
1518		}
1519	
1520		return out;
1521	};
1522	
1523	
1524	var _removeEmpty = function ( a )
1525	{
1526		var out = [];
1527	
1528		for ( var i=0, ien=a.length ; i<ien ; i++ ) {
1529			if ( a[i] ) { // careful - will remove all falsy values!
1530				out.push( a[i] );
1531			}
1532		}
1533	
1534		return out;
1535	};
1536	
1537	
1538	var _stripHtml = function ( d ) {
1539		return d.replace( _re_html, '' );
1540	};
1541	
1542	
1543	/**
1544	 * Find the unique elements in a source array.
1545	 *
1546	 * @param  {array} src Source array
1547	 * @return {array} Array of unique items
1548	 * @ignore
1549	 */
1550	var _unique = function ( src )
1551	{
1552		// A faster unique method is to use object keys to identify used values,
1553		// but this doesn't work with arrays or objects, which we must also
1554		// consider. See jsperf.com/compare-array-unique-versions/4 for more
1555		// information.
1556		var
1557			out = [],
1558			val,
1559			i, ien=src.length,
1560			j, k=0;
1561	
1562		again: for ( i=0 ; i<ien ; i++ ) {
1563			val = src[i];
1564	
1565			for ( j=0 ; j<k ; j++ ) {
1566				if ( out[j] === val ) {
1567					continue again;
1568				}
1569			}
1570	
1571			out.push( val );
1572			k++;
1573		}
1574	
1575		return out;
1576	};
1577	
1578	
1579	/**
1580	 * DataTables utility methods
1581	 * 
1582	 * This namespace provides helper methods that DataTables uses internally to
1583	 * create a DataTable, but which are not exclusively used only for DataTables.
1584	 * These methods can be used by extension authors to save the duplication of
1585	 * code.
1586	 *
1587	 *  @namespace
1588	 */
1589	DataTable.util = {
1590		/**
1591		 * Throttle the calls to a function. Arguments and context are maintained
1592		 * for the throttled function.
1593		 *
1594		 * @param {function} fn Function to be called
1595		 * @param {integer} freq Call frequency in mS
1596		 * @return {function} Wrapped function
1597		 */
1598		throttle: function ( fn, freq ) {
1599			var
1600				frequency = freq !== undefined ? freq : 200,
1601				last,
1602				timer;
1603	
1604			return function () {
1605				var
1606					that = this,
1607					now  = +new Date(),
1608					args = arguments;
1609	
1610				if ( last && now < last + frequency ) {
1611					clearTimeout( timer );
1612	
1613					timer = setTimeout( function () {
1614						last = undefined;
1615						fn.apply( that, args );
1616					}, frequency );
1617				}
1618				else {
1619					last = now;
1620					fn.apply( that, args );
1621				}
1622			};
1623		},
1624	
1625	
1626		/**
1627		 * Escape a string such that it can be used in a regular expression
1628		 *
1629		 *  @param {string} val string to escape
1630		 *  @returns {string} escaped string
1631		 */
1632		escapeRegex: function ( val ) {
1633			return val.replace( _re_escape_regex, '\\$1' );
1634		}
1635	};
1636	
1637	
1638	
1639	/**
1640	 * Create a mapping object that allows camel case parameters to be looked up
1641	 * for their Hungarian counterparts. The mapping is stored in a private
1642	 * parameter called `_hungarianMap` which can be accessed on the source object.
1643	 *  @param {object} o
1644	 *  @memberof DataTable#oApi
1645	 */
1646	function _fnHungarianMap ( o )
1647	{
1648		var
1649			hungarian = 'a aa ai ao as b fn i m o s ',
1650			match,
1651			newKey,
1652			map = {};
1653	
1654		$.each( o, function (key, val) {
1655			match = key.match(/^([^A-Z]+?)([A-Z])/);
1656	
1657			if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
1658			{
1659				newKey = key.replace( match[0], match[2].toLowerCase() );
1660				map[ newKey ] = key;
1661	
1662				if ( match[1] === 'o' )
1663				{
1664					_fnHungarianMap( o[key] );
1665				}
1666			}
1667		} );
1668	
1669		o._hungarianMap = map;
1670	}
1671	
1672	
1673	/**
1674	 * Convert from camel case parameters to Hungarian, based on a Hungarian map
1675	 * created by _fnHungarianMap.
1676	 *  @param {object} src The model object which holds all parameters that can be
1677	 *    mapped.
1678	 *  @param {object} user The object to convert from camel case to Hungarian.
1679	 *  @param {boolean} force When set to `true`, properties which already have a
1680	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
1681	 *    won't be.
1682	 *  @memberof DataTable#oApi
1683	 */
1684	function _fnCamelToHungarian ( src, user, force )
1685	{
1686		if ( ! src._hungarianMap ) {
1687			_fnHungarianMap( src );
1688		}
1689	
1690		var hungarianKey;
1691	
1692		$.each( user, function (key, val) {
1693			hungarianKey = src._hungarianMap[ key ];
1694	
1695			if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
1696			{
1697				// For objects, we need to buzz down into the object to copy parameters
1698				if ( hungarianKey.charAt(0) === 'o' )
1699				{
1700					// Copy the camelCase options over to the hungarian
1701					if ( ! user[ hungarianKey ] ) {
1702						user[ hungarianKey ] = {};
1703					}
1704					$.extend( true, user[hungarianKey], user[key] );
1705	
1706					_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
1707				}
1708				else {
1709					user[hungarianKey] = user[ key ];
1710				}
1711			}
1712		} );
1713	}
1714	
1715	
1716	/**
1717	 * Language compatibility - when certain options are given, and others aren't, we
1718	 * need to duplicate the values over, in order to provide backwards compatibility
1719	 * with older language files.
1720	 *  @param {object} oSettings dataTables settings object
1721	 *  @memberof DataTable#oApi
1722	 */
1723	function _fnLanguageCompat( lang )
1724	{
1725		var defaults = DataTable.defaults.oLanguage;
1726		var zeroRecords = lang.sZeroRecords;
1727	
1728		/* Backwards compatibility - if there is no sEmptyTable given, then use the same as
1729		 * sZeroRecords - assuming that is given.
1730		 */
1731		if ( ! lang.sEmptyTable && zeroRecords &&
1732			defaults.sEmptyTable === "No data available in table" )
1733		{
1734			_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
1735		}
1736	
1737		/* Likewise with loading records */
1738		if ( ! lang.sLoadingRecords && zeroRecords &&
1739			defaults.sLoadingRecords === "Loading..." )
1740		{
1741			_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
1742		}
1743	
1744		// Old parameter name of the thousands separator mapped onto the new
1745		if ( lang.sInfoThousands ) {
1746			lang.sThousands = lang.sInfoThousands;
1747		}
1748	
1749		var decimal = lang.sDecimal;
1750		if ( decimal ) {
1751			_addNumericSort( decimal );
1752		}
1753	}
1754	
1755	
1756	/**
1757	 * Map one parameter onto another
1758	 *  @param {object} o Object to map
1759	 *  @param {*} knew The new parameter name
1760	 *  @param {*} old The old parameter name
1761	 */
1762	var _fnCompatMap = function ( o, knew, old ) {
1763		if ( o[ knew ] !== undefined ) {
1764			o[ old ] = o[ knew ];
1765		}
1766	};
1767	
1768	
1769	/**
1770	 * Provide backwards compatibility for the main DT options. Note that the new
1771	 * options are mapped onto the old parameters, so this is an external interface
1772	 * change only.
1773	 *  @param {object} init Object to map
1774	 */
1775	function _fnCompatOpts ( init )
1776	{
1777		_fnCompatMap( init, 'ordering',      'bSort' );
1778		_fnCompatMap( init, 'orderMulti',    'bSortMulti' );
1779		_fnCompatMap( init, 'orderClasses',  'bSortClasses' );
1780		_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
1781		_fnCompatMap( init, 'order',         'aaSorting' );
1782		_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );
1783		_fnCompatMap( init, 'paging',        'bPaginate' );
1784		_fnCompatMap( init, 'pagingType',    'sPaginationType' );
1785		_fnCompatMap( init, 'pageLength',    'iDisplayLength' );
1786		_fnCompatMap( init, 'searching',     'bFilter' );
1787	
1788		// Boolean initialisation of x-scrolling
1789		if ( typeof init.sScrollX === 'boolean' ) {
1790			init.sScrollX = init.sScrollX ? '100%' : '';
1791		}
1792		if ( typeof init.scrollX === 'boolean' ) {
1793			init.scrollX = init.scrollX ? '100%' : '';
1794		}
1795	
1796		// Column search objects are in an array, so it needs to be converted
1797		// element by element
1798		var searchCols = init.aoSearchCols;
1799	
1800		if ( searchCols ) {
1801			for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
1802				if ( searchCols[i] ) {
1803					_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
1804				}
1805			}
1806		}
1807	}
1808	
1809	
1810	/**
1811	 * Provide backwards compatibility for column options. Note that the new options
1812	 * are mapped onto the old parameters, so this is an external interface change
1813	 * only.
1814	 *  @param {object} init Object to map
1815	 */
1816	function _fnCompatCols ( init )
1817	{
1818		_fnCompatMap( init, 'orderable',     'bSortable' );
1819		_fnCompatMap( init, 'orderData',     'aDataSort' );
1820		_fnCompatMap( init, 'orderSequence', 'asSorting' );
1821		_fnCompatMap( init, 'orderDataType', 'sortDataType' );
1822	
1823		// orderData can be given as an integer
1824		var dataSort = init.aDataSort;
1825		if ( dataSort && ! $.isArray( dataSort ) ) {
1826			init.aDataSort = [ dataSort ];
1827		}
1828	}
1829	
1830	
1831	/**
1832	 * Browser feature detection for capabilities, quirks
1833	 *  @param {object} settings dataTables settings object
1834	 *  @memberof DataTable#oApi
1835	 */
1836	function _fnBrowserDetect( settings )
1837	{
1838		// We don't need to do this every time DataTables is constructed, the values
1839		// calculated are specific to the browser and OS configuration which we
1840		// don't expect to change between initialisations
1841		if ( ! DataTable.__browser ) {
1842			var browser = {};
1843			DataTable.__browser = browser;
1844	
1845			// Scrolling feature / quirks detection
1846			var n = $('<div/>')
1847				.css( {
1848					position: 'fixed',
1849					top: 0,
1850					left: $(window).scrollLeft()*-1, // allow for scrolling
1851					height: 1,
1852					width: 1,
1853					overflow: 'hidden'
1854				} )
1855				.append(
1856					$('<div/>')
1857						.css( {
1858							position: 'absolute',
1859							top: 1,
1860							left: 1,
1861							width: 100,
1862							overflow: 'scroll'
1863						} )
1864						.append(
1865							$('<div/>')
1866								.css( {
1867									width: '100%',
1868									height: 10
1869								} )
1870						)
1871				)
1872				.appendTo( 'body' );
1873	
1874			var outer = n.children();
1875			var inner = outer.children();
1876	
1877			// Numbers below, in order, are:
1878			// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
1879			//
1880			// IE6 XP:                           100 100 100  83
1881			// IE7 Vista:                        100 100 100  83
1882			// IE 8+ Windows:                     83  83 100  83
1883			// Evergreen Windows:                 83  83 100  83
1884			// Evergreen Mac with scrollbars:     85  85 100  85
1885			// Evergreen Mac without scrollbars: 100 100 100 100
1886	
1887			// Get scrollbar width
1888			browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
1889	
1890			// IE6/7 will oversize a width 100% element inside a scrolling element, to
1891			// include the width of the scrollbar, while other browsers ensure the inner
1892			// element is contained without forcing scrolling
1893			browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
1894	
1895			// In rtl text layout, some browsers (most, but not all) will place the
1896			// scrollbar on the left, rather than the right.
1897			browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
1898	
1899			// IE8- don't provide height and width for getBoundingClientRect
1900			browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
1901	
1902			n.remove();
1903		}
1904	
1905		$.extend( settings.oBrowser, DataTable.__browser );
1906		settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
1907	}
1908	
1909	
1910	/**
1911	 * Array.prototype reduce[Right] method, used for browsers which don't support
1912	 * JS 1.6. Done this way to reduce code size, since we iterate either way
1913	 *  @param {object} settings dataTables settings object
1914	 *  @memberof DataTable#oApi
1915	 */
1916	function _fnReduce ( that, fn, init, start, end, inc )
1917	{
1918		var
1919			i = start,
1920			value,
1921			isSet = false;
1922	
1923		if ( init !== undefined ) {
1924			value = init;
1925			isSet = true;
1926		}
1927	
1928		while ( i !== end ) {
1929			if ( ! that.hasOwnProperty(i) ) {
1930				continue;
1931			}
1932	
1933			value = isSet ?
1934				fn( value, that[i], i, that ) :
1935				that[i];
1936	
1937			isSet = true;
1938			i += inc;
1939		}
1940	
1941		return value;
1942	}
1943	
1944	/**
1945	 * Add a column to the list used for the table with default values
1946	 *  @param {object} oSettings dataTables settings object
1947	 *  @param {node} nTh The th element for this column
1948	 *  @memberof DataTable#oApi
1949	 */
1950	function _fnAddColumn( oSettings, nTh )
1951	{
1952		// Add column to aoColumns array
1953		var oDefaults = DataTable.defaults.column;
1954		var iCol = oSettings.aoColumns.length;
1955		var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
1956			"nTh": nTh ? nTh : document.createElement('th'),
1957			"sTitle":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',
1958			"aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
1959			"mData": oDefaults.mData ? oDefaults.mData : iCol,
1960			idx: iCol
1961		} );
1962		oSettings.aoColumns.push( oCol );
1963	
1964		// Add search object for column specific search. Note that the `searchCols[ iCol ]`
1965		// passed into extend can be undefined. This allows the user to give a default
1966		// with only some of the parameters defined, and also not give a default
1967		var searchCols = oSettings.aoPreSearchCols;
1968		searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
1969	
1970		// Use the default column options function to initialise classes etc
1971		_fnColumnOptions( oSettings, iCol, $(nTh).data() );
1972	}
1973	
1974	
1975	/**
1976	 * Apply options for a column
1977	 *  @param {object} oSettings dataTables settings object
1978	 *  @param {int} iCol column index to consider
1979	 *  @param {object} oOptions object with sType, bVisible and bSearchable etc
1980	 *  @memberof DataTable#oApi
1981	 */
1982	function _fnColumnOptions( oSettings, iCol, oOptions )
1983	{
1984		var oCol = oSettings.aoColumns[ iCol ];
1985		var oClasses = oSettings.oClasses;
1986		var th = $(oCol.nTh);
1987	
1988		// Try to get width information from the DOM. We can't get it from CSS
1989		// as we'd need to parse the CSS stylesheet. `width` option can override
1990		if ( ! oCol.sWidthOrig ) {
1991			// Width attribute
1992			oCol.sWidthOrig = th.attr('width') || null;
1993	
1994			// Style attribute
1995			var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
1996			if ( t ) {
1997				oCol.sWidthOrig = t[1];
1998			}
1999		}
2000	
2001		/* User specified column options */
2002		if ( oOptions !== undefined && oOptions !== null )
2003		{
2004			// Backwards compatibility
2005			_fnCompatCols( oOptions );
2006	
2007			// Map camel case parameters to their Hungarian counterparts
2008			_fnCamelToHungarian( DataTable.defaults.column, oOptions );
2009	
2010			/* Backwards compatibility for mDataProp */
2011			if ( oOptions.mDataProp !== undefined && !oOptions.mData )
2012			{
2013				oOptions.mData = oOptions.mDataProp;
2014			}
2015	
2016			if ( oOptions.sType )
2017			{
2018				oCol._sManualType = oOptions.sType;
2019			}
2020	
2021			// `class` is a reserved word in Javascript, so we need to provide
2022			// the ability to use a valid name for the camel case input
2023			if ( oOptions.className && ! oOptions.sClass )
2024			{
2025				oOptions.sClass = oOptions.className;
2026			}
2027	
2028			$.extend( oCol, oOptions );
2029			_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
2030	
2031			/* iDataSort to be applied (backwards compatibility), but aDataSort will take
2032			 * priority if defined
2033			 */
2034			if ( oOptions.iDataSort !== undefined )
2035			{
2036				oCol.aDataSort = [ oOptions.iDataSort ];
2037			}
2038			_fnMap( oCol, oOptions, "aDataSort" );
2039		}
2040	
2041		/* Cache the data get and set functions for speed */
2042		var mDataSrc = oCol.mData;
2043		var mData = _fnGetObjectDataFn( mDataSrc );
2044		var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
2045	
2046		var attrTest = function( src ) {
2047			return typeof src === 'string' && src.indexOf('@') !== -1;
2048		};
2049		oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
2050			attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
2051		);
2052		oCol._setter = null;
2053	
2054		oCol.fnGetData = function (rowData, type, meta) {
2055			var innerData = mData( rowData, type, undefined, meta );
2056	
2057			return mRender && type ?
2058				mRender( innerData, type, rowData, meta ) :
2059				innerData;
2060		};
2061		oCol.fnSetData = function ( rowData, val, meta ) {
2062			return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
2063		};
2064	
2065		// Indicate if DataTables should read DOM data as an object or array
2066		// Used in _fnGetRowElements
2067		if ( typeof mDataSrc !== 'number' ) {
2068			oSettings._rowReadObject = true;
2069		}
2070	
2071		/* Feature sorting overrides column specific when off */
2072		if ( !oSettings.oFeatures.bSort )
2073		{
2074			oCol.bSortable = false;
2075			th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
2076		}
2077	
2078		/* Check that the class assignment is correct for sorting */
2079		var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
2080		var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
2081		if ( !oCol.bSortable || (!bAsc && !bDesc) )
2082		{
2083			oCol.sSortingClass = oClasses.sSortableNone;
2084			oCol.sSortingClassJUI = "";
2085		}
2086		else if ( bAsc && !bDesc )
2087		{
2088			oCol.sSortingClass = oClasses.sSortableAsc;
2089			oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
2090		}
2091		else if ( !bAsc && bDesc )
2092		{
2093			oCol.sSortingClass = oClasses.sSortableDesc;
2094			oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
2095		}
2096		else
2097		{
2098			oCol.sSortingClass = oClasses.sSortable;
2099			oCol.sSortingClassJUI = oClasses.sSortJUI;
2100		}
2101	}
2102	
2103	
2104	/**
2105	 * Adjust the table column widths for new data. Note: you would probably want to
2106	 * do a redraw after calling this function!
2107	 *  @param {object} settings dataTables settings object
2108	 *  @memberof DataTable#oApi
2109	 */
2110	function _fnAdjustColumnSizing ( settings )
2111	{
2112		/* Not interested in doing column width calculation if auto-width is disabled */
2113		if ( settings.oFeatures.bAutoWidth !== false )
2114		{
2115			var columns = settings.aoColumns;
2116	
2117			_fnCalculateColumnWidths( settings );
2118			for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
2119			{
2120				columns[i].nTh.style.width = columns[i].sWidth;
2121			}
2122		}
2123	
2124		var scroll = settings.oScroll;
2125		if ( scroll.sY !== '' || scroll.sX !== '')
2126		{
2127			_fnScrollDraw( settings );
2128		}
2129	
2130		_fnCallbackFire( settings, null, 'column-sizing', [settings] );
2131	}
2132	
2133	
2134	/**
2135	 * Covert the index of a visible column to the index in the data array (take account
2136	 * of hidden columns)
2137	 *  @param {object} oSettings dataTables settings object
2138	 *  @param {int} iMatch Visible column index to lookup
2139	 *  @returns {int} i the data index
2140	 *  @memberof DataTable#oApi
2141	 */
2142	function _fnVisibleToColumnIndex( oSettings, iMatch )
2143	{
2144		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
2145	
2146		return typeof aiVis[iMatch] === 'number' ?
2147			aiVis[iMatch] :
2148			null;
2149	}
2150	
2151	
2152	/**
2153	 * Covert the index of an index in the data array and convert it to the visible
2154	 *   column index (take account of hidden columns)
2155	 *  @param {int} iMatch Column index to lookup
2156	 *  @param {object} oSettings dataTables settings object
2157	 *  @returns {int} i the data index
2158	 *  @memberof DataTable#oApi
2159	 */
2160	function _fnColumnIndexToVisible( oSettings, iMatch )
2161	{
2162		var aiVis = _fnGetColumns( oSettings, 'bVisible' );
2163		var iPos = $.inArray( iMatch, aiVis );
2164	
2165		return iPos !== -1 ? iPos : null;
2166	}
2167	
2168	
2169	/**
2170	 * Get the number of visible columns
2171	 *  @param {object} oSettings dataTables settings object
2172	 *  @returns {int} i the number of visible columns
2173	 *  @memberof DataTable#oApi
2174	 */
2175	function _fnVisbleColumns( oSettings )
2176	{
2177		var vis = 0;
2178	
2179		// No reduce in IE8, use a loop for now
2180		$.each( oSettings.aoColumns, function ( i, col ) {
2181			if ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {
2182				vis++;
2183			}
2184		} );
2185	
2186		return vis;
2187	}
2188	
2189	
2190	/**
2191	 * Get an array of column indexes that match a given property
2192	 *  @param {object} oSettings dataTables settings object
2193	 *  @param {string} sParam Parameter in aoColumns to look for - typically
2194	 *    bVisible or bSearchable
2195	 *  @returns {array} Array of indexes with matched properties
2196	 *  @memberof DataTable#oApi
2197	 */
2198	function _fnGetColumns( oSettings, sParam )
2199	{
2200		var a = [];
2201	
2202		$.map( oSettings.aoColumns, function(val, i) {
2203			if ( val[sParam] ) {
2204				a.push( i );
2205			}
2206		} );
2207	
2208		return a;
2209	}
2210	
2211	
2212	/**
2213	 * Calculate the 'type' of a column
2214	 *  @param {object} settings dataTables settings object
2215	 *  @memberof DataTable#oApi
2216	 */
2217	function _fnColumnTypes ( settings )
2218	{
2219		var columns = settings.aoColumns;
2220		var data = settings.aoData;
2221		var types = DataTable.ext.type.detect;
2222		var i, ien, j, jen, k, ken;
2223		var col, cell, detectedType, cache;
2224	
2225		// For each column, spin over the 
2226		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
2227			col = columns[i];
2228			cache = [];
2229	
2230			if ( ! col.sType && col._sManualType ) {
2231				col.sType = col._sManualType;
2232			}
2233			else if ( ! col.sType ) {
2234				for ( j=0, jen=types.length ; j<jen ; j++ ) {
2235					for ( k=0, ken=data.length ; k<ken ; k++ ) {
2236						// Use a cache array so we only need to get the type data
2237						// from the formatter once (when using multiple detectors)
2238						if ( cache[k] === undefined ) {
2239							cache[k] = _fnGetCellData( settings, k, i, 'type' );
2240						}
2241	
2242						detectedType = types[j]( cache[k], settings );
2243	
2244						// If null, then this type can't apply to this column, so
2245						// rather than testing all cells, break out. There is an
2246						// exception for the last type which is `html`. We need to
2247						// scan all rows since it is possible to mix string and HTML
2248						// types
2249						if ( ! detectedType && j !== types.length-1 ) {
2250							break;
2251						}
2252	
2253						// Only a single match is needed for html type since it is
2254						// bottom of the pile and very similar to string
2255						if ( detectedType === 'html' ) {
2256							break;
2257						}
2258					}
2259	
2260					// Type is valid for all data points in the column - use this
2261					// type
2262					if ( detectedType ) {
2263						col.sType = detectedType;
2264						break;
2265					}
2266				}
2267	
2268				// Fall back - if no type was detected, always use string
2269				if ( ! col.sType ) {
2270					col.sType = 'string';
2271				}
2272			}
2273		}
2274	}
2275	
2276	
2277	/**
2278	 * Take the column definitions and static columns arrays and calculate how
2279	 * they relate to column indexes. The callback function will then apply the
2280	 * definition found for a column to a suitable configuration object.
2281	 *  @param {object} oSettings dataTables settings object
2282	 *  @param {array} aoColDefs The aoColumnDefs array that is to be applied
2283	 *  @param {array} aoCols The aoColumns array that defines columns individually
2284	 *  @param {function} fn Callback function - takes two parameters, the calculated
2285	 *    column index and the definition for that column.
2286	 *  @memberof DataTable#oApi
2287	 */
2288	function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
2289	{
2290		var i, iLen, j, jLen, k, kLen, def;
2291		var columns = oSettings.aoColumns;
2292	
2293		// Column definitions with aTargets
2294		if ( aoColDefs )
2295		{
2296			/* Loop over the definitions array - loop in reverse so first instance has priority */
2297			for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
2298			{
2299				def = aoColDefs[i];
2300	
2301				/* Each definition can target multiple columns, as it is an array */
2302				var aTargets = def.targets !== undefined ?
2303					def.targets :
2304					def.aTargets;
2305	
2306				if ( ! $.isArray( aTargets ) )
2307				{
2308					aTargets = [ aTargets ];
2309				}
2310	
2311				for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
2312				{
2313					if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
2314					{
2315						/* Add columns that we don't yet know about */
2316						while( columns.length <= aTargets[j] )
2317						{
2318							_fnAddColumn( oSettings );
2319						}
2320	
2321						/* Integer, basic index */
2322						fn( aTargets[j], def );
2323					}
2324					else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
2325					{
2326						/* Negative integer, right to left column counting */
2327						fn( columns.length+aTargets[j], def );
2328					}
2329					else if ( typeof aTargets[j] === 'string' )
2330					{
2331						/* Class name matching on TH element */
2332						for ( k=0, kLen=columns.length ; k<kLen ; k++ )
2333						{
2334							if ( aTargets[j] == "_all" ||
2335							     $(columns[k].nTh).hasClass( aTargets[j] ) )
2336							{
2337								fn( k, def );
2338							}
2339						}
2340					}
2341				}
2342			}
2343		}
2344	
2345		// Statically defined columns array
2346		if ( aoCols )
2347		{
2348			for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
2349			{
2350				fn( i, aoCols[i] );
2351			}
2352		}
2353	}
2354	
2355	/**
2356	 * Add a data array to the table, creating DOM node etc. This is the parallel to
2357	 * _fnGatherData, but for adding rows from a Javascript source, rather than a
2358	 * DOM source.
2359	 *  @param {object} oSettings dataTables settings object
2360	 *  @param {array} aData data array to be added
2361	 *  @param {node} [nTr] TR element to add to the table - optional. If not given,
2362	 *    DataTables will create a row automatically
2363	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
2364	 *    if nTr is.
2365	 *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
2366	 *  @memberof DataTable#oApi
2367	 */
2368	function _fnAddData ( oSettings, aDataIn, nTr, anTds )
2369	{
2370		/* Create the object for storing information about this new row */
2371		var iRow = oSettings.aoData.length;
2372		var oData = $.extend( true, {}, DataTable.models.oRow, {
2373			src: nTr ? 'dom' : 'data',
2374			idx: iRow
2375		} );
2376	
2377		oData._aData = aDataIn;
2378		oSettings.aoData.push( oData );
2379	
2380		/* Create the cells */
2381		var nTd, sThisType;
2382		var columns = oSettings.aoColumns;
2383	
2384		// Invalidate the column types as the new data needs to be revalidated
2385		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
2386		{
2387			columns[i].sType = null;
2388		}
2389	
2390		/* Add to the display array */
2391		oSettings.aiDisplayMaster.push( iRow );
2392	
2393		var id = oSettings.rowIdFn( aDataIn );
2394		if ( id !== undefined ) {
2395			oSettings.aIds[ id ] = oData;
2396		}
2397	
2398		/* Create the DOM information, or register it if already present */
2399		if ( nTr || ! oSettings.oFeatures.bDeferRender )
2400		{
2401			_fnCreateTr( oSettings, iRow, nTr, anTds );
2402		}
2403	
2404		return iRow;
2405	}
2406	
2407	
2408	/**
2409	 * Add one or more TR elements to the table. Generally we'd expect to
2410	 * use this for reading data from a DOM sourced table, but it could be
2411	 * used for an TR element. Note that if a TR is given, it is used (i.e.
2412	 * it is not cloned).
2413	 *  @param {object} settings dataTables settings object
2414	 *  @param {array|node|jQuery} trs The TR element(s) to add to the table
2415	 *  @returns {array} Array of indexes for the added rows
2416	 *  @memberof DataTable#oApi
2417	 */
2418	function _fnAddTr( settings, trs )
2419	{
2420		var row;
2421	
2422		// Allow an individual node to be passed in
2423		if ( ! (trs instanceof $) ) {
2424			trs = $(trs);
2425		}
2426	
2427		return trs.map( function (i, el) {
2428			row = _fnGetRowElements( settings, el );
2429			return _fnAddData( settings, row.data, el, row.cells );
2430		} );
2431	}
2432	
2433	
2434	/**
2435	 * Take a TR element and convert it to an index in aoData
2436	 *  @param {object} oSettings dataTables settings object
2437	 *  @param {node} n the TR element to find
2438	 *  @returns {int} index if the node is found, null if not
2439	 *  @memberof DataTable#oApi
2440	 */
2441	function _fnNodeToDataIndex( oSettings, n )
2442	{
2443		return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
2444	}
2445	
2446	
2447	/**
2448	 * Take a TD element and convert it into a column data index (not the visible index)
2449	 *  @param {object} oSettings dataTables settings object
2450	 *  @param {int} iRow The row number the TD/TH can be found in
2451	 *  @param {node} n The TD/TH element to find
2452	 *  @returns {int} index if the node is found, -1 if not
2453	 *  @memberof DataTable#oApi
2454	 */
2455	function _fnNodeToColumnIndex( oSettings, iRow, n )
2456	{
2457		return $.inArray( n, oSettings.aoData[ iRow ].anCells );
2458	}
2459	
2460	
2461	/**
2462	 * Get the data for a given cell from the internal cache, taking into account data mapping
2463	 *  @param {object} settings dataTables settings object
2464	 *  @param {int} rowIdx aoData row id
2465	 *  @param {int} colIdx Column index
2466	 *  @param {string} type data get type ('display', 'type' 'filter' 'sort')
2467	 *  @returns {*} Cell data
2468	 *  @memberof DataTable#oApi
2469	 */
2470	function _fnGetCellData( settings, rowIdx, colIdx, type )
2471	{
2472		var draw           = settings.iDraw;
2473		var col            = settings.aoColumns[colIdx];
2474		var rowData        = settings.aoData[rowIdx]._aData;
2475		var defaultContent = col.sDefaultContent;
2476		var cellData       = col.fnGetData( rowData, type, {
2477			settings: settings,
2478			row:      rowIdx,
2479			col:      colIdx
2480		} );
2481	
2482		if ( cellData === undefined ) {
2483			if ( settings.iDrawError != draw && defaultContent === null ) {
2484				_fnLog( settings, 0, "Requested unknown parameter "+
2485					(typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
2486					" for row "+rowIdx+", column "+colIdx, 4 );
2487				settings.iDrawError = draw;
2488			}
2489			return defaultContent;
2490		}
2491	
2492		// When the data source is null and a specific data type is requested (i.e.
2493		// not the original data), we can use default column data
2494		if ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {
2495			cellData = defaultContent;
2496		}
2497		else if ( typeof cellData === 'function' ) {
2498			// If the data source is a function, then we run it and use the return,
2499			// executing in the scope of the data object (for instances)
2500			return cellData.call( rowData );
2501		}
2502	
2503		if ( cellData === null && type == 'display' ) {
2504			return '';
2505		}
2506		return cellData;
2507	}
2508	
2509	
2510	/**
2511	 * Set the value for a specific cell, into the internal data cache
2512	 *  @param {object} settings dataTables settings object
2513	 *  @param {int} rowIdx aoData row id
2514	 *  @param {int} colIdx Column index
2515	 *  @param {*} val Value to set
2516	 *  @memberof DataTable#oApi
2517	 */
2518	function _fnSetCellData( settings, rowIdx, colIdx, val )
2519	{
2520		var col     = settings.aoColumns[colIdx];
2521		var rowData = settings.aoData[rowIdx]._aData;
2522	
2523		col.fnSetData( rowData, val, {
2524			settings: settings,
2525			row:      rowIdx,
2526			col:      colIdx
2527		}  );
2528	}
2529	
2530	
2531	// Private variable that is used to match action syntax in the data property object
2532	var __reArray = /\[.*?\]$/;
2533	var __reFn = /\(\)$/;
2534	
2535	/**
2536	 * Split string on periods, taking into account escaped periods
2537	 * @param  {string} str String to split
2538	 * @return {array} Split string
2539	 */
2540	function _fnSplitObjNotation( str )
2541	{
2542		return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
2543			return s.replace(/\\\./g, '.');
2544		} );
2545	}
2546	
2547	
2548	/**
2549	 * Return a function that can be used to get data from a source object, taking
2550	 * into account the ability to use nested objects as a source
2551	 *  @param {string|int|function} mSource The data source for the object
2552	 *  @returns {function} Data get function
2553	 *  @memberof DataTable#oApi
2554	 */
2555	function _fnGetObjectDataFn( mSource )
2556	{
2557		if ( $.isPlainObject( mSource ) )
2558		{
2559			/* Build an object of get functions, and wrap them in a single call */
2560			var o = {};
2561			$.each( mSource, function (key, val) {
2562				if ( val ) {
2563					o[key] = _fnGetObjectDataFn( val );
2564				}
2565			} );
2566	
2567			return function (data, type, row, meta) {
2568				var t = o[type] || o._;
2569				return t !== undefined ?
2570					t(data, type, row, meta) :
2571					data;
2572			};
2573		}
2574		else if ( mSource === null )
2575		{
2576			/* Give an empty string for rendering / sorting etc */
2577			return function (data) { // type, row and meta also passed, but not used
2578				return data;
2579			};
2580		}
2581		else if ( typeof mSource === 'function' )
2582		{
2583			return function (data, type, row, meta) {
2584				return mSource( data, type, row, meta );
2585			};
2586		}
2587		else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2588			      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
2589		{
2590			/* If there is a . in the source string then the data source is in a
2591			 * nested object so we loop over the data for each level to get the next
2592			 * level down. On each loop we test for undefined, and if found immediately
2593			 * return. This allows entire objects to be missing and sDefaultContent to
2594			 * be used if defined, rather than throwing an error
2595			 */
2596			var fetchData = function (data, type, src) {
2597				var arrayNotation, funcNotation, out, innerSrc;
2598	
2599				if ( src !== "" )
2600				{
2601					var a = _fnSplitObjNotation( src );
2602	
2603					for ( var i=0, iLen=a.length ; i<iLen ; i++ )
2604					{
2605						// Check if we are dealing with special notation
2606						arrayNotation = a[i].match(__reArray);
2607						funcNotation = a[i].match(__reFn);
2608	
2609						if ( arrayNotation )
2610						{
2611							// Array notation
2612							a[i] = a[i].replace(__reArray, '');
2613	
2614							// Condition allows simply [] to be passed in
2615							if ( a[i] !== "" ) {
2616								data = data[ a[i] ];
2617							}
2618							out = [];
2619	
2620							// Get the remainder of the nested object to get
2621							a.splice( 0, i+1 );
2622							innerSrc = a.join('.');
2623	
2624							// Traverse each entry in the array getting the properties requested
2625							if ( $.isArray( data ) ) {
2626								for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
2627									out.push( fetchData( data[j], type, innerSrc ) );
2628								}
2629							}
2630	
2631							// If a string is given in between the array notation indicators, that
2632							// is used to join the strings together, otherwise an array is returned
2633							var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
2634							data = (join==="") ? out : out.join(join);
2635	
2636							// The inner call to fetchData has already traversed through the remainder
2637							// of the source requested, so we exit from the loop
2638							break;
2639						}
2640						else if ( funcNotation )
2641						{
2642							// Function call
2643							a[i] = a[i].replace(__reFn, '');
2644							data = data[ a[i] ]();
2645							continue;
2646						}
2647	
2648						if ( data === null || data[ a[i] ] === undefined )
2649						{
2650							return undefined;
2651						}
2652						data = data[ a[i] ];
2653					}
2654				}
2655	
2656				return data;
2657			};
2658	
2659			return function (data, type) { // row and meta also passed, but not used
2660				return fetchData( data, type, mSource );
2661			};
2662		}
2663		else
2664		{
2665			/* Array or flat object mapping */
2666			return function (data, type) { // row and meta also passed, but not used
2667				return data[mSource];
2668			};
2669		}
2670	}
2671	
2672	
2673	/**
2674	 * Return a function that can be used to set data from a source object, taking
2675	 * into account the ability to use nested objects as a source
2676	 *  @param {string|int|function} mSource The data source for the object
2677	 *  @returns {function} Data set function
2678	 *  @memberof DataTable#oApi
2679	 */
2680	function _fnSetObjectDataFn( mSource )
2681	{
2682		if ( $.isPlainObject( mSource ) )
2683		{
2684			/* Unlike get, only the underscore (global) option is used for for
2685			 * setting data since we don't know the type here. This is why an object
2686			 * option is not documented for `mData` (which is read/write), but it is
2687			 * for `mRender` which is read only.
2688			 */
2689			return _fnSetObjectDataFn( mSource._ );
2690		}
2691		else if ( mSource === null )
2692		{
2693			/* Nothing to do when the data source is null */
2694			return function () {};
2695		}
2696		else if ( typeof mSource === 'function' )
2697		{
2698			return function (data, val, meta) {
2699				mSource( data, 'set', val, meta );
2700			};
2701		}
2702		else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2703			      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
2704		{
2705			/* Like the get, we need to get data from a nested object */
2706			var setData = function (data, val, src) {
2707				var a = _fnSplitObjNotation( src ), b;
2708				var aLast = a[a.length-1];
2709				var arrayNotation, funcNotation, o, innerSrc;
2710	
2711				for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
2712				{
2713					// Check if we are dealing with an array notation request
2714					arrayNotation = a[i].match(__reArray);
2715					funcNotation = a[i].match(__reFn);
2716	
2717					if ( arrayNotation )
2718					{
2719						a[i] = a[i].replace(__reArray, '');
2720						data[ a[i] ] = [];
2721	
2722						// Get the remainder of the nested object to set so we can recurse
2723						b = a.slice();
2724						b.splice( 0, i+1 );
2725						innerSrc = b.join('.');
2726	
2727						// Traverse each entry in the array setting the properties requested
2728						if ( $.isArray( val ) )
2729						{
2730							for ( var j=0, jLen=val.length ; j<jLen ; j++ )
2731							{
2732								o = {};
2733								setData( o, val[j], innerSrc );
2734								data[ a[i] ].push( o );
2735							}
2736						}
2737						else
2738						{
2739							// We've been asked to save data to an array, but it
2740							// isn't array data to be saved. Best that can be done
2741							// is to just save the value.
2742							data[ a[i] ] = val;
2743						}
2744	
2745						// The inner call to setData has already traversed through the remainder
2746						// of the source and has set the data, thus we can exit here
2747						return;
2748					}
2749					else if ( funcNotation )
2750					{
2751						// Function call
2752						a[i] = a[i].replace(__reFn, '');
2753						data = data[ a[i] ]( val );
2754					}
2755	
2756					// If the nested object doesn't currently exist - since we are
2757					// trying to set the value - create it
2758					if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
2759					{
2760						data[ a[i] ] = {};
2761					}
2762					data = data[ a[i] ];
2763				}
2764	
2765				// Last item in the input - i.e, the actual set
2766				if ( aLast.match(__reFn ) )
2767				{
2768					// Function call
2769					data = data[ aLast.replace(__reFn, '') ]( val );
2770				}
2771				else
2772				{
2773					// If array notation is used, we just want to strip it and use the property name
2774					// and assign the value. If it isn't used, then we get the result we want anyway
2775					data[ aLast.replace(__reArray, '') ] = val;
2776				}
2777			};
2778	
2779			return function (data, val) { // meta is also passed in, but not used
2780				return setData( data, val, mSource );
2781			};
2782		}
2783		else
2784		{
2785			/* Array or flat object mapping */
2786			return function (data, val) { // meta is also passed in, but not used
2787				data[mSource] = val;
2788			};
2789		}
2790	}
2791	
2792	
2793	/**
2794	 * Return an array with the full table data
2795	 *  @param {object} oSettings dataTables settings object
2796	 *  @returns array {array} aData Master data array
2797	 *  @memberof DataTable#oApi
2798	 */
2799	function _fnGetDataMaster ( settings )
2800	{
2801		return _pluck( settings.aoData, '_aData' );
2802	}
2803	
2804	
2805	/**
2806	 * Nuke the table
2807	 *  @param {object} oSettings dataTables settings object
2808	 *  @memberof DataTable#oApi
2809	 */
2810	function _fnClearTable( settings )
2811	{
2812		settings.aoData.length = 0;
2813		settings.aiDisplayMaster.length = 0;
2814		settings.aiDisplay.length = 0;
2815		settings.aIds = {};
2816	}
2817	
2818	
2819	 /**
2820	 * Take an array of integers (index array) and remove a target integer (value - not
2821	 * the key!)
2822	 *  @param {array} a Index array to target
2823	 *  @param {int} iTarget value to find
2824	 *  @memberof DataTable#oApi
2825	 */
2826	function _fnDeleteIndex( a, iTarget, splice )
2827	{
2828		var iTargetIndex = -1;
2829	
2830		for ( var i=0, iLen=a.length ; i<iLen ; i++ )
2831		{
2832			if ( a[i] == iTarget )
2833			{
2834				iTargetIndex = i;
2835			}
2836			else if ( a[i] > iTarget )
2837			{
2838				a[i]--;
2839			}
2840		}
2841	
2842		if ( iTargetIndex != -1 && splice === undefined )
2843		{
2844			a.splice( iTargetIndex, 1 );
2845		}
2846	}
2847	
2848	
2849	/**
2850	 * Mark cached data as invalid such that a re-read of the data will occur when
2851	 * the cached data is next requested. Also update from the data source object.
2852	 *
2853	 * @param {object} settings DataTables settings object
2854	 * @param {int}    rowIdx   Row index to invalidate
2855	 * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'
2856	 *     or 'data'
2857	 * @param {int}    [colIdx] Column index to invalidate. If undefined the whole
2858	 *     row will be invalidated
2859	 * @memberof DataTable#oApi
2860	 *
2861	 * @todo For the modularisation of v1.11 this will need to become a callback, so
2862	 *   the sort and filter methods can subscribe to it. That will required
2863	 *   initialisation options for sorting, which is why it is not already baked in
2864	 */
2865	function _fnInvalidate( settings, rowIdx, src, colIdx )
2866	{
2867		var row = settings.aoData[ rowIdx ];
2868		var i, ien;
2869		var cellWrite = function ( cell, col ) {
2870			// This is very frustrating, but in IE if you just write directly
2871			// to innerHTML, and elements that are overwritten are GC'ed,
2872			// even if there is a reference to them elsewhere
2873			while ( cell.childNodes.length ) {
2874				cell.removeChild( cell.firstChild );
2875			}
2876	
2877			cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
2878		};
2879	
2880		// Are we reading last data from DOM or the data object?
2881		if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
2882			// Read the data from the DOM
2883			row._aData = _fnGetRowElements(
2884					settings, row, colIdx, colIdx === undefined ? undefined : row._aData
2885				)
2886				.data;
2887		}
2888		else {
2889			// Reading from data object, update the DOM
2890			var cells = row.anCells;
2891	
2892			if ( cells ) {
2893				if ( colIdx !== undefined ) {
2894					cellWrite( cells[colIdx], colIdx );
2895				}
2896				else {
2897					for ( i=0, ien=cells.length ; i<ien ; i++ ) {
2898						cellWrite( cells[i], i );
2899					}
2900				}
2901			}
2902		}
2903	
2904		// For both row and cell invalidation, the cached data for sorting and
2905		// filtering is nulled out
2906		row._aSortData = null;
2907		row._aFilterData = null;
2908	
2909		// Invalidate the type for a specific column (if given) or all columns since
2910		// the data might have changed
2911		var cols = settings.aoColumns;
2912		if ( colIdx !== undefined ) {
2913			cols[ colIdx ].sType = null;
2914		}
2915		else {
2916			for ( i=0, ien=cols.length ; i<ien ; i++ ) {
2917				cols[i].sType = null;
2918			}
2919	
2920			// Update DataTables special `DT_*` attributes for the row
2921			_fnRowAttributes( settings, row );
2922		}
2923	}
2924	
2925	
2926	/**
2927	 * Build a data source object from an HTML row, reading the contents of the
2928	 * cells that are in the row.
2929	 *
2930	 * @param {object} settings DataTables settings object
2931	 * @param {node|object} TR element from which to read data or existing row
2932	 *   object from which to re-read the data from the cells
2933	 * @param {int} [colIdx] Optional column index
2934	 * @param {array|object} [d] Data source object. If `colIdx` is given then this
2935	 *   parameter should also be given and will be used to write the data into.
2936	 *   Only the column in question will be written
2937	 * @returns {object} Object with two parameters: `data` the data read, in
2938	 *   document order, and `cells` and array of nodes (they can be useful to the
2939	 *   caller, so rather than needing a second traversal to get them, just return
2940	 *   them from here).
2941	 * @memberof DataTable#oApi
2942	 */
2943	function _fnGetRowElements( settings, row, colIdx, d )
2944	{
2945		var
2946			tds = [],
2947			td = row.firstChild,
2948			name, col, o, i=0, contents,
2949			columns = settings.aoColumns,
2950			objectRead = settings._rowReadObject;
2951	
2952		// Allow the data object to be passed in, or construct
2953		d = d !== undefined ?
2954			d :
2955			objectRead ?
2956				{} :
2957				[];
2958	
2959		var attr = function ( str, td  ) {
2960			if ( typeof str === 'string' ) {
2961				var idx = str.indexOf('@');
2962	
2963				if ( idx !== -1 ) {
2964					var attr = str.substring( idx+1 );
2965					var setter = _fnSetObjectDataFn( str );
2966					setter( d, td.getAttribute( attr ) );
2967				}
2968			}
2969		};
2970	
2971		// Read data from a cell and store into the data object
2972		var cellProcess = function ( cell ) {
2973			if ( colIdx === undefined || colIdx === i ) {
2974				col = columns[i];
2975				contents = $.trim(cell.innerHTML);
2976	
2977				if ( col && col._bAttrSrc ) {
2978					var setter = _fnSetObjectDataFn( col.mData._ );
2979					setter( d, contents );
2980	
2981					attr( col.mData.sort, cell );
2982					attr( col.mData.type, cell );
2983					attr( col.mData.filter, cell );
2984				}
2985				else {
2986					// Depending on the `data` option for the columns the data can
2987					// be read to either an object or an array.
vendor: 11,978 bytes, lines 2988-3445
2988					if ( objectRead ) {
2989						if ( ! col._setter ) {
2990							// Cache the setter function
2991							col._setter = _fnSetObjectDataFn( col.mData );
2992						}
2993						col._setter( d, contents );
2994					}
2995					else {
2996						d[i] = contents;
2997					}
2998				}
2999			}
3000	
3001			i++;
3002		};
3003	
3004		if ( td ) {
3005			// `tr` element was passed in
3006			while ( td ) {
3007				name = td.nodeName.toUpperCase();
3008	
3009				if ( name == "TD" || name == "TH" ) {
3010					cellProcess( td );
3011					tds.push( td );
3012				}
3013	
3014				td = td.nextSibling;
3015			}
3016		}
3017		else {
3018			// Existing row object passed in
3019			tds = row.anCells;
3020	
3021			for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
3022				cellProcess( tds[j] );
3023			}
3024		}
3025	
3026		// Read the ID from the DOM if present
3027		var rowNode = row.firstChild ? row : row.nTr;
3028	
3029		if ( rowNode ) {
3030			var id = rowNode.getAttribute( 'id' );
3031	
3032			if ( id ) {
3033				_fnSetObjectDataFn( settings.rowId )( d, id );
3034			}
3035		}
3036	
3037		return {
3038			data: d,
3039			cells: tds
3040		};
3041	}
3042	/**
3043	 * Create a new TR element (and it's TD children) for a row
3044	 *  @param {object} oSettings dataTables settings object
3045	 *  @param {int} iRow Row to consider
3046	 *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,
3047	 *    DataTables will create a row automatically
3048	 *  @param {array} [anTds] Array of TD|TH elements for the row - must be given
3049	 *    if nTr is.
3050	 *  @memberof DataTable#oApi
3051	 */
3052	function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
3053	{
3054		var
3055			row = oSettings.aoData[iRow],
3056			rowData = row._aData,
3057			cells = [],
3058			nTr, nTd, oCol,
3059			i, iLen;
3060	
3061		if ( row.nTr === null )
3062		{
3063			nTr = nTrIn || document.createElement('tr');
3064	
3065			row.nTr = nTr;
3066			row.anCells = cells;
3067	
3068			/* Use a private property on the node to allow reserve mapping from the node
3069			 * to the aoData array for fast look up
3070			 */
3071			nTr._DT_RowIndex = iRow;
3072	
3073			/* Special parameters can be given by the data source to be used on the row */
3074			_fnRowAttributes( oSettings, row );
3075	
3076			/* Process each column */
3077			for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
3078			{
3079				oCol = oSettings.aoColumns[i];
3080	
3081				nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
3082				nTd._DT_CellIndex = {
3083					row: iRow,
3084					column: i
3085				};
3086				
3087				cells.push( nTd );
3088	
3089				// Need to create the HTML if new, or if a rendering function is defined
3090				if ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&
3091					 (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')
3092				) {
3093					nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
3094				}
3095	
3096				/* Add user defined class */
3097				if ( oCol.sClass )
3098				{
3099					nTd.className += ' '+oCol.sClass;
3100				}
3101	
3102				// Visibility - add or remove as required
3103				if ( oCol.bVisible && ! nTrIn )
3104				{
3105					nTr.appendChild( nTd );
3106				}
3107				else if ( ! oCol.bVisible && nTrIn )
3108				{
3109					nTd.parentNode.removeChild( nTd );
3110				}
3111	
3112				if ( oCol.fnCreatedCell )
3113				{
3114					oCol.fnCreatedCell.call( oSettings.oInstance,
3115						nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
3116					);
3117				}
3118			}
3119	
3120			_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
3121		}
3122	
3123		// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
3124		// and deployed
3125		row.nTr.setAttribute( 'role', 'row' );
3126	}
3127	
3128	
3129	/**
3130	 * Add attributes to a row based on the special `DT_*` parameters in a data
3131	 * source object.
3132	 *  @param {object} settings DataTables settings object
3133	 *  @param {object} DataTables row object for the row to be modified
3134	 *  @memberof DataTable#oApi
3135	 */
3136	function _fnRowAttributes( settings, row )
3137	{
3138		var tr = row.nTr;
3139		var data = row._aData;
3140	
3141		if ( tr ) {
3142			var id = settings.rowIdFn( data );
3143	
3144			if ( id ) {
3145				tr.id = id;
3146			}
3147	
3148			if ( data.DT_RowClass ) {
3149				// Remove any classes added by DT_RowClass before
3150				var a = data.DT_RowClass.split(' ');
3151				row.__rowc = row.__rowc ?
3152					_unique( row.__rowc.concat( a ) ) :
3153					a;
3154	
3155				$(tr)
3156					.removeClass( row.__rowc.join(' ') )
3157					.addClass( data.DT_RowClass );
3158			}
3159	
3160			if ( data.DT_RowAttr ) {
3161				$(tr).attr( data.DT_RowAttr );
3162			}
3163	
3164			if ( data.DT_RowData ) {
3165				$(tr).data( data.DT_RowData );
3166			}
3167		}
3168	}
3169	
3170	
3171	/**
3172	 * Create the HTML header for the table
3173	 *  @param {object} oSettings dataTables settings object
3174	 *  @memberof DataTable#oApi
3175	 */
3176	function _fnBuildHead( oSettings )
3177	{
3178		var i, ien, cell, row, column;
3179		var thead = oSettings.nTHead;
3180		var tfoot = oSettings.nTFoot;
3181		var createHeader = $('th, td', thead).length === 0;
3182		var classes = oSettings.oClasses;
3183		var columns = oSettings.aoColumns;
3184	
3185		if ( createHeader ) {
3186			row = $('<tr/>').appendTo( thead );
3187		}
3188	
3189		for ( i=0, ien=columns.length ; i<ien ; i++ ) {
3190			column = columns[i];
3191			cell = $( column.nTh ).addClass( column.sClass );
3192	
3193			if ( createHeader ) {
3194				cell.appendTo( row );
3195			}
3196	
3197			// 1.11 move into sorting
3198			if ( oSettings.oFeatures.bSort ) {
3199				cell.addClass( column.sSortingClass );
3200	
3201				if ( column.bSortable !== false ) {
3202					cell
3203						.attr( 'tabindex', oSettings.iTabIndex )
3204						.attr( 'aria-controls', oSettings.sTableId );
3205	
3206					_fnSortAttachListener( oSettings, column.nTh, i );
3207				}
3208			}
3209	
3210			if ( column.sTitle != cell[0].innerHTML ) {
3211				cell.html( column.sTitle );
3212			}
3213	
3214			_fnRenderer( oSettings, 'header' )(
3215				oSettings, cell, column, classes
3216			);
3217		}
3218	
3219		if ( createHeader ) {
3220			_fnDetectHeader( oSettings.aoHeader, thead );
3221		}
3222		
3223		/* ARIA role for the rows */
3224	 	$(thead).find('>tr').attr('role', 'row');
3225	
3226		/* Deal with the footer - add classes if required */
3227		$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
3228		$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
3229	
3230		// Cache the footer cells. Note that we only take the cells from the first
3231		// row in the footer. If there is more than one row the user wants to
3232		// interact with, they need to use the table().foot() method. Note also this
3233		// allows cells to be used for multiple columns using colspan
3234		if ( tfoot !== null ) {
3235			var cells = oSettings.aoFooter[0];
3236	
3237			for ( i=0, ien=cells.length ; i<ien ; i++ ) {
3238				column = columns[i];
3239				column.nTf = cells[i].cell;
3240	
3241				if ( column.sClass ) {
3242					$(column.nTf).addClass( column.sClass );
3243				}
3244			}
3245		}
3246	}
3247	
3248	
3249	/**
3250	 * Draw the header (or footer) element based on the column visibility states. The
3251	 * methodology here is to use the layout array from _fnDetectHeader, modified for
3252	 * the instantaneous column visibility, to construct the new layout. The grid is
3253	 * traversed over cell at a time in a rows x columns grid fashion, although each
3254	 * cell insert can cover multiple elements in the grid - which is tracks using the
3255	 * aApplied array. Cell inserts in the grid will only occur where there isn't
3256	 * already a cell in that position.
3257	 *  @param {object} oSettings dataTables settings object
3258	 *  @param array {objects} aoSource Layout array from _fnDetectHeader
3259	 *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
3260	 *  @memberof DataTable#oApi
3261	 */
3262	function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
3263	{
3264		var i, iLen, j, jLen, k, kLen, n, nLocalTr;
3265		var aoLocal = [];
3266		var aApplied = [];
3267		var iColumns = oSettings.aoColumns.length;
3268		var iRowspan, iColspan;
3269	
3270		if ( ! aoSource )
3271		{
3272			return;
3273		}
3274	
3275		if (  bIncludeHidden === undefined )
3276		{
3277			bIncludeHidden = false;
3278		}
3279	
3280		/* Make a copy of the master layout array, but without the visible columns in it */
3281		for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
3282		{
3283			aoLocal[i] = aoSource[i].slice();
3284			aoLocal[i].nTr = aoSource[i].nTr;
3285	
3286			/* Remove any columns which are currently hidden */
3287			for ( j=iColumns-1 ; j>=0 ; j-- )
3288			{
3289				if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
3290				{
3291					aoLocal[i].splice( j, 1 );
3292				}
3293			}
3294	
3295			/* Prep the applied array - it needs an element for each row */
3296			aApplied.push( [] );
3297		}
3298	
3299		for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
3300		{
3301			nLocalTr = aoLocal[i].nTr;
3302	
3303			/* All cells are going to be replaced, so empty out the row */
3304			if ( nLocalTr )
3305			{
3306				while( (n = nLocalTr.firstChild) )
3307				{
3308					nLocalTr.removeChild( n );
3309				}
3310			}
3311	
3312			for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
3313			{
3314				iRowspan = 1;
3315				iColspan = 1;
3316	
3317				/* Check to see if there is already a cell (row/colspan) covering our target
3318				 * insert point. If there is, then there is nothing to do.
3319				 */
3320				if ( aApplied[i][j] === undefined )
3321				{
3322					nLocalTr.appendChild( aoLocal[i][j].cell );
3323					aApplied[i][j] = 1;
3324	
3325					/* Expand the cell to cover as many rows as needed */
3326					while ( aoLocal[i+iRowspan] !== undefined &&
3327					        aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
3328					{
3329						aApplied[i+iRowspan][j] = 1;
3330						iRowspan++;
3331					}
3332	
3333					/* Expand the cell to cover as many columns as needed */
3334					while ( aoLocal[i][j+iColspan] !== undefined &&
3335					        aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
3336					{
3337						/* Must update the applied array over the rows for the columns */
3338						for ( k=0 ; k<iRowspan ; k++ )
3339						{
3340							aApplied[i+k][j+iColspan] = 1;
3341						}
3342						iColspan++;
3343					}
3344	
3345					/* Do the actual expansion in the DOM */
3346					$(aoLocal[i][j].cell)
3347						.attr('rowspan', iRowspan)
3348						.attr('colspan', iColspan);
3349				}
3350			}
3351		}
3352	}
3353	
3354	
3355	/**
3356	 * Insert the required TR nodes into the table for display
3357	 *  @param {object} oSettings dataTables settings object
3358	 *  @memberof DataTable#oApi
3359	 */
3360	function _fnDraw( oSettings )
3361	{
3362		/* Provide a pre-callback function which can be used to cancel the draw is false is returned */
3363		var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
3364		if ( $.inArray( false, aPreDraw ) !== -1 )
3365		{
3366			_fnProcessingDisplay( oSettings, false );
3367			return;
3368		}
3369	
3370		var i, iLen, n;
3371		var anRows = [];
3372		var iRowCount = 0;
3373		var asStripeClasses = oSettings.asStripeClasses;
3374		var iStripes = asStripeClasses.length;
3375		var iOpenRows = oSettings.aoOpenRows.length;
3376		var oLang = oSettings.oLanguage;
3377		var iInitDisplayStart = oSettings.iInitDisplayStart;
3378		var bServerSide = _fnDataSource( oSettings ) == 'ssp';
3379		var aiDisplay = oSettings.aiDisplay;
3380	
3381		oSettings.bDrawing = true;
3382	
3383		/* Check and see if we have an initial draw position from state saving */
3384		if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
3385		{
3386			oSettings._iDisplayStart = bServerSide ?
3387				iInitDisplayStart :
3388				iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
3389					0 :
3390					iInitDisplayStart;
3391	
3392			oSettings.iInitDisplayStart = -1;
3393		}
3394	
3395		var iDisplayStart = oSettings._iDisplayStart;
3396		var iDisplayEnd = oSettings.fnDisplayEnd();
3397	
3398		/* Server-side processing draw intercept */
3399		if ( oSettings.bDeferLoading )
3400		{
3401			oSettings.bDeferLoading = false;
3402			oSettings.iDraw++;
3403			_fnProcessingDisplay( oSettings, false );
3404		}
3405		else if ( !bServerSide )
3406		{
3407			oSettings.iDraw++;
3408		}
3409		else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
3410		{
3411			return;
3412		}
3413	
3414		if ( aiDisplay.length !== 0 )
3415		{
3416			var iStart = bServerSide ? 0 : iDisplayStart;
3417			var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
3418	
3419			for ( var j=iStart ; j<iEnd ; j++ )
3420			{
3421				var iDataIndex = aiDisplay[j];
3422				var aoData = oSettings.aoData[ iDataIndex ];
3423				if ( aoData.nTr === null )
3424				{
3425					_fnCreateTr( oSettings, iDataIndex );
3426				}
3427	
3428				var nRow = aoData.nTr;
3429	
3430				/* Remove the old striping classes and then add the new one */
3431				if ( iStripes !== 0 )
3432				{
3433					var sStripe = asStripeClasses[ iRowCount % iStripes ];
3434					if ( aoData._sRowStripe != sStripe )
3435					{
3436						$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
3437						aoData._sRowStripe = sStripe;
3438					}
3439				}
3440	
3441				// Row callback functions - might want to manipulate the row
3442				// iRowCount and j are not currently documented. Are they at all
3443				// useful?
3444				_fnCallbackFire( oSettings, 'aoRowCallback', null,
3445					[nRow, aoData._aData, iRowCount, j
vendor: 9,503 bytes, lines 3445-3799
3445] );
3446	
3447				anRows.push( nRow );
3448				iRowCount++;
3449			}
3450		}
3451		else
3452		{
3453			/* Table is empty - create a row with an empty message in it */
3454			var sZero = oLang.sZeroRecords;
3455			if ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )
3456			{
3457				sZero = oLang.sLoadingRecords;
3458			}
3459			else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
3460			{
3461				sZero = oLang.sEmptyTable;
3462			}
3463	
3464			anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
3465				.append( $('<td />', {
3466					'valign':  'top',
3467					'colSpan': _fnVisbleColumns( oSettings ),
3468					'class':   oSettings.oClasses.sRowEmpty
3469				} ).html( sZero ) )[0];
3470		}
3471	
3472		/* Header and footer callbacks */
3473		_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
3474			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3475	
3476		_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
3477			_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
3478	
3479		var body = $(oSettings.nTBody);
3480	
3481		body.children().detach();
3482		body.append( $(anRows) );
3483	
3484		/* Call all required callback functions for the end of a draw */
3485		_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
3486	
3487		/* Draw is complete, sorting and filtering must be as well */
3488		oSettings.bSorted = false;
3489		oSettings.bFiltered = false;
3490		oSettings.bDrawing = false;
3491	}
3492	
3493	
3494	/**
3495	 * Redraw the table - taking account of the various features which are enabled
3496	 *  @param {object} oSettings dataTables settings object
3497	 *  @param {boolean} [holdPosition] Keep the current paging position. By default
3498	 *    the paging is reset to the first page
3499	 *  @memberof DataTable#oApi
3500	 */
3501	function _fnReDraw( settings, holdPosition )
3502	{
3503		var
3504			features = settings.oFeatures,
3505			sort     = features.bSort,
3506			filter   = features.bFilter;
3507	
3508		if ( sort ) {
3509			_fnSort( settings );
3510		}
3511	
3512		if ( filter ) {
3513			_fnFilterComplete( settings, settings.oPreviousSearch );
3514		}
3515		else {
3516			// No filtering, so we want to just use the display master
3517			settings.aiDisplay = settings.aiDisplayMaster.slice();
3518		}
3519	
3520		if ( holdPosition !== true ) {
3521			settings._iDisplayStart = 0;
3522		}
3523	
3524		// Let any modules know about the draw hold position state (used by
3525		// scrolling internally)
3526		settings._drawHold = holdPosition;
3527	
3528		_fnDraw( settings );
3529	
3530		settings._drawHold = false;
3531	}
3532	
3533	
3534	/**
3535	 * Add the options to the page HTML for the table
3536	 *  @param {object} oSettings dataTables settings object
3537	 *  @memberof DataTable#oApi
3538	 */
3539	function _fnAddOptionsHtml ( oSettings )
3540	{
3541		var classes = oSettings.oClasses;
3542		var table = $(oSettings.nTable);
3543		var holding = $('<div/>').insertBefore( table ); // Holding element for speed
3544		var features = oSettings.oFeatures;
3545	
3546		// All DataTables are wrapped in a div
3547		var insert = $('<div/>', {
3548			id:      oSettings.sTableId+'_wrapper',
3549			'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
3550		} );
3551	
3552		oSettings.nHolding = holding[0];
3553		oSettings.nTableWrapper = insert[0];
3554		oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
3555	
3556		/* Loop over the user set positioning and place the elements as needed */
3557		var aDom = oSettings.sDom.split('');
3558		var featureNode, cOption, nNewNode, cNext, sAttr, j;
3559		for ( var i=0 ; i<aDom.length ; i++ )
3560		{
3561			featureNode = null;
3562			cOption = aDom[i];
3563	
3564			if ( cOption == '<' )
3565			{
3566				/* New container div */
3567				nNewNode = $('<div/>')[0];
3568	
3569				/* Check to see if we should append an id and/or a class name to the container */
3570				cNext = aDom[i+1];
3571				if ( cNext == "'" || cNext == '"' )
3572				{
3573					sAttr = "";
3574					j = 2;
3575					while ( aDom[i+j] != cNext )
3576					{
3577						sAttr += aDom[i+j];
3578						j++;
3579					}
3580	
3581					/* Replace jQuery UI constants @todo depreciated */
3582					if ( sAttr == "H" )
3583					{
3584						sAttr = classes.sJUIHeader;
3585					}
3586					else if ( sAttr == "F" )
3587					{
3588						sAttr = classes.sJUIFooter;
3589					}
3590	
3591					/* The attribute can be in the format of "#id.class", "#id" or "class" This logic
3592					 * breaks the string into parts and applies them as needed
3593					 */
3594					if ( sAttr.indexOf('.') != -1 )
3595					{
3596						var aSplit = sAttr.split('.');
3597						nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
3598						nNewNode.className = aSplit[1];
3599					}
3600					else if ( sAttr.charAt(0) == "#" )
3601					{
3602						nNewNode.id = sAttr.substr(1, sAttr.length-1);
3603					}
3604					else
3605					{
3606						nNewNode.className = sAttr;
3607					}
3608	
3609					i += j; /* Move along the position array */
3610				}
3611	
3612				insert.append( nNewNode );
3613				insert = $(nNewNode);
3614			}
3615			else if ( cOption == '>' )
3616			{
3617				/* End container div */
3618				insert = insert.parent();
3619			}
3620			// @todo Move options into their own plugins?
3621			else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
3622			{
3623				/* Length */
3624				featureNode = _fnFeatureHtmlLength( oSettings );
3625			}
3626			else if ( cOption == 'f' && features.bFilter )
3627			{
3628				/* Filter */
3629				featureNode = _fnFeatureHtmlFilter( oSettings );
3630			}
3631			else if ( cOption == 'r' && features.bProcessing )
3632			{
3633				/* pRocessing */
3634				featureNode = _fnFeatureHtmlProcessing( oSettings );
3635			}
3636			else if ( cOption == 't' )
3637			{
3638				/* Table */
3639				featureNode = _fnFeatureHtmlTable( oSettings );
3640			}
3641			else if ( cOption ==  'i' && features.bInfo )
3642			{
3643				/* Info */
3644				featureNode = _fnFeatureHtmlInfo( oSettings );
3645			}
3646			else if ( cOption == 'p' && features.bPaginate )
3647			{
3648				/* Pagination */
3649				featureNode = _fnFeatureHtmlPaginate( oSettings );
3650			}
3651			else if ( DataTable.ext.feature.length !== 0 )
3652			{
3653				/* Plug-in features */
3654				var aoFeatures = DataTable.ext.feature;
3655				for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
3656				{
3657					if ( cOption == aoFeatures[k].cFeature )
3658					{
3659						featureNode = aoFeatures[k].fnInit( oSettings );
3660						break;
3661					}
3662				}
3663			}
3664	
3665			/* Add to the 2D features array */
3666			if ( featureNode )
3667			{
3668				var aanFeatures = oSettings.aanFeatures;
3669	
3670				if ( ! aanFeatures[cOption] )
3671				{
3672					aanFeatures[cOption] = [];
3673				}
3674	
3675				aanFeatures[cOption].push( featureNode );
3676				insert.append( featureNode );
3677			}
3678		}
3679	
3680		/* Built our DOM structure - replace the holding div with what we want */
3681		holding.replaceWith( insert );
3682		oSettings.nHolding = null;
3683	}
3684	
3685	
3686	/**
3687	 * Use the DOM source to create up an array of header cells. The idea here is to
3688	 * create a layout grid (array) of rows x columns, which contains a reference
3689	 * to the cell that that point in the grid (regardless of col/rowspan), such that
3690	 * any column / row could be removed and the new grid constructed
3691	 *  @param array {object} aLayout Array to store the calculated layout in
3692	 *  @param {node} nThead The header/footer element for the table
3693	 *  @memberof DataTable#oApi
3694	 */
3695	function _fnDetectHeader ( aLayout, nThead )
3696	{
3697		var nTrs = $(nThead).children('tr');
3698		var nTr, nCell;
3699		var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
3700		var bUnique;
3701		var fnShiftCol = function ( a, i, j ) {
3702			var k = a[i];
3703	                while ( k[j] ) {
3704				j++;
3705			}
3706			return j;
3707		};
3708	
3709		aLayout.splice( 0, aLayout.length );
3710	
3711		/* We know how many rows there are in the layout - so prep it */
3712		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
3713		{
3714			aLayout.push( [] );
3715		}
3716	
3717		/* Calculate a layout array */
3718		for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
3719		{
3720			nTr = nTrs[i];
3721			iColumn = 0;
3722	
3723			/* For every cell in the row... */
3724			nCell = nTr.firstChild;
3725			while ( nCell ) {
3726				if ( nCell.nodeName.toUpperCase() == "TD" ||
3727				     nCell.nodeName.toUpperCase() == "TH" )
3728				{
3729					/* Get the col and rowspan attributes from the DOM and sanitise them */
3730					iColspan = nCell.getAttribute('colspan') * 1;
3731					iRowspan = nCell.getAttribute('rowspan') * 1;
3732					iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
3733					iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
3734	
3735					/* There might be colspan cells already in this row, so shift our target
3736					 * accordingly
3737					 */
3738					iColShifted = fnShiftCol( aLayout, i, iColumn );
3739	
3740					/* Cache calculation for unique columns */
3741					bUnique = iColspan === 1 ? true : false;
3742	
3743					/* If there is col / rowspan, copy the information into the layout grid */
3744					for ( l=0 ; l<iColspan ; l++ )
3745					{
3746						for ( k=0 ; k<iRowspan ; k++ )
3747						{
3748							aLayout[i+k][iColShifted+l] = {
3749								"cell": nCell,
3750								"unique": bUnique
3751							};
3752							aLayout[i+k].nTr = nTr;
3753						}
3754					}
3755				}
3756				nCell = nCell.nextSibling;
3757			}
3758		}
3759	}
3760	
3761	
3762	/**
3763	 * Get an array of unique th elements, one for each column
3764	 *  @param {object} oSettings dataTables settings object
3765	 *  @param {node} nHeader automatically detect the layout from this node - optional
3766	 *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
3767	 *  @returns array {node} aReturn list of unique th's
3768	 *  @memberof DataTable#oApi
3769	 */
3770	function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
3771	{
3772		var aReturn = [];
3773		if ( !aLayout )
3774		{
3775			aLayout = oSettings.aoHeader;
3776			if ( nHeader )
3777			{
3778				aLayout = [];
3779				_fnDetectHeader( aLayout, nHeader );
3780			}
3781		}
3782	
3783		for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
3784		{
3785			for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
3786			{
3787				if ( aLayout[i][j].unique &&
3788					 (!aReturn[j] || !oSettings.bSortCellsTop) )
3789				{
3790					aReturn[j] = aLayout[i][j].cell;
3791				}
3792			}
3793		}
3794	
3795		return aReturn;
3796	}
3797	
3798	/**
3799	 * 
3799Create an Ajax call based on the table's settings, taking into account that
3800	 * parameters can have multiple forms, and backwards compatibility.
3801	 *
3802	 * @param {object} oSettings dataTables settings object
3803	 * @param {array} data Data to send to the server, required by
3804	 *     DataTables - may be augmented by developer callbacks
3805	 * @param {function} fn Callback function to run when data is obtained
3806	 */
3807	function _fnBuildAjax( oSettings, data, fn )
3808	{
3809		// Compatibility with 1.9-, allow fnServerData and event to manipulate
3810		_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
3811	
3812		// Convert to object based for 1.10+ if using the old array scheme which can
3813		// come from server-side processing or serverParams
3814		if ( data && $.isArray(data) ) {
3815			var tmp = {};
3816			var rbracket = /(.*?)\[\]$/;
3817	
3818			$.each( data, function (key, val) {
3819				var match = val.name.match(rbracket);
3820	
3821				if ( match ) {
3822					// Support for arrays
3823					var name = match[0];
3824	
3825					if ( ! tmp[ name ] ) {
3826						tmp[ name ] = [];
3827					}
3828					tmp[ name ].push( val.value );
3829				}
3830				else {
3831					tmp[val.name] = val.value;
3832				}
3833			} );
3834			data = tmp;
3835		}
3836	
3837		var ajaxData;
3838		var ajax = oSettings.ajax;
3839		var instance = oSettings.oInstance;
3840		var callback = function ( json ) {
3841			_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
3842			fn( json );
3843		};
3844	
3845		if ( $.isPlainObject( ajax ) && ajax.data )
3846		{
3847			ajaxData = ajax.data;
3848	
3849			var newData = $.isFunction( ajaxData ) ?
3850				ajaxData( data, oSettings ) :  // fn can manipulate data or return
3851				ajaxData;                      // an object object or array to merge
3852	
3853			// If the function returned something, use that alone
3854			data = $.isFunction( ajaxData ) && newData ?
3855				newData :
3856				$.extend( true, data, newData );
3857	
3858			// Remove the data property as we've resolved it already and don't want
3859			// jQuery to do it again (it is restored at the end of the function)
3860			delete ajax.data;
3861		}
3862	
3863		var baseAjax = {
3864			"data": data,
3865			"success": function (json) {
3866				var error = json.error || json.sError;
3867				if ( error ) {
3868					_fnLog( oSettings, 0, error );
3869				}
3870	
3871				oSettings.json = json;
3872				callback( json );
3873			},
3874			"dataType": "json",
3875			"cache": false,
3876			"type": oSettings.sServerMethod,
3877			"error": function (xhr, error, thrown) {
3878				var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
3879	
3880				if ( $.inArray( true, ret ) === -1 ) {
3881					if ( error == "parsererror" ) {
3882						_fnLog( oSettings, 0, 'Invalid JSON response', 1 );
3883					}
3884					else if ( xhr.readyState === 4 ) {
3885						_fnLog( oSettings, 0, 'Ajax error', 7 );
3886					}
3887				}
3888	
3889				_fnProcessingDisplay( oSettings, false );
3890			}
3891		};
3892	
3893		// Store the data submitted for the API
3894		oSettings.oAjaxData = data;
3895	
3896		// Allow plug-ins and external processes to modify the data
3897		_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
3898	
3899		if ( oSettings.fnServerData )
3900		{
3901			// DataTables 1.9- compatibility
3902			oSettings.fnServerData.call( instance,
3903				oSettings.sAjaxSource,
3904				$.map( data, function (val, key) { // Need to convert back to 1.9 trad format
3905					return { name: key, value: val };
3906				} ),
3907				callback,
3908				oSettings
3909			);
3910		}
3911		else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
3912		{
3913			// DataTables 1.9- compatibility
3914			oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
3915				url: ajax || oSettings.sAjaxSource
3916			} ) );
3917		}
3918		else if ( $.isFunction( ajax ) )
3919		{
3920			// Is a function - let the caller define what needs to be done
3921			oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
3922		}
3923		else
3924		{
3925			// Object to extend the base settings
3926			oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
3927	
3928			// Restore for next time around
3929			ajax.data = ajaxData;
3930		}
3931	}
3932	
3933	
3934	/**
3935	 * Update the table using an Ajax call
3936	 *  @param {object} settings dataTables settings object
3937	 *  @returns {boolean} Block the table drawing or not
3938	 *  @memberof DataTable#oApi
3939	 */
3940	function _fnAjaxUpdate( settings )
3941	{
3942		if ( settings.bAjaxDataGet ) {
3943			settings.iDraw++;
3944			_fnProcessingDisplay( settings, true );
3945	
3946			_fnBuildAjax(
3947				settings,
3948				_fnAjaxParameters( settings ),
3949				function(json) {
3950					_fnAjaxUpdateDraw( settings, json );
3951				}
3952			);
3953	
3954			return false;
vendor: 43,049 bytes, lines 3955-5429
3955		}
3956		return true;
3957	}
3958	
3959	
3960	/**
3961	 * Build up the parameters in an object needed for a server-side processing
3962	 * request. Note that this is basically done twice, is different ways - a modern
3963	 * method which is used by default in DataTables 1.10 which uses objects and
3964	 * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
3965	 * the sAjaxSource option is used in the initialisation, or the legacyAjax
3966	 * option is set.
3967	 *  @param {object} oSettings dataTables settings object
3968	 *  @returns {bool} block the table drawing or not
3969	 *  @memberof DataTable#oApi
3970	 */
3971	function _fnAjaxParameters( settings )
3972	{
3973		var
3974			columns = settings.aoColumns,
3975			columnCount = columns.length,
3976			features = settings.oFeatures,
3977			preSearch = settings.oPreviousSearch,
3978			preColSearch = settings.aoPreSearchCols,
3979			i, data = [], dataProp, column, columnSearch,
3980			sort = _fnSortFlatten( settings ),
3981			displayStart = settings._iDisplayStart,
3982			displayLength = features.bPaginate !== false ?
3983				settings._iDisplayLength :
3984				-1;
3985	
3986		var param = function ( name, value ) {
3987			data.push( { 'name': name, 'value': value } );
3988		};
3989	
3990		// DataTables 1.9- compatible method
3991		param( 'sEcho',          settings.iDraw );
3992		param( 'iColumns',       columnCount );
3993		param( 'sColumns',       _pluck( columns, 'sName' ).join(',') );
3994		param( 'iDisplayStart',  displayStart );
3995		param( 'iDisplayLength', displayLength );
3996	
3997		// DataTables 1.10+ method
3998		var d = {
3999			draw:    settings.iDraw,
4000			columns: [],
4001			order:   [],
4002			start:   displayStart,
4003			length:  displayLength,
4004			search:  {
4005				value: preSearch.sSearch,
4006				regex: preSearch.bRegex
4007			}
4008		};
4009	
4010		for ( i=0 ; i<columnCount ; i++ ) {
4011			column = columns[i];
4012			columnSearch = preColSearch[i];
4013			dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
4014	
4015			d.columns.push( {
4016				data:       dataProp,
4017				name:       column.sName,
4018				searchable: column.bSearchable,
4019				orderable:  column.bSortable,
4020				search:     {
4021					value: columnSearch.sSearch,
4022					regex: columnSearch.bRegex
4023				}
4024			} );
4025	
4026			param( "mDataProp_"+i, dataProp );
4027	
4028			if ( features.bFilter ) {
4029				param( 'sSearch_'+i,     columnSearch.sSearch );
4030				param( 'bRegex_'+i,      columnSearch.bRegex );
4031				param( 'bSearchable_'+i, column.bSearchable );
4032			}
4033	
4034			if ( features.bSort ) {
4035				param( 'bSortable_'+i, column.bSortable );
4036			}
4037		}
4038	
4039		if ( features.bFilter ) {
4040			param( 'sSearch', preSearch.sSearch );
4041			param( 'bRegex', preSearch.bRegex );
4042		}
4043	
4044		if ( features.bSort ) {
4045			$.each( sort, function ( i, val ) {
4046				d.order.push( { column: val.col, dir: val.dir } );
4047	
4048				param( 'iSortCol_'+i, val.col );
4049				param( 'sSortDir_'+i, val.dir );
4050			} );
4051	
4052			param( 'iSortingCols', sort.length );
4053		}
4054	
4055		// If the legacy.ajax parameter is null, then we automatically decide which
4056		// form to use, based on sAjaxSource
4057		var legacy = DataTable.ext.legacy.ajax;
4058		if ( legacy === null ) {
4059			return settings.sAjaxSource ? data : d;
4060		}
4061	
4062		// Otherwise, if legacy has been specified then we use that to decide on the
4063		// form
4064		return legacy ? data : d;
4065	}
4066	
4067	
4068	/**
4069	 * Data the data from the server (nuking the old) and redraw the table
4070	 *  @param {object} oSettings dataTables settings object
4071	 *  @param {object} json json data return from the server.
4072	 *  @param {string} json.sEcho Tracking flag for DataTables to match requests
4073	 *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
4074	 *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
4075	 *  @param {array} json.aaData The data to display on this page
4076	 *  @param {string} [json.sColumns] Column ordering (sName, comma separated)
4077	 *  @memberof DataTable#oApi
4078	 */
4079	function _fnAjaxUpdateDraw ( settings, json )
4080	{
4081		// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
4082		// Support both
4083		var compat = function ( old, modern ) {
4084			return json[old] !== undefined ? json[old] : json[modern];
4085		};
4086	
4087		var data = _fnAjaxDataSrc( settings, json );
4088		var draw            = compat( 'sEcho',                'draw' );
4089		var recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );
4090		var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
4091	
4092		if ( draw ) {
4093			// Protect against out of sequence returns
4094			if ( draw*1 < settings.iDraw ) {
4095				return;
4096			}
4097			settings.iDraw = draw * 1;
4098		}
4099	
4100		_fnClearTable( settings );
4101		settings._iRecordsTotal   = parseInt(recordsTotal, 10);
4102		settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
4103	
4104		for ( var i=0, ien=data.length ; i<ien ; i++ ) {
4105			_fnAddData( settings, data[i] );
4106		}
4107		settings.aiDisplay = settings.aiDisplayMaster.slice();
4108	
4109		settings.bAjaxDataGet = false;
4110		_fnDraw( settings );
4111	
4112		if ( ! settings._bInitComplete ) {
4113			_fnInitComplete( settings, json );
4114		}
4115	
4116		settings.bAjaxDataGet = true;
4117		_fnProcessingDisplay( settings, false );
4118	}
4119	
4120	
4121	/**
4122	 * Get the data from the JSON data source to use for drawing a table. Using
4123	 * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
4124	 * source object, or from a processing function.
4125	 *  @param {object} oSettings dataTables settings object
4126	 *  @param  {object} json Data source object / array from the server
4127	 *  @return {array} Array of data to use
4128	 */
4129	function _fnAjaxDataSrc ( oSettings, json )
4130	{
4131		var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
4132			oSettings.ajax.dataSrc :
4133			oSettings.sAjaxDataProp; // Compatibility with 1.9-.
4134	
4135		// Compatibility with 1.9-. In order to read from aaData, check if the
4136		// default has been changed, if not, check for aaData
4137		if ( dataSrc === 'data' ) {
4138			return json.aaData || json[dataSrc];
4139		}
4140	
4141		return dataSrc !== "" ?
4142			_fnGetObjectDataFn( dataSrc )( json ) :
4143			json;
4144	}
4145	
4146	/**
4147	 * Generate the node required for filtering text
4148	 *  @returns {node} Filter control element
4149	 *  @param {object} oSettings dataTables settings object
4150	 *  @memberof DataTable#oApi
4151	 */
4152	function _fnFeatureHtmlFilter ( settings )
4153	{
4154		var classes = settings.oClasses;
4155		var tableId = settings.sTableId;
4156		var language = settings.oLanguage;
4157		var previousSearch = settings.oPreviousSearch;
4158		var features = settings.aanFeatures;
4159		var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
4160	
4161		var str = language.sSearch;
4162		str = str.match(/_INPUT_/) ?
4163			str.replace('_INPUT_', input) :
4164			str+input;
4165	
4166		var filter = $('<div/>', {
4167				'id': ! features.f ? tableId+'_filter' : null,
4168				'class': classes.sFilter
4169			} )
4170			.append( $('<label/>' ).append( str ) );
4171	
4172		var searchFn = function() {
4173			/* Update all other filter input elements for the new display */
4174			var n = features.f;
4175			var val = !this.value ? "" : this.value; // mental IE8 fix :-(
4176	
4177			/* Now do the filter */
4178			if ( val != previousSearch.sSearch ) {
4179				_fnFilterComplete( settings, {
4180					"sSearch": val,
4181					"bRegex": previousSearch.bRegex,
4182					"bSmart": previousSearch.bSmart ,
4183					"bCaseInsensitive": previousSearch.bCaseInsensitive
4184				} );
4185	
4186				// Need to redraw, without resorting
4187				settings._iDisplayStart = 0;
4188				_fnDraw( settings );
4189			}
4190		};
4191	
4192		var searchDelay = settings.searchDelay !== null ?
4193			settings.searchDelay :
4194			_fnDataSource( settings ) === 'ssp' ?
4195				400 :
4196				0;
4197	
4198		var jqFilter = $('input', filter)
4199			.val( previousSearch.sSearch )
4200			.attr( 'placeholder', language.sSearchPlaceholder )
4201			.on(
4202				'keyup.DT search.DT input.DT paste.DT cut.DT',
4203				searchDelay ?
4204					_fnThrottle( searchFn, searchDelay ) :
4205					searchFn
4206			)
4207			.on( 'keypress.DT', function(e) {
4208				/* Prevent form submission */
4209				if ( e.keyCode == 13 ) {
4210					return false;
4211				}
4212			} )
4213			.attr('aria-controls', tableId);
4214	
4215		// Update the input elements whenever the table is filtered
4216		$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
4217			if ( settings === s ) {
4218				// IE9 throws an 'unknown error' if document.activeElement is used
4219				// inside an iframe or frame...
4220				try {
4221					if ( jqFilter[0] !== document.activeElement ) {
4222						jqFilter.val( previousSearch.sSearch );
4223					}
4224				}
4225				catch ( e ) {}
4226			}
4227		} );
4228	
4229		return filter[0];
4230	}
4231	
4232	
4233	/**
4234	 * Filter the table using both the global filter and column based filtering
4235	 *  @param {object} oSettings dataTables settings object
4236	 *  @param {object} oSearch search information
4237	 *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
4238	 *  @memberof DataTable#oApi
4239	 */
4240	function _fnFilterComplete ( oSettings, oInput, iForce )
4241	{
4242		var oPrevSearch = oSettings.oPreviousSearch;
4243		var aoPrevSearch = oSettings.aoPreSearchCols;
4244		var fnSaveFilter = function ( oFilter ) {
4245			/* Save the filtering values */
4246			oPrevSearch.sSearch = oFilter.sSearch;
4247			oPrevSearch.bRegex = oFilter.bRegex;
4248			oPrevSearch.bSmart = oFilter.bSmart;
4249			oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
4250		};
4251		var fnRegex = function ( o ) {
4252			// Backwards compatibility with the bEscapeRegex option
4253			return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
4254		};
4255	
4256		// Resolve any column types that are unknown due to addition or invalidation
4257		// @todo As per sort - can this be moved into an event handler?
4258		_fnColumnTypes( oSettings );
4259	
4260		/* In server-side processing all filtering is done by the server, so no point hanging around here */
4261		if ( _fnDataSource( oSettings ) != 'ssp' )
4262		{
4263			/* Global filter */
4264			_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
4265			fnSaveFilter( oInput );
4266	
4267			/* Now do the individual column filter */
4268			for ( var i=0 ; i<aoPrevSearch.length ; i++ )
4269			{
4270				_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
4271					aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
4272			}
4273	
4274			/* Custom filtering */
4275			_fnFilterCustom( oSettings );
4276		}
4277		else
4278		{
4279			fnSaveFilter( oInput );
4280		}
4281	
4282		/* Tell the draw function we have been filtering */
4283		oSettings.bFiltered = true;
4284		_fnCallbackFire( oSettings, null, 'search', [oSettings] );
4285	}
4286	
4287	
4288	/**
4289	 * Apply custom filtering functions
4290	 *  @param {object} oSettings dataTables settings object
4291	 *  @memberof DataTable#oApi
4292	 */
4293	function _fnFilterCustom( settings )
4294	{
4295		var filters = DataTable.ext.search;
4296		var displayRows = settings.aiDisplay;
4297		var row, rowIdx;
4298	
4299		for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
4300			var rows = [];
4301	
4302			// Loop over each row and see if it should be included
4303			for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
4304				rowIdx = displayRows[ j ];
4305				row = settings.aoData[ rowIdx ];
4306	
4307				if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
4308					rows.push( rowIdx );
4309				}
4310			}
4311	
4312			// So the array reference doesn't break set the results into the
4313			// existing array
4314			displayRows.length = 0;
4315			$.merge( displayRows, rows );
4316		}
4317	}
4318	
4319	
4320	/**
4321	 * Filter the table on a per-column basis
4322	 *  @param {object} oSettings dataTables settings object
4323	 *  @param {string} sInput string to filter on
4324	 *  @param {int} iColumn column to filter
4325	 *  @param {bool} bRegex treat search string as a regular expression or not
4326	 *  @param {bool} bSmart use smart filtering or not
4327	 *  @param {bool} bCaseInsensitive Do case insenstive matching or not
4328	 *  @memberof DataTable#oApi
4329	 */
4330	function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
4331	{
4332		if ( searchStr === '' ) {
4333			return;
4334		}
4335	
4336		var data;
4337		var out = [];
4338		var display = settings.aiDisplay;
4339		var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
4340	
4341		for ( var i=0 ; i<display.length ; i++ ) {
4342			data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
4343	
4344			if ( rpSearch.test( data ) ) {
4345				out.push( display[i] );
4346			}
4347		}
4348	
4349		settings.aiDisplay = out;
4350	}
4351	
4352	
4353	/**
4354	 * Filter the data table based on user input and draw the table
4355	 *  @param {object} settings dataTables settings object
4356	 *  @param {string} input string to filter on
4357	 *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
4358	 *  @param {bool} regex treat as a regular expression or not
4359	 *  @param {bool} smart perform smart filtering or not
4360	 *  @param {bool} caseInsensitive Do case insenstive matching or not
4361	 *  @memberof DataTable#oApi
4362	 */
4363	function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
4364	{
4365		var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
4366		var prevSearch = settings.oPreviousSearch.sSearch;
4367		var displayMaster = settings.aiDisplayMaster;
4368		var display, invalidated, i;
4369		var filtered = [];
4370	
4371		// Need to take account of custom filtering functions - always filter
4372		if ( DataTable.ext.search.length !== 0 ) {
4373			force = true;
4374		}
4375	
4376		// Check if any of the rows were invalidated
4377		invalidated = _fnFilterData( settings );
4378	
4379		// If the input is blank - we just want the full data set
4380		if ( input.length <= 0 ) {
4381			settings.aiDisplay = displayMaster.slice();
4382		}
4383		else {
4384			// New search - start from the master array
4385			if ( invalidated ||
4386				 force ||
4387				 prevSearch.length > input.length ||
4388				 input.indexOf(prevSearch) !== 0 ||
4389				 settings.bSorted // On resort, the display master needs to be
4390				                  // re-filtered since indexes will have changed
4391			) {
4392				settings.aiDisplay = displayMaster.slice();
4393			}
4394	
4395			// Search the display array
4396			display = settings.aiDisplay;
4397	
4398			for ( i=0 ; i<display.length ; i++ ) {
4399				if ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
4400					filtered.push( display[i] );
4401				}
4402			}
4403	
4404			settings.aiDisplay = filtered;
4405		}
4406	}
4407	
4408	
4409	/**
4410	 * Build a regular expression object suitable for searching a table
4411	 *  @param {string} sSearch string to search for
4412	 *  @param {bool} bRegex treat as a regular expression or not
4413	 *  @param {bool} bSmart perform smart filtering or not
4414	 *  @param {bool} bCaseInsensitive Do case insensitive matching or not
4415	 *  @returns {RegExp} constructed object
4416	 *  @memberof DataTable#oApi
4417	 */
4418	function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
4419	{
4420		search = regex ?
4421			search :
4422			_fnEscapeRegex( search );
4423		
4424		if ( smart ) {
4425			/* For smart filtering we want to allow the search to work regardless of
4426			 * word order. We also want double quoted text to be preserved, so word
4427			 * order is important - a la google. So this is what we want to
4428			 * generate:
4429			 * 
4430			 * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
4431			 */
4432			var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
4433				if ( word.charAt(0) === '"' ) {
4434					var m = word.match( /^"(.*)"$/ );
4435					word = m ? m[1] : word;
4436				}
4437	
4438				return word.replace('"', '');
4439			} );
4440	
4441			search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
4442		}
4443	
4444		return new RegExp( search, caseInsensitive ? 'i' : '' );
4445	}
4446	
4447	
4448	/**
4449	 * Escape a string such that it can be used in a regular expression
4450	 *  @param {string} sVal string to escape
4451	 *  @returns {string} escaped string
4452	 *  @memberof DataTable#oApi
4453	 */
4454	var _fnEscapeRegex = DataTable.util.escapeRegex;
4455	
4456	var __filter_div = $('<div>')[0];
4457	var __filter_div_textContent = __filter_div.textContent !== undefined;
4458	
4459	// Update the filtering data for each row if needed (by invalidation or first run)
4460	function _fnFilterData ( settings )
4461	{
4462		var columns = settings.aoColumns;
4463		var column;
4464		var i, j, ien, jen, filterData, cellData, row;
4465		var fomatters = DataTable.ext.type.search;
4466		var wasInvalidated = false;
4467	
4468		for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4469			row = settings.aoData[i];
4470	
4471			if ( ! row._aFilterData ) {
4472				filterData = [];
4473	
4474				for ( j=0, jen=columns.length ; j<jen ; j++ ) {
4475					column = columns[j];
4476	
4477					if ( column.bSearchable ) {
4478						cellData = _fnGetCellData( settings, i, j, 'filter' );
4479	
4480						if ( fomatters[ column.sType ] ) {
4481							cellData = fomatters[ column.sType ]( cellData );
4482						}
4483	
4484						// Search in DataTables 1.10 is string based. In 1.11 this
4485						// should be altered to also allow strict type checking.
4486						if ( cellData === null ) {
4487							cellData = '';
4488						}
4489	
4490						if ( typeof cellData !== 'string' && cellData.toString ) {
4491							cellData = cellData.toString();
4492						}
4493					}
4494					else {
4495						cellData = '';
4496					}
4497	
4498					// If it looks like there is an HTML entity in the string,
4499					// attempt to decode it so sorting works as expected. Note that
4500					// we could use a single line of jQuery to do this, but the DOM
4501					// method used here is much faster http://jsperf.com/html-decode
4502					if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
4503						__filter_div.innerHTML = cellData;
4504						cellData = __filter_div_textContent ?
4505							__filter_div.textContent :
4506							__filter_div.innerText;
4507					}
4508	
4509					if ( cellData.replace ) {
4510						cellData = cellData.replace(/[\r\n]/g, '');
4511					}
4512	
4513					filterData.push( cellData );
4514				}
4515	
4516				row._aFilterData = filterData;
4517				row._sFilterRow = filterData.join('  ');
4518				wasInvalidated = true;
4519			}
4520		}
4521	
4522		return wasInvalidated;
4523	}
4524	
4525	
4526	/**
4527	 * Convert from the internal Hungarian notation to camelCase for external
4528	 * interaction
4529	 *  @param {object} obj Object to convert
4530	 *  @returns {object} Inverted object
4531	 *  @memberof DataTable#oApi
4532	 */
4533	function _fnSearchToCamel ( obj )
4534	{
4535		return {
4536			search:          obj.sSearch,
4537			smart:           obj.bSmart,
4538			regex:           obj.bRegex,
4539			caseInsensitive: obj.bCaseInsensitive
4540		};
4541	}
4542	
4543	
4544	
4545	/**
4546	 * Convert from camelCase notation to the internal Hungarian. We could use the
4547	 * Hungarian convert function here, but this is cleaner
4548	 *  @param {object} obj Object to convert
4549	 *  @returns {object} Inverted object
4550	 *  @memberof DataTable#oApi
4551	 */
4552	function _fnSearchToHung ( obj )
4553	{
4554		return {
4555			sSearch:          obj.search,
4556			bSmart:           obj.smart,
4557			bRegex:           obj.regex,
4558			bCaseInsensitive: obj.caseInsensitive
4559		};
4560	}
4561	
4562	/**
4563	 * Generate the node required for the info display
4564	 *  @param {object} oSettings dataTables settings object
4565	 *  @returns {node} Information element
4566	 *  @memberof DataTable#oApi
4567	 */
4568	function _fnFeatureHtmlInfo ( settings )
4569	{
4570		var
4571			tid = settings.sTableId,
4572			nodes = settings.aanFeatures.i,
4573			n = $('<div/>', {
4574				'class': settings.oClasses.sInfo,
4575				'id': ! nodes ? tid+'_info' : null
4576			} );
4577	
4578		if ( ! nodes ) {
4579			// Update display on each draw
4580			settings.aoDrawCallback.push( {
4581				"fn": _fnUpdateInfo,
4582				"sName": "information"
4583			} );
4584	
4585			n
4586				.attr( 'role', 'status' )
4587				.attr( 'aria-live', 'polite' );
4588	
4589			// Table is described by our info div
4590			$(settings.nTable).attr( 'aria-describedby', tid+'_info' );
4591		}
4592	
4593		return n[0];
4594	}
4595	
4596	
4597	/**
4598	 * Update the information elements in the display
4599	 *  @param {object} settings dataTables settings object
4600	 *  @memberof DataTable#oApi
4601	 */
4602	function _fnUpdateInfo ( settings )
4603	{
4604		/* Show information about the table */
4605		var nodes = settings.aanFeatures.i;
4606		if ( nodes.length === 0 ) {
4607			return;
4608		}
4609	
4610		var
4611			lang  = settings.oLanguage,
4612			start = settings._iDisplayStart+1,
4613			end   = settings.fnDisplayEnd(),
4614			max   = settings.fnRecordsTotal(),
4615			total = settings.fnRecordsDisplay(),
4616			out   = total ?
4617				lang.sInfo :
4618				lang.sInfoEmpty;
4619	
4620		if ( total !== max ) {
4621			/* Record set after filtering */
4622			out += ' ' + lang.sInfoFiltered;
4623		}
4624	
4625		// Convert the macros
4626		out += lang.sInfoPostFix;
4627		out = _fnInfoMacros( settings, out );
4628	
4629		var callback = lang.fnInfoCallback;
4630		if ( callback !== null ) {
4631			out = callback.call( settings.oInstance,
4632				settings, start, end, max, total, out
4633			);
4634		}
4635	
4636		$(nodes).html( out );
4637	}
4638	
4639	
4640	function _fnInfoMacros ( settings, str )
4641	{
4642		// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
4643		// internally
4644		var
4645			formatter  = settings.fnFormatNumber,
4646			start      = settings._iDisplayStart+1,
4647			len        = settings._iDisplayLength,
4648			vis        = settings.fnRecordsDisplay(),
4649			all        = len === -1;
4650	
4651		return str.
4652			replace(/_START_/g, formatter.call( settings, start ) ).
4653			replace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).
4654			replace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).
4655			replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
4656			replace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
4657			replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
4658	}
4659	
4660	
4661	
4662	/**
4663	 * Draw the table for the first time, adding all required features
4664	 *  @param {object} settings dataTables settings object
4665	 *  @memberof DataTable#oApi
4666	 */
4667	function _fnInitialise ( settings )
4668	{
4669		var i, iLen, iAjaxStart=settings.iInitDisplayStart;
4670		var columns = settings.aoColumns, column;
4671		var features = settings.oFeatures;
4672		var deferLoading = settings.bDeferLoading; // value modified by the draw
4673	
4674		/* Ensure that the table data is fully initialised */
4675		if ( ! settings.bInitialised ) {
4676			setTimeout( function(){ _fnInitialise( settings ); }, 200 );
4677			return;
4678		}
4679	
4680		/* Show the display HTML options */
4681		_fnAddOptionsHtml( settings );
4682	
4683		/* Build and draw the header / footer for the table */
4684		_fnBuildHead( settings );
4685		_fnDrawHead( settings, settings.aoHeader );
4686		_fnDrawHead( settings, settings.aoFooter );
4687	
4688		/* Okay to show that something is going on now */
4689		_fnProcessingDisplay( settings, true );
4690	
4691		/* Calculate sizes for columns */
4692		if ( features.bAutoWidth ) {
4693			_fnCalculateColumnWidths( settings );
4694		}
4695	
4696		for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
4697			column = columns[i];
4698	
4699			if ( column.sWidth ) {
4700				column.nTh.style.width = _fnStringToCss( column.sWidth );
4701			}
4702		}
4703	
4704		_fnCallbackFire( settings, null, 'preInit', [settings] );
4705	
4706		// If there is default sorting required - let's do it. The sort function
4707		// will do the drawing for us. Otherwise we draw the table regardless of the
4708		// Ajax source - this allows the table to look initialised for Ajax sourcing
4709		// data (show 'loading' message possibly)
4710		_fnReDraw( settings );
4711	
4712		// Server-side processing init complete is done by _fnAjaxUpdateDraw
4713		var dataSrc = _fnDataSource( settings );
4714		if ( dataSrc != 'ssp' || deferLoading ) {
4715			// if there is an ajax source load the data
4716			if ( dataSrc == 'ajax' ) {
4717				_fnBuildAjax( settings, [], function(json) {
4718					var aData = _fnAjaxDataSrc( settings, json );
4719	
4720					// Got the data - add it to the table
4721					for ( i=0 ; i<aData.length ; i++ ) {
4722						_fnAddData( settings, aData[i] );
4723					}
4724	
4725					// Reset the init display for cookie saving. We've already done
4726					// a filter, and therefore cleared it before. So we need to make
4727					// it appear 'fresh'
4728					settings.iInitDisplayStart = iAjaxStart;
4729	
4730					_fnReDraw( settings );
4731	
4732					_fnProcessingDisplay( settings, false );
4733					_fnInitComplete( settings, json );
4734				}, settings );
4735			}
4736			else {
4737				_fnProcessingDisplay( settings, false );
4738				_fnInitComplete( settings );
4739			}
4740		}
4741	}
4742	
4743	
4744	/**
4745	 * Draw the table for the first time, adding all required features
4746	 *  @param {object} oSettings dataTables settings object
4747	 *  @param {object} [json] JSON from the server that completed the table, if using Ajax source
4748	 *    with client-side processing (optional)
4749	 *  @memberof DataTable#oApi
4750	 */
4751	function _fnInitComplete ( settings, json )
4752	{
4753		settings._bInitComplete = true;
4754	
4755		// When data was added after the initialisation (data or Ajax) we need to
4756		// calculate the column sizing
4757		if ( json || settings.oInit.aaData ) {
4758			_fnAdjustColumnSizing( settings );
4759		}
4760	
4761		_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );
4762		_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
4763	}
4764	
4765	
4766	function _fnLengthChange ( settings, val )
4767	{
4768		var len = parseInt( val, 10 );
4769		settings._iDisplayLength = len;
4770	
4771		_fnLengthOverflow( settings );
4772	
4773		// Fire length change event
4774		_fnCallbackFire( settings, null, 'length', [settings, len] );
4775	}
4776	
4777	
4778	/**
4779	 * Generate the node required for user display length changing
4780	 *  @param {object} settings dataTables settings object
4781	 *  @returns {node} Display length feature node
4782	 *  @memberof DataTable#oApi
4783	 */
4784	function _fnFeatureHtmlLength ( settings )
4785	{
4786		var
4787			classes  = settings.oClasses,
4788			tableId  = settings.sTableId,
4789			menu     = settings.aLengthMenu,
4790			d2       = $.isArray( menu[0] ),
4791			lengths  = d2 ? menu[0] : menu,
4792			language = d2 ? menu[1] : menu;
4793	
4794		var select = $('<select/>', {
4795			'name':          tableId+'_length',
4796			'aria-controls': tableId,
4797			'class':         classes.sLengthSelect
4798		} );
4799	
4800		for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
4801			select[0][ i ] = new Option( language[i], lengths[i] );
4802		}
4803	
4804		var div = $('<div><label/></div>').addClass( classes.sLength );
4805		if ( ! settings.aanFeatures.l ) {
4806			div[0].id = tableId+'_length';
4807		}
4808	
4809		div.children().append(
4810			settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
4811		);
4812	
4813		// Can't use `select` variable as user might provide their own and the
4814		// reference is broken by the use of outerHTML
4815		$('select', div)
4816			.val( settings._iDisplayLength )
4817			.on( 'change.DT', function(e) {
4818				_fnLengthChange( settings, $(this).val() );
4819				_fnDraw( settings );
4820			} );
4821	
4822		// Update node value whenever anything changes the table's length
4823		$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {
4824			if ( settings === s ) {
4825				$('select', div).val( len );
4826			}
4827		} );
4828	
4829		return div[0];
4830	}
4831	
4832	
4833	
4834	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4835	 * Note that most of the paging logic is done in
4836	 * DataTable.ext.pager
4837	 */
4838	
4839	/**
4840	 * Generate the node required for default pagination
4841	 *  @param {object} oSettings dataTables settings object
4842	 *  @returns {node} Pagination feature node
4843	 *  @memberof DataTable#oApi
4844	 */
4845	function _fnFeatureHtmlPaginate ( settings )
4846	{
4847		var
4848			type   = settings.sPaginationType,
4849			plugin = DataTable.ext.pager[ type ],
4850			modern = typeof plugin === 'function',
4851			redraw = function( settings ) {
4852				_fnDraw( settings );
4853			},
4854			node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
4855			features = settings.aanFeatures;
4856	
4857		if ( ! modern ) {
4858			plugin.fnInit( settings, node, redraw );
4859		}
4860	
4861		/* Add a draw callback for the pagination on first instance, to update the paging display */
4862		if ( ! features.p )
4863		{
4864			node.id = settings.sTableId+'_paginate';
4865	
4866			settings.aoDrawCallback.push( {
4867				"fn": function( settings ) {
4868					if ( modern ) {
4869						var
4870							start      = settings._iDisplayStart,
4871							len        = settings._iDisplayLength,
4872							visRecords = settings.fnRecordsDisplay(),
4873							all        = len === -1,
4874							page = all ? 0 : Math.ceil( start / len ),
4875							pages = all ? 1 : Math.ceil( visRecords / len ),
4876							buttons = plugin(page, pages),
4877							i, ien;
4878	
4879						for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
4880							_fnRenderer( settings, 'pageButton' )(
4881								settings, features.p[i], i, buttons, page, pages
4882							);
4883						}
4884					}
4885					else {
4886						plugin.fnUpdate( settings, redraw );
4887					}
4888				},
4889				"sName": "pagination"
4890			} );
4891		}
4892	
4893		return node;
4894	}
4895	
4896	
4897	/**
4898	 * Alter the display settings to change the page
4899	 *  @param {object} settings DataTables settings object
4900	 *  @param {string|int} action Paging action to take: "first", "previous",
4901	 *    "next" or "last" or page number to jump to (integer)
4902	 *  @param [bool] redraw Automatically draw the update or not
4903	 *  @returns {bool} true page has changed, false - no change
4904	 *  @memberof DataTable#oApi
4905	 */
4906	function _fnPageChange ( settings, action, redraw )
4907	{
4908		var
4909			start     = settings._iDisplayStart,
4910			len       = settings._iDisplayLength,
4911			records   = settings.fnRecordsDisplay();
4912	
4913		if ( records === 0 || len === -1 )
4914		{
4915			start = 0;
4916		}
4917		else if ( typeof action === "number" )
4918		{
4919			start = action * len;
4920	
4921			if ( start > records )
4922			{
4923				start = 0;
4924			}
4925		}
4926		else if ( action == "first" )
4927		{
4928			start = 0;
4929		}
4930		else if ( action == "previous" )
4931		{
4932			start = len >= 0 ?
4933				start - len :
4934				0;
4935	
4936			if ( start < 0 )
4937			{
4938			  start = 0;
4939			}
4940		}
4941		else if ( action == "next" )
4942		{
4943			if ( start + len < records )
4944			{
4945				start += len;
4946			}
4947		}
4948		else if ( action == "last" )
4949		{
4950			start = Math.floor( (records-1) / len) * len;
4951		}
4952		else
4953		{
4954			_fnLog( settings, 0, "Unknown paging action: "+action, 5 );
4955		}
4956	
4957		var changed = settings._iDisplayStart !== start;
4958		settings._iDisplayStart = start;
4959	
4960		if ( changed ) {
4961			_fnCallbackFire( settings, null, 'page', [settings] );
4962	
4963			if ( redraw ) {
4964				_fnDraw( settings );
4965			}
4966		}
4967	
4968		return changed;
4969	}
4970	
4971	
4972	
4973	/**
4974	 * Generate the node required for the processing node
4975	 *  @param {object} settings dataTables settings object
4976	 *  @returns {node} Processing element
4977	 *  @memberof DataTable#oApi
4978	 */
4979	function _fnFeatureHtmlProcessing ( settings )
4980	{
4981		return $('<div/>', {
4982				'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
4983				'class': settings.oClasses.sProcessing
4984			} )
4985			.html( settings.oLanguage.sProcessing )
4986			.insertBefore( settings.nTable )[0];
4987	}
4988	
4989	
4990	/**
4991	 * Display or hide the processing indicator
4992	 *  @param {object} settings dataTables settings object
4993	 *  @param {bool} show Show the processing indicator (true) or not (false)
4994	 *  @memberof DataTable#oApi
4995	 */
4996	function _fnProcessingDisplay ( settings, show )
4997	{
4998		if ( settings.oFeatures.bProcessing ) {
4999			$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
5000		}
5001	
5002		_fnCallbackFire( settings, null, 'processing', [settings, show] );
5003	}
5004	
5005	/**
5006	 * Add any control elements for the table - specifically scrolling
5007	 *  @param {object} settings dataTables settings object
5008	 *  @returns {node} Node to add to the DOM
5009	 *  @memberof DataTable#oApi
5010	 */
5011	function _fnFeatureHtmlTable ( settings )
5012	{
5013		var table = $(settings.nTable);
5014	
5015		// Add the ARIA grid role to the table
5016		table.attr( 'role', 'grid' );
5017	
5018		// Scrolling from here on in
5019		var scroll = settings.oScroll;
5020	
5021		if ( scroll.sX === '' && scroll.sY === '' ) {
5022			return settings.nTable;
5023		}
5024	
5025		var scrollX = scroll.sX;
5026		var scrollY = scroll.sY;
5027		var classes = settings.oClasses;
5028		var caption = table.children('caption');
5029		var captionSide = caption.length ? caption[0]._captionSide : null;
5030		var headerClone = $( table[0].cloneNode(false) );
5031		var footerClone = $( table[0].cloneNode(false) );
5032		var footer = table.children('tfoot');
5033		var _div = '<div/>';
5034		var size = function ( s ) {
5035			return !s ? null : _fnStringToCss( s );
5036		};
5037	
5038		if ( ! footer.length ) {
5039			footer = null;
5040		}
5041	
5042		/*
5043		 * The HTML structure that we want to generate in this function is:
5044		 *  div - scroller
5045		 *    div - scroll head
5046		 *      div - scroll head inner
5047		 *        table - scroll head table
5048		 *          thead - thead
5049		 *    div - scroll body
5050		 *      table - table (master table)
5051		 *        thead - thead clone for sizing
5052		 *        tbody - tbody
5053		 *    div - scroll foot
5054		 *      div - scroll foot inner
5055		 *        table - scroll foot table
5056		 *          tfoot - tfoot
5057		 */
5058		var scroller = $( _div, { 'class': classes.sScrollWrapper } )
5059			.append(
5060				$(_div, { 'class': classes.sScrollHead } )
5061					.css( {
5062						overflow: 'hidden',
5063						position: 'relative',
5064						border: 0,
5065						width: scrollX ? size(scrollX) : '100%'
5066					} )
5067					.append(
5068						$(_div, { 'class': classes.sScrollHeadInner } )
5069							.css( {
5070								'box-sizing': 'content-box',
5071								width: scroll.sXInner || '100%'
5072							} )
5073							.append(
5074								headerClone
5075									.removeAttr('id')
5076									.css( 'margin-left', 0 )
5077									.append( captionSide === 'top' ? caption : null )
5078									.append(
5079										table.children('thead')
5080									)
5081							)
5082					)
5083			)
5084			.append(
5085				$(_div, { 'class': classes.sScrollBody } )
5086					.css( {
5087						position: 'relative',
5088						overflow: 'auto',
5089						width: size( scrollX )
5090					} )
5091					.append( table )
5092			);
5093	
5094		if ( footer ) {
5095			scroller.append(
5096				$(_div, { 'class': classes.sScrollFoot } )
5097					.css( {
5098						overflow: 'hidden',
5099						border: 0,
5100						width: scrollX ? size(scrollX) : '100%'
5101					} )
5102					.append(
5103						$(_div, { 'class': classes.sScrollFootInner } )
5104							.append(
5105								footerClone
5106									.removeAttr('id')
5107									.css( 'margin-left', 0 )
5108									.append( captionSide === 'bottom' ? caption : null )
5109									.append(
5110										table.children('tfoot')
5111									)
5112							)
5113					)
5114			);
5115		}
5116	
5117		var children = scroller.children();
5118		var scrollHead = children[0];
5119		var scrollBody = children[1];
5120		var scrollFoot = footer ? children[2] : null;
5121	
5122		// When the body is scrolled, then we also want to scroll the headers
5123		if ( scrollX ) {
5124			$(scrollBody).on( 'scroll.DT', function (e) {
5125				var scrollLeft = this.scrollLeft;
5126	
5127				scrollHead.scrollLeft = scrollLeft;
5128	
5129				if ( footer ) {
5130					scrollFoot.scrollLeft = scrollLeft;
5131				}
5132			} );
5133		}
5134	
5135		$(scrollBody).css(
5136			scrollY && scroll.bCollapse ? 'max-height' : 'height', 
5137			scrollY
5138		);
5139	
5140		settings.nScrollHead = scrollHead;
5141		settings.nScrollBody = scrollBody;
5142		settings.nScrollFoot = scrollFoot;
5143	
5144		// On redraw - align columns
5145		settings.aoDrawCallback.push( {
5146			"fn": _fnScrollDraw,
5147			"sName": "scrolling"
5148		} );
5149	
5150		return scroller[0];
5151	}
5152	
5153	
5154	
5155	/**
5156	 * Update the header, footer and body tables for resizing - i.e. column
5157	 * alignment.
5158	 *
5159	 * Welcome to the most horrible function DataTables. The process that this
5160	 * function follows is basically:
5161	 *   1. Re-create the table inside the scrolling div
5162	 *   2. Take live measurements from the DOM
5163	 *   3. Apply the measurements to align the columns
5164	 *   4. Clean up
5165	 *
5166	 *  @param {object} settings dataTables settings object
5167	 *  @memberof DataTable#oApi
5168	 */
5169	function _fnScrollDraw ( settings )
5170	{
5171		// Given that this is such a monster function, a lot of variables are use
5172		// to try and keep the minimised size as small as possible
5173		var
5174			scroll         = settings.oScroll,
5175			scrollX        = scroll.sX,
5176			scrollXInner   = scroll.sXInner,
5177			scrollY        = scroll.sY,
5178			barWidth       = scroll.iBarWidth,
5179			divHeader      = $(settings.nScrollHead),
5180			divHeaderStyle = divHeader[0].style,
5181			divHeaderInner = divHeader.children('div'),
5182			divHeaderInnerStyle = divHeaderInner[0].style,
5183			divHeaderTable = divHeaderInner.children('table'),
5184			divBodyEl      = settings.nScrollBody,
5185			divBody        = $(divBodyEl),
5186			divBodyStyle   = divBodyEl.style,
5187			divFooter      = $(settings.nScrollFoot),
5188			divFooterInner = divFooter.children('div'),
5189			divFooterTable = divFooterInner.children('table'),
5190			header         = $(settings.nTHead),
5191			table          = $(settings.nTable),
5192			tableEl        = table[0],
5193			tableStyle     = tableEl.style,
5194			footer         = settings.nTFoot ? $(settings.nTFoot) : null,
5195			browser        = settings.oBrowser,
5196			ie67           = browser.bScrollOversize,
5197			dtHeaderCells  = _pluck( settings.aoColumns, 'nTh' ),
5198			headerTrgEls, footerTrgEls,
5199			headerSrcEls, footerSrcEls,
5200			headerCopy, footerCopy,
5201			headerWidths=[], footerWidths=[],
5202			headerContent=[], footerContent=[],
5203			idx, correction, sanityWidth,
5204			zeroOut = function(nSizer) {
5205				var style = nSizer.style;
5206				style.paddingTop = "0";
5207				style.paddingBottom = "0";
5208				style.borderTopWidth = "0";
5209				style.borderBottomWidth = "0";
5210				style.height = 0;
5211			};
5212	
5213		// If the scrollbar visibility has changed from the last draw, we need to
5214		// adjust the column sizes as the table width will have changed to account
5215		// for the scrollbar
5216		var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
5217		
5218		if ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {
5219			settings.scrollBarVis = scrollBarVis;
5220			_fnAdjustColumnSizing( settings );
5221			return; // adjust column sizing will call this function again
5222		}
5223		else {
5224			settings.scrollBarVis = scrollBarVis;
5225		}
5226	
5227		/*
5228		 * 1. Re-create the table inside the scrolling div
5229		 */
5230	
5231		// Remove the old minimised thead and tfoot elements in the inner table
5232		table.children('thead, tfoot').remove();
5233	
5234		if ( footer ) {
5235			footerCopy = footer.clone().prependTo( table );
5236			footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
5237			footerSrcEls = footerCopy.find('tr');
5238		}
5239	
5240		// Clone the current header and footer elements and then place it into the inner table
5241		headerCopy = header.clone().prependTo( table );
5242		headerTrgEls = header.find('tr'); // original header is in its own table
5243		headerSrcEls = headerCopy.find('tr');
5244		headerCopy.find('th, td').removeAttr('tabindex');
5245	
5246	
5247		/*
5248		 * 2. Take live measurements from the DOM - do not alter the DOM itself!
5249		 */
5250	
5251		// Remove old sizing and apply the calculated column widths
5252		// Get the unique column headers in the newly created (cloned) header. We want to apply the
5253		// calculated sizes to this header
5254		if ( ! scrollX )
5255		{
5256			divBodyStyle.width = '100%';
5257			divHeader[0].style.width = '100%';
5258		}
5259	
5260		$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
5261			idx = _fnVisibleToColumnIndex( settings, i );
5262			el.style.width = settings.aoColumns[idx].sWidth;
5263		} );
5264	
5265		if ( footer ) {
5266			_fnApplyToChildren( function(n) {
5267				n.style.width = "";
5268			}, footerSrcEls );
5269		}
5270	
5271		// Size the table as a whole
5272		sanityWidth = table.outerWidth();
5273		if ( scrollX === "" ) {
5274			// No x scrolling
5275			tableStyle.width = "100%";
5276	
5277			// IE7 will make the width of the table when 100% include the scrollbar
5278			// - which is shouldn't. When there is a scrollbar we need to take this
5279			// into account.
5280			if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
5281				divBody.css('overflow-y') == "scroll")
5282			) {
5283				tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
5284			}
5285	
5286			// Recalculate the sanity width
5287			sanityWidth = table.outerWidth();
5288		}
5289		else if ( scrollXInner !== "" ) {
5290			// legacy x scroll inner has been given - use it
5291			tableStyle.width = _fnStringToCss(scrollXInner);
5292	
5293			// Recalculate the sanity width
5294			sanityWidth = table.outerWidth();
5295		}
5296	
5297		// Hidden header should have zero height, so remove padding and borders. Then
5298		// set the width based on the real headers
5299	
5300		// Apply all styles in one pass
5301		_fnApplyToChildren( zeroOut, headerSrcEls );
5302	
5303		// Read all widths in next pass
5304		_fnApplyToChildren( function(nSizer) {
5305			headerContent.push( nSizer.innerHTML );
5306			headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
5307		}, headerSrcEls );
5308	
5309		// Apply all widths in final pass
5310		_fnApplyToChildren( function(nToSize, i) {
5311			// Only apply widths to the DataTables detected header cells - this
5312			// prevents complex headers from having contradictory sizes applied
5313			if ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {
5314				nToSize.style.width = headerWidths[i];
5315			}
5316		}, headerTrgEls );
5317	
5318		$(headerSrcEls).height(0);
5319	
5320		/* Same again with the footer if we have one */
5321		if ( footer )
5322		{
5323			_fnApplyToChildren( zeroOut, footerSrcEls );
5324	
5325			_fnApplyToChildren( function(nSizer) {
5326				footerContent.push( nSizer.innerHTML );
5327				footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
5328			}, footerSrcEls );
5329	
5330			_fnApplyToChildren( function(nToSize, i) {
5331				nToSize.style.width = footerWidths[i];
5332			}, footerTrgEls );
5333	
5334			$(footerSrcEls).height(0);
5335		}
5336	
5337	
5338		/*
5339		 * 3. Apply the measurements
5340		 */
5341	
5342		// "Hide" the header and footer that we used for the sizing. We need to keep
5343		// the content of the cell so that the width applied to the header and body
5344		// both match, but we want to hide it completely. We want to also fix their
5345		// width to what they currently are
5346		_fnApplyToChildren( function(nSizer, i) {
5347			nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
5348			nSizer.style.width = headerWidths[i];
5349		}, headerSrcEls );
5350	
5351		if ( footer )
5352		{
5353			_fnApplyToChildren( function(nSizer, i) {
5354				nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+footerContent[i]+'</div>';
5355				nSizer.style.width = footerWidths[i];
5356			}, footerSrcEls );
5357		}
5358	
5359		// Sanity check that the table is of a sensible width. If not then we are going to get
5360		// misalignment - try to prevent this by not allowing the table to shrink below its min width
5361		if ( table.outerWidth() < sanityWidth )
5362		{
5363			// The min width depends upon if we have a vertical scrollbar visible or not */
5364			correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
5365				divBody.css('overflow-y') == "scroll")) ?
5366					sanityWidth+barWidth :
5367					sanityWidth;
5368	
5369			// IE6/7 are a law unto themselves...
5370			if ( ie67 && (divBodyEl.scrollHeight >
5371				divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
5372			) {
5373				tableStyle.width = _fnStringToCss( correction-barWidth );
5374			}
5375	
5376			// And give the user a warning that we've stopped the table getting too small
5377			if ( scrollX === "" || scrollXInner !== "" ) {
5378				_fnLog( settings, 1, 'Possible column misalignment', 6 );
5379			}
5380		}
5381		else
5382		{
5383			correction = '100%';
5384		}
5385	
5386		// Apply to the container elements
5387		divBodyStyle.width = _fnStringToCss( correction );
5388		divHeaderStyle.width = _fnStringToCss( correction );
5389	
5390		if ( footer ) {
5391			settings.nScrollFoot.style.width = _fnStringToCss( correction );
5392		}
5393	
5394	
5395		/*
5396		 * 4. Clean up
5397		 */
5398		if ( ! scrollY ) {
5399			/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
5400			 * the scrollbar height from the visible display, rather than adding it on. We need to
5401			 * set the height in order to sort this. Don't want to do it in any other browsers.
5402			 */
5403			if ( ie67 ) {
5404				divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
5405			}
5406		}
5407	
5408		/* Finally set the width's of the header and footer tables */
5409		var iOuterWidth = table.outerWidth();
5410		divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
5411		divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
5412	
5413		// Figure out if there are scrollbar present - if so then we need a the header and footer to
5414		// provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
5415		var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
5416		var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
5417		divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
5418	
5419		if ( footer ) {
5420			divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
5421			divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
5422			divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
5423		}
5424	
5425		// Correct DOM ordering for colgroup - comes before the thead
5426		table.children('colgroup').insertBefore( table.children('thead') );
5427	
5428		/* Adjust the position of the header in case we loose the y-scrollbar */
5429		divBody.scroll(
vendor: 11,594 bytes, lines 5429-5827
5429);
5430	
5431		// If sorting or filtering has occurred, jump the scrolling back to the top
5432		// only if we aren't holding the position
5433		if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
5434			divBodyEl.scrollTop = 0;
5435		}
5436	}
5437	
5438	
5439	
5440	/**
5441	 * Apply a given function to the display child nodes of an element array (typically
5442	 * TD children of TR rows
5443	 *  @param {function} fn Method to apply to the objects
5444	 *  @param array {nodes} an1 List of elements to look through for display children
5445	 *  @param array {nodes} an2 Another list (identical structure to the first) - optional
5446	 *  @memberof DataTable#oApi
5447	 */
5448	function _fnApplyToChildren( fn, an1, an2 )
5449	{
5450		var index=0, i=0, iLen=an1.length;
5451		var nNode1, nNode2;
5452	
5453		while ( i < iLen ) {
5454			nNode1 = an1[i].firstChild;
5455			nNode2 = an2 ? an2[i].firstChild : null;
5456	
5457			while ( nNode1 ) {
5458				if ( nNode1.nodeType === 1 ) {
5459					if ( an2 ) {
5460						fn( nNode1, nNode2, index );
5461					}
5462					else {
5463						fn( nNode1, index );
5464					}
5465	
5466					index++;
5467				}
5468	
5469				nNode1 = nNode1.nextSibling;
5470				nNode2 = an2 ? nNode2.nextSibling : null;
5471			}
5472	
5473			i++;
5474		}
5475	}
5476	
5477	
5478	
5479	var __re_html_remove = /<.*?>/g;
5480	
5481	
5482	/**
5483	 * Calculate the width of columns for the table
5484	 *  @param {object} oSettings dataTables settings object
5485	 *  @memberof DataTable#oApi
5486	 */
5487	function _fnCalculateColumnWidths ( oSettings )
5488	{
5489		var
5490			table = oSettings.nTable,
5491			columns = oSettings.aoColumns,
5492			scroll = oSettings.oScroll,
5493			scrollY = scroll.sY,
5494			scrollX = scroll.sX,
5495			scrollXInner = scroll.sXInner,
5496			columnCount = columns.length,
5497			visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
5498			headerCells = $('th', oSettings.nTHead),
5499			tableWidthAttr = table.getAttribute('width'), // from DOM element
5500			tableContainer = table.parentNode,
5501			userInputs = false,
5502			i, column, columnIdx, width, outerWidth,
5503			browser = oSettings.oBrowser,
5504			ie67 = browser.bScrollOversize;
5505	
5506		var styleWidth = table.style.width;
5507		if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
5508			tableWidthAttr = styleWidth;
5509		}
5510	
5511		/* Convert any user input sizes into pixel sizes */
5512		for ( i=0 ; i<visibleColumns.length ; i++ ) {
5513			column = columns[ visibleColumns[i] ];
5514	
5515			if ( column.sWidth !== null ) {
5516				column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
5517	
5518				userInputs = true;
5519			}
5520		}
5521	
5522		/* If the number of columns in the DOM equals the number that we have to
5523		 * process in DataTables, then we can use the offsets that are created by
5524		 * the web- browser. No custom sizes can be set in order for this to happen,
5525		 * nor scrolling used
5526		 */
5527		if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
5528		     columnCount == _fnVisbleColumns( oSettings ) &&
5529		     columnCount == headerCells.length
5530		) {
5531			for ( i=0 ; i<columnCount ; i++ ) {
5532				var colIdx = _fnVisibleToColumnIndex( oSettings, i );
5533	
5534				if ( colIdx !== null ) {
5535					columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
5536				}
5537			}
5538		}
5539		else
5540		{
5541			// Otherwise construct a single row, worst case, table with the widest
5542			// node in the data, assign any user defined widths, then insert it into
5543			// the DOM and allow the browser to do all the hard work of calculating
5544			// table widths
5545			var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
5546				.css( 'visibility', 'hidden' )
5547				.removeAttr( 'id' );
5548	
5549			// Clean up the table body
5550			tmpTable.find('tbody tr').remove();
5551			var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
5552	
5553			// Clone the table header and footer - we can't use the header / footer
5554			// from the cloned table, since if scrolling is active, the table's
5555			// real header and footer are contained in different table tags
5556			tmpTable.find('thead, tfoot').remove();
5557			tmpTable
5558				.append( $(oSettings.nTHead).clone() )
5559				.append( $(oSettings.nTFoot).clone() );
5560	
5561			// Remove any assigned widths from the footer (from scrolling)
5562			tmpTable.find('tfoot th, tfoot td').css('width', '');
5563	
5564			// Apply custom sizing to the cloned header
5565			headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
5566	
5567			for ( i=0 ; i<visibleColumns.length ; i++ ) {
5568				column = columns[ visibleColumns[i] ];
5569	
5570				headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
5571					_fnStringToCss( column.sWidthOrig ) :
5572					'';
5573	
5574				// For scrollX we need to force the column width otherwise the
5575				// browser will collapse it. If this width is smaller than the
5576				// width the column requires, then it will have no effect
5577				if ( column.sWidthOrig && scrollX ) {
5578					$( headerCells[i] ).append( $('<div/>').css( {
5579						width: column.sWidthOrig,
5580						margin: 0,
5581						padding: 0,
5582						border: 0,
5583						height: 1
5584					} ) );
5585				}
5586			}
5587	
5588			// Find the widest cell for each column and put it into the table
5589			if ( oSettings.aoData.length ) {
5590				for ( i=0 ; i<visibleColumns.length ; i++ ) {
5591					columnIdx = visibleColumns[i];
5592					column = columns[ columnIdx ];
5593	
5594					$( _fnGetWidestNode( oSettings, columnIdx ) )
5595						.clone( false )
5596						.append( column.sContentPadding )
5597						.appendTo( tr );
5598				}
5599			}
5600	
5601			// Tidy the temporary table - remove name attributes so there aren't
5602			// duplicated in the dom (radio elements for example)
5603			$('[name]', tmpTable).removeAttr('name');
5604	
5605			// Table has been built, attach to the document so we can work with it.
5606			// A holding element is used, positioned at the top of the container
5607			// with minimal height, so it has no effect on if the container scrolls
5608			// or not. Otherwise it might trigger scrolling when it actually isn't
5609			// needed
5610			var holder = $('<div/>').css( scrollX || scrollY ?
5611					{
5612						position: 'absolute',
5613						top: 0,
5614						left: 0,
5615						height: 1,
5616						right: 0,
5617						overflow: 'hidden'
5618					} :
5619					{}
5620				)
5621				.append( tmpTable )
5622				.appendTo( tableContainer );
5623	
5624			// When scrolling (X or Y) we want to set the width of the table as 
5625			// appropriate. However, when not scrolling leave the table width as it
5626			// is. This results in slightly different, but I think correct behaviour
5627			if ( scrollX && scrollXInner ) {
5628				tmpTable.width( scrollXInner );
5629			}
5630			else if ( scrollX ) {
5631				tmpTable.css( 'width', 'auto' );
5632				tmpTable.removeAttr('width');
5633	
5634				// If there is no width attribute or style, then allow the table to
5635				// collapse
5636				if ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {
5637					tmpTable.width( tableContainer.clientWidth );
5638				}
5639			}
5640			else if ( scrollY ) {
5641				tmpTable.width( tableContainer.clientWidth );
5642			}
5643			else if ( tableWidthAttr ) {
5644				tmpTable.width( tableWidthAttr );
5645			}
5646	
5647			// Get the width of each column in the constructed table - we need to
5648			// know the inner width (so it can be assigned to the other table's
5649			// cells) and the outer width so we can calculate the full width of the
5650			// table. This is safe since DataTables requires a unique cell for each
5651			// column, but if ever a header can span multiple columns, this will
5652			// need to be modified.
5653			var total = 0;
5654			for ( i=0 ; i<visibleColumns.length ; i++ ) {
5655				var cell = $(headerCells[i]);
5656				var border = cell.outerWidth() - cell.width();
5657	
5658				// Use getBounding... where possible (not IE8-) because it can give
5659				// sub-pixel accuracy, which we then want to round up!
5660				var bounding = browser.bBounding ?
5661					Math.ceil( headerCells[i].getBoundingClientRect().width ) :
5662					cell.outerWidth();
5663	
5664				// Total is tracked to remove any sub-pixel errors as the outerWidth
5665				// of the table might not equal the total given here (IE!).
5666				total += bounding;
5667	
5668				// Width for each column to use
5669				columns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );
5670			}
5671	
5672			table.style.width = _fnStringToCss( total );
5673	
5674			// Finished with the table - ditch it
5675			holder.remove();
5676		}
5677	
5678		// If there is a width attr, we want to attach an event listener which
5679		// allows the table sizing to automatically adjust when the window is
5680		// resized. Use the width attr rather than CSS, since we can't know if the
5681		// CSS is a relative value or absolute - DOM read is always px.
5682		if ( tableWidthAttr ) {
5683			table.style.width = _fnStringToCss( tableWidthAttr );
5684		}
5685	
5686		if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
5687			var bindResize = function () {
5688				$(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
5689					_fnAdjustColumnSizing( oSettings );
5690				} ) );
5691			};
5692	
5693			// IE6/7 will crash if we bind a resize event handler on page load.
5694			// To be removed in 1.11 which drops IE6/7 support
5695			if ( ie67 ) {
5696				setTimeout( bindResize, 1000 );
5697			}
5698			else {
5699				bindResize();
5700			}
5701	
5702			oSettings._reszEvt = true;
5703		}
5704	}
5705	
5706	
5707	/**
5708	 * Throttle the calls to a function. Arguments and context are maintained for
5709	 * the throttled function
5710	 *  @param {function} fn Function to be called
5711	 *  @param {int} [freq=200] call frequency in mS
5712	 *  @returns {function} wrapped function
5713	 *  @memberof DataTable#oApi
5714	 */
5715	var _fnThrottle = DataTable.util.throttle;
5716	
5717	
5718	/**
5719	 * Convert a CSS unit width to pixels (e.g. 2em)
5720	 *  @param {string} width width to be converted
5721	 *  @param {node} parent parent to get the with for (required for relative widths) - optional
5722	 *  @returns {int} width in pixels
5723	 *  @memberof DataTable#oApi
5724	 */
5725	function _fnConvertToWidth ( width, parent )
5726	{
5727		if ( ! width ) {
5728			return 0;
5729		}
5730	
5731		var n = $('<div/>')
5732			.css( 'width', _fnStringToCss( width ) )
5733			.appendTo( parent || document.body );
5734	
5735		var val = n[0].offsetWidth;
5736		n.remove();
5737	
5738		return val;
5739	}
5740	
5741	
5742	/**
5743	 * Get the widest node
5744	 *  @param {object} settings dataTables settings object
5745	 *  @param {int} colIdx column of interest
5746	 *  @returns {node} widest table node
5747	 *  @memberof DataTable#oApi
5748	 */
5749	function _fnGetWidestNode( settings, colIdx )
5750	{
5751		var idx = _fnGetMaxLenString( settings, colIdx );
5752		if ( idx < 0 ) {
5753			return null;
5754		}
5755	
5756		var data = settings.aoData[ idx ];
5757		return ! data.nTr ? // Might not have been created when deferred rendering
5758			$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
5759			data.anCells[ colIdx ];
5760	}
5761	
5762	
5763	/**
5764	 * Get the maximum strlen for each data column
5765	 *  @param {object} settings dataTables settings object
5766	 *  @param {int} colIdx column of interest
5767	 *  @returns {string} max string length for each column
5768	 *  @memberof DataTable#oApi
5769	 */
5770	function _fnGetMaxLenString( settings, colIdx )
5771	{
5772		var s, max=-1, maxIdx = -1;
5773	
5774		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
5775			s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
5776			s = s.replace( __re_html_remove, '' );
5777			s = s.replace( /&nbsp;/g, ' ' );
5778	
5779			if ( s.length > max ) {
5780				max = s.length;
5781				maxIdx = i;
5782			}
5783		}
5784	
5785		return maxIdx;
5786	}
5787	
5788	
5789	/**
5790	 * Append a CSS unit (only if required) to a string
5791	 *  @param {string} value to css-ify
5792	 *  @returns {string} value with css unit
5793	 *  @memberof DataTable#oApi
5794	 */
5795	function _fnStringToCss( s )
5796	{
5797		if ( s === null ) {
5798			return '0px';
5799		}
5800	
5801		if ( typeof s == 'number' ) {
5802			return s < 0 ?
5803				'0px' :
5804				s+'px';
5805		}
5806	
5807		// Check it has a unit character already
5808		return s.match(/\d$/) ?
5809			s+'px' :
5810			s;
5811	}
5812	
5813	
5814	
5815	function _fnSortFlatten ( settings )
5816	{
5817		var
5818			i, iLen, k, kLen,
5819			aSort = [],
5820			aiOrig = [],
5821			aoColumns = settings.aoColumns,
5822			aDataSort, iCol, sType, srcCol,
5823			fixed = settings.aaSortingFixed,
5824			fixedObj = $.isPlainObject( fixed ),
5825			nestedSort = [],
5826			add = function ( a ) {
5827				if ( a.length && ! 
vendor: 39,694 bytes, lines 5827-7343
5827$.isArray( a[0] ) ) {
5828					// 1D array
5829					nestedSort.push( a );
5830				}
5831				else {
5832					// 2D array
5833					$.merge( nestedSort, a );
5834				}
5835			};
5836	
5837		// Build the sort array, with pre-fix and post-fix options if they have been
5838		// specified
5839		if ( $.isArray( fixed ) ) {
5840			add( fixed );
5841		}
5842	
5843		if ( fixedObj && fixed.pre ) {
5844			add( fixed.pre );
5845		}
5846	
5847		add( settings.aaSorting );
5848	
5849		if (fixedObj && fixed.post ) {
5850			add( fixed.post );
5851		}
5852	
5853		for ( i=0 ; i<nestedSort.length ; i++ )
5854		{
5855			srcCol = nestedSort[i][0];
5856			aDataSort = aoColumns[ srcCol ].aDataSort;
5857	
5858			for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
5859			{
5860				iCol = aDataSort[k];
5861				sType = aoColumns[ iCol ].sType || 'string';
5862	
5863				if ( nestedSort[i]._idx === undefined ) {
5864					nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
5865				}
5866	
5867				aSort.push( {
5868					src:       srcCol,
5869					col:       iCol,
5870					dir:       nestedSort[i][1],
5871					index:     nestedSort[i]._idx,
5872					type:      sType,
5873					formatter: DataTable.ext.type.order[ sType+"-pre" ]
5874				} );
5875			}
5876		}
5877	
5878		return aSort;
5879	}
5880	
5881	/**
5882	 * Change the order of the table
5883	 *  @param {object} oSettings dataTables settings object
5884	 *  @memberof DataTable#oApi
5885	 *  @todo This really needs split up!
5886	 */
5887	function _fnSort ( oSettings )
5888	{
5889		var
5890			i, ien, iLen, j, jLen, k, kLen,
5891			sDataType, nTh,
5892			aiOrig = [],
5893			oExtSort = DataTable.ext.type.order,
5894			aoData = oSettings.aoData,
5895			aoColumns = oSettings.aoColumns,
5896			aDataSort, data, iCol, sType, oSort,
5897			formatters = 0,
5898			sortCol,
5899			displayMaster = oSettings.aiDisplayMaster,
5900			aSort;
5901	
5902		// Resolve any column types that are unknown due to addition or invalidation
5903		// @todo Can this be moved into a 'data-ready' handler which is called when
5904		//   data is going to be used in the table?
5905		_fnColumnTypes( oSettings );
5906	
5907		aSort = _fnSortFlatten( oSettings );
5908	
5909		for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
5910			sortCol = aSort[i];
5911	
5912			// Track if we can use the fast sort algorithm
5913			if ( sortCol.formatter ) {
5914				formatters++;
5915			}
5916	
5917			// Load the data needed for the sort, for each cell
5918			_fnSortData( oSettings, sortCol.col );
5919		}
5920	
5921		/* No sorting required if server-side or no sorting array */
5922		if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
5923		{
5924			// Create a value - key array of the current row positions such that we can use their
5925			// current position during the sort, if values match, in order to perform stable sorting
5926			for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
5927				aiOrig[ displayMaster[i] ] = i;
5928			}
5929	
5930			/* Do the sort - here we want multi-column sorting based on a given data source (column)
5931			 * and sorting function (from oSort) in a certain direction. It's reasonably complex to
5932			 * follow on it's own, but this is what we want (example two column sorting):
5933			 *  fnLocalSorting = function(a,b){
5934			 *    var iTest;
5935			 *    iTest = oSort['string-asc']('data11', 'data12');
5936			 *      if (iTest !== 0)
5937			 *        return iTest;
5938			 *    iTest = oSort['numeric-desc']('data21', 'data22');
5939			 *    if (iTest !== 0)
5940			 *      return iTest;
5941			 *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
5942			 *  }
5943			 * Basically we have a test for each sorting column, if the data in that column is equal,
5944			 * test the next column. If all columns match, then we use a numeric sort on the row
5945			 * positions in the original data array to provide a stable sort.
5946			 *
5947			 * Note - I know it seems excessive to have two sorting methods, but the first is around
5948			 * 15% faster, so the second is only maintained for backwards compatibility with sorting
5949			 * methods which do not have a pre-sort formatting function.
5950			 */
5951			if ( formatters === aSort.length ) {
5952				// All sort types have formatting functions
5953				displayMaster.sort( function ( a, b ) {
5954					var
5955						x, y, k, test, sort,
5956						len=aSort.length,
5957						dataA = aoData[a]._aSortData,
5958						dataB = aoData[b]._aSortData;
5959	
5960					for ( k=0 ; k<len ; k++ ) {
5961						sort = aSort[k];
5962	
5963						x = dataA[ sort.col ];
5964						y = dataB[ sort.col ];
5965	
5966						test = x<y ? -1 : x>y ? 1 : 0;
5967						if ( test !== 0 ) {
5968							return sort.dir === 'asc' ? test : -test;
5969						}
5970					}
5971	
5972					x = aiOrig[a];
5973					y = aiOrig[b];
5974					return x<y ? -1 : x>y ? 1 : 0;
5975				} );
5976			}
5977			else {
5978				// Depreciated - remove in 1.11 (providing a plug-in option)
5979				// Not all sort types have formatting methods, so we have to call their sorting
5980				// methods.
5981				displayMaster.sort( function ( a, b ) {
5982					var
5983						x, y, k, l, test, sort, fn,
5984						len=aSort.length,
5985						dataA = aoData[a]._aSortData,
5986						dataB = aoData[b]._aSortData;
5987	
5988					for ( k=0 ; k<len ; k++ ) {
5989						sort = aSort[k];
5990	
5991						x = dataA[ sort.col ];
5992						y = dataB[ sort.col ];
5993	
5994						fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
5995						test = fn( x, y );
5996						if ( test !== 0 ) {
5997							return test;
5998						}
5999					}
6000	
6001					x = aiOrig[a];
6002					y = aiOrig[b];
6003					return x<y ? -1 : x>y ? 1 : 0;
6004				} );
6005			}
6006		}
6007	
6008		/* Tell the draw function that we have sorted the data */
6009		oSettings.bSorted = true;
6010	}
6011	
6012	
6013	function _fnSortAria ( settings )
6014	{
6015		var label;
6016		var nextSort;
6017		var columns = settings.aoColumns;
6018		var aSort = _fnSortFlatten( settings );
6019		var oAria = settings.oLanguage.oAria;
6020	
6021		// ARIA attributes - need to loop all columns, to update all (removing old
6022		// attributes as needed)
6023		for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
6024		{
6025			var col = columns[i];
6026			var asSorting = col.asSorting;
6027			var sTitle = col.sTitle.replace( /<.*?>/g, "" );
6028			var th = col.nTh;
6029	
6030			// IE7 is throwing an error when setting these properties with jQuery's
6031			// attr() and removeAttr() methods...
6032			th.removeAttribute('aria-sort');
6033	
6034			/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
6035			if ( col.bSortable ) {
6036				if ( aSort.length > 0 && aSort[0].col == i ) {
6037					th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
6038					nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
6039				}
6040				else {
6041					nextSort = asSorting[0];
6042				}
6043	
6044				label = sTitle + ( nextSort === "asc" ?
6045					oAria.sSortAscending :
6046					oAria.sSortDescending
6047				);
6048			}
6049			else {
6050				label = sTitle;
6051			}
6052	
6053			th.setAttribute('aria-label', label);
6054		}
6055	}
6056	
6057	
6058	/**
6059	 * Function to run on user sort request
6060	 *  @param {object} settings dataTables settings object
6061	 *  @param {node} attachTo node to attach the handler to
6062	 *  @param {int} colIdx column sorting index
6063	 *  @param {boolean} [append=false] Append the requested sort to the existing
6064	 *    sort if true (i.e. multi-column sort)
6065	 *  @param {function} [callback] callback function
6066	 *  @memberof DataTable#oApi
6067	 */
6068	function _fnSortListener ( settings, colIdx, append, callback )
6069	{
6070		var col = settings.aoColumns[ colIdx ];
6071		var sorting = settings.aaSorting;
6072		var asSorting = col.asSorting;
6073		var nextSortIdx;
6074		var next = function ( a, overflow ) {
6075			var idx = a._idx;
6076			if ( idx === undefined ) {
6077				idx = $.inArray( a[1], asSorting );
6078			}
6079	
6080			return idx+1 < asSorting.length ?
6081				idx+1 :
6082				overflow ?
6083					null :
6084					0;
6085		};
6086	
6087		// Convert to 2D array if needed
6088		if ( typeof sorting[0] === 'number' ) {
6089			sorting = settings.aaSorting = [ sorting ];
6090		}
6091	
6092		// If appending the sort then we are multi-column sorting
6093		if ( append && settings.oFeatures.bSortMulti ) {
6094			// Are we already doing some kind of sort on this column?
6095			var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
6096	
6097			if ( sortIdx !== -1 ) {
6098				// Yes, modify the sort
6099				nextSortIdx = next( sorting[sortIdx], true );
6100	
6101				if ( nextSortIdx === null && sorting.length === 1 ) {
6102					nextSortIdx = 0; // can't remove sorting completely
6103				}
6104	
6105				if ( nextSortIdx === null ) {
6106					sorting.splice( sortIdx, 1 );
6107				}
6108				else {
6109					sorting[sortIdx][1] = asSorting[ nextSortIdx ];
6110					sorting[sortIdx]._idx = nextSortIdx;
6111				}
6112			}
6113			else {
6114				// No sort on this column yet
6115				sorting.push( [ colIdx, asSorting[0], 0 ] );
6116				sorting[sorting.length-1]._idx = 0;
6117			}
6118		}
6119		else if ( sorting.length && sorting[0][0] == colIdx ) {
6120			// Single column - already sorting on this column, modify the sort
6121			nextSortIdx = next( sorting[0] );
6122	
6123			sorting.length = 1;
6124			sorting[0][1] = asSorting[ nextSortIdx ];
6125			sorting[0]._idx = nextSortIdx;
6126		}
6127		else {
6128			// Single column - sort only on this column
6129			sorting.length = 0;
6130			sorting.push( [ colIdx, asSorting[0] ] );
6131			sorting[0]._idx = 0;
6132		}
6133	
6134		// Run the sort by calling a full redraw
6135		_fnReDraw( settings );
6136	
6137		// callback used for async user interaction
6138		if ( typeof callback == 'function' ) {
6139			callback( settings );
6140		}
6141	}
6142	
6143	
6144	/**
6145	 * Attach a sort handler (click) to a node
6146	 *  @param {object} settings dataTables settings object
6147	 *  @param {node} attachTo node to attach the handler to
6148	 *  @param {int} colIdx column sorting index
6149	 *  @param {function} [callback] callback function
6150	 *  @memberof DataTable#oApi
6151	 */
6152	function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
6153	{
6154		var col = settings.aoColumns[ colIdx ];
6155	
6156		_fnBindAction( attachTo, {}, function (e) {
6157			/* If the column is not sortable - don't to anything */
6158			if ( col.bSortable === false ) {
6159				return;
6160			}
6161	
6162			// If processing is enabled use a timeout to allow the processing
6163			// display to be shown - otherwise to it synchronously
6164			if ( settings.oFeatures.bProcessing ) {
6165				_fnProcessingDisplay( settings, true );
6166	
6167				setTimeout( function() {
6168					_fnSortListener( settings, colIdx, e.shiftKey, callback );
6169	
6170					// In server-side processing, the draw callback will remove the
6171					// processing display
6172					if ( _fnDataSource( settings ) !== 'ssp' ) {
6173						_fnProcessingDisplay( settings, false );
6174					}
6175				}, 0 );
6176			}
6177			else {
6178				_fnSortListener( settings, colIdx, e.shiftKey, callback );
6179			}
6180		} );
6181	}
6182	
6183	
6184	/**
6185	 * Set the sorting classes on table's body, Note: it is safe to call this function
6186	 * when bSort and bSortClasses are false
6187	 *  @param {object} oSettings dataTables settings object
6188	 *  @memberof DataTable#oApi
6189	 */
6190	function _fnSortingClasses( settings )
6191	{
6192		var oldSort = settings.aLastSort;
6193		var sortClass = settings.oClasses.sSortColumn;
6194		var sort = _fnSortFlatten( settings );
6195		var features = settings.oFeatures;
6196		var i, ien, colIdx;
6197	
6198		if ( features.bSort && features.bSortClasses ) {
6199			// Remove old sorting classes
6200			for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
6201				colIdx = oldSort[i].src;
6202	
6203				// Remove column sorting
6204				$( _pluck( settings.aoData, 'anCells', colIdx ) )
6205					.removeClass( sortClass + (i<2 ? i+1 : 3) );
6206			}
6207	
6208			// Add new column sorting
6209			for ( i=0, ien=sort.length ; i<ien ; i++ ) {
6210				colIdx = sort[i].src;
6211	
6212				$( _pluck( settings.aoData, 'anCells', colIdx ) )
6213					.addClass( sortClass + (i<2 ? i+1 : 3) );
6214			}
6215		}
6216	
6217		settings.aLastSort = sort;
6218	}
6219	
6220	
6221	// Get the data to sort a column, be it from cache, fresh (populating the
6222	// cache), or from a sort formatter
6223	function _fnSortData( settings, idx )
6224	{
6225		// Custom sorting function - provided by the sort data type
6226		var column = settings.aoColumns[ idx ];
6227		var customSort = DataTable.ext.order[ column.sSortDataType ];
6228		var customData;
6229	
6230		if ( customSort ) {
6231			customData = customSort.call( settings.oInstance, settings, idx,
6232				_fnColumnIndexToVisible( settings, idx )
6233			);
6234		}
6235	
6236		// Use / populate cache
6237		var row, cellData;
6238		var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
6239	
6240		for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
6241			row = settings.aoData[i];
6242	
6243			if ( ! row._aSortData ) {
6244				row._aSortData = [];
6245			}
6246	
6247			if ( ! row._aSortData[idx] || customSort ) {
6248				cellData = customSort ?
6249					customData[i] : // If there was a custom sort function, use data from there
6250					_fnGetCellData( settings, i, idx, 'sort' );
6251	
6252				row._aSortData[ idx ] = formatter ?
6253					formatter( cellData ) :
6254					cellData;
6255			}
6256		}
6257	}
6258	
6259	
6260	
6261	/**
6262	 * Save the state of a table
6263	 *  @param {object} oSettings dataTables settings object
6264	 *  @memberof DataTable#oApi
6265	 */
6266	function _fnSaveState ( settings )
6267	{
6268		if ( !settings.oFeatures.bStateSave || settings.bDestroying )
6269		{
6270			return;
6271		}
6272	
6273		/* Store the interesting variables */
6274		var state = {
6275			time:    +new Date(),
6276			start:   settings._iDisplayStart,
6277			length:  settings._iDisplayLength,
6278			order:   $.extend( true, [], settings.aaSorting ),
6279			search:  _fnSearchToCamel( settings.oPreviousSearch ),
6280			columns: $.map( settings.aoColumns, function ( col, i ) {
6281				return {
6282					visible: col.bVisible,
6283					search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
6284				};
6285			} )
6286		};
6287	
6288		_fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
6289	
6290		settings.oSavedState = state;
6291		settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
6292	}
6293	
6294	
6295	/**
6296	 * Attempt to load a saved table state
6297	 *  @param {object} oSettings dataTables settings object
6298	 *  @param {object} oInit DataTables init object so we can override settings
6299	 *  @param {function} callback Callback to execute when the state has been loaded
6300	 *  @memberof DataTable#oApi
6301	 */
6302	function _fnLoadState ( settings, oInit, callback )
6303	{
6304		var i, ien;
6305		var columns = settings.aoColumns;
6306		var loaded = function ( s ) {
6307			if ( ! s || ! s.time ) {
6308				callback();
6309				return;
6310			}
6311	
6312			// Allow custom and plug-in manipulation functions to alter the saved data set and
6313			// cancelling of loading by returning false
6314			var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
6315			if ( $.inArray( false, abStateLoad ) !== -1 ) {
6316				callback();
6317				return;
6318			}
6319	
6320			// Reject old data
6321			var duration = settings.iStateDuration;
6322			if ( duration > 0 && s.time < +new Date() - (duration*1000) ) {
6323				callback();
6324				return;
6325			}
6326	
6327			// Number of columns have changed - all bets are off, no restore of settings
6328			if ( s.columns && columns.length !== s.columns.length ) {
6329				callback();
6330				return;
6331			}
6332	
6333			// Store the saved state so it might be accessed at any time
6334			settings.oLoadedState = $.extend( true, {}, state );
6335	
6336			// Restore key features - todo - for 1.11 this needs to be done by
6337			// subscribed events
6338			if ( s.start !== undefined ) {
6339				settings._iDisplayStart    = s.start;
6340				settings.iInitDisplayStart = s.start;
6341			}
6342			if ( s.length !== undefined ) {
6343				settings._iDisplayLength   = s.length;
6344			}
6345	
6346			// Order
6347			if ( s.order !== undefined ) {
6348				settings.aaSorting = [];
6349				$.each( s.order, function ( i, col ) {
6350					settings.aaSorting.push( col[0] >= columns.length ?
6351						[ 0, col[1] ] :
6352						col
6353					);
6354				} );
6355			}
6356	
6357			// Search
6358			if ( s.search !== undefined ) {
6359				$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );
6360			}
6361	
6362			// Columns
6363			// 
6364			if ( s.columns ) {
6365				for ( i=0, ien=s.columns.length ; i<ien ; i++ ) {
6366					var col = s.columns[i];
6367	
6368					// Visibility
6369					if ( col.visible !== undefined ) {
6370						columns[i].bVisible = col.visible;
6371					}
6372	
6373					// Search
6374					if ( col.search !== undefined ) {
6375						$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
6376					}
6377				}
6378			}
6379	
6380			_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
6381			callback();
6382		}
6383	
6384		if ( ! settings.oFeatures.bStateSave ) {
6385			callback();
6386			return;
6387		}
6388	
6389		var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );
6390	
6391		if ( state !== undefined ) {
6392			loaded( state );
6393		}
6394		// otherwise, wait for the loaded callback to be executed
6395	}
6396	
6397	
6398	/**
6399	 * Return the settings object for a particular table
6400	 *  @param {node} table table we are using as a dataTable
6401	 *  @returns {object} Settings object - or null if not found
6402	 *  @memberof DataTable#oApi
6403	 */
6404	function _fnSettingsFromNode ( table )
6405	{
6406		var settings = DataTable.settings;
6407		var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
6408	
6409		return idx !== -1 ?
6410			settings[ idx ] :
6411			null;
6412	}
6413	
6414	
6415	/**
6416	 * Log an error message
6417	 *  @param {object} settings dataTables settings object
6418	 *  @param {int} level log error messages, or display them to the user
6419	 *  @param {string} msg error message
6420	 *  @param {int} tn Technical note id to get more information about the error.
6421	 *  @memberof DataTable#oApi
6422	 */
6423	function _fnLog( settings, level, msg, tn )
6424	{
6425		msg = 'DataTables warning: '+
6426			(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
6427	
6428		if ( tn ) {
6429			msg += '. For more information about this error, please see '+
6430			'http://datatables.net/tn/'+tn;
6431		}
6432	
6433		if ( ! level  ) {
6434			// Backwards compatibility pre 1.10
6435			var ext = DataTable.ext;
6436			var type = ext.sErrMode || ext.errMode;
6437	
6438			if ( settings ) {
6439				_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
6440			}
6441	
6442			if ( type == 'alert' ) {
6443				alert( msg );
6444			}
6445			else if ( type == 'throw' ) {
6446				throw new Error(msg);
6447			}
6448			else if ( typeof type == 'function' ) {
6449				type( settings, tn, msg );
6450			}
6451		}
6452		else if ( window.console && console.log ) {
6453			console.log( msg );
6454		}
6455	}
6456	
6457	
6458	/**
6459	 * See if a property is defined on one object, if so assign it to the other object
6460	 *  @param {object} ret target object
6461	 *  @param {object} src source object
6462	 *  @param {string} name property
6463	 *  @param {string} [mappedName] name to map too - optional, name used if not given
6464	 *  @memberof DataTable#oApi
6465	 */
6466	function _fnMap( ret, src, name, mappedName )
6467	{
6468		if ( $.isArray( name ) ) {
6469			$.each( name, function (i, val) {
6470				if ( $.isArray( val ) ) {
6471					_fnMap( ret, src, val[0], val[1] );
6472				}
6473				else {
6474					_fnMap( ret, src, val );
6475				}
6476			} );
6477	
6478			return;
6479		}
6480	
6481		if ( mappedName === undefined ) {
6482			mappedName = name;
6483		}
6484	
6485		if ( src[name] !== undefined ) {
6486			ret[mappedName] = src[name];
6487		}
6488	}
6489	
6490	
6491	/**
6492	 * Extend objects - very similar to jQuery.extend, but deep copy objects, and
6493	 * shallow copy arrays. The reason we need to do this, is that we don't want to
6494	 * deep copy array init values (such as aaSorting) since the dev wouldn't be
6495	 * able to override them, but we do want to deep copy arrays.
6496	 *  @param {object} out Object to extend
6497	 *  @param {object} extender Object from which the properties will be applied to
6498	 *      out
6499	 *  @param {boolean} breakRefs If true, then arrays will be sliced to take an
6500	 *      independent copy with the exception of the `data` or `aaData` parameters
6501	 *      if they are present. This is so you can pass in a collection to
6502	 *      DataTables and have that used as your data source without breaking the
6503	 *      references
6504	 *  @returns {object} out Reference, just for convenience - out === the return.
6505	 *  @memberof DataTable#oApi
6506	 *  @todo This doesn't take account of arrays inside the deep copied objects.
6507	 */
6508	function _fnExtend( out, extender, breakRefs )
6509	{
6510		var val;
6511	
6512		for ( var prop in extender ) {
6513			if ( extender.hasOwnProperty(prop) ) {
6514				val = extender[prop];
6515	
6516				if ( $.isPlainObject( val ) ) {
6517					if ( ! $.isPlainObject( out[prop] ) ) {
6518						out[prop] = {};
6519					}
6520					$.extend( true, out[prop], val );
6521				}
6522				else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
6523					out[prop] = val.slice();
6524				}
6525				else {
6526					out[prop] = val;
6527				}
6528			}
6529		}
6530	
6531		return out;
6532	}
6533	
6534	
6535	/**
6536	 * Bind an event handers to allow a click or return key to activate the callback.
6537	 * This is good for accessibility since a return on the keyboard will have the
6538	 * same effect as a click, if the element has focus.
6539	 *  @param {element} n Element to bind the action to
6540	 *  @param {object} oData Data object to pass to the triggered function
6541	 *  @param {function} fn Callback function for when the event is triggered
6542	 *  @memberof DataTable#oApi
6543	 */
6544	function _fnBindAction( n, oData, fn )
6545	{
6546		$(n)
6547			.on( 'click.DT', oData, function (e) {
6548					n.blur(); // Remove focus outline for mouse users
6549					fn(e);
6550				} )
6551			.on( 'keypress.DT', oData, function (e){
6552					if ( e.which === 13 ) {
6553						e.preventDefault();
6554						fn(e);
6555					}
6556				} )
6557			.on( 'selectstart.DT', function () {
6558					/* Take the brutal approach to cancelling text selection */
6559					return false;
6560				} );
6561	}
6562	
6563	
6564	/**
6565	 * Register a callback function. Easily allows a callback function to be added to
6566	 * an array store of callback functions that can then all be called together.
6567	 *  @param {object} oSettings dataTables settings object
6568	 *  @param {string} sStore Name of the array storage for the callbacks in oSettings
6569	 *  @param {function} fn Function to be called back
6570	 *  @param {string} sName Identifying name for the callback (i.e. a label)
6571	 *  @memberof DataTable#oApi
6572	 */
6573	function _fnCallbackReg( oSettings, sStore, fn, sName )
6574	{
6575		if ( fn )
6576		{
6577			oSettings[sStore].push( {
6578				"fn": fn,
6579				"sName": sName
6580			} );
6581		}
6582	}
6583	
6584	
6585	/**
6586	 * Fire callback functions and trigger events. Note that the loop over the
6587	 * callback array store is done backwards! Further note that you do not want to
6588	 * fire off triggers in time sensitive applications (for example cell creation)
6589	 * as its slow.
6590	 *  @param {object} settings dataTables settings object
6591	 *  @param {string} callbackArr Name of the array storage for the callbacks in
6592	 *      oSettings
6593	 *  @param {string} eventName Name of the jQuery custom event to trigger. If
6594	 *      null no trigger is fired
6595	 *  @param {array} args Array of arguments to pass to the callback function /
6596	 *      trigger
6597	 *  @memberof DataTable#oApi
6598	 */
6599	function _fnCallbackFire( settings, callbackArr, eventName, args )
6600	{
6601		var ret = [];
6602	
6603		if ( callbackArr ) {
6604			ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
6605				return val.fn.apply( settings.oInstance, args );
6606			} );
6607		}
6608	
6609		if ( eventName !== null ) {
6610			var e = $.Event( eventName+'.dt' );
6611	
6612			$(settings.nTable).trigger( e, args );
6613	
6614			ret.push( e.result );
6615		}
6616	
6617		return ret;
6618	}
6619	
6620	
6621	function _fnLengthOverflow ( settings )
6622	{
6623		var
6624			start = settings._iDisplayStart,
6625			end = settings.fnDisplayEnd(),
6626			len = settings._iDisplayLength;
6627	
6628		/* If we have space to show extra rows (backing up from the end point - then do so */
6629		if ( start >= end )
6630		{
6631			start = end - len;
6632		}
6633	
6634		// Keep the start record on the current page
6635		start -= (start % len);
6636	
6637		if ( len === -1 || start < 0 )
6638		{
6639			start = 0;
6640		}
6641	
6642		settings._iDisplayStart = start;
6643	}
6644	
6645	
6646	function _fnRenderer( settings, type )
6647	{
6648		var renderer = settings.renderer;
6649		var host = DataTable.ext.renderer[type];
6650	
6651		if ( $.isPlainObject( renderer ) && renderer[type] ) {
6652			// Specific renderer for this type. If available use it, otherwise use
6653			// the default.
6654			return host[renderer[type]] || host._;
6655		}
6656		else if ( typeof renderer === 'string' ) {
6657			// Common renderer - if there is one available for this type use it,
6658			// otherwise use the default
6659			return host[renderer] || host._;
6660		}
6661	
6662		// Use the default
6663		return host._;
6664	}
6665	
6666	
6667	/**
6668	 * Detect the data source being used for the table. Used to simplify the code
6669	 * a little (ajax) and to make it compress a little smaller.
6670	 *
6671	 *  @param {object} settings dataTables settings object
6672	 *  @returns {string} Data source
6673	 *  @memberof DataTable#oApi
6674	 */
6675	function _fnDataSource ( settings )
6676	{
6677		if ( settings.oFeatures.bServerSide ) {
6678			return 'ssp';
6679		}
6680		else if ( settings.ajax || settings.sAjaxSource ) {
6681			return 'ajax';
6682		}
6683		return 'dom';
6684	}
6685	
6686
6687	
6688	
6689	/**
6690	 * Computed structure of the DataTables API, defined by the options passed to
6691	 * `DataTable.Api.register()` when building the API.
6692	 *
6693	 * The structure is built in order to speed creation and extension of the Api
6694	 * objects since the extensions are effectively pre-parsed.
6695	 *
6696	 * The array is an array of objects with the following structure, where this
6697	 * base array represents the Api prototype base:
6698	 *
6699	 *     [
6700	 *       {
6701	 *         name:      'data'                -- string   - Property name
6702	 *         val:       function () {},       -- function - Api method (or undefined if just an object
6703	 *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
6704	 *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
6705	 *       },
6706	 *       {
6707	 *         name:     'row'
6708	 *         val:       {},
6709	 *         methodExt: [ ... ],
6710	 *         propExt:   [
6711	 *           {
6712	 *             name:      'data'
6713	 *             val:       function () {},
6714	 *             methodExt: [ ... ],
6715	 *             propExt:   [ ... ]
6716	 *           },
6717	 *           ...
6718	 *         ]
6719	 *       }
6720	 *     ]
6721	 *
6722	 * @type {Array}
6723	 * @ignore
6724	 */
6725	var __apiStruct = [];
6726	
6727	
6728	/**
6729	 * `Array.prototype` reference.
6730	 *
6731	 * @type object
6732	 * @ignore
6733	 */
6734	var __arrayProto = Array.prototype;
6735	
6736	
6737	/**
6738	 * Abstraction for `context` parameter of the `Api` constructor to allow it to
6739	 * take several different forms for ease of use.
6740	 *
6741	 * Each of the input parameter types will be converted to a DataTables settings
6742	 * object where possible.
6743	 *
6744	 * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one
6745	 *   of:
6746	 *
6747	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
6748	 *     with be found and used.
6749	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
6750	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
6751	 *   * `object` - DataTables settings object
6752	 *   * `DataTables.Api` - API instance
6753	 * @return {array|null} Matching DataTables settings objects. `null` or
6754	 *   `undefined` is returned if no matching DataTable is found.
6755	 * @ignore
6756	 */
6757	var _toSettings = function ( mixed )
6758	{
6759		var idx, jq;
6760		var settings = DataTable.settings;
6761		var tables = $.map( settings, function (el, i) {
6762			return el.nTable;
6763		} );
6764	
6765		if ( ! mixed ) {
6766			return [];
6767		}
6768		else if ( mixed.nTable && mixed.oApi ) {
6769			// DataTables settings object
6770			return [ mixed ];
6771		}
6772		else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
6773			// Table node
6774			idx = $.inArray( mixed, tables );
6775			return idx !== -1 ? [ settings[idx] ] : null;
6776		}
6777		else if ( mixed && typeof mixed.settings === 'function' ) {
6778			return mixed.settings().toArray();
6779		}
6780		else if ( typeof mixed === 'string' ) {
6781			// jQuery selector
6782			jq = $(mixed);
6783		}
6784		else if ( mixed instanceof $ ) {
6785			// jQuery object (also DataTables instance)
6786			jq = mixed;
6787		}
6788	
6789		if ( jq ) {
6790			return jq.map( function(i) {
6791				idx = $.inArray( this, tables );
6792				return idx !== -1 ? settings[idx] : null;
6793			} ).toArray();
6794		}
6795	};
6796	
6797	
6798	/**
6799	 * DataTables API class - used to control and interface with  one or more
6800	 * DataTables enhanced tables.
6801	 *
6802	 * The API class is heavily based on jQuery, presenting a chainable interface
6803	 * that you can use to interact with tables. Each instance of the API class has
6804	 * a "context" - i.e. the tables that it will operate on. This could be a single
6805	 * table, all tables on a page or a sub-set thereof.
6806	 *
6807	 * Additionally the API is designed to allow you to easily work with the data in
6808	 * the tables, retrieving and manipulating it as required. This is done by
6809	 * presenting the API class as an array like interface. The contents of the
6810	 * array depend upon the actions requested by each method (for example
6811	 * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6812	 * return an array of objects or arrays depending upon your table's
6813	 * configuration). The API object has a number of array like methods (`push`,
6814	 * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6815	 * `unique` etc) to assist your working with the data held in a table.
6816	 *
6817	 * Most methods (those which return an Api instance) are chainable, which means
6818	 * the return from a method call also has all of the methods available that the
6819	 * top level object had. For example, these two calls are equivalent:
6820	 *
6821	 *     // Not chained
6822	 *     api.row.add( {...} );
6823	 *     api.draw();
6824	 *
6825	 *     // Chained
6826	 *     api.row.add( {...} ).draw();
6827	 *
6828	 * @class DataTable.Api
6829	 * @param {array|object|string|jQuery} context DataTable identifier. This is
6830	 *   used to define which DataTables enhanced tables this API will operate on.
6831	 *   Can be one of:
6832	 *
6833	 *   * `string` - jQuery selector. Any DataTables' matching the given selector
6834	 *     with be found and used.
6835	 *   * `node` - `TABLE` node which has already been formed into a DataTable.
6836	 *   * `jQuery` - A jQuery object of `TABLE` nodes.
6837	 *   * `object` - DataTables settings object
6838	 * @param {array} [data] Data to initialise the Api instance with.
6839	 *
6840	 * @example
6841	 *   // Direct initialisation during DataTables construction
6842	 *   var api = $('#example').DataTable();
6843	 *
6844	 * @example
6845	 *   // Initialisation using a DataTables jQuery object
6846	 *   var api = $('#example').dataTable().api();
6847	 *
6848	 * @example
6849	 *   // Initialisation as a constructor
6850	 *   var api = new $.fn.DataTable.Api( 'table.dataTable' );
6851	 */
6852	_Api = function ( context, data )
6853	{
6854		if ( ! (this instanceof _Api) ) {
6855			return new _Api( context, data );
6856		}
6857	
6858		var settings = [];
6859		var ctxSettings = function ( o ) {
6860			var a = _toSettings( o );
6861			if ( a ) {
6862				settings = settings.concat( a );
6863			}
6864		};
6865	
6866		if ( $.isArray( context ) ) {
6867			for ( var i=0, ien=context.length ; i<ien ; i++ ) {
6868				ctxSettings( context[i] );
6869			}
6870		}
6871		else {
6872			ctxSettings( context );
6873		}
6874	
6875		// Remove duplicates
6876		this.context = _unique( settings );
6877	
6878		// Initial data
6879		if ( data ) {
6880			$.merge( this, data );
6881		}
6882	
6883		// selector
6884		this.selector = {
6885			rows: null,
6886			cols: null,
6887			opts: null
6888		};
6889	
6890		_Api.extend( this, this, __apiStruct );
6891	};
6892	
6893	DataTable.Api = _Api;
6894	
6895	// Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6896	// isPlainObject.
6897	$.extend( _Api.prototype, {
6898		any: function ()
6899		{
6900			return this.count() !== 0;
6901		},
6902	
6903	
6904		concat:  __arrayProto.concat,
6905	
6906	
6907		context: [], // array of table settings objects
6908	
6909	
6910		count: function ()
6911		{
6912			return this.flatten().length;
6913		},
6914	
6915	
6916		each: function ( fn )
6917		{
6918			for ( var i=0, ien=this.length ; i<ien; i++ ) {
6919				fn.call( this, this[i], i, this );
6920			}
6921	
6922			return this;
6923		},
6924	
6925	
6926		eq: function ( idx )
6927		{
6928			var ctx = this.context;
6929	
6930			return ctx.length > idx ?
6931				new _Api( ctx[idx], this[idx] ) :
6932				null;
6933		},
6934	
6935	
6936		filter: function ( fn )
6937		{
6938			var a = [];
6939	
6940			if ( __arrayProto.filter ) {
6941				a = __arrayProto.filter.call( this, fn, this );
6942			}
6943			else {
6944				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
6945				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6946					if ( fn.call( this, this[i], i, this ) ) {
6947						a.push( this[i] );
6948					}
6949				}
6950			}
6951	
6952			return new _Api( this.context, a );
6953		},
6954	
6955	
6956		flatten: function ()
6957		{
6958			var a = [];
6959			return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
6960		},
6961	
6962	
6963		join:    __arrayProto.join,
6964	
6965	
6966		indexOf: __arrayProto.indexOf || function (obj, start)
6967		{
6968			for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
6969				if ( this[i] === obj ) {
6970					return i;
6971				}
6972			}
6973			return -1;
6974		},
6975	
6976		iterator: function ( flatten, type, fn, alwaysNew ) {
6977			var
6978				a = [], ret,
6979				i, ien, j, jen,
6980				context = this.context,
6981				rows, items, item,
6982				selector = this.selector;
6983	
6984			// Argument shifting
6985			if ( typeof flatten === 'string' ) {
6986				alwaysNew = fn;
6987				fn = type;
6988				type = flatten;
6989				flatten = false;
6990			}
6991	
6992			for ( i=0, ien=context.length ; i<ien ; i++ ) {
6993				var apiInst = new _Api( context[i] );
6994	
6995				if ( type === 'table' ) {
6996					ret = fn.call( apiInst, context[i], i );
6997	
6998					if ( ret !== undefined ) {
6999						a.push( ret );
7000					}
7001				}
7002				else if ( type === 'columns' || type === 'rows' ) {
7003					// this has same length as context - one entry for each table
7004					ret = fn.call( apiInst, context[i], this[i], i );
7005	
7006					if ( ret !== undefined ) {
7007						a.push( ret );
7008					}
7009				}
7010				else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
7011					// columns and rows share the same structure.
7012					// 'this' is an array of column indexes for each context
7013					items = this[i];
7014	
7015					if ( type === 'column-rows' ) {
7016						rows = _selector_row_indexes( context[i], selector.opts );
7017					}
7018	
7019					for ( j=0, jen=items.length ; j<jen ; j++ ) {
7020						item = items[j];
7021	
7022						if ( type === 'cell' ) {
7023							ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
7024						}
7025						else {
7026							ret = fn.call( apiInst, context[i], item, i, j, rows );
7027						}
7028	
7029						if ( ret !== undefined ) {
7030							a.push( ret );
7031						}
7032					}
7033				}
7034			}
7035	
7036			if ( a.length || alwaysNew ) {
7037				var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
7038				var apiSelector = api.selector;
7039				apiSelector.rows = selector.rows;
7040				apiSelector.cols = selector.cols;
7041				apiSelector.opts = selector.opts;
7042				return api;
7043			}
7044			return this;
7045		},
7046	
7047	
7048		lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
7049		{
7050			// Bit cheeky...
7051			return this.indexOf.apply( this.toArray.reverse(), arguments );
7052		},
7053	
7054	
7055		length:  0,
7056	
7057	
7058		map: function ( fn )
7059		{
7060			var a = [];
7061	
7062			if ( __arrayProto.map ) {
7063				a = __arrayProto.map.call( this, fn, this );
7064			}
7065			else {
7066				// Compatibility for browsers without EMCA-252-5 (JS 1.6)
7067				for ( var i=0, ien=this.length ; i<ien ; i++ ) {
7068					a.push( fn.call( this, this[i], i ) );
7069				}
7070			}
7071	
7072			return new _Api( this.context, a );
7073		},
7074	
7075	
7076		pluck: function ( prop )
7077		{
7078			return this.map( function ( el ) {
7079				return el[ prop ];
7080			} );
7081		},
7082	
7083		pop:     __arrayProto.pop,
7084	
7085	
7086		push:    __arrayProto.push,
7087	
7088	
7089		// Does not return an API instance
7090		reduce: __arrayProto.reduce || function ( fn, init )
7091		{
7092			return _fnReduce( this, fn, init, 0, this.length, 1 );
7093		},
7094	
7095	
7096		reduceRight: __arrayProto.reduceRight || function ( fn, init )
7097		{
7098			return _fnReduce( this, fn, init, this.length-1, -1, -1 );
7099		},
7100	
7101	
7102		reverse: __arrayProto.reverse,
7103	
7104	
7105		// Object with rows, columns and opts
7106		selector: null,
7107	
7108	
7109		shift:   __arrayProto.shift,
7110	
7111	
7112		sort:    __arrayProto.sort, // ? name - order?
7113	
7114	
7115		splice:  __arrayProto.splice,
7116	
7117	
7118		toArray: function ()
7119		{
7120			return __arrayProto.slice.call( this );
7121		},
7122	
7123	
7124		to$: function ()
7125		{
7126			return $( this );
7127		},
7128	
7129	
7130		toJQuery: function ()
7131		{
7132			return $( this );
7133		},
7134	
7135	
7136		unique: function ()
7137		{
7138			return new _Api( this.context, _unique(this) );
7139		},
7140	
7141	
7142		unshift: __arrayProto.unshift
7143	} );
7144	
7145	
7146	_Api.extend = function ( scope, obj, ext )
7147	{
7148		// Only extend API instances and static properties of the API
7149		if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
7150			return;
7151		}
7152	
7153		var
7154			i, ien,
7155			j, jen,
7156			struct, inner,
7157			methodScoping = function ( scope, fn, struc ) {
7158				return function () {
7159					var ret = fn.apply( scope, arguments );
7160	
7161					// Method extension
7162					_Api.extend( ret, ret, struc.methodExt );
7163					return ret;
7164				};
7165			};
7166	
7167		for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7168			struct = ext[i];
7169	
7170			// Value
7171			obj[ struct.name ] = typeof struct.val === 'function' ?
7172				methodScoping( scope, struct.val, struct ) :
7173				$.isPlainObject( struct.val ) ?
7174					{} :
7175					struct.val;
7176	
7177			obj[ struct.name ].__dt_wrapper = true;
7178	
7179			// Property extension
7180			_Api.extend( scope, obj[ struct.name ], struct.propExt );
7181		}
7182	};
7183	
7184	
7185	// @todo - Is there need for an augment function?
7186	// _Api.augment = function ( inst, name )
7187	// {
7188	// 	// Find src object in the structure from the name
7189	// 	var parts = name.split('.');
7190	
7191	// 	_Api.extend( inst, obj );
7192	// };
7193	
7194	
7195	//     [
7196	//       {
7197	//         name:      'data'                -- string   - Property name
7198	//         val:       function () {},       -- function - Api method (or undefined if just an object
7199	//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result
7200	//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property
7201	//       },
7202	//       {
7203	//         name:     'row'
7204	//         val:       {},
7205	//         methodExt: [ ... ],
7206	//         propExt:   [
7207	//           {
7208	//             name:      'data'
7209	//             val:       function () {},
7210	//             methodExt: [ ... ],
7211	//             propExt:   [ ... ]
7212	//           },
7213	//           ...
7214	//         ]
7215	//       }
7216	//     ]
7217	
7218	_Api.register = _api_register = function ( name, val )
7219	{
7220		if ( $.isArray( name ) ) {
7221			for ( var j=0, jen=name.length ; j<jen ; j++ ) {
7222				_Api.register( name[j], val );
7223			}
7224			return;
7225		}
7226	
7227		var
7228			i, ien,
7229			heir = name.split('.'),
7230			struct = __apiStruct,
7231			key, method;
7232	
7233		var find = function ( src, name ) {
7234			for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7235				if ( src[i].name === name ) {
7236					return src[i];
7237				}
7238			}
7239			return null;
7240		};
7241	
7242		for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7243			method = heir[i].indexOf('()') !== -1;
7244			key = method ?
7245				heir[i].replace('()', '') :
7246				heir[i];
7247	
7248			var src = find( struct, key );
7249			if ( ! src ) {
7250				src = {
7251					name:      key,
7252					val:       {},
7253					methodExt: [],
7254					propExt:   []
7255				};
7256				struct.push( src );
7257			}
7258	
7259			if ( i === ien-1 ) {
7260				src.val = val;
7261			}
7262			else {
7263				struct = method ?
7264					src.methodExt :
7265					src.propExt;
7266			}
7267		}
7268	};
7269	
7270	
7271	_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
7272		_Api.register( pluralName, val );
7273	
7274		_Api.register( singularName, function () {
7275			var ret = val.apply( this, arguments );
7276	
7277			if ( ret === this ) {
7278				// Returned item is the API instance that was passed in, return it
7279				return this;
7280			}
7281			else if ( ret instanceof _Api ) {
7282				// New API instance returned, want the value from the first item
7283				// in the returned array for the singular result.
7284				return ret.length ?
7285					$.isArray( ret[0] ) ?
7286						new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
7287						ret[0] :
7288					undefined;
7289			}
7290	
7291			// Non-API return - just fire it back
7292			return ret;
7293		} );
7294	};
7295	
7296	
7297	/**
7298	 * Selector for HTML tables. Apply the given selector to the give array of
7299	 * DataTables settings objects.
7300	 *
7301	 * @param {string|integer} [selector] jQuery selector string or integer
7302	 * @param  {array} Array of DataTables settings objects to be filtered
7303	 * @return {array}
7304	 * @ignore
7305	 */
7306	var __table_selector = function ( selector, a )
7307	{
7308		// Integer is used to pick out a table by index
7309		if ( typeof selector === 'number' ) {
7310			return [ a[ selector ] ];
7311		}
7312	
7313		// Perform a jQuery selector on the table nodes
7314		var nodes = $.map( a, function (el, i) {
7315			return el.nTable;
7316		} );
7317	
7318		return $(nodes)
7319			.filter( selector )
7320			.map( function (i) {
7321				// Need to translate back from the table node to the settings
7322				var idx = $.inArray( this, nodes );
7323				return a[ idx ];
7324			} )
7325			.toArray();
7326	};
7327	
7328	
7329	
7330	/**
7331	 * Context selector for the API's context (i.e. the tables the API instance
7332	 * refers to.
7333	 *
7334	 * @name    DataTable.Api#tables
7335	 * @param {string|integer} [selector] Selector to pick which tables the iterator
7336	 *   should operate on. If not given, all tables in the current context are
7337	 *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7338	 *   select multiple tables or as an integer to select a single table.
7339	 * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7340	 */
7341	_api_register( 'tables()', function ( selector ) {
7342		// A new instance is created if there was a selector specified
7343		return selector
vendor: 9,632 bytes, lines 7343-7691
7343 ?
7344			new _Api( __table_selector( selector, this.context ) ) :
7345			this;
7346	} );
7347	
7348	
7349	_api_register( 'table()', function ( selector ) {
7350		var tables = this.tables( selector );
7351		var ctx = tables.context;
7352	
7353		// Truncate to the first matched table
7354		return ctx.length ?
7355			new _Api( ctx[0] ) :
7356			tables;
7357	} );
7358	
7359	
7360	_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
7361		return this.iterator( 'table', function ( ctx ) {
7362			return ctx.nTable;
7363		}, 1 );
7364	} );
7365	
7366	
7367	_api_registerPlural( 'tables().body()', 'table().body()' , function () {
7368		return this.iterator( 'table', function ( ctx ) {
7369			return ctx.nTBody;
7370		}, 1 );
7371	} );
7372	
7373	
7374	_api_registerPlural( 'tables().header()', 'table().header()' , function () {
7375		return this.iterator( 'table', function ( ctx ) {
7376			return ctx.nTHead;
7377		}, 1 );
7378	} );
7379	
7380	
7381	_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
7382		return this.iterator( 'table', function ( ctx ) {
7383			return ctx.nTFoot;
7384		}, 1 );
7385	} );
7386	
7387	
7388	_api_registerPlural( 'tables().containers()', 'table().container()' , function () {
7389		return this.iterator( 'table', function ( ctx ) {
7390			return ctx.nTableWrapper;
7391		}, 1 );
7392	} );
7393	
7394	
7395	
7396	/**
7397	 * Redraw the tables in the current context.
7398	 */
7399	_api_register( 'draw()', function ( paging ) {
7400		return this.iterator( 'table', function ( settings ) {
7401			if ( paging === 'page' ) {
7402				_fnDraw( settings );
7403			}
7404			else {
7405				if ( typeof paging === 'string' ) {
7406					paging = paging === 'full-hold' ?
7407						false :
7408						true;
7409				}
7410	
7411				_fnReDraw( settings, paging===false );
7412			}
7413		} );
7414	} );
7415	
7416	
7417	
7418	/**
7419	 * Get the current page index.
7420	 *
7421	 * @return {integer} Current page index (zero based)
7422	 *//**
7423	 * Set the current page.
7424	 *
7425	 * Note that if you attempt to show a page which does not exist, DataTables will
7426	 * not throw an error, but rather reset the paging.
7427	 *
7428	 * @param {integer|string} action The paging action to take. This can be one of:
7429	 *  * `integer` - The page index to jump to
7430	 *  * `string` - An action to take:
7431	 *    * `first` - Jump to first page.
7432	 *    * `next` - Jump to the next page
7433	 *    * `previous` - Jump to previous page
7434	 *    * `last` - Jump to the last page.
7435	 * @returns {DataTables.Api} this
7436	 */
7437	_api_register( 'page()', function ( action ) {
7438		if ( action === undefined ) {
7439			return this.page.info().page; // not an expensive call
7440		}
7441	
7442		// else, have an action to take on all tables
7443		return this.iterator( 'table', function ( settings ) {
7444			_fnPageChange( settings, action );
7445		} );
7446	} );
7447	
7448	
7449	/**
7450	 * Paging information for the first table in the current context.
7451	 *
7452	 * If you require paging information for another table, use the `table()` method
7453	 * with a suitable selector.
7454	 *
7455	 * @return {object} Object with the following properties set:
7456	 *  * `page` - Current page index (zero based - i.e. the first page is `0`)
7457	 *  * `pages` - Total number of pages
7458	 *  * `start` - Display index for the first record shown on the current page
7459	 *  * `end` - Display index for the last record shown on the current page
7460	 *  * `length` - Display length (number of records). Note that generally `start
7461	 *    + length = end`, but this is not always true, for example if there are
7462	 *    only 2 records to show on the final page, with a length of 10.
7463	 *  * `recordsTotal` - Full data set length
7464	 *  * `recordsDisplay` - Data set length once the current filtering criterion
7465	 *    are applied.
7466	 */
7467	_api_register( 'page.info()', function ( action ) {
7468		if ( this.context.length === 0 ) {
7469			return undefined;
7470		}
7471	
7472		var
7473			settings   = this.context[0],
7474			start      = settings._iDisplayStart,
7475			len        = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
7476			visRecords = settings.fnRecordsDisplay(),
7477			all        = len === -1;
7478	
7479		return {
7480			"page":           all ? 0 : Math.floor( start / len ),
7481			"pages":          all ? 1 : Math.ceil( visRecords / len ),
7482			"start":          start,
7483			"end":            settings.fnDisplayEnd(),
7484			"length":         len,
7485			"recordsTotal":   settings.fnRecordsTotal(),
7486			"recordsDisplay": visRecords,
7487			"serverSide":     _fnDataSource( settings ) === 'ssp'
7488		};
7489	} );
7490	
7491	
7492	/**
7493	 * Get the current page length.
7494	 *
7495	 * @return {integer} Current page length. Note `-1` indicates that all records
7496	 *   are to be shown.
7497	 *//**
7498	 * Set the current page length.
7499	 *
7500	 * @param {integer} Page length to set. Use `-1` to show all records.
7501	 * @returns {DataTables.Api} this
7502	 */
7503	_api_register( 'page.len()', function ( len ) {
7504		// Note that we can't call this function 'length()' because `length`
7505		// is a Javascript property of functions which defines how many arguments
7506		// the function expects.
7507		if ( len === undefined ) {
7508			return this.context.length !== 0 ?
7509				this.context[0]._iDisplayLength :
7510				undefined;
7511		}
7512	
7513		// else, set the page length
7514		return this.iterator( 'table', function ( settings ) {
7515			_fnLengthChange( settings, len );
7516		} );
7517	} );
7518	
7519	
7520	
7521	var __reload = function ( settings, holdPosition, callback ) {
7522		// Use the draw event to trigger a callback
7523		if ( callback ) {
7524			var api = new _Api( settings );
7525	
7526			api.one( 'draw', function () {
7527				callback( api.ajax.json() );
7528			} );
7529		}
7530	
7531		if ( _fnDataSource( settings ) == 'ssp' ) {
7532			_fnReDraw( settings, holdPosition );
7533		}
7534		else {
7535			_fnProcessingDisplay( settings, true );
7536	
7537			// Cancel an existing request
7538			var xhr = settings.jqXHR;
7539			if ( xhr && xhr.readyState !== 4 ) {
7540				xhr.abort();
7541			}
7542	
7543			// Trigger xhr
7544			_fnBuildAjax( settings, [], function( json ) {
7545				_fnClearTable( settings );
7546	
7547				var data = _fnAjaxDataSrc( settings, json );
7548				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7549					_fnAddData( settings, data[i] );
7550				}
7551	
7552				_fnReDraw( settings, holdPosition );
7553				_fnProcessingDisplay( settings, false );
7554			} );
7555		}
7556	};
7557	
7558	
7559	/**
7560	 * Get the JSON response from the last Ajax request that DataTables made to the
7561	 * server. Note that this returns the JSON from the first table in the current
7562	 * context.
7563	 *
7564	 * @return {object} JSON received from the server.
7565	 */
7566	_api_register( 'ajax.json()', function () {
7567		var ctx = this.context;
7568	
7569		if ( ctx.length > 0 ) {
7570			return ctx[0].json;
7571		}
7572	
7573		// else return undefined;
7574	} );
7575	
7576	
7577	/**
7578	 * Get the data submitted in the last Ajax request
7579	 */
7580	_api_register( 'ajax.params()', function () {
7581		var ctx = this.context;
7582	
7583		if ( ctx.length > 0 ) {
7584			return ctx[0].oAjaxData;
7585		}
7586	
7587		// else return undefined;
7588	} );
7589	
7590	
7591	/**
7592	 * Reload tables from the Ajax data source. Note that this function will
7593	 * automatically re-draw the table when the remote data has been loaded.
7594	 *
7595	 * @param {boolean} [reset=true] Reset (default) or hold the current paging
7596	 *   position. A full re-sort and re-filter is performed when this method is
7597	 *   called, which is why the pagination reset is the default action.
7598	 * @returns {DataTables.Api} this
7599	 */
7600	_api_register( 'ajax.reload()', function ( callback, resetPaging ) {
7601		return this.iterator( 'table', function (settings) {
7602			__reload( settings, resetPaging===false, callback );
7603		} );
7604	} );
7605	
7606	
7607	/**
7608	 * Get the current Ajax URL. Note that this returns the URL from the first
7609	 * table in the current context.
7610	 *
7611	 * @return {string} Current Ajax source URL
7612	 *//**
7613	 * Set the Ajax URL. Note that this will set the URL for all tables in the
7614	 * current context.
7615	 *
7616	 * @param {string} url URL to set.
7617	 * @returns {DataTables.Api} this
7618	 */
7619	_api_register( 'ajax.url()', function ( url ) {
7620		var ctx = this.context;
7621	
7622		if ( url === undefined ) {
7623			// get
7624			if ( ctx.length === 0 ) {
7625				return undefined;
7626			}
7627			ctx = ctx[0];
7628	
7629			return ctx.ajax ?
7630				$.isPlainObject( ctx.ajax ) ?
7631					ctx.ajax.url :
7632					ctx.ajax :
7633				ctx.sAjaxSource;
7634		}
7635	
7636		// set
7637		return this.iterator( 'table', function ( settings ) {
7638			if ( $.isPlainObject( settings.ajax ) ) {
7639				settings.ajax.url = url;
7640			}
7641			else {
7642				settings.ajax = url;
7643			}
7644			// No need to consider sAjaxSource here since DataTables gives priority
7645			// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7646			// value of `sAjaxSource` redundant.
7647		} );
7648	} );
7649	
7650	
7651	/**
7652	 * Load data from the newly set Ajax URL. Note that this method is only
7653	 * available when `ajax.url()` is used to set a URL. Additionally, this method
7654	 * has the same effect as calling `ajax.reload()` but is provided for
7655	 * convenience when setting a new URL. Like `ajax.reload()` it will
7656	 * automatically redraw the table once the remote data has been loaded.
7657	 *
7658	 * @returns {DataTables.Api} this
7659	 */
7660	_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
7661		// Same as a reload, but makes sense to present it for easy access after a
7662		// url change
7663		return this.iterator( 'table', function ( ctx ) {
7664			__reload( ctx, resetPaging===false, callback );
7665		} );
7666	} );
7667	
7668	
7669	
7670	
7671	var _selector_run = function ( type, selector, selectFn, settings, opts )
7672	{
7673		var
7674			out = [], res,
7675			a, i, ien, j, jen,
7676			selectorType = typeof selector;
7677	
7678		// Can't just check for isArray here, as an API or jQuery instance might be
7679		// given with their array like look
7680		if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
7681			selector = [ selector ];
7682		}
7683	
7684		for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7685			// Only split on simple strings - complex expressions will be jQuery selectors
7686			a = selector[i] && selector[i].split && ! selector[i].match(/[\[\(:]/) ?
7687				selector[i].split(',') :
7688				[ selector[i] ];
7689	
7690			for ( j=0, jen=a.length ; j<jen ; j++ ) {
7691				res = selectFn( typeof a[j] === 'string' ? 
vendor: 44,990 bytes, lines 7691-9391
7691$.trim(a[j]) : a[j] );
7692	
7693				if ( res && res.length ) {
7694					out = out.concat( res );
7695				}
7696			}
7697		}
7698	
7699		// selector extensions
7700		var ext = _ext.selector[ type ];
7701		if ( ext.length ) {
7702			for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7703				out = ext[i]( settings, opts, out );
7704			}
7705		}
7706	
7707		return _unique( out );
7708	};
7709	
7710	
7711	var _selector_opts = function ( opts )
7712	{
7713		if ( ! opts ) {
7714			opts = {};
7715		}
7716	
7717		// Backwards compatibility for 1.9- which used the terminology filter rather
7718		// than search
7719		if ( opts.filter && opts.search === undefined ) {
7720			opts.search = opts.filter;
7721		}
7722	
7723		return $.extend( {
7724			search: 'none',
7725			order: 'current',
7726			page: 'all'
7727		}, opts );
7728	};
7729	
7730	
7731	var _selector_first = function ( inst )
7732	{
7733		// Reduce the API instance to the first item found
7734		for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
7735			if ( inst[i].length > 0 ) {
7736				// Assign the first element to the first item in the instance
7737				// and truncate the instance and context
7738				inst[0] = inst[i];
7739				inst[0].length = 1;
7740				inst.length = 1;
7741				inst.context = [ inst.context[i] ];
7742	
7743				return inst;
7744			}
7745		}
7746	
7747		// Not found - return an empty instance
7748		inst.length = 0;
7749		return inst;
7750	};
7751	
7752	
7753	var _selector_row_indexes = function ( settings, opts )
7754	{
7755		var
7756			i, ien, tmp, a=[],
7757			displayFiltered = settings.aiDisplay,
7758			displayMaster = settings.aiDisplayMaster;
7759	
7760		var
7761			search = opts.search,  // none, applied, removed
7762			order  = opts.order,   // applied, current, index (original - compatibility with 1.9)
7763			page   = opts.page;    // all, current
7764	
7765		if ( _fnDataSource( settings ) == 'ssp' ) {
7766			// In server-side processing mode, most options are irrelevant since
7767			// rows not shown don't exist and the index order is the applied order
7768			// Removed is a special case - for consistency just return an empty
7769			// array
7770			return search === 'removed' ?
7771				[] :
7772				_range( 0, displayMaster.length );
7773		}
7774		else if ( page == 'current' ) {
7775			// Current page implies that order=current and fitler=applied, since it is
7776			// fairly senseless otherwise, regardless of what order and search actually
7777			// are
7778			for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
7779				a.push( displayFiltered[i] );
7780			}
7781		}
7782		else if ( order == 'current' || order == 'applied' ) {
7783			a = search == 'none' ?
7784				displayMaster.slice() :                      // no search
7785				search == 'applied' ?
7786					displayFiltered.slice() :                // applied search
7787					$.map( displayMaster, function (el, i) { // removed search
7788						return $.inArray( el, displayFiltered ) === -1 ? el : null;
7789					} );
7790		}
7791		else if ( order == 'index' || order == 'original' ) {
7792			for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7793				if ( search == 'none' ) {
7794					a.push( i );
7795				}
7796				else { // applied | removed
7797					tmp = $.inArray( i, displayFiltered );
7798	
7799					if ((tmp === -1 && search == 'removed') ||
7800						(tmp >= 0   && search == 'applied') )
7801					{
7802						a.push( i );
7803					}
7804				}
7805			}
7806		}
7807	
7808		return a;
7809	};
7810	
7811	
7812	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7813	 * Rows
7814	 *
7815	 * {}          - no selector - use all available rows
7816	 * {integer}   - row aoData index
7817	 * {node}      - TR node
7818	 * {string}    - jQuery selector to apply to the TR elements
7819	 * {array}     - jQuery array of nodes, or simply an array of TR nodes
7820	 *
7821	 */
7822	
7823	
7824	var __row_selector = function ( settings, selector, opts )
7825	{
7826		var rows;
7827		var run = function ( sel ) {
7828			var selInt = _intVal( sel );
7829			var i, ien;
7830	
7831			// Short cut - selector is a number and no options provided (default is
7832			// all records, so no need to check if the index is in there, since it
7833			// must be - dev error if the index doesn't exist).
7834			if ( selInt !== null && ! opts ) {
7835				return [ selInt ];
7836			}
7837	
7838			if ( ! rows ) {
7839				rows = _selector_row_indexes( settings, opts );
7840			}
7841	
7842			if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7843				// Selector - integer
7844				return [ selInt ];
7845			}
7846			else if ( sel === null || sel === undefined || sel === '' ) {
7847				// Selector - none
7848				return rows;
7849			}
7850	
7851			// Selector - function
7852			if ( typeof sel === 'function' ) {
7853				return $.map( rows, function (idx) {
7854					var row = settings.aoData[ idx ];
7855					return sel( idx, row._aData, row.nTr ) ? idx : null;
7856				} );
7857			}
7858	
7859			// Get nodes in the order from the `rows` array with null values removed
7860			var nodes = _removeEmpty(
7861				_pluck_order( settings.aoData, rows, 'nTr' )
7862			);
7863	
7864			// Selector - node
7865			if ( sel.nodeName ) {
7866				if ( sel._DT_RowIndex !== undefined ) {
7867					return [ sel._DT_RowIndex ]; // Property added by DT for fast lookup
7868				}
7869				else if ( sel._DT_CellIndex ) {
7870					return [ sel._DT_CellIndex.row ];
7871				}
7872				else {
7873					var host = $(sel).closest('*[data-dt-row]');
7874					return host.length ?
7875						[ host.data('dt-row') ] :
7876						[];
7877				}
7878			}
7879	
7880			// ID selector. Want to always be able to select rows by id, regardless
7881			// of if the tr element has been created or not, so can't rely upon
7882			// jQuery here - hence a custom implementation. This does not match
7883			// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7884			// but to select it using a CSS selector engine (like Sizzle or
7885			// querySelect) it would need to need to be escaped for some characters.
7886			// DataTables simplifies this for row selectors since you can select
7887			// only a row. A # indicates an id any anything that follows is the id -
7888			// unescaped.
7889			if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7890				// get row index from id
7891				var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7892				if ( rowObj !== undefined ) {
7893					return [ rowObj.idx ];
7894				}
7895	
7896				// need to fall through to jQuery in case there is DOM id that
7897				// matches
7898			}
7899	
7900			// Selector - jQuery selector string, array of nodes or jQuery object/
7901			// As jQuery's .filter() allows jQuery objects to be passed in filter,
7902			// it also allows arrays, so this will cope with all three options
7903			return $(nodes)
7904				.filter( sel )
7905				.map( function () {
7906					return this._DT_RowIndex;
7907				} )
7908				.toArray();
7909		};
7910	
7911		return _selector_run( 'row', selector, run, settings, opts );
7912	};
7913	
7914	
7915	_api_register( 'rows()', function ( selector, opts ) {
7916		// argument shifting
7917		if ( selector === undefined ) {
7918			selector = '';
7919		}
7920		else if ( $.isPlainObject( selector ) ) {
7921			opts = selector;
7922			selector = '';
7923		}
7924	
7925		opts = _selector_opts( opts );
7926	
7927		var inst = this.iterator( 'table', function ( settings ) {
7928			return __row_selector( settings, selector, opts );
7929		}, 1 );
7930	
7931		// Want argument shifting here and in __row_selector?
7932		inst.selector.rows = selector;
7933		inst.selector.opts = opts;
7934	
7935		return inst;
7936	} );
7937	
7938	_api_register( 'rows().nodes()', function () {
7939		return this.iterator( 'row', function ( settings, row ) {
7940			return settings.aoData[ row ].nTr || undefined;
7941		}, 1 );
7942	} );
7943	
7944	_api_register( 'rows().data()', function () {
7945		return this.iterator( true, 'rows', function ( settings, rows ) {
7946			return _pluck_order( settings.aoData, rows, '_aData' );
7947		}, 1 );
7948	} );
7949	
7950	_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
7951		return this.iterator( 'row', function ( settings, row ) {
7952			var r = settings.aoData[ row ];
7953			return type === 'search' ? r._aFilterData : r._aSortData;
7954		}, 1 );
7955	} );
7956	
7957	_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
7958		return this.iterator( 'row', function ( settings, row ) {
7959			_fnInvalidate( settings, row, src );
7960		} );
7961	} );
7962	
7963	_api_registerPlural( 'rows().indexes()', 'row().index()', function () {
7964		return this.iterator( 'row', function ( settings, row ) {
7965			return row;
7966		}, 1 );
7967	} );
7968	
7969	_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
7970		var a = [];
7971		var context = this.context;
7972	
7973		// `iterator` will drop undefined values, but in this case we want them
7974		for ( var i=0, ien=context.length ; i<ien ; i++ ) {
7975			for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
7976				var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
7977				a.push( (hash === true ? '#' : '' )+ id );
7978			}
7979		}
7980	
7981		return new _Api( context, a );
7982	} );
7983	
7984	_api_registerPlural( 'rows().remove()', 'row().remove()', function () {
7985		var that = this;
7986	
7987		this.iterator( 'row', function ( settings, row, thatIdx ) {
7988			var data = settings.aoData;
7989			var rowData = data[ row ];
7990			var i, ien, j, jen;
7991			var loopRow, loopCells;
7992	
7993			data.splice( row, 1 );
7994	
7995			// Update the cached indexes
7996			for ( i=0, ien=data.length ; i<ien ; i++ ) {
7997				loopRow = data[i];
7998				loopCells = loopRow.anCells;
7999	
8000				// Rows
8001				if ( loopRow.nTr !== null ) {
8002					loopRow.nTr._DT_RowIndex = i;
8003				}
8004	
8005				// Cells
8006				if ( loopCells !== null ) {
8007					for ( j=0, jen=loopCells.length ; j<jen ; j++ ) {
8008						loopCells[j]._DT_CellIndex.row = i;
8009					}
8010				}
8011			}
8012	
8013			// Delete from the display arrays
8014			_fnDeleteIndex( settings.aiDisplayMaster, row );
8015			_fnDeleteIndex( settings.aiDisplay, row );
8016			_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
8017	
8018			// Check for an 'overflow' they case for displaying the table
8019			_fnLengthOverflow( settings );
8020	
8021			// Remove the row's ID reference if there is one
8022			var id = settings.rowIdFn( rowData._aData );
8023			if ( id !== undefined ) {
8024				delete settings.aIds[ id ];
8025			}
8026		} );
8027	
8028		this.iterator( 'table', function ( settings ) {
8029			for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
8030				settings.aoData[i].idx = i;
8031			}
8032		} );
8033	
8034		return this;
8035	} );
8036	
8037	
8038	_api_register( 'rows.add()', function ( rows ) {
8039		var newRows = this.iterator( 'table', function ( settings ) {
8040				var row, i, ien;
8041				var out = [];
8042	
8043				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8044					row = rows[i];
8045	
8046					if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
8047						out.push( _fnAddTr( settings, row )[0] );
8048					}
8049					else {
8050						out.push( _fnAddData( settings, row ) );
8051					}
8052				}
8053	
8054				return out;
8055			}, 1 );
8056	
8057		// Return an Api.rows() extended instance, so rows().nodes() etc can be used
8058		var modRows = this.rows( -1 );
8059		modRows.pop();
8060		$.merge( modRows, newRows );
8061	
8062		return modRows;
8063	} );
8064	
8065	
8066	
8067	
8068	
8069	/**
8070	 *
8071	 */
8072	_api_register( 'row()', function ( selector, opts ) {
8073		return _selector_first( this.rows( selector, opts ) );
8074	} );
8075	
8076	
8077	_api_register( 'row().data()', function ( data ) {
8078		var ctx = this.context;
8079	
8080		if ( data === undefined ) {
8081			// Get
8082			return ctx.length && this.length ?
8083				ctx[0].aoData[ this[0] ]._aData :
8084				undefined;
8085		}
8086	
8087		// Set
8088		ctx[0].aoData[ this[0] ]._aData = data;
8089	
8090		// Automatically invalidate
8091		_fnInvalidate( ctx[0], this[0], 'data' );
8092	
8093		return this;
8094	} );
8095	
8096	
8097	_api_register( 'row().node()', function () {
8098		var ctx = this.context;
8099	
8100		return ctx.length && this.length ?
8101			ctx[0].aoData[ this[0] ].nTr || null :
8102			null;
8103	} );
8104	
8105	
8106	_api_register( 'row.add()', function ( row ) {
8107		// Allow a jQuery object to be passed in - only a single row is added from
8108		// it though - the first element in the set
8109		if ( row instanceof $ && row.length ) {
8110			row = row[0];
8111		}
8112	
8113		var rows = this.iterator( 'table', function ( settings ) {
8114			if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
8115				return _fnAddTr( settings, row )[0];
8116			}
8117			return _fnAddData( settings, row );
8118		} );
8119	
8120		// Return an Api.rows() extended instance, with the newly added row selected
8121		return this.row( rows[0] );
8122	} );
8123	
8124	
8125	
8126	var __details_add = function ( ctx, row, data, klass )
8127	{
8128		// Convert to array of TR elements
8129		var rows = [];
8130		var addRow = function ( r, k ) {
8131			// Recursion to allow for arrays of jQuery objects
8132			if ( $.isArray( r ) || r instanceof $ ) {
8133				for ( var i=0, ien=r.length ; i<ien ; i++ ) {
8134					addRow( r[i], k );
8135				}
8136				return;
8137			}
8138	
8139			// If we get a TR element, then just add it directly - up to the dev
8140			// to add the correct number of columns etc
8141			if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
8142				rows.push( r );
8143			}
8144			else {
8145				// Otherwise create a row with a wrapper
8146				var created = $('<tr><td/></tr>').addClass( k );
8147				$('td', created)
8148					.addClass( k )
8149					.html( r )
8150					[0].colSpan = _fnVisbleColumns( ctx );
8151	
8152				rows.push( created[0] );
8153			}
8154		};
8155	
8156		addRow( data, klass );
8157	
8158		if ( row._details ) {
8159			row._details.detach();
8160		}
8161	
8162		row._details = $(rows);
8163	
8164		// If the children were already shown, that state should be retained
8165		if ( row._detailsShow ) {
8166			row._details.insertAfter( row.nTr );
8167		}
8168	};
8169	
8170	
8171	var __details_remove = function ( api, idx )
8172	{
8173		var ctx = api.context;
8174	
8175		if ( ctx.length ) {
8176			var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8177	
8178			if ( row && row._details ) {
8179				row._details.remove();
8180	
8181				row._detailsShow = undefined;
8182				row._details = undefined;
8183			}
8184		}
8185	};
8186	
8187	
8188	var __details_display = function ( api, show ) {
8189		var ctx = api.context;
8190	
8191		if ( ctx.length && api.length ) {
8192			var row = ctx[0].aoData[ api[0] ];
8193	
8194			if ( row._details ) {
8195				row._detailsShow = show;
8196	
8197				if ( show ) {
8198					row._details.insertAfter( row.nTr );
8199				}
8200				else {
8201					row._details.detach();
8202				}
8203	
8204				__details_events( ctx[0] );
8205			}
8206		}
8207	};
8208	
8209	
8210	var __details_events = function ( settings )
8211	{
8212		var api = new _Api( settings );
8213		var namespace = '.dt.DT_details';
8214		var drawEvent = 'draw'+namespace;
8215		var colvisEvent = 'column-visibility'+namespace;
8216		var destroyEvent = 'destroy'+namespace;
8217		var data = settings.aoData;
8218	
8219		api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
8220	
8221		if ( _pluck( data, '_details' ).length > 0 ) {
8222			// On each draw, insert the required elements into the document
8223			api.on( drawEvent, function ( e, ctx ) {
8224				if ( settings !== ctx ) {
8225					return;
8226				}
8227	
8228				api.rows( {page:'current'} ).eq(0).each( function (idx) {
8229					// Internal data grab
8230					var row = data[ idx ];
8231	
8232					if ( row._detailsShow ) {
8233						row._details.insertAfter( row.nTr );
8234					}
8235				} );
8236			} );
8237	
8238			// Column visibility change - update the colspan
8239			api.on( colvisEvent, function ( e, ctx, idx, vis ) {
8240				if ( settings !== ctx ) {
8241					return;
8242				}
8243	
8244				// Update the colspan for the details rows (note, only if it already has
8245				// a colspan)
8246				var row, visible = _fnVisbleColumns( ctx );
8247	
8248				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8249					row = data[i];
8250	
8251					if ( row._details ) {
8252						row._details.children('td[colspan]').attr('colspan', visible );
8253					}
8254				}
8255			} );
8256	
8257			// Table destroyed - nuke any child rows
8258			api.on( destroyEvent, function ( e, ctx ) {
8259				if ( settings !== ctx ) {
8260					return;
8261				}
8262	
8263				for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8264					if ( data[i]._details ) {
8265						__details_remove( api, i );
8266					}
8267				}
8268			} );
8269		}
8270	};
8271	
8272	// Strings for the method names to help minification
8273	var _emp = '';
8274	var _child_obj = _emp+'row().child';
8275	var _child_mth = _child_obj+'()';
8276	
8277	// data can be:
8278	//  tr
8279	//  string
8280	//  jQuery or array of any of the above
8281	_api_register( _child_mth, function ( data, klass ) {
8282		var ctx = this.context;
8283	
8284		if ( data === undefined ) {
8285			// get
8286			return ctx.length && this.length ?
8287				ctx[0].aoData[ this[0] ]._details :
8288				undefined;
8289		}
8290		else if ( data === true ) {
8291			// show
8292			this.child.show();
8293		}
8294		else if ( data === false ) {
8295			// remove
8296			__details_remove( this );
8297		}
8298		else if ( ctx.length && this.length ) {
8299			// set
8300			__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
8301		}
8302	
8303		return this;
8304	} );
8305	
8306	
8307	_api_register( [
8308		_child_obj+'.show()',
8309		_child_mth+'.show()' // only when `child()` was called with parameters (without
8310	], function ( show ) {   // it returns an object and this method is not executed)
8311		__details_display( this, true );
8312		return this;
8313	} );
8314	
8315	
8316	_api_register( [
8317		_child_obj+'.hide()',
8318		_child_mth+'.hide()' // only when `child()` was called with parameters (without
8319	], function () {         // it returns an object and this method is not executed)
8320		__details_display( this, false );
8321		return this;
8322	} );
8323	
8324	
8325	_api_register( [
8326		_child_obj+'.remove()',
8327		_child_mth+'.remove()' // only when `child()` was called with parameters (without
8328	], function () {           // it returns an object and this method is not executed)
8329		__details_remove( this );
8330		return this;
8331	} );
8332	
8333	
8334	_api_register( _child_obj+'.isShown()', function () {
8335		var ctx = this.context;
8336	
8337		if ( ctx.length && this.length ) {
8338			// _detailsShown as false or undefined will fall through to return false
8339			return ctx[0].aoData[ this[0] ]._detailsShow || false;
8340		}
8341		return false;
8342	} );
8343	
8344	
8345	
8346	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8347	 * Columns
8348	 *
8349	 * {integer}           - column index (>=0 count from left, <0 count from right)
8350	 * "{integer}:visIdx"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)
8351	 * "{integer}:visible" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)
8352	 * "{string}:name"     - column name
8353	 * "{string}"          - jQuery selector on column header nodes
8354	 *
8355	 */
8356	
8357	// can be an array of these items, comma separated list, or an array of comma
8358	// separated lists
8359	
8360	var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
8361	
8362	
8363	// r1 and r2 are redundant - but it means that the parameters match for the
8364	// iterator callback in columns().data()
8365	var __columnData = function ( settings, column, r1, r2, rows ) {
8366		var a = [];
8367		for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8368			a.push( _fnGetCellData( settings, rows[row], column ) );
8369		}
8370		return a;
8371	};
8372	
8373	
8374	var __column_selector = function ( settings, selector, opts )
8375	{
8376		var
8377			columns = settings.aoColumns,
8378			names = _pluck( columns, 'sName' ),
8379			nodes = _pluck( columns, 'nTh' );
8380	
8381		var run = function ( s ) {
8382			var selInt = _intVal( s );
8383	
8384			// Selector - all
8385			if ( s === '' ) {
8386				return _range( columns.length );
8387			}
8388	
8389			// Selector - index
8390			if ( selInt !== null ) {
8391				return [ selInt >= 0 ?
8392					selInt : // Count from left
8393					columns.length + selInt // Count from right (+ because its a negative value)
8394				];
8395			}
8396	
8397			// Selector = function
8398			if ( typeof s === 'function' ) {
8399				var rows = _selector_row_indexes( settings, opts );
8400	
8401				return $.map( columns, function (col, idx) {
8402					return s(
8403							idx,
8404							__columnData( settings, idx, 0, 0, rows ),
8405							nodes[ idx ]
8406						) ? idx : null;
8407				} );
8408			}
8409	
8410			// jQuery or string selector
8411			var match = typeof s === 'string' ?
8412				s.match( __re_column_selector ) :
8413				'';
8414	
8415			if ( match ) {
8416				switch( match[2] ) {
8417					case 'visIdx':
8418					case 'visible':
8419						var idx = parseInt( match[1], 10 );
8420						// Visible index given, convert to column index
8421						if ( idx < 0 ) {
8422							// Counting from the right
8423							var visColumns = $.map( columns, function (col,i) {
8424								return col.bVisible ? i : null;
8425							} );
8426							return [ visColumns[ visColumns.length + idx ] ];
8427						}
8428						// Counting from the left
8429						return [ _fnVisibleToColumnIndex( settings, idx ) ];
8430	
8431					case 'name':
8432						// match by name. `names` is column index complete and in order
8433						return $.map( names, function (name, i) {
8434							return name === match[1] ? i : null;
8435						} );
8436	
8437					default:
8438						return [];
8439				}
8440			}
8441	
8442			// Cell in the table body
8443			if ( s.nodeName && s._DT_CellIndex ) {
8444				return [ s._DT_CellIndex.column ];
8445			}
8446	
8447			// jQuery selector on the TH elements for the columns
8448			var jqResult = $( nodes )
8449				.filter( s )
8450				.map( function () {
8451					return $.inArray( this, nodes ); // `nodes` is column index complete and in order
8452				} )
8453				.toArray();
8454	
8455			if ( jqResult.length || ! s.nodeName ) {
8456				return jqResult;
8457			}
8458	
8459			// Otherwise a node which might have a `dt-column` data attribute, or be
8460			// a child or such an element
8461			var host = $(s).closest('*[data-dt-column]');
8462			return host.length ?
8463				[ host.data('dt-column') ] :
8464				[];
8465		};
8466	
8467		return _selector_run( 'column', selector, run, settings, opts );
8468	};
8469	
8470	
8471	var __setColumnVis = function ( settings, column, vis ) {
8472		var
8473			cols = settings.aoColumns,
8474			col  = cols[ column ],
8475			data = settings.aoData,
8476			row, cells, i, ien, tr;
8477	
8478		// Get
8479		if ( vis === undefined ) {
8480			return col.bVisible;
8481		}
8482	
8483		// Set
8484		// No change
8485		if ( col.bVisible === vis ) {
8486			return;
8487		}
8488	
8489		if ( vis ) {
8490			// Insert column
8491			// Need to decide if we should use appendChild or insertBefore
8492			var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
8493	
8494			for ( i=0, ien=data.length ; i<ien ; i++ ) {
8495				tr = data[i].nTr;
8496				cells = data[i].anCells;
8497	
8498				if ( tr ) {
8499					// insertBefore can act like appendChild if 2nd arg is null
8500					tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
8501				}
8502			}
8503		}
8504		else {
8505			// Remove column
8506			$( _pluck( settings.aoData, 'anCells', column ) ).detach();
8507		}
8508	
8509		// Common actions
8510		col.bVisible = vis;
8511		_fnDrawHead( settings, settings.aoHeader );
8512		_fnDrawHead( settings, settings.aoFooter );
8513	
8514		_fnSaveState( settings );
8515	};
8516	
8517	
8518	_api_register( 'columns()', function ( selector, opts ) {
8519		// argument shifting
8520		if ( selector === undefined ) {
8521			selector = '';
8522		}
8523		else if ( $.isPlainObject( selector ) ) {
8524			opts = selector;
8525			selector = '';
8526		}
8527	
8528		opts = _selector_opts( opts );
8529	
8530		var inst = this.iterator( 'table', function ( settings ) {
8531			return __column_selector( settings, selector, opts );
8532		}, 1 );
8533	
8534		// Want argument shifting here and in _row_selector?
8535		inst.selector.cols = selector;
8536		inst.selector.opts = opts;
8537	
8538		return inst;
8539	} );
8540	
8541	_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
8542		return this.iterator( 'column', function ( settings, column ) {
8543			return settings.aoColumns[column].nTh;
8544		}, 1 );
8545	} );
8546	
8547	_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
8548		return this.iterator( 'column', function ( settings, column ) {
8549			return settings.aoColumns[column].nTf;
8550		}, 1 );
8551	} );
8552	
8553	_api_registerPlural( 'columns().data()', 'column().data()', function () {
8554		return this.iterator( 'column-rows', __columnData, 1 );
8555	} );
8556	
8557	_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
8558		return this.iterator( 'column', function ( settings, column ) {
8559			return settings.aoColumns[column].mData;
8560		}, 1 );
8561	} );
8562	
8563	_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
8564		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8565			return _pluck_order( settings.aoData, rows,
8566				type === 'search' ? '_aFilterData' : '_aSortData', column
8567			);
8568		}, 1 );
8569	} );
8570	
8571	_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8572		return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8573			return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
8574		}, 1 );
8575	} );
8576	
8577	_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
8578		var ret = this.iterator( 'column', function ( settings, column ) {
8579			if ( vis === undefined ) {
8580				return settings.aoColumns[ column ].bVisible;
8581			} // else
8582			__setColumnVis( settings, column, vis );
8583		} );
8584	
8585		// Group the column visibility changes
8586		if ( vis !== undefined ) {
8587			// Second loop once the first is done for events
8588			this.iterator( 'column', function ( settings, column ) {
8589				_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
8590			} );
8591	
8592			if ( calc === undefined || calc ) {
8593				this.columns.adjust();
8594			}
8595		}
8596	
8597		return ret;
8598	} );
8599	
8600	_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
8601		return this.iterator( 'column', function ( settings, column ) {
8602			return type === 'visible' ?
8603				_fnColumnIndexToVisible( settings, column ) :
8604				column;
8605		}, 1 );
8606	} );
8607	
8608	_api_register( 'columns.adjust()', function () {
8609		return this.iterator( 'table', function ( settings ) {
8610			_fnAdjustColumnSizing( settings );
8611		}, 1 );
8612	} );
8613	
8614	_api_register( 'column.index()', function ( type, idx ) {
8615		if ( this.context.length !== 0 ) {
8616			var ctx = this.context[0];
8617	
8618			if ( type === 'fromVisible' || type === 'toData' ) {
8619				return _fnVisibleToColumnIndex( ctx, idx );
8620			}
8621			else if ( type === 'fromData' || type === 'toVisible' ) {
8622				return _fnColumnIndexToVisible( ctx, idx );
8623			}
8624		}
8625	} );
8626	
8627	_api_register( 'column()', function ( selector, opts ) {
8628		return _selector_first( this.columns( selector, opts ) );
8629	} );
8630	
8631	
8632	
8633	var __cell_selector = function ( settings, selector, opts )
8634	{
8635		var data = settings.aoData;
8636		var rows = _selector_row_indexes( settings, opts );
8637		var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
8638		var allCells = $( [].concat.apply([], cells) );
8639		var row;
8640		var columns = settings.aoColumns.length;
8641		var a, i, ien, j, o, host;
8642	
8643		var run = function ( s ) {
8644			var fnSelector = typeof s === 'function';
8645	
8646			if ( s === null || s === undefined || fnSelector ) {
8647				// All cells and function selectors
8648				a = [];
8649	
8650				for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8651					row = rows[i];
8652	
8653					for ( j=0 ; j<columns ; j++ ) {
8654						o = {
8655							row: row,
8656							column: j
8657						};
8658	
8659						if ( fnSelector ) {
8660							// Selector - function
8661							host = data[ row ];
8662	
8663							if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8664								a.push( o );
8665							}
8666						}
8667						else {
8668							// Selector - all
8669							a.push( o );
8670						}
8671					}
8672				}
8673	
8674				return a;
8675			}
8676			
8677			// Selector - index
8678			if ( $.isPlainObject( s ) ) {
8679				return [s];
8680			}
8681	
8682			// Selector - jQuery filtered cells
8683			var jqResult = allCells
8684				.filter( s )
8685				.map( function (i, el) {
8686					return { // use a new object, in case someone changes the values
8687						row:    el._DT_CellIndex.row,
8688						column: el._DT_CellIndex.column
8689	 				};
8690				} )
8691				.toArray();
8692	
8693			if ( jqResult.length || ! s.nodeName ) {
8694				return jqResult;
8695			}
8696	
8697			// Otherwise the selector is a node, and there is one last option - the
8698			// element might be a child of an element which has dt-row and dt-column
8699			// data attributes
8700			host = $(s).closest('*[data-dt-row]');
8701			return host.length ?
8702				[ {
8703					row: host.data('dt-row'),
8704					column: host.data('dt-column')
8705				} ] :
8706				[];
8707		};
8708	
8709		return _selector_run( 'cell', selector, run, settings, opts );
8710	};
8711	
8712	
8713	
8714	
8715	_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
8716		// Argument shifting
8717		if ( $.isPlainObject( rowSelector ) ) {
8718			// Indexes
8719			if ( rowSelector.row === undefined ) {
8720				// Selector options in first parameter
8721				opts = rowSelector;
8722				rowSelector = null;
8723			}
8724			else {
8725				// Cell index objects in first parameter
8726				opts = columnSelector;
8727				columnSelector = null;
8728			}
8729		}
8730		if ( $.isPlainObject( columnSelector ) ) {
8731			opts = columnSelector;
8732			columnSelector = null;
8733		}
8734	
8735		// Cell selector
8736		if ( columnSelector === null || columnSelector === undefined ) {
8737			return this.iterator( 'table', function ( settings ) {
8738				return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
8739			} );
8740		}
8741	
8742		// Row + column selector
8743		var columns = this.columns( columnSelector, opts );
8744		var rows = this.rows( rowSelector, opts );
8745		var a, i, ien, j, jen;
8746	
8747		var cells = this.iterator( 'table', function ( settings, idx ) {
8748			a = [];
8749	
8750			for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
8751				for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
8752					a.push( {
8753						row:    rows[idx][i],
8754						column: columns[idx][j]
8755					} );
8756				}
8757			}
8758	
8759			return a;
8760		}, 1 );
8761	
8762		$.extend( cells.selector, {
8763			cols: columnSelector,
8764			rows: rowSelector,
8765			opts: opts
8766		} );
8767	
8768		return cells;
8769	} );
8770	
8771	
8772	_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
8773		return this.iterator( 'cell', function ( settings, row, column ) {
8774			var data = settings.aoData[ row ];
8775	
8776			return data && data.anCells ?
8777				data.anCells[ column ] :
8778				undefined;
8779		}, 1 );
8780	} );
8781	
8782	
8783	_api_register( 'cells().data()', function () {
8784		return this.iterator( 'cell', function ( settings, row, column ) {
8785			return _fnGetCellData( settings, row, column );
8786		}, 1 );
8787	} );
8788	
8789	
8790	_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
8791		type = type === 'search' ? '_aFilterData' : '_aSortData';
8792	
8793		return this.iterator( 'cell', function ( settings, row, column ) {
8794			return settings.aoData[ row ][ type ][ column ];
8795		}, 1 );
8796	} );
8797	
8798	
8799	_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
8800		return this.iterator( 'cell', function ( settings, row, column ) {
8801			return _fnGetCellData( settings, row, column, type );
8802		}, 1 );
8803	} );
8804	
8805	
8806	_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
8807		return this.iterator( 'cell', function ( settings, row, column ) {
8808			return {
8809				row: row,
8810				column: column,
8811				columnVisible: _fnColumnIndexToVisible( settings, column )
8812			};
8813		}, 1 );
8814	} );
8815	
8816	
8817	_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
8818		return this.iterator( 'cell', function ( settings, row, column ) {
8819			_fnInvalidate( settings, row, src, column );
8820		} );
8821	} );
8822	
8823	
8824	
8825	_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
8826		return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
8827	} );
8828	
8829	
8830	_api_register( 'cell().data()', function ( data ) {
8831		var ctx = this.context;
8832		var cell = this[0];
8833	
8834		if ( data === undefined ) {
8835			// Get
8836			return ctx.length && cell.length ?
8837				_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
8838				undefined;
8839		}
8840	
8841		// Set
8842		_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
8843		_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
8844	
8845		return this;
8846	} );
8847	
8848	
8849	
8850	/**
8851	 * Get current ordering (sorting) that has been applied to the table.
8852	 *
8853	 * @returns {array} 2D array containing the sorting information for the first
8854	 *   table in the current context. Each element in the parent array represents
8855	 *   a column being sorted upon (i.e. multi-sorting with two columns would have
8856	 *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8857	 *   the column index that the sorting condition applies to, the second is the
8858	 *   direction of the sort (`desc` or `asc`) and, optionally, the third is the
8859	 *   index of the sorting order from the `column.sorting` initialisation array.
8860	 *//**
8861	 * Set the ordering for the table.
8862	 *
8863	 * @param {integer} order Column index to sort upon.
8864	 * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8865	 * @returns {DataTables.Api} this
8866	 *//**
8867	 * Set the ordering for the table.
8868	 *
8869	 * @param {array} order 1D array of sorting information to be applied.
8870	 * @param {array} [...] Optional additional sorting conditions
8871	 * @returns {DataTables.Api} this
8872	 *//**
8873	 * Set the ordering for the table.
8874	 *
8875	 * @param {array} order 2D array of sorting information to be applied.
8876	 * @returns {DataTables.Api} this
8877	 */
8878	_api_register( 'order()', function ( order, dir ) {
8879		var ctx = this.context;
8880	
8881		if ( order === undefined ) {
8882			// get
8883			return ctx.length !== 0 ?
8884				ctx[0].aaSorting :
8885				undefined;
8886		}
8887	
8888		// set
8889		if ( typeof order === 'number' ) {
8890			// Simple column / direction passed in
8891			order = [ [ order, dir ] ];
8892		}
8893		else if ( order.length && ! $.isArray( order[0] ) ) {
8894			// Arguments passed in (list of 1D arrays)
8895			order = Array.prototype.slice.call( arguments );
8896		}
8897		// otherwise a 2D array was passed in
8898	
8899		return this.iterator( 'table', function ( settings ) {
8900			settings.aaSorting = order.slice();
8901		} );
8902	} );
8903	
8904	
8905	/**
8906	 * Attach a sort listener to an element for a given column
8907	 *
8908	 * @param {node|jQuery|string} node Identifier for the element(s) to attach the
8909	 *   listener to. This can take the form of a single DOM node, a jQuery
8910	 *   collection of nodes or a jQuery selector which will identify the node(s).
8911	 * @param {integer} column the column that a click on this node will sort on
8912	 * @param {function} [callback] callback function when sort is run
8913	 * @returns {DataTables.Api} this
8914	 */
8915	_api_register( 'order.listener()', function ( node, column, callback ) {
8916		return this.iterator( 'table', function ( settings ) {
8917			_fnSortAttachListener( settings, node, column, callback );
8918		} );
8919	} );
8920	
8921	
8922	_api_register( 'order.fixed()', function ( set ) {
8923		if ( ! set ) {
8924			var ctx = this.context;
8925			var fixed = ctx.length ?
8926				ctx[0].aaSortingFixed :
8927				undefined;
8928	
8929			return $.isArray( fixed ) ?
8930				{ pre: fixed } :
8931				fixed;
8932		}
8933	
8934		return this.iterator( 'table', function ( settings ) {
8935			settings.aaSortingFixed = $.extend( true, {}, set );
8936		} );
8937	} );
8938	
8939	
8940	// Order by the selected column(s)
8941	_api_register( [
8942		'columns().order()',
8943		'column().order()'
8944	], function ( dir ) {
8945		var that = this;
8946	
8947		return this.iterator( 'table', function ( settings, i ) {
8948			var sort = [];
8949	
8950			$.each( that[i], function (j, col) {
8951				sort.push( [ col, dir ] );
8952			} );
8953	
8954			settings.aaSorting = sort;
8955		} );
8956	} );
8957	
8958	
8959	
8960	_api_register( 'search()', function ( input, regex, smart, caseInsen ) {
8961		var ctx = this.context;
8962	
8963		if ( input === undefined ) {
8964			// get
8965			return ctx.length !== 0 ?
8966				ctx[0].oPreviousSearch.sSearch :
8967				undefined;
8968		}
8969	
8970		// set
8971		return this.iterator( 'table', function ( settings ) {
8972			if ( ! settings.oFeatures.bFilter ) {
8973				return;
8974			}
8975	
8976			_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
8977				"sSearch": input+"",
8978				"bRegex":  regex === null ? false : regex,
8979				"bSmart":  smart === null ? true  : smart,
8980				"bCaseInsensitive": caseInsen === null ? true : caseInsen
8981			} ), 1 );
8982		} );
8983	} );
8984	
8985	
8986	_api_registerPlural(
8987		'columns().search()',
8988		'column().search()',
8989		function ( input, regex, smart, caseInsen ) {
8990			return this.iterator( 'column', function ( settings, column ) {
8991				var preSearch = settings.aoPreSearchCols;
8992	
8993				if ( input === undefined ) {
8994					// get
8995					return preSearch[ column ].sSearch;
8996				}
8997	
8998				// set
8999				if ( ! settings.oFeatures.bFilter ) {
9000					return;
9001				}
9002	
9003				$.extend( preSearch[ column ], {
9004					"sSearch": input+"",
9005					"bRegex":  regex === null ? false : regex,
9006					"bSmart":  smart === null ? true  : smart,
9007					"bCaseInsensitive": caseInsen === null ? true : caseInsen
9008				} );
9009	
9010				_fnFilterComplete( settings, settings.oPreviousSearch, 1 );
9011			} );
9012		}
9013	);
9014	
9015	/*
9016	 * State API methods
9017	 */
9018	
9019	_api_register( 'state()', function () {
9020		return this.context.length ?
9021			this.context[0].oSavedState :
9022			null;
9023	} );
9024	
9025	
9026	_api_register( 'state.clear()', function () {
9027		return this.iterator( 'table', function ( settings ) {
9028			// Save an empty object
9029			settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
9030		} );
9031	} );
9032	
9033	
9034	_api_register( 'state.loaded()', function () {
9035		return this.context.length ?
9036			this.context[0].oLoadedState :
9037			null;
9038	} );
9039	
9040	
9041	_api_register( 'state.save()', function () {
9042		return this.iterator( 'table', function ( settings ) {
9043			_fnSaveState( settings );
9044		} );
9045	} );
9046	
9047	
9048	
9049	/**
9050	 * Provide a common method for plug-ins to check the version of DataTables being
9051	 * used, in order to ensure compatibility.
9052	 *
9053	 *  @param {string} version Version string to check for, in the format "X.Y.Z".
9054	 *    Note that the formats "X" and "X.Y" are also acceptable.
9055	 *  @returns {boolean} true if this version of DataTables is greater or equal to
9056	 *    the required version, or false if this version of DataTales is not
9057	 *    suitable
9058	 *  @static
9059	 *  @dtopt API-Static
9060	 *
9061	 *  @example
9062	 *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
9063	 */
9064	DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
9065	{
9066		var aThis = DataTable.version.split('.');
9067		var aThat = version.split('.');
9068		var iThis, iThat;
9069	
9070		for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
9071			iThis = parseInt( aThis[i], 10 ) || 0;
9072			iThat = parseInt( aThat[i], 10 ) || 0;
9073	
9074			// Parts are the same, keep comparing
9075			if (iThis === iThat) {
9076				continue;
9077			}
9078	
9079			// Parts are different, return immediately
9080			return iThis > iThat;
9081		}
9082	
9083		return true;
9084	};
9085	
9086	
9087	/**
9088	 * Check if a `<table>` node is a DataTable table already or not.
9089	 *
9090	 *  @param {node|jquery|string} table Table node, jQuery object or jQuery
9091	 *      selector for the table to test. Note that if more than more than one
9092	 *      table is passed on, only the first will be checked
9093	 *  @returns {boolean} true the table given is a DataTable, or false otherwise
9094	 *  @static
9095	 *  @dtopt API-Static
9096	 *
9097	 *  @example
9098	 *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
9099	 *      $('#example').dataTable();
9100	 *    }
9101	 */
9102	DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
9103	{
9104		var t = $(table).get(0);
9105		var is = false;
9106	
9107		if ( table instanceof DataTable.Api ) {
9108			return true;
9109		}
9110	
9111		$.each( DataTable.settings, function (i, o) {
9112			var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
9113			var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
9114	
9115			if ( o.nTable === t || head === t || foot === t ) {
9116				is = true;
9117			}
9118		} );
9119	
9120		return is;
9121	};
9122	
9123	
9124	/**
9125	 * Get all DataTable tables that have been initialised - optionally you can
9126	 * select to get only currently visible tables.
9127	 *
9128	 *  @param {boolean} [visible=false] Flag to indicate if you want all (default)
9129	 *    or visible tables only.
9130	 *  @returns {array} Array of `table` nodes (not DataTable instances) which are
9131	 *    DataTables
9132	 *  @static
9133	 *  @dtopt API-Static
9134	 *
9135	 *  @example
9136	 *    $.each( $.fn.dataTable.tables(true), function () {
9137	 *      $(table).DataTable().columns.adjust();
9138	 *    } );
9139	 */
9140	DataTable.tables = DataTable.fnTables = function ( visible )
9141	{
9142		var api = false;
9143	
9144		if ( $.isPlainObject( visible ) ) {
9145			api = visible.api;
9146			visible = visible.visible;
9147		}
9148	
9149		var a = $.map( DataTable.settings, function (o) {
9150			if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
9151				return o.nTable;
9152			}
9153		} );
9154	
9155		return api ?
9156			new _Api( a ) :
9157			a;
9158	};
9159	
9160	
9161	/**
9162	 * Convert from camel case parameters to Hungarian notation. This is made public
9163	 * for the extensions to provide the same ability as DataTables core to accept
9164	 * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9165	 * parameters.
9166	 *
9167	 *  @param {object} src The model object which holds all parameters that can be
9168	 *    mapped.
9169	 *  @param {object} user The object to convert from camel case to Hungarian.
9170	 *  @param {boolean} force When set to `true`, properties which already have a
9171	 *    Hungarian value in the `user` object will be overwritten. Otherwise they
9172	 *    won't be.
9173	 */
9174	DataTable.camelToHungarian = _fnCamelToHungarian;
9175	
9176	
9177	
9178	/**
9179	 *
9180	 */
9181	_api_register( '$()', function ( selector, opts ) {
9182		var
9183			rows   = this.rows( opts ).nodes(), // Get all rows
9184			jqRows = $(rows);
9185	
9186		return $( [].concat(
9187			jqRows.filter( selector ).toArray(),
9188			jqRows.find( selector ).toArray()
9189		) );
9190	} );
9191	
9192	
9193	// jQuery functions to operate on the tables
9194	$.each( [ 'on', 'one', 'off' ], function (i, key) {
9195		_api_register( key+'()', function ( /* event, handler */ ) {
9196			var args = Array.prototype.slice.call(arguments);
9197	
9198			// Add the `dt` namespace automatically if it isn't already present
9199			args[0] = $.map( args[0].split( /\s/ ), function ( e ) {
9200				return ! e.match(/\.dt\b/) ?
9201					e+'.dt' :
9202					e;
9203				} ).join( ' ' );
9204	
9205			var inst = $( this.tables().nodes() );
9206			inst[key].apply( inst, args );
9207			return this;
9208		} );
9209	} );
9210	
9211	
9212	_api_register( 'clear()', function () {
9213		return this.iterator( 'table', function ( settings ) {
9214			_fnClearTable( settings );
9215		} );
9216	} );
9217	
9218	
9219	_api_register( 'settings()', function () {
9220		return new _Api( this.context, this.context );
9221	} );
9222	
9223	
9224	_api_register( 'init()', function () {
9225		var ctx = this.context;
9226		return ctx.length ? ctx[0].oInit : null;
9227	} );
9228	
9229	
9230	_api_register( 'data()', function () {
9231		return this.iterator( 'table', function ( settings ) {
9232			return _pluck( settings.aoData, '_aData' );
9233		} ).flatten();
9234	} );
9235	
9236	
9237	_api_register( 'destroy()', function ( remove ) {
9238		remove = remove || false;
9239	
9240		return this.iterator( 'table', function ( settings ) {
9241			var orig      = settings.nTableWrapper.parentNode;
9242			var classes   = settings.oClasses;
9243			var table     = settings.nTable;
9244			var tbody     = settings.nTBody;
9245			var thead     = settings.nTHead;
9246			var tfoot     = settings.nTFoot;
9247			var jqTable   = $(table);
9248			var jqTbody   = $(tbody);
9249			var jqWrapper = $(settings.nTableWrapper);
9250			var rows      = $.map( settings.aoData, function (r) { return r.nTr; } );
9251			var i, ien;
9252	
9253			// Flag to note that the table is currently being destroyed - no action
9254			// should be taken
9255			settings.bDestroying = true;
9256	
9257			// Fire off the destroy callbacks for plug-ins etc
9258			_fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
9259	
9260			// If not being removed from the document, make all columns visible
9261			if ( ! remove ) {
9262				new _Api( settings ).columns().visible( true );
9263			}
9264	
9265			// Blitz all `DT` namespaced events (these are internal events, the
9266			// lowercase, `dt` events are user subscribed and they are responsible
9267			// for removing them
9268			jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
9269			$(window).off('.DT-'+settings.sInstance);
9270	
9271			// When scrolling we had to break the table up - restore it
9272			if ( table != thead.parentNode ) {
9273				jqTable.children('thead').detach();
9274				jqTable.append( thead );
9275			}
9276	
9277			if ( tfoot && table != tfoot.parentNode ) {
9278				jqTable.children('tfoot').detach();
9279				jqTable.append( tfoot );
9280			}
9281	
9282			settings.aaSorting = [];
9283			settings.aaSortingFixed = [];
9284			_fnSortingClasses( settings );
9285	
9286			$( rows ).removeClass( settings.asStripeClasses.join(' ') );
9287	
9288			$('th, td', thead).removeClass( classes.sSortable+' '+
9289				classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
9290			);
9291	
9292			if ( settings.bJUI ) {
9293				$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
9294				$('th, td', thead).each( function () {
9295					var wrapper = $('div.'+classes.sSortJUIWrapper, this);
9296					$(this).append( wrapper.contents() );
9297					wrapper.detach();
9298				} );
9299			}
9300	
9301			// Add the TR elements back into the table in their original order
9302			jqTbody.children().detach();
9303			jqTbody.append( rows );
9304	
9305			// Remove the DataTables generated nodes, events and classes
9306			var removedMethod = remove ? 'remove' : 'detach';
9307			jqTable[ removedMethod ]();
9308			jqWrapper[ removedMethod ]();
9309	
9310			// If we need to reattach the table to the document
9311			if ( ! remove && orig ) {
9312				// insertBefore acts like appendChild if !arg[1]
9313				orig.insertBefore( table, settings.nTableReinsertBefore );
9314	
9315				// Restore the width of the original table - was read from the style property,
9316				// so we can restore directly to that
9317				jqTable
9318					.css( 'width', settings.sDestroyWidth )
9319					.removeClass( classes.sTable );
9320	
9321				// If the were originally stripe classes - then we add them back here.
9322				// Note this is not fool proof (for example if not all rows had stripe
9323				// classes - but it's a good effort without getting carried away
9324				ien = settings.asDestroyStripes.length;
9325	
9326				if ( ien ) {
9327					jqTbody.children().each( function (i) {
9328						$(this).addClass( settings.asDestroyStripes[i % ien] );
9329					} );
9330				}
9331			}
9332	
9333			/* Remove the settings object from the settings array */
9334			var idx = $.inArray( settings, DataTable.settings );
9335			if ( idx !== -1 ) {
9336				DataTable.settings.splice( idx, 1 );
9337			}
9338		} );
9339	} );
9340	
9341	
9342	// Add the `every()` method for rows, columns and cells in a compact form
9343	$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9344		_api_register( type+'s().every()', function ( fn ) {
9345			var opts = this.selector.opts;
9346			var api = this;
9347	
9348			return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9349				// Rows and columns:
9350				//  arg1 - index
9351				//  arg2 - table counter
9352				//  arg3 - loop counter
9353				//  arg4 - undefined
9354				// Cells:
9355				//  arg1 - row index
9356				//  arg2 - column index
9357				//  arg3 - table counter
9358				//  arg4 - loop counter
9359				fn.call(
9360					api[ type ](
9361						arg1,
9362						type==='cell' ? arg2 : opts,
9363						type==='cell' ? opts : undefined
9364					),
9365					arg1, arg2, arg3, arg4
9366				);
9367			} );
9368		} );
9369	} );
9370	
9371	
9372	// i18n method for extensions to be able to use the language object from the
9373	// DataTable
9374	_api_register( 'i18n()', function ( token, def, plural ) {
9375		var ctx = this.context[0];
9376		var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9377	
9378		if ( resolved === undefined ) {
9379			resolved = def;
9380		}
9381	
9382		if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9383			resolved = resolved[ plural ] !== undefined ?
9384				resolved[ plural ] :
9385				resolved._;
9386		}
9387	
9388		return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9389	} );
9390
9391	/**
9392	 * Version string for plug-ins to check compatibility. Allowed format is
9393	 * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9394	 * only for non-release builds. See http://semver.org/ for more information.
9395	 *  @member
9396	 *  @type string
9397	 *  @default Version number
9398	 */
9399	DataTable.version = "1.10.13";
9400
9401	/**
9402	 * Private data store, containing all of the settings objects that are
9403	 * created for the tables on a given page.
9404	 *
9405	 * Note that the `DataTable.settings` object is aliased to
9406	 * `jQuery.fn.dataTableExt` through which it may be accessed and
9407	 * manipulated, or `jQuery.fn.dataTable.settings`.
9408	 *  @member
9409	 *  @type array
9410	 *  @default []
9411	 *  @private
9412	 */
9413	DataTable.settings = [];
9414
9415	/**
9416	 * Object models container, for the various models that DataTables has
9417	 * available to it. These models define the objects that are used to hold
9418	 * the active state and configuration of the table.
9419	 *  @namespace
9420	 */
9421	DataTable.models = {};
9422	
9423	
9424	
9425	/**
9426	 * Template object for the way in which DataTables holds information about
9427	 * search information for the global filter and individual column filters.
9428	 *  @namespace
9429	 */
9430	DataTable.models.oSearch = {
9431		/**
9432		 * Flag to indicate if the filtering should be case insensitive or not
9433		 *  @type boolean
9434		 *  @default true
9435		 */
9436		"bCaseInsensitive": true,
9437	
9438		/**
9439		 * Applied search term
9440		 *  @type string
9441		 *  @default <i>Empty string</i>
9442		 */
9443		"sSearch": "",
9444	
9445		/**
9446		 * Flag to indicate if the search term should be interpreted as a
9447		 * regular expression (true) or not (false) and therefore and special
9448		 * regex characters escaped.
9449		 *  @type boolean
9450		 *  @default false
9451		 */
9452		"bRegex": false,
9453	
9454		/**
9455		 * Flag to indicate if DataTables is to use its smart filtering or not.
9456		 *  @type boolean
9457		 *  @default true
9458		 */
9459		"bSmart": true
9460	};
9461	
9462	
9463	
9464	
9465	/**
9466	 * Template object for the way in which DataTables holds information about
9467	 * each individual row. This is the object format used for the settings
9468	 * aoData array.
9469	 *  @namespace
9470	 */
9471	DataTable.models.oRow = {
9472		/**
9473		 * TR element for the row
9474		 *  @type node
9475		 *  @default null
9476		 */
9477		"nTr": null,
9478	
9479		/**
9480		 * Array of TD elements for each row. This is null until the row has been
9481		 * created.
9482		 *  @type array nodes
9483		 *  @default []
9484		 */
9485		"anCells": null,
9486	
9487		/**
9488		 * Data object from the original data source for the row. This is either
9489		 * an array if using the traditional form of DataTables, or an object if
9490		 * using mData options. The exact type will depend on the passed in
9491		 * data from the data source, or will be an array if using DOM a data
9492		 * source.
9493		 *  @type array|object
9494		 *  @default []
9495		 */
9496		"_aData": [],
9497	
9498		/**
9499		 * Sorting data cache - this array is ostensibly the same length as the
9500		 * number of columns (although each index is generated only as it is
9501		 * needed), and holds the data that is used for sorting each column in the
9502		 * row. We do this cache generation at the start of the sort in order that
9503		 * the formatting of the sort data need be done only once for each cell
9504		 * per sort. This array should not be read from or written to by anything
9505		 * other than the master sorting methods.
9506		 *  @type array
9507		 *  @default null
9508		 *  @private
9509		 */
9510		"_aSortData": null,
9511	
9512		/**
9513		 * Per cell filtering data cache. As per the sort data cache, used to
9514		 * increase the performance of the filtering in DataTables
9515		 *  @type array
9516		 *  @default null
9517		 *  @private
9518		 */
9519		"_aFilterData": null,
9520	
9521		/**
9522		 * Filtering data cache. This is the same as the cell filtering cache, but
9523		 * in this case a string rather than an array. This is easily computed with
9524		 * a join on `_aFilterData`, but is provided as a cache so the join isn't
9525		 * needed on every search (memory traded for performance)
9526		 *  @type array
9527		 *  @default null
9528		 *  @private
9529		 */
9530		"_sFilterRow": null,
9531	
9532		/**
9533		 * Cache of the class name that DataTables has applied to the row, so we
9534		 * can quickly look at this variable rather than needing to do a DOM check
9535		 * on className for the nTr property.
9536		 *  @type string
9537		 *  @default <i>Empty string</i>
9538		 *  @private
9539		 */
9540		"_sRowStripe": "",
9541	
9542		/**
9543		 * Denote if the original data source was from the DOM, or the data source
9544		 * object. This is used for invalidating data, so DataTables can
9545		 * automatically read data from the original source, unless uninstructed
9546		 * otherwise.
9547		 *  @type string
9548		 *  @default null
9549		 *  @private
9550		 */
9551		"src": null,
9552	
9553		/**
9554		 * Index in the aoData array. This saves an indexOf lookup when we have the
9555		 * object, but want to know the index
9556		 *  @type integer
9557		 *  @default -1
9558		 *  @private
9559		 */
9560		"idx": -1
9561	};
9562	
9563	
9564	/**
9565	 * Template object for the column information object in DataTables. This object
9566	 * is held in the settings aoColumns array and contains all the information that
9567	 * DataTables needs about each individual column.
9568	 *
9569	 * Note that this object is related to {@link DataTable.defaults.column}
9570	 * but this one is the internal data store for DataTables's cache of columns.
9571	 * It should NOT be manipulated outside of DataTables. Any configuration should
9572	 * be done through the initialisation options.
9573	 *  @namespace
9574	 */
9575	DataTable.models.oColumn = {
9576		/**
9577		 * Column index. This could be worked out on-the-fly with $.inArray, but it
9578		 * is faster to just hold it as a variable
9579		 *  @type integer
9580		 *  @default null
9581		 */
9582		"idx": null,
9583	
9584		/**
9585		 * A list of the columns that sorting should occur on when this column
9586		 * is sorted. That this property is an array allows multi-column s
9586orting
9587		 * to be defined for a column (for example first name / last name columns
9588		 * would benefit from this). The values are integers pointing to the
9589		 * columns to be sorted on (typically it will be a single integer pointing
9590		 * at itself, but that doesn't need to be the case).
9591		 *  @type array
9592		 */
9593		"aDataSort": null,
9594	
9595		/**
9596		 * Define the sorting directions that are applied to the column, in sequence
9597		 * as the column is repeatedly sorted upon - i.e. the first value is used
9598		 * as the sorting direction when the column if first sorted (clicked on).
9599		 * Sort it again (click again) and it will move on to the next index.
9600		 * Repeat until loop.
9601		 *  @type array
9602		 */
9603		"asSorting": null,
9604	
9605		/**
9606		 * Flag to indicate if the column is searchable, and thus should be included
9607		 * in the filtering or not.
9608		 *  @type boolean
9609		 */
9610		"bSearchable": null,
9611	
9612		/**
9613		 * Flag to indicate if the column is sortable or not.
9614		 *  @type boolean
9615		 */
9616		"bSortable": null,
9617	
9618		/**
9619		 * Flag to indicate if the column is currently visible in the table or not
9620		 *  @type boolean
9621		 */
9622		"bVisible": null,
9623	
9624		/**
9625		 * Store for manual type assignment using the `column.type` option. This
9626		 * is held in store so we can manipulate the column's `sType` property.
9627		 *  @type string
9628		 *  @default null
9629		 *  @private
9630		 */
9631		"_sManualType": null,
9632	
9633		/**
9634		 * Flag to indicate if HTML5 data attributes should be used as the data
9635		 * source for filtering or sorting. True is either are.
9636		 *  @type boolean
9637		 *  @default false
9638		 *  @private
9639		 */
9640		"_bAttrSrc": false,
9641	
9642		/**
9643		 * Developer definable function that is called whenever a cell is created (Ajax source,
9644		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9645		 * allowing you to modify the DOM element (add background colour for example) when the
9646		 * element is available.
9647		 *  @type function
9648		 *  @param {element} nTd The TD node that has been created
9649		 *  @param {*} sData The Data for the cell
9650		 *  @param {array|object} oData The data for the whole row
9651		 *  @param {int} iRow The row index for the aoData data store
9652		 *  @default null
9653		 */
9654		"fnCreatedCell": null,
9655	
9656		/**
9657		 * Function to get data from a cell in a column. You should <b>never</b>
9658		 * access data directly through _aData internally in DataTables - always use
9659		 * the method attached to this property. It allows mData to function as
9660		 * required. This function is automatically assigned by the column
9661		 * initialisation method
9662		 *  @type function
9663		 *  @param {array|object} oData The data array/object for the array
9664		 *    (i.e. aoData[]._aData)
9665		 *  @param {string} sSpecific The specific data type you want to get -
9666		 *    'display', 'type' 'filter' 'sort'
9667		 *  @returns {*} The data for the cell from the given row's data
9668		 *  @default null
9669		 */
9670		"fnGetData": null,
9671	
9672		/**
9673		 * Function to set data for a cell in the column. You should <b>never</b>
9674		 * set the data directly to _aData internally in DataTables - always use
9675		 * this method. It allows mData to function as required. This function
9676		 * is automatically assigned by the column initialisation method
9677		 *  @type function
9678		 *  @param {array|object} oData The data array/object for the array
9679		 *    (i.e. aoData[]._aData)
9680		 *  @param {*} sValue Value to set
9681		 *  @default null
9682		 */
9683		"fnSetData": null,
9684	
9685		/**
9686		 * Property to read the value for the cells in the column from the data
9687		 * source array / object. If null, then the default content is used, if a
9688		 * function is given then the return from the function is used.
9689		 *  @type function|int|string|null
9690		 *  @default null
9691		 */
9692		"mData": null,
9693	
9694		/**
9695		 * Partner property to mData which is used (only when defined) to get
9696		 * the data - i.e. it is basically the same as mData, but without the
9697		 * 'set' option, and also the data fed to it is the result from mData.
9698		 * This is the rendering method to match the data method of mData.
9699		 *  @type function|int|string|null
9700		 *  @default null
9701		 */
9702		"mRender": null,
9703	
9704		/**
9705		 * Unique header TH/TD element for this column - this is what the sorting
9706		 * listener is attached to (if sorting is enabled.)
9707		 *  @type node
9708		 *  @default null
9709		 */
9710		"nTh": null,
9711	
9712		/**
9713		 * Unique footer TH/TD element for this column (if there is one). Not used
9714		 * in DataTables as such, but can be used for plug-ins to reference the
9715		 * footer for each column.
9716		 *  @type node
9717		 *  @default null
9718		 */
9719		"nTf": null,
9720	
9721		/**
9722		 * The class to apply to all TD elements in the table's TBODY for the column
9723		 *  @type string
9724		 *  @default null
9725		 */
9726		"sClass": null,
9727	
9728		/**
9729		 * When DataTables calculates the column widths to assign to each column,
9730		 * it finds the longest string in each column and then constructs a
9731		 * temporary table and reads the widths from that. The problem with this
9732		 * is that "mmm" is much wider then "iiii", but the latter is a longer
9733		 * string - thus the calculation can go wrong (doing it properly and putting
9734		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
9735		 * a "work around" we provide this option. It will append its value to the
9736		 * text that is found to be the longest string for the column - i.e. padding.
9737		 *  @type string
9738		 */
9739		"sContentPadding": null,
9740	
9741		/**
9742		 * Allows a default value to be given for a column's data, and will be used
9743		 * whenever a null data source is encountered (this can be because mData
9744		 * is set to null, or because the data source itself is null).
9745		 *  @type string
9746		 *  @default null
9747		 */
9748		"sDefaultContent": null,
9749	
9750		/**
9751		 * Name for the column, allowing reference to the column by name as well as
9752		 * by index (needs a lookup to work by name).
9753		 *  @type string
9754		 */
9755		"sName": null,
9756	
9757		/**
9758		 * Custom sorting data type - defines which of the available plug-ins in
9759		 * afnSortData the custom sorting will use - if any is defined.
9760		 *  @type string
9761		 *  @default std
9762		 */
9763		"sSortDataType": 'std',
9764	
9765		/**
9766		 * Class to be applied to the header element when sorting on this column
9767		 *  @type string
9768		 *  @default null
9769		 */
9770		"sSortingClass": null,
9771	
9772		/**
9773		 * Class to be applied to the header element when sorting on this column -
9774		 * when jQuery UI theming is used.
9775		 *  @type string
9776		 *  @default null
9777		 */
9778		"sSortingClassJUI": null,
9779	
9780		/**
9781		 * Title of the column - what is seen in the TH element (nTh).
9782		 *  @type string
9783		 */
9784		"sTitle": null,
9785	
9786		/**
9787		 * Column sorting and filtering type
9788		 *  @type string
9789		 *  @default null
9790		 */
9791		"sType": null,
9792	
9793		/**
9794		 * Width of the column
9795		 *  @type string
9796		 *  @default null
9797		 */
9798		"sWidth": null,
9799	
9800		/**
9801		 * Width of the column when it was first "encountered"
9802		 *  @type string
9803		 *  @default null
9804		 */
9805		"sWidthOrig": null
9806	};
9807	
9808	
9809	/*
9810	 * Developer note: The properties of the object below are given in Hungarian
9811	 * notation, that was used as the interface for DataTables prior to v1.10, however
9812	 * from v1.10 onwards the primary interface is camel case. In order to avoid
9813	 * breaking backwards compatibility utterly with this change, the Hungarian
9814	 * version is still, internally the primary interface, but is is not documented
9815	 * - hence the @name tags in each doc comment. This allows a Javascript function
9816	 * to create a map from Hungarian notation to camel case (going the other direction
9817	 * would require each property to be listed, which would at around 3K to the size
9818	 * of DataTables, while this method is about a 0.5K hit
vendor: 16,919 bytes, lines 9818-10329
9818.
9819	 *
9820	 * Ultimately this does pave the way for Hungarian notation to be dropped
9821	 * completely, but that is a massive amount of work and will break current
9822	 * installs (therefore is on-hold until v2).
9823	 */
9824	
9825	/**
9826	 * Initialisation options that can be given to DataTables at initialisation
9827	 * time.
9828	 *  @namespace
9829	 */
9830	DataTable.defaults = {
9831		/**
9832		 * An array of data to use for the table, passed in at initialisation which
9833		 * will be used in preference to any data which is already in the DOM. This is
9834		 * particularly useful for constructing tables purely in Javascript, for
9835		 * example with a custom Ajax call.
9836		 *  @type array
9837		 *  @default null
9838		 *
9839		 *  @dtopt Option
9840		 *  @name DataTable.defaults.data
9841		 *
9842		 *  @example
9843		 *    // Using a 2D array data source
9844		 *    $(document).ready( function () {
9845		 *      $('#example').dataTable( {
9846		 *        "data": [
9847		 *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9848		 *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9849		 *        ],
9850		 *        "columns": [
9851		 *          { "title": "Engine" },
9852		 *          { "title": "Browser" },
9853		 *          { "title": "Platform" },
9854		 *          { "title": "Version" },
9855		 *          { "title": "Grade" }
9856		 *        ]
9857		 *      } );
9858		 *    } );
9859		 *
9860		 *  @example
9861		 *    // Using an array of objects as a data source (`data`)
9862		 *    $(document).ready( function () {
9863		 *      $('#example').dataTable( {
9864		 *        "data": [
9865		 *          {
9866		 *            "engine":   "Trident",
9867		 *            "browser":  "Internet Explorer 4.0",
9868		 *            "platform": "Win 95+",
9869		 *            "version":  4,
9870		 *            "grade":    "X"
9871		 *          },
9872		 *          {
9873		 *            "engine":   "Trident",
9874		 *            "browser":  "Internet Explorer 5.0",
9875		 *            "platform": "Win 95+",
9876		 *            "version":  5,
9877		 *            "grade":    "C"
9878		 *          }
9879		 *        ],
9880		 *        "columns": [
9881		 *          { "title": "Engine",   "data": "engine" },
9882		 *          { "title": "Browser",  "data": "browser" },
9883		 *          { "title": "Platform", "data": "platform" },
9884		 *          { "title": "Version",  "data": "version" },
9885		 *          { "title": "Grade",    "data": "grade" }
9886		 *        ]
9887		 *      } );
9888		 *    } );
9889		 */
9890		"aaData": null,
9891	
9892	
9893		/**
9894		 * If ordering is enabled, then DataTables will perform a first pass sort on
9895		 * initialisation. You can define which column(s) the sort is performed
9896		 * upon, and the sorting direction, with this variable. The `sorting` array
9897		 * should contain an array for each column to be sorted initially containing
9898		 * the column's index and a direction string ('asc' or 'desc').
9899		 *  @type array
9900		 *  @default [[0,'asc']]
9901		 *
9902		 *  @dtopt Option
9903		 *  @name DataTable.defaults.order
9904		 *
9905		 *  @example
9906		 *    // Sort by 3rd column first, and then 4th column
9907		 *    $(document).ready( function() {
9908		 *      $('#example').dataTable( {
9909		 *        "order": [[2,'asc'], [3,'desc']]
9910		 *      } );
9911		 *    } );
9912		 *
9913		 *    // No initial sorting
9914		 *    $(document).ready( function() {
9915		 *      $('#example').dataTable( {
9916		 *        "order": []
9917		 *      } );
9918		 *    } );
9919		 */
9920		"aaSorting": [[0,'asc']],
9921	
9922	
9923		/**
9924		 * This parameter is basically identical to the `sorting` parameter, but
9925		 * cannot be overridden by user interaction with the table. What this means
9926		 * is that you could have a column (visible or hidden) which the sorting
9927		 * will always be forced on first - any sorting after that (from the user)
9928		 * will then be performed as required. This can be useful for grouping rows
9929		 * together.
9930		 *  @type array
9931		 *  @default null
9932		 *
9933		 *  @dtopt Option
9934		 *  @name DataTable.defaults.orderFixed
9935		 *
9936		 *  @example
9937		 *    $(document).ready( function() {
9938		 *      $('#example').dataTable( {
9939		 *        "orderFixed": [[0,'asc']]
9940		 *      } );
9941		 *    } )
9942		 */
9943		"aaSortingFixed": [],
9944	
9945	
9946		/**
9947		 * DataTables can be instructed to load data to display in the table from a
9948		 * Ajax source. This option defines how that Ajax call is made and where to.
9949		 *
9950		 * The `ajax` property has three different modes of operation, depending on
9951		 * how it is defined. These are:
9952		 *
9953		 * * `string` - Set the URL from where the data should be loaded from.
9954		 * * `object` - Define properties for `jQuery.ajax`.
9955		 * * `function` - Custom data get function
9956		 *
9957		 * `string`
9958		 * --------
9959		 *
9960		 * As a string, the `ajax` property simply defines the URL from which
9961		 * DataTables will load data.
9962		 *
9963		 * `object`
9964		 * --------
9965		 *
9966		 * As an object, the parameters in the object are passed to
9967		 * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
9968		 * of the Ajax request. DataTables has a number of default parameters which
9969		 * you can override using this option. Please refer to the jQuery
9970		 * documentation for a full description of the options available, although
9971		 * the following parameters provide additional options in DataTables or
9972		 * require special consideration:
9973		 *
9974		 * * `data` - As with jQuery, `data` can be provided as an object, but it
9975		 *   can also be used as a function to manipulate the data DataTables sends
9976		 *   to the server. The function takes a single parameter, an object of
9977		 *   parameters with the values that DataTables has readied for sending. An
9978		 *   object may be returned which will be merged into the DataTables
9979		 *   defaults, or you can add the items to the object that was passed in and
9980		 *   not return anything from the function. This supersedes `fnServerParams`
9981		 *   from DataTables 1.9-.
9982		 *
9983		 * * `dataSrc` - By default DataTables will look for the property `data` (or
9984		 *   `aaData` for compatibility with DataTables 1.9-) when obtaining data
9985		 *   from an Ajax source or for server-side processing - this parameter
9986		 *   allows that property to be changed. You can use Javascript dotted
9987		 *   object notation to get a data source for multiple levels of nesting, or
9988		 *   it my be used as a function. As a function it takes a single parameter,
9989		 *   the JSON returned from the server, which can be manipulated as
9990		 *   required, with the returned value being that used by DataTables as the
9991		 *   data source for the table. This supersedes `sAjaxDataProp` from
9992		 *   DataTables 1.9-.
9993		 *
9994		 * * `success` - Should not be overridden it is used internally in
9995		 *   DataTables. To manipulate / transform the data returned by the server
9996		 *   use `ajax.dataSrc`, or use `ajax` as a function (see below).
9997		 *
9998		 * `function`
9999		 * ----------
10000		 *
10001		 * As a function, making the Ajax call is left up to yourself allowing
10002		 * complete control of the Ajax request. Indeed, if desired, a method other
10003		 * than Ajax could be used to obtain the required data, such as Web storage
10004		 * or an AIR database.
10005		 *
10006		 * The function is given four parameters and no return is required. The
10007		 * parameters are:
10008		 *
10009		 * 1. _object_ - Data to send to the server
10010		 * 2. _function_ - Callback function that must be executed when the required
10011		 *    data has been obtained. That data should be passed into the callback
10012		 *    as the only parameter
10013		 * 3. _object_ - DataTables settings object for the table
10014		 *
10015		 * Note that this supersedes `fnServerData` from DataTables 1.9-.
10016		 *
10017		 *  @type string|object|function
10018		 *  @default null
10019		 *
10020		 *  @dtopt Option
10021		 *  @name DataTable.defaults.ajax
10022		 *  @since 1.10.0
10023		 *
10024		 * @example
10025		 *   // Get JSON data from a file via Ajax.
10026		 *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
10027		 *   $('#example').dataTable( {
10028		 *     "ajax": "data.json"
10029		 *   } );
10030		 *
10031		 * @example
10032		 *   // Get JSON data from a file via Ajax, using `dataSrc` to change
10033		 *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
10034		 *   $('#example').dataTable( {
10035		 *     "ajax": {
10036		 *       "url": "data.json",
10037		 *       "dataSrc": "tableData"
10038		 *     }
10039		 *   } );
10040		 *
10041		 * @example
10042		 *   // Get JSON data from a file via Ajax, using `dataSrc` to read data
10043		 *   // from a plain array rather than an array in an object
10044		 *   $('#example').dataTable( {
10045		 *     "ajax": {
10046		 *       "url": "data.json",
10047		 *       "dataSrc": ""
10048		 *     }
10049		 *   } );
10050		 *
10051		 * @example
10052		 *   // Manipulate the data returned from the server - add a link to data
10053		 *   // (note this can, should, be done using `render` for the column - this
10054		 *   // is just a simple example of how the data can be manipulated).
10055		 *   $('#example').dataTable( {
10056		 *     "ajax": {
10057		 *       "url": "data.json",
10058		 *       "dataSrc": function ( json ) {
10059		 *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {
10060		 *           json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
10061		 *         }
10062		 *         return json;
10063		 *       }
10064		 *     }
10065		 *   } );
10066		 *
10067		 * @example
10068		 *   // Add data to the request
10069		 *   $('#example').dataTable( {
10070		 *     "ajax": {
10071		 *       "url": "data.json",
10072		 *       "data": function ( d ) {
10073		 *         return {
10074		 *           "extra_search": $('#extra').val()
10075		 *         };
10076		 *       }
10077		 *     }
10078		 *   } );
10079		 *
10080		 * @example
10081		 *   // Send request as POST
10082		 *   $('#example').dataTable( {
10083		 *     "ajax": {
10084		 *       "url": "data.json",
10085		 *       "type": "POST"
10086		 *     }
10087		 *   } );
10088		 *
10089		 * @example
10090		 *   // Get the data from localStorage (could interface with a form for
10091		 *   // adding, editing and removing rows).
10092		 *   $('#example').dataTable( {
10093		 *     "ajax": function (data, callback, settings) {
10094		 *       callback(
10095		 *         JSON.parse( localStorage.getItem('dataTablesData') )
10096		 *       );
10097		 *     }
10098		 *   } );
10099		 */
10100		"ajax": null,
10101	
10102	
10103		/**
10104		 * This parameter allows you to readily specify the entries in the length drop
10105		 * down menu that DataTables shows when pagination is enabled. It can be
10106		 * either a 1D array of options which will be used for both the displayed
10107		 * option and the value, or a 2D array which will use the array in the first
10108		 * position as the value, and the array in the second position as the
10109		 * displayed options (useful for language strings such as 'All').
10110		 *
10111		 * Note that the `pageLength` property will be automatically set to the
10112		 * first value given in this array, unless `pageLength` is also provided.
10113		 *  @type array
10114		 *  @default [ 10, 25, 50, 100 ]
10115		 *
10116		 *  @dtopt Option
10117		 *  @name DataTable.defaults.lengthMenu
10118		 *
10119		 *  @example
10120		 *    $(document).ready( function() {
10121		 *      $('#example').dataTable( {
10122		 *        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
10123		 *      } );
10124		 *    } );
10125		 */
10126		"aLengthMenu": [ 10, 25, 50, 100 ],
10127	
10128	
10129		/**
10130		 * The `columns` option in the initialisation parameter allows you to define
10131		 * details about the way individual columns behave. For a full list of
10132		 * column options that can be set, please see
10133		 * {@link DataTable.defaults.column}. Note that if you use `columns` to
10134		 * define your columns, you must have an entry in the array for every single
10135		 * column that you have in your table (these can be null if you don't which
10136		 * to specify any options).
10137		 *  @member
10138		 *
10139		 *  @name DataTable.defaults.column
10140		 */
10141		"aoColumns": null,
10142	
10143		/**
10144		 * Very similar to `columns`, `columnDefs` allows you to target a specific
10145		 * column, multiple columns, or all columns, using the `targets` property of
10146		 * each object in the array. This allows great flexibility when creating
10147		 * tables, as the `columnDefs` arrays can be of any length, targeting the
10148		 * columns you specifically want. `columnDefs` may use any of the column
10149		 * options available: {@link DataTable.defaults.column}, but it _must_
10150		 * have `targets` defined in each object in the array. Values in the `targets`
10151		 * array may be:
10152		 *   <ul>
10153		 *     <li>a string - class name will be matched on the TH for the column</li>
10154		 *     <li>0 or a positive integer - column index counting from the left</li>
10155		 *     <li>a negative integer - column index counting from the right</li>
10156		 *     <li>the string "_all" - all columns (i.e. assign a default)</li>
10157		 *   </ul>
10158		 *  @member
10159		 *
10160		 *  @name DataTable.defaults.columnDefs
10161		 */
10162		"aoColumnDefs": null,
10163	
10164	
10165		/**
10166		 * Basically the same as `search`, this parameter defines the individual column
10167		 * filtering state at initialisation time. The array must be of the same size
10168		 * as the number of columns, and each element be an object with the parameters
10169		 * `search` and `escapeRegex` (the latter is optional). 'null' is also
10170		 * accepted and the default will be used.
10171		 *  @type array
10172		 *  @default []
10173		 *
10174		 *  @dtopt Option
10175		 *  @name DataTable.defaults.searchCols
10176		 *
10177		 *  @example
10178		 *    $(document).ready( function() {
10179		 *      $('#example').dataTable( {
10180		 *        "searchCols": [
10181		 *          null,
10182		 *          { "search": "My filter" },
10183		 *          null,
10184		 *          { "search": "^[0-9]", "escapeRegex": false }
10185		 *        ]
10186		 *      } );
10187		 *    } )
10188		 */
10189		"aoSearchCols": [],
10190	
10191	
10192		/**
10193		 * An array of CSS classes that should be applied to displayed rows. This
10194		 * array may be of any length, and DataTables will apply each class
10195		 * sequentially, looping when required.
10196		 *  @type array
10197		 *  @default null <i>Will take the values determined by the `oClasses.stripe*`
10198		 *    options</i>
10199		 *
10200		 *  @dtopt Option
10201		 *  @name DataTable.defaults.stripeClasses
10202		 *
10203		 *  @example
10204		 *    $(document).ready( function() {
10205		 *      $('#example').dataTable( {
10206		 *        "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10207		 *      } );
10208		 *    } )
10209		 */
10210		"asStripeClasses": null,
10211	
10212	
10213		/**
10214		 * Enable or disable automatic column width calculation. This can be disabled
10215		 * as an optimisation (it takes some time to calculate the widths) if the
10216		 * tables widths are passed in using `columns`.
10217		 *  @type boolean
10218		 *  @default true
10219		 *
10220		 *  @dtopt Features
10221		 *  @name DataTable.defaults.autoWidth
10222		 *
10223		 *  @example
10224		 *    $(document).ready( function () {
10225		 *      $('#example').dataTable( {
10226		 *        "autoWidth": false
10227		 *      } );
10228		 *    } );
10229		 */
10230		"bAutoWidth": true,
10231	
10232	
10233		/**
10234		 * Deferred rendering can provide DataTables with a huge speed boost when you
10235		 * are using an Ajax or JS data source for the table. This option, when set to
10236		 * true, will cause DataTables to defer the creation of the table elements for
10237		 * each row until they are needed for a draw - saving a significant amount of
10238		 * time.
10239		 *  @type boolean
10240		 *  @default false
10241		 *
10242		 *  @dtopt Features
10243		 *  @name DataTable.defaults.deferRender
10244		 *
10245		 *  @example
10246		 *    $(document).ready( function() {
10247		 *      $('#example').dataTable( {
10248		 *        "ajax": "sources/arrays.txt",
10249		 *        "deferRender": true
10250		 *      } );
10251		 *    } );
10252		 */
10253		"bDeferRender": false,
10254	
10255	
10256		/**
10257		 * Replace a DataTable which matches the given selector and replace it with
10258		 * one which has the properties of the new initialisation object passed. If no
10259		 * table matches the selector, then the new DataTable will be constructed as
10260		 * per normal.
10261		 *  @type boolean
10262		 *  @default false
10263		 *
10264		 *  @dtopt Options
10265		 *  @name DataTable.defaults.destroy
10266		 *
10267		 *  @example
10268		 *    $(document).ready( function() {
10269		 *      $('#example').dataTable( {
10270		 *        "srollY": "200px",
10271		 *        "paginate": false
10272		 *      } );
10273		 *
10274		 *      // Some time later....
10275		 *      $('#example').dataTable( {
10276		 *        "filter": false,
10277		 *        "destroy": true
10278		 *      } );
10279		 *    } );
10280		 */
10281		"bDestroy": false,
10282	
10283	
10284		/**
10285		 * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10286		 * that it allows the end user to input multiple words (space separated) and
10287		 * will match a row containing those words, even if not in the order that was
10288		 * specified (this allow matching across multiple columns). Note that if you
10289		 * wish to use filtering in DataTables this must remain 'true' - to remove the
10290		 * default filtering input box and retain filtering abilities, please use
10291		 * {@link DataTable.defaults.dom}.
10292		 *  @type boolean
10293		 *  @default true
10294		 *
10295		 *  @dtopt Features
10296		 *  @name DataTable.defaults.searching
10297		 *
10298		 *  @example
10299		 *    $(document).ready( function () {
10300		 *      $('#example').dataTable( {
10301		 *        "searching": false
10302		 *      } );
10303		 *    } );
10304		 */
10305		"bFilter": true,
10306	
10307	
10308		/**
10309		 * Enable or disable the table information display. This shows information
10310		 * about the data that is currently visible on the page, including information
10311		 * about filtered data if that action is being performed.
10312		 *  @type boolean
10313		 *  @default true
10314		 *
10315		 *  @dtopt Features
10316		 *  @name DataTable.defaults.info
10317		 *
10318		 *  @example
10319		 *    $(document).ready( function () {
10320		 *      $('#example').dataTable( {
10321		 *        "info": false
10322		 *      } );
10323		 *    } );
10324		 */
10325		"bInfo": true,
10326	
10327	
10328		/**
10329		 * 
10329Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
10330		 * slightly different and additional mark-up from what DataTables has
10331		 * traditionally used).
10332		 *  @type boolean
10333		 *  @default false
10334		 *
10335		 *  @dtopt Features
10336		 *  @name DataTable.defaults.jQueryUI
10337		 *
10338		 *  @example
10339		 *    $(document).ready( function() {
10340		 *      $('#example').dataTable( {
10341		 *        "jQueryUI": true
10342		 *      } );
10343		 *    } );
10344		 */
10345		"bJQueryUI": fals
vendor: 40,186 bytes, lines 10345-11614
10345e,
10346	
10347	
10348		/**
10349		 * Allows the end user to select the size of a formatted page from a select
10350		 * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10351		 *  @type boolean
10352		 *  @default true
10353		 *
10354		 *  @dtopt Features
10355		 *  @name DataTable.defaults.lengthChange
10356		 *
10357		 *  @example
10358		 *    $(document).ready( function () {
10359		 *      $('#example').dataTable( {
10360		 *        "lengthChange": false
10361		 *      } );
10362		 *    } );
10363		 */
10364		"bLengthChange": true,
10365	
10366	
10367		/**
10368		 * Enable or disable pagination.
10369		 *  @type boolean
10370		 *  @default true
10371		 *
10372		 *  @dtopt Features
10373		 *  @name DataTable.defaults.paging
10374		 *
10375		 *  @example
10376		 *    $(document).ready( function () {
10377		 *      $('#example').dataTable( {
10378		 *        "paging": false
10379		 *      } );
10380		 *    } );
10381		 */
10382		"bPaginate": true,
10383	
10384	
10385		/**
10386		 * Enable or disable the display of a 'processing' indicator when the table is
10387		 * being processed (e.g. a sort). This is particularly useful for tables with
10388		 * large amounts of data where it can take a noticeable amount of time to sort
10389		 * the entries.
10390		 *  @type boolean
10391		 *  @default false
10392		 *
10393		 *  @dtopt Features
10394		 *  @name DataTable.defaults.processing
10395		 *
10396		 *  @example
10397		 *    $(document).ready( function () {
10398		 *      $('#example').dataTable( {
10399		 *        "processing": true
10400		 *      } );
10401		 *    } );
10402		 */
10403		"bProcessing": false,
10404	
10405	
10406		/**
10407		 * Retrieve the DataTables object for the given selector. Note that if the
10408		 * table has already been initialised, this parameter will cause DataTables
10409		 * to simply return the object that has already been set up - it will not take
10410		 * account of any changes you might have made to the initialisation object
10411		 * passed to DataTables (setting this parameter to true is an acknowledgement
10412		 * that you understand this). `destroy` can be used to reinitialise a table if
10413		 * you need.
10414		 *  @type boolean
10415		 *  @default false
10416		 *
10417		 *  @dtopt Options
10418		 *  @name DataTable.defaults.retrieve
10419		 *
10420		 *  @example
10421		 *    $(document).ready( function() {
10422		 *      initTable();
10423		 *      tableActions();
10424		 *    } );
10425		 *
10426		 *    function initTable ()
10427		 *    {
10428		 *      return $('#example').dataTable( {
10429		 *        "scrollY": "200px",
10430		 *        "paginate": false,
10431		 *        "retrieve": true
10432		 *      } );
10433		 *    }
10434		 *
10435		 *    function tableActions ()
10436		 *    {
10437		 *      var table = initTable();
10438		 *      // perform API operations with oTable
10439		 *    }
10440		 */
10441		"bRetrieve": false,
10442	
10443	
10444		/**
10445		 * When vertical (y) scrolling is enabled, DataTables will force the height of
10446		 * the table's viewport to the given height at all times (useful for layout).
10447		 * However, this can look odd when filtering data down to a small data set,
10448		 * and the footer is left "floating" further down. This parameter (when
10449		 * enabled) will cause DataTables to collapse the table's viewport down when
10450		 * the result set will fit within the given Y height.
10451		 *  @type boolean
10452		 *  @default false
10453		 *
10454		 *  @dtopt Options
10455		 *  @name DataTable.defaults.scrollCollapse
10456		 *
10457		 *  @example
10458		 *    $(document).ready( function() {
10459		 *      $('#example').dataTable( {
10460		 *        "scrollY": "200",
10461		 *        "scrollCollapse": true
10462		 *      } );
10463		 *    } );
10464		 */
10465		"bScrollCollapse": false,
10466	
10467	
10468		/**
10469		 * Configure DataTables to use server-side processing. Note that the
10470		 * `ajax` parameter must also be given in order to give DataTables a
10471		 * source to obtain the required data for each draw.
10472		 *  @type boolean
10473		 *  @default false
10474		 *
10475		 *  @dtopt Features
10476		 *  @dtopt Server-side
10477		 *  @name DataTable.defaults.serverSide
10478		 *
10479		 *  @example
10480		 *    $(document).ready( function () {
10481		 *      $('#example').dataTable( {
10482		 *        "serverSide": true,
10483		 *        "ajax": "xhr.php"
10484		 *      } );
10485		 *    } );
10486		 */
10487		"bServerSide": false,
10488	
10489	
10490		/**
10491		 * Enable or disable sorting of columns. Sorting of individual columns can be
10492		 * disabled by the `sortable` option for each column.
10493		 *  @type boolean
10494		 *  @default true
10495		 *
10496		 *  @dtopt Features
10497		 *  @name DataTable.defaults.ordering
10498		 *
10499		 *  @example
10500		 *    $(document).ready( function () {
10501		 *      $('#example').dataTable( {
10502		 *        "ordering": false
10503		 *      } );
10504		 *    } );
10505		 */
10506		"bSort": true,
10507	
10508	
10509		/**
10510		 * Enable or display DataTables' ability to sort multiple columns at the
10511		 * same time (activated by shift-click by the user).
10512		 *  @type boolean
10513		 *  @default true
10514		 *
10515		 *  @dtopt Options
10516		 *  @name DataTable.defaults.orderMulti
10517		 *
10518		 *  @example
10519		 *    // Disable multiple column sorting ability
10520		 *    $(document).ready( function () {
10521		 *      $('#example').dataTable( {
10522		 *        "orderMulti": false
10523		 *      } );
10524		 *    } );
10525		 */
10526		"bSortMulti": true,
10527	
10528	
10529		/**
10530		 * Allows control over whether DataTables should use the top (true) unique
10531		 * cell that is found for a single column, or the bottom (false - default).
10532		 * This is useful when using complex headers.
10533		 *  @type boolean
10534		 *  @default false
10535		 *
10536		 *  @dtopt Options
10537		 *  @name DataTable.defaults.orderCellsTop
10538		 *
10539		 *  @example
10540		 *    $(document).ready( function() {
10541		 *      $('#example').dataTable( {
10542		 *        "orderCellsTop": true
10543		 *      } );
10544		 *    } );
10545		 */
10546		"bSortCellsTop": false,
10547	
10548	
10549		/**
10550		 * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10551		 * `sorting\_3` to the columns which are currently being sorted on. This is
10552		 * presented as a feature switch as it can increase processing time (while
10553		 * classes are removed and added) so for large data sets you might want to
10554		 * turn this off.
10555		 *  @type boolean
10556		 *  @default true
10557		 *
10558		 *  @dtopt Features
10559		 *  @name DataTable.defaults.orderClasses
10560		 *
10561		 *  @example
10562		 *    $(document).ready( function () {
10563		 *      $('#example').dataTable( {
10564		 *        "orderClasses": false
10565		 *      } );
10566		 *    } );
10567		 */
10568		"bSortClasses": true,
10569	
10570	
10571		/**
10572		 * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10573		 * used to save table display information such as pagination information,
10574		 * display length, filtering and sorting. As such when the end user reloads
10575		 * the page the display display will match what thy had previously set up.
10576		 *
10577		 * Due to the use of `localStorage` the default state saving is not supported
10578		 * in IE6 or 7. If state saving is required in those browsers, use
10579		 * `stateSaveCallback` to provide a storage solution such as cookies.
10580		 *  @type boolean
10581		 *  @default false
10582		 *
10583		 *  @dtopt Features
10584		 *  @name DataTable.defaults.stateSave
10585		 *
10586		 *  @example
10587		 *    $(document).ready( function () {
10588		 *      $('#example').dataTable( {
10589		 *        "stateSave": true
10590		 *      } );
10591		 *    } );
10592		 */
10593		"bStateSave": false,
10594	
10595	
10596		/**
10597		 * This function is called when a TR element is created (and all TD child
10598		 * elements have been inserted), or registered if using a DOM source, allowing
10599		 * manipulation of the TR element (adding classes etc).
10600		 *  @type function
10601		 *  @param {node} row "TR" element for the current row
10602		 *  @param {array} data Raw data array for this row
10603		 *  @param {int} dataIndex The index of this row in the internal aoData array
10604		 *
10605		 *  @dtopt Callbacks
10606		 *  @name DataTable.defaults.createdRow
10607		 *
10608		 *  @example
10609		 *    $(document).ready( function() {
10610		 *      $('#example').dataTable( {
10611		 *        "createdRow": function( row, data, dataIndex ) {
10612		 *          // Bold the grade for all 'A' grade browsers
10613		 *          if ( data[4] == "A" )
10614		 *          {
10615		 *            $('td:eq(4)', row).html( '<b>A</b>' );
10616		 *          }
10617		 *        }
10618		 *      } );
10619		 *    } );
10620		 */
10621		"fnCreatedRow": null,
10622	
10623	
10624		/**
10625		 * This function is called on every 'draw' event, and allows you to
10626		 * dynamically modify any aspect you want about the created DOM.
10627		 *  @type function
10628		 *  @param {object} settings DataTables settings object
10629		 *
10630		 *  @dtopt Callbacks
10631		 *  @name DataTable.defaults.drawCallback
10632		 *
10633		 *  @example
10634		 *    $(document).ready( function() {
10635		 *      $('#example').dataTable( {
10636		 *        "drawCallback": function( settings ) {
10637		 *          alert( 'DataTables has redrawn the table' );
10638		 *        }
10639		 *      } );
10640		 *    } );
10641		 */
10642		"fnDrawCallback": null,
10643	
10644	
10645		/**
10646		 * Identical to fnHeaderCallback() but for the table footer this function
10647		 * allows you to modify the table footer on every 'draw' event.
10648		 *  @type function
10649		 *  @param {node} foot "TR" element for the footer
10650		 *  @param {array} data Full table data (as derived from the original HTML)
10651		 *  @param {int} start Index for the current display starting point in the
10652		 *    display array
10653		 *  @param {int} end Index for the current display ending point in the
10654		 *    display array
10655		 *  @param {array int} display Index array to translate the visual position
10656		 *    to the full data array
10657		 *
10658		 *  @dtopt Callbacks
10659		 *  @name DataTable.defaults.footerCallback
10660		 *
10661		 *  @example
10662		 *    $(document).ready( function() {
10663		 *      $('#example').dataTable( {
10664		 *        "footerCallback": function( tfoot, data, start, end, display ) {
10665		 *          tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10666		 *        }
10667		 *      } );
10668		 *    } )
10669		 */
10670		"fnFooterCallback": null,
10671	
10672	
10673		/**
10674		 * When rendering large numbers in the information element for the table
10675		 * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10676		 * to have a comma separator for the 'thousands' units (e.g. 1 million is
10677		 * rendered as "1,000,000") to help readability for the end user. This
10678		 * function will override the default method DataTables uses.
10679		 *  @type function
10680		 *  @member
10681		 *  @param {int} toFormat number to be formatted
10682		 *  @returns {string} formatted string for DataTables to show the number
10683		 *
10684		 *  @dtopt Callbacks
10685		 *  @name DataTable.defaults.formatNumber
10686		 *
10687		 *  @example
10688		 *    // Format a number using a single quote for the separator (note that
10689		 *    // this can also be done with the language.thousands option)
10690		 *    $(document).ready( function() {
10691		 *      $('#example').dataTable( {
10692		 *        "formatNumber": function ( toFormat ) {
10693		 *          return toFormat.toString().replace(
10694		 *            /\B(?=(\d{3})+(?!\d))/g, "'"
10695		 *          );
10696		 *        };
10697		 *      } );
10698		 *    } );
10699		 */
10700		"fnFormatNumber": function ( toFormat ) {
10701			return toFormat.toString().replace(
10702				/\B(?=(\d{3})+(?!\d))/g,
10703				this.oLanguage.sThousands
10704			);
10705		},
10706	
10707	
10708		/**
10709		 * This function is called on every 'draw' event, and allows you to
10710		 * dynamically modify the header row. This can be used to calculate and
10711		 * display useful information about the table.
10712		 *  @type function
10713		 *  @param {node} head "TR" element for the header
10714		 *  @param {array} data Full table data (as derived from the original HTML)
10715		 *  @param {int} start Index for the current display starting point in the
10716		 *    display array
10717		 *  @param {int} end Index for the current display ending point in the
10718		 *    display array
10719		 *  @param {array int} display Index array to translate the visual position
10720		 *    to the full data array
10721		 *
10722		 *  @dtopt Callbacks
10723		 *  @name DataTable.defaults.headerCallback
10724		 *
10725		 *  @example
10726		 *    $(document).ready( function() {
10727		 *      $('#example').dataTable( {
10728		 *        "fheaderCallback": function( head, data, start, end, display ) {
10729		 *          head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10730		 *        }
10731		 *      } );
10732		 *    } )
10733		 */
10734		"fnHeaderCallback": null,
10735	
10736	
10737		/**
10738		 * The information element can be used to convey information about the current
10739		 * state of the table. Although the internationalisation options presented by
10740		 * DataTables are quite capable of dealing with most customisations, there may
10741		 * be times where you wish to customise the string further. This callback
10742		 * allows you to do exactly that.
10743		 *  @type function
10744		 *  @param {object} oSettings DataTables settings object
10745		 *  @param {int} start Starting position in data for the draw
10746		 *  @param {int} end End position in data for the draw
10747		 *  @param {int} max Total number of rows in the table (regardless of
10748		 *    filtering)
10749		 *  @param {int} total Total number of rows in the data set, after filtering
10750		 *  @param {string} pre The string that DataTables has formatted using it's
10751		 *    own rules
10752		 *  @returns {string} The string to be displayed in the information element.
10753		 *
10754		 *  @dtopt Callbacks
10755		 *  @name DataTable.defaults.infoCallback
10756		 *
10757		 *  @example
10758		 *    $('#example').dataTable( {
10759		 *      "infoCallback": function( settings, start, end, max, total, pre ) {
10760		 *        return start +" to "+ end;
10761		 *      }
10762		 *    } );
10763		 */
10764		"fnInfoCallback": null,
10765	
10766	
10767		/**
10768		 * Called when the table has been initialised. Normally DataTables will
10769		 * initialise sequentially and there will be no need for this function,
10770		 * however, this does not hold true when using external language information
10771		 * since that is obtained using an async XHR call.
10772		 *  @type function
10773		 *  @param {object} settings DataTables settings object
10774		 *  @param {object} json The JSON object request from the server - only
10775		 *    present if client-side Ajax sourced data is used
10776		 *
10777		 *  @dtopt Callbacks
10778		 *  @name DataTable.defaults.initComplete
10779		 *
10780		 *  @example
10781		 *    $(document).ready( function() {
10782		 *      $('#example').dataTable( {
10783		 *        "initComplete": function(settings, json) {
10784		 *          alert( 'DataTables has finished its initialisation.' );
10785		 *        }
10786		 *      } );
10787		 *    } )
10788		 */
10789		"fnInitComplete": null,
10790	
10791	
10792		/**
10793		 * Called at the very start of each table draw and can be used to cancel the
10794		 * draw by returning false, any other return (including undefined) results in
10795		 * the full draw occurring).
10796		 *  @type function
10797		 *  @param {object} settings DataTables settings object
10798		 *  @returns {boolean} False will cancel the draw, anything else (including no
10799		 *    return) will allow it to complete.
10800		 *
10801		 *  @dtopt Callbacks
10802		 *  @name DataTable.defaults.preDrawCallback
10803		 *
10804		 *  @example
10805		 *    $(document).ready( function() {
10806		 *      $('#example').dataTable( {
10807		 *        "preDrawCallback": function( settings ) {
10808		 *          if ( $('#test').val() == 1 ) {
10809		 *            return false;
10810		 *          }
10811		 *        }
10812		 *      } );
10813		 *    } );
10814		 */
10815		"fnPreDrawCallback": null,
10816	
10817	
10818		/**
10819		 * This function allows you to 'post process' each row after it have been
10820		 * generated for each table draw, but before it is rendered on screen. This
10821		 * function might be used for setting the row class name etc.
10822		 *  @type function
10823		 *  @param {node} row "TR" element for the current row
10824		 *  @param {array} data Raw data array for this row
10825		 *  @param {int} displayIndex The display index for the current table draw
10826		 *  @param {int} displayIndexFull The index of the data in the full list of
10827		 *    rows (after filtering)
10828		 *
10829		 *  @dtopt Callbacks
10830		 *  @name DataTable.defaults.rowCallback
10831		 *
10832		 *  @example
10833		 *    $(document).ready( function() {
10834		 *      $('#example').dataTable( {
10835		 *        "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10836		 *          // Bold the grade for all 'A' grade browsers
10837		 *          if ( data[4] == "A" ) {
10838		 *            $('td:eq(4)', row).html( '<b>A</b>' );
10839		 *          }
10840		 *        }
10841		 *      } );
10842		 *    } );
10843		 */
10844		"fnRowCallback": null,
10845	
10846	
10847		/**
10848		 * __Deprecated__ The functionality provided by this parameter has now been
10849		 * superseded by that provided through `ajax`, which should be used instead.
10850		 *
10851		 * This parameter allows you to override the default function which obtains
10852		 * the data from the server so something more suitable for your application.
10853		 * For example you could use POST data, or pull information from a Gears or
10854		 * AIR database.
10855		 *  @type function
10856		 *  @member
10857		 *  @param {string} source HTTP source to obtain the data from (`ajax`)
10858		 *  @param {array} data A key/value pair object containing the data to send
10859		 *    to the server
10860		 *  @param {function} callback to be called on completion of the data get
10861		 *    process that will draw the data on the page.
10862		 *  @param {object} settings DataTables settings object
10863		 *
10864		 *  @dtopt Callbacks
10865		 *  @dtopt Server-side
10866		 *  @name DataTable.defaults.serverData
10867		 *
10868		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
10869		 */
10870		"fnServerData": null,
10871	
10872	
10873		/**
10874		 * __Deprecated__ The functionality provided by this parameter has now been
10875		 * superseded by that provided through `ajax`, which should be used instead.
10876		 *
10877		 *  It is often useful to send extra data to the server when making an Ajax
10878		 * request - for example custom filtering information, and this callback
10879		 * function makes it trivial to send extra information to the server. The
10880		 * passed in parameter is the data set that has been constructed by
10881		 * DataTables, and you can add to this or modify it as you require.
10882		 *  @type function
10883		 *  @param {array} data Data array (array of objects which are name/value
10884		 *    pairs) that has been constructed by DataTables and will be sent to the
10885		 *    server. In the case of Ajax sourced data with server-side processing
10886		 *    this will be an empty array, for server-side processing there will be a
10887		 *    significant number of parameters!
10888		 *  @returns {undefined} Ensure that you modify the data array passed in,
10889		 *    as this is passed by reference.
10890		 *
10891		 *  @dtopt Callbacks
10892		 *  @dtopt Server-side
10893		 *  @name DataTable.defaults.serverParams
10894		 *
10895		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
10896		 */
10897		"fnServerParams": null,
10898	
10899	
10900		/**
10901		 * Load the table state. With this function you can define from where, and how, the
10902		 * state of a table is loaded. By default DataTables will load from `localStorage`
10903		 * but you might wish to use a server-side database or cookies.
10904		 *  @type function
10905		 *  @member
10906		 *  @param {object} settings DataTables settings object
10907		 *  @param {object} callback Callback that can be executed when done. It
10908		 *    should be passed the loaded state object.
10909		 *  @return {object} The DataTables state object to be loaded
10910		 *
10911		 *  @dtopt Callbacks
10912		 *  @name DataTable.defaults.stateLoadCallback
10913		 *
10914		 *  @example
10915		 *    $(document).ready( function() {
10916		 *      $('#example').dataTable( {
10917		 *        "stateSave": true,
10918		 *        "stateLoadCallback": function (settings, callback) {
10919		 *          $.ajax( {
10920		 *            "url": "/state_load",
10921		 *            "dataType": "json",
10922		 *            "success": function (json) {
10923		 *              callback( json );
10924		 *            }
10925		 *          } );
10926		 *        }
10927		 *      } );
10928		 *    } );
10929		 */
10930		"fnStateLoadCallback": function ( settings ) {
10931			try {
10932				return JSON.parse(
10933					(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
10934						'DataTables_'+settings.sInstance+'_'+location.pathname
10935					)
10936				);
10937			} catch (e) {}
10938		},
10939	
10940	
10941		/**
10942		 * Callback which allows modification of the saved state prior to loading that state.
10943		 * This callback is called when the table is loading state from the stored data, but
10944		 * prior to the settings object being modified by the saved state. Note that for
10945		 * plug-in authors, you should use the `stateLoadParams` event to load parameters for
10946		 * a plug-in.
10947		 *  @type function
10948		 *  @param {object} settings DataTables settings object
10949		 *  @param {object} data The state object that is to be loaded
10950		 *
10951		 *  @dtopt Callbacks
10952		 *  @name DataTable.defaults.stateLoadParams
10953		 *
10954		 *  @example
10955		 *    // Remove a saved filter, so filtering is never loaded
10956		 *    $(document).ready( function() {
10957		 *      $('#example').dataTable( {
10958		 *        "stateSave": true,
10959		 *        "stateLoadParams": function (settings, data) {
10960		 *          data.oSearch.sSearch = "";
10961		 *        }
10962		 *      } );
10963		 *    } );
10964		 *
10965		 *  @example
10966		 *    // Disallow state loading by returning false
10967		 *    $(document).ready( function() {
10968		 *      $('#example').dataTable( {
10969		 *        "stateSave": true,
10970		 *        "stateLoadParams": function (settings, data) {
10971		 *          return false;
10972		 *        }
10973		 *      } );
10974		 *    } );
10975		 */
10976		"fnStateLoadParams": null,
10977	
10978	
10979		/**
10980		 * Callback that is called when the state has been loaded from the state saving method
10981		 * and the DataTables settings object has been modified as a result of the loaded state.
10982		 *  @type function
10983		 *  @param {object} settings DataTables settings object
10984		 *  @param {object} data The state object that was loaded
10985		 *
10986		 *  @dtopt Callbacks
10987		 *  @name DataTable.defaults.stateLoaded
10988		 *
10989		 *  @example
10990		 *    // Show an alert with the filtering value that was saved
10991		 *    $(document).ready( function() {
10992		 *      $('#example').dataTable( {
10993		 *        "stateSave": true,
10994		 *        "stateLoaded": function (settings, data) {
10995		 *          alert( 'Saved filter was: '+data.oSearch.sSearch );
10996		 *        }
10997		 *      } );
10998		 *    } );
10999		 */
11000		"fnStateLoaded": null,
11001	
11002	
11003		/**
11004		 * Save the table state. This function allows you to define where and how the state
11005		 * information for the table is stored By default DataTables will use `localStorage`
11006		 * but you might wish to use a server-side database or cookies.
11007		 *  @type function
11008		 *  @member
11009		 *  @param {object} settings DataTables settings object
11010		 *  @param {object} data The state object to be saved
11011		 *
11012		 *  @dtopt Callbacks
11013		 *  @name DataTable.defaults.stateSaveCallback
11014		 *
11015		 *  @example
11016		 *    $(document).ready( function() {
11017		 *      $('#example').dataTable( {
11018		 *        "stateSave": true,
11019		 *        "stateSaveCallback": function (settings, data) {
11020		 *          // Send an Ajax request to the server with the state object
11021		 *          $.ajax( {
11022		 *            "url": "/state_save",
11023		 *            "data": data,
11024		 *            "dataType": "json",
11025		 *            "method": "POST"
11026		 *            "success": function () {}
11027		 *          } );
11028		 *        }
11029		 *      } );
11030		 *    } );
11031		 */
11032		"fnStateSaveCallback": function ( settings, data ) {
11033			try {
11034				(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
11035					'DataTables_'+settings.sInstance+'_'+location.pathname,
11036					JSON.stringify( data )
11037				);
11038			} catch (e) {}
11039		},
11040	
11041	
11042		/**
11043		 * Callback which allows modification of the state to be saved. Called when the table
11044		 * has changed state a new state save is required. This method allows modification of
11045		 * the state saving object prior to actually doing the save, including addition or
11046		 * other state properties or modification. Note that for plug-in authors, you should
11047		 * use the `stateSaveParams` event to save parameters for a plug-in.
11048		 *  @type function
11049		 *  @param {object} settings DataTables settings object
11050		 *  @param {object} data The state object to be saved
11051		 *
11052		 *  @dtopt Callbacks
11053		 *  @name DataTable.defaults.stateSaveParams
11054		 *
11055		 *  @example
11056		 *    // Remove a saved filter, so filtering is never saved
11057		 *    $(document).ready( function() {
11058		 *      $('#example').dataTable( {
11059		 *        "stateSave": true,
11060		 *        "stateSaveParams": function (settings, data) {
11061		 *          data.oSearch.sSearch = "";
11062		 *        }
11063		 *      } );
11064		 *    } );
11065		 */
11066		"fnStateSaveParams": null,
11067	
11068	
11069		/**
11070		 * Duration for which the saved state information is considered valid. After this period
11071		 * has elapsed the state will be returned to the default.
11072		 * Value is given in seconds.
11073		 *  @type int
11074		 *  @default 7200 <i>(2 hours)</i>
11075		 *
11076		 *  @dtopt Options
11077		 *  @name DataTable.defaults.stateDuration
11078		 *
11079		 *  @example
11080		 *    $(document).ready( function() {
11081		 *      $('#example').dataTable( {
11082		 *        "stateDuration": 60*60*24; // 1 day
11083		 *      } );
11084		 *    } )
11085		 */
11086		"iStateDuration": 7200,
11087	
11088	
11089		/**
11090		 * When enabled DataTables will not make a request to the server for the first
11091		 * page draw - rather it will use the data already on the page (no sorting etc
11092		 * will be applied to it), thus saving on an XHR at load time. `deferLoading`
11093		 * is used to indicate that deferred loading is required, but it is also used
11094		 * to tell DataTables how many records there are in the full table (allowing
11095		 * the information element and pagination to be displayed correctly). In the case
11096		 * where a filtering is applied to the table on initial load, this can be
11097		 * indicated by giving the parameter as an array, where the first element is
11098		 * the number of records available after filtering and the second element is the
11099		 * number of records without filtering (allowing the table information element
11100		 * to be shown correctly).
11101		 *  @type int | array
11102		 *  @default null
11103		 *
11104		 *  @dtopt Options
11105		 *  @name DataTable.defaults.deferLoading
11106		 *
11107		 *  @example
11108		 *    // 57 records available in the table, no filtering applied
11109		 *    $(document).ready( function() {
11110		 *      $('#example').dataTable( {
11111		 *        "serverSide": true,
11112		 *        "ajax": "scripts/server_processing.php",
11113		 *        "deferLoading": 57
11114		 *      } );
11115		 *    } );
11116		 *
11117		 *  @example
11118		 *    // 57 records after filtering, 100 without filtering (an initial filter applied)
11119		 *    $(document).ready( function() {
11120		 *      $('#example').dataTable( {
11121		 *        "serverSide": true,
11122		 *        "ajax": "scripts/server_processing.php",
11123		 *        "deferLoading": [ 57, 100 ],
11124		 *        "search": {
11125		 *          "search": "my_filter"
11126		 *        }
11127		 *      } );
11128		 *    } );
11129		 */
11130		"iDeferLoading": null,
11131	
11132	
11133		/**
11134		 * Number of rows to display on a single page when using pagination. If
11135		 * feature enabled (`lengthChange`) then the end user will be able to override
11136		 * this to a custom setting using a pop-up menu.
11137		 *  @type int
11138		 *  @default 10
11139		 *
11140		 *  @dtopt Options
11141		 *  @name DataTable.defaults.pageLength
11142		 *
11143		 *  @example
11144		 *    $(document).ready( function() {
11145		 *      $('#example').dataTable( {
11146		 *        "pageLength": 50
11147		 *      } );
11148		 *    } )
11149		 */
11150		"iDisplayLength": 10,
11151	
11152	
11153		/**
11154		 * Define the starting point for data display when using DataTables with
11155		 * pagination. Note that this parameter is the number of records, rather than
11156		 * the page number, so if you have 10 records per page and want to start on
11157		 * the third page, it should be "20".
11158		 *  @type int
11159		 *  @default 0
11160		 *
11161		 *  @dtopt Options
11162		 *  @name DataTable.defaults.displayStart
11163		 *
11164		 *  @example
11165		 *    $(document).ready( function() {
11166		 *      $('#example').dataTable( {
11167		 *        "displayStart": 20
11168		 *      } );
11169		 *    } )
11170		 */
11171		"iDisplayStart": 0,
11172	
11173	
11174		/**
11175		 * By default DataTables allows keyboard navigation of the table (sorting, paging,
11176		 * and filtering) by adding a `tabindex` attribute to the required elements. This
11177		 * allows you to tab through the controls and press the enter key to activate them.
11178		 * The tabindex is default 0, meaning that the tab follows the flow of the document.
11179		 * You can overrule this using this parameter if you wish. Use a value of -1 to
11180		 * disable built-in keyboard navigation.
11181		 *  @type int
11182		 *  @default 0
11183		 *
11184		 *  @dtopt Options
11185		 *  @name DataTable.defaults.tabIndex
11186		 *
11187		 *  @example
11188		 *    $(document).ready( function() {
11189		 *      $('#example').dataTable( {
11190		 *        "tabIndex": 1
11191		 *      } );
11192		 *    } );
11193		 */
11194		"iTabIndex": 0,
11195	
11196	
11197		/**
11198		 * Classes that DataTables assigns to the various components and features
11199		 * that it adds to the HTML table. This allows classes to be configured
11200		 * during initialisation in addition to through the static
11201		 * {@link DataTable.ext.oStdClasses} object).
11202		 *  @namespace
11203		 *  @name DataTable.defaults.classes
11204		 */
11205		"oClasses": {},
11206	
11207	
11208		/**
11209		 * All strings that DataTables uses in the user interface that it creates
11210		 * are defined in this object, allowing you to modified them individually or
11211		 * completely replace them all as required.
11212		 *  @namespace
11213		 *  @name DataTable.defaults.language
11214		 */
11215		"oLanguage": {
11216			/**
11217			 * Strings that are used for WAI-ARIA labels and controls only (these are not
11218			 * actually visible on the page, but will be read by screenreaders, and thus
11219			 * must be internationalised as well).
11220			 *  @namespace
11221			 *  @name DataTable.defaults.language.aria
11222			 */
11223			"oAria": {
11224				/**
11225				 * ARIA label that is added to the table headers when the column may be
11226				 * sorted ascending by activing the column (click or return when focused).
11227				 * Note that the column header is prefixed to this string.
11228				 *  @type string
11229				 *  @default : activate to sort column ascending
11230				 *
11231				 *  @dtopt Language
11232				 *  @name DataTable.defaults.language.aria.sortAscending
11233				 *
11234				 *  @example
11235				 *    $(document).ready( function() {
11236				 *      $('#example').dataTable( {
11237				 *        "language": {
11238				 *          "aria": {
11239				 *            "sortAscending": " - click/return to sort ascending"
11240				 *          }
11241				 *        }
11242				 *      } );
11243				 *    } );
11244				 */
11245				"sSortAscending": ": activate to sort column ascending",
11246	
11247				/**
11248				 * ARIA label that is added to the table headers when the column may be
11249				 * sorted descending by activing the column (click or return when focused).
11250				 * Note that the column header is prefixed to this string.
11251				 *  @type string
11252				 *  @default : activate to sort column ascending
11253				 *
11254				 *  @dtopt Language
11255				 *  @name DataTable.defaults.language.aria.sortDescending
11256				 *
11257				 *  @example
11258				 *    $(document).ready( function() {
11259				 *      $('#example').dataTable( {
11260				 *        "language": {
11261				 *          "aria": {
11262				 *            "sortDescending": " - click/return to sort descending"
11263				 *          }
11264				 *        }
11265				 *      } );
11266				 *    } );
11267				 */
11268				"sSortDescending": ": activate to sort column descending"
11269			},
11270	
11271			/**
11272			 * Pagination string used by DataTables for the built-in pagination
11273			 * control types.
11274			 *  @namespace
11275			 *  @name DataTable.defaults.language.paginate
11276			 */
11277			"oPaginate": {
11278				/**
11279				 * Text to use when using the 'full_numbers' type of pagination for the
11280				 * button to take the user to the first page.
11281				 *  @type string
11282				 *  @default First
11283				 *
11284				 *  @dtopt Language
11285				 *  @name DataTable.defaults.language.paginate.first
11286				 *
11287				 *  @example
11288				 *    $(document).ready( function() {
11289				 *      $('#example').dataTable( {
11290				 *        "language": {
11291				 *          "paginate": {
11292				 *            "first": "First page"
11293				 *          }
11294				 *        }
11295				 *      } );
11296				 *    } );
11297				 */
11298				"sFirst": "First",
11299	
11300	
11301				/**
11302				 * Text to use when using the 'full_numbers' type of pagination for the
11303				 * button to take the user to the last page.
11304				 *  @type string
11305				 *  @default Last
11306				 *
11307				 *  @dtopt Language
11308				 *  @name DataTable.defaults.language.paginate.last
11309				 *
11310				 *  @example
11311				 *    $(document).ready( function() {
11312				 *      $('#example').dataTable( {
11313				 *        "language": {
11314				 *          "paginate": {
11315				 *            "last": "Last page"
11316				 *          }
11317				 *        }
11318				 *      } );
11319				 *    } );
11320				 */
11321				"sLast": "Last",
11322	
11323	
11324				/**
11325				 * Text to use for the 'next' pagination button (to take the user to the
11326				 * next page).
11327				 *  @type string
11328				 *  @default Next
11329				 *
11330				 *  @dtopt Language
11331				 *  @name DataTable.defaults.language.paginate.next
11332				 *
11333				 *  @example
11334				 *    $(document).ready( function() {
11335				 *      $('#example').dataTable( {
11336				 *        "language": {
11337				 *          "paginate": {
11338				 *            "next": "Next page"
11339				 *          }
11340				 *        }
11341				 *      } );
11342				 *    } );
11343				 */
11344				"sNext": "Next",
11345	
11346	
11347				/**
11348				 * Text to use for the 'previous' pagination button (to take the user to
11349				 * the previous page).
11350				 *  @type string
11351				 *  @default Previous
11352				 *
11353				 *  @dtopt Language
11354				 *  @name DataTable.defaults.language.paginate.previous
11355				 *
11356				 *  @example
11357				 *    $(document).ready( function() {
11358				 *      $('#example').dataTable( {
11359				 *        "language": {
11360				 *          "paginate": {
11361				 *            "previous": "Previous page"
11362				 *          }
11363				 *        }
11364				 *      } );
11365				 *    } );
11366				 */
11367				"sPrevious": "Previous"
11368			},
11369	
11370			/**
11371			 * This string is shown in preference to `zeroRecords` when the table is
11372			 * empty of data (regardless of filtering). Note that this is an optional
11373			 * parameter - if it is not given, the value of `zeroRecords` will be used
11374			 * instead (either the default or given value).
11375			 *  @type string
11376			 *  @default No data available in table
11377			 *
11378			 *  @dtopt Language
11379			 *  @name DataTable.defaults.language.emptyTable
11380			 *
11381			 *  @example
11382			 *    $(document).ready( function() {
11383			 *      $('#example').dataTable( {
11384			 *        "language": {
11385			 *          "emptyTable": "No data available in table"
11386			 *        }
11387			 *      } );
11388			 *    } );
11389			 */
11390			"sEmptyTable": "No data available in table",
11391	
11392	
11393			/**
11394			 * This string gives information to the end user about the information
11395			 * that is current on display on the page. The following tokens can be
11396			 * used in the string and will be dynamically replaced as the table
11397			 * display updates. This tokens can be placed anywhere in the string, or
11398			 * removed as needed by the language requires:
11399			 *
11400			 * * `\_START\_` - Display index of the first record on the current page
11401			 * * `\_END\_` - Display index of the last record on the current page
11402			 * * `\_TOTAL\_` - Number of records in the table after filtering
11403			 * * `\_MAX\_` - Number of records in the table without filtering
11404			 * * `\_PAGE\_` - Current page number
11405			 * * `\_PAGES\_` - Total number of pages of data in the table
11406			 *
11407			 *  @type string
11408			 *  @default Showing _START_ to _END_ of _TOTAL_ entries
11409			 *
11410			 *  @dtopt Language
11411			 *  @name DataTable.defaults.language.info
11412			 *
11413			 *  @example
11414			 *    $(document).ready( function() {
11415			 *      $('#example').dataTable( {
11416			 *        "language": {
11417			 *          "info": "Showing page _PAGE_ of _PAGES_"
11418			 *        }
11419			 *      } );
11420			 *    } );
11421			 */
11422			"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11423	
11424	
11425			/**
11426			 * Display information string for when the table is empty. Typically the
11427			 * format of this string should match `info`.
11428			 *  @type string
11429			 *  @default Showing 0 to 0 of 0 entries
11430			 *
11431			 *  @dtopt Language
11432			 *  @name DataTable.defaults.language.infoEmpty
11433			 *
11434			 *  @example
11435			 *    $(document).ready( function() {
11436			 *      $('#example').dataTable( {
11437			 *        "language": {
11438			 *          "infoEmpty": "No entries to show"
11439			 *        }
11440			 *      } );
11441			 *    } );
11442			 */
11443			"sInfoEmpty": "Showing 0 to 0 of 0 entries",
11444	
11445	
11446			/**
11447			 * When a user filters the information in a table, this string is appended
11448			 * to the information (`info`) to give an idea of how strong the filtering
11449			 * is. The variable _MAX_ is dynamically updated.
11450			 *  @type string
11451			 *  @default (filtered from _MAX_ total entries)
11452			 *
11453			 *  @dtopt Language
11454			 *  @name DataTable.defaults.language.infoFiltered
11455			 *
11456			 *  @example
11457			 *    $(document).ready( function() {
11458			 *      $('#example').dataTable( {
11459			 *        "language": {
11460			 *          "infoFiltered": " - filtering from _MAX_ records"
11461			 *        }
11462			 *      } );
11463			 *    } );
11464			 */
11465			"sInfoFiltered": "(filtered from _MAX_ total entries)",
11466	
11467	
11468			/**
11469			 * If can be useful to append extra information to the info string at times,
11470			 * and this variable does exactly that. This information will be appended to
11471			 * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11472			 * being used) at all times.
11473			 *  @type string
11474			 *  @default <i>Empty string</i>
11475			 *
11476			 *  @dtopt Language
11477			 *  @name DataTable.defaults.language.infoPostFix
11478			 *
11479			 *  @example
11480			 *    $(document).ready( function() {
11481			 *      $('#example').dataTable( {
11482			 *        "language": {
11483			 *          "infoPostFix": "All records shown are derived from real information."
11484			 *        }
11485			 *      } );
11486			 *    } );
11487			 */
11488			"sInfoPostFix": "",
11489	
11490	
11491			/**
11492			 * This decimal place operator is a little different from the other
11493			 * language options since DataTables doesn't output floating point
11494			 * numbers, so it won't ever use this for display of a number. Rather,
11495			 * what this parameter does is modify the sort methods of the table so
11496			 * that numbers which are in a format which has a character other than
11497			 * a period (`.`) as a decimal place will be sorted numerically.
11498			 *
11499			 * Note that numbers with different decimal places cannot be shown in
11500			 * the same table and still be sortable, the table must be consistent.
11501			 * However, multiple different tables on the page can use different
11502			 * decimal place characters.
11503			 *  @type string
11504			 *  @default 
11505			 *
11506			 *  @dtopt Language
11507			 *  @name DataTable.defaults.language.decimal
11508			 *
11509			 *  @example
11510			 *    $(document).ready( function() {
11511			 *      $('#example').dataTable( {
11512			 *        "language": {
11513			 *          "decimal": ","
11514			 *          "thousands": "."
11515			 *        }
11516			 *      } );
11517			 *    } );
11518			 */
11519			"sDecimal": "",
11520	
11521	
11522			/**
11523			 * DataTables has a build in number formatter (`formatNumber`) which is
11524			 * used to format large numbers that are used in the table information.
11525			 * By default a comma is used, but this can be trivially changed to any
11526			 * character you wish with this parameter.
11527			 *  @type string
11528			 *  @default ,
11529			 *
11530			 *  @dtopt Language
11531			 *  @name DataTable.defaults.language.thousands
11532			 *
11533			 *  @example
11534			 *    $(document).ready( function() {
11535			 *      $('#example').dataTable( {
11536			 *        "language": {
11537			 *          "thousands": "'"
11538			 *        }
11539			 *      } );
11540			 *    } );
11541			 */
11542			"sThousands": ",",
11543	
11544	
11545			/**
11546			 * Detail the action that will be taken when the drop down menu for the
11547			 * pagination length option is changed. The '_MENU_' variable is replaced
11548			 * with a default select list of 10, 25, 50 and 100, and can be replaced
11549			 * with a custom select box if required.
11550			 *  @type string
11551			 *  @default Show _MENU_ entries
11552			 *
11553			 *  @dtopt Language
11554			 *  @name DataTable.defaults.language.lengthMenu
11555			 *
11556			 *  @example
11557			 *    // Language change only
11558			 *    $(document).ready( function() {
11559			 *      $('#example').dataTable( {
11560			 *        "language": {
11561			 *          "lengthMenu": "Display _MENU_ records"
11562			 *        }
11563			 *      } );
11564			 *    } );
11565			 *
11566			 *  @example
11567			 *    // Language and options change
11568			 *    $(document).ready( function() {
11569			 *      $('#example').dataTable( {
11570			 *        "language": {
11571			 *          "lengthMenu": 'Display <select>'+
11572			 *            '<option value="10">10</option>'+
11573			 *            '<option value="20">20</option>'+
11574			 *            '<option value="30">30</option>'+
11575			 *            '<option value="40">40</option>'+
11576			 *            '<option value="50">50</option>'+
11577			 *            '<option value="-1">All</option>'+
11578			 *            '</select> records'
11579			 *        }
11580			 *      } );
11581			 *    } );
11582			 */
11583			"sLengthMenu": "Show _MENU_ entries",
11584	
11585	
11586			/**
11587			 * When using Ajax sourced data and during the first draw when DataTables is
11588			 * gathering the data, this message is shown in an empty row in the table to
11589			 * indicate to the end user the the data is being loaded. Note that this
11590			 * parameter is not used when loading data by server-side processing, just
11591			 * Ajax sourced data with client-side processing.
11592			 *  @type string
11593			 *  @default Loading...
11594			 *
11595			 *  @dtopt Language
11596			 *  @name DataTable.defaults.language.loadingRecords
11597			 *
11598			 *  @example
11599			 *    $(document).ready( function() {
11600			 *      $('#example').dataTable( {
11601			 *        "language": {
11602			 *          "loadingRecords": "Please wait - loading..."
11603			 *        }
11604			 *      } );
11605			 *    } );
11606			 */
11607			"sLoadingRecords": "Loading...",
11608	
11609	
11610			/**
11611			 * Text which is displayed when the table is processing a user action
11612			 * (usually a sort command or similar).
11613			 *  @type string
11614			 *
11614  @default Processing...
11615			 *
11616			 *  @dtopt Language
11617			 *  @name DataTable.defaults.language.processing
11618			 *
11619			 *  @example
11620			 *    $(document).ready( function() {
11621			 *      $('#example').dataTable( {
11622			 *        "language": {
11623			 *          "processing": "DataTables is currently busy"
11624			 *        }
11625			 *      } );
11626			 *    } );
11627			 */
11628			"sProcessing": "Processing...
vendor: 24,082 bytes, lines 11628-12357
11628",
11629	
11630	
11631			/**
11632			 * Details the actions that will be taken when the user types into the
11633			 * filtering input text box. The variable "_INPUT_", if used in the string,
11634			 * is replaced with the HTML text box for the filtering input allowing
11635			 * control over where it appears in the string. If "_INPUT_" is not given
11636			 * then the input box is appended to the string automatically.
11637			 *  @type string
11638			 *  @default Search:
11639			 *
11640			 *  @dtopt Language
11641			 *  @name DataTable.defaults.language.search
11642			 *
11643			 *  @example
11644			 *    // Input text box will be appended at the end automatically
11645			 *    $(document).ready( function() {
11646			 *      $('#example').dataTable( {
11647			 *        "language": {
11648			 *          "search": "Filter records:"
11649			 *        }
11650			 *      } );
11651			 *    } );
11652			 *
11653			 *  @example
11654			 *    // Specify where the filter should appear
11655			 *    $(document).ready( function() {
11656			 *      $('#example').dataTable( {
11657			 *        "language": {
11658			 *          "search": "Apply filter _INPUT_ to table"
11659			 *        }
11660			 *      } );
11661			 *    } );
11662			 */
11663			"sSearch": "Search:",
11664	
11665	
11666			/**
11667			 * Assign a `placeholder` attribute to the search `input` element
11668			 *  @type string
11669			 *  @default 
11670			 *
11671			 *  @dtopt Language
11672			 *  @name DataTable.defaults.language.searchPlaceholder
11673			 */
11674			"sSearchPlaceholder": "",
11675	
11676	
11677			/**
11678			 * All of the language information can be stored in a file on the
11679			 * server-side, which DataTables will look up if this parameter is passed.
11680			 * It must store the URL of the language file, which is in a JSON format,
11681			 * and the object has the same properties as the oLanguage object in the
11682			 * initialiser object (i.e. the above parameters). Please refer to one of
11683			 * the example language files to see how this works in action.
11684			 *  @type string
11685			 *  @default <i>Empty string - i.e. disabled</i>
11686			 *
11687			 *  @dtopt Language
11688			 *  @name DataTable.defaults.language.url
11689			 *
11690			 *  @example
11691			 *    $(document).ready( function() {
11692			 *      $('#example').dataTable( {
11693			 *        "language": {
11694			 *          "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11695			 *        }
11696			 *      } );
11697			 *    } );
11698			 */
11699			"sUrl": "",
11700	
11701	
11702			/**
11703			 * Text shown inside the table records when the is no information to be
11704			 * displayed after filtering. `emptyTable` is shown when there is simply no
11705			 * information in the table at all (regardless of filtering).
11706			 *  @type string
11707			 *  @default No matching records found
11708			 *
11709			 *  @dtopt Language
11710			 *  @name DataTable.defaults.language.zeroRecords
11711			 *
11712			 *  @example
11713			 *    $(document).ready( function() {
11714			 *      $('#example').dataTable( {
11715			 *        "language": {
11716			 *          "zeroRecords": "No records to display"
11717			 *        }
11718			 *      } );
11719			 *    } );
11720			 */
11721			"sZeroRecords": "No matching records found"
11722		},
11723	
11724	
11725		/**
11726		 * This parameter allows you to have define the global filtering state at
11727		 * initialisation time. As an object the `search` parameter must be
11728		 * defined, but all other parameters are optional. When `regex` is true,
11729		 * the search string will be treated as a regular expression, when false
11730		 * (default) it will be treated as a straight string. When `smart`
11731		 * DataTables will use it's smart filtering methods (to word match at
11732		 * any point in the data), when false this will not be done.
11733		 *  @namespace
11734		 *  @extends DataTable.models.oSearch
11735		 *
11736		 *  @dtopt Options
11737		 *  @name DataTable.defaults.search
11738		 *
11739		 *  @example
11740		 *    $(document).ready( function() {
11741		 *      $('#example').dataTable( {
11742		 *        "search": {"search": "Initial search"}
11743		 *      } );
11744		 *    } )
11745		 */
11746		"oSearch": $.extend( {}, DataTable.models.oSearch ),
11747	
11748	
11749		/**
11750		 * __Deprecated__ The functionality provided by this parameter has now been
11751		 * superseded by that provided through `ajax`, which should be used instead.
11752		 *
11753		 * By default DataTables will look for the property `data` (or `aaData` for
11754		 * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11755		 * source or for server-side processing - this parameter allows that
11756		 * property to be changed. You can use Javascript dotted object notation to
11757		 * get a data source for multiple levels of nesting.
11758		 *  @type string
11759		 *  @default data
11760		 *
11761		 *  @dtopt Options
11762		 *  @dtopt Server-side
11763		 *  @name DataTable.defaults.ajaxDataProp
11764		 *
11765		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
11766		 */
11767		"sAjaxDataProp": "data",
11768	
11769	
11770		/**
11771		 * __Deprecated__ The functionality provided by this parameter has now been
11772		 * superseded by that provided through `ajax`, which should be used instead.
11773		 *
11774		 * You can instruct DataTables to load data from an external
11775		 * source using this parameter (use aData if you want to pass data in you
11776		 * already have). Simply provide a url a JSON object can be obtained from.
11777		 *  @type string
11778		 *  @default null
11779		 *
11780		 *  @dtopt Options
11781		 *  @dtopt Server-side
11782		 *  @name DataTable.defaults.ajaxSource
11783		 *
11784		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
11785		 */
11786		"sAjaxSource": null,
11787	
11788	
11789		/**
11790		 * This initialisation variable allows you to specify exactly where in the
11791		 * DOM you want DataTables to inject the various controls it adds to the page
11792		 * (for example you might want the pagination controls at the top of the
11793		 * table). DIV elements (with or without a custom class) can also be added to
11794		 * aid styling. The follow syntax is used:
11795		 *   <ul>
11796		 *     <li>The following options are allowed:
11797		 *       <ul>
11798		 *         <li>'l' - Length changing</li>
11799		 *         <li>'f' - Filtering input</li>
11800		 *         <li>'t' - The table!</li>
11801		 *         <li>'i' - Information</li>
11802		 *         <li>'p' - Pagination</li>
11803		 *         <li>'r' - pRocessing</li>
11804		 *       </ul>
11805		 *     </li>
11806		 *     <li>The following constants are allowed:
11807		 *       <ul>
11808		 *         <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11809		 *         <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11810		 *       </ul>
11811		 *     </li>
11812		 *     <li>The following syntax is expected:
11813		 *       <ul>
11814		 *         <li>'&lt;' and '&gt;' - div elements</li>
11815		 *         <li>'&lt;"class" and '&gt;' - div with a class</li>
11816		 *         <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11817		 *       </ul>
11818		 *     </li>
11819		 *     <li>Examples:
11820		 *       <ul>
11821		 *         <li>'&lt;"wrapper"flipt&gt;'</li>
11822		 *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11823		 *       </ul>
11824		 *     </li>
11825		 *   </ul>
11826		 *  @type string
11827		 *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11828		 *    <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11829		 *
11830		 *  @dtopt Options
11831		 *  @name DataTable.defaults.dom
11832		 *
11833		 *  @example
11834		 *    $(document).ready( function() {
11835		 *      $('#example').dataTable( {
11836		 *        "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11837		 *      } );
11838		 *    } );
11839		 */
11840		"sDom": "lfrtip",
11841	
11842	
11843		/**
11844		 * Search delay option. This will throttle full table searches that use the
11845		 * DataTables provided search input element (it does not effect calls to
11846		 * `dt-api search()`, providing a delay before the search is made.
11847		 *  @type integer
11848		 *  @default 0
11849		 *
11850		 *  @dtopt Options
11851		 *  @name DataTable.defaults.searchDelay
11852		 *
11853		 *  @example
11854		 *    $(document).ready( function() {
11855		 *      $('#example').dataTable( {
11856		 *        "searchDelay": 200
11857		 *      } );
11858		 *    } )
11859		 */
11860		"searchDelay": null,
11861	
11862	
11863		/**
11864		 * DataTables features six different built-in options for the buttons to
11865		 * display for pagination control:
11866		 *
11867		 * * `numbers` - Page number buttons only
11868		 * * `simple` - 'Previous' and 'Next' buttons only
11869		 * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11870		 * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11871		 * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
11872		 * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
11873		 *  
11874		 * Further methods can be added using {@link DataTable.ext.oPagination}.
11875		 *  @type string
11876		 *  @default simple_numbers
11877		 *
11878		 *  @dtopt Options
11879		 *  @name DataTable.defaults.pagingType
11880		 *
11881		 *  @example
11882		 *    $(document).ready( function() {
11883		 *      $('#example').dataTable( {
11884		 *        "pagingType": "full_numbers"
11885		 *      } );
11886		 *    } )
11887		 */
11888		"sPaginationType": "simple_numbers",
11889	
11890	
11891		/**
11892		 * Enable horizontal scrolling. When a table is too wide to fit into a
11893		 * certain layout, or you have a large number of columns in the table, you
11894		 * can enable x-scrolling to show the table in a viewport, which can be
11895		 * scrolled. This property can be `true` which will allow the table to
11896		 * scroll horizontally when needed, or any CSS unit, or a number (in which
11897		 * case it will be treated as a pixel measurement). Setting as simply `true`
11898		 * is recommended.
11899		 *  @type boolean|string
11900		 *  @default <i>blank string - i.e. disabled</i>
11901		 *
11902		 *  @dtopt Features
11903		 *  @name DataTable.defaults.scrollX
11904		 *
11905		 *  @example
11906		 *    $(document).ready( function() {
11907		 *      $('#example').dataTable( {
11908		 *        "scrollX": true,
11909		 *        "scrollCollapse": true
11910		 *      } );
11911		 *    } );
11912		 */
11913		"sScrollX": "",
11914	
11915	
11916		/**
11917		 * This property can be used to force a DataTable to use more width than it
11918		 * might otherwise do when x-scrolling is enabled. For example if you have a
11919		 * table which requires to be well spaced, this parameter is useful for
11920		 * "over-sizing" the table, and thus forcing scrolling. This property can by
11921		 * any CSS unit, or a number (in which case it will be treated as a pixel
11922		 * measurement).
11923		 *  @type string
11924		 *  @default <i>blank string - i.e. disabled</i>
11925		 *
11926		 *  @dtopt Options
11927		 *  @name DataTable.defaults.scrollXInner
11928		 *
11929		 *  @example
11930		 *    $(document).ready( function() {
11931		 *      $('#example').dataTable( {
11932		 *        "scrollX": "100%",
11933		 *        "scrollXInner": "110%"
11934		 *      } );
11935		 *    } );
11936		 */
11937		"sScrollXInner": "",
11938	
11939	
11940		/**
11941		 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
11942		 * to the given height, and enable scrolling for any data which overflows the
11943		 * current viewport. This can be used as an alternative to paging to display
11944		 * a lot of data in a small area (although paging and scrolling can both be
11945		 * enabled at the same time). This property can be any CSS unit, or a number
11946		 * (in which case it will be treated as a pixel measurement).
11947		 *  @type string
11948		 *  @default <i>blank string - i.e. disabled</i>
11949		 *
11950		 *  @dtopt Features
11951		 *  @name DataTable.defaults.scrollY
11952		 *
11953		 *  @example
11954		 *    $(document).ready( function() {
11955		 *      $('#example').dataTable( {
11956		 *        "scrollY": "200px",
11957		 *        "paginate": false
11958		 *      } );
11959		 *    } );
11960		 */
11961		"sScrollY": "",
11962	
11963	
11964		/**
11965		 * __Deprecated__ The functionality provided by this parameter has now been
11966		 * superseded by that provided through `ajax`, which should be used instead.
11967		 *
11968		 * Set the HTTP method that is used to make the Ajax call for server-side
11969		 * processing or Ajax sourced data.
11970		 *  @type string
11971		 *  @default GET
11972		 *
11973		 *  @dtopt Options
11974		 *  @dtopt Server-side
11975		 *  @name DataTable.defaults.serverMethod
11976		 *
11977		 *  @deprecated 1.10. Please use `ajax` for this functionality now.
11978		 */
11979		"sServerMethod": "GET",
11980	
11981	
11982		/**
11983		 * DataTables makes use of renderers when displaying HTML elements for
11984		 * a table. These renderers can be added or modified by plug-ins to
11985		 * generate suitable mark-up for a site. For example the Bootstrap
11986		 * integration plug-in for DataTables uses a paging button renderer to
11987		 * display pagination buttons in the mark-up required by Bootstrap.
11988		 *
11989		 * For further information about the renderers available see
11990		 * DataTable.ext.renderer
11991		 *  @type string|object
11992		 *  @default null
11993		 *
11994		 *  @name DataTable.defaults.renderer
11995		 *
11996		 */
11997		"renderer": null,
11998	
11999	
12000		/**
12001		 * Set the data property name that DataTables should use to get a row's id
12002		 * to set as the `id` property in the node.
12003		 *  @type string
12004		 *  @default DT_RowId
12005		 *
12006		 *  @name DataTable.defaults.rowId
12007		 */
12008		"rowId": "DT_RowId"
12009	};
12010	
12011	_fnHungarianMap( DataTable.defaults );
12012	
12013	
12014	
12015	/*
12016	 * Developer note - See note in model.defaults.js about the use of Hungarian
12017	 * notation and camel case.
12018	 */
12019	
12020	/**
12021	 * Column options that can be given to DataTables at initialisation time.
12022	 *  @namespace
12023	 */
12024	DataTable.defaults.column = {
12025		/**
12026		 * Define which column(s) an order will occur on for this column. This
12027		 * allows a column's ordering to take multiple columns into account when
12028		 * doing a sort or use the data from a different column. For example first
12029		 * name / last name columns make sense to do a multi-column sort over the
12030		 * two columns.
12031		 *  @type array|int
12032		 *  @default null <i>Takes the value of the column index automatically</i>
12033		 *
12034		 *  @name DataTable.defaults.column.orderData
12035		 *  @dtopt Columns
12036		 *
12037		 *  @example
12038		 *    // Using `columnDefs`
12039		 *    $(document).ready( function() {
12040		 *      $('#example').dataTable( {
12041		 *        "columnDefs": [
12042		 *          { "orderData": [ 0, 1 ], "targets": [ 0 ] },
12043		 *          { "orderData": [ 1, 0 ], "targets": [ 1 ] },
12044		 *          { "orderData": 2, "targets": [ 2 ] }
12045		 *        ]
12046		 *      } );
12047		 *    } );
12048		 *
12049		 *  @example
12050		 *    // Using `columns`
12051		 *    $(document).ready( function() {
12052		 *      $('#example').dataTable( {
12053		 *        "columns": [
12054		 *          { "orderData": [ 0, 1 ] },
12055		 *          { "orderData": [ 1, 0 ] },
12056		 *          { "orderData": 2 },
12057		 *          null,
12058		 *          null
12059		 *        ]
12060		 *      } );
12061		 *    } );
12062		 */
12063		"aDataSort": null,
12064		"iDataSort": -1,
12065	
12066	
12067		/**
12068		 * You can control the default ordering direction, and even alter the
12069		 * behaviour of the sort handler (i.e. only allow ascending ordering etc)
12070		 * using this parameter.
12071		 *  @type array
12072		 *  @default [ 'asc', 'desc' ]
12073		 *
12074		 *  @name DataTable.defaults.column.orderSequence
12075		 *  @dtopt Columns
12076		 *
12077		 *  @example
12078		 *    // Using `columnDefs`
12079		 *    $(document).ready( function() {
12080		 *      $('#example').dataTable( {
12081		 *        "columnDefs": [
12082		 *          { "orderSequence": [ "asc" ], "targets": [ 1 ] },
12083		 *          { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
12084		 *          { "orderSequence": [ "desc" ], "targets": [ 3 ] }
12085		 *        ]
12086		 *      } );
12087		 *    } );
12088		 *
12089		 *  @example
12090		 *    // Using `columns`
12091		 *    $(document).ready( function() {
12092		 *      $('#example').dataTable( {
12093		 *        "columns": [
12094		 *          null,
12095		 *          { "orderSequence": [ "asc" ] },
12096		 *          { "orderSequence": [ "desc", "asc", "asc" ] },
12097		 *          { "orderSequence": [ "desc" ] },
12098		 *          null
12099		 *        ]
12100		 *      } );
12101		 *    } );
12102		 */
12103		"asSorting": [ 'asc', 'desc' ],
12104	
12105	
12106		/**
12107		 * Enable or disable filtering on the data in this column.
12108		 *  @type boolean
12109		 *  @default true
12110		 *
12111		 *  @name DataTable.defaults.column.searchable
12112		 *  @dtopt Columns
12113		 *
12114		 *  @example
12115		 *    // Using `columnDefs`
12116		 *    $(document).ready( function() {
12117		 *      $('#example').dataTable( {
12118		 *        "columnDefs": [
12119		 *          { "searchable": false, "targets": [ 0 ] }
12120		 *        ] } );
12121		 *    } );
12122		 *
12123		 *  @example
12124		 *    // Using `columns`
12125		 *    $(document).ready( function() {
12126		 *      $('#example').dataTable( {
12127		 *        "columns": [
12128		 *          { "searchable": false },
12129		 *          null,
12130		 *          null,
12131		 *          null,
12132		 *          null
12133		 *        ] } );
12134		 *    } );
12135		 */
12136		"bSearchable": true,
12137	
12138	
12139		/**
12140		 * Enable or disable ordering on this column.
12141		 *  @type boolean
12142		 *  @default true
12143		 *
12144		 *  @name DataTable.defaults.column.orderable
12145		 *  @dtopt Columns
12146		 *
12147		 *  @example
12148		 *    // Using `columnDefs`
12149		 *    $(document).ready( function() {
12150		 *      $('#example').dataTable( {
12151		 *        "columnDefs": [
12152		 *          { "orderable": false, "targets": [ 0 ] }
12153		 *        ] } );
12154		 *    } );
12155		 *
12156		 *  @example
12157		 *    // Using `columns`
12158		 *    $(document).ready( function() {
12159		 *      $('#example').dataTable( {
12160		 *        "columns": [
12161		 *          { "orderable": false },
12162		 *          null,
12163		 *          null,
12164		 *          null,
12165		 *          null
12166		 *        ] } );
12167		 *    } );
12168		 */
12169		"bSortable": true,
12170	
12171	
12172		/**
12173		 * Enable or disable the display of this column.
12174		 *  @type boolean
12175		 *  @default true
12176		 *
12177		 *  @name DataTable.defaults.column.visible
12178		 *  @dtopt Columns
12179		 *
12180		 *  @example
12181		 *    // Using `columnDefs`
12182		 *    $(document).ready( function() {
12183		 *      $('#example').dataTable( {
12184		 *        "columnDefs": [
12185		 *          { "visible": false, "targets": [ 0 ] }
12186		 *        ] } );
12187		 *    } );
12188		 *
12189		 *  @example
12190		 *    // Using `columns`
12191		 *    $(document).ready( function() {
12192		 *      $('#example').dataTable( {
12193		 *        "columns": [
12194		 *          { "visible": false },
12195		 *          null,
12196		 *          null,
12197		 *          null,
12198		 *          null
12199		 *        ] } );
12200		 *    } );
12201		 */
12202		"bVisible": true,
12203	
12204	
12205		/**
12206		 * Developer definable function that is called whenever a cell is created (Ajax source,
12207		 * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12208		 * allowing you to modify the DOM element (add background colour for example) when the
12209		 * element is available.
12210		 *  @type function
12211		 *  @param {element} td The TD node that has been created
12212		 *  @param {*} cellData The Data for the cell
12213		 *  @param {array|object} rowData The data for the whole row
12214		 *  @param {int} row The row index for the aoData data store
12215		 *  @param {int} col The column index for aoColumns
12216		 *
12217		 *  @name DataTable.defaults.column.createdCell
12218		 *  @dtopt Columns
12219		 *
12220		 *  @example
12221		 *    $(document).ready( function() {
12222		 *      $('#example').dataTable( {
12223		 *        "columnDefs": [ {
12224		 *          "targets": [3],
12225		 *          "createdCell": function (td, cellData, rowData, row, col) {
12226		 *            if ( cellData == "1.7" ) {
12227		 *              $(td).css('color', 'blue')
12228		 *            }
12229		 *          }
12230		 *        } ]
12231		 *      });
12232		 *    } );
12233		 */
12234		"fnCreatedCell": null,
12235	
12236	
12237		/**
12238		 * This parameter has been replaced by `data` in DataTables to ensure naming
12239		 * consistency. `dataProp` can still be used, as there is backwards
12240		 * compatibility in DataTables for this option, but it is strongly
12241		 * recommended that you use `data` in preference to `dataProp`.
12242		 *  @name DataTable.defaults.column.dataProp
12243		 */
12244	
12245	
12246		/**
12247		 * This property can be used to read data from any data source property,
12248		 * including deeply nested objects / properties. `data` can be given in a
12249		 * number of different ways which effect its behaviour:
12250		 *
12251		 * * `integer` - treated as an array index for the data source. This is the
12252		 *   default that DataTables uses (incrementally increased for each column).
12253		 * * `string` - read an object property from the data source. There are
12254		 *   three 'special' options that can be used in the string to alter how
12255		 *   DataTables reads the data from the source object:
12256		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
12257		 *      Javascript to read from nested objects, so to can the options
12258		 *      specified in `data`. For example: `browser.version` or
12259		 *      `browser.name`. If your object parameter name contains a period, use
12260		 *      `\\` to escape it - i.e. `first\\.name`.
12261		 *    * `[]` - Array notation. DataTables can automatically combine data
12262		 *      from and array source, joining the data with the characters provided
12263		 *      between the two brackets. For example: `name[, ]` would provide a
12264		 *      comma-space separated list from the source array. If no characters
12265		 *      are provided between the brackets, the original array source is
12266		 *      returned.
12267		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
12268		 *      execute a function of the name given. For example: `browser()` for a
12269		 *      simple function on the data source, `browser.version()` for a
12270		 *      function in a nested property or even `browser().version` to get an
12271		 *      object property if the function called returns an object. Note that
12272		 *      function notation is recommended for use in `render` rather than
12273		 *      `data` as it is much simpler to use as a renderer.
12274		 * * `null` - use the original data source for the row rather than plucking
12275		 *   data directly from it. This action has effects on two other
12276		 *   initialisation options:
12277		 *    * `defaultContent` - When null is given as the `data` option and
12278		 *      `defaultContent` is specified for the column, the value defined by
12279		 *      `defaultContent` will be used for the cell.
12280		 *    * `render` - When null is used for the `data` option and the `render`
12281		 *      option is specified for the column, the whole data source for the
12282		 *      row is used for the renderer.
12283		 * * `function` - the function given will be executed whenever DataTables
12284		 *   needs to set or get the data for a cell in the column. The function
12285		 *   takes three parameters:
12286		 *    * Parameters:
12287		 *      * `{array|object}` The data source for the row
12288		 *      * `{string}` The type call data requested - this will be 'set' when
12289		 *        setting data or 'filter', 'display', 'type', 'sort' or undefined
12290		 *        when gathering data. Note that when `undefined` is given for the
12291		 *        type DataTables expects to get the raw data for the object back<
12292		 *      * `{*}` Data to set when the second parameter is 'set'.
12293		 *    * Return:
12294		 *      * The return value from the function is not required when 'set' is
12295		 *        the type of call, but otherwise the return is what will be used
12296		 *        for the data requested.
12297		 *
12298		 * Note that `data` is a getter and setter option. If you just require
12299		 * formatting of data for output, you will likely want to use `render` which
12300		 * is simply a getter and thus simpler to use.
12301		 *
12302		 * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12303		 * name change reflects the flexibility of this property and is consistent
12304		 * with the naming of mRender. If 'mDataProp' is given, then it will still
12305		 * be used by DataTables, as it automatically maps the old name to the new
12306		 * if required.
12307		 *
12308		 *  @type string|int|function|null
12309		 *  @default null <i>Use automatically calculated column index</i>
12310		 *
12311		 *  @name DataTable.defaults.column.data
12312		 *  @dtopt Columns
12313		 *
12314		 *  @example
12315		 *    // Read table data from objects
12316		 *    // JSON structure for each row:
12317		 *    //   {
12318		 *    //      "engine": {value},
12319		 *    //      "browser": {value},
12320		 *    //      "platform": {value},
12321		 *    //      "version": {value},
12322		 *    //      "grade": {value}
12323		 *    //   }
12324		 *    $(document).ready( function() {
12325		 *      $('#example').dataTable( {
12326		 *        "ajaxSource": "sources/objects.txt",
12327		 *        "columns": [
12328		 *          { "data": "engine" },
12329		 *          { "data": "browser" },
12330		 *          { "data": "platform" },
12331		 *          { "data": "version" },
12332		 *          { "data": "grade" }
12333		 *        ]
12334		 *      } );
12335		 *    } );
12336		 *
12337		 *  @example
12338		 *    // Read information from deeply nested objects
12339		 *    // JSON structure for each row:
12340		 *    //   {
12341		 *    //      "engine": {value},
12342		 *    //      "browser": {value},
12343		 *    //      "platform": {
12344		 *    //         "inner": {value}
12345		 *    //      },
12346		 *    //      "details": [
12347		 *    //         {value}, {value}
12348		 *    //      ]
12349		 *    //   }
12350		 *    $(document).ready( function() {
12351		 *      $('#example').dataTable( {
12352		 *        "ajaxSource": "sources/deep.txt",
12353		 *        "columns": [
12354		 *          { "data": "engine" },
12355		 *          { "data": "browser" },
12356		 *          { "data": "platform.inner" },
12357		 *          { "data": "
12357platform.details.0" },
12358		 *          { "data": "platform.details.1" }
12359		 *        ]
12360		 *      } );
12361		 *    } );
12362		 *
12363		 *  @example
12364		 *    // Using `data` as a function to provide different information for
12365		 *    // sorting, filtering and display. In this case, currency (price)
12366		 *    $(document).ready( function() {
12367		 *      $('#example').dataTable( {
12368		 *        "columnDefs": [ {
12369		 *          "targets": [ 0 ],
12370		 *          "data": function ( source, type, val ) {
12371		 *            if (type === 'set') {
12372		 *              source.price = val;
12373		 *              // Store the computed dis
vendor: 18,284 bytes, lines 12373-12922
12373lay and filter values for efficiency
12374		 *              source.price_display = val=="" ? "" : "$"+numberFormat(val);
12375		 *              source.price_filter  = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12376		 *              return;
12377		 *            }
12378		 *            else if (type === 'display') {
12379		 *              return source.price_display;
12380		 *            }
12381		 *            else if (type === 'filter') {
12382		 *              return source.price_filter;
12383		 *            }
12384		 *            // 'sort', 'type' and undefined all just use the integer
12385		 *            return source.price;
12386		 *          }
12387		 *        } ]
12388		 *      } );
12389		 *    } );
12390		 *
12391		 *  @example
12392		 *    // Using default content
12393		 *    $(document).ready( function() {
12394		 *      $('#example').dataTable( {
12395		 *        "columnDefs": [ {
12396		 *          "targets": [ 0 ],
12397		 *          "data": null,
12398		 *          "defaultContent": "Click to edit"
12399		 *        } ]
12400		 *      } );
12401		 *    } );
12402		 *
12403		 *  @example
12404		 *    // Using array notation - outputting a list from an array
12405		 *    $(document).ready( function() {
12406		 *      $('#example').dataTable( {
12407		 *        "columnDefs": [ {
12408		 *          "targets": [ 0 ],
12409		 *          "data": "name[, ]"
12410		 *        } ]
12411		 *      } );
12412		 *    } );
12413		 *
12414		 */
12415		"mData": null,
12416	
12417	
12418		/**
12419		 * This property is the rendering partner to `data` and it is suggested that
12420		 * when you want to manipulate data for display (including filtering,
12421		 * sorting etc) without altering the underlying data for the table, use this
12422		 * property. `render` can be considered to be the the read only companion to
12423		 * `data` which is read / write (then as such more complex). Like `data`
12424		 * this option can be given in a number of different ways to effect its
12425		 * behaviour:
12426		 *
12427		 * * `integer` - treated as an array index for the data source. This is the
12428		 *   default that DataTables uses (incrementally increased for each column).
12429		 * * `string` - read an object property from the data source. There are
12430		 *   three 'special' options that can be used in the string to alter how
12431		 *   DataTables reads the data from the source object:
12432		 *    * `.` - Dotted Javascript notation. Just as you use a `.` in
12433		 *      Javascript to read from nested objects, so to can the options
12434		 *      specified in `data`. For example: `browser.version` or
12435		 *      `browser.name`. If your object parameter name contains a period, use
12436		 *      `\\` to escape it - i.e. `first\\.name`.
12437		 *    * `[]` - Array notation. DataTables can automatically combine data
12438		 *      from and array source, joining the data with the characters provided
12439		 *      between the two brackets. For example: `name[, ]` would provide a
12440		 *      comma-space separated list from the source array. If no characters
12441		 *      are provided between the brackets, the original array source is
12442		 *      returned.
12443		 *    * `()` - Function notation. Adding `()` to the end of a parameter will
12444		 *      execute a function of the name given. For example: `browser()` for a
12445		 *      simple function on the data source, `browser.version()` for a
12446		 *      function in a nested property or even `browser().version` to get an
12447		 *      object property if the function called returns an object.
12448		 * * `object` - use different data for the different data types requested by
12449		 *   DataTables ('filter', 'display', 'type' or 'sort'). The property names
12450		 *   of the object is the data type the property refers to and the value can
12451		 *   defined using an integer, string or function using the same rules as
12452		 *   `render` normally does. Note that an `_` option _must_ be specified.
12453		 *   This is the default value to use if you haven't specified a value for
12454		 *   the data type requested by DataTables.
12455		 * * `function` - the function given will be executed whenever DataTables
12456		 *   needs to set or get the data for a cell in the column. The function
12457		 *   takes three parameters:
12458		 *    * Parameters:
12459		 *      * {array|object} The data source for the row (based on `data`)
12460		 *      * {string} The type call data requested - this will be 'filter',
12461		 *        'display', 'type' or 'sort'.
12462		 *      * {array|object} The full data source for the row (not based on
12463		 *        `data`)
12464		 *    * Return:
12465		 *      * The return value from the function is what will be used for the
12466		 *        data requested.
12467		 *
12468		 *  @type string|int|function|object|null
12469		 *  @default null Use the data source value.
12470		 *
12471		 *  @name DataTable.defaults.column.render
12472		 *  @dtopt Columns
12473		 *
12474		 *  @example
12475		 *    // Create a comma separated list from an array of objects
12476		 *    $(document).ready( function() {
12477		 *      $('#example').dataTable( {
12478		 *        "ajaxSource": "sources/deep.txt",
12479		 *        "columns": [
12480		 *          { "data": "engine" },
12481		 *          { "data": "browser" },
12482		 *          {
12483		 *            "data": "platform",
12484		 *            "render": "[, ].name"
12485		 *          }
12486		 *        ]
12487		 *      } );
12488		 *    } );
12489		 *
12490		 *  @example
12491		 *    // Execute a function to obtain data
12492		 *    $(document).ready( function() {
12493		 *      $('#example').dataTable( {
12494		 *        "columnDefs": [ {
12495		 *          "targets": [ 0 ],
12496		 *          "data": null, // Use the full data source object for the renderer's source
12497		 *          "render": "browserName()"
12498		 *        } ]
12499		 *      } );
12500		 *    } );
12501		 *
12502		 *  @example
12503		 *    // As an object, extracting different data for the different types
12504		 *    // This would be used with a data source such as:
12505		 *    //   { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12506		 *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12507		 *    // (which has both forms) is used for filtering for if a user inputs either format, while
12508		 *    // the formatted phone number is the one that is shown in the table.
12509		 *    $(document).ready( function() {
12510		 *      $('#example').dataTable( {
12511		 *        "columnDefs": [ {
12512		 *          "targets": [ 0 ],
12513		 *          "data": null, // Use the full data source object for the renderer's source
12514		 *          "render": {
12515		 *            "_": "phone",
12516		 *            "filter": "phone_filter",
12517		 *            "display": "phone_display"
12518		 *          }
12519		 *        } ]
12520		 *      } );
12521		 *    } );
12522		 *
12523		 *  @example
12524		 *    // Use as a function to create a link from the data source
12525		 *    $(document).ready( function() {
12526		 *      $('#example').dataTable( {
12527		 *        "columnDefs": [ {
12528		 *          "targets": [ 0 ],
12529		 *          "data": "download_link",
12530		 *          "render": function ( data, type, full ) {
12531		 *            return '<a href="'+data+'">Download</a>';
12532		 *          }
12533		 *        } ]
12534		 *      } );
12535		 *    } );
12536		 */
12537		"mRender": null,
12538	
12539	
12540		/**
12541		 * Change the cell type created for the column - either TD cells or TH cells. This
12542		 * can be useful as TH cells have semantic meaning in the table body, allowing them
12543		 * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12544		 *  @type string
12545		 *  @default td
12546		 *
12547		 *  @name DataTable.defaults.column.cellType
12548		 *  @dtopt Columns
12549		 *
12550		 *  @example
12551		 *    // Make the first column use TH cells
12552		 *    $(document).ready( function() {
12553		 *      $('#example').dataTable( {
12554		 *        "columnDefs": [ {
12555		 *          "targets": [ 0 ],
12556		 *          "cellType": "th"
12557		 *        } ]
12558		 *      } );
12559		 *    } );
12560		 */
12561		"sCellType": "td",
12562	
12563	
12564		/**
12565		 * Class to give to each cell in this column.
12566		 *  @type string
12567		 *  @default <i>Empty string</i>
12568		 *
12569		 *  @name DataTable.defaults.column.class
12570		 *  @dtopt Columns
12571		 *
12572		 *  @example
12573		 *    // Using `columnDefs`
12574		 *    $(document).ready( function() {
12575		 *      $('#example').dataTable( {
12576		 *        "columnDefs": [
12577		 *          { "class": "my_class", "targets": [ 0 ] }
12578		 *        ]
12579		 *      } );
12580		 *    } );
12581		 *
12582		 *  @example
12583		 *    // Using `columns`
12584		 *    $(document).ready( function() {
12585		 *      $('#example').dataTable( {
12586		 *        "columns": [
12587		 *          { "class": "my_class" },
12588		 *          null,
12589		 *          null,
12590		 *          null,
12591		 *          null
12592		 *        ]
12593		 *      } );
12594		 *    } );
12595		 */
12596		"sClass": "",
12597	
12598		/**
12599		 * When DataTables calculates the column widths to assign to each column,
12600		 * it finds the longest string in each column and then constructs a
12601		 * temporary table and reads the widths from that. The problem with this
12602		 * is that "mmm" is much wider then "iiii", but the latter is a longer
12603		 * string - thus the calculation can go wrong (doing it properly and putting
12604		 * it into an DOM object and measuring that is horribly(!) slow). Thus as
12605		 * a "work around" we provide this option. It will append its value to the
12606		 * text that is found to be the longest string for the column - i.e. padding.
12607		 * Generally you shouldn't need this!
12608		 *  @type string
12609		 *  @default <i>Empty string<i>
12610		 *
12611		 *  @name DataTable.defaults.column.contentPadding
12612		 *  @dtopt Columns
12613		 *
12614		 *  @example
12615		 *    // Using `columns`
12616		 *    $(document).ready( function() {
12617		 *      $('#example').dataTable( {
12618		 *        "columns": [
12619		 *          null,
12620		 *          null,
12621		 *          null,
12622		 *          {
12623		 *            "contentPadding": "mmm"
12624		 *          }
12625		 *        ]
12626		 *      } );
12627		 *    } );
12628		 */
12629		"sContentPadding": "",
12630	
12631	
12632		/**
12633		 * Allows a default value to be given for a column's data, and will be used
12634		 * whenever a null data source is encountered (this can be because `data`
12635		 * is set to null, or because the data source itself is null).
12636		 *  @type string
12637		 *  @default null
12638		 *
12639		 *  @name DataTable.defaults.column.defaultContent
12640		 *  @dtopt Columns
12641		 *
12642		 *  @example
12643		 *    // Using `columnDefs`
12644		 *    $(document).ready( function() {
12645		 *      $('#example').dataTable( {
12646		 *        "columnDefs": [
12647		 *          {
12648		 *            "data": null,
12649		 *            "defaultContent": "Edit",
12650		 *            "targets": [ -1 ]
12651		 *          }
12652		 *        ]
12653		 *      } );
12654		 *    } );
12655		 *
12656		 *  @example
12657		 *    // Using `columns`
12658		 *    $(document).ready( function() {
12659		 *      $('#example').dataTable( {
12660		 *        "columns": [
12661		 *          null,
12662		 *          null,
12663		 *          null,
12664		 *          {
12665		 *            "data": null,
12666		 *            "defaultContent": "Edit"
12667		 *          }
12668		 *        ]
12669		 *      } );
12670		 *    } );
12671		 */
12672		"sDefaultContent": null,
12673	
12674	
12675		/**
12676		 * This parameter is only used in DataTables' server-side processing. It can
12677		 * be exceptionally useful to know what columns are being displayed on the
12678		 * client side, and to map these to database fields. When defined, the names
12679		 * also allow DataTables to reorder information from the server if it comes
12680		 * back in an unexpected order (i.e. if you switch your columns around on the
12681		 * client-side, your server-side code does not also need updating).
12682		 *  @type string
12683		 *  @default <i>Empty string</i>
12684		 *
12685		 *  @name DataTable.defaults.column.name
12686		 *  @dtopt Columns
12687		 *
12688		 *  @example
12689		 *    // Using `columnDefs`
12690		 *    $(document).ready( function() {
12691		 *      $('#example').dataTable( {
12692		 *        "columnDefs": [
12693		 *          { "name": "engine", "targets": [ 0 ] },
12694		 *          { "name": "browser", "targets": [ 1 ] },
12695		 *          { "name": "platform", "targets": [ 2 ] },
12696		 *          { "name": "version", "targets": [ 3 ] },
12697		 *          { "name": "grade", "targets": [ 4 ] }
12698		 *        ]
12699		 *      } );
12700		 *    } );
12701		 *
12702		 *  @example
12703		 *    // Using `columns`
12704		 *    $(document).ready( function() {
12705		 *      $('#example').dataTable( {
12706		 *        "columns": [
12707		 *          { "name": "engine" },
12708		 *          { "name": "browser" },
12709		 *          { "name": "platform" },
12710		 *          { "name": "version" },
12711		 *          { "name": "grade" }
12712		 *        ]
12713		 *      } );
12714		 *    } );
12715		 */
12716		"sName": "",
12717	
12718	
12719		/**
12720		 * Defines a data source type for the ordering which can be used to read
12721		 * real-time information from the table (updating the internally cached
12722		 * version) prior to ordering. This allows ordering to occur on user
12723		 * editable elements such as form inputs.
12724		 *  @type string
12725		 *  @default std
12726		 *
12727		 *  @name DataTable.defaults.column.orderDataType
12728		 *  @dtopt Columns
12729		 *
12730		 *  @example
12731		 *    // Using `columnDefs`
12732		 *    $(document).ready( function() {
12733		 *      $('#example').dataTable( {
12734		 *        "columnDefs": [
12735		 *          { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12736		 *          { "type": "numeric", "targets": [ 3 ] },
12737		 *          { "orderDataType": "dom-select", "targets": [ 4 ] },
12738		 *          { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12739		 *        ]
12740		 *      } );
12741		 *    } );
12742		 *
12743		 *  @example
12744		 *    // Using `columns`
12745		 *    $(document).ready( function() {
12746		 *      $('#example').dataTable( {
12747		 *        "columns": [
12748		 *          null,
12749		 *          null,
12750		 *          { "orderDataType": "dom-text" },
12751		 *          { "orderDataType": "dom-text", "type": "numeric" },
12752		 *          { "orderDataType": "dom-select" },
12753		 *          { "orderDataType": "dom-checkbox" }
12754		 *        ]
12755		 *      } );
12756		 *    } );
12757		 */
12758		"sSortDataType": "std",
12759	
12760	
12761		/**
12762		 * The title of this column.
12763		 *  @type string
12764		 *  @default null <i>Derived from the 'TH' value for this column in the
12765		 *    original HTML table.</i>
12766		 *
12767		 *  @name DataTable.defaults.column.title
12768		 *  @dtopt Columns
12769		 *
12770		 *  @example
12771		 *    // Using `columnDefs`
12772		 *    $(document).ready( function() {
12773		 *      $('#example').dataTable( {
12774		 *        "columnDefs": [
12775		 *          { "title": "My column title", "targets": [ 0 ] }
12776		 *        ]
12777		 *      } );
12778		 *    } );
12779		 *
12780		 *  @example
12781		 *    // Using `columns`
12782		 *    $(document).ready( function() {
12783		 *      $('#example').dataTable( {
12784		 *        "columns": [
12785		 *          { "title": "My column title" },
12786		 *          null,
12787		 *          null,
12788		 *          null,
12789		 *          null
12790		 *        ]
12791		 *      } );
12792		 *    } );
12793		 */
12794		"sTitle": null,
12795	
12796	
12797		/**
12798		 * The type allows you to specify how the data for this column will be
12799		 * ordered. Four types (string, numeric, date and html (which will strip
12800		 * HTML tags before ordering)) are currently available. Note that only date
12801		 * formats understood by Javascript's Date() object will be accepted as type
12802		 * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12803		 * 'numeric', 'date' or 'html' (by default). Further types can be adding
12804		 * through plug-ins.
12805		 *  @type string
12806		 *  @default null <i>Auto-detected from raw data</i>
12807		 *
12808		 *  @name DataTable.defaults.column.type
12809		 *  @dtopt Columns
12810		 *
12811		 *  @example
12812		 *    // Using `columnDefs`
12813		 *    $(document).ready( function() {
12814		 *      $('#example').dataTable( {
12815		 *        "columnDefs": [
12816		 *          { "type": "html", "targets": [ 0 ] }
12817		 *        ]
12818		 *      } );
12819		 *    } );
12820		 *
12821		 *  @example
12822		 *    // Using `columns`
12823		 *    $(document).ready( function() {
12824		 *      $('#example').dataTable( {
12825		 *        "columns": [
12826		 *          { "type": "html" },
12827		 *          null,
12828		 *          null,
12829		 *          null,
12830		 *          null
12831		 *        ]
12832		 *      } );
12833		 *    } );
12834		 */
12835		"sType": null,
12836	
12837	
12838		/**
12839		 * Defining the width of the column, this parameter may take any CSS value
12840		 * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12841		 * been given a specific width through this interface ensuring that the table
12842		 * remains readable.
12843		 *  @type string
12844		 *  @default null <i>Automatic</i>
12845		 *
12846		 *  @name DataTable.defaults.column.width
12847		 *  @dtopt Columns
12848		 *
12849		 *  @example
12850		 *    // Using `columnDefs`
12851		 *    $(document).ready( function() {
12852		 *      $('#example').dataTable( {
12853		 *        "columnDefs": [
12854		 *          { "width": "20%", "targets": [ 0 ] }
12855		 *        ]
12856		 *      } );
12857		 *    } );
12858		 *
12859		 *  @example
12860		 *    // Using `columns`
12861		 *    $(document).ready( function() {
12862		 *      $('#example').dataTable( {
12863		 *        "columns": [
12864		 *          { "width": "20%" },
12865		 *          null,
12866		 *          null,
12867		 *          null,
12868		 *          null
12869		 *        ]
12870		 *      } );
12871		 *    } );
12872		 */
12873		"sWidth": null
12874	};
12875	
12876	_fnHungarianMap( DataTable.defaults.column );
12877	
12878	
12879	
12880	/**
12881	 * DataTables settings object - this holds all the information needed for a
12882	 * given table, including configuration, data and current application of the
12883	 * table options. DataTables does not have a single instance for each DataTable
12884	 * with the settings attached to that instance, but rather instances of the
12885	 * DataTable "class" are created on-the-fly as needed (typically by a
12886	 * $().dataTable() call) and the settings object is then applied to that
12887	 * instance.
12888	 *
12889	 * Note that this object is related to {@link DataTable.defaults} but this
12890	 * one is the internal data store for DataTables's cache of columns. It should
12891	 * NOT be manipulated outside of DataTables. Any configuration should be done
12892	 * through the initialisation options.
12893	 *  @namespace
12894	 *  @todo Really should attach the settings object to individual instances so we
12895	 *    don't need to create new instances on each $().dataTable() call (if the
12896	 *    table already exists). It would also save passing oSettings around and
12897	 *    into every single function. However, this is a very significant
12898	 *    architecture change for DataTables and will almost certainly break
12899	 *    backwards compatibility with older installations. This is something that
12900	 *    will be done in 2.0.
12901	 */
12902	DataTable.models.oSettings = {
12903		/**
12904		 * Primary features of DataTables and their enablement state.
12905		 *  @namespace
12906		 */
12907		"oFeatures": {
12908	
12909			/**
12910			 * Flag to say if DataTables should automatically try to calculate the
12911			 * optimum table and columns widths (true) or not (false).
12912			 * Note that this parameter will be set by the initialisation routine. To
12913			 * set a default use {@link DataTable.defaults}.
12914			 *  @type boolean
12915			 */
12916			"bAutoWidth": null,
12917	
12918			/**
12919			 * Delay the creation of TR and TD elements until they are actually
12920			 * needed by a driven page draw. This can give a significant speed
12921			 * increase for Ajax source and Javascript source data, but makes no
12922			 * difference at all f
12922ro
vendor: 14,836 bytes, lines 12922-13499
12922 DOM and server-side processing tables.
12923			 * Note that this parameter will be set by the initialisation routine. To
12924			 * set a default use {@link DataTable.defaults}.
12925			 *  @type boolean
12926			 */
12927			"bDeferRender": null,
12928	
12929			/**
12930			 * Enable filtering on the table or not. Note that if this is disabled
12931			 * then there is no filtering at all on the table, including fnFilter.
12932			 * To just remove the filtering input use sDom and remove the 'f' option.
12933			 * Note that this parameter will be set by the initialisation routine. To
12934			 * set a default use {@link DataTable.defaults}.
12935			 *  @type boolean
12936			 */
12937			"bFilter": null,
12938	
12939			/**
12940			 * Table information element (the 'Showing x of y records' div) enable
12941			 * flag.
12942			 * Note that this parameter will be set by the initialisation routine. To
12943			 * set a default use {@link DataTable.defaults}.
12944			 *  @type boolean
12945			 */
12946			"bInfo": null,
12947	
12948			/**
12949			 * Present a user control allowing the end user to change the page size
12950			 * when pagination is enabled.
12951			 * Note that this parameter will be set by the initialisation routine. To
12952			 * set a default use {@link DataTable.defaults}.
12953			 *  @type boolean
12954			 */
12955			"bLengthChange": null,
12956	
12957			/**
12958			 * Pagination enabled or not. Note that if this is disabled then length
12959			 * changing must also be disabled.
12960			 * Note that this parameter will be set by the initialisation routine. To
12961			 * set a default use {@link DataTable.defaults}.
12962			 *  @type boolean
12963			 */
12964			"bPaginate": null,
12965	
12966			/**
12967			 * Processing indicator enable flag whenever DataTables is enacting a
12968			 * user request - typically an Ajax request for server-side processing.
12969			 * Note that this parameter will be set by the initialisation routine. To
12970			 * set a default use {@link DataTable.defaults}.
12971			 *  @type boolean
12972			 */
12973			"bProcessing": null,
12974	
12975			/**
12976			 * Server-side processing enabled flag - when enabled DataTables will
12977			 * get all data from the server for every draw - there is no filtering,
12978			 * sorting or paging done on the client-side.
12979			 * Note that this parameter will be set by the initialisation routine. To
12980			 * set a default use {@link DataTable.defaults}.
12981			 *  @type boolean
12982			 */
12983			"bServerSide": null,
12984	
12985			/**
12986			 * Sorting enablement flag.
12987			 * Note that this parameter will be set by the initialisation routine. To
12988			 * set a default use {@link DataTable.defaults}.
12989			 *  @type boolean
12990			 */
12991			"bSort": null,
12992	
12993			/**
12994			 * Multi-column sorting
12995			 * Note that this parameter will be set by the initialisation routine. To
12996			 * set a default use {@link DataTable.defaults}.
12997			 *  @type boolean
12998			 */
12999			"bSortMulti": null,
13000	
13001			/**
13002			 * Apply a class to the columns which are being sorted to provide a
13003			 * visual highlight or not. This can slow things down when enabled since
13004			 * there is a lot of DOM interaction.
13005			 * Note that this parameter will be set by the initialisation routine. To
13006			 * set a default use {@link DataTable.defaults}.
13007			 *  @type boolean
13008			 */
13009			"bSortClasses": null,
13010	
13011			/**
13012			 * State saving enablement flag.
13013			 * Note that this parameter will be set by the initialisation routine. To
13014			 * set a default use {@link DataTable.defaults}.
13015			 *  @type boolean
13016			 */
13017			"bStateSave": null
13018		},
13019	
13020	
13021		/**
13022		 * Scrolling settings for a table.
13023		 *  @namespace
13024		 */
13025		"oScroll": {
13026			/**
13027			 * When the table is shorter in height than sScrollY, collapse the
13028			 * table container down to the height of the table (when true).
13029			 * Note that this parameter will be set by the initialisation routine. To
13030			 * set a default use {@link DataTable.defaults}.
13031			 *  @type boolean
13032			 */
13033			"bCollapse": null,
13034	
13035			/**
13036			 * Width of the scrollbar for the web-browser's platform. Calculated
13037			 * during table initialisation.
13038			 *  @type int
13039			 *  @default 0
13040			 */
13041			"iBarWidth": 0,
13042	
13043			/**
13044			 * Viewport width for horizontal scrolling. Horizontal scrolling is
13045			 * disabled if an empty string.
13046			 * Note that this parameter will be set by the initialisation routine. To
13047			 * set a default use {@link DataTable.defaults}.
13048			 *  @type string
13049			 */
13050			"sX": null,
13051	
13052			/**
13053			 * Width to expand the table to when using x-scrolling. Typically you
13054			 * should not need to use this.
13055			 * Note that this parameter will be set by the initialisation routine. To
13056			 * set a default use {@link DataTable.defaults}.
13057			 *  @type string
13058			 *  @deprecated
13059			 */
13060			"sXInner": null,
13061	
13062			/**
13063			 * Viewport height for vertical scrolling. Vertical scrolling is disabled
13064			 * if an empty string.
13065			 * Note that this parameter will be set by the initialisation routine. To
13066			 * set a default use {@link DataTable.defaults}.
13067			 *  @type string
13068			 */
13069			"sY": null
13070		},
13071	
13072		/**
13073		 * Language information for the table.
13074		 *  @namespace
13075		 *  @extends DataTable.defaults.oLanguage
13076		 */
13077		"oLanguage": {
13078			/**
13079			 * Information callback function. See
13080			 * {@link DataTable.defaults.fnInfoCallback}
13081			 *  @type function
13082			 *  @default null
13083			 */
13084			"fnInfoCallback": null
13085		},
13086	
13087		/**
13088		 * Browser support parameters
13089		 *  @namespace
13090		 */
13091		"oBrowser": {
13092			/**
13093			 * Indicate if the browser incorrectly calculates width:100% inside a
13094			 * scrolling element (IE6/7)
13095			 *  @type boolean
13096			 *  @default false
13097			 */
13098			"bScrollOversize": false,
13099	
13100			/**
13101			 * Determine if the vertical scrollbar is on the right or left of the
13102			 * scrolling container - needed for rtl language layout, although not
13103			 * all browsers move the scrollbar (Safari).
13104			 *  @type boolean
13105			 *  @default false
13106			 */
13107			"bScrollbarLeft": false,
13108	
13109			/**
13110			 * Flag for if `getBoundingClientRect` is fully supported or not
13111			 *  @type boolean
13112			 *  @default false
13113			 */
13114			"bBounding": false,
13115	
13116			/**
13117			 * Browser scrollbar width
13118			 *  @type integer
13119			 *  @default 0
13120			 */
13121			"barWidth": 0
13122		},
13123	
13124	
13125		"ajax": null,
13126	
13127	
13128		/**
13129		 * Array referencing the nodes which are used for the features. The
13130		 * parameters of this object match what is allowed by sDom - i.e.
13131		 *   <ul>
13132		 *     <li>'l' - Length changing</li>
13133		 *     <li>'f' - Filtering input</li>
13134		 *     <li>'t' - The table!</li>
13135		 *     <li>'i' - Information</li>
13136		 *     <li>'p' - Pagination</li>
13137		 *     <li>'r' - pRocessing</li>
13138		 *   </ul>
13139		 *  @type array
13140		 *  @default []
13141		 */
13142		"aanFeatures": [],
13143	
13144		/**
13145		 * Store data information - see {@link DataTable.models.oRow} for detailed
13146		 * information.
13147		 *  @type array
13148		 *  @default []
13149		 */
13150		"aoData": [],
13151	
13152		/**
13153		 * Array of indexes which are in the current display (after filtering etc)
13154		 *  @type array
13155		 *  @default []
13156		 */
13157		"aiDisplay": [],
13158	
13159		/**
13160		 * Array of indexes for display - no filtering
13161		 *  @type array
13162		 *  @default []
13163		 */
13164		"aiDisplayMaster": [],
13165	
13166		/**
13167		 * Map of row ids to data indexes
13168		 *  @type object
13169		 *  @default {}
13170		 */
13171		"aIds": {},
13172	
13173		/**
13174		 * Store information about each column that is in use
13175		 *  @type array
13176		 *  @default []
13177		 */
13178		"aoColumns": [],
13179	
13180		/**
13181		 * Store information about the table's header
13182		 *  @type array
13183		 *  @default []
13184		 */
13185		"aoHeader": [],
13186	
13187		/**
13188		 * Store information about the table's footer
13189		 *  @type array
13190		 *  @default []
13191		 */
13192		"aoFooter": [],
13193	
13194		/**
13195		 * Store the applied global search information in case we want to force a
13196		 * research or compare the old search to a new one.
13197		 * Note that this parameter will be set by the initialisation routine. To
13198		 * set a default use {@link DataTable.defaults}.
13199		 *  @namespace
13200		 *  @extends DataTable.models.oSearch
13201		 */
13202		"oPreviousSearch": {},
13203	
13204		/**
13205		 * Store the applied search for each column - see
13206		 * {@link DataTable.models.oSearch} for the format that is used for the
13207		 * filtering information for each column.
13208		 *  @type array
13209		 *  @default []
13210		 */
13211		"aoPreSearchCols": [],
13212	
13213		/**
13214		 * Sorting that is applied to the table. Note that the inner arrays are
13215		 * used in the following manner:
13216		 * <ul>
13217		 *   <li>Index 0 - column number</li>
13218		 *   <li>Index 1 - current sorting direction</li>
13219		 * </ul>
13220		 * Note that this parameter will be set by the initialisation routine. To
13221		 * set a default use {@link DataTable.defaults}.
13222		 *  @type array
13223		 *  @todo These inner arrays should really be objects
13224		 */
13225		"aaSorting": null,
13226	
13227		/**
13228		 * Sorting that is always applied to the table (i.e. prefixed in front of
13229		 * aaSorting).
13230		 * Note that this parameter will be set by the initialisation routine. To
13231		 * set a default use {@link DataTable.defaults}.
13232		 *  @type array
13233		 *  @default []
13234		 */
13235		"aaSortingFixed": [],
13236	
13237		/**
13238		 * Classes to use for the striping of a table.
13239		 * Note that this parameter will be set by the initialisation routine. To
13240		 * set a default use {@link DataTable.defaults}.
13241		 *  @type array
13242		 *  @default []
13243		 */
13244		"asStripeClasses": null,
13245	
13246		/**
13247		 * If restoring a table - we should restore its striping classes as well
13248		 *  @type array
13249		 *  @default []
13250		 */
13251		"asDestroyStripes": [],
13252	
13253		/**
13254		 * If restoring a table - we should restore its width
13255		 *  @type int
13256		 *  @default 0
13257		 */
13258		"sDestroyWidth": 0,
13259	
13260		/**
13261		 * Callback functions array for every time a row is inserted (i.e. on a draw).
13262		 *  @type array
13263		 *  @default []
13264		 */
13265		"aoRowCallback": [],
13266	
13267		/**
13268		 * Callback functions for the header on each draw.
13269		 *  @type array
13270		 *  @default []
13271		 */
13272		"aoHeaderCallback": [],
13273	
13274		/**
13275		 * Callback function for the footer on each draw.
13276		 *  @type array
13277		 *  @default []
13278		 */
13279		"aoFooterCallback": [],
13280	
13281		/**
13282		 * Array of callback functions for draw callback functions
13283		 *  @type array
13284		 *  @default []
13285		 */
13286		"aoDrawCallback": [],
13287	
13288		/**
13289		 * Array of callback functions for row created function
13290		 *  @type array
13291		 *  @default []
13292		 */
13293		"aoRowCreatedCallback": [],
13294	
13295		/**
13296		 * Callback functions for just before the table is redrawn. A return of
13297		 * false will be used to cancel the draw.
13298		 *  @type array
13299		 *  @default []
13300		 */
13301		"aoPreDrawCallback": [],
13302	
13303		/**
13304		 * Callback functions for when the table has been initialised.
13305		 *  @type array
13306		 *  @default []
13307		 */
13308		"aoInitComplete": [],
13309	
13310	
13311		/**
13312		 * Callbacks for modifying the settings to be stored for state saving, prior to
13313		 * saving state.
13314		 *  @type array
13315		 *  @default []
13316		 */
13317		"aoStateSaveParams": [],
13318	
13319		/**
13320		 * Callbacks for modifying the settings that have been stored for state saving
13321		 * prior to using the stored values to restore the state.
13322		 *  @type array
13323		 *  @default []
13324		 */
13325		"aoStateLoadParams": [],
13326	
13327		/**
13328		 * Callbacks for operating on the settings object once the saved state has been
13329		 * loaded
13330		 *  @type array
13331		 *  @default []
13332		 */
13333		"aoStateLoaded": [],
13334	
13335		/**
13336		 * Cache the table ID for quick access
13337		 *  @type string
13338		 *  @default <i>Empty string</i>
13339		 */
13340		"sTableId": "",
13341	
13342		/**
13343		 * The TABLE node for the main table
13344		 *  @type node
13345		 *  @default null
13346		 */
13347		"nTable": null,
13348	
13349		/**
13350		 * Permanent ref to the thead element
13351		 *  @type node
13352		 *  @default null
13353		 */
13354		"nTHead": null,
13355	
13356		/**
13357		 * Permanent ref to the tfoot element - if it exists
13358		 *  @type node
13359		 *  @default null
13360		 */
13361		"nTFoot": null,
13362	
13363		/**
13364		 * Permanent ref to the tbody element
13365		 *  @type node
13366		 *  @default null
13367		 */
13368		"nTBody": null,
13369	
13370		/**
13371		 * Cache the wrapper node (contains all DataTables controlled elements)
13372		 *  @type node
13373		 *  @default null
13374		 */
13375		"nTableWrapper": null,
13376	
13377		/**
13378		 * Indicate if when using server-side processing the loading of data
13379		 * should be deferred until the second draw.
13380		 * Note that this parameter will be set by the initialisation routine. To
13381		 * set a default use {@link DataTable.defaults}.
13382		 *  @type boolean
13383		 *  @default false
13384		 */
13385		"bDeferLoading": false,
13386	
13387		/**
13388		 * Indicate if all required information has been read in
13389		 *  @type boolean
13390		 *  @default false
13391		 */
13392		"bInitialised": false,
13393	
13394		/**
13395		 * Information about open rows. Each object in the array has the parameters
13396		 * 'nTr' and 'nParent'
13397		 *  @type array
13398		 *  @default []
13399		 */
13400		"aoOpenRows": [],
13401	
13402		/**
13403		 * Dictate the positioning of DataTables' control elements - see
13404		 * {@link DataTable.model.oInit.sDom}.
13405		 * Note that this parameter will be set by the initialisation routine. To
13406		 * set a default use {@link DataTable.defaults}.
13407		 *  @type string
13408		 *  @default null
13409		 */
13410		"sDom": null,
13411	
13412		/**
13413		 * Search delay (in mS)
13414		 *  @type integer
13415		 *  @default null
13416		 */
13417		"searchDelay": null,
13418	
13419		/**
13420		 * Which type of pagination should be used.
13421		 * Note that this parameter will be set by the initialisation routine. To
13422		 * set a default use {@link DataTable.defaults}.
13423		 *  @type string
13424		 *  @default two_button
13425		 */
13426		"sPaginationType": "two_button",
13427	
13428		/**
13429		 * The state duration (for `stateSave`) in seconds.
13430		 * Note that this parameter will be set by the initialisation routine. To
13431		 * set a default use {@link DataTable.defaults}.
13432		 *  @type int
13433		 *  @default 0
13434		 */
13435		"iStateDuration": 0,
13436	
13437		/**
13438		 * Array of callback functions for state saving. Each array element is an
13439		 * object with the following parameters:
13440		 *   <ul>
13441		 *     <li>function:fn - function to call. Takes two parameters, oSettings
13442		 *       and the JSON string to save that has been thus far created. Returns
13443		 *       a JSON string to be inserted into a json object
13444		 *       (i.e. '"param": [ 0, 1, 2]')</li>
13445		 *     <li>string:sName - name of callback</li>
13446		 *   </ul>
13447		 *  @type array
13448		 *  @default []
13449		 */
13450		"aoStateSave": [],
13451	
13452		/**
13453		 * Array of callback functions for state loading. Each array element is an
13454		 * object with the following parameters:
13455		 *   <ul>
13456		 *     <li>function:fn - function to call. Takes two parameters, oSettings
13457		 *       and the object stored. May return false to cancel state loading</li>
13458		 *     <li>string:sName - name of callback</li>
13459		 *   </ul>
13460		 *  @type array
13461		 *  @default []
13462		 */
13463		"aoStateLoad": [],
13464	
13465		/**
13466		 * State that was saved. Useful for back reference
13467		 *  @type object
13468		 *  @default null
13469		 */
13470		"oSavedState": null,
13471	
13472		/**
13473		 * State that was loaded. Useful for back reference
13474		 *  @type object
13475		 *  @default null
13476		 */
13477		"oLoadedState": null,
13478	
13479		/**
13480		 * Source url for AJAX data for the table.
13481		 * Note that this parameter will be set by the initialisation routine. To
13482		 * set a default use {@link DataTable.defaults}.
13483		 *  @type string
13484		 *  @default null
13485		 */
13486		"sAjaxSource": null,
13487	
13488		/**
13489		 * Property from a given object from which to read the table data from. This
13490		 * can be an empty string (when not server-side processing), in which case
13491		 * it is  assumed an an array is given directly.
13492		 * Note that this parameter will be set by the initialisation routine. To
13493		 * set a default use {@link DataTable.defaults}.
13494		 *  @type string
13495		 */
13496		"sAjaxDataProp": null,
13497	
13498		/**
13499		 * 
13499Note if draw should be blocked while getting data
13500		 *  @type boolean
13501		 *  @default true
13502		 */
13503		"bAjaxDataGet": true,
13504	
13505		/**
13506		 * The last jQuery XHR object that was used for server-side data gathering.
13507		 * This can be used for working with the XHR information in one of the
13508		 * callbacks
13509		 *  @type object
13510		 *  @default null
13511		 */
13512		"jqXHR": null,
13513	
13514		/**
13515		 * JSON returned from the server in the last Ajax request
13516		 *  @type object
13517		 *  @default undefined
13518		 */
13519		"json": undefined,
13520	
13521		/**
13522		 * Data submitted as part of the last Ajax request
13523		 *  @type object
13524		 *  @default undefined
13525		 */
13526		"oAjaxData": undefined,
13527	
13528		/**
13529		 * Function to get the server-side data.
13530		 * Note that this parameter will be set by the initialisation routine. To
13531		 * set a default use {@link DataTable.defaults}.
13532		 *  @type function
13533		 */
13534		"fnServerData": null,
13535	
13536		/**
13537		 * Functions which are called prior to sending an Ajax request so extra
13538		 * parameters can easily be sent to the server
13539		 *  @type array
13540		 *  @default []
13541		 */
13542		"aoServerParams": [],
13543	
13544		/**
13545		 * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13546		 * required).
13547		 * Note that this parameter will be set by the initialisation routine. To
13548		 * set a default use {@link DataTable.defaults}.
13549		 *  @type string
13550		 */
13551		"sServerMethod": null,
13552	
13553		/**
13554		 * Format numbers for display.
13555		 * Note that this parameter will be set by the initialisation routine. To
13556		 * set a default use {@link DataTable.defaults}.
13557		 *  @type function
13558		 */
13559		"fnFormatNumber": null,
13560	
13561		/**
13562		 * List of options that can be used for the user selectable length menu.
13563		 * Note that this parameter will be set by the initialisation routine. To
13564		 * set a default use {@link DataTable.defaults}.
13565		 *  @type array
13566		 *  @default []
13567		 */
13568		"aLengthMenu": null,
13569	
13570		/**
13571		 * Counter for the draws that the table does. Also used as a tracker for
13572		 * server-side processing
13573		 *  @type int
13574		 *  @default 0
13575		 */
13576		"iDraw": 0,
13577	
13578		/**
13579		 * Indicate if a redraw is being done - useful for Ajax
13580		 *  @type boolean
13581		 *  @default false
13582		 */
13583		"bDrawing": false,
13584	
13585		/**
13586		 * Draw index (iDraw) of the last error when parsing the returned data
13587		 *  @type int
13588		 *  @default -1
13589		 */
13590		"iDrawError": -1,
13591	
13592		/**
13593		 * Paging display length
13594		 *  @type int
13595		 *  @default 10
13596		 */
13597		"_iDisplayLength": 10,
13598	
13599		/**
13600		 * Paging start point - aiDisplay index
13601		 *  @type int
13602		 *  @default 0
13603		 */
13604		"_iDisplayStart": 0,
13605	
13606		/**
13607		 * Server-side processing - number of records in the result set
13608		 * (i.e. before filtering), Use fnRecordsTotal rather than
13609		 * this property to get the value of the number of records, regardless of
13610		 * the server-side processing setting.
13611		 *  @type int
13612		 *  @default 0
13613		 *  @private
13614		 */
13615		"_iRecordsTotal": 0,
13616	
13617		/**
13618		 * Server-side processing - number of records in the current display set
13619		 * (i.e. after filtering). Use fnRecordsDisplay rather than
13620		 * this property to get the value of the number of records, regardless of
13621		 * the server-side processing setting.
13622		 *  @type boolean
13623		 *  @default 0
13624		 *  @private
13625		 */
13626		"_iRecordsDisplay": 0,
13627	
13628		/**
13629		 * Flag to indicate if jQuery UI marking and classes should be used.
13630		 * Note that this parameter will be set by the initialisation routine. To
13631		 * set a default use {@link DataTable.defaults}.
13632		 *  @type boolean
13633		 */
13634		"bJUI": null,
13635	
13636		/**
13637		 * The classes to use for the table
13638		 *  @type object
13639		 *  @default {}
13640		 */
vendor: 3,548 bytes, lines 13641-13796
13641		"oClasses": {},
13642	
13643		/**
13644		 * Flag attached to the settings object so you can check in the draw
13645		 * callback if filtering has been done in the draw. Deprecated in favour of
13646		 * events.
13647		 *  @type boolean
13648		 *  @default false
13649		 *  @deprecated
13650		 */
13651		"bFiltered": false,
13652	
13653		/**
13654		 * Flag attached to the settings object so you can check in the draw
13655		 * callback if sorting has been done in the draw. Deprecated in favour of
13656		 * events.
13657		 *  @type boolean
13658		 *  @default false
13659		 *  @deprecated
13660		 */
13661		"bSorted": false,
13662	
13663		/**
13664		 * Indicate that if multiple rows are in the header and there is more than
13665		 * one unique cell per column, if the top one (true) or bottom one (false)
13666		 * should be used for sorting / title by DataTables.
13667		 * Note that this parameter will be set by the initialisation routine. To
13668		 * set a default use {@link DataTable.defaults}.
13669		 *  @type boolean
13670		 */
13671		"bSortCellsTop": null,
13672	
13673		/**
13674		 * Initialisation object that is used for the table
13675		 *  @type object
13676		 *  @default null
13677		 */
13678		"oInit": null,
13679	
13680		/**
13681		 * Destroy callback functions - for plug-ins to attach themselves to the
13682		 * destroy so they can clean up markup and events.
13683		 *  @type array
13684		 *  @default []
13685		 */
13686		"aoDestroyCallback": [],
13687	
13688	
13689		/**
13690		 * Get the number of records in the current record set, before filtering
13691		 *  @type function
13692		 */
13693		"fnRecordsTotal": function ()
13694		{
13695			return _fnDataSource( this ) == 'ssp' ?
13696				this._iRecordsTotal * 1 :
13697				this.aiDisplayMaster.length;
13698		},
13699	
13700		/**
13701		 * Get the number of records in the current record set, after filtering
13702		 *  @type function
13703		 */
13704		"fnRecordsDisplay": function ()
13705		{
13706			return _fnDataSource( this ) == 'ssp' ?
13707				this._iRecordsDisplay * 1 :
13708				this.aiDisplay.length;
13709		},
13710	
13711		/**
13712		 * Get the display end point - aiDisplay index
13713		 *  @type function
13714		 */
13715		"fnDisplayEnd": function ()
13716		{
13717			var
13718				len      = this._iDisplayLength,
13719				start    = this._iDisplayStart,
13720				calc     = start + len,
13721				records  = this.aiDisplay.length,
13722				features = this.oFeatures,
13723				paginate = features.bPaginate;
13724	
13725			if ( features.bServerSide ) {
13726				return paginate === false || len === -1 ?
13727					start + records :
13728					Math.min( start+len, this._iRecordsDisplay );
13729			}
13730			else {
13731				return ! paginate || calc>records || len===-1 ?
13732					records :
13733					calc;
13734			}
13735		},
13736	
13737		/**
13738		 * The DataTables object for this table
13739		 *  @type object
13740		 *  @default null
13741		 */
13742		"oInstance": null,
13743	
13744		/**
13745		 * Unique identifier for each instance of the DataTables object. If there
13746		 * is an ID on the table node, then it takes that value, otherwise an
13747		 * incrementing internal counter is used.
13748		 *  @type string
13749		 *  @default null
13750		 */
13751		"sInstance": null,
13752	
13753		/**
13754		 * tabindex attribute value that is added to DataTables control elements, allowing
13755		 * keyboard navigation of the table and its controls.
13756		 */
13757		"iTabIndex": 0,
13758	
13759		/**
13760		 * DIV container for the footer scrolling table if scrolling
13761		 */
13762		"nScrollHead": null,
13763	
13764		/**
13765		 * DIV container for the footer scrolling table if scrolling
13766		 */
13767		"nScrollFoot": null,
13768	
13769		/**
13770		 * Last applied sort
13771		 *  @type array
13772		 *  @default []
13773		 */
13774		"aLastSort": [],
13775	
13776		/**
13777		 * Stored plug-in instances
13778		 *  @type object
13779		 *  @default {}
13780		 */
13781		"oPlugins": {},
13782	
13783		/**
13784		 * Function used to get a row's id from the row's data
13785		 *  @type function
13786		 *  @default null
13787		 */
13788		"rowIdFn": null,
13789	
13790		/**
13791		 * Data location where to store a row's id
13792		 *  @type string
13793		 *  @default null
13794		 */
13795		"rowId": null
13796	};
vendor: 11,984 bytes, lines 13797-14163
13797
13798	/**
13799	 * Extension object for DataTables that is used to provide all extension
13800	 * options.
13801	 *
13802	 * Note that the `DataTable.ext` object is available through
13803	 * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13804	 * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13805	 *  @namespace
13806	 *  @extends DataTable.models.ext
13807	 */
13808	
13809	
13810	/**
13811	 * DataTables extensions
13812	 * 
13813	 * This namespace acts as a collection area for plug-ins that can be used to
13814	 * extend DataTables capabilities. Indeed many of the build in methods
13815	 * use this method to provide their own capabilities (sorting methods for
13816	 * example).
13817	 *
13818	 * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13819	 * reasons
13820	 *
13821	 *  @namespace
13822	 */
13823	DataTable.ext = _ext = {
13824		/**
13825		 * Buttons. For use with the Buttons extension for DataTables. This is
13826		 * defined here so other extensions can define buttons regardless of load
13827		 * order. It is _not_ used by DataTables core.
13828		 *
13829		 *  @type object
13830		 *  @default {}
13831		 */
13832		buttons: {},
13833	
13834	
13835		/**
13836		 * Element class names
13837		 *
13838		 *  @type object
13839		 *  @default {}
13840		 */
13841		classes: {},
13842	
13843	
13844		/**
13845		 * DataTables build type (expanded by the download builder)
13846		 *
13847		 *  @type string
13848		 */
13849		builder: "-source-",
13850	
13851	
13852		/**
13853		 * Error reporting.
13854		 * 
13855		 * How should DataTables report an error. Can take the value 'alert',
13856		 * 'throw', 'none' or a function.
13857		 *
13858		 *  @type string|function
13859		 *  @default alert
13860		 */
13861		errMode: "alert",
13862	
13863	
13864		/**
13865		 * Feature plug-ins.
13866		 * 
13867		 * This is an array of objects which describe the feature plug-ins that are
13868		 * available to DataTables. These feature plug-ins are then available for
13869		 * use through the `dom` initialisation option.
13870		 * 
13871		 * Each feature plug-in is described by an object which must have the
13872		 * following properties:
13873		 * 
13874		 * * `fnInit` - function that is used to initialise the plug-in,
13875		 * * `cFeature` - a character so the feature can be enabled by the `dom`
13876		 *   instillation option. This is case sensitive.
13877		 *
13878		 * The `fnInit` function has the following input parameters:
13879		 *
13880		 * 1. `{object}` DataTables settings object: see
13881		 *    {@link DataTable.models.oSettings}
13882		 *
13883		 * And the following return is expected:
13884		 * 
13885		 * * {node|null} The element which contains your feature. Note that the
13886		 *   return may also be void if your plug-in does not require to inject any
13887		 *   DOM elements into DataTables control (`dom`) - for example this might
13888		 *   be useful when developing a plug-in which allows table control via
13889		 *   keyboard entry
13890		 *
13891		 *  @type array
13892		 *
13893		 *  @example
13894		 *    $.fn.dataTable.ext.features.push( {
13895		 *      "fnInit": function( oSettings ) {
13896		 *        return new TableTools( { "oDTSettings": oSettings } );
13897		 *      },
13898		 *      "cFeature": "T"
13899		 *    } );
13900		 */
13901		feature: [],
13902	
13903	
13904		/**
13905		 * Row searching.
13906		 * 
13907		 * This method of searching is complimentary to the default type based
13908		 * searching, and a lot more comprehensive as it allows you complete control
13909		 * over the searching logic. Each element in this array is a function
13910		 * (parameters described below) that is called for every row in the table,
13911		 * and your logic decides if it should be included in the searching data set
13912		 * or not.
13913		 *
13914		 * Searching functions have the following input parameters:
13915		 *
13916		 * 1. `{object}` DataTables settings object: see
13917		 *    {@link DataTable.models.oSettings}
13918		 * 2. `{array|object}` Data for the row to be processed (same as the
13919		 *    original format that was passed in as the data source, or an array
13920		 *    from a DOM data source
13921		 * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
13922		 *    can be useful to retrieve the `TR` element if you need DOM interaction.
13923		 *
13924		 * And the following return is expected:
13925		 *
13926		 * * {boolean} Include the row in the searched result set (true) or not
13927		 *   (false)
13928		 *
13929		 * Note that as with the main search ability in DataTables, technically this
13930		 * is "filtering", since it is subtractive. However, for consistency in
13931		 * naming we call it searching here.
13932		 *
13933		 *  @type array
13934		 *  @default []
13935		 *
13936		 *  @example
13937		 *    // The following example shows custom search being applied to the
13938		 *    // fourth column (i.e. the data[3] index) based on two input values
13939		 *    // from the end-user, matching the data in a certain range.
13940		 *    $.fn.dataTable.ext.search.push(
13941		 *      function( settings, data, dataIndex ) {
13942		 *        var min = document.getElementById('min').value * 1;
13943		 *        var max = document.getElementById('max').value * 1;
13944		 *        var version = data[3] == "-" ? 0 : data[3]*1;
13945		 *
13946		 *        if ( min == "" && max == "" ) {
13947		 *          return true;
13948		 *        }
13949		 *        else if ( min == "" && version < max ) {
13950		 *          return true;
13951		 *        }
13952		 *        else if ( min < version && "" == max ) {
13953		 *          return true;
13954		 *        }
13955		 *        else if ( min < version && version < max ) {
13956		 *          return true;
13957		 *        }
13958		 *        return false;
13959		 *      }
13960		 *    );
13961		 */
13962		search: [],
13963	
13964	
13965		/**
13966		 * Selector extensions
13967		 *
13968		 * The `selector` option can be used to extend the options available for the
13969		 * selector modifier options (`selector-modifier` object data type) that
13970		 * each of the three built in selector types offer (row, column and cell +
13971		 * their plural counterparts). For example the Select extension uses this
13972		 * mechanism to provide an option to select only rows, columns and cells
13973		 * that have been marked as selected by the end user (`{selected: true}`),
13974		 * which can be used in conjunction with the existing built in selector
13975		 * options.
13976		 *
13977		 * Each property is an array to which functions can be pushed. The functions
13978		 * take three attributes:
13979		 *
13980		 * * Settings object for the host table
13981		 * * Options object (`selector-modifier` object type)
13982		 * * Array of selected item indexes
13983		 *
13984		 * The return is an array of the resulting item indexes after the custom
13985		 * selector has been applied.
13986		 *
13987		 *  @type object
13988		 */
13989		selector: {
13990			cell: [],
13991			column: [],
13992			row: []
13993		},
13994	
13995	
13996		/**
13997		 * Internal functions, exposed for used in plug-ins.
13998		 * 
13999		 * Please note that you should not need to use the internal methods for
14000		 * anything other than a plug-in (and even then, try to avoid if possible).
14001		 * The internal function may change between releases.
14002		 *
14003		 *  @type object
14004		 *  @default {}
14005		 */
14006		internal: {},
14007	
14008	
14009		/**
14010		 * Legacy configuration options. Enable and disable legacy options that
14011		 * are available in DataTables.
14012		 *
14013		 *  @type object
14014		 */
14015		legacy: {
14016			/**
14017			 * Enable / disable DataTables 1.9 compatible server-side processing
14018			 * requests
14019			 *
14020			 *  @type boolean
14021			 *  @default null
14022			 */
14023			ajax: null
14024		},
14025	
14026	
14027		/**
14028		 * Pagination plug-in methods.
14029		 * 
14030		 * Each entry in this object is a function and defines which buttons should
14031		 * be shown by the pagination rendering method that is used for the table:
14032		 * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
14033		 * buttons are displayed in the document, while the functions here tell it
14034		 * what buttons to display. This is done by returning an array of button
14035		 * descriptions (what each button will do).
14036		 *
14037		 * Pagination types (the four built in options and any additional plug-in
14038		 * options defined here) can be used through the `paginationType`
14039		 * initialisation parameter.
14040		 *
14041		 * The functions defined take two parameters:
14042		 *
14043		 * 1. `{int} page` The current page index
14044		 * 2. `{int} pages` The number of pages in the table
14045		 *
14046		 * Each function is expected to return an array where each element of the
14047		 * array can be one of:
14048		 *
14049		 * * `first` - Jump to first page when activated
14050		 * * `last` - Jump to last page when activated
14051		 * * `previous` - Show previous page when activated
14052		 * * `next` - Show next page when activated
14053		 * * `{int}` - Show page of the index given
14054		 * * `{array}` - A nested array containing the above elements to add a
14055		 *   containing 'DIV' element (might be useful for styling).
14056		 *
14057		 * Note that DataTables v1.9- used this object slightly differently whereby
14058		 * an object with two functions would be defined for each plug-in. That
14059		 * ability is still supported by DataTables 1.10+ to provide backwards
14060		 * compatibility, but this option of use is now decremented and no longer
14061		 * documented in DataTables 1.10+.
14062		 *
14063		 *  @type object
14064		 *  @default {}
14065		 *
14066		 *  @example
14067		 *    // Show previous, next and current page buttons only
14068		 *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
14069		 *      return [ 'previous', page, 'next' ];
14070		 *    };
14071		 */
14072		pager: {},
14073	
14074	
14075		renderer: {
14076			pageButton: {},
14077			header: {}
14078		},
14079	
14080	
14081		/**
14082		 * Ordering plug-ins - custom data source
14083		 * 
14084		 * The extension options for ordering of data available here is complimentary
14085		 * to the default type based ordering that DataTables typically uses. It
14086		 * allows much greater control over the the data that is being used to
14087		 * order a column, but is necessarily therefore more complex.
14088		 * 
14089		 * This type of ordering is useful if you want to do ordering based on data
14090		 * live from the DOM (for example the contents of an 'input' element) rather
14091		 * than just the static string that DataTables knows of.
14092		 * 
14093		 * The way these plug-ins work is that you create an array of the values you
14094		 * wish to be ordering for the column in question and then return that
14095		 * array. The data in the array much be in the index order of the rows in
14096		 * the table (not the currently ordering order!). Which order data gathering
14097		 * function is run here depends on the `dt-init columns.orderDataType`
14098		 * parameter that is used for the column (if any).
14099		 *
14100		 * The functions defined take two parameters:
14101		 *
14102		 * 1. `{object}` DataTables settings object: see
14103		 *    {@link DataTable.models.oSettings}
14104		 * 2. `{int}` Target column index
14105		 *
14106		 * Each function is expected to return an array:
14107		 *
14108		 * * `{array}` Data for the column to be ordering upon
14109		 *
14110		 *  @type array
14111		 *
14112		 *  @example
14113		 *    // Ordering using `input` node values
14114		 *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )
14115		 *    {
14116		 *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
14117		 *        return $('input', td).val();
14118		 *      } );
14119		 *    }
14120		 */
14121		order: {},
14122	
14123	
14124		/**
14125		 * Type based plug-ins.
14126		 *
14127		 * Each column in DataTables has a type assigned to it, either by automatic
14128		 * detection or by direct assignment using the `type` option for the column.
14129		 * The type of a column will effect how it is ordering and search (plug-ins
14130		 * can also make use of the column type if required).
14131		 *
14132		 * @namespace
14133		 */
14134		type: {
14135			/**
14136			 * Type detection functions.
14137			 *
14138			 * The functions defined in this object are used to automatically detect
14139			 * a column's type, making initialisation of DataTables super easy, even
14140			 * when complex data is in the table.
14141			 *
14142			 * The functions defined take two parameters:
14143			 *
14144		     *  1. `{*}` Data from the column cell to be analysed
14145		     *  2. `{settings}` DataTables settings object. This can be used to
14146		     *     perform context specific type detection - for example detection
14147		     *     based on language settings such as using a comma for a decimal
14148		     *     place. Generally speaking the options from the settings will not
14149		     *     be required
14150			 *
14151			 * Each function is expected to return:
14152			 *
14153			 * * `{string|null}` Data type detected, or null if unknown (and thus
14154			 *   pass it on to the other type detection functions.
14155			 *
14156			 *  @type array
14157			 *
14158			 *  @example
14159			 *    // Currency type detection plug-in:
14160			 *    $.fn.dataTable.ext.type.detect.push(
14161			 *      function ( data, settings ) {
14162			 *        // Check the numeric part
14163			 *        if ( ! 
14163$.isNumeric( data.substring(1) ) ) {
14164			 *          return null;
14165			 *        }
14166			 *
14167			 *        // Check prefixed by currency
14168			 *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
14169			 *          return 'currency';
14170			 *        }
14171			 *        return null;
14172			 *      }
14173			 *    );
14174			 */
14175			detect: [],
14176	
14177	
14178			/**
14179			 * Type based search formatting.
14180			 *
14181			 * The type based searching functions can be used to pre-format the
14182			 * data to be search on. For example, it can be used to strip HTML
14183			 * tags or to de-format telephone numbers for numeric only searching.
14184			 *
14185			 * Note that is a search is not defined for a column of a given type,
14186			 * no search formatting will be performed.
14187			 * 
14188			 * Pre-processing of searching data plug-ins - When you assign the sType
14189			 * for a column (or have it automatically detected for you by DataTables
14190			 * or a type detection plug-in), you will typically be using this for
14191			 * custom sorting, but it can also be used to provide custom searching
14192			 * by allowing you to pre-processing the data and returning the data in
14193			 * the format that should be searched upon. This is done by adding
14194			 * functions this object with a parameter name which matches the sType
14195			 * for that target column. This is the corollary of <i>afnSortData</i>
14196			 * for searching data.
14197			 *
14198			 * The functions defined take a single parameter:
14199			 *
14200		     *  1. `{*}` Data from the column cell to be prepared for searching
14201			 *
14202			 * Each function is expected to return:
14203			 *
14204			 * * `{string|null}` Formatted string that will be used for the searching.
14205			 *
14206			 *  @type object
14207			 *  @default {}
14208			 *
14209			 *  @example
14210			 *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
14211			 *      return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
14212			 *    }
14213			 */
14214			search: {},
14215	
14216	
14217			/**
14218			 * Type based ordering.
14219			 *
14220			 * The column type tells DataTables what ordering to apply to the table
14221			 * when a column is sorted upon. The order for each type that is defined,
14222			 * is defined by the functions available in this object.
14223			 *
14224			 * Each ordering option can be described by three properties added to
14225			 * this object:
14226			 *
14227			 * * `{type}-pre` - Pre-formatting function
14228			 * * `{type}-asc` - Ascending order function
14229			 * * `{type}-desc` - Descending order function
14230			 *
14231			 * All three can be used together, only `{type}-pre` or only
14232			 * `{type}-asc` and `{type}-desc` together. It is generally recommended
14233			 * that only `{type}-pre` is used, as this provides the optimal
14234			 * implementation in terms of speed, although the others are provided
14235			 * for compatibility with existing Javascript sort functions.
14236			 *
14237			 * `{type}-pre`: Functions defined take a single parameter:
14238			 *
14239		     *  1. `{*}` Data from the column cell to be prepared for ordering
14240			 *
14241			 * And return:
14242			 *
14243			 * * `{*}` Data to be sorted upon
14244			 *
14245			 * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14246			 * functions, taking two parameters:
14247			 *
14248		     *  1. `{*}` Data to compare to the second parameter
14249		     *  2. `{*}` Data to compare to the first parameter
14250			 *
14251			 * And returning:
14252			 *
14253			 * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14254			 *   than the second parameter, ===0 if the two parameters are equal and
14255			 *   >0 if the first parameter should be sorted height than the second
14256			 *   parameter.
14257			 * 
14258			 *  @type object
14259			 *  @default {}
14260			 *
14261			 *  @example
14262			 *    // Numeric ordering of formatted numbers with a pre-formatter
14263			 *    $.extend( $.fn.dataTable.ext.type.order, {
14264			 *      "string-pre": function(x) {
14265			 *        a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14266			 *        return parseFloat( a );
14267			 *      }
14268			 *    } );
14269			 *
14270			 *  @example
14271			 *    // Case-sensitive string ordering, with no pre-formatting method
14272			 *    $.extend( $.fn.dataTable.ext.order, {
14273			 *      "string-case-asc": function(x,y) {
14274			 *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14275			 *      },
14276			 *      "string-case-desc": function(x,y) {
14277			 *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14278			 *      }
14279			 *    } );
14280			 */
14281			order: {}
14282		},
14283	
14284		/**
14285		 * Unique DataTables instance counter
14286		 *
14287		 * @type int
14288		 * @private
14289		 */
14290		_unique: 0,
14291	
14292	
14293		//
14294		// Depreciated
14295		// The following properties are retained for backwards compatiblity only.
14296		// The should not be used in new projects and will be removed in a future
14297		// version
14298		//
14299	
14300		/**
14301		 * Version check function.
14302		 *  @type function
14303		 *  @depreciated Since 1.10
14304		 */
14305		fnVersionCheck: DataTable.fnVersionCheck,
14306	
14307	
14308		/**
14309		 * Index for what 'this' index API functions should use
14310		 *  @type int
14311		 *  @deprecated Since v1.10
14312		 */
14313		iApiIndex: 0,
14314	
14315	
14316		/**
14317		 * jQuery UI class container
14318		 *  @type object
14319		 *  @deprecated Since v1.10
14320		 */
14321		oJUIClasses: {},
14322	
14323	
14324		/**
14325		 * Software version
14326		 *  @type string
14327		 *  @deprecated Since v1.10
14328		 */
14329		sVersion: DataTable.version
14330	};
14331	
14332	
14333	//
14334	// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14335	//
14336	$.extend( _ext, {
14337		afnFiltering: _ext.search,
14338		aTypes:       _ext.type.detect,
14339		ofnSearch:    _ext.type.search,
14340		oSort:        _ext.type.order,
14341		afnSortData:  _ext.order,
14342		aoFeatures:   _ext.feature,
14343		oApi:         _ext.internal,
14344		oStdClasses:  _ext.classes,
14345		oPagination:  _ext.pager
14346	} );
14347	
14348	
14349	$.extend( DataTable.ext.classes, {
14350		"sTable": "dataTable",
14351		"sNoFooter": "no-footer",
14352	
14353		/* Paging buttons */
14354		"sPageButton": "paginate_button",
14355		"sPageButtonActive": "current",
14356		"sPageButtonDisabled": "disabled",
14357	
14358		/* Striping classes */
14359		"sStripeOdd": "odd",
14360		"sStripeEven": "even",
14361	
14362		/* Empty row */
14363		"sRowEmpty": "dataTables_empty",
14364	
14365		/* Features */
14366		"sWrapper": "dataTables_wrapper",
14367		"sFilter": "dataTables_filter",
14368		"sInfo": "dataTables_info",
14369		"sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14370		"sLength": "dataTables_length",
14371		"sProcessing": "dataTables_processing",
14372	
14373		/* Sorting */
14374		"sSortAsc": "sorting_asc",
14375		"sSortDesc": "sorting_desc",
14376		"sSortable": "sorting", /* Sortable in both directions */
14377		"sSortableAsc": "sorting_asc_disabled",
14378		"sSortableDesc": "sorting_desc_disabled",
14379		"sSortableNone": "sorting_disabled",
14380		"sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14381	
14382		/* Filtering */
14383		"sFilterInput": "",
14384	
14385		/* Page length */
14386		"sLengthSelect": "",
14387	
14388		/* Scrolling */
14389		"sScrollWrapper": "dataTables_scroll",
14390		"sScrollHead": "dataTables_scrollHead",
14391		"sScrollHeadInner": "dataTables_scrollHeadInner",
14392		"sScrollBody": "dataTables_scrollBody",
14393		"sScrollFoot": "dataTables_scrollFoot",
14394		"sScrollFootInner": "dataTables_scrollFootInner",
14395	
14396		/* Misc */
14397		"sHeaderTH": "",
14398		"sFooterTH": "",
14399	
14400		// Deprecated
14401		"sSortJUIAsc": "",
14402		"sSortJUIDesc": "",
14403		"sSortJUI": "",
14404		"sSortJUIAscAllowed": "",
14405		"sSortJUIDescAllowed": "",
14406		"sSortJUIWrapper": "",
14407		"sSortIcon": "",
14408		"sJUIHeader": "",
14409		"sJUIFooter": ""
14410	} );
14411	
14412	
14413	(function() {
14414	
14415	// Reused strings for better compression. Closure compiler appears to have a
vendor: 24,949 bytes, lines 14416-15242
14416	// weird edge case where it is trying to expand strings rather than use the
14417	// variable version. This results in about 200 bytes being added, for very
14418	// little preference benefit since it this run on script load only.
14419	var _empty = '';
14420	_empty = '';
14421	
14422	var _stateDefault = _empty + 'ui-state-default';
14423	var _sortIcon     = _empty + 'css_right ui-icon ui-icon-';
14424	var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
14425	
14426	$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
14427		/* Full numbers paging buttons */
14428		"sPageButton":         "fg-button ui-button "+_stateDefault,
14429		"sPageButtonActive":   "ui-state-disabled",
14430		"sPageButtonDisabled": "ui-state-disabled",
14431	
14432		/* Features */
14433		"sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
14434			"ui-buttonset-multi paging_", /* Note that the type is postfixed */
14435	
14436		/* Sorting */
14437		"sSortAsc":            _stateDefault+" sorting_asc",
14438		"sSortDesc":           _stateDefault+" sorting_desc",
14439		"sSortable":           _stateDefault+" sorting",
14440		"sSortableAsc":        _stateDefault+" sorting_asc_disabled",
14441		"sSortableDesc":       _stateDefault+" sorting_desc_disabled",
14442		"sSortableNone":       _stateDefault+" sorting_disabled",
14443		"sSortJUIAsc":         _sortIcon+"triangle-1-n",
14444		"sSortJUIDesc":        _sortIcon+"triangle-1-s",
14445		"sSortJUI":            _sortIcon+"carat-2-n-s",
14446		"sSortJUIAscAllowed":  _sortIcon+"carat-1-n",
14447		"sSortJUIDescAllowed": _sortIcon+"carat-1-s",
14448		"sSortJUIWrapper":     "DataTables_sort_wrapper",
14449		"sSortIcon":           "DataTables_sort_icon",
14450	
14451		/* Scrolling */
14452		"sScrollHead": "dataTables_scrollHead "+_stateDefault,
14453		"sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
14454	
14455		/* Misc */
14456		"sHeaderTH":  _stateDefault,
14457		"sFooterTH":  _stateDefault,
14458		"sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
14459		"sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
14460	} );
14461	
14462	}());
14463	
14464	
14465	
14466	var extPagination = DataTable.ext.pager;
14467	
14468	function _numbers ( page, pages ) {
14469		var
14470			numbers = [],
14471			buttons = extPagination.numbers_length,
14472			half = Math.floor( buttons / 2 ),
14473			i = 1;
14474	
14475		if ( pages <= buttons ) {
14476			numbers = _range( 0, pages );
14477		}
14478		else if ( page <= half ) {
14479			numbers = _range( 0, buttons-2 );
14480			numbers.push( 'ellipsis' );
14481			numbers.push( pages-1 );
14482		}
14483		else if ( page >= pages - 1 - half ) {
14484			numbers = _range( pages-(buttons-2), pages );
14485			numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
14486			numbers.splice( 0, 0, 0 );
14487		}
14488		else {
14489			numbers = _range( page-half+2, page+half-1 );
14490			numbers.push( 'ellipsis' );
14491			numbers.push( pages-1 );
14492			numbers.splice( 0, 0, 'ellipsis' );
14493			numbers.splice( 0, 0, 0 );
14494		}
14495	
14496		numbers.DT_el = 'span';
14497		return numbers;
14498	}
14499	
14500	
14501	$.extend( extPagination, {
14502		simple: function ( page, pages ) {
14503			return [ 'previous', 'next' ];
14504		},
14505	
14506		full: function ( page, pages ) {
14507			return [  'first', 'previous', 'next', 'last' ];
14508		},
14509	
14510		numbers: function ( page, pages ) {
14511			return [ _numbers(page, pages) ];
14512		},
14513	
14514		simple_numbers: function ( page, pages ) {
14515			return [ 'previous', _numbers(page, pages), 'next' ];
14516		},
14517	
14518		full_numbers: function ( page, pages ) {
14519			return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14520		},
14521		
14522		first_last_numbers: function (page, pages) {
14523	 		return ['first', _numbers(page, pages), 'last'];
14524	 	},
14525	
14526		// For testing and plug-ins to use
14527		_numbers: _numbers,
14528	
14529		// Number of number buttons (including ellipsis) to show. _Must be odd!_
14530		numbers_length: 7
14531	} );
14532	
14533	
14534	$.extend( true, DataTable.ext.renderer, {
14535		pageButton: {
14536			_: function ( settings, host, idx, buttons, page, pages ) {
14537				var classes = settings.oClasses;
14538				var lang = settings.oLanguage.oPaginate;
14539				var aria = settings.oLanguage.oAria.paginate || {};
14540				var btnDisplay, btnClass, counter=0;
14541	
14542				var attach = function( container, buttons ) {
14543					var i, ien, node, button;
14544					var clickHandler = function ( e ) {
14545						_fnPageChange( settings, e.data.action, true );
14546					};
14547	
14548					for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
14549						button = buttons[i];
14550	
14551						if ( $.isArray( button ) ) {
14552							var inner = $( '<'+(button.DT_el || 'div')+'/>' )
14553								.appendTo( container );
14554							attach( inner, button );
14555						}
14556						else {
14557							btnDisplay = null;
14558							btnClass = '';
14559	
14560							switch ( button ) {
14561								case 'ellipsis':
14562									container.append('<span class="ellipsis">&#x2026;</span>');
14563									break;
14564	
14565								case 'first':
14566									btnDisplay = lang.sFirst;
14567									btnClass = button + (page > 0 ?
14568										'' : ' '+classes.sPageButtonDisabled);
14569									break;
14570	
14571								case 'previous':
14572									btnDisplay = lang.sPrevious;
14573									btnClass = button + (page > 0 ?
14574										'' : ' '+classes.sPageButtonDisabled);
14575									break;
14576	
14577								case 'next':
14578									btnDisplay = lang.sNext;
14579									btnClass = button + (page < pages-1 ?
14580										'' : ' '+classes.sPageButtonDisabled);
14581									break;
14582	
14583								case 'last':
14584									btnDisplay = lang.sLast;
14585									btnClass = button + (page < pages-1 ?
14586										'' : ' '+classes.sPageButtonDisabled);
14587									break;
14588	
14589								default:
14590									btnDisplay = button + 1;
14591									btnClass = page === button ?
14592										classes.sPageButtonActive : '';
14593									break;
14594							}
14595	
14596							if ( btnDisplay !== null ) {
14597								node = $('<a>', {
14598										'class': classes.sPageButton+' '+btnClass,
14599										'aria-controls': settings.sTableId,
14600										'aria-label': aria[ button ],
14601										'data-dt-idx': counter,
14602										'tabindex': settings.iTabIndex,
14603										'id': idx === 0 && typeof button === 'string' ?
14604											settings.sTableId +'_'+ button :
14605											null
14606									} )
14607									.html( btnDisplay )
14608									.appendTo( container );
14609	
14610								_fnBindAction(
14611									node, {action: button}, clickHandler
14612								);
14613	
14614								counter++;
14615							}
14616						}
14617					}
14618				};
14619	
14620				// IE9 throws an 'unknown error' if document.activeElement is used
14621				// inside an iframe or frame. Try / catch the error. Not good for
14622				// accessibility, but neither are frames.
14623				var activeEl;
14624	
14625				try {
14626					// Because this approach is destroying and recreating the paging
14627					// elements, focus is lost on the select button which is bad for
14628					// accessibility. So we want to restore focus once the draw has
14629					// completed
14630					activeEl = $(host).find(document.activeElement).data('dt-idx');
14631				}
14632				catch (e) {}
14633	
14634				attach( $(host).empty(), buttons );
14635	
14636				if ( activeEl !== undefined ) {
14637					$(host).find( '[data-dt-idx='+activeEl+']' ).focus();
14638				}
14639			}
14640		}
14641	} );
14642	
14643	
14644	
14645	// Built in type detection. See model.ext.aTypes for information about
14646	// what is required from this methods.
14647	$.extend( DataTable.ext.type.detect, [
14648		// Plain numbers - first since V8 detects some plain numbers as dates
14649		// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14650		function ( d, settings )
14651		{
14652			var decimal = settings.oLanguage.sDecimal;
14653			return _isNumber( d, decimal ) ? 'num'+decimal : null;
14654		},
14655	
14656		// Dates (only those recognised by the browser's Date.parse)
14657		function ( d, settings )
14658		{
14659			// V8 tries _very_ hard to make a string passed into `Date.parse()`
14660			// valid, so we need to use a regex to restrict date formats. Use a
14661			// plug-in for anything other than ISO8601 style strings
14662			if ( d && !(d instanceof Date) && ! _re_date.test(d) ) {
14663				return null;
14664			}
14665			var parsed = Date.parse(d);
14666			return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14667		},
14668	
14669		// Formatted numbers
14670		function ( d, settings )
14671		{
14672			var decimal = settings.oLanguage.sDecimal;
14673			return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
14674		},
14675	
14676		// HTML numeric
14677		function ( d, settings )
14678		{
14679			var decimal = settings.oLanguage.sDecimal;
14680			return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
14681		},
14682	
14683		// HTML numeric, formatted
14684		function ( d, settings )
14685		{
14686			var decimal = settings.oLanguage.sDecimal;
14687			return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
14688		},
14689	
14690		// HTML (this is strict checking - there must be html)
14691		function ( d, settings )
14692		{
14693			return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14694				'html' : null;
14695		}
14696	] );
14697	
14698	
14699	
14700	// Filter formatting functions. See model.ext.ofnSearch for information about
14701	// what is required from these methods.
14702	// 
14703	// Note that additional search methods are added for the html numbers and
14704	// html formatted numbers by `_addNumericSort()` when we know what the decimal
14705	// place is
14706	
14707	
14708	$.extend( DataTable.ext.type.search, {
14709		html: function ( data ) {
14710			return _empty(data) ?
14711				data :
14712				typeof data === 'string' ?
14713					data
14714						.replace( _re_new_lines, " " )
14715						.replace( _re_html, "" ) :
14716					'';
14717		},
14718	
14719		string: function ( data ) {
14720			return _empty(data) ?
14721				data :
14722				typeof data === 'string' ?
14723					data.replace( _re_new_lines, " " ) :
14724					data;
14725		}
14726	} );
14727	
14728	
14729	
14730	var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
14731		if ( d !== 0 && (!d || d === '-') ) {
14732			return -Infinity;
14733		}
14734	
14735		// If a decimal place other than `.` is used, it needs to be given to the
14736		// function so we can detect it and replace with a `.` which is the only
14737		// decimal place Javascript recognises - it is not locale aware.
14738		if ( decimalPlace ) {
14739			d = _numToDecimal( d, decimalPlace );
14740		}
14741	
14742		if ( d.replace ) {
14743			if ( re1 ) {
14744				d = d.replace( re1, '' );
14745			}
14746	
14747			if ( re2 ) {
14748				d = d.replace( re2, '' );
14749			}
14750		}
14751	
14752		return d * 1;
14753	};
14754	
14755	
14756	// Add the numeric 'deformatting' functions for sorting and search. This is done
14757	// in a function to provide an easy ability for the language options to add
14758	// additional methods if a non-period decimal place is used.
14759	function _addNumericSort ( decimalPlace ) {
14760		$.each(
14761			{
14762				// Plain numbers
14763				"num": function ( d ) {
14764					return __numericReplace( d, decimalPlace );
14765				},
14766	
14767				// Formatted numbers
14768				"num-fmt": function ( d ) {
14769					return __numericReplace( d, decimalPlace, _re_formatted_numeric );
14770				},
14771	
14772				// HTML numeric
14773				"html-num": function ( d ) {
14774					return __numericReplace( d, decimalPlace, _re_html );
14775				},
14776	
14777				// HTML numeric, formatted
14778				"html-num-fmt": function ( d ) {
14779					return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
14780				}
14781			},
14782			function ( key, fn ) {
14783				// Add the ordering method
14784				_ext.type.order[ key+decimalPlace+'-pre' ] = fn;
14785	
14786				// For HTML types add a search formatter that will strip the HTML
14787				if ( key.match(/^html\-/) ) {
14788					_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
14789				}
14790			}
14791		);
14792	}
14793	
14794	
14795	// Default sort methods
14796	$.extend( _ext.type.order, {
14797		// Dates
14798		"date-pre": function ( d ) {
14799			return Date.parse( d ) || -Infinity;
14800		},
14801	
14802		// html
14803		"html-pre": function ( a ) {
14804			return _empty(a) ?
14805				'' :
14806				a.replace ?
14807					a.replace( /<.*?>/g, "" ).toLowerCase() :
14808					a+'';
14809		},
14810	
14811		// string
14812		"string-pre": function ( a ) {
14813			// This is a little complex, but faster than always calling toString,
14814			// http://jsperf.com/tostring-v-check
14815			return _empty(a) ?
14816				'' :
14817				typeof a === 'string' ?
14818					a.toLowerCase() :
14819					! a.toString ?
14820						'' :
14821						a.toString();
14822		},
14823	
14824		// string-asc and -desc are retained only for compatibility with the old
14825		// sort methods
14826		"string-asc": function ( x, y ) {
14827			return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14828		},
14829	
14830		"string-desc": function ( x, y ) {
14831			return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14832		}
14833	} );
14834	
14835	
14836	// Numeric sorting types - order doesn't matter here
14837	_addNumericSort( '' );
14838	
14839	
14840	$.extend( true, DataTable.ext.renderer, {
14841		header: {
14842			_: function ( settings, cell, column, classes ) {
14843				// No additional mark-up required
14844				// Attach a sort listener to update on sort - note that using the
14845				// `DT` namespace will allow the event to be removed automatically
14846				// on destroy, while the `dt` namespaced event is the one we are
14847				// listening for
14848				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14849					if ( settings !== ctx ) { // need to check this this is the host
14850						return;               // table, not a nested one
14851					}
14852	
14853					var colIdx = column.idx;
14854	
14855					cell
14856						.removeClass(
14857							column.sSortingClass +' '+
14858							classes.sSortAsc +' '+
14859							classes.sSortDesc
14860						)
14861						.addClass( columns[ colIdx ] == 'asc' ?
14862							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14863								classes.sSortDesc :
14864								column.sSortingClass
14865						);
14866				} );
14867			},
14868	
14869			jqueryui: function ( settings, cell, column, classes ) {
14870				$('<div/>')
14871					.addClass( classes.sSortJUIWrapper )
14872					.append( cell.contents() )
14873					.append( $('<span/>')
14874						.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
14875					)
14876					.appendTo( cell );
14877	
14878				// Attach a sort listener to update on sort
14879				$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14880					if ( settings !== ctx ) {
14881						return;
14882					}
14883	
14884					var colIdx = column.idx;
14885	
14886					cell
14887						.removeClass( classes.sSortAsc +" "+classes.sSortDesc )
14888						.addClass( columns[ colIdx ] == 'asc' ?
14889							classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14890								classes.sSortDesc :
14891								column.sSortingClass
14892						);
14893	
14894					cell
14895						.find( 'span.'+classes.sSortIcon )
14896						.removeClass(
14897							classes.sSortJUIAsc +" "+
14898							classes.sSortJUIDesc +" "+
14899							classes.sSortJUI +" "+
14900							classes.sSortJUIAscAllowed +" "+
14901							classes.sSortJUIDescAllowed
14902						)
14903						.addClass( columns[ colIdx ] == 'asc' ?
14904							classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14905								classes.sSortJUIDesc :
14906								column.sSortingClassJUI
14907						);
14908				} );
14909			}
14910		}
14911	} );
14912	
14913	/*
14914	 * Public helper functions. These aren't used internally by DataTables, or
14915	 * called by any of the options passed into DataTables, but they can be used
14916	 * externally by developers working with DataTables. They are helper functions
14917	 * to make working with DataTables a little bit easier.
14918	 */
14919	
14920	var __htmlEscapeEntities = function ( d ) {
14921		return typeof d === 'string' ?
14922			d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
14923			d;
14924	};
14925	
14926	/**
14927	 * Helpers for `columns.render`.
14928	 *
14929	 * The options defined here can be used with the `columns.render` initialisation
14930	 * option to provide a display renderer. The following functions are defined:
14931	 *
14932	 * * `number` - Will format numeric data (defined by `columns.data`) for
14933	 *   display, retaining the original unformatted data for sorting and filtering.
14934	 *   It takes 5 parameters:
14935	 *   * `string` - Thousands grouping separator
14936	 *   * `string` - Decimal point indicator
14937	 *   * `integer` - Number of decimal points to show
14938	 *   * `string` (optional) - Prefix.
14939	 *   * `string` (optional) - Postfix (/suffix).
14940	 * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
14941	 *   parameters.
14942	 *
14943	 * @example
14944	 *   // Column definition using the number renderer
14945	 *   {
14946	 *     data: "salary",
14947	 *     render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14948	 *   }
14949	 *
14950	 * @namespace
14951	 */
14952	DataTable.render = {
14953		number: function ( thousands, decimal, precision, prefix, postfix ) {
14954			return {
14955				display: function ( d ) {
14956					if ( typeof d !== 'number' && typeof d !== 'string' ) {
14957						return d;
14958					}
14959	
14960					var negative = d < 0 ? '-' : '';
14961					var flo = parseFloat( d );
14962	
14963					// If NaN then there isn't much formatting that we can do - just
14964					// return immediately, escaping any HTML (this was supposed to
14965					// be a number after all)
14966					if ( isNaN( flo ) ) {
14967						return __htmlEscapeEntities( d );
14968					}
14969	
14970					flo = flo.toFixed( precision );
14971					d = Math.abs( flo );
14972	
14973					var intPart = parseInt( d, 10 );
14974					var floatPart = precision ?
14975						decimal+(d - intPart).toFixed( precision ).substring( 2 ):
14976						'';
14977	
14978					return negative + (prefix||'') +
14979						intPart.toString().replace(
14980							/\B(?=(\d{3})+(?!\d))/g, thousands
14981						) +
14982						floatPart +
14983						(postfix||'');
14984				}
14985			};
14986		},
14987	
14988		text: function () {
14989			return {
14990				display: __htmlEscapeEntities
14991			};
14992		}
14993	};
14994	
14995	
14996	/*
14997	 * This is really a good bit rubbish this method of exposing the internal methods
14998	 * publicly... - To be fixed in 2.0 using methods on the prototype
14999	 */
15000	
15001	
15002	/**
15003	 * Create a wrapper function for exporting an internal functions to an external API.
15004	 *  @param {string} fn API function name
15005	 *  @returns {function} wrapped function
15006	 *  @memberof DataTable#internal
15007	 */
15008	function _fnExternApiFunc (fn)
15009	{
15010		return function() {
15011			var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
15012				Array.prototype.slice.call(arguments)
15013			);
15014			return DataTable.ext.internal[fn].apply( this, args );
15015		};
15016	}
15017	
15018	
15019	/**
15020	 * Reference to internal functions for use by plug-in developers. Note that
15021	 * these methods are references to internal functions and are considered to be
15022	 * private. If you use these methods, be aware that they are liable to change
15023	 * between versions.
15024	 *  @namespace
15025	 */
15026	$.extend( DataTable.ext.internal, {
15027		_fnExternApiFunc: _fnExternApiFunc,
15028		_fnBuildAjax: _fnBuildAjax,
15029		_fnAjaxUpdate: _fnAjaxUpdate,
15030		_fnAjaxParameters: _fnAjaxParameters,
15031		_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
15032		_fnAjaxDataSrc: _fnAjaxDataSrc,
15033		_fnAddColumn: _fnAddColumn,
15034		_fnColumnOptions: _fnColumnOptions,
15035		_fnAdjustColumnSizing: _fnAdjustColumnSizing,
15036		_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
15037		_fnColumnIndexToVisible: _fnColumnIndexToVisible,
15038		_fnVisbleColumns: _fnVisbleColumns,
15039		_fnGetColumns: _fnGetColumns,
15040		_fnColumnTypes: _fnColumnTypes,
15041		_fnApplyColumnDefs: _fnApplyColumnDefs,
15042		_fnHungarianMap: _fnHungarianMap,
15043		_fnCamelToHungarian: _fnCamelToHungarian,
15044		_fnLanguageCompat: _fnLanguageCompat,
15045		_fnBrowserDetect: _fnBrowserDetect,
15046		_fnAddData: _fnAddData,
15047		_fnAddTr: _fnAddTr,
15048		_fnNodeToDataIndex: _fnNodeToDataIndex,
15049		_fnNodeToColumnIndex: _fnNodeToColumnIndex,
15050		_fnGetCellData: _fnGetCellData,
15051		_fnSetCellData: _fnSetCellData,
15052		_fnSplitObjNotation: _fnSplitObjNotation,
15053		_fnGetObjectDataFn: _fnGetObjectDataFn,
15054		_fnSetObjectDataFn: _fnSetObjectDataFn,
15055		_fnGetDataMaster: _fnGetDataMaster,
15056		_fnClearTable: _fnClearTable,
15057		_fnDeleteIndex: _fnDeleteIndex,
15058		_fnInvalidate: _fnInvalidate,
15059		_fnGetRowElements: _fnGetRowElements,
15060		_fnCreateTr: _fnCreateTr,
15061		_fnBuildHead: _fnBuildHead,
15062		_fnDrawHead: _fnDrawHead,
15063		_fnDraw: _fnDraw,
15064		_fnReDraw: _fnReDraw,
15065		_fnAddOptionsHtml: _fnAddOptionsHtml,
15066		_fnDetectHeader: _fnDetectHeader,
15067		_fnGetUniqueThs: _fnGetUniqueThs,
15068		_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
15069		_fnFilterComplete: _fnFilterComplete,
15070		_fnFilterCustom: _fnFilterCustom,
15071		_fnFilterColumn: _fnFilterColumn,
15072		_fnFilter: _fnFilter,
15073		_fnFilterCreateSearch: _fnFilterCreateSearch,
15074		_fnEscapeRegex: _fnEscapeRegex,
15075		_fnFilterData: _fnFilterData,
15076		_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
15077		_fnUpdateInfo: _fnUpdateInfo,
15078		_fnInfoMacros: _fnInfoMacros,
15079		_fnInitialise: _fnInitialise,
15080		_fnInitComplete: _fnInitComplete,
15081		_fnLengthChange: _fnLengthChange,
15082		_fnFeatureHtmlLength: _fnFeatureHtmlLength,
15083		_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
15084		_fnPageChange: _fnPageChange,
15085		_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
15086		_fnProcessingDisplay: _fnProcessingDisplay,
15087		_fnFeatureHtmlTable: _fnFeatureHtmlTable,
15088		_fnScrollDraw: _fnScrollDraw,
15089		_fnApplyToChildren: _fnApplyToChildren,
15090		_fnCalculateColumnWidths: _fnCalculateColumnWidths,
15091		_fnThrottle: _fnThrottle,
15092		_fnConvertToWidth: _fnConvertToWidth,
15093		_fnGetWidestNode: _fnGetWidestNode,
15094		_fnGetMaxLenString: _fnGetMaxLenString,
15095		_fnStringToCss: _fnStringToCss,
15096		_fnSortFlatten: _fnSortFlatten,
15097		_fnSort: _fnSort,
15098		_fnSortAria: _fnSortAria,
15099		_fnSortListener: _fnSortListener,
15100		_fnSortAttachListener: _fnSortAttachListener,
15101		_fnSortingClasses: _fnSortingClasses,
15102		_fnSortData: _fnSortData,
15103		_fnSaveState: _fnSaveState,
15104		_fnLoadState: _fnLoadState,
15105		_fnSettingsFromNode: _fnSettingsFromNode,
15106		_fnLog: _fnLog,
15107		_fnMap: _fnMap,
15108		_fnBindAction: _fnBindAction,
15109		_fnCallbackReg: _fnCallbackReg,
15110		_fnCallbackFire: _fnCallbackFire,
15111		_fnLengthOverflow: _fnLengthOverflow,
15112		_fnRenderer: _fnRenderer,
15113		_fnDataSource: _fnDataSource,
15114		_fnRowAttributes: _fnRowAttributes,
15115		_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
15116		                                // in 1.10, so this dead-end function is
15117		                                // added to prevent errors
15118	} );
15119	
15120
15121	// jQuery access
15122	$.fn.dataTable = DataTable;
15123
15124	// Provide access to the host jQuery object (circular reference)
15125	DataTable.$ = $;
15126
15127	// Legacy aliases
15128	$.fn.dataTableSettings = DataTable.settings;
15129	$.fn.dataTableExt = DataTable.ext;
15130
15131	// With a capital `D` we return a DataTables API instance rather than a
15132	// jQuery object
15133	$.fn.DataTable = function ( opts ) {
15134		return $(this).dataTable( opts ).api();
15135	};
15136
15137	// All properties that are available to $.fn.dataTable should also be
15138	// available on $.fn.DataTable
15139	$.each( DataTable, function ( prop, val ) {
15140		$.fn.DataTable[ prop ] = val;
15141	} );
15142
15143
15144	// Information about events fired by DataTables - for documentation.
15145	/**
15146	 * Draw event, fired whenever the table is redrawn on the page, at the same
15147	 * point as fnDrawCallback. This may be useful for binding events or
15148	 * performing calculations when the table is altered at all.
15149	 *  @name DataTable#draw.dt
15150	 *  @event
15151	 *  @param {event} e jQuery event object
15152	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15153	 */
15154
15155	/**
15156	 * Search event, fired when the searching applied to the table (using the
15157	 * built-in global search, or column filters) is altered.
15158	 *  @name DataTable#search.dt
15159	 *  @event
15160	 *  @param {event} e jQuery event object
15161	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15162	 */
15163
15164	/**
15165	 * Page change event, fired when the paging of the table is altered.
15166	 *  @name DataTable#page.dt
15167	 *  @event
15168	 *  @param {event} e jQuery event object
15169	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15170	 */
15171
15172	/**
15173	 * Order event, fired when the ordering applied to the table is altered.
15174	 *  @name DataTable#order.dt
15175	 *  @event
15176	 *  @param {event} e jQuery event object
15177	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15178	 */
15179
15180	/**
15181	 * DataTables initialisation complete event, fired when the table is fully
15182	 * drawn, including Ajax data loaded, if Ajax data is required.
15183	 *  @name DataTable#init.dt
15184	 *  @event
15185	 *  @param {event} e jQuery event object
15186	 *  @param {object} oSettings DataTables settings object
15187	 *  @param {object} json The JSON object request from the server - only
15188	 *    present if client-side Ajax sourced data is used</li></ol>
15189	 */
15190
15191	/**
15192	 * State save event, fired when the table has changed state a new state save
15193	 * is required. This event allows modification of the state saving object
15194	 * prior to actually doing the save, including addition or other state
15195	 * properties (for plug-ins) or modification of a DataTables core property.
15196	 *  @name DataTable#stateSaveParams.dt
15197	 *  @event
15198	 *  @param {event} e jQuery event object
15199	 *  @param {object} oSettings DataTables settings object
15200	 *  @param {object} json The state information to be saved
15201	 */
15202
15203	/**
15204	 * State load event, fired when the table is loading state from the stored
15205	 * data, but prior to the settings object being modified by the saved state
15206	 * - allowing modification of the saved state is required or loading of
15207	 * state for a plug-in.
15208	 *  @name DataTable#stateLoadParams.dt
15209	 *  @event
15210	 *  @param {event} e jQuery event object
15211	 *  @param {object} oSettings DataTables settings object
15212	 *  @param {object} json The saved state information
15213	 */
15214
15215	/**
15216	 * State loaded event, fired when state has been loaded from stored data and
15217	 * the settings object has been modified by the loaded data.
15218	 *  @name DataTable#stateLoaded.dt
15219	 *  @event
15220	 *  @param {event} e jQuery event object
15221	 *  @param {object} oSettings DataTables settings object
15222	 *  @param {object} json The saved state information
15223	 */
15224
15225	/**
15226	 * Processing event, fired when DataTables is doing some kind of processing
15227	 * (be it, order, searcg or anything else). It can be used to indicate to
15228	 * the end user that there is something happening, or that something has
15229	 * finished.
15230	 *  @name DataTable#processing.dt
15231	 *  @event
15232	 *  @param {event} e jQuery event object
15233	 *  @param {object} oSettings DataTables settings object
15234	 *  @param {boolean} bShow Flag for if DataTables is doing processing or not
15235	 */
15236
15237	/**
15238	 * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15239	 * request to made to the server for new data. This event is called before
15240	 * DataTables processed the returned data, so it can also be used to pre-
15241	 * process the data returned from the server, if needed.
15242	 *
15243	 * Note that this trigger is called in `fnServerData`, if you override
15244	 * `fnServerData` and which to use this event, you need to trigger it in you
15245	 * success function.
15246	 *  @name DataTable#xhr.dt
15247	 *  @event
15248	 *  @param {event} e jQuery event object
15249	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15250	 *  @param {object} json JSON returned from the server
15251	 *
15252	 *  @example
15253	 *     // Use a custom property returned from the server in another DOM element
15254	 *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15255	 *       $('#status').html( json.status );
15256	 *     } );
15257	 *
15258	 *  @example
15259	 *     // Pre-process the data returned from the server
15260	 *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15261	 *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15262	 *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15263	 *       }
15264	 *       // Note no return - manipulate the data directly in the JSON object.
15265	 *     } );
15266	 */
15267
15268	/**
15269	 * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15270	 * or passing the bDestroy:true parameter in the initialisation object. This
15271	 * can be used to remove bound events, added DOM nodes, etc.
15272	 *  @name DataTable#destroy.dt
15273	 *  @event
15274	 *  @param {event} e jQuery event object
15275	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15276	 */
15277
15278	/**
15279	 * Page length change event, fired when number of records to show on each
15280	 * page (the length) is changed.
15281	 *  @name DataTable#length.dt
15282	 *  @event
15283	 *  @param {event} e jQuery event object
15284	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15285	 *  @param {integer} len New length
15286	 */
15287
15288	/**
15289	 * Column sizing has changed.
15290	 *  @name DataTable#column-sizing.dt
15291	 *  @event
15292	 *  @param {event} e jQuery event object
15293	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15294	 */
15295
15296	/**
15297	 * Column visibility has changed.
15298	 *  @name DataTable#column-visibility.dt
15299	 *  @event
15300	 *  @param {event} e jQuery event object
15301	 *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15302	 *  @param {int} column Column index
15303	 *  @param {bool} vis `false` if column now hidden, or `true` if visible
15304	 */
15305
15306	return $.fn.dataTable;
15307}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.