{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "true" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "require 'data_tables'" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "application/javascript": [ "\n", " /* BEGIN jquery.dataTables.js */\n", "\n", "/*! DataTables 1.10.16-dev\n", " * ©2008-2017 SpryMedia Ltd - datatables.net/license\n", " */\n", "\n", "/**\n", " * @summary DataTables\n", " * @description Paginate, search and order HTML tables\n", " * @version 1.10.16-dev\n", " * @file jquery.dataTables.js\n", " * @author SpryMedia Ltd\n", " * @contact www.datatables.net\n", " * @copyright Copyright 2008-2017 SpryMedia Ltd.\n", " *\n", " * This source file is free software, available under the following license:\n", " * MIT license - http://datatables.net/license\n", " *\n", " * This source file is distributed in the hope that it will be useful, but\n", " * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n", " * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n", " *\n", " * For details please refer to: http://www.datatables.net\n", " */\n", "\n", "/*jslint evil: true, undef: true, browser: true */\n", "/*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*/\n", "\n", "(function( factory ) {\n", "\t\"use strict\";\n", "\n", "\tif ( typeof define === 'function' && define.amd ) {\n", "\t\t// AMD\n", "\t\tdefine( ['jquery'], function ( $ ) {\n", "\t\t\treturn factory( $, window, document );\n", "\t\t} );\n", "\t}\n", "\telse if ( typeof exports === 'object' ) {\n", "\t\t// CommonJS\n", "\t\tmodule.exports = function (root, $) {\n", "\t\t\tif ( ! root ) {\n", "\t\t\t\t// CommonJS environments without a window global must pass a\n", "\t\t\t\t// root. This will give an error otherwise\n", "\t\t\t\troot = window;\n", "\t\t\t}\n", "\n", "\t\t\tif ( ! $ ) {\n", "\t\t\t\t$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window\n", "\t\t\t\t\trequire('jquery') :\n", "\t\t\t\t\trequire('jquery')( root );\n", "\t\t\t}\n", "\n", "\t\t\treturn factory( $, root, root.document );\n", "\t\t};\n", "\t}\n", "\telse {\n", "\t\t// Browser\n", "\t\tfactory( jQuery, window, document );\n", "\t}\n", "}\n", "(function( $, window, document, undefined ) {\n", "\t\"use strict\";\n", "\n", "\t/**\n", "\t * DataTables is a plug-in for the jQuery Javascript library. It is a highly\n", "\t * flexible tool, based upon the foundations of progressive enhancement,\n", "\t * which will add advanced interaction controls to any HTML table. For a\n", "\t * full list of features please refer to\n", "\t * [DataTables.net](href=\"http://datatables.net).\n", "\t *\n", "\t * Note that the `DataTable` object is not a global variable but is aliased\n", "\t * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may\n", "\t * be accessed.\n", "\t *\n", "\t * @class\n", "\t * @param {object} [init={}] Configuration object for DataTables. Options\n", "\t * are defined by {@link DataTable.defaults}\n", "\t * @requires jQuery 1.7+\n", "\t *\n", "\t * @example\n", "\t * // Basic initialisation\n", "\t * $(document).ready( function {\n", "\t * $('#example').dataTable();\n", "\t * } );\n", "\t *\n", "\t * @example\n", "\t * // Initialisation with configuration options - in this case, disable\n", "\t * // pagination and sorting.\n", "\t * $(document).ready( function {\n", "\t * $('#example').dataTable( {\n", "\t * \"paginate\": false,\n", "\t * \"sort\": false\n", "\t * } );\n", "\t * } );\n", "\t */\n", "\tvar DataTable = function ( options )\n", "\t{\n", "\t\t/**\n", "\t\t * Perform a jQuery selector action on the table's TR elements (from the tbody) and\n", "\t\t * return the resulting jQuery object.\n", "\t\t * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n", "\t\t * @param {object} [oOpts] Optional parameters for modifying the rows to be included\n", "\t\t * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter\n", "\t\t * criterion (\"applied\") or all TR elements (i.e. no filter).\n", "\t\t * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.\n", "\t\t * Can be either 'current', whereby the current sorting of the table is used, or\n", "\t\t * 'original' whereby the original order the data was read into the table is used.\n", "\t\t * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n", "\t\t * (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n", "\t\t * 'current' and filter is 'applied', regardless of what they might be given as.\n", "\t\t * @returns {object} jQuery object, filtered by the given selector.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Highlight every second row\n", "\t\t * oTable.$('tr:odd').css('backgroundColor', 'blue');\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Filter to rows with 'Webkit' in them, add a background colour and then\n", "\t\t * // remove the filter, thus highlighting the 'Webkit' rows only.\n", "\t\t * oTable.fnFilter('Webkit');\n", "\t\t * oTable.$('tr', {\"search\": \"applied\"}).css('backgroundColor', 'blue');\n", "\t\t * oTable.fnFilter('');\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.$ = function ( sSelector, oOpts )\n", "\t\t{\n", "\t\t\treturn this.api(true).$( sSelector, oOpts );\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Almost identical to $ in operation, but in this case returns the data for the matched\n", "\t\t * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes\n", "\t\t * rather than any descendants, so the data can be obtained for the row/cell. If matching\n", "\t\t * rows are found, the data returned is the original data array/object that was used to\n", "\t\t * create the row (or a generated array if from a DOM source).\n", "\t\t *\n", "\t\t * This method is often useful in-combination with $ where both functions are given the\n", "\t\t * same parameters and the array indexes will match identically.\n", "\t\t * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n", "\t\t * @param {object} [oOpts] Optional parameters for modifying the rows to be included\n", "\t\t * @param {string} [oOpts.filter=none] Select elements that meet the current filter\n", "\t\t * criterion (\"applied\") or all elements (i.e. no filter).\n", "\t\t * @param {string} [oOpts.order=current] Order of the data in the processed array.\n", "\t\t * Can be either 'current', whereby the current sorting of the table is used, or\n", "\t\t * 'original' whereby the original order the data was read into the table is used.\n", "\t\t * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n", "\t\t * (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n", "\t\t * 'current' and filter is 'applied', regardless of what they might be given as.\n", "\t\t * @returns {array} Data for the matched elements. If any elements, as a result of the\n", "\t\t * selector, were not TR, TD or TH elements in the DataTable, they will have a null\n", "\t\t * entry in the array.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Get the data from the first row in the table\n", "\t\t * var data = oTable._('tr:first');\n", "\t\t *\n", "\t\t * // Do something useful with the data\n", "\t\t * alert( \"First cell is: \"+data[0] );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Filter to 'Webkit' and get all data for\n", "\t\t * oTable.fnFilter('Webkit');\n", "\t\t * var data = oTable._('tr', {\"search\": \"applied\"});\n", "\t\t *\n", "\t\t * // Do something with the data\n", "\t\t * alert( data.length+\" rows matched the search\" );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis._ = function ( sSelector, oOpts )\n", "\t\t{\n", "\t\t\treturn this.api(true).rows( sSelector, oOpts ).data();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Create a DataTables Api instance, with the currently selected tables for\n", "\t\t * the Api's context.\n", "\t\t * @param {boolean} [traditional=false] Set the API instance's context to be\n", "\t\t * only the table referred to by the `DataTable.ext.iApiIndex` option, as was\n", "\t\t * used in the API presented by DataTables 1.9- (i.e. the traditional mode),\n", "\t\t * or if all tables captured in the jQuery object should be used.\n", "\t\t * @return {DataTables.Api}\n", "\t\t */\n", "\t\tthis.api = function ( traditional )\n", "\t\t{\n", "\t\t\treturn traditional ?\n", "\t\t\t\tnew _Api(\n", "\t\t\t\t\t_fnSettingsFromNode( this[ _ext.iApiIndex ] )\n", "\t\t\t\t) :\n", "\t\t\t\tnew _Api( this );\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Add a single new row or multiple rows of data to the table. Please note\n", "\t\t * that this is suitable for client-side processing only - if you are using\n", "\t\t * server-side processing (i.e. \"bServerSide\": true), then to add data, you\n", "\t\t * must add it to the data source, i.e. the server-side, through an Ajax call.\n", "\t\t * @param {array|object} data The data to be added to the table. This can be:\n", "\t\t * <ul>\n", "\t\t * <li>1D array of data - add a single row with the data provided</li>\n", "\t\t * <li>2D array of arrays - add multiple rows in a single call</li>\n", "\t\t * <li>object - data object when using <i>mData</i></li>\n", "\t\t * <li>array of objects - multiple data objects when using <i>mData</i></li>\n", "\t\t * </ul>\n", "\t\t * @param {bool} [redraw=true] redraw the table or not\n", "\t\t * @returns {array} An array of integers, representing the list of indexes in\n", "\t\t * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to\n", "\t\t * the table.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Global var for counter\n", "\t\t * var giCount = 2;\n", "\t\t *\n", "\t\t * $(document).ready(function() {\n", "\t\t * $('#example').dataTable();\n", "\t\t * } );\n", "\t\t *\n", "\t\t * function fnClickAddRow() {\n", "\t\t * $('#example').dataTable().fnAddData( [\n", "\t\t * giCount+\".1\",\n", "\t\t * giCount+\".2\",\n", "\t\t * giCount+\".3\",\n", "\t\t * giCount+\".4\" ]\n", "\t\t * );\n", "\t\t *\n", "\t\t * giCount++;\n", "\t\t * }\n", "\t\t */\n", "\t\tthis.fnAddData = function( data, redraw )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\n", "\t\t\t/* Check if we want to add multiple rows or not */\n", "\t\t\tvar rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\n", "\t\t\t\tapi.rows.add( data ) :\n", "\t\t\t\tapi.row.add( data );\n", "\t\t\n", "\t\t\tif ( redraw === undefined || redraw ) {\n", "\t\t\t\tapi.draw();\n", "\t\t\t}\n", "\t\t\n", "\t\t\treturn rows.flatten().toArray();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * This function will make DataTables recalculate the column sizes, based on the data\n", "\t\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\n", "\t\t * through the sWidth parameter). This can be useful when the width of the table's\n", "\t\t * parent element changes (for example a window resize).\n", "\t\t * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable( {\n", "\t\t * \"sScrollY\": \"200px\",\n", "\t\t * \"bPaginate\": false\n", "\t\t * } );\n", "\t\t *\n", "\t\t * $(window).on('resize', function () {\n", "\t\t * oTable.fnAdjustColumnSizing();\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnAdjustColumnSizing = function ( bRedraw )\n", "\t\t{\n", "\t\t\tvar api = this.api( true ).columns.adjust();\n", "\t\t\tvar settings = api.settings()[0];\n", "\t\t\tvar scroll = settings.oScroll;\n", "\t\t\n", "\t\t\tif ( bRedraw === undefined || bRedraw ) {\n", "\t\t\t\tapi.draw( false );\n", "\t\t\t}\n", "\t\t\telse if ( scroll.sX !== \"\" || scroll.sY !== \"\" ) {\n", "\t\t\t\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\n", "\t\t\t\t_fnScrollDraw( settings );\n", "\t\t\t}\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Quickly and simply clear a table\n", "\t\t * @param {bool} [bRedraw=true] redraw the table or not\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\n", "\t\t * oTable.fnClearTable();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnClearTable = function( bRedraw )\n", "\t\t{\n", "\t\t\tvar api = this.api( true ).clear();\n", "\t\t\n", "\t\t\tif ( bRedraw === undefined || bRedraw ) {\n", "\t\t\t\tapi.draw();\n", "\t\t\t}\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * The exact opposite of 'opening' a row, this function will close any rows which\n", "\t\t * are currently 'open'.\n", "\t\t * @param {node} nTr the table row to 'close'\n", "\t\t * @returns {int} 0 on success, or 1 if failed (can't find the row)\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable;\n", "\t\t *\n", "\t\t * // 'open' an information row when a row is clicked on\n", "\t\t * $('#example tbody tr').click( function () {\n", "\t\t * if ( oTable.fnIsOpen(this) ) {\n", "\t\t * oTable.fnClose( this );\n", "\t\t * } else {\n", "\t\t * oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * oTable = $('#example').dataTable();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnClose = function( nTr )\n", "\t\t{\n", "\t\t\tthis.api( true ).row( nTr ).child.hide();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Remove a row for the table\n", "\t\t * @param {mixed} target The index of the row from aoData to be deleted, or\n", "\t\t * the TR element you want to delete\n", "\t\t * @param {function|null} [callBack] Callback function\n", "\t\t * @param {bool} [redraw=true] Redraw the table or not\n", "\t\t * @returns {array} The row that was deleted\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Immediately remove the first row\n", "\t\t * oTable.fnDeleteRow( 0 );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnDeleteRow = function( target, callback, redraw )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\tvar rows = api.rows( target );\n", "\t\t\tvar settings = rows.settings()[0];\n", "\t\t\tvar data = settings.aoData[ rows[0][0] ];\n", "\t\t\n", "\t\t\trows.remove();\n", "\t\t\n", "\t\t\tif ( callback ) {\n", "\t\t\t\tcallback.call( this, settings, data );\n", "\t\t\t}\n", "\t\t\n", "\t\t\tif ( redraw === undefined || redraw ) {\n", "\t\t\t\tapi.draw();\n", "\t\t\t}\n", "\t\t\n", "\t\t\treturn data;\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Restore the table to it's original state in the DOM by removing all of DataTables\n", "\t\t * enhancements, alterations to the DOM structure of the table and event listeners.\n", "\t\t * @param {boolean} [remove=false] Completely remove the table from the DOM\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * // This example is fairly pointless in reality, but shows how fnDestroy can be used\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t * oTable.fnDestroy();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnDestroy = function ( remove )\n", "\t\t{\n", "\t\t\tthis.api( true ).destroy( remove );\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Redraw the table\n", "\t\t * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\n", "\t\t * oTable.fnDraw();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnDraw = function( complete )\n", "\t\t{\n", "\t\t\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\n", "\t\t\t// into account the new data, but can hold position.\n", "\t\t\tthis.api( true ).draw( complete );\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Filter the input based on data\n", "\t\t * @param {string} sInput String to filter the table on\n", "\t\t * @param {int|null} [iColumn] Column to limit filtering to\n", "\t\t * @param {bool} [bRegex=false] Treat as regular expression or not\n", "\t\t * @param {bool} [bSmart=true] Perform smart filtering or not\n", "\t\t * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\n", "\t\t * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Sometime later - filter...\n", "\t\t * oTable.fnFilter( 'test string' );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\n", "\t\t\tif ( iColumn === null || iColumn === undefined ) {\n", "\t\t\t\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\n", "\t\t\t}\n", "\t\t\n", "\t\t\tapi.draw();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Get the data for the whole table, an individual row or an individual cell based on the\n", "\t\t * provided parameters.\n", "\t\t * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\n", "\t\t * a TR node then the data source for the whole row will be returned. If given as a\n", "\t\t * TD/TH cell node then iCol will be automatically calculated and the data for the\n", "\t\t * cell returned. If given as an integer, then this is treated as the aoData internal\n", "\t\t * data index for the row (see fnGetPosition) and the data for that row used.\n", "\t\t * @param {int} [col] Optional column index that you want the data of.\n", "\t\t * @returns {array|object|string} If mRow is undefined, then the data for all rows is\n", "\t\t * returned. If mRow is defined, just data for that row, and is iCol is\n", "\t\t * defined, only data for the designated cell is returned.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Row data\n", "\t\t * $(document).ready(function() {\n", "\t\t * oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * oTable.$('tr').click( function () {\n", "\t\t * var data = oTable.fnGetData( this );\n", "\t\t * // ... do something with the array / object of data for the row\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Individual cell data\n", "\t\t * $(document).ready(function() {\n", "\t\t * oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * oTable.$('td').click( function () {\n", "\t\t * var sData = oTable.fnGetData( this );\n", "\t\t * alert( 'The cell clicked on had the value of '+sData );\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnGetData = function( src, col )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\n", "\t\t\tif ( src !== undefined ) {\n", "\t\t\t\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\n", "\t\t\n", "\t\t\t\treturn col !== undefined || type == 'td' || type == 'th' ?\n", "\t\t\t\t\tapi.cell( src, col ).data() :\n", "\t\t\t\t\tapi.row( src ).data() || null;\n", "\t\t\t}\n", "\t\t\n", "\t\t\treturn api.data().toArray();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Get an array of the TR nodes that are used in the table's body. Note that you will\n", "\t\t * typically want to use the '$' API method in preference to this as it is more\n", "\t\t * flexible.\n", "\t\t * @param {int} [iRow] Optional row index for the TR element you want\n", "\t\t * @returns {array|node} If iRow is undefined, returns an array of all TR elements\n", "\t\t * in the table's body, or iRow is defined, just the TR element requested.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Get the nodes from the table\n", "\t\t * var nNodes = oTable.fnGetNodes( );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnGetNodes = function( iRow )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\n", "\t\t\treturn iRow !== undefined ?\n", "\t\t\t\tapi.row( iRow ).node() :\n", "\t\t\t\tapi.rows().nodes().flatten().toArray();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Get the array indexes of a particular cell from it's DOM element\n", "\t\t * and column index including hidden columns\n", "\t\t * @param {node} node this can either be a TR, TD or TH in the table's body\n", "\t\t * @returns {int} If nNode is given as a TR, then a single index is returned, or\n", "\t\t * if given as a cell, an array of [row index, column index (visible),\n", "\t\t * column index (all)] is given.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * $('#example tbody td').click( function () {\n", "\t\t * // Get the position of the current data from the node\n", "\t\t * var aPos = oTable.fnGetPosition( this );\n", "\t\t *\n", "\t\t * // Get the data array for this row\n", "\t\t * var aData = oTable.fnGetData( aPos[0] );\n", "\t\t *\n", "\t\t * // Update the data array and return the value\n", "\t\t * aData[ aPos[1] ] = 'clicked';\n", "\t\t * this.innerHTML = 'clicked';\n", "\t\t * } );\n", "\t\t *\n", "\t\t * // Init DataTables\n", "\t\t * oTable = $('#example').dataTable();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnGetPosition = function( node )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\tvar nodeName = node.nodeName.toUpperCase();\n", "\t\t\n", "\t\t\tif ( nodeName == 'TR' ) {\n", "\t\t\t\treturn api.row( node ).index();\n", "\t\t\t}\n", "\t\t\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\n", "\t\t\t\tvar cell = api.cell( node ).index();\n", "\t\t\n", "\t\t\t\treturn [\n", "\t\t\t\t\tcell.row,\n", "\t\t\t\t\tcell.columnVisible,\n", "\t\t\t\t\tcell.column\n", "\t\t\t\t];\n", "\t\t\t}\n", "\t\t\treturn null;\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Check to see if a row is 'open' or not.\n", "\t\t * @param {node} nTr the table row to check\n", "\t\t * @returns {boolean} true if the row is currently open, false otherwise\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable;\n", "\t\t *\n", "\t\t * // 'open' an information row when a row is clicked on\n", "\t\t * $('#example tbody tr').click( function () {\n", "\t\t * if ( oTable.fnIsOpen(this) ) {\n", "\t\t * oTable.fnClose( this );\n", "\t\t * } else {\n", "\t\t * oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * oTable = $('#example').dataTable();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnIsOpen = function( nTr )\n", "\t\t{\n", "\t\t\treturn this.api( true ).row( nTr ).child.isShown();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * This function will place a new row directly after a row which is currently\n", "\t\t * on display on the page, with the HTML contents that is passed into the\n", "\t\t * function. This can be used, for example, to ask for confirmation that a\n", "\t\t * particular record should be deleted.\n", "\t\t * @param {node} nTr The table row to 'open'\n", "\t\t * @param {string|node|jQuery} mHtml The HTML to put into the row\n", "\t\t * @param {string} sClass Class to give the new TD cell\n", "\t\t * @returns {node} The row opened. Note that if the table row passed in as the\n", "\t\t * first parameter, is not found in the table, this method will silently\n", "\t\t * return.\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable;\n", "\t\t *\n", "\t\t * // 'open' an information row when a row is clicked on\n", "\t\t * $('#example tbody tr').click( function () {\n", "\t\t * if ( oTable.fnIsOpen(this) ) {\n", "\t\t * oTable.fnClose( this );\n", "\t\t * } else {\n", "\t\t * oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * oTable = $('#example').dataTable();\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnOpen = function( nTr, mHtml, sClass )\n", "\t\t{\n", "\t\t\treturn this.api( true )\n", "\t\t\t\t.row( nTr )\n", "\t\t\t\t.child( mHtml, sClass )\n", "\t\t\t\t.show()\n", "\t\t\t\t.child()[0];\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Change the pagination - provides the internal logic for pagination in a simple API\n", "\t\t * function. With this function you can have a DataTables table go to the next,\n", "\t\t * previous, first or last pages.\n", "\t\t * @param {string|int} mAction Paging action to take: \"first\", \"previous\", \"next\" or \"last\"\n", "\t\t * or page number to jump to (integer), note that page 0 is the first page.\n", "\t\t * @param {bool} [bRedraw=true] Redraw the table or not\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t * oTable.fnPageChange( 'next' );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnPageChange = function ( mAction, bRedraw )\n", "\t\t{\n", "\t\t\tvar api = this.api( true ).page( mAction );\n", "\t\t\n", "\t\t\tif ( bRedraw === undefined || bRedraw ) {\n", "\t\t\t\tapi.draw(false);\n", "\t\t\t}\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Show a particular column\n", "\t\t * @param {int} iCol The column whose display should be changed\n", "\t\t * @param {bool} bShow Show (true) or hide (false) the column\n", "\t\t * @param {bool} [bRedraw=true] Redraw the table or not\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Hide the second column after initialisation\n", "\t\t * oTable.fnSetColumnVis( 1, false );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\n", "\t\t{\n", "\t\t\tvar api = this.api( true ).column( iCol ).visible( bShow );\n", "\t\t\n", "\t\t\tif ( bRedraw === undefined || bRedraw ) {\n", "\t\t\t\tapi.columns.adjust().draw();\n", "\t\t\t}\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Get the settings for a particular table for external manipulation\n", "\t\t * @returns {object} DataTables settings object. See\n", "\t\t * {@link DataTable.models.oSettings}\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t * var oSettings = oTable.fnSettings();\n", "\t\t *\n", "\t\t * // Show an example parameter from the settings\n", "\t\t * alert( oSettings._iDisplayStart );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnSettings = function()\n", "\t\t{\n", "\t\t\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Sort the table by a particular column\n", "\t\t * @param {int} iCol the data index to sort on. Note that this will not match the\n", "\t\t * 'display index' if you have hidden data entries\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Sort immediately with columns 0 and 1\n", "\t\t * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnSort = function( aaSort )\n", "\t\t{\n", "\t\t\tthis.api( true ).order( aaSort ).draw();\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Attach a sort listener to an element for a given column\n", "\t\t * @param {node} nNode the element to attach the sort listener to\n", "\t\t * @param {int} iColumn the column that a click on this node will sort on\n", "\t\t * @param {function} [fnCallback] callback function when sort is run\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t *\n", "\t\t * // Sort on column 1, when 'sorter' is clicked on\n", "\t\t * oTable.fnSortListener( document.getElementById('sorter'), 1 );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\n", "\t\t{\n", "\t\t\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Update a table cell or row - this method will accept either a single value to\n", "\t\t * update the cell with, an array of values with one element for each column or\n", "\t\t * an object in the same format as the original data source. The function is\n", "\t\t * self-referencing in order to make the multi column updates easier.\n", "\t\t * @param {object|array|string} mData Data to update the cell/row with\n", "\t\t * @param {node|int} mRow TR element you want to update or the aoData index\n", "\t\t * @param {int} [iColumn] The column to update, give as null or undefined to\n", "\t\t * update a whole row.\n", "\t\t * @param {bool} [bRedraw=true] Redraw the table or not\n", "\t\t * @param {bool} [bAction=true] Perform pre-draw actions or not\n", "\t\t * @returns {int} 0 on success, 1 on error\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\n", "\t\t * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\n", "\t\t{\n", "\t\t\tvar api = this.api( true );\n", "\t\t\n", "\t\t\tif ( iColumn === undefined || iColumn === null ) {\n", "\t\t\t\tapi.row( mRow ).data( mData );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tapi.cell( mRow, iColumn ).data( mData );\n", "\t\t\t}\n", "\t\t\n", "\t\t\tif ( bAction === undefined || bAction ) {\n", "\t\t\t\tapi.columns.adjust();\n", "\t\t\t}\n", "\t\t\n", "\t\t\tif ( bRedraw === undefined || bRedraw ) {\n", "\t\t\t\tapi.draw();\n", "\t\t\t}\n", "\t\t\treturn 0;\n", "\t\t};\n", "\t\t\n", "\t\t\n", "\t\t/**\n", "\t\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\n", "\t\t * to ensure compatibility.\n", "\t\t * @param {string} sVersion Version string to check for, in the format \"X.Y.Z\". Note that the\n", "\t\t * formats \"X\" and \"X.Y\" are also acceptable.\n", "\t\t * @returns {boolean} true if this version of DataTables is greater or equal to the required\n", "\t\t * version, or false if this version of DataTales is not suitable\n", "\t\t * @method\n", "\t\t * @dtopt API\n", "\t\t * @deprecated Since v1.10\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready(function() {\n", "\t\t * var oTable = $('#example').dataTable();\n", "\t\t * alert( oTable.fnVersionCheck( '1.9.0' ) );\n", "\t\t * } );\n", "\t\t */\n", "\t\tthis.fnVersionCheck = _ext.fnVersionCheck;\n", "\t\t\n", "\n", "\t\tvar _that = this;\n", "\t\tvar emptyInit = options === undefined;\n", "\t\tvar len = this.length;\n", "\n", "\t\tif ( emptyInit ) {\n", "\t\t\toptions = {};\n", "\t\t}\n", "\n", "\t\tthis.oApi = this.internal = _ext.internal;\n", "\n", "\t\t// Extend with old style plug-in API methods\n", "\t\tfor ( var fn in DataTable.ext.internal ) {\n", "\t\t\tif ( fn ) {\n", "\t\t\t\tthis[fn] = _fnExternApiFunc(fn);\n", "\t\t\t}\n", "\t\t}\n", "\n", "\t\tthis.each(function() {\n", "\t\t\t// For each initialisation we want to give it a clean initialisation\n", "\t\t\t// object that can be bashed around\n", "\t\t\tvar o = {};\n", "\t\t\tvar oInit = len > 1 ? // optimisation for single table case\n", "\t\t\t\t_fnExtend( o, options, true ) :\n", "\t\t\t\toptions;\n", "\n", "\t\t\t/*global oInit,_that,emptyInit*/\n", "\t\t\tvar i=0, iLen, j, jLen, k, kLen;\n", "\t\t\tvar sId = this.getAttribute( 'id' );\n", "\t\t\tvar bInitHandedOff = false;\n", "\t\t\tvar defaults = DataTable.defaults;\n", "\t\t\tvar $this = $(this);\n", "\t\t\t\n", "\t\t\t\n", "\t\t\t/* Sanity check */\n", "\t\t\tif ( this.nodeName.toLowerCase() != 'table' )\n", "\t\t\t{\n", "\t\t\t\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Backwards compatibility for the defaults */\n", "\t\t\t_fnCompatOpts( defaults );\n", "\t\t\t_fnCompatCols( defaults.column );\n", "\t\t\t\n", "\t\t\t/* Convert the camel-case defaults to Hungarian */\n", "\t\t\t_fnCamelToHungarian( defaults, defaults, true );\n", "\t\t\t_fnCamelToHungarian( defaults.column, defaults.column, true );\n", "\t\t\t\n", "\t\t\t/* Setting up the initialisation object */\n", "\t\t\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );\n", "\t\t\t\n", "\t\t\t\n", "\t\t\t\n", "\t\t\t/* Check to see if we are re-initialising a table */\n", "\t\t\tvar allSettings = DataTable.settings;\n", "\t\t\tfor ( i=0, iLen=allSettings.length ; i<iLen ; i++ )\n", "\t\t\t{\n", "\t\t\t\tvar s = allSettings[i];\n", "\t\t\t\n", "\t\t\t\t/* Base check on table node */\n", "\t\t\t\tif ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )\n", "\t\t\t\t{\n", "\t\t\t\t\tvar bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;\n", "\t\t\t\t\tvar bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;\n", "\t\t\t\n", "\t\t\t\t\tif ( emptyInit || bRetrieve )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\treturn s.oInstance;\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( bDestroy )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\ts.oInstance.fnDestroy();\n", "\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );\n", "\t\t\t\t\t\treturn;\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\n", "\t\t\t\t/* If the element we are initialising has the same ID as a table which was previously\n", "\t\t\t\t * initialised, but the table nodes don't match (from before) then we destroy the old\n", "\t\t\t\t * instance by simply deleting it. This is under the assumption that the table has been\n", "\t\t\t\t * destroyed by other methods. Anyone using non-id selectors will need to do this manually\n", "\t\t\t\t */\n", "\t\t\t\tif ( s.sTableId == this.id )\n", "\t\t\t\t{\n", "\t\t\t\t\tallSettings.splice( i, 1 );\n", "\t\t\t\t\tbreak;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Ensure the table has an ID - required for accessibility */\n", "\t\t\tif ( sId === null || sId === \"\" )\n", "\t\t\t{\n", "\t\t\t\tsId = \"DataTables_Table_\"+(DataTable.ext._unique++);\n", "\t\t\t\tthis.id = sId;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Create the settings object for this table and set some of the default parameters */\n", "\t\t\tvar oSettings = $.extend( true, {}, DataTable.models.oSettings, {\n", "\t\t\t\t\"sDestroyWidth\": $this[0].style.width,\n", "\t\t\t\t\"sInstance\": sId,\n", "\t\t\t\t\"sTableId\": sId\n", "\t\t\t} );\n", "\t\t\toSettings.nTable = this;\n", "\t\t\toSettings.oApi = _that.internal;\n", "\t\t\toSettings.oInit = oInit;\n", "\t\t\t\n", "\t\t\tallSettings.push( oSettings );\n", "\t\t\t\n", "\t\t\t// Need to add the instance after the instance after the settings object has been added\n", "\t\t\t// to the settings array, so we can self reference the table instance if more than one\n", "\t\t\toSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();\n", "\t\t\t\n", "\t\t\t// Backwards compatibility, before we apply all the defaults\n", "\t\t\t_fnCompatOpts( oInit );\n", "\t\t\t\n", "\t\t\tif ( oInit.oLanguage )\n", "\t\t\t{\n", "\t\t\t\t_fnLanguageCompat( oInit.oLanguage );\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t// If the length menu is given, but the init display length is not, use the length menu\n", "\t\t\tif ( oInit.aLengthMenu && ! oInit.iDisplayLength )\n", "\t\t\t{\n", "\t\t\t\toInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?\n", "\t\t\t\t\toInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t// Apply the defaults and init options to make a single init object will all\n", "\t\t\t// options defined from defaults and instance options.\n", "\t\t\toInit = _fnExtend( $.extend( true, {}, defaults ), oInit );\n", "\t\t\t\n", "\t\t\t\n", "\t\t\t// Map the initialisation options onto the settings object\n", "\t\t\t_fnMap( oSettings.oFeatures, oInit, [\n", "\t\t\t\t\"bPaginate\",\n", "\t\t\t\t\"bLengthChange\",\n", "\t\t\t\t\"bFilter\",\n", "\t\t\t\t\"bSort\",\n", "\t\t\t\t\"bSortMulti\",\n", "\t\t\t\t\"bInfo\",\n", "\t\t\t\t\"bProcessing\",\n", "\t\t\t\t\"bAutoWidth\",\n", "\t\t\t\t\"bSortClasses\",\n", "\t\t\t\t\"bServerSide\",\n", "\t\t\t\t\"bDeferRender\"\n", "\t\t\t] );\n", "\t\t\t_fnMap( oSettings, oInit, [\n", "\t\t\t\t\"asStripeClasses\",\n", "\t\t\t\t\"ajax\",\n", "\t\t\t\t\"fnServerData\",\n", "\t\t\t\t\"fnFormatNumber\",\n", "\t\t\t\t\"sServerMethod\",\n", "\t\t\t\t\"aaSorting\",\n", "\t\t\t\t\"aaSortingFixed\",\n", "\t\t\t\t\"aLengthMenu\",\n", "\t\t\t\t\"sPaginationType\",\n", "\t\t\t\t\"sAjaxSource\",\n", "\t\t\t\t\"sAjaxDataProp\",\n", "\t\t\t\t\"iStateDuration\",\n", "\t\t\t\t\"sDom\",\n", "\t\t\t\t\"bSortCellsTop\",\n", "\t\t\t\t\"iTabIndex\",\n", "\t\t\t\t\"fnStateLoadCallback\",\n", "\t\t\t\t\"fnStateSaveCallback\",\n", "\t\t\t\t\"renderer\",\n", "\t\t\t\t\"searchDelay\",\n", "\t\t\t\t\"rowId\",\n", "\t\t\t\t[ \"iCookieDuration\", \"iStateDuration\" ], // backwards compat\n", "\t\t\t\t[ \"oSearch\", \"oPreviousSearch\" ],\n", "\t\t\t\t[ \"aoSearchCols\", \"aoPreSearchCols\" ],\n", "\t\t\t\t[ \"iDisplayLength\", \"_iDisplayLength\" ]\n", "\t\t\t] );\n", "\t\t\t_fnMap( oSettings.oScroll, oInit, [\n", "\t\t\t\t[ \"sScrollX\", \"sX\" ],\n", "\t\t\t\t[ \"sScrollXInner\", \"sXInner\" ],\n", "\t\t\t\t[ \"sScrollY\", \"sY\" ],\n", "\t\t\t\t[ \"bScrollCollapse\", \"bCollapse\" ]\n", "\t\t\t] );\n", "\t\t\t_fnMap( oSettings.oLanguage, oInit, \"fnInfoCallback\" );\n", "\t\t\t\n", "\t\t\t/* Callback functions which are array driven */\n", "\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );\n", "\t\t\t_fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );\n", "\t\t\t\n", "\t\t\toSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );\n", "\t\t\t\n", "\t\t\t/* Browser support detection */\n", "\t\t\t_fnBrowserDetect( oSettings );\n", "\t\t\t\n", "\t\t\tvar oClasses = oSettings.oClasses;\n", "\t\t\t\n", "\t\t\t$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );\n", "\t\t\t$this.addClass( oClasses.sTable );\n", "\t\t\t\n", "\t\t\t\n", "\t\t\tif ( oSettings.iInitDisplayStart === undefined )\n", "\t\t\t{\n", "\t\t\t\t/* Display start point, taking into account the save saving */\n", "\t\t\t\toSettings.iInitDisplayStart = oInit.iDisplayStart;\n", "\t\t\t\toSettings._iDisplayStart = oInit.iDisplayStart;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\tif ( oInit.iDeferLoading !== null )\n", "\t\t\t{\n", "\t\t\t\toSettings.bDeferLoading = true;\n", "\t\t\t\tvar tmp = $.isArray( oInit.iDeferLoading );\n", "\t\t\t\toSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;\n", "\t\t\t\toSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Language definitions */\n", "\t\t\tvar oLanguage = oSettings.oLanguage;\n", "\t\t\t$.extend( true, oLanguage, oInit.oLanguage );\n", "\t\t\t\n", "\t\t\tif ( oLanguage.sUrl )\n", "\t\t\t{\n", "\t\t\t\t/* Get the language definitions from a file - because this Ajax call makes the language\n", "\t\t\t\t * get async to the remainder of this function we use bInitHandedOff to indicate that\n", "\t\t\t\t * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor\n", "\t\t\t\t */\n", "\t\t\t\t$.ajax( {\n", "\t\t\t\t\tdataType: 'json',\n", "\t\t\t\t\turl: oLanguage.sUrl,\n", "\t\t\t\t\tsuccess: function ( json ) {\n", "\t\t\t\t\t\t_fnLanguageCompat( json );\n", "\t\t\t\t\t\t_fnCamelToHungarian( defaults.oLanguage, json );\n", "\t\t\t\t\t\t$.extend( true, oLanguage, json );\n", "\t\t\t\t\t\t_fnInitialise( oSettings );\n", "\t\t\t\t\t},\n", "\t\t\t\t\terror: function () {\n", "\t\t\t\t\t\t// Error occurred loading language file, continue on as best we can\n", "\t\t\t\t\t\t_fnInitialise( oSettings );\n", "\t\t\t\t\t}\n", "\t\t\t\t} );\n", "\t\t\t\tbInitHandedOff = true;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/*\n", "\t\t\t * Stripes\n", "\t\t\t */\n", "\t\t\tif ( oInit.asStripeClasses === null )\n", "\t\t\t{\n", "\t\t\t\toSettings.asStripeClasses =[\n", "\t\t\t\t\toClasses.sStripeOdd,\n", "\t\t\t\t\toClasses.sStripeEven\n", "\t\t\t\t];\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Remove row stripe classes if they are already on the table row */\n", "\t\t\tvar stripeClasses = oSettings.asStripeClasses;\n", "\t\t\tvar rowOne = $this.children('tbody').find('tr').eq(0);\n", "\t\t\tif ( $.inArray( true, $.map( stripeClasses, function(el, i) {\n", "\t\t\t\treturn rowOne.hasClass(el);\n", "\t\t\t} ) ) !== -1 ) {\n", "\t\t\t\t$('tbody tr', this).removeClass( stripeClasses.join(' ') );\n", "\t\t\t\toSettings.asDestroyStripes = stripeClasses.slice();\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/*\n", "\t\t\t * Columns\n", "\t\t\t * See if we should load columns automatically or use defined ones\n", "\t\t\t */\n", "\t\t\tvar anThs = [];\n", "\t\t\tvar aoColumnsInit;\n", "\t\t\tvar nThead = this.getElementsByTagName('thead');\n", "\t\t\tif ( nThead.length !== 0 )\n", "\t\t\t{\n", "\t\t\t\t_fnDetectHeader( oSettings.aoHeader, nThead[0] );\n", "\t\t\t\tanThs = _fnGetUniqueThs( oSettings );\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* If not given a column array, generate one with nulls */\n", "\t\t\tif ( oInit.aoColumns === null )\n", "\t\t\t{\n", "\t\t\t\taoColumnsInit = [];\n", "\t\t\t\tfor ( i=0, iLen=anThs.length ; i<iLen ; i++ )\n", "\t\t\t\t{\n", "\t\t\t\t\taoColumnsInit.push( null );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t\telse\n", "\t\t\t{\n", "\t\t\t\taoColumnsInit = oInit.aoColumns;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Add the columns */\n", "\t\t\tfor ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )\n", "\t\t\t{\n", "\t\t\t\t_fnAddColumn( oSettings, anThs ? anThs[i] : null );\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t/* Apply the column definitions */\n", "\t\t\t_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {\n", "\t\t\t\t_fnColumnOptions( oSettings, iCol, oDef );\n", "\t\t\t} );\n", "\t\t\t\n", "\t\t\t/* HTML5 attribute detection - build an mData object automatically if the\n", "\t\t\t * attributes are found\n", "\t\t\t */\n", "\t\t\tif ( rowOne.length ) {\n", "\t\t\t\tvar a = function ( cell, name ) {\n", "\t\t\t\t\treturn cell.getAttribute( 'data-'+name ) !== null ? name : null;\n", "\t\t\t\t};\n", "\t\t\t\n", "\t\t\t\t$( rowOne[0] ).children('th, td').each( function (i, cell) {\n", "\t\t\t\t\tvar col = oSettings.aoColumns[i];\n", "\t\t\t\n", "\t\t\t\t\tif ( col.mData === i ) {\n", "\t\t\t\t\t\tvar sort = a( cell, 'sort' ) || a( cell, 'order' );\n", "\t\t\t\t\t\tvar filter = a( cell, 'filter' ) || a( cell, 'search' );\n", "\t\t\t\n", "\t\t\t\t\t\tif ( sort !== null || filter !== null ) {\n", "\t\t\t\t\t\t\tcol.mData = {\n", "\t\t\t\t\t\t\t\t_: i+'.display',\n", "\t\t\t\t\t\t\t\tsort: sort !== null ? i+'.@data-'+sort : undefined,\n", "\t\t\t\t\t\t\t\ttype: sort !== null ? i+'.@data-'+sort : undefined,\n", "\t\t\t\t\t\t\t\tfilter: filter !== null ? i+'.@data-'+filter : undefined\n", "\t\t\t\t\t\t\t};\n", "\t\t\t\n", "\t\t\t\t\t\t\t_fnColumnOptions( oSettings, i );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\tvar features = oSettings.oFeatures;\n", "\t\t\tvar loadedInit = function () {\n", "\t\t\t\t/*\n", "\t\t\t\t * Sorting\n", "\t\t\t\t * @todo For modularisation (1.11) this needs to do into a sort start up handler\n", "\t\t\t\t */\n", "\t\t\t\n", "\t\t\t\t// If aaSorting is not defined, then we use the first indicator in asSorting\n", "\t\t\t\t// in case that has been altered, so the default sort reflects that option\n", "\t\t\t\tif ( oInit.aaSorting === undefined ) {\n", "\t\t\t\t\tvar sorting = oSettings.aaSorting;\n", "\t\t\t\t\tfor ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {\n", "\t\t\t\t\t\tsorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\n", "\t\t\t\t/* Do a first pass on the sorting classes (allows any size changes to be taken into\n", "\t\t\t\t * account, and also will apply sorting disabled classes if disabled\n", "\t\t\t\t */\n", "\t\t\t\t_fnSortingClasses( oSettings );\n", "\t\t\t\n", "\t\t\t\tif ( features.bSort ) {\n", "\t\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n", "\t\t\t\t\t\tif ( oSettings.bSorted ) {\n", "\t\t\t\t\t\t\tvar aSort = _fnSortFlatten( oSettings );\n", "\t\t\t\t\t\t\tvar sortedColumns = {};\n", "\t\t\t\n", "\t\t\t\t\t\t\t$.each( aSort, function (i, val) {\n", "\t\t\t\t\t\t\t\tsortedColumns[ val.src ] = val.dir;\n", "\t\t\t\t\t\t\t} );\n", "\t\t\t\n", "\t\t\t\t\t\t\t_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );\n", "\t\t\t\t\t\t\t_fnSortAria( oSettings );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t} );\n", "\t\t\t\t}\n", "\t\t\t\n", "\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n", "\t\t\t\t\tif ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {\n", "\t\t\t\t\t\t_fnSortingClasses( oSettings );\n", "\t\t\t\t\t}\n", "\t\t\t\t}, 'sc' );\n", "\t\t\t\n", "\t\t\t\n", "\t\t\t\t/*\n", "\t\t\t\t * Final init\n", "\t\t\t\t * Cache the header, body and footer as required, creating them if needed\n", "\t\t\t\t */\n", "\t\t\t\n", "\t\t\t\t// Work around for Webkit bug 83867 - store the caption-side before removing from doc\n", "\t\t\t\tvar captions = $this.children('caption').each( function () {\n", "\t\t\t\t\tthis._captionSide = $(this).css('caption-side');\n", "\t\t\t\t} );\n", "\t\t\t\n", "\t\t\t\tvar thead = $this.children('thead');\n", "\t\t\t\tif ( thead.length === 0 ) {\n", "\t\t\t\t\tthead = $('<thead/>').appendTo($this);\n", "\t\t\t\t}\n", "\t\t\t\toSettings.nTHead = thead[0];\n", "\t\t\t\n", "\t\t\t\tvar tbody = $this.children('tbody');\n", "\t\t\t\tif ( tbody.length === 0 ) {\n", "\t\t\t\t\ttbody = $('<tbody/>').appendTo($this);\n", "\t\t\t\t}\n", "\t\t\t\toSettings.nTBody = tbody[0];\n", "\t\t\t\n", "\t\t\t\tvar tfoot = $this.children('tfoot');\n", "\t\t\t\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") ) {\n", "\t\t\t\t\t// If we are a scrolling table, and no footer has been given, then we need to create\n", "\t\t\t\t\t// a tfoot element for the caption element to be appended to\n", "\t\t\t\t\ttfoot = $('<tfoot/>').appendTo($this);\n", "\t\t\t\t}\n", "\t\t\t\n", "\t\t\t\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\n", "\t\t\t\t\t$this.addClass( oClasses.sNoFooter );\n", "\t\t\t\t}\n", "\t\t\t\telse if ( tfoot.length > 0 ) {\n", "\t\t\t\t\toSettings.nTFoot = tfoot[0];\n", "\t\t\t\t\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\n", "\t\t\t\t}\n", "\t\t\t\n", "\t\t\t\t/* Check if there is data passing into the constructor */\n", "\t\t\t\tif ( oInit.aaData ) {\n", "\t\t\t\t\tfor ( i=0 ; i<oInit.aaData.length ; i++ ) {\n", "\t\t\t\t\t\t_fnAddData( oSettings, oInit.aaData[ i ] );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\telse if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {\n", "\t\t\t\t\t/* Grab the data from the page - only do this when deferred loading or no Ajax\n", "\t\t\t\t\t * source since there is no point in reading the DOM data if we are then going\n", "\t\t\t\t\t * to replace it with Ajax data\n", "\t\t\t\t\t */\n", "\t\t\t\t\t_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );\n", "\t\t\t\t}\n", "\t\t\t\n", "\t\t\t\t/* Copy the data index array */\n", "\t\t\t\toSettings.aiDisplay = oSettings.aiDisplayMaster.slice();\n", "\t\t\t\n", "\t\t\t\t/* Initialisation complete - table can be drawn */\n", "\t\t\t\toSettings.bInitialised = true;\n", "\t\t\t\n", "\t\t\t\t/* Check if we need to initialise the table (it might not have been handed off to the\n", "\t\t\t\t * language processor)\n", "\t\t\t\t */\n", "\t\t\t\tif ( bInitHandedOff === false ) {\n", "\t\t\t\t\t_fnInitialise( oSettings );\n", "\t\t\t\t}\n", "\t\t\t};\n", "\t\t\t\n", "\t\t\t/* Must be done after everything which can be overridden by the state saving! */\n", "\t\t\tif ( oInit.bStateSave )\n", "\t\t\t{\n", "\t\t\t\tfeatures.bStateSave = true;\n", "\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );\n", "\t\t\t\t_fnLoadState( oSettings, oInit, loadedInit );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tloadedInit();\n", "\t\t\t}\n", "\t\t\t\n", "\t\t} );\n", "\t\t_that = null;\n", "\t\treturn this;\n", "\t};\n", "\n", "\t\n", "\t/*\n", "\t * It is useful to have variables which are scoped locally so only the\n", "\t * DataTables functions can access them and they don't leak into global space.\n", "\t * At the same time these functions are often useful over multiple files in the\n", "\t * core and API, so we list, or at least document, all variables which are used\n", "\t * by DataTables as private variables here. This also ensures that there is no\n", "\t * clashing of variable names and that they can easily referenced for reuse.\n", "\t */\n", "\t\n", "\t\n", "\t// Defined else where\n", "\t// _selector_run\n", "\t// _selector_opts\n", "\t// _selector_first\n", "\t// _selector_row_indexes\n", "\t\n", "\tvar _ext; // DataTable.ext\n", "\tvar _Api; // DataTable.Api\n", "\tvar _api_register; // DataTable.Api.register\n", "\tvar _api_registerPlural; // DataTable.Api.registerPlural\n", "\t\n", "\tvar _re_dic = {};\n", "\tvar _re_new_lines = /[\\r\\n]/g;\n", "\tvar _re_html = /<.*?>/g;\n", "\t\n", "\t// This is not strict ISO8601 - Date.parse() is quite lax, although\n", "\t// implementations differ between browsers.\n", "\tvar _re_date = /^\\d{2,4}[\\.\\/\\-]\\d{1,2}[\\.\\/\\-]\\d{1,2}([T ]{1}\\d{1,2}[:\\.]\\d{2}([\\.:]\\d{2})?)?$/;\n", "\t\n", "\t// Escape regular expression special characters\n", "\tvar _re_escape_regex = new RegExp( '(\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\', '$', '^', '-' ].join('|\\\\') + ')', 'g' );\n", "\t\n", "\t// http://en.wikipedia.org/wiki/Foreign_exchange_market\n", "\t// - \\u20BD - Russian ruble.\n", "\t// - \\u20a9 - South Korean Won\n", "\t// - \\u20BA - Turkish Lira\n", "\t// - \\u20B9 - Indian Rupee\n", "\t// - R - Brazil (R$) and South Africa\n", "\t// - fr - Swiss Franc\n", "\t// - kr - Swedish krona, Norwegian krone and Danish krone\n", "\t// - \\u2009 is thin space and \\u202F is narrow no-break space, both used in many\n", "\t// standards as thousands separators.\n", "\tvar _re_formatted_numeric = /[',$£€¥%\\u2009\\u202F\\u20BD\\u20a9\\u20BArfk]/gi;\n", "\t\n", "\t\n", "\tvar _empty = function ( d ) {\n", "\t\treturn !d || d === true || d === '-' ? true : false;\n", "\t};\n", "\t\n", "\t\n", "\tvar _intVal = function ( s ) {\n", "\t\tvar integer = parseInt( s, 10 );\n", "\t\treturn !isNaN(integer) && isFinite(s) ? integer : null;\n", "\t};\n", "\t\n", "\t// Convert from a formatted number with characters other than `.` as the\n", "\t// decimal place, to a Javascript number\n", "\tvar _numToDecimal = function ( num, decimalPoint ) {\n", "\t\t// Cache created regular expressions for speed as this function is called often\n", "\t\tif ( ! _re_dic[ decimalPoint ] ) {\n", "\t\t\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\n", "\t\t}\n", "\t\treturn typeof num === 'string' && decimalPoint !== '.' ?\n", "\t\t\tnum.replace( /\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\n", "\t\t\tnum;\n", "\t};\n", "\t\n", "\t\n", "\tvar _isNumber = function ( d, decimalPoint, formatted ) {\n", "\t\tvar strType = typeof d === 'string';\n", "\t\n", "\t\t// If empty return immediately so there must be a number if it is a\n", "\t\t// formatted string (this stops the string \"k\", or \"kr\", etc being detected\n", "\t\t// as a formatted number for currency\n", "\t\tif ( _empty( d ) ) {\n", "\t\t\treturn true;\n", "\t\t}\n", "\t\n", "\t\tif ( decimalPoint && strType ) {\n", "\t\t\td = _numToDecimal( d, decimalPoint );\n", "\t\t}\n", "\t\n", "\t\tif ( formatted && strType ) {\n", "\t\t\td = d.replace( _re_formatted_numeric, '' );\n", "\t\t}\n", "\t\n", "\t\treturn !isNaN( parseFloat(d) ) && isFinite( d );\n", "\t};\n", "\t\n", "\t\n", "\t// A string without HTML in it can be considered to be HTML still\n", "\tvar _isHtml = function ( d ) {\n", "\t\treturn _empty( d ) || typeof d === 'string';\n", "\t};\n", "\t\n", "\t\n", "\tvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\n", "\t\tif ( _empty( d ) ) {\n", "\t\t\treturn true;\n", "\t\t}\n", "\t\n", "\t\tvar html = _isHtml( d );\n", "\t\treturn ! html ?\n", "\t\t\tnull :\n", "\t\t\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\n", "\t\t\t\ttrue :\n", "\t\t\t\tnull;\n", "\t};\n", "\t\n", "\t\n", "\tvar _pluck = function ( a, prop, prop2 ) {\n", "\t\tvar out = [];\n", "\t\tvar i=0, ien=a.length;\n", "\t\n", "\t\t// Could have the test in the loop for slightly smaller code, but speed\n", "\t\t// is essential here\n", "\t\tif ( prop2 !== undefined ) {\n", "\t\t\tfor ( ; i<ien ; i++ ) {\n", "\t\t\t\tif ( a[i] && a[i][ prop ] ) {\n", "\t\t\t\t\tout.push( a[i][ prop ][ prop2 ] );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\telse {\n", "\t\t\tfor ( ; i<ien ; i++ ) {\n", "\t\t\t\tif ( a[i] ) {\n", "\t\t\t\t\tout.push( a[i][ prop ] );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn out;\n", "\t};\n", "\t\n", "\t\n", "\t// Basically the same as _pluck, but rather than looping over `a` we use `order`\n", "\t// as the indexes to pick from `a`\n", "\tvar _pluck_order = function ( a, order, prop, prop2 )\n", "\t{\n", "\t\tvar out = [];\n", "\t\tvar i=0, ien=order.length;\n", "\t\n", "\t\t// Could have the test in the loop for slightly smaller code, but speed\n", "\t\t// is essential here\n", "\t\tif ( prop2 !== undefined ) {\n", "\t\t\tfor ( ; i<ien ; i++ ) {\n", "\t\t\t\tif ( a[ order[i] ][ prop ] ) {\n", "\t\t\t\t\tout.push( a[ order[i] ][ prop ][ prop2 ] );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\telse {\n", "\t\t\tfor ( ; i<ien ; i++ ) {\n", "\t\t\t\tout.push( a[ order[i] ][ prop ] );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn out;\n", "\t};\n", "\t\n", "\t\n", "\tvar _range = function ( len, start )\n", "\t{\n", "\t\tvar out = [];\n", "\t\tvar end;\n", "\t\n", "\t\tif ( start === undefined ) {\n", "\t\t\tstart = 0;\n", "\t\t\tend = len;\n", "\t\t}\n", "\t\telse {\n", "\t\t\tend = start;\n", "\t\t\tstart = len;\n", "\t\t}\n", "\t\n", "\t\tfor ( var i=start ; i<end ; i++ ) {\n", "\t\t\tout.push( i );\n", "\t\t}\n", "\t\n", "\t\treturn out;\n", "\t};\n", "\t\n", "\t\n", "\tvar _removeEmpty = function ( a )\n", "\t{\n", "\t\tvar out = [];\n", "\t\n", "\t\tfor ( var i=0, ien=a.length ; i<ien ; i++ ) {\n", "\t\t\tif ( a[i] ) { // careful - will remove all falsy values!\n", "\t\t\t\tout.push( a[i] );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn out;\n", "\t};\n", "\t\n", "\t\n", "\tvar _stripHtml = function ( d ) {\n", "\t\treturn d.replace( _re_html, '' );\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Determine if all values in the array are unique. This means we can short\n", "\t * cut the _unique method at the cost of a single loop. A sorted array is used\n", "\t * to easily check the values.\n", "\t *\n", "\t * @param {array} src Source array\n", "\t * @return {boolean} true if all unique, false otherwise\n", "\t * @ignore\n", "\t */\n", "\tvar _areAllUnique = function ( src ) {\n", "\t\tif ( src.length < 2 ) {\n", "\t\t\treturn true;\n", "\t\t}\n", "\t\n", "\t\tvar sorted = src.slice().sort();\n", "\t\tvar last = sorted[0];\n", "\t\n", "\t\tfor ( var i=1, ien=sorted.length ; i<ien ; i++ ) {\n", "\t\t\tif ( sorted[i] === last ) {\n", "\t\t\t\treturn false;\n", "\t\t\t}\n", "\t\n", "\t\t\tlast = sorted[i];\n", "\t\t}\n", "\t\n", "\t\treturn true;\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Find the unique elements in a source array.\n", "\t *\n", "\t * @param {array} src Source array\n", "\t * @return {array} Array of unique items\n", "\t * @ignore\n", "\t */\n", "\tvar _unique = function ( src )\n", "\t{\n", "\t\tif ( _areAllUnique( src ) ) {\n", "\t\t\treturn src.slice();\n", "\t\t}\n", "\t\n", "\t\t// A faster unique method is to use object keys to identify used values,\n", "\t\t// but this doesn't work with arrays or objects, which we must also\n", "\t\t// consider. See jsperf.com/compare-array-unique-versions/4 for more\n", "\t\t// information.\n", "\t\tvar\n", "\t\t\tout = [],\n", "\t\t\tval,\n", "\t\t\ti, ien=src.length,\n", "\t\t\tj, k=0;\n", "\t\n", "\t\tagain: for ( i=0 ; i<ien ; i++ ) {\n", "\t\t\tval = src[i];\n", "\t\n", "\t\t\tfor ( j=0 ; j<k ; j++ ) {\n", "\t\t\t\tif ( out[j] === val ) {\n", "\t\t\t\t\tcontinue again;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\tout.push( val );\n", "\t\t\tk++;\n", "\t\t}\n", "\t\n", "\t\treturn out;\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * DataTables utility methods\n", "\t * \n", "\t * This namespace provides helper methods that DataTables uses internally to\n", "\t * create a DataTable, but which are not exclusively used only for DataTables.\n", "\t * These methods can be used by extension authors to save the duplication of\n", "\t * code.\n", "\t *\n", "\t * @namespace\n", "\t */\n", "\tDataTable.util = {\n", "\t\t/**\n", "\t\t * Throttle the calls to a function. Arguments and context are maintained\n", "\t\t * for the throttled function.\n", "\t\t *\n", "\t\t * @param {function} fn Function to be called\n", "\t\t * @param {integer} freq Call frequency in mS\n", "\t\t * @return {function} Wrapped function\n", "\t\t */\n", "\t\tthrottle: function ( fn, freq ) {\n", "\t\t\tvar\n", "\t\t\t\tfrequency = freq !== undefined ? freq : 200,\n", "\t\t\t\tlast,\n", "\t\t\t\ttimer;\n", "\t\n", "\t\t\treturn function () {\n", "\t\t\t\tvar\n", "\t\t\t\t\tthat = this,\n", "\t\t\t\t\tnow = +new Date(),\n", "\t\t\t\t\targs = arguments;\n", "\t\n", "\t\t\t\tif ( last && now < last + frequency ) {\n", "\t\t\t\t\tclearTimeout( timer );\n", "\t\n", "\t\t\t\t\ttimer = setTimeout( function () {\n", "\t\t\t\t\t\tlast = undefined;\n", "\t\t\t\t\t\tfn.apply( that, args );\n", "\t\t\t\t\t}, frequency );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tlast = now;\n", "\t\t\t\t\tfn.apply( that, args );\n", "\t\t\t\t}\n", "\t\t\t};\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Escape a string such that it can be used in a regular expression\n", "\t\t *\n", "\t\t * @param {string} val string to escape\n", "\t\t * @returns {string} escaped string\n", "\t\t */\n", "\t\tescapeRegex: function ( val ) {\n", "\t\t\treturn val.replace( _re_escape_regex, '\\\\$1' );\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Create a mapping object that allows camel case parameters to be looked up\n", "\t * for their Hungarian counterparts. The mapping is stored in a private\n", "\t * parameter called `_hungarianMap` which can be accessed on the source object.\n", "\t * @param {object} o\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnHungarianMap ( o )\n", "\t{\n", "\t\tvar\n", "\t\t\thungarian = 'a aa ai ao as b fn i m o s ',\n", "\t\t\tmatch,\n", "\t\t\tnewKey,\n", "\t\t\tmap = {};\n", "\t\n", "\t\t$.each( o, function (key, val) {\n", "\t\t\tmatch = key.match(/^([^A-Z]+?)([A-Z])/);\n", "\t\n", "\t\t\tif ( match && hungarian.indexOf(match[1]+' ') !== -1 )\n", "\t\t\t{\n", "\t\t\t\tnewKey = key.replace( match[0], match[2].toLowerCase() );\n", "\t\t\t\tmap[ newKey ] = key;\n", "\t\n", "\t\t\t\tif ( match[1] === 'o' )\n", "\t\t\t\t{\n", "\t\t\t\t\t_fnHungarianMap( o[key] );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\to._hungarianMap = map;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Convert from camel case parameters to Hungarian, based on a Hungarian map\n", "\t * created by _fnHungarianMap.\n", "\t * @param {object} src The model object which holds all parameters that can be\n", "\t * mapped.\n", "\t * @param {object} user The object to convert from camel case to Hungarian.\n", "\t * @param {boolean} force When set to `true`, properties which already have a\n", "\t * Hungarian value in the `user` object will be overwritten. Otherwise they\n", "\t * won't be.\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnCamelToHungarian ( src, user, force )\n", "\t{\n", "\t\tif ( ! src._hungarianMap ) {\n", "\t\t\t_fnHungarianMap( src );\n", "\t\t}\n", "\t\n", "\t\tvar hungarianKey;\n", "\t\n", "\t\t$.each( user, function (key, val) {\n", "\t\t\thungarianKey = src._hungarianMap[ key ];\n", "\t\n", "\t\t\tif ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )\n", "\t\t\t{\n", "\t\t\t\t// For objects, we need to buzz down into the object to copy parameters\n", "\t\t\t\tif ( hungarianKey.charAt(0) === 'o' )\n", "\t\t\t\t{\n", "\t\t\t\t\t// Copy the camelCase options over to the hungarian\n", "\t\t\t\t\tif ( ! user[ hungarianKey ] ) {\n", "\t\t\t\t\t\tuser[ hungarianKey ] = {};\n", "\t\t\t\t\t}\n", "\t\t\t\t\t$.extend( true, user[hungarianKey], user[key] );\n", "\t\n", "\t\t\t\t\t_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tuser[hungarianKey] = user[ key ];\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t} );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Language compatibility - when certain options are given, and others aren't, we\n", "\t * need to duplicate the values over, in order to provide backwards compatibility\n", "\t * with older language files.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnLanguageCompat( lang )\n", "\t{\n", "\t\tvar defaults = DataTable.defaults.oLanguage;\n", "\t\tvar zeroRecords = lang.sZeroRecords;\n", "\t\n", "\t\t/* Backwards compatibility - if there is no sEmptyTable given, then use the same as\n", "\t\t * sZeroRecords - assuming that is given.\n", "\t\t */\n", "\t\tif ( ! lang.sEmptyTable && zeroRecords &&\n", "\t\t\tdefaults.sEmptyTable === \"No data available in table\" )\n", "\t\t{\n", "\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );\n", "\t\t}\n", "\t\n", "\t\t/* Likewise with loading records */\n", "\t\tif ( ! lang.sLoadingRecords && zeroRecords &&\n", "\t\t\tdefaults.sLoadingRecords === \"Loading...\" )\n", "\t\t{\n", "\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );\n", "\t\t}\n", "\t\n", "\t\t// Old parameter name of the thousands separator mapped onto the new\n", "\t\tif ( lang.sInfoThousands ) {\n", "\t\t\tlang.sThousands = lang.sInfoThousands;\n", "\t\t}\n", "\t\n", "\t\tvar decimal = lang.sDecimal;\n", "\t\tif ( decimal ) {\n", "\t\t\t_addNumericSort( decimal );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Map one parameter onto another\n", "\t * @param {object} o Object to map\n", "\t * @param {*} knew The new parameter name\n", "\t * @param {*} old The old parameter name\n", "\t */\n", "\tvar _fnCompatMap = function ( o, knew, old ) {\n", "\t\tif ( o[ knew ] !== undefined ) {\n", "\t\t\to[ old ] = o[ knew ];\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Provide backwards compatibility for the main DT options. Note that the new\n", "\t * options are mapped onto the old parameters, so this is an external interface\n", "\t * change only.\n", "\t * @param {object} init Object to map\n", "\t */\n", "\tfunction _fnCompatOpts ( init )\n", "\t{\n", "\t\t_fnCompatMap( init, 'ordering', 'bSort' );\n", "\t\t_fnCompatMap( init, 'orderMulti', 'bSortMulti' );\n", "\t\t_fnCompatMap( init, 'orderClasses', 'bSortClasses' );\n", "\t\t_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );\n", "\t\t_fnCompatMap( init, 'order', 'aaSorting' );\n", "\t\t_fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );\n", "\t\t_fnCompatMap( init, 'paging', 'bPaginate' );\n", "\t\t_fnCompatMap( init, 'pagingType', 'sPaginationType' );\n", "\t\t_fnCompatMap( init, 'pageLength', 'iDisplayLength' );\n", "\t\t_fnCompatMap( init, 'searching', 'bFilter' );\n", "\t\n", "\t\t// Boolean initialisation of x-scrolling\n", "\t\tif ( typeof init.sScrollX === 'boolean' ) {\n", "\t\t\tinit.sScrollX = init.sScrollX ? '100%' : '';\n", "\t\t}\n", "\t\tif ( typeof init.scrollX === 'boolean' ) {\n", "\t\t\tinit.scrollX = init.scrollX ? '100%' : '';\n", "\t\t}\n", "\t\n", "\t\t// Column search objects are in an array, so it needs to be converted\n", "\t\t// element by element\n", "\t\tvar searchCols = init.aoSearchCols;\n", "\t\n", "\t\tif ( searchCols ) {\n", "\t\t\tfor ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {\n", "\t\t\t\tif ( searchCols[i] ) {\n", "\t\t\t\t\t_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Provide backwards compatibility for column options. Note that the new options\n", "\t * are mapped onto the old parameters, so this is an external interface change\n", "\t * only.\n", "\t * @param {object} init Object to map\n", "\t */\n", "\tfunction _fnCompatCols ( init )\n", "\t{\n", "\t\t_fnCompatMap( init, 'orderable', 'bSortable' );\n", "\t\t_fnCompatMap( init, 'orderData', 'aDataSort' );\n", "\t\t_fnCompatMap( init, 'orderSequence', 'asSorting' );\n", "\t\t_fnCompatMap( init, 'orderDataType', 'sortDataType' );\n", "\t\n", "\t\t// orderData can be given as an integer\n", "\t\tvar dataSort = init.aDataSort;\n", "\t\tif ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) {\n", "\t\t\tinit.aDataSort = [ dataSort ];\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Browser feature detection for capabilities, quirks\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnBrowserDetect( settings )\n", "\t{\n", "\t\t// We don't need to do this every time DataTables is constructed, the values\n", "\t\t// calculated are specific to the browser and OS configuration which we\n", "\t\t// don't expect to change between initialisations\n", "\t\tif ( ! DataTable.__browser ) {\n", "\t\t\tvar browser = {};\n", "\t\t\tDataTable.__browser = browser;\n", "\t\n", "\t\t\t// Scrolling feature / quirks detection\n", "\t\t\tvar n = $('<div/>')\n", "\t\t\t\t.css( {\n", "\t\t\t\t\tposition: 'fixed',\n", "\t\t\t\t\ttop: 0,\n", "\t\t\t\t\tleft: $(window).scrollLeft()*-1, // allow for scrolling\n", "\t\t\t\t\theight: 1,\n", "\t\t\t\t\twidth: 1,\n", "\t\t\t\t\toverflow: 'hidden'\n", "\t\t\t\t} )\n", "\t\t\t\t.append(\n", "\t\t\t\t\t$('<div/>')\n", "\t\t\t\t\t\t.css( {\n", "\t\t\t\t\t\t\tposition: 'absolute',\n", "\t\t\t\t\t\t\ttop: 1,\n", "\t\t\t\t\t\t\tleft: 1,\n", "\t\t\t\t\t\t\twidth: 100,\n", "\t\t\t\t\t\t\toverflow: 'scroll'\n", "\t\t\t\t\t\t} )\n", "\t\t\t\t\t\t.append(\n", "\t\t\t\t\t\t\t$('<div/>')\n", "\t\t\t\t\t\t\t\t.css( {\n", "\t\t\t\t\t\t\t\t\twidth: '100%',\n", "\t\t\t\t\t\t\t\t\theight: 10\n", "\t\t\t\t\t\t\t\t} )\n", "\t\t\t\t\t\t)\n", "\t\t\t\t)\n", "\t\t\t\t.appendTo( 'body' );\n", "\t\n", "\t\t\tvar outer = n.children();\n", "\t\t\tvar inner = outer.children();\n", "\t\n", "\t\t\t// Numbers below, in order, are:\n", "\t\t\t// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth\n", "\t\t\t//\n", "\t\t\t// IE6 XP: 100 100 100 83\n", "\t\t\t// IE7 Vista: 100 100 100 83\n", "\t\t\t// IE 8+ Windows: 83 83 100 83\n", "\t\t\t// Evergreen Windows: 83 83 100 83\n", "\t\t\t// Evergreen Mac with scrollbars: 85 85 100 85\n", "\t\t\t// Evergreen Mac without scrollbars: 100 100 100 100\n", "\t\n", "\t\t\t// Get scrollbar width\n", "\t\t\tbrowser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;\n", "\t\n", "\t\t\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\n", "\t\t\t// include the width of the scrollbar, while other browsers ensure the inner\n", "\t\t\t// element is contained without forcing scrolling\n", "\t\t\tbrowser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;\n", "\t\n", "\t\t\t// In rtl text layout, some browsers (most, but not all) will place the\n", "\t\t\t// scrollbar on the left, rather than the right.\n", "\t\t\tbrowser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;\n", "\t\n", "\t\t\t// IE8- don't provide height and width for getBoundingClientRect\n", "\t\t\tbrowser.bBounding = n[0].getBoundingClientRect().width ? true : false;\n", "\t\n", "\t\t\tn.remove();\n", "\t\t}\n", "\t\n", "\t\t$.extend( settings.oBrowser, DataTable.__browser );\n", "\t\tsettings.oScroll.iBarWidth = DataTable.__browser.barWidth;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Array.prototype reduce[Right] method, used for browsers which don't support\n", "\t * JS 1.6. Done this way to reduce code size, since we iterate either way\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnReduce ( that, fn, init, start, end, inc )\n", "\t{\n", "\t\tvar\n", "\t\t\ti = start,\n", "\t\t\tvalue,\n", "\t\t\tisSet = false;\n", "\t\n", "\t\tif ( init !== undefined ) {\n", "\t\t\tvalue = init;\n", "\t\t\tisSet = true;\n", "\t\t}\n", "\t\n", "\t\twhile ( i !== end ) {\n", "\t\t\tif ( ! that.hasOwnProperty(i) ) {\n", "\t\t\t\tcontinue;\n", "\t\t\t}\n", "\t\n", "\t\t\tvalue = isSet ?\n", "\t\t\t\tfn( value, that[i], i, that ) :\n", "\t\t\t\tthat[i];\n", "\t\n", "\t\t\tisSet = true;\n", "\t\t\ti += inc;\n", "\t\t}\n", "\t\n", "\t\treturn value;\n", "\t}\n", "\t\n", "\t/**\n", "\t * Add a column to the list used for the table with default values\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {node} nTh The th element for this column\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAddColumn( oSettings, nTh )\n", "\t{\n", "\t\t// Add column to aoColumns array\n", "\t\tvar oDefaults = DataTable.defaults.column;\n", "\t\tvar iCol = oSettings.aoColumns.length;\n", "\t\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\n", "\t\t\t\"nTh\": nTh ? nTh : document.createElement('th'),\n", "\t\t\t\"sTitle\": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',\n", "\t\t\t\"aDataSort\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\n", "\t\t\t\"mData\": oDefaults.mData ? oDefaults.mData : iCol,\n", "\t\t\tidx: iCol\n", "\t\t} );\n", "\t\toSettings.aoColumns.push( oCol );\n", "\t\n", "\t\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\n", "\t\t// passed into extend can be undefined. This allows the user to give a default\n", "\t\t// with only some of the parameters defined, and also not give a default\n", "\t\tvar searchCols = oSettings.aoPreSearchCols;\n", "\t\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\n", "\t\n", "\t\t// Use the default column options function to initialise classes etc\n", "\t\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Apply options for a column\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {int} iCol column index to consider\n", "\t * @param {object} oOptions object with sType, bVisible and bSearchable etc\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnColumnOptions( oSettings, iCol, oOptions )\n", "\t{\n", "\t\tvar oCol = oSettings.aoColumns[ iCol ];\n", "\t\tvar oClasses = oSettings.oClasses;\n", "\t\tvar th = $(oCol.nTh);\n", "\t\n", "\t\t// Try to get width information from the DOM. We can't get it from CSS\n", "\t\t// as we'd need to parse the CSS stylesheet. `width` option can override\n", "\t\tif ( ! oCol.sWidthOrig ) {\n", "\t\t\t// Width attribute\n", "\t\t\toCol.sWidthOrig = th.attr('width') || null;\n", "\t\n", "\t\t\t// Style attribute\n", "\t\t\tvar t = (th.attr('style') || '').match(/width:\\s*(\\d+[pxem%]+)/);\n", "\t\t\tif ( t ) {\n", "\t\t\t\toCol.sWidthOrig = t[1];\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t/* User specified column options */\n", "\t\tif ( oOptions !== undefined && oOptions !== null )\n", "\t\t{\n", "\t\t\t// Backwards compatibility\n", "\t\t\t_fnCompatCols( oOptions );\n", "\t\n", "\t\t\t// Map camel case parameters to their Hungarian counterparts\n", "\t\t\t_fnCamelToHungarian( DataTable.defaults.column, oOptions );\n", "\t\n", "\t\t\t/* Backwards compatibility for mDataProp */\n", "\t\t\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\n", "\t\t\t{\n", "\t\t\t\toOptions.mData = oOptions.mDataProp;\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( oOptions.sType )\n", "\t\t\t{\n", "\t\t\t\toCol._sManualType = oOptions.sType;\n", "\t\t\t}\n", "\t\n", "\t\t\t// `class` is a reserved word in Javascript, so we need to provide\n", "\t\t\t// the ability to use a valid name for the camel case input\n", "\t\t\tif ( oOptions.className && ! oOptions.sClass )\n", "\t\t\t{\n", "\t\t\t\toOptions.sClass = oOptions.className;\n", "\t\t\t}\n", "\t\t\tif ( oOptions.sClass ) {\n", "\t\t\t\tth.addClass( oOptions.sClass );\n", "\t\t\t}\n", "\t\n", "\t\t\t$.extend( oCol, oOptions );\n", "\t\t\t_fnMap( oCol, oOptions, \"sWidth\", \"sWidthOrig\" );\n", "\t\n", "\t\t\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\n", "\t\t\t * priority if defined\n", "\t\t\t */\n", "\t\t\tif ( oOptions.iDataSort !== undefined )\n", "\t\t\t{\n", "\t\t\t\toCol.aDataSort = [ oOptions.iDataSort ];\n", "\t\t\t}\n", "\t\t\t_fnMap( oCol, oOptions, \"aDataSort\" );\n", "\t\t}\n", "\t\n", "\t\t/* Cache the data get and set functions for speed */\n", "\t\tvar mDataSrc = oCol.mData;\n", "\t\tvar mData = _fnGetObjectDataFn( mDataSrc );\n", "\t\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\n", "\t\n", "\t\tvar attrTest = function( src ) {\n", "\t\t\treturn typeof src === 'string' && src.indexOf('@') !== -1;\n", "\t\t};\n", "\t\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\n", "\t\t\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\n", "\t\t);\n", "\t\toCol._setter = null;\n", "\t\n", "\t\toCol.fnGetData = function (rowData, type, meta) {\n", "\t\t\tvar innerData = mData( rowData, type, undefined, meta );\n", "\t\n", "\t\t\treturn mRender && type ?\n", "\t\t\t\tmRender( innerData, type, rowData, meta ) :\n", "\t\t\t\tinnerData;\n", "\t\t};\n", "\t\toCol.fnSetData = function ( rowData, val, meta ) {\n", "\t\t\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\n", "\t\t};\n", "\t\n", "\t\t// Indicate if DataTables should read DOM data as an object or array\n", "\t\t// Used in _fnGetRowElements\n", "\t\tif ( typeof mDataSrc !== 'number' ) {\n", "\t\t\toSettings._rowReadObject = true;\n", "\t\t}\n", "\t\n", "\t\t/* Feature sorting overrides column specific when off */\n", "\t\tif ( !oSettings.oFeatures.bSort )\n", "\t\t{\n", "\t\t\toCol.bSortable = false;\n", "\t\t\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\n", "\t\t}\n", "\t\n", "\t\t/* Check that the class assignment is correct for sorting */\n", "\t\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\n", "\t\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\n", "\t\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\n", "\t\t{\n", "\t\t\toCol.sSortingClass = oClasses.sSortableNone;\n", "\t\t\toCol.sSortingClassJUI = \"\";\n", "\t\t}\n", "\t\telse if ( bAsc && !bDesc )\n", "\t\t{\n", "\t\t\toCol.sSortingClass = oClasses.sSortableAsc;\n", "\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\n", "\t\t}\n", "\t\telse if ( !bAsc && bDesc )\n", "\t\t{\n", "\t\t\toCol.sSortingClass = oClasses.sSortableDesc;\n", "\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\toCol.sSortingClass = oClasses.sSortable;\n", "\t\t\toCol.sSortingClassJUI = oClasses.sSortJUI;\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Adjust the table column widths for new data. Note: you would probably want to\n", "\t * do a redraw after calling this function!\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAdjustColumnSizing ( settings )\n", "\t{\n", "\t\t/* Not interested in doing column width calculation if auto-width is disabled */\n", "\t\tif ( settings.oFeatures.bAutoWidth !== false )\n", "\t\t{\n", "\t\t\tvar columns = settings.aoColumns;\n", "\t\n", "\t\t\t_fnCalculateColumnWidths( settings );\n", "\t\t\tfor ( var i=0 , iLen=columns.length ; i<iLen ; i++ )\n", "\t\t\t{\n", "\t\t\t\tcolumns[i].nTh.style.width = columns[i].sWidth;\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\tvar scroll = settings.oScroll;\n", "\t\tif ( scroll.sY !== '' || scroll.sX !== '')\n", "\t\t{\n", "\t\t\t_fnScrollDraw( settings );\n", "\t\t}\n", "\t\n", "\t\t_fnCallbackFire( settings, null, 'column-sizing', [settings] );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Covert the index of a visible column to the index in the data array (take account\n", "\t * of hidden columns)\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {int} iMatch Visible column index to lookup\n", "\t * @returns {int} i the data index\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnVisibleToColumnIndex( oSettings, iMatch )\n", "\t{\n", "\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n", "\t\n", "\t\treturn typeof aiVis[iMatch] === 'number' ?\n", "\t\t\taiVis[iMatch] :\n", "\t\t\tnull;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Covert the index of an index in the data array and convert it to the visible\n", "\t * column index (take account of hidden columns)\n", "\t * @param {int} iMatch Column index to lookup\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @returns {int} i the data index\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnColumnIndexToVisible( oSettings, iMatch )\n", "\t{\n", "\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n", "\t\tvar iPos = $.inArray( iMatch, aiVis );\n", "\t\n", "\t\treturn iPos !== -1 ? iPos : null;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the number of visible columns\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @returns {int} i the number of visible columns\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnVisbleColumns( oSettings )\n", "\t{\n", "\t\tvar vis = 0;\n", "\t\n", "\t\t// No reduce in IE8, use a loop for now\n", "\t\t$.each( oSettings.aoColumns, function ( i, col ) {\n", "\t\t\tif ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {\n", "\t\t\t\tvis++;\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn vis;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get an array of column indexes that match a given property\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {string} sParam Parameter in aoColumns to look for - typically\n", "\t * bVisible or bSearchable\n", "\t * @returns {array} Array of indexes with matched properties\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetColumns( oSettings, sParam )\n", "\t{\n", "\t\tvar a = [];\n", "\t\n", "\t\t$.map( oSettings.aoColumns, function(val, i) {\n", "\t\t\tif ( val[sParam] ) {\n", "\t\t\t\ta.push( i );\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn a;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Calculate the 'type' of a column\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnColumnTypes ( settings )\n", "\t{\n", "\t\tvar columns = settings.aoColumns;\n", "\t\tvar data = settings.aoData;\n", "\t\tvar types = DataTable.ext.type.detect;\n", "\t\tvar i, ien, j, jen, k, ken;\n", "\t\tvar col, cell, detectedType, cache;\n", "\t\n", "\t\t// For each column, spin over the \n", "\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n", "\t\t\tcol = columns[i];\n", "\t\t\tcache = [];\n", "\t\n", "\t\t\tif ( ! col.sType && col._sManualType ) {\n", "\t\t\t\tcol.sType = col._sManualType;\n", "\t\t\t}\n", "\t\t\telse if ( ! col.sType ) {\n", "\t\t\t\tfor ( j=0, jen=types.length ; j<jen ; j++ ) {\n", "\t\t\t\t\tfor ( k=0, ken=data.length ; k<ken ; k++ ) {\n", "\t\t\t\t\t\t// Use a cache array so we only need to get the type data\n", "\t\t\t\t\t\t// from the formatter once (when using multiple detectors)\n", "\t\t\t\t\t\tif ( cache[k] === undefined ) {\n", "\t\t\t\t\t\t\tcache[k] = _fnGetCellData( settings, k, i, 'type' );\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\tdetectedType = types[j]( cache[k], settings );\n", "\t\n", "\t\t\t\t\t\t// If null, then this type can't apply to this column, so\n", "\t\t\t\t\t\t// rather than testing all cells, break out. There is an\n", "\t\t\t\t\t\t// exception for the last type which is `html`. We need to\n", "\t\t\t\t\t\t// scan all rows since it is possible to mix string and HTML\n", "\t\t\t\t\t\t// types\n", "\t\t\t\t\t\tif ( ! detectedType && j !== types.length-1 ) {\n", "\t\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\t// Only a single match is needed for html type since it is\n", "\t\t\t\t\t\t// bottom of the pile and very similar to string\n", "\t\t\t\t\t\tif ( detectedType === 'html' ) {\n", "\t\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t// Type is valid for all data points in the column - use this\n", "\t\t\t\t\t// type\n", "\t\t\t\t\tif ( detectedType ) {\n", "\t\t\t\t\t\tcol.sType = detectedType;\n", "\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// Fall back - if no type was detected, always use string\n", "\t\t\t\tif ( ! col.sType ) {\n", "\t\t\t\t\tcol.sType = 'string';\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Take the column definitions and static columns arrays and calculate how\n", "\t * they relate to column indexes. The callback function will then apply the\n", "\t * definition found for a column to a suitable configuration object.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {array} aoColDefs The aoColumnDefs array that is to be applied\n", "\t * @param {array} aoCols The aoColumns array that defines columns individually\n", "\t * @param {function} fn Callback function - takes two parameters, the calculated\n", "\t * column index and the definition for that column.\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )\n", "\t{\n", "\t\tvar i, iLen, j, jLen, k, kLen, def;\n", "\t\tvar columns = oSettings.aoColumns;\n", "\t\n", "\t\t// Column definitions with aTargets\n", "\t\tif ( aoColDefs )\n", "\t\t{\n", "\t\t\t/* Loop over the definitions array - loop in reverse so first instance has priority */\n", "\t\t\tfor ( i=aoColDefs.length-1 ; i>=0 ; i-- )\n", "\t\t\t{\n", "\t\t\t\tdef = aoColDefs[i];\n", "\t\n", "\t\t\t\t/* Each definition can target multiple columns, as it is an array */\n", "\t\t\t\tvar aTargets = def.targets !== undefined ?\n", "\t\t\t\t\tdef.targets :\n", "\t\t\t\t\tdef.aTargets;\n", "\t\n", "\t\t\t\tif ( ! $.isArray( aTargets ) )\n", "\t\t\t\t{\n", "\t\t\t\t\taTargets = [ aTargets ];\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tfor ( j=0, jLen=aTargets.length ; j<jLen ; j++ )\n", "\t\t\t\t{\n", "\t\t\t\t\tif ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t/* Add columns that we don't yet know about */\n", "\t\t\t\t\t\twhile( columns.length <= aTargets[j] )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\t_fnAddColumn( oSettings );\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\t/* Integer, basic index */\n", "\t\t\t\t\t\tfn( aTargets[j], def );\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t/* Negative integer, right to left column counting */\n", "\t\t\t\t\t\tfn( columns.length+aTargets[j], def );\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( typeof aTargets[j] === 'string' )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t/* Class name matching on TH element */\n", "\t\t\t\t\t\tfor ( k=0, kLen=columns.length ; k<kLen ; k++ )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\tif ( aTargets[j] == \"_all\" ||\n", "\t\t\t\t\t\t\t $(columns[k].nTh).hasClass( aTargets[j] ) )\n", "\t\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\t\tfn( k, def );\n", "\t\t\t\t\t\t\t}\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t// Statically defined columns array\n", "\t\tif ( aoCols )\n", "\t\t{\n", "\t\t\tfor ( i=0, iLen=aoCols.length ; i<iLen ; i++ )\n", "\t\t\t{\n", "\t\t\t\tfn( i, aoCols[i] );\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t/**\n", "\t * Add a data array to the table, creating DOM node etc. This is the parallel to\n", "\t * _fnGatherData, but for adding rows from a Javascript source, rather than a\n", "\t * DOM source.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {array} aData data array to be added\n", "\t * @param {node} [nTr] TR element to add to the table - optional. If not given,\n", "\t * DataTables will create a row automatically\n", "\t * @param {array} [anTds] Array of TD|TH elements for the row - must be given\n", "\t * if nTr is.\n", "\t * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\n", "\t{\n", "\t\t/* Create the object for storing information about this new row */\n", "\t\tvar iRow = oSettings.aoData.length;\n", "\t\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\n", "\t\t\tsrc: nTr ? 'dom' : 'data',\n", "\t\t\tidx: iRow\n", "\t\t} );\n", "\t\n", "\t\toData._aData = aDataIn;\n", "\t\toSettings.aoData.push( oData );\n", "\t\n", "\t\t/* Create the cells */\n", "\t\tvar nTd, sThisType;\n", "\t\tvar columns = oSettings.aoColumns;\n", "\t\n", "\t\t// Invalidate the column types as the new data needs to be revalidated\n", "\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\tcolumns[i].sType = null;\n", "\t\t}\n", "\t\n", "\t\t/* Add to the display array */\n", "\t\toSettings.aiDisplayMaster.push( iRow );\n", "\t\n", "\t\tvar id = oSettings.rowIdFn( aDataIn );\n", "\t\tif ( id !== undefined ) {\n", "\t\t\toSettings.aIds[ id ] = oData;\n", "\t\t}\n", "\t\n", "\t\t/* Create the DOM information, or register it if already present */\n", "\t\tif ( nTr || ! oSettings.oFeatures.bDeferRender )\n", "\t\t{\n", "\t\t\t_fnCreateTr( oSettings, iRow, nTr, anTds );\n", "\t\t}\n", "\t\n", "\t\treturn iRow;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Add one or more TR elements to the table. Generally we'd expect to\n", "\t * use this for reading data from a DOM sourced table, but it could be\n", "\t * used for an TR element. Note that if a TR is given, it is used (i.e.\n", "\t * it is not cloned).\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {array|node|jQuery} trs The TR element(s) to add to the table\n", "\t * @returns {array} Array of indexes for the added rows\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAddTr( settings, trs )\n", "\t{\n", "\t\tvar row;\n", "\t\n", "\t\t// Allow an individual node to be passed in\n", "\t\tif ( ! (trs instanceof $) ) {\n", "\t\t\ttrs = $(trs);\n", "\t\t}\n", "\t\n", "\t\treturn trs.map( function (i, el) {\n", "\t\t\trow = _fnGetRowElements( settings, el );\n", "\t\t\treturn _fnAddData( settings, row.data, el, row.cells );\n", "\t\t} );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Take a TR element and convert it to an index in aoData\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {node} n the TR element to find\n", "\t * @returns {int} index if the node is found, null if not\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnNodeToDataIndex( oSettings, n )\n", "\t{\n", "\t\treturn (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Take a TD element and convert it into a column data index (not the visible index)\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {int} iRow The row number the TD/TH can be found in\n", "\t * @param {node} n The TD/TH element to find\n", "\t * @returns {int} index if the node is found, -1 if not\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnNodeToColumnIndex( oSettings, iRow, n )\n", "\t{\n", "\t\treturn $.inArray( n, oSettings.aoData[ iRow ].anCells );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the data for a given cell from the internal cache, taking into account data mapping\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {int} rowIdx aoData row id\n", "\t * @param {int} colIdx Column index\n", "\t * @param {string} type data get type ('display', 'type' 'filter' 'sort')\n", "\t * @returns {*} Cell data\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetCellData( settings, rowIdx, colIdx, type )\n", "\t{\n", "\t\tvar draw = settings.iDraw;\n", "\t\tvar col = settings.aoColumns[colIdx];\n", "\t\tvar rowData = settings.aoData[rowIdx]._aData;\n", "\t\tvar defaultContent = col.sDefaultContent;\n", "\t\tvar cellData = col.fnGetData( rowData, type, {\n", "\t\t\tsettings: settings,\n", "\t\t\trow: rowIdx,\n", "\t\t\tcol: colIdx\n", "\t\t} );\n", "\t\n", "\t\tif ( cellData === undefined ) {\n", "\t\t\tif ( settings.iDrawError != draw && defaultContent === null ) {\n", "\t\t\t\t_fnLog( settings, 0, \"Requested unknown parameter \"+\n", "\t\t\t\t\t(typeof col.mData=='function' ? '{function}' : \"'\"+col.mData+\"'\")+\n", "\t\t\t\t\t\" for row \"+rowIdx+\", column \"+colIdx, 4 );\n", "\t\t\t\tsettings.iDrawError = draw;\n", "\t\t\t}\n", "\t\t\treturn defaultContent;\n", "\t\t}\n", "\t\n", "\t\t// When the data source is null and a specific data type is requested (i.e.\n", "\t\t// not the original data), we can use default column data\n", "\t\tif ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {\n", "\t\t\tcellData = defaultContent;\n", "\t\t}\n", "\t\telse if ( typeof cellData === 'function' ) {\n", "\t\t\t// If the data source is a function, then we run it and use the return,\n", "\t\t\t// executing in the scope of the data object (for instances)\n", "\t\t\treturn cellData.call( rowData );\n", "\t\t}\n", "\t\n", "\t\tif ( cellData === null && type == 'display' ) {\n", "\t\t\treturn '';\n", "\t\t}\n", "\t\treturn cellData;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Set the value for a specific cell, into the internal data cache\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {int} rowIdx aoData row id\n", "\t * @param {int} colIdx Column index\n", "\t * @param {*} val Value to set\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSetCellData( settings, rowIdx, colIdx, val )\n", "\t{\n", "\t\tvar col = settings.aoColumns[colIdx];\n", "\t\tvar rowData = settings.aoData[rowIdx]._aData;\n", "\t\n", "\t\tcol.fnSetData( rowData, val, {\n", "\t\t\tsettings: settings,\n", "\t\t\trow: rowIdx,\n", "\t\t\tcol: colIdx\n", "\t\t} );\n", "\t}\n", "\t\n", "\t\n", "\t// Private variable that is used to match action syntax in the data property object\n", "\tvar __reArray = /\\[.*?\\]$/;\n", "\tvar __reFn = /\\(\\)$/;\n", "\t\n", "\t/**\n", "\t * Split string on periods, taking into account escaped periods\n", "\t * @param {string} str String to split\n", "\t * @return {array} Split string\n", "\t */\n", "\tfunction _fnSplitObjNotation( str )\n", "\t{\n", "\t\treturn $.map( str.match(/(\\\\.|[^\\.])+/g) || [''], function ( s ) {\n", "\t\t\treturn s.replace(/\\\\\\./g, '.');\n", "\t\t} );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Return a function that can be used to get data from a source object, taking\n", "\t * into account the ability to use nested objects as a source\n", "\t * @param {string|int|function} mSource The data source for the object\n", "\t * @returns {function} Data get function\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetObjectDataFn( mSource )\n", "\t{\n", "\t\tif ( $.isPlainObject( mSource ) )\n", "\t\t{\n", "\t\t\t/* Build an object of get functions, and wrap them in a single call */\n", "\t\t\tvar o = {};\n", "\t\t\t$.each( mSource, function (key, val) {\n", "\t\t\t\tif ( val ) {\n", "\t\t\t\t\to[key] = _fnGetObjectDataFn( val );\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\n", "\t\t\treturn function (data, type, row, meta) {\n", "\t\t\t\tvar t = o[type] || o._;\n", "\t\t\t\treturn t !== undefined ?\n", "\t\t\t\t\tt(data, type, row, meta) :\n", "\t\t\t\t\tdata;\n", "\t\t\t};\n", "\t\t}\n", "\t\telse if ( mSource === null )\n", "\t\t{\n", "\t\t\t/* Give an empty string for rendering / sorting etc */\n", "\t\t\treturn function (data) { // type, row and meta also passed, but not used\n", "\t\t\t\treturn data;\n", "\t\t\t};\n", "\t\t}\n", "\t\telse if ( typeof mSource === 'function' )\n", "\t\t{\n", "\t\t\treturn function (data, type, row, meta) {\n", "\t\t\t\treturn mSource( data, type, row, meta );\n", "\t\t\t};\n", "\t\t}\n", "\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n", "\t\t\t mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n", "\t\t{\n", "\t\t\t/* If there is a . in the source string then the data source is in a\n", "\t\t\t * nested object so we loop over the data for each level to get the next\n", "\t\t\t * level down. On each loop we test for undefined, and if found immediately\n", "\t\t\t * return. This allows entire objects to be missing and sDefaultContent to\n", "\t\t\t * be used if defined, rather than throwing an error\n", "\t\t\t */\n", "\t\t\tvar fetchData = function (data, type, src) {\n", "\t\t\t\tvar arrayNotation, funcNotation, out, innerSrc;\n", "\t\n", "\t\t\t\tif ( src !== \"\" )\n", "\t\t\t\t{\n", "\t\t\t\t\tvar a = _fnSplitObjNotation( src );\n", "\t\n", "\t\t\t\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t// Check if we are dealing with special notation\n", "\t\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n", "\t\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n", "\t\n", "\t\t\t\t\t\tif ( arrayNotation )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\t// Array notation\n", "\t\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n", "\t\n", "\t\t\t\t\t\t\t// Condition allows simply [] to be passed in\n", "\t\t\t\t\t\t\tif ( a[i] !== \"\" ) {\n", "\t\t\t\t\t\t\t\tdata = data[ a[i] ];\n", "\t\t\t\t\t\t\t}\n", "\t\t\t\t\t\t\tout = [];\n", "\t\n", "\t\t\t\t\t\t\t// Get the remainder of the nested object to get\n", "\t\t\t\t\t\t\ta.splice( 0, i+1 );\n", "\t\t\t\t\t\t\tinnerSrc = a.join('.');\n", "\t\n", "\t\t\t\t\t\t\t// Traverse each entry in the array getting the properties requested\n", "\t\t\t\t\t\t\tif ( $.isArray( data ) ) {\n", "\t\t\t\t\t\t\t\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\n", "\t\t\t\t\t\t\t\t\tout.push( fetchData( data[j], type, innerSrc ) );\n", "\t\t\t\t\t\t\t\t}\n", "\t\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\t\t// If a string is given in between the array notation indicators, that\n", "\t\t\t\t\t\t\t// is used to join the strings together, otherwise an array is returned\n", "\t\t\t\t\t\t\tvar join = arrayNotation[0].substring(1, arrayNotation[0].length-1);\n", "\t\t\t\t\t\t\tdata = (join===\"\") ? out : out.join(join);\n", "\t\n", "\t\t\t\t\t\t\t// The inner call to fetchData has already traversed through the remainder\n", "\t\t\t\t\t\t\t// of the source requested, so we exit from the loop\n", "\t\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\telse if ( funcNotation )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\t// Function call\n", "\t\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n", "\t\t\t\t\t\t\tdata = data[ a[i] ]();\n", "\t\t\t\t\t\t\tcontinue;\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\tif ( data === null || data[ a[i] ] === undefined )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\treturn undefined;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\tdata = data[ a[i] ];\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\treturn data;\n", "\t\t\t};\n", "\t\n", "\t\t\treturn function (data, type) { // row and meta also passed, but not used\n", "\t\t\t\treturn fetchData( data, type, mSource );\n", "\t\t\t};\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\t/* Array or flat object mapping */\n", "\t\t\treturn function (data, type) { // row and meta also passed, but not used\n", "\t\t\t\treturn data[mSource];\n", "\t\t\t};\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Return a function that can be used to set data from a source object, taking\n", "\t * into account the ability to use nested objects as a source\n", "\t * @param {string|int|function} mSource The data source for the object\n", "\t * @returns {function} Data set function\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSetObjectDataFn( mSource )\n", "\t{\n", "\t\tif ( $.isPlainObject( mSource ) )\n", "\t\t{\n", "\t\t\t/* Unlike get, only the underscore (global) option is used for for\n", "\t\t\t * setting data since we don't know the type here. This is why an object\n", "\t\t\t * option is not documented for `mData` (which is read/write), but it is\n", "\t\t\t * for `mRender` which is read only.\n", "\t\t\t */\n", "\t\t\treturn _fnSetObjectDataFn( mSource._ );\n", "\t\t}\n", "\t\telse if ( mSource === null )\n", "\t\t{\n", "\t\t\t/* Nothing to do when the data source is null */\n", "\t\t\treturn function () {};\n", "\t\t}\n", "\t\telse if ( typeof mSource === 'function' )\n", "\t\t{\n", "\t\t\treturn function (data, val, meta) {\n", "\t\t\t\tmSource( data, 'set', val, meta );\n", "\t\t\t};\n", "\t\t}\n", "\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n", "\t\t\t mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n", "\t\t{\n", "\t\t\t/* Like the get, we need to get data from a nested object */\n", "\t\t\tvar setData = function (data, val, src) {\n", "\t\t\t\tvar a = _fnSplitObjNotation( src ), b;\n", "\t\t\t\tvar aLast = a[a.length-1];\n", "\t\t\t\tvar arrayNotation, funcNotation, o, innerSrc;\n", "\t\n", "\t\t\t\tfor ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )\n", "\t\t\t\t{\n", "\t\t\t\t\t// Check if we are dealing with an array notation request\n", "\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n", "\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n", "\t\n", "\t\t\t\t\tif ( arrayNotation )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n", "\t\t\t\t\t\tdata[ a[i] ] = [];\n", "\t\n", "\t\t\t\t\t\t// Get the remainder of the nested object to set so we can recurse\n", "\t\t\t\t\t\tb = a.slice();\n", "\t\t\t\t\t\tb.splice( 0, i+1 );\n", "\t\t\t\t\t\tinnerSrc = b.join('.');\n", "\t\n", "\t\t\t\t\t\t// Traverse each entry in the array setting the properties requested\n", "\t\t\t\t\t\tif ( $.isArray( val ) )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\n", "\t\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\t\to = {};\n", "\t\t\t\t\t\t\t\tsetData( o, val[j], innerSrc );\n", "\t\t\t\t\t\t\t\tdata[ a[i] ].push( o );\n", "\t\t\t\t\t\t\t}\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\telse\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\t// We've been asked to save data to an array, but it\n", "\t\t\t\t\t\t\t// isn't array data to be saved. Best that can be done\n", "\t\t\t\t\t\t\t// is to just save the value.\n", "\t\t\t\t\t\t\tdata[ a[i] ] = val;\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\t// The inner call to setData has already traversed through the remainder\n", "\t\t\t\t\t\t// of the source and has set the data, thus we can exit here\n", "\t\t\t\t\t\treturn;\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( funcNotation )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t// Function call\n", "\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n", "\t\t\t\t\t\tdata = data[ a[i] ]( val );\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t// If the nested object doesn't currently exist - since we are\n", "\t\t\t\t\t// trying to set the value - create it\n", "\t\t\t\t\tif ( data[ a[i] ] === null || data[ a[i] ] === undefined )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tdata[ a[i] ] = {};\n", "\t\t\t\t\t}\n", "\t\t\t\t\tdata = data[ a[i] ];\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// Last item in the input - i.e, the actual set\n", "\t\t\t\tif ( aLast.match(__reFn ) )\n", "\t\t\t\t{\n", "\t\t\t\t\t// Function call\n", "\t\t\t\t\tdata = data[ aLast.replace(__reFn, '') ]( val );\n", "\t\t\t\t}\n", "\t\t\t\telse\n", "\t\t\t\t{\n", "\t\t\t\t\t// If array notation is used, we just want to strip it and use the property name\n", "\t\t\t\t\t// and assign the value. If it isn't used, then we get the result we want anyway\n", "\t\t\t\t\tdata[ aLast.replace(__reArray, '') ] = val;\n", "\t\t\t\t}\n", "\t\t\t};\n", "\t\n", "\t\t\treturn function (data, val) { // meta is also passed in, but not used\n", "\t\t\t\treturn setData( data, val, mSource );\n", "\t\t\t};\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\t/* Array or flat object mapping */\n", "\t\t\treturn function (data, val) { // meta is also passed in, but not used\n", "\t\t\t\tdata[mSource] = val;\n", "\t\t\t};\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Return an array with the full table data\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @returns array {array} aData Master data array\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetDataMaster ( settings )\n", "\t{\n", "\t\treturn _pluck( settings.aoData, '_aData' );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Nuke the table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnClearTable( settings )\n", "\t{\n", "\t\tsettings.aoData.length = 0;\n", "\t\tsettings.aiDisplayMaster.length = 0;\n", "\t\tsettings.aiDisplay.length = 0;\n", "\t\tsettings.aIds = {};\n", "\t}\n", "\t\n", "\t\n", "\t /**\n", "\t * Take an array of integers (index array) and remove a target integer (value - not\n", "\t * the key!)\n", "\t * @param {array} a Index array to target\n", "\t * @param {int} iTarget value to find\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnDeleteIndex( a, iTarget, splice )\n", "\t{\n", "\t\tvar iTargetIndex = -1;\n", "\t\n", "\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\tif ( a[i] == iTarget )\n", "\t\t\t{\n", "\t\t\t\tiTargetIndex = i;\n", "\t\t\t}\n", "\t\t\telse if ( a[i] > iTarget )\n", "\t\t\t{\n", "\t\t\t\ta[i]--;\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\tif ( iTargetIndex != -1 && splice === undefined )\n", "\t\t{\n", "\t\t\ta.splice( iTargetIndex, 1 );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Mark cached data as invalid such that a re-read of the data will occur when\n", "\t * the cached data is next requested. Also update from the data source object.\n", "\t *\n", "\t * @param {object} settings DataTables settings object\n", "\t * @param {int} rowIdx Row index to invalidate\n", "\t * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'\n", "\t * or 'data'\n", "\t * @param {int} [colIdx] Column index to invalidate. If undefined the whole\n", "\t * row will be invalidated\n", "\t * @memberof DataTable#oApi\n", "\t *\n", "\t * @todo For the modularisation of v1.11 this will need to become a callback, so\n", "\t * the sort and filter methods can subscribe to it. That will required\n", "\t * initialisation options for sorting, which is why it is not already baked in\n", "\t */\n", "\tfunction _fnInvalidate( settings, rowIdx, src, colIdx )\n", "\t{\n", "\t\tvar row = settings.aoData[ rowIdx ];\n", "\t\tvar i, ien;\n", "\t\tvar cellWrite = function ( cell, col ) {\n", "\t\t\t// This is very frustrating, but in IE if you just write directly\n", "\t\t\t// to innerHTML, and elements that are overwritten are GC'ed,\n", "\t\t\t// even if there is a reference to them elsewhere\n", "\t\t\twhile ( cell.childNodes.length ) {\n", "\t\t\t\tcell.removeChild( cell.firstChild );\n", "\t\t\t}\n", "\t\n", "\t\t\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\n", "\t\t};\n", "\t\n", "\t\t// Are we reading last data from DOM or the data object?\n", "\t\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\n", "\t\t\t// Read the data from the DOM\n", "\t\t\trow._aData = _fnGetRowElements(\n", "\t\t\t\t\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\n", "\t\t\t\t)\n", "\t\t\t\t.data;\n", "\t\t}\n", "\t\telse {\n", "\t\t\t// Reading from data object, update the DOM\n", "\t\t\tvar cells = row.anCells;\n", "\t\n", "\t\t\tif ( cells ) {\n", "\t\t\t\tif ( colIdx !== undefined ) {\n", "\t\t\t\t\tcellWrite( cells[colIdx], colIdx );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n", "\t\t\t\t\t\tcellWrite( cells[i], i );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t// For both row and cell invalidation, the cached data for sorting and\n", "\t\t// filtering is nulled out\n", "\t\trow._aSortData = null;\n", "\t\trow._aFilterData = null;\n", "\t\n", "\t\t// Invalidate the type for a specific column (if given) or all columns since\n", "\t\t// the data might have changed\n", "\t\tvar cols = settings.aoColumns;\n", "\t\tif ( colIdx !== undefined ) {\n", "\t\t\tcols[ colIdx ].sType = null;\n", "\t\t}\n", "\t\telse {\n", "\t\t\tfor ( i=0, ien=cols.length ; i<ien ; i++ ) {\n", "\t\t\t\tcols[i].sType = null;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Update DataTables special `DT_*` attributes for the row\n", "\t\t\t_fnRowAttributes( settings, row );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Build a data source object from an HTML row, reading the contents of the\n", "\t * cells that are in the row.\n", "\t *\n", "\t * @param {object} settings DataTables settings object\n", "\t * @param {node|object} TR element from which to read data or existing row\n", "\t * object from which to re-read the data from the cells\n", "\t * @param {int} [colIdx] Optional column index\n", "\t * @param {array|object} [d] Data source object. If `colIdx` is given then this\n", "\t * parameter should also be given and will be used to write the data into.\n", "\t * Only the column in question will be written\n", "\t * @returns {object} Object with two parameters: `data` the data read, in\n", "\t * document order, and `cells` and array of nodes (they can be useful to the\n", "\t * caller, so rather than needing a second traversal to get them, just return\n", "\t * them from here).\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetRowElements( settings, row, colIdx, d )\n", "\t{\n", "\t\tvar\n", "\t\t\ttds = [],\n", "\t\t\ttd = row.firstChild,\n", "\t\t\tname, col, o, i=0, contents,\n", "\t\t\tcolumns = settings.aoColumns,\n", "\t\t\tobjectRead = settings._rowReadObject;\n", "\t\n", "\t\t// Allow the data object to be passed in, or construct\n", "\t\td = d !== undefined ?\n", "\t\t\td :\n", "\t\t\tobjectRead ?\n", "\t\t\t\t{} :\n", "\t\t\t\t[];\n", "\t\n", "\t\tvar attr = function ( str, td ) {\n", "\t\t\tif ( typeof str === 'string' ) {\n", "\t\t\t\tvar idx = str.indexOf('@');\n", "\t\n", "\t\t\t\tif ( idx !== -1 ) {\n", "\t\t\t\t\tvar attr = str.substring( idx+1 );\n", "\t\t\t\t\tvar setter = _fnSetObjectDataFn( str );\n", "\t\t\t\t\tsetter( d, td.getAttribute( attr ) );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t};\n", "\t\n", "\t\t// Read data from a cell and store into the data object\n", "\t\tvar cellProcess = function ( cell ) {\n", "\t\t\tif ( colIdx === undefined || colIdx === i ) {\n", "\t\t\t\tcol = columns[i];\n", "\t\t\t\tcontents = $.trim(cell.innerHTML);\n", "\t\n", "\t\t\t\tif ( col && col._bAttrSrc ) {\n", "\t\t\t\t\tvar setter = _fnSetObjectDataFn( col.mData._ );\n", "\t\t\t\t\tsetter( d, contents );\n", "\t\n", "\t\t\t\t\tattr( col.mData.sort, cell );\n", "\t\t\t\t\tattr( col.mData.type, cell );\n", "\t\t\t\t\tattr( col.mData.filter, cell );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\t// Depending on the `data` option for the columns the data can\n", "\t\t\t\t\t// be read to either an object or an array.\n", "\t\t\t\t\tif ( objectRead ) {\n", "\t\t\t\t\t\tif ( ! col._setter ) {\n", "\t\t\t\t\t\t\t// Cache the setter function\n", "\t\t\t\t\t\t\tcol._setter = _fnSetObjectDataFn( col.mData );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\tcol._setter( d, contents );\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse {\n", "\t\t\t\t\t\td[i] = contents;\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\ti++;\n", "\t\t};\n", "\t\n", "\t\tif ( td ) {\n", "\t\t\t// `tr` element was passed in\n", "\t\t\twhile ( td ) {\n", "\t\t\t\tname = td.nodeName.toUpperCase();\n", "\t\n", "\t\t\t\tif ( name == \"TD\" || name == \"TH\" ) {\n", "\t\t\t\t\tcellProcess( td );\n", "\t\t\t\t\ttds.push( td );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\ttd = td.nextSibling;\n", "\t\t\t}\n", "\t\t}\n", "\t\telse {\n", "\t\t\t// Existing row object passed in\n", "\t\t\ttds = row.anCells;\n", "\t\n", "\t\t\tfor ( var j=0, jen=tds.length ; j<jen ; j++ ) {\n", "\t\t\t\tcellProcess( tds[j] );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t// Read the ID from the DOM if present\n", "\t\tvar rowNode = row.firstChild ? row : row.nTr;\n", "\t\n", "\t\tif ( rowNode ) {\n", "\t\t\tvar id = rowNode.getAttribute( 'id' );\n", "\t\n", "\t\t\tif ( id ) {\n", "\t\t\t\t_fnSetObjectDataFn( settings.rowId )( d, id );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn {\n", "\t\t\tdata: d,\n", "\t\t\tcells: tds\n", "\t\t};\n", "\t}\n", "\t/**\n", "\t * Create a new TR element (and it's TD children) for a row\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {int} iRow Row to consider\n", "\t * @param {node} [nTrIn] TR element to add to the table - optional. If not given,\n", "\t * DataTables will create a row automatically\n", "\t * @param {array} [anTds] Array of TD|TH elements for the row - must be given\n", "\t * if nTr is.\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnCreateTr ( oSettings, iRow, nTrIn, anTds )\n", "\t{\n", "\t\tvar\n", "\t\t\trow = oSettings.aoData[iRow],\n", "\t\t\trowData = row._aData,\n", "\t\t\tcells = [],\n", "\t\t\tnTr, nTd, oCol,\n", "\t\t\ti, iLen;\n", "\t\n", "\t\tif ( row.nTr === null )\n", "\t\t{\n", "\t\t\tnTr = nTrIn || document.createElement('tr');\n", "\t\n", "\t\t\trow.nTr = nTr;\n", "\t\t\trow.anCells = cells;\n", "\t\n", "\t\t\t/* Use a private property on the node to allow reserve mapping from the node\n", "\t\t\t * to the aoData array for fast look up\n", "\t\t\t */\n", "\t\t\tnTr._DT_RowIndex = iRow;\n", "\t\n", "\t\t\t/* Special parameters can be given by the data source to be used on the row */\n", "\t\t\t_fnRowAttributes( oSettings, row );\n", "\t\n", "\t\t\t/* Process each column */\n", "\t\t\tfor ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )\n", "\t\t\t{\n", "\t\t\t\toCol = oSettings.aoColumns[i];\n", "\t\n", "\t\t\t\tnTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );\n", "\t\t\t\tnTd._DT_CellIndex = {\n", "\t\t\t\t\trow: iRow,\n", "\t\t\t\t\tcolumn: i\n", "\t\t\t\t};\n", "\t\t\t\t\n", "\t\t\t\tcells.push( nTd );\n", "\t\n", "\t\t\t\t// Need to create the HTML if new, or if a rendering function is defined\n", "\t\t\t\tif ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&\n", "\t\t\t\t\t (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')\n", "\t\t\t\t) {\n", "\t\t\t\t\tnTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t/* Add user defined class */\n", "\t\t\t\tif ( oCol.sClass )\n", "\t\t\t\t{\n", "\t\t\t\t\tnTd.className += ' '+oCol.sClass;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// Visibility - add or remove as required\n", "\t\t\t\tif ( oCol.bVisible && ! nTrIn )\n", "\t\t\t\t{\n", "\t\t\t\t\tnTr.appendChild( nTd );\n", "\t\t\t\t}\n", "\t\t\t\telse if ( ! oCol.bVisible && nTrIn )\n", "\t\t\t\t{\n", "\t\t\t\t\tnTd.parentNode.removeChild( nTd );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tif ( oCol.fnCreatedCell )\n", "\t\t\t\t{\n", "\t\t\t\t\toCol.fnCreatedCell.call( oSettings.oInstance,\n", "\t\t\t\t\t\tnTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i\n", "\t\t\t\t\t);\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );\n", "\t\t}\n", "\t\n", "\t\t// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved\n", "\t\t// and deployed\n", "\t\trow.nTr.setAttribute( 'role', 'row' );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Add attributes to a row based on the special `DT_*` parameters in a data\n", "\t * source object.\n", "\t * @param {object} settings DataTables settings object\n", "\t * @param {object} DataTables row object for the row to be modified\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnRowAttributes( settings, row )\n", "\t{\n", "\t\tvar tr = row.nTr;\n", "\t\tvar data = row._aData;\n", "\t\n", "\t\tif ( tr ) {\n", "\t\t\tvar id = settings.rowIdFn( data );\n", "\t\n", "\t\t\tif ( id ) {\n", "\t\t\t\ttr.id = id;\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( data.DT_RowClass ) {\n", "\t\t\t\t// Remove any classes added by DT_RowClass before\n", "\t\t\t\tvar a = data.DT_RowClass.split(' ');\n", "\t\t\t\trow.__rowc = row.__rowc ?\n", "\t\t\t\t\t_unique( row.__rowc.concat( a ) ) :\n", "\t\t\t\t\ta;\n", "\t\n", "\t\t\t\t$(tr)\n", "\t\t\t\t\t.removeClass( row.__rowc.join(' ') )\n", "\t\t\t\t\t.addClass( data.DT_RowClass );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( data.DT_RowAttr ) {\n", "\t\t\t\t$(tr).attr( data.DT_RowAttr );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( data.DT_RowData ) {\n", "\t\t\t\t$(tr).data( data.DT_RowData );\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Create the HTML header for the table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnBuildHead( oSettings )\n", "\t{\n", "\t\tvar i, ien, cell, row, column;\n", "\t\tvar thead = oSettings.nTHead;\n", "\t\tvar tfoot = oSettings.nTFoot;\n", "\t\tvar createHeader = $('th, td', thead).length === 0;\n", "\t\tvar classes = oSettings.oClasses;\n", "\t\tvar columns = oSettings.aoColumns;\n", "\t\n", "\t\tif ( createHeader ) {\n", "\t\t\trow = $('<tr/>').appendTo( thead );\n", "\t\t}\n", "\t\n", "\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n", "\t\t\tcolumn = columns[i];\n", "\t\t\tcell = $( column.nTh ).addClass( column.sClass );\n", "\t\n", "\t\t\tif ( createHeader ) {\n", "\t\t\t\tcell.appendTo( row );\n", "\t\t\t}\n", "\t\n", "\t\t\t// 1.11 move into sorting\n", "\t\t\tif ( oSettings.oFeatures.bSort ) {\n", "\t\t\t\tcell.addClass( column.sSortingClass );\n", "\t\n", "\t\t\t\tif ( column.bSortable !== false ) {\n", "\t\t\t\t\tcell\n", "\t\t\t\t\t\t.attr( 'tabindex', oSettings.iTabIndex )\n", "\t\t\t\t\t\t.attr( 'aria-controls', oSettings.sTableId );\n", "\t\n", "\t\t\t\t\t_fnSortAttachListener( oSettings, column.nTh, i );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( column.sTitle != cell[0].innerHTML ) {\n", "\t\t\t\tcell.html( column.sTitle );\n", "\t\t\t}\n", "\t\n", "\t\t\t_fnRenderer( oSettings, 'header' )(\n", "\t\t\t\toSettings, cell, column, classes\n", "\t\t\t);\n", "\t\t}\n", "\t\n", "\t\tif ( createHeader ) {\n", "\t\t\t_fnDetectHeader( oSettings.aoHeader, thead );\n", "\t\t}\n", "\t\t\n", "\t\t/* ARIA role for the rows */\n", "\t \t$(thead).find('>tr').attr('role', 'row');\n", "\t\n", "\t\t/* Deal with the footer - add classes if required */\n", "\t\t$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );\n", "\t\t$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );\n", "\t\n", "\t\t// Cache the footer cells. Note that we only take the cells from the first\n", "\t\t// row in the footer. If there is more than one row the user wants to\n", "\t\t// interact with, they need to use the table().foot() method. Note also this\n", "\t\t// allows cells to be used for multiple columns using colspan\n", "\t\tif ( tfoot !== null ) {\n", "\t\t\tvar cells = oSettings.aoFooter[0];\n", "\t\n", "\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n", "\t\t\t\tcolumn = columns[i];\n", "\t\t\t\tcolumn.nTf = cells[i].cell;\n", "\t\n", "\t\t\t\tif ( column.sClass ) {\n", "\t\t\t\t\t$(column.nTf).addClass( column.sClass );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Draw the header (or footer) element based on the column visibility states. The\n", "\t * methodology here is to use the layout array from _fnDetectHeader, modified for\n", "\t * the instantaneous column visibility, to construct the new layout. The grid is\n", "\t * traversed over cell at a time in a rows x columns grid fashion, although each\n", "\t * cell insert can cover multiple elements in the grid - which is tracks using the\n", "\t * aApplied array. Cell inserts in the grid will only occur where there isn't\n", "\t * already a cell in that position.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param array {objects} aoSource Layout array from _fnDetectHeader\n", "\t * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnDrawHead( oSettings, aoSource, bIncludeHidden )\n", "\t{\n", "\t\tvar i, iLen, j, jLen, k, kLen, n, nLocalTr;\n", "\t\tvar aoLocal = [];\n", "\t\tvar aApplied = [];\n", "\t\tvar iColumns = oSettings.aoColumns.length;\n", "\t\tvar iRowspan, iColspan;\n", "\t\n", "\t\tif ( ! aoSource )\n", "\t\t{\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tif ( bIncludeHidden === undefined )\n", "\t\t{\n", "\t\t\tbIncludeHidden = false;\n", "\t\t}\n", "\t\n", "\t\t/* Make a copy of the master layout array, but without the visible columns in it */\n", "\t\tfor ( i=0, iLen=aoSource.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\taoLocal[i] = aoSource[i].slice();\n", "\t\t\taoLocal[i].nTr = aoSource[i].nTr;\n", "\t\n", "\t\t\t/* Remove any columns which are currently hidden */\n", "\t\t\tfor ( j=iColumns-1 ; j>=0 ; j-- )\n", "\t\t\t{\n", "\t\t\t\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\n", "\t\t\t\t{\n", "\t\t\t\t\taoLocal[i].splice( j, 1 );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t/* Prep the applied array - it needs an element for each row */\n", "\t\t\taApplied.push( [] );\n", "\t\t}\n", "\t\n", "\t\tfor ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\tnLocalTr = aoLocal[i].nTr;\n", "\t\n", "\t\t\t/* All cells are going to be replaced, so empty out the row */\n", "\t\t\tif ( nLocalTr )\n", "\t\t\t{\n", "\t\t\t\twhile( (n = nLocalTr.firstChild) )\n", "\t\t\t\t{\n", "\t\t\t\t\tnLocalTr.removeChild( n );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\tfor ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )\n", "\t\t\t{\n", "\t\t\t\tiRowspan = 1;\n", "\t\t\t\tiColspan = 1;\n", "\t\n", "\t\t\t\t/* Check to see if there is already a cell (row/colspan) covering our target\n", "\t\t\t\t * insert point. If there is, then there is nothing to do.\n", "\t\t\t\t */\n", "\t\t\t\tif ( aApplied[i][j] === undefined )\n", "\t\t\t\t{\n", "\t\t\t\t\tnLocalTr.appendChild( aoLocal[i][j].cell );\n", "\t\t\t\t\taApplied[i][j] = 1;\n", "\t\n", "\t\t\t\t\t/* Expand the cell to cover as many rows as needed */\n", "\t\t\t\t\twhile ( aoLocal[i+iRowspan] !== undefined &&\n", "\t\t\t\t\t aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\taApplied[i+iRowspan][j] = 1;\n", "\t\t\t\t\t\tiRowspan++;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t/* Expand the cell to cover as many columns as needed */\n", "\t\t\t\t\twhile ( aoLocal[i][j+iColspan] !== undefined &&\n", "\t\t\t\t\t aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t/* Must update the applied array over the rows for the columns */\n", "\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\taApplied[i+k][j+iColspan] = 1;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\tiColspan++;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t/* Do the actual expansion in the DOM */\n", "\t\t\t\t\t$(aoLocal[i][j].cell)\n", "\t\t\t\t\t\t.attr('rowspan', iRowspan)\n", "\t\t\t\t\t\t.attr('colspan', iColspan);\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Insert the required TR nodes into the table for display\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnDraw( oSettings )\n", "\t{\n", "\t\t/* Provide a pre-callback function which can be used to cancel the draw is false is returned */\n", "\t\tvar aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );\n", "\t\tif ( $.inArray( false, aPreDraw ) !== -1 )\n", "\t\t{\n", "\t\t\t_fnProcessingDisplay( oSettings, false );\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tvar i, iLen, n;\n", "\t\tvar anRows = [];\n", "\t\tvar iRowCount = 0;\n", "\t\tvar asStripeClasses = oSettings.asStripeClasses;\n", "\t\tvar iStripes = asStripeClasses.length;\n", "\t\tvar iOpenRows = oSettings.aoOpenRows.length;\n", "\t\tvar oLang = oSettings.oLanguage;\n", "\t\tvar iInitDisplayStart = oSettings.iInitDisplayStart;\n", "\t\tvar bServerSide = _fnDataSource( oSettings ) == 'ssp';\n", "\t\tvar aiDisplay = oSettings.aiDisplay;\n", "\t\n", "\t\toSettings.bDrawing = true;\n", "\t\n", "\t\t/* Check and see if we have an initial draw position from state saving */\n", "\t\tif ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )\n", "\t\t{\n", "\t\t\toSettings._iDisplayStart = bServerSide ?\n", "\t\t\t\tiInitDisplayStart :\n", "\t\t\t\tiInitDisplayStart >= oSettings.fnRecordsDisplay() ?\n", "\t\t\t\t\t0 :\n", "\t\t\t\t\tiInitDisplayStart;\n", "\t\n", "\t\t\toSettings.iInitDisplayStart = -1;\n", "\t\t}\n", "\t\n", "\t\tvar iDisplayStart = oSettings._iDisplayStart;\n", "\t\tvar iDisplayEnd = oSettings.fnDisplayEnd();\n", "\t\n", "\t\t/* Server-side processing draw intercept */\n", "\t\tif ( oSettings.bDeferLoading )\n", "\t\t{\n", "\t\t\toSettings.bDeferLoading = false;\n", "\t\t\toSettings.iDraw++;\n", "\t\t\t_fnProcessingDisplay( oSettings, false );\n", "\t\t}\n", "\t\telse if ( !bServerSide )\n", "\t\t{\n", "\t\t\toSettings.iDraw++;\n", "\t\t}\n", "\t\telse if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )\n", "\t\t{\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tif ( aiDisplay.length !== 0 )\n", "\t\t{\n", "\t\t\tvar iStart = bServerSide ? 0 : iDisplayStart;\n", "\t\t\tvar iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;\n", "\t\n", "\t\t\tfor ( var j=iStart ; j<iEnd ; j++ )\n", "\t\t\t{\n", "\t\t\t\tvar iDataIndex = aiDisplay[j];\n", "\t\t\t\tvar aoData = oSettings.aoData[ iDataIndex ];\n", "\t\t\t\tif ( aoData.nTr === null )\n", "\t\t\t\t{\n", "\t\t\t\t\t_fnCreateTr( oSettings, iDataIndex );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tvar nRow = aoData.nTr;\n", "\t\n", "\t\t\t\t/* Remove the old striping classes and then add the new one */\n", "\t\t\t\tif ( iStripes !== 0 )\n", "\t\t\t\t{\n", "\t\t\t\t\tvar sStripe = asStripeClasses[ iRowCount % iStripes ];\n", "\t\t\t\t\tif ( aoData._sRowStripe != sStripe )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\t$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );\n", "\t\t\t\t\t\taoData._sRowStripe = sStripe;\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// Row callback functions - might want to manipulate the row\n", "\t\t\t\t// iRowCount and j are not currently documented. Are they at all\n", "\t\t\t\t// useful?\n", "\t\t\t\t_fnCallbackFire( oSettings, 'aoRowCallback', null,\n", "\t\t\t\t\t[nRow, aoData._aData, iRowCount, j] );\n", "\t\n", "\t\t\t\tanRows.push( nRow );\n", "\t\t\t\tiRowCount++;\n", "\t\t\t}\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\t/* Table is empty - create a row with an empty message in it */\n", "\t\t\tvar sZero = oLang.sZeroRecords;\n", "\t\t\tif ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )\n", "\t\t\t{\n", "\t\t\t\tsZero = oLang.sLoadingRecords;\n", "\t\t\t}\n", "\t\t\telse if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )\n", "\t\t\t{\n", "\t\t\t\tsZero = oLang.sEmptyTable;\n", "\t\t\t}\n", "\t\n", "\t\t\tanRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )\n", "\t\t\t\t.append( $('<td />', {\n", "\t\t\t\t\t'valign': 'top',\n", "\t\t\t\t\t'colSpan': _fnVisbleColumns( oSettings ),\n", "\t\t\t\t\t'class': oSettings.oClasses.sRowEmpty\n", "\t\t\t\t} ).html( sZero ) )[0];\n", "\t\t}\n", "\t\n", "\t\t/* Header and footer callbacks */\n", "\t\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\n", "\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n", "\t\n", "\t\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\n", "\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n", "\t\n", "\t\tvar body = $(oSettings.nTBody);\n", "\t\n", "\t\tbody.children().detach();\n", "\t\tbody.append( $(anRows) );\n", "\t\n", "\t\t/* Call all required callback functions for the end of a draw */\n", "\t\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\n", "\t\n", "\t\t/* Draw is complete, sorting and filtering must be as well */\n", "\t\toSettings.bSorted = false;\n", "\t\toSettings.bFiltered = false;\n", "\t\toSettings.bDrawing = false;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Redraw the table - taking account of the various features which are enabled\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {boolean} [holdPosition] Keep the current paging position. By default\n", "\t * the paging is reset to the first page\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnReDraw( settings, holdPosition )\n", "\t{\n", "\t\tvar\n", "\t\t\tfeatures = settings.oFeatures,\n", "\t\t\tsort = features.bSort,\n", "\t\t\tfilter = features.bFilter;\n", "\t\n", "\t\tif ( sort ) {\n", "\t\t\t_fnSort( settings );\n", "\t\t}\n", "\t\n", "\t\tif ( filter ) {\n", "\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch );\n", "\t\t}\n", "\t\telse {\n", "\t\t\t// No filtering, so we want to just use the display master\n", "\t\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n", "\t\t}\n", "\t\n", "\t\tif ( holdPosition !== true ) {\n", "\t\t\tsettings._iDisplayStart = 0;\n", "\t\t}\n", "\t\n", "\t\t// Let any modules know about the draw hold position state (used by\n", "\t\t// scrolling internally)\n", "\t\tsettings._drawHold = holdPosition;\n", "\t\n", "\t\t_fnDraw( settings );\n", "\t\n", "\t\tsettings._drawHold = false;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Add the options to the page HTML for the table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAddOptionsHtml ( oSettings )\n", "\t{\n", "\t\tvar classes = oSettings.oClasses;\n", "\t\tvar table = $(oSettings.nTable);\n", "\t\tvar holding = $('<div/>').insertBefore( table ); // Holding element for speed\n", "\t\tvar features = oSettings.oFeatures;\n", "\t\n", "\t\t// All DataTables are wrapped in a div\n", "\t\tvar insert = $('<div/>', {\n", "\t\t\tid: oSettings.sTableId+'_wrapper',\n", "\t\t\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\n", "\t\t} );\n", "\t\n", "\t\toSettings.nHolding = holding[0];\n", "\t\toSettings.nTableWrapper = insert[0];\n", "\t\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\n", "\t\n", "\t\t/* Loop over the user set positioning and place the elements as needed */\n", "\t\tvar aDom = oSettings.sDom.split('');\n", "\t\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\n", "\t\tfor ( var i=0 ; i<aDom.length ; i++ )\n", "\t\t{\n", "\t\t\tfeatureNode = null;\n", "\t\t\tcOption = aDom[i];\n", "\t\n", "\t\t\tif ( cOption == '<' )\n", "\t\t\t{\n", "\t\t\t\t/* New container div */\n", "\t\t\t\tnNewNode = $('<div/>')[0];\n", "\t\n", "\t\t\t\t/* Check to see if we should append an id and/or a class name to the container */\n", "\t\t\t\tcNext = aDom[i+1];\n", "\t\t\t\tif ( cNext == \"'\" || cNext == '\"' )\n", "\t\t\t\t{\n", "\t\t\t\t\tsAttr = \"\";\n", "\t\t\t\t\tj = 2;\n", "\t\t\t\t\twhile ( aDom[i+j] != cNext )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tsAttr += aDom[i+j];\n", "\t\t\t\t\t\tj++;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t/* Replace jQuery UI constants @todo depreciated */\n", "\t\t\t\t\tif ( sAttr == \"H\" )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tsAttr = classes.sJUIHeader;\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( sAttr == \"F\" )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tsAttr = classes.sJUIFooter;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t/* The attribute can be in the format of \"#id.class\", \"#id\" or \"class\" This logic\n", "\t\t\t\t\t * breaks the string into parts and applies them as needed\n", "\t\t\t\t\t */\n", "\t\t\t\t\tif ( sAttr.indexOf('.') != -1 )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tvar aSplit = sAttr.split('.');\n", "\t\t\t\t\t\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\n", "\t\t\t\t\t\tnNewNode.className = aSplit[1];\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( sAttr.charAt(0) == \"#\" )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tnNewNode.className = sAttr;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\ti += j; /* Move along the position array */\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tinsert.append( nNewNode );\n", "\t\t\t\tinsert = $(nNewNode);\n", "\t\t\t}\n", "\t\t\telse if ( cOption == '>' )\n", "\t\t\t{\n", "\t\t\t\t/* End container div */\n", "\t\t\t\tinsert = insert.parent();\n", "\t\t\t}\n", "\t\t\t// @todo Move options into their own plugins?\n", "\t\t\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\n", "\t\t\t{\n", "\t\t\t\t/* Length */\n", "\t\t\t\tfeatureNode = _fnFeatureHtmlLength( oSettings );\n", "\t\t\t}\n", "\t\t\telse if ( cOption == 'f' && features.bFilter )\n", "\t\t\t{\n", "\t\t\t\t/* Filter */\n", "\t\t\t\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\n", "\t\t\t}\n", "\t\t\telse if ( cOption == 'r' && features.bProcessing )\n", "\t\t\t{\n", "\t\t\t\t/* pRocessing */\n", "\t\t\t\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\n", "\t\t\t}\n", "\t\t\telse if ( cOption == 't' )\n", "\t\t\t{\n", "\t\t\t\t/* Table */\n", "\t\t\t\tfeatureNode = _fnFeatureHtmlTable( oSettings );\n", "\t\t\t}\n", "\t\t\telse if ( cOption == 'i' && features.bInfo )\n", "\t\t\t{\n", "\t\t\t\t/* Info */\n", "\t\t\t\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\n", "\t\t\t}\n", "\t\t\telse if ( cOption == 'p' && features.bPaginate )\n", "\t\t\t{\n", "\t\t\t\t/* Pagination */\n", "\t\t\t\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\n", "\t\t\t}\n", "\t\t\telse if ( DataTable.ext.feature.length !== 0 )\n", "\t\t\t{\n", "\t\t\t\t/* Plug-in features */\n", "\t\t\t\tvar aoFeatures = DataTable.ext.feature;\n", "\t\t\t\tfor ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )\n", "\t\t\t\t{\n", "\t\t\t\t\tif ( cOption == aoFeatures[k].cFeature )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tfeatureNode = aoFeatures[k].fnInit( oSettings );\n", "\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t/* Add to the 2D features array */\n", "\t\t\tif ( featureNode )\n", "\t\t\t{\n", "\t\t\t\tvar aanFeatures = oSettings.aanFeatures;\n", "\t\n", "\t\t\t\tif ( ! aanFeatures[cOption] )\n", "\t\t\t\t{\n", "\t\t\t\t\taanFeatures[cOption] = [];\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\taanFeatures[cOption].push( featureNode );\n", "\t\t\t\tinsert.append( featureNode );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t/* Built our DOM structure - replace the holding div with what we want */\n", "\t\tholding.replaceWith( insert );\n", "\t\toSettings.nHolding = null;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Use the DOM source to create up an array of header cells. The idea here is to\n", "\t * create a layout grid (array) of rows x columns, which contains a reference\n", "\t * to the cell that that point in the grid (regardless of col/rowspan), such that\n", "\t * any column / row could be removed and the new grid constructed\n", "\t * @param array {object} aLayout Array to store the calculated layout in\n", "\t * @param {node} nThead The header/footer element for the table\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnDetectHeader ( aLayout, nThead )\n", "\t{\n", "\t\tvar nTrs = $(nThead).children('tr');\n", "\t\tvar nTr, nCell;\n", "\t\tvar i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;\n", "\t\tvar bUnique;\n", "\t\tvar fnShiftCol = function ( a, i, j ) {\n", "\t\t\tvar k = a[i];\n", "\t while ( k[j] ) {\n", "\t\t\t\tj++;\n", "\t\t\t}\n", "\t\t\treturn j;\n", "\t\t};\n", "\t\n", "\t\taLayout.splice( 0, aLayout.length );\n", "\t\n", "\t\t/* We know how many rows there are in the layout - so prep it */\n", "\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\taLayout.push( [] );\n", "\t\t}\n", "\t\n", "\t\t/* Calculate a layout array */\n", "\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\tnTr = nTrs[i];\n", "\t\t\tiColumn = 0;\n", "\t\n", "\t\t\t/* For every cell in the row... */\n", "\t\t\tnCell = nTr.firstChild;\n", "\t\t\twhile ( nCell ) {\n", "\t\t\t\tif ( nCell.nodeName.toUpperCase() == \"TD\" ||\n", "\t\t\t\t nCell.nodeName.toUpperCase() == \"TH\" )\n", "\t\t\t\t{\n", "\t\t\t\t\t/* Get the col and rowspan attributes from the DOM and sanitise them */\n", "\t\t\t\t\tiColspan = nCell.getAttribute('colspan') * 1;\n", "\t\t\t\t\tiRowspan = nCell.getAttribute('rowspan') * 1;\n", "\t\t\t\t\tiColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;\n", "\t\t\t\t\tiRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;\n", "\t\n", "\t\t\t\t\t/* There might be colspan cells already in this row, so shift our target\n", "\t\t\t\t\t * accordingly\n", "\t\t\t\t\t */\n", "\t\t\t\t\tiColShifted = fnShiftCol( aLayout, i, iColumn );\n", "\t\n", "\t\t\t\t\t/* Cache calculation for unique columns */\n", "\t\t\t\t\tbUnique = iColspan === 1 ? true : false;\n", "\t\n", "\t\t\t\t\t/* If there is col / rowspan, copy the information into the layout grid */\n", "\t\t\t\t\tfor ( l=0 ; l<iColspan ; l++ )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n", "\t\t\t\t\t\t{\n", "\t\t\t\t\t\t\taLayout[i+k][iColShifted+l] = {\n", "\t\t\t\t\t\t\t\t\"cell\": nCell,\n", "\t\t\t\t\t\t\t\t\"unique\": bUnique\n", "\t\t\t\t\t\t\t};\n", "\t\t\t\t\t\t\taLayout[i+k].nTr = nTr;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\tnCell = nCell.nextSibling;\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get an array of unique th elements, one for each column\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {node} nHeader automatically detect the layout from this node - optional\n", "\t * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional\n", "\t * @returns array {node} aReturn list of unique th's\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetUniqueThs ( oSettings, nHeader, aLayout )\n", "\t{\n", "\t\tvar aReturn = [];\n", "\t\tif ( !aLayout )\n", "\t\t{\n", "\t\t\taLayout = oSettings.aoHeader;\n", "\t\t\tif ( nHeader )\n", "\t\t\t{\n", "\t\t\t\taLayout = [];\n", "\t\t\t\t_fnDetectHeader( aLayout, nHeader );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\tfor ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\tfor ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )\n", "\t\t\t{\n", "\t\t\t\tif ( aLayout[i][j].unique &&\n", "\t\t\t\t\t (!aReturn[j] || !oSettings.bSortCellsTop) )\n", "\t\t\t\t{\n", "\t\t\t\t\taReturn[j] = aLayout[i][j].cell;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn aReturn;\n", "\t}\n", "\t\n", "\t/**\n", "\t * Create an Ajax call based on the table's settings, taking into account that\n", "\t * parameters can have multiple forms, and backwards compatibility.\n", "\t *\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {array} data Data to send to the server, required by\n", "\t * DataTables - may be augmented by developer callbacks\n", "\t * @param {function} fn Callback function to run when data is obtained\n", "\t */\n", "\tfunction _fnBuildAjax( oSettings, data, fn )\n", "\t{\n", "\t\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\n", "\t\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\n", "\t\n", "\t\t// Convert to object based for 1.10+ if using the old array scheme which can\n", "\t\t// come from server-side processing or serverParams\n", "\t\tif ( data && $.isArray(data) ) {\n", "\t\t\tvar tmp = {};\n", "\t\t\tvar rbracket = /(.*?)\\[\\]$/;\n", "\t\n", "\t\t\t$.each( data, function (key, val) {\n", "\t\t\t\tvar match = val.name.match(rbracket);\n", "\t\n", "\t\t\t\tif ( match ) {\n", "\t\t\t\t\t// Support for arrays\n", "\t\t\t\t\tvar name = match[0];\n", "\t\n", "\t\t\t\t\tif ( ! tmp[ name ] ) {\n", "\t\t\t\t\t\ttmp[ name ] = [];\n", "\t\t\t\t\t}\n", "\t\t\t\t\ttmp[ name ].push( val.value );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\ttmp[val.name] = val.value;\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\t\tdata = tmp;\n", "\t\t}\n", "\t\n", "\t\tvar ajaxData;\n", "\t\tvar ajax = oSettings.ajax;\n", "\t\tvar instance = oSettings.oInstance;\n", "\t\tvar callback = function ( json ) {\n", "\t\t\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\n", "\t\t\tfn( json );\n", "\t\t};\n", "\t\n", "\t\tif ( $.isPlainObject( ajax ) && ajax.data )\n", "\t\t{\n", "\t\t\tajaxData = ajax.data;\n", "\t\n", "\t\t\tvar newData = $.isFunction( ajaxData ) ?\n", "\t\t\t\tajaxData( data, oSettings ) : // fn can manipulate data or return\n", "\t\t\t\tajaxData; // an object object or array to merge\n", "\t\n", "\t\t\t// If the function returned something, use that alone\n", "\t\t\tdata = $.isFunction( ajaxData ) && newData ?\n", "\t\t\t\tnewData :\n", "\t\t\t\t$.extend( true, data, newData );\n", "\t\n", "\t\t\t// Remove the data property as we've resolved it already and don't want\n", "\t\t\t// jQuery to do it again (it is restored at the end of the function)\n", "\t\t\tdelete ajax.data;\n", "\t\t}\n", "\t\n", "\t\tvar baseAjax = {\n", "\t\t\t\"data\": data,\n", "\t\t\t\"success\": function (json) {\n", "\t\t\t\tvar error = json.error || json.sError;\n", "\t\t\t\tif ( error ) {\n", "\t\t\t\t\t_fnLog( oSettings, 0, error );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\toSettings.json = json;\n", "\t\t\t\tcallback( json );\n", "\t\t\t},\n", "\t\t\t\"dataType\": \"json\",\n", "\t\t\t\"cache\": false,\n", "\t\t\t\"type\": oSettings.sServerMethod,\n", "\t\t\t\"error\": function (xhr, error, thrown) {\n", "\t\t\t\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\n", "\t\n", "\t\t\t\tif ( $.inArray( true, ret ) === -1 ) {\n", "\t\t\t\t\tif ( error == \"parsererror\" ) {\n", "\t\t\t\t\t\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse if ( xhr.readyState === 4 ) {\n", "\t\t\t\t\t\t_fnLog( oSettings, 0, 'Ajax error', 7 );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t_fnProcessingDisplay( oSettings, false );\n", "\t\t\t}\n", "\t\t};\n", "\t\n", "\t\t// Store the data submitted for the API\n", "\t\toSettings.oAjaxData = data;\n", "\t\n", "\t\t// Allow plug-ins and external processes to modify the data\n", "\t\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\n", "\t\n", "\t\tif ( oSettings.fnServerData )\n", "\t\t{\n", "\t\t\t// DataTables 1.9- compatibility\n", "\t\t\toSettings.fnServerData.call( instance,\n", "\t\t\t\toSettings.sAjaxSource,\n", "\t\t\t\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\n", "\t\t\t\t\treturn { name: key, value: val };\n", "\t\t\t\t} ),\n", "\t\t\t\tcallback,\n", "\t\t\t\toSettings\n", "\t\t\t);\n", "\t\t}\n", "\t\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\n", "\t\t{\n", "\t\t\t// DataTables 1.9- compatibility\n", "\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\n", "\t\t\t\turl: ajax || oSettings.sAjaxSource\n", "\t\t\t} ) );\n", "\t\t}\n", "\t\telse if ( $.isFunction( ajax ) )\n", "\t\t{\n", "\t\t\t// Is a function - let the caller define what needs to be done\n", "\t\t\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\t// Object to extend the base settings\n", "\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\n", "\t\n", "\t\t\t// Restore for next time around\n", "\t\t\tajax.data = ajaxData;\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Update the table using an Ajax call\n", "\t * @param {object} settings dataTables settings object\n", "\t * @returns {boolean} Block the table drawing or not\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAjaxUpdate( settings )\n", "\t{\n", "\t\tif ( settings.bAjaxDataGet ) {\n", "\t\t\tsettings.iDraw++;\n", "\t\t\t_fnProcessingDisplay( settings, true );\n", "\t\n", "\t\t\t_fnBuildAjax(\n", "\t\t\t\tsettings,\n", "\t\t\t\t_fnAjaxParameters( settings ),\n", "\t\t\t\tfunction(json) {\n", "\t\t\t\t\t_fnAjaxUpdateDraw( settings, json );\n", "\t\t\t\t}\n", "\t\t\t);\n", "\t\n", "\t\t\treturn false;\n", "\t\t}\n", "\t\treturn true;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Build up the parameters in an object needed for a server-side processing\n", "\t * request. Note that this is basically done twice, is different ways - a modern\n", "\t * method which is used by default in DataTables 1.10 which uses objects and\n", "\t * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\n", "\t * the sAjaxSource option is used in the initialisation, or the legacyAjax\n", "\t * option is set.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @returns {bool} block the table drawing or not\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAjaxParameters( settings )\n", "\t{\n", "\t\tvar\n", "\t\t\tcolumns = settings.aoColumns,\n", "\t\t\tcolumnCount = columns.length,\n", "\t\t\tfeatures = settings.oFeatures,\n", "\t\t\tpreSearch = settings.oPreviousSearch,\n", "\t\t\tpreColSearch = settings.aoPreSearchCols,\n", "\t\t\ti, data = [], dataProp, column, columnSearch,\n", "\t\t\tsort = _fnSortFlatten( settings ),\n", "\t\t\tdisplayStart = settings._iDisplayStart,\n", "\t\t\tdisplayLength = features.bPaginate !== false ?\n", "\t\t\t\tsettings._iDisplayLength :\n", "\t\t\t\t-1;\n", "\t\n", "\t\tvar param = function ( name, value ) {\n", "\t\t\tdata.push( { 'name': name, 'value': value } );\n", "\t\t};\n", "\t\n", "\t\t// DataTables 1.9- compatible method\n", "\t\tparam( 'sEcho', settings.iDraw );\n", "\t\tparam( 'iColumns', columnCount );\n", "\t\tparam( 'sColumns', _pluck( columns, 'sName' ).join(',') );\n", "\t\tparam( 'iDisplayStart', displayStart );\n", "\t\tparam( 'iDisplayLength', displayLength );\n", "\t\n", "\t\t// DataTables 1.10+ method\n", "\t\tvar d = {\n", "\t\t\tdraw: settings.iDraw,\n", "\t\t\tcolumns: [],\n", "\t\t\torder: [],\n", "\t\t\tstart: displayStart,\n", "\t\t\tlength: displayLength,\n", "\t\t\tsearch: {\n", "\t\t\t\tvalue: preSearch.sSearch,\n", "\t\t\t\tregex: preSearch.bRegex\n", "\t\t\t}\n", "\t\t};\n", "\t\n", "\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n", "\t\t\tcolumn = columns[i];\n", "\t\t\tcolumnSearch = preColSearch[i];\n", "\t\t\tdataProp = typeof column.mData==\"function\" ? 'function' : column.mData ;\n", "\t\n", "\t\t\td.columns.push( {\n", "\t\t\t\tdata: dataProp,\n", "\t\t\t\tname: column.sName,\n", "\t\t\t\tsearchable: column.bSearchable,\n", "\t\t\t\torderable: column.bSortable,\n", "\t\t\t\tsearch: {\n", "\t\t\t\t\tvalue: columnSearch.sSearch,\n", "\t\t\t\t\tregex: columnSearch.bRegex\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\n", "\t\t\tparam( \"mDataProp_\"+i, dataProp );\n", "\t\n", "\t\t\tif ( features.bFilter ) {\n", "\t\t\t\tparam( 'sSearch_'+i, columnSearch.sSearch );\n", "\t\t\t\tparam( 'bRegex_'+i, columnSearch.bRegex );\n", "\t\t\t\tparam( 'bSearchable_'+i, column.bSearchable );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( features.bSort ) {\n", "\t\t\t\tparam( 'bSortable_'+i, column.bSortable );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\tif ( features.bFilter ) {\n", "\t\t\tparam( 'sSearch', preSearch.sSearch );\n", "\t\t\tparam( 'bRegex', preSearch.bRegex );\n", "\t\t}\n", "\t\n", "\t\tif ( features.bSort ) {\n", "\t\t\t$.each( sort, function ( i, val ) {\n", "\t\t\t\td.order.push( { column: val.col, dir: val.dir } );\n", "\t\n", "\t\t\t\tparam( 'iSortCol_'+i, val.col );\n", "\t\t\t\tparam( 'sSortDir_'+i, val.dir );\n", "\t\t\t} );\n", "\t\n", "\t\t\tparam( 'iSortingCols', sort.length );\n", "\t\t}\n", "\t\n", "\t\t// If the legacy.ajax parameter is null, then we automatically decide which\n", "\t\t// form to use, based on sAjaxSource\n", "\t\tvar legacy = DataTable.ext.legacy.ajax;\n", "\t\tif ( legacy === null ) {\n", "\t\t\treturn settings.sAjaxSource ? data : d;\n", "\t\t}\n", "\t\n", "\t\t// Otherwise, if legacy has been specified then we use that to decide on the\n", "\t\t// form\n", "\t\treturn legacy ? data : d;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Data the data from the server (nuking the old) and redraw the table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {object} json json data return from the server.\n", "\t * @param {string} json.sEcho Tracking flag for DataTables to match requests\n", "\t * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering\n", "\t * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering\n", "\t * @param {array} json.aaData The data to display on this page\n", "\t * @param {string} [json.sColumns] Column ordering (sName, comma separated)\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnAjaxUpdateDraw ( settings, json )\n", "\t{\n", "\t\t// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.\n", "\t\t// Support both\n", "\t\tvar compat = function ( old, modern ) {\n", "\t\t\treturn json[old] !== undefined ? json[old] : json[modern];\n", "\t\t};\n", "\t\n", "\t\tvar data = _fnAjaxDataSrc( settings, json );\n", "\t\tvar draw = compat( 'sEcho', 'draw' );\n", "\t\tvar recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );\n", "\t\tvar recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );\n", "\t\n", "\t\tif ( draw ) {\n", "\t\t\t// Protect against out of sequence returns\n", "\t\t\tif ( draw*1 < settings.iDraw ) {\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\t\tsettings.iDraw = draw * 1;\n", "\t\t}\n", "\t\n", "\t\t_fnClearTable( settings );\n", "\t\tsettings._iRecordsTotal = parseInt(recordsTotal, 10);\n", "\t\tsettings._iRecordsDisplay = parseInt(recordsFiltered, 10);\n", "\t\n", "\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n", "\t\t\t_fnAddData( settings, data[i] );\n", "\t\t}\n", "\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n", "\t\n", "\t\tsettings.bAjaxDataGet = false;\n", "\t\t_fnDraw( settings );\n", "\t\n", "\t\tif ( ! settings._bInitComplete ) {\n", "\t\t\t_fnInitComplete( settings, json );\n", "\t\t}\n", "\t\n", "\t\tsettings.bAjaxDataGet = true;\n", "\t\t_fnProcessingDisplay( settings, false );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the data from the JSON data source to use for drawing a table. Using\n", "\t * `_fnGetObjectDataFn` allows the data to be sourced from a property of the\n", "\t * source object, or from a processing function.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {object} json Data source object / array from the server\n", "\t * @return {array} Array of data to use\n", "\t */\n", "\tfunction _fnAjaxDataSrc ( oSettings, json )\n", "\t{\n", "\t\tvar dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?\n", "\t\t\toSettings.ajax.dataSrc :\n", "\t\t\toSettings.sAjaxDataProp; // Compatibility with 1.9-.\n", "\t\n", "\t\t// Compatibility with 1.9-. In order to read from aaData, check if the\n", "\t\t// default has been changed, if not, check for aaData\n", "\t\tif ( dataSrc === 'data' ) {\n", "\t\t\treturn json.aaData || json[dataSrc];\n", "\t\t}\n", "\t\n", "\t\treturn dataSrc !== \"\" ?\n", "\t\t\t_fnGetObjectDataFn( dataSrc )( json ) :\n", "\t\t\tjson;\n", "\t}\n", "\t\n", "\t/**\n", "\t * Generate the node required for filtering text\n", "\t * @returns {node} Filter control element\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFeatureHtmlFilter ( settings )\n", "\t{\n", "\t\tvar classes = settings.oClasses;\n", "\t\tvar tableId = settings.sTableId;\n", "\t\tvar language = settings.oLanguage;\n", "\t\tvar previousSearch = settings.oPreviousSearch;\n", "\t\tvar features = settings.aanFeatures;\n", "\t\tvar input = '<input type=\"search\" class=\"'+classes.sFilterInput+'\"/>';\n", "\t\n", "\t\tvar str = language.sSearch;\n", "\t\tstr = str.match(/_INPUT_/) ?\n", "\t\t\tstr.replace('_INPUT_', input) :\n", "\t\t\tstr+input;\n", "\t\n", "\t\tvar filter = $('<div/>', {\n", "\t\t\t\t'id': ! features.f ? tableId+'_filter' : null,\n", "\t\t\t\t'class': classes.sFilter\n", "\t\t\t} )\n", "\t\t\t.append( $('<label/>' ).append( str ) );\n", "\t\n", "\t\tvar searchFn = function() {\n", "\t\t\t/* Update all other filter input elements for the new display */\n", "\t\t\tvar n = features.f;\n", "\t\t\tvar val = !this.value ? \"\" : this.value; // mental IE8 fix :-(\n", "\t\n", "\t\t\t/* Now do the filter */\n", "\t\t\tif ( val != previousSearch.sSearch ) {\n", "\t\t\t\t_fnFilterComplete( settings, {\n", "\t\t\t\t\t\"sSearch\": val,\n", "\t\t\t\t\t\"bRegex\": previousSearch.bRegex,\n", "\t\t\t\t\t\"bSmart\": previousSearch.bSmart ,\n", "\t\t\t\t\t\"bCaseInsensitive\": previousSearch.bCaseInsensitive\n", "\t\t\t\t} );\n", "\t\n", "\t\t\t\t// Need to redraw, without resorting\n", "\t\t\t\tsettings._iDisplayStart = 0;\n", "\t\t\t\t_fnDraw( settings );\n", "\t\t\t}\n", "\t\t};\n", "\t\n", "\t\tvar searchDelay = settings.searchDelay !== null ?\n", "\t\t\tsettings.searchDelay :\n", "\t\t\t_fnDataSource( settings ) === 'ssp' ?\n", "\t\t\t\t400 :\n", "\t\t\t\t0;\n", "\t\n", "\t\tvar jqFilter = $('input', filter)\n", "\t\t\t.val( previousSearch.sSearch )\n", "\t\t\t.attr( 'placeholder', language.sSearchPlaceholder )\n", "\t\t\t.on(\n", "\t\t\t\t'keyup.DT search.DT input.DT paste.DT cut.DT',\n", "\t\t\t\tsearchDelay ?\n", "\t\t\t\t\t_fnThrottle( searchFn, searchDelay ) :\n", "\t\t\t\t\tsearchFn\n", "\t\t\t)\n", "\t\t\t.on( 'keypress.DT', function(e) {\n", "\t\t\t\t/* Prevent form submission */\n", "\t\t\t\tif ( e.keyCode == 13 ) {\n", "\t\t\t\t\treturn false;\n", "\t\t\t\t}\n", "\t\t\t} )\n", "\t\t\t.attr('aria-controls', tableId);\n", "\t\n", "\t\t// Update the input elements whenever the table is filtered\n", "\t\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\n", "\t\t\tif ( settings === s ) {\n", "\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n", "\t\t\t\t// inside an iframe or frame...\n", "\t\t\t\ttry {\n", "\t\t\t\t\tif ( jqFilter[0] !== document.activeElement ) {\n", "\t\t\t\t\t\tjqFilter.val( previousSearch.sSearch );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\tcatch ( e ) {}\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn filter[0];\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Filter the table using both the global filter and column based filtering\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {object} oSearch search information\n", "\t * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFilterComplete ( oSettings, oInput, iForce )\n", "\t{\n", "\t\tvar oPrevSearch = oSettings.oPreviousSearch;\n", "\t\tvar aoPrevSearch = oSettings.aoPreSearchCols;\n", "\t\tvar fnSaveFilter = function ( oFilter ) {\n", "\t\t\t/* Save the filtering values */\n", "\t\t\toPrevSearch.sSearch = oFilter.sSearch;\n", "\t\t\toPrevSearch.bRegex = oFilter.bRegex;\n", "\t\t\toPrevSearch.bSmart = oFilter.bSmart;\n", "\t\t\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\n", "\t\t};\n", "\t\tvar fnRegex = function ( o ) {\n", "\t\t\t// Backwards compatibility with the bEscapeRegex option\n", "\t\t\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\n", "\t\t};\n", "\t\n", "\t\t// Resolve any column types that are unknown due to addition or invalidation\n", "\t\t// @todo As per sort - can this be moved into an event handler?\n", "\t\t_fnColumnTypes( oSettings );\n", "\t\n", "\t\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\n", "\t\tif ( _fnDataSource( oSettings ) != 'ssp' )\n", "\t\t{\n", "\t\t\t/* Global filter */\n", "\t\t\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\n", "\t\t\tfnSaveFilter( oInput );\n", "\t\n", "\t\t\t/* Now do the individual column filter */\n", "\t\t\tfor ( var i=0 ; i<aoPrevSearch.length ; i++ )\n", "\t\t\t{\n", "\t\t\t\t_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),\n", "\t\t\t\t\taoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );\n", "\t\t\t}\n", "\t\n", "\t\t\t/* Custom filtering */\n", "\t\t\t_fnFilterCustom( oSettings );\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\tfnSaveFilter( oInput );\n", "\t\t}\n", "\t\n", "\t\t/* Tell the draw function we have been filtering */\n", "\t\toSettings.bFiltered = true;\n", "\t\t_fnCallbackFire( oSettings, null, 'search', [oSettings] );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Apply custom filtering functions\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFilterCustom( settings )\n", "\t{\n", "\t\tvar filters = DataTable.ext.search;\n", "\t\tvar displayRows = settings.aiDisplay;\n", "\t\tvar row, rowIdx;\n", "\t\n", "\t\tfor ( var i=0, ien=filters.length ; i<ien ; i++ ) {\n", "\t\t\tvar rows = [];\n", "\t\n", "\t\t\t// Loop over each row and see if it should be included\n", "\t\t\tfor ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {\n", "\t\t\t\trowIdx = displayRows[ j ];\n", "\t\t\t\trow = settings.aoData[ rowIdx ];\n", "\t\n", "\t\t\t\tif ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {\n", "\t\t\t\t\trows.push( rowIdx );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t// So the array reference doesn't break set the results into the\n", "\t\t\t// existing array\n", "\t\t\tdisplayRows.length = 0;\n", "\t\t\t$.merge( displayRows, rows );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Filter the table on a per-column basis\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {string} sInput string to filter on\n", "\t * @param {int} iColumn column to filter\n", "\t * @param {bool} bRegex treat search string as a regular expression or not\n", "\t * @param {bool} bSmart use smart filtering or not\n", "\t * @param {bool} bCaseInsensitive Do case insenstive matching or not\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )\n", "\t{\n", "\t\tif ( searchStr === '' ) {\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tvar data;\n", "\t\tvar out = [];\n", "\t\tvar display = settings.aiDisplay;\n", "\t\tvar rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );\n", "\t\n", "\t\tfor ( var i=0 ; i<display.length ; i++ ) {\n", "\t\t\tdata = settings.aoData[ display[i] ]._aFilterData[ colIdx ];\n", "\t\n", "\t\t\tif ( rpSearch.test( data ) ) {\n", "\t\t\t\tout.push( display[i] );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\tsettings.aiDisplay = out;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Filter the data table based on user input and draw the table\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {string} input string to filter on\n", "\t * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)\n", "\t * @param {bool} regex treat as a regular expression or not\n", "\t * @param {bool} smart perform smart filtering or not\n", "\t * @param {bool} caseInsensitive Do case insenstive matching or not\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFilter( settings, input, force, regex, smart, caseInsensitive )\n", "\t{\n", "\t\tvar rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );\n", "\t\tvar prevSearch = settings.oPreviousSearch.sSearch;\n", "\t\tvar displayMaster = settings.aiDisplayMaster;\n", "\t\tvar display, invalidated, i;\n", "\t\tvar filtered = [];\n", "\t\n", "\t\t// Need to take account of custom filtering functions - always filter\n", "\t\tif ( DataTable.ext.search.length !== 0 ) {\n", "\t\t\tforce = true;\n", "\t\t}\n", "\t\n", "\t\t// Check if any of the rows were invalidated\n", "\t\tinvalidated = _fnFilterData( settings );\n", "\t\n", "\t\t// If the input is blank - we just want the full data set\n", "\t\tif ( input.length <= 0 ) {\n", "\t\t\tsettings.aiDisplay = displayMaster.slice();\n", "\t\t}\n", "\t\telse {\n", "\t\t\t// New search - start from the master array\n", "\t\t\tif ( invalidated ||\n", "\t\t\t\t force ||\n", "\t\t\t\t prevSearch.length > input.length ||\n", "\t\t\t\t input.indexOf(prevSearch) !== 0 ||\n", "\t\t\t\t settings.bSorted // On resort, the display master needs to be\n", "\t\t\t\t // re-filtered since indexes will have changed\n", "\t\t\t) {\n", "\t\t\t\tsettings.aiDisplay = displayMaster.slice();\n", "\t\t\t}\n", "\t\n", "\t\t\t// Search the display array\n", "\t\t\tdisplay = settings.aiDisplay;\n", "\t\n", "\t\t\tfor ( i=0 ; i<display.length ; i++ ) {\n", "\t\t\t\tif ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {\n", "\t\t\t\t\tfiltered.push( display[i] );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\tsettings.aiDisplay = filtered;\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Build a regular expression object suitable for searching a table\n", "\t * @param {string} sSearch string to search for\n", "\t * @param {bool} bRegex treat as a regular expression or not\n", "\t * @param {bool} bSmart perform smart filtering or not\n", "\t * @param {bool} bCaseInsensitive Do case insensitive matching or not\n", "\t * @returns {RegExp} constructed object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFilterCreateSearch( search, regex, smart, caseInsensitive )\n", "\t{\n", "\t\tsearch = regex ?\n", "\t\t\tsearch :\n", "\t\t\t_fnEscapeRegex( search );\n", "\t\t\n", "\t\tif ( smart ) {\n", "\t\t\t/* For smart filtering we want to allow the search to work regardless of\n", "\t\t\t * word order. We also want double quoted text to be preserved, so word\n", "\t\t\t * order is important - a la google. So this is what we want to\n", "\t\t\t * generate:\n", "\t\t\t * \n", "\t\t\t * ^(?=.*?\\bone\\b)(?=.*?\\btwo three\\b)(?=.*?\\bfour\\b).*$\n", "\t\t\t */\n", "\t\t\tvar a = $.map( search.match( /\"[^\"]+\"|[^ ]+/g ) || [''], function ( word ) {\n", "\t\t\t\tif ( word.charAt(0) === '\"' ) {\n", "\t\t\t\t\tvar m = word.match( /^\"(.*)\"$/ );\n", "\t\t\t\t\tword = m ? m[1] : word;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\treturn word.replace('\"', '');\n", "\t\t\t} );\n", "\t\n", "\t\t\tsearch = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';\n", "\t\t}\n", "\t\n", "\t\treturn new RegExp( search, caseInsensitive ? 'i' : '' );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Escape a string such that it can be used in a regular expression\n", "\t * @param {string} sVal string to escape\n", "\t * @returns {string} escaped string\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tvar _fnEscapeRegex = DataTable.util.escapeRegex;\n", "\t\n", "\tvar __filter_div = $('<div>')[0];\n", "\tvar __filter_div_textContent = __filter_div.textContent !== undefined;\n", "\t\n", "\t// Update the filtering data for each row if needed (by invalidation or first run)\n", "\tfunction _fnFilterData ( settings )\n", "\t{\n", "\t\tvar columns = settings.aoColumns;\n", "\t\tvar column;\n", "\t\tvar i, j, ien, jen, filterData, cellData, row;\n", "\t\tvar fomatters = DataTable.ext.type.search;\n", "\t\tvar wasInvalidated = false;\n", "\t\n", "\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n", "\t\t\trow = settings.aoData[i];\n", "\t\n", "\t\t\tif ( ! row._aFilterData ) {\n", "\t\t\t\tfilterData = [];\n", "\t\n", "\t\t\t\tfor ( j=0, jen=columns.length ; j<jen ; j++ ) {\n", "\t\t\t\t\tcolumn = columns[j];\n", "\t\n", "\t\t\t\t\tif ( column.bSearchable ) {\n", "\t\t\t\t\t\tcellData = _fnGetCellData( settings, i, j, 'filter' );\n", "\t\n", "\t\t\t\t\t\tif ( fomatters[ column.sType ] ) {\n", "\t\t\t\t\t\t\tcellData = fomatters[ column.sType ]( cellData );\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\t// Search in DataTables 1.10 is string based. In 1.11 this\n", "\t\t\t\t\t\t// should be altered to also allow strict type checking.\n", "\t\t\t\t\t\tif ( cellData === null ) {\n", "\t\t\t\t\t\t\tcellData = '';\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\tif ( typeof cellData !== 'string' && cellData.toString ) {\n", "\t\t\t\t\t\t\tcellData = cellData.toString();\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse {\n", "\t\t\t\t\t\tcellData = '';\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t// If it looks like there is an HTML entity in the string,\n", "\t\t\t\t\t// attempt to decode it so sorting works as expected. Note that\n", "\t\t\t\t\t// we could use a single line of jQuery to do this, but the DOM\n", "\t\t\t\t\t// method used here is much faster http://jsperf.com/html-decode\n", "\t\t\t\t\tif ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {\n", "\t\t\t\t\t\t__filter_div.innerHTML = cellData;\n", "\t\t\t\t\t\tcellData = __filter_div_textContent ?\n", "\t\t\t\t\t\t\t__filter_div.textContent :\n", "\t\t\t\t\t\t\t__filter_div.innerText;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tif ( cellData.replace ) {\n", "\t\t\t\t\t\tcellData = cellData.replace(/[\\r\\n]/g, '');\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tfilterData.push( cellData );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\trow._aFilterData = filterData;\n", "\t\t\t\trow._sFilterRow = filterData.join(' ');\n", "\t\t\t\twasInvalidated = true;\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn wasInvalidated;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Convert from the internal Hungarian notation to camelCase for external\n", "\t * interaction\n", "\t * @param {object} obj Object to convert\n", "\t * @returns {object} Inverted object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSearchToCamel ( obj )\n", "\t{\n", "\t\treturn {\n", "\t\t\tsearch: obj.sSearch,\n", "\t\t\tsmart: obj.bSmart,\n", "\t\t\tregex: obj.bRegex,\n", "\t\t\tcaseInsensitive: obj.bCaseInsensitive\n", "\t\t};\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Convert from camelCase notation to the internal Hungarian. We could use the\n", "\t * Hungarian convert function here, but this is cleaner\n", "\t * @param {object} obj Object to convert\n", "\t * @returns {object} Inverted object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSearchToHung ( obj )\n", "\t{\n", "\t\treturn {\n", "\t\t\tsSearch: obj.search,\n", "\t\t\tbSmart: obj.smart,\n", "\t\t\tbRegex: obj.regex,\n", "\t\t\tbCaseInsensitive: obj.caseInsensitive\n", "\t\t};\n", "\t}\n", "\t\n", "\t/**\n", "\t * Generate the node required for the info display\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @returns {node} Information element\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFeatureHtmlInfo ( settings )\n", "\t{\n", "\t\tvar\n", "\t\t\ttid = settings.sTableId,\n", "\t\t\tnodes = settings.aanFeatures.i,\n", "\t\t\tn = $('<div/>', {\n", "\t\t\t\t'class': settings.oClasses.sInfo,\n", "\t\t\t\t'id': ! nodes ? tid+'_info' : null\n", "\t\t\t} );\n", "\t\n", "\t\tif ( ! nodes ) {\n", "\t\t\t// Update display on each draw\n", "\t\t\tsettings.aoDrawCallback.push( {\n", "\t\t\t\t\"fn\": _fnUpdateInfo,\n", "\t\t\t\t\"sName\": \"information\"\n", "\t\t\t} );\n", "\t\n", "\t\t\tn\n", "\t\t\t\t.attr( 'role', 'status' )\n", "\t\t\t\t.attr( 'aria-live', 'polite' );\n", "\t\n", "\t\t\t// Table is described by our info div\n", "\t\t\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\n", "\t\t}\n", "\t\n", "\t\treturn n[0];\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Update the information elements in the display\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnUpdateInfo ( settings )\n", "\t{\n", "\t\t/* Show information about the table */\n", "\t\tvar nodes = settings.aanFeatures.i;\n", "\t\tif ( nodes.length === 0 ) {\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tvar\n", "\t\t\tlang = settings.oLanguage,\n", "\t\t\tstart = settings._iDisplayStart+1,\n", "\t\t\tend = settings.fnDisplayEnd(),\n", "\t\t\tmax = settings.fnRecordsTotal(),\n", "\t\t\ttotal = settings.fnRecordsDisplay(),\n", "\t\t\tout = total ?\n", "\t\t\t\tlang.sInfo :\n", "\t\t\t\tlang.sInfoEmpty;\n", "\t\n", "\t\tif ( total !== max ) {\n", "\t\t\t/* Record set after filtering */\n", "\t\t\tout += ' ' + lang.sInfoFiltered;\n", "\t\t}\n", "\t\n", "\t\t// Convert the macros\n", "\t\tout += lang.sInfoPostFix;\n", "\t\tout = _fnInfoMacros( settings, out );\n", "\t\n", "\t\tvar callback = lang.fnInfoCallback;\n", "\t\tif ( callback !== null ) {\n", "\t\t\tout = callback.call( settings.oInstance,\n", "\t\t\t\tsettings, start, end, max, total, out\n", "\t\t\t);\n", "\t\t}\n", "\t\n", "\t\t$(nodes).html( out );\n", "\t}\n", "\t\n", "\t\n", "\tfunction _fnInfoMacros ( settings, str )\n", "\t{\n", "\t\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\n", "\t\t// internally\n", "\t\tvar\n", "\t\t\tformatter = settings.fnFormatNumber,\n", "\t\t\tstart = settings._iDisplayStart+1,\n", "\t\t\tlen = settings._iDisplayLength,\n", "\t\t\tvis = settings.fnRecordsDisplay(),\n", "\t\t\tall = len === -1;\n", "\t\n", "\t\treturn str.\n", "\t\t\treplace(/_START_/g, formatter.call( settings, start ) ).\n", "\t\t\treplace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).\n", "\t\t\treplace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).\n", "\t\t\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\n", "\t\t\treplace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\n", "\t\t\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Draw the table for the first time, adding all required features\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnInitialise ( settings )\n", "\t{\n", "\t\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\n", "\t\tvar columns = settings.aoColumns, column;\n", "\t\tvar features = settings.oFeatures;\n", "\t\tvar deferLoading = settings.bDeferLoading; // value modified by the draw\n", "\t\n", "\t\t/* Ensure that the table data is fully initialised */\n", "\t\tif ( ! settings.bInitialised ) {\n", "\t\t\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\t/* Show the display HTML options */\n", "\t\t_fnAddOptionsHtml( settings );\n", "\t\n", "\t\t/* Build and draw the header / footer for the table */\n", "\t\t_fnBuildHead( settings );\n", "\t\t_fnDrawHead( settings, settings.aoHeader );\n", "\t\t_fnDrawHead( settings, settings.aoFooter );\n", "\t\n", "\t\t/* Okay to show that something is going on now */\n", "\t\t_fnProcessingDisplay( settings, true );\n", "\t\n", "\t\t/* Calculate sizes for columns */\n", "\t\tif ( features.bAutoWidth ) {\n", "\t\t\t_fnCalculateColumnWidths( settings );\n", "\t\t}\n", "\t\n", "\t\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ ) {\n", "\t\t\tcolumn = columns[i];\n", "\t\n", "\t\t\tif ( column.sWidth ) {\n", "\t\t\t\tcolumn.nTh.style.width = _fnStringToCss( column.sWidth );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t_fnCallbackFire( settings, null, 'preInit', [settings] );\n", "\t\n", "\t\t// If there is default sorting required - let's do it. The sort function\n", "\t\t// will do the drawing for us. Otherwise we draw the table regardless of the\n", "\t\t// Ajax source - this allows the table to look initialised for Ajax sourcing\n", "\t\t// data (show 'loading' message possibly)\n", "\t\t_fnReDraw( settings );\n", "\t\n", "\t\t// Server-side processing init complete is done by _fnAjaxUpdateDraw\n", "\t\tvar dataSrc = _fnDataSource( settings );\n", "\t\tif ( dataSrc != 'ssp' || deferLoading ) {\n", "\t\t\t// if there is an ajax source load the data\n", "\t\t\tif ( dataSrc == 'ajax' ) {\n", "\t\t\t\t_fnBuildAjax( settings, [], function(json) {\n", "\t\t\t\t\tvar aData = _fnAjaxDataSrc( settings, json );\n", "\t\n", "\t\t\t\t\t// Got the data - add it to the table\n", "\t\t\t\t\tfor ( i=0 ; i<aData.length ; i++ ) {\n", "\t\t\t\t\t\t_fnAddData( settings, aData[i] );\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t// Reset the init display for cookie saving. We've already done\n", "\t\t\t\t\t// a filter, and therefore cleared it before. So we need to make\n", "\t\t\t\t\t// it appear 'fresh'\n", "\t\t\t\t\tsettings.iInitDisplayStart = iAjaxStart;\n", "\t\n", "\t\t\t\t\t_fnReDraw( settings );\n", "\t\n", "\t\t\t\t\t_fnProcessingDisplay( settings, false );\n", "\t\t\t\t\t_fnInitComplete( settings, json );\n", "\t\t\t\t}, settings );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t_fnProcessingDisplay( settings, false );\n", "\t\t\t\t_fnInitComplete( settings );\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Draw the table for the first time, adding all required features\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {object} [json] JSON from the server that completed the table, if using Ajax source\n", "\t * with client-side processing (optional)\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnInitComplete ( settings, json )\n", "\t{\n", "\t\tsettings._bInitComplete = true;\n", "\t\n", "\t\t// When data was added after the initialisation (data or Ajax) we need to\n", "\t\t// calculate the column sizing\n", "\t\tif ( json || settings.oInit.aaData ) {\n", "\t\t\t_fnAdjustColumnSizing( settings );\n", "\t\t}\n", "\t\n", "\t\t_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );\n", "\t\t_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );\n", "\t}\n", "\t\n", "\t\n", "\tfunction _fnLengthChange ( settings, val )\n", "\t{\n", "\t\tvar len = parseInt( val, 10 );\n", "\t\tsettings._iDisplayLength = len;\n", "\t\n", "\t\t_fnLengthOverflow( settings );\n", "\t\n", "\t\t// Fire length change event\n", "\t\t_fnCallbackFire( settings, null, 'length', [settings, len] );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Generate the node required for user display length changing\n", "\t * @param {object} settings dataTables settings object\n", "\t * @returns {node} Display length feature node\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFeatureHtmlLength ( settings )\n", "\t{\n", "\t\tvar\n", "\t\t\tclasses = settings.oClasses,\n", "\t\t\ttableId = settings.sTableId,\n", "\t\t\tmenu = settings.aLengthMenu,\n", "\t\t\td2 = $.isArray( menu[0] ),\n", "\t\t\tlengths = d2 ? menu[0] : menu,\n", "\t\t\tlanguage = d2 ? menu[1] : menu;\n", "\t\n", "\t\tvar select = $('<select/>', {\n", "\t\t\t'name': tableId+'_length',\n", "\t\t\t'aria-controls': tableId,\n", "\t\t\t'class': classes.sLengthSelect\n", "\t\t} );\n", "\t\n", "\t\tfor ( var i=0, ien=lengths.length ; i<ien ; i++ ) {\n", "\t\t\tselect[0][ i ] = new Option( language[i], lengths[i] );\n", "\t\t}\n", "\t\n", "\t\tvar div = $('<div><label/></div>').addClass( classes.sLength );\n", "\t\tif ( ! settings.aanFeatures.l ) {\n", "\t\t\tdiv[0].id = tableId+'_length';\n", "\t\t}\n", "\t\n", "\t\tdiv.children().append(\n", "\t\t\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\n", "\t\t);\n", "\t\n", "\t\t// Can't use `select` variable as user might provide their own and the\n", "\t\t// reference is broken by the use of outerHTML\n", "\t\t$('select', div)\n", "\t\t\t.val( settings._iDisplayLength )\n", "\t\t\t.on( 'change.DT', function(e) {\n", "\t\t\t\t_fnLengthChange( settings, $(this).val() );\n", "\t\t\t\t_fnDraw( settings );\n", "\t\t\t} );\n", "\t\n", "\t\t// Update node value whenever anything changes the table's length\n", "\t\t$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {\n", "\t\t\tif ( settings === s ) {\n", "\t\t\t\t$('select', div).val( len );\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn div[0];\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n", "\t * Note that most of the paging logic is done in\n", "\t * DataTable.ext.pager\n", "\t */\n", "\t\n", "\t/**\n", "\t * Generate the node required for default pagination\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @returns {node} Pagination feature node\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFeatureHtmlPaginate ( settings )\n", "\t{\n", "\t\tvar\n", "\t\t\ttype = settings.sPaginationType,\n", "\t\t\tplugin = DataTable.ext.pager[ type ],\n", "\t\t\tmodern = typeof plugin === 'function',\n", "\t\t\tredraw = function( settings ) {\n", "\t\t\t\t_fnDraw( settings );\n", "\t\t\t},\n", "\t\t\tnode = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],\n", "\t\t\tfeatures = settings.aanFeatures;\n", "\t\n", "\t\tif ( ! modern ) {\n", "\t\t\tplugin.fnInit( settings, node, redraw );\n", "\t\t}\n", "\t\n", "\t\t/* Add a draw callback for the pagination on first instance, to update the paging display */\n", "\t\tif ( ! features.p )\n", "\t\t{\n", "\t\t\tnode.id = settings.sTableId+'_paginate';\n", "\t\n", "\t\t\tsettings.aoDrawCallback.push( {\n", "\t\t\t\t\"fn\": function( settings ) {\n", "\t\t\t\t\tif ( modern ) {\n", "\t\t\t\t\t\tvar\n", "\t\t\t\t\t\t\tstart = settings._iDisplayStart,\n", "\t\t\t\t\t\t\tlen = settings._iDisplayLength,\n", "\t\t\t\t\t\t\tvisRecords = settings.fnRecordsDisplay(),\n", "\t\t\t\t\t\t\tall = len === -1,\n", "\t\t\t\t\t\t\tpage = all ? 0 : Math.ceil( start / len ),\n", "\t\t\t\t\t\t\tpages = all ? 1 : Math.ceil( visRecords / len ),\n", "\t\t\t\t\t\t\tbuttons = plugin(page, pages),\n", "\t\t\t\t\t\t\ti, ien;\n", "\t\n", "\t\t\t\t\t\tfor ( i=0, ien=features.p.length ; i<ien ; i++ ) {\n", "\t\t\t\t\t\t\t_fnRenderer( settings, 'pageButton' )(\n", "\t\t\t\t\t\t\t\tsettings, features.p[i], i, buttons, page, pages\n", "\t\t\t\t\t\t\t);\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse {\n", "\t\t\t\t\t\tplugin.fnUpdate( settings, redraw );\n", "\t\t\t\t\t}\n", "\t\t\t\t},\n", "\t\t\t\t\"sName\": \"pagination\"\n", "\t\t\t} );\n", "\t\t}\n", "\t\n", "\t\treturn node;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Alter the display settings to change the page\n", "\t * @param {object} settings DataTables settings object\n", "\t * @param {string|int} action Paging action to take: \"first\", \"previous\",\n", "\t * \"next\" or \"last\" or page number to jump to (integer)\n", "\t * @param [bool] redraw Automatically draw the update or not\n", "\t * @returns {bool} true page has changed, false - no change\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnPageChange ( settings, action, redraw )\n", "\t{\n", "\t\tvar\n", "\t\t\tstart = settings._iDisplayStart,\n", "\t\t\tlen = settings._iDisplayLength,\n", "\t\t\trecords = settings.fnRecordsDisplay();\n", "\t\n", "\t\tif ( records === 0 || len === -1 )\n", "\t\t{\n", "\t\t\tstart = 0;\n", "\t\t}\n", "\t\telse if ( typeof action === \"number\" )\n", "\t\t{\n", "\t\t\tstart = action * len;\n", "\t\n", "\t\t\tif ( start > records )\n", "\t\t\t{\n", "\t\t\t\tstart = 0;\n", "\t\t\t}\n", "\t\t}\n", "\t\telse if ( action == \"first\" )\n", "\t\t{\n", "\t\t\tstart = 0;\n", "\t\t}\n", "\t\telse if ( action == \"previous\" )\n", "\t\t{\n", "\t\t\tstart = len >= 0 ?\n", "\t\t\t\tstart - len :\n", "\t\t\t\t0;\n", "\t\n", "\t\t\tif ( start < 0 )\n", "\t\t\t{\n", "\t\t\t start = 0;\n", "\t\t\t}\n", "\t\t}\n", "\t\telse if ( action == \"next\" )\n", "\t\t{\n", "\t\t\tif ( start + len < records )\n", "\t\t\t{\n", "\t\t\t\tstart += len;\n", "\t\t\t}\n", "\t\t}\n", "\t\telse if ( action == \"last\" )\n", "\t\t{\n", "\t\t\tstart = Math.floor( (records-1) / len) * len;\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\t_fnLog( settings, 0, \"Unknown paging action: \"+action, 5 );\n", "\t\t}\n", "\t\n", "\t\tvar changed = settings._iDisplayStart !== start;\n", "\t\tsettings._iDisplayStart = start;\n", "\t\n", "\t\tif ( changed ) {\n", "\t\t\t_fnCallbackFire( settings, null, 'page', [settings] );\n", "\t\n", "\t\t\tif ( redraw ) {\n", "\t\t\t\t_fnDraw( settings );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn changed;\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Generate the node required for the processing node\n", "\t * @param {object} settings dataTables settings object\n", "\t * @returns {node} Processing element\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFeatureHtmlProcessing ( settings )\n", "\t{\n", "\t\treturn $('<div/>', {\n", "\t\t\t\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\n", "\t\t\t\t'class': settings.oClasses.sProcessing\n", "\t\t\t} )\n", "\t\t\t.html( settings.oLanguage.sProcessing )\n", "\t\t\t.insertBefore( settings.nTable )[0];\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Display or hide the processing indicator\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {bool} show Show the processing indicator (true) or not (false)\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnProcessingDisplay ( settings, show )\n", "\t{\n", "\t\tif ( settings.oFeatures.bProcessing ) {\n", "\t\t\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\n", "\t\t}\n", "\t\n", "\t\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\n", "\t}\n", "\t\n", "\t/**\n", "\t * Add any control elements for the table - specifically scrolling\n", "\t * @param {object} settings dataTables settings object\n", "\t * @returns {node} Node to add to the DOM\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnFeatureHtmlTable ( settings )\n", "\t{\n", "\t\tvar table = $(settings.nTable);\n", "\t\n", "\t\t// Add the ARIA grid role to the table\n", "\t\ttable.attr( 'role', 'grid' );\n", "\t\n", "\t\t// Scrolling from here on in\n", "\t\tvar scroll = settings.oScroll;\n", "\t\n", "\t\tif ( scroll.sX === '' && scroll.sY === '' ) {\n", "\t\t\treturn settings.nTable;\n", "\t\t}\n", "\t\n", "\t\tvar scrollX = scroll.sX;\n", "\t\tvar scrollY = scroll.sY;\n", "\t\tvar classes = settings.oClasses;\n", "\t\tvar caption = table.children('caption');\n", "\t\tvar captionSide = caption.length ? caption[0]._captionSide : null;\n", "\t\tvar headerClone = $( table[0].cloneNode(false) );\n", "\t\tvar footerClone = $( table[0].cloneNode(false) );\n", "\t\tvar footer = table.children('tfoot');\n", "\t\tvar _div = '<div/>';\n", "\t\tvar size = function ( s ) {\n", "\t\t\treturn !s ? null : _fnStringToCss( s );\n", "\t\t};\n", "\t\n", "\t\tif ( ! footer.length ) {\n", "\t\t\tfooter = null;\n", "\t\t}\n", "\t\n", "\t\t/*\n", "\t\t * The HTML structure that we want to generate in this function is:\n", "\t\t * div - scroller\n", "\t\t * div - scroll head\n", "\t\t * div - scroll head inner\n", "\t\t * table - scroll head table\n", "\t\t * thead - thead\n", "\t\t * div - scroll body\n", "\t\t * table - table (master table)\n", "\t\t * thead - thead clone for sizing\n", "\t\t * tbody - tbody\n", "\t\t * div - scroll foot\n", "\t\t * div - scroll foot inner\n", "\t\t * table - scroll foot table\n", "\t\t * tfoot - tfoot\n", "\t\t */\n", "\t\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\n", "\t\t\t.append(\n", "\t\t\t\t$(_div, { 'class': classes.sScrollHead } )\n", "\t\t\t\t\t.css( {\n", "\t\t\t\t\t\toverflow: 'hidden',\n", "\t\t\t\t\t\tposition: 'relative',\n", "\t\t\t\t\t\tborder: 0,\n", "\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n", "\t\t\t\t\t} )\n", "\t\t\t\t\t.append(\n", "\t\t\t\t\t\t$(_div, { 'class': classes.sScrollHeadInner } )\n", "\t\t\t\t\t\t\t.css( {\n", "\t\t\t\t\t\t\t\t'box-sizing': 'content-box',\n", "\t\t\t\t\t\t\t\twidth: scroll.sXInner || '100%'\n", "\t\t\t\t\t\t\t} )\n", "\t\t\t\t\t\t\t.append(\n", "\t\t\t\t\t\t\t\theaderClone\n", "\t\t\t\t\t\t\t\t\t.removeAttr('id')\n", "\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n", "\t\t\t\t\t\t\t\t\t.append( captionSide === 'top' ? caption : null )\n", "\t\t\t\t\t\t\t\t\t.append(\n", "\t\t\t\t\t\t\t\t\t\ttable.children('thead')\n", "\t\t\t\t\t\t\t\t\t)\n", "\t\t\t\t\t\t\t)\n", "\t\t\t\t\t)\n", "\t\t\t)\n", "\t\t\t.append(\n", "\t\t\t\t$(_div, { 'class': classes.sScrollBody } )\n", "\t\t\t\t\t.css( {\n", "\t\t\t\t\t\tposition: 'relative',\n", "\t\t\t\t\t\toverflow: 'auto',\n", "\t\t\t\t\t\twidth: size( scrollX )\n", "\t\t\t\t\t} )\n", "\t\t\t\t\t.append( table )\n", "\t\t\t);\n", "\t\n", "\t\tif ( footer ) {\n", "\t\t\tscroller.append(\n", "\t\t\t\t$(_div, { 'class': classes.sScrollFoot } )\n", "\t\t\t\t\t.css( {\n", "\t\t\t\t\t\toverflow: 'hidden',\n", "\t\t\t\t\t\tborder: 0,\n", "\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n", "\t\t\t\t\t} )\n", "\t\t\t\t\t.append(\n", "\t\t\t\t\t\t$(_div, { 'class': classes.sScrollFootInner } )\n", "\t\t\t\t\t\t\t.append(\n", "\t\t\t\t\t\t\t\tfooterClone\n", "\t\t\t\t\t\t\t\t\t.removeAttr('id')\n", "\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n", "\t\t\t\t\t\t\t\t\t.append( captionSide === 'bottom' ? caption : null )\n", "\t\t\t\t\t\t\t\t\t.append(\n", "\t\t\t\t\t\t\t\t\t\ttable.children('tfoot')\n", "\t\t\t\t\t\t\t\t\t)\n", "\t\t\t\t\t\t\t)\n", "\t\t\t\t\t)\n", "\t\t\t);\n", "\t\t}\n", "\t\n", "\t\tvar children = scroller.children();\n", "\t\tvar scrollHead = children[0];\n", "\t\tvar scrollBody = children[1];\n", "\t\tvar scrollFoot = footer ? children[2] : null;\n", "\t\n", "\t\t// When the body is scrolled, then we also want to scroll the headers\n", "\t\tif ( scrollX ) {\n", "\t\t\t$(scrollBody).on( 'scroll.DT', function (e) {\n", "\t\t\t\tvar scrollLeft = this.scrollLeft;\n", "\t\n", "\t\t\t\tscrollHead.scrollLeft = scrollLeft;\n", "\t\n", "\t\t\t\tif ( footer ) {\n", "\t\t\t\t\tscrollFoot.scrollLeft = scrollLeft;\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\t}\n", "\t\n", "\t\t$(scrollBody).css(\n", "\t\t\tscrollY && scroll.bCollapse ? 'max-height' : 'height', \n", "\t\t\tscrollY\n", "\t\t);\n", "\t\n", "\t\tsettings.nScrollHead = scrollHead;\n", "\t\tsettings.nScrollBody = scrollBody;\n", "\t\tsettings.nScrollFoot = scrollFoot;\n", "\t\n", "\t\t// On redraw - align columns\n", "\t\tsettings.aoDrawCallback.push( {\n", "\t\t\t\"fn\": _fnScrollDraw,\n", "\t\t\t\"sName\": \"scrolling\"\n", "\t\t} );\n", "\t\n", "\t\treturn scroller[0];\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Update the header, footer and body tables for resizing - i.e. column\n", "\t * alignment.\n", "\t *\n", "\t * Welcome to the most horrible function DataTables. The process that this\n", "\t * function follows is basically:\n", "\t * 1. Re-create the table inside the scrolling div\n", "\t * 2. Take live measurements from the DOM\n", "\t * 3. Apply the measurements to align the columns\n", "\t * 4. Clean up\n", "\t *\n", "\t * @param {object} settings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnScrollDraw ( settings )\n", "\t{\n", "\t\t// Given that this is such a monster function, a lot of variables are use\n", "\t\t// to try and keep the minimised size as small as possible\n", "\t\tvar\n", "\t\t\tscroll = settings.oScroll,\n", "\t\t\tscrollX = scroll.sX,\n", "\t\t\tscrollXInner = scroll.sXInner,\n", "\t\t\tscrollY = scroll.sY,\n", "\t\t\tbarWidth = scroll.iBarWidth,\n", "\t\t\tdivHeader = $(settings.nScrollHead),\n", "\t\t\tdivHeaderStyle = divHeader[0].style,\n", "\t\t\tdivHeaderInner = divHeader.children('div'),\n", "\t\t\tdivHeaderInnerStyle = divHeaderInner[0].style,\n", "\t\t\tdivHeaderTable = divHeaderInner.children('table'),\n", "\t\t\tdivBodyEl = settings.nScrollBody,\n", "\t\t\tdivBody = $(divBodyEl),\n", "\t\t\tdivBodyStyle = divBodyEl.style,\n", "\t\t\tdivFooter = $(settings.nScrollFoot),\n", "\t\t\tdivFooterInner = divFooter.children('div'),\n", "\t\t\tdivFooterTable = divFooterInner.children('table'),\n", "\t\t\theader = $(settings.nTHead),\n", "\t\t\ttable = $(settings.nTable),\n", "\t\t\ttableEl = table[0],\n", "\t\t\ttableStyle = tableEl.style,\n", "\t\t\tfooter = settings.nTFoot ? $(settings.nTFoot) : null,\n", "\t\t\tbrowser = settings.oBrowser,\n", "\t\t\tie67 = browser.bScrollOversize,\n", "\t\t\tdtHeaderCells = _pluck( settings.aoColumns, 'nTh' ),\n", "\t\t\theaderTrgEls, footerTrgEls,\n", "\t\t\theaderSrcEls, footerSrcEls,\n", "\t\t\theaderCopy, footerCopy,\n", "\t\t\theaderWidths=[], footerWidths=[],\n", "\t\t\theaderContent=[], footerContent=[],\n", "\t\t\tidx, correction, sanityWidth,\n", "\t\t\tzeroOut = function(nSizer) {\n", "\t\t\t\tvar style = nSizer.style;\n", "\t\t\t\tstyle.paddingTop = \"0\";\n", "\t\t\t\tstyle.paddingBottom = \"0\";\n", "\t\t\t\tstyle.borderTopWidth = \"0\";\n", "\t\t\t\tstyle.borderBottomWidth = \"0\";\n", "\t\t\t\tstyle.height = 0;\n", "\t\t\t};\n", "\t\n", "\t\t// If the scrollbar visibility has changed from the last draw, we need to\n", "\t\t// adjust the column sizes as the table width will have changed to account\n", "\t\t// for the scrollbar\n", "\t\tvar scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;\n", "\t\t\n", "\t\tif ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {\n", "\t\t\tsettings.scrollBarVis = scrollBarVis;\n", "\t\t\t_fnAdjustColumnSizing( settings );\n", "\t\t\treturn; // adjust column sizing will call this function again\n", "\t\t}\n", "\t\telse {\n", "\t\t\tsettings.scrollBarVis = scrollBarVis;\n", "\t\t}\n", "\t\n", "\t\t/*\n", "\t\t * 1. Re-create the table inside the scrolling div\n", "\t\t */\n", "\t\n", "\t\t// Remove the old minimised thead and tfoot elements in the inner table\n", "\t\ttable.children('thead, tfoot').remove();\n", "\t\n", "\t\tif ( footer ) {\n", "\t\t\tfooterCopy = footer.clone().prependTo( table );\n", "\t\t\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\n", "\t\t\tfooterSrcEls = footerCopy.find('tr');\n", "\t\t}\n", "\t\n", "\t\t// Clone the current header and footer elements and then place it into the inner table\n", "\t\theaderCopy = header.clone().prependTo( table );\n", "\t\theaderTrgEls = header.find('tr'); // original header is in its own table\n", "\t\theaderSrcEls = headerCopy.find('tr');\n", "\t\theaderCopy.find('th, td').removeAttr('tabindex');\n", "\t\n", "\t\n", "\t\t/*\n", "\t\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\n", "\t\t */\n", "\t\n", "\t\t// Remove old sizing and apply the calculated column widths\n", "\t\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\n", "\t\t// calculated sizes to this header\n", "\t\tif ( ! scrollX )\n", "\t\t{\n", "\t\t\tdivBodyStyle.width = '100%';\n", "\t\t\tdivHeader[0].style.width = '100%';\n", "\t\t}\n", "\t\n", "\t\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\n", "\t\t\tidx = _fnVisibleToColumnIndex( settings, i );\n", "\t\t\tel.style.width = settings.aoColumns[idx].sWidth;\n", "\t\t} );\n", "\t\n", "\t\tif ( footer ) {\n", "\t\t\t_fnApplyToChildren( function(n) {\n", "\t\t\t\tn.style.width = \"\";\n", "\t\t\t}, footerSrcEls );\n", "\t\t}\n", "\t\n", "\t\t// Size the table as a whole\n", "\t\tsanityWidth = table.outerWidth();\n", "\t\tif ( scrollX === \"\" ) {\n", "\t\t\t// No x scrolling\n", "\t\t\ttableStyle.width = \"100%\";\n", "\t\n", "\t\t\t// IE7 will make the width of the table when 100% include the scrollbar\n", "\t\t\t// - which is shouldn't. When there is a scrollbar we need to take this\n", "\t\t\t// into account.\n", "\t\t\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\n", "\t\t\t\tdivBody.css('overflow-y') == \"scroll\")\n", "\t\t\t) {\n", "\t\t\t\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\n", "\t\t\t}\n", "\t\n", "\t\t\t// Recalculate the sanity width\n", "\t\t\tsanityWidth = table.outerWidth();\n", "\t\t}\n", "\t\telse if ( scrollXInner !== \"\" ) {\n", "\t\t\t// legacy x scroll inner has been given - use it\n", "\t\t\ttableStyle.width = _fnStringToCss(scrollXInner);\n", "\t\n", "\t\t\t// Recalculate the sanity width\n", "\t\t\tsanityWidth = table.outerWidth();\n", "\t\t}\n", "\t\n", "\t\t// Hidden header should have zero height, so remove padding and borders. Then\n", "\t\t// set the width based on the real headers\n", "\t\n", "\t\t// Apply all styles in one pass\n", "\t\t_fnApplyToChildren( zeroOut, headerSrcEls );\n", "\t\n", "\t\t// Read all widths in next pass\n", "\t\t_fnApplyToChildren( function(nSizer) {\n", "\t\t\theaderContent.push( nSizer.innerHTML );\n", "\t\t\theaderWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n", "\t\t}, headerSrcEls );\n", "\t\n", "\t\t// Apply all widths in final pass\n", "\t\t_fnApplyToChildren( function(nToSize, i) {\n", "\t\t\t// Only apply widths to the DataTables detected header cells - this\n", "\t\t\t// prevents complex headers from having contradictory sizes applied\n", "\t\t\tif ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {\n", "\t\t\t\tnToSize.style.width = headerWidths[i];\n", "\t\t\t}\n", "\t\t}, headerTrgEls );\n", "\t\n", "\t\t$(headerSrcEls).height(0);\n", "\t\n", "\t\t/* Same again with the footer if we have one */\n", "\t\tif ( footer )\n", "\t\t{\n", "\t\t\t_fnApplyToChildren( zeroOut, footerSrcEls );\n", "\t\n", "\t\t\t_fnApplyToChildren( function(nSizer) {\n", "\t\t\t\tfooterContent.push( nSizer.innerHTML );\n", "\t\t\t\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n", "\t\t\t}, footerSrcEls );\n", "\t\n", "\t\t\t_fnApplyToChildren( function(nToSize, i) {\n", "\t\t\t\tnToSize.style.width = footerWidths[i];\n", "\t\t\t}, footerTrgEls );\n", "\t\n", "\t\t\t$(footerSrcEls).height(0);\n", "\t\t}\n", "\t\n", "\t\n", "\t\t/*\n", "\t\t * 3. Apply the measurements\n", "\t\t */\n", "\t\n", "\t\t// \"Hide\" the header and footer that we used for the sizing. We need to keep\n", "\t\t// the content of the cell so that the width applied to the header and body\n", "\t\t// both match, but we want to hide it completely. We want to also fix their\n", "\t\t// width to what they currently are\n", "\t\t_fnApplyToChildren( function(nSizer, i) {\n", "\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+headerContent[i]+'</div>';\n", "\t\t\tnSizer.style.width = headerWidths[i];\n", "\t\t}, headerSrcEls );\n", "\t\n", "\t\tif ( footer )\n", "\t\t{\n", "\t\t\t_fnApplyToChildren( function(nSizer, i) {\n", "\t\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+footerContent[i]+'</div>';\n", "\t\t\t\tnSizer.style.width = footerWidths[i];\n", "\t\t\t}, footerSrcEls );\n", "\t\t}\n", "\t\n", "\t\t// Sanity check that the table is of a sensible width. If not then we are going to get\n", "\t\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\n", "\t\tif ( table.outerWidth() < sanityWidth )\n", "\t\t{\n", "\t\t\t// The min width depends upon if we have a vertical scrollbar visible or not */\n", "\t\t\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\n", "\t\t\t\tdivBody.css('overflow-y') == \"scroll\")) ?\n", "\t\t\t\t\tsanityWidth+barWidth :\n", "\t\t\t\t\tsanityWidth;\n", "\t\n", "\t\t\t// IE6/7 are a law unto themselves...\n", "\t\t\tif ( ie67 && (divBodyEl.scrollHeight >\n", "\t\t\t\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \"scroll\")\n", "\t\t\t) {\n", "\t\t\t\ttableStyle.width = _fnStringToCss( correction-barWidth );\n", "\t\t\t}\n", "\t\n", "\t\t\t// And give the user a warning that we've stopped the table getting too small\n", "\t\t\tif ( scrollX === \"\" || scrollXInner !== \"\" ) {\n", "\t\t\t\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\n", "\t\t\t}\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\tcorrection = '100%';\n", "\t\t}\n", "\t\n", "\t\t// Apply to the container elements\n", "\t\tdivBodyStyle.width = _fnStringToCss( correction );\n", "\t\tdivHeaderStyle.width = _fnStringToCss( correction );\n", "\t\n", "\t\tif ( footer ) {\n", "\t\t\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\n", "\t\t}\n", "\t\n", "\t\n", "\t\t/*\n", "\t\t * 4. Clean up\n", "\t\t */\n", "\t\tif ( ! scrollY ) {\n", "\t\t\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\n", "\t\t\t * the scrollbar height from the visible display, rather than adding it on. We need to\n", "\t\t\t * set the height in order to sort this. Don't want to do it in any other browsers.\n", "\t\t\t */\n", "\t\t\tif ( ie67 ) {\n", "\t\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t/* Finally set the width's of the header and footer tables */\n", "\t\tvar iOuterWidth = table.outerWidth();\n", "\t\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\n", "\t\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\n", "\t\n", "\t\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\n", "\t\t// provide a bit more space to allow \"overflow\" scrolling (i.e. past the scrollbar)\n", "\t\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \"scroll\";\n", "\t\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\n", "\t\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\"px\" : \"0px\";\n", "\t\n", "\t\tif ( footer ) {\n", "\t\t\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\n", "\t\t\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\n", "\t\t\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\"px\" : \"0px\";\n", "\t\t}\n", "\t\n", "\t\t// Correct DOM ordering for colgroup - comes before the thead\n", "\t\ttable.children('colgroup').insertBefore( table.children('thead') );\n", "\t\n", "\t\t/* Adjust the position of the header in case we loose the y-scrollbar */\n", "\t\tdivBody.scroll();\n", "\t\n", "\t\t// If sorting or filtering has occurred, jump the scrolling back to the top\n", "\t\t// only if we aren't holding the position\n", "\t\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\n", "\t\t\tdivBodyEl.scrollTop = 0;\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Apply a given function to the display child nodes of an element array (typically\n", "\t * TD children of TR rows\n", "\t * @param {function} fn Method to apply to the objects\n", "\t * @param array {nodes} an1 List of elements to look through for display children\n", "\t * @param array {nodes} an2 Another list (identical structure to the first) - optional\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnApplyToChildren( fn, an1, an2 )\n", "\t{\n", "\t\tvar index=0, i=0, iLen=an1.length;\n", "\t\tvar nNode1, nNode2;\n", "\t\n", "\t\twhile ( i < iLen ) {\n", "\t\t\tnNode1 = an1[i].firstChild;\n", "\t\t\tnNode2 = an2 ? an2[i].firstChild : null;\n", "\t\n", "\t\t\twhile ( nNode1 ) {\n", "\t\t\t\tif ( nNode1.nodeType === 1 ) {\n", "\t\t\t\t\tif ( an2 ) {\n", "\t\t\t\t\t\tfn( nNode1, nNode2, index );\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse {\n", "\t\t\t\t\t\tfn( nNode1, index );\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tindex++;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tnNode1 = nNode1.nextSibling;\n", "\t\t\t\tnNode2 = an2 ? nNode2.nextSibling : null;\n", "\t\t\t}\n", "\t\n", "\t\t\ti++;\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\tvar __re_html_remove = /<.*?>/g;\n", "\t\n", "\t\n", "\t/**\n", "\t * Calculate the width of columns for the table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnCalculateColumnWidths ( oSettings )\n", "\t{\n", "\t\tvar\n", "\t\t\ttable = oSettings.nTable,\n", "\t\t\tcolumns = oSettings.aoColumns,\n", "\t\t\tscroll = oSettings.oScroll,\n", "\t\t\tscrollY = scroll.sY,\n", "\t\t\tscrollX = scroll.sX,\n", "\t\t\tscrollXInner = scroll.sXInner,\n", "\t\t\tcolumnCount = columns.length,\n", "\t\t\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\n", "\t\t\theaderCells = $('th', oSettings.nTHead),\n", "\t\t\ttableWidthAttr = table.getAttribute('width'), // from DOM element\n", "\t\t\ttableContainer = table.parentNode,\n", "\t\t\tuserInputs = false,\n", "\t\t\ti, column, columnIdx, width, outerWidth,\n", "\t\t\tbrowser = oSettings.oBrowser,\n", "\t\t\tie67 = browser.bScrollOversize;\n", "\t\n", "\t\tvar styleWidth = table.style.width;\n", "\t\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\n", "\t\t\ttableWidthAttr = styleWidth;\n", "\t\t}\n", "\t\n", "\t\t/* Convert any user input sizes into pixel sizes */\n", "\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n", "\t\t\tcolumn = columns[ visibleColumns[i] ];\n", "\t\n", "\t\t\tif ( column.sWidth !== null ) {\n", "\t\t\t\tcolumn.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );\n", "\t\n", "\t\t\t\tuserInputs = true;\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t/* If the number of columns in the DOM equals the number that we have to\n", "\t\t * process in DataTables, then we can use the offsets that are created by\n", "\t\t * the web- browser. No custom sizes can be set in order for this to happen,\n", "\t\t * nor scrolling used\n", "\t\t */\n", "\t\tif ( ie67 || ! userInputs && ! scrollX && ! scrollY &&\n", "\t\t columnCount == _fnVisbleColumns( oSettings ) &&\n", "\t\t columnCount == headerCells.length\n", "\t\t) {\n", "\t\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n", "\t\t\t\tvar colIdx = _fnVisibleToColumnIndex( oSettings, i );\n", "\t\n", "\t\t\t\tif ( colIdx !== null ) {\n", "\t\t\t\t\tcolumns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\telse\n", "\t\t{\n", "\t\t\t// Otherwise construct a single row, worst case, table with the widest\n", "\t\t\t// node in the data, assign any user defined widths, then insert it into\n", "\t\t\t// the DOM and allow the browser to do all the hard work of calculating\n", "\t\t\t// table widths\n", "\t\t\tvar tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table\n", "\t\t\t\t.css( 'visibility', 'hidden' )\n", "\t\t\t\t.removeAttr( 'id' );\n", "\t\n", "\t\t\t// Clean up the table body\n", "\t\t\ttmpTable.find('tbody tr').remove();\n", "\t\t\tvar tr = $('<tr/>').appendTo( tmpTable.find('tbody') );\n", "\t\n", "\t\t\t// Clone the table header and footer - we can't use the header / footer\n", "\t\t\t// from the cloned table, since if scrolling is active, the table's\n", "\t\t\t// real header and footer are contained in different table tags\n", "\t\t\ttmpTable.find('thead, tfoot').remove();\n", "\t\t\ttmpTable\n", "\t\t\t\t.append( $(oSettings.nTHead).clone() )\n", "\t\t\t\t.append( $(oSettings.nTFoot).clone() );\n", "\t\n", "\t\t\t// Remove any assigned widths from the footer (from scrolling)\n", "\t\t\ttmpTable.find('tfoot th, tfoot td').css('width', '');\n", "\t\n", "\t\t\t// Apply custom sizing to the cloned header\n", "\t\t\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\n", "\t\n", "\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n", "\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n", "\t\n", "\t\t\t\theaderCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?\n", "\t\t\t\t\t_fnStringToCss( column.sWidthOrig ) :\n", "\t\t\t\t\t'';\n", "\t\n", "\t\t\t\t// For scrollX we need to force the column width otherwise the\n", "\t\t\t\t// browser will collapse it. If this width is smaller than the\n", "\t\t\t\t// width the column requires, then it will have no effect\n", "\t\t\t\tif ( column.sWidthOrig && scrollX ) {\n", "\t\t\t\t\t$( headerCells[i] ).append( $('<div/>').css( {\n", "\t\t\t\t\t\twidth: column.sWidthOrig,\n", "\t\t\t\t\t\tmargin: 0,\n", "\t\t\t\t\t\tpadding: 0,\n", "\t\t\t\t\t\tborder: 0,\n", "\t\t\t\t\t\theight: 1\n", "\t\t\t\t\t} ) );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t// Find the widest cell for each column and put it into the table\n", "\t\t\tif ( oSettings.aoData.length ) {\n", "\t\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n", "\t\t\t\t\tcolumnIdx = visibleColumns[i];\n", "\t\t\t\t\tcolumn = columns[ columnIdx ];\n", "\t\n", "\t\t\t\t\t$( _fnGetWidestNode( oSettings, columnIdx ) )\n", "\t\t\t\t\t\t.clone( false )\n", "\t\t\t\t\t\t.append( column.sContentPadding )\n", "\t\t\t\t\t\t.appendTo( tr );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t// Tidy the temporary table - remove name attributes so there aren't\n", "\t\t\t// duplicated in the dom (radio elements for example)\n", "\t\t\t$('[name]', tmpTable).removeAttr('name');\n", "\t\n", "\t\t\t// Table has been built, attach to the document so we can work with it.\n", "\t\t\t// A holding element is used, positioned at the top of the container\n", "\t\t\t// with minimal height, so it has no effect on if the container scrolls\n", "\t\t\t// or not. Otherwise it might trigger scrolling when it actually isn't\n", "\t\t\t// needed\n", "\t\t\tvar holder = $('<div/>').css( scrollX || scrollY ?\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\tposition: 'absolute',\n", "\t\t\t\t\t\ttop: 0,\n", "\t\t\t\t\t\tleft: 0,\n", "\t\t\t\t\t\theight: 1,\n", "\t\t\t\t\t\tright: 0,\n", "\t\t\t\t\t\toverflow: 'hidden'\n", "\t\t\t\t\t} :\n", "\t\t\t\t\t{}\n", "\t\t\t\t)\n", "\t\t\t\t.append( tmpTable )\n", "\t\t\t\t.appendTo( tableContainer );\n", "\t\n", "\t\t\t// When scrolling (X or Y) we want to set the width of the table as \n", "\t\t\t// appropriate. However, when not scrolling leave the table width as it\n", "\t\t\t// is. This results in slightly different, but I think correct behaviour\n", "\t\t\tif ( scrollX && scrollXInner ) {\n", "\t\t\t\ttmpTable.width( scrollXInner );\n", "\t\t\t}\n", "\t\t\telse if ( scrollX ) {\n", "\t\t\t\ttmpTable.css( 'width', 'auto' );\n", "\t\t\t\ttmpTable.removeAttr('width');\n", "\t\n", "\t\t\t\t// If there is no width attribute or style, then allow the table to\n", "\t\t\t\t// collapse\n", "\t\t\t\tif ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {\n", "\t\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t\telse if ( scrollY ) {\n", "\t\t\t\ttmpTable.width( tableContainer.clientWidth );\n", "\t\t\t}\n", "\t\t\telse if ( tableWidthAttr ) {\n", "\t\t\t\ttmpTable.width( tableWidthAttr );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Get the width of each column in the constructed table - we need to\n", "\t\t\t// know the inner width (so it can be assigned to the other table's\n", "\t\t\t// cells) and the outer width so we can calculate the full width of the\n", "\t\t\t// table. This is safe since DataTables requires a unique cell for each\n", "\t\t\t// column, but if ever a header can span multiple columns, this will\n", "\t\t\t// need to be modified.\n", "\t\t\tvar total = 0;\n", "\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n", "\t\t\t\tvar cell = $(headerCells[i]);\n", "\t\t\t\tvar border = cell.outerWidth() - cell.width();\n", "\t\n", "\t\t\t\t// Use getBounding... where possible (not IE8-) because it can give\n", "\t\t\t\t// sub-pixel accuracy, which we then want to round up!\n", "\t\t\t\tvar bounding = browser.bBounding ?\n", "\t\t\t\t\tMath.ceil( headerCells[i].getBoundingClientRect().width ) :\n", "\t\t\t\t\tcell.outerWidth();\n", "\t\n", "\t\t\t\t// Total is tracked to remove any sub-pixel errors as the outerWidth\n", "\t\t\t\t// of the table might not equal the total given here (IE!).\n", "\t\t\t\ttotal += bounding;\n", "\t\n", "\t\t\t\t// Width for each column to use\n", "\t\t\t\tcolumns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );\n", "\t\t\t}\n", "\t\n", "\t\t\ttable.style.width = _fnStringToCss( total );\n", "\t\n", "\t\t\t// Finished with the table - ditch it\n", "\t\t\tholder.remove();\n", "\t\t}\n", "\t\n", "\t\t// If there is a width attr, we want to attach an event listener which\n", "\t\t// allows the table sizing to automatically adjust when the window is\n", "\t\t// resized. Use the width attr rather than CSS, since we can't know if the\n", "\t\t// CSS is a relative value or absolute - DOM read is always px.\n", "\t\tif ( tableWidthAttr ) {\n", "\t\t\ttable.style.width = _fnStringToCss( tableWidthAttr );\n", "\t\t}\n", "\t\n", "\t\tif ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {\n", "\t\t\tvar bindResize = function () {\n", "\t\t\t\t$(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {\n", "\t\t\t\t\t_fnAdjustColumnSizing( oSettings );\n", "\t\t\t\t} ) );\n", "\t\t\t};\n", "\t\n", "\t\t\t// IE6/7 will crash if we bind a resize event handler on page load.\n", "\t\t\t// To be removed in 1.11 which drops IE6/7 support\n", "\t\t\tif ( ie67 ) {\n", "\t\t\t\tsetTimeout( bindResize, 1000 );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tbindResize();\n", "\t\t\t}\n", "\t\n", "\t\t\toSettings._reszEvt = true;\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Throttle the calls to a function. Arguments and context are maintained for\n", "\t * the throttled function\n", "\t * @param {function} fn Function to be called\n", "\t * @param {int} [freq=200] call frequency in mS\n", "\t * @returns {function} wrapped function\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tvar _fnThrottle = DataTable.util.throttle;\n", "\t\n", "\t\n", "\t/**\n", "\t * Convert a CSS unit width to pixels (e.g. 2em)\n", "\t * @param {string} width width to be converted\n", "\t * @param {node} parent parent to get the with for (required for relative widths) - optional\n", "\t * @returns {int} width in pixels\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnConvertToWidth ( width, parent )\n", "\t{\n", "\t\tif ( ! width ) {\n", "\t\t\treturn 0;\n", "\t\t}\n", "\t\n", "\t\tvar n = $('<div/>')\n", "\t\t\t.css( 'width', _fnStringToCss( width ) )\n", "\t\t\t.appendTo( parent || document.body );\n", "\t\n", "\t\tvar val = n[0].offsetWidth;\n", "\t\tn.remove();\n", "\t\n", "\t\treturn val;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the widest node\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {int} colIdx column of interest\n", "\t * @returns {node} widest table node\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetWidestNode( settings, colIdx )\n", "\t{\n", "\t\tvar idx = _fnGetMaxLenString( settings, colIdx );\n", "\t\tif ( idx < 0 ) {\n", "\t\t\treturn null;\n", "\t\t}\n", "\t\n", "\t\tvar data = settings.aoData[ idx ];\n", "\t\treturn ! data.nTr ? // Might not have been created when deferred rendering\n", "\t\t\t$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\n", "\t\t\tdata.anCells[ colIdx ];\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the maximum strlen for each data column\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {int} colIdx column of interest\n", "\t * @returns {string} max string length for each column\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnGetMaxLenString( settings, colIdx )\n", "\t{\n", "\t\tvar s, max=-1, maxIdx = -1;\n", "\t\n", "\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n", "\t\t\ts = _fnGetCellData( settings, i, colIdx, 'display' )+'';\n", "\t\t\ts = s.replace( __re_html_remove, '' );\n", "\t\t\ts = s.replace( / /g, ' ' );\n", "\t\n", "\t\t\tif ( s.length > max ) {\n", "\t\t\t\tmax = s.length;\n", "\t\t\t\tmaxIdx = i;\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn maxIdx;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Append a CSS unit (only if required) to a string\n", "\t * @param {string} value to css-ify\n", "\t * @returns {string} value with css unit\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnStringToCss( s )\n", "\t{\n", "\t\tif ( s === null ) {\n", "\t\t\treturn '0px';\n", "\t\t}\n", "\t\n", "\t\tif ( typeof s == 'number' ) {\n", "\t\t\treturn s < 0 ?\n", "\t\t\t\t'0px' :\n", "\t\t\t\ts+'px';\n", "\t\t}\n", "\t\n", "\t\t// Check it has a unit character already\n", "\t\treturn s.match(/\\d$/) ?\n", "\t\t\ts+'px' :\n", "\t\t\ts;\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\tfunction _fnSortFlatten ( settings )\n", "\t{\n", "\t\tvar\n", "\t\t\ti, iLen, k, kLen,\n", "\t\t\taSort = [],\n", "\t\t\taiOrig = [],\n", "\t\t\taoColumns = settings.aoColumns,\n", "\t\t\taDataSort, iCol, sType, srcCol,\n", "\t\t\tfixed = settings.aaSortingFixed,\n", "\t\t\tfixedObj = $.isPlainObject( fixed ),\n", "\t\t\tnestedSort = [],\n", "\t\t\tadd = function ( a ) {\n", "\t\t\t\tif ( a.length && ! $.isArray( a[0] ) ) {\n", "\t\t\t\t\t// 1D array\n", "\t\t\t\t\tnestedSort.push( a );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\t// 2D array\n", "\t\t\t\t\t$.merge( nestedSort, a );\n", "\t\t\t\t}\n", "\t\t\t};\n", "\t\n", "\t\t// Build the sort array, with pre-fix and post-fix options if they have been\n", "\t\t// specified\n", "\t\tif ( $.isArray( fixed ) ) {\n", "\t\t\tadd( fixed );\n", "\t\t}\n", "\t\n", "\t\tif ( fixedObj && fixed.pre ) {\n", "\t\t\tadd( fixed.pre );\n", "\t\t}\n", "\t\n", "\t\tadd( settings.aaSorting );\n", "\t\n", "\t\tif (fixedObj && fixed.post ) {\n", "\t\t\tadd( fixed.post );\n", "\t\t}\n", "\t\n", "\t\tfor ( i=0 ; i<nestedSort.length ; i++ )\n", "\t\t{\n", "\t\t\tsrcCol = nestedSort[i][0];\n", "\t\t\taDataSort = aoColumns[ srcCol ].aDataSort;\n", "\t\n", "\t\t\tfor ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )\n", "\t\t\t{\n", "\t\t\t\tiCol = aDataSort[k];\n", "\t\t\t\tsType = aoColumns[ iCol ].sType || 'string';\n", "\t\n", "\t\t\t\tif ( nestedSort[i]._idx === undefined ) {\n", "\t\t\t\t\tnestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\taSort.push( {\n", "\t\t\t\t\tsrc: srcCol,\n", "\t\t\t\t\tcol: iCol,\n", "\t\t\t\t\tdir: nestedSort[i][1],\n", "\t\t\t\t\tindex: nestedSort[i]._idx,\n", "\t\t\t\t\ttype: sType,\n", "\t\t\t\t\tformatter: DataTable.ext.type.order[ sType+\"-pre\" ]\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn aSort;\n", "\t}\n", "\t\n", "\t/**\n", "\t * Change the order of the table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t * @todo This really needs split up!\n", "\t */\n", "\tfunction _fnSort ( oSettings )\n", "\t{\n", "\t\tvar\n", "\t\t\ti, ien, iLen, j, jLen, k, kLen,\n", "\t\t\tsDataType, nTh,\n", "\t\t\taiOrig = [],\n", "\t\t\toExtSort = DataTable.ext.type.order,\n", "\t\t\taoData = oSettings.aoData,\n", "\t\t\taoColumns = oSettings.aoColumns,\n", "\t\t\taDataSort, data, iCol, sType, oSort,\n", "\t\t\tformatters = 0,\n", "\t\t\tsortCol,\n", "\t\t\tdisplayMaster = oSettings.aiDisplayMaster,\n", "\t\t\taSort;\n", "\t\n", "\t\t// Resolve any column types that are unknown due to addition or invalidation\n", "\t\t// @todo Can this be moved into a 'data-ready' handler which is called when\n", "\t\t// data is going to be used in the table?\n", "\t\t_fnColumnTypes( oSettings );\n", "\t\n", "\t\taSort = _fnSortFlatten( oSettings );\n", "\t\n", "\t\tfor ( i=0, ien=aSort.length ; i<ien ; i++ ) {\n", "\t\t\tsortCol = aSort[i];\n", "\t\n", "\t\t\t// Track if we can use the fast sort algorithm\n", "\t\t\tif ( sortCol.formatter ) {\n", "\t\t\t\tformatters++;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Load the data needed for the sort, for each cell\n", "\t\t\t_fnSortData( oSettings, sortCol.col );\n", "\t\t}\n", "\t\n", "\t\t/* No sorting required if server-side or no sorting array */\n", "\t\tif ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )\n", "\t\t{\n", "\t\t\t// Create a value - key array of the current row positions such that we can use their\n", "\t\t\t// current position during the sort, if values match, in order to perform stable sorting\n", "\t\t\tfor ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {\n", "\t\t\t\taiOrig[ displayMaster[i] ] = i;\n", "\t\t\t}\n", "\t\n", "\t\t\t/* Do the sort - here we want multi-column sorting based on a given data source (column)\n", "\t\t\t * and sorting function (from oSort) in a certain direction. It's reasonably complex to\n", "\t\t\t * follow on it's own, but this is what we want (example two column sorting):\n", "\t\t\t * fnLocalSorting = function(a,b){\n", "\t\t\t * var iTest;\n", "\t\t\t * iTest = oSort['string-asc']('data11', 'data12');\n", "\t\t\t * if (iTest !== 0)\n", "\t\t\t * return iTest;\n", "\t\t\t * iTest = oSort['numeric-desc']('data21', 'data22');\n", "\t\t\t * if (iTest !== 0)\n", "\t\t\t * return iTest;\n", "\t\t\t * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );\n", "\t\t\t * }\n", "\t\t\t * Basically we have a test for each sorting column, if the data in that column is equal,\n", "\t\t\t * test the next column. If all columns match, then we use a numeric sort on the row\n", "\t\t\t * positions in the original data array to provide a stable sort.\n", "\t\t\t *\n", "\t\t\t * Note - I know it seems excessive to have two sorting methods, but the first is around\n", "\t\t\t * 15% faster, so the second is only maintained for backwards compatibility with sorting\n", "\t\t\t * methods which do not have a pre-sort formatting function.\n", "\t\t\t */\n", "\t\t\tif ( formatters === aSort.length ) {\n", "\t\t\t\t// All sort types have formatting functions\n", "\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n", "\t\t\t\t\tvar\n", "\t\t\t\t\t\tx, y, k, test, sort,\n", "\t\t\t\t\t\tlen=aSort.length,\n", "\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n", "\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n", "\t\n", "\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n", "\t\t\t\t\t\tsort = aSort[k];\n", "\t\n", "\t\t\t\t\t\tx = dataA[ sort.col ];\n", "\t\t\t\t\t\ty = dataB[ sort.col ];\n", "\t\n", "\t\t\t\t\t\ttest = x<y ? -1 : x>y ? 1 : 0;\n", "\t\t\t\t\t\tif ( test !== 0 ) {\n", "\t\t\t\t\t\t\treturn sort.dir === 'asc' ? test : -test;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tx = aiOrig[a];\n", "\t\t\t\t\ty = aiOrig[b];\n", "\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t// Depreciated - remove in 1.11 (providing a plug-in option)\n", "\t\t\t\t// Not all sort types have formatting methods, so we have to call their sorting\n", "\t\t\t\t// methods.\n", "\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n", "\t\t\t\t\tvar\n", "\t\t\t\t\t\tx, y, k, l, test, sort, fn,\n", "\t\t\t\t\t\tlen=aSort.length,\n", "\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n", "\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n", "\t\n", "\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n", "\t\t\t\t\t\tsort = aSort[k];\n", "\t\n", "\t\t\t\t\t\tx = dataA[ sort.col ];\n", "\t\t\t\t\t\ty = dataB[ sort.col ];\n", "\t\n", "\t\t\t\t\t\tfn = oExtSort[ sort.type+\"-\"+sort.dir ] || oExtSort[ \"string-\"+sort.dir ];\n", "\t\t\t\t\t\ttest = fn( x, y );\n", "\t\t\t\t\t\tif ( test !== 0 ) {\n", "\t\t\t\t\t\t\treturn test;\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tx = aiOrig[a];\n", "\t\t\t\t\ty = aiOrig[b];\n", "\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t/* Tell the draw function that we have sorted the data */\n", "\t\toSettings.bSorted = true;\n", "\t}\n", "\t\n", "\t\n", "\tfunction _fnSortAria ( settings )\n", "\t{\n", "\t\tvar label;\n", "\t\tvar nextSort;\n", "\t\tvar columns = settings.aoColumns;\n", "\t\tvar aSort = _fnSortFlatten( settings );\n", "\t\tvar oAria = settings.oLanguage.oAria;\n", "\t\n", "\t\t// ARIA attributes - need to loop all columns, to update all (removing old\n", "\t\t// attributes as needed)\n", "\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n", "\t\t{\n", "\t\t\tvar col = columns[i];\n", "\t\t\tvar asSorting = col.asSorting;\n", "\t\t\tvar sTitle = col.sTitle.replace( /<.*?>/g, \"\" );\n", "\t\t\tvar th = col.nTh;\n", "\t\n", "\t\t\t// IE7 is throwing an error when setting these properties with jQuery's\n", "\t\t\t// attr() and removeAttr() methods...\n", "\t\t\tth.removeAttribute('aria-sort');\n", "\t\n", "\t\t\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\n", "\t\t\tif ( col.bSortable ) {\n", "\t\t\t\tif ( aSort.length > 0 && aSort[0].col == i ) {\n", "\t\t\t\t\tth.setAttribute('aria-sort', aSort[0].dir==\"asc\" ? \"ascending\" : \"descending\" );\n", "\t\t\t\t\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tnextSort = asSorting[0];\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tlabel = sTitle + ( nextSort === \"asc\" ?\n", "\t\t\t\t\toAria.sSortAscending :\n", "\t\t\t\t\toAria.sSortDescending\n", "\t\t\t\t);\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tlabel = sTitle;\n", "\t\t\t}\n", "\t\n", "\t\t\tth.setAttribute('aria-label', label);\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Function to run on user sort request\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {node} attachTo node to attach the handler to\n", "\t * @param {int} colIdx column sorting index\n", "\t * @param {boolean} [append=false] Append the requested sort to the existing\n", "\t * sort if true (i.e. multi-column sort)\n", "\t * @param {function} [callback] callback function\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSortListener ( settings, colIdx, append, callback )\n", "\t{\n", "\t\tvar col = settings.aoColumns[ colIdx ];\n", "\t\tvar sorting = settings.aaSorting;\n", "\t\tvar asSorting = col.asSorting;\n", "\t\tvar nextSortIdx;\n", "\t\tvar next = function ( a, overflow ) {\n", "\t\t\tvar idx = a._idx;\n", "\t\t\tif ( idx === undefined ) {\n", "\t\t\t\tidx = $.inArray( a[1], asSorting );\n", "\t\t\t}\n", "\t\n", "\t\t\treturn idx+1 < asSorting.length ?\n", "\t\t\t\tidx+1 :\n", "\t\t\t\toverflow ?\n", "\t\t\t\t\tnull :\n", "\t\t\t\t\t0;\n", "\t\t};\n", "\t\n", "\t\t// Convert to 2D array if needed\n", "\t\tif ( typeof sorting[0] === 'number' ) {\n", "\t\t\tsorting = settings.aaSorting = [ sorting ];\n", "\t\t}\n", "\t\n", "\t\t// If appending the sort then we are multi-column sorting\n", "\t\tif ( append && settings.oFeatures.bSortMulti ) {\n", "\t\t\t// Are we already doing some kind of sort on this column?\n", "\t\t\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\n", "\t\n", "\t\t\tif ( sortIdx !== -1 ) {\n", "\t\t\t\t// Yes, modify the sort\n", "\t\t\t\tnextSortIdx = next( sorting[sortIdx], true );\n", "\t\n", "\t\t\t\tif ( nextSortIdx === null && sorting.length === 1 ) {\n", "\t\t\t\t\tnextSortIdx = 0; // can't remove sorting completely\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tif ( nextSortIdx === null ) {\n", "\t\t\t\t\tsorting.splice( sortIdx, 1 );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\n", "\t\t\t\t\tsorting[sortIdx]._idx = nextSortIdx;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t// No sort on this column yet\n", "\t\t\t\tsorting.push( [ colIdx, asSorting[0], 0 ] );\n", "\t\t\t\tsorting[sorting.length-1]._idx = 0;\n", "\t\t\t}\n", "\t\t}\n", "\t\telse if ( sorting.length && sorting[0][0] == colIdx ) {\n", "\t\t\t// Single column - already sorting on this column, modify the sort\n", "\t\t\tnextSortIdx = next( sorting[0] );\n", "\t\n", "\t\t\tsorting.length = 1;\n", "\t\t\tsorting[0][1] = asSorting[ nextSortIdx ];\n", "\t\t\tsorting[0]._idx = nextSortIdx;\n", "\t\t}\n", "\t\telse {\n", "\t\t\t// Single column - sort only on this column\n", "\t\t\tsorting.length = 0;\n", "\t\t\tsorting.push( [ colIdx, asSorting[0] ] );\n", "\t\t\tsorting[0]._idx = 0;\n", "\t\t}\n", "\t\n", "\t\t// Run the sort by calling a full redraw\n", "\t\t_fnReDraw( settings );\n", "\t\n", "\t\t// callback used for async user interaction\n", "\t\tif ( typeof callback == 'function' ) {\n", "\t\t\tcallback( settings );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Attach a sort handler (click) to a node\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {node} attachTo node to attach the handler to\n", "\t * @param {int} colIdx column sorting index\n", "\t * @param {function} [callback] callback function\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\n", "\t{\n", "\t\tvar col = settings.aoColumns[ colIdx ];\n", "\t\n", "\t\t_fnBindAction( attachTo, {}, function (e) {\n", "\t\t\t/* If the column is not sortable - don't to anything */\n", "\t\t\tif ( col.bSortable === false ) {\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t// If processing is enabled use a timeout to allow the processing\n", "\t\t\t// display to be shown - otherwise to it synchronously\n", "\t\t\tif ( settings.oFeatures.bProcessing ) {\n", "\t\t\t\t_fnProcessingDisplay( settings, true );\n", "\t\n", "\t\t\t\tsetTimeout( function() {\n", "\t\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n", "\t\n", "\t\t\t\t\t// In server-side processing, the draw callback will remove the\n", "\t\t\t\t\t// processing display\n", "\t\t\t\t\tif ( _fnDataSource( settings ) !== 'ssp' ) {\n", "\t\t\t\t\t\t_fnProcessingDisplay( settings, false );\n", "\t\t\t\t\t}\n", "\t\t\t\t}, 0 );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n", "\t\t\t}\n", "\t\t} );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Set the sorting classes on table's body, Note: it is safe to call this function\n", "\t * when bSort and bSortClasses are false\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSortingClasses( settings )\n", "\t{\n", "\t\tvar oldSort = settings.aLastSort;\n", "\t\tvar sortClass = settings.oClasses.sSortColumn;\n", "\t\tvar sort = _fnSortFlatten( settings );\n", "\t\tvar features = settings.oFeatures;\n", "\t\tvar i, ien, colIdx;\n", "\t\n", "\t\tif ( features.bSort && features.bSortClasses ) {\n", "\t\t\t// Remove old sorting classes\n", "\t\t\tfor ( i=0, ien=oldSort.length ; i<ien ; i++ ) {\n", "\t\t\t\tcolIdx = oldSort[i].src;\n", "\t\n", "\t\t\t\t// Remove column sorting\n", "\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n", "\t\t\t\t\t.removeClass( sortClass + (i<2 ? i+1 : 3) );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Add new column sorting\n", "\t\t\tfor ( i=0, ien=sort.length ; i<ien ; i++ ) {\n", "\t\t\t\tcolIdx = sort[i].src;\n", "\t\n", "\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n", "\t\t\t\t\t.addClass( sortClass + (i<2 ? i+1 : 3) );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\tsettings.aLastSort = sort;\n", "\t}\n", "\t\n", "\t\n", "\t// Get the data to sort a column, be it from cache, fresh (populating the\n", "\t// cache), or from a sort formatter\n", "\tfunction _fnSortData( settings, idx )\n", "\t{\n", "\t\t// Custom sorting function - provided by the sort data type\n", "\t\tvar column = settings.aoColumns[ idx ];\n", "\t\tvar customSort = DataTable.ext.order[ column.sSortDataType ];\n", "\t\tvar customData;\n", "\t\n", "\t\tif ( customSort ) {\n", "\t\t\tcustomData = customSort.call( settings.oInstance, settings, idx,\n", "\t\t\t\t_fnColumnIndexToVisible( settings, idx )\n", "\t\t\t);\n", "\t\t}\n", "\t\n", "\t\t// Use / populate cache\n", "\t\tvar row, cellData;\n", "\t\tvar formatter = DataTable.ext.type.order[ column.sType+\"-pre\" ];\n", "\t\n", "\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n", "\t\t\trow = settings.aoData[i];\n", "\t\n", "\t\t\tif ( ! row._aSortData ) {\n", "\t\t\t\trow._aSortData = [];\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( ! row._aSortData[idx] || customSort ) {\n", "\t\t\t\tcellData = customSort ?\n", "\t\t\t\t\tcustomData[i] : // If there was a custom sort function, use data from there\n", "\t\t\t\t\t_fnGetCellData( settings, i, idx, 'sort' );\n", "\t\n", "\t\t\t\trow._aSortData[ idx ] = formatter ?\n", "\t\t\t\t\tformatter( cellData ) :\n", "\t\t\t\t\tcellData;\n", "\t\t\t}\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Save the state of a table\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSaveState ( settings )\n", "\t{\n", "\t\tif ( !settings.oFeatures.bStateSave || settings.bDestroying )\n", "\t\t{\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\t/* Store the interesting variables */\n", "\t\tvar state = {\n", "\t\t\ttime: +new Date(),\n", "\t\t\tstart: settings._iDisplayStart,\n", "\t\t\tlength: settings._iDisplayLength,\n", "\t\t\torder: $.extend( true, [], settings.aaSorting ),\n", "\t\t\tsearch: _fnSearchToCamel( settings.oPreviousSearch ),\n", "\t\t\tcolumns: $.map( settings.aoColumns, function ( col, i ) {\n", "\t\t\t\treturn {\n", "\t\t\t\t\tvisible: col.bVisible,\n", "\t\t\t\t\tsearch: _fnSearchToCamel( settings.aoPreSearchCols[i] )\n", "\t\t\t\t};\n", "\t\t\t} )\n", "\t\t};\n", "\t\n", "\t\t_fnCallbackFire( settings, \"aoStateSaveParams\", 'stateSaveParams', [settings, state] );\n", "\t\n", "\t\tsettings.oSavedState = state;\n", "\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, state );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Attempt to load a saved table state\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {object} oInit DataTables init object so we can override settings\n", "\t * @param {function} callback Callback to execute when the state has been loaded\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnLoadState ( settings, oInit, callback )\n", "\t{\n", "\t\tvar i, ien;\n", "\t\tvar columns = settings.aoColumns;\n", "\t\tvar loaded = function ( s ) {\n", "\t\t\tif ( ! s || ! s.time ) {\n", "\t\t\t\tcallback();\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Allow custom and plug-in manipulation functions to alter the saved data set and\n", "\t\t\t// cancelling of loading by returning false\n", "\t\t\tvar abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );\n", "\t\t\tif ( $.inArray( false, abStateLoad ) !== -1 ) {\n", "\t\t\t\tcallback();\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Reject old data\n", "\t\t\tvar duration = settings.iStateDuration;\n", "\t\t\tif ( duration > 0 && s.time < +new Date() - (duration*1000) ) {\n", "\t\t\t\tcallback();\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Number of columns have changed - all bets are off, no restore of settings\n", "\t\t\tif ( s.columns && columns.length !== s.columns.length ) {\n", "\t\t\t\tcallback();\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Store the saved state so it might be accessed at any time\n", "\t\t\tsettings.oLoadedState = $.extend( true, {}, s );\n", "\t\n", "\t\t\t// Restore key features - todo - for 1.11 this needs to be done by\n", "\t\t\t// subscribed events\n", "\t\t\tif ( s.start !== undefined ) {\n", "\t\t\t\tsettings._iDisplayStart = s.start;\n", "\t\t\t\tsettings.iInitDisplayStart = s.start;\n", "\t\t\t}\n", "\t\t\tif ( s.length !== undefined ) {\n", "\t\t\t\tsettings._iDisplayLength = s.length;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Order\n", "\t\t\tif ( s.order !== undefined ) {\n", "\t\t\t\tsettings.aaSorting = [];\n", "\t\t\t\t$.each( s.order, function ( i, col ) {\n", "\t\t\t\t\tsettings.aaSorting.push( col[0] >= columns.length ?\n", "\t\t\t\t\t\t[ 0, col[1] ] :\n", "\t\t\t\t\t\tcol\n", "\t\t\t\t\t);\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Search\n", "\t\t\tif ( s.search !== undefined ) {\n", "\t\t\t\t$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Columns\n", "\t\t\t//\n", "\t\t\tif ( s.columns ) {\n", "\t\t\t\tfor ( i=0, ien=s.columns.length ; i<ien ; i++ ) {\n", "\t\t\t\t\tvar col = s.columns[i];\n", "\t\n", "\t\t\t\t\t// Visibility\n", "\t\t\t\t\tif ( col.visible !== undefined ) {\n", "\t\t\t\t\t\tcolumns[i].bVisible = col.visible;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t// Search\n", "\t\t\t\t\tif ( col.search !== undefined ) {\n", "\t\t\t\t\t\t$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );\n", "\t\t\tcallback();\n", "\t\t}\n", "\t\n", "\t\tif ( ! settings.oFeatures.bStateSave ) {\n", "\t\t\tcallback();\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tvar state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );\n", "\t\n", "\t\tif ( state !== undefined ) {\n", "\t\t\tloaded( state );\n", "\t\t}\n", "\t\t// otherwise, wait for the loaded callback to be executed\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Return the settings object for a particular table\n", "\t * @param {node} table table we are using as a dataTable\n", "\t * @returns {object} Settings object - or null if not found\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnSettingsFromNode ( table )\n", "\t{\n", "\t\tvar settings = DataTable.settings;\n", "\t\tvar idx = $.inArray( table, _pluck( settings, 'nTable' ) );\n", "\t\n", "\t\treturn idx !== -1 ?\n", "\t\t\tsettings[ idx ] :\n", "\t\t\tnull;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Log an error message\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {int} level log error messages, or display them to the user\n", "\t * @param {string} msg error message\n", "\t * @param {int} tn Technical note id to get more information about the error.\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnLog( settings, level, msg, tn )\n", "\t{\n", "\t\tmsg = 'DataTables warning: '+\n", "\t\t\t(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;\n", "\t\n", "\t\tif ( tn ) {\n", "\t\t\tmsg += '. For more information about this error, please see '+\n", "\t\t\t'http://datatables.net/tn/'+tn;\n", "\t\t}\n", "\t\n", "\t\tif ( ! level ) {\n", "\t\t\t// Backwards compatibility pre 1.10\n", "\t\t\tvar ext = DataTable.ext;\n", "\t\t\tvar type = ext.sErrMode || ext.errMode;\n", "\t\n", "\t\t\tif ( settings ) {\n", "\t\t\t\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( type == 'alert' ) {\n", "\t\t\t\talert( msg );\n", "\t\t\t}\n", "\t\t\telse if ( type == 'throw' ) {\n", "\t\t\t\tthrow new Error(msg);\n", "\t\t\t}\n", "\t\t\telse if ( typeof type == 'function' ) {\n", "\t\t\t\ttype( settings, tn, msg );\n", "\t\t\t}\n", "\t\t}\n", "\t\telse if ( window.console && console.log ) {\n", "\t\t\tconsole.log( msg );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * See if a property is defined on one object, if so assign it to the other object\n", "\t * @param {object} ret target object\n", "\t * @param {object} src source object\n", "\t * @param {string} name property\n", "\t * @param {string} [mappedName] name to map too - optional, name used if not given\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnMap( ret, src, name, mappedName )\n", "\t{\n", "\t\tif ( $.isArray( name ) ) {\n", "\t\t\t$.each( name, function (i, val) {\n", "\t\t\t\tif ( $.isArray( val ) ) {\n", "\t\t\t\t\t_fnMap( ret, src, val[0], val[1] );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\t_fnMap( ret, src, val );\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tif ( mappedName === undefined ) {\n", "\t\t\tmappedName = name;\n", "\t\t}\n", "\t\n", "\t\tif ( src[name] !== undefined ) {\n", "\t\t\tret[mappedName] = src[name];\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Extend objects - very similar to jQuery.extend, but deep copy objects, and\n", "\t * shallow copy arrays. The reason we need to do this, is that we don't want to\n", "\t * deep copy array init values (such as aaSorting) since the dev wouldn't be\n", "\t * able to override them, but we do want to deep copy arrays.\n", "\t * @param {object} out Object to extend\n", "\t * @param {object} extender Object from which the properties will be applied to\n", "\t * out\n", "\t * @param {boolean} breakRefs If true, then arrays will be sliced to take an\n", "\t * independent copy with the exception of the `data` or `aaData` parameters\n", "\t * if they are present. This is so you can pass in a collection to\n", "\t * DataTables and have that used as your data source without breaking the\n", "\t * references\n", "\t * @returns {object} out Reference, just for convenience - out === the return.\n", "\t * @memberof DataTable#oApi\n", "\t * @todo This doesn't take account of arrays inside the deep copied objects.\n", "\t */\n", "\tfunction _fnExtend( out, extender, breakRefs )\n", "\t{\n", "\t\tvar val;\n", "\t\n", "\t\tfor ( var prop in extender ) {\n", "\t\t\tif ( extender.hasOwnProperty(prop) ) {\n", "\t\t\t\tval = extender[prop];\n", "\t\n", "\t\t\t\tif ( $.isPlainObject( val ) ) {\n", "\t\t\t\t\tif ( ! $.isPlainObject( out[prop] ) ) {\n", "\t\t\t\t\t\tout[prop] = {};\n", "\t\t\t\t\t}\n", "\t\t\t\t\t$.extend( true, out[prop], val );\n", "\t\t\t\t}\n", "\t\t\t\telse if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {\n", "\t\t\t\t\tout[prop] = val.slice();\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tout[prop] = val;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn out;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Bind an event handers to allow a click or return key to activate the callback.\n", "\t * This is good for accessibility since a return on the keyboard will have the\n", "\t * same effect as a click, if the element has focus.\n", "\t * @param {element} n Element to bind the action to\n", "\t * @param {object} oData Data object to pass to the triggered function\n", "\t * @param {function} fn Callback function for when the event is triggered\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnBindAction( n, oData, fn )\n", "\t{\n", "\t\t$(n)\n", "\t\t\t.on( 'click.DT', oData, function (e) {\n", "\t\t\t\t\tn.blur(); // Remove focus outline for mouse users\n", "\t\t\t\t\tfn(e);\n", "\t\t\t\t} )\n", "\t\t\t.on( 'keypress.DT', oData, function (e){\n", "\t\t\t\t\tif ( e.which === 13 ) {\n", "\t\t\t\t\t\te.preventDefault();\n", "\t\t\t\t\t\tfn(e);\n", "\t\t\t\t\t}\n", "\t\t\t\t} )\n", "\t\t\t.on( 'selectstart.DT', function () {\n", "\t\t\t\t\t/* Take the brutal approach to cancelling text selection */\n", "\t\t\t\t\treturn false;\n", "\t\t\t\t} );\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Register a callback function. Easily allows a callback function to be added to\n", "\t * an array store of callback functions that can then all be called together.\n", "\t * @param {object} oSettings dataTables settings object\n", "\t * @param {string} sStore Name of the array storage for the callbacks in oSettings\n", "\t * @param {function} fn Function to be called back\n", "\t * @param {string} sName Identifying name for the callback (i.e. a label)\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnCallbackReg( oSettings, sStore, fn, sName )\n", "\t{\n", "\t\tif ( fn )\n", "\t\t{\n", "\t\t\toSettings[sStore].push( {\n", "\t\t\t\t\"fn\": fn,\n", "\t\t\t\t\"sName\": sName\n", "\t\t\t} );\n", "\t\t}\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Fire callback functions and trigger events. Note that the loop over the\n", "\t * callback array store is done backwards! Further note that you do not want to\n", "\t * fire off triggers in time sensitive applications (for example cell creation)\n", "\t * as its slow.\n", "\t * @param {object} settings dataTables settings object\n", "\t * @param {string} callbackArr Name of the array storage for the callbacks in\n", "\t * oSettings\n", "\t * @param {string} eventName Name of the jQuery custom event to trigger. If\n", "\t * null no trigger is fired\n", "\t * @param {array} args Array of arguments to pass to the callback function /\n", "\t * trigger\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnCallbackFire( settings, callbackArr, eventName, args )\n", "\t{\n", "\t\tvar ret = [];\n", "\t\n", "\t\tif ( callbackArr ) {\n", "\t\t\tret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {\n", "\t\t\t\treturn val.fn.apply( settings.oInstance, args );\n", "\t\t\t} );\n", "\t\t}\n", "\t\n", "\t\tif ( eventName !== null ) {\n", "\t\t\tvar e = $.Event( eventName+'.dt' );\n", "\t\n", "\t\t\t$(settings.nTable).trigger( e, args );\n", "\t\n", "\t\t\tret.push( e.result );\n", "\t\t}\n", "\t\n", "\t\treturn ret;\n", "\t}\n", "\t\n", "\t\n", "\tfunction _fnLengthOverflow ( settings )\n", "\t{\n", "\t\tvar\n", "\t\t\tstart = settings._iDisplayStart,\n", "\t\t\tend = settings.fnDisplayEnd(),\n", "\t\t\tlen = settings._iDisplayLength;\n", "\t\n", "\t\t/* If we have space to show extra rows (backing up from the end point - then do so */\n", "\t\tif ( start >= end )\n", "\t\t{\n", "\t\t\tstart = end - len;\n", "\t\t}\n", "\t\n", "\t\t// Keep the start record on the current page\n", "\t\tstart -= (start % len);\n", "\t\n", "\t\tif ( len === -1 || start < 0 )\n", "\t\t{\n", "\t\t\tstart = 0;\n", "\t\t}\n", "\t\n", "\t\tsettings._iDisplayStart = start;\n", "\t}\n", "\t\n", "\t\n", "\tfunction _fnRenderer( settings, type )\n", "\t{\n", "\t\tvar renderer = settings.renderer;\n", "\t\tvar host = DataTable.ext.renderer[type];\n", "\t\n", "\t\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\n", "\t\t\t// Specific renderer for this type. If available use it, otherwise use\n", "\t\t\t// the default.\n", "\t\t\treturn host[renderer[type]] || host._;\n", "\t\t}\n", "\t\telse if ( typeof renderer === 'string' ) {\n", "\t\t\t// Common renderer - if there is one available for this type use it,\n", "\t\t\t// otherwise use the default\n", "\t\t\treturn host[renderer] || host._;\n", "\t\t}\n", "\t\n", "\t\t// Use the default\n", "\t\treturn host._;\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Detect the data source being used for the table. Used to simplify the code\n", "\t * a little (ajax) and to make it compress a little smaller.\n", "\t *\n", "\t * @param {object} settings dataTables settings object\n", "\t * @returns {string} Data source\n", "\t * @memberof DataTable#oApi\n", "\t */\n", "\tfunction _fnDataSource ( settings )\n", "\t{\n", "\t\tif ( settings.oFeatures.bServerSide ) {\n", "\t\t\treturn 'ssp';\n", "\t\t}\n", "\t\telse if ( settings.ajax || settings.sAjaxSource ) {\n", "\t\t\treturn 'ajax';\n", "\t\t}\n", "\t\treturn 'dom';\n", "\t}\n", "\t\n", "\n", "\t\n", "\t\n", "\t/**\n", "\t * Computed structure of the DataTables API, defined by the options passed to\n", "\t * `DataTable.Api.register()` when building the API.\n", "\t *\n", "\t * The structure is built in order to speed creation and extension of the Api\n", "\t * objects since the extensions are effectively pre-parsed.\n", "\t *\n", "\t * The array is an array of objects with the following structure, where this\n", "\t * base array represents the Api prototype base:\n", "\t *\n", "\t * [\n", "\t * {\n", "\t * name: 'data' -- string - Property name\n", "\t * val: function () {}, -- function - Api method (or undefined if just an object\n", "\t * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\n", "\t * propExt: [ ... ] -- array - Array of Api object definitions to extend the property\n", "\t * },\n", "\t * {\n", "\t * name: 'row'\n", "\t * val: {},\n", "\t * methodExt: [ ... ],\n", "\t * propExt: [\n", "\t * {\n", "\t * name: 'data'\n", "\t * val: function () {},\n", "\t * methodExt: [ ... ],\n", "\t * propExt: [ ... ]\n", "\t * },\n", "\t * ...\n", "\t * ]\n", "\t * }\n", "\t * ]\n", "\t *\n", "\t * @type {Array}\n", "\t * @ignore\n", "\t */\n", "\tvar __apiStruct = [];\n", "\t\n", "\t\n", "\t/**\n", "\t * `Array.prototype` reference.\n", "\t *\n", "\t * @type object\n", "\t * @ignore\n", "\t */\n", "\tvar __arrayProto = Array.prototype;\n", "\t\n", "\t\n", "\t/**\n", "\t * Abstraction for `context` parameter of the `Api` constructor to allow it to\n", "\t * take several different forms for ease of use.\n", "\t *\n", "\t * Each of the input parameter types will be converted to a DataTables settings\n", "\t * object where possible.\n", "\t *\n", "\t * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one\n", "\t * of:\n", "\t *\n", "\t * * `string` - jQuery selector. Any DataTables' matching the given selector\n", "\t * with be found and used.\n", "\t * * `node` - `TABLE` node which has already been formed into a DataTable.\n", "\t * * `jQuery` - A jQuery object of `TABLE` nodes.\n", "\t * * `object` - DataTables settings object\n", "\t * * `DataTables.Api` - API instance\n", "\t * @return {array|null} Matching DataTables settings objects. `null` or\n", "\t * `undefined` is returned if no matching DataTable is found.\n", "\t * @ignore\n", "\t */\n", "\tvar _toSettings = function ( mixed )\n", "\t{\n", "\t\tvar idx, jq;\n", "\t\tvar settings = DataTable.settings;\n", "\t\tvar tables = $.map( settings, function (el, i) {\n", "\t\t\treturn el.nTable;\n", "\t\t} );\n", "\t\n", "\t\tif ( ! mixed ) {\n", "\t\t\treturn [];\n", "\t\t}\n", "\t\telse if ( mixed.nTable && mixed.oApi ) {\n", "\t\t\t// DataTables settings object\n", "\t\t\treturn [ mixed ];\n", "\t\t}\n", "\t\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\n", "\t\t\t// Table node\n", "\t\t\tidx = $.inArray( mixed, tables );\n", "\t\t\treturn idx !== -1 ? [ settings[idx] ] : null;\n", "\t\t}\n", "\t\telse if ( mixed && typeof mixed.settings === 'function' ) {\n", "\t\t\treturn mixed.settings().toArray();\n", "\t\t}\n", "\t\telse if ( typeof mixed === 'string' ) {\n", "\t\t\t// jQuery selector\n", "\t\t\tjq = $(mixed);\n", "\t\t}\n", "\t\telse if ( mixed instanceof $ ) {\n", "\t\t\t// jQuery object (also DataTables instance)\n", "\t\t\tjq = mixed;\n", "\t\t}\n", "\t\n", "\t\tif ( jq ) {\n", "\t\t\treturn jq.map( function(i) {\n", "\t\t\t\tidx = $.inArray( this, tables );\n", "\t\t\t\treturn idx !== -1 ? settings[idx] : null;\n", "\t\t\t} ).toArray();\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * DataTables API class - used to control and interface with one or more\n", "\t * DataTables enhanced tables.\n", "\t *\n", "\t * The API class is heavily based on jQuery, presenting a chainable interface\n", "\t * that you can use to interact with tables. Each instance of the API class has\n", "\t * a \"context\" - i.e. the tables that it will operate on. This could be a single\n", "\t * table, all tables on a page or a sub-set thereof.\n", "\t *\n", "\t * Additionally the API is designed to allow you to easily work with the data in\n", "\t * the tables, retrieving and manipulating it as required. This is done by\n", "\t * presenting the API class as an array like interface. The contents of the\n", "\t * array depend upon the actions requested by each method (for example\n", "\t * `rows().nodes()` will return an array of nodes, while `rows().data()` will\n", "\t * return an array of objects or arrays depending upon your table's\n", "\t * configuration). The API object has a number of array like methods (`push`,\n", "\t * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\n", "\t * `unique` etc) to assist your working with the data held in a table.\n", "\t *\n", "\t * Most methods (those which return an Api instance) are chainable, which means\n", "\t * the return from a method call also has all of the methods available that the\n", "\t * top level object had. For example, these two calls are equivalent:\n", "\t *\n", "\t * // Not chained\n", "\t * api.row.add( {...} );\n", "\t * api.draw();\n", "\t *\n", "\t * // Chained\n", "\t * api.row.add( {...} ).draw();\n", "\t *\n", "\t * @class DataTable.Api\n", "\t * @param {array|object|string|jQuery} context DataTable identifier. This is\n", "\t * used to define which DataTables enhanced tables this API will operate on.\n", "\t * Can be one of:\n", "\t *\n", "\t * * `string` - jQuery selector. Any DataTables' matching the given selector\n", "\t * with be found and used.\n", "\t * * `node` - `TABLE` node which has already been formed into a DataTable.\n", "\t * * `jQuery` - A jQuery object of `TABLE` nodes.\n", "\t * * `object` - DataTables settings object\n", "\t * @param {array} [data] Data to initialise the Api instance with.\n", "\t *\n", "\t * @example\n", "\t * // Direct initialisation during DataTables construction\n", "\t * var api = $('#example').DataTable();\n", "\t *\n", "\t * @example\n", "\t * // Initialisation using a DataTables jQuery object\n", "\t * var api = $('#example').dataTable().api();\n", "\t *\n", "\t * @example\n", "\t * // Initialisation as a constructor\n", "\t * var api = new $.fn.DataTable.Api( 'table.dataTable' );\n", "\t */\n", "\t_Api = function ( context, data )\n", "\t{\n", "\t\tif ( ! (this instanceof _Api) ) {\n", "\t\t\treturn new _Api( context, data );\n", "\t\t}\n", "\t\n", "\t\tvar settings = [];\n", "\t\tvar ctxSettings = function ( o ) {\n", "\t\t\tvar a = _toSettings( o );\n", "\t\t\tif ( a ) {\n", "\t\t\t\tsettings = settings.concat( a );\n", "\t\t\t}\n", "\t\t};\n", "\t\n", "\t\tif ( $.isArray( context ) ) {\n", "\t\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n", "\t\t\t\tctxSettings( context[i] );\n", "\t\t\t}\n", "\t\t}\n", "\t\telse {\n", "\t\t\tctxSettings( context );\n", "\t\t}\n", "\t\n", "\t\t// Remove duplicates\n", "\t\tthis.context = _unique( settings );\n", "\t\n", "\t\t// Initial data\n", "\t\tif ( data ) {\n", "\t\t\t$.merge( this, data );\n", "\t\t}\n", "\t\n", "\t\t// selector\n", "\t\tthis.selector = {\n", "\t\t\trows: null,\n", "\t\t\tcols: null,\n", "\t\t\topts: null\n", "\t\t};\n", "\t\n", "\t\t_Api.extend( this, this, __apiStruct );\n", "\t};\n", "\t\n", "\tDataTable.Api = _Api;\n", "\t\n", "\t// Don't destroy the existing prototype, just extend it. Required for jQuery 2's\n", "\t// isPlainObject.\n", "\t$.extend( _Api.prototype, {\n", "\t\tany: function ()\n", "\t\t{\n", "\t\t\treturn this.count() !== 0;\n", "\t\t},\n", "\t\n", "\t\n", "\t\tconcat: __arrayProto.concat,\n", "\t\n", "\t\n", "\t\tcontext: [], // array of table settings objects\n", "\t\n", "\t\n", "\t\tcount: function ()\n", "\t\t{\n", "\t\t\treturn this.flatten().length;\n", "\t\t},\n", "\t\n", "\t\n", "\t\teach: function ( fn )\n", "\t\t{\n", "\t\t\tfor ( var i=0, ien=this.length ; i<ien; i++ ) {\n", "\t\t\t\tfn.call( this, this[i], i, this );\n", "\t\t\t}\n", "\t\n", "\t\t\treturn this;\n", "\t\t},\n", "\t\n", "\t\n", "\t\teq: function ( idx )\n", "\t\t{\n", "\t\t\tvar ctx = this.context;\n", "\t\n", "\t\t\treturn ctx.length > idx ?\n", "\t\t\t\tnew _Api( ctx[idx], this[idx] ) :\n", "\t\t\t\tnull;\n", "\t\t},\n", "\t\n", "\t\n", "\t\tfilter: function ( fn )\n", "\t\t{\n", "\t\t\tvar a = [];\n", "\t\n", "\t\t\tif ( __arrayProto.filter ) {\n", "\t\t\t\ta = __arrayProto.filter.call( this, fn, this );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n", "\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n", "\t\t\t\t\tif ( fn.call( this, this[i], i, this ) ) {\n", "\t\t\t\t\t\ta.push( this[i] );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\treturn new _Api( this.context, a );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tflatten: function ()\n", "\t\t{\n", "\t\t\tvar a = [];\n", "\t\t\treturn new _Api( this.context, a.concat.apply( a, this.toArray() ) );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tjoin: __arrayProto.join,\n", "\t\n", "\t\n", "\t\tindexOf: __arrayProto.indexOf || function (obj, start)\n", "\t\t{\n", "\t\t\tfor ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {\n", "\t\t\t\tif ( this[i] === obj ) {\n", "\t\t\t\t\treturn i;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t\treturn -1;\n", "\t\t},\n", "\t\n", "\t\titerator: function ( flatten, type, fn, alwaysNew ) {\n", "\t\t\tvar\n", "\t\t\t\ta = [], ret,\n", "\t\t\t\ti, ien, j, jen,\n", "\t\t\t\tcontext = this.context,\n", "\t\t\t\trows, items, item,\n", "\t\t\t\tselector = this.selector;\n", "\t\n", "\t\t\t// Argument shifting\n", "\t\t\tif ( typeof flatten === 'string' ) {\n", "\t\t\t\talwaysNew = fn;\n", "\t\t\t\tfn = type;\n", "\t\t\t\ttype = flatten;\n", "\t\t\t\tflatten = false;\n", "\t\t\t}\n", "\t\n", "\t\t\tfor ( i=0, ien=context.length ; i<ien ; i++ ) {\n", "\t\t\t\tvar apiInst = new _Api( context[i] );\n", "\t\n", "\t\t\t\tif ( type === 'table' ) {\n", "\t\t\t\t\tret = fn.call( apiInst, context[i], i );\n", "\t\n", "\t\t\t\t\tif ( ret !== undefined ) {\n", "\t\t\t\t\t\ta.push( ret );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\telse if ( type === 'columns' || type === 'rows' ) {\n", "\t\t\t\t\t// this has same length as context - one entry for each table\n", "\t\t\t\t\tret = fn.call( apiInst, context[i], this[i], i );\n", "\t\n", "\t\t\t\t\tif ( ret !== undefined ) {\n", "\t\t\t\t\t\ta.push( ret );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t\telse if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {\n", "\t\t\t\t\t// columns and rows share the same structure.\n", "\t\t\t\t\t// 'this' is an array of column indexes for each context\n", "\t\t\t\t\titems = this[i];\n", "\t\n", "\t\t\t\t\tif ( type === 'column-rows' ) {\n", "\t\t\t\t\t\trows = _selector_row_indexes( context[i], selector.opts );\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tfor ( j=0, jen=items.length ; j<jen ; j++ ) {\n", "\t\t\t\t\t\titem = items[j];\n", "\t\n", "\t\t\t\t\t\tif ( type === 'cell' ) {\n", "\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item.row, item.column, i, j );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\telse {\n", "\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item, i, j, rows );\n", "\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\tif ( ret !== undefined ) {\n", "\t\t\t\t\t\t\ta.push( ret );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( a.length || alwaysNew ) {\n", "\t\t\t\tvar api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );\n", "\t\t\t\tvar apiSelector = api.selector;\n", "\t\t\t\tapiSelector.rows = selector.rows;\n", "\t\t\t\tapiSelector.cols = selector.cols;\n", "\t\t\t\tapiSelector.opts = selector.opts;\n", "\t\t\t\treturn api;\n", "\t\t\t}\n", "\t\t\treturn this;\n", "\t\t},\n", "\t\n", "\t\n", "\t\tlastIndexOf: __arrayProto.lastIndexOf || function (obj, start)\n", "\t\t{\n", "\t\t\t// Bit cheeky...\n", "\t\t\treturn this.indexOf.apply( this.toArray.reverse(), arguments );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tlength: 0,\n", "\t\n", "\t\n", "\t\tmap: function ( fn )\n", "\t\t{\n", "\t\t\tvar a = [];\n", "\t\n", "\t\t\tif ( __arrayProto.map ) {\n", "\t\t\t\ta = __arrayProto.map.call( this, fn, this );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n", "\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n", "\t\t\t\t\ta.push( fn.call( this, this[i], i ) );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\treturn new _Api( this.context, a );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tpluck: function ( prop )\n", "\t\t{\n", "\t\t\treturn this.map( function ( el ) {\n", "\t\t\t\treturn el[ prop ];\n", "\t\t\t} );\n", "\t\t},\n", "\t\n", "\t\tpop: __arrayProto.pop,\n", "\t\n", "\t\n", "\t\tpush: __arrayProto.push,\n", "\t\n", "\t\n", "\t\t// Does not return an API instance\n", "\t\treduce: __arrayProto.reduce || function ( fn, init )\n", "\t\t{\n", "\t\t\treturn _fnReduce( this, fn, init, 0, this.length, 1 );\n", "\t\t},\n", "\t\n", "\t\n", "\t\treduceRight: __arrayProto.reduceRight || function ( fn, init )\n", "\t\t{\n", "\t\t\treturn _fnReduce( this, fn, init, this.length-1, -1, -1 );\n", "\t\t},\n", "\t\n", "\t\n", "\t\treverse: __arrayProto.reverse,\n", "\t\n", "\t\n", "\t\t// Object with rows, columns and opts\n", "\t\tselector: null,\n", "\t\n", "\t\n", "\t\tshift: __arrayProto.shift,\n", "\t\n", "\t\n", "\t\tslice: function () {\n", "\t\t\treturn new _Api( this.context, this );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tsort: __arrayProto.sort, // ? name - order?\n", "\t\n", "\t\n", "\t\tsplice: __arrayProto.splice,\n", "\t\n", "\t\n", "\t\ttoArray: function ()\n", "\t\t{\n", "\t\t\treturn __arrayProto.slice.call( this );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tto$: function ()\n", "\t\t{\n", "\t\t\treturn $( this );\n", "\t\t},\n", "\t\n", "\t\n", "\t\ttoJQuery: function ()\n", "\t\t{\n", "\t\t\treturn $( this );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tunique: function ()\n", "\t\t{\n", "\t\t\treturn new _Api( this.context, _unique(this) );\n", "\t\t},\n", "\t\n", "\t\n", "\t\tunshift: __arrayProto.unshift\n", "\t} );\n", "\t\n", "\t\n", "\t_Api.extend = function ( scope, obj, ext )\n", "\t{\n", "\t\t// Only extend API instances and static properties of the API\n", "\t\tif ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tvar\n", "\t\t\ti, ien,\n", "\t\t\tj, jen,\n", "\t\t\tstruct, inner,\n", "\t\t\tmethodScoping = function ( scope, fn, struc ) {\n", "\t\t\t\treturn function () {\n", "\t\t\t\t\tvar ret = fn.apply( scope, arguments );\n", "\t\n", "\t\t\t\t\t// Method extension\n", "\t\t\t\t\t_Api.extend( ret, ret, struc.methodExt );\n", "\t\t\t\t\treturn ret;\n", "\t\t\t\t};\n", "\t\t\t};\n", "\t\n", "\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n", "\t\t\tstruct = ext[i];\n", "\t\n", "\t\t\t// Value\n", "\t\t\tobj[ struct.name ] = typeof struct.val === 'function' ?\n", "\t\t\t\tmethodScoping( scope, struct.val, struct ) :\n", "\t\t\t\t$.isPlainObject( struct.val ) ?\n", "\t\t\t\t\t{} :\n", "\t\t\t\t\tstruct.val;\n", "\t\n", "\t\t\tobj[ struct.name ].__dt_wrapper = true;\n", "\t\n", "\t\t\t// Property extension\n", "\t\t\t_Api.extend( scope, obj[ struct.name ], struct.propExt );\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t// @todo - Is there need for an augment function?\n", "\t// _Api.augment = function ( inst, name )\n", "\t// {\n", "\t// \t// Find src object in the structure from the name\n", "\t// \tvar parts = name.split('.');\n", "\t\n", "\t// \t_Api.extend( inst, obj );\n", "\t// };\n", "\t\n", "\t\n", "\t// [\n", "\t// {\n", "\t// name: 'data' -- string - Property name\n", "\t// val: function () {}, -- function - Api method (or undefined if just an object\n", "\t// methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\n", "\t// propExt: [ ... ] -- array - Array of Api object definitions to extend the property\n", "\t// },\n", "\t// {\n", "\t// name: 'row'\n", "\t// val: {},\n", "\t// methodExt: [ ... ],\n", "\t// propExt: [\n", "\t// {\n", "\t// name: 'data'\n", "\t// val: function () {},\n", "\t// methodExt: [ ... ],\n", "\t// propExt: [ ... ]\n", "\t// },\n", "\t// ...\n", "\t// ]\n", "\t// }\n", "\t// ]\n", "\t\n", "\t_Api.register = _api_register = function ( name, val )\n", "\t{\n", "\t\tif ( $.isArray( name ) ) {\n", "\t\t\tfor ( var j=0, jen=name.length ; j<jen ; j++ ) {\n", "\t\t\t\t_Api.register( name[j], val );\n", "\t\t\t}\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tvar\n", "\t\t\ti, ien,\n", "\t\t\their = name.split('.'),\n", "\t\t\tstruct = __apiStruct,\n", "\t\t\tkey, method;\n", "\t\n", "\t\tvar find = function ( src, name ) {\n", "\t\t\tfor ( var i=0, ien=src.length ; i<ien ; i++ ) {\n", "\t\t\t\tif ( src[i].name === name ) {\n", "\t\t\t\t\treturn src[i];\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t\treturn null;\n", "\t\t};\n", "\t\n", "\t\tfor ( i=0, ien=heir.length ; i<ien ; i++ ) {\n", "\t\t\tmethod = heir[i].indexOf('()') !== -1;\n", "\t\t\tkey = method ?\n", "\t\t\t\their[i].replace('()', '') :\n", "\t\t\t\their[i];\n", "\t\n", "\t\t\tvar src = find( struct, key );\n", "\t\t\tif ( ! src ) {\n", "\t\t\t\tsrc = {\n", "\t\t\t\t\tname: key,\n", "\t\t\t\t\tval: {},\n", "\t\t\t\t\tmethodExt: [],\n", "\t\t\t\t\tpropExt: []\n", "\t\t\t\t};\n", "\t\t\t\tstruct.push( src );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( i === ien-1 ) {\n", "\t\t\t\tsrc.val = val;\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tstruct = method ?\n", "\t\t\t\t\tsrc.methodExt :\n", "\t\t\t\t\tsrc.propExt;\n", "\t\t\t}\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {\n", "\t\t_Api.register( pluralName, val );\n", "\t\n", "\t\t_Api.register( singularName, function () {\n", "\t\t\tvar ret = val.apply( this, arguments );\n", "\t\n", "\t\t\tif ( ret === this ) {\n", "\t\t\t\t// Returned item is the API instance that was passed in, return it\n", "\t\t\t\treturn this;\n", "\t\t\t}\n", "\t\t\telse if ( ret instanceof _Api ) {\n", "\t\t\t\t// New API instance returned, want the value from the first item\n", "\t\t\t\t// in the returned array for the singular result.\n", "\t\t\t\treturn ret.length ?\n", "\t\t\t\t\t$.isArray( ret[0] ) ?\n", "\t\t\t\t\t\tnew _Api( ret.context, ret[0] ) : // Array results are 'enhanced'\n", "\t\t\t\t\t\tret[0] :\n", "\t\t\t\t\tundefined;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Non-API return - just fire it back\n", "\t\t\treturn ret;\n", "\t\t} );\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Selector for HTML tables. Apply the given selector to the give array of\n", "\t * DataTables settings objects.\n", "\t *\n", "\t * @param {string|integer} [selector] jQuery selector string or integer\n", "\t * @param {array} Array of DataTables settings objects to be filtered\n", "\t * @return {array}\n", "\t * @ignore\n", "\t */\n", "\tvar __table_selector = function ( selector, a )\n", "\t{\n", "\t\t// Integer is used to pick out a table by index\n", "\t\tif ( typeof selector === 'number' ) {\n", "\t\t\treturn [ a[ selector ] ];\n", "\t\t}\n", "\t\n", "\t\t// Perform a jQuery selector on the table nodes\n", "\t\tvar nodes = $.map( a, function (el, i) {\n", "\t\t\treturn el.nTable;\n", "\t\t} );\n", "\t\n", "\t\treturn $(nodes)\n", "\t\t\t.filter( selector )\n", "\t\t\t.map( function (i) {\n", "\t\t\t\t// Need to translate back from the table node to the settings\n", "\t\t\t\tvar idx = $.inArray( this, nodes );\n", "\t\t\t\treturn a[ idx ];\n", "\t\t\t} )\n", "\t\t\t.toArray();\n", "\t};\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Context selector for the API's context (i.e. the tables the API instance\n", "\t * refers to.\n", "\t *\n", "\t * @name DataTable.Api#tables\n", "\t * @param {string|integer} [selector] Selector to pick which tables the iterator\n", "\t * should operate on. If not given, all tables in the current context are\n", "\t * used. This can be given as a jQuery selector (for example `':gt(0)'`) to\n", "\t * select multiple tables or as an integer to select a single table.\n", "\t * @returns {DataTable.Api} Returns a new API instance if a selector is given.\n", "\t */\n", "\t_api_register( 'tables()', function ( selector ) {\n", "\t\t// A new instance is created if there was a selector specified\n", "\t\treturn selector ?\n", "\t\t\tnew _Api( __table_selector( selector, this.context ) ) :\n", "\t\t\tthis;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'table()', function ( selector ) {\n", "\t\tvar tables = this.tables( selector );\n", "\t\tvar ctx = tables.context;\n", "\t\n", "\t\t// Truncate to the first matched table\n", "\t\treturn ctx.length ?\n", "\t\t\tnew _Api( ctx[0] ) :\n", "\t\t\ttables;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {\n", "\t\treturn this.iterator( 'table', function ( ctx ) {\n", "\t\t\treturn ctx.nTable;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'tables().body()', 'table().body()' , function () {\n", "\t\treturn this.iterator( 'table', function ( ctx ) {\n", "\t\t\treturn ctx.nTBody;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'tables().header()', 'table().header()' , function () {\n", "\t\treturn this.iterator( 'table', function ( ctx ) {\n", "\t\t\treturn ctx.nTHead;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {\n", "\t\treturn this.iterator( 'table', function ( ctx ) {\n", "\t\t\treturn ctx.nTFoot;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'tables().containers()', 'table().container()' , function () {\n", "\t\treturn this.iterator( 'table', function ( ctx ) {\n", "\t\t\treturn ctx.nTableWrapper;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Redraw the tables in the current context.\n", "\t */\n", "\t_api_register( 'draw()', function ( paging ) {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\tif ( paging === 'page' ) {\n", "\t\t\t\t_fnDraw( settings );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tif ( typeof paging === 'string' ) {\n", "\t\t\t\t\tpaging = paging === 'full-hold' ?\n", "\t\t\t\t\t\tfalse :\n", "\t\t\t\t\t\ttrue;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t_fnReDraw( settings, paging===false );\n", "\t\t\t}\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the current page index.\n", "\t *\n", "\t * @return {integer} Current page index (zero based)\n", "\t *//**\n", "\t * Set the current page.\n", "\t *\n", "\t * Note that if you attempt to show a page which does not exist, DataTables will\n", "\t * not throw an error, but rather reset the paging.\n", "\t *\n", "\t * @param {integer|string} action The paging action to take. This can be one of:\n", "\t * * `integer` - The page index to jump to\n", "\t * * `string` - An action to take:\n", "\t * * `first` - Jump to first page.\n", "\t * * `next` - Jump to the next page\n", "\t * * `previous` - Jump to previous page\n", "\t * * `last` - Jump to the last page.\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'page()', function ( action ) {\n", "\t\tif ( action === undefined ) {\n", "\t\t\treturn this.page.info().page; // not an expensive call\n", "\t\t}\n", "\t\n", "\t\t// else, have an action to take on all tables\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t_fnPageChange( settings, action );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Paging information for the first table in the current context.\n", "\t *\n", "\t * If you require paging information for another table, use the `table()` method\n", "\t * with a suitable selector.\n", "\t *\n", "\t * @return {object} Object with the following properties set:\n", "\t * * `page` - Current page index (zero based - i.e. the first page is `0`)\n", "\t * * `pages` - Total number of pages\n", "\t * * `start` - Display index for the first record shown on the current page\n", "\t * * `end` - Display index for the last record shown on the current page\n", "\t * * `length` - Display length (number of records). Note that generally `start\n", "\t * + length = end`, but this is not always true, for example if there are\n", "\t * only 2 records to show on the final page, with a length of 10.\n", "\t * * `recordsTotal` - Full data set length\n", "\t * * `recordsDisplay` - Data set length once the current filtering criterion\n", "\t * are applied.\n", "\t */\n", "\t_api_register( 'page.info()', function ( action ) {\n", "\t\tif ( this.context.length === 0 ) {\n", "\t\t\treturn undefined;\n", "\t\t}\n", "\t\n", "\t\tvar\n", "\t\t\tsettings = this.context[0],\n", "\t\t\tstart = settings._iDisplayStart,\n", "\t\t\tlen = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,\n", "\t\t\tvisRecords = settings.fnRecordsDisplay(),\n", "\t\t\tall = len === -1;\n", "\t\n", "\t\treturn {\n", "\t\t\t\"page\": all ? 0 : Math.floor( start / len ),\n", "\t\t\t\"pages\": all ? 1 : Math.ceil( visRecords / len ),\n", "\t\t\t\"start\": start,\n", "\t\t\t\"end\": settings.fnDisplayEnd(),\n", "\t\t\t\"length\": len,\n", "\t\t\t\"recordsTotal\": settings.fnRecordsTotal(),\n", "\t\t\t\"recordsDisplay\": visRecords,\n", "\t\t\t\"serverSide\": _fnDataSource( settings ) === 'ssp'\n", "\t\t};\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the current page length.\n", "\t *\n", "\t * @return {integer} Current page length. Note `-1` indicates that all records\n", "\t * are to be shown.\n", "\t *//**\n", "\t * Set the current page length.\n", "\t *\n", "\t * @param {integer} Page length to set. Use `-1` to show all records.\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'page.len()', function ( len ) {\n", "\t\t// Note that we can't call this function 'length()' because `length`\n", "\t\t// is a Javascript property of functions which defines how many arguments\n", "\t\t// the function expects.\n", "\t\tif ( len === undefined ) {\n", "\t\t\treturn this.context.length !== 0 ?\n", "\t\t\t\tthis.context[0]._iDisplayLength :\n", "\t\t\t\tundefined;\n", "\t\t}\n", "\t\n", "\t\t// else, set the page length\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t_fnLengthChange( settings, len );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\tvar __reload = function ( settings, holdPosition, callback ) {\n", "\t\t// Use the draw event to trigger a callback\n", "\t\tif ( callback ) {\n", "\t\t\tvar api = new _Api( settings );\n", "\t\n", "\t\t\tapi.one( 'draw', function () {\n", "\t\t\t\tcallback( api.ajax.json() );\n", "\t\t\t} );\n", "\t\t}\n", "\t\n", "\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n", "\t\t\t_fnReDraw( settings, holdPosition );\n", "\t\t}\n", "\t\telse {\n", "\t\t\t_fnProcessingDisplay( settings, true );\n", "\t\n", "\t\t\t// Cancel an existing request\n", "\t\t\tvar xhr = settings.jqXHR;\n", "\t\t\tif ( xhr && xhr.readyState !== 4 ) {\n", "\t\t\t\txhr.abort();\n", "\t\t\t}\n", "\t\n", "\t\t\t// Trigger xhr\n", "\t\t\t_fnBuildAjax( settings, [], function( json ) {\n", "\t\t\t\t_fnClearTable( settings );\n", "\t\n", "\t\t\t\tvar data = _fnAjaxDataSrc( settings, json );\n", "\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n", "\t\t\t\t\t_fnAddData( settings, data[i] );\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t_fnReDraw( settings, holdPosition );\n", "\t\t\t\t_fnProcessingDisplay( settings, false );\n", "\t\t\t} );\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the JSON response from the last Ajax request that DataTables made to the\n", "\t * server. Note that this returns the JSON from the first table in the current\n", "\t * context.\n", "\t *\n", "\t * @return {object} JSON received from the server.\n", "\t */\n", "\t_api_register( 'ajax.json()', function () {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( ctx.length > 0 ) {\n", "\t\t\treturn ctx[0].json;\n", "\t\t}\n", "\t\n", "\t\t// else return undefined;\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the data submitted in the last Ajax request\n", "\t */\n", "\t_api_register( 'ajax.params()', function () {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( ctx.length > 0 ) {\n", "\t\t\treturn ctx[0].oAjaxData;\n", "\t\t}\n", "\t\n", "\t\t// else return undefined;\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Reload tables from the Ajax data source. Note that this function will\n", "\t * automatically re-draw the table when the remote data has been loaded.\n", "\t *\n", "\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\n", "\t * position. A full re-sort and re-filter is performed when this method is\n", "\t * called, which is why the pagination reset is the default action.\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\n", "\t\treturn this.iterator( 'table', function (settings) {\n", "\t\t\t__reload( settings, resetPaging===false, callback );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Get the current Ajax URL. Note that this returns the URL from the first\n", "\t * table in the current context.\n", "\t *\n", "\t * @return {string} Current Ajax source URL\n", "\t *//**\n", "\t * Set the Ajax URL. Note that this will set the URL for all tables in the\n", "\t * current context.\n", "\t *\n", "\t * @param {string} url URL to set.\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'ajax.url()', function ( url ) {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( url === undefined ) {\n", "\t\t\t// get\n", "\t\t\tif ( ctx.length === 0 ) {\n", "\t\t\t\treturn undefined;\n", "\t\t\t}\n", "\t\t\tctx = ctx[0];\n", "\t\n", "\t\t\treturn ctx.ajax ?\n", "\t\t\t\t$.isPlainObject( ctx.ajax ) ?\n", "\t\t\t\t\tctx.ajax.url :\n", "\t\t\t\t\tctx.ajax :\n", "\t\t\t\tctx.sAjaxSource;\n", "\t\t}\n", "\t\n", "\t\t// set\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\tif ( $.isPlainObject( settings.ajax ) ) {\n", "\t\t\t\tsettings.ajax.url = url;\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\tsettings.ajax = url;\n", "\t\t\t}\n", "\t\t\t// No need to consider sAjaxSource here since DataTables gives priority\n", "\t\t\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\n", "\t\t\t// value of `sAjaxSource` redundant.\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Load data from the newly set Ajax URL. Note that this method is only\n", "\t * available when `ajax.url()` is used to set a URL. Additionally, this method\n", "\t * has the same effect as calling `ajax.reload()` but is provided for\n", "\t * convenience when setting a new URL. Like `ajax.reload()` it will\n", "\t * automatically redraw the table once the remote data has been loaded.\n", "\t *\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\n", "\t\t// Same as a reload, but makes sense to present it for easy access after a\n", "\t\t// url change\n", "\t\treturn this.iterator( 'table', function ( ctx ) {\n", "\t\t\t__reload( ctx, resetPaging===false, callback );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t\n", "\tvar _selector_run = function ( type, selector, selectFn, settings, opts )\n", "\t{\n", "\t\tvar\n", "\t\t\tout = [], res,\n", "\t\t\ta, i, ien, j, jen,\n", "\t\t\tselectorType = typeof selector;\n", "\t\n", "\t\t// Can't just check for isArray here, as an API or jQuery instance might be\n", "\t\t// given with their array like look\n", "\t\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\n", "\t\t\tselector = [ selector ];\n", "\t\t}\n", "\t\n", "\t\tfor ( i=0, ien=selector.length ; i<ien ; i++ ) {\n", "\t\t\t// Only split on simple strings - complex expressions will be jQuery selectors\n", "\t\t\ta = selector[i] && selector[i].split && ! selector[i].match(/[\\[\\(:]/) ?\n", "\t\t\t\tselector[i].split(',') :\n", "\t\t\t\t[ selector[i] ];\n", "\t\n", "\t\t\tfor ( j=0, jen=a.length ; j<jen ; j++ ) {\n", "\t\t\t\tres = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );\n", "\t\n", "\t\t\t\tif ( res && res.length ) {\n", "\t\t\t\t\tout = out.concat( res );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t// selector extensions\n", "\t\tvar ext = _ext.selector[ type ];\n", "\t\tif ( ext.length ) {\n", "\t\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n", "\t\t\t\tout = ext[i]( settings, opts, out );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn _unique( out );\n", "\t};\n", "\t\n", "\t\n", "\tvar _selector_opts = function ( opts )\n", "\t{\n", "\t\tif ( ! opts ) {\n", "\t\t\topts = {};\n", "\t\t}\n", "\t\n", "\t\t// Backwards compatibility for 1.9- which used the terminology filter rather\n", "\t\t// than search\n", "\t\tif ( opts.filter && opts.search === undefined ) {\n", "\t\t\topts.search = opts.filter;\n", "\t\t}\n", "\t\n", "\t\treturn $.extend( {\n", "\t\t\tsearch: 'none',\n", "\t\t\torder: 'current',\n", "\t\t\tpage: 'all'\n", "\t\t}, opts );\n", "\t};\n", "\t\n", "\t\n", "\tvar _selector_first = function ( inst )\n", "\t{\n", "\t\t// Reduce the API instance to the first item found\n", "\t\tfor ( var i=0, ien=inst.length ; i<ien ; i++ ) {\n", "\t\t\tif ( inst[i].length > 0 ) {\n", "\t\t\t\t// Assign the first element to the first item in the instance\n", "\t\t\t\t// and truncate the instance and context\n", "\t\t\t\tinst[0] = inst[i];\n", "\t\t\t\tinst[0].length = 1;\n", "\t\t\t\tinst.length = 1;\n", "\t\t\t\tinst.context = [ inst.context[i] ];\n", "\t\n", "\t\t\t\treturn inst;\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\t// Not found - return an empty instance\n", "\t\tinst.length = 0;\n", "\t\treturn inst;\n", "\t};\n", "\t\n", "\t\n", "\tvar _selector_row_indexes = function ( settings, opts )\n", "\t{\n", "\t\tvar\n", "\t\t\ti, ien, tmp, a=[],\n", "\t\t\tdisplayFiltered = settings.aiDisplay,\n", "\t\t\tdisplayMaster = settings.aiDisplayMaster;\n", "\t\n", "\t\tvar\n", "\t\t\tsearch = opts.search, // none, applied, removed\n", "\t\t\torder = opts.order, // applied, current, index (original - compatibility with 1.9)\n", "\t\t\tpage = opts.page; // all, current\n", "\t\n", "\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n", "\t\t\t// In server-side processing mode, most options are irrelevant since\n", "\t\t\t// rows not shown don't exist and the index order is the applied order\n", "\t\t\t// Removed is a special case - for consistency just return an empty\n", "\t\t\t// array\n", "\t\t\treturn search === 'removed' ?\n", "\t\t\t\t[] :\n", "\t\t\t\t_range( 0, displayMaster.length );\n", "\t\t}\n", "\t\telse if ( page == 'current' ) {\n", "\t\t\t// Current page implies that order=current and fitler=applied, since it is\n", "\t\t\t// fairly senseless otherwise, regardless of what order and search actually\n", "\t\t\t// are\n", "\t\t\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {\n", "\t\t\t\ta.push( displayFiltered[i] );\n", "\t\t\t}\n", "\t\t}\n", "\t\telse if ( order == 'current' || order == 'applied' ) {\n", "\t\t\ta = search == 'none' ?\n", "\t\t\t\tdisplayMaster.slice() : // no search\n", "\t\t\t\tsearch == 'applied' ?\n", "\t\t\t\t\tdisplayFiltered.slice() : // applied search\n", "\t\t\t\t\t$.map( displayMaster, function (el, i) { // removed search\n", "\t\t\t\t\t\treturn $.inArray( el, displayFiltered ) === -1 ? el : null;\n", "\t\t\t\t\t} );\n", "\t\t}\n", "\t\telse if ( order == 'index' || order == 'original' ) {\n", "\t\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n", "\t\t\t\tif ( search == 'none' ) {\n", "\t\t\t\t\ta.push( i );\n", "\t\t\t\t}\n", "\t\t\t\telse { // applied | removed\n", "\t\t\t\t\ttmp = $.inArray( i, displayFiltered );\n", "\t\n", "\t\t\t\t\tif ((tmp === -1 && search == 'removed') ||\n", "\t\t\t\t\t\t(tmp >= 0 && search == 'applied') )\n", "\t\t\t\t\t{\n", "\t\t\t\t\t\ta.push( i );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn a;\n", "\t};\n", "\t\n", "\t\n", "\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n", "\t * Rows\n", "\t *\n", "\t * {} - no selector - use all available rows\n", "\t * {integer} - row aoData index\n", "\t * {node} - TR node\n", "\t * {string} - jQuery selector to apply to the TR elements\n", "\t * {array} - jQuery array of nodes, or simply an array of TR nodes\n", "\t *\n", "\t */\n", "\t\n", "\t\n", "\tvar __row_selector = function ( settings, selector, opts )\n", "\t{\n", "\t\tvar rows;\n", "\t\tvar run = function ( sel ) {\n", "\t\t\tvar selInt = _intVal( sel );\n", "\t\t\tvar i, ien;\n", "\t\n", "\t\t\t// Short cut - selector is a number and no options provided (default is\n", "\t\t\t// all records, so no need to check if the index is in there, since it\n", "\t\t\t// must be - dev error if the index doesn't exist).\n", "\t\t\tif ( selInt !== null && ! opts ) {\n", "\t\t\t\treturn [ selInt ];\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( ! rows ) {\n", "\t\t\t\trows = _selector_row_indexes( settings, opts );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\n", "\t\t\t\t// Selector - integer\n", "\t\t\t\treturn [ selInt ];\n", "\t\t\t}\n", "\t\t\telse if ( sel === null || sel === undefined || sel === '' ) {\n", "\t\t\t\t// Selector - none\n", "\t\t\t\treturn rows;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Selector - function\n", "\t\t\tif ( typeof sel === 'function' ) {\n", "\t\t\t\treturn $.map( rows, function (idx) {\n", "\t\t\t\t\tvar row = settings.aoData[ idx ];\n", "\t\t\t\t\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Get nodes in the order from the `rows` array with null values removed\n", "\t\t\tvar nodes = _removeEmpty(\n", "\t\t\t\t_pluck_order( settings.aoData, rows, 'nTr' )\n", "\t\t\t);\n", "\t\n", "\t\t\t// Selector - node\n", "\t\t\tif ( sel.nodeName ) {\n", "\t\t\t\tif ( sel._DT_RowIndex !== undefined ) {\n", "\t\t\t\t\treturn [ sel._DT_RowIndex ]; // Property added by DT for fast lookup\n", "\t\t\t\t}\n", "\t\t\t\telse if ( sel._DT_CellIndex ) {\n", "\t\t\t\t\treturn [ sel._DT_CellIndex.row ];\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\tvar host = $(sel).closest('*[data-dt-row]');\n", "\t\t\t\t\treturn host.length ?\n", "\t\t\t\t\t\t[ host.data('dt-row') ] :\n", "\t\t\t\t\t\t[];\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t// ID selector. Want to always be able to select rows by id, regardless\n", "\t\t\t// of if the tr element has been created or not, so can't rely upon\n", "\t\t\t// jQuery here - hence a custom implementation. This does not match\n", "\t\t\t// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,\n", "\t\t\t// but to select it using a CSS selector engine (like Sizzle or\n", "\t\t\t// querySelect) it would need to need to be escaped for some characters.\n", "\t\t\t// DataTables simplifies this for row selectors since you can select\n", "\t\t\t// only a row. A # indicates an id any anything that follows is the id -\n", "\t\t\t// unescaped.\n", "\t\t\tif ( typeof sel === 'string' && sel.charAt(0) === '#' ) {\n", "\t\t\t\t// get row index from id\n", "\t\t\t\tvar rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];\n", "\t\t\t\tif ( rowObj !== undefined ) {\n", "\t\t\t\t\treturn [ rowObj.idx ];\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// need to fall through to jQuery in case there is DOM id that\n", "\t\t\t\t// matches\n", "\t\t\t}\n", "\t\n", "\t\t\t// Selector - jQuery selector string, array of nodes or jQuery object/\n", "\t\t\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\n", "\t\t\t// it also allows arrays, so this will cope with all three options\n", "\t\t\treturn $(nodes)\n", "\t\t\t\t.filter( sel )\n", "\t\t\t\t.map( function () {\n", "\t\t\t\t\treturn this._DT_RowIndex;\n", "\t\t\t\t} )\n", "\t\t\t\t.toArray();\n", "\t\t};\n", "\t\n", "\t\treturn _selector_run( 'row', selector, run, settings, opts );\n", "\t};\n", "\t\n", "\t\n", "\t_api_register( 'rows()', function ( selector, opts ) {\n", "\t\t// argument shifting\n", "\t\tif ( selector === undefined ) {\n", "\t\t\tselector = '';\n", "\t\t}\n", "\t\telse if ( $.isPlainObject( selector ) ) {\n", "\t\t\topts = selector;\n", "\t\t\tselector = '';\n", "\t\t}\n", "\t\n", "\t\topts = _selector_opts( opts );\n", "\t\n", "\t\tvar inst = this.iterator( 'table', function ( settings ) {\n", "\t\t\treturn __row_selector( settings, selector, opts );\n", "\t\t}, 1 );\n", "\t\n", "\t\t// Want argument shifting here and in __row_selector?\n", "\t\tinst.selector.rows = selector;\n", "\t\tinst.selector.opts = opts;\n", "\t\n", "\t\treturn inst;\n", "\t} );\n", "\t\n", "\t_api_register( 'rows().nodes()', function () {\n", "\t\treturn this.iterator( 'row', function ( settings, row ) {\n", "\t\t\treturn settings.aoData[ row ].nTr || undefined;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_register( 'rows().data()', function () {\n", "\t\treturn this.iterator( true, 'rows', function ( settings, rows ) {\n", "\t\t\treturn _pluck_order( settings.aoData, rows, '_aData' );\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\n", "\t\treturn this.iterator( 'row', function ( settings, row ) {\n", "\t\t\tvar r = settings.aoData[ row ];\n", "\t\t\treturn type === 'search' ? r._aFilterData : r._aSortData;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\n", "\t\treturn this.iterator( 'row', function ( settings, row ) {\n", "\t\t\t_fnInvalidate( settings, row, src );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\n", "\t\treturn this.iterator( 'row', function ( settings, row ) {\n", "\t\t\treturn row;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {\n", "\t\tvar a = [];\n", "\t\tvar context = this.context;\n", "\t\n", "\t\t// `iterator` will drop undefined values, but in this case we want them\n", "\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n", "\t\t\tfor ( var j=0, jen=this[i].length ; j<jen ; j++ ) {\n", "\t\t\t\tvar id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );\n", "\t\t\t\ta.push( (hash === true ? '#' : '' )+ id );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn new _Api( context, a );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'rows().remove()', 'row().remove()', function () {\n", "\t\tvar that = this;\n", "\t\n", "\t\tthis.iterator( 'row', function ( settings, row, thatIdx ) {\n", "\t\t\tvar data = settings.aoData;\n", "\t\t\tvar rowData = data[ row ];\n", "\t\t\tvar i, ien, j, jen;\n", "\t\t\tvar loopRow, loopCells;\n", "\t\n", "\t\t\tdata.splice( row, 1 );\n", "\t\n", "\t\t\t// Update the cached indexes\n", "\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n", "\t\t\t\tloopRow = data[i];\n", "\t\t\t\tloopCells = loopRow.anCells;\n", "\t\n", "\t\t\t\t// Rows\n", "\t\t\t\tif ( loopRow.nTr !== null ) {\n", "\t\t\t\t\tloopRow.nTr._DT_RowIndex = i;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// Cells\n", "\t\t\t\tif ( loopCells !== null ) {\n", "\t\t\t\t\tfor ( j=0, jen=loopCells.length ; j<jen ; j++ ) {\n", "\t\t\t\t\t\tloopCells[j]._DT_CellIndex.row = i;\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t// Delete from the display arrays\n", "\t\t\t_fnDeleteIndex( settings.aiDisplayMaster, row );\n", "\t\t\t_fnDeleteIndex( settings.aiDisplay, row );\n", "\t\t\t_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes\n", "\t\n", "\t\t\t// Check for an 'overflow' they case for displaying the table\n", "\t\t\t_fnLengthOverflow( settings );\n", "\t\n", "\t\t\t// Remove the row's ID reference if there is one\n", "\t\t\tvar id = settings.rowIdFn( rowData._aData );\n", "\t\t\tif ( id !== undefined ) {\n", "\t\t\t\tdelete settings.aIds[ id ];\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\tthis.iterator( 'table', function ( settings ) {\n", "\t\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n", "\t\t\t\tsettings.aoData[i].idx = i;\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'rows.add()', function ( rows ) {\n", "\t\tvar newRows = this.iterator( 'table', function ( settings ) {\n", "\t\t\t\tvar row, i, ien;\n", "\t\t\t\tvar out = [];\n", "\t\n", "\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n", "\t\t\t\t\trow = rows[i];\n", "\t\n", "\t\t\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n", "\t\t\t\t\t\tout.push( _fnAddTr( settings, row )[0] );\n", "\t\t\t\t\t}\n", "\t\t\t\t\telse {\n", "\t\t\t\t\t\tout.push( _fnAddData( settings, row ) );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\treturn out;\n", "\t\t\t}, 1 );\n", "\t\n", "\t\t// Return an Api.rows() extended instance, so rows().nodes() etc can be used\n", "\t\tvar modRows = this.rows( -1 );\n", "\t\tmodRows.pop();\n", "\t\t$.merge( modRows, newRows );\n", "\t\n", "\t\treturn modRows;\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t *\n", "\t */\n", "\t_api_register( 'row()', function ( selector, opts ) {\n", "\t\treturn _selector_first( this.rows( selector, opts ) );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'row().data()', function ( data ) {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( data === undefined ) {\n", "\t\t\t// Get\n", "\t\t\treturn ctx.length && this.length ?\n", "\t\t\t\tctx[0].aoData[ this[0] ]._aData :\n", "\t\t\t\tundefined;\n", "\t\t}\n", "\t\n", "\t\t// Set\n", "\t\tctx[0].aoData[ this[0] ]._aData = data;\n", "\t\n", "\t\t// Automatically invalidate\n", "\t\t_fnInvalidate( ctx[0], this[0], 'data' );\n", "\t\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'row().node()', function () {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\treturn ctx.length && this.length ?\n", "\t\t\tctx[0].aoData[ this[0] ].nTr || null :\n", "\t\t\tnull;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'row.add()', function ( row ) {\n", "\t\t// Allow a jQuery object to be passed in - only a single row is added from\n", "\t\t// it though - the first element in the set\n", "\t\tif ( row instanceof $ && row.length ) {\n", "\t\t\trow = row[0];\n", "\t\t}\n", "\t\n", "\t\tvar rows = this.iterator( 'table', function ( settings ) {\n", "\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n", "\t\t\t\treturn _fnAddTr( settings, row )[0];\n", "\t\t\t}\n", "\t\t\treturn _fnAddData( settings, row );\n", "\t\t} );\n", "\t\n", "\t\t// Return an Api.rows() extended instance, with the newly added row selected\n", "\t\treturn this.row( rows[0] );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\tvar __details_add = function ( ctx, row, data, klass )\n", "\t{\n", "\t\t// Convert to array of TR elements\n", "\t\tvar rows = [];\n", "\t\tvar addRow = function ( r, k ) {\n", "\t\t\t// Recursion to allow for arrays of jQuery objects\n", "\t\t\tif ( $.isArray( r ) || r instanceof $ ) {\n", "\t\t\t\tfor ( var i=0, ien=r.length ; i<ien ; i++ ) {\n", "\t\t\t\t\taddRow( r[i], k );\n", "\t\t\t\t}\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t// If we get a TR element, then just add it directly - up to the dev\n", "\t\t\t// to add the correct number of columns etc\n", "\t\t\tif ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {\n", "\t\t\t\trows.push( r );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t// Otherwise create a row with a wrapper\n", "\t\t\t\tvar created = $('<tr><td/></tr>').addClass( k );\n", "\t\t\t\t$('td', created)\n", "\t\t\t\t\t.addClass( k )\n", "\t\t\t\t\t.html( r )\n", "\t\t\t\t\t[0].colSpan = _fnVisbleColumns( ctx );\n", "\t\n", "\t\t\t\trows.push( created[0] );\n", "\t\t\t}\n", "\t\t};\n", "\t\n", "\t\taddRow( data, klass );\n", "\t\n", "\t\tif ( row._details ) {\n", "\t\t\trow._details.detach();\n", "\t\t}\n", "\t\n", "\t\trow._details = $(rows);\n", "\t\n", "\t\t// If the children were already shown, that state should be retained\n", "\t\tif ( row._detailsShow ) {\n", "\t\t\trow._details.insertAfter( row.nTr );\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\tvar __details_remove = function ( api, idx )\n", "\t{\n", "\t\tvar ctx = api.context;\n", "\t\n", "\t\tif ( ctx.length ) {\n", "\t\t\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\n", "\t\n", "\t\t\tif ( row && row._details ) {\n", "\t\t\t\trow._details.remove();\n", "\t\n", "\t\t\t\trow._detailsShow = undefined;\n", "\t\t\t\trow._details = undefined;\n", "\t\t\t}\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\tvar __details_display = function ( api, show ) {\n", "\t\tvar ctx = api.context;\n", "\t\n", "\t\tif ( ctx.length && api.length ) {\n", "\t\t\tvar row = ctx[0].aoData[ api[0] ];\n", "\t\n", "\t\t\tif ( row._details ) {\n", "\t\t\t\trow._detailsShow = show;\n", "\t\n", "\t\t\t\tif ( show ) {\n", "\t\t\t\t\trow._details.insertAfter( row.nTr );\n", "\t\t\t\t}\n", "\t\t\t\telse {\n", "\t\t\t\t\trow._details.detach();\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t__details_events( ctx[0] );\n", "\t\t\t}\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\tvar __details_events = function ( settings )\n", "\t{\n", "\t\tvar api = new _Api( settings );\n", "\t\tvar namespace = '.dt.DT_details';\n", "\t\tvar drawEvent = 'draw'+namespace;\n", "\t\tvar colvisEvent = 'column-visibility'+namespace;\n", "\t\tvar destroyEvent = 'destroy'+namespace;\n", "\t\tvar data = settings.aoData;\n", "\t\n", "\t\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\n", "\t\n", "\t\tif ( _pluck( data, '_details' ).length > 0 ) {\n", "\t\t\t// On each draw, insert the required elements into the document\n", "\t\t\tapi.on( drawEvent, function ( e, ctx ) {\n", "\t\t\t\tif ( settings !== ctx ) {\n", "\t\t\t\t\treturn;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\n", "\t\t\t\t\t// Internal data grab\n", "\t\t\t\t\tvar row = data[ idx ];\n", "\t\n", "\t\t\t\t\tif ( row._detailsShow ) {\n", "\t\t\t\t\t\trow._details.insertAfter( row.nTr );\n", "\t\t\t\t\t}\n", "\t\t\t\t} );\n", "\t\t\t} );\n", "\t\n", "\t\t\t// Column visibility change - update the colspan\n", "\t\t\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\n", "\t\t\t\tif ( settings !== ctx ) {\n", "\t\t\t\t\treturn;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// Update the colspan for the details rows (note, only if it already has\n", "\t\t\t\t// a colspan)\n", "\t\t\t\tvar row, visible = _fnVisbleColumns( ctx );\n", "\t\n", "\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n", "\t\t\t\t\trow = data[i];\n", "\t\n", "\t\t\t\t\tif ( row._details ) {\n", "\t\t\t\t\t\trow._details.children('td[colspan]').attr('colspan', visible );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\n", "\t\t\t// Table destroyed - nuke any child rows\n", "\t\t\tapi.on( destroyEvent, function ( e, ctx ) {\n", "\t\t\t\tif ( settings !== ctx ) {\n", "\t\t\t\t\treturn;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n", "\t\t\t\t\tif ( data[i]._details ) {\n", "\t\t\t\t\t\t__details_remove( api, i );\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\t\t} );\n", "\t\t}\n", "\t};\n", "\t\n", "\t// Strings for the method names to help minification\n", "\tvar _emp = '';\n", "\tvar _child_obj = _emp+'row().child';\n", "\tvar _child_mth = _child_obj+'()';\n", "\t\n", "\t// data can be:\n", "\t// tr\n", "\t// string\n", "\t// jQuery or array of any of the above\n", "\t_api_register( _child_mth, function ( data, klass ) {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( data === undefined ) {\n", "\t\t\t// get\n", "\t\t\treturn ctx.length && this.length ?\n", "\t\t\t\tctx[0].aoData[ this[0] ]._details :\n", "\t\t\t\tundefined;\n", "\t\t}\n", "\t\telse if ( data === true ) {\n", "\t\t\t// show\n", "\t\t\tthis.child.show();\n", "\t\t}\n", "\t\telse if ( data === false ) {\n", "\t\t\t// remove\n", "\t\t\t__details_remove( this );\n", "\t\t}\n", "\t\telse if ( ctx.length && this.length ) {\n", "\t\t\t// set\n", "\t\t\t__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );\n", "\t\t}\n", "\t\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( [\n", "\t\t_child_obj+'.show()',\n", "\t\t_child_mth+'.show()' // only when `child()` was called with parameters (without\n", "\t], function ( show ) { // it returns an object and this method is not executed)\n", "\t\t__details_display( this, true );\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( [\n", "\t\t_child_obj+'.hide()',\n", "\t\t_child_mth+'.hide()' // only when `child()` was called with parameters (without\n", "\t], function () { // it returns an object and this method is not executed)\n", "\t\t__details_display( this, false );\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( [\n", "\t\t_child_obj+'.remove()',\n", "\t\t_child_mth+'.remove()' // only when `child()` was called with parameters (without\n", "\t], function () { // it returns an object and this method is not executed)\n", "\t\t__details_remove( this );\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( _child_obj+'.isShown()', function () {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( ctx.length && this.length ) {\n", "\t\t\t// _detailsShown as false or undefined will fall through to return false\n", "\t\t\treturn ctx[0].aoData[ this[0] ]._detailsShow || false;\n", "\t\t}\n", "\t\treturn false;\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n", "\t * Columns\n", "\t *\n", "\t * {integer} - column index (>=0 count from left, <0 count from right)\n", "\t * \"{integer}:visIdx\" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)\n", "\t * \"{integer}:visible\" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)\n", "\t * \"{string}:name\" - column name\n", "\t * \"{string}\" - jQuery selector on column header nodes\n", "\t *\n", "\t */\n", "\t\n", "\t// can be an array of these items, comma separated list, or an array of comma\n", "\t// separated lists\n", "\t\n", "\tvar __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;\n", "\t\n", "\t\n", "\t// r1 and r2 are redundant - but it means that the parameters match for the\n", "\t// iterator callback in columns().data()\n", "\tvar __columnData = function ( settings, column, r1, r2, rows ) {\n", "\t\tvar a = [];\n", "\t\tfor ( var row=0, ien=rows.length ; row<ien ; row++ ) {\n", "\t\t\ta.push( _fnGetCellData( settings, rows[row], column ) );\n", "\t\t}\n", "\t\treturn a;\n", "\t};\n", "\t\n", "\t\n", "\tvar __column_selector = function ( settings, selector, opts )\n", "\t{\n", "\t\tvar\n", "\t\t\tcolumns = settings.aoColumns,\n", "\t\t\tnames = _pluck( columns, 'sName' ),\n", "\t\t\tnodes = _pluck( columns, 'nTh' );\n", "\t\n", "\t\tvar run = function ( s ) {\n", "\t\t\tvar selInt = _intVal( s );\n", "\t\n", "\t\t\t// Selector - all\n", "\t\t\tif ( s === '' ) {\n", "\t\t\t\treturn _range( columns.length );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Selector - index\n", "\t\t\tif ( selInt !== null ) {\n", "\t\t\t\treturn [ selInt >= 0 ?\n", "\t\t\t\t\tselInt : // Count from left\n", "\t\t\t\t\tcolumns.length + selInt // Count from right (+ because its a negative value)\n", "\t\t\t\t];\n", "\t\t\t}\n", "\t\n", "\t\t\t// Selector = function\n", "\t\t\tif ( typeof s === 'function' ) {\n", "\t\t\t\tvar rows = _selector_row_indexes( settings, opts );\n", "\t\n", "\t\t\t\treturn $.map( columns, function (col, idx) {\n", "\t\t\t\t\treturn s(\n", "\t\t\t\t\t\t\tidx,\n", "\t\t\t\t\t\t\t__columnData( settings, idx, 0, 0, rows ),\n", "\t\t\t\t\t\t\tnodes[ idx ]\n", "\t\t\t\t\t\t) ? idx : null;\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\n", "\t\t\t// jQuery or string selector\n", "\t\t\tvar match = typeof s === 'string' ?\n", "\t\t\t\ts.match( __re_column_selector ) :\n", "\t\t\t\t'';\n", "\t\n", "\t\t\tif ( match ) {\n", "\t\t\t\tswitch( match[2] ) {\n", "\t\t\t\t\tcase 'visIdx':\n", "\t\t\t\t\tcase 'visible':\n", "\t\t\t\t\t\tvar idx = parseInt( match[1], 10 );\n", "\t\t\t\t\t\t// Visible index given, convert to column index\n", "\t\t\t\t\t\tif ( idx < 0 ) {\n", "\t\t\t\t\t\t\t// Counting from the right\n", "\t\t\t\t\t\t\tvar visColumns = $.map( columns, function (col,i) {\n", "\t\t\t\t\t\t\t\treturn col.bVisible ? i : null;\n", "\t\t\t\t\t\t\t} );\n", "\t\t\t\t\t\t\treturn [ visColumns[ visColumns.length + idx ] ];\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\t// Counting from the left\n", "\t\t\t\t\t\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\n", "\t\n", "\t\t\t\t\tcase 'name':\n", "\t\t\t\t\t\t// match by name. `names` is column index complete and in order\n", "\t\t\t\t\t\treturn $.map( names, function (name, i) {\n", "\t\t\t\t\t\t\treturn name === match[1] ? i : null;\n", "\t\t\t\t\t\t} );\n", "\t\n", "\t\t\t\t\tdefault:\n", "\t\t\t\t\t\treturn [];\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t// Cell in the table body\n", "\t\t\tif ( s.nodeName && s._DT_CellIndex ) {\n", "\t\t\t\treturn [ s._DT_CellIndex.column ];\n", "\t\t\t}\n", "\t\n", "\t\t\t// jQuery selector on the TH elements for the columns\n", "\t\t\tvar jqResult = $( nodes )\n", "\t\t\t\t.filter( s )\n", "\t\t\t\t.map( function () {\n", "\t\t\t\t\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\n", "\t\t\t\t} )\n", "\t\t\t\t.toArray();\n", "\t\n", "\t\t\tif ( jqResult.length || ! s.nodeName ) {\n", "\t\t\t\treturn jqResult;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Otherwise a node which might have a `dt-column` data attribute, or be\n", "\t\t\t// a child or such an element\n", "\t\t\tvar host = $(s).closest('*[data-dt-column]');\n", "\t\t\treturn host.length ?\n", "\t\t\t\t[ host.data('dt-column') ] :\n", "\t\t\t\t[];\n", "\t\t};\n", "\t\n", "\t\treturn _selector_run( 'column', selector, run, settings, opts );\n", "\t};\n", "\t\n", "\t\n", "\tvar __setColumnVis = function ( settings, column, vis ) {\n", "\t\tvar\n", "\t\t\tcols = settings.aoColumns,\n", "\t\t\tcol = cols[ column ],\n", "\t\t\tdata = settings.aoData,\n", "\t\t\trow, cells, i, ien, tr;\n", "\t\n", "\t\t// Get\n", "\t\tif ( vis === undefined ) {\n", "\t\t\treturn col.bVisible;\n", "\t\t}\n", "\t\n", "\t\t// Set\n", "\t\t// No change\n", "\t\tif ( col.bVisible === vis ) {\n", "\t\t\treturn;\n", "\t\t}\n", "\t\n", "\t\tif ( vis ) {\n", "\t\t\t// Insert column\n", "\t\t\t// Need to decide if we should use appendChild or insertBefore\n", "\t\t\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\n", "\t\n", "\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n", "\t\t\t\ttr = data[i].nTr;\n", "\t\t\t\tcells = data[i].anCells;\n", "\t\n", "\t\t\t\tif ( tr ) {\n", "\t\t\t\t\t// insertBefore can act like appendChild if 2nd arg is null\n", "\t\t\t\t\ttr.insertBefore( cells[ column ], cells[ insertBefore ] || null );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t\telse {\n", "\t\t\t// Remove column\n", "\t\t\t$( _pluck( settings.aoData, 'anCells', column ) ).detach();\n", "\t\t}\n", "\t\n", "\t\t// Common actions\n", "\t\tcol.bVisible = vis;\n", "\t\t_fnDrawHead( settings, settings.aoHeader );\n", "\t\t_fnDrawHead( settings, settings.aoFooter );\n", "\t\n", "\t\t_fnSaveState( settings );\n", "\t};\n", "\t\n", "\t\n", "\t_api_register( 'columns()', function ( selector, opts ) {\n", "\t\t// argument shifting\n", "\t\tif ( selector === undefined ) {\n", "\t\t\tselector = '';\n", "\t\t}\n", "\t\telse if ( $.isPlainObject( selector ) ) {\n", "\t\t\topts = selector;\n", "\t\t\tselector = '';\n", "\t\t}\n", "\t\n", "\t\topts = _selector_opts( opts );\n", "\t\n", "\t\tvar inst = this.iterator( 'table', function ( settings ) {\n", "\t\t\treturn __column_selector( settings, selector, opts );\n", "\t\t}, 1 );\n", "\t\n", "\t\t// Want argument shifting here and in _row_selector?\n", "\t\tinst.selector.cols = selector;\n", "\t\tinst.selector.opts = opts;\n", "\t\n", "\t\treturn inst;\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {\n", "\t\treturn this.iterator( 'column', function ( settings, column ) {\n", "\t\t\treturn settings.aoColumns[column].nTh;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {\n", "\t\treturn this.iterator( 'column', function ( settings, column ) {\n", "\t\t\treturn settings.aoColumns[column].nTf;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().data()', 'column().data()', function () {\n", "\t\treturn this.iterator( 'column-rows', __columnData, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {\n", "\t\treturn this.iterator( 'column', function ( settings, column ) {\n", "\t\t\treturn settings.aoColumns[column].mData;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {\n", "\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n", "\t\t\treturn _pluck_order( settings.aoData, rows,\n", "\t\t\t\ttype === 'search' ? '_aFilterData' : '_aSortData', column\n", "\t\t\t);\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {\n", "\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n", "\t\t\treturn _pluck_order( settings.aoData, rows, 'anCells', column ) ;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {\n", "\t\tvar ret = this.iterator( 'column', function ( settings, column ) {\n", "\t\t\tif ( vis === undefined ) {\n", "\t\t\t\treturn settings.aoColumns[ column ].bVisible;\n", "\t\t\t} // else\n", "\t\t\t__setColumnVis( settings, column, vis );\n", "\t\t} );\n", "\t\n", "\t\t// Group the column visibility changes\n", "\t\tif ( vis !== undefined ) {\n", "\t\t\t// Second loop once the first is done for events\n", "\t\t\tthis.iterator( 'column', function ( settings, column ) {\n", "\t\t\t\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );\n", "\t\t\t} );\n", "\t\n", "\t\t\tif ( calc === undefined || calc ) {\n", "\t\t\t\tthis.columns.adjust();\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn ret;\n", "\t} );\n", "\t\n", "\t_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {\n", "\t\treturn this.iterator( 'column', function ( settings, column ) {\n", "\t\t\treturn type === 'visible' ?\n", "\t\t\t\t_fnColumnIndexToVisible( settings, column ) :\n", "\t\t\t\tcolumn;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_register( 'columns.adjust()', function () {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t_fnAdjustColumnSizing( settings );\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t_api_register( 'column.index()', function ( type, idx ) {\n", "\t\tif ( this.context.length !== 0 ) {\n", "\t\t\tvar ctx = this.context[0];\n", "\t\n", "\t\t\tif ( type === 'fromVisible' || type === 'toData' ) {\n", "\t\t\t\treturn _fnVisibleToColumnIndex( ctx, idx );\n", "\t\t\t}\n", "\t\t\telse if ( type === 'fromData' || type === 'toVisible' ) {\n", "\t\t\t\treturn _fnColumnIndexToVisible( ctx, idx );\n", "\t\t\t}\n", "\t\t}\n", "\t} );\n", "\t\n", "\t_api_register( 'column()', function ( selector, opts ) {\n", "\t\treturn _selector_first( this.columns( selector, opts ) );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\tvar __cell_selector = function ( settings, selector, opts )\n", "\t{\n", "\t\tvar data = settings.aoData;\n", "\t\tvar rows = _selector_row_indexes( settings, opts );\n", "\t\tvar cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );\n", "\t\tvar allCells = $( [].concat.apply([], cells) );\n", "\t\tvar row;\n", "\t\tvar columns = settings.aoColumns.length;\n", "\t\tvar a, i, ien, j, o, host;\n", "\t\n", "\t\tvar run = function ( s ) {\n", "\t\t\tvar fnSelector = typeof s === 'function';\n", "\t\n", "\t\t\tif ( s === null || s === undefined || fnSelector ) {\n", "\t\t\t\t// All cells and function selectors\n", "\t\t\t\ta = [];\n", "\t\n", "\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n", "\t\t\t\t\trow = rows[i];\n", "\t\n", "\t\t\t\t\tfor ( j=0 ; j<columns ; j++ ) {\n", "\t\t\t\t\t\to = {\n", "\t\t\t\t\t\t\trow: row,\n", "\t\t\t\t\t\t\tcolumn: j\n", "\t\t\t\t\t\t};\n", "\t\n", "\t\t\t\t\t\tif ( fnSelector ) {\n", "\t\t\t\t\t\t\t// Selector - function\n", "\t\t\t\t\t\t\thost = data[ row ];\n", "\t\n", "\t\t\t\t\t\t\tif ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {\n", "\t\t\t\t\t\t\t\ta.push( o );\n", "\t\t\t\t\t\t\t}\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\telse {\n", "\t\t\t\t\t\t\t// Selector - all\n", "\t\t\t\t\t\t\ta.push( o );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\treturn a;\n", "\t\t\t}\n", "\t\t\t\n", "\t\t\t// Selector - index\n", "\t\t\tif ( $.isPlainObject( s ) ) {\n", "\t\t\t\treturn [s];\n", "\t\t\t}\n", "\t\n", "\t\t\t// Selector - jQuery filtered cells\n", "\t\t\tvar jqResult = allCells\n", "\t\t\t\t.filter( s )\n", "\t\t\t\t.map( function (i, el) {\n", "\t\t\t\t\treturn { // use a new object, in case someone changes the values\n", "\t\t\t\t\t\trow: el._DT_CellIndex.row,\n", "\t\t\t\t\t\tcolumn: el._DT_CellIndex.column\n", "\t \t\t\t\t};\n", "\t\t\t\t} )\n", "\t\t\t\t.toArray();\n", "\t\n", "\t\t\tif ( jqResult.length || ! s.nodeName ) {\n", "\t\t\t\treturn jqResult;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Otherwise the selector is a node, and there is one last option - the\n", "\t\t\t// element might be a child of an element which has dt-row and dt-column\n", "\t\t\t// data attributes\n", "\t\t\thost = $(s).closest('*[data-dt-row]');\n", "\t\t\treturn host.length ?\n", "\t\t\t\t[ {\n", "\t\t\t\t\trow: host.data('dt-row'),\n", "\t\t\t\t\tcolumn: host.data('dt-column')\n", "\t\t\t\t} ] :\n", "\t\t\t\t[];\n", "\t\t};\n", "\t\n", "\t\treturn _selector_run( 'cell', selector, run, settings, opts );\n", "\t};\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {\n", "\t\t// Argument shifting\n", "\t\tif ( $.isPlainObject( rowSelector ) ) {\n", "\t\t\t// Indexes\n", "\t\t\tif ( rowSelector.row === undefined ) {\n", "\t\t\t\t// Selector options in first parameter\n", "\t\t\t\topts = rowSelector;\n", "\t\t\t\trowSelector = null;\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\t// Cell index objects in first parameter\n", "\t\t\t\topts = columnSelector;\n", "\t\t\t\tcolumnSelector = null;\n", "\t\t\t}\n", "\t\t}\n", "\t\tif ( $.isPlainObject( columnSelector ) ) {\n", "\t\t\topts = columnSelector;\n", "\t\t\tcolumnSelector = null;\n", "\t\t}\n", "\t\n", "\t\t// Cell selector\n", "\t\tif ( columnSelector === null || columnSelector === undefined ) {\n", "\t\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t\treturn __cell_selector( settings, rowSelector, _selector_opts( opts ) );\n", "\t\t\t} );\n", "\t\t}\n", "\t\n", "\t\t// Row + column selector\n", "\t\tvar columns = this.columns( columnSelector, opts );\n", "\t\tvar rows = this.rows( rowSelector, opts );\n", "\t\tvar a, i, ien, j, jen;\n", "\t\n", "\t\tvar cells = this.iterator( 'table', function ( settings, idx ) {\n", "\t\t\ta = [];\n", "\t\n", "\t\t\tfor ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {\n", "\t\t\t\tfor ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {\n", "\t\t\t\t\ta.push( {\n", "\t\t\t\t\t\trow: rows[idx][i],\n", "\t\t\t\t\t\tcolumn: columns[idx][j]\n", "\t\t\t\t\t} );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\treturn a;\n", "\t\t}, 1 );\n", "\t\n", "\t\t$.extend( cells.selector, {\n", "\t\t\tcols: columnSelector,\n", "\t\t\trows: rowSelector,\n", "\t\t\topts: opts\n", "\t\t} );\n", "\t\n", "\t\treturn cells;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {\n", "\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n", "\t\t\tvar data = settings.aoData[ row ];\n", "\t\n", "\t\t\treturn data && data.anCells ?\n", "\t\t\t\tdata.anCells[ column ] :\n", "\t\t\t\tundefined;\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'cells().data()', function () {\n", "\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n", "\t\t\treturn _fnGetCellData( settings, row, column );\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {\n", "\t\ttype = type === 'search' ? '_aFilterData' : '_aSortData';\n", "\t\n", "\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n", "\t\t\treturn settings.aoData[ row ][ type ][ column ];\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {\n", "\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n", "\t\t\treturn _fnGetCellData( settings, row, column, type );\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {\n", "\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n", "\t\t\treturn {\n", "\t\t\t\trow: row,\n", "\t\t\t\tcolumn: column,\n", "\t\t\t\tcolumnVisible: _fnColumnIndexToVisible( settings, column )\n", "\t\t\t};\n", "\t\t}, 1 );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {\n", "\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n", "\t\t\t_fnInvalidate( settings, row, src, column );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {\n", "\t\treturn _selector_first( this.cells( rowSelector, columnSelector, opts ) );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'cell().data()', function ( data ) {\n", "\t\tvar ctx = this.context;\n", "\t\tvar cell = this[0];\n", "\t\n", "\t\tif ( data === undefined ) {\n", "\t\t\t// Get\n", "\t\t\treturn ctx.length && cell.length ?\n", "\t\t\t\t_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :\n", "\t\t\t\tundefined;\n", "\t\t}\n", "\t\n", "\t\t// Set\n", "\t\t_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );\n", "\t\t_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );\n", "\t\n", "\t\treturn this;\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Get current ordering (sorting) that has been applied to the table.\n", "\t *\n", "\t * @returns {array} 2D array containing the sorting information for the first\n", "\t * table in the current context. Each element in the parent array represents\n", "\t * a column being sorted upon (i.e. multi-sorting with two columns would have\n", "\t * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is\n", "\t * the column index that the sorting condition applies to, the second is the\n", "\t * direction of the sort (`desc` or `asc`) and, optionally, the third is the\n", "\t * index of the sorting order from the `column.sorting` initialisation array.\n", "\t *//**\n", "\t * Set the ordering for the table.\n", "\t *\n", "\t * @param {integer} order Column index to sort upon.\n", "\t * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)\n", "\t * @returns {DataTables.Api} this\n", "\t *//**\n", "\t * Set the ordering for the table.\n", "\t *\n", "\t * @param {array} order 1D array of sorting information to be applied.\n", "\t * @param {array} [...] Optional additional sorting conditions\n", "\t * @returns {DataTables.Api} this\n", "\t *//**\n", "\t * Set the ordering for the table.\n", "\t *\n", "\t * @param {array} order 2D array of sorting information to be applied.\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'order()', function ( order, dir ) {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( order === undefined ) {\n", "\t\t\t// get\n", "\t\t\treturn ctx.length !== 0 ?\n", "\t\t\t\tctx[0].aaSorting :\n", "\t\t\t\tundefined;\n", "\t\t}\n", "\t\n", "\t\t// set\n", "\t\tif ( typeof order === 'number' ) {\n", "\t\t\t// Simple column / direction passed in\n", "\t\t\torder = [ [ order, dir ] ];\n", "\t\t}\n", "\t\telse if ( order.length && ! $.isArray( order[0] ) ) {\n", "\t\t\t// Arguments passed in (list of 1D arrays)\n", "\t\t\torder = Array.prototype.slice.call( arguments );\n", "\t\t}\n", "\t\t// otherwise a 2D array was passed in\n", "\t\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\tsettings.aaSorting = order.slice();\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t/**\n", "\t * Attach a sort listener to an element for a given column\n", "\t *\n", "\t * @param {node|jQuery|string} node Identifier for the element(s) to attach the\n", "\t * listener to. This can take the form of a single DOM node, a jQuery\n", "\t * collection of nodes or a jQuery selector which will identify the node(s).\n", "\t * @param {integer} column the column that a click on this node will sort on\n", "\t * @param {function} [callback] callback function when sort is run\n", "\t * @returns {DataTables.Api} this\n", "\t */\n", "\t_api_register( 'order.listener()', function ( node, column, callback ) {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t_fnSortAttachListener( settings, node, column, callback );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'order.fixed()', function ( set ) {\n", "\t\tif ( ! set ) {\n", "\t\t\tvar ctx = this.context;\n", "\t\t\tvar fixed = ctx.length ?\n", "\t\t\t\tctx[0].aaSortingFixed :\n", "\t\t\t\tundefined;\n", "\t\n", "\t\t\treturn $.isArray( fixed ) ?\n", "\t\t\t\t{ pre: fixed } :\n", "\t\t\t\tfixed;\n", "\t\t}\n", "\t\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\tsettings.aaSortingFixed = $.extend( true, {}, set );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t// Order by the selected column(s)\n", "\t_api_register( [\n", "\t\t'columns().order()',\n", "\t\t'column().order()'\n", "\t], function ( dir ) {\n", "\t\tvar that = this;\n", "\t\n", "\t\treturn this.iterator( 'table', function ( settings, i ) {\n", "\t\t\tvar sort = [];\n", "\t\n", "\t\t\t$.each( that[i], function (j, col) {\n", "\t\t\t\tsort.push( [ col, dir ] );\n", "\t\t\t} );\n", "\t\n", "\t\t\tsettings.aaSorting = sort;\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t_api_register( 'search()', function ( input, regex, smart, caseInsen ) {\n", "\t\tvar ctx = this.context;\n", "\t\n", "\t\tif ( input === undefined ) {\n", "\t\t\t// get\n", "\t\t\treturn ctx.length !== 0 ?\n", "\t\t\t\tctx[0].oPreviousSearch.sSearch :\n", "\t\t\t\tundefined;\n", "\t\t}\n", "\t\n", "\t\t// set\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\tif ( ! settings.oFeatures.bFilter ) {\n", "\t\t\t\treturn;\n", "\t\t\t}\n", "\t\n", "\t\t\t_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {\n", "\t\t\t\t\"sSearch\": input+\"\",\n", "\t\t\t\t\"bRegex\": regex === null ? false : regex,\n", "\t\t\t\t\"bSmart\": smart === null ? true : smart,\n", "\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n", "\t\t\t} ), 1 );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_registerPlural(\n", "\t\t'columns().search()',\n", "\t\t'column().search()',\n", "\t\tfunction ( input, regex, smart, caseInsen ) {\n", "\t\t\treturn this.iterator( 'column', function ( settings, column ) {\n", "\t\t\t\tvar preSearch = settings.aoPreSearchCols;\n", "\t\n", "\t\t\t\tif ( input === undefined ) {\n", "\t\t\t\t\t// get\n", "\t\t\t\t\treturn preSearch[ column ].sSearch;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t// set\n", "\t\t\t\tif ( ! settings.oFeatures.bFilter ) {\n", "\t\t\t\t\treturn;\n", "\t\t\t\t}\n", "\t\n", "\t\t\t\t$.extend( preSearch[ column ], {\n", "\t\t\t\t\t\"sSearch\": input+\"\",\n", "\t\t\t\t\t\"bRegex\": regex === null ? false : regex,\n", "\t\t\t\t\t\"bSmart\": smart === null ? true : smart,\n", "\t\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n", "\t\t\t\t} );\n", "\t\n", "\t\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch, 1 );\n", "\t\t\t} );\n", "\t\t}\n", "\t);\n", "\t\n", "\t/*\n", "\t * State API methods\n", "\t */\n", "\t\n", "\t_api_register( 'state()', function () {\n", "\t\treturn this.context.length ?\n", "\t\t\tthis.context[0].oSavedState :\n", "\t\t\tnull;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'state.clear()', function () {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t// Save an empty object\n", "\t\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, {} );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'state.loaded()', function () {\n", "\t\treturn this.context.length ?\n", "\t\t\tthis.context[0].oLoadedState :\n", "\t\t\tnull;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'state.save()', function () {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t_fnSaveState( settings );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Provide a common method for plug-ins to check the version of DataTables being\n", "\t * used, in order to ensure compatibility.\n", "\t *\n", "\t * @param {string} version Version string to check for, in the format \"X.Y.Z\".\n", "\t * Note that the formats \"X\" and \"X.Y\" are also acceptable.\n", "\t * @returns {boolean} true if this version of DataTables is greater or equal to\n", "\t * the required version, or false if this version of DataTales is not\n", "\t * suitable\n", "\t * @static\n", "\t * @dtopt API-Static\n", "\t *\n", "\t * @example\n", "\t * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );\n", "\t */\n", "\tDataTable.versionCheck = DataTable.fnVersionCheck = function( version )\n", "\t{\n", "\t\tvar aThis = DataTable.version.split('.');\n", "\t\tvar aThat = version.split('.');\n", "\t\tvar iThis, iThat;\n", "\t\n", "\t\tfor ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {\n", "\t\t\tiThis = parseInt( aThis[i], 10 ) || 0;\n", "\t\t\tiThat = parseInt( aThat[i], 10 ) || 0;\n", "\t\n", "\t\t\t// Parts are the same, keep comparing\n", "\t\t\tif (iThis === iThat) {\n", "\t\t\t\tcontinue;\n", "\t\t\t}\n", "\t\n", "\t\t\t// Parts are different, return immediately\n", "\t\t\treturn iThis > iThat;\n", "\t\t}\n", "\t\n", "\t\treturn true;\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Check if a `<table>` node is a DataTable table already or not.\n", "\t *\n", "\t * @param {node|jquery|string} table Table node, jQuery object or jQuery\n", "\t * selector for the table to test. Note that if more than more than one\n", "\t * table is passed on, only the first will be checked\n", "\t * @returns {boolean} true the table given is a DataTable, or false otherwise\n", "\t * @static\n", "\t * @dtopt API-Static\n", "\t *\n", "\t * @example\n", "\t * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\n", "\t * $('#example').dataTable();\n", "\t * }\n", "\t */\n", "\tDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\n", "\t{\n", "\t\tvar t = $(table).get(0);\n", "\t\tvar is = false;\n", "\t\n", "\t\tif ( table instanceof DataTable.Api ) {\n", "\t\t\treturn true;\n", "\t\t}\n", "\t\n", "\t\t$.each( DataTable.settings, function (i, o) {\n", "\t\t\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\n", "\t\t\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\n", "\t\n", "\t\t\tif ( o.nTable === t || head === t || foot === t ) {\n", "\t\t\t\tis = true;\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn is;\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Get all DataTable tables that have been initialised - optionally you can\n", "\t * select to get only currently visible tables.\n", "\t *\n", "\t * @param {boolean} [visible=false] Flag to indicate if you want all (default)\n", "\t * or visible tables only.\n", "\t * @returns {array} Array of `table` nodes (not DataTable instances) which are\n", "\t * DataTables\n", "\t * @static\n", "\t * @dtopt API-Static\n", "\t *\n", "\t * @example\n", "\t * $.each( $.fn.dataTable.tables(true), function () {\n", "\t * $(table).DataTable().columns.adjust();\n", "\t * } );\n", "\t */\n", "\tDataTable.tables = DataTable.fnTables = function ( visible )\n", "\t{\n", "\t\tvar api = false;\n", "\t\n", "\t\tif ( $.isPlainObject( visible ) ) {\n", "\t\t\tapi = visible.api;\n", "\t\t\tvisible = visible.visible;\n", "\t\t}\n", "\t\n", "\t\tvar a = $.map( DataTable.settings, function (o) {\n", "\t\t\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\n", "\t\t\t\treturn o.nTable;\n", "\t\t\t}\n", "\t\t} );\n", "\t\n", "\t\treturn api ?\n", "\t\t\tnew _Api( a ) :\n", "\t\t\ta;\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Convert from camel case parameters to Hungarian notation. This is made public\n", "\t * for the extensions to provide the same ability as DataTables core to accept\n", "\t * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\n", "\t * parameters.\n", "\t *\n", "\t * @param {object} src The model object which holds all parameters that can be\n", "\t * mapped.\n", "\t * @param {object} user The object to convert from camel case to Hungarian.\n", "\t * @param {boolean} force When set to `true`, properties which already have a\n", "\t * Hungarian value in the `user` object will be overwritten. Otherwise they\n", "\t * won't be.\n", "\t */\n", "\tDataTable.camelToHungarian = _fnCamelToHungarian;\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t *\n", "\t */\n", "\t_api_register( '$()', function ( selector, opts ) {\n", "\t\tvar\n", "\t\t\trows = this.rows( opts ).nodes(), // Get all rows\n", "\t\t\tjqRows = $(rows);\n", "\t\n", "\t\treturn $( [].concat(\n", "\t\t\tjqRows.filter( selector ).toArray(),\n", "\t\t\tjqRows.find( selector ).toArray()\n", "\t\t) );\n", "\t} );\n", "\t\n", "\t\n", "\t// jQuery functions to operate on the tables\n", "\t$.each( [ 'on', 'one', 'off' ], function (i, key) {\n", "\t\t_api_register( key+'()', function ( /* event, handler */ ) {\n", "\t\t\tvar args = Array.prototype.slice.call(arguments);\n", "\t\n", "\t\t\t// Add the `dt` namespace automatically if it isn't already present\n", "\t\t\targs[0] = $.map( args[0].split( /\\s/ ), function ( e ) {\n", "\t\t\t\treturn ! e.match(/\\.dt\\b/) ?\n", "\t\t\t\t\te+'.dt' :\n", "\t\t\t\t\te;\n", "\t\t\t\t} ).join( ' ' );\n", "\t\n", "\t\t\tvar inst = $( this.tables().nodes() );\n", "\t\t\tinst[key].apply( inst, args );\n", "\t\t\treturn this;\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'clear()', function () {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\t_fnClearTable( settings );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'settings()', function () {\n", "\t\treturn new _Api( this.context, this.context );\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'init()', function () {\n", "\t\tvar ctx = this.context;\n", "\t\treturn ctx.length ? ctx[0].oInit : null;\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'data()', function () {\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\treturn _pluck( settings.aoData, '_aData' );\n", "\t\t} ).flatten();\n", "\t} );\n", "\t\n", "\t\n", "\t_api_register( 'destroy()', function ( remove ) {\n", "\t\tremove = remove || false;\n", "\t\n", "\t\treturn this.iterator( 'table', function ( settings ) {\n", "\t\t\tvar orig = settings.nTableWrapper.parentNode;\n", "\t\t\tvar classes = settings.oClasses;\n", "\t\t\tvar table = settings.nTable;\n", "\t\t\tvar tbody = settings.nTBody;\n", "\t\t\tvar thead = settings.nTHead;\n", "\t\t\tvar tfoot = settings.nTFoot;\n", "\t\t\tvar jqTable = $(table);\n", "\t\t\tvar jqTbody = $(tbody);\n", "\t\t\tvar jqWrapper = $(settings.nTableWrapper);\n", "\t\t\tvar rows = $.map( settings.aoData, function (r) { return r.nTr; } );\n", "\t\t\tvar i, ien;\n", "\t\n", "\t\t\t// Flag to note that the table is currently being destroyed - no action\n", "\t\t\t// should be taken\n", "\t\t\tsettings.bDestroying = true;\n", "\t\n", "\t\t\t// Fire off the destroy callbacks for plug-ins etc\n", "\t\t\t_fnCallbackFire( settings, \"aoDestroyCallback\", \"destroy\", [settings] );\n", "\t\n", "\t\t\t// If not being removed from the document, make all columns visible\n", "\t\t\tif ( ! remove ) {\n", "\t\t\t\tnew _Api( settings ).columns().visible( true );\n", "\t\t\t}\n", "\t\n", "\t\t\t// Blitz all `DT` namespaced events (these are internal events, the\n", "\t\t\t// lowercase, `dt` events are user subscribed and they are responsible\n", "\t\t\t// for removing them\n", "\t\t\tjqWrapper.off('.DT').find(':not(tbody *)').off('.DT');\n", "\t\t\t$(window).off('.DT-'+settings.sInstance);\n", "\t\n", "\t\t\t// When scrolling we had to break the table up - restore it\n", "\t\t\tif ( table != thead.parentNode ) {\n", "\t\t\t\tjqTable.children('thead').detach();\n", "\t\t\t\tjqTable.append( thead );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( tfoot && table != tfoot.parentNode ) {\n", "\t\t\t\tjqTable.children('tfoot').detach();\n", "\t\t\t\tjqTable.append( tfoot );\n", "\t\t\t}\n", "\t\n", "\t\t\tsettings.aaSorting = [];\n", "\t\t\tsettings.aaSortingFixed = [];\n", "\t\t\t_fnSortingClasses( settings );\n", "\t\n", "\t\t\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\n", "\t\n", "\t\t\t$('th, td', thead).removeClass( classes.sSortable+' '+\n", "\t\t\t\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\n", "\t\t\t);\n", "\t\n", "\t\t\t// Add the TR elements back into the table in their original order\n", "\t\t\tjqTbody.children().detach();\n", "\t\t\tjqTbody.append( rows );\n", "\t\n", "\t\t\t// Remove the DataTables generated nodes, events and classes\n", "\t\t\tvar removedMethod = remove ? 'remove' : 'detach';\n", "\t\t\tjqTable[ removedMethod ]();\n", "\t\t\tjqWrapper[ removedMethod ]();\n", "\t\n", "\t\t\t// If we need to reattach the table to the document\n", "\t\t\tif ( ! remove && orig ) {\n", "\t\t\t\t// insertBefore acts like appendChild if !arg[1]\n", "\t\t\t\torig.insertBefore( table, settings.nTableReinsertBefore );\n", "\t\n", "\t\t\t\t// Restore the width of the original table - was read from the style property,\n", "\t\t\t\t// so we can restore directly to that\n", "\t\t\t\tjqTable\n", "\t\t\t\t\t.css( 'width', settings.sDestroyWidth )\n", "\t\t\t\t\t.removeClass( classes.sTable );\n", "\t\n", "\t\t\t\t// If the were originally stripe classes - then we add them back here.\n", "\t\t\t\t// Note this is not fool proof (for example if not all rows had stripe\n", "\t\t\t\t// classes - but it's a good effort without getting carried away\n", "\t\t\t\tien = settings.asDestroyStripes.length;\n", "\t\n", "\t\t\t\tif ( ien ) {\n", "\t\t\t\t\tjqTbody.children().each( function (i) {\n", "\t\t\t\t\t\t$(this).addClass( settings.asDestroyStripes[i % ien] );\n", "\t\t\t\t\t} );\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\n", "\t\t\t/* Remove the settings object from the settings array */\n", "\t\t\tvar idx = $.inArray( settings, DataTable.settings );\n", "\t\t\tif ( idx !== -1 ) {\n", "\t\t\t\tDataTable.settings.splice( idx, 1 );\n", "\t\t\t}\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t// Add the `every()` method for rows, columns and cells in a compact form\n", "\t$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\n", "\t\t_api_register( type+'s().every()', function ( fn ) {\n", "\t\t\tvar opts = this.selector.opts;\n", "\t\t\tvar api = this;\n", "\t\n", "\t\t\treturn this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {\n", "\t\t\t\t// Rows and columns:\n", "\t\t\t\t// arg1 - index\n", "\t\t\t\t// arg2 - table counter\n", "\t\t\t\t// arg3 - loop counter\n", "\t\t\t\t// arg4 - undefined\n", "\t\t\t\t// Cells:\n", "\t\t\t\t// arg1 - row index\n", "\t\t\t\t// arg2 - column index\n", "\t\t\t\t// arg3 - table counter\n", "\t\t\t\t// arg4 - loop counter\n", "\t\t\t\tfn.call(\n", "\t\t\t\t\tapi[ type ](\n", "\t\t\t\t\t\targ1,\n", "\t\t\t\t\t\ttype==='cell' ? arg2 : opts,\n", "\t\t\t\t\t\ttype==='cell' ? opts : undefined\n", "\t\t\t\t\t),\n", "\t\t\t\t\targ1, arg2, arg3, arg4\n", "\t\t\t\t);\n", "\t\t\t} );\n", "\t\t} );\n", "\t} );\n", "\t\n", "\t\n", "\t// i18n method for extensions to be able to use the language object from the\n", "\t// DataTable\n", "\t_api_register( 'i18n()', function ( token, def, plural ) {\n", "\t\tvar ctx = this.context[0];\n", "\t\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\n", "\t\n", "\t\tif ( resolved === undefined ) {\n", "\t\t\tresolved = def;\n", "\t\t}\n", "\t\n", "\t\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\n", "\t\t\tresolved = resolved[ plural ] !== undefined ?\n", "\t\t\t\tresolved[ plural ] :\n", "\t\t\t\tresolved._;\n", "\t\t}\n", "\t\n", "\t\treturn resolved.replace( '%d', plural ); // nb: plural might be undefined,\n", "\t} );\n", "\t/**\n", "\t * Version string for plug-ins to check compatibility. Allowed format is\n", "\t * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\n", "\t * only for non-release builds. See http://semver.org/ for more information.\n", "\t * @member\n", "\t * @type string\n", "\t * @default Version number\n", "\t */\n", "\tDataTable.version = \"1.10.16-dev\";\n", "\n", "\t/**\n", "\t * Private data store, containing all of the settings objects that are\n", "\t * created for the tables on a given page.\n", "\t *\n", "\t * Note that the `DataTable.settings` object is aliased to\n", "\t * `jQuery.fn.dataTableExt` through which it may be accessed and\n", "\t * manipulated, or `jQuery.fn.dataTable.settings`.\n", "\t * @member\n", "\t * @type array\n", "\t * @default []\n", "\t * @private\n", "\t */\n", "\tDataTable.settings = [];\n", "\n", "\t/**\n", "\t * Object models container, for the various models that DataTables has\n", "\t * available to it. These models define the objects that are used to hold\n", "\t * the active state and configuration of the table.\n", "\t * @namespace\n", "\t */\n", "\tDataTable.models = {};\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Template object for the way in which DataTables holds information about\n", "\t * search information for the global filter and individual column filters.\n", "\t * @namespace\n", "\t */\n", "\tDataTable.models.oSearch = {\n", "\t\t/**\n", "\t\t * Flag to indicate if the filtering should be case insensitive or not\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t */\n", "\t\t\"bCaseInsensitive\": true,\n", "\t\n", "\t\t/**\n", "\t\t * Applied search term\n", "\t\t * @type string\n", "\t\t * @default <i>Empty string</i>\n", "\t\t */\n", "\t\t\"sSearch\": \"\",\n", "\t\n", "\t\t/**\n", "\t\t * Flag to indicate if the search term should be interpreted as a\n", "\t\t * regular expression (true) or not (false) and therefore and special\n", "\t\t * regex characters escaped.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t */\n", "\t\t\"bRegex\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Flag to indicate if DataTables is to use its smart filtering or not.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t */\n", "\t\t\"bSmart\": true\n", "\t};\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * Template object for the way in which DataTables holds information about\n", "\t * each individual row. This is the object format used for the settings\n", "\t * aoData array.\n", "\t * @namespace\n", "\t */\n", "\tDataTable.models.oRow = {\n", "\t\t/**\n", "\t\t * TR element for the row\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTr\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Array of TD elements for each row. This is null until the row has been\n", "\t\t * created.\n", "\t\t * @type array nodes\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"anCells\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Data object from the original data source for the row. This is either\n", "\t\t * an array if using the traditional form of DataTables, or an object if\n", "\t\t * using mData options. The exact type will depend on the passed in\n", "\t\t * data from the data source, or will be an array if using DOM a data\n", "\t\t * source.\n", "\t\t * @type array|object\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"_aData\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Sorting data cache - this array is ostensibly the same length as the\n", "\t\t * number of columns (although each index is generated only as it is\n", "\t\t * needed), and holds the data that is used for sorting each column in the\n", "\t\t * row. We do this cache generation at the start of the sort in order that\n", "\t\t * the formatting of the sort data need be done only once for each cell\n", "\t\t * per sort. This array should not be read from or written to by anything\n", "\t\t * other than the master sorting methods.\n", "\t\t * @type array\n", "\t\t * @default null\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_aSortData\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Per cell filtering data cache. As per the sort data cache, used to\n", "\t\t * increase the performance of the filtering in DataTables\n", "\t\t * @type array\n", "\t\t * @default null\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_aFilterData\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Filtering data cache. This is the same as the cell filtering cache, but\n", "\t\t * in this case a string rather than an array. This is easily computed with\n", "\t\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\n", "\t\t * needed on every search (memory traded for performance)\n", "\t\t * @type array\n", "\t\t * @default null\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_sFilterRow\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Cache of the class name that DataTables has applied to the row, so we\n", "\t\t * can quickly look at this variable rather than needing to do a DOM check\n", "\t\t * on className for the nTr property.\n", "\t\t * @type string\n", "\t\t * @default <i>Empty string</i>\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_sRowStripe\": \"\",\n", "\t\n", "\t\t/**\n", "\t\t * Denote if the original data source was from the DOM, or the data source\n", "\t\t * object. This is used for invalidating data, so DataTables can\n", "\t\t * automatically read data from the original source, unless uninstructed\n", "\t\t * otherwise.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"src\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Index in the aoData array. This saves an indexOf lookup when we have the\n", "\t\t * object, but want to know the index\n", "\t\t * @type integer\n", "\t\t * @default -1\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"idx\": -1\n", "\t};\n", "\t\n", "\t\n", "\t/**\n", "\t * Template object for the column information object in DataTables. This object\n", "\t * is held in the settings aoColumns array and contains all the information that\n", "\t * DataTables needs about each individual column.\n", "\t *\n", "\t * Note that this object is related to {@link DataTable.defaults.column}\n", "\t * but this one is the internal data store for DataTables's cache of columns.\n", "\t * It should NOT be manipulated outside of DataTables. Any configuration should\n", "\t * be done through the initialisation options.\n", "\t * @namespace\n", "\t */\n", "\tDataTable.models.oColumn = {\n", "\t\t/**\n", "\t\t * Column index. This could be worked out on-the-fly with $.inArray, but it\n", "\t\t * is faster to just hold it as a variable\n", "\t\t * @type integer\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"idx\": null,\n", "\t\n", "\t\t/**\n", "\t\t * A list of the columns that sorting should occur on when this column\n", "\t\t * is sorted. That this property is an array allows multi-column sorting\n", "\t\t * to be defined for a column (for example first name / last name columns\n", "\t\t * would benefit from this). The values are integers pointing to the\n", "\t\t * columns to be sorted on (typically it will be a single integer pointing\n", "\t\t * at itself, but that doesn't need to be the case).\n", "\t\t * @type array\n", "\t\t */\n", "\t\t\"aDataSort\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Define the sorting directions that are applied to the column, in sequence\n", "\t\t * as the column is repeatedly sorted upon - i.e. the first value is used\n", "\t\t * as the sorting direction when the column if first sorted (clicked on).\n", "\t\t * Sort it again (click again) and it will move on to the next index.\n", "\t\t * Repeat until loop.\n", "\t\t * @type array\n", "\t\t */\n", "\t\t\"asSorting\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Flag to indicate if the column is searchable, and thus should be included\n", "\t\t * in the filtering or not.\n", "\t\t * @type boolean\n", "\t\t */\n", "\t\t\"bSearchable\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Flag to indicate if the column is sortable or not.\n", "\t\t * @type boolean\n", "\t\t */\n", "\t\t\"bSortable\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Flag to indicate if the column is currently visible in the table or not\n", "\t\t * @type boolean\n", "\t\t */\n", "\t\t\"bVisible\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Store for manual type assignment using the `column.type` option. This\n", "\t\t * is held in store so we can manipulate the column's `sType` property.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_sManualType\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Flag to indicate if HTML5 data attributes should be used as the data\n", "\t\t * source for filtering or sorting. True is either are.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_bAttrSrc\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n", "\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n", "\t\t * allowing you to modify the DOM element (add background colour for example) when the\n", "\t\t * element is available.\n", "\t\t * @type function\n", "\t\t * @param {element} nTd The TD node that has been created\n", "\t\t * @param {*} sData The Data for the cell\n", "\t\t * @param {array|object} oData The data for the whole row\n", "\t\t * @param {int} iRow The row index for the aoData data store\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"fnCreatedCell\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Function to get data from a cell in a column. You should <b>never</b>\n", "\t\t * access data directly through _aData internally in DataTables - always use\n", "\t\t * the method attached to this property. It allows mData to function as\n", "\t\t * required. This function is automatically assigned by the column\n", "\t\t * initialisation method\n", "\t\t * @type function\n", "\t\t * @param {array|object} oData The data array/object for the array\n", "\t\t * (i.e. aoData[]._aData)\n", "\t\t * @param {string} sSpecific The specific data type you want to get -\n", "\t\t * 'display', 'type' 'filter' 'sort'\n", "\t\t * @returns {*} The data for the cell from the given row's data\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"fnGetData\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Function to set data for a cell in the column. You should <b>never</b>\n", "\t\t * set the data directly to _aData internally in DataTables - always use\n", "\t\t * this method. It allows mData to function as required. This function\n", "\t\t * is automatically assigned by the column initialisation method\n", "\t\t * @type function\n", "\t\t * @param {array|object} oData The data array/object for the array\n", "\t\t * (i.e. aoData[]._aData)\n", "\t\t * @param {*} sValue Value to set\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"fnSetData\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Property to read the value for the cells in the column from the data\n", "\t\t * source array / object. If null, then the default content is used, if a\n", "\t\t * function is given then the return from the function is used.\n", "\t\t * @type function|int|string|null\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"mData\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Partner property to mData which is used (only when defined) to get\n", "\t\t * the data - i.e. it is basically the same as mData, but without the\n", "\t\t * 'set' option, and also the data fed to it is the result from mData.\n", "\t\t * This is the rendering method to match the data method of mData.\n", "\t\t * @type function|int|string|null\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"mRender\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Unique header TH/TD element for this column - this is what the sorting\n", "\t\t * listener is attached to (if sorting is enabled.)\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTh\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Unique footer TH/TD element for this column (if there is one). Not used\n", "\t\t * in DataTables as such, but can be used for plug-ins to reference the\n", "\t\t * footer for each column.\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTf\": null,\n", "\t\n", "\t\t/**\n", "\t\t * The class to apply to all TD elements in the table's TBODY for the column\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sClass\": null,\n", "\t\n", "\t\t/**\n", "\t\t * When DataTables calculates the column widths to assign to each column,\n", "\t\t * it finds the longest string in each column and then constructs a\n", "\t\t * temporary table and reads the widths from that. The problem with this\n", "\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n", "\t\t * string - thus the calculation can go wrong (doing it properly and putting\n", "\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n", "\t\t * a \"work around\" we provide this option. It will append its value to the\n", "\t\t * text that is found to be the longest string for the column - i.e. padding.\n", "\t\t * @type string\n", "\t\t */\n", "\t\t\"sContentPadding\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Allows a default value to be given for a column's data, and will be used\n", "\t\t * whenever a null data source is encountered (this can be because mData\n", "\t\t * is set to null, or because the data source itself is null).\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sDefaultContent\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Name for the column, allowing reference to the column by name as well as\n", "\t\t * by index (needs a lookup to work by name).\n", "\t\t * @type string\n", "\t\t */\n", "\t\t\"sName\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Custom sorting data type - defines which of the available plug-ins in\n", "\t\t * afnSortData the custom sorting will use - if any is defined.\n", "\t\t * @type string\n", "\t\t * @default std\n", "\t\t */\n", "\t\t\"sSortDataType\": 'std',\n", "\t\n", "\t\t/**\n", "\t\t * Class to be applied to the header element when sorting on this column\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sSortingClass\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Class to be applied to the header element when sorting on this column -\n", "\t\t * when jQuery UI theming is used.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sSortingClassJUI\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Title of the column - what is seen in the TH element (nTh).\n", "\t\t * @type string\n", "\t\t */\n", "\t\t\"sTitle\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Column sorting and filtering type\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sType\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Width of the column\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sWidth\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Width of the column when it was first \"encountered\"\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sWidthOrig\": null\n", "\t};\n", "\t\n", "\t\n", "\t/*\n", "\t * Developer note: The properties of the object below are given in Hungarian\n", "\t * notation, that was used as the interface for DataTables prior to v1.10, however\n", "\t * from v1.10 onwards the primary interface is camel case. In order to avoid\n", "\t * breaking backwards compatibility utterly with this change, the Hungarian\n", "\t * version is still, internally the primary interface, but is is not documented\n", "\t * - hence the @name tags in each doc comment. This allows a Javascript function\n", "\t * to create a map from Hungarian notation to camel case (going the other direction\n", "\t * would require each property to be listed, which would at around 3K to the size\n", "\t * of DataTables, while this method is about a 0.5K hit.\n", "\t *\n", "\t * Ultimately this does pave the way for Hungarian notation to be dropped\n", "\t * completely, but that is a massive amount of work and will break current\n", "\t * installs (therefore is on-hold until v2).\n", "\t */\n", "\t\n", "\t/**\n", "\t * Initialisation options that can be given to DataTables at initialisation\n", "\t * time.\n", "\t * @namespace\n", "\t */\n", "\tDataTable.defaults = {\n", "\t\t/**\n", "\t\t * An array of data to use for the table, passed in at initialisation which\n", "\t\t * will be used in preference to any data which is already in the DOM. This is\n", "\t\t * particularly useful for constructing tables purely in Javascript, for\n", "\t\t * example with a custom Ajax call.\n", "\t\t * @type array\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.data\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using a 2D array data source\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"data\": [\n", "\t\t * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\n", "\t\t * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\n", "\t\t * ],\n", "\t\t * \"columns\": [\n", "\t\t * { \"title\": \"Engine\" },\n", "\t\t * { \"title\": \"Browser\" },\n", "\t\t * { \"title\": \"Platform\" },\n", "\t\t * { \"title\": \"Version\" },\n", "\t\t * { \"title\": \"Grade\" }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using an array of objects as a data source (`data`)\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"data\": [\n", "\t\t * {\n", "\t\t * \"engine\": \"Trident\",\n", "\t\t * \"browser\": \"Internet Explorer 4.0\",\n", "\t\t * \"platform\": \"Win 95+\",\n", "\t\t * \"version\": 4,\n", "\t\t * \"grade\": \"X\"\n", "\t\t * },\n", "\t\t * {\n", "\t\t * \"engine\": \"Trident\",\n", "\t\t * \"browser\": \"Internet Explorer 5.0\",\n", "\t\t * \"platform\": \"Win 95+\",\n", "\t\t * \"version\": 5,\n", "\t\t * \"grade\": \"C\"\n", "\t\t * }\n", "\t\t * ],\n", "\t\t * \"columns\": [\n", "\t\t * { \"title\": \"Engine\", \"data\": \"engine\" },\n", "\t\t * { \"title\": \"Browser\", \"data\": \"browser\" },\n", "\t\t * { \"title\": \"Platform\", \"data\": \"platform\" },\n", "\t\t * { \"title\": \"Version\", \"data\": \"version\" },\n", "\t\t * { \"title\": \"Grade\", \"data\": \"grade\" }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"aaData\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * If ordering is enabled, then DataTables will perform a first pass sort on\n", "\t\t * initialisation. You can define which column(s) the sort is performed\n", "\t\t * upon, and the sorting direction, with this variable. The `sorting` array\n", "\t\t * should contain an array for each column to be sorted initially containing\n", "\t\t * the column's index and a direction string ('asc' or 'desc').\n", "\t\t * @type array\n", "\t\t * @default [[0,'asc']]\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.order\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Sort by 3rd column first, and then 4th column\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"order\": [[2,'asc'], [3,'desc']]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * // No initial sorting\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"order\": []\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"aaSorting\": [[0,'asc']],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This parameter is basically identical to the `sorting` parameter, but\n", "\t\t * cannot be overridden by user interaction with the table. What this means\n", "\t\t * is that you could have a column (visible or hidden) which the sorting\n", "\t\t * will always be forced on first - any sorting after that (from the user)\n", "\t\t * will then be performed as required. This can be useful for grouping rows\n", "\t\t * together.\n", "\t\t * @type array\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.orderFixed\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"orderFixed\": [[0,'asc']]\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"aaSortingFixed\": [],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * DataTables can be instructed to load data to display in the table from a\n", "\t\t * Ajax source. This option defines how that Ajax call is made and where to.\n", "\t\t *\n", "\t\t * The `ajax` property has three different modes of operation, depending on\n", "\t\t * how it is defined. These are:\n", "\t\t *\n", "\t\t * * `string` - Set the URL from where the data should be loaded from.\n", "\t\t * * `object` - Define properties for `jQuery.ajax`.\n", "\t\t * * `function` - Custom data get function\n", "\t\t *\n", "\t\t * `string`\n", "\t\t * --------\n", "\t\t *\n", "\t\t * As a string, the `ajax` property simply defines the URL from which\n", "\t\t * DataTables will load data.\n", "\t\t *\n", "\t\t * `object`\n", "\t\t * --------\n", "\t\t *\n", "\t\t * As an object, the parameters in the object are passed to\n", "\t\t * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control\n", "\t\t * of the Ajax request. DataTables has a number of default parameters which\n", "\t\t * you can override using this option. Please refer to the jQuery\n", "\t\t * documentation for a full description of the options available, although\n", "\t\t * the following parameters provide additional options in DataTables or\n", "\t\t * require special consideration:\n", "\t\t *\n", "\t\t * * `data` - As with jQuery, `data` can be provided as an object, but it\n", "\t\t * can also be used as a function to manipulate the data DataTables sends\n", "\t\t * to the server. The function takes a single parameter, an object of\n", "\t\t * parameters with the values that DataTables has readied for sending. An\n", "\t\t * object may be returned which will be merged into the DataTables\n", "\t\t * defaults, or you can add the items to the object that was passed in and\n", "\t\t * not return anything from the function. This supersedes `fnServerParams`\n", "\t\t * from DataTables 1.9-.\n", "\t\t *\n", "\t\t * * `dataSrc` - By default DataTables will look for the property `data` (or\n", "\t\t * `aaData` for compatibility with DataTables 1.9-) when obtaining data\n", "\t\t * from an Ajax source or for server-side processing - this parameter\n", "\t\t * allows that property to be changed. You can use Javascript dotted\n", "\t\t * object notation to get a data source for multiple levels of nesting, or\n", "\t\t * it my be used as a function. As a function it takes a single parameter,\n", "\t\t * the JSON returned from the server, which can be manipulated as\n", "\t\t * required, with the returned value being that used by DataTables as the\n", "\t\t * data source for the table. This supersedes `sAjaxDataProp` from\n", "\t\t * DataTables 1.9-.\n", "\t\t *\n", "\t\t * * `success` - Should not be overridden it is used internally in\n", "\t\t * DataTables. To manipulate / transform the data returned by the server\n", "\t\t * use `ajax.dataSrc`, or use `ajax` as a function (see below).\n", "\t\t *\n", "\t\t * `function`\n", "\t\t * ----------\n", "\t\t *\n", "\t\t * As a function, making the Ajax call is left up to yourself allowing\n", "\t\t * complete control of the Ajax request. Indeed, if desired, a method other\n", "\t\t * than Ajax could be used to obtain the required data, such as Web storage\n", "\t\t * or an AIR database.\n", "\t\t *\n", "\t\t * The function is given four parameters and no return is required. The\n", "\t\t * parameters are:\n", "\t\t *\n", "\t\t * 1. _object_ - Data to send to the server\n", "\t\t * 2. _function_ - Callback function that must be executed when the required\n", "\t\t * data has been obtained. That data should be passed into the callback\n", "\t\t * as the only parameter\n", "\t\t * 3. _object_ - DataTables settings object for the table\n", "\t\t *\n", "\t\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\n", "\t\t *\n", "\t\t * @type string|object|function\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.ajax\n", "\t\t * @since 1.10.0\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Get JSON data from a file via Ajax.\n", "\t\t * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": \"data.json\"\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Get JSON data from a file via Ajax, using `dataSrc` to change\n", "\t\t * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": {\n", "\t\t * \"url\": \"data.json\",\n", "\t\t * \"dataSrc\": \"tableData\"\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Get JSON data from a file via Ajax, using `dataSrc` to read data\n", "\t\t * // from a plain array rather than an array in an object\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": {\n", "\t\t * \"url\": \"data.json\",\n", "\t\t * \"dataSrc\": \"\"\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Manipulate the data returned from the server - add a link to data\n", "\t\t * // (note this can, should, be done using `render` for the column - this\n", "\t\t * // is just a simple example of how the data can be manipulated).\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": {\n", "\t\t * \"url\": \"data.json\",\n", "\t\t * \"dataSrc\": function ( json ) {\n", "\t\t * for ( var i=0, ien=json.length ; i<ien ; i++ ) {\n", "\t\t * json[i][0] = '<a href=\"/message/'+json[i][0]+'>View message</a>';\n", "\t\t * }\n", "\t\t * return json;\n", "\t\t * }\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Add data to the request\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": {\n", "\t\t * \"url\": \"data.json\",\n", "\t\t * \"data\": function ( d ) {\n", "\t\t * return {\n", "\t\t * \"extra_search\": $('#extra').val()\n", "\t\t * };\n", "\t\t * }\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Send request as POST\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": {\n", "\t\t * \"url\": \"data.json\",\n", "\t\t * \"type\": \"POST\"\n", "\t\t * }\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Get the data from localStorage (could interface with a form for\n", "\t\t * // adding, editing and removing rows).\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": function (data, callback, settings) {\n", "\t\t * callback(\n", "\t\t * JSON.parse( localStorage.getItem('dataTablesData') )\n", "\t\t * );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"ajax\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This parameter allows you to readily specify the entries in the length drop\n", "\t\t * down menu that DataTables shows when pagination is enabled. It can be\n", "\t\t * either a 1D array of options which will be used for both the displayed\n", "\t\t * option and the value, or a 2D array which will use the array in the first\n", "\t\t * position as the value, and the array in the second position as the\n", "\t\t * displayed options (useful for language strings such as 'All').\n", "\t\t *\n", "\t\t * Note that the `pageLength` property will be automatically set to the\n", "\t\t * first value given in this array, unless `pageLength` is also provided.\n", "\t\t * @type array\n", "\t\t * @default [ 10, 25, 50, 100 ]\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.lengthMenu\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"lengthMenu\": [[10, 25, 50, -1], [10, 25, 50, \"All\"]]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"aLengthMenu\": [ 10, 25, 50, 100 ],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * The `columns` option in the initialisation parameter allows you to define\n", "\t\t * details about the way individual columns behave. For a full list of\n", "\t\t * column options that can be set, please see\n", "\t\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\n", "\t\t * define your columns, you must have an entry in the array for every single\n", "\t\t * column that you have in your table (these can be null if you don't which\n", "\t\t * to specify any options).\n", "\t\t * @member\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column\n", "\t\t */\n", "\t\t\"aoColumns\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Very similar to `columns`, `columnDefs` allows you to target a specific\n", "\t\t * column, multiple columns, or all columns, using the `targets` property of\n", "\t\t * each object in the array. This allows great flexibility when creating\n", "\t\t * tables, as the `columnDefs` arrays can be of any length, targeting the\n", "\t\t * columns you specifically want. `columnDefs` may use any of the column\n", "\t\t * options available: {@link DataTable.defaults.column}, but it _must_\n", "\t\t * have `targets` defined in each object in the array. Values in the `targets`\n", "\t\t * array may be:\n", "\t\t * <ul>\n", "\t\t * <li>a string - class name will be matched on the TH for the column</li>\n", "\t\t * <li>0 or a positive integer - column index counting from the left</li>\n", "\t\t * <li>a negative integer - column index counting from the right</li>\n", "\t\t * <li>the string \"_all\" - all columns (i.e. assign a default)</li>\n", "\t\t * </ul>\n", "\t\t * @member\n", "\t\t *\n", "\t\t * @name DataTable.defaults.columnDefs\n", "\t\t */\n", "\t\t\"aoColumnDefs\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Basically the same as `search`, this parameter defines the individual column\n", "\t\t * filtering state at initialisation time. The array must be of the same size\n", "\t\t * as the number of columns, and each element be an object with the parameters\n", "\t\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\n", "\t\t * accepted and the default will be used.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.searchCols\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"searchCols\": [\n", "\t\t * null,\n", "\t\t * { \"search\": \"My filter\" },\n", "\t\t * null,\n", "\t\t * { \"search\": \"^[0-9]\", \"escapeRegex\": false }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"aoSearchCols\": [],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * An array of CSS classes that should be applied to displayed rows. This\n", "\t\t * array may be of any length, and DataTables will apply each class\n", "\t\t * sequentially, looping when required.\n", "\t\t * @type array\n", "\t\t * @default null <i>Will take the values determined by the `oClasses.stripe*`\n", "\t\t * options</i>\n", "\t\t *\n", "\t\t * @dtopt Option\n", "\t\t * @name DataTable.defaults.stripeClasses\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stripeClasses\": [ 'strip1', 'strip2', 'strip3' ]\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"asStripeClasses\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable automatic column width calculation. This can be disabled\n", "\t\t * as an optimisation (it takes some time to calculate the widths) if the\n", "\t\t * tables widths are passed in using `columns`.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.autoWidth\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"autoWidth\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bAutoWidth\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Deferred rendering can provide DataTables with a huge speed boost when you\n", "\t\t * are using an Ajax or JS data source for the table. This option, when set to\n", "\t\t * true, will cause DataTables to defer the creation of the table elements for\n", "\t\t * each row until they are needed for a draw - saving a significant amount of\n", "\t\t * time.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.deferRender\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajax\": \"sources/arrays.txt\",\n", "\t\t * \"deferRender\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bDeferRender\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Replace a DataTable which matches the given selector and replace it with\n", "\t\t * one which has the properties of the new initialisation object passed. If no\n", "\t\t * table matches the selector, then the new DataTable will be constructed as\n", "\t\t * per normal.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.destroy\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"srollY\": \"200px\",\n", "\t\t * \"paginate\": false\n", "\t\t * } );\n", "\t\t *\n", "\t\t * // Some time later....\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"filter\": false,\n", "\t\t * \"destroy\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bDestroy\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable filtering of data. Filtering in DataTables is \"smart\" in\n", "\t\t * that it allows the end user to input multiple words (space separated) and\n", "\t\t * will match a row containing those words, even if not in the order that was\n", "\t\t * specified (this allow matching across multiple columns). Note that if you\n", "\t\t * wish to use filtering in DataTables this must remain 'true' - to remove the\n", "\t\t * default filtering input box and retain filtering abilities, please use\n", "\t\t * {@link DataTable.defaults.dom}.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.searching\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"searching\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bFilter\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable the table information display. This shows information\n", "\t\t * about the data that is currently visible on the page, including information\n", "\t\t * about filtered data if that action is being performed.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.info\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"info\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bInfo\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Allows the end user to select the size of a formatted page from a select\n", "\t\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.lengthChange\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"lengthChange\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bLengthChange\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable pagination.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.paging\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"paging\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bPaginate\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable the display of a 'processing' indicator when the table is\n", "\t\t * being processed (e.g. a sort). This is particularly useful for tables with\n", "\t\t * large amounts of data where it can take a noticeable amount of time to sort\n", "\t\t * the entries.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.processing\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"processing\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bProcessing\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Retrieve the DataTables object for the given selector. Note that if the\n", "\t\t * table has already been initialised, this parameter will cause DataTables\n", "\t\t * to simply return the object that has already been set up - it will not take\n", "\t\t * account of any changes you might have made to the initialisation object\n", "\t\t * passed to DataTables (setting this parameter to true is an acknowledgement\n", "\t\t * that you understand this). `destroy` can be used to reinitialise a table if\n", "\t\t * you need.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.retrieve\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * initTable();\n", "\t\t * tableActions();\n", "\t\t * } );\n", "\t\t *\n", "\t\t * function initTable ()\n", "\t\t * {\n", "\t\t * return $('#example').dataTable( {\n", "\t\t * \"scrollY\": \"200px\",\n", "\t\t * \"paginate\": false,\n", "\t\t * \"retrieve\": true\n", "\t\t * } );\n", "\t\t * }\n", "\t\t *\n", "\t\t * function tableActions ()\n", "\t\t * {\n", "\t\t * var table = initTable();\n", "\t\t * // perform API operations with oTable\n", "\t\t * }\n", "\t\t */\n", "\t\t\"bRetrieve\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * When vertical (y) scrolling is enabled, DataTables will force the height of\n", "\t\t * the table's viewport to the given height at all times (useful for layout).\n", "\t\t * However, this can look odd when filtering data down to a small data set,\n", "\t\t * and the footer is left \"floating\" further down. This parameter (when\n", "\t\t * enabled) will cause DataTables to collapse the table's viewport down when\n", "\t\t * the result set will fit within the given Y height.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.scrollCollapse\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"scrollY\": \"200\",\n", "\t\t * \"scrollCollapse\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bScrollCollapse\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Configure DataTables to use server-side processing. Note that the\n", "\t\t * `ajax` parameter must also be given in order to give DataTables a\n", "\t\t * source to obtain the required data for each draw.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @dtopt Server-side\n", "\t\t * @name DataTable.defaults.serverSide\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"serverSide\": true,\n", "\t\t * \"ajax\": \"xhr.php\"\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bServerSide\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable sorting of columns. Sorting of individual columns can be\n", "\t\t * disabled by the `sortable` option for each column.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.ordering\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ordering\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bSort\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or display DataTables' ability to sort multiple columns at the\n", "\t\t * same time (activated by shift-click by the user).\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.orderMulti\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Disable multiple column sorting ability\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"orderMulti\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bSortMulti\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Allows control over whether DataTables should use the top (true) unique\n", "\t\t * cell that is found for a single column, or the bottom (false - default).\n", "\t\t * This is useful when using complex headers.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.orderCellsTop\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"orderCellsTop\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bSortCellsTop\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable the addition of the classes `sorting\\_1`, `sorting\\_2` and\n", "\t\t * `sorting\\_3` to the columns which are currently being sorted on. This is\n", "\t\t * presented as a feature switch as it can increase processing time (while\n", "\t\t * classes are removed and added) so for large data sets you might want to\n", "\t\t * turn this off.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.orderClasses\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"orderClasses\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bSortClasses\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\n", "\t\t * used to save table display information such as pagination information,\n", "\t\t * display length, filtering and sorting. As such when the end user reloads\n", "\t\t * the page the display display will match what thy had previously set up.\n", "\t\t *\n", "\t\t * Due to the use of `localStorage` the default state saving is not supported\n", "\t\t * in IE6 or 7. If state saving is required in those browsers, use\n", "\t\t * `stateSaveCallback` to provide a storage solution such as cookies.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.stateSave\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function () {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bStateSave\": false,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This function is called when a TR element is created (and all TD child\n", "\t\t * elements have been inserted), or registered if using a DOM source, allowing\n", "\t\t * manipulation of the TR element (adding classes etc).\n", "\t\t * @type function\n", "\t\t * @param {node} row \"TR\" element for the current row\n", "\t\t * @param {array} data Raw data array for this row\n", "\t\t * @param {int} dataIndex The index of this row in the internal aoData array\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.createdRow\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"createdRow\": function( row, data, dataIndex ) {\n", "\t\t * // Bold the grade for all 'A' grade browsers\n", "\t\t * if ( data[4] == \"A\" )\n", "\t\t * {\n", "\t\t * $('td:eq(4)', row).html( '<b>A</b>' );\n", "\t\t * }\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnCreatedRow\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This function is called on every 'draw' event, and allows you to\n", "\t\t * dynamically modify any aspect you want about the created DOM.\n", "\t\t * @type function\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.drawCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"drawCallback\": function( settings ) {\n", "\t\t * alert( 'DataTables has redrawn the table' );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnDrawCallback\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Identical to fnHeaderCallback() but for the table footer this function\n", "\t\t * allows you to modify the table footer on every 'draw' event.\n", "\t\t * @type function\n", "\t\t * @param {node} foot \"TR\" element for the footer\n", "\t\t * @param {array} data Full table data (as derived from the original HTML)\n", "\t\t * @param {int} start Index for the current display starting point in the\n", "\t\t * display array\n", "\t\t * @param {int} end Index for the current display ending point in the\n", "\t\t * display array\n", "\t\t * @param {array int} display Index array to translate the visual position\n", "\t\t * to the full data array\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.footerCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"footerCallback\": function( tfoot, data, start, end, display ) {\n", "\t\t * tfoot.getElementsByTagName('th')[0].innerHTML = \"Starting index is \"+start;\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"fnFooterCallback\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * When rendering large numbers in the information element for the table\n", "\t\t * (i.e. \"Showing 1 to 10 of 57 entries\") DataTables will render large numbers\n", "\t\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\n", "\t\t * rendered as \"1,000,000\") to help readability for the end user. This\n", "\t\t * function will override the default method DataTables uses.\n", "\t\t * @type function\n", "\t\t * @member\n", "\t\t * @param {int} toFormat number to be formatted\n", "\t\t * @returns {string} formatted string for DataTables to show the number\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.formatNumber\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Format a number using a single quote for the separator (note that\n", "\t\t * // this can also be done with the language.thousands option)\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"formatNumber\": function ( toFormat ) {\n", "\t\t * return toFormat.toString().replace(\n", "\t\t * /\\B(?=(\\d{3})+(?!\\d))/g, \"'\"\n", "\t\t * );\n", "\t\t * };\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnFormatNumber\": function ( toFormat ) {\n", "\t\t\treturn toFormat.toString().replace(\n", "\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g,\n", "\t\t\t\tthis.oLanguage.sThousands\n", "\t\t\t);\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This function is called on every 'draw' event, and allows you to\n", "\t\t * dynamically modify the header row. This can be used to calculate and\n", "\t\t * display useful information about the table.\n", "\t\t * @type function\n", "\t\t * @param {node} head \"TR\" element for the header\n", "\t\t * @param {array} data Full table data (as derived from the original HTML)\n", "\t\t * @param {int} start Index for the current display starting point in the\n", "\t\t * display array\n", "\t\t * @param {int} end Index for the current display ending point in the\n", "\t\t * display array\n", "\t\t * @param {array int} display Index array to translate the visual position\n", "\t\t * to the full data array\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.headerCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"fheaderCallback\": function( head, data, start, end, display ) {\n", "\t\t * head.getElementsByTagName('th')[0].innerHTML = \"Displaying \"+(end-start)+\" records\";\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"fnHeaderCallback\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * The information element can be used to convey information about the current\n", "\t\t * state of the table. Although the internationalisation options presented by\n", "\t\t * DataTables are quite capable of dealing with most customisations, there may\n", "\t\t * be times where you wish to customise the string further. This callback\n", "\t\t * allows you to do exactly that.\n", "\t\t * @type function\n", "\t\t * @param {object} oSettings DataTables settings object\n", "\t\t * @param {int} start Starting position in data for the draw\n", "\t\t * @param {int} end End position in data for the draw\n", "\t\t * @param {int} max Total number of rows in the table (regardless of\n", "\t\t * filtering)\n", "\t\t * @param {int} total Total number of rows in the data set, after filtering\n", "\t\t * @param {string} pre The string that DataTables has formatted using it's\n", "\t\t * own rules\n", "\t\t * @returns {string} The string to be displayed in the information element.\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.infoCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"infoCallback\": function( settings, start, end, max, total, pre ) {\n", "\t\t * return start +\" to \"+ end;\n", "\t\t * }\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnInfoCallback\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Called when the table has been initialised. Normally DataTables will\n", "\t\t * initialise sequentially and there will be no need for this function,\n", "\t\t * however, this does not hold true when using external language information\n", "\t\t * since that is obtained using an async XHR call.\n", "\t\t * @type function\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @param {object} json The JSON object request from the server - only\n", "\t\t * present if client-side Ajax sourced data is used\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.initComplete\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"initComplete\": function(settings, json) {\n", "\t\t * alert( 'DataTables has finished its initialisation.' );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"fnInitComplete\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Called at the very start of each table draw and can be used to cancel the\n", "\t\t * draw by returning false, any other return (including undefined) results in\n", "\t\t * the full draw occurring).\n", "\t\t * @type function\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @returns {boolean} False will cancel the draw, anything else (including no\n", "\t\t * return) will allow it to complete.\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.preDrawCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"preDrawCallback\": function( settings ) {\n", "\t\t * if ( $('#test').val() == 1 ) {\n", "\t\t * return false;\n", "\t\t * }\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnPreDrawCallback\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This function allows you to 'post process' each row after it have been\n", "\t\t * generated for each table draw, but before it is rendered on screen. This\n", "\t\t * function might be used for setting the row class name etc.\n", "\t\t * @type function\n", "\t\t * @param {node} row \"TR\" element for the current row\n", "\t\t * @param {array} data Raw data array for this row\n", "\t\t * @param {int} displayIndex The display index for the current table draw\n", "\t\t * @param {int} displayIndexFull The index of the data in the full list of\n", "\t\t * rows (after filtering)\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.rowCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"rowCallback\": function( row, data, displayIndex, displayIndexFull ) {\n", "\t\t * // Bold the grade for all 'A' grade browsers\n", "\t\t * if ( data[4] == \"A\" ) {\n", "\t\t * $('td:eq(4)', row).html( '<b>A</b>' );\n", "\t\t * }\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnRowCallback\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * __Deprecated__ The functionality provided by this parameter has now been\n", "\t\t * superseded by that provided through `ajax`, which should be used instead.\n", "\t\t *\n", "\t\t * This parameter allows you to override the default function which obtains\n", "\t\t * the data from the server so something more suitable for your application.\n", "\t\t * For example you could use POST data, or pull information from a Gears or\n", "\t\t * AIR database.\n", "\t\t * @type function\n", "\t\t * @member\n", "\t\t * @param {string} source HTTP source to obtain the data from (`ajax`)\n", "\t\t * @param {array} data A key/value pair object containing the data to send\n", "\t\t * to the server\n", "\t\t * @param {function} callback to be called on completion of the data get\n", "\t\t * process that will draw the data on the page.\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @dtopt Server-side\n", "\t\t * @name DataTable.defaults.serverData\n", "\t\t *\n", "\t\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n", "\t\t */\n", "\t\t\"fnServerData\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * __Deprecated__ The functionality provided by this parameter has now been\n", "\t\t * superseded by that provided through `ajax`, which should be used instead.\n", "\t\t *\n", "\t\t * It is often useful to send extra data to the server when making an Ajax\n", "\t\t * request - for example custom filtering information, and this callback\n", "\t\t * function makes it trivial to send extra information to the server. The\n", "\t\t * passed in parameter is the data set that has been constructed by\n", "\t\t * DataTables, and you can add to this or modify it as you require.\n", "\t\t * @type function\n", "\t\t * @param {array} data Data array (array of objects which are name/value\n", "\t\t * pairs) that has been constructed by DataTables and will be sent to the\n", "\t\t * server. In the case of Ajax sourced data with server-side processing\n", "\t\t * this will be an empty array, for server-side processing there will be a\n", "\t\t * significant number of parameters!\n", "\t\t * @returns {undefined} Ensure that you modify the data array passed in,\n", "\t\t * as this is passed by reference.\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @dtopt Server-side\n", "\t\t * @name DataTable.defaults.serverParams\n", "\t\t *\n", "\t\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n", "\t\t */\n", "\t\t\"fnServerParams\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Load the table state. With this function you can define from where, and how, the\n", "\t\t * state of a table is loaded. By default DataTables will load from `localStorage`\n", "\t\t * but you might wish to use a server-side database or cookies.\n", "\t\t * @type function\n", "\t\t * @member\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @param {object} callback Callback that can be executed when done. It\n", "\t\t * should be passed the loaded state object.\n", "\t\t * @return {object} The DataTables state object to be loaded\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.stateLoadCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true,\n", "\t\t * \"stateLoadCallback\": function (settings, callback) {\n", "\t\t * $.ajax( {\n", "\t\t * \"url\": \"/state_load\",\n", "\t\t * \"dataType\": \"json\",\n", "\t\t * \"success\": function (json) {\n", "\t\t * callback( json );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnStateLoadCallback\": function ( settings ) {\n", "\t\t\ttry {\n", "\t\t\t\treturn JSON.parse(\n", "\t\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\n", "\t\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname\n", "\t\t\t\t\t)\n", "\t\t\t\t);\n", "\t\t\t} catch (e) {}\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Callback which allows modification of the saved state prior to loading that state.\n", "\t\t * This callback is called when the table is loading state from the stored data, but\n", "\t\t * prior to the settings object being modified by the saved state. Note that for\n", "\t\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\n", "\t\t * a plug-in.\n", "\t\t * @type function\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @param {object} data The state object that is to be loaded\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.stateLoadParams\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Remove a saved filter, so filtering is never loaded\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true,\n", "\t\t * \"stateLoadParams\": function (settings, data) {\n", "\t\t * data.oSearch.sSearch = \"\";\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Disallow state loading by returning false\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true,\n", "\t\t * \"stateLoadParams\": function (settings, data) {\n", "\t\t * return false;\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnStateLoadParams\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Callback that is called when the state has been loaded from the state saving method\n", "\t\t * and the DataTables settings object has been modified as a result of the loaded state.\n", "\t\t * @type function\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @param {object} data The state object that was loaded\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.stateLoaded\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Show an alert with the filtering value that was saved\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true,\n", "\t\t * \"stateLoaded\": function (settings, data) {\n", "\t\t * alert( 'Saved filter was: '+data.oSearch.sSearch );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnStateLoaded\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Save the table state. This function allows you to define where and how the state\n", "\t\t * information for the table is stored By default DataTables will use `localStorage`\n", "\t\t * but you might wish to use a server-side database or cookies.\n", "\t\t * @type function\n", "\t\t * @member\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @param {object} data The state object to be saved\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.stateSaveCallback\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true,\n", "\t\t * \"stateSaveCallback\": function (settings, data) {\n", "\t\t * // Send an Ajax request to the server with the state object\n", "\t\t * $.ajax( {\n", "\t\t * \"url\": \"/state_save\",\n", "\t\t * \"data\": data,\n", "\t\t * \"dataType\": \"json\",\n", "\t\t * \"method\": \"POST\"\n", "\t\t * \"success\": function () {}\n", "\t\t * } );\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnStateSaveCallback\": function ( settings, data ) {\n", "\t\t\ttry {\n", "\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\n", "\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname,\n", "\t\t\t\t\tJSON.stringify( data )\n", "\t\t\t\t);\n", "\t\t\t} catch (e) {}\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Callback which allows modification of the state to be saved. Called when the table\n", "\t\t * has changed state a new state save is required. This method allows modification of\n", "\t\t * the state saving object prior to actually doing the save, including addition or\n", "\t\t * other state properties or modification. Note that for plug-in authors, you should\n", "\t\t * use the `stateSaveParams` event to save parameters for a plug-in.\n", "\t\t * @type function\n", "\t\t * @param {object} settings DataTables settings object\n", "\t\t * @param {object} data The state object to be saved\n", "\t\t *\n", "\t\t * @dtopt Callbacks\n", "\t\t * @name DataTable.defaults.stateSaveParams\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Remove a saved filter, so filtering is never saved\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateSave\": true,\n", "\t\t * \"stateSaveParams\": function (settings, data) {\n", "\t\t * data.oSearch.sSearch = \"\";\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnStateSaveParams\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Duration for which the saved state information is considered valid. After this period\n", "\t\t * has elapsed the state will be returned to the default.\n", "\t\t * Value is given in seconds.\n", "\t\t * @type int\n", "\t\t * @default 7200 <i>(2 hours)</i>\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.stateDuration\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"stateDuration\": 60*60*24; // 1 day\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"iStateDuration\": 7200,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * When enabled DataTables will not make a request to the server for the first\n", "\t\t * page draw - rather it will use the data already on the page (no sorting etc\n", "\t\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\n", "\t\t * is used to indicate that deferred loading is required, but it is also used\n", "\t\t * to tell DataTables how many records there are in the full table (allowing\n", "\t\t * the information element and pagination to be displayed correctly). In the case\n", "\t\t * where a filtering is applied to the table on initial load, this can be\n", "\t\t * indicated by giving the parameter as an array, where the first element is\n", "\t\t * the number of records available after filtering and the second element is the\n", "\t\t * number of records without filtering (allowing the table information element\n", "\t\t * to be shown correctly).\n", "\t\t * @type int | array\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.deferLoading\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // 57 records available in the table, no filtering applied\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"serverSide\": true,\n", "\t\t * \"ajax\": \"scripts/server_processing.php\",\n", "\t\t * \"deferLoading\": 57\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // 57 records after filtering, 100 without filtering (an initial filter applied)\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"serverSide\": true,\n", "\t\t * \"ajax\": \"scripts/server_processing.php\",\n", "\t\t * \"deferLoading\": [ 57, 100 ],\n", "\t\t * \"search\": {\n", "\t\t * \"search\": \"my_filter\"\n", "\t\t * }\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"iDeferLoading\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Number of rows to display on a single page when using pagination. If\n", "\t\t * feature enabled (`lengthChange`) then the end user will be able to override\n", "\t\t * this to a custom setting using a pop-up menu.\n", "\t\t * @type int\n", "\t\t * @default 10\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.pageLength\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"pageLength\": 50\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"iDisplayLength\": 10,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Define the starting point for data display when using DataTables with\n", "\t\t * pagination. Note that this parameter is the number of records, rather than\n", "\t\t * the page number, so if you have 10 records per page and want to start on\n", "\t\t * the third page, it should be \"20\".\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.displayStart\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"displayStart\": 20\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"iDisplayStart\": 0,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\n", "\t\t * and filtering) by adding a `tabindex` attribute to the required elements. This\n", "\t\t * allows you to tab through the controls and press the enter key to activate them.\n", "\t\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\n", "\t\t * You can overrule this using this parameter if you wish. Use a value of -1 to\n", "\t\t * disable built-in keyboard navigation.\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.tabIndex\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"tabIndex\": 1\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"iTabIndex\": 0,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Classes that DataTables assigns to the various components and features\n", "\t\t * that it adds to the HTML table. This allows classes to be configured\n", "\t\t * during initialisation in addition to through the static\n", "\t\t * {@link DataTable.ext.oStdClasses} object).\n", "\t\t * @namespace\n", "\t\t * @name DataTable.defaults.classes\n", "\t\t */\n", "\t\t\"oClasses\": {},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * All strings that DataTables uses in the user interface that it creates\n", "\t\t * are defined in this object, allowing you to modified them individually or\n", "\t\t * completely replace them all as required.\n", "\t\t * @namespace\n", "\t\t * @name DataTable.defaults.language\n", "\t\t */\n", "\t\t\"oLanguage\": {\n", "\t\t\t/**\n", "\t\t\t * Strings that are used for WAI-ARIA labels and controls only (these are not\n", "\t\t\t * actually visible on the page, but will be read by screenreaders, and thus\n", "\t\t\t * must be internationalised as well).\n", "\t\t\t * @namespace\n", "\t\t\t * @name DataTable.defaults.language.aria\n", "\t\t\t */\n", "\t\t\t\"oAria\": {\n", "\t\t\t\t/**\n", "\t\t\t\t * ARIA label that is added to the table headers when the column may be\n", "\t\t\t\t * sorted ascending by activing the column (click or return when focused).\n", "\t\t\t\t * Note that the column header is prefixed to this string.\n", "\t\t\t\t * @type string\n", "\t\t\t\t * @default : activate to sort column ascending\n", "\t\t\t\t *\n", "\t\t\t\t * @dtopt Language\n", "\t\t\t\t * @name DataTable.defaults.language.aria.sortAscending\n", "\t\t\t\t *\n", "\t\t\t\t * @example\n", "\t\t\t\t * $(document).ready( function() {\n", "\t\t\t\t * $('#example').dataTable( {\n", "\t\t\t\t * \"language\": {\n", "\t\t\t\t * \"aria\": {\n", "\t\t\t\t * \"sortAscending\": \" - click/return to sort ascending\"\n", "\t\t\t\t * }\n", "\t\t\t\t * }\n", "\t\t\t\t * } );\n", "\t\t\t\t * } );\n", "\t\t\t\t */\n", "\t\t\t\t\"sSortAscending\": \": activate to sort column ascending\",\n", "\t\n", "\t\t\t\t/**\n", "\t\t\t\t * ARIA label that is added to the table headers when the column may be\n", "\t\t\t\t * sorted descending by activing the column (click or return when focused).\n", "\t\t\t\t * Note that the column header is prefixed to this string.\n", "\t\t\t\t * @type string\n", "\t\t\t\t * @default : activate to sort column ascending\n", "\t\t\t\t *\n", "\t\t\t\t * @dtopt Language\n", "\t\t\t\t * @name DataTable.defaults.language.aria.sortDescending\n", "\t\t\t\t *\n", "\t\t\t\t * @example\n", "\t\t\t\t * $(document).ready( function() {\n", "\t\t\t\t * $('#example').dataTable( {\n", "\t\t\t\t * \"language\": {\n", "\t\t\t\t * \"aria\": {\n", "\t\t\t\t * \"sortDescending\": \" - click/return to sort descending\"\n", "\t\t\t\t * }\n", "\t\t\t\t * }\n", "\t\t\t\t * } );\n", "\t\t\t\t * } );\n", "\t\t\t\t */\n", "\t\t\t\t\"sSortDescending\": \": activate to sort column descending\"\n", "\t\t\t},\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Pagination string used by DataTables for the built-in pagination\n", "\t\t\t * control types.\n", "\t\t\t * @namespace\n", "\t\t\t * @name DataTable.defaults.language.paginate\n", "\t\t\t */\n", "\t\t\t\"oPaginate\": {\n", "\t\t\t\t/**\n", "\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n", "\t\t\t\t * button to take the user to the first page.\n", "\t\t\t\t * @type string\n", "\t\t\t\t * @default First\n", "\t\t\t\t *\n", "\t\t\t\t * @dtopt Language\n", "\t\t\t\t * @name DataTable.defaults.language.paginate.first\n", "\t\t\t\t *\n", "\t\t\t\t * @example\n", "\t\t\t\t * $(document).ready( function() {\n", "\t\t\t\t * $('#example').dataTable( {\n", "\t\t\t\t * \"language\": {\n", "\t\t\t\t * \"paginate\": {\n", "\t\t\t\t * \"first\": \"First page\"\n", "\t\t\t\t * }\n", "\t\t\t\t * }\n", "\t\t\t\t * } );\n", "\t\t\t\t * } );\n", "\t\t\t\t */\n", "\t\t\t\t\"sFirst\": \"First\",\n", "\t\n", "\t\n", "\t\t\t\t/**\n", "\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n", "\t\t\t\t * button to take the user to the last page.\n", "\t\t\t\t * @type string\n", "\t\t\t\t * @default Last\n", "\t\t\t\t *\n", "\t\t\t\t * @dtopt Language\n", "\t\t\t\t * @name DataTable.defaults.language.paginate.last\n", "\t\t\t\t *\n", "\t\t\t\t * @example\n", "\t\t\t\t * $(document).ready( function() {\n", "\t\t\t\t * $('#example').dataTable( {\n", "\t\t\t\t * \"language\": {\n", "\t\t\t\t * \"paginate\": {\n", "\t\t\t\t * \"last\": \"Last page\"\n", "\t\t\t\t * }\n", "\t\t\t\t * }\n", "\t\t\t\t * } );\n", "\t\t\t\t * } );\n", "\t\t\t\t */\n", "\t\t\t\t\"sLast\": \"Last\",\n", "\t\n", "\t\n", "\t\t\t\t/**\n", "\t\t\t\t * Text to use for the 'next' pagination button (to take the user to the\n", "\t\t\t\t * next page).\n", "\t\t\t\t * @type string\n", "\t\t\t\t * @default Next\n", "\t\t\t\t *\n", "\t\t\t\t * @dtopt Language\n", "\t\t\t\t * @name DataTable.defaults.language.paginate.next\n", "\t\t\t\t *\n", "\t\t\t\t * @example\n", "\t\t\t\t * $(document).ready( function() {\n", "\t\t\t\t * $('#example').dataTable( {\n", "\t\t\t\t * \"language\": {\n", "\t\t\t\t * \"paginate\": {\n", "\t\t\t\t * \"next\": \"Next page\"\n", "\t\t\t\t * }\n", "\t\t\t\t * }\n", "\t\t\t\t * } );\n", "\t\t\t\t * } );\n", "\t\t\t\t */\n", "\t\t\t\t\"sNext\": \"Next\",\n", "\t\n", "\t\n", "\t\t\t\t/**\n", "\t\t\t\t * Text to use for the 'previous' pagination button (to take the user to\n", "\t\t\t\t * the previous page).\n", "\t\t\t\t * @type string\n", "\t\t\t\t * @default Previous\n", "\t\t\t\t *\n", "\t\t\t\t * @dtopt Language\n", "\t\t\t\t * @name DataTable.defaults.language.paginate.previous\n", "\t\t\t\t *\n", "\t\t\t\t * @example\n", "\t\t\t\t * $(document).ready( function() {\n", "\t\t\t\t * $('#example').dataTable( {\n", "\t\t\t\t * \"language\": {\n", "\t\t\t\t * \"paginate\": {\n", "\t\t\t\t * \"previous\": \"Previous page\"\n", "\t\t\t\t * }\n", "\t\t\t\t * }\n", "\t\t\t\t * } );\n", "\t\t\t\t * } );\n", "\t\t\t\t */\n", "\t\t\t\t\"sPrevious\": \"Previous\"\n", "\t\t\t},\n", "\t\n", "\t\t\t/**\n", "\t\t\t * This string is shown in preference to `zeroRecords` when the table is\n", "\t\t\t * empty of data (regardless of filtering). Note that this is an optional\n", "\t\t\t * parameter - if it is not given, the value of `zeroRecords` will be used\n", "\t\t\t * instead (either the default or given value).\n", "\t\t\t * @type string\n", "\t\t\t * @default No data available in table\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.emptyTable\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"emptyTable\": \"No data available in table\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sEmptyTable\": \"No data available in table\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * This string gives information to the end user about the information\n", "\t\t\t * that is current on display on the page. The following tokens can be\n", "\t\t\t * used in the string and will be dynamically replaced as the table\n", "\t\t\t * display updates. This tokens can be placed anywhere in the string, or\n", "\t\t\t * removed as needed by the language requires:\n", "\t\t\t *\n", "\t\t\t * * `\\_START\\_` - Display index of the first record on the current page\n", "\t\t\t * * `\\_END\\_` - Display index of the last record on the current page\n", "\t\t\t * * `\\_TOTAL\\_` - Number of records in the table after filtering\n", "\t\t\t * * `\\_MAX\\_` - Number of records in the table without filtering\n", "\t\t\t * * `\\_PAGE\\_` - Current page number\n", "\t\t\t * * `\\_PAGES\\_` - Total number of pages of data in the table\n", "\t\t\t *\n", "\t\t\t * @type string\n", "\t\t\t * @default Showing _START_ to _END_ of _TOTAL_ entries\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.info\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"info\": \"Showing page _PAGE_ of _PAGES_\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sInfo\": \"Showing _START_ to _END_ of _TOTAL_ entries\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Display information string for when the table is empty. Typically the\n", "\t\t\t * format of this string should match `info`.\n", "\t\t\t * @type string\n", "\t\t\t * @default Showing 0 to 0 of 0 entries\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.infoEmpty\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"infoEmpty\": \"No entries to show\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sInfoEmpty\": \"Showing 0 to 0 of 0 entries\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * When a user filters the information in a table, this string is appended\n", "\t\t\t * to the information (`info`) to give an idea of how strong the filtering\n", "\t\t\t * is. The variable _MAX_ is dynamically updated.\n", "\t\t\t * @type string\n", "\t\t\t * @default (filtered from _MAX_ total entries)\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.infoFiltered\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"infoFiltered\": \" - filtering from _MAX_ records\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sInfoFiltered\": \"(filtered from _MAX_ total entries)\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * If can be useful to append extra information to the info string at times,\n", "\t\t\t * and this variable does exactly that. This information will be appended to\n", "\t\t\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\n", "\t\t\t * being used) at all times.\n", "\t\t\t * @type string\n", "\t\t\t * @default <i>Empty string</i>\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.infoPostFix\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"infoPostFix\": \"All records shown are derived from real information.\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sInfoPostFix\": \"\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * This decimal place operator is a little different from the other\n", "\t\t\t * language options since DataTables doesn't output floating point\n", "\t\t\t * numbers, so it won't ever use this for display of a number. Rather,\n", "\t\t\t * what this parameter does is modify the sort methods of the table so\n", "\t\t\t * that numbers which are in a format which has a character other than\n", "\t\t\t * a period (`.`) as a decimal place will be sorted numerically.\n", "\t\t\t *\n", "\t\t\t * Note that numbers with different decimal places cannot be shown in\n", "\t\t\t * the same table and still be sortable, the table must be consistent.\n", "\t\t\t * However, multiple different tables on the page can use different\n", "\t\t\t * decimal place characters.\n", "\t\t\t * @type string\n", "\t\t\t * @default \n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.decimal\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"decimal\": \",\"\n", "\t\t\t * \"thousands\": \".\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sDecimal\": \"\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * DataTables has a build in number formatter (`formatNumber`) which is\n", "\t\t\t * used to format large numbers that are used in the table information.\n", "\t\t\t * By default a comma is used, but this can be trivially changed to any\n", "\t\t\t * character you wish with this parameter.\n", "\t\t\t * @type string\n", "\t\t\t * @default ,\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.thousands\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"thousands\": \"'\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sThousands\": \",\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Detail the action that will be taken when the drop down menu for the\n", "\t\t\t * pagination length option is changed. The '_MENU_' variable is replaced\n", "\t\t\t * with a default select list of 10, 25, 50 and 100, and can be replaced\n", "\t\t\t * with a custom select box if required.\n", "\t\t\t * @type string\n", "\t\t\t * @default Show _MENU_ entries\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.lengthMenu\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Language change only\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"lengthMenu\": \"Display _MENU_ records\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Language and options change\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"lengthMenu\": 'Display <select>'+\n", "\t\t\t * '<option value=\"10\">10</option>'+\n", "\t\t\t * '<option value=\"20\">20</option>'+\n", "\t\t\t * '<option value=\"30\">30</option>'+\n", "\t\t\t * '<option value=\"40\">40</option>'+\n", "\t\t\t * '<option value=\"50\">50</option>'+\n", "\t\t\t * '<option value=\"-1\">All</option>'+\n", "\t\t\t * '</select> records'\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sLengthMenu\": \"Show _MENU_ entries\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * When using Ajax sourced data and during the first draw when DataTables is\n", "\t\t\t * gathering the data, this message is shown in an empty row in the table to\n", "\t\t\t * indicate to the end user the the data is being loaded. Note that this\n", "\t\t\t * parameter is not used when loading data by server-side processing, just\n", "\t\t\t * Ajax sourced data with client-side processing.\n", "\t\t\t * @type string\n", "\t\t\t * @default Loading...\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.loadingRecords\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"loadingRecords\": \"Please wait - loading...\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sLoadingRecords\": \"Loading...\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Text which is displayed when the table is processing a user action\n", "\t\t\t * (usually a sort command or similar).\n", "\t\t\t * @type string\n", "\t\t\t * @default Processing...\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.processing\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"processing\": \"DataTables is currently busy\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sProcessing\": \"Processing...\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Details the actions that will be taken when the user types into the\n", "\t\t\t * filtering input text box. The variable \"_INPUT_\", if used in the string,\n", "\t\t\t * is replaced with the HTML text box for the filtering input allowing\n", "\t\t\t * control over where it appears in the string. If \"_INPUT_\" is not given\n", "\t\t\t * then the input box is appended to the string automatically.\n", "\t\t\t * @type string\n", "\t\t\t * @default Search:\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.search\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Input text box will be appended at the end automatically\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"search\": \"Filter records:\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Specify where the filter should appear\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"search\": \"Apply filter _INPUT_ to table\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sSearch\": \"Search:\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Assign a `placeholder` attribute to the search `input` element\n", "\t\t\t * @type string\n", "\t\t\t * @default \n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.searchPlaceholder\n", "\t\t\t */\n", "\t\t\t\"sSearchPlaceholder\": \"\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * All of the language information can be stored in a file on the\n", "\t\t\t * server-side, which DataTables will look up if this parameter is passed.\n", "\t\t\t * It must store the URL of the language file, which is in a JSON format,\n", "\t\t\t * and the object has the same properties as the oLanguage object in the\n", "\t\t\t * initialiser object (i.e. the above parameters). Please refer to one of\n", "\t\t\t * the example language files to see how this works in action.\n", "\t\t\t * @type string\n", "\t\t\t * @default <i>Empty string - i.e. disabled</i>\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.url\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"url\": \"http://www.sprymedia.co.uk/dataTables/lang.txt\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sUrl\": \"\",\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Text shown inside the table records when the is no information to be\n", "\t\t\t * displayed after filtering. `emptyTable` is shown when there is simply no\n", "\t\t\t * information in the table at all (regardless of filtering).\n", "\t\t\t * @type string\n", "\t\t\t * @default No matching records found\n", "\t\t\t *\n", "\t\t\t * @dtopt Language\n", "\t\t\t * @name DataTable.defaults.language.zeroRecords\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $(document).ready( function() {\n", "\t\t\t * $('#example').dataTable( {\n", "\t\t\t * \"language\": {\n", "\t\t\t * \"zeroRecords\": \"No records to display\"\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\t\"sZeroRecords\": \"No matching records found\"\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This parameter allows you to have define the global filtering state at\n", "\t\t * initialisation time. As an object the `search` parameter must be\n", "\t\t * defined, but all other parameters are optional. When `regex` is true,\n", "\t\t * the search string will be treated as a regular expression, when false\n", "\t\t * (default) it will be treated as a straight string. When `smart`\n", "\t\t * DataTables will use it's smart filtering methods (to word match at\n", "\t\t * any point in the data), when false this will not be done.\n", "\t\t * @namespace\n", "\t\t * @extends DataTable.models.oSearch\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.search\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"search\": {\"search\": \"Initial search\"}\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"oSearch\": $.extend( {}, DataTable.models.oSearch ),\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * __Deprecated__ The functionality provided by this parameter has now been\n", "\t\t * superseded by that provided through `ajax`, which should be used instead.\n", "\t\t *\n", "\t\t * By default DataTables will look for the property `data` (or `aaData` for\n", "\t\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\n", "\t\t * source or for server-side processing - this parameter allows that\n", "\t\t * property to be changed. You can use Javascript dotted object notation to\n", "\t\t * get a data source for multiple levels of nesting.\n", "\t\t * @type string\n", "\t\t * @default data\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @dtopt Server-side\n", "\t\t * @name DataTable.defaults.ajaxDataProp\n", "\t\t *\n", "\t\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n", "\t\t */\n", "\t\t\"sAjaxDataProp\": \"data\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * __Deprecated__ The functionality provided by this parameter has now been\n", "\t\t * superseded by that provided through `ajax`, which should be used instead.\n", "\t\t *\n", "\t\t * You can instruct DataTables to load data from an external\n", "\t\t * source using this parameter (use aData if you want to pass data in you\n", "\t\t * already have). Simply provide a url a JSON object can be obtained from.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @dtopt Server-side\n", "\t\t * @name DataTable.defaults.ajaxSource\n", "\t\t *\n", "\t\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n", "\t\t */\n", "\t\t\"sAjaxSource\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This initialisation variable allows you to specify exactly where in the\n", "\t\t * DOM you want DataTables to inject the various controls it adds to the page\n", "\t\t * (for example you might want the pagination controls at the top of the\n", "\t\t * table). DIV elements (with or without a custom class) can also be added to\n", "\t\t * aid styling. The follow syntax is used:\n", "\t\t * <ul>\n", "\t\t * <li>The following options are allowed:\n", "\t\t * <ul>\n", "\t\t * <li>'l' - Length changing</li>\n", "\t\t * <li>'f' - Filtering input</li>\n", "\t\t * <li>'t' - The table!</li>\n", "\t\t * <li>'i' - Information</li>\n", "\t\t * <li>'p' - Pagination</li>\n", "\t\t * <li>'r' - pRocessing</li>\n", "\t\t * </ul>\n", "\t\t * </li>\n", "\t\t * <li>The following constants are allowed:\n", "\t\t * <ul>\n", "\t\t * <li>'H' - jQueryUI theme \"header\" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>\n", "\t\t * <li>'F' - jQueryUI theme \"footer\" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>\n", "\t\t * </ul>\n", "\t\t * </li>\n", "\t\t * <li>The following syntax is expected:\n", "\t\t * <ul>\n", "\t\t * <li>'<' and '>' - div elements</li>\n", "\t\t * <li>'<\"class\" and '>' - div with a class</li>\n", "\t\t * <li>'<\"#id\" and '>' - div with an ID</li>\n", "\t\t * </ul>\n", "\t\t * </li>\n", "\t\t * <li>Examples:\n", "\t\t * <ul>\n", "\t\t * <li>'<\"wrapper\"flipt>'</li>\n", "\t\t * <li>'<lf<t>ip>'</li>\n", "\t\t * </ul>\n", "\t\t * </li>\n", "\t\t * </ul>\n", "\t\t * @type string\n", "\t\t * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>\n", "\t\t * <\"H\"lfr>t<\"F\"ip> <i>(when `jQueryUI` is true)</i>\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.dom\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"dom\": '<\"top\"i>rt<\"bottom\"flp><\"clear\">'\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sDom\": \"lfrtip\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Search delay option. This will throttle full table searches that use the\n", "\t\t * DataTables provided search input element (it does not effect calls to\n", "\t\t * `dt-api search()`, providing a delay before the search is made.\n", "\t\t * @type integer\n", "\t\t * @default 0\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.searchDelay\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"searchDelay\": 200\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"searchDelay\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * DataTables features six different built-in options for the buttons to\n", "\t\t * display for pagination control:\n", "\t\t *\n", "\t\t * * `numbers` - Page number buttons only\n", "\t\t * * `simple` - 'Previous' and 'Next' buttons only\n", "\t\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\n", "\t\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\n", "\t\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers\n", "\t\t * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers\n", "\t\t * \n", "\t\t * Further methods can be added using {@link DataTable.ext.oPagination}.\n", "\t\t * @type string\n", "\t\t * @default simple_numbers\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.pagingType\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"pagingType\": \"full_numbers\"\n", "\t\t * } );\n", "\t\t * } )\n", "\t\t */\n", "\t\t\"sPaginationType\": \"simple_numbers\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable horizontal scrolling. When a table is too wide to fit into a\n", "\t\t * certain layout, or you have a large number of columns in the table, you\n", "\t\t * can enable x-scrolling to show the table in a viewport, which can be\n", "\t\t * scrolled. This property can be `true` which will allow the table to\n", "\t\t * scroll horizontally when needed, or any CSS unit, or a number (in which\n", "\t\t * case it will be treated as a pixel measurement). Setting as simply `true`\n", "\t\t * is recommended.\n", "\t\t * @type boolean|string\n", "\t\t * @default <i>blank string - i.e. disabled</i>\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.scrollX\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"scrollX\": true,\n", "\t\t * \"scrollCollapse\": true\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sScrollX\": \"\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This property can be used to force a DataTable to use more width than it\n", "\t\t * might otherwise do when x-scrolling is enabled. For example if you have a\n", "\t\t * table which requires to be well spaced, this parameter is useful for\n", "\t\t * \"over-sizing\" the table, and thus forcing scrolling. This property can by\n", "\t\t * any CSS unit, or a number (in which case it will be treated as a pixel\n", "\t\t * measurement).\n", "\t\t * @type string\n", "\t\t * @default <i>blank string - i.e. disabled</i>\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @name DataTable.defaults.scrollXInner\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"scrollX\": \"100%\",\n", "\t\t * \"scrollXInner\": \"110%\"\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sScrollXInner\": \"\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\n", "\t\t * to the given height, and enable scrolling for any data which overflows the\n", "\t\t * current viewport. This can be used as an alternative to paging to display\n", "\t\t * a lot of data in a small area (although paging and scrolling can both be\n", "\t\t * enabled at the same time). This property can be any CSS unit, or a number\n", "\t\t * (in which case it will be treated as a pixel measurement).\n", "\t\t * @type string\n", "\t\t * @default <i>blank string - i.e. disabled</i>\n", "\t\t *\n", "\t\t * @dtopt Features\n", "\t\t * @name DataTable.defaults.scrollY\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"scrollY\": \"200px\",\n", "\t\t * \"paginate\": false\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sScrollY\": \"\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * __Deprecated__ The functionality provided by this parameter has now been\n", "\t\t * superseded by that provided through `ajax`, which should be used instead.\n", "\t\t *\n", "\t\t * Set the HTTP method that is used to make the Ajax call for server-side\n", "\t\t * processing or Ajax sourced data.\n", "\t\t * @type string\n", "\t\t * @default GET\n", "\t\t *\n", "\t\t * @dtopt Options\n", "\t\t * @dtopt Server-side\n", "\t\t * @name DataTable.defaults.serverMethod\n", "\t\t *\n", "\t\t * @deprecated 1.10. Please use `ajax` for this functionality now.\n", "\t\t */\n", "\t\t\"sServerMethod\": \"GET\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * DataTables makes use of renderers when displaying HTML elements for\n", "\t\t * a table. These renderers can be added or modified by plug-ins to\n", "\t\t * generate suitable mark-up for a site. For example the Bootstrap\n", "\t\t * integration plug-in for DataTables uses a paging button renderer to\n", "\t\t * display pagination buttons in the mark-up required by Bootstrap.\n", "\t\t *\n", "\t\t * For further information about the renderers available see\n", "\t\t * DataTable.ext.renderer\n", "\t\t * @type string|object\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @name DataTable.defaults.renderer\n", "\t\t *\n", "\t\t */\n", "\t\t\"renderer\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Set the data property name that DataTables should use to get a row's id\n", "\t\t * to set as the `id` property in the node.\n", "\t\t * @type string\n", "\t\t * @default DT_RowId\n", "\t\t *\n", "\t\t * @name DataTable.defaults.rowId\n", "\t\t */\n", "\t\t\"rowId\": \"DT_RowId\"\n", "\t};\n", "\t\n", "\t_fnHungarianMap( DataTable.defaults );\n", "\t\n", "\t\n", "\t\n", "\t/*\n", "\t * Developer note - See note in model.defaults.js about the use of Hungarian\n", "\t * notation and camel case.\n", "\t */\n", "\t\n", "\t/**\n", "\t * Column options that can be given to DataTables at initialisation time.\n", "\t * @namespace\n", "\t */\n", "\tDataTable.defaults.column = {\n", "\t\t/**\n", "\t\t * Define which column(s) an order will occur on for this column. This\n", "\t\t * allows a column's ordering to take multiple columns into account when\n", "\t\t * doing a sort or use the data from a different column. For example first\n", "\t\t * name / last name columns make sense to do a multi-column sort over the\n", "\t\t * two columns.\n", "\t\t * @type array|int\n", "\t\t * @default null <i>Takes the value of the column index automatically</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.orderData\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"orderData\": [ 0, 1 ], \"targets\": [ 0 ] },\n", "\t\t * { \"orderData\": [ 1, 0 ], \"targets\": [ 1 ] },\n", "\t\t * { \"orderData\": 2, \"targets\": [ 2 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"orderData\": [ 0, 1 ] },\n", "\t\t * { \"orderData\": [ 1, 0 ] },\n", "\t\t * { \"orderData\": 2 },\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"aDataSort\": null,\n", "\t\t\"iDataSort\": -1,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * You can control the default ordering direction, and even alter the\n", "\t\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\n", "\t\t * using this parameter.\n", "\t\t * @type array\n", "\t\t * @default [ 'asc', 'desc' ]\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.orderSequence\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"orderSequence\": [ \"asc\" ], \"targets\": [ 1 ] },\n", "\t\t * { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ], \"targets\": [ 2 ] },\n", "\t\t * { \"orderSequence\": [ \"desc\" ], \"targets\": [ 3 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * null,\n", "\t\t * { \"orderSequence\": [ \"asc\" ] },\n", "\t\t * { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ] },\n", "\t\t * { \"orderSequence\": [ \"desc\" ] },\n", "\t\t * null\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"asSorting\": [ 'asc', 'desc' ],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable filtering on the data in this column.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.searchable\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"searchable\": false, \"targets\": [ 0 ] }\n", "\t\t * ] } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"searchable\": false },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ] } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bSearchable\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable ordering on this column.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.orderable\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"orderable\": false, \"targets\": [ 0 ] }\n", "\t\t * ] } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"orderable\": false },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ] } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bSortable\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Enable or disable the display of this column.\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.visible\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"visible\": false, \"targets\": [ 0 ] }\n", "\t\t * ] } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"visible\": false },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ] } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"bVisible\": true,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n", "\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n", "\t\t * allowing you to modify the DOM element (add background colour for example) when the\n", "\t\t * element is available.\n", "\t\t * @type function\n", "\t\t * @param {element} td The TD node that has been created\n", "\t\t * @param {*} cellData The Data for the cell\n", "\t\t * @param {array|object} rowData The data for the whole row\n", "\t\t * @param {int} row The row index for the aoData data store\n", "\t\t * @param {int} col The column index for aoColumns\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.createdCell\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [3],\n", "\t\t * \"createdCell\": function (td, cellData, rowData, row, col) {\n", "\t\t * if ( cellData == \"1.7\" ) {\n", "\t\t * $(td).css('color', 'blue')\n", "\t\t * }\n", "\t\t * }\n", "\t\t * } ]\n", "\t\t * });\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"fnCreatedCell\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This parameter has been replaced by `data` in DataTables to ensure naming\n", "\t\t * consistency. `dataProp` can still be used, as there is backwards\n", "\t\t * compatibility in DataTables for this option, but it is strongly\n", "\t\t * recommended that you use `data` in preference to `dataProp`.\n", "\t\t * @name DataTable.defaults.column.dataProp\n", "\t\t */\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This property can be used to read data from any data source property,\n", "\t\t * including deeply nested objects / properties. `data` can be given in a\n", "\t\t * number of different ways which effect its behaviour:\n", "\t\t *\n", "\t\t * * `integer` - treated as an array index for the data source. This is the\n", "\t\t * default that DataTables uses (incrementally increased for each column).\n", "\t\t * * `string` - read an object property from the data source. There are\n", "\t\t * three 'special' options that can be used in the string to alter how\n", "\t\t * DataTables reads the data from the source object:\n", "\t\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\n", "\t\t * Javascript to read from nested objects, so to can the options\n", "\t\t * specified in `data`. For example: `browser.version` or\n", "\t\t * `browser.name`. If your object parameter name contains a period, use\n", "\t\t * `\\\\` to escape it - i.e. `first\\\\.name`.\n", "\t\t * * `[]` - Array notation. DataTables can automatically combine data\n", "\t\t * from and array source, joining the data with the characters provided\n", "\t\t * between the two brackets. For example: `name[, ]` would provide a\n", "\t\t * comma-space separated list from the source array. If no characters\n", "\t\t * are provided between the brackets, the original array source is\n", "\t\t * returned.\n", "\t\t * * `()` - Function notation. Adding `()` to the end of a parameter will\n", "\t\t * execute a function of the name given. For example: `browser()` for a\n", "\t\t * simple function on the data source, `browser.version()` for a\n", "\t\t * function in a nested property or even `browser().version` to get an\n", "\t\t * object property if the function called returns an object. Note that\n", "\t\t * function notation is recommended for use in `render` rather than\n", "\t\t * `data` as it is much simpler to use as a renderer.\n", "\t\t * * `null` - use the original data source for the row rather than plucking\n", "\t\t * data directly from it. This action has effects on two other\n", "\t\t * initialisation options:\n", "\t\t * * `defaultContent` - When null is given as the `data` option and\n", "\t\t * `defaultContent` is specified for the column, the value defined by\n", "\t\t * `defaultContent` will be used for the cell.\n", "\t\t * * `render` - When null is used for the `data` option and the `render`\n", "\t\t * option is specified for the column, the whole data source for the\n", "\t\t * row is used for the renderer.\n", "\t\t * * `function` - the function given will be executed whenever DataTables\n", "\t\t * needs to set or get the data for a cell in the column. The function\n", "\t\t * takes three parameters:\n", "\t\t * * Parameters:\n", "\t\t * * `{array|object}` The data source for the row\n", "\t\t * * `{string}` The type call data requested - this will be 'set' when\n", "\t\t * setting data or 'filter', 'display', 'type', 'sort' or undefined\n", "\t\t * when gathering data. Note that when `undefined` is given for the\n", "\t\t * type DataTables expects to get the raw data for the object back<\n", "\t\t * * `{*}` Data to set when the second parameter is 'set'.\n", "\t\t * * Return:\n", "\t\t * * The return value from the function is not required when 'set' is\n", "\t\t * the type of call, but otherwise the return is what will be used\n", "\t\t * for the data requested.\n", "\t\t *\n", "\t\t * Note that `data` is a getter and setter option. If you just require\n", "\t\t * formatting of data for output, you will likely want to use `render` which\n", "\t\t * is simply a getter and thus simpler to use.\n", "\t\t *\n", "\t\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\n", "\t\t * name change reflects the flexibility of this property and is consistent\n", "\t\t * with the naming of mRender. If 'mDataProp' is given, then it will still\n", "\t\t * be used by DataTables, as it automatically maps the old name to the new\n", "\t\t * if required.\n", "\t\t *\n", "\t\t * @type string|int|function|null\n", "\t\t * @default null <i>Use automatically calculated column index</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.data\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Read table data from objects\n", "\t\t * // JSON structure for each row:\n", "\t\t * // {\n", "\t\t * // \"engine\": {value},\n", "\t\t * // \"browser\": {value},\n", "\t\t * // \"platform\": {value},\n", "\t\t * // \"version\": {value},\n", "\t\t * // \"grade\": {value}\n", "\t\t * // }\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajaxSource\": \"sources/objects.txt\",\n", "\t\t * \"columns\": [\n", "\t\t * { \"data\": \"engine\" },\n", "\t\t * { \"data\": \"browser\" },\n", "\t\t * { \"data\": \"platform\" },\n", "\t\t * { \"data\": \"version\" },\n", "\t\t * { \"data\": \"grade\" }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Read information from deeply nested objects\n", "\t\t * // JSON structure for each row:\n", "\t\t * // {\n", "\t\t * // \"engine\": {value},\n", "\t\t * // \"browser\": {value},\n", "\t\t * // \"platform\": {\n", "\t\t * // \"inner\": {value}\n", "\t\t * // },\n", "\t\t * // \"details\": [\n", "\t\t * // {value}, {value}\n", "\t\t * // ]\n", "\t\t * // }\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajaxSource\": \"sources/deep.txt\",\n", "\t\t * \"columns\": [\n", "\t\t * { \"data\": \"engine\" },\n", "\t\t * { \"data\": \"browser\" },\n", "\t\t * { \"data\": \"platform.inner\" },\n", "\t\t * { \"data\": \"platform.details.0\" },\n", "\t\t * { \"data\": \"platform.details.1\" }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `data` as a function to provide different information for\n", "\t\t * // sorting, filtering and display. In this case, currency (price)\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"data\": function ( source, type, val ) {\n", "\t\t * if (type === 'set') {\n", "\t\t * source.price = val;\n", "\t\t * // Store the computed dislay and filter values for efficiency\n", "\t\t * source.price_display = val==\"\" ? \"\" : \"$\"+numberFormat(val);\n", "\t\t * source.price_filter = val==\"\" ? \"\" : \"$\"+numberFormat(val)+\" \"+val;\n", "\t\t * return;\n", "\t\t * }\n", "\t\t * else if (type === 'display') {\n", "\t\t * return source.price_display;\n", "\t\t * }\n", "\t\t * else if (type === 'filter') {\n", "\t\t * return source.price_filter;\n", "\t\t * }\n", "\t\t * // 'sort', 'type' and undefined all just use the integer\n", "\t\t * return source.price;\n", "\t\t * }\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using default content\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"data\": null,\n", "\t\t * \"defaultContent\": \"Click to edit\"\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using array notation - outputting a list from an array\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"data\": \"name[, ]\"\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t */\n", "\t\t\"mData\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This property is the rendering partner to `data` and it is suggested that\n", "\t\t * when you want to manipulate data for display (including filtering,\n", "\t\t * sorting etc) without altering the underlying data for the table, use this\n", "\t\t * property. `render` can be considered to be the the read only companion to\n", "\t\t * `data` which is read / write (then as such more complex). Like `data`\n", "\t\t * this option can be given in a number of different ways to effect its\n", "\t\t * behaviour:\n", "\t\t *\n", "\t\t * * `integer` - treated as an array index for the data source. This is the\n", "\t\t * default that DataTables uses (incrementally increased for each column).\n", "\t\t * * `string` - read an object property from the data source. There are\n", "\t\t * three 'special' options that can be used in the string to alter how\n", "\t\t * DataTables reads the data from the source object:\n", "\t\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\n", "\t\t * Javascript to read from nested objects, so to can the options\n", "\t\t * specified in `data`. For example: `browser.version` or\n", "\t\t * `browser.name`. If your object parameter name contains a period, use\n", "\t\t * `\\\\` to escape it - i.e. `first\\\\.name`.\n", "\t\t * * `[]` - Array notation. DataTables can automatically combine data\n", "\t\t * from and array source, joining the data with the characters provided\n", "\t\t * between the two brackets. For example: `name[, ]` would provide a\n", "\t\t * comma-space separated list from the source array. If no characters\n", "\t\t * are provided between the brackets, the original array source is\n", "\t\t * returned.\n", "\t\t * * `()` - Function notation. Adding `()` to the end of a parameter will\n", "\t\t * execute a function of the name given. For example: `browser()` for a\n", "\t\t * simple function on the data source, `browser.version()` for a\n", "\t\t * function in a nested property or even `browser().version` to get an\n", "\t\t * object property if the function called returns an object.\n", "\t\t * * `object` - use different data for the different data types requested by\n", "\t\t * DataTables ('filter', 'display', 'type' or 'sort'). The property names\n", "\t\t * of the object is the data type the property refers to and the value can\n", "\t\t * defined using an integer, string or function using the same rules as\n", "\t\t * `render` normally does. Note that an `_` option _must_ be specified.\n", "\t\t * This is the default value to use if you haven't specified a value for\n", "\t\t * the data type requested by DataTables.\n", "\t\t * * `function` - the function given will be executed whenever DataTables\n", "\t\t * needs to set or get the data for a cell in the column. The function\n", "\t\t * takes three parameters:\n", "\t\t * * Parameters:\n", "\t\t * * {array|object} The data source for the row (based on `data`)\n", "\t\t * * {string} The type call data requested - this will be 'filter',\n", "\t\t * 'display', 'type' or 'sort'.\n", "\t\t * * {array|object} The full data source for the row (not based on\n", "\t\t * `data`)\n", "\t\t * * Return:\n", "\t\t * * The return value from the function is what will be used for the\n", "\t\t * data requested.\n", "\t\t *\n", "\t\t * @type string|int|function|object|null\n", "\t\t * @default null Use the data source value.\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.render\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Create a comma separated list from an array of objects\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"ajaxSource\": \"sources/deep.txt\",\n", "\t\t * \"columns\": [\n", "\t\t * { \"data\": \"engine\" },\n", "\t\t * { \"data\": \"browser\" },\n", "\t\t * {\n", "\t\t * \"data\": \"platform\",\n", "\t\t * \"render\": \"[, ].name\"\n", "\t\t * }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Execute a function to obtain data\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"data\": null, // Use the full data source object for the renderer's source\n", "\t\t * \"render\": \"browserName()\"\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // As an object, extracting different data for the different types\n", "\t\t * // This would be used with a data source such as:\n", "\t\t * // { \"phone\": 5552368, \"phone_filter\": \"5552368 555-2368\", \"phone_display\": \"555-2368\" }\n", "\t\t * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\n", "\t\t * // (which has both forms) is used for filtering for if a user inputs either format, while\n", "\t\t * // the formatted phone number is the one that is shown in the table.\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"data\": null, // Use the full data source object for the renderer's source\n", "\t\t * \"render\": {\n", "\t\t * \"_\": \"phone\",\n", "\t\t * \"filter\": \"phone_filter\",\n", "\t\t * \"display\": \"phone_display\"\n", "\t\t * }\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Use as a function to create a link from the data source\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"data\": \"download_link\",\n", "\t\t * \"render\": function ( data, type, full ) {\n", "\t\t * return '<a href=\"'+data+'\">Download</a>';\n", "\t\t * }\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"mRender\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Change the cell type created for the column - either TD cells or TH cells. This\n", "\t\t * can be useful as TH cells have semantic meaning in the table body, allowing them\n", "\t\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\n", "\t\t * @type string\n", "\t\t * @default td\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.cellType\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Make the first column use TH cells\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [ {\n", "\t\t * \"targets\": [ 0 ],\n", "\t\t * \"cellType\": \"th\"\n", "\t\t * } ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sCellType\": \"td\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Class to give to each cell in this column.\n", "\t\t * @type string\n", "\t\t * @default <i>Empty string</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.class\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"class\": \"my_class\", \"targets\": [ 0 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"class\": \"my_class\" },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sClass\": \"\",\n", "\t\n", "\t\t/**\n", "\t\t * When DataTables calculates the column widths to assign to each column,\n", "\t\t * it finds the longest string in each column and then constructs a\n", "\t\t * temporary table and reads the widths from that. The problem with this\n", "\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n", "\t\t * string - thus the calculation can go wrong (doing it properly and putting\n", "\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n", "\t\t * a \"work around\" we provide this option. It will append its value to the\n", "\t\t * text that is found to be the longest string for the column - i.e. padding.\n", "\t\t * Generally you shouldn't need this!\n", "\t\t * @type string\n", "\t\t * @default <i>Empty string<i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.contentPadding\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * {\n", "\t\t * \"contentPadding\": \"mmm\"\n", "\t\t * }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sContentPadding\": \"\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Allows a default value to be given for a column's data, and will be used\n", "\t\t * whenever a null data source is encountered (this can be because `data`\n", "\t\t * is set to null, or because the data source itself is null).\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.defaultContent\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * {\n", "\t\t * \"data\": null,\n", "\t\t * \"defaultContent\": \"Edit\",\n", "\t\t * \"targets\": [ -1 ]\n", "\t\t * }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * {\n", "\t\t * \"data\": null,\n", "\t\t * \"defaultContent\": \"Edit\"\n", "\t\t * }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sDefaultContent\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * This parameter is only used in DataTables' server-side processing. It can\n", "\t\t * be exceptionally useful to know what columns are being displayed on the\n", "\t\t * client side, and to map these to database fields. When defined, the names\n", "\t\t * also allow DataTables to reorder information from the server if it comes\n", "\t\t * back in an unexpected order (i.e. if you switch your columns around on the\n", "\t\t * client-side, your server-side code does not also need updating).\n", "\t\t * @type string\n", "\t\t * @default <i>Empty string</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.name\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"name\": \"engine\", \"targets\": [ 0 ] },\n", "\t\t * { \"name\": \"browser\", \"targets\": [ 1 ] },\n", "\t\t * { \"name\": \"platform\", \"targets\": [ 2 ] },\n", "\t\t * { \"name\": \"version\", \"targets\": [ 3 ] },\n", "\t\t * { \"name\": \"grade\", \"targets\": [ 4 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"name\": \"engine\" },\n", "\t\t * { \"name\": \"browser\" },\n", "\t\t * { \"name\": \"platform\" },\n", "\t\t * { \"name\": \"version\" },\n", "\t\t * { \"name\": \"grade\" }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sName\": \"\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Defines a data source type for the ordering which can be used to read\n", "\t\t * real-time information from the table (updating the internally cached\n", "\t\t * version) prior to ordering. This allows ordering to occur on user\n", "\t\t * editable elements such as form inputs.\n", "\t\t * @type string\n", "\t\t * @default std\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.orderDataType\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"orderDataType\": \"dom-text\", \"targets\": [ 2, 3 ] },\n", "\t\t * { \"type\": \"numeric\", \"targets\": [ 3 ] },\n", "\t\t * { \"orderDataType\": \"dom-select\", \"targets\": [ 4 ] },\n", "\t\t * { \"orderDataType\": \"dom-checkbox\", \"targets\": [ 5 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * { \"orderDataType\": \"dom-text\" },\n", "\t\t * { \"orderDataType\": \"dom-text\", \"type\": \"numeric\" },\n", "\t\t * { \"orderDataType\": \"dom-select\" },\n", "\t\t * { \"orderDataType\": \"dom-checkbox\" }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sSortDataType\": \"std\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * The title of this column.\n", "\t\t * @type string\n", "\t\t * @default null <i>Derived from the 'TH' value for this column in the\n", "\t\t * original HTML table.</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.title\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"title\": \"My column title\", \"targets\": [ 0 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"title\": \"My column title\" },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sTitle\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * The type allows you to specify how the data for this column will be\n", "\t\t * ordered. Four types (string, numeric, date and html (which will strip\n", "\t\t * HTML tags before ordering)) are currently available. Note that only date\n", "\t\t * formats understood by Javascript's Date() object will be accepted as type\n", "\t\t * date. For example: \"Mar 26, 2008 5:03 PM\". May take the values: 'string',\n", "\t\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\n", "\t\t * through plug-ins.\n", "\t\t * @type string\n", "\t\t * @default null <i>Auto-detected from raw data</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.type\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"type\": \"html\", \"targets\": [ 0 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"type\": \"html\" },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sType\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Defining the width of the column, this parameter may take any CSS value\n", "\t\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\n", "\t\t * been given a specific width through this interface ensuring that the table\n", "\t\t * remains readable.\n", "\t\t * @type string\n", "\t\t * @default null <i>Automatic</i>\n", "\t\t *\n", "\t\t * @name DataTable.defaults.column.width\n", "\t\t * @dtopt Columns\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columnDefs`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columnDefs\": [\n", "\t\t * { \"width\": \"20%\", \"targets\": [ 0 ] }\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Using `columns`\n", "\t\t * $(document).ready( function() {\n", "\t\t * $('#example').dataTable( {\n", "\t\t * \"columns\": [\n", "\t\t * { \"width\": \"20%\" },\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null,\n", "\t\t * null\n", "\t\t * ]\n", "\t\t * } );\n", "\t\t * } );\n", "\t\t */\n", "\t\t\"sWidth\": null\n", "\t};\n", "\t\n", "\t_fnHungarianMap( DataTable.defaults.column );\n", "\t\n", "\t\n", "\t\n", "\t/**\n", "\t * DataTables settings object - this holds all the information needed for a\n", "\t * given table, including configuration, data and current application of the\n", "\t * table options. DataTables does not have a single instance for each DataTable\n", "\t * with the settings attached to that instance, but rather instances of the\n", "\t * DataTable \"class\" are created on-the-fly as needed (typically by a\n", "\t * $().dataTable() call) and the settings object is then applied to that\n", "\t * instance.\n", "\t *\n", "\t * Note that this object is related to {@link DataTable.defaults} but this\n", "\t * one is the internal data store for DataTables's cache of columns. It should\n", "\t * NOT be manipulated outside of DataTables. Any configuration should be done\n", "\t * through the initialisation options.\n", "\t * @namespace\n", "\t * @todo Really should attach the settings object to individual instances so we\n", "\t * don't need to create new instances on each $().dataTable() call (if the\n", "\t * table already exists). It would also save passing oSettings around and\n", "\t * into every single function. However, this is a very significant\n", "\t * architecture change for DataTables and will almost certainly break\n", "\t * backwards compatibility with older installations. This is something that\n", "\t * will be done in 2.0.\n", "\t */\n", "\tDataTable.models.oSettings = {\n", "\t\t/**\n", "\t\t * Primary features of DataTables and their enablement state.\n", "\t\t * @namespace\n", "\t\t */\n", "\t\t\"oFeatures\": {\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Flag to say if DataTables should automatically try to calculate the\n", "\t\t\t * optimum table and columns widths (true) or not (false).\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bAutoWidth\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Delay the creation of TR and TD elements until they are actually\n", "\t\t\t * needed by a driven page draw. This can give a significant speed\n", "\t\t\t * increase for Ajax source and Javascript source data, but makes no\n", "\t\t\t * difference at all fro DOM and server-side processing tables.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bDeferRender\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Enable filtering on the table or not. Note that if this is disabled\n", "\t\t\t * then there is no filtering at all on the table, including fnFilter.\n", "\t\t\t * To just remove the filtering input use sDom and remove the 'f' option.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bFilter\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Table information element (the 'Showing x of y records' div) enable\n", "\t\t\t * flag.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bInfo\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Present a user control allowing the end user to change the page size\n", "\t\t\t * when pagination is enabled.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bLengthChange\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Pagination enabled or not. Note that if this is disabled then length\n", "\t\t\t * changing must also be disabled.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bPaginate\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Processing indicator enable flag whenever DataTables is enacting a\n", "\t\t\t * user request - typically an Ajax request for server-side processing.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bProcessing\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Server-side processing enabled flag - when enabled DataTables will\n", "\t\t\t * get all data from the server for every draw - there is no filtering,\n", "\t\t\t * sorting or paging done on the client-side.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bServerSide\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Sorting enablement flag.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bSort\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Multi-column sorting\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bSortMulti\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Apply a class to the columns which are being sorted to provide a\n", "\t\t\t * visual highlight or not. This can slow things down when enabled since\n", "\t\t\t * there is a lot of DOM interaction.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bSortClasses\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * State saving enablement flag.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bStateSave\": null\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Scrolling settings for a table.\n", "\t\t * @namespace\n", "\t\t */\n", "\t\t\"oScroll\": {\n", "\t\t\t/**\n", "\t\t\t * When the table is shorter in height than sScrollY, collapse the\n", "\t\t\t * table container down to the height of the table (when true).\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type boolean\n", "\t\t\t */\n", "\t\t\t\"bCollapse\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Width of the scrollbar for the web-browser's platform. Calculated\n", "\t\t\t * during table initialisation.\n", "\t\t\t * @type int\n", "\t\t\t * @default 0\n", "\t\t\t */\n", "\t\t\t\"iBarWidth\": 0,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Viewport width for horizontal scrolling. Horizontal scrolling is\n", "\t\t\t * disabled if an empty string.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type string\n", "\t\t\t */\n", "\t\t\t\"sX\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Width to expand the table to when using x-scrolling. Typically you\n", "\t\t\t * should not need to use this.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type string\n", "\t\t\t * @deprecated\n", "\t\t\t */\n", "\t\t\t\"sXInner\": null,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\n", "\t\t\t * if an empty string.\n", "\t\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t\t * @type string\n", "\t\t\t */\n", "\t\t\t\"sY\": null\n", "\t\t},\n", "\t\n", "\t\t/**\n", "\t\t * Language information for the table.\n", "\t\t * @namespace\n", "\t\t * @extends DataTable.defaults.oLanguage\n", "\t\t */\n", "\t\t\"oLanguage\": {\n", "\t\t\t/**\n", "\t\t\t * Information callback function. See\n", "\t\t\t * {@link DataTable.defaults.fnInfoCallback}\n", "\t\t\t * @type function\n", "\t\t\t * @default null\n", "\t\t\t */\n", "\t\t\t\"fnInfoCallback\": null\n", "\t\t},\n", "\t\n", "\t\t/**\n", "\t\t * Browser support parameters\n", "\t\t * @namespace\n", "\t\t */\n", "\t\t\"oBrowser\": {\n", "\t\t\t/**\n", "\t\t\t * Indicate if the browser incorrectly calculates width:100% inside a\n", "\t\t\t * scrolling element (IE6/7)\n", "\t\t\t * @type boolean\n", "\t\t\t * @default false\n", "\t\t\t */\n", "\t\t\t\"bScrollOversize\": false,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Determine if the vertical scrollbar is on the right or left of the\n", "\t\t\t * scrolling container - needed for rtl language layout, although not\n", "\t\t\t * all browsers move the scrollbar (Safari).\n", "\t\t\t * @type boolean\n", "\t\t\t * @default false\n", "\t\t\t */\n", "\t\t\t\"bScrollbarLeft\": false,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Flag for if `getBoundingClientRect` is fully supported or not\n", "\t\t\t * @type boolean\n", "\t\t\t * @default false\n", "\t\t\t */\n", "\t\t\t\"bBounding\": false,\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Browser scrollbar width\n", "\t\t\t * @type integer\n", "\t\t\t * @default 0\n", "\t\t\t */\n", "\t\t\t\"barWidth\": 0\n", "\t\t},\n", "\t\n", "\t\n", "\t\t\"ajax\": null,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Array referencing the nodes which are used for the features. The\n", "\t\t * parameters of this object match what is allowed by sDom - i.e.\n", "\t\t * <ul>\n", "\t\t * <li>'l' - Length changing</li>\n", "\t\t * <li>'f' - Filtering input</li>\n", "\t\t * <li>'t' - The table!</li>\n", "\t\t * <li>'i' - Information</li>\n", "\t\t * <li>'p' - Pagination</li>\n", "\t\t * <li>'r' - pRocessing</li>\n", "\t\t * </ul>\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aanFeatures\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Store data information - see {@link DataTable.models.oRow} for detailed\n", "\t\t * information.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoData\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Array of indexes which are in the current display (after filtering etc)\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aiDisplay\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Array of indexes for display - no filtering\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aiDisplayMaster\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Map of row ids to data indexes\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t */\n", "\t\t\"aIds\": {},\n", "\t\n", "\t\t/**\n", "\t\t * Store information about each column that is in use\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoColumns\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Store information about the table's header\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoHeader\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Store information about the table's footer\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoFooter\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Store the applied global search information in case we want to force a\n", "\t\t * research or compare the old search to a new one.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @namespace\n", "\t\t * @extends DataTable.models.oSearch\n", "\t\t */\n", "\t\t\"oPreviousSearch\": {},\n", "\t\n", "\t\t/**\n", "\t\t * Store the applied search for each column - see\n", "\t\t * {@link DataTable.models.oSearch} for the format that is used for the\n", "\t\t * filtering information for each column.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoPreSearchCols\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Sorting that is applied to the table. Note that the inner arrays are\n", "\t\t * used in the following manner:\n", "\t\t * <ul>\n", "\t\t * <li>Index 0 - column number</li>\n", "\t\t * <li>Index 1 - current sorting direction</li>\n", "\t\t * </ul>\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type array\n", "\t\t * @todo These inner arrays should really be objects\n", "\t\t */\n", "\t\t\"aaSorting\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Sorting that is always applied to the table (i.e. prefixed in front of\n", "\t\t * aaSorting).\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aaSortingFixed\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Classes to use for the striping of a table.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"asStripeClasses\": null,\n", "\t\n", "\t\t/**\n", "\t\t * If restoring a table - we should restore its striping classes as well\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"asDestroyStripes\": [],\n", "\t\n", "\t\t/**\n", "\t\t * If restoring a table - we should restore its width\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t */\n", "\t\t\"sDestroyWidth\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * Callback functions array for every time a row is inserted (i.e. on a draw).\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoRowCallback\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Callback functions for the header on each draw.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoHeaderCallback\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Callback function for the footer on each draw.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoFooterCallback\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Array of callback functions for draw callback functions\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoDrawCallback\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Array of callback functions for row created function\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoRowCreatedCallback\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Callback functions for just before the table is redrawn. A return of\n", "\t\t * false will be used to cancel the draw.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoPreDrawCallback\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Callback functions for when the table has been initialised.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoInitComplete\": [],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Callbacks for modifying the settings to be stored for state saving, prior to\n", "\t\t * saving state.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoStateSaveParams\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Callbacks for modifying the settings that have been stored for state saving\n", "\t\t * prior to using the stored values to restore the state.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoStateLoadParams\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Callbacks for operating on the settings object once the saved state has been\n", "\t\t * loaded\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoStateLoaded\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Cache the table ID for quick access\n", "\t\t * @type string\n", "\t\t * @default <i>Empty string</i>\n", "\t\t */\n", "\t\t\"sTableId\": \"\",\n", "\t\n", "\t\t/**\n", "\t\t * The TABLE node for the main table\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTable\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Permanent ref to the thead element\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTHead\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Permanent ref to the tfoot element - if it exists\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTFoot\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Permanent ref to the tbody element\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTBody\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Cache the wrapper node (contains all DataTables controlled elements)\n", "\t\t * @type node\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"nTableWrapper\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Indicate if when using server-side processing the loading of data\n", "\t\t * should be deferred until the second draw.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t */\n", "\t\t\"bDeferLoading\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Indicate if all required information has been read in\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t */\n", "\t\t\"bInitialised\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Information about open rows. Each object in the array has the parameters\n", "\t\t * 'nTr' and 'nParent'\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoOpenRows\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Dictate the positioning of DataTables' control elements - see\n", "\t\t * {@link DataTable.model.oInit.sDom}.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sDom\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Search delay (in mS)\n", "\t\t * @type integer\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"searchDelay\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Which type of pagination should be used.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type string\n", "\t\t * @default two_button\n", "\t\t */\n", "\t\t\"sPaginationType\": \"two_button\",\n", "\t\n", "\t\t/**\n", "\t\t * The state duration (for `stateSave`) in seconds.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t */\n", "\t\t\"iStateDuration\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * Array of callback functions for state saving. Each array element is an\n", "\t\t * object with the following parameters:\n", "\t\t * <ul>\n", "\t\t * <li>function:fn - function to call. Takes two parameters, oSettings\n", "\t\t * and the JSON string to save that has been thus far created. Returns\n", "\t\t * a JSON string to be inserted into a json object\n", "\t\t * (i.e. '\"param\": [ 0, 1, 2]')</li>\n", "\t\t * <li>string:sName - name of callback</li>\n", "\t\t * </ul>\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoStateSave\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Array of callback functions for state loading. Each array element is an\n", "\t\t * object with the following parameters:\n", "\t\t * <ul>\n", "\t\t * <li>function:fn - function to call. Takes two parameters, oSettings\n", "\t\t * and the object stored. May return false to cancel state loading</li>\n", "\t\t * <li>string:sName - name of callback</li>\n", "\t\t * </ul>\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoStateLoad\": [],\n", "\t\n", "\t\t/**\n", "\t\t * State that was saved. Useful for back reference\n", "\t\t * @type object\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"oSavedState\": null,\n", "\t\n", "\t\t/**\n", "\t\t * State that was loaded. Useful for back reference\n", "\t\t * @type object\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"oLoadedState\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Source url for AJAX data for the table.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sAjaxSource\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Property from a given object from which to read the table data from. This\n", "\t\t * can be an empty string (when not server-side processing), in which case\n", "\t\t * it is assumed an an array is given directly.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type string\n", "\t\t */\n", "\t\t\"sAjaxDataProp\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Note if draw should be blocked while getting data\n", "\t\t * @type boolean\n", "\t\t * @default true\n", "\t\t */\n", "\t\t\"bAjaxDataGet\": true,\n", "\t\n", "\t\t/**\n", "\t\t * The last jQuery XHR object that was used for server-side data gathering.\n", "\t\t * This can be used for working with the XHR information in one of the\n", "\t\t * callbacks\n", "\t\t * @type object\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"jqXHR\": null,\n", "\t\n", "\t\t/**\n", "\t\t * JSON returned from the server in the last Ajax request\n", "\t\t * @type object\n", "\t\t * @default undefined\n", "\t\t */\n", "\t\t\"json\": undefined,\n", "\t\n", "\t\t/**\n", "\t\t * Data submitted as part of the last Ajax request\n", "\t\t * @type object\n", "\t\t * @default undefined\n", "\t\t */\n", "\t\t\"oAjaxData\": undefined,\n", "\t\n", "\t\t/**\n", "\t\t * Function to get the server-side data.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type function\n", "\t\t */\n", "\t\t\"fnServerData\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Functions which are called prior to sending an Ajax request so extra\n", "\t\t * parameters can easily be sent to the server\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoServerParams\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\n", "\t\t * required).\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type string\n", "\t\t */\n", "\t\t\"sServerMethod\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Format numbers for display.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type function\n", "\t\t */\n", "\t\t\"fnFormatNumber\": null,\n", "\t\n", "\t\t/**\n", "\t\t * List of options that can be used for the user selectable length menu.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aLengthMenu\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Counter for the draws that the table does. Also used as a tracker for\n", "\t\t * server-side processing\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t */\n", "\t\t\"iDraw\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * Indicate if a redraw is being done - useful for Ajax\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t */\n", "\t\t\"bDrawing\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Draw index (iDraw) of the last error when parsing the returned data\n", "\t\t * @type int\n", "\t\t * @default -1\n", "\t\t */\n", "\t\t\"iDrawError\": -1,\n", "\t\n", "\t\t/**\n", "\t\t * Paging display length\n", "\t\t * @type int\n", "\t\t * @default 10\n", "\t\t */\n", "\t\t\"_iDisplayLength\": 10,\n", "\t\n", "\t\t/**\n", "\t\t * Paging start point - aiDisplay index\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t */\n", "\t\t\"_iDisplayStart\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * Server-side processing - number of records in the result set\n", "\t\t * (i.e. before filtering), Use fnRecordsTotal rather than\n", "\t\t * this property to get the value of the number of records, regardless of\n", "\t\t * the server-side processing setting.\n", "\t\t * @type int\n", "\t\t * @default 0\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_iRecordsTotal\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * Server-side processing - number of records in the current display set\n", "\t\t * (i.e. after filtering). Use fnRecordsDisplay rather than\n", "\t\t * this property to get the value of the number of records, regardless of\n", "\t\t * the server-side processing setting.\n", "\t\t * @type boolean\n", "\t\t * @default 0\n", "\t\t * @private\n", "\t\t */\n", "\t\t\"_iRecordsDisplay\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * The classes to use for the table\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t */\n", "\t\t\"oClasses\": {},\n", "\t\n", "\t\t/**\n", "\t\t * Flag attached to the settings object so you can check in the draw\n", "\t\t * callback if filtering has been done in the draw. Deprecated in favour of\n", "\t\t * events.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t * @deprecated\n", "\t\t */\n", "\t\t\"bFiltered\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Flag attached to the settings object so you can check in the draw\n", "\t\t * callback if sorting has been done in the draw. Deprecated in favour of\n", "\t\t * events.\n", "\t\t * @type boolean\n", "\t\t * @default false\n", "\t\t * @deprecated\n", "\t\t */\n", "\t\t\"bSorted\": false,\n", "\t\n", "\t\t/**\n", "\t\t * Indicate that if multiple rows are in the header and there is more than\n", "\t\t * one unique cell per column, if the top one (true) or bottom one (false)\n", "\t\t * should be used for sorting / title by DataTables.\n", "\t\t * Note that this parameter will be set by the initialisation routine. To\n", "\t\t * set a default use {@link DataTable.defaults}.\n", "\t\t * @type boolean\n", "\t\t */\n", "\t\t\"bSortCellsTop\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Initialisation object that is used for the table\n", "\t\t * @type object\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"oInit\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Destroy callback functions - for plug-ins to attach themselves to the\n", "\t\t * destroy so they can clean up markup and events.\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aoDestroyCallback\": [],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Get the number of records in the current record set, before filtering\n", "\t\t * @type function\n", "\t\t */\n", "\t\t\"fnRecordsTotal\": function ()\n", "\t\t{\n", "\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n", "\t\t\t\tthis._iRecordsTotal * 1 :\n", "\t\t\t\tthis.aiDisplayMaster.length;\n", "\t\t},\n", "\t\n", "\t\t/**\n", "\t\t * Get the number of records in the current record set, after filtering\n", "\t\t * @type function\n", "\t\t */\n", "\t\t\"fnRecordsDisplay\": function ()\n", "\t\t{\n", "\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n", "\t\t\t\tthis._iRecordsDisplay * 1 :\n", "\t\t\t\tthis.aiDisplay.length;\n", "\t\t},\n", "\t\n", "\t\t/**\n", "\t\t * Get the display end point - aiDisplay index\n", "\t\t * @type function\n", "\t\t */\n", "\t\t\"fnDisplayEnd\": function ()\n", "\t\t{\n", "\t\t\tvar\n", "\t\t\t\tlen = this._iDisplayLength,\n", "\t\t\t\tstart = this._iDisplayStart,\n", "\t\t\t\tcalc = start + len,\n", "\t\t\t\trecords = this.aiDisplay.length,\n", "\t\t\t\tfeatures = this.oFeatures,\n", "\t\t\t\tpaginate = features.bPaginate;\n", "\t\n", "\t\t\tif ( features.bServerSide ) {\n", "\t\t\t\treturn paginate === false || len === -1 ?\n", "\t\t\t\t\tstart + records :\n", "\t\t\t\t\tMath.min( start+len, this._iRecordsDisplay );\n", "\t\t\t}\n", "\t\t\telse {\n", "\t\t\t\treturn ! paginate || calc>records || len===-1 ?\n", "\t\t\t\t\trecords :\n", "\t\t\t\t\tcalc;\n", "\t\t\t}\n", "\t\t},\n", "\t\n", "\t\t/**\n", "\t\t * The DataTables object for this table\n", "\t\t * @type object\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"oInstance\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Unique identifier for each instance of the DataTables object. If there\n", "\t\t * is an ID on the table node, then it takes that value, otherwise an\n", "\t\t * incrementing internal counter is used.\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"sInstance\": null,\n", "\t\n", "\t\t/**\n", "\t\t * tabindex attribute value that is added to DataTables control elements, allowing\n", "\t\t * keyboard navigation of the table and its controls.\n", "\t\t */\n", "\t\t\"iTabIndex\": 0,\n", "\t\n", "\t\t/**\n", "\t\t * DIV container for the footer scrolling table if scrolling\n", "\t\t */\n", "\t\t\"nScrollHead\": null,\n", "\t\n", "\t\t/**\n", "\t\t * DIV container for the footer scrolling table if scrolling\n", "\t\t */\n", "\t\t\"nScrollFoot\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Last applied sort\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t */\n", "\t\t\"aLastSort\": [],\n", "\t\n", "\t\t/**\n", "\t\t * Stored plug-in instances\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t */\n", "\t\t\"oPlugins\": {},\n", "\t\n", "\t\t/**\n", "\t\t * Function used to get a row's id from the row's data\n", "\t\t * @type function\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"rowIdFn\": null,\n", "\t\n", "\t\t/**\n", "\t\t * Data location where to store a row's id\n", "\t\t * @type string\n", "\t\t * @default null\n", "\t\t */\n", "\t\t\"rowId\": null\n", "\t};\n", "\n", "\t/**\n", "\t * Extension object for DataTables that is used to provide all extension\n", "\t * options.\n", "\t *\n", "\t * Note that the `DataTable.ext` object is available through\n", "\t * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\n", "\t * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\n", "\t * @namespace\n", "\t * @extends DataTable.models.ext\n", "\t */\n", "\t\n", "\t\n", "\t/**\n", "\t * DataTables extensions\n", "\t * \n", "\t * This namespace acts as a collection area for plug-ins that can be used to\n", "\t * extend DataTables capabilities. Indeed many of the build in methods\n", "\t * use this method to provide their own capabilities (sorting methods for\n", "\t * example).\n", "\t *\n", "\t * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\n", "\t * reasons\n", "\t *\n", "\t * @namespace\n", "\t */\n", "\tDataTable.ext = _ext = {\n", "\t\t/**\n", "\t\t * Buttons. For use with the Buttons extension for DataTables. This is\n", "\t\t * defined here so other extensions can define buttons regardless of load\n", "\t\t * order. It is _not_ used by DataTables core.\n", "\t\t *\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t */\n", "\t\tbuttons: {},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Element class names\n", "\t\t *\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t */\n", "\t\tclasses: {},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * DataTables build type (expanded by the download builder)\n", "\t\t *\n", "\t\t * @type string\n", "\t\t */\n", "\t\tbuilder: \"-source-\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Error reporting.\n", "\t\t * \n", "\t\t * How should DataTables report an error. Can take the value 'alert',\n", "\t\t * 'throw', 'none' or a function.\n", "\t\t *\n", "\t\t * @type string|function\n", "\t\t * @default alert\n", "\t\t */\n", "\t\terrMode: \"alert\",\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Feature plug-ins.\n", "\t\t * \n", "\t\t * This is an array of objects which describe the feature plug-ins that are\n", "\t\t * available to DataTables. These feature plug-ins are then available for\n", "\t\t * use through the `dom` initialisation option.\n", "\t\t * \n", "\t\t * Each feature plug-in is described by an object which must have the\n", "\t\t * following properties:\n", "\t\t * \n", "\t\t * * `fnInit` - function that is used to initialise the plug-in,\n", "\t\t * * `cFeature` - a character so the feature can be enabled by the `dom`\n", "\t\t * instillation option. This is case sensitive.\n", "\t\t *\n", "\t\t * The `fnInit` function has the following input parameters:\n", "\t\t *\n", "\t\t * 1. `{object}` DataTables settings object: see\n", "\t\t * {@link DataTable.models.oSettings}\n", "\t\t *\n", "\t\t * And the following return is expected:\n", "\t\t * \n", "\t\t * * {node|null} The element which contains your feature. Note that the\n", "\t\t * return may also be void if your plug-in does not require to inject any\n", "\t\t * DOM elements into DataTables control (`dom`) - for example this might\n", "\t\t * be useful when developing a plug-in which allows table control via\n", "\t\t * keyboard entry\n", "\t\t *\n", "\t\t * @type array\n", "\t\t *\n", "\t\t * @example\n", "\t\t * $.fn.dataTable.ext.features.push( {\n", "\t\t * \"fnInit\": function( oSettings ) {\n", "\t\t * return new TableTools( { \"oDTSettings\": oSettings } );\n", "\t\t * },\n", "\t\t * \"cFeature\": \"T\"\n", "\t\t * } );\n", "\t\t */\n", "\t\tfeature: [],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Row searching.\n", "\t\t * \n", "\t\t * This method of searching is complimentary to the default type based\n", "\t\t * searching, and a lot more comprehensive as it allows you complete control\n", "\t\t * over the searching logic. Each element in this array is a function\n", "\t\t * (parameters described below) that is called for every row in the table,\n", "\t\t * and your logic decides if it should be included in the searching data set\n", "\t\t * or not.\n", "\t\t *\n", "\t\t * Searching functions have the following input parameters:\n", "\t\t *\n", "\t\t * 1. `{object}` DataTables settings object: see\n", "\t\t * {@link DataTable.models.oSettings}\n", "\t\t * 2. `{array|object}` Data for the row to be processed (same as the\n", "\t\t * original format that was passed in as the data source, or an array\n", "\t\t * from a DOM data source\n", "\t\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\n", "\t\t * can be useful to retrieve the `TR` element if you need DOM interaction.\n", "\t\t *\n", "\t\t * And the following return is expected:\n", "\t\t *\n", "\t\t * * {boolean} Include the row in the searched result set (true) or not\n", "\t\t * (false)\n", "\t\t *\n", "\t\t * Note that as with the main search ability in DataTables, technically this\n", "\t\t * is \"filtering\", since it is subtractive. However, for consistency in\n", "\t\t * naming we call it searching here.\n", "\t\t *\n", "\t\t * @type array\n", "\t\t * @default []\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // The following example shows custom search being applied to the\n", "\t\t * // fourth column (i.e. the data[3] index) based on two input values\n", "\t\t * // from the end-user, matching the data in a certain range.\n", "\t\t * $.fn.dataTable.ext.search.push(\n", "\t\t * function( settings, data, dataIndex ) {\n", "\t\t * var min = document.getElementById('min').value * 1;\n", "\t\t * var max = document.getElementById('max').value * 1;\n", "\t\t * var version = data[3] == \"-\" ? 0 : data[3]*1;\n", "\t\t *\n", "\t\t * if ( min == \"\" && max == \"\" ) {\n", "\t\t * return true;\n", "\t\t * }\n", "\t\t * else if ( min == \"\" && version < max ) {\n", "\t\t * return true;\n", "\t\t * }\n", "\t\t * else if ( min < version && \"\" == max ) {\n", "\t\t * return true;\n", "\t\t * }\n", "\t\t * else if ( min < version && version < max ) {\n", "\t\t * return true;\n", "\t\t * }\n", "\t\t * return false;\n", "\t\t * }\n", "\t\t * );\n", "\t\t */\n", "\t\tsearch: [],\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Selector extensions\n", "\t\t *\n", "\t\t * The `selector` option can be used to extend the options available for the\n", "\t\t * selector modifier options (`selector-modifier` object data type) that\n", "\t\t * each of the three built in selector types offer (row, column and cell +\n", "\t\t * their plural counterparts). For example the Select extension uses this\n", "\t\t * mechanism to provide an option to select only rows, columns and cells\n", "\t\t * that have been marked as selected by the end user (`{selected: true}`),\n", "\t\t * which can be used in conjunction with the existing built in selector\n", "\t\t * options.\n", "\t\t *\n", "\t\t * Each property is an array to which functions can be pushed. The functions\n", "\t\t * take three attributes:\n", "\t\t *\n", "\t\t * * Settings object for the host table\n", "\t\t * * Options object (`selector-modifier` object type)\n", "\t\t * * Array of selected item indexes\n", "\t\t *\n", "\t\t * The return is an array of the resulting item indexes after the custom\n", "\t\t * selector has been applied.\n", "\t\t *\n", "\t\t * @type object\n", "\t\t */\n", "\t\tselector: {\n", "\t\t\tcell: [],\n", "\t\t\tcolumn: [],\n", "\t\t\trow: []\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Internal functions, exposed for used in plug-ins.\n", "\t\t * \n", "\t\t * Please note that you should not need to use the internal methods for\n", "\t\t * anything other than a plug-in (and even then, try to avoid if possible).\n", "\t\t * The internal function may change between releases.\n", "\t\t *\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t */\n", "\t\tinternal: {},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Legacy configuration options. Enable and disable legacy options that\n", "\t\t * are available in DataTables.\n", "\t\t *\n", "\t\t * @type object\n", "\t\t */\n", "\t\tlegacy: {\n", "\t\t\t/**\n", "\t\t\t * Enable / disable DataTables 1.9 compatible server-side processing\n", "\t\t\t * requests\n", "\t\t\t *\n", "\t\t\t * @type boolean\n", "\t\t\t * @default null\n", "\t\t\t */\n", "\t\t\tajax: null\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Pagination plug-in methods.\n", "\t\t * \n", "\t\t * Each entry in this object is a function and defines which buttons should\n", "\t\t * be shown by the pagination rendering method that is used for the table:\n", "\t\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\n", "\t\t * buttons are displayed in the document, while the functions here tell it\n", "\t\t * what buttons to display. This is done by returning an array of button\n", "\t\t * descriptions (what each button will do).\n", "\t\t *\n", "\t\t * Pagination types (the four built in options and any additional plug-in\n", "\t\t * options defined here) can be used through the `paginationType`\n", "\t\t * initialisation parameter.\n", "\t\t *\n", "\t\t * The functions defined take two parameters:\n", "\t\t *\n", "\t\t * 1. `{int} page` The current page index\n", "\t\t * 2. `{int} pages` The number of pages in the table\n", "\t\t *\n", "\t\t * Each function is expected to return an array where each element of the\n", "\t\t * array can be one of:\n", "\t\t *\n", "\t\t * * `first` - Jump to first page when activated\n", "\t\t * * `last` - Jump to last page when activated\n", "\t\t * * `previous` - Show previous page when activated\n", "\t\t * * `next` - Show next page when activated\n", "\t\t * * `{int}` - Show page of the index given\n", "\t\t * * `{array}` - A nested array containing the above elements to add a\n", "\t\t * containing 'DIV' element (might be useful for styling).\n", "\t\t *\n", "\t\t * Note that DataTables v1.9- used this object slightly differently whereby\n", "\t\t * an object with two functions would be defined for each plug-in. That\n", "\t\t * ability is still supported by DataTables 1.10+ to provide backwards\n", "\t\t * compatibility, but this option of use is now decremented and no longer\n", "\t\t * documented in DataTables 1.10+.\n", "\t\t *\n", "\t\t * @type object\n", "\t\t * @default {}\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Show previous, next and current page buttons only\n", "\t\t * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\n", "\t\t * return [ 'previous', page, 'next' ];\n", "\t\t * };\n", "\t\t */\n", "\t\tpager: {},\n", "\t\n", "\t\n", "\t\trenderer: {\n", "\t\t\tpageButton: {},\n", "\t\t\theader: {}\n", "\t\t},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Ordering plug-ins - custom data source\n", "\t\t * \n", "\t\t * The extension options for ordering of data available here is complimentary\n", "\t\t * to the default type based ordering that DataTables typically uses. It\n", "\t\t * allows much greater control over the the data that is being used to\n", "\t\t * order a column, but is necessarily therefore more complex.\n", "\t\t * \n", "\t\t * This type of ordering is useful if you want to do ordering based on data\n", "\t\t * live from the DOM (for example the contents of an 'input' element) rather\n", "\t\t * than just the static string that DataTables knows of.\n", "\t\t * \n", "\t\t * The way these plug-ins work is that you create an array of the values you\n", "\t\t * wish to be ordering for the column in question and then return that\n", "\t\t * array. The data in the array much be in the index order of the rows in\n", "\t\t * the table (not the currently ordering order!). Which order data gathering\n", "\t\t * function is run here depends on the `dt-init columns.orderDataType`\n", "\t\t * parameter that is used for the column (if any).\n", "\t\t *\n", "\t\t * The functions defined take two parameters:\n", "\t\t *\n", "\t\t * 1. `{object}` DataTables settings object: see\n", "\t\t * {@link DataTable.models.oSettings}\n", "\t\t * 2. `{int}` Target column index\n", "\t\t *\n", "\t\t * Each function is expected to return an array:\n", "\t\t *\n", "\t\t * * `{array}` Data for the column to be ordering upon\n", "\t\t *\n", "\t\t * @type array\n", "\t\t *\n", "\t\t * @example\n", "\t\t * // Ordering using `input` node values\n", "\t\t * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )\n", "\t\t * {\n", "\t\t * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\n", "\t\t * return $('input', td).val();\n", "\t\t * } );\n", "\t\t * }\n", "\t\t */\n", "\t\torder: {},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Type based plug-ins.\n", "\t\t *\n", "\t\t * Each column in DataTables has a type assigned to it, either by automatic\n", "\t\t * detection or by direct assignment using the `type` option for the column.\n", "\t\t * The type of a column will effect how it is ordering and search (plug-ins\n", "\t\t * can also make use of the column type if required).\n", "\t\t *\n", "\t\t * @namespace\n", "\t\t */\n", "\t\ttype: {\n", "\t\t\t/**\n", "\t\t\t * Type detection functions.\n", "\t\t\t *\n", "\t\t\t * The functions defined in this object are used to automatically detect\n", "\t\t\t * a column's type, making initialisation of DataTables super easy, even\n", "\t\t\t * when complex data is in the table.\n", "\t\t\t *\n", "\t\t\t * The functions defined take two parameters:\n", "\t\t\t *\n", "\t\t * 1. `{*}` Data from the column cell to be analysed\n", "\t\t * 2. `{settings}` DataTables settings object. This can be used to\n", "\t\t * perform context specific type detection - for example detection\n", "\t\t * based on language settings such as using a comma for a decimal\n", "\t\t * place. Generally speaking the options from the settings will not\n", "\t\t * be required\n", "\t\t\t *\n", "\t\t\t * Each function is expected to return:\n", "\t\t\t *\n", "\t\t\t * * `{string|null}` Data type detected, or null if unknown (and thus\n", "\t\t\t * pass it on to the other type detection functions.\n", "\t\t\t *\n", "\t\t\t * @type array\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Currency type detection plug-in:\n", "\t\t\t * $.fn.dataTable.ext.type.detect.push(\n", "\t\t\t * function ( data, settings ) {\n", "\t\t\t * // Check the numeric part\n", "\t\t\t * if ( ! $.isNumeric( data.substring(1) ) ) {\n", "\t\t\t * return null;\n", "\t\t\t * }\n", "\t\t\t *\n", "\t\t\t * // Check prefixed by currency\n", "\t\t\t * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {\n", "\t\t\t * return 'currency';\n", "\t\t\t * }\n", "\t\t\t * return null;\n", "\t\t\t * }\n", "\t\t\t * );\n", "\t\t\t */\n", "\t\t\tdetect: [],\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Type based search formatting.\n", "\t\t\t *\n", "\t\t\t * The type based searching functions can be used to pre-format the\n", "\t\t\t * data to be search on. For example, it can be used to strip HTML\n", "\t\t\t * tags or to de-format telephone numbers for numeric only searching.\n", "\t\t\t *\n", "\t\t\t * Note that is a search is not defined for a column of a given type,\n", "\t\t\t * no search formatting will be performed.\n", "\t\t\t * \n", "\t\t\t * Pre-processing of searching data plug-ins - When you assign the sType\n", "\t\t\t * for a column (or have it automatically detected for you by DataTables\n", "\t\t\t * or a type detection plug-in), you will typically be using this for\n", "\t\t\t * custom sorting, but it can also be used to provide custom searching\n", "\t\t\t * by allowing you to pre-processing the data and returning the data in\n", "\t\t\t * the format that should be searched upon. This is done by adding\n", "\t\t\t * functions this object with a parameter name which matches the sType\n", "\t\t\t * for that target column. This is the corollary of <i>afnSortData</i>\n", "\t\t\t * for searching data.\n", "\t\t\t *\n", "\t\t\t * The functions defined take a single parameter:\n", "\t\t\t *\n", "\t\t * 1. `{*}` Data from the column cell to be prepared for searching\n", "\t\t\t *\n", "\t\t\t * Each function is expected to return:\n", "\t\t\t *\n", "\t\t\t * * `{string|null}` Formatted string that will be used for the searching.\n", "\t\t\t *\n", "\t\t\t * @type object\n", "\t\t\t * @default {}\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\n", "\t\t\t * return d.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" );\n", "\t\t\t * }\n", "\t\t\t */\n", "\t\t\tsearch: {},\n", "\t\n", "\t\n", "\t\t\t/**\n", "\t\t\t * Type based ordering.\n", "\t\t\t *\n", "\t\t\t * The column type tells DataTables what ordering to apply to the table\n", "\t\t\t * when a column is sorted upon. The order for each type that is defined,\n", "\t\t\t * is defined by the functions available in this object.\n", "\t\t\t *\n", "\t\t\t * Each ordering option can be described by three properties added to\n", "\t\t\t * this object:\n", "\t\t\t *\n", "\t\t\t * * `{type}-pre` - Pre-formatting function\n", "\t\t\t * * `{type}-asc` - Ascending order function\n", "\t\t\t * * `{type}-desc` - Descending order function\n", "\t\t\t *\n", "\t\t\t * All three can be used together, only `{type}-pre` or only\n", "\t\t\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\n", "\t\t\t * that only `{type}-pre` is used, as this provides the optimal\n", "\t\t\t * implementation in terms of speed, although the others are provided\n", "\t\t\t * for compatibility with existing Javascript sort functions.\n", "\t\t\t *\n", "\t\t\t * `{type}-pre`: Functions defined take a single parameter:\n", "\t\t\t *\n", "\t\t * 1. `{*}` Data from the column cell to be prepared for ordering\n", "\t\t\t *\n", "\t\t\t * And return:\n", "\t\t\t *\n", "\t\t\t * * `{*}` Data to be sorted upon\n", "\t\t\t *\n", "\t\t\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\n", "\t\t\t * functions, taking two parameters:\n", "\t\t\t *\n", "\t\t * 1. `{*}` Data to compare to the second parameter\n", "\t\t * 2. `{*}` Data to compare to the first parameter\n", "\t\t\t *\n", "\t\t\t * And returning:\n", "\t\t\t *\n", "\t\t\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\n", "\t\t\t * than the second parameter, ===0 if the two parameters are equal and\n", "\t\t\t * >0 if the first parameter should be sorted height than the second\n", "\t\t\t * parameter.\n", "\t\t\t * \n", "\t\t\t * @type object\n", "\t\t\t * @default {}\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Numeric ordering of formatted numbers with a pre-formatter\n", "\t\t\t * $.extend( $.fn.dataTable.ext.type.order, {\n", "\t\t\t * \"string-pre\": function(x) {\n", "\t\t\t * a = (a === \"-\" || a === \"\") ? 0 : a.replace( /[^\\d\\-\\.]/g, \"\" );\n", "\t\t\t * return parseFloat( a );\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t *\n", "\t\t\t * @example\n", "\t\t\t * // Case-sensitive string ordering, with no pre-formatting method\n", "\t\t\t * $.extend( $.fn.dataTable.ext.order, {\n", "\t\t\t * \"string-case-asc\": function(x,y) {\n", "\t\t\t * return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n", "\t\t\t * },\n", "\t\t\t * \"string-case-desc\": function(x,y) {\n", "\t\t\t * return ((x < y) ? 1 : ((x > y) ? -1 : 0));\n", "\t\t\t * }\n", "\t\t\t * } );\n", "\t\t\t */\n", "\t\t\torder: {}\n", "\t\t},\n", "\t\n", "\t\t/**\n", "\t\t * Unique DataTables instance counter\n", "\t\t *\n", "\t\t * @type int\n", "\t\t * @private\n", "\t\t */\n", "\t\t_unique: 0,\n", "\t\n", "\t\n", "\t\t//\n", "\t\t// Depreciated\n", "\t\t// The following properties are retained for backwards compatiblity only.\n", "\t\t// The should not be used in new projects and will be removed in a future\n", "\t\t// version\n", "\t\t//\n", "\t\n", "\t\t/**\n", "\t\t * Version check function.\n", "\t\t * @type function\n", "\t\t * @depreciated Since 1.10\n", "\t\t */\n", "\t\tfnVersionCheck: DataTable.fnVersionCheck,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Index for what 'this' index API functions should use\n", "\t\t * @type int\n", "\t\t * @deprecated Since v1.10\n", "\t\t */\n", "\t\tiApiIndex: 0,\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * jQuery UI class container\n", "\t\t * @type object\n", "\t\t * @deprecated Since v1.10\n", "\t\t */\n", "\t\toJUIClasses: {},\n", "\t\n", "\t\n", "\t\t/**\n", "\t\t * Software version\n", "\t\t * @type string\n", "\t\t * @deprecated Since v1.10\n", "\t\t */\n", "\t\tsVersion: DataTable.version\n", "\t};\n", "\t\n", "\t\n", "\t//\n", "\t// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\n", "\t//\n", "\t$.extend( _ext, {\n", "\t\tafnFiltering: _ext.search,\n", "\t\taTypes: _ext.type.detect,\n", "\t\tofnSearch: _ext.type.search,\n", "\t\toSort: _ext.type.order,\n", "\t\tafnSortData: _ext.order,\n", "\t\taoFeatures: _ext.feature,\n", "\t\toApi: _ext.internal,\n", "\t\toStdClasses: _ext.classes,\n", "\t\toPagination: _ext.pager\n", "\t} );\n", "\t\n", "\t\n", "\t$.extend( DataTable.ext.classes, {\n", "\t\t\"sTable\": \"dataTable\",\n", "\t\t\"sNoFooter\": \"no-footer\",\n", "\t\n", "\t\t/* Paging buttons */\n", "\t\t\"sPageButton\": \"paginate_button\",\n", "\t\t\"sPageButtonActive\": \"current\",\n", "\t\t\"sPageButtonDisabled\": \"disabled\",\n", "\t\n", "\t\t/* Striping classes */\n", "\t\t\"sStripeOdd\": \"odd\",\n", "\t\t\"sStripeEven\": \"even\",\n", "\t\n", "\t\t/* Empty row */\n", "\t\t\"sRowEmpty\": \"dataTables_empty\",\n", "\t\n", "\t\t/* Features */\n", "\t\t\"sWrapper\": \"dataTables_wrapper\",\n", "\t\t\"sFilter\": \"dataTables_filter\",\n", "\t\t\"sInfo\": \"dataTables_info\",\n", "\t\t\"sPaging\": \"dataTables_paginate paging_\", /* Note that the type is postfixed */\n", "\t\t\"sLength\": \"dataTables_length\",\n", "\t\t\"sProcessing\": \"dataTables_processing\",\n", "\t\n", "\t\t/* Sorting */\n", "\t\t\"sSortAsc\": \"sorting_asc\",\n", "\t\t\"sSortDesc\": \"sorting_desc\",\n", "\t\t\"sSortable\": \"sorting\", /* Sortable in both directions */\n", "\t\t\"sSortableAsc\": \"sorting_asc_disabled\",\n", "\t\t\"sSortableDesc\": \"sorting_desc_disabled\",\n", "\t\t\"sSortableNone\": \"sorting_disabled\",\n", "\t\t\"sSortColumn\": \"sorting_\", /* Note that an int is postfixed for the sorting order */\n", "\t\n", "\t\t/* Filtering */\n", "\t\t\"sFilterInput\": \"\",\n", "\t\n", "\t\t/* Page length */\n", "\t\t\"sLengthSelect\": \"\",\n", "\t\n", "\t\t/* Scrolling */\n", "\t\t\"sScrollWrapper\": \"dataTables_scroll\",\n", "\t\t\"sScrollHead\": \"dataTables_scrollHead\",\n", "\t\t\"sScrollHeadInner\": \"dataTables_scrollHeadInner\",\n", "\t\t\"sScrollBody\": \"dataTables_scrollBody\",\n", "\t\t\"sScrollFoot\": \"dataTables_scrollFoot\",\n", "\t\t\"sScrollFootInner\": \"dataTables_scrollFootInner\",\n", "\t\n", "\t\t/* Misc */\n", "\t\t\"sHeaderTH\": \"\",\n", "\t\t\"sFooterTH\": \"\",\n", "\t\n", "\t\t// Deprecated\n", "\t\t\"sSortJUIAsc\": \"\",\n", "\t\t\"sSortJUIDesc\": \"\",\n", "\t\t\"sSortJUI\": \"\",\n", "\t\t\"sSortJUIAscAllowed\": \"\",\n", "\t\t\"sSortJUIDescAllowed\": \"\",\n", "\t\t\"sSortJUIWrapper\": \"\",\n", "\t\t\"sSortIcon\": \"\",\n", "\t\t\"sJUIHeader\": \"\",\n", "\t\t\"sJUIFooter\": \"\"\n", "\t} );\n", "\t\n", "\t\n", "\tvar extPagination = DataTable.ext.pager;\n", "\t\n", "\tfunction _numbers ( page, pages ) {\n", "\t\tvar\n", "\t\t\tnumbers = [],\n", "\t\t\tbuttons = extPagination.numbers_length,\n", "\t\t\thalf = Math.floor( buttons / 2 ),\n", "\t\t\ti = 1;\n", "\t\n", "\t\tif ( pages <= buttons ) {\n", "\t\t\tnumbers = _range( 0, pages );\n", "\t\t}\n", "\t\telse if ( page <= half ) {\n", "\t\t\tnumbers = _range( 0, buttons-2 );\n", "\t\t\tnumbers.push( 'ellipsis' );\n", "\t\t\tnumbers.push( pages-1 );\n", "\t\t}\n", "\t\telse if ( page >= pages - 1 - half ) {\n", "\t\t\tnumbers = _range( pages-(buttons-2), pages );\n", "\t\t\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\n", "\t\t\tnumbers.splice( 0, 0, 0 );\n", "\t\t}\n", "\t\telse {\n", "\t\t\tnumbers = _range( page-half+2, page+half-1 );\n", "\t\t\tnumbers.push( 'ellipsis' );\n", "\t\t\tnumbers.push( pages-1 );\n", "\t\t\tnumbers.splice( 0, 0, 'ellipsis' );\n", "\t\t\tnumbers.splice( 0, 0, 0 );\n", "\t\t}\n", "\t\n", "\t\tnumbers.DT_el = 'span';\n", "\t\treturn numbers;\n", "\t}\n", "\t\n", "\t\n", "\t$.extend( extPagination, {\n", "\t\tsimple: function ( page, pages ) {\n", "\t\t\treturn [ 'previous', 'next' ];\n", "\t\t},\n", "\t\n", "\t\tfull: function ( page, pages ) {\n", "\t\t\treturn [ 'first', 'previous', 'next', 'last' ];\n", "\t\t},\n", "\t\n", "\t\tnumbers: function ( page, pages ) {\n", "\t\t\treturn [ _numbers(page, pages) ];\n", "\t\t},\n", "\t\n", "\t\tsimple_numbers: function ( page, pages ) {\n", "\t\t\treturn [ 'previous', _numbers(page, pages), 'next' ];\n", "\t\t},\n", "\t\n", "\t\tfull_numbers: function ( page, pages ) {\n", "\t\t\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\n", "\t\t},\n", "\t\t\n", "\t\tfirst_last_numbers: function (page, pages) {\n", "\t \t\treturn ['first', _numbers(page, pages), 'last'];\n", "\t \t},\n", "\t\n", "\t\t// For testing and plug-ins to use\n", "\t\t_numbers: _numbers,\n", "\t\n", "\t\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\n", "\t\tnumbers_length: 7\n", "\t} );\n", "\t\n", "\t\n", "\t$.extend( true, DataTable.ext.renderer, {\n", "\t\tpageButton: {\n", "\t\t\t_: function ( settings, host, idx, buttons, page, pages ) {\n", "\t\t\t\tvar classes = settings.oClasses;\n", "\t\t\t\tvar lang = settings.oLanguage.oPaginate;\n", "\t\t\t\tvar aria = settings.oLanguage.oAria.paginate || {};\n", "\t\t\t\tvar btnDisplay, btnClass, counter=0;\n", "\t\n", "\t\t\t\tvar attach = function( container, buttons ) {\n", "\t\t\t\t\tvar i, ien, node, button;\n", "\t\t\t\t\tvar clickHandler = function ( e ) {\n", "\t\t\t\t\t\t_fnPageChange( settings, e.data.action, true );\n", "\t\t\t\t\t};\n", "\t\n", "\t\t\t\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n", "\t\t\t\t\t\tbutton = buttons[i];\n", "\t\n", "\t\t\t\t\t\tif ( $.isArray( button ) ) {\n", "\t\t\t\t\t\t\tvar inner = $( '<'+(button.DT_el || 'div')+'/>' )\n", "\t\t\t\t\t\t\t\t.appendTo( container );\n", "\t\t\t\t\t\t\tattach( inner, button );\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t\telse {\n", "\t\t\t\t\t\t\tbtnDisplay = null;\n", "\t\t\t\t\t\t\tbtnClass = '';\n", "\t\n", "\t\t\t\t\t\t\tswitch ( button ) {\n", "\t\t\t\t\t\t\t\tcase 'ellipsis':\n", "\t\t\t\t\t\t\t\t\tcontainer.append('<span class=\"ellipsis\">…</span>');\n", "\t\t\t\t\t\t\t\t\tbreak;\n", "\t\n", "\t\t\t\t\t\t\t\tcase 'first':\n", "\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n", "\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n", "\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n", "\t\t\t\t\t\t\t\t\tbreak;\n", "\t\n", "\t\t\t\t\t\t\t\tcase 'previous':\n", "\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n", "\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n", "\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n", "\t\t\t\t\t\t\t\t\tbreak;\n", "\t\n", "\t\t\t\t\t\t\t\tcase 'next':\n", "\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sNext;\n", "\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n", "\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n", "\t\t\t\t\t\t\t\t\tbreak;\n", "\t\n", "\t\t\t\t\t\t\t\tcase 'last':\n", "\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sLast;\n", "\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n", "\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n", "\t\t\t\t\t\t\t\t\tbreak;\n", "\t\n", "\t\t\t\t\t\t\t\tdefault:\n", "\t\t\t\t\t\t\t\t\tbtnDisplay = button + 1;\n", "\t\t\t\t\t\t\t\t\tbtnClass = page === button ?\n", "\t\t\t\t\t\t\t\t\t\tclasses.sPageButtonActive : '';\n", "\t\t\t\t\t\t\t\t\tbreak;\n", "\t\t\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\t\t\tif ( btnDisplay !== null ) {\n", "\t\t\t\t\t\t\t\tnode = $('<a>', {\n", "\t\t\t\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n", "\t\t\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n", "\t\t\t\t\t\t\t\t\t\t'aria-label': aria[ button ],\n", "\t\t\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n", "\t\t\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n", "\t\t\t\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n", "\t\t\t\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n", "\t\t\t\t\t\t\t\t\t\t\tnull\n", "\t\t\t\t\t\t\t\t\t} )\n", "\t\t\t\t\t\t\t\t\t.html( btnDisplay )\n", "\t\t\t\t\t\t\t\t\t.appendTo( container );\n", "\t\n", "\t\t\t\t\t\t\t\t_fnBindAction(\n", "\t\t\t\t\t\t\t\t\tnode, {action: button}, clickHandler\n", "\t\t\t\t\t\t\t\t);\n", "\t\n", "\t\t\t\t\t\t\t\tcounter++;\n", "\t\t\t\t\t\t\t}\n", "\t\t\t\t\t\t}\n", "\t\t\t\t\t}\n", "\t\t\t\t};\n", "\t\n", "\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n", "\t\t\t\t// inside an iframe or frame. Try / catch the error. Not good for\n", "\t\t\t\t// accessibility, but neither are frames.\n", "\t\t\t\tvar activeEl;\n", "\t\n", "\t\t\t\ttry {\n", "\t\t\t\t\t// Because this approach is destroying and recreating the paging\n", "\t\t\t\t\t// elements, focus is lost on the select button which is bad for\n", "\t\t\t\t\t// accessibility. So we want to restore focus once the draw has\n", "\t\t\t\t\t// completed\n", "\t\t\t\t\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\n", "\t\t\t\t}\n", "\t\t\t\tcatch (e) {}\n", "\t\n", "\t\t\t\tattach( $(host).empty(), buttons );\n", "\t\n", "\t\t\t\tif ( activeEl !== undefined ) {\n", "\t\t\t\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t}\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\t// Built in type detection. See model.ext.aTypes for information about\n", "\t// what is required from this methods.\n", "\t$.extend( DataTable.ext.type.detect, [\n", "\t\t// Plain numbers - first since V8 detects some plain numbers as dates\n", "\t\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\n", "\t\tfunction ( d, settings )\n", "\t\t{\n", "\t\t\tvar decimal = settings.oLanguage.sDecimal;\n", "\t\t\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\n", "\t\t},\n", "\t\n", "\t\t// Dates (only those recognised by the browser's Date.parse)\n", "\t\tfunction ( d, settings )\n", "\t\t{\n", "\t\t\t// V8 tries _very_ hard to make a string passed into `Date.parse()`\n", "\t\t\t// valid, so we need to use a regex to restrict date formats. Use a\n", "\t\t\t// plug-in for anything other than ISO8601 style strings\n", "\t\t\tif ( d && !(d instanceof Date) && ! _re_date.test(d) ) {\n", "\t\t\t\treturn null;\n", "\t\t\t}\n", "\t\t\tvar parsed = Date.parse(d);\n", "\t\t\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\n", "\t\t},\n", "\t\n", "\t\t// Formatted numbers\n", "\t\tfunction ( d, settings )\n", "\t\t{\n", "\t\t\tvar decimal = settings.oLanguage.sDecimal;\n", "\t\t\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\n", "\t\t},\n", "\t\n", "\t\t// HTML numeric\n", "\t\tfunction ( d, settings )\n", "\t\t{\n", "\t\t\tvar decimal = settings.oLanguage.sDecimal;\n", "\t\t\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\n", "\t\t},\n", "\t\n", "\t\t// HTML numeric, formatted\n", "\t\tfunction ( d, settings )\n", "\t\t{\n", "\t\t\tvar decimal = settings.oLanguage.sDecimal;\n", "\t\t\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\n", "\t\t},\n", "\t\n", "\t\t// HTML (this is strict checking - there must be html)\n", "\t\tfunction ( d, settings )\n", "\t\t{\n", "\t\t\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\n", "\t\t\t\t'html' : null;\n", "\t\t}\n", "\t] );\n", "\t\n", "\t\n", "\t\n", "\t// Filter formatting functions. See model.ext.ofnSearch for information about\n", "\t// what is required from these methods.\n", "\t// \n", "\t// Note that additional search methods are added for the html numbers and\n", "\t// html formatted numbers by `_addNumericSort()` when we know what the decimal\n", "\t// place is\n", "\t\n", "\t\n", "\t$.extend( DataTable.ext.type.search, {\n", "\t\thtml: function ( data ) {\n", "\t\t\treturn _empty(data) ?\n", "\t\t\t\tdata :\n", "\t\t\t\ttypeof data === 'string' ?\n", "\t\t\t\t\tdata\n", "\t\t\t\t\t\t.replace( _re_new_lines, \" \" )\n", "\t\t\t\t\t\t.replace( _re_html, \"\" ) :\n", "\t\t\t\t\t'';\n", "\t\t},\n", "\t\n", "\t\tstring: function ( data ) {\n", "\t\t\treturn _empty(data) ?\n", "\t\t\t\tdata :\n", "\t\t\t\ttypeof data === 'string' ?\n", "\t\t\t\t\tdata.replace( _re_new_lines, \" \" ) :\n", "\t\t\t\t\tdata;\n", "\t\t}\n", "\t} );\n", "\t\n", "\t\n", "\t\n", "\tvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\n", "\t\tif ( d !== 0 && (!d || d === '-') ) {\n", "\t\t\treturn -Infinity;\n", "\t\t}\n", "\t\n", "\t\t// If a decimal place other than `.` is used, it needs to be given to the\n", "\t\t// function so we can detect it and replace with a `.` which is the only\n", "\t\t// decimal place Javascript recognises - it is not locale aware.\n", "\t\tif ( decimalPlace ) {\n", "\t\t\td = _numToDecimal( d, decimalPlace );\n", "\t\t}\n", "\t\n", "\t\tif ( d.replace ) {\n", "\t\t\tif ( re1 ) {\n", "\t\t\t\td = d.replace( re1, '' );\n", "\t\t\t}\n", "\t\n", "\t\t\tif ( re2 ) {\n", "\t\t\t\td = d.replace( re2, '' );\n", "\t\t\t}\n", "\t\t}\n", "\t\n", "\t\treturn d * 1;\n", "\t};\n", "\t\n", "\t\n", "\t// Add the numeric 'deformatting' functions for sorting and search. This is done\n", "\t// in a function to provide an easy ability for the language options to add\n", "\t// additional methods if a non-period decimal place is used.\n", "\tfunction _addNumericSort ( decimalPlace ) {\n", "\t\t$.each(\n", "\t\t\t{\n", "\t\t\t\t// Plain numbers\n", "\t\t\t\t\"num\": function ( d ) {\n", "\t\t\t\t\treturn __numericReplace( d, decimalPlace );\n", "\t\t\t\t},\n", "\t\n", "\t\t\t\t// Formatted numbers\n", "\t\t\t\t\"num-fmt\": function ( d ) {\n", "\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\n", "\t\t\t\t},\n", "\t\n", "\t\t\t\t// HTML numeric\n", "\t\t\t\t\"html-num\": function ( d ) {\n", "\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html );\n", "\t\t\t\t},\n", "\t\n", "\t\t\t\t// HTML numeric, formatted\n", "\t\t\t\t\"html-num-fmt\": function ( d ) {\n", "\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\n", "\t\t\t\t}\n", "\t\t\t},\n", "\t\t\tfunction ( key, fn ) {\n", "\t\t\t\t// Add the ordering method\n", "\t\t\t\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\n", "\t\n", "\t\t\t\t// For HTML types add a search formatter that will strip the HTML\n", "\t\t\t\tif ( key.match(/^html\\-/) ) {\n", "\t\t\t\t\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\n", "\t\t\t\t}\n", "\t\t\t}\n", "\t\t);\n", "\t}\n", "\t\n", "\t\n", "\t// Default sort methods\n", "\t$.extend( _ext.type.order, {\n", "\t\t// Dates\n", "\t\t\"date-pre\": function ( d ) {\n", "\t\t\treturn Date.parse( d ) || -Infinity;\n", "\t\t},\n", "\t\n", "\t\t// html\n", "\t\t\"html-pre\": function ( a ) {\n", "\t\t\treturn _empty(a) ?\n", "\t\t\t\t'' :\n", "\t\t\t\ta.replace ?\n", "\t\t\t\t\ta.replace( /<.*?>/g, \"\" ).toLowerCase() :\n", "\t\t\t\t\ta+'';\n", "\t\t},\n", "\t\n", "\t\t// string\n", "\t\t\"string-pre\": function ( a ) {\n", "\t\t\t// This is a little complex, but faster than always calling toString,\n", "\t\t\t// http://jsperf.com/tostring-v-check\n", "\t\t\treturn _empty(a) ?\n", "\t\t\t\t'' :\n", "\t\t\t\ttypeof a === 'string' ?\n", "\t\t\t\t\ta.toLowerCase() :\n", "\t\t\t\t\t! a.toString ?\n", "\t\t\t\t\t\t'' :\n", "\t\t\t\t\t\ta.toString();\n", "\t\t},\n", "\t\n", "\t\t// string-asc and -desc are retained only for compatibility with the old\n", "\t\t// sort methods\n", "\t\t\"string-asc\": function ( x, y ) {\n", "\t\t\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\n", "\t\t},\n", "\t\n", "\t\t\"string-desc\": function ( x, y ) {\n", "\t\t\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\n", "\t\t}\n", "\t} );\n", "\t\n", "\t\n", "\t// Numeric sorting types - order doesn't matter here\n", "\t_addNumericSort( '' );\n", "\t\n", "\t\n", "\t$.extend( true, DataTable.ext.renderer, {\n", "\t\theader: {\n", "\t\t\t_: function ( settings, cell, column, classes ) {\n", "\t\t\t\t// No additional mark-up required\n", "\t\t\t\t// Attach a sort listener to update on sort - note that using the\n", "\t\t\t\t// `DT` namespace will allow the event to be removed automatically\n", "\t\t\t\t// on destroy, while the `dt` namespaced event is the one we are\n", "\t\t\t\t// listening for\n", "\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n", "\t\t\t\t\tif ( settings !== ctx ) { // need to check this this is the host\n", "\t\t\t\t\t\treturn; // table, not a nested one\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tvar colIdx = column.idx;\n", "\t\n", "\t\t\t\t\tcell\n", "\t\t\t\t\t\t.removeClass(\n", "\t\t\t\t\t\t\tcolumn.sSortingClass +' '+\n", "\t\t\t\t\t\t\tclasses.sSortAsc +' '+\n", "\t\t\t\t\t\t\tclasses.sSortDesc\n", "\t\t\t\t\t\t)\n", "\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n", "\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n", "\t\t\t\t\t\t\t\tclasses.sSortDesc :\n", "\t\t\t\t\t\t\t\tcolumn.sSortingClass\n", "\t\t\t\t\t\t);\n", "\t\t\t\t} );\n", "\t\t\t},\n", "\t\n", "\t\t\tjqueryui: function ( settings, cell, column, classes ) {\n", "\t\t\t\t$('<div/>')\n", "\t\t\t\t\t.addClass( classes.sSortJUIWrapper )\n", "\t\t\t\t\t.append( cell.contents() )\n", "\t\t\t\t\t.append( $('<span/>')\n", "\t\t\t\t\t\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\n", "\t\t\t\t\t)\n", "\t\t\t\t\t.appendTo( cell );\n", "\t\n", "\t\t\t\t// Attach a sort listener to update on sort\n", "\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n", "\t\t\t\t\tif ( settings !== ctx ) {\n", "\t\t\t\t\t\treturn;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tvar colIdx = column.idx;\n", "\t\n", "\t\t\t\t\tcell\n", "\t\t\t\t\t\t.removeClass( classes.sSortAsc +\" \"+classes.sSortDesc )\n", "\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n", "\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n", "\t\t\t\t\t\t\t\tclasses.sSortDesc :\n", "\t\t\t\t\t\t\t\tcolumn.sSortingClass\n", "\t\t\t\t\t\t);\n", "\t\n", "\t\t\t\t\tcell\n", "\t\t\t\t\t\t.find( 'span.'+classes.sSortIcon )\n", "\t\t\t\t\t\t.removeClass(\n", "\t\t\t\t\t\t\tclasses.sSortJUIAsc +\" \"+\n", "\t\t\t\t\t\t\tclasses.sSortJUIDesc +\" \"+\n", "\t\t\t\t\t\t\tclasses.sSortJUI +\" \"+\n", "\t\t\t\t\t\t\tclasses.sSortJUIAscAllowed +\" \"+\n", "\t\t\t\t\t\t\tclasses.sSortJUIDescAllowed\n", "\t\t\t\t\t\t)\n", "\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n", "\t\t\t\t\t\t\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\n", "\t\t\t\t\t\t\t\tclasses.sSortJUIDesc :\n", "\t\t\t\t\t\t\t\tcolumn.sSortingClassJUI\n", "\t\t\t\t\t\t);\n", "\t\t\t\t} );\n", "\t\t\t}\n", "\t\t}\n", "\t} );\n", "\t\n", "\t/*\n", "\t * Public helper functions. These aren't used internally by DataTables, or\n", "\t * called by any of the options passed into DataTables, but they can be used\n", "\t * externally by developers working with DataTables. They are helper functions\n", "\t * to make working with DataTables a little bit easier.\n", "\t */\n", "\t\n", "\tvar __htmlEscapeEntities = function ( d ) {\n", "\t\treturn typeof d === 'string' ?\n", "\t\t\td.replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"') :\n", "\t\t\td;\n", "\t};\n", "\t\n", "\t/**\n", "\t * Helpers for `columns.render`.\n", "\t *\n", "\t * The options defined here can be used with the `columns.render` initialisation\n", "\t * option to provide a display renderer. The following functions are defined:\n", "\t *\n", "\t * * `number` - Will format numeric data (defined by `columns.data`) for\n", "\t * display, retaining the original unformatted data for sorting and filtering.\n", "\t * It takes 5 parameters:\n", "\t * * `string` - Thousands grouping separator\n", "\t * * `string` - Decimal point indicator\n", "\t * * `integer` - Number of decimal points to show\n", "\t * * `string` (optional) - Prefix.\n", "\t * * `string` (optional) - Postfix (/suffix).\n", "\t * * `text` - Escape HTML to help prevent XSS attacks. It has no optional\n", "\t * parameters.\n", "\t *\n", "\t * @example\n", "\t * // Column definition using the number renderer\n", "\t * {\n", "\t * data: \"salary\",\n", "\t * render: $.fn.dataTable.render.number( '\\'', '.', 0, '$' )\n", "\t * }\n", "\t *\n", "\t * @namespace\n", "\t */\n", "\tDataTable.render = {\n", "\t\tnumber: function ( thousands, decimal, precision, prefix, postfix ) {\n", "\t\t\treturn {\n", "\t\t\t\tdisplay: function ( d ) {\n", "\t\t\t\t\tif ( typeof d !== 'number' && typeof d !== 'string' ) {\n", "\t\t\t\t\t\treturn d;\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tvar negative = d < 0 ? '-' : '';\n", "\t\t\t\t\tvar flo = parseFloat( d );\n", "\t\n", "\t\t\t\t\t// If NaN then there isn't much formatting that we can do - just\n", "\t\t\t\t\t// return immediately, escaping any HTML (this was supposed to\n", "\t\t\t\t\t// be a number after all)\n", "\t\t\t\t\tif ( isNaN( flo ) ) {\n", "\t\t\t\t\t\treturn __htmlEscapeEntities( d );\n", "\t\t\t\t\t}\n", "\t\n", "\t\t\t\t\tflo = flo.toFixed( precision );\n", "\t\t\t\t\td = Math.abs( flo );\n", "\t\n", "\t\t\t\t\tvar intPart = parseInt( d, 10 );\n", "\t\t\t\t\tvar floatPart = precision ?\n", "\t\t\t\t\t\tdecimal+(d - intPart).toFixed( precision ).substring( 2 ):\n", "\t\t\t\t\t\t'';\n", "\t\n", "\t\t\t\t\treturn negative + (prefix||'') +\n", "\t\t\t\t\t\tintPart.toString().replace(\n", "\t\t\t\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g, thousands\n", "\t\t\t\t\t\t) +\n", "\t\t\t\t\t\tfloatPart +\n", "\t\t\t\t\t\t(postfix||'');\n", "\t\t\t\t}\n", "\t\t\t};\n", "\t\t},\n", "\t\n", "\t\ttext: function () {\n", "\t\t\treturn {\n", "\t\t\t\tdisplay: __htmlEscapeEntities\n", "\t\t\t};\n", "\t\t}\n", "\t};\n", "\t\n", "\t\n", "\t/*\n", "\t * This is really a good bit rubbish this method of exposing the internal methods\n", "\t * publicly... - To be fixed in 2.0 using methods on the prototype\n", "\t */\n", "\t\n", "\t\n", "\t/**\n", "\t * Create a wrapper function for exporting an internal functions to an external API.\n", "\t * @param {string} fn API function name\n", "\t * @returns {function} wrapped function\n", "\t * @memberof DataTable#internal\n", "\t */\n", "\tfunction _fnExternApiFunc (fn)\n", "\t{\n", "\t\treturn function() {\n", "\t\t\tvar args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(\n", "\t\t\t\tArray.prototype.slice.call(arguments)\n", "\t\t\t);\n", "\t\t\treturn DataTable.ext.internal[fn].apply( this, args );\n", "\t\t};\n", "\t}\n", "\t\n", "\t\n", "\t/**\n", "\t * Reference to internal functions for use by plug-in developers. Note that\n", "\t * these methods are references to internal functions and are considered to be\n", "\t * private. If you use these methods, be aware that they are liable to change\n", "\t * between versions.\n", "\t * @namespace\n", "\t */\n", "\t$.extend( DataTable.ext.internal, {\n", "\t\t_fnExternApiFunc: _fnExternApiFunc,\n", "\t\t_fnBuildAjax: _fnBuildAjax,\n", "\t\t_fnAjaxUpdate: _fnAjaxUpdate,\n", "\t\t_fnAjaxParameters: _fnAjaxParameters,\n", "\t\t_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,\n", "\t\t_fnAjaxDataSrc: _fnAjaxDataSrc,\n", "\t\t_fnAddColumn: _fnAddColumn,\n", "\t\t_fnColumnOptions: _fnColumnOptions,\n", "\t\t_fnAdjustColumnSizing: _fnAdjustColumnSizing,\n", "\t\t_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,\n", "\t\t_fnColumnIndexToVisible: _fnColumnIndexToVisible,\n", "\t\t_fnVisbleColumns: _fnVisbleColumns,\n", "\t\t_fnGetColumns: _fnGetColumns,\n", "\t\t_fnColumnTypes: _fnColumnTypes,\n", "\t\t_fnApplyColumnDefs: _fnApplyColumnDefs,\n", "\t\t_fnHungarianMap: _fnHungarianMap,\n", "\t\t_fnCamelToHungarian: _fnCamelToHungarian,\n", "\t\t_fnLanguageCompat: _fnLanguageCompat,\n", "\t\t_fnBrowserDetect: _fnBrowserDetect,\n", "\t\t_fnAddData: _fnAddData,\n", "\t\t_fnAddTr: _fnAddTr,\n", "\t\t_fnNodeToDataIndex: _fnNodeToDataIndex,\n", "\t\t_fnNodeToColumnIndex: _fnNodeToColumnIndex,\n", "\t\t_fnGetCellData: _fnGetCellData,\n", "\t\t_fnSetCellData: _fnSetCellData,\n", "\t\t_fnSplitObjNotation: _fnSplitObjNotation,\n", "\t\t_fnGetObjectDataFn: _fnGetObjectDataFn,\n", "\t\t_fnSetObjectDataFn: _fnSetObjectDataFn,\n", "\t\t_fnGetDataMaster: _fnGetDataMaster,\n", "\t\t_fnClearTable: _fnClearTable,\n", "\t\t_fnDeleteIndex: _fnDeleteIndex,\n", "\t\t_fnInvalidate: _fnInvalidate,\n", "\t\t_fnGetRowElements: _fnGetRowElements,\n", "\t\t_fnCreateTr: _fnCreateTr,\n", "\t\t_fnBuildHead: _fnBuildHead,\n", "\t\t_fnDrawHead: _fnDrawHead,\n", "\t\t_fnDraw: _fnDraw,\n", "\t\t_fnReDraw: _fnReDraw,\n", "\t\t_fnAddOptionsHtml: _fnAddOptionsHtml,\n", "\t\t_fnDetectHeader: _fnDetectHeader,\n", "\t\t_fnGetUniqueThs: _fnGetUniqueThs,\n", "\t\t_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,\n", "\t\t_fnFilterComplete: _fnFilterComplete,\n", "\t\t_fnFilterCustom: _fnFilterCustom,\n", "\t\t_fnFilterColumn: _fnFilterColumn,\n", "\t\t_fnFilter: _fnFilter,\n", "\t\t_fnFilterCreateSearch: _fnFilterCreateSearch,\n", "\t\t_fnEscapeRegex: _fnEscapeRegex,\n", "\t\t_fnFilterData: _fnFilterData,\n", "\t\t_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,\n", "\t\t_fnUpdateInfo: _fnUpdateInfo,\n", "\t\t_fnInfoMacros: _fnInfoMacros,\n", "\t\t_fnInitialise: _fnInitialise,\n", "\t\t_fnInitComplete: _fnInitComplete,\n", "\t\t_fnLengthChange: _fnLengthChange,\n", "\t\t_fnFeatureHtmlLength: _fnFeatureHtmlLength,\n", "\t\t_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,\n", "\t\t_fnPageChange: _fnPageChange,\n", "\t\t_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,\n", "\t\t_fnProcessingDisplay: _fnProcessingDisplay,\n", "\t\t_fnFeatureHtmlTable: _fnFeatureHtmlTable,\n", "\t\t_fnScrollDraw: _fnScrollDraw,\n", "\t\t_fnApplyToChildren: _fnApplyToChildren,\n", "\t\t_fnCalculateColumnWidths: _fnCalculateColumnWidths,\n", "\t\t_fnThrottle: _fnThrottle,\n", "\t\t_fnConvertToWidth: _fnConvertToWidth,\n", "\t\t_fnGetWidestNode: _fnGetWidestNode,\n", "\t\t_fnGetMaxLenString: _fnGetMaxLenString,\n", "\t\t_fnStringToCss: _fnStringToCss,\n", "\t\t_fnSortFlatten: _fnSortFlatten,\n", "\t\t_fnSort: _fnSort,\n", "\t\t_fnSortAria: _fnSortAria,\n", "\t\t_fnSortListener: _fnSortListener,\n", "\t\t_fnSortAttachListener: _fnSortAttachListener,\n", "\t\t_fnSortingClasses: _fnSortingClasses,\n", "\t\t_fnSortData: _fnSortData,\n", "\t\t_fnSaveState: _fnSaveState,\n", "\t\t_fnLoadState: _fnLoadState,\n", "\t\t_fnSettingsFromNode: _fnSettingsFromNode,\n", "\t\t_fnLog: _fnLog,\n", "\t\t_fnMap: _fnMap,\n", "\t\t_fnBindAction: _fnBindAction,\n", "\t\t_fnCallbackReg: _fnCallbackReg,\n", "\t\t_fnCallbackFire: _fnCallbackFire,\n", "\t\t_fnLengthOverflow: _fnLengthOverflow,\n", "\t\t_fnRenderer: _fnRenderer,\n", "\t\t_fnDataSource: _fnDataSource,\n", "\t\t_fnRowAttributes: _fnRowAttributes,\n", "\t\t_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant\n", "\t\t // in 1.10, so this dead-end function is\n", "\t\t // added to prevent errors\n", "\t} );\n", "\t\n", "\n", "\t// jQuery access\n", "\t$.fn.dataTable = DataTable;\n", "\n", "\t// Provide access to the host jQuery object (circular reference)\n", "\tDataTable.$ = $;\n", "\n", "\t// Legacy aliases\n", "\t$.fn.dataTableSettings = DataTable.settings;\n", "\t$.fn.dataTableExt = DataTable.ext;\n", "\n", "\t// With a capital `D` we return a DataTables API instance rather than a\n", "\t// jQuery object\n", "\t$.fn.DataTable = function ( opts ) {\n", "\t\treturn $(this).dataTable( opts ).api();\n", "\t};\n", "\n", "\t// All properties that are available to $.fn.dataTable should also be\n", "\t// available on $.fn.DataTable\n", "\t$.each( DataTable, function ( prop, val ) {\n", "\t\t$.fn.DataTable[ prop ] = val;\n", "\t} );\n", "\n", "\n", "\t// Information about events fired by DataTables - for documentation.\n", "\t/**\n", "\t * Draw event, fired whenever the table is redrawn on the page, at the same\n", "\t * point as fnDrawCallback. This may be useful for binding events or\n", "\t * performing calculations when the table is altered at all.\n", "\t * @name DataTable#draw.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t */\n", "\n", "\t/**\n", "\t * Search event, fired when the searching applied to the table (using the\n", "\t * built-in global search, or column filters) is altered.\n", "\t * @name DataTable#search.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t */\n", "\n", "\t/**\n", "\t * Page change event, fired when the paging of the table is altered.\n", "\t * @name DataTable#page.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t */\n", "\n", "\t/**\n", "\t * Order event, fired when the ordering applied to the table is altered.\n", "\t * @name DataTable#order.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t */\n", "\n", "\t/**\n", "\t * DataTables initialisation complete event, fired when the table is fully\n", "\t * drawn, including Ajax data loaded, if Ajax data is required.\n", "\t * @name DataTable#init.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} oSettings DataTables settings object\n", "\t * @param {object} json The JSON object request from the server - only\n", "\t * present if client-side Ajax sourced data is used</li></ol>\n", "\t */\n", "\n", "\t/**\n", "\t * State save event, fired when the table has changed state a new state save\n", "\t * is required. This event allows modification of the state saving object\n", "\t * prior to actually doing the save, including addition or other state\n", "\t * properties (for plug-ins) or modification of a DataTables core property.\n", "\t * @name DataTable#stateSaveParams.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} oSettings DataTables settings object\n", "\t * @param {object} json The state information to be saved\n", "\t */\n", "\n", "\t/**\n", "\t * State load event, fired when the table is loading state from the stored\n", "\t * data, but prior to the settings object being modified by the saved state\n", "\t * - allowing modification of the saved state is required or loading of\n", "\t * state for a plug-in.\n", "\t * @name DataTable#stateLoadParams.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} oSettings DataTables settings object\n", "\t * @param {object} json The saved state information\n", "\t */\n", "\n", "\t/**\n", "\t * State loaded event, fired when state has been loaded from stored data and\n", "\t * the settings object has been modified by the loaded data.\n", "\t * @name DataTable#stateLoaded.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} oSettings DataTables settings object\n", "\t * @param {object} json The saved state information\n", "\t */\n", "\n", "\t/**\n", "\t * Processing event, fired when DataTables is doing some kind of processing\n", "\t * (be it, order, searcg or anything else). It can be used to indicate to\n", "\t * the end user that there is something happening, or that something has\n", "\t * finished.\n", "\t * @name DataTable#processing.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} oSettings DataTables settings object\n", "\t * @param {boolean} bShow Flag for if DataTables is doing processing or not\n", "\t */\n", "\n", "\t/**\n", "\t * Ajax (XHR) event, fired whenever an Ajax request is completed from a\n", "\t * request to made to the server for new data. This event is called before\n", "\t * DataTables processed the returned data, so it can also be used to pre-\n", "\t * process the data returned from the server, if needed.\n", "\t *\n", "\t * Note that this trigger is called in `fnServerData`, if you override\n", "\t * `fnServerData` and which to use this event, you need to trigger it in you\n", "\t * success function.\n", "\t * @name DataTable#xhr.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t * @param {object} json JSON returned from the server\n", "\t *\n", "\t * @example\n", "\t * // Use a custom property returned from the server in another DOM element\n", "\t * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n", "\t * $('#status').html( json.status );\n", "\t * } );\n", "\t *\n", "\t * @example\n", "\t * // Pre-process the data returned from the server\n", "\t * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n", "\t * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {\n", "\t * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;\n", "\t * }\n", "\t * // Note no return - manipulate the data directly in the JSON object.\n", "\t * } );\n", "\t */\n", "\n", "\t/**\n", "\t * Destroy event, fired when the DataTable is destroyed by calling fnDestroy\n", "\t * or passing the bDestroy:true parameter in the initialisation object. This\n", "\t * can be used to remove bound events, added DOM nodes, etc.\n", "\t * @name DataTable#destroy.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t */\n", "\n", "\t/**\n", "\t * Page length change event, fired when number of records to show on each\n", "\t * page (the length) is changed.\n", "\t * @name DataTable#length.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t * @param {integer} len New length\n", "\t */\n", "\n", "\t/**\n", "\t * Column sizing has changed.\n", "\t * @name DataTable#column-sizing.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t */\n", "\n", "\t/**\n", "\t * Column visibility has changed.\n", "\t * @name DataTable#column-visibility.dt\n", "\t * @event\n", "\t * @param {event} e jQuery event object\n", "\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n", "\t * @param {int} column Column index\n", "\t * @param {bool} vis `false` if column now hidden, or `true` if visible\n", "\t */\n", "\n", "\treturn $.fn.dataTable;\n", "}));\n", "\n", " /* END jquery.dataTables.js*/\n", "\n", "\n", "var event = document.createEvent(\"HTMLEvents\");\n", "event.initEvent(\"load_datatables\", false, false);\n", "window.dispatchEvent(event);\n", "console.log(\"Finish loading datatables js files\");\n", "\n" ], "text/plain": [ "\"\\n /* BEGIN jquery.dataTables.js */\\n\\n/*! DataTables 1.10.16-dev\\n * ©2008-2017 SpryMedia Ltd - datatables.net/license\\n */\\n\\n/**\\n * @summary DataTables\\n * @description Paginate, search and order HTML tables\\n * @version 1.10.16-dev\\n * @file jquery.dataTables.js\\n * @author SpryMedia Ltd\\n * @contact www.datatables.net\\n * @copyright Copyright 2008-2017 SpryMedia Ltd.\\n *\\n * This source file is free software, available under the following license:\\n * MIT license - http://datatables.net/license\\n *\\n * This source file is distributed in the hope that it will be useful, but\\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\\n *\\n * For details please refer to: http://www.datatables.net\\n */\\n\\n/*jslint evil: true, undef: true, browser: true */\\n/*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*/\\n\\n(function( factory ) {\\n\\t\\\"use strict\\\";\\n\\n\\tif ( typeof define === 'function' && define.amd ) {\\n\\t\\t// AMD\\n\\t\\tdefine( ['jquery'], function ( $ ) {\\n\\t\\t\\treturn factory( $, window, document );\\n\\t\\t} );\\n\\t}\\n\\telse if ( typeof exports === 'object' ) {\\n\\t\\t// CommonJS\\n\\t\\tmodule.exports = function (root, $) {\\n\\t\\t\\tif ( ! root ) {\\n\\t\\t\\t\\t// CommonJS environments without a window global must pass a\\n\\t\\t\\t\\t// root. This will give an error otherwise\\n\\t\\t\\t\\troot = window;\\n\\t\\t\\t}\\n\\n\\t\\t\\tif ( ! $ ) {\\n\\t\\t\\t\\t$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window\\n\\t\\t\\t\\t\\trequire('jquery') :\\n\\t\\t\\t\\t\\trequire('jquery')( root );\\n\\t\\t\\t}\\n\\n\\t\\t\\treturn factory( $, root, root.document );\\n\\t\\t};\\n\\t}\\n\\telse {\\n\\t\\t// Browser\\n\\t\\tfactory( jQuery, window, document );\\n\\t}\\n}\\n(function( $, window, document, undefined ) {\\n\\t\\\"use strict\\\";\\n\\n\\t/**\\n\\t * DataTables is a plug-in for the jQuery Javascript library. It is a highly\\n\\t * flexible tool, based upon the foundations of progressive enhancement,\\n\\t * which will add advanced interaction controls to any HTML table. For a\\n\\t * full list of features please refer to\\n\\t * [DataTables.net](href=\\\"http://datatables.net).\\n\\t *\\n\\t * Note that the `DataTable` object is not a global variable but is aliased\\n\\t * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may\\n\\t * be accessed.\\n\\t *\\n\\t * @class\\n\\t * @param {object} [init={}] Configuration object for DataTables. Options\\n\\t * are defined by {@link DataTable.defaults}\\n\\t * @requires jQuery 1.7+\\n\\t *\\n\\t * @example\\n\\t * // Basic initialisation\\n\\t * $(document).ready( function {\\n\\t * $('#example').dataTable();\\n\\t * } );\\n\\t *\\n\\t * @example\\n\\t * // Initialisation with configuration options - in this case, disable\\n\\t * // pagination and sorting.\\n\\t * $(document).ready( function {\\n\\t * $('#example').dataTable( {\\n\\t * \\\"paginate\\\": false,\\n\\t * \\\"sort\\\": false\\n\\t * } );\\n\\t * } );\\n\\t */\\n\\tvar DataTable = function ( options )\\n\\t{\\n\\t\\t/**\\n\\t\\t * Perform a jQuery selector action on the table's TR elements (from the tbody) and\\n\\t\\t * return the resulting jQuery object.\\n\\t\\t * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\\n\\t\\t * @param {object} [oOpts] Optional parameters for modifying the rows to be included\\n\\t\\t * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter\\n\\t\\t * criterion (\\\"applied\\\") or all TR elements (i.e. no filter).\\n\\t\\t * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.\\n\\t\\t * Can be either 'current', whereby the current sorting of the table is used, or\\n\\t\\t * 'original' whereby the original order the data was read into the table is used.\\n\\t\\t * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\\n\\t\\t * (\\\"current\\\") or not (\\\"all\\\"). If 'current' is given, then order is assumed to be\\n\\t\\t * 'current' and filter is 'applied', regardless of what they might be given as.\\n\\t\\t * @returns {object} jQuery object, filtered by the given selector.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Highlight every second row\\n\\t\\t * oTable.$('tr:odd').css('backgroundColor', 'blue');\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Filter to rows with 'Webkit' in them, add a background colour and then\\n\\t\\t * // remove the filter, thus highlighting the 'Webkit' rows only.\\n\\t\\t * oTable.fnFilter('Webkit');\\n\\t\\t * oTable.$('tr', {\\\"search\\\": \\\"applied\\\"}).css('backgroundColor', 'blue');\\n\\t\\t * oTable.fnFilter('');\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.$ = function ( sSelector, oOpts )\\n\\t\\t{\\n\\t\\t\\treturn this.api(true).$( sSelector, oOpts );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Almost identical to $ in operation, but in this case returns the data for the matched\\n\\t\\t * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes\\n\\t\\t * rather than any descendants, so the data can be obtained for the row/cell. If matching\\n\\t\\t * rows are found, the data returned is the original data array/object that was used to\\n\\t\\t * create the row (or a generated array if from a DOM source).\\n\\t\\t *\\n\\t\\t * This method is often useful in-combination with $ where both functions are given the\\n\\t\\t * same parameters and the array indexes will match identically.\\n\\t\\t * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\\n\\t\\t * @param {object} [oOpts] Optional parameters for modifying the rows to be included\\n\\t\\t * @param {string} [oOpts.filter=none] Select elements that meet the current filter\\n\\t\\t * criterion (\\\"applied\\\") or all elements (i.e. no filter).\\n\\t\\t * @param {string} [oOpts.order=current] Order of the data in the processed array.\\n\\t\\t * Can be either 'current', whereby the current sorting of the table is used, or\\n\\t\\t * 'original' whereby the original order the data was read into the table is used.\\n\\t\\t * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\\n\\t\\t * (\\\"current\\\") or not (\\\"all\\\"). If 'current' is given, then order is assumed to be\\n\\t\\t * 'current' and filter is 'applied', regardless of what they might be given as.\\n\\t\\t * @returns {array} Data for the matched elements. If any elements, as a result of the\\n\\t\\t * selector, were not TR, TD or TH elements in the DataTable, they will have a null\\n\\t\\t * entry in the array.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Get the data from the first row in the table\\n\\t\\t * var data = oTable._('tr:first');\\n\\t\\t *\\n\\t\\t * // Do something useful with the data\\n\\t\\t * alert( \\\"First cell is: \\\"+data[0] );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Filter to 'Webkit' and get all data for\\n\\t\\t * oTable.fnFilter('Webkit');\\n\\t\\t * var data = oTable._('tr', {\\\"search\\\": \\\"applied\\\"});\\n\\t\\t *\\n\\t\\t * // Do something with the data\\n\\t\\t * alert( data.length+\\\" rows matched the search\\\" );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis._ = function ( sSelector, oOpts )\\n\\t\\t{\\n\\t\\t\\treturn this.api(true).rows( sSelector, oOpts ).data();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Create a DataTables Api instance, with the currently selected tables for\\n\\t\\t * the Api's context.\\n\\t\\t * @param {boolean} [traditional=false] Set the API instance's context to be\\n\\t\\t * only the table referred to by the `DataTable.ext.iApiIndex` option, as was\\n\\t\\t * used in the API presented by DataTables 1.9- (i.e. the traditional mode),\\n\\t\\t * or if all tables captured in the jQuery object should be used.\\n\\t\\t * @return {DataTables.Api}\\n\\t\\t */\\n\\t\\tthis.api = function ( traditional )\\n\\t\\t{\\n\\t\\t\\treturn traditional ?\\n\\t\\t\\t\\tnew _Api(\\n\\t\\t\\t\\t\\t_fnSettingsFromNode( this[ _ext.iApiIndex ] )\\n\\t\\t\\t\\t) :\\n\\t\\t\\t\\tnew _Api( this );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Add a single new row or multiple rows of data to the table. Please note\\n\\t\\t * that this is suitable for client-side processing only - if you are using\\n\\t\\t * server-side processing (i.e. \\\"bServerSide\\\": true), then to add data, you\\n\\t\\t * must add it to the data source, i.e. the server-side, through an Ajax call.\\n\\t\\t * @param {array|object} data The data to be added to the table. This can be:\\n\\t\\t * <ul>\\n\\t\\t * <li>1D array of data - add a single row with the data provided</li>\\n\\t\\t * <li>2D array of arrays - add multiple rows in a single call</li>\\n\\t\\t * <li>object - data object when using <i>mData</i></li>\\n\\t\\t * <li>array of objects - multiple data objects when using <i>mData</i></li>\\n\\t\\t * </ul>\\n\\t\\t * @param {bool} [redraw=true] redraw the table or not\\n\\t\\t * @returns {array} An array of integers, representing the list of indexes in\\n\\t\\t * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to\\n\\t\\t * the table.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Global var for counter\\n\\t\\t * var giCount = 2;\\n\\t\\t *\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * function fnClickAddRow() {\\n\\t\\t * $('#example').dataTable().fnAddData( [\\n\\t\\t * giCount+\\\".1\\\",\\n\\t\\t * giCount+\\\".2\\\",\\n\\t\\t * giCount+\\\".3\\\",\\n\\t\\t * giCount+\\\".4\\\" ]\\n\\t\\t * );\\n\\t\\t *\\n\\t\\t * giCount++;\\n\\t\\t * }\\n\\t\\t */\\n\\t\\tthis.fnAddData = function( data, redraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\t/* Check if we want to add multiple rows or not */\\n\\t\\t\\tvar rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\\n\\t\\t\\t\\tapi.rows.add( data ) :\\n\\t\\t\\t\\tapi.row.add( data );\\n\\t\\t\\n\\t\\t\\tif ( redraw === undefined || redraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\treturn rows.flatten().toArray();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * This function will make DataTables recalculate the column sizes, based on the data\\n\\t\\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\\n\\t\\t * through the sWidth parameter). This can be useful when the width of the table's\\n\\t\\t * parent element changes (for example a window resize).\\n\\t\\t * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable( {\\n\\t\\t * \\\"sScrollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"bPaginate\\\": false\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * $(window).on('resize', function () {\\n\\t\\t * oTable.fnAdjustColumnSizing();\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnAdjustColumnSizing = function ( bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).columns.adjust();\\n\\t\\t\\tvar settings = api.settings()[0];\\n\\t\\t\\tvar scroll = settings.oScroll;\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw( false );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( scroll.sX !== \\\"\\\" || scroll.sY !== \\\"\\\" ) {\\n\\t\\t\\t\\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\\n\\t\\t\\t\\t_fnScrollDraw( settings );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Quickly and simply clear a table\\n\\t\\t * @param {bool} [bRedraw=true] redraw the table or not\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\\n\\t\\t * oTable.fnClearTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnClearTable = function( bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).clear();\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * The exact opposite of 'opening' a row, this function will close any rows which\\n\\t\\t * are currently 'open'.\\n\\t\\t * @param {node} nTr the table row to 'close'\\n\\t\\t * @returns {int} 0 on success, or 1 if failed (can't find the row)\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable;\\n\\t\\t *\\n\\t\\t * // 'open' an information row when a row is clicked on\\n\\t\\t * $('#example tbody tr').click( function () {\\n\\t\\t * if ( oTable.fnIsOpen(this) ) {\\n\\t\\t * oTable.fnClose( this );\\n\\t\\t * } else {\\n\\t\\t * oTable.fnOpen( this, \\\"Temporary row opened\\\", \\\"info_row\\\" );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnClose = function( nTr )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).row( nTr ).child.hide();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Remove a row for the table\\n\\t\\t * @param {mixed} target The index of the row from aoData to be deleted, or\\n\\t\\t * the TR element you want to delete\\n\\t\\t * @param {function|null} [callBack] Callback function\\n\\t\\t * @param {bool} [redraw=true] Redraw the table or not\\n\\t\\t * @returns {array} The row that was deleted\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Immediately remove the first row\\n\\t\\t * oTable.fnDeleteRow( 0 );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnDeleteRow = function( target, callback, redraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\tvar rows = api.rows( target );\\n\\t\\t\\tvar settings = rows.settings()[0];\\n\\t\\t\\tvar data = settings.aoData[ rows[0][0] ];\\n\\t\\t\\n\\t\\t\\trows.remove();\\n\\t\\t\\n\\t\\t\\tif ( callback ) {\\n\\t\\t\\t\\tcallback.call( this, settings, data );\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tif ( redraw === undefined || redraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\treturn data;\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Restore the table to it's original state in the DOM by removing all of DataTables\\n\\t\\t * enhancements, alterations to the DOM structure of the table and event listeners.\\n\\t\\t * @param {boolean} [remove=false] Completely remove the table from the DOM\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * // This example is fairly pointless in reality, but shows how fnDestroy can be used\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * oTable.fnDestroy();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnDestroy = function ( remove )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).destroy( remove );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Redraw the table\\n\\t\\t * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\\n\\t\\t * oTable.fnDraw();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnDraw = function( complete )\\n\\t\\t{\\n\\t\\t\\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\\n\\t\\t\\t// into account the new data, but can hold position.\\n\\t\\t\\tthis.api( true ).draw( complete );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Filter the input based on data\\n\\t\\t * @param {string} sInput String to filter the table on\\n\\t\\t * @param {int|null} [iColumn] Column to limit filtering to\\n\\t\\t * @param {bool} [bRegex=false] Treat as regular expression or not\\n\\t\\t * @param {bool} [bSmart=true] Perform smart filtering or not\\n\\t\\t * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\\n\\t\\t * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Sometime later - filter...\\n\\t\\t * oTable.fnFilter( 'test string' );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\tif ( iColumn === null || iColumn === undefined ) {\\n\\t\\t\\t\\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tapi.draw();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get the data for the whole table, an individual row or an individual cell based on the\\n\\t\\t * provided parameters.\\n\\t\\t * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\\n\\t\\t * a TR node then the data source for the whole row will be returned. If given as a\\n\\t\\t * TD/TH cell node then iCol will be automatically calculated and the data for the\\n\\t\\t * cell returned. If given as an integer, then this is treated as the aoData internal\\n\\t\\t * data index for the row (see fnGetPosition) and the data for that row used.\\n\\t\\t * @param {int} [col] Optional column index that you want the data of.\\n\\t\\t * @returns {array|object|string} If mRow is undefined, then the data for all rows is\\n\\t\\t * returned. If mRow is defined, just data for that row, and is iCol is\\n\\t\\t * defined, only data for the designated cell is returned.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Row data\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * oTable.$('tr').click( function () {\\n\\t\\t * var data = oTable.fnGetData( this );\\n\\t\\t * // ... do something with the array / object of data for the row\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Individual cell data\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * oTable.$('td').click( function () {\\n\\t\\t * var sData = oTable.fnGetData( this );\\n\\t\\t * alert( 'The cell clicked on had the value of '+sData );\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnGetData = function( src, col )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\tif ( src !== undefined ) {\\n\\t\\t\\t\\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\\n\\t\\t\\n\\t\\t\\t\\treturn col !== undefined || type == 'td' || type == 'th' ?\\n\\t\\t\\t\\t\\tapi.cell( src, col ).data() :\\n\\t\\t\\t\\t\\tapi.row( src ).data() || null;\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\treturn api.data().toArray();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get an array of the TR nodes that are used in the table's body. Note that you will\\n\\t\\t * typically want to use the '$' API method in preference to this as it is more\\n\\t\\t * flexible.\\n\\t\\t * @param {int} [iRow] Optional row index for the TR element you want\\n\\t\\t * @returns {array|node} If iRow is undefined, returns an array of all TR elements\\n\\t\\t * in the table's body, or iRow is defined, just the TR element requested.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Get the nodes from the table\\n\\t\\t * var nNodes = oTable.fnGetNodes( );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnGetNodes = function( iRow )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\treturn iRow !== undefined ?\\n\\t\\t\\t\\tapi.row( iRow ).node() :\\n\\t\\t\\t\\tapi.rows().nodes().flatten().toArray();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get the array indexes of a particular cell from it's DOM element\\n\\t\\t * and column index including hidden columns\\n\\t\\t * @param {node} node this can either be a TR, TD or TH in the table's body\\n\\t\\t * @returns {int} If nNode is given as a TR, then a single index is returned, or\\n\\t\\t * if given as a cell, an array of [row index, column index (visible),\\n\\t\\t * column index (all)] is given.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * $('#example tbody td').click( function () {\\n\\t\\t * // Get the position of the current data from the node\\n\\t\\t * var aPos = oTable.fnGetPosition( this );\\n\\t\\t *\\n\\t\\t * // Get the data array for this row\\n\\t\\t * var aData = oTable.fnGetData( aPos[0] );\\n\\t\\t *\\n\\t\\t * // Update the data array and return the value\\n\\t\\t * aData[ aPos[1] ] = 'clicked';\\n\\t\\t * this.innerHTML = 'clicked';\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * // Init DataTables\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnGetPosition = function( node )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\tvar nodeName = node.nodeName.toUpperCase();\\n\\t\\t\\n\\t\\t\\tif ( nodeName == 'TR' ) {\\n\\t\\t\\t\\treturn api.row( node ).index();\\n\\t\\t\\t}\\n\\t\\t\\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\\n\\t\\t\\t\\tvar cell = api.cell( node ).index();\\n\\t\\t\\n\\t\\t\\t\\treturn [\\n\\t\\t\\t\\t\\tcell.row,\\n\\t\\t\\t\\t\\tcell.columnVisible,\\n\\t\\t\\t\\t\\tcell.column\\n\\t\\t\\t\\t];\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Check to see if a row is 'open' or not.\\n\\t\\t * @param {node} nTr the table row to check\\n\\t\\t * @returns {boolean} true if the row is currently open, false otherwise\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable;\\n\\t\\t *\\n\\t\\t * // 'open' an information row when a row is clicked on\\n\\t\\t * $('#example tbody tr').click( function () {\\n\\t\\t * if ( oTable.fnIsOpen(this) ) {\\n\\t\\t * oTable.fnClose( this );\\n\\t\\t * } else {\\n\\t\\t * oTable.fnOpen( this, \\\"Temporary row opened\\\", \\\"info_row\\\" );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnIsOpen = function( nTr )\\n\\t\\t{\\n\\t\\t\\treturn this.api( true ).row( nTr ).child.isShown();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * This function will place a new row directly after a row which is currently\\n\\t\\t * on display on the page, with the HTML contents that is passed into the\\n\\t\\t * function. This can be used, for example, to ask for confirmation that a\\n\\t\\t * particular record should be deleted.\\n\\t\\t * @param {node} nTr The table row to 'open'\\n\\t\\t * @param {string|node|jQuery} mHtml The HTML to put into the row\\n\\t\\t * @param {string} sClass Class to give the new TD cell\\n\\t\\t * @returns {node} The row opened. Note that if the table row passed in as the\\n\\t\\t * first parameter, is not found in the table, this method will silently\\n\\t\\t * return.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable;\\n\\t\\t *\\n\\t\\t * // 'open' an information row when a row is clicked on\\n\\t\\t * $('#example tbody tr').click( function () {\\n\\t\\t * if ( oTable.fnIsOpen(this) ) {\\n\\t\\t * oTable.fnClose( this );\\n\\t\\t * } else {\\n\\t\\t * oTable.fnOpen( this, \\\"Temporary row opened\\\", \\\"info_row\\\" );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnOpen = function( nTr, mHtml, sClass )\\n\\t\\t{\\n\\t\\t\\treturn this.api( true )\\n\\t\\t\\t\\t.row( nTr )\\n\\t\\t\\t\\t.child( mHtml, sClass )\\n\\t\\t\\t\\t.show()\\n\\t\\t\\t\\t.child()[0];\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Change the pagination - provides the internal logic for pagination in a simple API\\n\\t\\t * function. With this function you can have a DataTables table go to the next,\\n\\t\\t * previous, first or last pages.\\n\\t\\t * @param {string|int} mAction Paging action to take: \\\"first\\\", \\\"previous\\\", \\\"next\\\" or \\\"last\\\"\\n\\t\\t * or page number to jump to (integer), note that page 0 is the first page.\\n\\t\\t * @param {bool} [bRedraw=true] Redraw the table or not\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * oTable.fnPageChange( 'next' );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnPageChange = function ( mAction, bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).page( mAction );\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw(false);\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Show a particular column\\n\\t\\t * @param {int} iCol The column whose display should be changed\\n\\t\\t * @param {bool} bShow Show (true) or hide (false) the column\\n\\t\\t * @param {bool} [bRedraw=true] Redraw the table or not\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Hide the second column after initialisation\\n\\t\\t * oTable.fnSetColumnVis( 1, false );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).column( iCol ).visible( bShow );\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.columns.adjust().draw();\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get the settings for a particular table for external manipulation\\n\\t\\t * @returns {object} DataTables settings object. See\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * var oSettings = oTable.fnSettings();\\n\\t\\t *\\n\\t\\t * // Show an example parameter from the settings\\n\\t\\t * alert( oSettings._iDisplayStart );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSettings = function()\\n\\t\\t{\\n\\t\\t\\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Sort the table by a particular column\\n\\t\\t * @param {int} iCol the data index to sort on. Note that this will not match the\\n\\t\\t * 'display index' if you have hidden data entries\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Sort immediately with columns 0 and 1\\n\\t\\t * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSort = function( aaSort )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).order( aaSort ).draw();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Attach a sort listener to an element for a given column\\n\\t\\t * @param {node} nNode the element to attach the sort listener to\\n\\t\\t * @param {int} iColumn the column that a click on this node will sort on\\n\\t\\t * @param {function} [fnCallback] callback function when sort is run\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Sort on column 1, when 'sorter' is clicked on\\n\\t\\t * oTable.fnSortListener( document.getElementById('sorter'), 1 );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Update a table cell or row - this method will accept either a single value to\\n\\t\\t * update the cell with, an array of values with one element for each column or\\n\\t\\t * an object in the same format as the original data source. The function is\\n\\t\\t * self-referencing in order to make the multi column updates easier.\\n\\t\\t * @param {object|array|string} mData Data to update the cell/row with\\n\\t\\t * @param {node|int} mRow TR element you want to update or the aoData index\\n\\t\\t * @param {int} [iColumn] The column to update, give as null or undefined to\\n\\t\\t * update a whole row.\\n\\t\\t * @param {bool} [bRedraw=true] Redraw the table or not\\n\\t\\t * @param {bool} [bAction=true] Perform pre-draw actions or not\\n\\t\\t * @returns {int} 0 on success, 1 on error\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\\n\\t\\t * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\tif ( iColumn === undefined || iColumn === null ) {\\n\\t\\t\\t\\tapi.row( mRow ).data( mData );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tapi.cell( mRow, iColumn ).data( mData );\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tif ( bAction === undefined || bAction ) {\\n\\t\\t\\t\\tapi.columns.adjust();\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t\\treturn 0;\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\\n\\t\\t * to ensure compatibility.\\n\\t\\t * @param {string} sVersion Version string to check for, in the format \\\"X.Y.Z\\\". Note that the\\n\\t\\t * formats \\\"X\\\" and \\\"X.Y\\\" are also acceptable.\\n\\t\\t * @returns {boolean} true if this version of DataTables is greater or equal to the required\\n\\t\\t * version, or false if this version of DataTales is not suitable\\n\\t\\t * @method\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * alert( oTable.fnVersionCheck( '1.9.0' ) );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnVersionCheck = _ext.fnVersionCheck;\\n\\t\\t\\n\\n\\t\\tvar _that = this;\\n\\t\\tvar emptyInit = options === undefined;\\n\\t\\tvar len = this.length;\\n\\n\\t\\tif ( emptyInit ) {\\n\\t\\t\\toptions = {};\\n\\t\\t}\\n\\n\\t\\tthis.oApi = this.internal = _ext.internal;\\n\\n\\t\\t// Extend with old style plug-in API methods\\n\\t\\tfor ( var fn in DataTable.ext.internal ) {\\n\\t\\t\\tif ( fn ) {\\n\\t\\t\\t\\tthis[fn] = _fnExternApiFunc(fn);\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\tthis.each(function() {\\n\\t\\t\\t// For each initialisation we want to give it a clean initialisation\\n\\t\\t\\t// object that can be bashed around\\n\\t\\t\\tvar o = {};\\n\\t\\t\\tvar oInit = len > 1 ? // optimisation for single table case\\n\\t\\t\\t\\t_fnExtend( o, options, true ) :\\n\\t\\t\\t\\toptions;\\n\\n\\t\\t\\t/*global oInit,_that,emptyInit*/\\n\\t\\t\\tvar i=0, iLen, j, jLen, k, kLen;\\n\\t\\t\\tvar sId = this.getAttribute( 'id' );\\n\\t\\t\\tvar bInitHandedOff = false;\\n\\t\\t\\tvar defaults = DataTable.defaults;\\n\\t\\t\\tvar $this = $(this);\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t/* Sanity check */\\n\\t\\t\\tif ( this.nodeName.toLowerCase() != 'table' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Backwards compatibility for the defaults */\\n\\t\\t\\t_fnCompatOpts( defaults );\\n\\t\\t\\t_fnCompatCols( defaults.column );\\n\\t\\t\\t\\n\\t\\t\\t/* Convert the camel-case defaults to Hungarian */\\n\\t\\t\\t_fnCamelToHungarian( defaults, defaults, true );\\n\\t\\t\\t_fnCamelToHungarian( defaults.column, defaults.column, true );\\n\\t\\t\\t\\n\\t\\t\\t/* Setting up the initialisation object */\\n\\t\\t\\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t/* Check to see if we are re-initialising a table */\\n\\t\\t\\tvar allSettings = DataTable.settings;\\n\\t\\t\\tfor ( i=0, iLen=allSettings.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tvar s = allSettings[i];\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Base check on table node */\\n\\t\\t\\t\\tif ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tvar bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;\\n\\t\\t\\t\\t\\tvar bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;\\n\\t\\t\\t\\n\\t\\t\\t\\t\\tif ( emptyInit || bRetrieve )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\treturn s.oInstance;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( bDestroy )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\ts.oInstance.fnDestroy();\\n\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* If the element we are initialising has the same ID as a table which was previously\\n\\t\\t\\t\\t * initialised, but the table nodes don't match (from before) then we destroy the old\\n\\t\\t\\t\\t * instance by simply deleting it. This is under the assumption that the table has been\\n\\t\\t\\t\\t * destroyed by other methods. Anyone using non-id selectors will need to do this manually\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\tif ( s.sTableId == this.id )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tallSettings.splice( i, 1 );\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Ensure the table has an ID - required for accessibility */\\n\\t\\t\\tif ( sId === null || sId === \\\"\\\" )\\n\\t\\t\\t{\\n\\t\\t\\t\\tsId = \\\"DataTables_Table_\\\"+(DataTable.ext._unique++);\\n\\t\\t\\t\\tthis.id = sId;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Create the settings object for this table and set some of the default parameters */\\n\\t\\t\\tvar oSettings = $.extend( true, {}, DataTable.models.oSettings, {\\n\\t\\t\\t\\t\\\"sDestroyWidth\\\": $this[0].style.width,\\n\\t\\t\\t\\t\\\"sInstance\\\": sId,\\n\\t\\t\\t\\t\\\"sTableId\\\": sId\\n\\t\\t\\t} );\\n\\t\\t\\toSettings.nTable = this;\\n\\t\\t\\toSettings.oApi = _that.internal;\\n\\t\\t\\toSettings.oInit = oInit;\\n\\t\\t\\t\\n\\t\\t\\tallSettings.push( oSettings );\\n\\t\\t\\t\\n\\t\\t\\t// Need to add the instance after the instance after the settings object has been added\\n\\t\\t\\t// to the settings array, so we can self reference the table instance if more than one\\n\\t\\t\\toSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();\\n\\t\\t\\t\\n\\t\\t\\t// Backwards compatibility, before we apply all the defaults\\n\\t\\t\\t_fnCompatOpts( oInit );\\n\\t\\t\\t\\n\\t\\t\\tif ( oInit.oLanguage )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnLanguageCompat( oInit.oLanguage );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t// If the length menu is given, but the init display length is not, use the length menu\\n\\t\\t\\tif ( oInit.aLengthMenu && ! oInit.iDisplayLength )\\n\\t\\t\\t{\\n\\t\\t\\t\\toInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?\\n\\t\\t\\t\\t\\toInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t// Apply the defaults and init options to make a single init object will all\\n\\t\\t\\t// options defined from defaults and instance options.\\n\\t\\t\\toInit = _fnExtend( $.extend( true, {}, defaults ), oInit );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t// Map the initialisation options onto the settings object\\n\\t\\t\\t_fnMap( oSettings.oFeatures, oInit, [\\n\\t\\t\\t\\t\\\"bPaginate\\\",\\n\\t\\t\\t\\t\\\"bLengthChange\\\",\\n\\t\\t\\t\\t\\\"bFilter\\\",\\n\\t\\t\\t\\t\\\"bSort\\\",\\n\\t\\t\\t\\t\\\"bSortMulti\\\",\\n\\t\\t\\t\\t\\\"bInfo\\\",\\n\\t\\t\\t\\t\\\"bProcessing\\\",\\n\\t\\t\\t\\t\\\"bAutoWidth\\\",\\n\\t\\t\\t\\t\\\"bSortClasses\\\",\\n\\t\\t\\t\\t\\\"bServerSide\\\",\\n\\t\\t\\t\\t\\\"bDeferRender\\\"\\n\\t\\t\\t] );\\n\\t\\t\\t_fnMap( oSettings, oInit, [\\n\\t\\t\\t\\t\\\"asStripeClasses\\\",\\n\\t\\t\\t\\t\\\"ajax\\\",\\n\\t\\t\\t\\t\\\"fnServerData\\\",\\n\\t\\t\\t\\t\\\"fnFormatNumber\\\",\\n\\t\\t\\t\\t\\\"sServerMethod\\\",\\n\\t\\t\\t\\t\\\"aaSorting\\\",\\n\\t\\t\\t\\t\\\"aaSortingFixed\\\",\\n\\t\\t\\t\\t\\\"aLengthMenu\\\",\\n\\t\\t\\t\\t\\\"sPaginationType\\\",\\n\\t\\t\\t\\t\\\"sAjaxSource\\\",\\n\\t\\t\\t\\t\\\"sAjaxDataProp\\\",\\n\\t\\t\\t\\t\\\"iStateDuration\\\",\\n\\t\\t\\t\\t\\\"sDom\\\",\\n\\t\\t\\t\\t\\\"bSortCellsTop\\\",\\n\\t\\t\\t\\t\\\"iTabIndex\\\",\\n\\t\\t\\t\\t\\\"fnStateLoadCallback\\\",\\n\\t\\t\\t\\t\\\"fnStateSaveCallback\\\",\\n\\t\\t\\t\\t\\\"renderer\\\",\\n\\t\\t\\t\\t\\\"searchDelay\\\",\\n\\t\\t\\t\\t\\\"rowId\\\",\\n\\t\\t\\t\\t[ \\\"iCookieDuration\\\", \\\"iStateDuration\\\" ], // backwards compat\\n\\t\\t\\t\\t[ \\\"oSearch\\\", \\\"oPreviousSearch\\\" ],\\n\\t\\t\\t\\t[ \\\"aoSearchCols\\\", \\\"aoPreSearchCols\\\" ],\\n\\t\\t\\t\\t[ \\\"iDisplayLength\\\", \\\"_iDisplayLength\\\" ]\\n\\t\\t\\t] );\\n\\t\\t\\t_fnMap( oSettings.oScroll, oInit, [\\n\\t\\t\\t\\t[ \\\"sScrollX\\\", \\\"sX\\\" ],\\n\\t\\t\\t\\t[ \\\"sScrollXInner\\\", \\\"sXInner\\\" ],\\n\\t\\t\\t\\t[ \\\"sScrollY\\\", \\\"sY\\\" ],\\n\\t\\t\\t\\t[ \\\"bScrollCollapse\\\", \\\"bCollapse\\\" ]\\n\\t\\t\\t] );\\n\\t\\t\\t_fnMap( oSettings.oLanguage, oInit, \\\"fnInfoCallback\\\" );\\n\\t\\t\\t\\n\\t\\t\\t/* Callback functions which are array driven */\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );\\n\\t\\t\\t\\n\\t\\t\\toSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );\\n\\t\\t\\t\\n\\t\\t\\t/* Browser support detection */\\n\\t\\t\\t_fnBrowserDetect( oSettings );\\n\\t\\t\\t\\n\\t\\t\\tvar oClasses = oSettings.oClasses;\\n\\t\\t\\t\\n\\t\\t\\t$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );\\n\\t\\t\\t$this.addClass( oClasses.sTable );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\tif ( oSettings.iInitDisplayStart === undefined )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Display start point, taking into account the save saving */\\n\\t\\t\\t\\toSettings.iInitDisplayStart = oInit.iDisplayStart;\\n\\t\\t\\t\\toSettings._iDisplayStart = oInit.iDisplayStart;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\tif ( oInit.iDeferLoading !== null )\\n\\t\\t\\t{\\n\\t\\t\\t\\toSettings.bDeferLoading = true;\\n\\t\\t\\t\\tvar tmp = $.isArray( oInit.iDeferLoading );\\n\\t\\t\\t\\toSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;\\n\\t\\t\\t\\toSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Language definitions */\\n\\t\\t\\tvar oLanguage = oSettings.oLanguage;\\n\\t\\t\\t$.extend( true, oLanguage, oInit.oLanguage );\\n\\t\\t\\t\\n\\t\\t\\tif ( oLanguage.sUrl )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Get the language definitions from a file - because this Ajax call makes the language\\n\\t\\t\\t\\t * get async to the remainder of this function we use bInitHandedOff to indicate that\\n\\t\\t\\t\\t * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t$.ajax( {\\n\\t\\t\\t\\t\\tdataType: 'json',\\n\\t\\t\\t\\t\\turl: oLanguage.sUrl,\\n\\t\\t\\t\\t\\tsuccess: function ( json ) {\\n\\t\\t\\t\\t\\t\\t_fnLanguageCompat( json );\\n\\t\\t\\t\\t\\t\\t_fnCamelToHungarian( defaults.oLanguage, json );\\n\\t\\t\\t\\t\\t\\t$.extend( true, oLanguage, json );\\n\\t\\t\\t\\t\\t\\t_fnInitialise( oSettings );\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\terror: function () {\\n\\t\\t\\t\\t\\t\\t// Error occurred loading language file, continue on as best we can\\n\\t\\t\\t\\t\\t\\t_fnInitialise( oSettings );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} );\\n\\t\\t\\t\\tbInitHandedOff = true;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/*\\n\\t\\t\\t * Stripes\\n\\t\\t\\t */\\n\\t\\t\\tif ( oInit.asStripeClasses === null )\\n\\t\\t\\t{\\n\\t\\t\\t\\toSettings.asStripeClasses =[\\n\\t\\t\\t\\t\\toClasses.sStripeOdd,\\n\\t\\t\\t\\t\\toClasses.sStripeEven\\n\\t\\t\\t\\t];\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Remove row stripe classes if they are already on the table row */\\n\\t\\t\\tvar stripeClasses = oSettings.asStripeClasses;\\n\\t\\t\\tvar rowOne = $this.children('tbody').find('tr').eq(0);\\n\\t\\t\\tif ( $.inArray( true, $.map( stripeClasses, function(el, i) {\\n\\t\\t\\t\\treturn rowOne.hasClass(el);\\n\\t\\t\\t} ) ) !== -1 ) {\\n\\t\\t\\t\\t$('tbody tr', this).removeClass( stripeClasses.join(' ') );\\n\\t\\t\\t\\toSettings.asDestroyStripes = stripeClasses.slice();\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/*\\n\\t\\t\\t * Columns\\n\\t\\t\\t * See if we should load columns automatically or use defined ones\\n\\t\\t\\t */\\n\\t\\t\\tvar anThs = [];\\n\\t\\t\\tvar aoColumnsInit;\\n\\t\\t\\tvar nThead = this.getElementsByTagName('thead');\\n\\t\\t\\tif ( nThead.length !== 0 )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnDetectHeader( oSettings.aoHeader, nThead[0] );\\n\\t\\t\\t\\tanThs = _fnGetUniqueThs( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* If not given a column array, generate one with nulls */\\n\\t\\t\\tif ( oInit.aoColumns === null )\\n\\t\\t\\t{\\n\\t\\t\\t\\taoColumnsInit = [];\\n\\t\\t\\t\\tfor ( i=0, iLen=anThs.length ; i<iLen ; i++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taoColumnsInit.push( null );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\telse\\n\\t\\t\\t{\\n\\t\\t\\t\\taoColumnsInit = oInit.aoColumns;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Add the columns */\\n\\t\\t\\tfor ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnAddColumn( oSettings, anThs ? anThs[i] : null );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Apply the column definitions */\\n\\t\\t\\t_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {\\n\\t\\t\\t\\t_fnColumnOptions( oSettings, iCol, oDef );\\n\\t\\t\\t} );\\n\\t\\t\\t\\n\\t\\t\\t/* HTML5 attribute detection - build an mData object automatically if the\\n\\t\\t\\t * attributes are found\\n\\t\\t\\t */\\n\\t\\t\\tif ( rowOne.length ) {\\n\\t\\t\\t\\tvar a = function ( cell, name ) {\\n\\t\\t\\t\\t\\treturn cell.getAttribute( 'data-'+name ) !== null ? name : null;\\n\\t\\t\\t\\t};\\n\\t\\t\\t\\n\\t\\t\\t\\t$( rowOne[0] ).children('th, td').each( function (i, cell) {\\n\\t\\t\\t\\t\\tvar col = oSettings.aoColumns[i];\\n\\t\\t\\t\\n\\t\\t\\t\\t\\tif ( col.mData === i ) {\\n\\t\\t\\t\\t\\t\\tvar sort = a( cell, 'sort' ) || a( cell, 'order' );\\n\\t\\t\\t\\t\\t\\tvar filter = a( cell, 'filter' ) || a( cell, 'search' );\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\tif ( sort !== null || filter !== null ) {\\n\\t\\t\\t\\t\\t\\t\\tcol.mData = {\\n\\t\\t\\t\\t\\t\\t\\t\\t_: i+'.display',\\n\\t\\t\\t\\t\\t\\t\\t\\tsort: sort !== null ? i+'.@data-'+sort : undefined,\\n\\t\\t\\t\\t\\t\\t\\t\\ttype: sort !== null ? i+'.@data-'+sort : undefined,\\n\\t\\t\\t\\t\\t\\t\\t\\tfilter: filter !== null ? i+'.@data-'+filter : undefined\\n\\t\\t\\t\\t\\t\\t\\t};\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t_fnColumnOptions( oSettings, i );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\tvar features = oSettings.oFeatures;\\n\\t\\t\\tvar loadedInit = function () {\\n\\t\\t\\t\\t/*\\n\\t\\t\\t\\t * Sorting\\n\\t\\t\\t\\t * @todo For modularisation (1.11) this needs to do into a sort start up handler\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\n\\t\\t\\t\\t// If aaSorting is not defined, then we use the first indicator in asSorting\\n\\t\\t\\t\\t// in case that has been altered, so the default sort reflects that option\\n\\t\\t\\t\\tif ( oInit.aaSorting === undefined ) {\\n\\t\\t\\t\\t\\tvar sorting = oSettings.aaSorting;\\n\\t\\t\\t\\t\\tfor ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {\\n\\t\\t\\t\\t\\t\\tsorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Do a first pass on the sorting classes (allows any size changes to be taken into\\n\\t\\t\\t\\t * account, and also will apply sorting disabled classes if disabled\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t_fnSortingClasses( oSettings );\\n\\t\\t\\t\\n\\t\\t\\t\\tif ( features.bSort ) {\\n\\t\\t\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\\n\\t\\t\\t\\t\\t\\tif ( oSettings.bSorted ) {\\n\\t\\t\\t\\t\\t\\t\\tvar aSort = _fnSortFlatten( oSettings );\\n\\t\\t\\t\\t\\t\\t\\tvar sortedColumns = {};\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t$.each( aSort, function (i, val) {\\n\\t\\t\\t\\t\\t\\t\\t\\tsortedColumns[ val.src ] = val.dir;\\n\\t\\t\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );\\n\\t\\t\\t\\t\\t\\t\\t_fnSortAria( oSettings );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\\n\\t\\t\\t\\t\\tif ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {\\n\\t\\t\\t\\t\\t\\t_fnSortingClasses( oSettings );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}, 'sc' );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\t/*\\n\\t\\t\\t\\t * Final init\\n\\t\\t\\t\\t * Cache the header, body and footer as required, creating them if needed\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\n\\t\\t\\t\\t// Work around for Webkit bug 83867 - store the caption-side before removing from doc\\n\\t\\t\\t\\tvar captions = $this.children('caption').each( function () {\\n\\t\\t\\t\\t\\tthis._captionSide = $(this).css('caption-side');\\n\\t\\t\\t\\t} );\\n\\t\\t\\t\\n\\t\\t\\t\\tvar thead = $this.children('thead');\\n\\t\\t\\t\\tif ( thead.length === 0 ) {\\n\\t\\t\\t\\t\\tthead = $('<thead/>').appendTo($this);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\toSettings.nTHead = thead[0];\\n\\t\\t\\t\\n\\t\\t\\t\\tvar tbody = $this.children('tbody');\\n\\t\\t\\t\\tif ( tbody.length === 0 ) {\\n\\t\\t\\t\\t\\ttbody = $('<tbody/>').appendTo($this);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\toSettings.nTBody = tbody[0];\\n\\t\\t\\t\\n\\t\\t\\t\\tvar tfoot = $this.children('tfoot');\\n\\t\\t\\t\\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \\\"\\\" || oSettings.oScroll.sY !== \\\"\\\") ) {\\n\\t\\t\\t\\t\\t// If we are a scrolling table, and no footer has been given, then we need to create\\n\\t\\t\\t\\t\\t// a tfoot element for the caption element to be appended to\\n\\t\\t\\t\\t\\ttfoot = $('<tfoot/>').appendTo($this);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\\n\\t\\t\\t\\t\\t$this.addClass( oClasses.sNoFooter );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( tfoot.length > 0 ) {\\n\\t\\t\\t\\t\\toSettings.nTFoot = tfoot[0];\\n\\t\\t\\t\\t\\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Check if there is data passing into the constructor */\\n\\t\\t\\t\\tif ( oInit.aaData ) {\\n\\t\\t\\t\\t\\tfor ( i=0 ; i<oInit.aaData.length ; i++ ) {\\n\\t\\t\\t\\t\\t\\t_fnAddData( oSettings, oInit.aaData[ i ] );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {\\n\\t\\t\\t\\t\\t/* Grab the data from the page - only do this when deferred loading or no Ajax\\n\\t\\t\\t\\t\\t * source since there is no point in reading the DOM data if we are then going\\n\\t\\t\\t\\t\\t * to replace it with Ajax data\\n\\t\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\t_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Copy the data index array */\\n\\t\\t\\t\\toSettings.aiDisplay = oSettings.aiDisplayMaster.slice();\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Initialisation complete - table can be drawn */\\n\\t\\t\\t\\toSettings.bInitialised = true;\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Check if we need to initialise the table (it might not have been handed off to the\\n\\t\\t\\t\\t * language processor)\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\tif ( bInitHandedOff === false ) {\\n\\t\\t\\t\\t\\t_fnInitialise( oSettings );\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\t\\t\\n\\t\\t\\t/* Must be done after everything which can be overridden by the state saving! */\\n\\t\\t\\tif ( oInit.bStateSave )\\n\\t\\t\\t{\\n\\t\\t\\t\\tfeatures.bStateSave = true;\\n\\t\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );\\n\\t\\t\\t\\t_fnLoadState( oSettings, oInit, loadedInit );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tloadedInit();\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t} );\\n\\t\\t_that = null;\\n\\t\\treturn this;\\n\\t};\\n\\n\\t\\n\\t/*\\n\\t * It is useful to have variables which are scoped locally so only the\\n\\t * DataTables functions can access them and they don't leak into global space.\\n\\t * At the same time these functions are often useful over multiple files in the\\n\\t * core and API, so we list, or at least document, all variables which are used\\n\\t * by DataTables as private variables here. This also ensures that there is no\\n\\t * clashing of variable names and that they can easily referenced for reuse.\\n\\t */\\n\\t\\n\\t\\n\\t// Defined else where\\n\\t// _selector_run\\n\\t// _selector_opts\\n\\t// _selector_first\\n\\t// _selector_row_indexes\\n\\t\\n\\tvar _ext; // DataTable.ext\\n\\tvar _Api; // DataTable.Api\\n\\tvar _api_register; // DataTable.Api.register\\n\\tvar _api_registerPlural; // DataTable.Api.registerPlural\\n\\t\\n\\tvar _re_dic = {};\\n\\tvar _re_new_lines = /[\\\\r\\\\n]/g;\\n\\tvar _re_html = /<.*?>/g;\\n\\t\\n\\t// This is not strict ISO8601 - Date.parse() is quite lax, although\\n\\t// implementations differ between browsers.\\n\\tvar _re_date = /^\\\\d{2,4}[\\\\.\\\\/\\\\-]\\\\d{1,2}[\\\\.\\\\/\\\\-]\\\\d{1,2}([T ]{1}\\\\d{1,2}[:\\\\.]\\\\d{2}([\\\\.:]\\\\d{2})?)?$/;\\n\\t\\n\\t// Escape regular expression special characters\\n\\tvar _re_escape_regex = new RegExp( '(\\\\\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\\\\\', '$', '^', '-' ].join('|\\\\\\\\') + ')', 'g' );\\n\\t\\n\\t// http://en.wikipedia.org/wiki/Foreign_exchange_market\\n\\t// - \\\\u20BD - Russian ruble.\\n\\t// - \\\\u20a9 - South Korean Won\\n\\t// - \\\\u20BA - Turkish Lira\\n\\t// - \\\\u20B9 - Indian Rupee\\n\\t// - R - Brazil (R$) and South Africa\\n\\t// - fr - Swiss Franc\\n\\t// - kr - Swedish krona, Norwegian krone and Danish krone\\n\\t// - \\\\u2009 is thin space and \\\\u202F is narrow no-break space, both used in many\\n\\t// standards as thousands separators.\\n\\tvar _re_formatted_numeric = /[',$£€¥%\\\\u2009\\\\u202F\\\\u20BD\\\\u20a9\\\\u20BArfk]/gi;\\n\\t\\n\\t\\n\\tvar _empty = function ( d ) {\\n\\t\\treturn !d || d === true || d === '-' ? true : false;\\n\\t};\\n\\t\\n\\t\\n\\tvar _intVal = function ( s ) {\\n\\t\\tvar integer = parseInt( s, 10 );\\n\\t\\treturn !isNaN(integer) && isFinite(s) ? integer : null;\\n\\t};\\n\\t\\n\\t// Convert from a formatted number with characters other than `.` as the\\n\\t// decimal place, to a Javascript number\\n\\tvar _numToDecimal = function ( num, decimalPoint ) {\\n\\t\\t// Cache created regular expressions for speed as this function is called often\\n\\t\\tif ( ! _re_dic[ decimalPoint ] ) {\\n\\t\\t\\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\\n\\t\\t}\\n\\t\\treturn typeof num === 'string' && decimalPoint !== '.' ?\\n\\t\\t\\tnum.replace( /\\\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\\n\\t\\t\\tnum;\\n\\t};\\n\\t\\n\\t\\n\\tvar _isNumber = function ( d, decimalPoint, formatted ) {\\n\\t\\tvar strType = typeof d === 'string';\\n\\t\\n\\t\\t// If empty return immediately so there must be a number if it is a\\n\\t\\t// formatted string (this stops the string \\\"k\\\", or \\\"kr\\\", etc being detected\\n\\t\\t// as a formatted number for currency\\n\\t\\tif ( _empty( d ) ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\tif ( decimalPoint && strType ) {\\n\\t\\t\\td = _numToDecimal( d, decimalPoint );\\n\\t\\t}\\n\\t\\n\\t\\tif ( formatted && strType ) {\\n\\t\\t\\td = d.replace( _re_formatted_numeric, '' );\\n\\t\\t}\\n\\t\\n\\t\\treturn !isNaN( parseFloat(d) ) && isFinite( d );\\n\\t};\\n\\t\\n\\t\\n\\t// A string without HTML in it can be considered to be HTML still\\n\\tvar _isHtml = function ( d ) {\\n\\t\\treturn _empty( d ) || typeof d === 'string';\\n\\t};\\n\\t\\n\\t\\n\\tvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\\n\\t\\tif ( _empty( d ) ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\tvar html = _isHtml( d );\\n\\t\\treturn ! html ?\\n\\t\\t\\tnull :\\n\\t\\t\\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\\n\\t\\t\\t\\ttrue :\\n\\t\\t\\t\\tnull;\\n\\t};\\n\\t\\n\\t\\n\\tvar _pluck = function ( a, prop, prop2 ) {\\n\\t\\tvar out = [];\\n\\t\\tvar i=0, ien=a.length;\\n\\t\\n\\t\\t// Could have the test in the loop for slightly smaller code, but speed\\n\\t\\t// is essential here\\n\\t\\tif ( prop2 !== undefined ) {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( a[i] && a[i][ prop ] ) {\\n\\t\\t\\t\\t\\tout.push( a[i][ prop ][ prop2 ] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( a[i] ) {\\n\\t\\t\\t\\t\\tout.push( a[i][ prop ] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\t// Basically the same as _pluck, but rather than looping over `a` we use `order`\\n\\t// as the indexes to pick from `a`\\n\\tvar _pluck_order = function ( a, order, prop, prop2 )\\n\\t{\\n\\t\\tvar out = [];\\n\\t\\tvar i=0, ien=order.length;\\n\\t\\n\\t\\t// Could have the test in the loop for slightly smaller code, but speed\\n\\t\\t// is essential here\\n\\t\\tif ( prop2 !== undefined ) {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( a[ order[i] ][ prop ] ) {\\n\\t\\t\\t\\t\\tout.push( a[ order[i] ][ prop ][ prop2 ] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tout.push( a[ order[i] ][ prop ] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\tvar _range = function ( len, start )\\n\\t{\\n\\t\\tvar out = [];\\n\\t\\tvar end;\\n\\t\\n\\t\\tif ( start === undefined ) {\\n\\t\\t\\tstart = 0;\\n\\t\\t\\tend = len;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tend = start;\\n\\t\\t\\tstart = len;\\n\\t\\t}\\n\\t\\n\\t\\tfor ( var i=start ; i<end ; i++ ) {\\n\\t\\t\\tout.push( i );\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\tvar _removeEmpty = function ( a )\\n\\t{\\n\\t\\tvar out = [];\\n\\t\\n\\t\\tfor ( var i=0, ien=a.length ; i<ien ; i++ ) {\\n\\t\\t\\tif ( a[i] ) { // careful - will remove all falsy values!\\n\\t\\t\\t\\tout.push( a[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\tvar _stripHtml = function ( d ) {\\n\\t\\treturn d.replace( _re_html, '' );\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Determine if all values in the array are unique. This means we can short\\n\\t * cut the _unique method at the cost of a single loop. A sorted array is used\\n\\t * to easily check the values.\\n\\t *\\n\\t * @param {array} src Source array\\n\\t * @return {boolean} true if all unique, false otherwise\\n\\t * @ignore\\n\\t */\\n\\tvar _areAllUnique = function ( src ) {\\n\\t\\tif ( src.length < 2 ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\tvar sorted = src.slice().sort();\\n\\t\\tvar last = sorted[0];\\n\\t\\n\\t\\tfor ( var i=1, ien=sorted.length ; i<ien ; i++ ) {\\n\\t\\t\\tif ( sorted[i] === last ) {\\n\\t\\t\\t\\treturn false;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tlast = sorted[i];\\n\\t\\t}\\n\\t\\n\\t\\treturn true;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Find the unique elements in a source array.\\n\\t *\\n\\t * @param {array} src Source array\\n\\t * @return {array} Array of unique items\\n\\t * @ignore\\n\\t */\\n\\tvar _unique = function ( src )\\n\\t{\\n\\t\\tif ( _areAllUnique( src ) ) {\\n\\t\\t\\treturn src.slice();\\n\\t\\t}\\n\\t\\n\\t\\t// A faster unique method is to use object keys to identify used values,\\n\\t\\t// but this doesn't work with arrays or objects, which we must also\\n\\t\\t// consider. See jsperf.com/compare-array-unique-versions/4 for more\\n\\t\\t// information.\\n\\t\\tvar\\n\\t\\t\\tout = [],\\n\\t\\t\\tval,\\n\\t\\t\\ti, ien=src.length,\\n\\t\\t\\tj, k=0;\\n\\t\\n\\t\\tagain: for ( i=0 ; i<ien ; i++ ) {\\n\\t\\t\\tval = src[i];\\n\\t\\n\\t\\t\\tfor ( j=0 ; j<k ; j++ ) {\\n\\t\\t\\t\\tif ( out[j] === val ) {\\n\\t\\t\\t\\t\\tcontinue again;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tout.push( val );\\n\\t\\t\\tk++;\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables utility methods\\n\\t * \\n\\t * This namespace provides helper methods that DataTables uses internally to\\n\\t * create a DataTable, but which are not exclusively used only for DataTables.\\n\\t * These methods can be used by extension authors to save the duplication of\\n\\t * code.\\n\\t *\\n\\t * @namespace\\n\\t */\\n\\tDataTable.util = {\\n\\t\\t/**\\n\\t\\t * Throttle the calls to a function. Arguments and context are maintained\\n\\t\\t * for the throttled function.\\n\\t\\t *\\n\\t\\t * @param {function} fn Function to be called\\n\\t\\t * @param {integer} freq Call frequency in mS\\n\\t\\t * @return {function} Wrapped function\\n\\t\\t */\\n\\t\\tthrottle: function ( fn, freq ) {\\n\\t\\t\\tvar\\n\\t\\t\\t\\tfrequency = freq !== undefined ? freq : 200,\\n\\t\\t\\t\\tlast,\\n\\t\\t\\t\\ttimer;\\n\\t\\n\\t\\t\\treturn function () {\\n\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\tthat = this,\\n\\t\\t\\t\\t\\tnow = +new Date(),\\n\\t\\t\\t\\t\\targs = arguments;\\n\\t\\n\\t\\t\\t\\tif ( last && now < last + frequency ) {\\n\\t\\t\\t\\t\\tclearTimeout( timer );\\n\\t\\n\\t\\t\\t\\t\\ttimer = setTimeout( function () {\\n\\t\\t\\t\\t\\t\\tlast = undefined;\\n\\t\\t\\t\\t\\t\\tfn.apply( that, args );\\n\\t\\t\\t\\t\\t}, frequency );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tlast = now;\\n\\t\\t\\t\\t\\tfn.apply( that, args );\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Escape a string such that it can be used in a regular expression\\n\\t\\t *\\n\\t\\t * @param {string} val string to escape\\n\\t\\t * @returns {string} escaped string\\n\\t\\t */\\n\\t\\tescapeRegex: function ( val ) {\\n\\t\\t\\treturn val.replace( _re_escape_regex, '\\\\\\\\$1' );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Create a mapping object that allows camel case parameters to be looked up\\n\\t * for their Hungarian counterparts. The mapping is stored in a private\\n\\t * parameter called `_hungarianMap` which can be accessed on the source object.\\n\\t * @param {object} o\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnHungarianMap ( o )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\thungarian = 'a aa ai ao as b fn i m o s ',\\n\\t\\t\\tmatch,\\n\\t\\t\\tnewKey,\\n\\t\\t\\tmap = {};\\n\\t\\n\\t\\t$.each( o, function (key, val) {\\n\\t\\t\\tmatch = key.match(/^([^A-Z]+?)([A-Z])/);\\n\\t\\n\\t\\t\\tif ( match && hungarian.indexOf(match[1]+' ') !== -1 )\\n\\t\\t\\t{\\n\\t\\t\\t\\tnewKey = key.replace( match[0], match[2].toLowerCase() );\\n\\t\\t\\t\\tmap[ newKey ] = key;\\n\\t\\n\\t\\t\\t\\tif ( match[1] === 'o' )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t_fnHungarianMap( o[key] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\to._hungarianMap = map;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from camel case parameters to Hungarian, based on a Hungarian map\\n\\t * created by _fnHungarianMap.\\n\\t * @param {object} src The model object which holds all parameters that can be\\n\\t * mapped.\\n\\t * @param {object} user The object to convert from camel case to Hungarian.\\n\\t * @param {boolean} force When set to `true`, properties which already have a\\n\\t * Hungarian value in the `user` object will be overwritten. Otherwise they\\n\\t * won't be.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCamelToHungarian ( src, user, force )\\n\\t{\\n\\t\\tif ( ! src._hungarianMap ) {\\n\\t\\t\\t_fnHungarianMap( src );\\n\\t\\t}\\n\\t\\n\\t\\tvar hungarianKey;\\n\\t\\n\\t\\t$.each( user, function (key, val) {\\n\\t\\t\\thungarianKey = src._hungarianMap[ key ];\\n\\t\\n\\t\\t\\tif ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )\\n\\t\\t\\t{\\n\\t\\t\\t\\t// For objects, we need to buzz down into the object to copy parameters\\n\\t\\t\\t\\tif ( hungarianKey.charAt(0) === 'o' )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// Copy the camelCase options over to the hungarian\\n\\t\\t\\t\\t\\tif ( ! user[ hungarianKey ] ) {\\n\\t\\t\\t\\t\\t\\tuser[ hungarianKey ] = {};\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t$.extend( true, user[hungarianKey], user[key] );\\n\\t\\n\\t\\t\\t\\t\\t_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tuser[hungarianKey] = user[ key ];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Language compatibility - when certain options are given, and others aren't, we\\n\\t * need to duplicate the values over, in order to provide backwards compatibility\\n\\t * with older language files.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnLanguageCompat( lang )\\n\\t{\\n\\t\\tvar defaults = DataTable.defaults.oLanguage;\\n\\t\\tvar zeroRecords = lang.sZeroRecords;\\n\\t\\n\\t\\t/* Backwards compatibility - if there is no sEmptyTable given, then use the same as\\n\\t\\t * sZeroRecords - assuming that is given.\\n\\t\\t */\\n\\t\\tif ( ! lang.sEmptyTable && zeroRecords &&\\n\\t\\t\\tdefaults.sEmptyTable === \\\"No data available in table\\\" )\\n\\t\\t{\\n\\t\\t\\t_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );\\n\\t\\t}\\n\\t\\n\\t\\t/* Likewise with loading records */\\n\\t\\tif ( ! lang.sLoadingRecords && zeroRecords &&\\n\\t\\t\\tdefaults.sLoadingRecords === \\\"Loading...\\\" )\\n\\t\\t{\\n\\t\\t\\t_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );\\n\\t\\t}\\n\\t\\n\\t\\t// Old parameter name of the thousands separator mapped onto the new\\n\\t\\tif ( lang.sInfoThousands ) {\\n\\t\\t\\tlang.sThousands = lang.sInfoThousands;\\n\\t\\t}\\n\\t\\n\\t\\tvar decimal = lang.sDecimal;\\n\\t\\tif ( decimal ) {\\n\\t\\t\\t_addNumericSort( decimal );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Map one parameter onto another\\n\\t * @param {object} o Object to map\\n\\t * @param {*} knew The new parameter name\\n\\t * @param {*} old The old parameter name\\n\\t */\\n\\tvar _fnCompatMap = function ( o, knew, old ) {\\n\\t\\tif ( o[ knew ] !== undefined ) {\\n\\t\\t\\to[ old ] = o[ knew ];\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Provide backwards compatibility for the main DT options. Note that the new\\n\\t * options are mapped onto the old parameters, so this is an external interface\\n\\t * change only.\\n\\t * @param {object} init Object to map\\n\\t */\\n\\tfunction _fnCompatOpts ( init )\\n\\t{\\n\\t\\t_fnCompatMap( init, 'ordering', 'bSort' );\\n\\t\\t_fnCompatMap( init, 'orderMulti', 'bSortMulti' );\\n\\t\\t_fnCompatMap( init, 'orderClasses', 'bSortClasses' );\\n\\t\\t_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );\\n\\t\\t_fnCompatMap( init, 'order', 'aaSorting' );\\n\\t\\t_fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );\\n\\t\\t_fnCompatMap( init, 'paging', 'bPaginate' );\\n\\t\\t_fnCompatMap( init, 'pagingType', 'sPaginationType' );\\n\\t\\t_fnCompatMap( init, 'pageLength', 'iDisplayLength' );\\n\\t\\t_fnCompatMap( init, 'searching', 'bFilter' );\\n\\t\\n\\t\\t// Boolean initialisation of x-scrolling\\n\\t\\tif ( typeof init.sScrollX === 'boolean' ) {\\n\\t\\t\\tinit.sScrollX = init.sScrollX ? '100%' : '';\\n\\t\\t}\\n\\t\\tif ( typeof init.scrollX === 'boolean' ) {\\n\\t\\t\\tinit.scrollX = init.scrollX ? '100%' : '';\\n\\t\\t}\\n\\t\\n\\t\\t// Column search objects are in an array, so it needs to be converted\\n\\t\\t// element by element\\n\\t\\tvar searchCols = init.aoSearchCols;\\n\\t\\n\\t\\tif ( searchCols ) {\\n\\t\\t\\tfor ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( searchCols[i] ) {\\n\\t\\t\\t\\t\\t_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Provide backwards compatibility for column options. Note that the new options\\n\\t * are mapped onto the old parameters, so this is an external interface change\\n\\t * only.\\n\\t * @param {object} init Object to map\\n\\t */\\n\\tfunction _fnCompatCols ( init )\\n\\t{\\n\\t\\t_fnCompatMap( init, 'orderable', 'bSortable' );\\n\\t\\t_fnCompatMap( init, 'orderData', 'aDataSort' );\\n\\t\\t_fnCompatMap( init, 'orderSequence', 'asSorting' );\\n\\t\\t_fnCompatMap( init, 'orderDataType', 'sortDataType' );\\n\\t\\n\\t\\t// orderData can be given as an integer\\n\\t\\tvar dataSort = init.aDataSort;\\n\\t\\tif ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) {\\n\\t\\t\\tinit.aDataSort = [ dataSort ];\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Browser feature detection for capabilities, quirks\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnBrowserDetect( settings )\\n\\t{\\n\\t\\t// We don't need to do this every time DataTables is constructed, the values\\n\\t\\t// calculated are specific to the browser and OS configuration which we\\n\\t\\t// don't expect to change between initialisations\\n\\t\\tif ( ! DataTable.__browser ) {\\n\\t\\t\\tvar browser = {};\\n\\t\\t\\tDataTable.__browser = browser;\\n\\t\\n\\t\\t\\t// Scrolling feature / quirks detection\\n\\t\\t\\tvar n = $('<div/>')\\n\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\tposition: 'fixed',\\n\\t\\t\\t\\t\\ttop: 0,\\n\\t\\t\\t\\t\\tleft: $(window).scrollLeft()*-1, // allow for scrolling\\n\\t\\t\\t\\t\\theight: 1,\\n\\t\\t\\t\\t\\twidth: 1,\\n\\t\\t\\t\\t\\toverflow: 'hidden'\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t$('<div/>')\\n\\t\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\t\\tposition: 'absolute',\\n\\t\\t\\t\\t\\t\\t\\ttop: 1,\\n\\t\\t\\t\\t\\t\\t\\tleft: 1,\\n\\t\\t\\t\\t\\t\\t\\twidth: 100,\\n\\t\\t\\t\\t\\t\\t\\toverflow: 'scroll'\\n\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t$('<div/>')\\n\\t\\t\\t\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\twidth: '100%',\\n\\t\\t\\t\\t\\t\\t\\t\\t\\theight: 10\\n\\t\\t\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.appendTo( 'body' );\\n\\t\\n\\t\\t\\tvar outer = n.children();\\n\\t\\t\\tvar inner = outer.children();\\n\\t\\n\\t\\t\\t// Numbers below, in order, are:\\n\\t\\t\\t// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth\\n\\t\\t\\t//\\n\\t\\t\\t// IE6 XP: 100 100 100 83\\n\\t\\t\\t// IE7 Vista: 100 100 100 83\\n\\t\\t\\t// IE 8+ Windows: 83 83 100 83\\n\\t\\t\\t// Evergreen Windows: 83 83 100 83\\n\\t\\t\\t// Evergreen Mac with scrollbars: 85 85 100 85\\n\\t\\t\\t// Evergreen Mac without scrollbars: 100 100 100 100\\n\\t\\n\\t\\t\\t// Get scrollbar width\\n\\t\\t\\tbrowser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;\\n\\t\\n\\t\\t\\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\\n\\t\\t\\t// include the width of the scrollbar, while other browsers ensure the inner\\n\\t\\t\\t// element is contained without forcing scrolling\\n\\t\\t\\tbrowser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;\\n\\t\\n\\t\\t\\t// In rtl text layout, some browsers (most, but not all) will place the\\n\\t\\t\\t// scrollbar on the left, rather than the right.\\n\\t\\t\\tbrowser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;\\n\\t\\n\\t\\t\\t// IE8- don't provide height and width for getBoundingClientRect\\n\\t\\t\\tbrowser.bBounding = n[0].getBoundingClientRect().width ? true : false;\\n\\t\\n\\t\\t\\tn.remove();\\n\\t\\t}\\n\\t\\n\\t\\t$.extend( settings.oBrowser, DataTable.__browser );\\n\\t\\tsettings.oScroll.iBarWidth = DataTable.__browser.barWidth;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Array.prototype reduce[Right] method, used for browsers which don't support\\n\\t * JS 1.6. Done this way to reduce code size, since we iterate either way\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnReduce ( that, fn, init, start, end, inc )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti = start,\\n\\t\\t\\tvalue,\\n\\t\\t\\tisSet = false;\\n\\t\\n\\t\\tif ( init !== undefined ) {\\n\\t\\t\\tvalue = init;\\n\\t\\t\\tisSet = true;\\n\\t\\t}\\n\\t\\n\\t\\twhile ( i !== end ) {\\n\\t\\t\\tif ( ! that.hasOwnProperty(i) ) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tvalue = isSet ?\\n\\t\\t\\t\\tfn( value, that[i], i, that ) :\\n\\t\\t\\t\\tthat[i];\\n\\t\\n\\t\\t\\tisSet = true;\\n\\t\\t\\ti += inc;\\n\\t\\t}\\n\\t\\n\\t\\treturn value;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Add a column to the list used for the table with default values\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {node} nTh The th element for this column\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddColumn( oSettings, nTh )\\n\\t{\\n\\t\\t// Add column to aoColumns array\\n\\t\\tvar oDefaults = DataTable.defaults.column;\\n\\t\\tvar iCol = oSettings.aoColumns.length;\\n\\t\\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\\n\\t\\t\\t\\\"nTh\\\": nTh ? nTh : document.createElement('th'),\\n\\t\\t\\t\\\"sTitle\\\": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',\\n\\t\\t\\t\\\"aDataSort\\\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\\n\\t\\t\\t\\\"mData\\\": oDefaults.mData ? oDefaults.mData : iCol,\\n\\t\\t\\tidx: iCol\\n\\t\\t} );\\n\\t\\toSettings.aoColumns.push( oCol );\\n\\t\\n\\t\\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\\n\\t\\t// passed into extend can be undefined. This allows the user to give a default\\n\\t\\t// with only some of the parameters defined, and also not give a default\\n\\t\\tvar searchCols = oSettings.aoPreSearchCols;\\n\\t\\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\\n\\t\\n\\t\\t// Use the default column options function to initialise classes etc\\n\\t\\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Apply options for a column\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iCol column index to consider\\n\\t * @param {object} oOptions object with sType, bVisible and bSearchable etc\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnColumnOptions( oSettings, iCol, oOptions )\\n\\t{\\n\\t\\tvar oCol = oSettings.aoColumns[ iCol ];\\n\\t\\tvar oClasses = oSettings.oClasses;\\n\\t\\tvar th = $(oCol.nTh);\\n\\t\\n\\t\\t// Try to get width information from the DOM. We can't get it from CSS\\n\\t\\t// as we'd need to parse the CSS stylesheet. `width` option can override\\n\\t\\tif ( ! oCol.sWidthOrig ) {\\n\\t\\t\\t// Width attribute\\n\\t\\t\\toCol.sWidthOrig = th.attr('width') || null;\\n\\t\\n\\t\\t\\t// Style attribute\\n\\t\\t\\tvar t = (th.attr('style') || '').match(/width:\\\\s*(\\\\d+[pxem%]+)/);\\n\\t\\t\\tif ( t ) {\\n\\t\\t\\t\\toCol.sWidthOrig = t[1];\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* User specified column options */\\n\\t\\tif ( oOptions !== undefined && oOptions !== null )\\n\\t\\t{\\n\\t\\t\\t// Backwards compatibility\\n\\t\\t\\t_fnCompatCols( oOptions );\\n\\t\\n\\t\\t\\t// Map camel case parameters to their Hungarian counterparts\\n\\t\\t\\t_fnCamelToHungarian( DataTable.defaults.column, oOptions );\\n\\t\\n\\t\\t\\t/* Backwards compatibility for mDataProp */\\n\\t\\t\\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\\n\\t\\t\\t{\\n\\t\\t\\t\\toOptions.mData = oOptions.mDataProp;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( oOptions.sType )\\n\\t\\t\\t{\\n\\t\\t\\t\\toCol._sManualType = oOptions.sType;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// `class` is a reserved word in Javascript, so we need to provide\\n\\t\\t\\t// the ability to use a valid name for the camel case input\\n\\t\\t\\tif ( oOptions.className && ! oOptions.sClass )\\n\\t\\t\\t{\\n\\t\\t\\t\\toOptions.sClass = oOptions.className;\\n\\t\\t\\t}\\n\\t\\t\\tif ( oOptions.sClass ) {\\n\\t\\t\\t\\tth.addClass( oOptions.sClass );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t$.extend( oCol, oOptions );\\n\\t\\t\\t_fnMap( oCol, oOptions, \\\"sWidth\\\", \\\"sWidthOrig\\\" );\\n\\t\\n\\t\\t\\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\\n\\t\\t\\t * priority if defined\\n\\t\\t\\t */\\n\\t\\t\\tif ( oOptions.iDataSort !== undefined )\\n\\t\\t\\t{\\n\\t\\t\\t\\toCol.aDataSort = [ oOptions.iDataSort ];\\n\\t\\t\\t}\\n\\t\\t\\t_fnMap( oCol, oOptions, \\\"aDataSort\\\" );\\n\\t\\t}\\n\\t\\n\\t\\t/* Cache the data get and set functions for speed */\\n\\t\\tvar mDataSrc = oCol.mData;\\n\\t\\tvar mData = _fnGetObjectDataFn( mDataSrc );\\n\\t\\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\\n\\t\\n\\t\\tvar attrTest = function( src ) {\\n\\t\\t\\treturn typeof src === 'string' && src.indexOf('@') !== -1;\\n\\t\\t};\\n\\t\\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\\n\\t\\t\\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\\n\\t\\t);\\n\\t\\toCol._setter = null;\\n\\t\\n\\t\\toCol.fnGetData = function (rowData, type, meta) {\\n\\t\\t\\tvar innerData = mData( rowData, type, undefined, meta );\\n\\t\\n\\t\\t\\treturn mRender && type ?\\n\\t\\t\\t\\tmRender( innerData, type, rowData, meta ) :\\n\\t\\t\\t\\tinnerData;\\n\\t\\t};\\n\\t\\toCol.fnSetData = function ( rowData, val, meta ) {\\n\\t\\t\\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\\n\\t\\t};\\n\\t\\n\\t\\t// Indicate if DataTables should read DOM data as an object or array\\n\\t\\t// Used in _fnGetRowElements\\n\\t\\tif ( typeof mDataSrc !== 'number' ) {\\n\\t\\t\\toSettings._rowReadObject = true;\\n\\t\\t}\\n\\t\\n\\t\\t/* Feature sorting overrides column specific when off */\\n\\t\\tif ( !oSettings.oFeatures.bSort )\\n\\t\\t{\\n\\t\\t\\toCol.bSortable = false;\\n\\t\\t\\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\\n\\t\\t}\\n\\t\\n\\t\\t/* Check that the class assignment is correct for sorting */\\n\\t\\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\\n\\t\\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\\n\\t\\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortableNone;\\n\\t\\t\\toCol.sSortingClassJUI = \\\"\\\";\\n\\t\\t}\\n\\t\\telse if ( bAsc && !bDesc )\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortableAsc;\\n\\t\\t\\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\\n\\t\\t}\\n\\t\\telse if ( !bAsc && bDesc )\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortableDesc;\\n\\t\\t\\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortable;\\n\\t\\t\\toCol.sSortingClassJUI = oClasses.sSortJUI;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Adjust the table column widths for new data. Note: you would probably want to\\n\\t * do a redraw after calling this function!\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAdjustColumnSizing ( settings )\\n\\t{\\n\\t\\t/* Not interested in doing column width calculation if auto-width is disabled */\\n\\t\\tif ( settings.oFeatures.bAutoWidth !== false )\\n\\t\\t{\\n\\t\\t\\tvar columns = settings.aoColumns;\\n\\t\\n\\t\\t\\t_fnCalculateColumnWidths( settings );\\n\\t\\t\\tfor ( var i=0 , iLen=columns.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tcolumns[i].nTh.style.width = columns[i].sWidth;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tvar scroll = settings.oScroll;\\n\\t\\tif ( scroll.sY !== '' || scroll.sX !== '')\\n\\t\\t{\\n\\t\\t\\t_fnScrollDraw( settings );\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'column-sizing', [settings] );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Covert the index of a visible column to the index in the data array (take account\\n\\t * of hidden columns)\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iMatch Visible column index to lookup\\n\\t * @returns {int} i the data index\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnVisibleToColumnIndex( oSettings, iMatch )\\n\\t{\\n\\t\\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\\n\\t\\n\\t\\treturn typeof aiVis[iMatch] === 'number' ?\\n\\t\\t\\taiVis[iMatch] :\\n\\t\\t\\tnull;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Covert the index of an index in the data array and convert it to the visible\\n\\t * column index (take account of hidden columns)\\n\\t * @param {int} iMatch Column index to lookup\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {int} i the data index\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnColumnIndexToVisible( oSettings, iMatch )\\n\\t{\\n\\t\\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\\n\\t\\tvar iPos = $.inArray( iMatch, aiVis );\\n\\t\\n\\t\\treturn iPos !== -1 ? iPos : null;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the number of visible columns\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {int} i the number of visible columns\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnVisbleColumns( oSettings )\\n\\t{\\n\\t\\tvar vis = 0;\\n\\t\\n\\t\\t// No reduce in IE8, use a loop for now\\n\\t\\t$.each( oSettings.aoColumns, function ( i, col ) {\\n\\t\\t\\tif ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {\\n\\t\\t\\t\\tvis++;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn vis;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get an array of column indexes that match a given property\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {string} sParam Parameter in aoColumns to look for - typically\\n\\t * bVisible or bSearchable\\n\\t * @returns {array} Array of indexes with matched properties\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetColumns( oSettings, sParam )\\n\\t{\\n\\t\\tvar a = [];\\n\\t\\n\\t\\t$.map( oSettings.aoColumns, function(val, i) {\\n\\t\\t\\tif ( val[sParam] ) {\\n\\t\\t\\t\\ta.push( i );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn a;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Calculate the 'type' of a column\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnColumnTypes ( settings )\\n\\t{\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar data = settings.aoData;\\n\\t\\tvar types = DataTable.ext.type.detect;\\n\\t\\tvar i, ien, j, jen, k, ken;\\n\\t\\tvar col, cell, detectedType, cache;\\n\\t\\n\\t\\t// For each column, spin over the \\n\\t\\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\\n\\t\\t\\tcol = columns[i];\\n\\t\\t\\tcache = [];\\n\\t\\n\\t\\t\\tif ( ! col.sType && col._sManualType ) {\\n\\t\\t\\t\\tcol.sType = col._sManualType;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( ! col.sType ) {\\n\\t\\t\\t\\tfor ( j=0, jen=types.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\tfor ( k=0, ken=data.length ; k<ken ; k++ ) {\\n\\t\\t\\t\\t\\t\\t// Use a cache array so we only need to get the type data\\n\\t\\t\\t\\t\\t\\t// from the formatter once (when using multiple detectors)\\n\\t\\t\\t\\t\\t\\tif ( cache[k] === undefined ) {\\n\\t\\t\\t\\t\\t\\t\\tcache[k] = _fnGetCellData( settings, k, i, 'type' );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tdetectedType = types[j]( cache[k], settings );\\n\\t\\n\\t\\t\\t\\t\\t\\t// If null, then this type can't apply to this column, so\\n\\t\\t\\t\\t\\t\\t// rather than testing all cells, break out. There is an\\n\\t\\t\\t\\t\\t\\t// exception for the last type which is `html`. We need to\\n\\t\\t\\t\\t\\t\\t// scan all rows since it is possible to mix string and HTML\\n\\t\\t\\t\\t\\t\\t// types\\n\\t\\t\\t\\t\\t\\tif ( ! detectedType && j !== types.length-1 ) {\\n\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t// Only a single match is needed for html type since it is\\n\\t\\t\\t\\t\\t\\t// bottom of the pile and very similar to string\\n\\t\\t\\t\\t\\t\\tif ( detectedType === 'html' ) {\\n\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// Type is valid for all data points in the column - use this\\n\\t\\t\\t\\t\\t// type\\n\\t\\t\\t\\t\\tif ( detectedType ) {\\n\\t\\t\\t\\t\\t\\tcol.sType = detectedType;\\n\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Fall back - if no type was detected, always use string\\n\\t\\t\\t\\tif ( ! col.sType ) {\\n\\t\\t\\t\\t\\tcol.sType = 'string';\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Take the column definitions and static columns arrays and calculate how\\n\\t * they relate to column indexes. The callback function will then apply the\\n\\t * definition found for a column to a suitable configuration object.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {array} aoColDefs The aoColumnDefs array that is to be applied\\n\\t * @param {array} aoCols The aoColumns array that defines columns individually\\n\\t * @param {function} fn Callback function - takes two parameters, the calculated\\n\\t * column index and the definition for that column.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )\\n\\t{\\n\\t\\tvar i, iLen, j, jLen, k, kLen, def;\\n\\t\\tvar columns = oSettings.aoColumns;\\n\\t\\n\\t\\t// Column definitions with aTargets\\n\\t\\tif ( aoColDefs )\\n\\t\\t{\\n\\t\\t\\t/* Loop over the definitions array - loop in reverse so first instance has priority */\\n\\t\\t\\tfor ( i=aoColDefs.length-1 ; i>=0 ; i-- )\\n\\t\\t\\t{\\n\\t\\t\\t\\tdef = aoColDefs[i];\\n\\t\\n\\t\\t\\t\\t/* Each definition can target multiple columns, as it is an array */\\n\\t\\t\\t\\tvar aTargets = def.targets !== undefined ?\\n\\t\\t\\t\\t\\tdef.targets :\\n\\t\\t\\t\\t\\tdef.aTargets;\\n\\t\\n\\t\\t\\t\\tif ( ! $.isArray( aTargets ) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taTargets = [ aTargets ];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tfor ( j=0, jLen=aTargets.length ; j<jLen ; j++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tif ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Add columns that we don't yet know about */\\n\\t\\t\\t\\t\\t\\twhile( columns.length <= aTargets[j] )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t_fnAddColumn( oSettings );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t/* Integer, basic index */\\n\\t\\t\\t\\t\\t\\tfn( aTargets[j], def );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Negative integer, right to left column counting */\\n\\t\\t\\t\\t\\t\\tfn( columns.length+aTargets[j], def );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( typeof aTargets[j] === 'string' )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Class name matching on TH element */\\n\\t\\t\\t\\t\\t\\tfor ( k=0, kLen=columns.length ; k<kLen ; k++ )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\tif ( aTargets[j] == \\\"_all\\\" ||\\n\\t\\t\\t\\t\\t\\t\\t $(columns[k].nTh).hasClass( aTargets[j] ) )\\n\\t\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t\\tfn( k, def );\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// Statically defined columns array\\n\\t\\tif ( aoCols )\\n\\t\\t{\\n\\t\\t\\tfor ( i=0, iLen=aoCols.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tfn( i, aoCols[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t/**\\n\\t * Add a data array to the table, creating DOM node etc. This is the parallel to\\n\\t * _fnGatherData, but for adding rows from a Javascript source, rather than a\\n\\t * DOM source.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {array} aData data array to be added\\n\\t * @param {node} [nTr] TR element to add to the table - optional. If not given,\\n\\t * DataTables will create a row automatically\\n\\t * @param {array} [anTds] Array of TD|TH elements for the row - must be given\\n\\t * if nTr is.\\n\\t * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\\n\\t{\\n\\t\\t/* Create the object for storing information about this new row */\\n\\t\\tvar iRow = oSettings.aoData.length;\\n\\t\\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\\n\\t\\t\\tsrc: nTr ? 'dom' : 'data',\\n\\t\\t\\tidx: iRow\\n\\t\\t} );\\n\\t\\n\\t\\toData._aData = aDataIn;\\n\\t\\toSettings.aoData.push( oData );\\n\\t\\n\\t\\t/* Create the cells */\\n\\t\\tvar nTd, sThisType;\\n\\t\\tvar columns = oSettings.aoColumns;\\n\\t\\n\\t\\t// Invalidate the column types as the new data needs to be revalidated\\n\\t\\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tcolumns[i].sType = null;\\n\\t\\t}\\n\\t\\n\\t\\t/* Add to the display array */\\n\\t\\toSettings.aiDisplayMaster.push( iRow );\\n\\t\\n\\t\\tvar id = oSettings.rowIdFn( aDataIn );\\n\\t\\tif ( id !== undefined ) {\\n\\t\\t\\toSettings.aIds[ id ] = oData;\\n\\t\\t}\\n\\t\\n\\t\\t/* Create the DOM information, or register it if already present */\\n\\t\\tif ( nTr || ! oSettings.oFeatures.bDeferRender )\\n\\t\\t{\\n\\t\\t\\t_fnCreateTr( oSettings, iRow, nTr, anTds );\\n\\t\\t}\\n\\t\\n\\t\\treturn iRow;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Add one or more TR elements to the table. Generally we'd expect to\\n\\t * use this for reading data from a DOM sourced table, but it could be\\n\\t * used for an TR element. Note that if a TR is given, it is used (i.e.\\n\\t * it is not cloned).\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {array|node|jQuery} trs The TR element(s) to add to the table\\n\\t * @returns {array} Array of indexes for the added rows\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddTr( settings, trs )\\n\\t{\\n\\t\\tvar row;\\n\\t\\n\\t\\t// Allow an individual node to be passed in\\n\\t\\tif ( ! (trs instanceof $) ) {\\n\\t\\t\\ttrs = $(trs);\\n\\t\\t}\\n\\t\\n\\t\\treturn trs.map( function (i, el) {\\n\\t\\t\\trow = _fnGetRowElements( settings, el );\\n\\t\\t\\treturn _fnAddData( settings, row.data, el, row.cells );\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Take a TR element and convert it to an index in aoData\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {node} n the TR element to find\\n\\t * @returns {int} index if the node is found, null if not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnNodeToDataIndex( oSettings, n )\\n\\t{\\n\\t\\treturn (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Take a TD element and convert it into a column data index (not the visible index)\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iRow The row number the TD/TH can be found in\\n\\t * @param {node} n The TD/TH element to find\\n\\t * @returns {int} index if the node is found, -1 if not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnNodeToColumnIndex( oSettings, iRow, n )\\n\\t{\\n\\t\\treturn $.inArray( n, oSettings.aoData[ iRow ].anCells );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the data for a given cell from the internal cache, taking into account data mapping\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} rowIdx aoData row id\\n\\t * @param {int} colIdx Column index\\n\\t * @param {string} type data get type ('display', 'type' 'filter' 'sort')\\n\\t * @returns {*} Cell data\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetCellData( settings, rowIdx, colIdx, type )\\n\\t{\\n\\t\\tvar draw = settings.iDraw;\\n\\t\\tvar col = settings.aoColumns[colIdx];\\n\\t\\tvar rowData = settings.aoData[rowIdx]._aData;\\n\\t\\tvar defaultContent = col.sDefaultContent;\\n\\t\\tvar cellData = col.fnGetData( rowData, type, {\\n\\t\\t\\tsettings: settings,\\n\\t\\t\\trow: rowIdx,\\n\\t\\t\\tcol: colIdx\\n\\t\\t} );\\n\\t\\n\\t\\tif ( cellData === undefined ) {\\n\\t\\t\\tif ( settings.iDrawError != draw && defaultContent === null ) {\\n\\t\\t\\t\\t_fnLog( settings, 0, \\\"Requested unknown parameter \\\"+\\n\\t\\t\\t\\t\\t(typeof col.mData=='function' ? '{function}' : \\\"'\\\"+col.mData+\\\"'\\\")+\\n\\t\\t\\t\\t\\t\\\" for row \\\"+rowIdx+\\\", column \\\"+colIdx, 4 );\\n\\t\\t\\t\\tsettings.iDrawError = draw;\\n\\t\\t\\t}\\n\\t\\t\\treturn defaultContent;\\n\\t\\t}\\n\\t\\n\\t\\t// When the data source is null and a specific data type is requested (i.e.\\n\\t\\t// not the original data), we can use default column data\\n\\t\\tif ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {\\n\\t\\t\\tcellData = defaultContent;\\n\\t\\t}\\n\\t\\telse if ( typeof cellData === 'function' ) {\\n\\t\\t\\t// If the data source is a function, then we run it and use the return,\\n\\t\\t\\t// executing in the scope of the data object (for instances)\\n\\t\\t\\treturn cellData.call( rowData );\\n\\t\\t}\\n\\t\\n\\t\\tif ( cellData === null && type == 'display' ) {\\n\\t\\t\\treturn '';\\n\\t\\t}\\n\\t\\treturn cellData;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Set the value for a specific cell, into the internal data cache\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} rowIdx aoData row id\\n\\t * @param {int} colIdx Column index\\n\\t * @param {*} val Value to set\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSetCellData( settings, rowIdx, colIdx, val )\\n\\t{\\n\\t\\tvar col = settings.aoColumns[colIdx];\\n\\t\\tvar rowData = settings.aoData[rowIdx]._aData;\\n\\t\\n\\t\\tcol.fnSetData( rowData, val, {\\n\\t\\t\\tsettings: settings,\\n\\t\\t\\trow: rowIdx,\\n\\t\\t\\tcol: colIdx\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t// Private variable that is used to match action syntax in the data property object\\n\\tvar __reArray = /\\\\[.*?\\\\]$/;\\n\\tvar __reFn = /\\\\(\\\\)$/;\\n\\t\\n\\t/**\\n\\t * Split string on periods, taking into account escaped periods\\n\\t * @param {string} str String to split\\n\\t * @return {array} Split string\\n\\t */\\n\\tfunction _fnSplitObjNotation( str )\\n\\t{\\n\\t\\treturn $.map( str.match(/(\\\\\\\\.|[^\\\\.])+/g) || [''], function ( s ) {\\n\\t\\t\\treturn s.replace(/\\\\\\\\\\\\./g, '.');\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return a function that can be used to get data from a source object, taking\\n\\t * into account the ability to use nested objects as a source\\n\\t * @param {string|int|function} mSource The data source for the object\\n\\t * @returns {function} Data get function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetObjectDataFn( mSource )\\n\\t{\\n\\t\\tif ( $.isPlainObject( mSource ) )\\n\\t\\t{\\n\\t\\t\\t/* Build an object of get functions, and wrap them in a single call */\\n\\t\\t\\tvar o = {};\\n\\t\\t\\t$.each( mSource, function (key, val) {\\n\\t\\t\\t\\tif ( val ) {\\n\\t\\t\\t\\t\\to[key] = _fnGetObjectDataFn( val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\treturn function (data, type, row, meta) {\\n\\t\\t\\t\\tvar t = o[type] || o._;\\n\\t\\t\\t\\treturn t !== undefined ?\\n\\t\\t\\t\\t\\tt(data, type, row, meta) :\\n\\t\\t\\t\\t\\tdata;\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( mSource === null )\\n\\t\\t{\\n\\t\\t\\t/* Give an empty string for rendering / sorting etc */\\n\\t\\t\\treturn function (data) { // type, row and meta also passed, but not used\\n\\t\\t\\t\\treturn data;\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'function' )\\n\\t\\t{\\n\\t\\t\\treturn function (data, type, row, meta) {\\n\\t\\t\\t\\treturn mSource( data, type, row, meta );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\\n\\t\\t\\t mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\\n\\t\\t{\\n\\t\\t\\t/* If there is a . in the source string then the data source is in a\\n\\t\\t\\t * nested object so we loop over the data for each level to get the next\\n\\t\\t\\t * level down. On each loop we test for undefined, and if found immediately\\n\\t\\t\\t * return. This allows entire objects to be missing and sDefaultContent to\\n\\t\\t\\t * be used if defined, rather than throwing an error\\n\\t\\t\\t */\\n\\t\\t\\tvar fetchData = function (data, type, src) {\\n\\t\\t\\t\\tvar arrayNotation, funcNotation, out, innerSrc;\\n\\t\\n\\t\\t\\t\\tif ( src !== \\\"\\\" )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tvar a = _fnSplitObjNotation( src );\\n\\t\\n\\t\\t\\t\\t\\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t// Check if we are dealing with special notation\\n\\t\\t\\t\\t\\t\\tarrayNotation = a[i].match(__reArray);\\n\\t\\t\\t\\t\\t\\tfuncNotation = a[i].match(__reFn);\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( arrayNotation )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t// Array notation\\n\\t\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reArray, '');\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// Condition allows simply [] to be passed in\\n\\t\\t\\t\\t\\t\\t\\tif ( a[i] !== \\\"\\\" ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tdata = data[ a[i] ];\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t\\tout = [];\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// Get the remainder of the nested object to get\\n\\t\\t\\t\\t\\t\\t\\ta.splice( 0, i+1 );\\n\\t\\t\\t\\t\\t\\t\\tinnerSrc = a.join('.');\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// Traverse each entry in the array getting the properties requested\\n\\t\\t\\t\\t\\t\\t\\tif ( $.isArray( data ) ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tout.push( fetchData( data[j], type, innerSrc ) );\\n\\t\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// If a string is given in between the array notation indicators, that\\n\\t\\t\\t\\t\\t\\t\\t// is used to join the strings together, otherwise an array is returned\\n\\t\\t\\t\\t\\t\\t\\tvar join = arrayNotation[0].substring(1, arrayNotation[0].length-1);\\n\\t\\t\\t\\t\\t\\t\\tdata = (join===\\\"\\\") ? out : out.join(join);\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// The inner call to fetchData has already traversed through the remainder\\n\\t\\t\\t\\t\\t\\t\\t// of the source requested, so we exit from the loop\\n\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse if ( funcNotation )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t// Function call\\n\\t\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reFn, '');\\n\\t\\t\\t\\t\\t\\t\\tdata = data[ a[i] ]();\\n\\t\\t\\t\\t\\t\\t\\tcontinue;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( data === null || data[ a[i] ] === undefined )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\treturn undefined;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\tdata = data[ a[i] ];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn data;\\n\\t\\t\\t};\\n\\t\\n\\t\\t\\treturn function (data, type) { // row and meta also passed, but not used\\n\\t\\t\\t\\treturn fetchData( data, type, mSource );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t/* Array or flat object mapping */\\n\\t\\t\\treturn function (data, type) { // row and meta also passed, but not used\\n\\t\\t\\t\\treturn data[mSource];\\n\\t\\t\\t};\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return a function that can be used to set data from a source object, taking\\n\\t * into account the ability to use nested objects as a source\\n\\t * @param {string|int|function} mSource The data source for the object\\n\\t * @returns {function} Data set function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSetObjectDataFn( mSource )\\n\\t{\\n\\t\\tif ( $.isPlainObject( mSource ) )\\n\\t\\t{\\n\\t\\t\\t/* Unlike get, only the underscore (global) option is used for for\\n\\t\\t\\t * setting data since we don't know the type here. This is why an object\\n\\t\\t\\t * option is not documented for `mData` (which is read/write), but it is\\n\\t\\t\\t * for `mRender` which is read only.\\n\\t\\t\\t */\\n\\t\\t\\treturn _fnSetObjectDataFn( mSource._ );\\n\\t\\t}\\n\\t\\telse if ( mSource === null )\\n\\t\\t{\\n\\t\\t\\t/* Nothing to do when the data source is null */\\n\\t\\t\\treturn function () {};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'function' )\\n\\t\\t{\\n\\t\\t\\treturn function (data, val, meta) {\\n\\t\\t\\t\\tmSource( data, 'set', val, meta );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\\n\\t\\t\\t mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\\n\\t\\t{\\n\\t\\t\\t/* Like the get, we need to get data from a nested object */\\n\\t\\t\\tvar setData = function (data, val, src) {\\n\\t\\t\\t\\tvar a = _fnSplitObjNotation( src ), b;\\n\\t\\t\\t\\tvar aLast = a[a.length-1];\\n\\t\\t\\t\\tvar arrayNotation, funcNotation, o, innerSrc;\\n\\t\\n\\t\\t\\t\\tfor ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// Check if we are dealing with an array notation request\\n\\t\\t\\t\\t\\tarrayNotation = a[i].match(__reArray);\\n\\t\\t\\t\\t\\tfuncNotation = a[i].match(__reFn);\\n\\t\\n\\t\\t\\t\\t\\tif ( arrayNotation )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reArray, '');\\n\\t\\t\\t\\t\\t\\tdata[ a[i] ] = [];\\n\\t\\n\\t\\t\\t\\t\\t\\t// Get the remainder of the nested object to set so we can recurse\\n\\t\\t\\t\\t\\t\\tb = a.slice();\\n\\t\\t\\t\\t\\t\\tb.splice( 0, i+1 );\\n\\t\\t\\t\\t\\t\\tinnerSrc = b.join('.');\\n\\t\\n\\t\\t\\t\\t\\t\\t// Traverse each entry in the array setting the properties requested\\n\\t\\t\\t\\t\\t\\tif ( $.isArray( val ) )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\\n\\t\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t\\to = {};\\n\\t\\t\\t\\t\\t\\t\\t\\tsetData( o, val[j], innerSrc );\\n\\t\\t\\t\\t\\t\\t\\t\\tdata[ a[i] ].push( o );\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t// We've been asked to save data to an array, but it\\n\\t\\t\\t\\t\\t\\t\\t// isn't array data to be saved. Best that can be done\\n\\t\\t\\t\\t\\t\\t\\t// is to just save the value.\\n\\t\\t\\t\\t\\t\\t\\tdata[ a[i] ] = val;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t// The inner call to setData has already traversed through the remainder\\n\\t\\t\\t\\t\\t\\t// of the source and has set the data, thus we can exit here\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( funcNotation )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t// Function call\\n\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reFn, '');\\n\\t\\t\\t\\t\\t\\tdata = data[ a[i] ]( val );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// If the nested object doesn't currently exist - since we are\\n\\t\\t\\t\\t\\t// trying to set the value - create it\\n\\t\\t\\t\\t\\tif ( data[ a[i] ] === null || data[ a[i] ] === undefined )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tdata[ a[i] ] = {};\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\tdata = data[ a[i] ];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Last item in the input - i.e, the actual set\\n\\t\\t\\t\\tif ( aLast.match(__reFn ) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// Function call\\n\\t\\t\\t\\t\\tdata = data[ aLast.replace(__reFn, '') ]( val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// If array notation is used, we just want to strip it and use the property name\\n\\t\\t\\t\\t\\t// and assign the value. If it isn't used, then we get the result we want anyway\\n\\t\\t\\t\\t\\tdata[ aLast.replace(__reArray, '') ] = val;\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\n\\t\\t\\treturn function (data, val) { // meta is also passed in, but not used\\n\\t\\t\\t\\treturn setData( data, val, mSource );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t/* Array or flat object mapping */\\n\\t\\t\\treturn function (data, val) { // meta is also passed in, but not used\\n\\t\\t\\t\\tdata[mSource] = val;\\n\\t\\t\\t};\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return an array with the full table data\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns array {array} aData Master data array\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetDataMaster ( settings )\\n\\t{\\n\\t\\treturn _pluck( settings.aoData, '_aData' );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Nuke the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnClearTable( settings )\\n\\t{\\n\\t\\tsettings.aoData.length = 0;\\n\\t\\tsettings.aiDisplayMaster.length = 0;\\n\\t\\tsettings.aiDisplay.length = 0;\\n\\t\\tsettings.aIds = {};\\n\\t}\\n\\t\\n\\t\\n\\t /**\\n\\t * Take an array of integers (index array) and remove a target integer (value - not\\n\\t * the key!)\\n\\t * @param {array} a Index array to target\\n\\t * @param {int} iTarget value to find\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDeleteIndex( a, iTarget, splice )\\n\\t{\\n\\t\\tvar iTargetIndex = -1;\\n\\t\\n\\t\\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tif ( a[i] == iTarget )\\n\\t\\t\\t{\\n\\t\\t\\t\\tiTargetIndex = i;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( a[i] > iTarget )\\n\\t\\t\\t{\\n\\t\\t\\t\\ta[i]--;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tif ( iTargetIndex != -1 && splice === undefined )\\n\\t\\t{\\n\\t\\t\\ta.splice( iTargetIndex, 1 );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Mark cached data as invalid such that a re-read of the data will occur when\\n\\t * the cached data is next requested. Also update from the data source object.\\n\\t *\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {int} rowIdx Row index to invalidate\\n\\t * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'\\n\\t * or 'data'\\n\\t * @param {int} [colIdx] Column index to invalidate. If undefined the whole\\n\\t * row will be invalidated\\n\\t * @memberof DataTable#oApi\\n\\t *\\n\\t * @todo For the modularisation of v1.11 this will need to become a callback, so\\n\\t * the sort and filter methods can subscribe to it. That will required\\n\\t * initialisation options for sorting, which is why it is not already baked in\\n\\t */\\n\\tfunction _fnInvalidate( settings, rowIdx, src, colIdx )\\n\\t{\\n\\t\\tvar row = settings.aoData[ rowIdx ];\\n\\t\\tvar i, ien;\\n\\t\\tvar cellWrite = function ( cell, col ) {\\n\\t\\t\\t// This is very frustrating, but in IE if you just write directly\\n\\t\\t\\t// to innerHTML, and elements that are overwritten are GC'ed,\\n\\t\\t\\t// even if there is a reference to them elsewhere\\n\\t\\t\\twhile ( cell.childNodes.length ) {\\n\\t\\t\\t\\tcell.removeChild( cell.firstChild );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\\n\\t\\t};\\n\\t\\n\\t\\t// Are we reading last data from DOM or the data object?\\n\\t\\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\\n\\t\\t\\t// Read the data from the DOM\\n\\t\\t\\trow._aData = _fnGetRowElements(\\n\\t\\t\\t\\t\\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.data;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Reading from data object, update the DOM\\n\\t\\t\\tvar cells = row.anCells;\\n\\t\\n\\t\\t\\tif ( cells ) {\\n\\t\\t\\t\\tif ( colIdx !== undefined ) {\\n\\t\\t\\t\\t\\tcellWrite( cells[colIdx], colIdx );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t\\tcellWrite( cells[i], i );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// For both row and cell invalidation, the cached data for sorting and\\n\\t\\t// filtering is nulled out\\n\\t\\trow._aSortData = null;\\n\\t\\trow._aFilterData = null;\\n\\t\\n\\t\\t// Invalidate the type for a specific column (if given) or all columns since\\n\\t\\t// the data might have changed\\n\\t\\tvar cols = settings.aoColumns;\\n\\t\\tif ( colIdx !== undefined ) {\\n\\t\\t\\tcols[ colIdx ].sType = null;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tfor ( i=0, ien=cols.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcols[i].sType = null;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Update DataTables special `DT_*` attributes for the row\\n\\t\\t\\t_fnRowAttributes( settings, row );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Build a data source object from an HTML row, reading the contents of the\\n\\t * cells that are in the row.\\n\\t *\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {node|object} TR element from which to read data or existing row\\n\\t * object from which to re-read the data from the cells\\n\\t * @param {int} [colIdx] Optional column index\\n\\t * @param {array|object} [d] Data source object. If `colIdx` is given then this\\n\\t * parameter should also be given and will be used to write the data into.\\n\\t * Only the column in question will be written\\n\\t * @returns {object} Object with two parameters: `data` the data read, in\\n\\t * document order, and `cells` and array of nodes (they can be useful to the\\n\\t * caller, so rather than needing a second traversal to get them, just return\\n\\t * them from here).\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetRowElements( settings, row, colIdx, d )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttds = [],\\n\\t\\t\\ttd = row.firstChild,\\n\\t\\t\\tname, col, o, i=0, contents,\\n\\t\\t\\tcolumns = settings.aoColumns,\\n\\t\\t\\tobjectRead = settings._rowReadObject;\\n\\t\\n\\t\\t// Allow the data object to be passed in, or construct\\n\\t\\td = d !== undefined ?\\n\\t\\t\\td :\\n\\t\\t\\tobjectRead ?\\n\\t\\t\\t\\t{} :\\n\\t\\t\\t\\t[];\\n\\t\\n\\t\\tvar attr = function ( str, td ) {\\n\\t\\t\\tif ( typeof str === 'string' ) {\\n\\t\\t\\t\\tvar idx = str.indexOf('@');\\n\\t\\n\\t\\t\\t\\tif ( idx !== -1 ) {\\n\\t\\t\\t\\t\\tvar attr = str.substring( idx+1 );\\n\\t\\t\\t\\t\\tvar setter = _fnSetObjectDataFn( str );\\n\\t\\t\\t\\t\\tsetter( d, td.getAttribute( attr ) );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\t// Read data from a cell and store into the data object\\n\\t\\tvar cellProcess = function ( cell ) {\\n\\t\\t\\tif ( colIdx === undefined || colIdx === i ) {\\n\\t\\t\\t\\tcol = columns[i];\\n\\t\\t\\t\\tcontents = $.trim(cell.innerHTML);\\n\\t\\n\\t\\t\\t\\tif ( col && col._bAttrSrc ) {\\n\\t\\t\\t\\t\\tvar setter = _fnSetObjectDataFn( col.mData._ );\\n\\t\\t\\t\\t\\tsetter( d, contents );\\n\\t\\n\\t\\t\\t\\t\\tattr( col.mData.sort, cell );\\n\\t\\t\\t\\t\\tattr( col.mData.type, cell );\\n\\t\\t\\t\\t\\tattr( col.mData.filter, cell );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t// Depending on the `data` option for the columns the data can\\n\\t\\t\\t\\t\\t// be read to either an object or an array.\\n\\t\\t\\t\\t\\tif ( objectRead ) {\\n\\t\\t\\t\\t\\t\\tif ( ! col._setter ) {\\n\\t\\t\\t\\t\\t\\t\\t// Cache the setter function\\n\\t\\t\\t\\t\\t\\t\\tcol._setter = _fnSetObjectDataFn( col.mData );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\tcol._setter( d, contents );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\td[i] = contents;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\ti++;\\n\\t\\t};\\n\\t\\n\\t\\tif ( td ) {\\n\\t\\t\\t// `tr` element was passed in\\n\\t\\t\\twhile ( td ) {\\n\\t\\t\\t\\tname = td.nodeName.toUpperCase();\\n\\t\\n\\t\\t\\t\\tif ( name == \\\"TD\\\" || name == \\\"TH\\\" ) {\\n\\t\\t\\t\\t\\tcellProcess( td );\\n\\t\\t\\t\\t\\ttds.push( td );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\ttd = td.nextSibling;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Existing row object passed in\\n\\t\\t\\ttds = row.anCells;\\n\\t\\n\\t\\t\\tfor ( var j=0, jen=tds.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\tcellProcess( tds[j] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// Read the ID from the DOM if present\\n\\t\\tvar rowNode = row.firstChild ? row : row.nTr;\\n\\t\\n\\t\\tif ( rowNode ) {\\n\\t\\t\\tvar id = rowNode.getAttribute( 'id' );\\n\\t\\n\\t\\t\\tif ( id ) {\\n\\t\\t\\t\\t_fnSetObjectDataFn( settings.rowId )( d, id );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn {\\n\\t\\t\\tdata: d,\\n\\t\\t\\tcells: tds\\n\\t\\t};\\n\\t}\\n\\t/**\\n\\t * Create a new TR element (and it's TD children) for a row\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iRow Row to consider\\n\\t * @param {node} [nTrIn] TR element to add to the table - optional. If not given,\\n\\t * DataTables will create a row automatically\\n\\t * @param {array} [anTds] Array of TD|TH elements for the row - must be given\\n\\t * if nTr is.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCreateTr ( oSettings, iRow, nTrIn, anTds )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\trow = oSettings.aoData[iRow],\\n\\t\\t\\trowData = row._aData,\\n\\t\\t\\tcells = [],\\n\\t\\t\\tnTr, nTd, oCol,\\n\\t\\t\\ti, iLen;\\n\\t\\n\\t\\tif ( row.nTr === null )\\n\\t\\t{\\n\\t\\t\\tnTr = nTrIn || document.createElement('tr');\\n\\t\\n\\t\\t\\trow.nTr = nTr;\\n\\t\\t\\trow.anCells = cells;\\n\\t\\n\\t\\t\\t/* Use a private property on the node to allow reserve mapping from the node\\n\\t\\t\\t * to the aoData array for fast look up\\n\\t\\t\\t */\\n\\t\\t\\tnTr._DT_RowIndex = iRow;\\n\\t\\n\\t\\t\\t/* Special parameters can be given by the data source to be used on the row */\\n\\t\\t\\t_fnRowAttributes( oSettings, row );\\n\\t\\n\\t\\t\\t/* Process each column */\\n\\t\\t\\tfor ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\toCol = oSettings.aoColumns[i];\\n\\t\\n\\t\\t\\t\\tnTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );\\n\\t\\t\\t\\tnTd._DT_CellIndex = {\\n\\t\\t\\t\\t\\trow: iRow,\\n\\t\\t\\t\\t\\tcolumn: i\\n\\t\\t\\t\\t};\\n\\t\\t\\t\\t\\n\\t\\t\\t\\tcells.push( nTd );\\n\\t\\n\\t\\t\\t\\t// Need to create the HTML if new, or if a rendering function is defined\\n\\t\\t\\t\\tif ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&\\n\\t\\t\\t\\t\\t (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')\\n\\t\\t\\t\\t) {\\n\\t\\t\\t\\t\\tnTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t/* Add user defined class */\\n\\t\\t\\t\\tif ( oCol.sClass )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnTd.className += ' '+oCol.sClass;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Visibility - add or remove as required\\n\\t\\t\\t\\tif ( oCol.bVisible && ! nTrIn )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnTr.appendChild( nTd );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( ! oCol.bVisible && nTrIn )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnTd.parentNode.removeChild( nTd );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tif ( oCol.fnCreatedCell )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\toCol.fnCreatedCell.call( oSettings.oInstance,\\n\\t\\t\\t\\t\\t\\tnTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i\\n\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );\\n\\t\\t}\\n\\t\\n\\t\\t// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved\\n\\t\\t// and deployed\\n\\t\\trow.nTr.setAttribute( 'role', 'row' );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Add attributes to a row based on the special `DT_*` parameters in a data\\n\\t * source object.\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {object} DataTables row object for the row to be modified\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnRowAttributes( settings, row )\\n\\t{\\n\\t\\tvar tr = row.nTr;\\n\\t\\tvar data = row._aData;\\n\\t\\n\\t\\tif ( tr ) {\\n\\t\\t\\tvar id = settings.rowIdFn( data );\\n\\t\\n\\t\\t\\tif ( id ) {\\n\\t\\t\\t\\ttr.id = id;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( data.DT_RowClass ) {\\n\\t\\t\\t\\t// Remove any classes added by DT_RowClass before\\n\\t\\t\\t\\tvar a = data.DT_RowClass.split(' ');\\n\\t\\t\\t\\trow.__rowc = row.__rowc ?\\n\\t\\t\\t\\t\\t_unique( row.__rowc.concat( a ) ) :\\n\\t\\t\\t\\t\\ta;\\n\\t\\n\\t\\t\\t\\t$(tr)\\n\\t\\t\\t\\t\\t.removeClass( row.__rowc.join(' ') )\\n\\t\\t\\t\\t\\t.addClass( data.DT_RowClass );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( data.DT_RowAttr ) {\\n\\t\\t\\t\\t$(tr).attr( data.DT_RowAttr );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( data.DT_RowData ) {\\n\\t\\t\\t\\t$(tr).data( data.DT_RowData );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Create the HTML header for the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnBuildHead( oSettings )\\n\\t{\\n\\t\\tvar i, ien, cell, row, column;\\n\\t\\tvar thead = oSettings.nTHead;\\n\\t\\tvar tfoot = oSettings.nTFoot;\\n\\t\\tvar createHeader = $('th, td', thead).length === 0;\\n\\t\\tvar classes = oSettings.oClasses;\\n\\t\\tvar columns = oSettings.aoColumns;\\n\\t\\n\\t\\tif ( createHeader ) {\\n\\t\\t\\trow = $('<tr/>').appendTo( thead );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\\n\\t\\t\\tcolumn = columns[i];\\n\\t\\t\\tcell = $( column.nTh ).addClass( column.sClass );\\n\\t\\n\\t\\t\\tif ( createHeader ) {\\n\\t\\t\\t\\tcell.appendTo( row );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// 1.11 move into sorting\\n\\t\\t\\tif ( oSettings.oFeatures.bSort ) {\\n\\t\\t\\t\\tcell.addClass( column.sSortingClass );\\n\\t\\n\\t\\t\\t\\tif ( column.bSortable !== false ) {\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.attr( 'tabindex', oSettings.iTabIndex )\\n\\t\\t\\t\\t\\t\\t.attr( 'aria-controls', oSettings.sTableId );\\n\\t\\n\\t\\t\\t\\t\\t_fnSortAttachListener( oSettings, column.nTh, i );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( column.sTitle != cell[0].innerHTML ) {\\n\\t\\t\\t\\tcell.html( column.sTitle );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnRenderer( oSettings, 'header' )(\\n\\t\\t\\t\\toSettings, cell, column, classes\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\tif ( createHeader ) {\\n\\t\\t\\t_fnDetectHeader( oSettings.aoHeader, thead );\\n\\t\\t}\\n\\t\\t\\n\\t\\t/* ARIA role for the rows */\\n\\t \\t$(thead).find('>tr').attr('role', 'row');\\n\\t\\n\\t\\t/* Deal with the footer - add classes if required */\\n\\t\\t$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );\\n\\t\\t$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );\\n\\t\\n\\t\\t// Cache the footer cells. Note that we only take the cells from the first\\n\\t\\t// row in the footer. If there is more than one row the user wants to\\n\\t\\t// interact with, they need to use the table().foot() method. Note also this\\n\\t\\t// allows cells to be used for multiple columns using colspan\\n\\t\\tif ( tfoot !== null ) {\\n\\t\\t\\tvar cells = oSettings.aoFooter[0];\\n\\t\\n\\t\\t\\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcolumn = columns[i];\\n\\t\\t\\t\\tcolumn.nTf = cells[i].cell;\\n\\t\\n\\t\\t\\t\\tif ( column.sClass ) {\\n\\t\\t\\t\\t\\t$(column.nTf).addClass( column.sClass );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Draw the header (or footer) element based on the column visibility states. The\\n\\t * methodology here is to use the layout array from _fnDetectHeader, modified for\\n\\t * the instantaneous column visibility, to construct the new layout. The grid is\\n\\t * traversed over cell at a time in a rows x columns grid fashion, although each\\n\\t * cell insert can cover multiple elements in the grid - which is tracks using the\\n\\t * aApplied array. Cell inserts in the grid will only occur where there isn't\\n\\t * already a cell in that position.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param array {objects} aoSource Layout array from _fnDetectHeader\\n\\t * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDrawHead( oSettings, aoSource, bIncludeHidden )\\n\\t{\\n\\t\\tvar i, iLen, j, jLen, k, kLen, n, nLocalTr;\\n\\t\\tvar aoLocal = [];\\n\\t\\tvar aApplied = [];\\n\\t\\tvar iColumns = oSettings.aoColumns.length;\\n\\t\\tvar iRowspan, iColspan;\\n\\t\\n\\t\\tif ( ! aoSource )\\n\\t\\t{\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( bIncludeHidden === undefined )\\n\\t\\t{\\n\\t\\t\\tbIncludeHidden = false;\\n\\t\\t}\\n\\t\\n\\t\\t/* Make a copy of the master layout array, but without the visible columns in it */\\n\\t\\tfor ( i=0, iLen=aoSource.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\taoLocal[i] = aoSource[i].slice();\\n\\t\\t\\taoLocal[i].nTr = aoSource[i].nTr;\\n\\t\\n\\t\\t\\t/* Remove any columns which are currently hidden */\\n\\t\\t\\tfor ( j=iColumns-1 ; j>=0 ; j-- )\\n\\t\\t\\t{\\n\\t\\t\\t\\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taoLocal[i].splice( j, 1 );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Prep the applied array - it needs an element for each row */\\n\\t\\t\\taApplied.push( [] );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tnLocalTr = aoLocal[i].nTr;\\n\\t\\n\\t\\t\\t/* All cells are going to be replaced, so empty out the row */\\n\\t\\t\\tif ( nLocalTr )\\n\\t\\t\\t{\\n\\t\\t\\t\\twhile( (n = nLocalTr.firstChild) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnLocalTr.removeChild( n );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tfor ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tiRowspan = 1;\\n\\t\\t\\t\\tiColspan = 1;\\n\\t\\n\\t\\t\\t\\t/* Check to see if there is already a cell (row/colspan) covering our target\\n\\t\\t\\t\\t * insert point. If there is, then there is nothing to do.\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\tif ( aApplied[i][j] === undefined )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnLocalTr.appendChild( aoLocal[i][j].cell );\\n\\t\\t\\t\\t\\taApplied[i][j] = 1;\\n\\t\\n\\t\\t\\t\\t\\t/* Expand the cell to cover as many rows as needed */\\n\\t\\t\\t\\t\\twhile ( aoLocal[i+iRowspan] !== undefined &&\\n\\t\\t\\t\\t\\t aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\taApplied[i+iRowspan][j] = 1;\\n\\t\\t\\t\\t\\t\\tiRowspan++;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* Expand the cell to cover as many columns as needed */\\n\\t\\t\\t\\t\\twhile ( aoLocal[i][j+iColspan] !== undefined &&\\n\\t\\t\\t\\t\\t aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Must update the applied array over the rows for the columns */\\n\\t\\t\\t\\t\\t\\tfor ( k=0 ; k<iRowspan ; k++ )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\taApplied[i+k][j+iColspan] = 1;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\tiColspan++;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* Do the actual expansion in the DOM */\\n\\t\\t\\t\\t\\t$(aoLocal[i][j].cell)\\n\\t\\t\\t\\t\\t\\t.attr('rowspan', iRowspan)\\n\\t\\t\\t\\t\\t\\t.attr('colspan', iColspan);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Insert the required TR nodes into the table for display\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDraw( oSettings )\\n\\t{\\n\\t\\t/* Provide a pre-callback function which can be used to cancel the draw is false is returned */\\n\\t\\tvar aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );\\n\\t\\tif ( $.inArray( false, aPreDraw ) !== -1 )\\n\\t\\t{\\n\\t\\t\\t_fnProcessingDisplay( oSettings, false );\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar i, iLen, n;\\n\\t\\tvar anRows = [];\\n\\t\\tvar iRowCount = 0;\\n\\t\\tvar asStripeClasses = oSettings.asStripeClasses;\\n\\t\\tvar iStripes = asStripeClasses.length;\\n\\t\\tvar iOpenRows = oSettings.aoOpenRows.length;\\n\\t\\tvar oLang = oSettings.oLanguage;\\n\\t\\tvar iInitDisplayStart = oSettings.iInitDisplayStart;\\n\\t\\tvar bServerSide = _fnDataSource( oSettings ) == 'ssp';\\n\\t\\tvar aiDisplay = oSettings.aiDisplay;\\n\\t\\n\\t\\toSettings.bDrawing = true;\\n\\t\\n\\t\\t/* Check and see if we have an initial draw position from state saving */\\n\\t\\tif ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )\\n\\t\\t{\\n\\t\\t\\toSettings._iDisplayStart = bServerSide ?\\n\\t\\t\\t\\tiInitDisplayStart :\\n\\t\\t\\t\\tiInitDisplayStart >= oSettings.fnRecordsDisplay() ?\\n\\t\\t\\t\\t\\t0 :\\n\\t\\t\\t\\t\\tiInitDisplayStart;\\n\\t\\n\\t\\t\\toSettings.iInitDisplayStart = -1;\\n\\t\\t}\\n\\t\\n\\t\\tvar iDisplayStart = oSettings._iDisplayStart;\\n\\t\\tvar iDisplayEnd = oSettings.fnDisplayEnd();\\n\\t\\n\\t\\t/* Server-side processing draw intercept */\\n\\t\\tif ( oSettings.bDeferLoading )\\n\\t\\t{\\n\\t\\t\\toSettings.bDeferLoading = false;\\n\\t\\t\\toSettings.iDraw++;\\n\\t\\t\\t_fnProcessingDisplay( oSettings, false );\\n\\t\\t}\\n\\t\\telse if ( !bServerSide )\\n\\t\\t{\\n\\t\\t\\toSettings.iDraw++;\\n\\t\\t}\\n\\t\\telse if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )\\n\\t\\t{\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( aiDisplay.length !== 0 )\\n\\t\\t{\\n\\t\\t\\tvar iStart = bServerSide ? 0 : iDisplayStart;\\n\\t\\t\\tvar iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;\\n\\t\\n\\t\\t\\tfor ( var j=iStart ; j<iEnd ; j++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tvar iDataIndex = aiDisplay[j];\\n\\t\\t\\t\\tvar aoData = oSettings.aoData[ iDataIndex ];\\n\\t\\t\\t\\tif ( aoData.nTr === null )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t_fnCreateTr( oSettings, iDataIndex );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tvar nRow = aoData.nTr;\\n\\t\\n\\t\\t\\t\\t/* Remove the old striping classes and then add the new one */\\n\\t\\t\\t\\tif ( iStripes !== 0 )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tvar sStripe = asStripeClasses[ iRowCount % iStripes ];\\n\\t\\t\\t\\t\\tif ( aoData._sRowStripe != sStripe )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );\\n\\t\\t\\t\\t\\t\\taoData._sRowStripe = sStripe;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Row callback functions - might want to manipulate the row\\n\\t\\t\\t\\t// iRowCount and j are not currently documented. Are they at all\\n\\t\\t\\t\\t// useful?\\n\\t\\t\\t\\t_fnCallbackFire( oSettings, 'aoRowCallback', null,\\n\\t\\t\\t\\t\\t[nRow, aoData._aData, iRowCount, j] );\\n\\t\\n\\t\\t\\t\\tanRows.push( nRow );\\n\\t\\t\\t\\tiRowCount++;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t/* Table is empty - create a row with an empty message in it */\\n\\t\\t\\tvar sZero = oLang.sZeroRecords;\\n\\t\\t\\tif ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )\\n\\t\\t\\t{\\n\\t\\t\\t\\tsZero = oLang.sLoadingRecords;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )\\n\\t\\t\\t{\\n\\t\\t\\t\\tsZero = oLang.sEmptyTable;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tanRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )\\n\\t\\t\\t\\t.append( $('<td />', {\\n\\t\\t\\t\\t\\t'valign': 'top',\\n\\t\\t\\t\\t\\t'colSpan': _fnVisbleColumns( oSettings ),\\n\\t\\t\\t\\t\\t'class': oSettings.oClasses.sRowEmpty\\n\\t\\t\\t\\t} ).html( sZero ) )[0];\\n\\t\\t}\\n\\t\\n\\t\\t/* Header and footer callbacks */\\n\\t\\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\\n\\t\\t\\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\\n\\t\\n\\t\\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\\n\\t\\t\\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\\n\\t\\n\\t\\tvar body = $(oSettings.nTBody);\\n\\t\\n\\t\\tbody.children().detach();\\n\\t\\tbody.append( $(anRows) );\\n\\t\\n\\t\\t/* Call all required callback functions for the end of a draw */\\n\\t\\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\\n\\t\\n\\t\\t/* Draw is complete, sorting and filtering must be as well */\\n\\t\\toSettings.bSorted = false;\\n\\t\\toSettings.bFiltered = false;\\n\\t\\toSettings.bDrawing = false;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Redraw the table - taking account of the various features which are enabled\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {boolean} [holdPosition] Keep the current paging position. By default\\n\\t * the paging is reset to the first page\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnReDraw( settings, holdPosition )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tfeatures = settings.oFeatures,\\n\\t\\t\\tsort = features.bSort,\\n\\t\\t\\tfilter = features.bFilter;\\n\\t\\n\\t\\tif ( sort ) {\\n\\t\\t\\t_fnSort( settings );\\n\\t\\t}\\n\\t\\n\\t\\tif ( filter ) {\\n\\t\\t\\t_fnFilterComplete( settings, settings.oPreviousSearch );\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// No filtering, so we want to just use the display master\\n\\t\\t\\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\\n\\t\\t}\\n\\t\\n\\t\\tif ( holdPosition !== true ) {\\n\\t\\t\\tsettings._iDisplayStart = 0;\\n\\t\\t}\\n\\t\\n\\t\\t// Let any modules know about the draw hold position state (used by\\n\\t\\t// scrolling internally)\\n\\t\\tsettings._drawHold = holdPosition;\\n\\t\\n\\t\\t_fnDraw( settings );\\n\\t\\n\\t\\tsettings._drawHold = false;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Add the options to the page HTML for the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddOptionsHtml ( oSettings )\\n\\t{\\n\\t\\tvar classes = oSettings.oClasses;\\n\\t\\tvar table = $(oSettings.nTable);\\n\\t\\tvar holding = $('<div/>').insertBefore( table ); // Holding element for speed\\n\\t\\tvar features = oSettings.oFeatures;\\n\\t\\n\\t\\t// All DataTables are wrapped in a div\\n\\t\\tvar insert = $('<div/>', {\\n\\t\\t\\tid: oSettings.sTableId+'_wrapper',\\n\\t\\t\\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\\n\\t\\t} );\\n\\t\\n\\t\\toSettings.nHolding = holding[0];\\n\\t\\toSettings.nTableWrapper = insert[0];\\n\\t\\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\\n\\t\\n\\t\\t/* Loop over the user set positioning and place the elements as needed */\\n\\t\\tvar aDom = oSettings.sDom.split('');\\n\\t\\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\\n\\t\\tfor ( var i=0 ; i<aDom.length ; i++ )\\n\\t\\t{\\n\\t\\t\\tfeatureNode = null;\\n\\t\\t\\tcOption = aDom[i];\\n\\t\\n\\t\\t\\tif ( cOption == '<' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* New container div */\\n\\t\\t\\t\\tnNewNode = $('<div/>')[0];\\n\\t\\n\\t\\t\\t\\t/* Check to see if we should append an id and/or a class name to the container */\\n\\t\\t\\t\\tcNext = aDom[i+1];\\n\\t\\t\\t\\tif ( cNext == \\\"'\\\" || cNext == '\\\"' )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tsAttr = \\\"\\\";\\n\\t\\t\\t\\t\\tj = 2;\\n\\t\\t\\t\\t\\twhile ( aDom[i+j] != cNext )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tsAttr += aDom[i+j];\\n\\t\\t\\t\\t\\t\\tj++;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* Replace jQuery UI constants @todo depreciated */\\n\\t\\t\\t\\t\\tif ( sAttr == \\\"H\\\" )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tsAttr = classes.sJUIHeader;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( sAttr == \\\"F\\\" )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tsAttr = classes.sJUIFooter;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* The attribute can be in the format of \\\"#id.class\\\", \\\"#id\\\" or \\\"class\\\" This logic\\n\\t\\t\\t\\t\\t * breaks the string into parts and applies them as needed\\n\\t\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\tif ( sAttr.indexOf('.') != -1 )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tvar aSplit = sAttr.split('.');\\n\\t\\t\\t\\t\\t\\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\\n\\t\\t\\t\\t\\t\\tnNewNode.className = aSplit[1];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( sAttr.charAt(0) == \\\"#\\\" )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tnNewNode.className = sAttr;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\ti += j; /* Move along the position array */\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tinsert.append( nNewNode );\\n\\t\\t\\t\\tinsert = $(nNewNode);\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == '>' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* End container div */\\n\\t\\t\\t\\tinsert = insert.parent();\\n\\t\\t\\t}\\n\\t\\t\\t// @todo Move options into their own plugins?\\n\\t\\t\\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Length */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlLength( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'f' && features.bFilter )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Filter */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'r' && features.bProcessing )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* pRocessing */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 't' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Table */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlTable( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'i' && features.bInfo )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Info */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'p' && features.bPaginate )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Pagination */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( DataTable.ext.feature.length !== 0 )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Plug-in features */\\n\\t\\t\\t\\tvar aoFeatures = DataTable.ext.feature;\\n\\t\\t\\t\\tfor ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tif ( cOption == aoFeatures[k].cFeature )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tfeatureNode = aoFeatures[k].fnInit( oSettings );\\n\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Add to the 2D features array */\\n\\t\\t\\tif ( featureNode )\\n\\t\\t\\t{\\n\\t\\t\\t\\tvar aanFeatures = oSettings.aanFeatures;\\n\\t\\n\\t\\t\\t\\tif ( ! aanFeatures[cOption] )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taanFeatures[cOption] = [];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\taanFeatures[cOption].push( featureNode );\\n\\t\\t\\t\\tinsert.append( featureNode );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* Built our DOM structure - replace the holding div with what we want */\\n\\t\\tholding.replaceWith( insert );\\n\\t\\toSettings.nHolding = null;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Use the DOM source to create up an array of header cells. The idea here is to\\n\\t * create a layout grid (array) of rows x columns, which contains a reference\\n\\t * to the cell that that point in the grid (regardless of col/rowspan), such that\\n\\t * any column / row could be removed and the new grid constructed\\n\\t * @param array {object} aLayout Array to store the calculated layout in\\n\\t * @param {node} nThead The header/footer element for the table\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDetectHeader ( aLayout, nThead )\\n\\t{\\n\\t\\tvar nTrs = $(nThead).children('tr');\\n\\t\\tvar nTr, nCell;\\n\\t\\tvar i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;\\n\\t\\tvar bUnique;\\n\\t\\tvar fnShiftCol = function ( a, i, j ) {\\n\\t\\t\\tvar k = a[i];\\n\\t while ( k[j] ) {\\n\\t\\t\\t\\tj++;\\n\\t\\t\\t}\\n\\t\\t\\treturn j;\\n\\t\\t};\\n\\t\\n\\t\\taLayout.splice( 0, aLayout.length );\\n\\t\\n\\t\\t/* We know how many rows there are in the layout - so prep it */\\n\\t\\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\taLayout.push( [] );\\n\\t\\t}\\n\\t\\n\\t\\t/* Calculate a layout array */\\n\\t\\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tnTr = nTrs[i];\\n\\t\\t\\tiColumn = 0;\\n\\t\\n\\t\\t\\t/* For every cell in the row... */\\n\\t\\t\\tnCell = nTr.firstChild;\\n\\t\\t\\twhile ( nCell ) {\\n\\t\\t\\t\\tif ( nCell.nodeName.toUpperCase() == \\\"TD\\\" ||\\n\\t\\t\\t\\t nCell.nodeName.toUpperCase() == \\\"TH\\\" )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t/* Get the col and rowspan attributes from the DOM and sanitise them */\\n\\t\\t\\t\\t\\tiColspan = nCell.getAttribute('colspan') * 1;\\n\\t\\t\\t\\t\\tiRowspan = nCell.getAttribute('rowspan') * 1;\\n\\t\\t\\t\\t\\tiColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;\\n\\t\\t\\t\\t\\tiRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;\\n\\t\\n\\t\\t\\t\\t\\t/* There might be colspan cells already in this row, so shift our target\\n\\t\\t\\t\\t\\t * accordingly\\n\\t\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\tiColShifted = fnShiftCol( aLayout, i, iColumn );\\n\\t\\n\\t\\t\\t\\t\\t/* Cache calculation for unique columns */\\n\\t\\t\\t\\t\\tbUnique = iColspan === 1 ? true : false;\\n\\t\\n\\t\\t\\t\\t\\t/* If there is col / rowspan, copy the information into the layout grid */\\n\\t\\t\\t\\t\\tfor ( l=0 ; l<iColspan ; l++ )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tfor ( k=0 ; k<iRowspan ; k++ )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\taLayout[i+k][iColShifted+l] = {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\\"cell\\\": nCell,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\\"unique\\\": bUnique\\n\\t\\t\\t\\t\\t\\t\\t};\\n\\t\\t\\t\\t\\t\\t\\taLayout[i+k].nTr = nTr;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tnCell = nCell.nextSibling;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get an array of unique th elements, one for each column\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {node} nHeader automatically detect the layout from this node - optional\\n\\t * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional\\n\\t * @returns array {node} aReturn list of unique th's\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetUniqueThs ( oSettings, nHeader, aLayout )\\n\\t{\\n\\t\\tvar aReturn = [];\\n\\t\\tif ( !aLayout )\\n\\t\\t{\\n\\t\\t\\taLayout = oSettings.aoHeader;\\n\\t\\t\\tif ( nHeader )\\n\\t\\t\\t{\\n\\t\\t\\t\\taLayout = [];\\n\\t\\t\\t\\t_fnDetectHeader( aLayout, nHeader );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tfor ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tfor ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tif ( aLayout[i][j].unique &&\\n\\t\\t\\t\\t\\t (!aReturn[j] || !oSettings.bSortCellsTop) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taReturn[j] = aLayout[i][j].cell;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn aReturn;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Create an Ajax call based on the table's settings, taking into account that\\n\\t * parameters can have multiple forms, and backwards compatibility.\\n\\t *\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {array} data Data to send to the server, required by\\n\\t * DataTables - may be augmented by developer callbacks\\n\\t * @param {function} fn Callback function to run when data is obtained\\n\\t */\\n\\tfunction _fnBuildAjax( oSettings, data, fn )\\n\\t{\\n\\t\\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\\n\\t\\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\\n\\t\\n\\t\\t// Convert to object based for 1.10+ if using the old array scheme which can\\n\\t\\t// come from server-side processing or serverParams\\n\\t\\tif ( data && $.isArray(data) ) {\\n\\t\\t\\tvar tmp = {};\\n\\t\\t\\tvar rbracket = /(.*?)\\\\[\\\\]$/;\\n\\t\\n\\t\\t\\t$.each( data, function (key, val) {\\n\\t\\t\\t\\tvar match = val.name.match(rbracket);\\n\\t\\n\\t\\t\\t\\tif ( match ) {\\n\\t\\t\\t\\t\\t// Support for arrays\\n\\t\\t\\t\\t\\tvar name = match[0];\\n\\t\\n\\t\\t\\t\\t\\tif ( ! tmp[ name ] ) {\\n\\t\\t\\t\\t\\t\\ttmp[ name ] = [];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\ttmp[ name ].push( val.value );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\ttmp[val.name] = val.value;\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\t\\tdata = tmp;\\n\\t\\t}\\n\\t\\n\\t\\tvar ajaxData;\\n\\t\\tvar ajax = oSettings.ajax;\\n\\t\\tvar instance = oSettings.oInstance;\\n\\t\\tvar callback = function ( json ) {\\n\\t\\t\\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\\n\\t\\t\\tfn( json );\\n\\t\\t};\\n\\t\\n\\t\\tif ( $.isPlainObject( ajax ) && ajax.data )\\n\\t\\t{\\n\\t\\t\\tajaxData = ajax.data;\\n\\t\\n\\t\\t\\tvar newData = $.isFunction( ajaxData ) ?\\n\\t\\t\\t\\tajaxData( data, oSettings ) : // fn can manipulate data or return\\n\\t\\t\\t\\tajaxData; // an object object or array to merge\\n\\t\\n\\t\\t\\t// If the function returned something, use that alone\\n\\t\\t\\tdata = $.isFunction( ajaxData ) && newData ?\\n\\t\\t\\t\\tnewData :\\n\\t\\t\\t\\t$.extend( true, data, newData );\\n\\t\\n\\t\\t\\t// Remove the data property as we've resolved it already and don't want\\n\\t\\t\\t// jQuery to do it again (it is restored at the end of the function)\\n\\t\\t\\tdelete ajax.data;\\n\\t\\t}\\n\\t\\n\\t\\tvar baseAjax = {\\n\\t\\t\\t\\\"data\\\": data,\\n\\t\\t\\t\\\"success\\\": function (json) {\\n\\t\\t\\t\\tvar error = json.error || json.sError;\\n\\t\\t\\t\\tif ( error ) {\\n\\t\\t\\t\\t\\t_fnLog( oSettings, 0, error );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\toSettings.json = json;\\n\\t\\t\\t\\tcallback( json );\\n\\t\\t\\t},\\n\\t\\t\\t\\\"dataType\\\": \\\"json\\\",\\n\\t\\t\\t\\\"cache\\\": false,\\n\\t\\t\\t\\\"type\\\": oSettings.sServerMethod,\\n\\t\\t\\t\\\"error\\\": function (xhr, error, thrown) {\\n\\t\\t\\t\\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\\n\\t\\n\\t\\t\\t\\tif ( $.inArray( true, ret ) === -1 ) {\\n\\t\\t\\t\\t\\tif ( error == \\\"parsererror\\\" ) {\\n\\t\\t\\t\\t\\t\\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( xhr.readyState === 4 ) {\\n\\t\\t\\t\\t\\t\\t_fnLog( oSettings, 0, 'Ajax error', 7 );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t_fnProcessingDisplay( oSettings, false );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\t// Store the data submitted for the API\\n\\t\\toSettings.oAjaxData = data;\\n\\t\\n\\t\\t// Allow plug-ins and external processes to modify the data\\n\\t\\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\\n\\t\\n\\t\\tif ( oSettings.fnServerData )\\n\\t\\t{\\n\\t\\t\\t// DataTables 1.9- compatibility\\n\\t\\t\\toSettings.fnServerData.call( instance,\\n\\t\\t\\t\\toSettings.sAjaxSource,\\n\\t\\t\\t\\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\\n\\t\\t\\t\\t\\treturn { name: key, value: val };\\n\\t\\t\\t\\t} ),\\n\\t\\t\\t\\tcallback,\\n\\t\\t\\t\\toSettings\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\\n\\t\\t{\\n\\t\\t\\t// DataTables 1.9- compatibility\\n\\t\\t\\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\\n\\t\\t\\t\\turl: ajax || oSettings.sAjaxSource\\n\\t\\t\\t} ) );\\n\\t\\t}\\n\\t\\telse if ( $.isFunction( ajax ) )\\n\\t\\t{\\n\\t\\t\\t// Is a function - let the caller define what needs to be done\\n\\t\\t\\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t// Object to extend the base settings\\n\\t\\t\\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\\n\\t\\n\\t\\t\\t// Restore for next time around\\n\\t\\t\\tajax.data = ajaxData;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Update the table using an Ajax call\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {boolean} Block the table drawing or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAjaxUpdate( settings )\\n\\t{\\n\\t\\tif ( settings.bAjaxDataGet ) {\\n\\t\\t\\tsettings.iDraw++;\\n\\t\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t\\t_fnBuildAjax(\\n\\t\\t\\t\\tsettings,\\n\\t\\t\\t\\t_fnAjaxParameters( settings ),\\n\\t\\t\\t\\tfunction(json) {\\n\\t\\t\\t\\t\\t_fnAjaxUpdateDraw( settings, json );\\n\\t\\t\\t\\t}\\n\\t\\t\\t);\\n\\t\\n\\t\\t\\treturn false;\\n\\t\\t}\\n\\t\\treturn true;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Build up the parameters in an object needed for a server-side processing\\n\\t * request. Note that this is basically done twice, is different ways - a modern\\n\\t * method which is used by default in DataTables 1.10 which uses objects and\\n\\t * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\\n\\t * the sAjaxSource option is used in the initialisation, or the legacyAjax\\n\\t * option is set.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {bool} block the table drawing or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAjaxParameters( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tcolumns = settings.aoColumns,\\n\\t\\t\\tcolumnCount = columns.length,\\n\\t\\t\\tfeatures = settings.oFeatures,\\n\\t\\t\\tpreSearch = settings.oPreviousSearch,\\n\\t\\t\\tpreColSearch = settings.aoPreSearchCols,\\n\\t\\t\\ti, data = [], dataProp, column, columnSearch,\\n\\t\\t\\tsort = _fnSortFlatten( settings ),\\n\\t\\t\\tdisplayStart = settings._iDisplayStart,\\n\\t\\t\\tdisplayLength = features.bPaginate !== false ?\\n\\t\\t\\t\\tsettings._iDisplayLength :\\n\\t\\t\\t\\t-1;\\n\\t\\n\\t\\tvar param = function ( name, value ) {\\n\\t\\t\\tdata.push( { 'name': name, 'value': value } );\\n\\t\\t};\\n\\t\\n\\t\\t// DataTables 1.9- compatible method\\n\\t\\tparam( 'sEcho', settings.iDraw );\\n\\t\\tparam( 'iColumns', columnCount );\\n\\t\\tparam( 'sColumns', _pluck( columns, 'sName' ).join(',') );\\n\\t\\tparam( 'iDisplayStart', displayStart );\\n\\t\\tparam( 'iDisplayLength', displayLength );\\n\\t\\n\\t\\t// DataTables 1.10+ method\\n\\t\\tvar d = {\\n\\t\\t\\tdraw: settings.iDraw,\\n\\t\\t\\tcolumns: [],\\n\\t\\t\\torder: [],\\n\\t\\t\\tstart: displayStart,\\n\\t\\t\\tlength: displayLength,\\n\\t\\t\\tsearch: {\\n\\t\\t\\t\\tvalue: preSearch.sSearch,\\n\\t\\t\\t\\tregex: preSearch.bRegex\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\tfor ( i=0 ; i<columnCount ; i++ ) {\\n\\t\\t\\tcolumn = columns[i];\\n\\t\\t\\tcolumnSearch = preColSearch[i];\\n\\t\\t\\tdataProp = typeof column.mData==\\\"function\\\" ? 'function' : column.mData ;\\n\\t\\n\\t\\t\\td.columns.push( {\\n\\t\\t\\t\\tdata: dataProp,\\n\\t\\t\\t\\tname: column.sName,\\n\\t\\t\\t\\tsearchable: column.bSearchable,\\n\\t\\t\\t\\torderable: column.bSortable,\\n\\t\\t\\t\\tsearch: {\\n\\t\\t\\t\\t\\tvalue: columnSearch.sSearch,\\n\\t\\t\\t\\t\\tregex: columnSearch.bRegex\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tparam( \\\"mDataProp_\\\"+i, dataProp );\\n\\t\\n\\t\\t\\tif ( features.bFilter ) {\\n\\t\\t\\t\\tparam( 'sSearch_'+i, columnSearch.sSearch );\\n\\t\\t\\t\\tparam( 'bRegex_'+i, columnSearch.bRegex );\\n\\t\\t\\t\\tparam( 'bSearchable_'+i, column.bSearchable );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( features.bSort ) {\\n\\t\\t\\t\\tparam( 'bSortable_'+i, column.bSortable );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tif ( features.bFilter ) {\\n\\t\\t\\tparam( 'sSearch', preSearch.sSearch );\\n\\t\\t\\tparam( 'bRegex', preSearch.bRegex );\\n\\t\\t}\\n\\t\\n\\t\\tif ( features.bSort ) {\\n\\t\\t\\t$.each( sort, function ( i, val ) {\\n\\t\\t\\t\\td.order.push( { column: val.col, dir: val.dir } );\\n\\t\\n\\t\\t\\t\\tparam( 'iSortCol_'+i, val.col );\\n\\t\\t\\t\\tparam( 'sSortDir_'+i, val.dir );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tparam( 'iSortingCols', sort.length );\\n\\t\\t}\\n\\t\\n\\t\\t// If the legacy.ajax parameter is null, then we automatically decide which\\n\\t\\t// form to use, based on sAjaxSource\\n\\t\\tvar legacy = DataTable.ext.legacy.ajax;\\n\\t\\tif ( legacy === null ) {\\n\\t\\t\\treturn settings.sAjaxSource ? data : d;\\n\\t\\t}\\n\\t\\n\\t\\t// Otherwise, if legacy has been specified then we use that to decide on the\\n\\t\\t// form\\n\\t\\treturn legacy ? data : d;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Data the data from the server (nuking the old) and redraw the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} json json data return from the server.\\n\\t * @param {string} json.sEcho Tracking flag for DataTables to match requests\\n\\t * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering\\n\\t * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering\\n\\t * @param {array} json.aaData The data to display on this page\\n\\t * @param {string} [json.sColumns] Column ordering (sName, comma separated)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAjaxUpdateDraw ( settings, json )\\n\\t{\\n\\t\\t// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.\\n\\t\\t// Support both\\n\\t\\tvar compat = function ( old, modern ) {\\n\\t\\t\\treturn json[old] !== undefined ? json[old] : json[modern];\\n\\t\\t};\\n\\t\\n\\t\\tvar data = _fnAjaxDataSrc( settings, json );\\n\\t\\tvar draw = compat( 'sEcho', 'draw' );\\n\\t\\tvar recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );\\n\\t\\tvar recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );\\n\\t\\n\\t\\tif ( draw ) {\\n\\t\\t\\t// Protect against out of sequence returns\\n\\t\\t\\tif ( draw*1 < settings.iDraw ) {\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\tsettings.iDraw = draw * 1;\\n\\t\\t}\\n\\t\\n\\t\\t_fnClearTable( settings );\\n\\t\\tsettings._iRecordsTotal = parseInt(recordsTotal, 10);\\n\\t\\tsettings._iRecordsDisplay = parseInt(recordsFiltered, 10);\\n\\t\\n\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t_fnAddData( settings, data[i] );\\n\\t\\t}\\n\\t\\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\\n\\t\\n\\t\\tsettings.bAjaxDataGet = false;\\n\\t\\t_fnDraw( settings );\\n\\t\\n\\t\\tif ( ! settings._bInitComplete ) {\\n\\t\\t\\t_fnInitComplete( settings, json );\\n\\t\\t}\\n\\t\\n\\t\\tsettings.bAjaxDataGet = true;\\n\\t\\t_fnProcessingDisplay( settings, false );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the data from the JSON data source to use for drawing a table. Using\\n\\t * `_fnGetObjectDataFn` allows the data to be sourced from a property of the\\n\\t * source object, or from a processing function.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} json Data source object / array from the server\\n\\t * @return {array} Array of data to use\\n\\t */\\n\\tfunction _fnAjaxDataSrc ( oSettings, json )\\n\\t{\\n\\t\\tvar dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?\\n\\t\\t\\toSettings.ajax.dataSrc :\\n\\t\\t\\toSettings.sAjaxDataProp; // Compatibility with 1.9-.\\n\\t\\n\\t\\t// Compatibility with 1.9-. In order to read from aaData, check if the\\n\\t\\t// default has been changed, if not, check for aaData\\n\\t\\tif ( dataSrc === 'data' ) {\\n\\t\\t\\treturn json.aaData || json[dataSrc];\\n\\t\\t}\\n\\t\\n\\t\\treturn dataSrc !== \\\"\\\" ?\\n\\t\\t\\t_fnGetObjectDataFn( dataSrc )( json ) :\\n\\t\\t\\tjson;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Generate the node required for filtering text\\n\\t * @returns {node} Filter control element\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlFilter ( settings )\\n\\t{\\n\\t\\tvar classes = settings.oClasses;\\n\\t\\tvar tableId = settings.sTableId;\\n\\t\\tvar language = settings.oLanguage;\\n\\t\\tvar previousSearch = settings.oPreviousSearch;\\n\\t\\tvar features = settings.aanFeatures;\\n\\t\\tvar input = '<input type=\\\"search\\\" class=\\\"'+classes.sFilterInput+'\\\"/>';\\n\\t\\n\\t\\tvar str = language.sSearch;\\n\\t\\tstr = str.match(/_INPUT_/) ?\\n\\t\\t\\tstr.replace('_INPUT_', input) :\\n\\t\\t\\tstr+input;\\n\\t\\n\\t\\tvar filter = $('<div/>', {\\n\\t\\t\\t\\t'id': ! features.f ? tableId+'_filter' : null,\\n\\t\\t\\t\\t'class': classes.sFilter\\n\\t\\t\\t} )\\n\\t\\t\\t.append( $('<label/>' ).append( str ) );\\n\\t\\n\\t\\tvar searchFn = function() {\\n\\t\\t\\t/* Update all other filter input elements for the new display */\\n\\t\\t\\tvar n = features.f;\\n\\t\\t\\tvar val = !this.value ? \\\"\\\" : this.value; // mental IE8 fix :-(\\n\\t\\n\\t\\t\\t/* Now do the filter */\\n\\t\\t\\tif ( val != previousSearch.sSearch ) {\\n\\t\\t\\t\\t_fnFilterComplete( settings, {\\n\\t\\t\\t\\t\\t\\\"sSearch\\\": val,\\n\\t\\t\\t\\t\\t\\\"bRegex\\\": previousSearch.bRegex,\\n\\t\\t\\t\\t\\t\\\"bSmart\\\": previousSearch.bSmart ,\\n\\t\\t\\t\\t\\t\\\"bCaseInsensitive\\\": previousSearch.bCaseInsensitive\\n\\t\\t\\t\\t} );\\n\\t\\n\\t\\t\\t\\t// Need to redraw, without resorting\\n\\t\\t\\t\\tsettings._iDisplayStart = 0;\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\tvar searchDelay = settings.searchDelay !== null ?\\n\\t\\t\\tsettings.searchDelay :\\n\\t\\t\\t_fnDataSource( settings ) === 'ssp' ?\\n\\t\\t\\t\\t400 :\\n\\t\\t\\t\\t0;\\n\\t\\n\\t\\tvar jqFilter = $('input', filter)\\n\\t\\t\\t.val( previousSearch.sSearch )\\n\\t\\t\\t.attr( 'placeholder', language.sSearchPlaceholder )\\n\\t\\t\\t.on(\\n\\t\\t\\t\\t'keyup.DT search.DT input.DT paste.DT cut.DT',\\n\\t\\t\\t\\tsearchDelay ?\\n\\t\\t\\t\\t\\t_fnThrottle( searchFn, searchDelay ) :\\n\\t\\t\\t\\t\\tsearchFn\\n\\t\\t\\t)\\n\\t\\t\\t.on( 'keypress.DT', function(e) {\\n\\t\\t\\t\\t/* Prevent form submission */\\n\\t\\t\\t\\tif ( e.keyCode == 13 ) {\\n\\t\\t\\t\\t\\treturn false;\\n\\t\\t\\t\\t}\\n\\t\\t\\t} )\\n\\t\\t\\t.attr('aria-controls', tableId);\\n\\t\\n\\t\\t// Update the input elements whenever the table is filtered\\n\\t\\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\\n\\t\\t\\tif ( settings === s ) {\\n\\t\\t\\t\\t// IE9 throws an 'unknown error' if document.activeElement is used\\n\\t\\t\\t\\t// inside an iframe or frame...\\n\\t\\t\\t\\ttry {\\n\\t\\t\\t\\t\\tif ( jqFilter[0] !== document.activeElement ) {\\n\\t\\t\\t\\t\\t\\tjqFilter.val( previousSearch.sSearch );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tcatch ( e ) {}\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn filter[0];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Filter the table using both the global filter and column based filtering\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} oSearch search information\\n\\t * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterComplete ( oSettings, oInput, iForce )\\n\\t{\\n\\t\\tvar oPrevSearch = oSettings.oPreviousSearch;\\n\\t\\tvar aoPrevSearch = oSettings.aoPreSearchCols;\\n\\t\\tvar fnSaveFilter = function ( oFilter ) {\\n\\t\\t\\t/* Save the filtering values */\\n\\t\\t\\toPrevSearch.sSearch = oFilter.sSearch;\\n\\t\\t\\toPrevSearch.bRegex = oFilter.bRegex;\\n\\t\\t\\toPrevSearch.bSmart = oFilter.bSmart;\\n\\t\\t\\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\\n\\t\\t};\\n\\t\\tvar fnRegex = function ( o ) {\\n\\t\\t\\t// Backwards compatibility with the bEscapeRegex option\\n\\t\\t\\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\\n\\t\\t};\\n\\t\\n\\t\\t// Resolve any column types that are unknown due to addition or invalidation\\n\\t\\t// @todo As per sort - can this be moved into an event handler?\\n\\t\\t_fnColumnTypes( oSettings );\\n\\t\\n\\t\\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\\n\\t\\tif ( _fnDataSource( oSettings ) != 'ssp' )\\n\\t\\t{\\n\\t\\t\\t/* Global filter */\\n\\t\\t\\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\\n\\t\\t\\tfnSaveFilter( oInput );\\n\\t\\n\\t\\t\\t/* Now do the individual column filter */\\n\\t\\t\\tfor ( var i=0 ; i<aoPrevSearch.length ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),\\n\\t\\t\\t\\t\\taoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Custom filtering */\\n\\t\\t\\t_fnFilterCustom( oSettings );\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\tfnSaveFilter( oInput );\\n\\t\\t}\\n\\t\\n\\t\\t/* Tell the draw function we have been filtering */\\n\\t\\toSettings.bFiltered = true;\\n\\t\\t_fnCallbackFire( oSettings, null, 'search', [oSettings] );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Apply custom filtering functions\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterCustom( settings )\\n\\t{\\n\\t\\tvar filters = DataTable.ext.search;\\n\\t\\tvar displayRows = settings.aiDisplay;\\n\\t\\tvar row, rowIdx;\\n\\t\\n\\t\\tfor ( var i=0, ien=filters.length ; i<ien ; i++ ) {\\n\\t\\t\\tvar rows = [];\\n\\t\\n\\t\\t\\t// Loop over each row and see if it should be included\\n\\t\\t\\tfor ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\trowIdx = displayRows[ j ];\\n\\t\\t\\t\\trow = settings.aoData[ rowIdx ];\\n\\t\\n\\t\\t\\t\\tif ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {\\n\\t\\t\\t\\t\\trows.push( rowIdx );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// So the array reference doesn't break set the results into the\\n\\t\\t\\t// existing array\\n\\t\\t\\tdisplayRows.length = 0;\\n\\t\\t\\t$.merge( displayRows, rows );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Filter the table on a per-column basis\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {string} sInput string to filter on\\n\\t * @param {int} iColumn column to filter\\n\\t * @param {bool} bRegex treat search string as a regular expression or not\\n\\t * @param {bool} bSmart use smart filtering or not\\n\\t * @param {bool} bCaseInsensitive Do case insenstive matching or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )\\n\\t{\\n\\t\\tif ( searchStr === '' ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar data;\\n\\t\\tvar out = [];\\n\\t\\tvar display = settings.aiDisplay;\\n\\t\\tvar rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );\\n\\t\\n\\t\\tfor ( var i=0 ; i<display.length ; i++ ) {\\n\\t\\t\\tdata = settings.aoData[ display[i] ]._aFilterData[ colIdx ];\\n\\t\\n\\t\\t\\tif ( rpSearch.test( data ) ) {\\n\\t\\t\\t\\tout.push( display[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tsettings.aiDisplay = out;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Filter the data table based on user input and draw the table\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {string} input string to filter on\\n\\t * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)\\n\\t * @param {bool} regex treat as a regular expression or not\\n\\t * @param {bool} smart perform smart filtering or not\\n\\t * @param {bool} caseInsensitive Do case insenstive matching or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilter( settings, input, force, regex, smart, caseInsensitive )\\n\\t{\\n\\t\\tvar rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );\\n\\t\\tvar prevSearch = settings.oPreviousSearch.sSearch;\\n\\t\\tvar displayMaster = settings.aiDisplayMaster;\\n\\t\\tvar display, invalidated, i;\\n\\t\\tvar filtered = [];\\n\\t\\n\\t\\t// Need to take account of custom filtering functions - always filter\\n\\t\\tif ( DataTable.ext.search.length !== 0 ) {\\n\\t\\t\\tforce = true;\\n\\t\\t}\\n\\t\\n\\t\\t// Check if any of the rows were invalidated\\n\\t\\tinvalidated = _fnFilterData( settings );\\n\\t\\n\\t\\t// If the input is blank - we just want the full data set\\n\\t\\tif ( input.length <= 0 ) {\\n\\t\\t\\tsettings.aiDisplay = displayMaster.slice();\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// New search - start from the master array\\n\\t\\t\\tif ( invalidated ||\\n\\t\\t\\t\\t force ||\\n\\t\\t\\t\\t prevSearch.length > input.length ||\\n\\t\\t\\t\\t input.indexOf(prevSearch) !== 0 ||\\n\\t\\t\\t\\t settings.bSorted // On resort, the display master needs to be\\n\\t\\t\\t\\t // re-filtered since indexes will have changed\\n\\t\\t\\t) {\\n\\t\\t\\t\\tsettings.aiDisplay = displayMaster.slice();\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Search the display array\\n\\t\\t\\tdisplay = settings.aiDisplay;\\n\\t\\n\\t\\t\\tfor ( i=0 ; i<display.length ; i++ ) {\\n\\t\\t\\t\\tif ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {\\n\\t\\t\\t\\t\\tfiltered.push( display[i] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tsettings.aiDisplay = filtered;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Build a regular expression object suitable for searching a table\\n\\t * @param {string} sSearch string to search for\\n\\t * @param {bool} bRegex treat as a regular expression or not\\n\\t * @param {bool} bSmart perform smart filtering or not\\n\\t * @param {bool} bCaseInsensitive Do case insensitive matching or not\\n\\t * @returns {RegExp} constructed object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterCreateSearch( search, regex, smart, caseInsensitive )\\n\\t{\\n\\t\\tsearch = regex ?\\n\\t\\t\\tsearch :\\n\\t\\t\\t_fnEscapeRegex( search );\\n\\t\\t\\n\\t\\tif ( smart ) {\\n\\t\\t\\t/* For smart filtering we want to allow the search to work regardless of\\n\\t\\t\\t * word order. We also want double quoted text to be preserved, so word\\n\\t\\t\\t * order is important - a la google. So this is what we want to\\n\\t\\t\\t * generate:\\n\\t\\t\\t * \\n\\t\\t\\t * ^(?=.*?\\\\bone\\\\b)(?=.*?\\\\btwo three\\\\b)(?=.*?\\\\bfour\\\\b).*$\\n\\t\\t\\t */\\n\\t\\t\\tvar a = $.map( search.match( /\\\"[^\\\"]+\\\"|[^ ]+/g ) || [''], function ( word ) {\\n\\t\\t\\t\\tif ( word.charAt(0) === '\\\"' ) {\\n\\t\\t\\t\\t\\tvar m = word.match( /^\\\"(.*)\\\"$/ );\\n\\t\\t\\t\\t\\tword = m ? m[1] : word;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn word.replace('\\\"', '');\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tsearch = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';\\n\\t\\t}\\n\\t\\n\\t\\treturn new RegExp( search, caseInsensitive ? 'i' : '' );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Escape a string such that it can be used in a regular expression\\n\\t * @param {string} sVal string to escape\\n\\t * @returns {string} escaped string\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tvar _fnEscapeRegex = DataTable.util.escapeRegex;\\n\\t\\n\\tvar __filter_div = $('<div>')[0];\\n\\tvar __filter_div_textContent = __filter_div.textContent !== undefined;\\n\\t\\n\\t// Update the filtering data for each row if needed (by invalidation or first run)\\n\\tfunction _fnFilterData ( settings )\\n\\t{\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar column;\\n\\t\\tvar i, j, ien, jen, filterData, cellData, row;\\n\\t\\tvar fomatters = DataTable.ext.type.search;\\n\\t\\tvar wasInvalidated = false;\\n\\t\\n\\t\\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\trow = settings.aoData[i];\\n\\t\\n\\t\\t\\tif ( ! row._aFilterData ) {\\n\\t\\t\\t\\tfilterData = [];\\n\\t\\n\\t\\t\\t\\tfor ( j=0, jen=columns.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\tcolumn = columns[j];\\n\\t\\n\\t\\t\\t\\t\\tif ( column.bSearchable ) {\\n\\t\\t\\t\\t\\t\\tcellData = _fnGetCellData( settings, i, j, 'filter' );\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( fomatters[ column.sType ] ) {\\n\\t\\t\\t\\t\\t\\t\\tcellData = fomatters[ column.sType ]( cellData );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t// Search in DataTables 1.10 is string based. In 1.11 this\\n\\t\\t\\t\\t\\t\\t// should be altered to also allow strict type checking.\\n\\t\\t\\t\\t\\t\\tif ( cellData === null ) {\\n\\t\\t\\t\\t\\t\\t\\tcellData = '';\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( typeof cellData !== 'string' && cellData.toString ) {\\n\\t\\t\\t\\t\\t\\t\\tcellData = cellData.toString();\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tcellData = '';\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// If it looks like there is an HTML entity in the string,\\n\\t\\t\\t\\t\\t// attempt to decode it so sorting works as expected. Note that\\n\\t\\t\\t\\t\\t// we could use a single line of jQuery to do this, but the DOM\\n\\t\\t\\t\\t\\t// method used here is much faster http://jsperf.com/html-decode\\n\\t\\t\\t\\t\\tif ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {\\n\\t\\t\\t\\t\\t\\t__filter_div.innerHTML = cellData;\\n\\t\\t\\t\\t\\t\\tcellData = __filter_div_textContent ?\\n\\t\\t\\t\\t\\t\\t\\t__filter_div.textContent :\\n\\t\\t\\t\\t\\t\\t\\t__filter_div.innerText;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tif ( cellData.replace ) {\\n\\t\\t\\t\\t\\t\\tcellData = cellData.replace(/[\\\\r\\\\n]/g, '');\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tfilterData.push( cellData );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\trow._aFilterData = filterData;\\n\\t\\t\\t\\trow._sFilterRow = filterData.join(' ');\\n\\t\\t\\t\\twasInvalidated = true;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn wasInvalidated;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from the internal Hungarian notation to camelCase for external\\n\\t * interaction\\n\\t * @param {object} obj Object to convert\\n\\t * @returns {object} Inverted object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSearchToCamel ( obj )\\n\\t{\\n\\t\\treturn {\\n\\t\\t\\tsearch: obj.sSearch,\\n\\t\\t\\tsmart: obj.bSmart,\\n\\t\\t\\tregex: obj.bRegex,\\n\\t\\t\\tcaseInsensitive: obj.bCaseInsensitive\\n\\t\\t};\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from camelCase notation to the internal Hungarian. We could use the\\n\\t * Hungarian convert function here, but this is cleaner\\n\\t * @param {object} obj Object to convert\\n\\t * @returns {object} Inverted object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSearchToHung ( obj )\\n\\t{\\n\\t\\treturn {\\n\\t\\t\\tsSearch: obj.search,\\n\\t\\t\\tbSmart: obj.smart,\\n\\t\\t\\tbRegex: obj.regex,\\n\\t\\t\\tbCaseInsensitive: obj.caseInsensitive\\n\\t\\t};\\n\\t}\\n\\t\\n\\t/**\\n\\t * Generate the node required for the info display\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {node} Information element\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlInfo ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttid = settings.sTableId,\\n\\t\\t\\tnodes = settings.aanFeatures.i,\\n\\t\\t\\tn = $('<div/>', {\\n\\t\\t\\t\\t'class': settings.oClasses.sInfo,\\n\\t\\t\\t\\t'id': ! nodes ? tid+'_info' : null\\n\\t\\t\\t} );\\n\\t\\n\\t\\tif ( ! nodes ) {\\n\\t\\t\\t// Update display on each draw\\n\\t\\t\\tsettings.aoDrawCallback.push( {\\n\\t\\t\\t\\t\\\"fn\\\": _fnUpdateInfo,\\n\\t\\t\\t\\t\\\"sName\\\": \\\"information\\\"\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tn\\n\\t\\t\\t\\t.attr( 'role', 'status' )\\n\\t\\t\\t\\t.attr( 'aria-live', 'polite' );\\n\\t\\n\\t\\t\\t// Table is described by our info div\\n\\t\\t\\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\\n\\t\\t}\\n\\t\\n\\t\\treturn n[0];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Update the information elements in the display\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnUpdateInfo ( settings )\\n\\t{\\n\\t\\t/* Show information about the table */\\n\\t\\tvar nodes = settings.aanFeatures.i;\\n\\t\\tif ( nodes.length === 0 ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\tlang = settings.oLanguage,\\n\\t\\t\\tstart = settings._iDisplayStart+1,\\n\\t\\t\\tend = settings.fnDisplayEnd(),\\n\\t\\t\\tmax = settings.fnRecordsTotal(),\\n\\t\\t\\ttotal = settings.fnRecordsDisplay(),\\n\\t\\t\\tout = total ?\\n\\t\\t\\t\\tlang.sInfo :\\n\\t\\t\\t\\tlang.sInfoEmpty;\\n\\t\\n\\t\\tif ( total !== max ) {\\n\\t\\t\\t/* Record set after filtering */\\n\\t\\t\\tout += ' ' + lang.sInfoFiltered;\\n\\t\\t}\\n\\t\\n\\t\\t// Convert the macros\\n\\t\\tout += lang.sInfoPostFix;\\n\\t\\tout = _fnInfoMacros( settings, out );\\n\\t\\n\\t\\tvar callback = lang.fnInfoCallback;\\n\\t\\tif ( callback !== null ) {\\n\\t\\t\\tout = callback.call( settings.oInstance,\\n\\t\\t\\t\\tsettings, start, end, max, total, out\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\t$(nodes).html( out );\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnInfoMacros ( settings, str )\\n\\t{\\n\\t\\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\\n\\t\\t// internally\\n\\t\\tvar\\n\\t\\t\\tformatter = settings.fnFormatNumber,\\n\\t\\t\\tstart = settings._iDisplayStart+1,\\n\\t\\t\\tlen = settings._iDisplayLength,\\n\\t\\t\\tvis = settings.fnRecordsDisplay(),\\n\\t\\t\\tall = len === -1;\\n\\t\\n\\t\\treturn str.\\n\\t\\t\\treplace(/_START_/g, formatter.call( settings, start ) ).\\n\\t\\t\\treplace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).\\n\\t\\t\\treplace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).\\n\\t\\t\\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\\n\\t\\t\\treplace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\\n\\t\\t\\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Draw the table for the first time, adding all required features\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnInitialise ( settings )\\n\\t{\\n\\t\\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\\n\\t\\tvar columns = settings.aoColumns, column;\\n\\t\\tvar features = settings.oFeatures;\\n\\t\\tvar deferLoading = settings.bDeferLoading; // value modified by the draw\\n\\t\\n\\t\\t/* Ensure that the table data is fully initialised */\\n\\t\\tif ( ! settings.bInitialised ) {\\n\\t\\t\\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\t/* Show the display HTML options */\\n\\t\\t_fnAddOptionsHtml( settings );\\n\\t\\n\\t\\t/* Build and draw the header / footer for the table */\\n\\t\\t_fnBuildHead( settings );\\n\\t\\t_fnDrawHead( settings, settings.aoHeader );\\n\\t\\t_fnDrawHead( settings, settings.aoFooter );\\n\\t\\n\\t\\t/* Okay to show that something is going on now */\\n\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t/* Calculate sizes for columns */\\n\\t\\tif ( features.bAutoWidth ) {\\n\\t\\t\\t_fnCalculateColumnWidths( settings );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ ) {\\n\\t\\t\\tcolumn = columns[i];\\n\\t\\n\\t\\t\\tif ( column.sWidth ) {\\n\\t\\t\\t\\tcolumn.nTh.style.width = _fnStringToCss( column.sWidth );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'preInit', [settings] );\\n\\t\\n\\t\\t// If there is default sorting required - let's do it. The sort function\\n\\t\\t// will do the drawing for us. Otherwise we draw the table regardless of the\\n\\t\\t// Ajax source - this allows the table to look initialised for Ajax sourcing\\n\\t\\t// data (show 'loading' message possibly)\\n\\t\\t_fnReDraw( settings );\\n\\t\\n\\t\\t// Server-side processing init complete is done by _fnAjaxUpdateDraw\\n\\t\\tvar dataSrc = _fnDataSource( settings );\\n\\t\\tif ( dataSrc != 'ssp' || deferLoading ) {\\n\\t\\t\\t// if there is an ajax source load the data\\n\\t\\t\\tif ( dataSrc == 'ajax' ) {\\n\\t\\t\\t\\t_fnBuildAjax( settings, [], function(json) {\\n\\t\\t\\t\\t\\tvar aData = _fnAjaxDataSrc( settings, json );\\n\\t\\n\\t\\t\\t\\t\\t// Got the data - add it to the table\\n\\t\\t\\t\\t\\tfor ( i=0 ; i<aData.length ; i++ ) {\\n\\t\\t\\t\\t\\t\\t_fnAddData( settings, aData[i] );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// Reset the init display for cookie saving. We've already done\\n\\t\\t\\t\\t\\t// a filter, and therefore cleared it before. So we need to make\\n\\t\\t\\t\\t\\t// it appear 'fresh'\\n\\t\\t\\t\\t\\tsettings.iInitDisplayStart = iAjaxStart;\\n\\t\\n\\t\\t\\t\\t\\t_fnReDraw( settings );\\n\\t\\n\\t\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t\\t\\t_fnInitComplete( settings, json );\\n\\t\\t\\t\\t}, settings );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t\\t_fnInitComplete( settings );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Draw the table for the first time, adding all required features\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} [json] JSON from the server that completed the table, if using Ajax source\\n\\t * with client-side processing (optional)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnInitComplete ( settings, json )\\n\\t{\\n\\t\\tsettings._bInitComplete = true;\\n\\t\\n\\t\\t// When data was added after the initialisation (data or Ajax) we need to\\n\\t\\t// calculate the column sizing\\n\\t\\tif ( json || settings.oInit.aaData ) {\\n\\t\\t\\t_fnAdjustColumnSizing( settings );\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );\\n\\t\\t_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnLengthChange ( settings, val )\\n\\t{\\n\\t\\tvar len = parseInt( val, 10 );\\n\\t\\tsettings._iDisplayLength = len;\\n\\t\\n\\t\\t_fnLengthOverflow( settings );\\n\\t\\n\\t\\t// Fire length change event\\n\\t\\t_fnCallbackFire( settings, null, 'length', [settings, len] );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Generate the node required for user display length changing\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {node} Display length feature node\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlLength ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tclasses = settings.oClasses,\\n\\t\\t\\ttableId = settings.sTableId,\\n\\t\\t\\tmenu = settings.aLengthMenu,\\n\\t\\t\\td2 = $.isArray( menu[0] ),\\n\\t\\t\\tlengths = d2 ? menu[0] : menu,\\n\\t\\t\\tlanguage = d2 ? menu[1] : menu;\\n\\t\\n\\t\\tvar select = $('<select/>', {\\n\\t\\t\\t'name': tableId+'_length',\\n\\t\\t\\t'aria-controls': tableId,\\n\\t\\t\\t'class': classes.sLengthSelect\\n\\t\\t} );\\n\\t\\n\\t\\tfor ( var i=0, ien=lengths.length ; i<ien ; i++ ) {\\n\\t\\t\\tselect[0][ i ] = new Option( language[i], lengths[i] );\\n\\t\\t}\\n\\t\\n\\t\\tvar div = $('<div><label/></div>').addClass( classes.sLength );\\n\\t\\tif ( ! settings.aanFeatures.l ) {\\n\\t\\t\\tdiv[0].id = tableId+'_length';\\n\\t\\t}\\n\\t\\n\\t\\tdiv.children().append(\\n\\t\\t\\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\\n\\t\\t);\\n\\t\\n\\t\\t// Can't use `select` variable as user might provide their own and the\\n\\t\\t// reference is broken by the use of outerHTML\\n\\t\\t$('select', div)\\n\\t\\t\\t.val( settings._iDisplayLength )\\n\\t\\t\\t.on( 'change.DT', function(e) {\\n\\t\\t\\t\\t_fnLengthChange( settings, $(this).val() );\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t// Update node value whenever anything changes the table's length\\n\\t\\t$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {\\n\\t\\t\\tif ( settings === s ) {\\n\\t\\t\\t\\t$('select', div).val( len );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn div[0];\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\\t * Note that most of the paging logic is done in\\n\\t * DataTable.ext.pager\\n\\t */\\n\\t\\n\\t/**\\n\\t * Generate the node required for default pagination\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {node} Pagination feature node\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlPaginate ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttype = settings.sPaginationType,\\n\\t\\t\\tplugin = DataTable.ext.pager[ type ],\\n\\t\\t\\tmodern = typeof plugin === 'function',\\n\\t\\t\\tredraw = function( settings ) {\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t},\\n\\t\\t\\tnode = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],\\n\\t\\t\\tfeatures = settings.aanFeatures;\\n\\t\\n\\t\\tif ( ! modern ) {\\n\\t\\t\\tplugin.fnInit( settings, node, redraw );\\n\\t\\t}\\n\\t\\n\\t\\t/* Add a draw callback for the pagination on first instance, to update the paging display */\\n\\t\\tif ( ! features.p )\\n\\t\\t{\\n\\t\\t\\tnode.id = settings.sTableId+'_paginate';\\n\\t\\n\\t\\t\\tsettings.aoDrawCallback.push( {\\n\\t\\t\\t\\t\\\"fn\\\": function( settings ) {\\n\\t\\t\\t\\t\\tif ( modern ) {\\n\\t\\t\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\t\\t\\t\\t\\tlen = settings._iDisplayLength,\\n\\t\\t\\t\\t\\t\\t\\tvisRecords = settings.fnRecordsDisplay(),\\n\\t\\t\\t\\t\\t\\t\\tall = len === -1,\\n\\t\\t\\t\\t\\t\\t\\tpage = all ? 0 : Math.ceil( start / len ),\\n\\t\\t\\t\\t\\t\\t\\tpages = all ? 1 : Math.ceil( visRecords / len ),\\n\\t\\t\\t\\t\\t\\t\\tbuttons = plugin(page, pages),\\n\\t\\t\\t\\t\\t\\t\\ti, ien;\\n\\t\\n\\t\\t\\t\\t\\t\\tfor ( i=0, ien=features.p.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t\\t\\t_fnRenderer( settings, 'pageButton' )(\\n\\t\\t\\t\\t\\t\\t\\t\\tsettings, features.p[i], i, buttons, page, pages\\n\\t\\t\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tplugin.fnUpdate( settings, redraw );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\\"sName\\\": \\\"pagination\\\"\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\treturn node;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Alter the display settings to change the page\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {string|int} action Paging action to take: \\\"first\\\", \\\"previous\\\",\\n\\t * \\\"next\\\" or \\\"last\\\" or page number to jump to (integer)\\n\\t * @param [bool] redraw Automatically draw the update or not\\n\\t * @returns {bool} true page has changed, false - no change\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnPageChange ( settings, action, redraw )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\tlen = settings._iDisplayLength,\\n\\t\\t\\trecords = settings.fnRecordsDisplay();\\n\\t\\n\\t\\tif ( records === 0 || len === -1 )\\n\\t\\t{\\n\\t\\t\\tstart = 0;\\n\\t\\t}\\n\\t\\telse if ( typeof action === \\\"number\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = action * len;\\n\\t\\n\\t\\t\\tif ( start > records )\\n\\t\\t\\t{\\n\\t\\t\\t\\tstart = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( action == \\\"first\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = 0;\\n\\t\\t}\\n\\t\\telse if ( action == \\\"previous\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = len >= 0 ?\\n\\t\\t\\t\\tstart - len :\\n\\t\\t\\t\\t0;\\n\\t\\n\\t\\t\\tif ( start < 0 )\\n\\t\\t\\t{\\n\\t\\t\\t start = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( action == \\\"next\\\" )\\n\\t\\t{\\n\\t\\t\\tif ( start + len < records )\\n\\t\\t\\t{\\n\\t\\t\\t\\tstart += len;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( action == \\\"last\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = Math.floor( (records-1) / len) * len;\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t_fnLog( settings, 0, \\\"Unknown paging action: \\\"+action, 5 );\\n\\t\\t}\\n\\t\\n\\t\\tvar changed = settings._iDisplayStart !== start;\\n\\t\\tsettings._iDisplayStart = start;\\n\\t\\n\\t\\tif ( changed ) {\\n\\t\\t\\t_fnCallbackFire( settings, null, 'page', [settings] );\\n\\t\\n\\t\\t\\tif ( redraw ) {\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn changed;\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Generate the node required for the processing node\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {node} Processing element\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlProcessing ( settings )\\n\\t{\\n\\t\\treturn $('<div/>', {\\n\\t\\t\\t\\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\\n\\t\\t\\t\\t'class': settings.oClasses.sProcessing\\n\\t\\t\\t} )\\n\\t\\t\\t.html( settings.oLanguage.sProcessing )\\n\\t\\t\\t.insertBefore( settings.nTable )[0];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Display or hide the processing indicator\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {bool} show Show the processing indicator (true) or not (false)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnProcessingDisplay ( settings, show )\\n\\t{\\n\\t\\tif ( settings.oFeatures.bProcessing ) {\\n\\t\\t\\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\\n\\t}\\n\\t\\n\\t/**\\n\\t * Add any control elements for the table - specifically scrolling\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {node} Node to add to the DOM\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlTable ( settings )\\n\\t{\\n\\t\\tvar table = $(settings.nTable);\\n\\t\\n\\t\\t// Add the ARIA grid role to the table\\n\\t\\ttable.attr( 'role', 'grid' );\\n\\t\\n\\t\\t// Scrolling from here on in\\n\\t\\tvar scroll = settings.oScroll;\\n\\t\\n\\t\\tif ( scroll.sX === '' && scroll.sY === '' ) {\\n\\t\\t\\treturn settings.nTable;\\n\\t\\t}\\n\\t\\n\\t\\tvar scrollX = scroll.sX;\\n\\t\\tvar scrollY = scroll.sY;\\n\\t\\tvar classes = settings.oClasses;\\n\\t\\tvar caption = table.children('caption');\\n\\t\\tvar captionSide = caption.length ? caption[0]._captionSide : null;\\n\\t\\tvar headerClone = $( table[0].cloneNode(false) );\\n\\t\\tvar footerClone = $( table[0].cloneNode(false) );\\n\\t\\tvar footer = table.children('tfoot');\\n\\t\\tvar _div = '<div/>';\\n\\t\\tvar size = function ( s ) {\\n\\t\\t\\treturn !s ? null : _fnStringToCss( s );\\n\\t\\t};\\n\\t\\n\\t\\tif ( ! footer.length ) {\\n\\t\\t\\tfooter = null;\\n\\t\\t}\\n\\t\\n\\t\\t/*\\n\\t\\t * The HTML structure that we want to generate in this function is:\\n\\t\\t * div - scroller\\n\\t\\t * div - scroll head\\n\\t\\t * div - scroll head inner\\n\\t\\t * table - scroll head table\\n\\t\\t * thead - thead\\n\\t\\t * div - scroll body\\n\\t\\t * table - table (master table)\\n\\t\\t * thead - thead clone for sizing\\n\\t\\t * tbody - tbody\\n\\t\\t * div - scroll foot\\n\\t\\t * div - scroll foot inner\\n\\t\\t * table - scroll foot table\\n\\t\\t * tfoot - tfoot\\n\\t\\t */\\n\\t\\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\\n\\t\\t\\t.append(\\n\\t\\t\\t\\t$(_div, { 'class': classes.sScrollHead } )\\n\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\toverflow: 'hidden',\\n\\t\\t\\t\\t\\t\\tposition: 'relative',\\n\\t\\t\\t\\t\\t\\tborder: 0,\\n\\t\\t\\t\\t\\t\\twidth: scrollX ? size(scrollX) : '100%'\\n\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t$(_div, { 'class': classes.sScrollHeadInner } )\\n\\t\\t\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\t\\t\\t'box-sizing': 'content-box',\\n\\t\\t\\t\\t\\t\\t\\t\\twidth: scroll.sXInner || '100%'\\n\\t\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\theaderClone\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.removeAttr('id')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.css( 'margin-left', 0 )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append( captionSide === 'top' ? caption : null )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\ttable.children('thead')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t)\\n\\t\\t\\t.append(\\n\\t\\t\\t\\t$(_div, { 'class': classes.sScrollBody } )\\n\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\tposition: 'relative',\\n\\t\\t\\t\\t\\t\\toverflow: 'auto',\\n\\t\\t\\t\\t\\t\\twidth: size( scrollX )\\n\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t.append( table )\\n\\t\\t\\t);\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tscroller.append(\\n\\t\\t\\t\\t$(_div, { 'class': classes.sScrollFoot } )\\n\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\toverflow: 'hidden',\\n\\t\\t\\t\\t\\t\\tborder: 0,\\n\\t\\t\\t\\t\\t\\twidth: scrollX ? size(scrollX) : '100%'\\n\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t$(_div, { 'class': classes.sScrollFootInner } )\\n\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\tfooterClone\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.removeAttr('id')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.css( 'margin-left', 0 )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append( captionSide === 'bottom' ? caption : null )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\ttable.children('tfoot')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\tvar children = scroller.children();\\n\\t\\tvar scrollHead = children[0];\\n\\t\\tvar scrollBody = children[1];\\n\\t\\tvar scrollFoot = footer ? children[2] : null;\\n\\t\\n\\t\\t// When the body is scrolled, then we also want to scroll the headers\\n\\t\\tif ( scrollX ) {\\n\\t\\t\\t$(scrollBody).on( 'scroll.DT', function (e) {\\n\\t\\t\\t\\tvar scrollLeft = this.scrollLeft;\\n\\t\\n\\t\\t\\t\\tscrollHead.scrollLeft = scrollLeft;\\n\\t\\n\\t\\t\\t\\tif ( footer ) {\\n\\t\\t\\t\\t\\tscrollFoot.scrollLeft = scrollLeft;\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\t$(scrollBody).css(\\n\\t\\t\\tscrollY && scroll.bCollapse ? 'max-height' : 'height', \\n\\t\\t\\tscrollY\\n\\t\\t);\\n\\t\\n\\t\\tsettings.nScrollHead = scrollHead;\\n\\t\\tsettings.nScrollBody = scrollBody;\\n\\t\\tsettings.nScrollFoot = scrollFoot;\\n\\t\\n\\t\\t// On redraw - align columns\\n\\t\\tsettings.aoDrawCallback.push( {\\n\\t\\t\\t\\\"fn\\\": _fnScrollDraw,\\n\\t\\t\\t\\\"sName\\\": \\\"scrolling\\\"\\n\\t\\t} );\\n\\t\\n\\t\\treturn scroller[0];\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Update the header, footer and body tables for resizing - i.e. column\\n\\t * alignment.\\n\\t *\\n\\t * Welcome to the most horrible function DataTables. The process that this\\n\\t * function follows is basically:\\n\\t * 1. Re-create the table inside the scrolling div\\n\\t * 2. Take live measurements from the DOM\\n\\t * 3. Apply the measurements to align the columns\\n\\t * 4. Clean up\\n\\t *\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnScrollDraw ( settings )\\n\\t{\\n\\t\\t// Given that this is such a monster function, a lot of variables are use\\n\\t\\t// to try and keep the minimised size as small as possible\\n\\t\\tvar\\n\\t\\t\\tscroll = settings.oScroll,\\n\\t\\t\\tscrollX = scroll.sX,\\n\\t\\t\\tscrollXInner = scroll.sXInner,\\n\\t\\t\\tscrollY = scroll.sY,\\n\\t\\t\\tbarWidth = scroll.iBarWidth,\\n\\t\\t\\tdivHeader = $(settings.nScrollHead),\\n\\t\\t\\tdivHeaderStyle = divHeader[0].style,\\n\\t\\t\\tdivHeaderInner = divHeader.children('div'),\\n\\t\\t\\tdivHeaderInnerStyle = divHeaderInner[0].style,\\n\\t\\t\\tdivHeaderTable = divHeaderInner.children('table'),\\n\\t\\t\\tdivBodyEl = settings.nScrollBody,\\n\\t\\t\\tdivBody = $(divBodyEl),\\n\\t\\t\\tdivBodyStyle = divBodyEl.style,\\n\\t\\t\\tdivFooter = $(settings.nScrollFoot),\\n\\t\\t\\tdivFooterInner = divFooter.children('div'),\\n\\t\\t\\tdivFooterTable = divFooterInner.children('table'),\\n\\t\\t\\theader = $(settings.nTHead),\\n\\t\\t\\ttable = $(settings.nTable),\\n\\t\\t\\ttableEl = table[0],\\n\\t\\t\\ttableStyle = tableEl.style,\\n\\t\\t\\tfooter = settings.nTFoot ? $(settings.nTFoot) : null,\\n\\t\\t\\tbrowser = settings.oBrowser,\\n\\t\\t\\tie67 = browser.bScrollOversize,\\n\\t\\t\\tdtHeaderCells = _pluck( settings.aoColumns, 'nTh' ),\\n\\t\\t\\theaderTrgEls, footerTrgEls,\\n\\t\\t\\theaderSrcEls, footerSrcEls,\\n\\t\\t\\theaderCopy, footerCopy,\\n\\t\\t\\theaderWidths=[], footerWidths=[],\\n\\t\\t\\theaderContent=[], footerContent=[],\\n\\t\\t\\tidx, correction, sanityWidth,\\n\\t\\t\\tzeroOut = function(nSizer) {\\n\\t\\t\\t\\tvar style = nSizer.style;\\n\\t\\t\\t\\tstyle.paddingTop = \\\"0\\\";\\n\\t\\t\\t\\tstyle.paddingBottom = \\\"0\\\";\\n\\t\\t\\t\\tstyle.borderTopWidth = \\\"0\\\";\\n\\t\\t\\t\\tstyle.borderBottomWidth = \\\"0\\\";\\n\\t\\t\\t\\tstyle.height = 0;\\n\\t\\t\\t};\\n\\t\\n\\t\\t// If the scrollbar visibility has changed from the last draw, we need to\\n\\t\\t// adjust the column sizes as the table width will have changed to account\\n\\t\\t// for the scrollbar\\n\\t\\tvar scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;\\n\\t\\t\\n\\t\\tif ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {\\n\\t\\t\\tsettings.scrollBarVis = scrollBarVis;\\n\\t\\t\\t_fnAdjustColumnSizing( settings );\\n\\t\\t\\treturn; // adjust column sizing will call this function again\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tsettings.scrollBarVis = scrollBarVis;\\n\\t\\t}\\n\\t\\n\\t\\t/*\\n\\t\\t * 1. Re-create the table inside the scrolling div\\n\\t\\t */\\n\\t\\n\\t\\t// Remove the old minimised thead and tfoot elements in the inner table\\n\\t\\ttable.children('thead, tfoot').remove();\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tfooterCopy = footer.clone().prependTo( table );\\n\\t\\t\\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\\n\\t\\t\\tfooterSrcEls = footerCopy.find('tr');\\n\\t\\t}\\n\\t\\n\\t\\t// Clone the current header and footer elements and then place it into the inner table\\n\\t\\theaderCopy = header.clone().prependTo( table );\\n\\t\\theaderTrgEls = header.find('tr'); // original header is in its own table\\n\\t\\theaderSrcEls = headerCopy.find('tr');\\n\\t\\theaderCopy.find('th, td').removeAttr('tabindex');\\n\\t\\n\\t\\n\\t\\t/*\\n\\t\\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\\n\\t\\t */\\n\\t\\n\\t\\t// Remove old sizing and apply the calculated column widths\\n\\t\\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\\n\\t\\t// calculated sizes to this header\\n\\t\\tif ( ! scrollX )\\n\\t\\t{\\n\\t\\t\\tdivBodyStyle.width = '100%';\\n\\t\\t\\tdivHeader[0].style.width = '100%';\\n\\t\\t}\\n\\t\\n\\t\\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\\n\\t\\t\\tidx = _fnVisibleToColumnIndex( settings, i );\\n\\t\\t\\tel.style.width = settings.aoColumns[idx].sWidth;\\n\\t\\t} );\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\t_fnApplyToChildren( function(n) {\\n\\t\\t\\t\\tn.style.width = \\\"\\\";\\n\\t\\t\\t}, footerSrcEls );\\n\\t\\t}\\n\\t\\n\\t\\t// Size the table as a whole\\n\\t\\tsanityWidth = table.outerWidth();\\n\\t\\tif ( scrollX === \\\"\\\" ) {\\n\\t\\t\\t// No x scrolling\\n\\t\\t\\ttableStyle.width = \\\"100%\\\";\\n\\t\\n\\t\\t\\t// IE7 will make the width of the table when 100% include the scrollbar\\n\\t\\t\\t// - which is shouldn't. When there is a scrollbar we need to take this\\n\\t\\t\\t// into account.\\n\\t\\t\\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\\n\\t\\t\\t\\tdivBody.css('overflow-y') == \\\"scroll\\\")\\n\\t\\t\\t) {\\n\\t\\t\\t\\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Recalculate the sanity width\\n\\t\\t\\tsanityWidth = table.outerWidth();\\n\\t\\t}\\n\\t\\telse if ( scrollXInner !== \\\"\\\" ) {\\n\\t\\t\\t// legacy x scroll inner has been given - use it\\n\\t\\t\\ttableStyle.width = _fnStringToCss(scrollXInner);\\n\\t\\n\\t\\t\\t// Recalculate the sanity width\\n\\t\\t\\tsanityWidth = table.outerWidth();\\n\\t\\t}\\n\\t\\n\\t\\t// Hidden header should have zero height, so remove padding and borders. Then\\n\\t\\t// set the width based on the real headers\\n\\t\\n\\t\\t// Apply all styles in one pass\\n\\t\\t_fnApplyToChildren( zeroOut, headerSrcEls );\\n\\t\\n\\t\\t// Read all widths in next pass\\n\\t\\t_fnApplyToChildren( function(nSizer) {\\n\\t\\t\\theaderContent.push( nSizer.innerHTML );\\n\\t\\t\\theaderWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\\n\\t\\t}, headerSrcEls );\\n\\t\\n\\t\\t// Apply all widths in final pass\\n\\t\\t_fnApplyToChildren( function(nToSize, i) {\\n\\t\\t\\t// Only apply widths to the DataTables detected header cells - this\\n\\t\\t\\t// prevents complex headers from having contradictory sizes applied\\n\\t\\t\\tif ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {\\n\\t\\t\\t\\tnToSize.style.width = headerWidths[i];\\n\\t\\t\\t}\\n\\t\\t}, headerTrgEls );\\n\\t\\n\\t\\t$(headerSrcEls).height(0);\\n\\t\\n\\t\\t/* Same again with the footer if we have one */\\n\\t\\tif ( footer )\\n\\t\\t{\\n\\t\\t\\t_fnApplyToChildren( zeroOut, footerSrcEls );\\n\\t\\n\\t\\t\\t_fnApplyToChildren( function(nSizer) {\\n\\t\\t\\t\\tfooterContent.push( nSizer.innerHTML );\\n\\t\\t\\t\\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\\n\\t\\t\\t}, footerSrcEls );\\n\\t\\n\\t\\t\\t_fnApplyToChildren( function(nToSize, i) {\\n\\t\\t\\t\\tnToSize.style.width = footerWidths[i];\\n\\t\\t\\t}, footerTrgEls );\\n\\t\\n\\t\\t\\t$(footerSrcEls).height(0);\\n\\t\\t}\\n\\t\\n\\t\\n\\t\\t/*\\n\\t\\t * 3. Apply the measurements\\n\\t\\t */\\n\\t\\n\\t\\t// \\\"Hide\\\" the header and footer that we used for the sizing. We need to keep\\n\\t\\t// the content of the cell so that the width applied to the header and body\\n\\t\\t// both match, but we want to hide it completely. We want to also fix their\\n\\t\\t// width to what they currently are\\n\\t\\t_fnApplyToChildren( function(nSizer, i) {\\n\\t\\t\\tnSizer.innerHTML = '<div class=\\\"dataTables_sizing\\\" style=\\\"height:0;overflow:hidden;\\\">'+headerContent[i]+'</div>';\\n\\t\\t\\tnSizer.style.width = headerWidths[i];\\n\\t\\t}, headerSrcEls );\\n\\t\\n\\t\\tif ( footer )\\n\\t\\t{\\n\\t\\t\\t_fnApplyToChildren( function(nSizer, i) {\\n\\t\\t\\t\\tnSizer.innerHTML = '<div class=\\\"dataTables_sizing\\\" style=\\\"height:0;overflow:hidden;\\\">'+footerContent[i]+'</div>';\\n\\t\\t\\t\\tnSizer.style.width = footerWidths[i];\\n\\t\\t\\t}, footerSrcEls );\\n\\t\\t}\\n\\t\\n\\t\\t// Sanity check that the table is of a sensible width. If not then we are going to get\\n\\t\\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\\n\\t\\tif ( table.outerWidth() < sanityWidth )\\n\\t\\t{\\n\\t\\t\\t// The min width depends upon if we have a vertical scrollbar visible or not */\\n\\t\\t\\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\\n\\t\\t\\t\\tdivBody.css('overflow-y') == \\\"scroll\\\")) ?\\n\\t\\t\\t\\t\\tsanityWidth+barWidth :\\n\\t\\t\\t\\t\\tsanityWidth;\\n\\t\\n\\t\\t\\t// IE6/7 are a law unto themselves...\\n\\t\\t\\tif ( ie67 && (divBodyEl.scrollHeight >\\n\\t\\t\\t\\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \\\"scroll\\\")\\n\\t\\t\\t) {\\n\\t\\t\\t\\ttableStyle.width = _fnStringToCss( correction-barWidth );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// And give the user a warning that we've stopped the table getting too small\\n\\t\\t\\tif ( scrollX === \\\"\\\" || scrollXInner !== \\\"\\\" ) {\\n\\t\\t\\t\\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\tcorrection = '100%';\\n\\t\\t}\\n\\t\\n\\t\\t// Apply to the container elements\\n\\t\\tdivBodyStyle.width = _fnStringToCss( correction );\\n\\t\\tdivHeaderStyle.width = _fnStringToCss( correction );\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\\n\\t\\t}\\n\\t\\n\\t\\n\\t\\t/*\\n\\t\\t * 4. Clean up\\n\\t\\t */\\n\\t\\tif ( ! scrollY ) {\\n\\t\\t\\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\\n\\t\\t\\t * the scrollbar height from the visible display, rather than adding it on. We need to\\n\\t\\t\\t * set the height in order to sort this. Don't want to do it in any other browsers.\\n\\t\\t\\t */\\n\\t\\t\\tif ( ie67 ) {\\n\\t\\t\\t\\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* Finally set the width's of the header and footer tables */\\n\\t\\tvar iOuterWidth = table.outerWidth();\\n\\t\\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\\n\\t\\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\\n\\t\\n\\t\\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\\n\\t\\t// provide a bit more space to allow \\\"overflow\\\" scrolling (i.e. past the scrollbar)\\n\\t\\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \\\"scroll\\\";\\n\\t\\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\\n\\t\\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\\\"px\\\" : \\\"0px\\\";\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\\n\\t\\t\\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\\n\\t\\t\\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\\\"px\\\" : \\\"0px\\\";\\n\\t\\t}\\n\\t\\n\\t\\t// Correct DOM ordering for colgroup - comes before the thead\\n\\t\\ttable.children('colgroup').insertBefore( table.children('thead') );\\n\\t\\n\\t\\t/* Adjust the position of the header in case we loose the y-scrollbar */\\n\\t\\tdivBody.scroll();\\n\\t\\n\\t\\t// If sorting or filtering has occurred, jump the scrolling back to the top\\n\\t\\t// only if we aren't holding the position\\n\\t\\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\\n\\t\\t\\tdivBodyEl.scrollTop = 0;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Apply a given function to the display child nodes of an element array (typically\\n\\t * TD children of TR rows\\n\\t * @param {function} fn Method to apply to the objects\\n\\t * @param array {nodes} an1 List of elements to look through for display children\\n\\t * @param array {nodes} an2 Another list (identical structure to the first) - optional\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnApplyToChildren( fn, an1, an2 )\\n\\t{\\n\\t\\tvar index=0, i=0, iLen=an1.length;\\n\\t\\tvar nNode1, nNode2;\\n\\t\\n\\t\\twhile ( i < iLen ) {\\n\\t\\t\\tnNode1 = an1[i].firstChild;\\n\\t\\t\\tnNode2 = an2 ? an2[i].firstChild : null;\\n\\t\\n\\t\\t\\twhile ( nNode1 ) {\\n\\t\\t\\t\\tif ( nNode1.nodeType === 1 ) {\\n\\t\\t\\t\\t\\tif ( an2 ) {\\n\\t\\t\\t\\t\\t\\tfn( nNode1, nNode2, index );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tfn( nNode1, index );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tindex++;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tnNode1 = nNode1.nextSibling;\\n\\t\\t\\t\\tnNode2 = an2 ? nNode2.nextSibling : null;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\ti++;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\tvar __re_html_remove = /<.*?>/g;\\n\\t\\n\\t\\n\\t/**\\n\\t * Calculate the width of columns for the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCalculateColumnWidths ( oSettings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttable = oSettings.nTable,\\n\\t\\t\\tcolumns = oSettings.aoColumns,\\n\\t\\t\\tscroll = oSettings.oScroll,\\n\\t\\t\\tscrollY = scroll.sY,\\n\\t\\t\\tscrollX = scroll.sX,\\n\\t\\t\\tscrollXInner = scroll.sXInner,\\n\\t\\t\\tcolumnCount = columns.length,\\n\\t\\t\\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\\n\\t\\t\\theaderCells = $('th', oSettings.nTHead),\\n\\t\\t\\ttableWidthAttr = table.getAttribute('width'), // from DOM element\\n\\t\\t\\ttableContainer = table.parentNode,\\n\\t\\t\\tuserInputs = false,\\n\\t\\t\\ti, column, columnIdx, width, outerWidth,\\n\\t\\t\\tbrowser = oSettings.oBrowser,\\n\\t\\t\\tie67 = browser.bScrollOversize;\\n\\t\\n\\t\\tvar styleWidth = table.style.width;\\n\\t\\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\\n\\t\\t\\ttableWidthAttr = styleWidth;\\n\\t\\t}\\n\\t\\n\\t\\t/* Convert any user input sizes into pixel sizes */\\n\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\tcolumn = columns[ visibleColumns[i] ];\\n\\t\\n\\t\\t\\tif ( column.sWidth !== null ) {\\n\\t\\t\\t\\tcolumn.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );\\n\\t\\n\\t\\t\\t\\tuserInputs = true;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* If the number of columns in the DOM equals the number that we have to\\n\\t\\t * process in DataTables, then we can use the offsets that are created by\\n\\t\\t * the web- browser. No custom sizes can be set in order for this to happen,\\n\\t\\t * nor scrolling used\\n\\t\\t */\\n\\t\\tif ( ie67 || ! userInputs && ! scrollX && ! scrollY &&\\n\\t\\t columnCount == _fnVisbleColumns( oSettings ) &&\\n\\t\\t columnCount == headerCells.length\\n\\t\\t) {\\n\\t\\t\\tfor ( i=0 ; i<columnCount ; i++ ) {\\n\\t\\t\\t\\tvar colIdx = _fnVisibleToColumnIndex( oSettings, i );\\n\\t\\n\\t\\t\\t\\tif ( colIdx !== null ) {\\n\\t\\t\\t\\t\\tcolumns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t// Otherwise construct a single row, worst case, table with the widest\\n\\t\\t\\t// node in the data, assign any user defined widths, then insert it into\\n\\t\\t\\t// the DOM and allow the browser to do all the hard work of calculating\\n\\t\\t\\t// table widths\\n\\t\\t\\tvar tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table\\n\\t\\t\\t\\t.css( 'visibility', 'hidden' )\\n\\t\\t\\t\\t.removeAttr( 'id' );\\n\\t\\n\\t\\t\\t// Clean up the table body\\n\\t\\t\\ttmpTable.find('tbody tr').remove();\\n\\t\\t\\tvar tr = $('<tr/>').appendTo( tmpTable.find('tbody') );\\n\\t\\n\\t\\t\\t// Clone the table header and footer - we can't use the header / footer\\n\\t\\t\\t// from the cloned table, since if scrolling is active, the table's\\n\\t\\t\\t// real header and footer are contained in different table tags\\n\\t\\t\\ttmpTable.find('thead, tfoot').remove();\\n\\t\\t\\ttmpTable\\n\\t\\t\\t\\t.append( $(oSettings.nTHead).clone() )\\n\\t\\t\\t\\t.append( $(oSettings.nTFoot).clone() );\\n\\t\\n\\t\\t\\t// Remove any assigned widths from the footer (from scrolling)\\n\\t\\t\\ttmpTable.find('tfoot th, tfoot td').css('width', '');\\n\\t\\n\\t\\t\\t// Apply custom sizing to the cloned header\\n\\t\\t\\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\\n\\t\\n\\t\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\t\\tcolumn = columns[ visibleColumns[i] ];\\n\\t\\n\\t\\t\\t\\theaderCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?\\n\\t\\t\\t\\t\\t_fnStringToCss( column.sWidthOrig ) :\\n\\t\\t\\t\\t\\t'';\\n\\t\\n\\t\\t\\t\\t// For scrollX we need to force the column width otherwise the\\n\\t\\t\\t\\t// browser will collapse it. If this width is smaller than the\\n\\t\\t\\t\\t// width the column requires, then it will have no effect\\n\\t\\t\\t\\tif ( column.sWidthOrig && scrollX ) {\\n\\t\\t\\t\\t\\t$( headerCells[i] ).append( $('<div/>').css( {\\n\\t\\t\\t\\t\\t\\twidth: column.sWidthOrig,\\n\\t\\t\\t\\t\\t\\tmargin: 0,\\n\\t\\t\\t\\t\\t\\tpadding: 0,\\n\\t\\t\\t\\t\\t\\tborder: 0,\\n\\t\\t\\t\\t\\t\\theight: 1\\n\\t\\t\\t\\t\\t} ) );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Find the widest cell for each column and put it into the table\\n\\t\\t\\tif ( oSettings.aoData.length ) {\\n\\t\\t\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\t\\t\\tcolumnIdx = visibleColumns[i];\\n\\t\\t\\t\\t\\tcolumn = columns[ columnIdx ];\\n\\t\\n\\t\\t\\t\\t\\t$( _fnGetWidestNode( oSettings, columnIdx ) )\\n\\t\\t\\t\\t\\t\\t.clone( false )\\n\\t\\t\\t\\t\\t\\t.append( column.sContentPadding )\\n\\t\\t\\t\\t\\t\\t.appendTo( tr );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Tidy the temporary table - remove name attributes so there aren't\\n\\t\\t\\t// duplicated in the dom (radio elements for example)\\n\\t\\t\\t$('[name]', tmpTable).removeAttr('name');\\n\\t\\n\\t\\t\\t// Table has been built, attach to the document so we can work with it.\\n\\t\\t\\t// A holding element is used, positioned at the top of the container\\n\\t\\t\\t// with minimal height, so it has no effect on if the container scrolls\\n\\t\\t\\t// or not. Otherwise it might trigger scrolling when it actually isn't\\n\\t\\t\\t// needed\\n\\t\\t\\tvar holder = $('<div/>').css( scrollX || scrollY ?\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tposition: 'absolute',\\n\\t\\t\\t\\t\\t\\ttop: 0,\\n\\t\\t\\t\\t\\t\\tleft: 0,\\n\\t\\t\\t\\t\\t\\theight: 1,\\n\\t\\t\\t\\t\\t\\tright: 0,\\n\\t\\t\\t\\t\\t\\toverflow: 'hidden'\\n\\t\\t\\t\\t\\t} :\\n\\t\\t\\t\\t\\t{}\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.append( tmpTable )\\n\\t\\t\\t\\t.appendTo( tableContainer );\\n\\t\\n\\t\\t\\t// When scrolling (X or Y) we want to set the width of the table as \\n\\t\\t\\t// appropriate. However, when not scrolling leave the table width as it\\n\\t\\t\\t// is. This results in slightly different, but I think correct behaviour\\n\\t\\t\\tif ( scrollX && scrollXInner ) {\\n\\t\\t\\t\\ttmpTable.width( scrollXInner );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( scrollX ) {\\n\\t\\t\\t\\ttmpTable.css( 'width', 'auto' );\\n\\t\\t\\t\\ttmpTable.removeAttr('width');\\n\\t\\n\\t\\t\\t\\t// If there is no width attribute or style, then allow the table to\\n\\t\\t\\t\\t// collapse\\n\\t\\t\\t\\tif ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {\\n\\t\\t\\t\\t\\ttmpTable.width( tableContainer.clientWidth );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\telse if ( scrollY ) {\\n\\t\\t\\t\\ttmpTable.width( tableContainer.clientWidth );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( tableWidthAttr ) {\\n\\t\\t\\t\\ttmpTable.width( tableWidthAttr );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Get the width of each column in the constructed table - we need to\\n\\t\\t\\t// know the inner width (so it can be assigned to the other table's\\n\\t\\t\\t// cells) and the outer width so we can calculate the full width of the\\n\\t\\t\\t// table. This is safe since DataTables requires a unique cell for each\\n\\t\\t\\t// column, but if ever a header can span multiple columns, this will\\n\\t\\t\\t// need to be modified.\\n\\t\\t\\tvar total = 0;\\n\\t\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\t\\tvar cell = $(headerCells[i]);\\n\\t\\t\\t\\tvar border = cell.outerWidth() - cell.width();\\n\\t\\n\\t\\t\\t\\t// Use getBounding... where possible (not IE8-) because it can give\\n\\t\\t\\t\\t// sub-pixel accuracy, which we then want to round up!\\n\\t\\t\\t\\tvar bounding = browser.bBounding ?\\n\\t\\t\\t\\t\\tMath.ceil( headerCells[i].getBoundingClientRect().width ) :\\n\\t\\t\\t\\t\\tcell.outerWidth();\\n\\t\\n\\t\\t\\t\\t// Total is tracked to remove any sub-pixel errors as the outerWidth\\n\\t\\t\\t\\t// of the table might not equal the total given here (IE!).\\n\\t\\t\\t\\ttotal += bounding;\\n\\t\\n\\t\\t\\t\\t// Width for each column to use\\n\\t\\t\\t\\tcolumns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\ttable.style.width = _fnStringToCss( total );\\n\\t\\n\\t\\t\\t// Finished with the table - ditch it\\n\\t\\t\\tholder.remove();\\n\\t\\t}\\n\\t\\n\\t\\t// If there is a width attr, we want to attach an event listener which\\n\\t\\t// allows the table sizing to automatically adjust when the window is\\n\\t\\t// resized. Use the width attr rather than CSS, since we can't know if the\\n\\t\\t// CSS is a relative value or absolute - DOM read is always px.\\n\\t\\tif ( tableWidthAttr ) {\\n\\t\\t\\ttable.style.width = _fnStringToCss( tableWidthAttr );\\n\\t\\t}\\n\\t\\n\\t\\tif ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {\\n\\t\\t\\tvar bindResize = function () {\\n\\t\\t\\t\\t$(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {\\n\\t\\t\\t\\t\\t_fnAdjustColumnSizing( oSettings );\\n\\t\\t\\t\\t} ) );\\n\\t\\t\\t};\\n\\t\\n\\t\\t\\t// IE6/7 will crash if we bind a resize event handler on page load.\\n\\t\\t\\t// To be removed in 1.11 which drops IE6/7 support\\n\\t\\t\\tif ( ie67 ) {\\n\\t\\t\\t\\tsetTimeout( bindResize, 1000 );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tbindResize();\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\toSettings._reszEvt = true;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Throttle the calls to a function. Arguments and context are maintained for\\n\\t * the throttled function\\n\\t * @param {function} fn Function to be called\\n\\t * @param {int} [freq=200] call frequency in mS\\n\\t * @returns {function} wrapped function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tvar _fnThrottle = DataTable.util.throttle;\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert a CSS unit width to pixels (e.g. 2em)\\n\\t * @param {string} width width to be converted\\n\\t * @param {node} parent parent to get the with for (required for relative widths) - optional\\n\\t * @returns {int} width in pixels\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnConvertToWidth ( width, parent )\\n\\t{\\n\\t\\tif ( ! width ) {\\n\\t\\t\\treturn 0;\\n\\t\\t}\\n\\t\\n\\t\\tvar n = $('<div/>')\\n\\t\\t\\t.css( 'width', _fnStringToCss( width ) )\\n\\t\\t\\t.appendTo( parent || document.body );\\n\\t\\n\\t\\tvar val = n[0].offsetWidth;\\n\\t\\tn.remove();\\n\\t\\n\\t\\treturn val;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the widest node\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} colIdx column of interest\\n\\t * @returns {node} widest table node\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetWidestNode( settings, colIdx )\\n\\t{\\n\\t\\tvar idx = _fnGetMaxLenString( settings, colIdx );\\n\\t\\tif ( idx < 0 ) {\\n\\t\\t\\treturn null;\\n\\t\\t}\\n\\t\\n\\t\\tvar data = settings.aoData[ idx ];\\n\\t\\treturn ! data.nTr ? // Might not have been created when deferred rendering\\n\\t\\t\\t$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\\n\\t\\t\\tdata.anCells[ colIdx ];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the maximum strlen for each data column\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} colIdx column of interest\\n\\t * @returns {string} max string length for each column\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetMaxLenString( settings, colIdx )\\n\\t{\\n\\t\\tvar s, max=-1, maxIdx = -1;\\n\\t\\n\\t\\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\ts = _fnGetCellData( settings, i, colIdx, 'display' )+'';\\n\\t\\t\\ts = s.replace( __re_html_remove, '' );\\n\\t\\t\\ts = s.replace( / /g, ' ' );\\n\\t\\n\\t\\t\\tif ( s.length > max ) {\\n\\t\\t\\t\\tmax = s.length;\\n\\t\\t\\t\\tmaxIdx = i;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn maxIdx;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Append a CSS unit (only if required) to a string\\n\\t * @param {string} value to css-ify\\n\\t * @returns {string} value with css unit\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnStringToCss( s )\\n\\t{\\n\\t\\tif ( s === null ) {\\n\\t\\t\\treturn '0px';\\n\\t\\t}\\n\\t\\n\\t\\tif ( typeof s == 'number' ) {\\n\\t\\t\\treturn s < 0 ?\\n\\t\\t\\t\\t'0px' :\\n\\t\\t\\t\\ts+'px';\\n\\t\\t}\\n\\t\\n\\t\\t// Check it has a unit character already\\n\\t\\treturn s.match(/\\\\d$/) ?\\n\\t\\t\\ts+'px' :\\n\\t\\t\\ts;\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\tfunction _fnSortFlatten ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti, iLen, k, kLen,\\n\\t\\t\\taSort = [],\\n\\t\\t\\taiOrig = [],\\n\\t\\t\\taoColumns = settings.aoColumns,\\n\\t\\t\\taDataSort, iCol, sType, srcCol,\\n\\t\\t\\tfixed = settings.aaSortingFixed,\\n\\t\\t\\tfixedObj = $.isPlainObject( fixed ),\\n\\t\\t\\tnestedSort = [],\\n\\t\\t\\tadd = function ( a ) {\\n\\t\\t\\t\\tif ( a.length && ! $.isArray( a[0] ) ) {\\n\\t\\t\\t\\t\\t// 1D array\\n\\t\\t\\t\\t\\tnestedSort.push( a );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t// 2D array\\n\\t\\t\\t\\t\\t$.merge( nestedSort, a );\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\n\\t\\t// Build the sort array, with pre-fix and post-fix options if they have been\\n\\t\\t// specified\\n\\t\\tif ( $.isArray( fixed ) ) {\\n\\t\\t\\tadd( fixed );\\n\\t\\t}\\n\\t\\n\\t\\tif ( fixedObj && fixed.pre ) {\\n\\t\\t\\tadd( fixed.pre );\\n\\t\\t}\\n\\t\\n\\t\\tadd( settings.aaSorting );\\n\\t\\n\\t\\tif (fixedObj && fixed.post ) {\\n\\t\\t\\tadd( fixed.post );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0 ; i<nestedSort.length ; i++ )\\n\\t\\t{\\n\\t\\t\\tsrcCol = nestedSort[i][0];\\n\\t\\t\\taDataSort = aoColumns[ srcCol ].aDataSort;\\n\\t\\n\\t\\t\\tfor ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tiCol = aDataSort[k];\\n\\t\\t\\t\\tsType = aoColumns[ iCol ].sType || 'string';\\n\\t\\n\\t\\t\\t\\tif ( nestedSort[i]._idx === undefined ) {\\n\\t\\t\\t\\t\\tnestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\taSort.push( {\\n\\t\\t\\t\\t\\tsrc: srcCol,\\n\\t\\t\\t\\t\\tcol: iCol,\\n\\t\\t\\t\\t\\tdir: nestedSort[i][1],\\n\\t\\t\\t\\t\\tindex: nestedSort[i]._idx,\\n\\t\\t\\t\\t\\ttype: sType,\\n\\t\\t\\t\\t\\tformatter: DataTable.ext.type.order[ sType+\\\"-pre\\\" ]\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn aSort;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Change the order of the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t * @todo This really needs split up!\\n\\t */\\n\\tfunction _fnSort ( oSettings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti, ien, iLen, j, jLen, k, kLen,\\n\\t\\t\\tsDataType, nTh,\\n\\t\\t\\taiOrig = [],\\n\\t\\t\\toExtSort = DataTable.ext.type.order,\\n\\t\\t\\taoData = oSettings.aoData,\\n\\t\\t\\taoColumns = oSettings.aoColumns,\\n\\t\\t\\taDataSort, data, iCol, sType, oSort,\\n\\t\\t\\tformatters = 0,\\n\\t\\t\\tsortCol,\\n\\t\\t\\tdisplayMaster = oSettings.aiDisplayMaster,\\n\\t\\t\\taSort;\\n\\t\\n\\t\\t// Resolve any column types that are unknown due to addition or invalidation\\n\\t\\t// @todo Can this be moved into a 'data-ready' handler which is called when\\n\\t\\t// data is going to be used in the table?\\n\\t\\t_fnColumnTypes( oSettings );\\n\\t\\n\\t\\taSort = _fnSortFlatten( oSettings );\\n\\t\\n\\t\\tfor ( i=0, ien=aSort.length ; i<ien ; i++ ) {\\n\\t\\t\\tsortCol = aSort[i];\\n\\t\\n\\t\\t\\t// Track if we can use the fast sort algorithm\\n\\t\\t\\tif ( sortCol.formatter ) {\\n\\t\\t\\t\\tformatters++;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Load the data needed for the sort, for each cell\\n\\t\\t\\t_fnSortData( oSettings, sortCol.col );\\n\\t\\t}\\n\\t\\n\\t\\t/* No sorting required if server-side or no sorting array */\\n\\t\\tif ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )\\n\\t\\t{\\n\\t\\t\\t// Create a value - key array of the current row positions such that we can use their\\n\\t\\t\\t// current position during the sort, if values match, in order to perform stable sorting\\n\\t\\t\\tfor ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {\\n\\t\\t\\t\\taiOrig[ displayMaster[i] ] = i;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Do the sort - here we want multi-column sorting based on a given data source (column)\\n\\t\\t\\t * and sorting function (from oSort) in a certain direction. It's reasonably complex to\\n\\t\\t\\t * follow on it's own, but this is what we want (example two column sorting):\\n\\t\\t\\t * fnLocalSorting = function(a,b){\\n\\t\\t\\t * var iTest;\\n\\t\\t\\t * iTest = oSort['string-asc']('data11', 'data12');\\n\\t\\t\\t * if (iTest !== 0)\\n\\t\\t\\t * return iTest;\\n\\t\\t\\t * iTest = oSort['numeric-desc']('data21', 'data22');\\n\\t\\t\\t * if (iTest !== 0)\\n\\t\\t\\t * return iTest;\\n\\t\\t\\t * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );\\n\\t\\t\\t * }\\n\\t\\t\\t * Basically we have a test for each sorting column, if the data in that column is equal,\\n\\t\\t\\t * test the next column. If all columns match, then we use a numeric sort on the row\\n\\t\\t\\t * positions in the original data array to provide a stable sort.\\n\\t\\t\\t *\\n\\t\\t\\t * Note - I know it seems excessive to have two sorting methods, but the first is around\\n\\t\\t\\t * 15% faster, so the second is only maintained for backwards compatibility with sorting\\n\\t\\t\\t * methods which do not have a pre-sort formatting function.\\n\\t\\t\\t */\\n\\t\\t\\tif ( formatters === aSort.length ) {\\n\\t\\t\\t\\t// All sort types have formatting functions\\n\\t\\t\\t\\tdisplayMaster.sort( function ( a, b ) {\\n\\t\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\t\\tx, y, k, test, sort,\\n\\t\\t\\t\\t\\t\\tlen=aSort.length,\\n\\t\\t\\t\\t\\t\\tdataA = aoData[a]._aSortData,\\n\\t\\t\\t\\t\\t\\tdataB = aoData[b]._aSortData;\\n\\t\\n\\t\\t\\t\\t\\tfor ( k=0 ; k<len ; k++ ) {\\n\\t\\t\\t\\t\\t\\tsort = aSort[k];\\n\\t\\n\\t\\t\\t\\t\\t\\tx = dataA[ sort.col ];\\n\\t\\t\\t\\t\\t\\ty = dataB[ sort.col ];\\n\\t\\n\\t\\t\\t\\t\\t\\ttest = x<y ? -1 : x>y ? 1 : 0;\\n\\t\\t\\t\\t\\t\\tif ( test !== 0 ) {\\n\\t\\t\\t\\t\\t\\t\\treturn sort.dir === 'asc' ? test : -test;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tx = aiOrig[a];\\n\\t\\t\\t\\t\\ty = aiOrig[b];\\n\\t\\t\\t\\t\\treturn x<y ? -1 : x>y ? 1 : 0;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Depreciated - remove in 1.11 (providing a plug-in option)\\n\\t\\t\\t\\t// Not all sort types have formatting methods, so we have to call their sorting\\n\\t\\t\\t\\t// methods.\\n\\t\\t\\t\\tdisplayMaster.sort( function ( a, b ) {\\n\\t\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\t\\tx, y, k, l, test, sort, fn,\\n\\t\\t\\t\\t\\t\\tlen=aSort.length,\\n\\t\\t\\t\\t\\t\\tdataA = aoData[a]._aSortData,\\n\\t\\t\\t\\t\\t\\tdataB = aoData[b]._aSortData;\\n\\t\\n\\t\\t\\t\\t\\tfor ( k=0 ; k<len ; k++ ) {\\n\\t\\t\\t\\t\\t\\tsort = aSort[k];\\n\\t\\n\\t\\t\\t\\t\\t\\tx = dataA[ sort.col ];\\n\\t\\t\\t\\t\\t\\ty = dataB[ sort.col ];\\n\\t\\n\\t\\t\\t\\t\\t\\tfn = oExtSort[ sort.type+\\\"-\\\"+sort.dir ] || oExtSort[ \\\"string-\\\"+sort.dir ];\\n\\t\\t\\t\\t\\t\\ttest = fn( x, y );\\n\\t\\t\\t\\t\\t\\tif ( test !== 0 ) {\\n\\t\\t\\t\\t\\t\\t\\treturn test;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tx = aiOrig[a];\\n\\t\\t\\t\\t\\ty = aiOrig[b];\\n\\t\\t\\t\\t\\treturn x<y ? -1 : x>y ? 1 : 0;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* Tell the draw function that we have sorted the data */\\n\\t\\toSettings.bSorted = true;\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnSortAria ( settings )\\n\\t{\\n\\t\\tvar label;\\n\\t\\tvar nextSort;\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar aSort = _fnSortFlatten( settings );\\n\\t\\tvar oAria = settings.oLanguage.oAria;\\n\\t\\n\\t\\t// ARIA attributes - need to loop all columns, to update all (removing old\\n\\t\\t// attributes as needed)\\n\\t\\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tvar col = columns[i];\\n\\t\\t\\tvar asSorting = col.asSorting;\\n\\t\\t\\tvar sTitle = col.sTitle.replace( /<.*?>/g, \\\"\\\" );\\n\\t\\t\\tvar th = col.nTh;\\n\\t\\n\\t\\t\\t// IE7 is throwing an error when setting these properties with jQuery's\\n\\t\\t\\t// attr() and removeAttr() methods...\\n\\t\\t\\tth.removeAttribute('aria-sort');\\n\\t\\n\\t\\t\\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\\n\\t\\t\\tif ( col.bSortable ) {\\n\\t\\t\\t\\tif ( aSort.length > 0 && aSort[0].col == i ) {\\n\\t\\t\\t\\t\\tth.setAttribute('aria-sort', aSort[0].dir==\\\"asc\\\" ? \\\"ascending\\\" : \\\"descending\\\" );\\n\\t\\t\\t\\t\\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tnextSort = asSorting[0];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tlabel = sTitle + ( nextSort === \\\"asc\\\" ?\\n\\t\\t\\t\\t\\toAria.sSortAscending :\\n\\t\\t\\t\\t\\toAria.sSortDescending\\n\\t\\t\\t\\t);\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tlabel = sTitle;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tth.setAttribute('aria-label', label);\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Function to run on user sort request\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {node} attachTo node to attach the handler to\\n\\t * @param {int} colIdx column sorting index\\n\\t * @param {boolean} [append=false] Append the requested sort to the existing\\n\\t * sort if true (i.e. multi-column sort)\\n\\t * @param {function} [callback] callback function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSortListener ( settings, colIdx, append, callback )\\n\\t{\\n\\t\\tvar col = settings.aoColumns[ colIdx ];\\n\\t\\tvar sorting = settings.aaSorting;\\n\\t\\tvar asSorting = col.asSorting;\\n\\t\\tvar nextSortIdx;\\n\\t\\tvar next = function ( a, overflow ) {\\n\\t\\t\\tvar idx = a._idx;\\n\\t\\t\\tif ( idx === undefined ) {\\n\\t\\t\\t\\tidx = $.inArray( a[1], asSorting );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn idx+1 < asSorting.length ?\\n\\t\\t\\t\\tidx+1 :\\n\\t\\t\\t\\toverflow ?\\n\\t\\t\\t\\t\\tnull :\\n\\t\\t\\t\\t\\t0;\\n\\t\\t};\\n\\t\\n\\t\\t// Convert to 2D array if needed\\n\\t\\tif ( typeof sorting[0] === 'number' ) {\\n\\t\\t\\tsorting = settings.aaSorting = [ sorting ];\\n\\t\\t}\\n\\t\\n\\t\\t// If appending the sort then we are multi-column sorting\\n\\t\\tif ( append && settings.oFeatures.bSortMulti ) {\\n\\t\\t\\t// Are we already doing some kind of sort on this column?\\n\\t\\t\\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\\n\\t\\n\\t\\t\\tif ( sortIdx !== -1 ) {\\n\\t\\t\\t\\t// Yes, modify the sort\\n\\t\\t\\t\\tnextSortIdx = next( sorting[sortIdx], true );\\n\\t\\n\\t\\t\\t\\tif ( nextSortIdx === null && sorting.length === 1 ) {\\n\\t\\t\\t\\t\\tnextSortIdx = 0; // can't remove sorting completely\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tif ( nextSortIdx === null ) {\\n\\t\\t\\t\\t\\tsorting.splice( sortIdx, 1 );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\\n\\t\\t\\t\\t\\tsorting[sortIdx]._idx = nextSortIdx;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// No sort on this column yet\\n\\t\\t\\t\\tsorting.push( [ colIdx, asSorting[0], 0 ] );\\n\\t\\t\\t\\tsorting[sorting.length-1]._idx = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( sorting.length && sorting[0][0] == colIdx ) {\\n\\t\\t\\t// Single column - already sorting on this column, modify the sort\\n\\t\\t\\tnextSortIdx = next( sorting[0] );\\n\\t\\n\\t\\t\\tsorting.length = 1;\\n\\t\\t\\tsorting[0][1] = asSorting[ nextSortIdx ];\\n\\t\\t\\tsorting[0]._idx = nextSortIdx;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Single column - sort only on this column\\n\\t\\t\\tsorting.length = 0;\\n\\t\\t\\tsorting.push( [ colIdx, asSorting[0] ] );\\n\\t\\t\\tsorting[0]._idx = 0;\\n\\t\\t}\\n\\t\\n\\t\\t// Run the sort by calling a full redraw\\n\\t\\t_fnReDraw( settings );\\n\\t\\n\\t\\t// callback used for async user interaction\\n\\t\\tif ( typeof callback == 'function' ) {\\n\\t\\t\\tcallback( settings );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Attach a sort handler (click) to a node\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {node} attachTo node to attach the handler to\\n\\t * @param {int} colIdx column sorting index\\n\\t * @param {function} [callback] callback function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\\n\\t{\\n\\t\\tvar col = settings.aoColumns[ colIdx ];\\n\\t\\n\\t\\t_fnBindAction( attachTo, {}, function (e) {\\n\\t\\t\\t/* If the column is not sortable - don't to anything */\\n\\t\\t\\tif ( col.bSortable === false ) {\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// If processing is enabled use a timeout to allow the processing\\n\\t\\t\\t// display to be shown - otherwise to it synchronously\\n\\t\\t\\tif ( settings.oFeatures.bProcessing ) {\\n\\t\\t\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t\\t\\tsetTimeout( function() {\\n\\t\\t\\t\\t\\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\\n\\t\\n\\t\\t\\t\\t\\t// In server-side processing, the draw callback will remove the\\n\\t\\t\\t\\t\\t// processing display\\n\\t\\t\\t\\t\\tif ( _fnDataSource( settings ) !== 'ssp' ) {\\n\\t\\t\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}, 0 );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Set the sorting classes on table's body, Note: it is safe to call this function\\n\\t * when bSort and bSortClasses are false\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSortingClasses( settings )\\n\\t{\\n\\t\\tvar oldSort = settings.aLastSort;\\n\\t\\tvar sortClass = settings.oClasses.sSortColumn;\\n\\t\\tvar sort = _fnSortFlatten( settings );\\n\\t\\tvar features = settings.oFeatures;\\n\\t\\tvar i, ien, colIdx;\\n\\t\\n\\t\\tif ( features.bSort && features.bSortClasses ) {\\n\\t\\t\\t// Remove old sorting classes\\n\\t\\t\\tfor ( i=0, ien=oldSort.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcolIdx = oldSort[i].src;\\n\\t\\n\\t\\t\\t\\t// Remove column sorting\\n\\t\\t\\t\\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\\n\\t\\t\\t\\t\\t.removeClass( sortClass + (i<2 ? i+1 : 3) );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Add new column sorting\\n\\t\\t\\tfor ( i=0, ien=sort.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcolIdx = sort[i].src;\\n\\t\\n\\t\\t\\t\\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\\n\\t\\t\\t\\t\\t.addClass( sortClass + (i<2 ? i+1 : 3) );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tsettings.aLastSort = sort;\\n\\t}\\n\\t\\n\\t\\n\\t// Get the data to sort a column, be it from cache, fresh (populating the\\n\\t// cache), or from a sort formatter\\n\\tfunction _fnSortData( settings, idx )\\n\\t{\\n\\t\\t// Custom sorting function - provided by the sort data type\\n\\t\\tvar column = settings.aoColumns[ idx ];\\n\\t\\tvar customSort = DataTable.ext.order[ column.sSortDataType ];\\n\\t\\tvar customData;\\n\\t\\n\\t\\tif ( customSort ) {\\n\\t\\t\\tcustomData = customSort.call( settings.oInstance, settings, idx,\\n\\t\\t\\t\\t_fnColumnIndexToVisible( settings, idx )\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\t// Use / populate cache\\n\\t\\tvar row, cellData;\\n\\t\\tvar formatter = DataTable.ext.type.order[ column.sType+\\\"-pre\\\" ];\\n\\t\\n\\t\\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\trow = settings.aoData[i];\\n\\t\\n\\t\\t\\tif ( ! row._aSortData ) {\\n\\t\\t\\t\\trow._aSortData = [];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( ! row._aSortData[idx] || customSort ) {\\n\\t\\t\\t\\tcellData = customSort ?\\n\\t\\t\\t\\t\\tcustomData[i] : // If there was a custom sort function, use data from there\\n\\t\\t\\t\\t\\t_fnGetCellData( settings, i, idx, 'sort' );\\n\\t\\n\\t\\t\\t\\trow._aSortData[ idx ] = formatter ?\\n\\t\\t\\t\\t\\tformatter( cellData ) :\\n\\t\\t\\t\\t\\tcellData;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Save the state of a table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSaveState ( settings )\\n\\t{\\n\\t\\tif ( !settings.oFeatures.bStateSave || settings.bDestroying )\\n\\t\\t{\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\t/* Store the interesting variables */\\n\\t\\tvar state = {\\n\\t\\t\\ttime: +new Date(),\\n\\t\\t\\tstart: settings._iDisplayStart,\\n\\t\\t\\tlength: settings._iDisplayLength,\\n\\t\\t\\torder: $.extend( true, [], settings.aaSorting ),\\n\\t\\t\\tsearch: _fnSearchToCamel( settings.oPreviousSearch ),\\n\\t\\t\\tcolumns: $.map( settings.aoColumns, function ( col, i ) {\\n\\t\\t\\t\\treturn {\\n\\t\\t\\t\\t\\tvisible: col.bVisible,\\n\\t\\t\\t\\t\\tsearch: _fnSearchToCamel( settings.aoPreSearchCols[i] )\\n\\t\\t\\t\\t};\\n\\t\\t\\t} )\\n\\t\\t};\\n\\t\\n\\t\\t_fnCallbackFire( settings, \\\"aoStateSaveParams\\\", 'stateSaveParams', [settings, state] );\\n\\t\\n\\t\\tsettings.oSavedState = state;\\n\\t\\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, state );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Attempt to load a saved table state\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} oInit DataTables init object so we can override settings\\n\\t * @param {function} callback Callback to execute when the state has been loaded\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnLoadState ( settings, oInit, callback )\\n\\t{\\n\\t\\tvar i, ien;\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar loaded = function ( s ) {\\n\\t\\t\\tif ( ! s || ! s.time ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Allow custom and plug-in manipulation functions to alter the saved data set and\\n\\t\\t\\t// cancelling of loading by returning false\\n\\t\\t\\tvar abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );\\n\\t\\t\\tif ( $.inArray( false, abStateLoad ) !== -1 ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Reject old data\\n\\t\\t\\tvar duration = settings.iStateDuration;\\n\\t\\t\\tif ( duration > 0 && s.time < +new Date() - (duration*1000) ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Number of columns have changed - all bets are off, no restore of settings\\n\\t\\t\\tif ( s.columns && columns.length !== s.columns.length ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Store the saved state so it might be accessed at any time\\n\\t\\t\\tsettings.oLoadedState = $.extend( true, {}, s );\\n\\t\\n\\t\\t\\t// Restore key features - todo - for 1.11 this needs to be done by\\n\\t\\t\\t// subscribed events\\n\\t\\t\\tif ( s.start !== undefined ) {\\n\\t\\t\\t\\tsettings._iDisplayStart = s.start;\\n\\t\\t\\t\\tsettings.iInitDisplayStart = s.start;\\n\\t\\t\\t}\\n\\t\\t\\tif ( s.length !== undefined ) {\\n\\t\\t\\t\\tsettings._iDisplayLength = s.length;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Order\\n\\t\\t\\tif ( s.order !== undefined ) {\\n\\t\\t\\t\\tsettings.aaSorting = [];\\n\\t\\t\\t\\t$.each( s.order, function ( i, col ) {\\n\\t\\t\\t\\t\\tsettings.aaSorting.push( col[0] >= columns.length ?\\n\\t\\t\\t\\t\\t\\t[ 0, col[1] ] :\\n\\t\\t\\t\\t\\t\\tcol\\n\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Search\\n\\t\\t\\tif ( s.search !== undefined ) {\\n\\t\\t\\t\\t$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Columns\\n\\t\\t\\t//\\n\\t\\t\\tif ( s.columns ) {\\n\\t\\t\\t\\tfor ( i=0, ien=s.columns.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\tvar col = s.columns[i];\\n\\t\\n\\t\\t\\t\\t\\t// Visibility\\n\\t\\t\\t\\t\\tif ( col.visible !== undefined ) {\\n\\t\\t\\t\\t\\t\\tcolumns[i].bVisible = col.visible;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// Search\\n\\t\\t\\t\\t\\tif ( col.search !== undefined ) {\\n\\t\\t\\t\\t\\t\\t$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );\\n\\t\\t\\tcallback();\\n\\t\\t}\\n\\t\\n\\t\\tif ( ! settings.oFeatures.bStateSave ) {\\n\\t\\t\\tcallback();\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );\\n\\t\\n\\t\\tif ( state !== undefined ) {\\n\\t\\t\\tloaded( state );\\n\\t\\t}\\n\\t\\t// otherwise, wait for the loaded callback to be executed\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return the settings object for a particular table\\n\\t * @param {node} table table we are using as a dataTable\\n\\t * @returns {object} Settings object - or null if not found\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSettingsFromNode ( table )\\n\\t{\\n\\t\\tvar settings = DataTable.settings;\\n\\t\\tvar idx = $.inArray( table, _pluck( settings, 'nTable' ) );\\n\\t\\n\\t\\treturn idx !== -1 ?\\n\\t\\t\\tsettings[ idx ] :\\n\\t\\t\\tnull;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Log an error message\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} level log error messages, or display them to the user\\n\\t * @param {string} msg error message\\n\\t * @param {int} tn Technical note id to get more information about the error.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnLog( settings, level, msg, tn )\\n\\t{\\n\\t\\tmsg = 'DataTables warning: '+\\n\\t\\t\\t(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;\\n\\t\\n\\t\\tif ( tn ) {\\n\\t\\t\\tmsg += '. For more information about this error, please see '+\\n\\t\\t\\t'http://datatables.net/tn/'+tn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( ! level ) {\\n\\t\\t\\t// Backwards compatibility pre 1.10\\n\\t\\t\\tvar ext = DataTable.ext;\\n\\t\\t\\tvar type = ext.sErrMode || ext.errMode;\\n\\t\\n\\t\\t\\tif ( settings ) {\\n\\t\\t\\t\\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( type == 'alert' ) {\\n\\t\\t\\t\\talert( msg );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( type == 'throw' ) {\\n\\t\\t\\t\\tthrow new Error(msg);\\n\\t\\t\\t}\\n\\t\\t\\telse if ( typeof type == 'function' ) {\\n\\t\\t\\t\\ttype( settings, tn, msg );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( window.console && console.log ) {\\n\\t\\t\\tconsole.log( msg );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * See if a property is defined on one object, if so assign it to the other object\\n\\t * @param {object} ret target object\\n\\t * @param {object} src source object\\n\\t * @param {string} name property\\n\\t * @param {string} [mappedName] name to map too - optional, name used if not given\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnMap( ret, src, name, mappedName )\\n\\t{\\n\\t\\tif ( $.isArray( name ) ) {\\n\\t\\t\\t$.each( name, function (i, val) {\\n\\t\\t\\t\\tif ( $.isArray( val ) ) {\\n\\t\\t\\t\\t\\t_fnMap( ret, src, val[0], val[1] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t_fnMap( ret, src, val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( mappedName === undefined ) {\\n\\t\\t\\tmappedName = name;\\n\\t\\t}\\n\\t\\n\\t\\tif ( src[name] !== undefined ) {\\n\\t\\t\\tret[mappedName] = src[name];\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Extend objects - very similar to jQuery.extend, but deep copy objects, and\\n\\t * shallow copy arrays. The reason we need to do this, is that we don't want to\\n\\t * deep copy array init values (such as aaSorting) since the dev wouldn't be\\n\\t * able to override them, but we do want to deep copy arrays.\\n\\t * @param {object} out Object to extend\\n\\t * @param {object} extender Object from which the properties will be applied to\\n\\t * out\\n\\t * @param {boolean} breakRefs If true, then arrays will be sliced to take an\\n\\t * independent copy with the exception of the `data` or `aaData` parameters\\n\\t * if they are present. This is so you can pass in a collection to\\n\\t * DataTables and have that used as your data source without breaking the\\n\\t * references\\n\\t * @returns {object} out Reference, just for convenience - out === the return.\\n\\t * @memberof DataTable#oApi\\n\\t * @todo This doesn't take account of arrays inside the deep copied objects.\\n\\t */\\n\\tfunction _fnExtend( out, extender, breakRefs )\\n\\t{\\n\\t\\tvar val;\\n\\t\\n\\t\\tfor ( var prop in extender ) {\\n\\t\\t\\tif ( extender.hasOwnProperty(prop) ) {\\n\\t\\t\\t\\tval = extender[prop];\\n\\t\\n\\t\\t\\t\\tif ( $.isPlainObject( val ) ) {\\n\\t\\t\\t\\t\\tif ( ! $.isPlainObject( out[prop] ) ) {\\n\\t\\t\\t\\t\\t\\tout[prop] = {};\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t$.extend( true, out[prop], val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {\\n\\t\\t\\t\\t\\tout[prop] = val.slice();\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tout[prop] = val;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Bind an event handers to allow a click or return key to activate the callback.\\n\\t * This is good for accessibility since a return on the keyboard will have the\\n\\t * same effect as a click, if the element has focus.\\n\\t * @param {element} n Element to bind the action to\\n\\t * @param {object} oData Data object to pass to the triggered function\\n\\t * @param {function} fn Callback function for when the event is triggered\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnBindAction( n, oData, fn )\\n\\t{\\n\\t\\t$(n)\\n\\t\\t\\t.on( 'click.DT', oData, function (e) {\\n\\t\\t\\t\\t\\tn.blur(); // Remove focus outline for mouse users\\n\\t\\t\\t\\t\\tfn(e);\\n\\t\\t\\t\\t} )\\n\\t\\t\\t.on( 'keypress.DT', oData, function (e){\\n\\t\\t\\t\\t\\tif ( e.which === 13 ) {\\n\\t\\t\\t\\t\\t\\te.preventDefault();\\n\\t\\t\\t\\t\\t\\tfn(e);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} )\\n\\t\\t\\t.on( 'selectstart.DT', function () {\\n\\t\\t\\t\\t\\t/* Take the brutal approach to cancelling text selection */\\n\\t\\t\\t\\t\\treturn false;\\n\\t\\t\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Register a callback function. Easily allows a callback function to be added to\\n\\t * an array store of callback functions that can then all be called together.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {string} sStore Name of the array storage for the callbacks in oSettings\\n\\t * @param {function} fn Function to be called back\\n\\t * @param {string} sName Identifying name for the callback (i.e. a label)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCallbackReg( oSettings, sStore, fn, sName )\\n\\t{\\n\\t\\tif ( fn )\\n\\t\\t{\\n\\t\\t\\toSettings[sStore].push( {\\n\\t\\t\\t\\t\\\"fn\\\": fn,\\n\\t\\t\\t\\t\\\"sName\\\": sName\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Fire callback functions and trigger events. Note that the loop over the\\n\\t * callback array store is done backwards! Further note that you do not want to\\n\\t * fire off triggers in time sensitive applications (for example cell creation)\\n\\t * as its slow.\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {string} callbackArr Name of the array storage for the callbacks in\\n\\t * oSettings\\n\\t * @param {string} eventName Name of the jQuery custom event to trigger. If\\n\\t * null no trigger is fired\\n\\t * @param {array} args Array of arguments to pass to the callback function /\\n\\t * trigger\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCallbackFire( settings, callbackArr, eventName, args )\\n\\t{\\n\\t\\tvar ret = [];\\n\\t\\n\\t\\tif ( callbackArr ) {\\n\\t\\t\\tret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {\\n\\t\\t\\t\\treturn val.fn.apply( settings.oInstance, args );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\tif ( eventName !== null ) {\\n\\t\\t\\tvar e = $.Event( eventName+'.dt' );\\n\\t\\n\\t\\t\\t$(settings.nTable).trigger( e, args );\\n\\t\\n\\t\\t\\tret.push( e.result );\\n\\t\\t}\\n\\t\\n\\t\\treturn ret;\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnLengthOverflow ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\tend = settings.fnDisplayEnd(),\\n\\t\\t\\tlen = settings._iDisplayLength;\\n\\t\\n\\t\\t/* If we have space to show extra rows (backing up from the end point - then do so */\\n\\t\\tif ( start >= end )\\n\\t\\t{\\n\\t\\t\\tstart = end - len;\\n\\t\\t}\\n\\t\\n\\t\\t// Keep the start record on the current page\\n\\t\\tstart -= (start % len);\\n\\t\\n\\t\\tif ( len === -1 || start < 0 )\\n\\t\\t{\\n\\t\\t\\tstart = 0;\\n\\t\\t}\\n\\t\\n\\t\\tsettings._iDisplayStart = start;\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnRenderer( settings, type )\\n\\t{\\n\\t\\tvar renderer = settings.renderer;\\n\\t\\tvar host = DataTable.ext.renderer[type];\\n\\t\\n\\t\\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\\n\\t\\t\\t// Specific renderer for this type. If available use it, otherwise use\\n\\t\\t\\t// the default.\\n\\t\\t\\treturn host[renderer[type]] || host._;\\n\\t\\t}\\n\\t\\telse if ( typeof renderer === 'string' ) {\\n\\t\\t\\t// Common renderer - if there is one available for this type use it,\\n\\t\\t\\t// otherwise use the default\\n\\t\\t\\treturn host[renderer] || host._;\\n\\t\\t}\\n\\t\\n\\t\\t// Use the default\\n\\t\\treturn host._;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Detect the data source being used for the table. Used to simplify the code\\n\\t * a little (ajax) and to make it compress a little smaller.\\n\\t *\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {string} Data source\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDataSource ( settings )\\n\\t{\\n\\t\\tif ( settings.oFeatures.bServerSide ) {\\n\\t\\t\\treturn 'ssp';\\n\\t\\t}\\n\\t\\telse if ( settings.ajax || settings.sAjaxSource ) {\\n\\t\\t\\treturn 'ajax';\\n\\t\\t}\\n\\t\\treturn 'dom';\\n\\t}\\n\\t\\n\\n\\t\\n\\t\\n\\t/**\\n\\t * Computed structure of the DataTables API, defined by the options passed to\\n\\t * `DataTable.Api.register()` when building the API.\\n\\t *\\n\\t * The structure is built in order to speed creation and extension of the Api\\n\\t * objects since the extensions are effectively pre-parsed.\\n\\t *\\n\\t * The array is an array of objects with the following structure, where this\\n\\t * base array represents the Api prototype base:\\n\\t *\\n\\t * [\\n\\t * {\\n\\t * name: 'data' -- string - Property name\\n\\t * val: function () {}, -- function - Api method (or undefined if just an object\\n\\t * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\\n\\t * propExt: [ ... ] -- array - Array of Api object definitions to extend the property\\n\\t * },\\n\\t * {\\n\\t * name: 'row'\\n\\t * val: {},\\n\\t * methodExt: [ ... ],\\n\\t * propExt: [\\n\\t * {\\n\\t * name: 'data'\\n\\t * val: function () {},\\n\\t * methodExt: [ ... ],\\n\\t * propExt: [ ... ]\\n\\t * },\\n\\t * ...\\n\\t * ]\\n\\t * }\\n\\t * ]\\n\\t *\\n\\t * @type {Array}\\n\\t * @ignore\\n\\t */\\n\\tvar __apiStruct = [];\\n\\t\\n\\t\\n\\t/**\\n\\t * `Array.prototype` reference.\\n\\t *\\n\\t * @type object\\n\\t * @ignore\\n\\t */\\n\\tvar __arrayProto = Array.prototype;\\n\\t\\n\\t\\n\\t/**\\n\\t * Abstraction for `context` parameter of the `Api` constructor to allow it to\\n\\t * take several different forms for ease of use.\\n\\t *\\n\\t * Each of the input parameter types will be converted to a DataTables settings\\n\\t * object where possible.\\n\\t *\\n\\t * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one\\n\\t * of:\\n\\t *\\n\\t * * `string` - jQuery selector. Any DataTables' matching the given selector\\n\\t * with be found and used.\\n\\t * * `node` - `TABLE` node which has already been formed into a DataTable.\\n\\t * * `jQuery` - A jQuery object of `TABLE` nodes.\\n\\t * * `object` - DataTables settings object\\n\\t * * `DataTables.Api` - API instance\\n\\t * @return {array|null} Matching DataTables settings objects. `null` or\\n\\t * `undefined` is returned if no matching DataTable is found.\\n\\t * @ignore\\n\\t */\\n\\tvar _toSettings = function ( mixed )\\n\\t{\\n\\t\\tvar idx, jq;\\n\\t\\tvar settings = DataTable.settings;\\n\\t\\tvar tables = $.map( settings, function (el, i) {\\n\\t\\t\\treturn el.nTable;\\n\\t\\t} );\\n\\t\\n\\t\\tif ( ! mixed ) {\\n\\t\\t\\treturn [];\\n\\t\\t}\\n\\t\\telse if ( mixed.nTable && mixed.oApi ) {\\n\\t\\t\\t// DataTables settings object\\n\\t\\t\\treturn [ mixed ];\\n\\t\\t}\\n\\t\\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\\n\\t\\t\\t// Table node\\n\\t\\t\\tidx = $.inArray( mixed, tables );\\n\\t\\t\\treturn idx !== -1 ? [ settings[idx] ] : null;\\n\\t\\t}\\n\\t\\telse if ( mixed && typeof mixed.settings === 'function' ) {\\n\\t\\t\\treturn mixed.settings().toArray();\\n\\t\\t}\\n\\t\\telse if ( typeof mixed === 'string' ) {\\n\\t\\t\\t// jQuery selector\\n\\t\\t\\tjq = $(mixed);\\n\\t\\t}\\n\\t\\telse if ( mixed instanceof $ ) {\\n\\t\\t\\t// jQuery object (also DataTables instance)\\n\\t\\t\\tjq = mixed;\\n\\t\\t}\\n\\t\\n\\t\\tif ( jq ) {\\n\\t\\t\\treturn jq.map( function(i) {\\n\\t\\t\\t\\tidx = $.inArray( this, tables );\\n\\t\\t\\t\\treturn idx !== -1 ? settings[idx] : null;\\n\\t\\t\\t} ).toArray();\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables API class - used to control and interface with one or more\\n\\t * DataTables enhanced tables.\\n\\t *\\n\\t * The API class is heavily based on jQuery, presenting a chainable interface\\n\\t * that you can use to interact with tables. Each instance of the API class has\\n\\t * a \\\"context\\\" - i.e. the tables that it will operate on. This could be a single\\n\\t * table, all tables on a page or a sub-set thereof.\\n\\t *\\n\\t * Additionally the API is designed to allow you to easily work with the data in\\n\\t * the tables, retrieving and manipulating it as required. This is done by\\n\\t * presenting the API class as an array like interface. The contents of the\\n\\t * array depend upon the actions requested by each method (for example\\n\\t * `rows().nodes()` will return an array of nodes, while `rows().data()` will\\n\\t * return an array of objects or arrays depending upon your table's\\n\\t * configuration). The API object has a number of array like methods (`push`,\\n\\t * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\\n\\t * `unique` etc) to assist your working with the data held in a table.\\n\\t *\\n\\t * Most methods (those which return an Api instance) are chainable, which means\\n\\t * the return from a method call also has all of the methods available that the\\n\\t * top level object had. For example, these two calls are equivalent:\\n\\t *\\n\\t * // Not chained\\n\\t * api.row.add( {...} );\\n\\t * api.draw();\\n\\t *\\n\\t * // Chained\\n\\t * api.row.add( {...} ).draw();\\n\\t *\\n\\t * @class DataTable.Api\\n\\t * @param {array|object|string|jQuery} context DataTable identifier. This is\\n\\t * used to define which DataTables enhanced tables this API will operate on.\\n\\t * Can be one of:\\n\\t *\\n\\t * * `string` - jQuery selector. Any DataTables' matching the given selector\\n\\t * with be found and used.\\n\\t * * `node` - `TABLE` node which has already been formed into a DataTable.\\n\\t * * `jQuery` - A jQuery object of `TABLE` nodes.\\n\\t * * `object` - DataTables settings object\\n\\t * @param {array} [data] Data to initialise the Api instance with.\\n\\t *\\n\\t * @example\\n\\t * // Direct initialisation during DataTables construction\\n\\t * var api = $('#example').DataTable();\\n\\t *\\n\\t * @example\\n\\t * // Initialisation using a DataTables jQuery object\\n\\t * var api = $('#example').dataTable().api();\\n\\t *\\n\\t * @example\\n\\t * // Initialisation as a constructor\\n\\t * var api = new $.fn.DataTable.Api( 'table.dataTable' );\\n\\t */\\n\\t_Api = function ( context, data )\\n\\t{\\n\\t\\tif ( ! (this instanceof _Api) ) {\\n\\t\\t\\treturn new _Api( context, data );\\n\\t\\t}\\n\\t\\n\\t\\tvar settings = [];\\n\\t\\tvar ctxSettings = function ( o ) {\\n\\t\\t\\tvar a = _toSettings( o );\\n\\t\\t\\tif ( a ) {\\n\\t\\t\\t\\tsettings = settings.concat( a );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\tif ( $.isArray( context ) ) {\\n\\t\\t\\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tctxSettings( context[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tctxSettings( context );\\n\\t\\t}\\n\\t\\n\\t\\t// Remove duplicates\\n\\t\\tthis.context = _unique( settings );\\n\\t\\n\\t\\t// Initial data\\n\\t\\tif ( data ) {\\n\\t\\t\\t$.merge( this, data );\\n\\t\\t}\\n\\t\\n\\t\\t// selector\\n\\t\\tthis.selector = {\\n\\t\\t\\trows: null,\\n\\t\\t\\tcols: null,\\n\\t\\t\\topts: null\\n\\t\\t};\\n\\t\\n\\t\\t_Api.extend( this, this, __apiStruct );\\n\\t};\\n\\t\\n\\tDataTable.Api = _Api;\\n\\t\\n\\t// Don't destroy the existing prototype, just extend it. Required for jQuery 2's\\n\\t// isPlainObject.\\n\\t$.extend( _Api.prototype, {\\n\\t\\tany: function ()\\n\\t\\t{\\n\\t\\t\\treturn this.count() !== 0;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tconcat: __arrayProto.concat,\\n\\t\\n\\t\\n\\t\\tcontext: [], // array of table settings objects\\n\\t\\n\\t\\n\\t\\tcount: function ()\\n\\t\\t{\\n\\t\\t\\treturn this.flatten().length;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\teach: function ( fn )\\n\\t\\t{\\n\\t\\t\\tfor ( var i=0, ien=this.length ; i<ien; i++ ) {\\n\\t\\t\\t\\tfn.call( this, this[i], i, this );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn this;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\teq: function ( idx )\\n\\t\\t{\\n\\t\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\t\\treturn ctx.length > idx ?\\n\\t\\t\\t\\tnew _Api( ctx[idx], this[idx] ) :\\n\\t\\t\\t\\tnull;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tfilter: function ( fn )\\n\\t\\t{\\n\\t\\t\\tvar a = [];\\n\\t\\n\\t\\t\\tif ( __arrayProto.filter ) {\\n\\t\\t\\t\\ta = __arrayProto.filter.call( this, fn, this );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\\n\\t\\t\\t\\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\tif ( fn.call( this, this[i], i, this ) ) {\\n\\t\\t\\t\\t\\t\\ta.push( this[i] );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn new _Api( this.context, a );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tflatten: function ()\\n\\t\\t{\\n\\t\\t\\tvar a = [];\\n\\t\\t\\treturn new _Api( this.context, a.concat.apply( a, this.toArray() ) );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tjoin: __arrayProto.join,\\n\\t\\n\\t\\n\\t\\tindexOf: __arrayProto.indexOf || function (obj, start)\\n\\t\\t{\\n\\t\\t\\tfor ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( this[i] === obj ) {\\n\\t\\t\\t\\t\\treturn i;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn -1;\\n\\t\\t},\\n\\t\\n\\t\\titerator: function ( flatten, type, fn, alwaysNew ) {\\n\\t\\t\\tvar\\n\\t\\t\\t\\ta = [], ret,\\n\\t\\t\\t\\ti, ien, j, jen,\\n\\t\\t\\t\\tcontext = this.context,\\n\\t\\t\\t\\trows, items, item,\\n\\t\\t\\t\\tselector = this.selector;\\n\\t\\n\\t\\t\\t// Argument shifting\\n\\t\\t\\tif ( typeof flatten === 'string' ) {\\n\\t\\t\\t\\talwaysNew = fn;\\n\\t\\t\\t\\tfn = type;\\n\\t\\t\\t\\ttype = flatten;\\n\\t\\t\\t\\tflatten = false;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tfor ( i=0, ien=context.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tvar apiInst = new _Api( context[i] );\\n\\t\\n\\t\\t\\t\\tif ( type === 'table' ) {\\n\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], i );\\n\\t\\n\\t\\t\\t\\t\\tif ( ret !== undefined ) {\\n\\t\\t\\t\\t\\t\\ta.push( ret );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( type === 'columns' || type === 'rows' ) {\\n\\t\\t\\t\\t\\t// this has same length as context - one entry for each table\\n\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], this[i], i );\\n\\t\\n\\t\\t\\t\\t\\tif ( ret !== undefined ) {\\n\\t\\t\\t\\t\\t\\ta.push( ret );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {\\n\\t\\t\\t\\t\\t// columns and rows share the same structure.\\n\\t\\t\\t\\t\\t// 'this' is an array of column indexes for each context\\n\\t\\t\\t\\t\\titems = this[i];\\n\\t\\n\\t\\t\\t\\t\\tif ( type === 'column-rows' ) {\\n\\t\\t\\t\\t\\t\\trows = _selector_row_indexes( context[i], selector.opts );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tfor ( j=0, jen=items.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\t\\titem = items[j];\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( type === 'cell' ) {\\n\\t\\t\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], item.row, item.column, i, j );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], item, i, j, rows );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( ret !== undefined ) {\\n\\t\\t\\t\\t\\t\\t\\ta.push( ret );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( a.length || alwaysNew ) {\\n\\t\\t\\t\\tvar api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );\\n\\t\\t\\t\\tvar apiSelector = api.selector;\\n\\t\\t\\t\\tapiSelector.rows = selector.rows;\\n\\t\\t\\t\\tapiSelector.cols = selector.cols;\\n\\t\\t\\t\\tapiSelector.opts = selector.opts;\\n\\t\\t\\t\\treturn api;\\n\\t\\t\\t}\\n\\t\\t\\treturn this;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tlastIndexOf: __arrayProto.lastIndexOf || function (obj, start)\\n\\t\\t{\\n\\t\\t\\t// Bit cheeky...\\n\\t\\t\\treturn this.indexOf.apply( this.toArray.reverse(), arguments );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tlength: 0,\\n\\t\\n\\t\\n\\t\\tmap: function ( fn )\\n\\t\\t{\\n\\t\\t\\tvar a = [];\\n\\t\\n\\t\\t\\tif ( __arrayProto.map ) {\\n\\t\\t\\t\\ta = __arrayProto.map.call( this, fn, this );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\\n\\t\\t\\t\\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\ta.push( fn.call( this, this[i], i ) );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn new _Api( this.context, a );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tpluck: function ( prop )\\n\\t\\t{\\n\\t\\t\\treturn this.map( function ( el ) {\\n\\t\\t\\t\\treturn el[ prop ];\\n\\t\\t\\t} );\\n\\t\\t},\\n\\t\\n\\t\\tpop: __arrayProto.pop,\\n\\t\\n\\t\\n\\t\\tpush: __arrayProto.push,\\n\\t\\n\\t\\n\\t\\t// Does not return an API instance\\n\\t\\treduce: __arrayProto.reduce || function ( fn, init )\\n\\t\\t{\\n\\t\\t\\treturn _fnReduce( this, fn, init, 0, this.length, 1 );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\treduceRight: __arrayProto.reduceRight || function ( fn, init )\\n\\t\\t{\\n\\t\\t\\treturn _fnReduce( this, fn, init, this.length-1, -1, -1 );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\treverse: __arrayProto.reverse,\\n\\t\\n\\t\\n\\t\\t// Object with rows, columns and opts\\n\\t\\tselector: null,\\n\\t\\n\\t\\n\\t\\tshift: __arrayProto.shift,\\n\\t\\n\\t\\n\\t\\tslice: function () {\\n\\t\\t\\treturn new _Api( this.context, this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tsort: __arrayProto.sort, // ? name - order?\\n\\t\\n\\t\\n\\t\\tsplice: __arrayProto.splice,\\n\\t\\n\\t\\n\\t\\ttoArray: function ()\\n\\t\\t{\\n\\t\\t\\treturn __arrayProto.slice.call( this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tto$: function ()\\n\\t\\t{\\n\\t\\t\\treturn $( this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\ttoJQuery: function ()\\n\\t\\t{\\n\\t\\t\\treturn $( this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tunique: function ()\\n\\t\\t{\\n\\t\\t\\treturn new _Api( this.context, _unique(this) );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tunshift: __arrayProto.unshift\\n\\t} );\\n\\t\\n\\t\\n\\t_Api.extend = function ( scope, obj, ext )\\n\\t{\\n\\t\\t// Only extend API instances and static properties of the API\\n\\t\\tif ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\ti, ien,\\n\\t\\t\\tj, jen,\\n\\t\\t\\tstruct, inner,\\n\\t\\t\\tmethodScoping = function ( scope, fn, struc ) {\\n\\t\\t\\t\\treturn function () {\\n\\t\\t\\t\\t\\tvar ret = fn.apply( scope, arguments );\\n\\t\\n\\t\\t\\t\\t\\t// Method extension\\n\\t\\t\\t\\t\\t_Api.extend( ret, ret, struc.methodExt );\\n\\t\\t\\t\\t\\treturn ret;\\n\\t\\t\\t\\t};\\n\\t\\t\\t};\\n\\t\\n\\t\\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\\n\\t\\t\\tstruct = ext[i];\\n\\t\\n\\t\\t\\t// Value\\n\\t\\t\\tobj[ struct.name ] = typeof struct.val === 'function' ?\\n\\t\\t\\t\\tmethodScoping( scope, struct.val, struct ) :\\n\\t\\t\\t\\t$.isPlainObject( struct.val ) ?\\n\\t\\t\\t\\t\\t{} :\\n\\t\\t\\t\\t\\tstruct.val;\\n\\t\\n\\t\\t\\tobj[ struct.name ].__dt_wrapper = true;\\n\\t\\n\\t\\t\\t// Property extension\\n\\t\\t\\t_Api.extend( scope, obj[ struct.name ], struct.propExt );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t// @todo - Is there need for an augment function?\\n\\t// _Api.augment = function ( inst, name )\\n\\t// {\\n\\t// \\t// Find src object in the structure from the name\\n\\t// \\tvar parts = name.split('.');\\n\\t\\n\\t// \\t_Api.extend( inst, obj );\\n\\t// };\\n\\t\\n\\t\\n\\t// [\\n\\t// {\\n\\t// name: 'data' -- string - Property name\\n\\t// val: function () {}, -- function - Api method (or undefined if just an object\\n\\t// methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\\n\\t// propExt: [ ... ] -- array - Array of Api object definitions to extend the property\\n\\t// },\\n\\t// {\\n\\t// name: 'row'\\n\\t// val: {},\\n\\t// methodExt: [ ... ],\\n\\t// propExt: [\\n\\t// {\\n\\t// name: 'data'\\n\\t// val: function () {},\\n\\t// methodExt: [ ... ],\\n\\t// propExt: [ ... ]\\n\\t// },\\n\\t// ...\\n\\t// ]\\n\\t// }\\n\\t// ]\\n\\t\\n\\t_Api.register = _api_register = function ( name, val )\\n\\t{\\n\\t\\tif ( $.isArray( name ) ) {\\n\\t\\t\\tfor ( var j=0, jen=name.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t_Api.register( name[j], val );\\n\\t\\t\\t}\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\ti, ien,\\n\\t\\t\\their = name.split('.'),\\n\\t\\t\\tstruct = __apiStruct,\\n\\t\\t\\tkey, method;\\n\\t\\n\\t\\tvar find = function ( src, name ) {\\n\\t\\t\\tfor ( var i=0, ien=src.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( src[i].name === name ) {\\n\\t\\t\\t\\t\\treturn src[i];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t};\\n\\t\\n\\t\\tfor ( i=0, ien=heir.length ; i<ien ; i++ ) {\\n\\t\\t\\tmethod = heir[i].indexOf('()') !== -1;\\n\\t\\t\\tkey = method ?\\n\\t\\t\\t\\their[i].replace('()', '') :\\n\\t\\t\\t\\their[i];\\n\\t\\n\\t\\t\\tvar src = find( struct, key );\\n\\t\\t\\tif ( ! src ) {\\n\\t\\t\\t\\tsrc = {\\n\\t\\t\\t\\t\\tname: key,\\n\\t\\t\\t\\t\\tval: {},\\n\\t\\t\\t\\t\\tmethodExt: [],\\n\\t\\t\\t\\t\\tpropExt: []\\n\\t\\t\\t\\t};\\n\\t\\t\\t\\tstruct.push( src );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( i === ien-1 ) {\\n\\t\\t\\t\\tsrc.val = val;\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tstruct = method ?\\n\\t\\t\\t\\t\\tsrc.methodExt :\\n\\t\\t\\t\\t\\tsrc.propExt;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {\\n\\t\\t_Api.register( pluralName, val );\\n\\t\\n\\t\\t_Api.register( singularName, function () {\\n\\t\\t\\tvar ret = val.apply( this, arguments );\\n\\t\\n\\t\\t\\tif ( ret === this ) {\\n\\t\\t\\t\\t// Returned item is the API instance that was passed in, return it\\n\\t\\t\\t\\treturn this;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( ret instanceof _Api ) {\\n\\t\\t\\t\\t// New API instance returned, want the value from the first item\\n\\t\\t\\t\\t// in the returned array for the singular result.\\n\\t\\t\\t\\treturn ret.length ?\\n\\t\\t\\t\\t\\t$.isArray( ret[0] ) ?\\n\\t\\t\\t\\t\\t\\tnew _Api( ret.context, ret[0] ) : // Array results are 'enhanced'\\n\\t\\t\\t\\t\\t\\tret[0] :\\n\\t\\t\\t\\t\\tundefined;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Non-API return - just fire it back\\n\\t\\t\\treturn ret;\\n\\t\\t} );\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Selector for HTML tables. Apply the given selector to the give array of\\n\\t * DataTables settings objects.\\n\\t *\\n\\t * @param {string|integer} [selector] jQuery selector string or integer\\n\\t * @param {array} Array of DataTables settings objects to be filtered\\n\\t * @return {array}\\n\\t * @ignore\\n\\t */\\n\\tvar __table_selector = function ( selector, a )\\n\\t{\\n\\t\\t// Integer is used to pick out a table by index\\n\\t\\tif ( typeof selector === 'number' ) {\\n\\t\\t\\treturn [ a[ selector ] ];\\n\\t\\t}\\n\\t\\n\\t\\t// Perform a jQuery selector on the table nodes\\n\\t\\tvar nodes = $.map( a, function (el, i) {\\n\\t\\t\\treturn el.nTable;\\n\\t\\t} );\\n\\t\\n\\t\\treturn $(nodes)\\n\\t\\t\\t.filter( selector )\\n\\t\\t\\t.map( function (i) {\\n\\t\\t\\t\\t// Need to translate back from the table node to the settings\\n\\t\\t\\t\\tvar idx = $.inArray( this, nodes );\\n\\t\\t\\t\\treturn a[ idx ];\\n\\t\\t\\t} )\\n\\t\\t\\t.toArray();\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Context selector for the API's context (i.e. the tables the API instance\\n\\t * refers to.\\n\\t *\\n\\t * @name DataTable.Api#tables\\n\\t * @param {string|integer} [selector] Selector to pick which tables the iterator\\n\\t * should operate on. If not given, all tables in the current context are\\n\\t * used. This can be given as a jQuery selector (for example `':gt(0)'`) to\\n\\t * select multiple tables or as an integer to select a single table.\\n\\t * @returns {DataTable.Api} Returns a new API instance if a selector is given.\\n\\t */\\n\\t_api_register( 'tables()', function ( selector ) {\\n\\t\\t// A new instance is created if there was a selector specified\\n\\t\\treturn selector ?\\n\\t\\t\\tnew _Api( __table_selector( selector, this.context ) ) :\\n\\t\\t\\tthis;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'table()', function ( selector ) {\\n\\t\\tvar tables = this.tables( selector );\\n\\t\\tvar ctx = tables.context;\\n\\t\\n\\t\\t// Truncate to the first matched table\\n\\t\\treturn ctx.length ?\\n\\t\\t\\tnew _Api( ctx[0] ) :\\n\\t\\t\\ttables;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTable;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().body()', 'table().body()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTBody;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().header()', 'table().header()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTHead;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTFoot;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().containers()', 'table().container()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTableWrapper;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Redraw the tables in the current context.\\n\\t */\\n\\t_api_register( 'draw()', function ( paging ) {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( paging === 'page' ) {\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tif ( typeof paging === 'string' ) {\\n\\t\\t\\t\\t\\tpaging = paging === 'full-hold' ?\\n\\t\\t\\t\\t\\t\\tfalse :\\n\\t\\t\\t\\t\\t\\ttrue;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t_fnReDraw( settings, paging===false );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the current page index.\\n\\t *\\n\\t * @return {integer} Current page index (zero based)\\n\\t *//**\\n\\t * Set the current page.\\n\\t *\\n\\t * Note that if you attempt to show a page which does not exist, DataTables will\\n\\t * not throw an error, but rather reset the paging.\\n\\t *\\n\\t * @param {integer|string} action The paging action to take. This can be one of:\\n\\t * * `integer` - The page index to jump to\\n\\t * * `string` - An action to take:\\n\\t * * `first` - Jump to first page.\\n\\t * * `next` - Jump to the next page\\n\\t * * `previous` - Jump to previous page\\n\\t * * `last` - Jump to the last page.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'page()', function ( action ) {\\n\\t\\tif ( action === undefined ) {\\n\\t\\t\\treturn this.page.info().page; // not an expensive call\\n\\t\\t}\\n\\t\\n\\t\\t// else, have an action to take on all tables\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnPageChange( settings, action );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Paging information for the first table in the current context.\\n\\t *\\n\\t * If you require paging information for another table, use the `table()` method\\n\\t * with a suitable selector.\\n\\t *\\n\\t * @return {object} Object with the following properties set:\\n\\t * * `page` - Current page index (zero based - i.e. the first page is `0`)\\n\\t * * `pages` - Total number of pages\\n\\t * * `start` - Display index for the first record shown on the current page\\n\\t * * `end` - Display index for the last record shown on the current page\\n\\t * * `length` - Display length (number of records). Note that generally `start\\n\\t * + length = end`, but this is not always true, for example if there are\\n\\t * only 2 records to show on the final page, with a length of 10.\\n\\t * * `recordsTotal` - Full data set length\\n\\t * * `recordsDisplay` - Data set length once the current filtering criterion\\n\\t * are applied.\\n\\t */\\n\\t_api_register( 'page.info()', function ( action ) {\\n\\t\\tif ( this.context.length === 0 ) {\\n\\t\\t\\treturn undefined;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\tsettings = this.context[0],\\n\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\tlen = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,\\n\\t\\t\\tvisRecords = settings.fnRecordsDisplay(),\\n\\t\\t\\tall = len === -1;\\n\\t\\n\\t\\treturn {\\n\\t\\t\\t\\\"page\\\": all ? 0 : Math.floor( start / len ),\\n\\t\\t\\t\\\"pages\\\": all ? 1 : Math.ceil( visRecords / len ),\\n\\t\\t\\t\\\"start\\\": start,\\n\\t\\t\\t\\\"end\\\": settings.fnDisplayEnd(),\\n\\t\\t\\t\\\"length\\\": len,\\n\\t\\t\\t\\\"recordsTotal\\\": settings.fnRecordsTotal(),\\n\\t\\t\\t\\\"recordsDisplay\\\": visRecords,\\n\\t\\t\\t\\\"serverSide\\\": _fnDataSource( settings ) === 'ssp'\\n\\t\\t};\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the current page length.\\n\\t *\\n\\t * @return {integer} Current page length. Note `-1` indicates that all records\\n\\t * are to be shown.\\n\\t *//**\\n\\t * Set the current page length.\\n\\t *\\n\\t * @param {integer} Page length to set. Use `-1` to show all records.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'page.len()', function ( len ) {\\n\\t\\t// Note that we can't call this function 'length()' because `length`\\n\\t\\t// is a Javascript property of functions which defines how many arguments\\n\\t\\t// the function expects.\\n\\t\\tif ( len === undefined ) {\\n\\t\\t\\treturn this.context.length !== 0 ?\\n\\t\\t\\t\\tthis.context[0]._iDisplayLength :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// else, set the page length\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnLengthChange( settings, len );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __reload = function ( settings, holdPosition, callback ) {\\n\\t\\t// Use the draw event to trigger a callback\\n\\t\\tif ( callback ) {\\n\\t\\t\\tvar api = new _Api( settings );\\n\\t\\n\\t\\t\\tapi.one( 'draw', function () {\\n\\t\\t\\t\\tcallback( api.ajax.json() );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\tif ( _fnDataSource( settings ) == 'ssp' ) {\\n\\t\\t\\t_fnReDraw( settings, holdPosition );\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t\\t// Cancel an existing request\\n\\t\\t\\tvar xhr = settings.jqXHR;\\n\\t\\t\\tif ( xhr && xhr.readyState !== 4 ) {\\n\\t\\t\\t\\txhr.abort();\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Trigger xhr\\n\\t\\t\\t_fnBuildAjax( settings, [], function( json ) {\\n\\t\\t\\t\\t_fnClearTable( settings );\\n\\t\\n\\t\\t\\t\\tvar data = _fnAjaxDataSrc( settings, json );\\n\\t\\t\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t_fnAddData( settings, data[i] );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t_fnReDraw( settings, holdPosition );\\n\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the JSON response from the last Ajax request that DataTables made to the\\n\\t * server. Note that this returns the JSON from the first table in the current\\n\\t * context.\\n\\t *\\n\\t * @return {object} JSON received from the server.\\n\\t */\\n\\t_api_register( 'ajax.json()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( ctx.length > 0 ) {\\n\\t\\t\\treturn ctx[0].json;\\n\\t\\t}\\n\\t\\n\\t\\t// else return undefined;\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the data submitted in the last Ajax request\\n\\t */\\n\\t_api_register( 'ajax.params()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( ctx.length > 0 ) {\\n\\t\\t\\treturn ctx[0].oAjaxData;\\n\\t\\t}\\n\\t\\n\\t\\t// else return undefined;\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Reload tables from the Ajax data source. Note that this function will\\n\\t * automatically re-draw the table when the remote data has been loaded.\\n\\t *\\n\\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\\n\\t * position. A full re-sort and re-filter is performed when this method is\\n\\t * called, which is why the pagination reset is the default action.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\\n\\t\\treturn this.iterator( 'table', function (settings) {\\n\\t\\t\\t__reload( settings, resetPaging===false, callback );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the current Ajax URL. Note that this returns the URL from the first\\n\\t * table in the current context.\\n\\t *\\n\\t * @return {string} Current Ajax source URL\\n\\t *//**\\n\\t * Set the Ajax URL. Note that this will set the URL for all tables in the\\n\\t * current context.\\n\\t *\\n\\t * @param {string} url URL to set.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'ajax.url()', function ( url ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( url === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\tif ( ctx.length === 0 ) {\\n\\t\\t\\t\\treturn undefined;\\n\\t\\t\\t}\\n\\t\\t\\tctx = ctx[0];\\n\\t\\n\\t\\t\\treturn ctx.ajax ?\\n\\t\\t\\t\\t$.isPlainObject( ctx.ajax ) ?\\n\\t\\t\\t\\t\\tctx.ajax.url :\\n\\t\\t\\t\\t\\tctx.ajax :\\n\\t\\t\\t\\tctx.sAjaxSource;\\n\\t\\t}\\n\\t\\n\\t\\t// set\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( $.isPlainObject( settings.ajax ) ) {\\n\\t\\t\\t\\tsettings.ajax.url = url;\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tsettings.ajax = url;\\n\\t\\t\\t}\\n\\t\\t\\t// No need to consider sAjaxSource here since DataTables gives priority\\n\\t\\t\\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\\n\\t\\t\\t// value of `sAjaxSource` redundant.\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Load data from the newly set Ajax URL. Note that this method is only\\n\\t * available when `ajax.url()` is used to set a URL. Additionally, this method\\n\\t * has the same effect as calling `ajax.reload()` but is provided for\\n\\t * convenience when setting a new URL. Like `ajax.reload()` it will\\n\\t * automatically redraw the table once the remote data has been loaded.\\n\\t *\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\\n\\t\\t// Same as a reload, but makes sense to present it for easy access after a\\n\\t\\t// url change\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\t__reload( ctx, resetPaging===false, callback );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t\\n\\tvar _selector_run = function ( type, selector, selectFn, settings, opts )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tout = [], res,\\n\\t\\t\\ta, i, ien, j, jen,\\n\\t\\t\\tselectorType = typeof selector;\\n\\t\\n\\t\\t// Can't just check for isArray here, as an API or jQuery instance might be\\n\\t\\t// given with their array like look\\n\\t\\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\\n\\t\\t\\tselector = [ selector ];\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, ien=selector.length ; i<ien ; i++ ) {\\n\\t\\t\\t// Only split on simple strings - complex expressions will be jQuery selectors\\n\\t\\t\\ta = selector[i] && selector[i].split && ! selector[i].match(/[\\\\[\\\\(:]/) ?\\n\\t\\t\\t\\tselector[i].split(',') :\\n\\t\\t\\t\\t[ selector[i] ];\\n\\t\\n\\t\\t\\tfor ( j=0, jen=a.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\tres = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );\\n\\t\\n\\t\\t\\t\\tif ( res && res.length ) {\\n\\t\\t\\t\\t\\tout = out.concat( res );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// selector extensions\\n\\t\\tvar ext = _ext.selector[ type ];\\n\\t\\tif ( ext.length ) {\\n\\t\\t\\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tout = ext[i]( settings, opts, out );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn _unique( out );\\n\\t};\\n\\t\\n\\t\\n\\tvar _selector_opts = function ( opts )\\n\\t{\\n\\t\\tif ( ! opts ) {\\n\\t\\t\\topts = {};\\n\\t\\t}\\n\\t\\n\\t\\t// Backwards compatibility for 1.9- which used the terminology filter rather\\n\\t\\t// than search\\n\\t\\tif ( opts.filter && opts.search === undefined ) {\\n\\t\\t\\topts.search = opts.filter;\\n\\t\\t}\\n\\t\\n\\t\\treturn $.extend( {\\n\\t\\t\\tsearch: 'none',\\n\\t\\t\\torder: 'current',\\n\\t\\t\\tpage: 'all'\\n\\t\\t}, opts );\\n\\t};\\n\\t\\n\\t\\n\\tvar _selector_first = function ( inst )\\n\\t{\\n\\t\\t// Reduce the API instance to the first item found\\n\\t\\tfor ( var i=0, ien=inst.length ; i<ien ; i++ ) {\\n\\t\\t\\tif ( inst[i].length > 0 ) {\\n\\t\\t\\t\\t// Assign the first element to the first item in the instance\\n\\t\\t\\t\\t// and truncate the instance and context\\n\\t\\t\\t\\tinst[0] = inst[i];\\n\\t\\t\\t\\tinst[0].length = 1;\\n\\t\\t\\t\\tinst.length = 1;\\n\\t\\t\\t\\tinst.context = [ inst.context[i] ];\\n\\t\\n\\t\\t\\t\\treturn inst;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// Not found - return an empty instance\\n\\t\\tinst.length = 0;\\n\\t\\treturn inst;\\n\\t};\\n\\t\\n\\t\\n\\tvar _selector_row_indexes = function ( settings, opts )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti, ien, tmp, a=[],\\n\\t\\t\\tdisplayFiltered = settings.aiDisplay,\\n\\t\\t\\tdisplayMaster = settings.aiDisplayMaster;\\n\\t\\n\\t\\tvar\\n\\t\\t\\tsearch = opts.search, // none, applied, removed\\n\\t\\t\\torder = opts.order, // applied, current, index (original - compatibility with 1.9)\\n\\t\\t\\tpage = opts.page; // all, current\\n\\t\\n\\t\\tif ( _fnDataSource( settings ) == 'ssp' ) {\\n\\t\\t\\t// In server-side processing mode, most options are irrelevant since\\n\\t\\t\\t// rows not shown don't exist and the index order is the applied order\\n\\t\\t\\t// Removed is a special case - for consistency just return an empty\\n\\t\\t\\t// array\\n\\t\\t\\treturn search === 'removed' ?\\n\\t\\t\\t\\t[] :\\n\\t\\t\\t\\t_range( 0, displayMaster.length );\\n\\t\\t}\\n\\t\\telse if ( page == 'current' ) {\\n\\t\\t\\t// Current page implies that order=current and fitler=applied, since it is\\n\\t\\t\\t// fairly senseless otherwise, regardless of what order and search actually\\n\\t\\t\\t// are\\n\\t\\t\\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {\\n\\t\\t\\t\\ta.push( displayFiltered[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( order == 'current' || order == 'applied' ) {\\n\\t\\t\\ta = search == 'none' ?\\n\\t\\t\\t\\tdisplayMaster.slice() : // no search\\n\\t\\t\\t\\tsearch == 'applied' ?\\n\\t\\t\\t\\t\\tdisplayFiltered.slice() : // applied search\\n\\t\\t\\t\\t\\t$.map( displayMaster, function (el, i) { // removed search\\n\\t\\t\\t\\t\\t\\treturn $.inArray( el, displayFiltered ) === -1 ? el : null;\\n\\t\\t\\t\\t\\t} );\\n\\t\\t}\\n\\t\\telse if ( order == 'index' || order == 'original' ) {\\n\\t\\t\\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( search == 'none' ) {\\n\\t\\t\\t\\t\\ta.push( i );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse { // applied | removed\\n\\t\\t\\t\\t\\ttmp = $.inArray( i, displayFiltered );\\n\\t\\n\\t\\t\\t\\t\\tif ((tmp === -1 && search == 'removed') ||\\n\\t\\t\\t\\t\\t\\t(tmp >= 0 && search == 'applied') )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\ta.push( i );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn a;\\n\\t};\\n\\t\\n\\t\\n\\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\\t * Rows\\n\\t *\\n\\t * {} - no selector - use all available rows\\n\\t * {integer} - row aoData index\\n\\t * {node} - TR node\\n\\t * {string} - jQuery selector to apply to the TR elements\\n\\t * {array} - jQuery array of nodes, or simply an array of TR nodes\\n\\t *\\n\\t */\\n\\t\\n\\t\\n\\tvar __row_selector = function ( settings, selector, opts )\\n\\t{\\n\\t\\tvar rows;\\n\\t\\tvar run = function ( sel ) {\\n\\t\\t\\tvar selInt = _intVal( sel );\\n\\t\\t\\tvar i, ien;\\n\\t\\n\\t\\t\\t// Short cut - selector is a number and no options provided (default is\\n\\t\\t\\t// all records, so no need to check if the index is in there, since it\\n\\t\\t\\t// must be - dev error if the index doesn't exist).\\n\\t\\t\\tif ( selInt !== null && ! opts ) {\\n\\t\\t\\t\\treturn [ selInt ];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( ! rows ) {\\n\\t\\t\\t\\trows = _selector_row_indexes( settings, opts );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\\n\\t\\t\\t\\t// Selector - integer\\n\\t\\t\\t\\treturn [ selInt ];\\n\\t\\t\\t}\\n\\t\\t\\telse if ( sel === null || sel === undefined || sel === '' ) {\\n\\t\\t\\t\\t// Selector - none\\n\\t\\t\\t\\treturn rows;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - function\\n\\t\\t\\tif ( typeof sel === 'function' ) {\\n\\t\\t\\t\\treturn $.map( rows, function (idx) {\\n\\t\\t\\t\\t\\tvar row = settings.aoData[ idx ];\\n\\t\\t\\t\\t\\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Get nodes in the order from the `rows` array with null values removed\\n\\t\\t\\tvar nodes = _removeEmpty(\\n\\t\\t\\t\\t_pluck_order( settings.aoData, rows, 'nTr' )\\n\\t\\t\\t);\\n\\t\\n\\t\\t\\t// Selector - node\\n\\t\\t\\tif ( sel.nodeName ) {\\n\\t\\t\\t\\tif ( sel._DT_RowIndex !== undefined ) {\\n\\t\\t\\t\\t\\treturn [ sel._DT_RowIndex ]; // Property added by DT for fast lookup\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( sel._DT_CellIndex ) {\\n\\t\\t\\t\\t\\treturn [ sel._DT_CellIndex.row ];\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tvar host = $(sel).closest('*[data-dt-row]');\\n\\t\\t\\t\\t\\treturn host.length ?\\n\\t\\t\\t\\t\\t\\t[ host.data('dt-row') ] :\\n\\t\\t\\t\\t\\t\\t[];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// ID selector. Want to always be able to select rows by id, regardless\\n\\t\\t\\t// of if the tr element has been created or not, so can't rely upon\\n\\t\\t\\t// jQuery here - hence a custom implementation. This does not match\\n\\t\\t\\t// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,\\n\\t\\t\\t// but to select it using a CSS selector engine (like Sizzle or\\n\\t\\t\\t// querySelect) it would need to need to be escaped for some characters.\\n\\t\\t\\t// DataTables simplifies this for row selectors since you can select\\n\\t\\t\\t// only a row. A # indicates an id any anything that follows is the id -\\n\\t\\t\\t// unescaped.\\n\\t\\t\\tif ( typeof sel === 'string' && sel.charAt(0) === '#' ) {\\n\\t\\t\\t\\t// get row index from id\\n\\t\\t\\t\\tvar rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];\\n\\t\\t\\t\\tif ( rowObj !== undefined ) {\\n\\t\\t\\t\\t\\treturn [ rowObj.idx ];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// need to fall through to jQuery in case there is DOM id that\\n\\t\\t\\t\\t// matches\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - jQuery selector string, array of nodes or jQuery object/\\n\\t\\t\\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\\n\\t\\t\\t// it also allows arrays, so this will cope with all three options\\n\\t\\t\\treturn $(nodes)\\n\\t\\t\\t\\t.filter( sel )\\n\\t\\t\\t\\t.map( function () {\\n\\t\\t\\t\\t\\treturn this._DT_RowIndex;\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.toArray();\\n\\t\\t};\\n\\t\\n\\t\\treturn _selector_run( 'row', selector, run, settings, opts );\\n\\t};\\n\\t\\n\\t\\n\\t_api_register( 'rows()', function ( selector, opts ) {\\n\\t\\t// argument shifting\\n\\t\\tif ( selector === undefined ) {\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\telse if ( $.isPlainObject( selector ) ) {\\n\\t\\t\\topts = selector;\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\n\\t\\topts = _selector_opts( opts );\\n\\t\\n\\t\\tvar inst = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\treturn __row_selector( settings, selector, opts );\\n\\t\\t}, 1 );\\n\\t\\n\\t\\t// Want argument shifting here and in __row_selector?\\n\\t\\tinst.selector.rows = selector;\\n\\t\\tinst.selector.opts = opts;\\n\\t\\n\\t\\treturn inst;\\n\\t} );\\n\\t\\n\\t_api_register( 'rows().nodes()', function () {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\treturn settings.aoData[ row ].nTr || undefined;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_register( 'rows().data()', function () {\\n\\t\\treturn this.iterator( true, 'rows', function ( settings, rows ) {\\n\\t\\t\\treturn _pluck_order( settings.aoData, rows, '_aData' );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\tvar r = settings.aoData[ row ];\\n\\t\\t\\treturn type === 'search' ? r._aFilterData : r._aSortData;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\t_fnInvalidate( settings, row, src );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\treturn row;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {\\n\\t\\tvar a = [];\\n\\t\\tvar context = this.context;\\n\\t\\n\\t\\t// `iterator` will drop undefined values, but in this case we want them\\n\\t\\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\\n\\t\\t\\tfor ( var j=0, jen=this[i].length ; j<jen ; j++ ) {\\n\\t\\t\\t\\tvar id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );\\n\\t\\t\\t\\ta.push( (hash === true ? '#' : '' )+ id );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn new _Api( context, a );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().remove()', 'row().remove()', function () {\\n\\t\\tvar that = this;\\n\\t\\n\\t\\tthis.iterator( 'row', function ( settings, row, thatIdx ) {\\n\\t\\t\\tvar data = settings.aoData;\\n\\t\\t\\tvar rowData = data[ row ];\\n\\t\\t\\tvar i, ien, j, jen;\\n\\t\\t\\tvar loopRow, loopCells;\\n\\t\\n\\t\\t\\tdata.splice( row, 1 );\\n\\t\\n\\t\\t\\t// Update the cached indexes\\n\\t\\t\\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tloopRow = data[i];\\n\\t\\t\\t\\tloopCells = loopRow.anCells;\\n\\t\\n\\t\\t\\t\\t// Rows\\n\\t\\t\\t\\tif ( loopRow.nTr !== null ) {\\n\\t\\t\\t\\t\\tloopRow.nTr._DT_RowIndex = i;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Cells\\n\\t\\t\\t\\tif ( loopCells !== null ) {\\n\\t\\t\\t\\t\\tfor ( j=0, jen=loopCells.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\t\\tloopCells[j]._DT_CellIndex.row = i;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Delete from the display arrays\\n\\t\\t\\t_fnDeleteIndex( settings.aiDisplayMaster, row );\\n\\t\\t\\t_fnDeleteIndex( settings.aiDisplay, row );\\n\\t\\t\\t_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes\\n\\t\\n\\t\\t\\t// Check for an 'overflow' they case for displaying the table\\n\\t\\t\\t_fnLengthOverflow( settings );\\n\\t\\n\\t\\t\\t// Remove the row's ID reference if there is one\\n\\t\\t\\tvar id = settings.rowIdFn( rowData._aData );\\n\\t\\t\\tif ( id !== undefined ) {\\n\\t\\t\\t\\tdelete settings.aIds[ id ];\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\tthis.iterator( 'table', function ( settings ) {\\n\\t\\t\\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tsettings.aoData[i].idx = i;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'rows.add()', function ( rows ) {\\n\\t\\tvar newRows = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t\\tvar row, i, ien;\\n\\t\\t\\t\\tvar out = [];\\n\\t\\n\\t\\t\\t\\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\trow = rows[i];\\n\\t\\n\\t\\t\\t\\t\\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\\n\\t\\t\\t\\t\\t\\tout.push( _fnAddTr( settings, row )[0] );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tout.push( _fnAddData( settings, row ) );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn out;\\n\\t\\t\\t}, 1 );\\n\\t\\n\\t\\t// Return an Api.rows() extended instance, so rows().nodes() etc can be used\\n\\t\\tvar modRows = this.rows( -1 );\\n\\t\\tmodRows.pop();\\n\\t\\t$.merge( modRows, newRows );\\n\\t\\n\\t\\treturn modRows;\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t *\\n\\t */\\n\\t_api_register( 'row()', function ( selector, opts ) {\\n\\t\\treturn _selector_first( this.rows( selector, opts ) );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'row().data()', function ( data ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( data === undefined ) {\\n\\t\\t\\t// Get\\n\\t\\t\\treturn ctx.length && this.length ?\\n\\t\\t\\t\\tctx[0].aoData[ this[0] ]._aData :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// Set\\n\\t\\tctx[0].aoData[ this[0] ]._aData = data;\\n\\t\\n\\t\\t// Automatically invalidate\\n\\t\\t_fnInvalidate( ctx[0], this[0], 'data' );\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'row().node()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\treturn ctx.length && this.length ?\\n\\t\\t\\tctx[0].aoData[ this[0] ].nTr || null :\\n\\t\\t\\tnull;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'row.add()', function ( row ) {\\n\\t\\t// Allow a jQuery object to be passed in - only a single row is added from\\n\\t\\t// it though - the first element in the set\\n\\t\\tif ( row instanceof $ && row.length ) {\\n\\t\\t\\trow = row[0];\\n\\t\\t}\\n\\t\\n\\t\\tvar rows = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\\n\\t\\t\\t\\treturn _fnAddTr( settings, row )[0];\\n\\t\\t\\t}\\n\\t\\t\\treturn _fnAddData( settings, row );\\n\\t\\t} );\\n\\t\\n\\t\\t// Return an Api.rows() extended instance, with the newly added row selected\\n\\t\\treturn this.row( rows[0] );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __details_add = function ( ctx, row, data, klass )\\n\\t{\\n\\t\\t// Convert to array of TR elements\\n\\t\\tvar rows = [];\\n\\t\\tvar addRow = function ( r, k ) {\\n\\t\\t\\t// Recursion to allow for arrays of jQuery objects\\n\\t\\t\\tif ( $.isArray( r ) || r instanceof $ ) {\\n\\t\\t\\t\\tfor ( var i=0, ien=r.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\taddRow( r[i], k );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// If we get a TR element, then just add it directly - up to the dev\\n\\t\\t\\t// to add the correct number of columns etc\\n\\t\\t\\tif ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {\\n\\t\\t\\t\\trows.push( r );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Otherwise create a row with a wrapper\\n\\t\\t\\t\\tvar created = $('<tr><td/></tr>').addClass( k );\\n\\t\\t\\t\\t$('td', created)\\n\\t\\t\\t\\t\\t.addClass( k )\\n\\t\\t\\t\\t\\t.html( r )\\n\\t\\t\\t\\t\\t[0].colSpan = _fnVisbleColumns( ctx );\\n\\t\\n\\t\\t\\t\\trows.push( created[0] );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\taddRow( data, klass );\\n\\t\\n\\t\\tif ( row._details ) {\\n\\t\\t\\trow._details.detach();\\n\\t\\t}\\n\\t\\n\\t\\trow._details = $(rows);\\n\\t\\n\\t\\t// If the children were already shown, that state should be retained\\n\\t\\tif ( row._detailsShow ) {\\n\\t\\t\\trow._details.insertAfter( row.nTr );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\tvar __details_remove = function ( api, idx )\\n\\t{\\n\\t\\tvar ctx = api.context;\\n\\t\\n\\t\\tif ( ctx.length ) {\\n\\t\\t\\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\\n\\t\\n\\t\\t\\tif ( row && row._details ) {\\n\\t\\t\\t\\trow._details.remove();\\n\\t\\n\\t\\t\\t\\trow._detailsShow = undefined;\\n\\t\\t\\t\\trow._details = undefined;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\tvar __details_display = function ( api, show ) {\\n\\t\\tvar ctx = api.context;\\n\\t\\n\\t\\tif ( ctx.length && api.length ) {\\n\\t\\t\\tvar row = ctx[0].aoData[ api[0] ];\\n\\t\\n\\t\\t\\tif ( row._details ) {\\n\\t\\t\\t\\trow._detailsShow = show;\\n\\t\\n\\t\\t\\t\\tif ( show ) {\\n\\t\\t\\t\\t\\trow._details.insertAfter( row.nTr );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\trow._details.detach();\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t__details_events( ctx[0] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\tvar __details_events = function ( settings )\\n\\t{\\n\\t\\tvar api = new _Api( settings );\\n\\t\\tvar namespace = '.dt.DT_details';\\n\\t\\tvar drawEvent = 'draw'+namespace;\\n\\t\\tvar colvisEvent = 'column-visibility'+namespace;\\n\\t\\tvar destroyEvent = 'destroy'+namespace;\\n\\t\\tvar data = settings.aoData;\\n\\t\\n\\t\\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\\n\\t\\n\\t\\tif ( _pluck( data, '_details' ).length > 0 ) {\\n\\t\\t\\t// On each draw, insert the required elements into the document\\n\\t\\t\\tapi.on( drawEvent, function ( e, ctx ) {\\n\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\\n\\t\\t\\t\\t\\t// Internal data grab\\n\\t\\t\\t\\t\\tvar row = data[ idx ];\\n\\t\\n\\t\\t\\t\\t\\tif ( row._detailsShow ) {\\n\\t\\t\\t\\t\\t\\trow._details.insertAfter( row.nTr );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\t// Column visibility change - update the colspan\\n\\t\\t\\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\\n\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Update the colspan for the details rows (note, only if it already has\\n\\t\\t\\t\\t// a colspan)\\n\\t\\t\\t\\tvar row, visible = _fnVisbleColumns( ctx );\\n\\t\\n\\t\\t\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\trow = data[i];\\n\\t\\n\\t\\t\\t\\t\\tif ( row._details ) {\\n\\t\\t\\t\\t\\t\\trow._details.children('td[colspan]').attr('colspan', visible );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\t// Table destroyed - nuke any child rows\\n\\t\\t\\tapi.on( destroyEvent, function ( e, ctx ) {\\n\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\tif ( data[i]._details ) {\\n\\t\\t\\t\\t\\t\\t__details_remove( api, i );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t// Strings for the method names to help minification\\n\\tvar _emp = '';\\n\\tvar _child_obj = _emp+'row().child';\\n\\tvar _child_mth = _child_obj+'()';\\n\\t\\n\\t// data can be:\\n\\t// tr\\n\\t// string\\n\\t// jQuery or array of any of the above\\n\\t_api_register( _child_mth, function ( data, klass ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( data === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\treturn ctx.length && this.length ?\\n\\t\\t\\t\\tctx[0].aoData[ this[0] ]._details :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\telse if ( data === true ) {\\n\\t\\t\\t// show\\n\\t\\t\\tthis.child.show();\\n\\t\\t}\\n\\t\\telse if ( data === false ) {\\n\\t\\t\\t// remove\\n\\t\\t\\t__details_remove( this );\\n\\t\\t}\\n\\t\\telse if ( ctx.length && this.length ) {\\n\\t\\t\\t// set\\n\\t\\t\\t__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );\\n\\t\\t}\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( [\\n\\t\\t_child_obj+'.show()',\\n\\t\\t_child_mth+'.show()' // only when `child()` was called with parameters (without\\n\\t], function ( show ) { // it returns an object and this method is not executed)\\n\\t\\t__details_display( this, true );\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( [\\n\\t\\t_child_obj+'.hide()',\\n\\t\\t_child_mth+'.hide()' // only when `child()` was called with parameters (without\\n\\t], function () { // it returns an object and this method is not executed)\\n\\t\\t__details_display( this, false );\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( [\\n\\t\\t_child_obj+'.remove()',\\n\\t\\t_child_mth+'.remove()' // only when `child()` was called with parameters (without\\n\\t], function () { // it returns an object and this method is not executed)\\n\\t\\t__details_remove( this );\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( _child_obj+'.isShown()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( ctx.length && this.length ) {\\n\\t\\t\\t// _detailsShown as false or undefined will fall through to return false\\n\\t\\t\\treturn ctx[0].aoData[ this[0] ]._detailsShow || false;\\n\\t\\t}\\n\\t\\treturn false;\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\\t * Columns\\n\\t *\\n\\t * {integer} - column index (>=0 count from left, <0 count from right)\\n\\t * \\\"{integer}:visIdx\\\" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)\\n\\t * \\\"{integer}:visible\\\" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)\\n\\t * \\\"{string}:name\\\" - column name\\n\\t * \\\"{string}\\\" - jQuery selector on column header nodes\\n\\t *\\n\\t */\\n\\t\\n\\t// can be an array of these items, comma separated list, or an array of comma\\n\\t// separated lists\\n\\t\\n\\tvar __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;\\n\\t\\n\\t\\n\\t// r1 and r2 are redundant - but it means that the parameters match for the\\n\\t// iterator callback in columns().data()\\n\\tvar __columnData = function ( settings, column, r1, r2, rows ) {\\n\\t\\tvar a = [];\\n\\t\\tfor ( var row=0, ien=rows.length ; row<ien ; row++ ) {\\n\\t\\t\\ta.push( _fnGetCellData( settings, rows[row], column ) );\\n\\t\\t}\\n\\t\\treturn a;\\n\\t};\\n\\t\\n\\t\\n\\tvar __column_selector = function ( settings, selector, opts )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tcolumns = settings.aoColumns,\\n\\t\\t\\tnames = _pluck( columns, 'sName' ),\\n\\t\\t\\tnodes = _pluck( columns, 'nTh' );\\n\\t\\n\\t\\tvar run = function ( s ) {\\n\\t\\t\\tvar selInt = _intVal( s );\\n\\t\\n\\t\\t\\t// Selector - all\\n\\t\\t\\tif ( s === '' ) {\\n\\t\\t\\t\\treturn _range( columns.length );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - index\\n\\t\\t\\tif ( selInt !== null ) {\\n\\t\\t\\t\\treturn [ selInt >= 0 ?\\n\\t\\t\\t\\t\\tselInt : // Count from left\\n\\t\\t\\t\\t\\tcolumns.length + selInt // Count from right (+ because its a negative value)\\n\\t\\t\\t\\t];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector = function\\n\\t\\t\\tif ( typeof s === 'function' ) {\\n\\t\\t\\t\\tvar rows = _selector_row_indexes( settings, opts );\\n\\t\\n\\t\\t\\t\\treturn $.map( columns, function (col, idx) {\\n\\t\\t\\t\\t\\treturn s(\\n\\t\\t\\t\\t\\t\\t\\tidx,\\n\\t\\t\\t\\t\\t\\t\\t__columnData( settings, idx, 0, 0, rows ),\\n\\t\\t\\t\\t\\t\\t\\tnodes[ idx ]\\n\\t\\t\\t\\t\\t\\t) ? idx : null;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// jQuery or string selector\\n\\t\\t\\tvar match = typeof s === 'string' ?\\n\\t\\t\\t\\ts.match( __re_column_selector ) :\\n\\t\\t\\t\\t'';\\n\\t\\n\\t\\t\\tif ( match ) {\\n\\t\\t\\t\\tswitch( match[2] ) {\\n\\t\\t\\t\\t\\tcase 'visIdx':\\n\\t\\t\\t\\t\\tcase 'visible':\\n\\t\\t\\t\\t\\t\\tvar idx = parseInt( match[1], 10 );\\n\\t\\t\\t\\t\\t\\t// Visible index given, convert to column index\\n\\t\\t\\t\\t\\t\\tif ( idx < 0 ) {\\n\\t\\t\\t\\t\\t\\t\\t// Counting from the right\\n\\t\\t\\t\\t\\t\\t\\tvar visColumns = $.map( columns, function (col,i) {\\n\\t\\t\\t\\t\\t\\t\\t\\treturn col.bVisible ? i : null;\\n\\t\\t\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t\\t\\t\\treturn [ visColumns[ visColumns.length + idx ] ];\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t// Counting from the left\\n\\t\\t\\t\\t\\t\\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\\n\\t\\n\\t\\t\\t\\t\\tcase 'name':\\n\\t\\t\\t\\t\\t\\t// match by name. `names` is column index complete and in order\\n\\t\\t\\t\\t\\t\\treturn $.map( names, function (name, i) {\\n\\t\\t\\t\\t\\t\\t\\treturn name === match[1] ? i : null;\\n\\t\\t\\t\\t\\t\\t} );\\n\\t\\n\\t\\t\\t\\t\\tdefault:\\n\\t\\t\\t\\t\\t\\treturn [];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Cell in the table body\\n\\t\\t\\tif ( s.nodeName && s._DT_CellIndex ) {\\n\\t\\t\\t\\treturn [ s._DT_CellIndex.column ];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// jQuery selector on the TH elements for the columns\\n\\t\\t\\tvar jqResult = $( nodes )\\n\\t\\t\\t\\t.filter( s )\\n\\t\\t\\t\\t.map( function () {\\n\\t\\t\\t\\t\\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.toArray();\\n\\t\\n\\t\\t\\tif ( jqResult.length || ! s.nodeName ) {\\n\\t\\t\\t\\treturn jqResult;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Otherwise a node which might have a `dt-column` data attribute, or be\\n\\t\\t\\t// a child or such an element\\n\\t\\t\\tvar host = $(s).closest('*[data-dt-column]');\\n\\t\\t\\treturn host.length ?\\n\\t\\t\\t\\t[ host.data('dt-column') ] :\\n\\t\\t\\t\\t[];\\n\\t\\t};\\n\\t\\n\\t\\treturn _selector_run( 'column', selector, run, settings, opts );\\n\\t};\\n\\t\\n\\t\\n\\tvar __setColumnVis = function ( settings, column, vis ) {\\n\\t\\tvar\\n\\t\\t\\tcols = settings.aoColumns,\\n\\t\\t\\tcol = cols[ column ],\\n\\t\\t\\tdata = settings.aoData,\\n\\t\\t\\trow, cells, i, ien, tr;\\n\\t\\n\\t\\t// Get\\n\\t\\tif ( vis === undefined ) {\\n\\t\\t\\treturn col.bVisible;\\n\\t\\t}\\n\\t\\n\\t\\t// Set\\n\\t\\t// No change\\n\\t\\tif ( col.bVisible === vis ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( vis ) {\\n\\t\\t\\t// Insert column\\n\\t\\t\\t// Need to decide if we should use appendChild or insertBefore\\n\\t\\t\\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\\n\\t\\n\\t\\t\\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\ttr = data[i].nTr;\\n\\t\\t\\t\\tcells = data[i].anCells;\\n\\t\\n\\t\\t\\t\\tif ( tr ) {\\n\\t\\t\\t\\t\\t// insertBefore can act like appendChild if 2nd arg is null\\n\\t\\t\\t\\t\\ttr.insertBefore( cells[ column ], cells[ insertBefore ] || null );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Remove column\\n\\t\\t\\t$( _pluck( settings.aoData, 'anCells', column ) ).detach();\\n\\t\\t}\\n\\t\\n\\t\\t// Common actions\\n\\t\\tcol.bVisible = vis;\\n\\t\\t_fnDrawHead( settings, settings.aoHeader );\\n\\t\\t_fnDrawHead( settings, settings.aoFooter );\\n\\t\\n\\t\\t_fnSaveState( settings );\\n\\t};\\n\\t\\n\\t\\n\\t_api_register( 'columns()', function ( selector, opts ) {\\n\\t\\t// argument shifting\\n\\t\\tif ( selector === undefined ) {\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\telse if ( $.isPlainObject( selector ) ) {\\n\\t\\t\\topts = selector;\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\n\\t\\topts = _selector_opts( opts );\\n\\t\\n\\t\\tvar inst = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\treturn __column_selector( settings, selector, opts );\\n\\t\\t}, 1 );\\n\\t\\n\\t\\t// Want argument shifting here and in _row_selector?\\n\\t\\tinst.selector.cols = selector;\\n\\t\\tinst.selector.opts = opts;\\n\\t\\n\\t\\treturn inst;\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn settings.aoColumns[column].nTh;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn settings.aoColumns[column].nTf;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().data()', 'column().data()', function () {\\n\\t\\treturn this.iterator( 'column-rows', __columnData, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn settings.aoColumns[column].mData;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {\\n\\t\\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\\n\\t\\t\\treturn _pluck_order( settings.aoData, rows,\\n\\t\\t\\t\\ttype === 'search' ? '_aFilterData' : '_aSortData', column\\n\\t\\t\\t);\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {\\n\\t\\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\\n\\t\\t\\treturn _pluck_order( settings.aoData, rows, 'anCells', column ) ;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {\\n\\t\\tvar ret = this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\tif ( vis === undefined ) {\\n\\t\\t\\t\\treturn settings.aoColumns[ column ].bVisible;\\n\\t\\t\\t} // else\\n\\t\\t\\t__setColumnVis( settings, column, vis );\\n\\t\\t} );\\n\\t\\n\\t\\t// Group the column visibility changes\\n\\t\\tif ( vis !== undefined ) {\\n\\t\\t\\t// Second loop once the first is done for events\\n\\t\\t\\tthis.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\t\\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tif ( calc === undefined || calc ) {\\n\\t\\t\\t\\tthis.columns.adjust();\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn ret;\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn type === 'visible' ?\\n\\t\\t\\t\\t_fnColumnIndexToVisible( settings, column ) :\\n\\t\\t\\t\\tcolumn;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_register( 'columns.adjust()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnAdjustColumnSizing( settings );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_register( 'column.index()', function ( type, idx ) {\\n\\t\\tif ( this.context.length !== 0 ) {\\n\\t\\t\\tvar ctx = this.context[0];\\n\\t\\n\\t\\t\\tif ( type === 'fromVisible' || type === 'toData' ) {\\n\\t\\t\\t\\treturn _fnVisibleToColumnIndex( ctx, idx );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( type === 'fromData' || type === 'toVisible' ) {\\n\\t\\t\\t\\treturn _fnColumnIndexToVisible( ctx, idx );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t_api_register( 'column()', function ( selector, opts ) {\\n\\t\\treturn _selector_first( this.columns( selector, opts ) );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __cell_selector = function ( settings, selector, opts )\\n\\t{\\n\\t\\tvar data = settings.aoData;\\n\\t\\tvar rows = _selector_row_indexes( settings, opts );\\n\\t\\tvar cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );\\n\\t\\tvar allCells = $( [].concat.apply([], cells) );\\n\\t\\tvar row;\\n\\t\\tvar columns = settings.aoColumns.length;\\n\\t\\tvar a, i, ien, j, o, host;\\n\\t\\n\\t\\tvar run = function ( s ) {\\n\\t\\t\\tvar fnSelector = typeof s === 'function';\\n\\t\\n\\t\\t\\tif ( s === null || s === undefined || fnSelector ) {\\n\\t\\t\\t\\t// All cells and function selectors\\n\\t\\t\\t\\ta = [];\\n\\t\\n\\t\\t\\t\\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\trow = rows[i];\\n\\t\\n\\t\\t\\t\\t\\tfor ( j=0 ; j<columns ; j++ ) {\\n\\t\\t\\t\\t\\t\\to = {\\n\\t\\t\\t\\t\\t\\t\\trow: row,\\n\\t\\t\\t\\t\\t\\t\\tcolumn: j\\n\\t\\t\\t\\t\\t\\t};\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( fnSelector ) {\\n\\t\\t\\t\\t\\t\\t\\t// Selector - function\\n\\t\\t\\t\\t\\t\\t\\thost = data[ row ];\\n\\t\\n\\t\\t\\t\\t\\t\\t\\tif ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {\\n\\t\\t\\t\\t\\t\\t\\t\\ta.push( o );\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\t\\t// Selector - all\\n\\t\\t\\t\\t\\t\\t\\ta.push( o );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn a;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t// Selector - index\\n\\t\\t\\tif ( $.isPlainObject( s ) ) {\\n\\t\\t\\t\\treturn [s];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - jQuery filtered cells\\n\\t\\t\\tvar jqResult = allCells\\n\\t\\t\\t\\t.filter( s )\\n\\t\\t\\t\\t.map( function (i, el) {\\n\\t\\t\\t\\t\\treturn { // use a new object, in case someone changes the values\\n\\t\\t\\t\\t\\t\\trow: el._DT_CellIndex.row,\\n\\t\\t\\t\\t\\t\\tcolumn: el._DT_CellIndex.column\\n\\t \\t\\t\\t\\t};\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.toArray();\\n\\t\\n\\t\\t\\tif ( jqResult.length || ! s.nodeName ) {\\n\\t\\t\\t\\treturn jqResult;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Otherwise the selector is a node, and there is one last option - the\\n\\t\\t\\t// element might be a child of an element which has dt-row and dt-column\\n\\t\\t\\t// data attributes\\n\\t\\t\\thost = $(s).closest('*[data-dt-row]');\\n\\t\\t\\treturn host.length ?\\n\\t\\t\\t\\t[ {\\n\\t\\t\\t\\t\\trow: host.data('dt-row'),\\n\\t\\t\\t\\t\\tcolumn: host.data('dt-column')\\n\\t\\t\\t\\t} ] :\\n\\t\\t\\t\\t[];\\n\\t\\t};\\n\\t\\n\\t\\treturn _selector_run( 'cell', selector, run, settings, opts );\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {\\n\\t\\t// Argument shifting\\n\\t\\tif ( $.isPlainObject( rowSelector ) ) {\\n\\t\\t\\t// Indexes\\n\\t\\t\\tif ( rowSelector.row === undefined ) {\\n\\t\\t\\t\\t// Selector options in first parameter\\n\\t\\t\\t\\topts = rowSelector;\\n\\t\\t\\t\\trowSelector = null;\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Cell index objects in first parameter\\n\\t\\t\\t\\topts = columnSelector;\\n\\t\\t\\t\\tcolumnSelector = null;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif ( $.isPlainObject( columnSelector ) ) {\\n\\t\\t\\topts = columnSelector;\\n\\t\\t\\tcolumnSelector = null;\\n\\t\\t}\\n\\t\\n\\t\\t// Cell selector\\n\\t\\tif ( columnSelector === null || columnSelector === undefined ) {\\n\\t\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t\\treturn __cell_selector( settings, rowSelector, _selector_opts( opts ) );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\t// Row + column selector\\n\\t\\tvar columns = this.columns( columnSelector, opts );\\n\\t\\tvar rows = this.rows( rowSelector, opts );\\n\\t\\tvar a, i, ien, j, jen;\\n\\t\\n\\t\\tvar cells = this.iterator( 'table', function ( settings, idx ) {\\n\\t\\t\\ta = [];\\n\\t\\n\\t\\t\\tfor ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tfor ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\ta.push( {\\n\\t\\t\\t\\t\\t\\trow: rows[idx][i],\\n\\t\\t\\t\\t\\t\\tcolumn: columns[idx][j]\\n\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn a;\\n\\t\\t}, 1 );\\n\\t\\n\\t\\t$.extend( cells.selector, {\\n\\t\\t\\tcols: columnSelector,\\n\\t\\t\\trows: rowSelector,\\n\\t\\t\\topts: opts\\n\\t\\t} );\\n\\t\\n\\t\\treturn cells;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\tvar data = settings.aoData[ row ];\\n\\t\\n\\t\\t\\treturn data && data.anCells ?\\n\\t\\t\\t\\tdata.anCells[ column ] :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'cells().data()', function () {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn _fnGetCellData( settings, row, column );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {\\n\\t\\ttype = type === 'search' ? '_aFilterData' : '_aSortData';\\n\\t\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn settings.aoData[ row ][ type ][ column ];\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn _fnGetCellData( settings, row, column, type );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn {\\n\\t\\t\\t\\trow: row,\\n\\t\\t\\t\\tcolumn: column,\\n\\t\\t\\t\\tcolumnVisible: _fnColumnIndexToVisible( settings, column )\\n\\t\\t\\t};\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\t_fnInvalidate( settings, row, src, column );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {\\n\\t\\treturn _selector_first( this.cells( rowSelector, columnSelector, opts ) );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'cell().data()', function ( data ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\tvar cell = this[0];\\n\\t\\n\\t\\tif ( data === undefined ) {\\n\\t\\t\\t// Get\\n\\t\\t\\treturn ctx.length && cell.length ?\\n\\t\\t\\t\\t_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// Set\\n\\t\\t_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );\\n\\t\\t_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Get current ordering (sorting) that has been applied to the table.\\n\\t *\\n\\t * @returns {array} 2D array containing the sorting information for the first\\n\\t * table in the current context. Each element in the parent array represents\\n\\t * a column being sorted upon (i.e. multi-sorting with two columns would have\\n\\t * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is\\n\\t * the column index that the sorting condition applies to, the second is the\\n\\t * direction of the sort (`desc` or `asc`) and, optionally, the third is the\\n\\t * index of the sorting order from the `column.sorting` initialisation array.\\n\\t *//**\\n\\t * Set the ordering for the table.\\n\\t *\\n\\t * @param {integer} order Column index to sort upon.\\n\\t * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)\\n\\t * @returns {DataTables.Api} this\\n\\t *//**\\n\\t * Set the ordering for the table.\\n\\t *\\n\\t * @param {array} order 1D array of sorting information to be applied.\\n\\t * @param {array} [...] Optional additional sorting conditions\\n\\t * @returns {DataTables.Api} this\\n\\t *//**\\n\\t * Set the ordering for the table.\\n\\t *\\n\\t * @param {array} order 2D array of sorting information to be applied.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'order()', function ( order, dir ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( order === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\treturn ctx.length !== 0 ?\\n\\t\\t\\t\\tctx[0].aaSorting :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// set\\n\\t\\tif ( typeof order === 'number' ) {\\n\\t\\t\\t// Simple column / direction passed in\\n\\t\\t\\torder = [ [ order, dir ] ];\\n\\t\\t}\\n\\t\\telse if ( order.length && ! $.isArray( order[0] ) ) {\\n\\t\\t\\t// Arguments passed in (list of 1D arrays)\\n\\t\\t\\torder = Array.prototype.slice.call( arguments );\\n\\t\\t}\\n\\t\\t// otherwise a 2D array was passed in\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tsettings.aaSorting = order.slice();\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Attach a sort listener to an element for a given column\\n\\t *\\n\\t * @param {node|jQuery|string} node Identifier for the element(s) to attach the\\n\\t * listener to. This can take the form of a single DOM node, a jQuery\\n\\t * collection of nodes or a jQuery selector which will identify the node(s).\\n\\t * @param {integer} column the column that a click on this node will sort on\\n\\t * @param {function} [callback] callback function when sort is run\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'order.listener()', function ( node, column, callback ) {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnSortAttachListener( settings, node, column, callback );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'order.fixed()', function ( set ) {\\n\\t\\tif ( ! set ) {\\n\\t\\t\\tvar ctx = this.context;\\n\\t\\t\\tvar fixed = ctx.length ?\\n\\t\\t\\t\\tctx[0].aaSortingFixed :\\n\\t\\t\\t\\tundefined;\\n\\t\\n\\t\\t\\treturn $.isArray( fixed ) ?\\n\\t\\t\\t\\t{ pre: fixed } :\\n\\t\\t\\t\\tfixed;\\n\\t\\t}\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tsettings.aaSortingFixed = $.extend( true, {}, set );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t// Order by the selected column(s)\\n\\t_api_register( [\\n\\t\\t'columns().order()',\\n\\t\\t'column().order()'\\n\\t], function ( dir ) {\\n\\t\\tvar that = this;\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings, i ) {\\n\\t\\t\\tvar sort = [];\\n\\t\\n\\t\\t\\t$.each( that[i], function (j, col) {\\n\\t\\t\\t\\tsort.push( [ col, dir ] );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tsettings.aaSorting = sort;\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t_api_register( 'search()', function ( input, regex, smart, caseInsen ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( input === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\treturn ctx.length !== 0 ?\\n\\t\\t\\t\\tctx[0].oPreviousSearch.sSearch :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// set\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( ! settings.oFeatures.bFilter ) {\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {\\n\\t\\t\\t\\t\\\"sSearch\\\": input+\\\"\\\",\\n\\t\\t\\t\\t\\\"bRegex\\\": regex === null ? false : regex,\\n\\t\\t\\t\\t\\\"bSmart\\\": smart === null ? true : smart,\\n\\t\\t\\t\\t\\\"bCaseInsensitive\\\": caseInsen === null ? true : caseInsen\\n\\t\\t\\t} ), 1 );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural(\\n\\t\\t'columns().search()',\\n\\t\\t'column().search()',\\n\\t\\tfunction ( input, regex, smart, caseInsen ) {\\n\\t\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\t\\tvar preSearch = settings.aoPreSearchCols;\\n\\t\\n\\t\\t\\t\\tif ( input === undefined ) {\\n\\t\\t\\t\\t\\t// get\\n\\t\\t\\t\\t\\treturn preSearch[ column ].sSearch;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// set\\n\\t\\t\\t\\tif ( ! settings.oFeatures.bFilter ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t$.extend( preSearch[ column ], {\\n\\t\\t\\t\\t\\t\\\"sSearch\\\": input+\\\"\\\",\\n\\t\\t\\t\\t\\t\\\"bRegex\\\": regex === null ? false : regex,\\n\\t\\t\\t\\t\\t\\\"bSmart\\\": smart === null ? true : smart,\\n\\t\\t\\t\\t\\t\\\"bCaseInsensitive\\\": caseInsen === null ? true : caseInsen\\n\\t\\t\\t\\t} );\\n\\t\\n\\t\\t\\t\\t_fnFilterComplete( settings, settings.oPreviousSearch, 1 );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t);\\n\\t\\n\\t/*\\n\\t * State API methods\\n\\t */\\n\\t\\n\\t_api_register( 'state()', function () {\\n\\t\\treturn this.context.length ?\\n\\t\\t\\tthis.context[0].oSavedState :\\n\\t\\t\\tnull;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'state.clear()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t// Save an empty object\\n\\t\\t\\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, {} );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'state.loaded()', function () {\\n\\t\\treturn this.context.length ?\\n\\t\\t\\tthis.context[0].oLoadedState :\\n\\t\\t\\tnull;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'state.save()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnSaveState( settings );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Provide a common method for plug-ins to check the version of DataTables being\\n\\t * used, in order to ensure compatibility.\\n\\t *\\n\\t * @param {string} version Version string to check for, in the format \\\"X.Y.Z\\\".\\n\\t * Note that the formats \\\"X\\\" and \\\"X.Y\\\" are also acceptable.\\n\\t * @returns {boolean} true if this version of DataTables is greater or equal to\\n\\t * the required version, or false if this version of DataTales is not\\n\\t * suitable\\n\\t * @static\\n\\t * @dtopt API-Static\\n\\t *\\n\\t * @example\\n\\t * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );\\n\\t */\\n\\tDataTable.versionCheck = DataTable.fnVersionCheck = function( version )\\n\\t{\\n\\t\\tvar aThis = DataTable.version.split('.');\\n\\t\\tvar aThat = version.split('.');\\n\\t\\tvar iThis, iThat;\\n\\t\\n\\t\\tfor ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {\\n\\t\\t\\tiThis = parseInt( aThis[i], 10 ) || 0;\\n\\t\\t\\tiThat = parseInt( aThat[i], 10 ) || 0;\\n\\t\\n\\t\\t\\t// Parts are the same, keep comparing\\n\\t\\t\\tif (iThis === iThat) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Parts are different, return immediately\\n\\t\\t\\treturn iThis > iThat;\\n\\t\\t}\\n\\t\\n\\t\\treturn true;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Check if a `<table>` node is a DataTable table already or not.\\n\\t *\\n\\t * @param {node|jquery|string} table Table node, jQuery object or jQuery\\n\\t * selector for the table to test. Note that if more than more than one\\n\\t * table is passed on, only the first will be checked\\n\\t * @returns {boolean} true the table given is a DataTable, or false otherwise\\n\\t * @static\\n\\t * @dtopt API-Static\\n\\t *\\n\\t * @example\\n\\t * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\\n\\t * $('#example').dataTable();\\n\\t * }\\n\\t */\\n\\tDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\\n\\t{\\n\\t\\tvar t = $(table).get(0);\\n\\t\\tvar is = false;\\n\\t\\n\\t\\tif ( table instanceof DataTable.Api ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\t$.each( DataTable.settings, function (i, o) {\\n\\t\\t\\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\\n\\t\\t\\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\\n\\t\\n\\t\\t\\tif ( o.nTable === t || head === t || foot === t ) {\\n\\t\\t\\t\\tis = true;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn is;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Get all DataTable tables that have been initialised - optionally you can\\n\\t * select to get only currently visible tables.\\n\\t *\\n\\t * @param {boolean} [visible=false] Flag to indicate if you want all (default)\\n\\t * or visible tables only.\\n\\t * @returns {array} Array of `table` nodes (not DataTable instances) which are\\n\\t * DataTables\\n\\t * @static\\n\\t * @dtopt API-Static\\n\\t *\\n\\t * @example\\n\\t * $.each( $.fn.dataTable.tables(true), function () {\\n\\t * $(table).DataTable().columns.adjust();\\n\\t * } );\\n\\t */\\n\\tDataTable.tables = DataTable.fnTables = function ( visible )\\n\\t{\\n\\t\\tvar api = false;\\n\\t\\n\\t\\tif ( $.isPlainObject( visible ) ) {\\n\\t\\t\\tapi = visible.api;\\n\\t\\t\\tvisible = visible.visible;\\n\\t\\t}\\n\\t\\n\\t\\tvar a = $.map( DataTable.settings, function (o) {\\n\\t\\t\\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\\n\\t\\t\\t\\treturn o.nTable;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn api ?\\n\\t\\t\\tnew _Api( a ) :\\n\\t\\t\\ta;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from camel case parameters to Hungarian notation. This is made public\\n\\t * for the extensions to provide the same ability as DataTables core to accept\\n\\t * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\\n\\t * parameters.\\n\\t *\\n\\t * @param {object} src The model object which holds all parameters that can be\\n\\t * mapped.\\n\\t * @param {object} user The object to convert from camel case to Hungarian.\\n\\t * @param {boolean} force When set to `true`, properties which already have a\\n\\t * Hungarian value in the `user` object will be overwritten. Otherwise they\\n\\t * won't be.\\n\\t */\\n\\tDataTable.camelToHungarian = _fnCamelToHungarian;\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t *\\n\\t */\\n\\t_api_register( '$()', function ( selector, opts ) {\\n\\t\\tvar\\n\\t\\t\\trows = this.rows( opts ).nodes(), // Get all rows\\n\\t\\t\\tjqRows = $(rows);\\n\\t\\n\\t\\treturn $( [].concat(\\n\\t\\t\\tjqRows.filter( selector ).toArray(),\\n\\t\\t\\tjqRows.find( selector ).toArray()\\n\\t\\t) );\\n\\t} );\\n\\t\\n\\t\\n\\t// jQuery functions to operate on the tables\\n\\t$.each( [ 'on', 'one', 'off' ], function (i, key) {\\n\\t\\t_api_register( key+'()', function ( /* event, handler */ ) {\\n\\t\\t\\tvar args = Array.prototype.slice.call(arguments);\\n\\t\\n\\t\\t\\t// Add the `dt` namespace automatically if it isn't already present\\n\\t\\t\\targs[0] = $.map( args[0].split( /\\\\s/ ), function ( e ) {\\n\\t\\t\\t\\treturn ! e.match(/\\\\.dt\\\\b/) ?\\n\\t\\t\\t\\t\\te+'.dt' :\\n\\t\\t\\t\\t\\te;\\n\\t\\t\\t\\t} ).join( ' ' );\\n\\t\\n\\t\\t\\tvar inst = $( this.tables().nodes() );\\n\\t\\t\\tinst[key].apply( inst, args );\\n\\t\\t\\treturn this;\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'clear()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnClearTable( settings );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'settings()', function () {\\n\\t\\treturn new _Api( this.context, this.context );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'init()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\treturn ctx.length ? ctx[0].oInit : null;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'data()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\treturn _pluck( settings.aoData, '_aData' );\\n\\t\\t} ).flatten();\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'destroy()', function ( remove ) {\\n\\t\\tremove = remove || false;\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tvar orig = settings.nTableWrapper.parentNode;\\n\\t\\t\\tvar classes = settings.oClasses;\\n\\t\\t\\tvar table = settings.nTable;\\n\\t\\t\\tvar tbody = settings.nTBody;\\n\\t\\t\\tvar thead = settings.nTHead;\\n\\t\\t\\tvar tfoot = settings.nTFoot;\\n\\t\\t\\tvar jqTable = $(table);\\n\\t\\t\\tvar jqTbody = $(tbody);\\n\\t\\t\\tvar jqWrapper = $(settings.nTableWrapper);\\n\\t\\t\\tvar rows = $.map( settings.aoData, function (r) { return r.nTr; } );\\n\\t\\t\\tvar i, ien;\\n\\t\\n\\t\\t\\t// Flag to note that the table is currently being destroyed - no action\\n\\t\\t\\t// should be taken\\n\\t\\t\\tsettings.bDestroying = true;\\n\\t\\n\\t\\t\\t// Fire off the destroy callbacks for plug-ins etc\\n\\t\\t\\t_fnCallbackFire( settings, \\\"aoDestroyCallback\\\", \\\"destroy\\\", [settings] );\\n\\t\\n\\t\\t\\t// If not being removed from the document, make all columns visible\\n\\t\\t\\tif ( ! remove ) {\\n\\t\\t\\t\\tnew _Api( settings ).columns().visible( true );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Blitz all `DT` namespaced events (these are internal events, the\\n\\t\\t\\t// lowercase, `dt` events are user subscribed and they are responsible\\n\\t\\t\\t// for removing them\\n\\t\\t\\tjqWrapper.off('.DT').find(':not(tbody *)').off('.DT');\\n\\t\\t\\t$(window).off('.DT-'+settings.sInstance);\\n\\t\\n\\t\\t\\t// When scrolling we had to break the table up - restore it\\n\\t\\t\\tif ( table != thead.parentNode ) {\\n\\t\\t\\t\\tjqTable.children('thead').detach();\\n\\t\\t\\t\\tjqTable.append( thead );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( tfoot && table != tfoot.parentNode ) {\\n\\t\\t\\t\\tjqTable.children('tfoot').detach();\\n\\t\\t\\t\\tjqTable.append( tfoot );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tsettings.aaSorting = [];\\n\\t\\t\\tsettings.aaSortingFixed = [];\\n\\t\\t\\t_fnSortingClasses( settings );\\n\\t\\n\\t\\t\\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\\n\\t\\n\\t\\t\\t$('th, td', thead).removeClass( classes.sSortable+' '+\\n\\t\\t\\t\\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\\n\\t\\t\\t);\\n\\t\\n\\t\\t\\t// Add the TR elements back into the table in their original order\\n\\t\\t\\tjqTbody.children().detach();\\n\\t\\t\\tjqTbody.append( rows );\\n\\t\\n\\t\\t\\t// Remove the DataTables generated nodes, events and classes\\n\\t\\t\\tvar removedMethod = remove ? 'remove' : 'detach';\\n\\t\\t\\tjqTable[ removedMethod ]();\\n\\t\\t\\tjqWrapper[ removedMethod ]();\\n\\t\\n\\t\\t\\t// If we need to reattach the table to the document\\n\\t\\t\\tif ( ! remove && orig ) {\\n\\t\\t\\t\\t// insertBefore acts like appendChild if !arg[1]\\n\\t\\t\\t\\torig.insertBefore( table, settings.nTableReinsertBefore );\\n\\t\\n\\t\\t\\t\\t// Restore the width of the original table - was read from the style property,\\n\\t\\t\\t\\t// so we can restore directly to that\\n\\t\\t\\t\\tjqTable\\n\\t\\t\\t\\t\\t.css( 'width', settings.sDestroyWidth )\\n\\t\\t\\t\\t\\t.removeClass( classes.sTable );\\n\\t\\n\\t\\t\\t\\t// If the were originally stripe classes - then we add them back here.\\n\\t\\t\\t\\t// Note this is not fool proof (for example if not all rows had stripe\\n\\t\\t\\t\\t// classes - but it's a good effort without getting carried away\\n\\t\\t\\t\\tien = settings.asDestroyStripes.length;\\n\\t\\n\\t\\t\\t\\tif ( ien ) {\\n\\t\\t\\t\\t\\tjqTbody.children().each( function (i) {\\n\\t\\t\\t\\t\\t\\t$(this).addClass( settings.asDestroyStripes[i % ien] );\\n\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Remove the settings object from the settings array */\\n\\t\\t\\tvar idx = $.inArray( settings, DataTable.settings );\\n\\t\\t\\tif ( idx !== -1 ) {\\n\\t\\t\\t\\tDataTable.settings.splice( idx, 1 );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t// Add the `every()` method for rows, columns and cells in a compact form\\n\\t$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\\n\\t\\t_api_register( type+'s().every()', function ( fn ) {\\n\\t\\t\\tvar opts = this.selector.opts;\\n\\t\\t\\tvar api = this;\\n\\t\\n\\t\\t\\treturn this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {\\n\\t\\t\\t\\t// Rows and columns:\\n\\t\\t\\t\\t// arg1 - index\\n\\t\\t\\t\\t// arg2 - table counter\\n\\t\\t\\t\\t// arg3 - loop counter\\n\\t\\t\\t\\t// arg4 - undefined\\n\\t\\t\\t\\t// Cells:\\n\\t\\t\\t\\t// arg1 - row index\\n\\t\\t\\t\\t// arg2 - column index\\n\\t\\t\\t\\t// arg3 - table counter\\n\\t\\t\\t\\t// arg4 - loop counter\\n\\t\\t\\t\\tfn.call(\\n\\t\\t\\t\\t\\tapi[ type ](\\n\\t\\t\\t\\t\\t\\targ1,\\n\\t\\t\\t\\t\\t\\ttype==='cell' ? arg2 : opts,\\n\\t\\t\\t\\t\\t\\ttype==='cell' ? opts : undefined\\n\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\targ1, arg2, arg3, arg4\\n\\t\\t\\t\\t);\\n\\t\\t\\t} );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t// i18n method for extensions to be able to use the language object from the\\n\\t// DataTable\\n\\t_api_register( 'i18n()', function ( token, def, plural ) {\\n\\t\\tvar ctx = this.context[0];\\n\\t\\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\\n\\t\\n\\t\\tif ( resolved === undefined ) {\\n\\t\\t\\tresolved = def;\\n\\t\\t}\\n\\t\\n\\t\\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\\n\\t\\t\\tresolved = resolved[ plural ] !== undefined ?\\n\\t\\t\\t\\tresolved[ plural ] :\\n\\t\\t\\t\\tresolved._;\\n\\t\\t}\\n\\t\\n\\t\\treturn resolved.replace( '%d', plural ); // nb: plural might be undefined,\\n\\t} );\\n\\t/**\\n\\t * Version string for plug-ins to check compatibility. Allowed format is\\n\\t * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\\n\\t * only for non-release builds. See http://semver.org/ for more information.\\n\\t * @member\\n\\t * @type string\\n\\t * @default Version number\\n\\t */\\n\\tDataTable.version = \\\"1.10.16-dev\\\";\\n\\n\\t/**\\n\\t * Private data store, containing all of the settings objects that are\\n\\t * created for the tables on a given page.\\n\\t *\\n\\t * Note that the `DataTable.settings` object is aliased to\\n\\t * `jQuery.fn.dataTableExt` through which it may be accessed and\\n\\t * manipulated, or `jQuery.fn.dataTable.settings`.\\n\\t * @member\\n\\t * @type array\\n\\t * @default []\\n\\t * @private\\n\\t */\\n\\tDataTable.settings = [];\\n\\n\\t/**\\n\\t * Object models container, for the various models that DataTables has\\n\\t * available to it. These models define the objects that are used to hold\\n\\t * the active state and configuration of the table.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models = {};\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Template object for the way in which DataTables holds information about\\n\\t * search information for the global filter and individual column filters.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models.oSearch = {\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the filtering should be case insensitive or not\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t */\\n\\t\\t\\\"bCaseInsensitive\\\": true,\\n\\t\\n\\t\\t/**\\n\\t\\t * Applied search term\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t */\\n\\t\\t\\\"sSearch\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the search term should be interpreted as a\\n\\t\\t * regular expression (true) or not (false) and therefore and special\\n\\t\\t * regex characters escaped.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bRegex\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if DataTables is to use its smart filtering or not.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t */\\n\\t\\t\\\"bSmart\\\": true\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Template object for the way in which DataTables holds information about\\n\\t * each individual row. This is the object format used for the settings\\n\\t * aoData array.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models.oRow = {\\n\\t\\t/**\\n\\t\\t * TR element for the row\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTr\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of TD elements for each row. This is null until the row has been\\n\\t\\t * created.\\n\\t\\t * @type array nodes\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"anCells\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Data object from the original data source for the row. This is either\\n\\t\\t * an array if using the traditional form of DataTables, or an object if\\n\\t\\t * using mData options. The exact type will depend on the passed in\\n\\t\\t * data from the data source, or will be an array if using DOM a data\\n\\t\\t * source.\\n\\t\\t * @type array|object\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"_aData\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Sorting data cache - this array is ostensibly the same length as the\\n\\t\\t * number of columns (although each index is generated only as it is\\n\\t\\t * needed), and holds the data that is used for sorting each column in the\\n\\t\\t * row. We do this cache generation at the start of the sort in order that\\n\\t\\t * the formatting of the sort data need be done only once for each cell\\n\\t\\t * per sort. This array should not be read from or written to by anything\\n\\t\\t * other than the master sorting methods.\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_aSortData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Per cell filtering data cache. As per the sort data cache, used to\\n\\t\\t * increase the performance of the filtering in DataTables\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_aFilterData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Filtering data cache. This is the same as the cell filtering cache, but\\n\\t\\t * in this case a string rather than an array. This is easily computed with\\n\\t\\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\\n\\t\\t * needed on every search (memory traded for performance)\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_sFilterRow\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Cache of the class name that DataTables has applied to the row, so we\\n\\t\\t * can quickly look at this variable rather than needing to do a DOM check\\n\\t\\t * on className for the nTr property.\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_sRowStripe\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * Denote if the original data source was from the DOM, or the data source\\n\\t\\t * object. This is used for invalidating data, so DataTables can\\n\\t\\t * automatically read data from the original source, unless uninstructed\\n\\t\\t * otherwise.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"src\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Index in the aoData array. This saves an indexOf lookup when we have the\\n\\t\\t * object, but want to know the index\\n\\t\\t * @type integer\\n\\t\\t * @default -1\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"idx\\\": -1\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Template object for the column information object in DataTables. This object\\n\\t * is held in the settings aoColumns array and contains all the information that\\n\\t * DataTables needs about each individual column.\\n\\t *\\n\\t * Note that this object is related to {@link DataTable.defaults.column}\\n\\t * but this one is the internal data store for DataTables's cache of columns.\\n\\t * It should NOT be manipulated outside of DataTables. Any configuration should\\n\\t * be done through the initialisation options.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models.oColumn = {\\n\\t\\t/**\\n\\t\\t * Column index. This could be worked out on-the-fly with $.inArray, but it\\n\\t\\t * is faster to just hold it as a variable\\n\\t\\t * @type integer\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"idx\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * A list of the columns that sorting should occur on when this column\\n\\t\\t * is sorted. That this property is an array allows multi-column sorting\\n\\t\\t * to be defined for a column (for example first name / last name columns\\n\\t\\t * would benefit from this). The values are integers pointing to the\\n\\t\\t * columns to be sorted on (typically it will be a single integer pointing\\n\\t\\t * at itself, but that doesn't need to be the case).\\n\\t\\t * @type array\\n\\t\\t */\\n\\t\\t\\\"aDataSort\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Define the sorting directions that are applied to the column, in sequence\\n\\t\\t * as the column is repeatedly sorted upon - i.e. the first value is used\\n\\t\\t * as the sorting direction when the column if first sorted (clicked on).\\n\\t\\t * Sort it again (click again) and it will move on to the next index.\\n\\t\\t * Repeat until loop.\\n\\t\\t * @type array\\n\\t\\t */\\n\\t\\t\\\"asSorting\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the column is searchable, and thus should be included\\n\\t\\t * in the filtering or not.\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bSearchable\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the column is sortable or not.\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bSortable\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the column is currently visible in the table or not\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bVisible\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Store for manual type assignment using the `column.type` option. This\\n\\t\\t * is held in store so we can manipulate the column's `sType` property.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_sManualType\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if HTML5 data attributes should be used as the data\\n\\t\\t * source for filtering or sorting. True is either are.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_bAttrSrc\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Developer definable function that is called whenever a cell is created (Ajax source,\\n\\t\\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\\n\\t\\t * allowing you to modify the DOM element (add background colour for example) when the\\n\\t\\t * element is available.\\n\\t\\t * @type function\\n\\t\\t * @param {element} nTd The TD node that has been created\\n\\t\\t * @param {*} sData The Data for the cell\\n\\t\\t * @param {array|object} oData The data for the whole row\\n\\t\\t * @param {int} iRow The row index for the aoData data store\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"fnCreatedCell\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Function to get data from a cell in a column. You should <b>never</b>\\n\\t\\t * access data directly through _aData internally in DataTables - always use\\n\\t\\t * the method attached to this property. It allows mData to function as\\n\\t\\t * required. This function is automatically assigned by the column\\n\\t\\t * initialisation method\\n\\t\\t * @type function\\n\\t\\t * @param {array|object} oData The data array/object for the array\\n\\t\\t * (i.e. aoData[]._aData)\\n\\t\\t * @param {string} sSpecific The specific data type you want to get -\\n\\t\\t * 'display', 'type' 'filter' 'sort'\\n\\t\\t * @returns {*} The data for the cell from the given row's data\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"fnGetData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Function to set data for a cell in the column. You should <b>never</b>\\n\\t\\t * set the data directly to _aData internally in DataTables - always use\\n\\t\\t * this method. It allows mData to function as required. This function\\n\\t\\t * is automatically assigned by the column initialisation method\\n\\t\\t * @type function\\n\\t\\t * @param {array|object} oData The data array/object for the array\\n\\t\\t * (i.e. aoData[]._aData)\\n\\t\\t * @param {*} sValue Value to set\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"fnSetData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Property to read the value for the cells in the column from the data\\n\\t\\t * source array / object. If null, then the default content is used, if a\\n\\t\\t * function is given then the return from the function is used.\\n\\t\\t * @type function|int|string|null\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"mData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Partner property to mData which is used (only when defined) to get\\n\\t\\t * the data - i.e. it is basically the same as mData, but without the\\n\\t\\t * 'set' option, and also the data fed to it is the result from mData.\\n\\t\\t * This is the rendering method to match the data method of mData.\\n\\t\\t * @type function|int|string|null\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"mRender\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique header TH/TD element for this column - this is what the sorting\\n\\t\\t * listener is attached to (if sorting is enabled.)\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTh\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique footer TH/TD element for this column (if there is one). Not used\\n\\t\\t * in DataTables as such, but can be used for plug-ins to reference the\\n\\t\\t * footer for each column.\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTf\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * The class to apply to all TD elements in the table's TBODY for the column\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sClass\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * When DataTables calculates the column widths to assign to each column,\\n\\t\\t * it finds the longest string in each column and then constructs a\\n\\t\\t * temporary table and reads the widths from that. The problem with this\\n\\t\\t * is that \\\"mmm\\\" is much wider then \\\"iiii\\\", but the latter is a longer\\n\\t\\t * string - thus the calculation can go wrong (doing it properly and putting\\n\\t\\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\\n\\t\\t * a \\\"work around\\\" we provide this option. It will append its value to the\\n\\t\\t * text that is found to be the longest string for the column - i.e. padding.\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sContentPadding\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows a default value to be given for a column's data, and will be used\\n\\t\\t * whenever a null data source is encountered (this can be because mData\\n\\t\\t * is set to null, or because the data source itself is null).\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sDefaultContent\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Name for the column, allowing reference to the column by name as well as\\n\\t\\t * by index (needs a lookup to work by name).\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sName\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Custom sorting data type - defines which of the available plug-ins in\\n\\t\\t * afnSortData the custom sorting will use - if any is defined.\\n\\t\\t * @type string\\n\\t\\t * @default std\\n\\t\\t */\\n\\t\\t\\\"sSortDataType\\\": 'std',\\n\\t\\n\\t\\t/**\\n\\t\\t * Class to be applied to the header element when sorting on this column\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sSortingClass\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Class to be applied to the header element when sorting on this column -\\n\\t\\t * when jQuery UI theming is used.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sSortingClassJUI\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Title of the column - what is seen in the TH element (nTh).\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sTitle\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Column sorting and filtering type\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sType\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Width of the column\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sWidth\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Width of the column when it was first \\\"encountered\\\"\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sWidthOrig\\\": null\\n\\t};\\n\\t\\n\\t\\n\\t/*\\n\\t * Developer note: The properties of the object below are given in Hungarian\\n\\t * notation, that was used as the interface for DataTables prior to v1.10, however\\n\\t * from v1.10 onwards the primary interface is camel case. In order to avoid\\n\\t * breaking backwards compatibility utterly with this change, the Hungarian\\n\\t * version is still, internally the primary interface, but is is not documented\\n\\t * - hence the @name tags in each doc comment. This allows a Javascript function\\n\\t * to create a map from Hungarian notation to camel case (going the other direction\\n\\t * would require each property to be listed, which would at around 3K to the size\\n\\t * of DataTables, while this method is about a 0.5K hit.\\n\\t *\\n\\t * Ultimately this does pave the way for Hungarian notation to be dropped\\n\\t * completely, but that is a massive amount of work and will break current\\n\\t * installs (therefore is on-hold until v2).\\n\\t */\\n\\t\\n\\t/**\\n\\t * Initialisation options that can be given to DataTables at initialisation\\n\\t * time.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.defaults = {\\n\\t\\t/**\\n\\t\\t * An array of data to use for the table, passed in at initialisation which\\n\\t\\t * will be used in preference to any data which is already in the DOM. This is\\n\\t\\t * particularly useful for constructing tables purely in Javascript, for\\n\\t\\t * example with a custom Ajax call.\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.data\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using a 2D array data source\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"data\\\": [\\n\\t\\t * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\\n\\t\\t * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\\n\\t\\t * ],\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"title\\\": \\\"Engine\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Browser\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Platform\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Version\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using an array of objects as a data source (`data`)\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"data\\\": [\\n\\t\\t * {\\n\\t\\t * \\\"engine\\\": \\\"Trident\\\",\\n\\t\\t * \\\"browser\\\": \\\"Internet Explorer 4.0\\\",\\n\\t\\t * \\\"platform\\\": \\\"Win 95+\\\",\\n\\t\\t * \\\"version\\\": 4,\\n\\t\\t * \\\"grade\\\": \\\"X\\\"\\n\\t\\t * },\\n\\t\\t * {\\n\\t\\t * \\\"engine\\\": \\\"Trident\\\",\\n\\t\\t * \\\"browser\\\": \\\"Internet Explorer 5.0\\\",\\n\\t\\t * \\\"platform\\\": \\\"Win 95+\\\",\\n\\t\\t * \\\"version\\\": 5,\\n\\t\\t * \\\"grade\\\": \\\"C\\\"\\n\\t\\t * }\\n\\t\\t * ],\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"title\\\": \\\"Engine\\\", \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Browser\\\", \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Platform\\\", \\\"data\\\": \\\"platform\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Version\\\", \\\"data\\\": \\\"version\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Grade\\\", \\\"data\\\": \\\"grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aaData\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * If ordering is enabled, then DataTables will perform a first pass sort on\\n\\t\\t * initialisation. You can define which column(s) the sort is performed\\n\\t\\t * upon, and the sorting direction, with this variable. The `sorting` array\\n\\t\\t * should contain an array for each column to be sorted initially containing\\n\\t\\t * the column's index and a direction string ('asc' or 'desc').\\n\\t\\t * @type array\\n\\t\\t * @default [[0,'asc']]\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.order\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Sort by 3rd column first, and then 4th column\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"order\\\": [[2,'asc'], [3,'desc']]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * // No initial sorting\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"order\\\": []\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aaSorting\\\": [[0,'asc']],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter is basically identical to the `sorting` parameter, but\\n\\t\\t * cannot be overridden by user interaction with the table. What this means\\n\\t\\t * is that you could have a column (visible or hidden) which the sorting\\n\\t\\t * will always be forced on first - any sorting after that (from the user)\\n\\t\\t * will then be performed as required. This can be useful for grouping rows\\n\\t\\t * together.\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.orderFixed\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderFixed\\\": [[0,'asc']]\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"aaSortingFixed\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables can be instructed to load data to display in the table from a\\n\\t\\t * Ajax source. This option defines how that Ajax call is made and where to.\\n\\t\\t *\\n\\t\\t * The `ajax` property has three different modes of operation, depending on\\n\\t\\t * how it is defined. These are:\\n\\t\\t *\\n\\t\\t * * `string` - Set the URL from where the data should be loaded from.\\n\\t\\t * * `object` - Define properties for `jQuery.ajax`.\\n\\t\\t * * `function` - Custom data get function\\n\\t\\t *\\n\\t\\t * `string`\\n\\t\\t * --------\\n\\t\\t *\\n\\t\\t * As a string, the `ajax` property simply defines the URL from which\\n\\t\\t * DataTables will load data.\\n\\t\\t *\\n\\t\\t * `object`\\n\\t\\t * --------\\n\\t\\t *\\n\\t\\t * As an object, the parameters in the object are passed to\\n\\t\\t * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control\\n\\t\\t * of the Ajax request. DataTables has a number of default parameters which\\n\\t\\t * you can override using this option. Please refer to the jQuery\\n\\t\\t * documentation for a full description of the options available, although\\n\\t\\t * the following parameters provide additional options in DataTables or\\n\\t\\t * require special consideration:\\n\\t\\t *\\n\\t\\t * * `data` - As with jQuery, `data` can be provided as an object, but it\\n\\t\\t * can also be used as a function to manipulate the data DataTables sends\\n\\t\\t * to the server. The function takes a single parameter, an object of\\n\\t\\t * parameters with the values that DataTables has readied for sending. An\\n\\t\\t * object may be returned which will be merged into the DataTables\\n\\t\\t * defaults, or you can add the items to the object that was passed in and\\n\\t\\t * not return anything from the function. This supersedes `fnServerParams`\\n\\t\\t * from DataTables 1.9-.\\n\\t\\t *\\n\\t\\t * * `dataSrc` - By default DataTables will look for the property `data` (or\\n\\t\\t * `aaData` for compatibility with DataTables 1.9-) when obtaining data\\n\\t\\t * from an Ajax source or for server-side processing - this parameter\\n\\t\\t * allows that property to be changed. You can use Javascript dotted\\n\\t\\t * object notation to get a data source for multiple levels of nesting, or\\n\\t\\t * it my be used as a function. As a function it takes a single parameter,\\n\\t\\t * the JSON returned from the server, which can be manipulated as\\n\\t\\t * required, with the returned value being that used by DataTables as the\\n\\t\\t * data source for the table. This supersedes `sAjaxDataProp` from\\n\\t\\t * DataTables 1.9-.\\n\\t\\t *\\n\\t\\t * * `success` - Should not be overridden it is used internally in\\n\\t\\t * DataTables. To manipulate / transform the data returned by the server\\n\\t\\t * use `ajax.dataSrc`, or use `ajax` as a function (see below).\\n\\t\\t *\\n\\t\\t * `function`\\n\\t\\t * ----------\\n\\t\\t *\\n\\t\\t * As a function, making the Ajax call is left up to yourself allowing\\n\\t\\t * complete control of the Ajax request. Indeed, if desired, a method other\\n\\t\\t * than Ajax could be used to obtain the required data, such as Web storage\\n\\t\\t * or an AIR database.\\n\\t\\t *\\n\\t\\t * The function is given four parameters and no return is required. The\\n\\t\\t * parameters are:\\n\\t\\t *\\n\\t\\t * 1. _object_ - Data to send to the server\\n\\t\\t * 2. _function_ - Callback function that must be executed when the required\\n\\t\\t * data has been obtained. That data should be passed into the callback\\n\\t\\t * as the only parameter\\n\\t\\t * 3. _object_ - DataTables settings object for the table\\n\\t\\t *\\n\\t\\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\\n\\t\\t *\\n\\t\\t * @type string|object|function\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.ajax\\n\\t\\t * @since 1.10.0\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get JSON data from a file via Ajax.\\n\\t\\t * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": \\\"data.json\\\"\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get JSON data from a file via Ajax, using `dataSrc` to change\\n\\t\\t * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"dataSrc\\\": \\\"tableData\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get JSON data from a file via Ajax, using `dataSrc` to read data\\n\\t\\t * // from a plain array rather than an array in an object\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"dataSrc\\\": \\\"\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Manipulate the data returned from the server - add a link to data\\n\\t\\t * // (note this can, should, be done using `render` for the column - this\\n\\t\\t * // is just a simple example of how the data can be manipulated).\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"dataSrc\\\": function ( json ) {\\n\\t\\t * for ( var i=0, ien=json.length ; i<ien ; i++ ) {\\n\\t\\t * json[i][0] = '<a href=\\\"/message/'+json[i][0]+'>View message</a>';\\n\\t\\t * }\\n\\t\\t * return json;\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Add data to the request\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"data\\\": function ( d ) {\\n\\t\\t * return {\\n\\t\\t * \\\"extra_search\\\": $('#extra').val()\\n\\t\\t * };\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Send request as POST\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"type\\\": \\\"POST\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get the data from localStorage (could interface with a form for\\n\\t\\t * // adding, editing and removing rows).\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": function (data, callback, settings) {\\n\\t\\t * callback(\\n\\t\\t * JSON.parse( localStorage.getItem('dataTablesData') )\\n\\t\\t * );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"ajax\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter allows you to readily specify the entries in the length drop\\n\\t\\t * down menu that DataTables shows when pagination is enabled. It can be\\n\\t\\t * either a 1D array of options which will be used for both the displayed\\n\\t\\t * option and the value, or a 2D array which will use the array in the first\\n\\t\\t * position as the value, and the array in the second position as the\\n\\t\\t * displayed options (useful for language strings such as 'All').\\n\\t\\t *\\n\\t\\t * Note that the `pageLength` property will be automatically set to the\\n\\t\\t * first value given in this array, unless `pageLength` is also provided.\\n\\t\\t * @type array\\n\\t\\t * @default [ 10, 25, 50, 100 ]\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.lengthMenu\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"lengthMenu\\\": [[10, 25, 50, -1], [10, 25, 50, \\\"All\\\"]]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aLengthMenu\\\": [ 10, 25, 50, 100 ],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The `columns` option in the initialisation parameter allows you to define\\n\\t\\t * details about the way individual columns behave. For a full list of\\n\\t\\t * column options that can be set, please see\\n\\t\\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\\n\\t\\t * define your columns, you must have an entry in the array for every single\\n\\t\\t * column that you have in your table (these can be null if you don't which\\n\\t\\t * to specify any options).\\n\\t\\t * @member\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column\\n\\t\\t */\\n\\t\\t\\\"aoColumns\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Very similar to `columns`, `columnDefs` allows you to target a specific\\n\\t\\t * column, multiple columns, or all columns, using the `targets` property of\\n\\t\\t * each object in the array. This allows great flexibility when creating\\n\\t\\t * tables, as the `columnDefs` arrays can be of any length, targeting the\\n\\t\\t * columns you specifically want. `columnDefs` may use any of the column\\n\\t\\t * options available: {@link DataTable.defaults.column}, but it _must_\\n\\t\\t * have `targets` defined in each object in the array. Values in the `targets`\\n\\t\\t * array may be:\\n\\t\\t * <ul>\\n\\t\\t * <li>a string - class name will be matched on the TH for the column</li>\\n\\t\\t * <li>0 or a positive integer - column index counting from the left</li>\\n\\t\\t * <li>a negative integer - column index counting from the right</li>\\n\\t\\t * <li>the string \\\"_all\\\" - all columns (i.e. assign a default)</li>\\n\\t\\t * </ul>\\n\\t\\t * @member\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.columnDefs\\n\\t\\t */\\n\\t\\t\\\"aoColumnDefs\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Basically the same as `search`, this parameter defines the individual column\\n\\t\\t * filtering state at initialisation time. The array must be of the same size\\n\\t\\t * as the number of columns, and each element be an object with the parameters\\n\\t\\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\\n\\t\\t * accepted and the default will be used.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.searchCols\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"searchCols\\\": [\\n\\t\\t * null,\\n\\t\\t * { \\\"search\\\": \\\"My filter\\\" },\\n\\t\\t * null,\\n\\t\\t * { \\\"search\\\": \\\"^[0-9]\\\", \\\"escapeRegex\\\": false }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"aoSearchCols\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * An array of CSS classes that should be applied to displayed rows. This\\n\\t\\t * array may be of any length, and DataTables will apply each class\\n\\t\\t * sequentially, looping when required.\\n\\t\\t * @type array\\n\\t\\t * @default null <i>Will take the values determined by the `oClasses.stripe*`\\n\\t\\t * options</i>\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.stripeClasses\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stripeClasses\\\": [ 'strip1', 'strip2', 'strip3' ]\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"asStripeClasses\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable automatic column width calculation. This can be disabled\\n\\t\\t * as an optimisation (it takes some time to calculate the widths) if the\\n\\t\\t * tables widths are passed in using `columns`.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.autoWidth\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"autoWidth\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bAutoWidth\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Deferred rendering can provide DataTables with a huge speed boost when you\\n\\t\\t * are using an Ajax or JS data source for the table. This option, when set to\\n\\t\\t * true, will cause DataTables to defer the creation of the table elements for\\n\\t\\t * each row until they are needed for a draw - saving a significant amount of\\n\\t\\t * time.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.deferRender\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": \\\"sources/arrays.txt\\\",\\n\\t\\t * \\\"deferRender\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bDeferRender\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Replace a DataTable which matches the given selector and replace it with\\n\\t\\t * one which has the properties of the new initialisation object passed. If no\\n\\t\\t * table matches the selector, then the new DataTable will be constructed as\\n\\t\\t * per normal.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.destroy\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"srollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"paginate\\\": false\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * // Some time later....\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"filter\\\": false,\\n\\t\\t * \\\"destroy\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bDestroy\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable filtering of data. Filtering in DataTables is \\\"smart\\\" in\\n\\t\\t * that it allows the end user to input multiple words (space separated) and\\n\\t\\t * will match a row containing those words, even if not in the order that was\\n\\t\\t * specified (this allow matching across multiple columns). Note that if you\\n\\t\\t * wish to use filtering in DataTables this must remain 'true' - to remove the\\n\\t\\t * default filtering input box and retain filtering abilities, please use\\n\\t\\t * {@link DataTable.defaults.dom}.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.searching\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"searching\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bFilter\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the table information display. This shows information\\n\\t\\t * about the data that is currently visible on the page, including information\\n\\t\\t * about filtered data if that action is being performed.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.info\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"info\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bInfo\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows the end user to select the size of a formatted page from a select\\n\\t\\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.lengthChange\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"lengthChange\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bLengthChange\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable pagination.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.paging\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"paging\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bPaginate\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the display of a 'processing' indicator when the table is\\n\\t\\t * being processed (e.g. a sort). This is particularly useful for tables with\\n\\t\\t * large amounts of data where it can take a noticeable amount of time to sort\\n\\t\\t * the entries.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.processing\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"processing\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bProcessing\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Retrieve the DataTables object for the given selector. Note that if the\\n\\t\\t * table has already been initialised, this parameter will cause DataTables\\n\\t\\t * to simply return the object that has already been set up - it will not take\\n\\t\\t * account of any changes you might have made to the initialisation object\\n\\t\\t * passed to DataTables (setting this parameter to true is an acknowledgement\\n\\t\\t * that you understand this). `destroy` can be used to reinitialise a table if\\n\\t\\t * you need.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.retrieve\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * initTable();\\n\\t\\t * tableActions();\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * function initTable ()\\n\\t\\t * {\\n\\t\\t * return $('#example').dataTable( {\\n\\t\\t * \\\"scrollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"paginate\\\": false,\\n\\t\\t * \\\"retrieve\\\": true\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t *\\n\\t\\t * function tableActions ()\\n\\t\\t * {\\n\\t\\t * var table = initTable();\\n\\t\\t * // perform API operations with oTable\\n\\t\\t * }\\n\\t\\t */\\n\\t\\t\\\"bRetrieve\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * When vertical (y) scrolling is enabled, DataTables will force the height of\\n\\t\\t * the table's viewport to the given height at all times (useful for layout).\\n\\t\\t * However, this can look odd when filtering data down to a small data set,\\n\\t\\t * and the footer is left \\\"floating\\\" further down. This parameter (when\\n\\t\\t * enabled) will cause DataTables to collapse the table's viewport down when\\n\\t\\t * the result set will fit within the given Y height.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.scrollCollapse\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollY\\\": \\\"200\\\",\\n\\t\\t * \\\"scrollCollapse\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bScrollCollapse\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Configure DataTables to use server-side processing. Note that the\\n\\t\\t * `ajax` parameter must also be given in order to give DataTables a\\n\\t\\t * source to obtain the required data for each draw.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverSide\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"serverSide\\\": true,\\n\\t\\t * \\\"ajax\\\": \\\"xhr.php\\\"\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bServerSide\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable sorting of columns. Sorting of individual columns can be\\n\\t\\t * disabled by the `sortable` option for each column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.ordering\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ordering\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSort\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or display DataTables' ability to sort multiple columns at the\\n\\t\\t * same time (activated by shift-click by the user).\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.orderMulti\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Disable multiple column sorting ability\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderMulti\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortMulti\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows control over whether DataTables should use the top (true) unique\\n\\t\\t * cell that is found for a single column, or the bottom (false - default).\\n\\t\\t * This is useful when using complex headers.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.orderCellsTop\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderCellsTop\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortCellsTop\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the addition of the classes `sorting\\\\_1`, `sorting\\\\_2` and\\n\\t\\t * `sorting\\\\_3` to the columns which are currently being sorted on. This is\\n\\t\\t * presented as a feature switch as it can increase processing time (while\\n\\t\\t * classes are removed and added) so for large data sets you might want to\\n\\t\\t * turn this off.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.orderClasses\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderClasses\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortClasses\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\\n\\t\\t * used to save table display information such as pagination information,\\n\\t\\t * display length, filtering and sorting. As such when the end user reloads\\n\\t\\t * the page the display display will match what thy had previously set up.\\n\\t\\t *\\n\\t\\t * Due to the use of `localStorage` the default state saving is not supported\\n\\t\\t * in IE6 or 7. If state saving is required in those browsers, use\\n\\t\\t * `stateSaveCallback` to provide a storage solution such as cookies.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.stateSave\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bStateSave\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function is called when a TR element is created (and all TD child\\n\\t\\t * elements have been inserted), or registered if using a DOM source, allowing\\n\\t\\t * manipulation of the TR element (adding classes etc).\\n\\t\\t * @type function\\n\\t\\t * @param {node} row \\\"TR\\\" element for the current row\\n\\t\\t * @param {array} data Raw data array for this row\\n\\t\\t * @param {int} dataIndex The index of this row in the internal aoData array\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.createdRow\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"createdRow\\\": function( row, data, dataIndex ) {\\n\\t\\t * // Bold the grade for all 'A' grade browsers\\n\\t\\t * if ( data[4] == \\\"A\\\" )\\n\\t\\t * {\\n\\t\\t * $('td:eq(4)', row).html( '<b>A</b>' );\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnCreatedRow\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function is called on every 'draw' event, and allows you to\\n\\t\\t * dynamically modify any aspect you want about the created DOM.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.drawCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"drawCallback\\\": function( settings ) {\\n\\t\\t * alert( 'DataTables has redrawn the table' );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnDrawCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Identical to fnHeaderCallback() but for the table footer this function\\n\\t\\t * allows you to modify the table footer on every 'draw' event.\\n\\t\\t * @type function\\n\\t\\t * @param {node} foot \\\"TR\\\" element for the footer\\n\\t\\t * @param {array} data Full table data (as derived from the original HTML)\\n\\t\\t * @param {int} start Index for the current display starting point in the\\n\\t\\t * display array\\n\\t\\t * @param {int} end Index for the current display ending point in the\\n\\t\\t * display array\\n\\t\\t * @param {array int} display Index array to translate the visual position\\n\\t\\t * to the full data array\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.footerCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"footerCallback\\\": function( tfoot, data, start, end, display ) {\\n\\t\\t * tfoot.getElementsByTagName('th')[0].innerHTML = \\\"Starting index is \\\"+start;\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"fnFooterCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * When rendering large numbers in the information element for the table\\n\\t\\t * (i.e. \\\"Showing 1 to 10 of 57 entries\\\") DataTables will render large numbers\\n\\t\\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\\n\\t\\t * rendered as \\\"1,000,000\\\") to help readability for the end user. This\\n\\t\\t * function will override the default method DataTables uses.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {int} toFormat number to be formatted\\n\\t\\t * @returns {string} formatted string for DataTables to show the number\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.formatNumber\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Format a number using a single quote for the separator (note that\\n\\t\\t * // this can also be done with the language.thousands option)\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"formatNumber\\\": function ( toFormat ) {\\n\\t\\t * return toFormat.toString().replace(\\n\\t\\t * /\\\\B(?=(\\\\d{3})+(?!\\\\d))/g, \\\"'\\\"\\n\\t\\t * );\\n\\t\\t * };\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnFormatNumber\\\": function ( toFormat ) {\\n\\t\\t\\treturn toFormat.toString().replace(\\n\\t\\t\\t\\t/\\\\B(?=(\\\\d{3})+(?!\\\\d))/g,\\n\\t\\t\\t\\tthis.oLanguage.sThousands\\n\\t\\t\\t);\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function is called on every 'draw' event, and allows you to\\n\\t\\t * dynamically modify the header row. This can be used to calculate and\\n\\t\\t * display useful information about the table.\\n\\t\\t * @type function\\n\\t\\t * @param {node} head \\\"TR\\\" element for the header\\n\\t\\t * @param {array} data Full table data (as derived from the original HTML)\\n\\t\\t * @param {int} start Index for the current display starting point in the\\n\\t\\t * display array\\n\\t\\t * @param {int} end Index for the current display ending point in the\\n\\t\\t * display array\\n\\t\\t * @param {array int} display Index array to translate the visual position\\n\\t\\t * to the full data array\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.headerCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"fheaderCallback\\\": function( head, data, start, end, display ) {\\n\\t\\t * head.getElementsByTagName('th')[0].innerHTML = \\\"Displaying \\\"+(end-start)+\\\" records\\\";\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"fnHeaderCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The information element can be used to convey information about the current\\n\\t\\t * state of the table. Although the internationalisation options presented by\\n\\t\\t * DataTables are quite capable of dealing with most customisations, there may\\n\\t\\t * be times where you wish to customise the string further. This callback\\n\\t\\t * allows you to do exactly that.\\n\\t\\t * @type function\\n\\t\\t * @param {object} oSettings DataTables settings object\\n\\t\\t * @param {int} start Starting position in data for the draw\\n\\t\\t * @param {int} end End position in data for the draw\\n\\t\\t * @param {int} max Total number of rows in the table (regardless of\\n\\t\\t * filtering)\\n\\t\\t * @param {int} total Total number of rows in the data set, after filtering\\n\\t\\t * @param {string} pre The string that DataTables has formatted using it's\\n\\t\\t * own rules\\n\\t\\t * @returns {string} The string to be displayed in the information element.\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.infoCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"infoCallback\\\": function( settings, start, end, max, total, pre ) {\\n\\t\\t * return start +\\\" to \\\"+ end;\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnInfoCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Called when the table has been initialised. Normally DataTables will\\n\\t\\t * initialise sequentially and there will be no need for this function,\\n\\t\\t * however, this does not hold true when using external language information\\n\\t\\t * since that is obtained using an async XHR call.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} json The JSON object request from the server - only\\n\\t\\t * present if client-side Ajax sourced data is used\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.initComplete\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"initComplete\\\": function(settings, json) {\\n\\t\\t * alert( 'DataTables has finished its initialisation.' );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"fnInitComplete\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Called at the very start of each table draw and can be used to cancel the\\n\\t\\t * draw by returning false, any other return (including undefined) results in\\n\\t\\t * the full draw occurring).\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @returns {boolean} False will cancel the draw, anything else (including no\\n\\t\\t * return) will allow it to complete.\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.preDrawCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"preDrawCallback\\\": function( settings ) {\\n\\t\\t * if ( $('#test').val() == 1 ) {\\n\\t\\t * return false;\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnPreDrawCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function allows you to 'post process' each row after it have been\\n\\t\\t * generated for each table draw, but before it is rendered on screen. This\\n\\t\\t * function might be used for setting the row class name etc.\\n\\t\\t * @type function\\n\\t\\t * @param {node} row \\\"TR\\\" element for the current row\\n\\t\\t * @param {array} data Raw data array for this row\\n\\t\\t * @param {int} displayIndex The display index for the current table draw\\n\\t\\t * @param {int} displayIndexFull The index of the data in the full list of\\n\\t\\t * rows (after filtering)\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.rowCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"rowCallback\\\": function( row, data, displayIndex, displayIndexFull ) {\\n\\t\\t * // Bold the grade for all 'A' grade browsers\\n\\t\\t * if ( data[4] == \\\"A\\\" ) {\\n\\t\\t * $('td:eq(4)', row).html( '<b>A</b>' );\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnRowCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * This parameter allows you to override the default function which obtains\\n\\t\\t * the data from the server so something more suitable for your application.\\n\\t\\t * For example you could use POST data, or pull information from a Gears or\\n\\t\\t * AIR database.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {string} source HTTP source to obtain the data from (`ajax`)\\n\\t\\t * @param {array} data A key/value pair object containing the data to send\\n\\t\\t * to the server\\n\\t\\t * @param {function} callback to be called on completion of the data get\\n\\t\\t * process that will draw the data on the page.\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverData\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"fnServerData\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * It is often useful to send extra data to the server when making an Ajax\\n\\t\\t * request - for example custom filtering information, and this callback\\n\\t\\t * function makes it trivial to send extra information to the server. The\\n\\t\\t * passed in parameter is the data set that has been constructed by\\n\\t\\t * DataTables, and you can add to this or modify it as you require.\\n\\t\\t * @type function\\n\\t\\t * @param {array} data Data array (array of objects which are name/value\\n\\t\\t * pairs) that has been constructed by DataTables and will be sent to the\\n\\t\\t * server. In the case of Ajax sourced data with server-side processing\\n\\t\\t * this will be an empty array, for server-side processing there will be a\\n\\t\\t * significant number of parameters!\\n\\t\\t * @returns {undefined} Ensure that you modify the data array passed in,\\n\\t\\t * as this is passed by reference.\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverParams\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"fnServerParams\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Load the table state. With this function you can define from where, and how, the\\n\\t\\t * state of a table is loaded. By default DataTables will load from `localStorage`\\n\\t\\t * but you might wish to use a server-side database or cookies.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} callback Callback that can be executed when done. It\\n\\t\\t * should be passed the loaded state object.\\n\\t\\t * @return {object} The DataTables state object to be loaded\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateLoadCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoadCallback\\\": function (settings, callback) {\\n\\t\\t * $.ajax( {\\n\\t\\t * \\\"url\\\": \\\"/state_load\\\",\\n\\t\\t * \\\"dataType\\\": \\\"json\\\",\\n\\t\\t * \\\"success\\\": function (json) {\\n\\t\\t * callback( json );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateLoadCallback\\\": function ( settings ) {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\treturn JSON.parse(\\n\\t\\t\\t\\t\\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\\n\\t\\t\\t\\t\\t\\t'DataTables_'+settings.sInstance+'_'+location.pathname\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t);\\n\\t\\t\\t} catch (e) {}\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback which allows modification of the saved state prior to loading that state.\\n\\t\\t * This callback is called when the table is loading state from the stored data, but\\n\\t\\t * prior to the settings object being modified by the saved state. Note that for\\n\\t\\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\\n\\t\\t * a plug-in.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object that is to be loaded\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateLoadParams\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Remove a saved filter, so filtering is never loaded\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoadParams\\\": function (settings, data) {\\n\\t\\t * data.oSearch.sSearch = \\\"\\\";\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Disallow state loading by returning false\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoadParams\\\": function (settings, data) {\\n\\t\\t * return false;\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateLoadParams\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback that is called when the state has been loaded from the state saving method\\n\\t\\t * and the DataTables settings object has been modified as a result of the loaded state.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object that was loaded\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateLoaded\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Show an alert with the filtering value that was saved\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoaded\\\": function (settings, data) {\\n\\t\\t * alert( 'Saved filter was: '+data.oSearch.sSearch );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateLoaded\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Save the table state. This function allows you to define where and how the state\\n\\t\\t * information for the table is stored By default DataTables will use `localStorage`\\n\\t\\t * but you might wish to use a server-side database or cookies.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object to be saved\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateSaveCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateSaveCallback\\\": function (settings, data) {\\n\\t\\t * // Send an Ajax request to the server with the state object\\n\\t\\t * $.ajax( {\\n\\t\\t * \\\"url\\\": \\\"/state_save\\\",\\n\\t\\t * \\\"data\\\": data,\\n\\t\\t * \\\"dataType\\\": \\\"json\\\",\\n\\t\\t * \\\"method\\\": \\\"POST\\\"\\n\\t\\t * \\\"success\\\": function () {}\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateSaveCallback\\\": function ( settings, data ) {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\\n\\t\\t\\t\\t\\t'DataTables_'+settings.sInstance+'_'+location.pathname,\\n\\t\\t\\t\\t\\tJSON.stringify( data )\\n\\t\\t\\t\\t);\\n\\t\\t\\t} catch (e) {}\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback which allows modification of the state to be saved. Called when the table\\n\\t\\t * has changed state a new state save is required. This method allows modification of\\n\\t\\t * the state saving object prior to actually doing the save, including addition or\\n\\t\\t * other state properties or modification. Note that for plug-in authors, you should\\n\\t\\t * use the `stateSaveParams` event to save parameters for a plug-in.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object to be saved\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateSaveParams\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Remove a saved filter, so filtering is never saved\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateSaveParams\\\": function (settings, data) {\\n\\t\\t * data.oSearch.sSearch = \\\"\\\";\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateSaveParams\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Duration for which the saved state information is considered valid. After this period\\n\\t\\t * has elapsed the state will be returned to the default.\\n\\t\\t * Value is given in seconds.\\n\\t\\t * @type int\\n\\t\\t * @default 7200 <i>(2 hours)</i>\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.stateDuration\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateDuration\\\": 60*60*24; // 1 day\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"iStateDuration\\\": 7200,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * When enabled DataTables will not make a request to the server for the first\\n\\t\\t * page draw - rather it will use the data already on the page (no sorting etc\\n\\t\\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\\n\\t\\t * is used to indicate that deferred loading is required, but it is also used\\n\\t\\t * to tell DataTables how many records there are in the full table (allowing\\n\\t\\t * the information element and pagination to be displayed correctly). In the case\\n\\t\\t * where a filtering is applied to the table on initial load, this can be\\n\\t\\t * indicated by giving the parameter as an array, where the first element is\\n\\t\\t * the number of records available after filtering and the second element is the\\n\\t\\t * number of records without filtering (allowing the table information element\\n\\t\\t * to be shown correctly).\\n\\t\\t * @type int | array\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.deferLoading\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // 57 records available in the table, no filtering applied\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"serverSide\\\": true,\\n\\t\\t * \\\"ajax\\\": \\\"scripts/server_processing.php\\\",\\n\\t\\t * \\\"deferLoading\\\": 57\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // 57 records after filtering, 100 without filtering (an initial filter applied)\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"serverSide\\\": true,\\n\\t\\t * \\\"ajax\\\": \\\"scripts/server_processing.php\\\",\\n\\t\\t * \\\"deferLoading\\\": [ 57, 100 ],\\n\\t\\t * \\\"search\\\": {\\n\\t\\t * \\\"search\\\": \\\"my_filter\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"iDeferLoading\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Number of rows to display on a single page when using pagination. If\\n\\t\\t * feature enabled (`lengthChange`) then the end user will be able to override\\n\\t\\t * this to a custom setting using a pop-up menu.\\n\\t\\t * @type int\\n\\t\\t * @default 10\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.pageLength\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"pageLength\\\": 50\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"iDisplayLength\\\": 10,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Define the starting point for data display when using DataTables with\\n\\t\\t * pagination. Note that this parameter is the number of records, rather than\\n\\t\\t * the page number, so if you have 10 records per page and want to start on\\n\\t\\t * the third page, it should be \\\"20\\\".\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.displayStart\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"displayStart\\\": 20\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"iDisplayStart\\\": 0,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\\n\\t\\t * and filtering) by adding a `tabindex` attribute to the required elements. This\\n\\t\\t * allows you to tab through the controls and press the enter key to activate them.\\n\\t\\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\\n\\t\\t * You can overrule this using this parameter if you wish. Use a value of -1 to\\n\\t\\t * disable built-in keyboard navigation.\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.tabIndex\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"tabIndex\\\": 1\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"iTabIndex\\\": 0,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Classes that DataTables assigns to the various components and features\\n\\t\\t * that it adds to the HTML table. This allows classes to be configured\\n\\t\\t * during initialisation in addition to through the static\\n\\t\\t * {@link DataTable.ext.oStdClasses} object).\\n\\t\\t * @namespace\\n\\t\\t * @name DataTable.defaults.classes\\n\\t\\t */\\n\\t\\t\\\"oClasses\\\": {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * All strings that DataTables uses in the user interface that it creates\\n\\t\\t * are defined in this object, allowing you to modified them individually or\\n\\t\\t * completely replace them all as required.\\n\\t\\t * @namespace\\n\\t\\t * @name DataTable.defaults.language\\n\\t\\t */\\n\\t\\t\\\"oLanguage\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * Strings that are used for WAI-ARIA labels and controls only (these are not\\n\\t\\t\\t * actually visible on the page, but will be read by screenreaders, and thus\\n\\t\\t\\t * must be internationalised as well).\\n\\t\\t\\t * @namespace\\n\\t\\t\\t * @name DataTable.defaults.language.aria\\n\\t\\t\\t */\\n\\t\\t\\t\\\"oAria\\\": {\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * ARIA label that is added to the table headers when the column may be\\n\\t\\t\\t\\t * sorted ascending by activing the column (click or return when focused).\\n\\t\\t\\t\\t * Note that the column header is prefixed to this string.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default : activate to sort column ascending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.aria.sortAscending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"aria\\\": {\\n\\t\\t\\t\\t * \\\"sortAscending\\\": \\\" - click/return to sort ascending\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sSortAscending\\\": \\\": activate to sort column ascending\\\",\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * ARIA label that is added to the table headers when the column may be\\n\\t\\t\\t\\t * sorted descending by activing the column (click or return when focused).\\n\\t\\t\\t\\t * Note that the column header is prefixed to this string.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default : activate to sort column ascending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.aria.sortDescending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"aria\\\": {\\n\\t\\t\\t\\t * \\\"sortDescending\\\": \\\" - click/return to sort descending\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sSortDescending\\\": \\\": activate to sort column descending\\\"\\n\\t\\t\\t},\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Pagination string used by DataTables for the built-in pagination\\n\\t\\t\\t * control types.\\n\\t\\t\\t * @namespace\\n\\t\\t\\t * @name DataTable.defaults.language.paginate\\n\\t\\t\\t */\\n\\t\\t\\t\\\"oPaginate\\\": {\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use when using the 'full_numbers' type of pagination for the\\n\\t\\t\\t\\t * button to take the user to the first page.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default First\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.first\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"first\\\": \\\"First page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sFirst\\\": \\\"First\\\",\\n\\t\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use when using the 'full_numbers' type of pagination for the\\n\\t\\t\\t\\t * button to take the user to the last page.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default Last\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.last\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"last\\\": \\\"Last page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sLast\\\": \\\"Last\\\",\\n\\t\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use for the 'next' pagination button (to take the user to the\\n\\t\\t\\t\\t * next page).\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default Next\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.next\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"next\\\": \\\"Next page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sNext\\\": \\\"Next\\\",\\n\\t\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use for the 'previous' pagination button (to take the user to\\n\\t\\t\\t\\t * the previous page).\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default Previous\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.previous\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"previous\\\": \\\"Previous page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sPrevious\\\": \\\"Previous\\\"\\n\\t\\t\\t},\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * This string is shown in preference to `zeroRecords` when the table is\\n\\t\\t\\t * empty of data (regardless of filtering). Note that this is an optional\\n\\t\\t\\t * parameter - if it is not given, the value of `zeroRecords` will be used\\n\\t\\t\\t * instead (either the default or given value).\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default No data available in table\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.emptyTable\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"emptyTable\\\": \\\"No data available in table\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sEmptyTable\\\": \\\"No data available in table\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * This string gives information to the end user about the information\\n\\t\\t\\t * that is current on display on the page. The following tokens can be\\n\\t\\t\\t * used in the string and will be dynamically replaced as the table\\n\\t\\t\\t * display updates. This tokens can be placed anywhere in the string, or\\n\\t\\t\\t * removed as needed by the language requires:\\n\\t\\t\\t *\\n\\t\\t\\t * * `\\\\_START\\\\_` - Display index of the first record on the current page\\n\\t\\t\\t * * `\\\\_END\\\\_` - Display index of the last record on the current page\\n\\t\\t\\t * * `\\\\_TOTAL\\\\_` - Number of records in the table after filtering\\n\\t\\t\\t * * `\\\\_MAX\\\\_` - Number of records in the table without filtering\\n\\t\\t\\t * * `\\\\_PAGE\\\\_` - Current page number\\n\\t\\t\\t * * `\\\\_PAGES\\\\_` - Total number of pages of data in the table\\n\\t\\t\\t *\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Showing _START_ to _END_ of _TOTAL_ entries\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.info\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"info\\\": \\\"Showing page _PAGE_ of _PAGES_\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfo\\\": \\\"Showing _START_ to _END_ of _TOTAL_ entries\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Display information string for when the table is empty. Typically the\\n\\t\\t\\t * format of this string should match `info`.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Showing 0 to 0 of 0 entries\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.infoEmpty\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"infoEmpty\\\": \\\"No entries to show\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfoEmpty\\\": \\\"Showing 0 to 0 of 0 entries\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * When a user filters the information in a table, this string is appended\\n\\t\\t\\t * to the information (`info`) to give an idea of how strong the filtering\\n\\t\\t\\t * is. The variable _MAX_ is dynamically updated.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default (filtered from _MAX_ total entries)\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.infoFiltered\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"infoFiltered\\\": \\\" - filtering from _MAX_ records\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfoFiltered\\\": \\\"(filtered from _MAX_ total entries)\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * If can be useful to append extra information to the info string at times,\\n\\t\\t\\t * and this variable does exactly that. This information will be appended to\\n\\t\\t\\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\\n\\t\\t\\t * being used) at all times.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default <i>Empty string</i>\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.infoPostFix\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"infoPostFix\\\": \\\"All records shown are derived from real information.\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfoPostFix\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * This decimal place operator is a little different from the other\\n\\t\\t\\t * language options since DataTables doesn't output floating point\\n\\t\\t\\t * numbers, so it won't ever use this for display of a number. Rather,\\n\\t\\t\\t * what this parameter does is modify the sort methods of the table so\\n\\t\\t\\t * that numbers which are in a format which has a character other than\\n\\t\\t\\t * a period (`.`) as a decimal place will be sorted numerically.\\n\\t\\t\\t *\\n\\t\\t\\t * Note that numbers with different decimal places cannot be shown in\\n\\t\\t\\t * the same table and still be sortable, the table must be consistent.\\n\\t\\t\\t * However, multiple different tables on the page can use different\\n\\t\\t\\t * decimal place characters.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default \\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.decimal\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"decimal\\\": \\\",\\\"\\n\\t\\t\\t * \\\"thousands\\\": \\\".\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sDecimal\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * DataTables has a build in number formatter (`formatNumber`) which is\\n\\t\\t\\t * used to format large numbers that are used in the table information.\\n\\t\\t\\t * By default a comma is used, but this can be trivially changed to any\\n\\t\\t\\t * character you wish with this parameter.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default ,\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.thousands\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"thousands\\\": \\\"'\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sThousands\\\": \\\",\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Detail the action that will be taken when the drop down menu for the\\n\\t\\t\\t * pagination length option is changed. The '_MENU_' variable is replaced\\n\\t\\t\\t * with a default select list of 10, 25, 50 and 100, and can be replaced\\n\\t\\t\\t * with a custom select box if required.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Show _MENU_ entries\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.lengthMenu\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Language change only\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"lengthMenu\\\": \\\"Display _MENU_ records\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Language and options change\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"lengthMenu\\\": 'Display <select>'+\\n\\t\\t\\t * '<option value=\\\"10\\\">10</option>'+\\n\\t\\t\\t * '<option value=\\\"20\\\">20</option>'+\\n\\t\\t\\t * '<option value=\\\"30\\\">30</option>'+\\n\\t\\t\\t * '<option value=\\\"40\\\">40</option>'+\\n\\t\\t\\t * '<option value=\\\"50\\\">50</option>'+\\n\\t\\t\\t * '<option value=\\\"-1\\\">All</option>'+\\n\\t\\t\\t * '</select> records'\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sLengthMenu\\\": \\\"Show _MENU_ entries\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * When using Ajax sourced data and during the first draw when DataTables is\\n\\t\\t\\t * gathering the data, this message is shown in an empty row in the table to\\n\\t\\t\\t * indicate to the end user the the data is being loaded. Note that this\\n\\t\\t\\t * parameter is not used when loading data by server-side processing, just\\n\\t\\t\\t * Ajax sourced data with client-side processing.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Loading...\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.loadingRecords\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"loadingRecords\\\": \\\"Please wait - loading...\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sLoadingRecords\\\": \\\"Loading...\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Text which is displayed when the table is processing a user action\\n\\t\\t\\t * (usually a sort command or similar).\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Processing...\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.processing\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"processing\\\": \\\"DataTables is currently busy\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sProcessing\\\": \\\"Processing...\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Details the actions that will be taken when the user types into the\\n\\t\\t\\t * filtering input text box. The variable \\\"_INPUT_\\\", if used in the string,\\n\\t\\t\\t * is replaced with the HTML text box for the filtering input allowing\\n\\t\\t\\t * control over where it appears in the string. If \\\"_INPUT_\\\" is not given\\n\\t\\t\\t * then the input box is appended to the string automatically.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Search:\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.search\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Input text box will be appended at the end automatically\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"search\\\": \\\"Filter records:\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Specify where the filter should appear\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"search\\\": \\\"Apply filter _INPUT_ to table\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sSearch\\\": \\\"Search:\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Assign a `placeholder` attribute to the search `input` element\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default \\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.searchPlaceholder\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sSearchPlaceholder\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * All of the language information can be stored in a file on the\\n\\t\\t\\t * server-side, which DataTables will look up if this parameter is passed.\\n\\t\\t\\t * It must store the URL of the language file, which is in a JSON format,\\n\\t\\t\\t * and the object has the same properties as the oLanguage object in the\\n\\t\\t\\t * initialiser object (i.e. the above parameters). Please refer to one of\\n\\t\\t\\t * the example language files to see how this works in action.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default <i>Empty string - i.e. disabled</i>\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.url\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"url\\\": \\\"http://www.sprymedia.co.uk/dataTables/lang.txt\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sUrl\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Text shown inside the table records when the is no information to be\\n\\t\\t\\t * displayed after filtering. `emptyTable` is shown when there is simply no\\n\\t\\t\\t * information in the table at all (regardless of filtering).\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default No matching records found\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.zeroRecords\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"zeroRecords\\\": \\\"No records to display\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sZeroRecords\\\": \\\"No matching records found\\\"\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter allows you to have define the global filtering state at\\n\\t\\t * initialisation time. As an object the `search` parameter must be\\n\\t\\t * defined, but all other parameters are optional. When `regex` is true,\\n\\t\\t * the search string will be treated as a regular expression, when false\\n\\t\\t * (default) it will be treated as a straight string. When `smart`\\n\\t\\t * DataTables will use it's smart filtering methods (to word match at\\n\\t\\t * any point in the data), when false this will not be done.\\n\\t\\t * @namespace\\n\\t\\t * @extends DataTable.models.oSearch\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.search\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"search\\\": {\\\"search\\\": \\\"Initial search\\\"}\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"oSearch\\\": $.extend( {}, DataTable.models.oSearch ),\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * By default DataTables will look for the property `data` (or `aaData` for\\n\\t\\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\\n\\t\\t * source or for server-side processing - this parameter allows that\\n\\t\\t * property to be changed. You can use Javascript dotted object notation to\\n\\t\\t * get a data source for multiple levels of nesting.\\n\\t\\t * @type string\\n\\t\\t * @default data\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.ajaxDataProp\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"sAjaxDataProp\\\": \\\"data\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * You can instruct DataTables to load data from an external\\n\\t\\t * source using this parameter (use aData if you want to pass data in you\\n\\t\\t * already have). Simply provide a url a JSON object can be obtained from.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.ajaxSource\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"sAjaxSource\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This initialisation variable allows you to specify exactly where in the\\n\\t\\t * DOM you want DataTables to inject the various controls it adds to the page\\n\\t\\t * (for example you might want the pagination controls at the top of the\\n\\t\\t * table). DIV elements (with or without a custom class) can also be added to\\n\\t\\t * aid styling. The follow syntax is used:\\n\\t\\t * <ul>\\n\\t\\t * <li>The following options are allowed:\\n\\t\\t * <ul>\\n\\t\\t * <li>'l' - Length changing</li>\\n\\t\\t * <li>'f' - Filtering input</li>\\n\\t\\t * <li>'t' - The table!</li>\\n\\t\\t * <li>'i' - Information</li>\\n\\t\\t * <li>'p' - Pagination</li>\\n\\t\\t * <li>'r' - pRocessing</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * <li>The following constants are allowed:\\n\\t\\t * <ul>\\n\\t\\t * <li>'H' - jQueryUI theme \\\"header\\\" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>\\n\\t\\t * <li>'F' - jQueryUI theme \\\"footer\\\" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * <li>The following syntax is expected:\\n\\t\\t * <ul>\\n\\t\\t * <li>'<' and '>' - div elements</li>\\n\\t\\t * <li>'<\\\"class\\\" and '>' - div with a class</li>\\n\\t\\t * <li>'<\\\"#id\\\" and '>' - div with an ID</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * <li>Examples:\\n\\t\\t * <ul>\\n\\t\\t * <li>'<\\\"wrapper\\\"flipt>'</li>\\n\\t\\t * <li>'<lf<t>ip>'</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * </ul>\\n\\t\\t * @type string\\n\\t\\t * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>\\n\\t\\t * <\\\"H\\\"lfr>t<\\\"F\\\"ip> <i>(when `jQueryUI` is true)</i>\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.dom\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"dom\\\": '<\\\"top\\\"i>rt<\\\"bottom\\\"flp><\\\"clear\\\">'\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sDom\\\": \\\"lfrtip\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Search delay option. This will throttle full table searches that use the\\n\\t\\t * DataTables provided search input element (it does not effect calls to\\n\\t\\t * `dt-api search()`, providing a delay before the search is made.\\n\\t\\t * @type integer\\n\\t\\t * @default 0\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.searchDelay\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"searchDelay\\\": 200\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"searchDelay\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables features six different built-in options for the buttons to\\n\\t\\t * display for pagination control:\\n\\t\\t *\\n\\t\\t * * `numbers` - Page number buttons only\\n\\t\\t * * `simple` - 'Previous' and 'Next' buttons only\\n\\t\\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\\n\\t\\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\\n\\t\\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers\\n\\t\\t * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers\\n\\t\\t * \\n\\t\\t * Further methods can be added using {@link DataTable.ext.oPagination}.\\n\\t\\t * @type string\\n\\t\\t * @default simple_numbers\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.pagingType\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"pagingType\\\": \\\"full_numbers\\\"\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"sPaginationType\\\": \\\"simple_numbers\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable horizontal scrolling. When a table is too wide to fit into a\\n\\t\\t * certain layout, or you have a large number of columns in the table, you\\n\\t\\t * can enable x-scrolling to show the table in a viewport, which can be\\n\\t\\t * scrolled. This property can be `true` which will allow the table to\\n\\t\\t * scroll horizontally when needed, or any CSS unit, or a number (in which\\n\\t\\t * case it will be treated as a pixel measurement). Setting as simply `true`\\n\\t\\t * is recommended.\\n\\t\\t * @type boolean|string\\n\\t\\t * @default <i>blank string - i.e. disabled</i>\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.scrollX\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollX\\\": true,\\n\\t\\t * \\\"scrollCollapse\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sScrollX\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This property can be used to force a DataTable to use more width than it\\n\\t\\t * might otherwise do when x-scrolling is enabled. For example if you have a\\n\\t\\t * table which requires to be well spaced, this parameter is useful for\\n\\t\\t * \\\"over-sizing\\\" the table, and thus forcing scrolling. This property can by\\n\\t\\t * any CSS unit, or a number (in which case it will be treated as a pixel\\n\\t\\t * measurement).\\n\\t\\t * @type string\\n\\t\\t * @default <i>blank string - i.e. disabled</i>\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.scrollXInner\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollX\\\": \\\"100%\\\",\\n\\t\\t * \\\"scrollXInner\\\": \\\"110%\\\"\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sScrollXInner\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\\n\\t\\t * to the given height, and enable scrolling for any data which overflows the\\n\\t\\t * current viewport. This can be used as an alternative to paging to display\\n\\t\\t * a lot of data in a small area (although paging and scrolling can both be\\n\\t\\t * enabled at the same time). This property can be any CSS unit, or a number\\n\\t\\t * (in which case it will be treated as a pixel measurement).\\n\\t\\t * @type string\\n\\t\\t * @default <i>blank string - i.e. disabled</i>\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.scrollY\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"paginate\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sScrollY\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * Set the HTTP method that is used to make the Ajax call for server-side\\n\\t\\t * processing or Ajax sourced data.\\n\\t\\t * @type string\\n\\t\\t * @default GET\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverMethod\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"sServerMethod\\\": \\\"GET\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables makes use of renderers when displaying HTML elements for\\n\\t\\t * a table. These renderers can be added or modified by plug-ins to\\n\\t\\t * generate suitable mark-up for a site. For example the Bootstrap\\n\\t\\t * integration plug-in for DataTables uses a paging button renderer to\\n\\t\\t * display pagination buttons in the mark-up required by Bootstrap.\\n\\t\\t *\\n\\t\\t * For further information about the renderers available see\\n\\t\\t * DataTable.ext.renderer\\n\\t\\t * @type string|object\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.renderer\\n\\t\\t *\\n\\t\\t */\\n\\t\\t\\\"renderer\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Set the data property name that DataTables should use to get a row's id\\n\\t\\t * to set as the `id` property in the node.\\n\\t\\t * @type string\\n\\t\\t * @default DT_RowId\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.rowId\\n\\t\\t */\\n\\t\\t\\\"rowId\\\": \\\"DT_RowId\\\"\\n\\t};\\n\\t\\n\\t_fnHungarianMap( DataTable.defaults );\\n\\t\\n\\t\\n\\t\\n\\t/*\\n\\t * Developer note - See note in model.defaults.js about the use of Hungarian\\n\\t * notation and camel case.\\n\\t */\\n\\t\\n\\t/**\\n\\t * Column options that can be given to DataTables at initialisation time.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.defaults.column = {\\n\\t\\t/**\\n\\t\\t * Define which column(s) an order will occur on for this column. This\\n\\t\\t * allows a column's ordering to take multiple columns into account when\\n\\t\\t * doing a sort or use the data from a different column. For example first\\n\\t\\t * name / last name columns make sense to do a multi-column sort over the\\n\\t\\t * two columns.\\n\\t\\t * @type array|int\\n\\t\\t * @default null <i>Takes the value of the column index automatically</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderData\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderData\\\": [ 0, 1 ], \\\"targets\\\": [ 0 ] },\\n\\t\\t * { \\\"orderData\\\": [ 1, 0 ], \\\"targets\\\": [ 1 ] },\\n\\t\\t * { \\\"orderData\\\": 2, \\\"targets\\\": [ 2 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"orderData\\\": [ 0, 1 ] },\\n\\t\\t * { \\\"orderData\\\": [ 1, 0 ] },\\n\\t\\t * { \\\"orderData\\\": 2 },\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aDataSort\\\": null,\\n\\t\\t\\\"iDataSort\\\": -1,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * You can control the default ordering direction, and even alter the\\n\\t\\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\\n\\t\\t * using this parameter.\\n\\t\\t * @type array\\n\\t\\t * @default [ 'asc', 'desc' ]\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderSequence\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"asc\\\" ], \\\"targets\\\": [ 1 ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\", \\\"asc\\\", \\\"asc\\\" ], \\\"targets\\\": [ 2 ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\" ], \\\"targets\\\": [ 3 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"asc\\\" ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\", \\\"asc\\\", \\\"asc\\\" ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\" ] },\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"asSorting\\\": [ 'asc', 'desc' ],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable filtering on the data in this column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.searchable\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"searchable\\\": false, \\\"targets\\\": [ 0 ] }\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"searchable\\\": false },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSearchable\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable ordering on this column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderable\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderable\\\": false, \\\"targets\\\": [ 0 ] }\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"orderable\\\": false },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortable\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the display of this column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.visible\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"visible\\\": false, \\\"targets\\\": [ 0 ] }\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"visible\\\": false },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bVisible\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Developer definable function that is called whenever a cell is created (Ajax source,\\n\\t\\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\\n\\t\\t * allowing you to modify the DOM element (add background colour for example) when the\\n\\t\\t * element is available.\\n\\t\\t * @type function\\n\\t\\t * @param {element} td The TD node that has been created\\n\\t\\t * @param {*} cellData The Data for the cell\\n\\t\\t * @param {array|object} rowData The data for the whole row\\n\\t\\t * @param {int} row The row index for the aoData data store\\n\\t\\t * @param {int} col The column index for aoColumns\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.createdCell\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [3],\\n\\t\\t * \\\"createdCell\\\": function (td, cellData, rowData, row, col) {\\n\\t\\t * if ( cellData == \\\"1.7\\\" ) {\\n\\t\\t * $(td).css('color', 'blue')\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * });\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnCreatedCell\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter has been replaced by `data` in DataTables to ensure naming\\n\\t\\t * consistency. `dataProp` can still be used, as there is backwards\\n\\t\\t * compatibility in DataTables for this option, but it is strongly\\n\\t\\t * recommended that you use `data` in preference to `dataProp`.\\n\\t\\t * @name DataTable.defaults.column.dataProp\\n\\t\\t */\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This property can be used to read data from any data source property,\\n\\t\\t * including deeply nested objects / properties. `data` can be given in a\\n\\t\\t * number of different ways which effect its behaviour:\\n\\t\\t *\\n\\t\\t * * `integer` - treated as an array index for the data source. This is the\\n\\t\\t * default that DataTables uses (incrementally increased for each column).\\n\\t\\t * * `string` - read an object property from the data source. There are\\n\\t\\t * three 'special' options that can be used in the string to alter how\\n\\t\\t * DataTables reads the data from the source object:\\n\\t\\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\\n\\t\\t * Javascript to read from nested objects, so to can the options\\n\\t\\t * specified in `data`. For example: `browser.version` or\\n\\t\\t * `browser.name`. If your object parameter name contains a period, use\\n\\t\\t * `\\\\\\\\` to escape it - i.e. `first\\\\\\\\.name`.\\n\\t\\t * * `[]` - Array notation. DataTables can automatically combine data\\n\\t\\t * from and array source, joining the data with the characters provided\\n\\t\\t * between the two brackets. For example: `name[, ]` would provide a\\n\\t\\t * comma-space separated list from the source array. If no characters\\n\\t\\t * are provided between the brackets, the original array source is\\n\\t\\t * returned.\\n\\t\\t * * `()` - Function notation. Adding `()` to the end of a parameter will\\n\\t\\t * execute a function of the name given. For example: `browser()` for a\\n\\t\\t * simple function on the data source, `browser.version()` for a\\n\\t\\t * function in a nested property or even `browser().version` to get an\\n\\t\\t * object property if the function called returns an object. Note that\\n\\t\\t * function notation is recommended for use in `render` rather than\\n\\t\\t * `data` as it is much simpler to use as a renderer.\\n\\t\\t * * `null` - use the original data source for the row rather than plucking\\n\\t\\t * data directly from it. This action has effects on two other\\n\\t\\t * initialisation options:\\n\\t\\t * * `defaultContent` - When null is given as the `data` option and\\n\\t\\t * `defaultContent` is specified for the column, the value defined by\\n\\t\\t * `defaultContent` will be used for the cell.\\n\\t\\t * * `render` - When null is used for the `data` option and the `render`\\n\\t\\t * option is specified for the column, the whole data source for the\\n\\t\\t * row is used for the renderer.\\n\\t\\t * * `function` - the function given will be executed whenever DataTables\\n\\t\\t * needs to set or get the data for a cell in the column. The function\\n\\t\\t * takes three parameters:\\n\\t\\t * * Parameters:\\n\\t\\t * * `{array|object}` The data source for the row\\n\\t\\t * * `{string}` The type call data requested - this will be 'set' when\\n\\t\\t * setting data or 'filter', 'display', 'type', 'sort' or undefined\\n\\t\\t * when gathering data. Note that when `undefined` is given for the\\n\\t\\t * type DataTables expects to get the raw data for the object back<\\n\\t\\t * * `{*}` Data to set when the second parameter is 'set'.\\n\\t\\t * * Return:\\n\\t\\t * * The return value from the function is not required when 'set' is\\n\\t\\t * the type of call, but otherwise the return is what will be used\\n\\t\\t * for the data requested.\\n\\t\\t *\\n\\t\\t * Note that `data` is a getter and setter option. If you just require\\n\\t\\t * formatting of data for output, you will likely want to use `render` which\\n\\t\\t * is simply a getter and thus simpler to use.\\n\\t\\t *\\n\\t\\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\\n\\t\\t * name change reflects the flexibility of this property and is consistent\\n\\t\\t * with the naming of mRender. If 'mDataProp' is given, then it will still\\n\\t\\t * be used by DataTables, as it automatically maps the old name to the new\\n\\t\\t * if required.\\n\\t\\t *\\n\\t\\t * @type string|int|function|null\\n\\t\\t * @default null <i>Use automatically calculated column index</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.data\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Read table data from objects\\n\\t\\t * // JSON structure for each row:\\n\\t\\t * // {\\n\\t\\t * // \\\"engine\\\": {value},\\n\\t\\t * // \\\"browser\\\": {value},\\n\\t\\t * // \\\"platform\\\": {value},\\n\\t\\t * // \\\"version\\\": {value},\\n\\t\\t * // \\\"grade\\\": {value}\\n\\t\\t * // }\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajaxSource\\\": \\\"sources/objects.txt\\\",\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform\\\" },\\n\\t\\t * { \\\"data\\\": \\\"version\\\" },\\n\\t\\t * { \\\"data\\\": \\\"grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Read information from deeply nested objects\\n\\t\\t * // JSON structure for each row:\\n\\t\\t * // {\\n\\t\\t * // \\\"engine\\\": {value},\\n\\t\\t * // \\\"browser\\\": {value},\\n\\t\\t * // \\\"platform\\\": {\\n\\t\\t * // \\\"inner\\\": {value}\\n\\t\\t * // },\\n\\t\\t * // \\\"details\\\": [\\n\\t\\t * // {value}, {value}\\n\\t\\t * // ]\\n\\t\\t * // }\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajaxSource\\\": \\\"sources/deep.txt\\\",\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform.inner\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform.details.0\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform.details.1\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `data` as a function to provide different information for\\n\\t\\t * // sorting, filtering and display. In this case, currency (price)\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": function ( source, type, val ) {\\n\\t\\t * if (type === 'set') {\\n\\t\\t * source.price = val;\\n\\t\\t * // Store the computed dislay and filter values for efficiency\\n\\t\\t * source.price_display = val==\\\"\\\" ? \\\"\\\" : \\\"$\\\"+numberFormat(val);\\n\\t\\t * source.price_filter = val==\\\"\\\" ? \\\"\\\" : \\\"$\\\"+numberFormat(val)+\\\" \\\"+val;\\n\\t\\t * return;\\n\\t\\t * }\\n\\t\\t * else if (type === 'display') {\\n\\t\\t * return source.price_display;\\n\\t\\t * }\\n\\t\\t * else if (type === 'filter') {\\n\\t\\t * return source.price_filter;\\n\\t\\t * }\\n\\t\\t * // 'sort', 'type' and undefined all just use the integer\\n\\t\\t * return source.price;\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using default content\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": null,\\n\\t\\t * \\\"defaultContent\\\": \\\"Click to edit\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using array notation - outputting a list from an array\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": \\\"name[, ]\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t */\\n\\t\\t\\\"mData\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This property is the rendering partner to `data` and it is suggested that\\n\\t\\t * when you want to manipulate data for display (including filtering,\\n\\t\\t * sorting etc) without altering the underlying data for the table, use this\\n\\t\\t * property. `render` can be considered to be the the read only companion to\\n\\t\\t * `data` which is read / write (then as such more complex). Like `data`\\n\\t\\t * this option can be given in a number of different ways to effect its\\n\\t\\t * behaviour:\\n\\t\\t *\\n\\t\\t * * `integer` - treated as an array index for the data source. This is the\\n\\t\\t * default that DataTables uses (incrementally increased for each column).\\n\\t\\t * * `string` - read an object property from the data source. There are\\n\\t\\t * three 'special' options that can be used in the string to alter how\\n\\t\\t * DataTables reads the data from the source object:\\n\\t\\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\\n\\t\\t * Javascript to read from nested objects, so to can the options\\n\\t\\t * specified in `data`. For example: `browser.version` or\\n\\t\\t * `browser.name`. If your object parameter name contains a period, use\\n\\t\\t * `\\\\\\\\` to escape it - i.e. `first\\\\\\\\.name`.\\n\\t\\t * * `[]` - Array notation. DataTables can automatically combine data\\n\\t\\t * from and array source, joining the data with the characters provided\\n\\t\\t * between the two brackets. For example: `name[, ]` would provide a\\n\\t\\t * comma-space separated list from the source array. If no characters\\n\\t\\t * are provided between the brackets, the original array source is\\n\\t\\t * returned.\\n\\t\\t * * `()` - Function notation. Adding `()` to the end of a parameter will\\n\\t\\t * execute a function of the name given. For example: `browser()` for a\\n\\t\\t * simple function on the data source, `browser.version()` for a\\n\\t\\t * function in a nested property or even `browser().version` to get an\\n\\t\\t * object property if the function called returns an object.\\n\\t\\t * * `object` - use different data for the different data types requested by\\n\\t\\t * DataTables ('filter', 'display', 'type' or 'sort'). The property names\\n\\t\\t * of the object is the data type the property refers to and the value can\\n\\t\\t * defined using an integer, string or function using the same rules as\\n\\t\\t * `render` normally does. Note that an `_` option _must_ be specified.\\n\\t\\t * This is the default value to use if you haven't specified a value for\\n\\t\\t * the data type requested by DataTables.\\n\\t\\t * * `function` - the function given will be executed whenever DataTables\\n\\t\\t * needs to set or get the data for a cell in the column. The function\\n\\t\\t * takes three parameters:\\n\\t\\t * * Parameters:\\n\\t\\t * * {array|object} The data source for the row (based on `data`)\\n\\t\\t * * {string} The type call data requested - this will be 'filter',\\n\\t\\t * 'display', 'type' or 'sort'.\\n\\t\\t * * {array|object} The full data source for the row (not based on\\n\\t\\t * `data`)\\n\\t\\t * * Return:\\n\\t\\t * * The return value from the function is what will be used for the\\n\\t\\t * data requested.\\n\\t\\t *\\n\\t\\t * @type string|int|function|object|null\\n\\t\\t * @default null Use the data source value.\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.render\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Create a comma separated list from an array of objects\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajaxSource\\\": \\\"sources/deep.txt\\\",\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * {\\n\\t\\t * \\\"data\\\": \\\"platform\\\",\\n\\t\\t * \\\"render\\\": \\\"[, ].name\\\"\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Execute a function to obtain data\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": null, // Use the full data source object for the renderer's source\\n\\t\\t * \\\"render\\\": \\\"browserName()\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // As an object, extracting different data for the different types\\n\\t\\t * // This would be used with a data source such as:\\n\\t\\t * // { \\\"phone\\\": 5552368, \\\"phone_filter\\\": \\\"5552368 555-2368\\\", \\\"phone_display\\\": \\\"555-2368\\\" }\\n\\t\\t * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\\n\\t\\t * // (which has both forms) is used for filtering for if a user inputs either format, while\\n\\t\\t * // the formatted phone number is the one that is shown in the table.\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": null, // Use the full data source object for the renderer's source\\n\\t\\t * \\\"render\\\": {\\n\\t\\t * \\\"_\\\": \\\"phone\\\",\\n\\t\\t * \\\"filter\\\": \\\"phone_filter\\\",\\n\\t\\t * \\\"display\\\": \\\"phone_display\\\"\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Use as a function to create a link from the data source\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": \\\"download_link\\\",\\n\\t\\t * \\\"render\\\": function ( data, type, full ) {\\n\\t\\t * return '<a href=\\\"'+data+'\\\">Download</a>';\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"mRender\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Change the cell type created for the column - either TD cells or TH cells. This\\n\\t\\t * can be useful as TH cells have semantic meaning in the table body, allowing them\\n\\t\\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\\n\\t\\t * @type string\\n\\t\\t * @default td\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.cellType\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Make the first column use TH cells\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"cellType\\\": \\\"th\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sCellType\\\": \\\"td\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Class to give to each cell in this column.\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.class\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"class\\\": \\\"my_class\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"class\\\": \\\"my_class\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sClass\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * When DataTables calculates the column widths to assign to each column,\\n\\t\\t * it finds the longest string in each column and then constructs a\\n\\t\\t * temporary table and reads the widths from that. The problem with this\\n\\t\\t * is that \\\"mmm\\\" is much wider then \\\"iiii\\\", but the latter is a longer\\n\\t\\t * string - thus the calculation can go wrong (doing it properly and putting\\n\\t\\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\\n\\t\\t * a \\\"work around\\\" we provide this option. It will append its value to the\\n\\t\\t * text that is found to be the longest string for the column - i.e. padding.\\n\\t\\t * Generally you shouldn't need this!\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string<i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.contentPadding\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * {\\n\\t\\t * \\\"contentPadding\\\": \\\"mmm\\\"\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sContentPadding\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows a default value to be given for a column's data, and will be used\\n\\t\\t * whenever a null data source is encountered (this can be because `data`\\n\\t\\t * is set to null, or because the data source itself is null).\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.defaultContent\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * {\\n\\t\\t * \\\"data\\\": null,\\n\\t\\t * \\\"defaultContent\\\": \\\"Edit\\\",\\n\\t\\t * \\\"targets\\\": [ -1 ]\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * {\\n\\t\\t * \\\"data\\\": null,\\n\\t\\t * \\\"defaultContent\\\": \\\"Edit\\\"\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sDefaultContent\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter is only used in DataTables' server-side processing. It can\\n\\t\\t * be exceptionally useful to know what columns are being displayed on the\\n\\t\\t * client side, and to map these to database fields. When defined, the names\\n\\t\\t * also allow DataTables to reorder information from the server if it comes\\n\\t\\t * back in an unexpected order (i.e. if you switch your columns around on the\\n\\t\\t * client-side, your server-side code does not also need updating).\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.name\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"name\\\": \\\"engine\\\", \\\"targets\\\": [ 0 ] },\\n\\t\\t * { \\\"name\\\": \\\"browser\\\", \\\"targets\\\": [ 1 ] },\\n\\t\\t * { \\\"name\\\": \\\"platform\\\", \\\"targets\\\": [ 2 ] },\\n\\t\\t * { \\\"name\\\": \\\"version\\\", \\\"targets\\\": [ 3 ] },\\n\\t\\t * { \\\"name\\\": \\\"grade\\\", \\\"targets\\\": [ 4 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"name\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"name\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"name\\\": \\\"platform\\\" },\\n\\t\\t * { \\\"name\\\": \\\"version\\\" },\\n\\t\\t * { \\\"name\\\": \\\"grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sName\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Defines a data source type for the ordering which can be used to read\\n\\t\\t * real-time information from the table (updating the internally cached\\n\\t\\t * version) prior to ordering. This allows ordering to occur on user\\n\\t\\t * editable elements such as form inputs.\\n\\t\\t * @type string\\n\\t\\t * @default std\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderDataType\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-text\\\", \\\"targets\\\": [ 2, 3 ] },\\n\\t\\t * { \\\"type\\\": \\\"numeric\\\", \\\"targets\\\": [ 3 ] },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-select\\\", \\\"targets\\\": [ 4 ] },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-checkbox\\\", \\\"targets\\\": [ 5 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-text\\\" },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-text\\\", \\\"type\\\": \\\"numeric\\\" },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-select\\\" },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-checkbox\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sSortDataType\\\": \\\"std\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The title of this column.\\n\\t\\t * @type string\\n\\t\\t * @default null <i>Derived from the 'TH' value for this column in the\\n\\t\\t * original HTML table.</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.title\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"title\\\": \\\"My column title\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"title\\\": \\\"My column title\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sTitle\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The type allows you to specify how the data for this column will be\\n\\t\\t * ordered. Four types (string, numeric, date and html (which will strip\\n\\t\\t * HTML tags before ordering)) are currently available. Note that only date\\n\\t\\t * formats understood by Javascript's Date() object will be accepted as type\\n\\t\\t * date. For example: \\\"Mar 26, 2008 5:03 PM\\\". May take the values: 'string',\\n\\t\\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\\n\\t\\t * through plug-ins.\\n\\t\\t * @type string\\n\\t\\t * @default null <i>Auto-detected from raw data</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.type\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"type\\\": \\\"html\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"type\\\": \\\"html\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sType\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Defining the width of the column, this parameter may take any CSS value\\n\\t\\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\\n\\t\\t * been given a specific width through this interface ensuring that the table\\n\\t\\t * remains readable.\\n\\t\\t * @type string\\n\\t\\t * @default null <i>Automatic</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.width\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"width\\\": \\\"20%\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"width\\\": \\\"20%\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sWidth\\\": null\\n\\t};\\n\\t\\n\\t_fnHungarianMap( DataTable.defaults.column );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables settings object - this holds all the information needed for a\\n\\t * given table, including configuration, data and current application of the\\n\\t * table options. DataTables does not have a single instance for each DataTable\\n\\t * with the settings attached to that instance, but rather instances of the\\n\\t * DataTable \\\"class\\\" are created on-the-fly as needed (typically by a\\n\\t * $().dataTable() call) and the settings object is then applied to that\\n\\t * instance.\\n\\t *\\n\\t * Note that this object is related to {@link DataTable.defaults} but this\\n\\t * one is the internal data store for DataTables's cache of columns. It should\\n\\t * NOT be manipulated outside of DataTables. Any configuration should be done\\n\\t * through the initialisation options.\\n\\t * @namespace\\n\\t * @todo Really should attach the settings object to individual instances so we\\n\\t * don't need to create new instances on each $().dataTable() call (if the\\n\\t * table already exists). It would also save passing oSettings around and\\n\\t * into every single function. However, this is a very significant\\n\\t * architecture change for DataTables and will almost certainly break\\n\\t * backwards compatibility with older installations. This is something that\\n\\t * will be done in 2.0.\\n\\t */\\n\\tDataTable.models.oSettings = {\\n\\t\\t/**\\n\\t\\t * Primary features of DataTables and their enablement state.\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\t\\\"oFeatures\\\": {\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Flag to say if DataTables should automatically try to calculate the\\n\\t\\t\\t * optimum table and columns widths (true) or not (false).\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bAutoWidth\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Delay the creation of TR and TD elements until they are actually\\n\\t\\t\\t * needed by a driven page draw. This can give a significant speed\\n\\t\\t\\t * increase for Ajax source and Javascript source data, but makes no\\n\\t\\t\\t * difference at all fro DOM and server-side processing tables.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bDeferRender\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Enable filtering on the table or not. Note that if this is disabled\\n\\t\\t\\t * then there is no filtering at all on the table, including fnFilter.\\n\\t\\t\\t * To just remove the filtering input use sDom and remove the 'f' option.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bFilter\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Table information element (the 'Showing x of y records' div) enable\\n\\t\\t\\t * flag.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bInfo\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Present a user control allowing the end user to change the page size\\n\\t\\t\\t * when pagination is enabled.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bLengthChange\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Pagination enabled or not. Note that if this is disabled then length\\n\\t\\t\\t * changing must also be disabled.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bPaginate\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Processing indicator enable flag whenever DataTables is enacting a\\n\\t\\t\\t * user request - typically an Ajax request for server-side processing.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bProcessing\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Server-side processing enabled flag - when enabled DataTables will\\n\\t\\t\\t * get all data from the server for every draw - there is no filtering,\\n\\t\\t\\t * sorting or paging done on the client-side.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bServerSide\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Sorting enablement flag.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bSort\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Multi-column sorting\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bSortMulti\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Apply a class to the columns which are being sorted to provide a\\n\\t\\t\\t * visual highlight or not. This can slow things down when enabled since\\n\\t\\t\\t * there is a lot of DOM interaction.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bSortClasses\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * State saving enablement flag.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bStateSave\\\": null\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Scrolling settings for a table.\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\t\\\"oScroll\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * When the table is shorter in height than sScrollY, collapse the\\n\\t\\t\\t * table container down to the height of the table (when true).\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bCollapse\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Width of the scrollbar for the web-browser's platform. Calculated\\n\\t\\t\\t * during table initialisation.\\n\\t\\t\\t * @type int\\n\\t\\t\\t * @default 0\\n\\t\\t\\t */\\n\\t\\t\\t\\\"iBarWidth\\\": 0,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Viewport width for horizontal scrolling. Horizontal scrolling is\\n\\t\\t\\t * disabled if an empty string.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type string\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sX\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Width to expand the table to when using x-scrolling. Typically you\\n\\t\\t\\t * should not need to use this.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @deprecated\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sXInner\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\\n\\t\\t\\t * if an empty string.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type string\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sY\\\": null\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Language information for the table.\\n\\t\\t * @namespace\\n\\t\\t * @extends DataTable.defaults.oLanguage\\n\\t\\t */\\n\\t\\t\\\"oLanguage\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * Information callback function. See\\n\\t\\t\\t * {@link DataTable.defaults.fnInfoCallback}\\n\\t\\t\\t * @type function\\n\\t\\t\\t * @default null\\n\\t\\t\\t */\\n\\t\\t\\t\\\"fnInfoCallback\\\": null\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Browser support parameters\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\t\\\"oBrowser\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * Indicate if the browser incorrectly calculates width:100% inside a\\n\\t\\t\\t * scrolling element (IE6/7)\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default false\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bScrollOversize\\\": false,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Determine if the vertical scrollbar is on the right or left of the\\n\\t\\t\\t * scrolling container - needed for rtl language layout, although not\\n\\t\\t\\t * all browsers move the scrollbar (Safari).\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default false\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bScrollbarLeft\\\": false,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Flag for if `getBoundingClientRect` is fully supported or not\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default false\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bBounding\\\": false,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Browser scrollbar width\\n\\t\\t\\t * @type integer\\n\\t\\t\\t * @default 0\\n\\t\\t\\t */\\n\\t\\t\\t\\\"barWidth\\\": 0\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t\\\"ajax\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Array referencing the nodes which are used for the features. The\\n\\t\\t * parameters of this object match what is allowed by sDom - i.e.\\n\\t\\t * <ul>\\n\\t\\t * <li>'l' - Length changing</li>\\n\\t\\t * <li>'f' - Filtering input</li>\\n\\t\\t * <li>'t' - The table!</li>\\n\\t\\t * <li>'i' - Information</li>\\n\\t\\t * <li>'p' - Pagination</li>\\n\\t\\t * <li>'r' - pRocessing</li>\\n\\t\\t * </ul>\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aanFeatures\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store data information - see {@link DataTable.models.oRow} for detailed\\n\\t\\t * information.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoData\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of indexes which are in the current display (after filtering etc)\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aiDisplay\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of indexes for display - no filtering\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aiDisplayMaster\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Map of row ids to data indexes\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\t\\\"aIds\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Store information about each column that is in use\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoColumns\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store information about the table's header\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoHeader\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store information about the table's footer\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoFooter\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store the applied global search information in case we want to force a\\n\\t\\t * research or compare the old search to a new one.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @namespace\\n\\t\\t * @extends DataTable.models.oSearch\\n\\t\\t */\\n\\t\\t\\\"oPreviousSearch\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Store the applied search for each column - see\\n\\t\\t * {@link DataTable.models.oSearch} for the format that is used for the\\n\\t\\t * filtering information for each column.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoPreSearchCols\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Sorting that is applied to the table. Note that the inner arrays are\\n\\t\\t * used in the following manner:\\n\\t\\t * <ul>\\n\\t\\t * <li>Index 0 - column number</li>\\n\\t\\t * <li>Index 1 - current sorting direction</li>\\n\\t\\t * </ul>\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @todo These inner arrays should really be objects\\n\\t\\t */\\n\\t\\t\\\"aaSorting\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Sorting that is always applied to the table (i.e. prefixed in front of\\n\\t\\t * aaSorting).\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aaSortingFixed\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Classes to use for the striping of a table.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"asStripeClasses\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * If restoring a table - we should restore its striping classes as well\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"asDestroyStripes\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * If restoring a table - we should restore its width\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"sDestroyWidth\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions array for every time a row is inserted (i.e. on a draw).\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoRowCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions for the header on each draw.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoHeaderCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback function for the footer on each draw.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoFooterCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for draw callback functions\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoDrawCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for row created function\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoRowCreatedCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions for just before the table is redrawn. A return of\\n\\t\\t * false will be used to cancel the draw.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoPreDrawCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions for when the table has been initialised.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoInitComplete\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callbacks for modifying the settings to be stored for state saving, prior to\\n\\t\\t * saving state.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateSaveParams\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callbacks for modifying the settings that have been stored for state saving\\n\\t\\t * prior to using the stored values to restore the state.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateLoadParams\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callbacks for operating on the settings object once the saved state has been\\n\\t\\t * loaded\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateLoaded\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Cache the table ID for quick access\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t */\\n\\t\\t\\\"sTableId\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * The TABLE node for the main table\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTable\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Permanent ref to the thead element\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTHead\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Permanent ref to the tfoot element - if it exists\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTFoot\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Permanent ref to the tbody element\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTBody\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Cache the wrapper node (contains all DataTables controlled elements)\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTableWrapper\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate if when using server-side processing the loading of data\\n\\t\\t * should be deferred until the second draw.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bDeferLoading\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate if all required information has been read in\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bInitialised\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Information about open rows. Each object in the array has the parameters\\n\\t\\t * 'nTr' and 'nParent'\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoOpenRows\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Dictate the positioning of DataTables' control elements - see\\n\\t\\t * {@link DataTable.model.oInit.sDom}.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sDom\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Search delay (in mS)\\n\\t\\t * @type integer\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"searchDelay\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Which type of pagination should be used.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t * @default two_button\\n\\t\\t */\\n\\t\\t\\\"sPaginationType\\\": \\\"two_button\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * The state duration (for `stateSave`) in seconds.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"iStateDuration\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for state saving. Each array element is an\\n\\t\\t * object with the following parameters:\\n\\t\\t * <ul>\\n\\t\\t * <li>function:fn - function to call. Takes two parameters, oSettings\\n\\t\\t * and the JSON string to save that has been thus far created. Returns\\n\\t\\t * a JSON string to be inserted into a json object\\n\\t\\t * (i.e. '\\\"param\\\": [ 0, 1, 2]')</li>\\n\\t\\t * <li>string:sName - name of callback</li>\\n\\t\\t * </ul>\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateSave\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for state loading. Each array element is an\\n\\t\\t * object with the following parameters:\\n\\t\\t * <ul>\\n\\t\\t * <li>function:fn - function to call. Takes two parameters, oSettings\\n\\t\\t * and the object stored. May return false to cancel state loading</li>\\n\\t\\t * <li>string:sName - name of callback</li>\\n\\t\\t * </ul>\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateLoad\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * State that was saved. Useful for back reference\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oSavedState\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * State that was loaded. Useful for back reference\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oLoadedState\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Source url for AJAX data for the table.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sAjaxSource\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Property from a given object from which to read the table data from. This\\n\\t\\t * can be an empty string (when not server-side processing), in which case\\n\\t\\t * it is assumed an an array is given directly.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sAjaxDataProp\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Note if draw should be blocked while getting data\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t */\\n\\t\\t\\\"bAjaxDataGet\\\": true,\\n\\t\\n\\t\\t/**\\n\\t\\t * The last jQuery XHR object that was used for server-side data gathering.\\n\\t\\t * This can be used for working with the XHR information in one of the\\n\\t\\t * callbacks\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"jqXHR\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * JSON returned from the server in the last Ajax request\\n\\t\\t * @type object\\n\\t\\t * @default undefined\\n\\t\\t */\\n\\t\\t\\\"json\\\": undefined,\\n\\t\\n\\t\\t/**\\n\\t\\t * Data submitted as part of the last Ajax request\\n\\t\\t * @type object\\n\\t\\t * @default undefined\\n\\t\\t */\\n\\t\\t\\\"oAjaxData\\\": undefined,\\n\\t\\n\\t\\t/**\\n\\t\\t * Function to get the server-side data.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnServerData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Functions which are called prior to sending an Ajax request so extra\\n\\t\\t * parameters can easily be sent to the server\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoServerParams\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\\n\\t\\t * required).\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sServerMethod\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Format numbers for display.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnFormatNumber\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * List of options that can be used for the user selectable length menu.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aLengthMenu\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Counter for the draws that the table does. Also used as a tracker for\\n\\t\\t * server-side processing\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"iDraw\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate if a redraw is being done - useful for Ajax\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bDrawing\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Draw index (iDraw) of the last error when parsing the returned data\\n\\t\\t * @type int\\n\\t\\t * @default -1\\n\\t\\t */\\n\\t\\t\\\"iDrawError\\\": -1,\\n\\t\\n\\t\\t/**\\n\\t\\t * Paging display length\\n\\t\\t * @type int\\n\\t\\t * @default 10\\n\\t\\t */\\n\\t\\t\\\"_iDisplayLength\\\": 10,\\n\\t\\n\\t\\t/**\\n\\t\\t * Paging start point - aiDisplay index\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"_iDisplayStart\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Server-side processing - number of records in the result set\\n\\t\\t * (i.e. before filtering), Use fnRecordsTotal rather than\\n\\t\\t * this property to get the value of the number of records, regardless of\\n\\t\\t * the server-side processing setting.\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_iRecordsTotal\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Server-side processing - number of records in the current display set\\n\\t\\t * (i.e. after filtering). Use fnRecordsDisplay rather than\\n\\t\\t * this property to get the value of the number of records, regardless of\\n\\t\\t * the server-side processing setting.\\n\\t\\t * @type boolean\\n\\t\\t * @default 0\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_iRecordsDisplay\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * The classes to use for the table\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\t\\\"oClasses\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag attached to the settings object so you can check in the draw\\n\\t\\t * callback if filtering has been done in the draw. Deprecated in favour of\\n\\t\\t * events.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t * @deprecated\\n\\t\\t */\\n\\t\\t\\\"bFiltered\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag attached to the settings object so you can check in the draw\\n\\t\\t * callback if sorting has been done in the draw. Deprecated in favour of\\n\\t\\t * events.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t * @deprecated\\n\\t\\t */\\n\\t\\t\\\"bSorted\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate that if multiple rows are in the header and there is more than\\n\\t\\t * one unique cell per column, if the top one (true) or bottom one (false)\\n\\t\\t * should be used for sorting / title by DataTables.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bSortCellsTop\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Initialisation object that is used for the table\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oInit\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Destroy callback functions - for plug-ins to attach themselves to the\\n\\t\\t * destroy so they can clean up markup and events.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoDestroyCallback\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Get the number of records in the current record set, before filtering\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnRecordsTotal\\\": function ()\\n\\t\\t{\\n\\t\\t\\treturn _fnDataSource( this ) == 'ssp' ?\\n\\t\\t\\t\\tthis._iRecordsTotal * 1 :\\n\\t\\t\\t\\tthis.aiDisplayMaster.length;\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Get the number of records in the current record set, after filtering\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnRecordsDisplay\\\": function ()\\n\\t\\t{\\n\\t\\t\\treturn _fnDataSource( this ) == 'ssp' ?\\n\\t\\t\\t\\tthis._iRecordsDisplay * 1 :\\n\\t\\t\\t\\tthis.aiDisplay.length;\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Get the display end point - aiDisplay index\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnDisplayEnd\\\": function ()\\n\\t\\t{\\n\\t\\t\\tvar\\n\\t\\t\\t\\tlen = this._iDisplayLength,\\n\\t\\t\\t\\tstart = this._iDisplayStart,\\n\\t\\t\\t\\tcalc = start + len,\\n\\t\\t\\t\\trecords = this.aiDisplay.length,\\n\\t\\t\\t\\tfeatures = this.oFeatures,\\n\\t\\t\\t\\tpaginate = features.bPaginate;\\n\\t\\n\\t\\t\\tif ( features.bServerSide ) {\\n\\t\\t\\t\\treturn paginate === false || len === -1 ?\\n\\t\\t\\t\\t\\tstart + records :\\n\\t\\t\\t\\t\\tMath.min( start+len, this._iRecordsDisplay );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\treturn ! paginate || calc>records || len===-1 ?\\n\\t\\t\\t\\t\\trecords :\\n\\t\\t\\t\\t\\tcalc;\\n\\t\\t\\t}\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * The DataTables object for this table\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oInstance\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique identifier for each instance of the DataTables object. If there\\n\\t\\t * is an ID on the table node, then it takes that value, otherwise an\\n\\t\\t * incrementing internal counter is used.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sInstance\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * tabindex attribute value that is added to DataTables control elements, allowing\\n\\t\\t * keyboard navigation of the table and its controls.\\n\\t\\t */\\n\\t\\t\\\"iTabIndex\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * DIV container for the footer scrolling table if scrolling\\n\\t\\t */\\n\\t\\t\\\"nScrollHead\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * DIV container for the footer scrolling table if scrolling\\n\\t\\t */\\n\\t\\t\\\"nScrollFoot\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Last applied sort\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aLastSort\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Stored plug-in instances\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\t\\\"oPlugins\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Function used to get a row's id from the row's data\\n\\t\\t * @type function\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"rowIdFn\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Data location where to store a row's id\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"rowId\\\": null\\n\\t};\\n\\n\\t/**\\n\\t * Extension object for DataTables that is used to provide all extension\\n\\t * options.\\n\\t *\\n\\t * Note that the `DataTable.ext` object is available through\\n\\t * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\\n\\t * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\\n\\t * @namespace\\n\\t * @extends DataTable.models.ext\\n\\t */\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables extensions\\n\\t * \\n\\t * This namespace acts as a collection area for plug-ins that can be used to\\n\\t * extend DataTables capabilities. Indeed many of the build in methods\\n\\t * use this method to provide their own capabilities (sorting methods for\\n\\t * example).\\n\\t *\\n\\t * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\\n\\t * reasons\\n\\t *\\n\\t * @namespace\\n\\t */\\n\\tDataTable.ext = _ext = {\\n\\t\\t/**\\n\\t\\t * Buttons. For use with the Buttons extension for DataTables. This is\\n\\t\\t * defined here so other extensions can define buttons regardless of load\\n\\t\\t * order. It is _not_ used by DataTables core.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\tbuttons: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Element class names\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\tclasses: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables build type (expanded by the download builder)\\n\\t\\t *\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\tbuilder: \\\"-source-\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Error reporting.\\n\\t\\t * \\n\\t\\t * How should DataTables report an error. Can take the value 'alert',\\n\\t\\t * 'throw', 'none' or a function.\\n\\t\\t *\\n\\t\\t * @type string|function\\n\\t\\t * @default alert\\n\\t\\t */\\n\\t\\terrMode: \\\"alert\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Feature plug-ins.\\n\\t\\t * \\n\\t\\t * This is an array of objects which describe the feature plug-ins that are\\n\\t\\t * available to DataTables. These feature plug-ins are then available for\\n\\t\\t * use through the `dom` initialisation option.\\n\\t\\t * \\n\\t\\t * Each feature plug-in is described by an object which must have the\\n\\t\\t * following properties:\\n\\t\\t * \\n\\t\\t * * `fnInit` - function that is used to initialise the plug-in,\\n\\t\\t * * `cFeature` - a character so the feature can be enabled by the `dom`\\n\\t\\t * instillation option. This is case sensitive.\\n\\t\\t *\\n\\t\\t * The `fnInit` function has the following input parameters:\\n\\t\\t *\\n\\t\\t * 1. `{object}` DataTables settings object: see\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t *\\n\\t\\t * And the following return is expected:\\n\\t\\t * \\n\\t\\t * * {node|null} The element which contains your feature. Note that the\\n\\t\\t * return may also be void if your plug-in does not require to inject any\\n\\t\\t * DOM elements into DataTables control (`dom`) - for example this might\\n\\t\\t * be useful when developing a plug-in which allows table control via\\n\\t\\t * keyboard entry\\n\\t\\t *\\n\\t\\t * @type array\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $.fn.dataTable.ext.features.push( {\\n\\t\\t * \\\"fnInit\\\": function( oSettings ) {\\n\\t\\t * return new TableTools( { \\\"oDTSettings\\\": oSettings } );\\n\\t\\t * },\\n\\t\\t * \\\"cFeature\\\": \\\"T\\\"\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tfeature: [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Row searching.\\n\\t\\t * \\n\\t\\t * This method of searching is complimentary to the default type based\\n\\t\\t * searching, and a lot more comprehensive as it allows you complete control\\n\\t\\t * over the searching logic. Each element in this array is a function\\n\\t\\t * (parameters described below) that is called for every row in the table,\\n\\t\\t * and your logic decides if it should be included in the searching data set\\n\\t\\t * or not.\\n\\t\\t *\\n\\t\\t * Searching functions have the following input parameters:\\n\\t\\t *\\n\\t\\t * 1. `{object}` DataTables settings object: see\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t * 2. `{array|object}` Data for the row to be processed (same as the\\n\\t\\t * original format that was passed in as the data source, or an array\\n\\t\\t * from a DOM data source\\n\\t\\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\\n\\t\\t * can be useful to retrieve the `TR` element if you need DOM interaction.\\n\\t\\t *\\n\\t\\t * And the following return is expected:\\n\\t\\t *\\n\\t\\t * * {boolean} Include the row in the searched result set (true) or not\\n\\t\\t * (false)\\n\\t\\t *\\n\\t\\t * Note that as with the main search ability in DataTables, technically this\\n\\t\\t * is \\\"filtering\\\", since it is subtractive. However, for consistency in\\n\\t\\t * naming we call it searching here.\\n\\t\\t *\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // The following example shows custom search being applied to the\\n\\t\\t * // fourth column (i.e. the data[3] index) based on two input values\\n\\t\\t * // from the end-user, matching the data in a certain range.\\n\\t\\t * $.fn.dataTable.ext.search.push(\\n\\t\\t * function( settings, data, dataIndex ) {\\n\\t\\t * var min = document.getElementById('min').value * 1;\\n\\t\\t * var max = document.getElementById('max').value * 1;\\n\\t\\t * var version = data[3] == \\\"-\\\" ? 0 : data[3]*1;\\n\\t\\t *\\n\\t\\t * if ( min == \\\"\\\" && max == \\\"\\\" ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * else if ( min == \\\"\\\" && version < max ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * else if ( min < version && \\\"\\\" == max ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * else if ( min < version && version < max ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * return false;\\n\\t\\t * }\\n\\t\\t * );\\n\\t\\t */\\n\\t\\tsearch: [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Selector extensions\\n\\t\\t *\\n\\t\\t * The `selector` option can be used to extend the options available for the\\n\\t\\t * selector modifier options (`selector-modifier` object data type) that\\n\\t\\t * each of the three built in selector types offer (row, column and cell +\\n\\t\\t * their plural counterparts). For example the Select extension uses this\\n\\t\\t * mechanism to provide an option to select only rows, columns and cells\\n\\t\\t * that have been marked as selected by the end user (`{selected: true}`),\\n\\t\\t * which can be used in conjunction with the existing built in selector\\n\\t\\t * options.\\n\\t\\t *\\n\\t\\t * Each property is an array to which functions can be pushed. The functions\\n\\t\\t * take three attributes:\\n\\t\\t *\\n\\t\\t * * Settings object for the host table\\n\\t\\t * * Options object (`selector-modifier` object type)\\n\\t\\t * * Array of selected item indexes\\n\\t\\t *\\n\\t\\t * The return is an array of the resulting item indexes after the custom\\n\\t\\t * selector has been applied.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t */\\n\\t\\tselector: {\\n\\t\\t\\tcell: [],\\n\\t\\t\\tcolumn: [],\\n\\t\\t\\trow: []\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Internal functions, exposed for used in plug-ins.\\n\\t\\t * \\n\\t\\t * Please note that you should not need to use the internal methods for\\n\\t\\t * anything other than a plug-in (and even then, try to avoid if possible).\\n\\t\\t * The internal function may change between releases.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\tinternal: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Legacy configuration options. Enable and disable legacy options that\\n\\t\\t * are available in DataTables.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t */\\n\\t\\tlegacy: {\\n\\t\\t\\t/**\\n\\t\\t\\t * Enable / disable DataTables 1.9 compatible server-side processing\\n\\t\\t\\t * requests\\n\\t\\t\\t *\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default null\\n\\t\\t\\t */\\n\\t\\t\\tajax: null\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Pagination plug-in methods.\\n\\t\\t * \\n\\t\\t * Each entry in this object is a function and defines which buttons should\\n\\t\\t * be shown by the pagination rendering method that is used for the table:\\n\\t\\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\\n\\t\\t * buttons are displayed in the document, while the functions here tell it\\n\\t\\t * what buttons to display. This is done by returning an array of button\\n\\t\\t * descriptions (what each button will do).\\n\\t\\t *\\n\\t\\t * Pagination types (the four built in options and any additional plug-in\\n\\t\\t * options defined here) can be used through the `paginationType`\\n\\t\\t * initialisation parameter.\\n\\t\\t *\\n\\t\\t * The functions defined take two parameters:\\n\\t\\t *\\n\\t\\t * 1. `{int} page` The current page index\\n\\t\\t * 2. `{int} pages` The number of pages in the table\\n\\t\\t *\\n\\t\\t * Each function is expected to return an array where each element of the\\n\\t\\t * array can be one of:\\n\\t\\t *\\n\\t\\t * * `first` - Jump to first page when activated\\n\\t\\t * * `last` - Jump to last page when activated\\n\\t\\t * * `previous` - Show previous page when activated\\n\\t\\t * * `next` - Show next page when activated\\n\\t\\t * * `{int}` - Show page of the index given\\n\\t\\t * * `{array}` - A nested array containing the above elements to add a\\n\\t\\t * containing 'DIV' element (might be useful for styling).\\n\\t\\t *\\n\\t\\t * Note that DataTables v1.9- used this object slightly differently whereby\\n\\t\\t * an object with two functions would be defined for each plug-in. That\\n\\t\\t * ability is still supported by DataTables 1.10+ to provide backwards\\n\\t\\t * compatibility, but this option of use is now decremented and no longer\\n\\t\\t * documented in DataTables 1.10+.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Show previous, next and current page buttons only\\n\\t\\t * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\\n\\t\\t * return [ 'previous', page, 'next' ];\\n\\t\\t * };\\n\\t\\t */\\n\\t\\tpager: {},\\n\\t\\n\\t\\n\\t\\trenderer: {\\n\\t\\t\\tpageButton: {},\\n\\t\\t\\theader: {}\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Ordering plug-ins - custom data source\\n\\t\\t * \\n\\t\\t * The extension options for ordering of data available here is complimentary\\n\\t\\t * to the default type based ordering that DataTables typically uses. It\\n\\t\\t * allows much greater control over the the data that is being used to\\n\\t\\t * order a column, but is necessarily therefore more complex.\\n\\t\\t * \\n\\t\\t * This type of ordering is useful if you want to do ordering based on data\\n\\t\\t * live from the DOM (for example the contents of an 'input' element) rather\\n\\t\\t * than just the static string that DataTables knows of.\\n\\t\\t * \\n\\t\\t * The way these plug-ins work is that you create an array of the values you\\n\\t\\t * wish to be ordering for the column in question and then return that\\n\\t\\t * array. The data in the array much be in the index order of the rows in\\n\\t\\t * the table (not the currently ordering order!). Which order data gathering\\n\\t\\t * function is run here depends on the `dt-init columns.orderDataType`\\n\\t\\t * parameter that is used for the column (if any).\\n\\t\\t *\\n\\t\\t * The functions defined take two parameters:\\n\\t\\t *\\n\\t\\t * 1. `{object}` DataTables settings object: see\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t * 2. `{int}` Target column index\\n\\t\\t *\\n\\t\\t * Each function is expected to return an array:\\n\\t\\t *\\n\\t\\t * * `{array}` Data for the column to be ordering upon\\n\\t\\t *\\n\\t\\t * @type array\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Ordering using `input` node values\\n\\t\\t * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )\\n\\t\\t * {\\n\\t\\t * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\\n\\t\\t * return $('input', td).val();\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t */\\n\\t\\torder: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Type based plug-ins.\\n\\t\\t *\\n\\t\\t * Each column in DataTables has a type assigned to it, either by automatic\\n\\t\\t * detection or by direct assignment using the `type` option for the column.\\n\\t\\t * The type of a column will effect how it is ordering and search (plug-ins\\n\\t\\t * can also make use of the column type if required).\\n\\t\\t *\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\ttype: {\\n\\t\\t\\t/**\\n\\t\\t\\t * Type detection functions.\\n\\t\\t\\t *\\n\\t\\t\\t * The functions defined in this object are used to automatically detect\\n\\t\\t\\t * a column's type, making initialisation of DataTables super easy, even\\n\\t\\t\\t * when complex data is in the table.\\n\\t\\t\\t *\\n\\t\\t\\t * The functions defined take two parameters:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data from the column cell to be analysed\\n\\t\\t * 2. `{settings}` DataTables settings object. This can be used to\\n\\t\\t * perform context specific type detection - for example detection\\n\\t\\t * based on language settings such as using a comma for a decimal\\n\\t\\t * place. Generally speaking the options from the settings will not\\n\\t\\t * be required\\n\\t\\t\\t *\\n\\t\\t\\t * Each function is expected to return:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{string|null}` Data type detected, or null if unknown (and thus\\n\\t\\t\\t * pass it on to the other type detection functions.\\n\\t\\t\\t *\\n\\t\\t\\t * @type array\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Currency type detection plug-in:\\n\\t\\t\\t * $.fn.dataTable.ext.type.detect.push(\\n\\t\\t\\t * function ( data, settings ) {\\n\\t\\t\\t * // Check the numeric part\\n\\t\\t\\t * if ( ! $.isNumeric( data.substring(1) ) ) {\\n\\t\\t\\t * return null;\\n\\t\\t\\t * }\\n\\t\\t\\t *\\n\\t\\t\\t * // Check prefixed by currency\\n\\t\\t\\t * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {\\n\\t\\t\\t * return 'currency';\\n\\t\\t\\t * }\\n\\t\\t\\t * return null;\\n\\t\\t\\t * }\\n\\t\\t\\t * );\\n\\t\\t\\t */\\n\\t\\t\\tdetect: [],\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Type based search formatting.\\n\\t\\t\\t *\\n\\t\\t\\t * The type based searching functions can be used to pre-format the\\n\\t\\t\\t * data to be search on. For example, it can be used to strip HTML\\n\\t\\t\\t * tags or to de-format telephone numbers for numeric only searching.\\n\\t\\t\\t *\\n\\t\\t\\t * Note that is a search is not defined for a column of a given type,\\n\\t\\t\\t * no search formatting will be performed.\\n\\t\\t\\t * \\n\\t\\t\\t * Pre-processing of searching data plug-ins - When you assign the sType\\n\\t\\t\\t * for a column (or have it automatically detected for you by DataTables\\n\\t\\t\\t * or a type detection plug-in), you will typically be using this for\\n\\t\\t\\t * custom sorting, but it can also be used to provide custom searching\\n\\t\\t\\t * by allowing you to pre-processing the data and returning the data in\\n\\t\\t\\t * the format that should be searched upon. This is done by adding\\n\\t\\t\\t * functions this object with a parameter name which matches the sType\\n\\t\\t\\t * for that target column. This is the corollary of <i>afnSortData</i>\\n\\t\\t\\t * for searching data.\\n\\t\\t\\t *\\n\\t\\t\\t * The functions defined take a single parameter:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data from the column cell to be prepared for searching\\n\\t\\t\\t *\\n\\t\\t\\t * Each function is expected to return:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{string|null}` Formatted string that will be used for the searching.\\n\\t\\t\\t *\\n\\t\\t\\t * @type object\\n\\t\\t\\t * @default {}\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\\n\\t\\t\\t * return d.replace(/\\\\n/g,\\\" \\\").replace( /<.*?>/g, \\\"\\\" );\\n\\t\\t\\t * }\\n\\t\\t\\t */\\n\\t\\t\\tsearch: {},\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Type based ordering.\\n\\t\\t\\t *\\n\\t\\t\\t * The column type tells DataTables what ordering to apply to the table\\n\\t\\t\\t * when a column is sorted upon. The order for each type that is defined,\\n\\t\\t\\t * is defined by the functions available in this object.\\n\\t\\t\\t *\\n\\t\\t\\t * Each ordering option can be described by three properties added to\\n\\t\\t\\t * this object:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{type}-pre` - Pre-formatting function\\n\\t\\t\\t * * `{type}-asc` - Ascending order function\\n\\t\\t\\t * * `{type}-desc` - Descending order function\\n\\t\\t\\t *\\n\\t\\t\\t * All three can be used together, only `{type}-pre` or only\\n\\t\\t\\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\\n\\t\\t\\t * that only `{type}-pre` is used, as this provides the optimal\\n\\t\\t\\t * implementation in terms of speed, although the others are provided\\n\\t\\t\\t * for compatibility with existing Javascript sort functions.\\n\\t\\t\\t *\\n\\t\\t\\t * `{type}-pre`: Functions defined take a single parameter:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data from the column cell to be prepared for ordering\\n\\t\\t\\t *\\n\\t\\t\\t * And return:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{*}` Data to be sorted upon\\n\\t\\t\\t *\\n\\t\\t\\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\\n\\t\\t\\t * functions, taking two parameters:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data to compare to the second parameter\\n\\t\\t * 2. `{*}` Data to compare to the first parameter\\n\\t\\t\\t *\\n\\t\\t\\t * And returning:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\\n\\t\\t\\t * than the second parameter, ===0 if the two parameters are equal and\\n\\t\\t\\t * >0 if the first parameter should be sorted height than the second\\n\\t\\t\\t * parameter.\\n\\t\\t\\t * \\n\\t\\t\\t * @type object\\n\\t\\t\\t * @default {}\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Numeric ordering of formatted numbers with a pre-formatter\\n\\t\\t\\t * $.extend( $.fn.dataTable.ext.type.order, {\\n\\t\\t\\t * \\\"string-pre\\\": function(x) {\\n\\t\\t\\t * a = (a === \\\"-\\\" || a === \\\"\\\") ? 0 : a.replace( /[^\\\\d\\\\-\\\\.]/g, \\\"\\\" );\\n\\t\\t\\t * return parseFloat( a );\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Case-sensitive string ordering, with no pre-formatting method\\n\\t\\t\\t * $.extend( $.fn.dataTable.ext.order, {\\n\\t\\t\\t * \\\"string-case-asc\\\": function(x,y) {\\n\\t\\t\\t * return ((x < y) ? -1 : ((x > y) ? 1 : 0));\\n\\t\\t\\t * },\\n\\t\\t\\t * \\\"string-case-desc\\\": function(x,y) {\\n\\t\\t\\t * return ((x < y) ? 1 : ((x > y) ? -1 : 0));\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\torder: {}\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique DataTables instance counter\\n\\t\\t *\\n\\t\\t * @type int\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t_unique: 0,\\n\\t\\n\\t\\n\\t\\t//\\n\\t\\t// Depreciated\\n\\t\\t// The following properties are retained for backwards compatiblity only.\\n\\t\\t// The should not be used in new projects and will be removed in a future\\n\\t\\t// version\\n\\t\\t//\\n\\t\\n\\t\\t/**\\n\\t\\t * Version check function.\\n\\t\\t * @type function\\n\\t\\t * @depreciated Since 1.10\\n\\t\\t */\\n\\t\\tfnVersionCheck: DataTable.fnVersionCheck,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Index for what 'this' index API functions should use\\n\\t\\t * @type int\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t */\\n\\t\\tiApiIndex: 0,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * jQuery UI class container\\n\\t\\t * @type object\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t */\\n\\t\\toJUIClasses: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Software version\\n\\t\\t * @type string\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t */\\n\\t\\tsVersion: DataTable.version\\n\\t};\\n\\t\\n\\t\\n\\t//\\n\\t// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\\n\\t//\\n\\t$.extend( _ext, {\\n\\t\\tafnFiltering: _ext.search,\\n\\t\\taTypes: _ext.type.detect,\\n\\t\\tofnSearch: _ext.type.search,\\n\\t\\toSort: _ext.type.order,\\n\\t\\tafnSortData: _ext.order,\\n\\t\\taoFeatures: _ext.feature,\\n\\t\\toApi: _ext.internal,\\n\\t\\toStdClasses: _ext.classes,\\n\\t\\toPagination: _ext.pager\\n\\t} );\\n\\t\\n\\t\\n\\t$.extend( DataTable.ext.classes, {\\n\\t\\t\\\"sTable\\\": \\\"dataTable\\\",\\n\\t\\t\\\"sNoFooter\\\": \\\"no-footer\\\",\\n\\t\\n\\t\\t/* Paging buttons */\\n\\t\\t\\\"sPageButton\\\": \\\"paginate_button\\\",\\n\\t\\t\\\"sPageButtonActive\\\": \\\"current\\\",\\n\\t\\t\\\"sPageButtonDisabled\\\": \\\"disabled\\\",\\n\\t\\n\\t\\t/* Striping classes */\\n\\t\\t\\\"sStripeOdd\\\": \\\"odd\\\",\\n\\t\\t\\\"sStripeEven\\\": \\\"even\\\",\\n\\t\\n\\t\\t/* Empty row */\\n\\t\\t\\\"sRowEmpty\\\": \\\"dataTables_empty\\\",\\n\\t\\n\\t\\t/* Features */\\n\\t\\t\\\"sWrapper\\\": \\\"dataTables_wrapper\\\",\\n\\t\\t\\\"sFilter\\\": \\\"dataTables_filter\\\",\\n\\t\\t\\\"sInfo\\\": \\\"dataTables_info\\\",\\n\\t\\t\\\"sPaging\\\": \\\"dataTables_paginate paging_\\\", /* Note that the type is postfixed */\\n\\t\\t\\\"sLength\\\": \\\"dataTables_length\\\",\\n\\t\\t\\\"sProcessing\\\": \\\"dataTables_processing\\\",\\n\\t\\n\\t\\t/* Sorting */\\n\\t\\t\\\"sSortAsc\\\": \\\"sorting_asc\\\",\\n\\t\\t\\\"sSortDesc\\\": \\\"sorting_desc\\\",\\n\\t\\t\\\"sSortable\\\": \\\"sorting\\\", /* Sortable in both directions */\\n\\t\\t\\\"sSortableAsc\\\": \\\"sorting_asc_disabled\\\",\\n\\t\\t\\\"sSortableDesc\\\": \\\"sorting_desc_disabled\\\",\\n\\t\\t\\\"sSortableNone\\\": \\\"sorting_disabled\\\",\\n\\t\\t\\\"sSortColumn\\\": \\\"sorting_\\\", /* Note that an int is postfixed for the sorting order */\\n\\t\\n\\t\\t/* Filtering */\\n\\t\\t\\\"sFilterInput\\\": \\\"\\\",\\n\\t\\n\\t\\t/* Page length */\\n\\t\\t\\\"sLengthSelect\\\": \\\"\\\",\\n\\t\\n\\t\\t/* Scrolling */\\n\\t\\t\\\"sScrollWrapper\\\": \\\"dataTables_scroll\\\",\\n\\t\\t\\\"sScrollHead\\\": \\\"dataTables_scrollHead\\\",\\n\\t\\t\\\"sScrollHeadInner\\\": \\\"dataTables_scrollHeadInner\\\",\\n\\t\\t\\\"sScrollBody\\\": \\\"dataTables_scrollBody\\\",\\n\\t\\t\\\"sScrollFoot\\\": \\\"dataTables_scrollFoot\\\",\\n\\t\\t\\\"sScrollFootInner\\\": \\\"dataTables_scrollFootInner\\\",\\n\\t\\n\\t\\t/* Misc */\\n\\t\\t\\\"sHeaderTH\\\": \\\"\\\",\\n\\t\\t\\\"sFooterTH\\\": \\\"\\\",\\n\\t\\n\\t\\t// Deprecated\\n\\t\\t\\\"sSortJUIAsc\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIDesc\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUI\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIAscAllowed\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIDescAllowed\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIWrapper\\\": \\\"\\\",\\n\\t\\t\\\"sSortIcon\\\": \\\"\\\",\\n\\t\\t\\\"sJUIHeader\\\": \\\"\\\",\\n\\t\\t\\\"sJUIFooter\\\": \\\"\\\"\\n\\t} );\\n\\t\\n\\t\\n\\tvar extPagination = DataTable.ext.pager;\\n\\t\\n\\tfunction _numbers ( page, pages ) {\\n\\t\\tvar\\n\\t\\t\\tnumbers = [],\\n\\t\\t\\tbuttons = extPagination.numbers_length,\\n\\t\\t\\thalf = Math.floor( buttons / 2 ),\\n\\t\\t\\ti = 1;\\n\\t\\n\\t\\tif ( pages <= buttons ) {\\n\\t\\t\\tnumbers = _range( 0, pages );\\n\\t\\t}\\n\\t\\telse if ( page <= half ) {\\n\\t\\t\\tnumbers = _range( 0, buttons-2 );\\n\\t\\t\\tnumbers.push( 'ellipsis' );\\n\\t\\t\\tnumbers.push( pages-1 );\\n\\t\\t}\\n\\t\\telse if ( page >= pages - 1 - half ) {\\n\\t\\t\\tnumbers = _range( pages-(buttons-2), pages );\\n\\t\\t\\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\\n\\t\\t\\tnumbers.splice( 0, 0, 0 );\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tnumbers = _range( page-half+2, page+half-1 );\\n\\t\\t\\tnumbers.push( 'ellipsis' );\\n\\t\\t\\tnumbers.push( pages-1 );\\n\\t\\t\\tnumbers.splice( 0, 0, 'ellipsis' );\\n\\t\\t\\tnumbers.splice( 0, 0, 0 );\\n\\t\\t}\\n\\t\\n\\t\\tnumbers.DT_el = 'span';\\n\\t\\treturn numbers;\\n\\t}\\n\\t\\n\\t\\n\\t$.extend( extPagination, {\\n\\t\\tsimple: function ( page, pages ) {\\n\\t\\t\\treturn [ 'previous', 'next' ];\\n\\t\\t},\\n\\t\\n\\t\\tfull: function ( page, pages ) {\\n\\t\\t\\treturn [ 'first', 'previous', 'next', 'last' ];\\n\\t\\t},\\n\\t\\n\\t\\tnumbers: function ( page, pages ) {\\n\\t\\t\\treturn [ _numbers(page, pages) ];\\n\\t\\t},\\n\\t\\n\\t\\tsimple_numbers: function ( page, pages ) {\\n\\t\\t\\treturn [ 'previous', _numbers(page, pages), 'next' ];\\n\\t\\t},\\n\\t\\n\\t\\tfull_numbers: function ( page, pages ) {\\n\\t\\t\\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\\n\\t\\t},\\n\\t\\t\\n\\t\\tfirst_last_numbers: function (page, pages) {\\n\\t \\t\\treturn ['first', _numbers(page, pages), 'last'];\\n\\t \\t},\\n\\t\\n\\t\\t// For testing and plug-ins to use\\n\\t\\t_numbers: _numbers,\\n\\t\\n\\t\\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\\n\\t\\tnumbers_length: 7\\n\\t} );\\n\\t\\n\\t\\n\\t$.extend( true, DataTable.ext.renderer, {\\n\\t\\tpageButton: {\\n\\t\\t\\t_: function ( settings, host, idx, buttons, page, pages ) {\\n\\t\\t\\t\\tvar classes = settings.oClasses;\\n\\t\\t\\t\\tvar lang = settings.oLanguage.oPaginate;\\n\\t\\t\\t\\tvar aria = settings.oLanguage.oAria.paginate || {};\\n\\t\\t\\t\\tvar btnDisplay, btnClass, counter=0;\\n\\t\\n\\t\\t\\t\\tvar attach = function( container, buttons ) {\\n\\t\\t\\t\\t\\tvar i, ien, node, button;\\n\\t\\t\\t\\t\\tvar clickHandler = function ( e ) {\\n\\t\\t\\t\\t\\t\\t_fnPageChange( settings, e.data.action, true );\\n\\t\\t\\t\\t\\t};\\n\\t\\n\\t\\t\\t\\t\\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t\\tbutton = buttons[i];\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( $.isArray( button ) ) {\\n\\t\\t\\t\\t\\t\\t\\tvar inner = $( '<'+(button.DT_el || 'div')+'/>' )\\n\\t\\t\\t\\t\\t\\t\\t\\t.appendTo( container );\\n\\t\\t\\t\\t\\t\\t\\tattach( inner, button );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\t\\tbtnDisplay = null;\\n\\t\\t\\t\\t\\t\\t\\tbtnClass = '';\\n\\t\\n\\t\\t\\t\\t\\t\\t\\tswitch ( button ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'ellipsis':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tcontainer.append('<span class=\\\"ellipsis\\\">…</span>');\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'first':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sFirst;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page > 0 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'previous':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sPrevious;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page > 0 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'next':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sNext;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page < pages-1 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'last':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sLast;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page < pages-1 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tdefault:\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = button + 1;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = page === button ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tclasses.sPageButtonActive : '';\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t\\tif ( btnDisplay !== null ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tnode = $('<a>', {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'class': classes.sPageButton+' '+btnClass,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'aria-controls': settings.sTableId,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'aria-label': aria[ button ],\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'data-dt-idx': counter,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'tabindex': settings.iTabIndex,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'id': idx === 0 && typeof button === 'string' ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tsettings.sTableId +'_'+ button :\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tnull\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.html( btnDisplay )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.appendTo( container );\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\t_fnBindAction(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tnode, {action: button}, clickHandler\\n\\t\\t\\t\\t\\t\\t\\t\\t);\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcounter++;\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t};\\n\\t\\n\\t\\t\\t\\t// IE9 throws an 'unknown error' if document.activeElement is used\\n\\t\\t\\t\\t// inside an iframe or frame. Try / catch the error. Not good for\\n\\t\\t\\t\\t// accessibility, but neither are frames.\\n\\t\\t\\t\\tvar activeEl;\\n\\t\\n\\t\\t\\t\\ttry {\\n\\t\\t\\t\\t\\t// Because this approach is destroying and recreating the paging\\n\\t\\t\\t\\t\\t// elements, focus is lost on the select button which is bad for\\n\\t\\t\\t\\t\\t// accessibility. So we want to restore focus once the draw has\\n\\t\\t\\t\\t\\t// completed\\n\\t\\t\\t\\t\\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tcatch (e) {}\\n\\t\\n\\t\\t\\t\\tattach( $(host).empty(), buttons );\\n\\t\\n\\t\\t\\t\\tif ( activeEl !== undefined ) {\\n\\t\\t\\t\\t\\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t// Built in type detection. See model.ext.aTypes for information about\\n\\t// what is required from this methods.\\n\\t$.extend( DataTable.ext.type.detect, [\\n\\t\\t// Plain numbers - first since V8 detects some plain numbers as dates\\n\\t\\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// Dates (only those recognised by the browser's Date.parse)\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\t// V8 tries _very_ hard to make a string passed into `Date.parse()`\\n\\t\\t\\t// valid, so we need to use a regex to restrict date formats. Use a\\n\\t\\t\\t// plug-in for anything other than ISO8601 style strings\\n\\t\\t\\tif ( d && !(d instanceof Date) && ! _re_date.test(d) ) {\\n\\t\\t\\t\\treturn null;\\n\\t\\t\\t}\\n\\t\\t\\tvar parsed = Date.parse(d);\\n\\t\\t\\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\\n\\t\\t},\\n\\t\\n\\t\\t// Formatted numbers\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// HTML numeric\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// HTML numeric, formatted\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// HTML (this is strict checking - there must be html)\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\\n\\t\\t\\t\\t'html' : null;\\n\\t\\t}\\n\\t] );\\n\\t\\n\\t\\n\\t\\n\\t// Filter formatting functions. See model.ext.ofnSearch for information about\\n\\t// what is required from these methods.\\n\\t// \\n\\t// Note that additional search methods are added for the html numbers and\\n\\t// html formatted numbers by `_addNumericSort()` when we know what the decimal\\n\\t// place is\\n\\t\\n\\t\\n\\t$.extend( DataTable.ext.type.search, {\\n\\t\\thtml: function ( data ) {\\n\\t\\t\\treturn _empty(data) ?\\n\\t\\t\\t\\tdata :\\n\\t\\t\\t\\ttypeof data === 'string' ?\\n\\t\\t\\t\\t\\tdata\\n\\t\\t\\t\\t\\t\\t.replace( _re_new_lines, \\\" \\\" )\\n\\t\\t\\t\\t\\t\\t.replace( _re_html, \\\"\\\" ) :\\n\\t\\t\\t\\t\\t'';\\n\\t\\t},\\n\\t\\n\\t\\tstring: function ( data ) {\\n\\t\\t\\treturn _empty(data) ?\\n\\t\\t\\t\\tdata :\\n\\t\\t\\t\\ttypeof data === 'string' ?\\n\\t\\t\\t\\t\\tdata.replace( _re_new_lines, \\\" \\\" ) :\\n\\t\\t\\t\\t\\tdata;\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\\n\\t\\tif ( d !== 0 && (!d || d === '-') ) {\\n\\t\\t\\treturn -Infinity;\\n\\t\\t}\\n\\t\\n\\t\\t// If a decimal place other than `.` is used, it needs to be given to the\\n\\t\\t// function so we can detect it and replace with a `.` which is the only\\n\\t\\t// decimal place Javascript recognises - it is not locale aware.\\n\\t\\tif ( decimalPlace ) {\\n\\t\\t\\td = _numToDecimal( d, decimalPlace );\\n\\t\\t}\\n\\t\\n\\t\\tif ( d.replace ) {\\n\\t\\t\\tif ( re1 ) {\\n\\t\\t\\t\\td = d.replace( re1, '' );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( re2 ) {\\n\\t\\t\\t\\td = d.replace( re2, '' );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn d * 1;\\n\\t};\\n\\t\\n\\t\\n\\t// Add the numeric 'deformatting' functions for sorting and search. This is done\\n\\t// in a function to provide an easy ability for the language options to add\\n\\t// additional methods if a non-period decimal place is used.\\n\\tfunction _addNumericSort ( decimalPlace ) {\\n\\t\\t$.each(\\n\\t\\t\\t{\\n\\t\\t\\t\\t// Plain numbers\\n\\t\\t\\t\\t\\\"num\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace );\\n\\t\\t\\t\\t},\\n\\t\\n\\t\\t\\t\\t// Formatted numbers\\n\\t\\t\\t\\t\\\"num-fmt\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\\n\\t\\t\\t\\t},\\n\\t\\n\\t\\t\\t\\t// HTML numeric\\n\\t\\t\\t\\t\\\"html-num\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace, _re_html );\\n\\t\\t\\t\\t},\\n\\t\\n\\t\\t\\t\\t// HTML numeric, formatted\\n\\t\\t\\t\\t\\\"html-num-fmt\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\\n\\t\\t\\t\\t}\\n\\t\\t\\t},\\n\\t\\t\\tfunction ( key, fn ) {\\n\\t\\t\\t\\t// Add the ordering method\\n\\t\\t\\t\\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\\n\\t\\n\\t\\t\\t\\t// For HTML types add a search formatter that will strip the HTML\\n\\t\\t\\t\\tif ( key.match(/^html\\\\-/) ) {\\n\\t\\t\\t\\t\\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t);\\n\\t}\\n\\t\\n\\t\\n\\t// Default sort methods\\n\\t$.extend( _ext.type.order, {\\n\\t\\t// Dates\\n\\t\\t\\\"date-pre\\\": function ( d ) {\\n\\t\\t\\treturn Date.parse( d ) || -Infinity;\\n\\t\\t},\\n\\t\\n\\t\\t// html\\n\\t\\t\\\"html-pre\\\": function ( a ) {\\n\\t\\t\\treturn _empty(a) ?\\n\\t\\t\\t\\t'' :\\n\\t\\t\\t\\ta.replace ?\\n\\t\\t\\t\\t\\ta.replace( /<.*?>/g, \\\"\\\" ).toLowerCase() :\\n\\t\\t\\t\\t\\ta+'';\\n\\t\\t},\\n\\t\\n\\t\\t// string\\n\\t\\t\\\"string-pre\\\": function ( a ) {\\n\\t\\t\\t// This is a little complex, but faster than always calling toString,\\n\\t\\t\\t// http://jsperf.com/tostring-v-check\\n\\t\\t\\treturn _empty(a) ?\\n\\t\\t\\t\\t'' :\\n\\t\\t\\t\\ttypeof a === 'string' ?\\n\\t\\t\\t\\t\\ta.toLowerCase() :\\n\\t\\t\\t\\t\\t! a.toString ?\\n\\t\\t\\t\\t\\t\\t'' :\\n\\t\\t\\t\\t\\t\\ta.toString();\\n\\t\\t},\\n\\t\\n\\t\\t// string-asc and -desc are retained only for compatibility with the old\\n\\t\\t// sort methods\\n\\t\\t\\\"string-asc\\\": function ( x, y ) {\\n\\t\\t\\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\\n\\t\\t},\\n\\t\\n\\t\\t\\\"string-desc\\\": function ( x, y ) {\\n\\t\\t\\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t\\n\\t// Numeric sorting types - order doesn't matter here\\n\\t_addNumericSort( '' );\\n\\t\\n\\t\\n\\t$.extend( true, DataTable.ext.renderer, {\\n\\t\\theader: {\\n\\t\\t\\t_: function ( settings, cell, column, classes ) {\\n\\t\\t\\t\\t// No additional mark-up required\\n\\t\\t\\t\\t// Attach a sort listener to update on sort - note that using the\\n\\t\\t\\t\\t// `DT` namespace will allow the event to be removed automatically\\n\\t\\t\\t\\t// on destroy, while the `dt` namespaced event is the one we are\\n\\t\\t\\t\\t// listening for\\n\\t\\t\\t\\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\\n\\t\\t\\t\\t\\tif ( settings !== ctx ) { // need to check this this is the host\\n\\t\\t\\t\\t\\t\\treturn; // table, not a nested one\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tvar colIdx = column.idx;\\n\\t\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.removeClass(\\n\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClass +' '+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortAsc +' '+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortDesc\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t.addClass( columns[ colIdx ] == 'asc' ?\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\\n\\t\\t\\t\\t\\t\\t\\t\\tclasses.sSortDesc :\\n\\t\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClass\\n\\t\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t} );\\n\\t\\t\\t},\\n\\t\\n\\t\\t\\tjqueryui: function ( settings, cell, column, classes ) {\\n\\t\\t\\t\\t$('<div/>')\\n\\t\\t\\t\\t\\t.addClass( classes.sSortJUIWrapper )\\n\\t\\t\\t\\t\\t.append( cell.contents() )\\n\\t\\t\\t\\t\\t.append( $('<span/>')\\n\\t\\t\\t\\t\\t\\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t.appendTo( cell );\\n\\t\\n\\t\\t\\t\\t// Attach a sort listener to update on sort\\n\\t\\t\\t\\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\\n\\t\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tvar colIdx = column.idx;\\n\\t\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.removeClass( classes.sSortAsc +\\\" \\\"+classes.sSortDesc )\\n\\t\\t\\t\\t\\t\\t.addClass( columns[ colIdx ] == 'asc' ?\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\\n\\t\\t\\t\\t\\t\\t\\t\\tclasses.sSortDesc :\\n\\t\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClass\\n\\t\\t\\t\\t\\t\\t);\\n\\t\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.find( 'span.'+classes.sSortIcon )\\n\\t\\t\\t\\t\\t\\t.removeClass(\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIAsc +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIDesc +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUI +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIAscAllowed +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIDescAllowed\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t.addClass( columns[ colIdx ] == 'asc' ?\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\\n\\t\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIDesc :\\n\\t\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClassJUI\\n\\t\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t/*\\n\\t * Public helper functions. These aren't used internally by DataTables, or\\n\\t * called by any of the options passed into DataTables, but they can be used\\n\\t * externally by developers working with DataTables. They are helper functions\\n\\t * to make working with DataTables a little bit easier.\\n\\t */\\n\\t\\n\\tvar __htmlEscapeEntities = function ( d ) {\\n\\t\\treturn typeof d === 'string' ?\\n\\t\\t\\td.replace(/</g, '<').replace(/>/g, '>').replace(/\\\"/g, '"') :\\n\\t\\t\\td;\\n\\t};\\n\\t\\n\\t/**\\n\\t * Helpers for `columns.render`.\\n\\t *\\n\\t * The options defined here can be used with the `columns.render` initialisation\\n\\t * option to provide a display renderer. The following functions are defined:\\n\\t *\\n\\t * * `number` - Will format numeric data (defined by `columns.data`) for\\n\\t * display, retaining the original unformatted data for sorting and filtering.\\n\\t * It takes 5 parameters:\\n\\t * * `string` - Thousands grouping separator\\n\\t * * `string` - Decimal point indicator\\n\\t * * `integer` - Number of decimal points to show\\n\\t * * `string` (optional) - Prefix.\\n\\t * * `string` (optional) - Postfix (/suffix).\\n\\t * * `text` - Escape HTML to help prevent XSS attacks. It has no optional\\n\\t * parameters.\\n\\t *\\n\\t * @example\\n\\t * // Column definition using the number renderer\\n\\t * {\\n\\t * data: \\\"salary\\\",\\n\\t * render: $.fn.dataTable.render.number( '\\\\'', '.', 0, '$' )\\n\\t * }\\n\\t *\\n\\t * @namespace\\n\\t */\\n\\tDataTable.render = {\\n\\t\\tnumber: function ( thousands, decimal, precision, prefix, postfix ) {\\n\\t\\t\\treturn {\\n\\t\\t\\t\\tdisplay: function ( d ) {\\n\\t\\t\\t\\t\\tif ( typeof d !== 'number' && typeof d !== 'string' ) {\\n\\t\\t\\t\\t\\t\\treturn d;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tvar negative = d < 0 ? '-' : '';\\n\\t\\t\\t\\t\\tvar flo = parseFloat( d );\\n\\t\\n\\t\\t\\t\\t\\t// If NaN then there isn't much formatting that we can do - just\\n\\t\\t\\t\\t\\t// return immediately, escaping any HTML (this was supposed to\\n\\t\\t\\t\\t\\t// be a number after all)\\n\\t\\t\\t\\t\\tif ( isNaN( flo ) ) {\\n\\t\\t\\t\\t\\t\\treturn __htmlEscapeEntities( d );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tflo = flo.toFixed( precision );\\n\\t\\t\\t\\t\\td = Math.abs( flo );\\n\\t\\n\\t\\t\\t\\t\\tvar intPart = parseInt( d, 10 );\\n\\t\\t\\t\\t\\tvar floatPart = precision ?\\n\\t\\t\\t\\t\\t\\tdecimal+(d - intPart).toFixed( precision ).substring( 2 ):\\n\\t\\t\\t\\t\\t\\t'';\\n\\t\\n\\t\\t\\t\\t\\treturn negative + (prefix||'') +\\n\\t\\t\\t\\t\\t\\tintPart.toString().replace(\\n\\t\\t\\t\\t\\t\\t\\t/\\\\B(?=(\\\\d{3})+(?!\\\\d))/g, thousands\\n\\t\\t\\t\\t\\t\\t) +\\n\\t\\t\\t\\t\\t\\tfloatPart +\\n\\t\\t\\t\\t\\t\\t(postfix||'');\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\t},\\n\\t\\n\\t\\ttext: function () {\\n\\t\\t\\treturn {\\n\\t\\t\\t\\tdisplay: __htmlEscapeEntities\\n\\t\\t\\t};\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/*\\n\\t * This is really a good bit rubbish this method of exposing the internal methods\\n\\t * publicly... - To be fixed in 2.0 using methods on the prototype\\n\\t */\\n\\t\\n\\t\\n\\t/**\\n\\t * Create a wrapper function for exporting an internal functions to an external API.\\n\\t * @param {string} fn API function name\\n\\t * @returns {function} wrapped function\\n\\t * @memberof DataTable#internal\\n\\t */\\n\\tfunction _fnExternApiFunc (fn)\\n\\t{\\n\\t\\treturn function() {\\n\\t\\t\\tvar args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(\\n\\t\\t\\t\\tArray.prototype.slice.call(arguments)\\n\\t\\t\\t);\\n\\t\\t\\treturn DataTable.ext.internal[fn].apply( this, args );\\n\\t\\t};\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Reference to internal functions for use by plug-in developers. Note that\\n\\t * these methods are references to internal functions and are considered to be\\n\\t * private. If you use these methods, be aware that they are liable to change\\n\\t * between versions.\\n\\t * @namespace\\n\\t */\\n\\t$.extend( DataTable.ext.internal, {\\n\\t\\t_fnExternApiFunc: _fnExternApiFunc,\\n\\t\\t_fnBuildAjax: _fnBuildAjax,\\n\\t\\t_fnAjaxUpdate: _fnAjaxUpdate,\\n\\t\\t_fnAjaxParameters: _fnAjaxParameters,\\n\\t\\t_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,\\n\\t\\t_fnAjaxDataSrc: _fnAjaxDataSrc,\\n\\t\\t_fnAddColumn: _fnAddColumn,\\n\\t\\t_fnColumnOptions: _fnColumnOptions,\\n\\t\\t_fnAdjustColumnSizing: _fnAdjustColumnSizing,\\n\\t\\t_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,\\n\\t\\t_fnColumnIndexToVisible: _fnColumnIndexToVisible,\\n\\t\\t_fnVisbleColumns: _fnVisbleColumns,\\n\\t\\t_fnGetColumns: _fnGetColumns,\\n\\t\\t_fnColumnTypes: _fnColumnTypes,\\n\\t\\t_fnApplyColumnDefs: _fnApplyColumnDefs,\\n\\t\\t_fnHungarianMap: _fnHungarianMap,\\n\\t\\t_fnCamelToHungarian: _fnCamelToHungarian,\\n\\t\\t_fnLanguageCompat: _fnLanguageCompat,\\n\\t\\t_fnBrowserDetect: _fnBrowserDetect,\\n\\t\\t_fnAddData: _fnAddData,\\n\\t\\t_fnAddTr: _fnAddTr,\\n\\t\\t_fnNodeToDataIndex: _fnNodeToDataIndex,\\n\\t\\t_fnNodeToColumnIndex: _fnNodeToColumnIndex,\\n\\t\\t_fnGetCellData: _fnGetCellData,\\n\\t\\t_fnSetCellData: _fnSetCellData,\\n\\t\\t_fnSplitObjNotation: _fnSplitObjNotation,\\n\\t\\t_fnGetObjectDataFn: _fnGetObjectDataFn,\\n\\t\\t_fnSetObjectDataFn: _fnSetObjectDataFn,\\n\\t\\t_fnGetDataMaster: _fnGetDataMaster,\\n\\t\\t_fnClearTable: _fnClearTable,\\n\\t\\t_fnDeleteIndex: _fnDeleteIndex,\\n\\t\\t_fnInvalidate: _fnInvalidate,\\n\\t\\t_fnGetRowElements: _fnGetRowElements,\\n\\t\\t_fnCreateTr: _fnCreateTr,\\n\\t\\t_fnBuildHead: _fnBuildHead,\\n\\t\\t_fnDrawHead: _fnDrawHead,\\n\\t\\t_fnDraw: _fnDraw,\\n\\t\\t_fnReDraw: _fnReDraw,\\n\\t\\t_fnAddOptionsHtml: _fnAddOptionsHtml,\\n\\t\\t_fnDetectHeader: _fnDetectHeader,\\n\\t\\t_fnGetUniqueThs: _fnGetUniqueThs,\\n\\t\\t_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,\\n\\t\\t_fnFilterComplete: _fnFilterComplete,\\n\\t\\t_fnFilterCustom: _fnFilterCustom,\\n\\t\\t_fnFilterColumn: _fnFilterColumn,\\n\\t\\t_fnFilter: _fnFilter,\\n\\t\\t_fnFilterCreateSearch: _fnFilterCreateSearch,\\n\\t\\t_fnEscapeRegex: _fnEscapeRegex,\\n\\t\\t_fnFilterData: _fnFilterData,\\n\\t\\t_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,\\n\\t\\t_fnUpdateInfo: _fnUpdateInfo,\\n\\t\\t_fnInfoMacros: _fnInfoMacros,\\n\\t\\t_fnInitialise: _fnInitialise,\\n\\t\\t_fnInitComplete: _fnInitComplete,\\n\\t\\t_fnLengthChange: _fnLengthChange,\\n\\t\\t_fnFeatureHtmlLength: _fnFeatureHtmlLength,\\n\\t\\t_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,\\n\\t\\t_fnPageChange: _fnPageChange,\\n\\t\\t_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,\\n\\t\\t_fnProcessingDisplay: _fnProcessingDisplay,\\n\\t\\t_fnFeatureHtmlTable: _fnFeatureHtmlTable,\\n\\t\\t_fnScrollDraw: _fnScrollDraw,\\n\\t\\t_fnApplyToChildren: _fnApplyToChildren,\\n\\t\\t_fnCalculateColumnWidths: _fnCalculateColumnWidths,\\n\\t\\t_fnThrottle: _fnThrottle,\\n\\t\\t_fnConvertToWidth: _fnConvertToWidth,\\n\\t\\t_fnGetWidestNode: _fnGetWidestNode,\\n\\t\\t_fnGetMaxLenString: _fnGetMaxLenString,\\n\\t\\t_fnStringToCss: _fnStringToCss,\\n\\t\\t_fnSortFlatten: _fnSortFlatten,\\n\\t\\t_fnSort: _fnSort,\\n\\t\\t_fnSortAria: _fnSortAria,\\n\\t\\t_fnSortListener: _fnSortListener,\\n\\t\\t_fnSortAttachListener: _fnSortAttachListener,\\n\\t\\t_fnSortingClasses: _fnSortingClasses,\\n\\t\\t_fnSortData: _fnSortData,\\n\\t\\t_fnSaveState: _fnSaveState,\\n\\t\\t_fnLoadState: _fnLoadState,\\n\\t\\t_fnSettingsFromNode: _fnSettingsFromNode,\\n\\t\\t_fnLog: _fnLog,\\n\\t\\t_fnMap: _fnMap,\\n\\t\\t_fnBindAction: _fnBindAction,\\n\\t\\t_fnCallbackReg: _fnCallbackReg,\\n\\t\\t_fnCallbackFire: _fnCallbackFire,\\n\\t\\t_fnLengthOverflow: _fnLengthOverflow,\\n\\t\\t_fnRenderer: _fnRenderer,\\n\\t\\t_fnDataSource: _fnDataSource,\\n\\t\\t_fnRowAttributes: _fnRowAttributes,\\n\\t\\t_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant\\n\\t\\t // in 1.10, so this dead-end function is\\n\\t\\t // added to prevent errors\\n\\t} );\\n\\t\\n\\n\\t// jQuery access\\n\\t$.fn.dataTable = DataTable;\\n\\n\\t// Provide access to the host jQuery object (circular reference)\\n\\tDataTable.$ = $;\\n\\n\\t// Legacy aliases\\n\\t$.fn.dataTableSettings = DataTable.settings;\\n\\t$.fn.dataTableExt = DataTable.ext;\\n\\n\\t// With a capital `D` we return a DataTables API instance rather than a\\n\\t// jQuery object\\n\\t$.fn.DataTable = function ( opts ) {\\n\\t\\treturn $(this).dataTable( opts ).api();\\n\\t};\\n\\n\\t// All properties that are available to $.fn.dataTable should also be\\n\\t// available on $.fn.DataTable\\n\\t$.each( DataTable, function ( prop, val ) {\\n\\t\\t$.fn.DataTable[ prop ] = val;\\n\\t} );\\n\\n\\n\\t// Information about events fired by DataTables - for documentation.\\n\\t/**\\n\\t * Draw event, fired whenever the table is redrawn on the page, at the same\\n\\t * point as fnDrawCallback. This may be useful for binding events or\\n\\t * performing calculations when the table is altered at all.\\n\\t * @name DataTable#draw.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Search event, fired when the searching applied to the table (using the\\n\\t * built-in global search, or column filters) is altered.\\n\\t * @name DataTable#search.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Page change event, fired when the paging of the table is altered.\\n\\t * @name DataTable#page.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Order event, fired when the ordering applied to the table is altered.\\n\\t * @name DataTable#order.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * DataTables initialisation complete event, fired when the table is fully\\n\\t * drawn, including Ajax data loaded, if Ajax data is required.\\n\\t * @name DataTable#init.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The JSON object request from the server - only\\n\\t * present if client-side Ajax sourced data is used</li></ol>\\n\\t */\\n\\n\\t/**\\n\\t * State save event, fired when the table has changed state a new state save\\n\\t * is required. This event allows modification of the state saving object\\n\\t * prior to actually doing the save, including addition or other state\\n\\t * properties (for plug-ins) or modification of a DataTables core property.\\n\\t * @name DataTable#stateSaveParams.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The state information to be saved\\n\\t */\\n\\n\\t/**\\n\\t * State load event, fired when the table is loading state from the stored\\n\\t * data, but prior to the settings object being modified by the saved state\\n\\t * - allowing modification of the saved state is required or loading of\\n\\t * state for a plug-in.\\n\\t * @name DataTable#stateLoadParams.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The saved state information\\n\\t */\\n\\n\\t/**\\n\\t * State loaded event, fired when state has been loaded from stored data and\\n\\t * the settings object has been modified by the loaded data.\\n\\t * @name DataTable#stateLoaded.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The saved state information\\n\\t */\\n\\n\\t/**\\n\\t * Processing event, fired when DataTables is doing some kind of processing\\n\\t * (be it, order, searcg or anything else). It can be used to indicate to\\n\\t * the end user that there is something happening, or that something has\\n\\t * finished.\\n\\t * @name DataTable#processing.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {boolean} bShow Flag for if DataTables is doing processing or not\\n\\t */\\n\\n\\t/**\\n\\t * Ajax (XHR) event, fired whenever an Ajax request is completed from a\\n\\t * request to made to the server for new data. This event is called before\\n\\t * DataTables processed the returned data, so it can also be used to pre-\\n\\t * process the data returned from the server, if needed.\\n\\t *\\n\\t * Note that this trigger is called in `fnServerData`, if you override\\n\\t * `fnServerData` and which to use this event, you need to trigger it in you\\n\\t * success function.\\n\\t * @name DataTable#xhr.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t * @param {object} json JSON returned from the server\\n\\t *\\n\\t * @example\\n\\t * // Use a custom property returned from the server in another DOM element\\n\\t * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\\n\\t * $('#status').html( json.status );\\n\\t * } );\\n\\t *\\n\\t * @example\\n\\t * // Pre-process the data returned from the server\\n\\t * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\\n\\t * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {\\n\\t * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;\\n\\t * }\\n\\t * // Note no return - manipulate the data directly in the JSON object.\\n\\t * } );\\n\\t */\\n\\n\\t/**\\n\\t * Destroy event, fired when the DataTable is destroyed by calling fnDestroy\\n\\t * or passing the bDestroy:true parameter in the initialisation object. This\\n\\t * can be used to remove bound events, added DOM nodes, etc.\\n\\t * @name DataTable#destroy.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Page length change event, fired when number of records to show on each\\n\\t * page (the length) is changed.\\n\\t * @name DataTable#length.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t * @param {integer} len New length\\n\\t */\\n\\n\\t/**\\n\\t * Column sizing has changed.\\n\\t * @name DataTable#column-sizing.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Column visibility has changed.\\n\\t * @name DataTable#column-visibility.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t * @param {int} column Column index\\n\\t * @param {bool} vis `false` if column now hidden, or `true` if visible\\n\\t */\\n\\n\\treturn $.fn.dataTable;\\n}));\\n\\n /* END jquery.dataTables.js*/\\n\\n\\nvar event = document.createEvent(\\\"HTMLEvents\\\");\\nevent.initEvent(\\\"load_datatables\\\", false, false);\\nwindow.dispatchEvent(event);\\nconsole.log(\\\"Finish loading datatables js files\\\");\\n\\n\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "DataTables.init_iruby" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"something\"\n" ] }, { "data": { "text/plain": [ "\"something\"" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "basic_table = DataTables::DataTable.new(data: [[1,2,3], [11,12,13]] , paging: true, info: false)\n", "p 'something'" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"\\n<script type='text/javascript'>\\n \\n$(document).ready(function() {\\n\\n $('#table_id1').DataTable(\\n {data: [[1,2,3],[11,12,13]], paging: true, info: false}\\n );\\n\\n});\\n</script>\\n\"" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# there is no table given so only javascript is generated\n", "basic_table.to_html(id = \"table_id1\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"\\n<script type='text/javascript'>\\n$(document).ready(function() {\\n\\n $('#911fb029-38b5-43ec-acf2-a6809491eb0d').DataTable(\\n {data: [[1,2,3],[11,12,13]], paging: true, info: false}\\n );\\n\\n});\\n</script>\"" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "basic_table.show_script" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "<script type='text/javascript'>\n", " \n", "$(document).ready(function() {\n", "\n", " $('#table_id1').DataTable(\n", " {data: [[1,2,3],[11,12,13]], paging: true, info: false}\n", " );\n", "\n", "});\n", "</script>\n", "<table class=\"display\" cellspacing=\"0\" width=\"100%\" id=\"table_id1\">\n", " <thead>\n", " <tr>\n", " <th>no1</th>\n", " <th>no2</th>\n", " <th>no3</th>\n", " </tr>\n", " </thead></table>" ], "text/plain": [ "\"\\n<script type='text/javascript'>\\n \\n$(document).ready(function() {\\n\\n $('#table_id1').DataTable(\\n {data: [[1,2,3],[11,12,13]], paging: true, info: false}\\n );\\n\\n});\\n</script>\\n<table class=\\\"display\\\" cellspacing=\\\"0\\\" width=\\\"100%\\\" id=\\\"table_id1\\\">\\n <thead>\\n <tr>\\n <th>no1</th>\\n <th>no2</th>\\n <th>no3</th>\\n </tr>\\n </thead></table>\"" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "options = {\n", " table_options: {\n", " class: 'display',\n", " cellspacing: \"0\",\n", " width: \"100%\",\n", " table_html: \"\n", " <thead>\n", " <tr>\n", " <th>no1</th>\n", " <th>no2</th>\n", " <th>no3</th>\n", " </tr>\n", " </thead>\".html_safe\n", " }\n", " }\n", "html_code = basic_table.to_html(id='table_id1', options)\n", "\n", "# Fix me: It is showing normal html code. That means DataTables js and css is not working or loading.\n", "IRuby.html html_code" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "\"\\n /* BEGIN jquery.dataTables.css */\\n\\n/*\\n * Table styles\\n */\\ntable.dataTable {\\n width: 100%;\\n margin: 0 auto;\\n clear: both;\\n border-collapse: separate;\\n border-spacing: 0;\\n /*\\n * Header and footer styles\\n */\\n /*\\n * Body styles\\n */\\n}\\ntable.dataTable thead th,\\ntable.dataTable tfoot th {\\n font-weight: bold;\\n}\\ntable.dataTable thead th,\\ntable.dataTable thead td {\\n padding: 10px 18px;\\n border-bottom: 1px solid #111111;\\n}\\ntable.dataTable thead th:active,\\ntable.dataTable thead td:active {\\n outline: none;\\n}\\ntable.dataTable tfoot th,\\ntable.dataTable tfoot td {\\n padding: 10px 18px 6px 18px;\\n border-top: 1px solid #111111;\\n}\\ntable.dataTable thead .sorting,\\ntable.dataTable thead .sorting_asc,\\ntable.dataTable thead .sorting_desc,\\ntable.dataTable thead .sorting_asc_disabled,\\ntable.dataTable thead .sorting_desc_disabled {\\n cursor: pointer;\\n *cursor: hand;\\n background-repeat: no-repeat;\\n background-position: center right;\\n}\\ntable.dataTable thead .sorting {\\n background-image: url(\\\"../images/sort_both.png\\\");\\n}\\ntable.dataTable thead .sorting_asc {\\n background-image: url(\\\"../images/sort_asc.png\\\");\\n}\\ntable.dataTable thead .sorting_desc {\\n background-image: url(\\\"../images/sort_desc.png\\\");\\n}\\ntable.dataTable thead .sorting_asc_disabled {\\n background-image: url(\\\"../images/sort_asc_disabled.png\\\");\\n}\\ntable.dataTable thead .sorting_desc_disabled {\\n background-image: url(\\\"../images/sort_desc_disabled.png\\\");\\n}\\ntable.dataTable tbody tr {\\n background-color: white;\\n}\\ntable.dataTable tbody tr.selected {\\n background-color: #b0bed9;\\n}\\ntable.dataTable tbody th,\\ntable.dataTable tbody td {\\n padding: 8px 10px;\\n}\\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\\n border-top: 1px solid #dddddd;\\n}\\ntable.dataTable.row-border tbody tr:first-child th,\\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\\ntable.dataTable.display tbody tr:first-child td {\\n border-top: none;\\n}\\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\\n border-top: 1px solid #dddddd;\\n border-right: 1px solid #dddddd;\\n}\\ntable.dataTable.cell-border tbody tr th:first-child,\\ntable.dataTable.cell-border tbody tr td:first-child {\\n border-left: 1px solid #dddddd;\\n}\\ntable.dataTable.cell-border tbody tr:first-child th,\\ntable.dataTable.cell-border tbody tr:first-child td {\\n border-top: none;\\n}\\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\\n background-color: #f9f9f9;\\n}\\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\\n background-color: #abb9d3;\\n}\\ntable.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\\n background-color: whitesmoke;\\n}\\ntable.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\\n background-color: #a9b7d1;\\n}\\ntable.dataTable.order-column tbody tr > .sorting_1,\\ntable.dataTable.order-column tbody tr > .sorting_2,\\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\\ntable.dataTable.display tbody tr > .sorting_2,\\ntable.dataTable.display tbody tr > .sorting_3 {\\n background-color: #f9f9f9;\\n}\\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\\ntable.dataTable.display tbody tr.selected > .sorting_2,\\ntable.dataTable.display tbody tr.selected > .sorting_3 {\\n background-color: #acbad4;\\n}\\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\\n background-color: #f1f1f1;\\n}\\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\\n background-color: #f3f3f3;\\n}\\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\\n background-color: whitesmoke;\\n}\\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\\n background-color: #a6b3cd;\\n}\\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\\n background-color: #a7b5ce;\\n}\\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\\n background-color: #a9b6d0;\\n}\\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\\n background-color: #f9f9f9;\\n}\\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\\n background-color: #fbfbfb;\\n}\\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\\n background-color: #fdfdfd;\\n}\\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\\n background-color: #acbad4;\\n}\\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\\n background-color: #adbbd6;\\n}\\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\\n background-color: #afbdd8;\\n}\\ntable.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\\n background-color: #eaeaea;\\n}\\ntable.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\\n background-color: #ebebeb;\\n}\\ntable.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\\n background-color: #eeeeee;\\n}\\ntable.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\\n background-color: #a1aec7;\\n}\\ntable.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\\n background-color: #a2afc8;\\n}\\ntable.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\\n background-color: #a4b2cb;\\n}\\ntable.dataTable.no-footer {\\n border-bottom: 1px solid #111111;\\n}\\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\\n white-space: nowrap;\\n}\\ntable.dataTable.compact thead th,\\ntable.dataTable.compact thead td {\\n padding: 4px 17px 4px 4px;\\n}\\ntable.dataTable.compact tfoot th,\\ntable.dataTable.compact tfoot td {\\n padding: 4px;\\n}\\ntable.dataTable.compact tbody th,\\ntable.dataTable.compact tbody td {\\n padding: 4px;\\n}\\ntable.dataTable th.dt-left,\\ntable.dataTable td.dt-left {\\n text-align: left;\\n}\\ntable.dataTable th.dt-center,\\ntable.dataTable td.dt-center,\\ntable.dataTable td.dataTables_empty {\\n text-align: center;\\n}\\ntable.dataTable th.dt-right,\\ntable.dataTable td.dt-right {\\n text-align: right;\\n}\\ntable.dataTable th.dt-justify,\\ntable.dataTable td.dt-justify {\\n text-align: justify;\\n}\\ntable.dataTable th.dt-nowrap,\\ntable.dataTable td.dt-nowrap {\\n white-space: nowrap;\\n}\\ntable.dataTable thead th.dt-head-left,\\ntable.dataTable thead td.dt-head-left,\\ntable.dataTable tfoot th.dt-head-left,\\ntable.dataTable tfoot td.dt-head-left {\\n text-align: left;\\n}\\ntable.dataTable thead th.dt-head-center,\\ntable.dataTable thead td.dt-head-center,\\ntable.dataTable tfoot th.dt-head-center,\\ntable.dataTable tfoot td.dt-head-center {\\n text-align: center;\\n}\\ntable.dataTable thead th.dt-head-right,\\ntable.dataTable thead td.dt-head-right,\\ntable.dataTable tfoot th.dt-head-right,\\ntable.dataTable tfoot td.dt-head-right {\\n text-align: right;\\n}\\ntable.dataTable thead th.dt-head-justify,\\ntable.dataTable thead td.dt-head-justify,\\ntable.dataTable tfoot th.dt-head-justify,\\ntable.dataTable tfoot td.dt-head-justify {\\n text-align: justify;\\n}\\ntable.dataTable thead th.dt-head-nowrap,\\ntable.dataTable thead td.dt-head-nowrap,\\ntable.dataTable tfoot th.dt-head-nowrap,\\ntable.dataTable tfoot td.dt-head-nowrap {\\n white-space: nowrap;\\n}\\ntable.dataTable tbody th.dt-body-left,\\ntable.dataTable tbody td.dt-body-left {\\n text-align: left;\\n}\\ntable.dataTable tbody th.dt-body-center,\\ntable.dataTable tbody td.dt-body-center {\\n text-align: center;\\n}\\ntable.dataTable tbody th.dt-body-right,\\ntable.dataTable tbody td.dt-body-right {\\n text-align: right;\\n}\\ntable.dataTable tbody th.dt-body-justify,\\ntable.dataTable tbody td.dt-body-justify {\\n text-align: justify;\\n}\\ntable.dataTable tbody th.dt-body-nowrap,\\ntable.dataTable tbody td.dt-body-nowrap {\\n white-space: nowrap;\\n}\\n\\ntable.dataTable,\\ntable.dataTable th,\\ntable.dataTable td {\\n box-sizing: content-box;\\n}\\n\\n/*\\n * Control feature layout\\n */\\n.dataTables_wrapper {\\n position: relative;\\n clear: both;\\n *zoom: 1;\\n zoom: 1;\\n}\\n.dataTables_wrapper .dataTables_length {\\n float: left;\\n}\\n.dataTables_wrapper .dataTables_filter {\\n float: right;\\n text-align: right;\\n}\\n.dataTables_wrapper .dataTables_filter input {\\n margin-left: 0.5em;\\n}\\n.dataTables_wrapper .dataTables_info {\\n clear: both;\\n float: left;\\n padding-top: 0.755em;\\n}\\n.dataTables_wrapper .dataTables_paginate {\\n float: right;\\n text-align: right;\\n padding-top: 0.25em;\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button {\\n box-sizing: border-box;\\n display: inline-block;\\n min-width: 1.5em;\\n padding: 0.5em 1em;\\n margin-left: 2px;\\n text-align: center;\\n text-decoration: none !important;\\n cursor: pointer;\\n *cursor: hand;\\n color: #333333 !important;\\n border: 1px solid transparent;\\n border-radius: 2px;\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\\n color: #333333 !important;\\n border: 1px solid #979797;\\n background-color: white;\\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, gainsboro));\\n /* Chrome,Safari4+ */\\n background: -webkit-linear-gradient(top, white 0%, gainsboro 100%);\\n /* Chrome10+,Safari5.1+ */\\n background: -moz-linear-gradient(top, white 0%, gainsboro 100%);\\n /* FF3.6+ */\\n background: -ms-linear-gradient(top, white 0%, gainsboro 100%);\\n /* IE10+ */\\n background: -o-linear-gradient(top, white 0%, gainsboro 100%);\\n /* Opera 11.10+ */\\n background: linear-gradient(to bottom, white 0%, gainsboro 100%);\\n /* W3C */\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\\n cursor: default;\\n color: #666 !important;\\n border: 1px solid transparent;\\n background: transparent;\\n box-shadow: none;\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button:hover {\\n color: white !important;\\n border: 1px solid #111111;\\n background-color: #585858;\\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111111));\\n /* Chrome,Safari4+ */\\n background: -webkit-linear-gradient(top, #585858 0%, #111111 100%);\\n /* Chrome10+,Safari5.1+ */\\n background: -moz-linear-gradient(top, #585858 0%, #111111 100%);\\n /* FF3.6+ */\\n background: -ms-linear-gradient(top, #585858 0%, #111111 100%);\\n /* IE10+ */\\n background: -o-linear-gradient(top, #585858 0%, #111111 100%);\\n /* Opera 11.10+ */\\n background: linear-gradient(to bottom, #585858 0%, #111111 100%);\\n /* W3C */\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button:active {\\n outline: none;\\n background-color: #2b2b2b;\\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));\\n /* Chrome,Safari4+ */\\n background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* Chrome10+,Safari5.1+ */\\n background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* FF3.6+ */\\n background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* IE10+ */\\n background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* Opera 11.10+ */\\n background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);\\n /* W3C */\\n box-shadow: inset 0 0 3px #111;\\n}\\n.dataTables_wrapper .dataTables_paginate .ellipsis {\\n padding: 0 1em;\\n}\\n.dataTables_wrapper .dataTables_processing {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n width: 100%;\\n height: 40px;\\n margin-left: -50%;\\n margin-top: -25px;\\n padding-top: 20px;\\n text-align: center;\\n font-size: 1.2em;\\n background-color: white;\\n background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\\n background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n}\\n.dataTables_wrapper .dataTables_length,\\n.dataTables_wrapper .dataTables_filter,\\n.dataTables_wrapper .dataTables_info,\\n.dataTables_wrapper .dataTables_processing,\\n.dataTables_wrapper .dataTables_paginate {\\n color: #333333;\\n}\\n.dataTables_wrapper .dataTables_scroll {\\n clear: both;\\n}\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\\n *margin-top: -1px;\\n -webkit-overflow-scrolling: touch;\\n}\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td {\\n vertical-align: middle;\\n}\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th > div.dataTables_sizing,\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th > div.dataTables_sizing,\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td > div.dataTables_sizing {\\n height: 0;\\n overflow: hidden;\\n margin: 0 !important;\\n padding: 0 !important;\\n}\\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\\n border-bottom: 1px solid #111111;\\n}\\n.dataTables_wrapper.no-footer div.dataTables_scrollHead > table,\\n.dataTables_wrapper.no-footer div.dataTables_scrollBody > table {\\n border-bottom: none;\\n}\\n.dataTables_wrapper:after {\\n visibility: hidden;\\n display: block;\\n content: \\\"\\\";\\n clear: both;\\n height: 0;\\n}\\n\\n@media screen and (max-width: 767px) {\\n .dataTables_wrapper .dataTables_info,\\n .dataTables_wrapper .dataTables_paginate {\\n float: none;\\n text-align: center;\\n }\\n .dataTables_wrapper .dataTables_paginate {\\n margin-top: 0.5em;\\n }\\n}\\n@media screen and (max-width: 640px) {\\n .dataTables_wrapper .dataTables_length,\\n .dataTables_wrapper .dataTables_filter {\\n float: none;\\n text-align: center;\\n }\\n .dataTables_wrapper .dataTables_filter {\\n margin-top: 0.5em;\\n }\\n}\\n\\n /* END jquery.dataTables.css*/\\n\\n\\n\\n\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# displaying css that is inicluded \n", "IRuby.display DataTables.generate_init_code_css(dependent_css=['jquery.dataTables.css'])" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"\\n<script type='text/javascript'>\\n /* BEGIN jquery-latest.min.js */\\n\\n/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */\\n!function(a,b){\\\"object\\\"==typeof module&&\\\"object\\\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\\\"jQuery requires a window with a document\\\");return b(a)}:b(a)}(\\\"undefined\\\"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=\\\"1.11.1\\\",m=function(a,b){return new m.fn.init(a,b)},n=/^[\\\\s\\\\uFEFF\\\\xA0]+|[\\\\s\\\\uFEFF\\\\xA0]+$/g,o=/^-ms-/,p=/-([\\\\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:\\\"\\\",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\\\"boolean\\\"==typeof g&&(j=g,g=arguments[h]||{},h++),\\\"object\\\"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:\\\"jQuery\\\"+(l+Math.random()).replace(/\\\\D/g,\\\"\\\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\\\"function\\\"===m.type(a)},isArray:Array.isArray||function(a){return\\\"array\\\"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||\\\"object\\\"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,\\\"constructor\\\")&&!j.call(a.constructor.prototype,\\\"isPrototypeOf\\\"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+\\\"\\\":\\\"object\\\"==typeof a||\\\"function\\\"==typeof a?h[i.call(a)]||\\\"object\\\":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,\\\"ms-\\\").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?\\\"\\\":(a+\\\"\\\").replace(n,\\\"\\\")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,\\\"string\\\"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return\\\"string\\\"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each(\\\"Boolean Number String Function Array Date RegExp Object Error\\\".split(\\\" \\\"),function(a,b){h[\\\"[object \\\"+b+\\\"]\\\"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return\\\"function\\\"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:\\\"array\\\"===c||0===b||\\\"number\\\"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\\\"sizzle\\\"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C=\\\"undefined\\\",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L=\\\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\\\",M=\\\"[\\\\\\\\x20\\\\\\\\t\\\\\\\\r\\\\\\\\n\\\\\\\\f]\\\",N=\\\"(?:\\\\\\\\\\\\\\\\.|[\\\\\\\\w-]|[^\\\\\\\\x00-\\\\\\\\xa0])+\\\",O=N.replace(\\\"w\\\",\\\"w#\\\"),P=\\\"\\\\\\\\[\\\"+M+\\\"*(\\\"+N+\\\")(?:\\\"+M+\\\"*([*^$|!~]?=)\\\"+M+\\\"*(?:'((?:\\\\\\\\\\\\\\\\.|[^\\\\\\\\\\\\\\\\'])*)'|\\\\\\\"((?:\\\\\\\\\\\\\\\\.|[^\\\\\\\\\\\\\\\\\\\\\\\"])*)\\\\\\\"|(\\\"+O+\\\"))|)\\\"+M+\\\"*\\\\\\\\]\\\",Q=\\\":(\\\"+N+\\\")(?:\\\\\\\\((('((?:\\\\\\\\\\\\\\\\.|[^\\\\\\\\\\\\\\\\'])*)'|\\\\\\\"((?:\\\\\\\\\\\\\\\\.|[^\\\\\\\\\\\\\\\\\\\\\\\"])*)\\\\\\\")|((?:\\\\\\\\\\\\\\\\.|[^\\\\\\\\\\\\\\\\()[\\\\\\\\]]|\\\"+P+\\\")*)|.*)\\\\\\\\)|)\\\",R=new RegExp(\\\"^\\\"+M+\\\"+|((?:^|[^\\\\\\\\\\\\\\\\])(?:\\\\\\\\\\\\\\\\.)*)\\\"+M+\\\"+$\\\",\\\"g\\\"),S=new RegExp(\\\"^\\\"+M+\\\"*,\\\"+M+\\\"*\\\"),T=new RegExp(\\\"^\\\"+M+\\\"*([>+~]|\\\"+M+\\\")\\\"+M+\\\"*\\\"),U=new RegExp(\\\"=\\\"+M+\\\"*([^\\\\\\\\]'\\\\\\\"]*?)\\\"+M+\\\"*\\\\\\\\]\\\",\\\"g\\\"),V=new RegExp(Q),W=new RegExp(\\\"^\\\"+O+\\\"$\\\"),X={ID:new RegExp(\\\"^#(\\\"+N+\\\")\\\"),CLASS:new RegExp(\\\"^\\\\\\\\.(\\\"+N+\\\")\\\"),TAG:new RegExp(\\\"^(\\\"+N.replace(\\\"w\\\",\\\"w*\\\")+\\\")\\\"),ATTR:new RegExp(\\\"^\\\"+P),PSEUDO:new RegExp(\\\"^\\\"+Q),CHILD:new RegExp(\\\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\\\\\(\\\"+M+\\\"*(even|odd|(([+-]|)(\\\\\\\\d*)n|)\\\"+M+\\\"*(?:([+-]|)\\\"+M+\\\"*(\\\\\\\\d+)|))\\\"+M+\\\"*\\\\\\\\)|)\\\",\\\"i\\\"),bool:new RegExp(\\\"^(?:\\\"+L+\\\")$\\\",\\\"i\\\"),needsContext:new RegExp(\\\"^\\\"+M+\\\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\\\\\(\\\"+M+\\\"*((?:-\\\\\\\\d)?\\\\\\\\d*)\\\"+M+\\\"*\\\\\\\\)|)(?=[^-]|$)\\\",\\\"i\\\")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\\\\d$/i,$=/^[^{]+\\\\{\\\\s*\\\\[native \\\\w/,_=/^(?:#([\\\\w-]+)|(\\\\w+)|\\\\.([\\\\w-]+))$/,ab=/[+~]/,bb=/'|\\\\\\\\/g,cb=new RegExp(\\\"\\\\\\\\\\\\\\\\([\\\\\\\\da-f]{1,6}\\\"+M+\\\"?|(\\\"+M+\\\")|.)\\\",\\\"ig\\\"),db=function(a,b,c){var d=\\\"0x\\\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||\\\"string\\\"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&\\\"object\\\"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute(\\\"id\\\"))?s=r.replace(bb,\\\"\\\\\\\\$&\\\"):b.setAttribute(\\\"id\\\",s),s=\\\"[id='\\\"+s+\\\"'] \\\",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(\\\",\\\")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute(\\\"id\\\")}}}return i(a.replace(R,\\\"$1\\\"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+\\\" \\\")>d.cacheLength&&delete b[a.shift()],b[c+\\\" \\\"]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement(\\\"div\\\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split(\\\"|\\\"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return\\\"input\\\"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return(\\\"input\\\"===c||\\\"button\\\"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\\\"HTML\\\"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener(\\\"unload\\\",function(){m()},!1):g.attachEvent&&g.attachEvent(\\\"onunload\\\",function(){m()})),c.attributes=ib(function(a){return a.className=\\\"i\\\",!a.getAttribute(\\\"className\\\")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment(\\\"\\\")),!a.getElementsByTagName(\\\"*\\\").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML=\\\"<div class='a'></div><div class='a i'></div>\\\",a.firstChild.className=\\\"i\\\",2===a.getElementsByClassName(\\\"i\\\").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute(\\\"id\\\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode(\\\"id\\\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\\\"*\\\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML=\\\"<select msallowclip=''><option selected=''></option></select>\\\",a.querySelectorAll(\\\"[msallowclip^='']\\\").length&&q.push(\\\"[*^$]=\\\"+M+\\\"*(?:''|\\\\\\\"\\\\\\\")\\\"),a.querySelectorAll(\\\"[selected]\\\").length||q.push(\\\"\\\\\\\\[\\\"+M+\\\"*(?:value|\\\"+L+\\\")\\\"),a.querySelectorAll(\\\":checked\\\").length||q.push(\\\":checked\\\")}),ib(function(a){var b=e.createElement(\\\"input\\\");b.setAttribute(\\\"type\\\",\\\"hidden\\\"),a.appendChild(b).setAttribute(\\\"name\\\",\\\"D\\\"),a.querySelectorAll(\\\"[name=d]\\\").length&&q.push(\\\"name\\\"+M+\\\"*[*^$|!~]?=\\\"),a.querySelectorAll(\\\":enabled\\\").length||q.push(\\\":enabled\\\",\\\":disabled\\\"),a.querySelectorAll(\\\"*,:x\\\"),q.push(\\\",.*:\\\")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,\\\"div\\\"),s.call(a,\\\"[s!='']:x\\\"),r.push(\\\"!=\\\",Q)}),q=q.length&&new RegExp(q.join(\\\"|\\\")),r=r.length&&new RegExp(r.join(\\\"|\\\")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,\\\"='$1']\\\"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error(\\\"Syntax error, unrecognized expression: \\\"+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c=\\\"\\\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\\\"string\\\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{\\\">\\\":{dir:\\\"parentNode\\\",first:!0},\\\" \\\":{dir:\\\"parentNode\\\"},\\\"+\\\":{dir:\\\"previousSibling\\\",first:!0},\\\"~\\\":{dir:\\\"previousSibling\\\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||\\\"\\\").replace(cb,db),\\\"~=\\\"===a[2]&&(a[3]=\\\" \\\"+a[3]+\\\" \\\"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\\\"nth\\\"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\\\"even\\\"===a[3]||\\\"odd\\\"===a[3])),a[5]=+(a[7]+a[8]||\\\"odd\\\"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\\\"\\\":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\\\")\\\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return\\\"*\\\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\\\" \\\"];return b||(b=new RegExp(\\\"(^|\\\"+M+\\\")\\\"+a+\\\"(\\\"+M+\\\"|$)\\\"))&&y(a,function(a){return b.test(\\\"string\\\"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute(\\\"class\\\")||\\\"\\\")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?\\\"!=\\\"===b:b?(e+=\\\"\\\",\\\"=\\\"===b?e===c:\\\"!=\\\"===b?e!==c:\\\"^=\\\"===b?c&&0===e.indexOf(c):\\\"*=\\\"===b?c&&e.indexOf(c)>-1:\\\"$=\\\"===b?c&&e.slice(-c.length)===c:\\\"~=\\\"===b?(\\\" \\\"+e+\\\" \\\").indexOf(c)>-1:\\\"|=\\\"===b?e===c||e.slice(0,c.length+1)===c+\\\"-\\\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\\\"nth\\\"!==a.slice(0,3),g=\\\"last\\\"!==a.slice(-4),h=\\\"of-type\\\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\\\"nextSibling\\\":\\\"previousSibling\\\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p=\\\"only\\\"===a&&!o&&\\\"nextSibling\\\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error(\\\"unsupported pseudo: \\\"+a);return e[u]?e(b):e.length>1?(c=[a,a,\\\"\\\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,\\\"$1\\\"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||\\\"\\\")||fb.error(\\\"unsupported lang: \\\"+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\\\"xml:lang\\\")||b.getAttribute(\\\"lang\\\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\\\"-\\\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\\\"input\\\"===b&&!!a.checked||\\\"option\\\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\\\"input\\\"===b&&\\\"button\\\"===a.type||\\\"button\\\"===b},text:function(a){var b;return\\\"input\\\"===a.nodeName.toLowerCase()&&\\\"text\\\"===a.type&&(null==(b=a.getAttribute(\\\"type\\\"))||\\\"text\\\"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\\\" \\\"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R,\\\" \\\")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d=\\\"\\\";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&\\\"parentNode\\\"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||\\\"*\\\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\\\" \\\"],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:\\\" \\\"===a[i-2].type?\\\"*\\\":\\\"\\\"})).replace(R,\\\"$1\\\"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q=\\\"0\\\",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG(\\\"*\\\",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+\\\" \\\"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n=\\\"function\\\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\\\"ID\\\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split(\\\"\\\").sort(B).join(\\\"\\\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement(\\\"div\\\"))}),ib(function(a){return a.innerHTML=\\\"<a href='#'></a>\\\",\\\"#\\\"===a.firstChild.getAttribute(\\\"href\\\")})||jb(\\\"type|href|height|width\\\",function(a,b,c){return c?void 0:a.getAttribute(b,\\\"type\\\"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=\\\"<input/>\\\",a.firstChild.setAttribute(\\\"value\\\",\\\"\\\"),\\\"\\\"===a.firstChild.getAttribute(\\\"value\\\")})||jb(\\\"value\\\",function(a,b,c){return c||\\\"input\\\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute(\\\"disabled\\\")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[\\\":\\\"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\\\\w+)\\\\s*\\\\/?>(?:<\\\\/\\\\1>|)$/,v=/^.[^:#\\\\[\\\\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if(\\\"string\\\"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=\\\":not(\\\"+a+\\\")\\\"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if(\\\"string\\\"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+\\\" \\\"+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,\\\"string\\\"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\\\\s*(<[\\\\w\\\\W]+>)[^>]*|#([\\\\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if(\\\"string\\\"==typeof a){if(c=\\\"<\\\"===a.charAt(0)&&\\\">\\\"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?\\\"undefined\\\"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||\\\"string\\\"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?\\\"string\\\"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,\\\"parentNode\\\")},parentsUntil:function(a,b,c){return m.dir(a,\\\"parentNode\\\",c)},next:function(a){return D(a,\\\"nextSibling\\\")},prev:function(a){return D(a,\\\"previousSibling\\\")},nextAll:function(a){return m.dir(a,\\\"nextSibling\\\")},prevAll:function(a){return m.dir(a,\\\"previousSibling\\\")},nextUntil:function(a,b,c){return m.dir(a,\\\"nextSibling\\\",c)},prevUntil:function(a,b,c){return m.dir(a,\\\"previousSibling\\\",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,\\\"iframe\\\")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return\\\"Until\\\"!==a.slice(-5)&&(d=c),d&&\\\"string\\\"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\\\\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a=\\\"string\\\"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);\\\"function\\\"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&\\\"string\\\"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[[\\\"resolve\\\",\\\"done\\\",m.Callbacks(\\\"once memory\\\"),\\\"resolved\\\"],[\\\"reject\\\",\\\"fail\\\",m.Callbacks(\\\"once memory\\\"),\\\"rejected\\\"],[\\\"notify\\\",\\\"progress\\\",m.Callbacks(\\\"memory\\\")]],c=\\\"pending\\\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+\\\"With\\\"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\\\"With\\\"](this===e?d:this,arguments),this},e[f[0]+\\\"With\\\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler(\\\"ready\\\"),m(y).off(\\\"ready\\\")))}}});function I(){y.addEventListener?(y.removeEventListener(\\\"DOMContentLoaded\\\",J,!1),a.removeEventListener(\\\"load\\\",J,!1)):(y.detachEvent(\\\"onreadystatechange\\\",J),a.detachEvent(\\\"onload\\\",J))}function J(){(y.addEventListener||\\\"load\\\"===event.type||\\\"complete\\\"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),\\\"complete\\\"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener(\\\"DOMContentLoaded\\\",J,!1),a.addEventListener(\\\"load\\\",J,!1);else{y.attachEvent(\\\"onreadystatechange\\\",J),a.attachEvent(\\\"onload\\\",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll(\\\"left\\\")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K=\\\"undefined\\\",L;for(L in m(k))break;k.ownLast=\\\"0\\\"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName(\\\"body\\\")[0],c&&c.style&&(b=y.createElement(\\\"div\\\"),d=y.createElement(\\\"div\\\"),d.style.cssText=\\\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\\\",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText=\\\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\\\",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement(\\\"div\\\");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+\\\" \\\").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute(\\\"classid\\\")===b};var M=/^(?:\\\\{[\\\\w\\\\W]*\\\\}|\\\\[[\\\\w\\\\W]*\\\\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d=\\\"data-\\\"+b.replace(N,\\\"-$1\\\").toLowerCase();if(c=a.getAttribute(d),\\\"string\\\"==typeof c){try{c=\\\"true\\\"===c?!0:\\\"false\\\"===c?!1:\\\"null\\\"===c?null:+c+\\\"\\\"===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if((\\\"data\\\"!==b||!m.isEmptyObject(a[b]))&&\\\"toJSON\\\"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;\\nif(k&&j[k]&&(e||j[k].data)||void 0!==d||\\\"string\\\"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),(\\\"object\\\"==typeof b||\\\"function\\\"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),\\\"string\\\"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(\\\" \\\")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{\\\"applet \\\":!0,\\\"embed \\\":!0,\\\"object \\\":\\\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\\\"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,\\\"parsedAttrs\\\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\\\"data-\\\")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,\\\"parsedAttrs\\\",!0)}return e}return\\\"object\\\"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||\\\"fx\\\")+\\\"queue\\\",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\\\"fx\\\";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};\\\"inprogress\\\"===e&&(e=c.shift(),d--),e&&(\\\"fx\\\"===b&&c.unshift(\\\"inprogress\\\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\\\"queueHooks\\\";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks(\\\"once memory\\\").add(function(){m._removeData(a,b+\\\"queue\\\"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return\\\"string\\\"!=typeof a&&(b=a,a=\\\"fx\\\",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),\\\"fx\\\"===a&&\\\"inprogress\\\"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\\\"fx\\\",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\\\"string\\\"!=typeof a&&(b=a,a=void 0),a=a||\\\"fx\\\";while(g--)c=m._data(f[g],a+\\\"queueHooks\\\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\\\\d*\\\\.|)\\\\d+(?:[eE][+-]?\\\\d+|)/.source,T=[\\\"Top\\\",\\\"Right\\\",\\\"Bottom\\\",\\\"Left\\\"],U=function(a,b){return a=b||a,\\\"none\\\"===m.css(a,\\\"display\\\")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\\\"object\\\"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement(\\\"input\\\"),b=y.createElement(\\\"div\\\"),c=y.createDocumentFragment();if(b.innerHTML=\\\" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\\\",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName(\\\"tbody\\\").length,k.htmlSerialize=!!b.getElementsByTagName(\\\"link\\\").length,k.html5Clone=\\\"<:nav></:nav>\\\"!==y.createElement(\\\"nav\\\").cloneNode(!0).outerHTML,a.type=\\\"checkbox\\\",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML=\\\"<textarea>x</textarea>\\\",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=\\\"<input type='radio' checked='checked' name='t'/>\\\",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent(\\\"onclick\\\",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement(\\\"div\\\");for(b in{submit:!0,change:!0,focusin:!0})c=\\\"on\\\"+b,(k[b+\\\"Bubbles\\\"]=c in a)||(d.setAttribute(c,\\\"t\\\"),k[b+\\\"Bubbles\\\"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\\\\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||\\\"\\\").match(E)||[\\\"\\\"],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||\\\"\\\").split(\\\".\\\").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(\\\".\\\")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent(\\\"on\\\"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||\\\"\\\").match(E)||[\\\"\\\"],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||\\\"\\\").split(\\\".\\\").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp(\\\"(^|\\\\\\\\.)\\\"+p.join(\\\"\\\\\\\\.(?:.*\\\\\\\\.|)\\\")+\\\"(\\\\\\\\.|$)\\\"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&(\\\"**\\\"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,\\\"events\\\"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,\\\"type\\\")?b.type:b,q=j.call(b,\\\"namespace\\\")?b.namespace.split(\\\".\\\"):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(\\\".\\\")>=0&&(q=p.split(\\\".\\\"),p=q.shift(),q.sort()),g=p.indexOf(\\\":\\\")<0&&\\\"on\\\"+p,b=b[m.expando]?b:new m.Event(p,\\\"object\\\"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join(\\\".\\\"),b.namespace_re=b.namespace?new RegExp(\\\"(^|\\\\\\\\.)\\\"+q.join(\\\"\\\\\\\\.(?:.*\\\\\\\\.|)\\\")+\\\"(\\\\\\\\.|$)\\\"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,\\\"events\\\")||{})[b.type]&&m._data(h,\\\"handle\\\"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,\\\"events\\\")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||\\\"click\\\"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||\\\"click\\\"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+\\\" \\\",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:\\\"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\\\".split(\\\" \\\"),fixHooks:{},keyHooks:{props:\\\"char charCode key keyCode\\\".split(\\\" \\\"),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:\\\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\\\".split(\\\" \\\"),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:\\\"focusin\\\"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:\\\"focusout\\\"},click:{trigger:function(){return m.nodeName(this,\\\"input\\\")&&\\\"checkbox\\\"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,\\\"a\\\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d=\\\"on\\\"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:\\\"mouseover\\\",mouseleave:\\\"mouseout\\\",pointerenter:\\\"pointerover\\\",pointerleave:\\\"pointerout\\\"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,\\\"form\\\")?!1:void m.event.add(this,\\\"click._submit keypress._submit\\\",function(a){var b=a.target,c=m.nodeName(b,\\\"input\\\")||m.nodeName(b,\\\"button\\\")?b.form:void 0;c&&!m._data(c,\\\"submitBubbles\\\")&&(m.event.add(c,\\\"submit._submit\\\",function(a){a._submit_bubble=!0}),m._data(c,\\\"submitBubbles\\\",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate(\\\"submit\\\",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,\\\"form\\\")?!1:void m.event.remove(this,\\\"._submit\\\")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?((\\\"checkbox\\\"===this.type||\\\"radio\\\"===this.type)&&(m.event.add(this,\\\"propertychange._change\\\",function(a){\\\"checked\\\"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,\\\"click._change\\\",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate(\\\"change\\\",this,a,!0)})),!1):void m.event.add(this,\\\"beforeactivate._change\\\",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,\\\"changeBubbles\\\")&&(m.event.add(b,\\\"change._change\\\",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate(\\\"change\\\",this.parentNode,a,!0)}),m._data(b,\\\"changeBubbles\\\",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||\\\"radio\\\"!==b.type&&\\\"checkbox\\\"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,\\\"._change\\\"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:\\\"focusin\\\",blur:\\\"focusout\\\"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if(\\\"object\\\"==typeof a){\\\"string\\\"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&(\\\"string\\\"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+\\\".\\\"+d.namespace:d.origType,d.selector,d.handler),this;if(\\\"object\\\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||\\\"function\\\"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split(\\\"|\\\"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb=\\\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\\\",fb=/ jQuery\\\\d+=\\\"(?:null|\\\\d+)\\\"/g,gb=new RegExp(\\\"<(?:\\\"+eb+\\\")[\\\\\\\\s/>]\\\",\\\"i\\\"),hb=/^\\\\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\\\w:]+)[^>]*)\\\\/>/gi,jb=/<([\\\\w:]+)/,kb=/<tbody/i,lb=/<|&#?\\\\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\\\\s*(?:[^=]|=\\\\s*.checked.)/i,ob=/^$|\\\\/(?:java|ecma)script/i,pb=/^true\\\\/(.*)/,qb=/^\\\\s*<!(?:\\\\[CDATA\\\\[|--)|(?:\\\\]\\\\]|--)>\\\\s*$/g,rb={option:[1,\\\"<select multiple='multiple'>\\\",\\\"</select>\\\"],legend:[1,\\\"<fieldset>\\\",\\\"</fieldset>\\\"],area:[1,\\\"<map>\\\",\\\"</map>\\\"],param:[1,\\\"<object>\\\",\\\"</object>\\\"],thead:[1,\\\"<table>\\\",\\\"</table>\\\"],tr:[2,\\\"<table><tbody>\\\",\\\"</tbody></table>\\\"],col:[2,\\\"<table><tbody></tbody><colgroup>\\\",\\\"</colgroup></table>\\\"],td:[3,\\\"<table><tbody><tr>\\\",\\\"</tr></tbody></table>\\\"],_default:k.htmlSerialize?[0,\\\"\\\",\\\"\\\"]:[1,\\\"X<div>\\\",\\\"</div>\\\"]},sb=db(y),tb=sb.appendChild(y.createElement(\\\"div\\\"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||\\\"*\\\"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||\\\"*\\\"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,\\\"table\\\")&&m.nodeName(11!==b.nodeType?b:b.firstChild,\\\"tr\\\")?a.getElementsByTagName(\\\"tbody\\\")[0]||a.appendChild(a.ownerDocument.createElement(\\\"tbody\\\")):a}function xb(a){return a.type=(null!==m.find.attr(a,\\\"type\\\"))+\\\"/\\\"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\\\"type\\\"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,\\\"globalEval\\\",!b||m._data(b[d],\\\"globalEval\\\"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}\\\"script\\\"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):\\\"object\\\"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):\\\"input\\\"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):\\\"option\\\"===c?b.defaultSelected=b.selected=a.defaultSelected:(\\\"input\\\"===c||\\\"textarea\\\"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test(\\\"<\\\"+a.nodeName+\\\">\\\")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,\\\"script\\\"),d.length>0&&zb(d,!i&&ub(a,\\\"script\\\")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if(\\\"object\\\"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement(\\\"div\\\")),i=(jb.exec(f)||[\\\"\\\",\\\"\\\"])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,\\\"<$1></$2>\\\")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f=\\\"table\\\"!==i||kb.test(f)?\\\"<table>\\\"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],\\\"tbody\\\")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent=\\\"\\\";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,\\\"input\\\"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),\\\"script\\\"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||\\\"\\\")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,\\\"script\\\")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,\\\"select\\\")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,\\\"\\\"):void 0;if(!(\\\"string\\\"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||[\\\"\\\",\\\"\\\"])[1].toLowerCase()])){a=a.replace(ib,\\\"<$1></$2>\\\");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&\\\"string\\\"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,\\\"script\\\"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,\\\"script\\\"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||\\\"\\\")&&!m._data(d,\\\"globalEval\\\")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||\\\"\\\").replace(qb,\\\"\\\")));i=c=null}return this}}),m.each({appendTo:\\\"append\\\",prependTo:\\\"prepend\\\",insertBefore:\\\"before\\\",insertAfter:\\\"after\\\",replaceAll:\\\"replaceWith\\\"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],\\\"display\\\");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),\\\"none\\\"!==c&&c||(Cb=(Cb||m(\\\"<iframe frameborder='0' width='0' height='0'/>\\\")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName(\\\"body\\\")[0],c&&c.style?(b=y.createElement(\\\"div\\\"),d=y.createElement(\\\"div\\\"),d.style.cssText=\\\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\\\",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText=\\\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\\\",b.appendChild(y.createElement(\\\"div\\\")).style.width=\\\"5px\\\",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp(\\\"^(\\\"+S+\\\")(?!px)[a-z%]+$\\\",\\\"i\\\"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(\\\"\\\"!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+\\\"\\\"}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left=\\\"fontSize\\\"===b?\\\"1em\\\":g,g=h.pixelLeft+\\\"px\\\",h.left=d,f&&(e.left=f)),void 0===g?g:g+\\\"\\\"||\\\"auto\\\"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement(\\\"div\\\"),b.innerHTML=\\\" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\\\",d=b.getElementsByTagName(\\\"a\\\")[0],c=d&&d.style){c.cssText=\\\"float:left;opacity:.5\\\",k.opacity=\\\"0.5\\\"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip=\\\"content-box\\\",b.cloneNode(!0).style.backgroundClip=\\\"\\\",k.clearCloneStyle=\\\"content-box\\\"===b.style.backgroundClip,k.boxSizing=\\\"\\\"===c.boxSizing||\\\"\\\"===c.MozBoxSizing||\\\"\\\"===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName(\\\"body\\\")[0],c&&c.style&&(b=y.createElement(\\\"div\\\"),d=y.createElement(\\\"div\\\"),d.style.cssText=\\\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\\\",c.appendChild(d).appendChild(b),b.style.cssText=\\\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute\\\",e=f=!1,h=!0,a.getComputedStyle&&(e=\\\"1%\\\"!==(a.getComputedStyle(b,null)||{}).top,f=\\\"4px\\\"===(a.getComputedStyle(b,null)||{width:\\\"4px\\\"}).width,i=b.appendChild(y.createElement(\\\"div\\\")),i.style.cssText=b.style.cssText=\\\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\\\",i.style.marginRight=i.style.width=\\\"0\\\",b.style.width=\\\"1px\\\",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML=\\\"<table><tr><td></td><td>t</td></tr></table>\\\",i=b.getElementsByTagName(\\\"td\\\"),i[0].style.cssText=\\\"margin:0;border:0;padding:0;display:none\\\",g=0===i[0].offsetHeight,g&&(i[0].style.display=\\\"\\\",i[1].style.display=\\\"none\\\",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\\\\([^)]*\\\\)/i,Nb=/opacity\\\\s*=\\\\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp(\\\"^(\\\"+S+\\\")(.*)$\\\",\\\"i\\\"),Qb=new RegExp(\\\"^([+-])=(\\\"+S+\\\")\\\",\\\"i\\\"),Rb={position:\\\"absolute\\\",visibility:\\\"hidden\\\",display:\\\"block\\\"},Sb={letterSpacing:\\\"0\\\",fontWeight:\\\"400\\\"},Tb=[\\\"Webkit\\\",\\\"O\\\",\\\"Moz\\\",\\\"ms\\\"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,\\\"olddisplay\\\"),c=d.style.display,b?(f[g]||\\\"none\\\"!==c||(d.style.display=\\\"\\\"),\\\"\\\"===d.style.display&&U(d)&&(f[g]=m._data(d,\\\"olddisplay\\\",Fb(d.nodeName)))):(e=U(d),(c&&\\\"none\\\"!==c||!e)&&m._data(d,\\\"olddisplay\\\",e?c:m.css(d,\\\"display\\\"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&\\\"none\\\"!==d.style.display&&\\\"\\\"!==d.style.display||(d.style.display=b?f[g]||\\\"\\\":\\\"none\\\"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||\\\"px\\\"):b}function Xb(a,b,c,d,e){for(var f=c===(d?\\\"border\\\":\\\"content\\\")?4:\\\"width\\\"===b?1:0,g=0;4>f;f+=2)\\\"margin\\\"===c&&(g+=m.css(a,c+T[f],!0,e)),d?(\\\"content\\\"===c&&(g-=m.css(a,\\\"padding\\\"+T[f],!0,e)),\\\"margin\\\"!==c&&(g-=m.css(a,\\\"border\\\"+T[f]+\\\"Width\\\",!0,e))):(g+=m.css(a,\\\"padding\\\"+T[f],!0,e),\\\"padding\\\"!==c&&(g+=m.css(a,\\\"border\\\"+T[f]+\\\"Width\\\",!0,e)));return g}function Yb(a,b,c){var d=!0,e=\\\"width\\\"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&\\\"border-box\\\"===m.css(a,\\\"boxSizing\\\",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?\\\"border\\\":\\\"content\\\"),d,f)+\\\"px\\\"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,\\\"opacity\\\");return\\\"\\\"===c?\\\"1\\\":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\\\"float\\\":k.cssFloat?\\\"cssFloat\\\":\\\"styleFloat\\\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&\\\"get\\\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,\\\"string\\\"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f=\\\"number\\\"),null!=c&&c===c&&(\\\"number\\\"!==f||m.cssNumber[h]||(c+=\\\"px\\\"),k.clearCloneStyle||\\\"\\\"!==c||0!==b.indexOf(\\\"background\\\")||(i[b]=\\\"inherit\\\"),!(g&&\\\"set\\\"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&\\\"get\\\"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),\\\"normal\\\"===f&&b in Sb&&(f=Sb[b]),\\\"\\\"===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each([\\\"height\\\",\\\"width\\\"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,\\\"display\\\"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&\\\"border-box\\\"===m.css(a,\\\"boxSizing\\\",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||\\\"\\\")?.01*parseFloat(RegExp.$1)+\\\"\\\":b?\\\"1\\\":\\\"\\\"},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?\\\"alpha(opacity=\\\"+100*b+\\\")\\\":\\\"\\\",f=d&&d.filter||c.filter||\\\"\\\";c.zoom=1,(b>=1||\\\"\\\"===b)&&\\\"\\\"===m.trim(f.replace(Mb,\\\"\\\"))&&c.removeAttribute&&(c.removeAttribute(\\\"filter\\\"),\\\"\\\"===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+\\\" \\\"+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:\\\"inline-block\\\"},Jb,[a,\\\"marginRight\\\"]):void 0}),m.each({margin:\\\"\\\",padding:\\\"\\\",border:\\\"Width\\\"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\\\"string\\\"==typeof c?c.split(\\\" \\\"):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return\\\"boolean\\\"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||\\\"swing\\\",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?\\\"\\\":\\\"px\\\")\\n},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,\\\"\\\"),b&&\\\"auto\\\"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp(\\\"^(?:([+-])=|)(\\\"+S+\\\")([a-z%]*)$\\\",\\\"i\\\"),cc=/queueHooks$/,dc=[ic],ec={\\\"*\\\":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?\\\"\\\":\\\"px\\\"),g=(m.cssNumber[a]||\\\"px\\\"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||\\\".5\\\",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d[\\\"margin\\\"+c]=d[\\\"padding\\\"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec[\\\"*\\\"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,\\\"fxshow\\\");c.queue||(h=m._queueHooks(a,\\\"fx\\\"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,\\\"fx\\\").length||h.empty.fire()})})),1===a.nodeType&&(\\\"height\\\"in b||\\\"width\\\"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,\\\"display\\\"),l=\\\"none\\\"===j?m._data(a,\\\"olddisplay\\\")||Fb(a.nodeName):j,\\\"inline\\\"===l&&\\\"none\\\"===m.css(a,\\\"float\\\")&&(k.inlineBlockNeedsLayout&&\\\"inline\\\"!==Fb(a.nodeName)?p.zoom=1:p.display=\\\"inline-block\\\")),c.overflow&&(p.overflow=\\\"hidden\\\",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||\\\"toggle\\\"===e,e===(q?\\\"hide\\\":\\\"show\\\")){if(\\\"show\\\"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))\\\"inline\\\"===(\\\"none\\\"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?\\\"hidden\\\"in r&&(q=r.hidden):r=m._data(a,\\\"fxshow\\\",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,\\\"fxshow\\\");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start=\\\"width\\\"===d||\\\"height\\\"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&\\\"expand\\\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=[\\\"*\\\"]):a=a.split(\\\" \\\");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&\\\"object\\\"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:\\\"number\\\"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue=\\\"fx\\\"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css(\\\"opacity\\\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,\\\"finish\\\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\\\"string\\\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\\\"fx\\\",[]),this.each(function(){var b=!0,e=null!=a&&a+\\\"queueHooks\\\",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\\\"fx\\\"),this.each(function(){var b,c=m._data(this),d=c[a+\\\"queue\\\"],e=c[a+\\\"queueHooks\\\"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each([\\\"toggle\\\",\\\"show\\\",\\\"hide\\\"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||\\\"boolean\\\"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc(\\\"show\\\"),slideUp:gc(\\\"hide\\\"),slideToggle:gc(\\\"toggle\\\"),fadeIn:{opacity:\\\"show\\\"},fadeOut:{opacity:\\\"hide\\\"},fadeToggle:{opacity:\\\"toggle\\\"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||\\\"fx\\\",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement(\\\"div\\\"),b.setAttribute(\\\"className\\\",\\\"t\\\"),b.innerHTML=\\\" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\\\",d=b.getElementsByTagName(\\\"a\\\")[0],c=y.createElement(\\\"select\\\"),e=c.appendChild(y.createElement(\\\"option\\\")),a=b.getElementsByTagName(\\\"input\\\")[0],d.style.cssText=\\\"top:1px\\\",k.getSetAttribute=\\\"t\\\"!==b.className,k.style=/top/.test(d.getAttribute(\\\"style\\\")),k.hrefNormalized=\\\"/a\\\"===d.getAttribute(\\\"href\\\"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement(\\\"form\\\").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement(\\\"input\\\"),a.setAttribute(\\\"value\\\",\\\"\\\"),k.input=\\\"\\\"===a.getAttribute(\\\"value\\\"),a.value=\\\"t\\\",a.setAttribute(\\\"type\\\",\\\"radio\\\"),k.radioValue=\\\"t\\\"===a.value}();var lc=/\\\\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e=\\\"\\\":\\\"number\\\"==typeof e?e+=\\\"\\\":m.isArray(e)&&(e=m.map(e,function(a){return null==a?\\\"\\\":a+\\\"\\\"})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&\\\"set\\\"in b&&void 0!==b.set(this,e,\\\"value\\\")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&\\\"get\\\"in b&&void 0!==(c=b.get(e,\\\"value\\\"))?c:(c=e.value,\\\"string\\\"==typeof c?c.replace(lc,\\\"\\\"):null==c?\\\"\\\":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,\\\"value\\\");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\\\"select-one\\\"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute(\\\"disabled\\\"))||c.parentNode.disabled&&m.nodeName(c.parentNode,\\\"optgroup\\\"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each([\\\"radio\\\",\\\"checkbox\\\"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute(\\\"value\\\")?\\\"on\\\":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&\\\"get\\\"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&\\\"set\\\"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+\\\"\\\"),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase(\\\"default-\\\"+c)]=a[d]=!1:m.attr(a,c,\\\"\\\"),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&\\\"radio\\\"===b&&m.nodeName(a,\\\"input\\\")){var c=a.value;return a.setAttribute(\\\"type\\\",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase(\\\"default-\\\"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\\\\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase(\\\"default-\\\"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,\\\"input\\\")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+=\\\"\\\",\\\"value\\\"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&\\\"\\\"!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,\\\"\\\"===b?!1:b,c)}},m.each([\\\"width\\\",\\\"height\\\"],function(a,b){m.attrHooks[b]={set:function(a,c){return\\\"\\\"===c?(a.setAttribute(b,\\\"auto\\\"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+\\\"\\\"}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{\\\"for\\\":\\\"htmlFor\\\",\\\"class\\\":\\\"className\\\"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&\\\"set\\\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\\\"get\\\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,\\\"tabindex\\\");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each([\\\"href\\\",\\\"src\\\"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each([\\\"tabIndex\\\",\\\"readOnly\\\",\\\"maxLength\\\",\\\"cellSpacing\\\",\\\"cellPadding\\\",\\\"rowSpan\\\",\\\"colSpan\\\",\\\"useMap\\\",\\\"frameBorder\\\",\\\"contentEditable\\\"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype=\\\"encoding\\\");var uc=/[\\\\t\\\\r\\\\n\\\\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=\\\"string\\\"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||\\\"\\\").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(\\\" \\\"+c.className+\\\" \\\").replace(uc,\\\" \\\"):\\\" \\\")){f=0;while(e=b[f++])d.indexOf(\\\" \\\"+e+\\\" \\\")<0&&(d+=e+\\\" \\\");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||\\\"string\\\"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||\\\"\\\").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(\\\" \\\"+c.className+\\\" \\\").replace(uc,\\\" \\\"):\\\"\\\")){f=0;while(e=b[f++])while(d.indexOf(\\\" \\\"+e+\\\" \\\")>=0)d=d.replace(\\\" \\\"+e+\\\" \\\",\\\" \\\");g=a?m.trim(d):\\\"\\\",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return\\\"boolean\\\"==typeof b&&\\\"string\\\"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if(\\\"string\\\"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||\\\"boolean\\\"===c)&&(this.className&&m._data(this,\\\"__className__\\\",this.className),this.className=this.className||a===!1?\\\"\\\":m._data(this,\\\"__className__\\\")||\\\"\\\")})},hasClass:function(a){for(var b=\\\" \\\"+a+\\\" \\\",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(\\\" \\\"+this[c].className+\\\" \\\").replace(uc,\\\" \\\").indexOf(b)>=0)return!0;return!1}}),m.each(\\\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\\\".split(\\\" \\\"),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\\\"**\\\"):this.off(b,a||\\\"**\\\",c)}});var vc=m.now(),wc=/\\\\?/,xc=/(,)|(\\\\[|{)|(}|])|\\\"(?:[^\\\"\\\\\\\\\\\\r\\\\n]|\\\\\\\\[\\\"\\\\\\\\\\\\/bfnrt]|\\\\\\\\u[\\\\da-fA-F]{4})*\\\"\\\\s*:?|true|false|null|-?(?!0\\\\d)\\\\d+(?:\\\\.\\\\d+|)(?:[eE][+-]?\\\\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+\\\"\\\");var c,d=null,e=m.trim(b+\\\"\\\");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,\\\"\\\")}))?Function(\\\"return \\\"+e)():m.error(\\\"Invalid JSON: \\\"+b)},m.parseXML=function(b){var c,d;if(!b||\\\"string\\\"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,\\\"text/xml\\\")):(c=new ActiveXObject(\\\"Microsoft.XMLDOM\\\"),c.async=\\\"false\\\",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName(\\\"parsererror\\\").length||m.error(\\\"Invalid XML: \\\"+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \\\\t]*([^\\\\r\\\\n]*)\\\\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\\\\/\\\\//,Gc=/^([\\\\w.+-]+:)(?:\\\\/\\\\/(?:[^\\\\/?#]*@|)([^\\\\/?#:]*)(?::(\\\\d+)|)|)/,Hc={},Ic={},Jc=\\\"*/\\\".concat(\\\"*\\\");try{zc=location.href}catch(Kc){zc=y.createElement(\\\"a\\\"),zc.href=\\\"\\\",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){\\\"string\\\"!=typeof b&&(c=b,b=\\\"*\\\");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])\\\"+\\\"===d.charAt(0)?(d=d.slice(1)||\\\"*\\\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return\\\"string\\\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\\\"*\\\"]&&g(\\\"*\\\")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\\\"*\\\"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader(\\\"Content-Type\\\"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+\\\" \\\"+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\\\"*\\\"===f)f=i;else if(\\\"*\\\"!==i&&i!==f){if(g=j[i+\\\" \\\"+f]||j[\\\"* \\\"+f],!g)for(e in j)if(h=e.split(\\\" \\\"),h[1]===f&&(g=j[i+\\\" \\\"+h[0]]||j[\\\"* \\\"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\\\"throws\\\"])b=g(b);else try{b=g(b)}catch(l){return{state:\\\"parsererror\\\",error:g?l:\\\"No conversion from \\\"+i+\\\" to \\\"+f}}}return{state:\\\"success\\\",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:\\\"GET\\\",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:\\\"application/x-www-form-urlencoded; charset=UTF-8\\\",accepts:{\\\"*\\\":Jc,text:\\\"text/plain\\\",html:\\\"text/html\\\",xml:\\\"application/xml, text/xml\\\",json:\\\"application/json, text/javascript\\\"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:\\\"responseXML\\\",text:\\\"responseText\\\",json:\\\"responseJSON\\\"},converters:{\\\"* text\\\":String,\\\"text html\\\":!0,\\\"text json\\\":m.parseJSON,\\\"text xml\\\":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){\\\"object\\\"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks(\\\"once memory\\\"),q=k.statusCode||{},r={},s={},t=0,u=\\\"canceled\\\",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+\\\"\\\").replace(Ac,\\\"\\\").replace(Fc,yc[1]+\\\"//\\\"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||\\\"*\\\").toLowerCase().match(E)||[\\\"\\\"],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||(\\\"http:\\\"===c[1]?\\\"80\\\":\\\"443\\\"))===(yc[3]||(\\\"http:\\\"===yc[1]?\\\"80\\\":\\\"443\\\")))),k.data&&k.processData&&\\\"string\\\"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger(\\\"ajaxStart\\\"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?\\\"&\\\":\\\"?\\\")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,\\\"$1_=\\\"+vc++):e+(wc.test(e)?\\\"&\\\":\\\"?\\\")+\\\"_=\\\"+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader(\\\"If-Modified-Since\\\",m.lastModified[e]),m.etag[e]&&v.setRequestHeader(\\\"If-None-Match\\\",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader(\\\"Content-Type\\\",k.contentType),v.setRequestHeader(\\\"Accept\\\",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+(\\\"*\\\"!==k.dataTypes[0]?\\\", \\\"+Jc+\\\"; q=0.01\\\":\\\"\\\"):k.accepts[\\\"*\\\"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u=\\\"abort\\\";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger(\\\"ajaxSend\\\",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort(\\\"timeout\\\")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,\\\"No Transport\\\");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||\\\"\\\",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader(\\\"Last-Modified\\\"),w&&(m.lastModified[e]=w),w=v.getResponseHeader(\\\"etag\\\"),w&&(m.etag[e]=w)),204===a||\\\"HEAD\\\"===k.type?x=\\\"nocontent\\\":304===a?x=\\\"notmodified\\\":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x=\\\"error\\\",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+\\\"\\\",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?\\\"ajaxSuccess\\\":\\\"ajaxError\\\",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger(\\\"ajaxComplete\\\",[v,k]),--m.active||m.event.trigger(\\\"ajaxStop\\\")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,\\\"json\\\")},getScript:function(a,b){return m.get(a,void 0,b,\\\"script\\\")}}),m.each([\\\"get\\\",\\\"post\\\"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each([\\\"ajaxStart\\\",\\\"ajaxStop\\\",\\\"ajaxComplete\\\",\\\"ajaxError\\\",\\\"ajaxSuccess\\\",\\\"ajaxSend\\\"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:\\\"GET\\\",dataType:\\\"script\\\",async:!1,global:!1,\\\"throws\\\":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,\\\"body\\\")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&\\\"none\\\"===(a.style&&a.style.display||m.css(a,\\\"display\\\"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\\\\[\\\\]$/,Sc=/\\\\r?\\\\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+\\\"[\\\"+(\\\"object\\\"==typeof e?b:\\\"\\\")+\\\"]\\\",e,c,d)});else if(c||\\\"object\\\"!==m.type(b))d(a,b);else for(e in b)Vc(a+\\\"[\\\"+e+\\\"]\\\",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?\\\"\\\":b,d[d.length]=encodeURIComponent(a)+\\\"=\\\"+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join(\\\"&\\\").replace(Qc,\\\"+\\\")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,\\\"elements\\\");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(\\\":disabled\\\")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,\\\"\\\\r\\\\n\\\")}}):{name:b.name,value:c.replace(Sc,\\\"\\\\r\\\\n\\\")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on(\\\"unload\\\",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&\\\"withCredentials\\\"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c[\\\"X-Requested-With\\\"]||(c[\\\"X-Requested-With\\\"]=\\\"XMLHttpRequest\\\");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+\\\"\\\");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,\\\"string\\\"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=\\\"\\\"}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject(\\\"Microsoft.XMLHTTP\\\")}catch(b){}}m.ajaxSetup({accepts:{script:\\\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\\\"},contents:{script:/(?:java|ecma)script/},converters:{\\\"text script\\\":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter(\\\"script\\\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\\\"GET\\\",a.global=!1)}),m.ajaxTransport(\\\"script\\\",function(a){if(a.crossDomain){var b,c=y.head||m(\\\"head\\\")[0]||y.documentElement;return{send:function(d,e){b=y.createElement(\\\"script\\\"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,\\\"success\\\"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\\\\?(?=&|$)|\\\\?\\\\?/;m.ajaxSetup({jsonp:\\\"callback\\\",jsonpCallback:function(){var a=_c.pop()||m.expando+\\\"_\\\"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter(\\\"json jsonp\\\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?\\\"url\\\":\\\"string\\\"==typeof b.data&&!(b.contentType||\\\"\\\").indexOf(\\\"application/x-www-form-urlencoded\\\")&&ad.test(b.data)&&\\\"data\\\");return h||\\\"jsonp\\\"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,\\\"$1\\\"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?\\\"&\\\":\\\"?\\\")+b.jsonp+\\\"=\\\"+e),b.converters[\\\"script json\\\"]=function(){return g||m.error(e+\\\" was not called\\\"),g[0]},b.dataTypes[0]=\\\"json\\\",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),\\\"script\\\"):void 0}),m.parseHTML=function(a,b,c){if(!a||\\\"string\\\"!=typeof a)return null;\\\"boolean\\\"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if(\\\"string\\\"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(\\\" \\\");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&\\\"object\\\"==typeof b&&(f=\\\"POST\\\"),g.length>0&&m.ajax({url:a,type:f,dataType:\\\"html\\\",data:b}).done(function(a){e=arguments,g.html(d?m(\\\"<div>\\\").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,\\\"position\\\"),l=m(a),n={};\\\"static\\\"===k&&(a.style.position=\\\"relative\\\"),h=l.offset(),f=m.css(a,\\\"top\\\"),i=m.css(a,\\\"left\\\"),j=(\\\"absolute\\\"===k||\\\"fixed\\\"===k)&&m.inArray(\\\"auto\\\",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),\\\"using\\\"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return\\\"fixed\\\"===m.css(d,\\\"position\\\")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],\\\"html\\\")||(c=a.offset()),c.top+=m.css(a[0],\\\"borderTopWidth\\\",!0),c.left+=m.css(a[0],\\\"borderLeftWidth\\\",!0)),{top:b.top-c.top-m.css(d,\\\"marginTop\\\",!0),left:b.left-c.left-m.css(d,\\\"marginLeft\\\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,\\\"html\\\")&&\\\"static\\\"===m.css(a,\\\"position\\\"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:\\\"pageXOffset\\\",scrollTop:\\\"pageYOffset\\\"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each([\\\"top\\\",\\\"left\\\"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+\\\"px\\\":c):void 0})}),m.each({Height:\\\"height\\\",Width:\\\"width\\\"},function(a,b){m.each({padding:\\\"inner\\\"+a,content:b,\\\"\\\":\\\"outer\\\"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||\\\"boolean\\\"!=typeof d),g=c||(d===!0||e===!0?\\\"margin\\\":\\\"border\\\");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement[\\\"client\\\"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body[\\\"scroll\\\"+a],e[\\\"scroll\\\"+a],b.body[\\\"offset\\\"+a],e[\\\"offset\\\"+a],e[\\\"client\\\"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,\\\"function\\\"==typeof define&&define.amd&&define(\\\"jquery\\\",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});\\n\\n /* END jquery-latest.min.js*/\\n\\n /* BEGIN jquery.dataTables.js */\\n\\n/*! DataTables 1.10.16-dev\\n * ©2008-2017 SpryMedia Ltd - datatables.net/license\\n */\\n\\n/**\\n * @summary DataTables\\n * @description Paginate, search and order HTML tables\\n * @version 1.10.16-dev\\n * @file jquery.dataTables.js\\n * @author SpryMedia Ltd\\n * @contact www.datatables.net\\n * @copyright Copyright 2008-2017 SpryMedia Ltd.\\n *\\n * This source file is free software, available under the following license:\\n * MIT license - http://datatables.net/license\\n *\\n * This source file is distributed in the hope that it will be useful, but\\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\\n *\\n * For details please refer to: http://www.datatables.net\\n */\\n\\n/*jslint evil: true, undef: true, browser: true */\\n/*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*/\\n\\n(function( factory ) {\\n\\t\\\"use strict\\\";\\n\\n\\tif ( typeof define === 'function' && define.amd ) {\\n\\t\\t// AMD\\n\\t\\tdefine( ['jquery'], function ( $ ) {\\n\\t\\t\\treturn factory( $, window, document );\\n\\t\\t} );\\n\\t}\\n\\telse if ( typeof exports === 'object' ) {\\n\\t\\t// CommonJS\\n\\t\\tmodule.exports = function (root, $) {\\n\\t\\t\\tif ( ! root ) {\\n\\t\\t\\t\\t// CommonJS environments without a window global must pass a\\n\\t\\t\\t\\t// root. This will give an error otherwise\\n\\t\\t\\t\\troot = window;\\n\\t\\t\\t}\\n\\n\\t\\t\\tif ( ! $ ) {\\n\\t\\t\\t\\t$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window\\n\\t\\t\\t\\t\\trequire('jquery') :\\n\\t\\t\\t\\t\\trequire('jquery')( root );\\n\\t\\t\\t}\\n\\n\\t\\t\\treturn factory( $, root, root.document );\\n\\t\\t};\\n\\t}\\n\\telse {\\n\\t\\t// Browser\\n\\t\\tfactory( jQuery, window, document );\\n\\t}\\n}\\n(function( $, window, document, undefined ) {\\n\\t\\\"use strict\\\";\\n\\n\\t/**\\n\\t * DataTables is a plug-in for the jQuery Javascript library. It is a highly\\n\\t * flexible tool, based upon the foundations of progressive enhancement,\\n\\t * which will add advanced interaction controls to any HTML table. For a\\n\\t * full list of features please refer to\\n\\t * [DataTables.net](href=\\\"http://datatables.net).\\n\\t *\\n\\t * Note that the `DataTable` object is not a global variable but is aliased\\n\\t * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may\\n\\t * be accessed.\\n\\t *\\n\\t * @class\\n\\t * @param {object} [init={}] Configuration object for DataTables. Options\\n\\t * are defined by {@link DataTable.defaults}\\n\\t * @requires jQuery 1.7+\\n\\t *\\n\\t * @example\\n\\t * // Basic initialisation\\n\\t * $(document).ready( function {\\n\\t * $('#example').dataTable();\\n\\t * } );\\n\\t *\\n\\t * @example\\n\\t * // Initialisation with configuration options - in this case, disable\\n\\t * // pagination and sorting.\\n\\t * $(document).ready( function {\\n\\t * $('#example').dataTable( {\\n\\t * \\\"paginate\\\": false,\\n\\t * \\\"sort\\\": false\\n\\t * } );\\n\\t * } );\\n\\t */\\n\\tvar DataTable = function ( options )\\n\\t{\\n\\t\\t/**\\n\\t\\t * Perform a jQuery selector action on the table's TR elements (from the tbody) and\\n\\t\\t * return the resulting jQuery object.\\n\\t\\t * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\\n\\t\\t * @param {object} [oOpts] Optional parameters for modifying the rows to be included\\n\\t\\t * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter\\n\\t\\t * criterion (\\\"applied\\\") or all TR elements (i.e. no filter).\\n\\t\\t * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.\\n\\t\\t * Can be either 'current', whereby the current sorting of the table is used, or\\n\\t\\t * 'original' whereby the original order the data was read into the table is used.\\n\\t\\t * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\\n\\t\\t * (\\\"current\\\") or not (\\\"all\\\"). If 'current' is given, then order is assumed to be\\n\\t\\t * 'current' and filter is 'applied', regardless of what they might be given as.\\n\\t\\t * @returns {object} jQuery object, filtered by the given selector.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Highlight every second row\\n\\t\\t * oTable.$('tr:odd').css('backgroundColor', 'blue');\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Filter to rows with 'Webkit' in them, add a background colour and then\\n\\t\\t * // remove the filter, thus highlighting the 'Webkit' rows only.\\n\\t\\t * oTable.fnFilter('Webkit');\\n\\t\\t * oTable.$('tr', {\\\"search\\\": \\\"applied\\\"}).css('backgroundColor', 'blue');\\n\\t\\t * oTable.fnFilter('');\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.$ = function ( sSelector, oOpts )\\n\\t\\t{\\n\\t\\t\\treturn this.api(true).$( sSelector, oOpts );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Almost identical to $ in operation, but in this case returns the data for the matched\\n\\t\\t * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes\\n\\t\\t * rather than any descendants, so the data can be obtained for the row/cell. If matching\\n\\t\\t * rows are found, the data returned is the original data array/object that was used to\\n\\t\\t * create the row (or a generated array if from a DOM source).\\n\\t\\t *\\n\\t\\t * This method is often useful in-combination with $ where both functions are given the\\n\\t\\t * same parameters and the array indexes will match identically.\\n\\t\\t * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\\n\\t\\t * @param {object} [oOpts] Optional parameters for modifying the rows to be included\\n\\t\\t * @param {string} [oOpts.filter=none] Select elements that meet the current filter\\n\\t\\t * criterion (\\\"applied\\\") or all elements (i.e. no filter).\\n\\t\\t * @param {string} [oOpts.order=current] Order of the data in the processed array.\\n\\t\\t * Can be either 'current', whereby the current sorting of the table is used, or\\n\\t\\t * 'original' whereby the original order the data was read into the table is used.\\n\\t\\t * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\\n\\t\\t * (\\\"current\\\") or not (\\\"all\\\"). If 'current' is given, then order is assumed to be\\n\\t\\t * 'current' and filter is 'applied', regardless of what they might be given as.\\n\\t\\t * @returns {array} Data for the matched elements. If any elements, as a result of the\\n\\t\\t * selector, were not TR, TD or TH elements in the DataTable, they will have a null\\n\\t\\t * entry in the array.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Get the data from the first row in the table\\n\\t\\t * var data = oTable._('tr:first');\\n\\t\\t *\\n\\t\\t * // Do something useful with the data\\n\\t\\t * alert( \\\"First cell is: \\\"+data[0] );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Filter to 'Webkit' and get all data for\\n\\t\\t * oTable.fnFilter('Webkit');\\n\\t\\t * var data = oTable._('tr', {\\\"search\\\": \\\"applied\\\"});\\n\\t\\t *\\n\\t\\t * // Do something with the data\\n\\t\\t * alert( data.length+\\\" rows matched the search\\\" );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis._ = function ( sSelector, oOpts )\\n\\t\\t{\\n\\t\\t\\treturn this.api(true).rows( sSelector, oOpts ).data();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Create a DataTables Api instance, with the currently selected tables for\\n\\t\\t * the Api's context.\\n\\t\\t * @param {boolean} [traditional=false] Set the API instance's context to be\\n\\t\\t * only the table referred to by the `DataTable.ext.iApiIndex` option, as was\\n\\t\\t * used in the API presented by DataTables 1.9- (i.e. the traditional mode),\\n\\t\\t * or if all tables captured in the jQuery object should be used.\\n\\t\\t * @return {DataTables.Api}\\n\\t\\t */\\n\\t\\tthis.api = function ( traditional )\\n\\t\\t{\\n\\t\\t\\treturn traditional ?\\n\\t\\t\\t\\tnew _Api(\\n\\t\\t\\t\\t\\t_fnSettingsFromNode( this[ _ext.iApiIndex ] )\\n\\t\\t\\t\\t) :\\n\\t\\t\\t\\tnew _Api( this );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Add a single new row or multiple rows of data to the table. Please note\\n\\t\\t * that this is suitable for client-side processing only - if you are using\\n\\t\\t * server-side processing (i.e. \\\"bServerSide\\\": true), then to add data, you\\n\\t\\t * must add it to the data source, i.e. the server-side, through an Ajax call.\\n\\t\\t * @param {array|object} data The data to be added to the table. This can be:\\n\\t\\t * <ul>\\n\\t\\t * <li>1D array of data - add a single row with the data provided</li>\\n\\t\\t * <li>2D array of arrays - add multiple rows in a single call</li>\\n\\t\\t * <li>object - data object when using <i>mData</i></li>\\n\\t\\t * <li>array of objects - multiple data objects when using <i>mData</i></li>\\n\\t\\t * </ul>\\n\\t\\t * @param {bool} [redraw=true] redraw the table or not\\n\\t\\t * @returns {array} An array of integers, representing the list of indexes in\\n\\t\\t * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to\\n\\t\\t * the table.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Global var for counter\\n\\t\\t * var giCount = 2;\\n\\t\\t *\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * function fnClickAddRow() {\\n\\t\\t * $('#example').dataTable().fnAddData( [\\n\\t\\t * giCount+\\\".1\\\",\\n\\t\\t * giCount+\\\".2\\\",\\n\\t\\t * giCount+\\\".3\\\",\\n\\t\\t * giCount+\\\".4\\\" ]\\n\\t\\t * );\\n\\t\\t *\\n\\t\\t * giCount++;\\n\\t\\t * }\\n\\t\\t */\\n\\t\\tthis.fnAddData = function( data, redraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\t/* Check if we want to add multiple rows or not */\\n\\t\\t\\tvar rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\\n\\t\\t\\t\\tapi.rows.add( data ) :\\n\\t\\t\\t\\tapi.row.add( data );\\n\\t\\t\\n\\t\\t\\tif ( redraw === undefined || redraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\treturn rows.flatten().toArray();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * This function will make DataTables recalculate the column sizes, based on the data\\n\\t\\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\\n\\t\\t * through the sWidth parameter). This can be useful when the width of the table's\\n\\t\\t * parent element changes (for example a window resize).\\n\\t\\t * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable( {\\n\\t\\t * \\\"sScrollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"bPaginate\\\": false\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * $(window).on('resize', function () {\\n\\t\\t * oTable.fnAdjustColumnSizing();\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnAdjustColumnSizing = function ( bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).columns.adjust();\\n\\t\\t\\tvar settings = api.settings()[0];\\n\\t\\t\\tvar scroll = settings.oScroll;\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw( false );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( scroll.sX !== \\\"\\\" || scroll.sY !== \\\"\\\" ) {\\n\\t\\t\\t\\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\\n\\t\\t\\t\\t_fnScrollDraw( settings );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Quickly and simply clear a table\\n\\t\\t * @param {bool} [bRedraw=true] redraw the table or not\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\\n\\t\\t * oTable.fnClearTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnClearTable = function( bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).clear();\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * The exact opposite of 'opening' a row, this function will close any rows which\\n\\t\\t * are currently 'open'.\\n\\t\\t * @param {node} nTr the table row to 'close'\\n\\t\\t * @returns {int} 0 on success, or 1 if failed (can't find the row)\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable;\\n\\t\\t *\\n\\t\\t * // 'open' an information row when a row is clicked on\\n\\t\\t * $('#example tbody tr').click( function () {\\n\\t\\t * if ( oTable.fnIsOpen(this) ) {\\n\\t\\t * oTable.fnClose( this );\\n\\t\\t * } else {\\n\\t\\t * oTable.fnOpen( this, \\\"Temporary row opened\\\", \\\"info_row\\\" );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnClose = function( nTr )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).row( nTr ).child.hide();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Remove a row for the table\\n\\t\\t * @param {mixed} target The index of the row from aoData to be deleted, or\\n\\t\\t * the TR element you want to delete\\n\\t\\t * @param {function|null} [callBack] Callback function\\n\\t\\t * @param {bool} [redraw=true] Redraw the table or not\\n\\t\\t * @returns {array} The row that was deleted\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Immediately remove the first row\\n\\t\\t * oTable.fnDeleteRow( 0 );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnDeleteRow = function( target, callback, redraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\tvar rows = api.rows( target );\\n\\t\\t\\tvar settings = rows.settings()[0];\\n\\t\\t\\tvar data = settings.aoData[ rows[0][0] ];\\n\\t\\t\\n\\t\\t\\trows.remove();\\n\\t\\t\\n\\t\\t\\tif ( callback ) {\\n\\t\\t\\t\\tcallback.call( this, settings, data );\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tif ( redraw === undefined || redraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\treturn data;\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Restore the table to it's original state in the DOM by removing all of DataTables\\n\\t\\t * enhancements, alterations to the DOM structure of the table and event listeners.\\n\\t\\t * @param {boolean} [remove=false] Completely remove the table from the DOM\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * // This example is fairly pointless in reality, but shows how fnDestroy can be used\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * oTable.fnDestroy();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnDestroy = function ( remove )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).destroy( remove );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Redraw the table\\n\\t\\t * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\\n\\t\\t * oTable.fnDraw();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnDraw = function( complete )\\n\\t\\t{\\n\\t\\t\\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\\n\\t\\t\\t// into account the new data, but can hold position.\\n\\t\\t\\tthis.api( true ).draw( complete );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Filter the input based on data\\n\\t\\t * @param {string} sInput String to filter the table on\\n\\t\\t * @param {int|null} [iColumn] Column to limit filtering to\\n\\t\\t * @param {bool} [bRegex=false] Treat as regular expression or not\\n\\t\\t * @param {bool} [bSmart=true] Perform smart filtering or not\\n\\t\\t * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\\n\\t\\t * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Sometime later - filter...\\n\\t\\t * oTable.fnFilter( 'test string' );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\tif ( iColumn === null || iColumn === undefined ) {\\n\\t\\t\\t\\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tapi.draw();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get the data for the whole table, an individual row or an individual cell based on the\\n\\t\\t * provided parameters.\\n\\t\\t * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\\n\\t\\t * a TR node then the data source for the whole row will be returned. If given as a\\n\\t\\t * TD/TH cell node then iCol will be automatically calculated and the data for the\\n\\t\\t * cell returned. If given as an integer, then this is treated as the aoData internal\\n\\t\\t * data index for the row (see fnGetPosition) and the data for that row used.\\n\\t\\t * @param {int} [col] Optional column index that you want the data of.\\n\\t\\t * @returns {array|object|string} If mRow is undefined, then the data for all rows is\\n\\t\\t * returned. If mRow is defined, just data for that row, and is iCol is\\n\\t\\t * defined, only data for the designated cell is returned.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Row data\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * oTable.$('tr').click( function () {\\n\\t\\t * var data = oTable.fnGetData( this );\\n\\t\\t * // ... do something with the array / object of data for the row\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Individual cell data\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * oTable.$('td').click( function () {\\n\\t\\t * var sData = oTable.fnGetData( this );\\n\\t\\t * alert( 'The cell clicked on had the value of '+sData );\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnGetData = function( src, col )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\tif ( src !== undefined ) {\\n\\t\\t\\t\\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\\n\\t\\t\\n\\t\\t\\t\\treturn col !== undefined || type == 'td' || type == 'th' ?\\n\\t\\t\\t\\t\\tapi.cell( src, col ).data() :\\n\\t\\t\\t\\t\\tapi.row( src ).data() || null;\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\treturn api.data().toArray();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get an array of the TR nodes that are used in the table's body. Note that you will\\n\\t\\t * typically want to use the '$' API method in preference to this as it is more\\n\\t\\t * flexible.\\n\\t\\t * @param {int} [iRow] Optional row index for the TR element you want\\n\\t\\t * @returns {array|node} If iRow is undefined, returns an array of all TR elements\\n\\t\\t * in the table's body, or iRow is defined, just the TR element requested.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Get the nodes from the table\\n\\t\\t * var nNodes = oTable.fnGetNodes( );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnGetNodes = function( iRow )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\treturn iRow !== undefined ?\\n\\t\\t\\t\\tapi.row( iRow ).node() :\\n\\t\\t\\t\\tapi.rows().nodes().flatten().toArray();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get the array indexes of a particular cell from it's DOM element\\n\\t\\t * and column index including hidden columns\\n\\t\\t * @param {node} node this can either be a TR, TD or TH in the table's body\\n\\t\\t * @returns {int} If nNode is given as a TR, then a single index is returned, or\\n\\t\\t * if given as a cell, an array of [row index, column index (visible),\\n\\t\\t * column index (all)] is given.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * $('#example tbody td').click( function () {\\n\\t\\t * // Get the position of the current data from the node\\n\\t\\t * var aPos = oTable.fnGetPosition( this );\\n\\t\\t *\\n\\t\\t * // Get the data array for this row\\n\\t\\t * var aData = oTable.fnGetData( aPos[0] );\\n\\t\\t *\\n\\t\\t * // Update the data array and return the value\\n\\t\\t * aData[ aPos[1] ] = 'clicked';\\n\\t\\t * this.innerHTML = 'clicked';\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * // Init DataTables\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnGetPosition = function( node )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\tvar nodeName = node.nodeName.toUpperCase();\\n\\t\\t\\n\\t\\t\\tif ( nodeName == 'TR' ) {\\n\\t\\t\\t\\treturn api.row( node ).index();\\n\\t\\t\\t}\\n\\t\\t\\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\\n\\t\\t\\t\\tvar cell = api.cell( node ).index();\\n\\t\\t\\n\\t\\t\\t\\treturn [\\n\\t\\t\\t\\t\\tcell.row,\\n\\t\\t\\t\\t\\tcell.columnVisible,\\n\\t\\t\\t\\t\\tcell.column\\n\\t\\t\\t\\t];\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Check to see if a row is 'open' or not.\\n\\t\\t * @param {node} nTr the table row to check\\n\\t\\t * @returns {boolean} true if the row is currently open, false otherwise\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable;\\n\\t\\t *\\n\\t\\t * // 'open' an information row when a row is clicked on\\n\\t\\t * $('#example tbody tr').click( function () {\\n\\t\\t * if ( oTable.fnIsOpen(this) ) {\\n\\t\\t * oTable.fnClose( this );\\n\\t\\t * } else {\\n\\t\\t * oTable.fnOpen( this, \\\"Temporary row opened\\\", \\\"info_row\\\" );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnIsOpen = function( nTr )\\n\\t\\t{\\n\\t\\t\\treturn this.api( true ).row( nTr ).child.isShown();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * This function will place a new row directly after a row which is currently\\n\\t\\t * on display on the page, with the HTML contents that is passed into the\\n\\t\\t * function. This can be used, for example, to ask for confirmation that a\\n\\t\\t * particular record should be deleted.\\n\\t\\t * @param {node} nTr The table row to 'open'\\n\\t\\t * @param {string|node|jQuery} mHtml The HTML to put into the row\\n\\t\\t * @param {string} sClass Class to give the new TD cell\\n\\t\\t * @returns {node} The row opened. Note that if the table row passed in as the\\n\\t\\t * first parameter, is not found in the table, this method will silently\\n\\t\\t * return.\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable;\\n\\t\\t *\\n\\t\\t * // 'open' an information row when a row is clicked on\\n\\t\\t * $('#example tbody tr').click( function () {\\n\\t\\t * if ( oTable.fnIsOpen(this) ) {\\n\\t\\t * oTable.fnClose( this );\\n\\t\\t * } else {\\n\\t\\t * oTable.fnOpen( this, \\\"Temporary row opened\\\", \\\"info_row\\\" );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * oTable = $('#example').dataTable();\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnOpen = function( nTr, mHtml, sClass )\\n\\t\\t{\\n\\t\\t\\treturn this.api( true )\\n\\t\\t\\t\\t.row( nTr )\\n\\t\\t\\t\\t.child( mHtml, sClass )\\n\\t\\t\\t\\t.show()\\n\\t\\t\\t\\t.child()[0];\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Change the pagination - provides the internal logic for pagination in a simple API\\n\\t\\t * function. With this function you can have a DataTables table go to the next,\\n\\t\\t * previous, first or last pages.\\n\\t\\t * @param {string|int} mAction Paging action to take: \\\"first\\\", \\\"previous\\\", \\\"next\\\" or \\\"last\\\"\\n\\t\\t * or page number to jump to (integer), note that page 0 is the first page.\\n\\t\\t * @param {bool} [bRedraw=true] Redraw the table or not\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * oTable.fnPageChange( 'next' );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnPageChange = function ( mAction, bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).page( mAction );\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw(false);\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Show a particular column\\n\\t\\t * @param {int} iCol The column whose display should be changed\\n\\t\\t * @param {bool} bShow Show (true) or hide (false) the column\\n\\t\\t * @param {bool} [bRedraw=true] Redraw the table or not\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Hide the second column after initialisation\\n\\t\\t * oTable.fnSetColumnVis( 1, false );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true ).column( iCol ).visible( bShow );\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.columns.adjust().draw();\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Get the settings for a particular table for external manipulation\\n\\t\\t * @returns {object} DataTables settings object. See\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * var oSettings = oTable.fnSettings();\\n\\t\\t *\\n\\t\\t * // Show an example parameter from the settings\\n\\t\\t * alert( oSettings._iDisplayStart );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSettings = function()\\n\\t\\t{\\n\\t\\t\\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Sort the table by a particular column\\n\\t\\t * @param {int} iCol the data index to sort on. Note that this will not match the\\n\\t\\t * 'display index' if you have hidden data entries\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Sort immediately with columns 0 and 1\\n\\t\\t * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSort = function( aaSort )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).order( aaSort ).draw();\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Attach a sort listener to an element for a given column\\n\\t\\t * @param {node} nNode the element to attach the sort listener to\\n\\t\\t * @param {int} iColumn the column that a click on this node will sort on\\n\\t\\t * @param {function} [fnCallback] callback function when sort is run\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t *\\n\\t\\t * // Sort on column 1, when 'sorter' is clicked on\\n\\t\\t * oTable.fnSortListener( document.getElementById('sorter'), 1 );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\\n\\t\\t{\\n\\t\\t\\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Update a table cell or row - this method will accept either a single value to\\n\\t\\t * update the cell with, an array of values with one element for each column or\\n\\t\\t * an object in the same format as the original data source. The function is\\n\\t\\t * self-referencing in order to make the multi column updates easier.\\n\\t\\t * @param {object|array|string} mData Data to update the cell/row with\\n\\t\\t * @param {node|int} mRow TR element you want to update or the aoData index\\n\\t\\t * @param {int} [iColumn] The column to update, give as null or undefined to\\n\\t\\t * update a whole row.\\n\\t\\t * @param {bool} [bRedraw=true] Redraw the table or not\\n\\t\\t * @param {bool} [bAction=true] Perform pre-draw actions or not\\n\\t\\t * @returns {int} 0 on success, 1 on error\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\\n\\t\\t * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\\n\\t\\t{\\n\\t\\t\\tvar api = this.api( true );\\n\\t\\t\\n\\t\\t\\tif ( iColumn === undefined || iColumn === null ) {\\n\\t\\t\\t\\tapi.row( mRow ).data( mData );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tapi.cell( mRow, iColumn ).data( mData );\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tif ( bAction === undefined || bAction ) {\\n\\t\\t\\t\\tapi.columns.adjust();\\n\\t\\t\\t}\\n\\t\\t\\n\\t\\t\\tif ( bRedraw === undefined || bRedraw ) {\\n\\t\\t\\t\\tapi.draw();\\n\\t\\t\\t}\\n\\t\\t\\treturn 0;\\n\\t\\t};\\n\\t\\t\\n\\t\\t\\n\\t\\t/**\\n\\t\\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\\n\\t\\t * to ensure compatibility.\\n\\t\\t * @param {string} sVersion Version string to check for, in the format \\\"X.Y.Z\\\". Note that the\\n\\t\\t * formats \\\"X\\\" and \\\"X.Y\\\" are also acceptable.\\n\\t\\t * @returns {boolean} true if this version of DataTables is greater or equal to the required\\n\\t\\t * version, or false if this version of DataTales is not suitable\\n\\t\\t * @method\\n\\t\\t * @dtopt API\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready(function() {\\n\\t\\t * var oTable = $('#example').dataTable();\\n\\t\\t * alert( oTable.fnVersionCheck( '1.9.0' ) );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tthis.fnVersionCheck = _ext.fnVersionCheck;\\n\\t\\t\\n\\n\\t\\tvar _that = this;\\n\\t\\tvar emptyInit = options === undefined;\\n\\t\\tvar len = this.length;\\n\\n\\t\\tif ( emptyInit ) {\\n\\t\\t\\toptions = {};\\n\\t\\t}\\n\\n\\t\\tthis.oApi = this.internal = _ext.internal;\\n\\n\\t\\t// Extend with old style plug-in API methods\\n\\t\\tfor ( var fn in DataTable.ext.internal ) {\\n\\t\\t\\tif ( fn ) {\\n\\t\\t\\t\\tthis[fn] = _fnExternApiFunc(fn);\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\tthis.each(function() {\\n\\t\\t\\t// For each initialisation we want to give it a clean initialisation\\n\\t\\t\\t// object that can be bashed around\\n\\t\\t\\tvar o = {};\\n\\t\\t\\tvar oInit = len > 1 ? // optimisation for single table case\\n\\t\\t\\t\\t_fnExtend( o, options, true ) :\\n\\t\\t\\t\\toptions;\\n\\n\\t\\t\\t/*global oInit,_that,emptyInit*/\\n\\t\\t\\tvar i=0, iLen, j, jLen, k, kLen;\\n\\t\\t\\tvar sId = this.getAttribute( 'id' );\\n\\t\\t\\tvar bInitHandedOff = false;\\n\\t\\t\\tvar defaults = DataTable.defaults;\\n\\t\\t\\tvar $this = $(this);\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t/* Sanity check */\\n\\t\\t\\tif ( this.nodeName.toLowerCase() != 'table' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Backwards compatibility for the defaults */\\n\\t\\t\\t_fnCompatOpts( defaults );\\n\\t\\t\\t_fnCompatCols( defaults.column );\\n\\t\\t\\t\\n\\t\\t\\t/* Convert the camel-case defaults to Hungarian */\\n\\t\\t\\t_fnCamelToHungarian( defaults, defaults, true );\\n\\t\\t\\t_fnCamelToHungarian( defaults.column, defaults.column, true );\\n\\t\\t\\t\\n\\t\\t\\t/* Setting up the initialisation object */\\n\\t\\t\\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t/* Check to see if we are re-initialising a table */\\n\\t\\t\\tvar allSettings = DataTable.settings;\\n\\t\\t\\tfor ( i=0, iLen=allSettings.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tvar s = allSettings[i];\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Base check on table node */\\n\\t\\t\\t\\tif ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tvar bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;\\n\\t\\t\\t\\t\\tvar bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;\\n\\t\\t\\t\\n\\t\\t\\t\\t\\tif ( emptyInit || bRetrieve )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\treturn s.oInstance;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( bDestroy )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\ts.oInstance.fnDestroy();\\n\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* If the element we are initialising has the same ID as a table which was previously\\n\\t\\t\\t\\t * initialised, but the table nodes don't match (from before) then we destroy the old\\n\\t\\t\\t\\t * instance by simply deleting it. This is under the assumption that the table has been\\n\\t\\t\\t\\t * destroyed by other methods. Anyone using non-id selectors will need to do this manually\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\tif ( s.sTableId == this.id )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tallSettings.splice( i, 1 );\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Ensure the table has an ID - required for accessibility */\\n\\t\\t\\tif ( sId === null || sId === \\\"\\\" )\\n\\t\\t\\t{\\n\\t\\t\\t\\tsId = \\\"DataTables_Table_\\\"+(DataTable.ext._unique++);\\n\\t\\t\\t\\tthis.id = sId;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Create the settings object for this table and set some of the default parameters */\\n\\t\\t\\tvar oSettings = $.extend( true, {}, DataTable.models.oSettings, {\\n\\t\\t\\t\\t\\\"sDestroyWidth\\\": $this[0].style.width,\\n\\t\\t\\t\\t\\\"sInstance\\\": sId,\\n\\t\\t\\t\\t\\\"sTableId\\\": sId\\n\\t\\t\\t} );\\n\\t\\t\\toSettings.nTable = this;\\n\\t\\t\\toSettings.oApi = _that.internal;\\n\\t\\t\\toSettings.oInit = oInit;\\n\\t\\t\\t\\n\\t\\t\\tallSettings.push( oSettings );\\n\\t\\t\\t\\n\\t\\t\\t// Need to add the instance after the instance after the settings object has been added\\n\\t\\t\\t// to the settings array, so we can self reference the table instance if more than one\\n\\t\\t\\toSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();\\n\\t\\t\\t\\n\\t\\t\\t// Backwards compatibility, before we apply all the defaults\\n\\t\\t\\t_fnCompatOpts( oInit );\\n\\t\\t\\t\\n\\t\\t\\tif ( oInit.oLanguage )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnLanguageCompat( oInit.oLanguage );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t// If the length menu is given, but the init display length is not, use the length menu\\n\\t\\t\\tif ( oInit.aLengthMenu && ! oInit.iDisplayLength )\\n\\t\\t\\t{\\n\\t\\t\\t\\toInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?\\n\\t\\t\\t\\t\\toInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t// Apply the defaults and init options to make a single init object will all\\n\\t\\t\\t// options defined from defaults and instance options.\\n\\t\\t\\toInit = _fnExtend( $.extend( true, {}, defaults ), oInit );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t// Map the initialisation options onto the settings object\\n\\t\\t\\t_fnMap( oSettings.oFeatures, oInit, [\\n\\t\\t\\t\\t\\\"bPaginate\\\",\\n\\t\\t\\t\\t\\\"bLengthChange\\\",\\n\\t\\t\\t\\t\\\"bFilter\\\",\\n\\t\\t\\t\\t\\\"bSort\\\",\\n\\t\\t\\t\\t\\\"bSortMulti\\\",\\n\\t\\t\\t\\t\\\"bInfo\\\",\\n\\t\\t\\t\\t\\\"bProcessing\\\",\\n\\t\\t\\t\\t\\\"bAutoWidth\\\",\\n\\t\\t\\t\\t\\\"bSortClasses\\\",\\n\\t\\t\\t\\t\\\"bServerSide\\\",\\n\\t\\t\\t\\t\\\"bDeferRender\\\"\\n\\t\\t\\t] );\\n\\t\\t\\t_fnMap( oSettings, oInit, [\\n\\t\\t\\t\\t\\\"asStripeClasses\\\",\\n\\t\\t\\t\\t\\\"ajax\\\",\\n\\t\\t\\t\\t\\\"fnServerData\\\",\\n\\t\\t\\t\\t\\\"fnFormatNumber\\\",\\n\\t\\t\\t\\t\\\"sServerMethod\\\",\\n\\t\\t\\t\\t\\\"aaSorting\\\",\\n\\t\\t\\t\\t\\\"aaSortingFixed\\\",\\n\\t\\t\\t\\t\\\"aLengthMenu\\\",\\n\\t\\t\\t\\t\\\"sPaginationType\\\",\\n\\t\\t\\t\\t\\\"sAjaxSource\\\",\\n\\t\\t\\t\\t\\\"sAjaxDataProp\\\",\\n\\t\\t\\t\\t\\\"iStateDuration\\\",\\n\\t\\t\\t\\t\\\"sDom\\\",\\n\\t\\t\\t\\t\\\"bSortCellsTop\\\",\\n\\t\\t\\t\\t\\\"iTabIndex\\\",\\n\\t\\t\\t\\t\\\"fnStateLoadCallback\\\",\\n\\t\\t\\t\\t\\\"fnStateSaveCallback\\\",\\n\\t\\t\\t\\t\\\"renderer\\\",\\n\\t\\t\\t\\t\\\"searchDelay\\\",\\n\\t\\t\\t\\t\\\"rowId\\\",\\n\\t\\t\\t\\t[ \\\"iCookieDuration\\\", \\\"iStateDuration\\\" ], // backwards compat\\n\\t\\t\\t\\t[ \\\"oSearch\\\", \\\"oPreviousSearch\\\" ],\\n\\t\\t\\t\\t[ \\\"aoSearchCols\\\", \\\"aoPreSearchCols\\\" ],\\n\\t\\t\\t\\t[ \\\"iDisplayLength\\\", \\\"_iDisplayLength\\\" ]\\n\\t\\t\\t] );\\n\\t\\t\\t_fnMap( oSettings.oScroll, oInit, [\\n\\t\\t\\t\\t[ \\\"sScrollX\\\", \\\"sX\\\" ],\\n\\t\\t\\t\\t[ \\\"sScrollXInner\\\", \\\"sXInner\\\" ],\\n\\t\\t\\t\\t[ \\\"sScrollY\\\", \\\"sY\\\" ],\\n\\t\\t\\t\\t[ \\\"bScrollCollapse\\\", \\\"bCollapse\\\" ]\\n\\t\\t\\t] );\\n\\t\\t\\t_fnMap( oSettings.oLanguage, oInit, \\\"fnInfoCallback\\\" );\\n\\t\\t\\t\\n\\t\\t\\t/* Callback functions which are array driven */\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );\\n\\t\\t\\t_fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );\\n\\t\\t\\t\\n\\t\\t\\toSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );\\n\\t\\t\\t\\n\\t\\t\\t/* Browser support detection */\\n\\t\\t\\t_fnBrowserDetect( oSettings );\\n\\t\\t\\t\\n\\t\\t\\tvar oClasses = oSettings.oClasses;\\n\\t\\t\\t\\n\\t\\t\\t$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );\\n\\t\\t\\t$this.addClass( oClasses.sTable );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\tif ( oSettings.iInitDisplayStart === undefined )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Display start point, taking into account the save saving */\\n\\t\\t\\t\\toSettings.iInitDisplayStart = oInit.iDisplayStart;\\n\\t\\t\\t\\toSettings._iDisplayStart = oInit.iDisplayStart;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\tif ( oInit.iDeferLoading !== null )\\n\\t\\t\\t{\\n\\t\\t\\t\\toSettings.bDeferLoading = true;\\n\\t\\t\\t\\tvar tmp = $.isArray( oInit.iDeferLoading );\\n\\t\\t\\t\\toSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;\\n\\t\\t\\t\\toSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Language definitions */\\n\\t\\t\\tvar oLanguage = oSettings.oLanguage;\\n\\t\\t\\t$.extend( true, oLanguage, oInit.oLanguage );\\n\\t\\t\\t\\n\\t\\t\\tif ( oLanguage.sUrl )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Get the language definitions from a file - because this Ajax call makes the language\\n\\t\\t\\t\\t * get async to the remainder of this function we use bInitHandedOff to indicate that\\n\\t\\t\\t\\t * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t$.ajax( {\\n\\t\\t\\t\\t\\tdataType: 'json',\\n\\t\\t\\t\\t\\turl: oLanguage.sUrl,\\n\\t\\t\\t\\t\\tsuccess: function ( json ) {\\n\\t\\t\\t\\t\\t\\t_fnLanguageCompat( json );\\n\\t\\t\\t\\t\\t\\t_fnCamelToHungarian( defaults.oLanguage, json );\\n\\t\\t\\t\\t\\t\\t$.extend( true, oLanguage, json );\\n\\t\\t\\t\\t\\t\\t_fnInitialise( oSettings );\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\terror: function () {\\n\\t\\t\\t\\t\\t\\t// Error occurred loading language file, continue on as best we can\\n\\t\\t\\t\\t\\t\\t_fnInitialise( oSettings );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} );\\n\\t\\t\\t\\tbInitHandedOff = true;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/*\\n\\t\\t\\t * Stripes\\n\\t\\t\\t */\\n\\t\\t\\tif ( oInit.asStripeClasses === null )\\n\\t\\t\\t{\\n\\t\\t\\t\\toSettings.asStripeClasses =[\\n\\t\\t\\t\\t\\toClasses.sStripeOdd,\\n\\t\\t\\t\\t\\toClasses.sStripeEven\\n\\t\\t\\t\\t];\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Remove row stripe classes if they are already on the table row */\\n\\t\\t\\tvar stripeClasses = oSettings.asStripeClasses;\\n\\t\\t\\tvar rowOne = $this.children('tbody').find('tr').eq(0);\\n\\t\\t\\tif ( $.inArray( true, $.map( stripeClasses, function(el, i) {\\n\\t\\t\\t\\treturn rowOne.hasClass(el);\\n\\t\\t\\t} ) ) !== -1 ) {\\n\\t\\t\\t\\t$('tbody tr', this).removeClass( stripeClasses.join(' ') );\\n\\t\\t\\t\\toSettings.asDestroyStripes = stripeClasses.slice();\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/*\\n\\t\\t\\t * Columns\\n\\t\\t\\t * See if we should load columns automatically or use defined ones\\n\\t\\t\\t */\\n\\t\\t\\tvar anThs = [];\\n\\t\\t\\tvar aoColumnsInit;\\n\\t\\t\\tvar nThead = this.getElementsByTagName('thead');\\n\\t\\t\\tif ( nThead.length !== 0 )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnDetectHeader( oSettings.aoHeader, nThead[0] );\\n\\t\\t\\t\\tanThs = _fnGetUniqueThs( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* If not given a column array, generate one with nulls */\\n\\t\\t\\tif ( oInit.aoColumns === null )\\n\\t\\t\\t{\\n\\t\\t\\t\\taoColumnsInit = [];\\n\\t\\t\\t\\tfor ( i=0, iLen=anThs.length ; i<iLen ; i++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taoColumnsInit.push( null );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\telse\\n\\t\\t\\t{\\n\\t\\t\\t\\taoColumnsInit = oInit.aoColumns;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Add the columns */\\n\\t\\t\\tfor ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnAddColumn( oSettings, anThs ? anThs[i] : null );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t/* Apply the column definitions */\\n\\t\\t\\t_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {\\n\\t\\t\\t\\t_fnColumnOptions( oSettings, iCol, oDef );\\n\\t\\t\\t} );\\n\\t\\t\\t\\n\\t\\t\\t/* HTML5 attribute detection - build an mData object automatically if the\\n\\t\\t\\t * attributes are found\\n\\t\\t\\t */\\n\\t\\t\\tif ( rowOne.length ) {\\n\\t\\t\\t\\tvar a = function ( cell, name ) {\\n\\t\\t\\t\\t\\treturn cell.getAttribute( 'data-'+name ) !== null ? name : null;\\n\\t\\t\\t\\t};\\n\\t\\t\\t\\n\\t\\t\\t\\t$( rowOne[0] ).children('th, td').each( function (i, cell) {\\n\\t\\t\\t\\t\\tvar col = oSettings.aoColumns[i];\\n\\t\\t\\t\\n\\t\\t\\t\\t\\tif ( col.mData === i ) {\\n\\t\\t\\t\\t\\t\\tvar sort = a( cell, 'sort' ) || a( cell, 'order' );\\n\\t\\t\\t\\t\\t\\tvar filter = a( cell, 'filter' ) || a( cell, 'search' );\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\tif ( sort !== null || filter !== null ) {\\n\\t\\t\\t\\t\\t\\t\\tcol.mData = {\\n\\t\\t\\t\\t\\t\\t\\t\\t_: i+'.display',\\n\\t\\t\\t\\t\\t\\t\\t\\tsort: sort !== null ? i+'.@data-'+sort : undefined,\\n\\t\\t\\t\\t\\t\\t\\t\\ttype: sort !== null ? i+'.@data-'+sort : undefined,\\n\\t\\t\\t\\t\\t\\t\\t\\tfilter: filter !== null ? i+'.@data-'+filter : undefined\\n\\t\\t\\t\\t\\t\\t\\t};\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t_fnColumnOptions( oSettings, i );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\tvar features = oSettings.oFeatures;\\n\\t\\t\\tvar loadedInit = function () {\\n\\t\\t\\t\\t/*\\n\\t\\t\\t\\t * Sorting\\n\\t\\t\\t\\t * @todo For modularisation (1.11) this needs to do into a sort start up handler\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\n\\t\\t\\t\\t// If aaSorting is not defined, then we use the first indicator in asSorting\\n\\t\\t\\t\\t// in case that has been altered, so the default sort reflects that option\\n\\t\\t\\t\\tif ( oInit.aaSorting === undefined ) {\\n\\t\\t\\t\\t\\tvar sorting = oSettings.aaSorting;\\n\\t\\t\\t\\t\\tfor ( i=0, iLen=sorting.length ; i<iLen ; i++ ) {\\n\\t\\t\\t\\t\\t\\tsorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Do a first pass on the sorting classes (allows any size changes to be taken into\\n\\t\\t\\t\\t * account, and also will apply sorting disabled classes if disabled\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t_fnSortingClasses( oSettings );\\n\\t\\t\\t\\n\\t\\t\\t\\tif ( features.bSort ) {\\n\\t\\t\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\\n\\t\\t\\t\\t\\t\\tif ( oSettings.bSorted ) {\\n\\t\\t\\t\\t\\t\\t\\tvar aSort = _fnSortFlatten( oSettings );\\n\\t\\t\\t\\t\\t\\t\\tvar sortedColumns = {};\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t$.each( aSort, function (i, val) {\\n\\t\\t\\t\\t\\t\\t\\t\\tsortedColumns[ val.src ] = val.dir;\\n\\t\\t\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\n\\t\\t\\t\\t\\t\\t\\t_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );\\n\\t\\t\\t\\t\\t\\t\\t_fnSortAria( oSettings );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\\n\\t\\t\\t\\t\\tif ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {\\n\\t\\t\\t\\t\\t\\t_fnSortingClasses( oSettings );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}, 'sc' );\\n\\t\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\t/*\\n\\t\\t\\t\\t * Final init\\n\\t\\t\\t\\t * Cache the header, body and footer as required, creating them if needed\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\n\\t\\t\\t\\t// Work around for Webkit bug 83867 - store the caption-side before removing from doc\\n\\t\\t\\t\\tvar captions = $this.children('caption').each( function () {\\n\\t\\t\\t\\t\\tthis._captionSide = $(this).css('caption-side');\\n\\t\\t\\t\\t} );\\n\\t\\t\\t\\n\\t\\t\\t\\tvar thead = $this.children('thead');\\n\\t\\t\\t\\tif ( thead.length === 0 ) {\\n\\t\\t\\t\\t\\tthead = $('<thead/>').appendTo($this);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\toSettings.nTHead = thead[0];\\n\\t\\t\\t\\n\\t\\t\\t\\tvar tbody = $this.children('tbody');\\n\\t\\t\\t\\tif ( tbody.length === 0 ) {\\n\\t\\t\\t\\t\\ttbody = $('<tbody/>').appendTo($this);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\toSettings.nTBody = tbody[0];\\n\\t\\t\\t\\n\\t\\t\\t\\tvar tfoot = $this.children('tfoot');\\n\\t\\t\\t\\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \\\"\\\" || oSettings.oScroll.sY !== \\\"\\\") ) {\\n\\t\\t\\t\\t\\t// If we are a scrolling table, and no footer has been given, then we need to create\\n\\t\\t\\t\\t\\t// a tfoot element for the caption element to be appended to\\n\\t\\t\\t\\t\\ttfoot = $('<tfoot/>').appendTo($this);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\\n\\t\\t\\t\\t\\t$this.addClass( oClasses.sNoFooter );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( tfoot.length > 0 ) {\\n\\t\\t\\t\\t\\toSettings.nTFoot = tfoot[0];\\n\\t\\t\\t\\t\\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Check if there is data passing into the constructor */\\n\\t\\t\\t\\tif ( oInit.aaData ) {\\n\\t\\t\\t\\t\\tfor ( i=0 ; i<oInit.aaData.length ; i++ ) {\\n\\t\\t\\t\\t\\t\\t_fnAddData( oSettings, oInit.aaData[ i ] );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' ) {\\n\\t\\t\\t\\t\\t/* Grab the data from the page - only do this when deferred loading or no Ajax\\n\\t\\t\\t\\t\\t * source since there is no point in reading the DOM data if we are then going\\n\\t\\t\\t\\t\\t * to replace it with Ajax data\\n\\t\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\t_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Copy the data index array */\\n\\t\\t\\t\\toSettings.aiDisplay = oSettings.aiDisplayMaster.slice();\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Initialisation complete - table can be drawn */\\n\\t\\t\\t\\toSettings.bInitialised = true;\\n\\t\\t\\t\\n\\t\\t\\t\\t/* Check if we need to initialise the table (it might not have been handed off to the\\n\\t\\t\\t\\t * language processor)\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\tif ( bInitHandedOff === false ) {\\n\\t\\t\\t\\t\\t_fnInitialise( oSettings );\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\t\\t\\n\\t\\t\\t/* Must be done after everything which can be overridden by the state saving! */\\n\\t\\t\\tif ( oInit.bStateSave )\\n\\t\\t\\t{\\n\\t\\t\\t\\tfeatures.bStateSave = true;\\n\\t\\t\\t\\t_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );\\n\\t\\t\\t\\t_fnLoadState( oSettings, oInit, loadedInit );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tloadedInit();\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t} );\\n\\t\\t_that = null;\\n\\t\\treturn this;\\n\\t};\\n\\n\\t\\n\\t/*\\n\\t * It is useful to have variables which are scoped locally so only the\\n\\t * DataTables functions can access them and they don't leak into global space.\\n\\t * At the same time these functions are often useful over multiple files in the\\n\\t * core and API, so we list, or at least document, all variables which are used\\n\\t * by DataTables as private variables here. This also ensures that there is no\\n\\t * clashing of variable names and that they can easily referenced for reuse.\\n\\t */\\n\\t\\n\\t\\n\\t// Defined else where\\n\\t// _selector_run\\n\\t// _selector_opts\\n\\t// _selector_first\\n\\t// _selector_row_indexes\\n\\t\\n\\tvar _ext; // DataTable.ext\\n\\tvar _Api; // DataTable.Api\\n\\tvar _api_register; // DataTable.Api.register\\n\\tvar _api_registerPlural; // DataTable.Api.registerPlural\\n\\t\\n\\tvar _re_dic = {};\\n\\tvar _re_new_lines = /[\\\\r\\\\n]/g;\\n\\tvar _re_html = /<.*?>/g;\\n\\t\\n\\t// This is not strict ISO8601 - Date.parse() is quite lax, although\\n\\t// implementations differ between browsers.\\n\\tvar _re_date = /^\\\\d{2,4}[\\\\.\\\\/\\\\-]\\\\d{1,2}[\\\\.\\\\/\\\\-]\\\\d{1,2}([T ]{1}\\\\d{1,2}[:\\\\.]\\\\d{2}([\\\\.:]\\\\d{2})?)?$/;\\n\\t\\n\\t// Escape regular expression special characters\\n\\tvar _re_escape_regex = new RegExp( '(\\\\\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\\\\\', '$', '^', '-' ].join('|\\\\\\\\') + ')', 'g' );\\n\\t\\n\\t// http://en.wikipedia.org/wiki/Foreign_exchange_market\\n\\t// - \\\\u20BD - Russian ruble.\\n\\t// - \\\\u20a9 - South Korean Won\\n\\t// - \\\\u20BA - Turkish Lira\\n\\t// - \\\\u20B9 - Indian Rupee\\n\\t// - R - Brazil (R$) and South Africa\\n\\t// - fr - Swiss Franc\\n\\t// - kr - Swedish krona, Norwegian krone and Danish krone\\n\\t// - \\\\u2009 is thin space and \\\\u202F is narrow no-break space, both used in many\\n\\t// standards as thousands separators.\\n\\tvar _re_formatted_numeric = /[',$£€¥%\\\\u2009\\\\u202F\\\\u20BD\\\\u20a9\\\\u20BArfk]/gi;\\n\\t\\n\\t\\n\\tvar _empty = function ( d ) {\\n\\t\\treturn !d || d === true || d === '-' ? true : false;\\n\\t};\\n\\t\\n\\t\\n\\tvar _intVal = function ( s ) {\\n\\t\\tvar integer = parseInt( s, 10 );\\n\\t\\treturn !isNaN(integer) && isFinite(s) ? integer : null;\\n\\t};\\n\\t\\n\\t// Convert from a formatted number with characters other than `.` as the\\n\\t// decimal place, to a Javascript number\\n\\tvar _numToDecimal = function ( num, decimalPoint ) {\\n\\t\\t// Cache created regular expressions for speed as this function is called often\\n\\t\\tif ( ! _re_dic[ decimalPoint ] ) {\\n\\t\\t\\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\\n\\t\\t}\\n\\t\\treturn typeof num === 'string' && decimalPoint !== '.' ?\\n\\t\\t\\tnum.replace( /\\\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\\n\\t\\t\\tnum;\\n\\t};\\n\\t\\n\\t\\n\\tvar _isNumber = function ( d, decimalPoint, formatted ) {\\n\\t\\tvar strType = typeof d === 'string';\\n\\t\\n\\t\\t// If empty return immediately so there must be a number if it is a\\n\\t\\t// formatted string (this stops the string \\\"k\\\", or \\\"kr\\\", etc being detected\\n\\t\\t// as a formatted number for currency\\n\\t\\tif ( _empty( d ) ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\tif ( decimalPoint && strType ) {\\n\\t\\t\\td = _numToDecimal( d, decimalPoint );\\n\\t\\t}\\n\\t\\n\\t\\tif ( formatted && strType ) {\\n\\t\\t\\td = d.replace( _re_formatted_numeric, '' );\\n\\t\\t}\\n\\t\\n\\t\\treturn !isNaN( parseFloat(d) ) && isFinite( d );\\n\\t};\\n\\t\\n\\t\\n\\t// A string without HTML in it can be considered to be HTML still\\n\\tvar _isHtml = function ( d ) {\\n\\t\\treturn _empty( d ) || typeof d === 'string';\\n\\t};\\n\\t\\n\\t\\n\\tvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\\n\\t\\tif ( _empty( d ) ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\tvar html = _isHtml( d );\\n\\t\\treturn ! html ?\\n\\t\\t\\tnull :\\n\\t\\t\\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\\n\\t\\t\\t\\ttrue :\\n\\t\\t\\t\\tnull;\\n\\t};\\n\\t\\n\\t\\n\\tvar _pluck = function ( a, prop, prop2 ) {\\n\\t\\tvar out = [];\\n\\t\\tvar i=0, ien=a.length;\\n\\t\\n\\t\\t// Could have the test in the loop for slightly smaller code, but speed\\n\\t\\t// is essential here\\n\\t\\tif ( prop2 !== undefined ) {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( a[i] && a[i][ prop ] ) {\\n\\t\\t\\t\\t\\tout.push( a[i][ prop ][ prop2 ] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( a[i] ) {\\n\\t\\t\\t\\t\\tout.push( a[i][ prop ] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\t// Basically the same as _pluck, but rather than looping over `a` we use `order`\\n\\t// as the indexes to pick from `a`\\n\\tvar _pluck_order = function ( a, order, prop, prop2 )\\n\\t{\\n\\t\\tvar out = [];\\n\\t\\tvar i=0, ien=order.length;\\n\\t\\n\\t\\t// Could have the test in the loop for slightly smaller code, but speed\\n\\t\\t// is essential here\\n\\t\\tif ( prop2 !== undefined ) {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( a[ order[i] ][ prop ] ) {\\n\\t\\t\\t\\t\\tout.push( a[ order[i] ][ prop ][ prop2 ] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tfor ( ; i<ien ; i++ ) {\\n\\t\\t\\t\\tout.push( a[ order[i] ][ prop ] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\tvar _range = function ( len, start )\\n\\t{\\n\\t\\tvar out = [];\\n\\t\\tvar end;\\n\\t\\n\\t\\tif ( start === undefined ) {\\n\\t\\t\\tstart = 0;\\n\\t\\t\\tend = len;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tend = start;\\n\\t\\t\\tstart = len;\\n\\t\\t}\\n\\t\\n\\t\\tfor ( var i=start ; i<end ; i++ ) {\\n\\t\\t\\tout.push( i );\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\tvar _removeEmpty = function ( a )\\n\\t{\\n\\t\\tvar out = [];\\n\\t\\n\\t\\tfor ( var i=0, ien=a.length ; i<ien ; i++ ) {\\n\\t\\t\\tif ( a[i] ) { // careful - will remove all falsy values!\\n\\t\\t\\t\\tout.push( a[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\tvar _stripHtml = function ( d ) {\\n\\t\\treturn d.replace( _re_html, '' );\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Determine if all values in the array are unique. This means we can short\\n\\t * cut the _unique method at the cost of a single loop. A sorted array is used\\n\\t * to easily check the values.\\n\\t *\\n\\t * @param {array} src Source array\\n\\t * @return {boolean} true if all unique, false otherwise\\n\\t * @ignore\\n\\t */\\n\\tvar _areAllUnique = function ( src ) {\\n\\t\\tif ( src.length < 2 ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\tvar sorted = src.slice().sort();\\n\\t\\tvar last = sorted[0];\\n\\t\\n\\t\\tfor ( var i=1, ien=sorted.length ; i<ien ; i++ ) {\\n\\t\\t\\tif ( sorted[i] === last ) {\\n\\t\\t\\t\\treturn false;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tlast = sorted[i];\\n\\t\\t}\\n\\t\\n\\t\\treturn true;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Find the unique elements in a source array.\\n\\t *\\n\\t * @param {array} src Source array\\n\\t * @return {array} Array of unique items\\n\\t * @ignore\\n\\t */\\n\\tvar _unique = function ( src )\\n\\t{\\n\\t\\tif ( _areAllUnique( src ) ) {\\n\\t\\t\\treturn src.slice();\\n\\t\\t}\\n\\t\\n\\t\\t// A faster unique method is to use object keys to identify used values,\\n\\t\\t// but this doesn't work with arrays or objects, which we must also\\n\\t\\t// consider. See jsperf.com/compare-array-unique-versions/4 for more\\n\\t\\t// information.\\n\\t\\tvar\\n\\t\\t\\tout = [],\\n\\t\\t\\tval,\\n\\t\\t\\ti, ien=src.length,\\n\\t\\t\\tj, k=0;\\n\\t\\n\\t\\tagain: for ( i=0 ; i<ien ; i++ ) {\\n\\t\\t\\tval = src[i];\\n\\t\\n\\t\\t\\tfor ( j=0 ; j<k ; j++ ) {\\n\\t\\t\\t\\tif ( out[j] === val ) {\\n\\t\\t\\t\\t\\tcontinue again;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tout.push( val );\\n\\t\\t\\tk++;\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables utility methods\\n\\t * \\n\\t * This namespace provides helper methods that DataTables uses internally to\\n\\t * create a DataTable, but which are not exclusively used only for DataTables.\\n\\t * These methods can be used by extension authors to save the duplication of\\n\\t * code.\\n\\t *\\n\\t * @namespace\\n\\t */\\n\\tDataTable.util = {\\n\\t\\t/**\\n\\t\\t * Throttle the calls to a function. Arguments and context are maintained\\n\\t\\t * for the throttled function.\\n\\t\\t *\\n\\t\\t * @param {function} fn Function to be called\\n\\t\\t * @param {integer} freq Call frequency in mS\\n\\t\\t * @return {function} Wrapped function\\n\\t\\t */\\n\\t\\tthrottle: function ( fn, freq ) {\\n\\t\\t\\tvar\\n\\t\\t\\t\\tfrequency = freq !== undefined ? freq : 200,\\n\\t\\t\\t\\tlast,\\n\\t\\t\\t\\ttimer;\\n\\t\\n\\t\\t\\treturn function () {\\n\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\tthat = this,\\n\\t\\t\\t\\t\\tnow = +new Date(),\\n\\t\\t\\t\\t\\targs = arguments;\\n\\t\\n\\t\\t\\t\\tif ( last && now < last + frequency ) {\\n\\t\\t\\t\\t\\tclearTimeout( timer );\\n\\t\\n\\t\\t\\t\\t\\ttimer = setTimeout( function () {\\n\\t\\t\\t\\t\\t\\tlast = undefined;\\n\\t\\t\\t\\t\\t\\tfn.apply( that, args );\\n\\t\\t\\t\\t\\t}, frequency );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tlast = now;\\n\\t\\t\\t\\t\\tfn.apply( that, args );\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Escape a string such that it can be used in a regular expression\\n\\t\\t *\\n\\t\\t * @param {string} val string to escape\\n\\t\\t * @returns {string} escaped string\\n\\t\\t */\\n\\t\\tescapeRegex: function ( val ) {\\n\\t\\t\\treturn val.replace( _re_escape_regex, '\\\\\\\\$1' );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Create a mapping object that allows camel case parameters to be looked up\\n\\t * for their Hungarian counterparts. The mapping is stored in a private\\n\\t * parameter called `_hungarianMap` which can be accessed on the source object.\\n\\t * @param {object} o\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnHungarianMap ( o )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\thungarian = 'a aa ai ao as b fn i m o s ',\\n\\t\\t\\tmatch,\\n\\t\\t\\tnewKey,\\n\\t\\t\\tmap = {};\\n\\t\\n\\t\\t$.each( o, function (key, val) {\\n\\t\\t\\tmatch = key.match(/^([^A-Z]+?)([A-Z])/);\\n\\t\\n\\t\\t\\tif ( match && hungarian.indexOf(match[1]+' ') !== -1 )\\n\\t\\t\\t{\\n\\t\\t\\t\\tnewKey = key.replace( match[0], match[2].toLowerCase() );\\n\\t\\t\\t\\tmap[ newKey ] = key;\\n\\t\\n\\t\\t\\t\\tif ( match[1] === 'o' )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t_fnHungarianMap( o[key] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\to._hungarianMap = map;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from camel case parameters to Hungarian, based on a Hungarian map\\n\\t * created by _fnHungarianMap.\\n\\t * @param {object} src The model object which holds all parameters that can be\\n\\t * mapped.\\n\\t * @param {object} user The object to convert from camel case to Hungarian.\\n\\t * @param {boolean} force When set to `true`, properties which already have a\\n\\t * Hungarian value in the `user` object will be overwritten. Otherwise they\\n\\t * won't be.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCamelToHungarian ( src, user, force )\\n\\t{\\n\\t\\tif ( ! src._hungarianMap ) {\\n\\t\\t\\t_fnHungarianMap( src );\\n\\t\\t}\\n\\t\\n\\t\\tvar hungarianKey;\\n\\t\\n\\t\\t$.each( user, function (key, val) {\\n\\t\\t\\thungarianKey = src._hungarianMap[ key ];\\n\\t\\n\\t\\t\\tif ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )\\n\\t\\t\\t{\\n\\t\\t\\t\\t// For objects, we need to buzz down into the object to copy parameters\\n\\t\\t\\t\\tif ( hungarianKey.charAt(0) === 'o' )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// Copy the camelCase options over to the hungarian\\n\\t\\t\\t\\t\\tif ( ! user[ hungarianKey ] ) {\\n\\t\\t\\t\\t\\t\\tuser[ hungarianKey ] = {};\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t$.extend( true, user[hungarianKey], user[key] );\\n\\t\\n\\t\\t\\t\\t\\t_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tuser[hungarianKey] = user[ key ];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Language compatibility - when certain options are given, and others aren't, we\\n\\t * need to duplicate the values over, in order to provide backwards compatibility\\n\\t * with older language files.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnLanguageCompat( lang )\\n\\t{\\n\\t\\tvar defaults = DataTable.defaults.oLanguage;\\n\\t\\tvar zeroRecords = lang.sZeroRecords;\\n\\t\\n\\t\\t/* Backwards compatibility - if there is no sEmptyTable given, then use the same as\\n\\t\\t * sZeroRecords - assuming that is given.\\n\\t\\t */\\n\\t\\tif ( ! lang.sEmptyTable && zeroRecords &&\\n\\t\\t\\tdefaults.sEmptyTable === \\\"No data available in table\\\" )\\n\\t\\t{\\n\\t\\t\\t_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );\\n\\t\\t}\\n\\t\\n\\t\\t/* Likewise with loading records */\\n\\t\\tif ( ! lang.sLoadingRecords && zeroRecords &&\\n\\t\\t\\tdefaults.sLoadingRecords === \\\"Loading...\\\" )\\n\\t\\t{\\n\\t\\t\\t_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );\\n\\t\\t}\\n\\t\\n\\t\\t// Old parameter name of the thousands separator mapped onto the new\\n\\t\\tif ( lang.sInfoThousands ) {\\n\\t\\t\\tlang.sThousands = lang.sInfoThousands;\\n\\t\\t}\\n\\t\\n\\t\\tvar decimal = lang.sDecimal;\\n\\t\\tif ( decimal ) {\\n\\t\\t\\t_addNumericSort( decimal );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Map one parameter onto another\\n\\t * @param {object} o Object to map\\n\\t * @param {*} knew The new parameter name\\n\\t * @param {*} old The old parameter name\\n\\t */\\n\\tvar _fnCompatMap = function ( o, knew, old ) {\\n\\t\\tif ( o[ knew ] !== undefined ) {\\n\\t\\t\\to[ old ] = o[ knew ];\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Provide backwards compatibility for the main DT options. Note that the new\\n\\t * options are mapped onto the old parameters, so this is an external interface\\n\\t * change only.\\n\\t * @param {object} init Object to map\\n\\t */\\n\\tfunction _fnCompatOpts ( init )\\n\\t{\\n\\t\\t_fnCompatMap( init, 'ordering', 'bSort' );\\n\\t\\t_fnCompatMap( init, 'orderMulti', 'bSortMulti' );\\n\\t\\t_fnCompatMap( init, 'orderClasses', 'bSortClasses' );\\n\\t\\t_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );\\n\\t\\t_fnCompatMap( init, 'order', 'aaSorting' );\\n\\t\\t_fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );\\n\\t\\t_fnCompatMap( init, 'paging', 'bPaginate' );\\n\\t\\t_fnCompatMap( init, 'pagingType', 'sPaginationType' );\\n\\t\\t_fnCompatMap( init, 'pageLength', 'iDisplayLength' );\\n\\t\\t_fnCompatMap( init, 'searching', 'bFilter' );\\n\\t\\n\\t\\t// Boolean initialisation of x-scrolling\\n\\t\\tif ( typeof init.sScrollX === 'boolean' ) {\\n\\t\\t\\tinit.sScrollX = init.sScrollX ? '100%' : '';\\n\\t\\t}\\n\\t\\tif ( typeof init.scrollX === 'boolean' ) {\\n\\t\\t\\tinit.scrollX = init.scrollX ? '100%' : '';\\n\\t\\t}\\n\\t\\n\\t\\t// Column search objects are in an array, so it needs to be converted\\n\\t\\t// element by element\\n\\t\\tvar searchCols = init.aoSearchCols;\\n\\t\\n\\t\\tif ( searchCols ) {\\n\\t\\t\\tfor ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( searchCols[i] ) {\\n\\t\\t\\t\\t\\t_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Provide backwards compatibility for column options. Note that the new options\\n\\t * are mapped onto the old parameters, so this is an external interface change\\n\\t * only.\\n\\t * @param {object} init Object to map\\n\\t */\\n\\tfunction _fnCompatCols ( init )\\n\\t{\\n\\t\\t_fnCompatMap( init, 'orderable', 'bSortable' );\\n\\t\\t_fnCompatMap( init, 'orderData', 'aDataSort' );\\n\\t\\t_fnCompatMap( init, 'orderSequence', 'asSorting' );\\n\\t\\t_fnCompatMap( init, 'orderDataType', 'sortDataType' );\\n\\t\\n\\t\\t// orderData can be given as an integer\\n\\t\\tvar dataSort = init.aDataSort;\\n\\t\\tif ( typeof dataSort === 'number' && ! $.isArray( dataSort ) ) {\\n\\t\\t\\tinit.aDataSort = [ dataSort ];\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Browser feature detection for capabilities, quirks\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnBrowserDetect( settings )\\n\\t{\\n\\t\\t// We don't need to do this every time DataTables is constructed, the values\\n\\t\\t// calculated are specific to the browser and OS configuration which we\\n\\t\\t// don't expect to change between initialisations\\n\\t\\tif ( ! DataTable.__browser ) {\\n\\t\\t\\tvar browser = {};\\n\\t\\t\\tDataTable.__browser = browser;\\n\\t\\n\\t\\t\\t// Scrolling feature / quirks detection\\n\\t\\t\\tvar n = $('<div/>')\\n\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\tposition: 'fixed',\\n\\t\\t\\t\\t\\ttop: 0,\\n\\t\\t\\t\\t\\tleft: $(window).scrollLeft()*-1, // allow for scrolling\\n\\t\\t\\t\\t\\theight: 1,\\n\\t\\t\\t\\t\\twidth: 1,\\n\\t\\t\\t\\t\\toverflow: 'hidden'\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t$('<div/>')\\n\\t\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\t\\tposition: 'absolute',\\n\\t\\t\\t\\t\\t\\t\\ttop: 1,\\n\\t\\t\\t\\t\\t\\t\\tleft: 1,\\n\\t\\t\\t\\t\\t\\t\\twidth: 100,\\n\\t\\t\\t\\t\\t\\t\\toverflow: 'scroll'\\n\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t$('<div/>')\\n\\t\\t\\t\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\twidth: '100%',\\n\\t\\t\\t\\t\\t\\t\\t\\t\\theight: 10\\n\\t\\t\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.appendTo( 'body' );\\n\\t\\n\\t\\t\\tvar outer = n.children();\\n\\t\\t\\tvar inner = outer.children();\\n\\t\\n\\t\\t\\t// Numbers below, in order, are:\\n\\t\\t\\t// inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth\\n\\t\\t\\t//\\n\\t\\t\\t// IE6 XP: 100 100 100 83\\n\\t\\t\\t// IE7 Vista: 100 100 100 83\\n\\t\\t\\t// IE 8+ Windows: 83 83 100 83\\n\\t\\t\\t// Evergreen Windows: 83 83 100 83\\n\\t\\t\\t// Evergreen Mac with scrollbars: 85 85 100 85\\n\\t\\t\\t// Evergreen Mac without scrollbars: 100 100 100 100\\n\\t\\n\\t\\t\\t// Get scrollbar width\\n\\t\\t\\tbrowser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;\\n\\t\\n\\t\\t\\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\\n\\t\\t\\t// include the width of the scrollbar, while other browsers ensure the inner\\n\\t\\t\\t// element is contained without forcing scrolling\\n\\t\\t\\tbrowser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;\\n\\t\\n\\t\\t\\t// In rtl text layout, some browsers (most, but not all) will place the\\n\\t\\t\\t// scrollbar on the left, rather than the right.\\n\\t\\t\\tbrowser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;\\n\\t\\n\\t\\t\\t// IE8- don't provide height and width for getBoundingClientRect\\n\\t\\t\\tbrowser.bBounding = n[0].getBoundingClientRect().width ? true : false;\\n\\t\\n\\t\\t\\tn.remove();\\n\\t\\t}\\n\\t\\n\\t\\t$.extend( settings.oBrowser, DataTable.__browser );\\n\\t\\tsettings.oScroll.iBarWidth = DataTable.__browser.barWidth;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Array.prototype reduce[Right] method, used for browsers which don't support\\n\\t * JS 1.6. Done this way to reduce code size, since we iterate either way\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnReduce ( that, fn, init, start, end, inc )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti = start,\\n\\t\\t\\tvalue,\\n\\t\\t\\tisSet = false;\\n\\t\\n\\t\\tif ( init !== undefined ) {\\n\\t\\t\\tvalue = init;\\n\\t\\t\\tisSet = true;\\n\\t\\t}\\n\\t\\n\\t\\twhile ( i !== end ) {\\n\\t\\t\\tif ( ! that.hasOwnProperty(i) ) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tvalue = isSet ?\\n\\t\\t\\t\\tfn( value, that[i], i, that ) :\\n\\t\\t\\t\\tthat[i];\\n\\t\\n\\t\\t\\tisSet = true;\\n\\t\\t\\ti += inc;\\n\\t\\t}\\n\\t\\n\\t\\treturn value;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Add a column to the list used for the table with default values\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {node} nTh The th element for this column\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddColumn( oSettings, nTh )\\n\\t{\\n\\t\\t// Add column to aoColumns array\\n\\t\\tvar oDefaults = DataTable.defaults.column;\\n\\t\\tvar iCol = oSettings.aoColumns.length;\\n\\t\\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\\n\\t\\t\\t\\\"nTh\\\": nTh ? nTh : document.createElement('th'),\\n\\t\\t\\t\\\"sTitle\\\": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',\\n\\t\\t\\t\\\"aDataSort\\\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\\n\\t\\t\\t\\\"mData\\\": oDefaults.mData ? oDefaults.mData : iCol,\\n\\t\\t\\tidx: iCol\\n\\t\\t} );\\n\\t\\toSettings.aoColumns.push( oCol );\\n\\t\\n\\t\\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\\n\\t\\t// passed into extend can be undefined. This allows the user to give a default\\n\\t\\t// with only some of the parameters defined, and also not give a default\\n\\t\\tvar searchCols = oSettings.aoPreSearchCols;\\n\\t\\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\\n\\t\\n\\t\\t// Use the default column options function to initialise classes etc\\n\\t\\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Apply options for a column\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iCol column index to consider\\n\\t * @param {object} oOptions object with sType, bVisible and bSearchable etc\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnColumnOptions( oSettings, iCol, oOptions )\\n\\t{\\n\\t\\tvar oCol = oSettings.aoColumns[ iCol ];\\n\\t\\tvar oClasses = oSettings.oClasses;\\n\\t\\tvar th = $(oCol.nTh);\\n\\t\\n\\t\\t// Try to get width information from the DOM. We can't get it from CSS\\n\\t\\t// as we'd need to parse the CSS stylesheet. `width` option can override\\n\\t\\tif ( ! oCol.sWidthOrig ) {\\n\\t\\t\\t// Width attribute\\n\\t\\t\\toCol.sWidthOrig = th.attr('width') || null;\\n\\t\\n\\t\\t\\t// Style attribute\\n\\t\\t\\tvar t = (th.attr('style') || '').match(/width:\\\\s*(\\\\d+[pxem%]+)/);\\n\\t\\t\\tif ( t ) {\\n\\t\\t\\t\\toCol.sWidthOrig = t[1];\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* User specified column options */\\n\\t\\tif ( oOptions !== undefined && oOptions !== null )\\n\\t\\t{\\n\\t\\t\\t// Backwards compatibility\\n\\t\\t\\t_fnCompatCols( oOptions );\\n\\t\\n\\t\\t\\t// Map camel case parameters to their Hungarian counterparts\\n\\t\\t\\t_fnCamelToHungarian( DataTable.defaults.column, oOptions );\\n\\t\\n\\t\\t\\t/* Backwards compatibility for mDataProp */\\n\\t\\t\\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\\n\\t\\t\\t{\\n\\t\\t\\t\\toOptions.mData = oOptions.mDataProp;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( oOptions.sType )\\n\\t\\t\\t{\\n\\t\\t\\t\\toCol._sManualType = oOptions.sType;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// `class` is a reserved word in Javascript, so we need to provide\\n\\t\\t\\t// the ability to use a valid name for the camel case input\\n\\t\\t\\tif ( oOptions.className && ! oOptions.sClass )\\n\\t\\t\\t{\\n\\t\\t\\t\\toOptions.sClass = oOptions.className;\\n\\t\\t\\t}\\n\\t\\t\\tif ( oOptions.sClass ) {\\n\\t\\t\\t\\tth.addClass( oOptions.sClass );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t$.extend( oCol, oOptions );\\n\\t\\t\\t_fnMap( oCol, oOptions, \\\"sWidth\\\", \\\"sWidthOrig\\\" );\\n\\t\\n\\t\\t\\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\\n\\t\\t\\t * priority if defined\\n\\t\\t\\t */\\n\\t\\t\\tif ( oOptions.iDataSort !== undefined )\\n\\t\\t\\t{\\n\\t\\t\\t\\toCol.aDataSort = [ oOptions.iDataSort ];\\n\\t\\t\\t}\\n\\t\\t\\t_fnMap( oCol, oOptions, \\\"aDataSort\\\" );\\n\\t\\t}\\n\\t\\n\\t\\t/* Cache the data get and set functions for speed */\\n\\t\\tvar mDataSrc = oCol.mData;\\n\\t\\tvar mData = _fnGetObjectDataFn( mDataSrc );\\n\\t\\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\\n\\t\\n\\t\\tvar attrTest = function( src ) {\\n\\t\\t\\treturn typeof src === 'string' && src.indexOf('@') !== -1;\\n\\t\\t};\\n\\t\\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\\n\\t\\t\\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\\n\\t\\t);\\n\\t\\toCol._setter = null;\\n\\t\\n\\t\\toCol.fnGetData = function (rowData, type, meta) {\\n\\t\\t\\tvar innerData = mData( rowData, type, undefined, meta );\\n\\t\\n\\t\\t\\treturn mRender && type ?\\n\\t\\t\\t\\tmRender( innerData, type, rowData, meta ) :\\n\\t\\t\\t\\tinnerData;\\n\\t\\t};\\n\\t\\toCol.fnSetData = function ( rowData, val, meta ) {\\n\\t\\t\\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\\n\\t\\t};\\n\\t\\n\\t\\t// Indicate if DataTables should read DOM data as an object or array\\n\\t\\t// Used in _fnGetRowElements\\n\\t\\tif ( typeof mDataSrc !== 'number' ) {\\n\\t\\t\\toSettings._rowReadObject = true;\\n\\t\\t}\\n\\t\\n\\t\\t/* Feature sorting overrides column specific when off */\\n\\t\\tif ( !oSettings.oFeatures.bSort )\\n\\t\\t{\\n\\t\\t\\toCol.bSortable = false;\\n\\t\\t\\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\\n\\t\\t}\\n\\t\\n\\t\\t/* Check that the class assignment is correct for sorting */\\n\\t\\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\\n\\t\\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\\n\\t\\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortableNone;\\n\\t\\t\\toCol.sSortingClassJUI = \\\"\\\";\\n\\t\\t}\\n\\t\\telse if ( bAsc && !bDesc )\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortableAsc;\\n\\t\\t\\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\\n\\t\\t}\\n\\t\\telse if ( !bAsc && bDesc )\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortableDesc;\\n\\t\\t\\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\toCol.sSortingClass = oClasses.sSortable;\\n\\t\\t\\toCol.sSortingClassJUI = oClasses.sSortJUI;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Adjust the table column widths for new data. Note: you would probably want to\\n\\t * do a redraw after calling this function!\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAdjustColumnSizing ( settings )\\n\\t{\\n\\t\\t/* Not interested in doing column width calculation if auto-width is disabled */\\n\\t\\tif ( settings.oFeatures.bAutoWidth !== false )\\n\\t\\t{\\n\\t\\t\\tvar columns = settings.aoColumns;\\n\\t\\n\\t\\t\\t_fnCalculateColumnWidths( settings );\\n\\t\\t\\tfor ( var i=0 , iLen=columns.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tcolumns[i].nTh.style.width = columns[i].sWidth;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tvar scroll = settings.oScroll;\\n\\t\\tif ( scroll.sY !== '' || scroll.sX !== '')\\n\\t\\t{\\n\\t\\t\\t_fnScrollDraw( settings );\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'column-sizing', [settings] );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Covert the index of a visible column to the index in the data array (take account\\n\\t * of hidden columns)\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iMatch Visible column index to lookup\\n\\t * @returns {int} i the data index\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnVisibleToColumnIndex( oSettings, iMatch )\\n\\t{\\n\\t\\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\\n\\t\\n\\t\\treturn typeof aiVis[iMatch] === 'number' ?\\n\\t\\t\\taiVis[iMatch] :\\n\\t\\t\\tnull;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Covert the index of an index in the data array and convert it to the visible\\n\\t * column index (take account of hidden columns)\\n\\t * @param {int} iMatch Column index to lookup\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {int} i the data index\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnColumnIndexToVisible( oSettings, iMatch )\\n\\t{\\n\\t\\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\\n\\t\\tvar iPos = $.inArray( iMatch, aiVis );\\n\\t\\n\\t\\treturn iPos !== -1 ? iPos : null;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the number of visible columns\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {int} i the number of visible columns\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnVisbleColumns( oSettings )\\n\\t{\\n\\t\\tvar vis = 0;\\n\\t\\n\\t\\t// No reduce in IE8, use a loop for now\\n\\t\\t$.each( oSettings.aoColumns, function ( i, col ) {\\n\\t\\t\\tif ( col.bVisible && $(col.nTh).css('display') !== 'none' ) {\\n\\t\\t\\t\\tvis++;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn vis;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get an array of column indexes that match a given property\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {string} sParam Parameter in aoColumns to look for - typically\\n\\t * bVisible or bSearchable\\n\\t * @returns {array} Array of indexes with matched properties\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetColumns( oSettings, sParam )\\n\\t{\\n\\t\\tvar a = [];\\n\\t\\n\\t\\t$.map( oSettings.aoColumns, function(val, i) {\\n\\t\\t\\tif ( val[sParam] ) {\\n\\t\\t\\t\\ta.push( i );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn a;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Calculate the 'type' of a column\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnColumnTypes ( settings )\\n\\t{\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar data = settings.aoData;\\n\\t\\tvar types = DataTable.ext.type.detect;\\n\\t\\tvar i, ien, j, jen, k, ken;\\n\\t\\tvar col, cell, detectedType, cache;\\n\\t\\n\\t\\t// For each column, spin over the \\n\\t\\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\\n\\t\\t\\tcol = columns[i];\\n\\t\\t\\tcache = [];\\n\\t\\n\\t\\t\\tif ( ! col.sType && col._sManualType ) {\\n\\t\\t\\t\\tcol.sType = col._sManualType;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( ! col.sType ) {\\n\\t\\t\\t\\tfor ( j=0, jen=types.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\tfor ( k=0, ken=data.length ; k<ken ; k++ ) {\\n\\t\\t\\t\\t\\t\\t// Use a cache array so we only need to get the type data\\n\\t\\t\\t\\t\\t\\t// from the formatter once (when using multiple detectors)\\n\\t\\t\\t\\t\\t\\tif ( cache[k] === undefined ) {\\n\\t\\t\\t\\t\\t\\t\\tcache[k] = _fnGetCellData( settings, k, i, 'type' );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tdetectedType = types[j]( cache[k], settings );\\n\\t\\n\\t\\t\\t\\t\\t\\t// If null, then this type can't apply to this column, so\\n\\t\\t\\t\\t\\t\\t// rather than testing all cells, break out. There is an\\n\\t\\t\\t\\t\\t\\t// exception for the last type which is `html`. We need to\\n\\t\\t\\t\\t\\t\\t// scan all rows since it is possible to mix string and HTML\\n\\t\\t\\t\\t\\t\\t// types\\n\\t\\t\\t\\t\\t\\tif ( ! detectedType && j !== types.length-1 ) {\\n\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t// Only a single match is needed for html type since it is\\n\\t\\t\\t\\t\\t\\t// bottom of the pile and very similar to string\\n\\t\\t\\t\\t\\t\\tif ( detectedType === 'html' ) {\\n\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// Type is valid for all data points in the column - use this\\n\\t\\t\\t\\t\\t// type\\n\\t\\t\\t\\t\\tif ( detectedType ) {\\n\\t\\t\\t\\t\\t\\tcol.sType = detectedType;\\n\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Fall back - if no type was detected, always use string\\n\\t\\t\\t\\tif ( ! col.sType ) {\\n\\t\\t\\t\\t\\tcol.sType = 'string';\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Take the column definitions and static columns arrays and calculate how\\n\\t * they relate to column indexes. The callback function will then apply the\\n\\t * definition found for a column to a suitable configuration object.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {array} aoColDefs The aoColumnDefs array that is to be applied\\n\\t * @param {array} aoCols The aoColumns array that defines columns individually\\n\\t * @param {function} fn Callback function - takes two parameters, the calculated\\n\\t * column index and the definition for that column.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )\\n\\t{\\n\\t\\tvar i, iLen, j, jLen, k, kLen, def;\\n\\t\\tvar columns = oSettings.aoColumns;\\n\\t\\n\\t\\t// Column definitions with aTargets\\n\\t\\tif ( aoColDefs )\\n\\t\\t{\\n\\t\\t\\t/* Loop over the definitions array - loop in reverse so first instance has priority */\\n\\t\\t\\tfor ( i=aoColDefs.length-1 ; i>=0 ; i-- )\\n\\t\\t\\t{\\n\\t\\t\\t\\tdef = aoColDefs[i];\\n\\t\\n\\t\\t\\t\\t/* Each definition can target multiple columns, as it is an array */\\n\\t\\t\\t\\tvar aTargets = def.targets !== undefined ?\\n\\t\\t\\t\\t\\tdef.targets :\\n\\t\\t\\t\\t\\tdef.aTargets;\\n\\t\\n\\t\\t\\t\\tif ( ! $.isArray( aTargets ) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taTargets = [ aTargets ];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tfor ( j=0, jLen=aTargets.length ; j<jLen ; j++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tif ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Add columns that we don't yet know about */\\n\\t\\t\\t\\t\\t\\twhile( columns.length <= aTargets[j] )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t_fnAddColumn( oSettings );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t/* Integer, basic index */\\n\\t\\t\\t\\t\\t\\tfn( aTargets[j], def );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Negative integer, right to left column counting */\\n\\t\\t\\t\\t\\t\\tfn( columns.length+aTargets[j], def );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( typeof aTargets[j] === 'string' )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Class name matching on TH element */\\n\\t\\t\\t\\t\\t\\tfor ( k=0, kLen=columns.length ; k<kLen ; k++ )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\tif ( aTargets[j] == \\\"_all\\\" ||\\n\\t\\t\\t\\t\\t\\t\\t $(columns[k].nTh).hasClass( aTargets[j] ) )\\n\\t\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t\\tfn( k, def );\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// Statically defined columns array\\n\\t\\tif ( aoCols )\\n\\t\\t{\\n\\t\\t\\tfor ( i=0, iLen=aoCols.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tfn( i, aoCols[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t/**\\n\\t * Add a data array to the table, creating DOM node etc. This is the parallel to\\n\\t * _fnGatherData, but for adding rows from a Javascript source, rather than a\\n\\t * DOM source.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {array} aData data array to be added\\n\\t * @param {node} [nTr] TR element to add to the table - optional. If not given,\\n\\t * DataTables will create a row automatically\\n\\t * @param {array} [anTds] Array of TD|TH elements for the row - must be given\\n\\t * if nTr is.\\n\\t * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\\n\\t{\\n\\t\\t/* Create the object for storing information about this new row */\\n\\t\\tvar iRow = oSettings.aoData.length;\\n\\t\\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\\n\\t\\t\\tsrc: nTr ? 'dom' : 'data',\\n\\t\\t\\tidx: iRow\\n\\t\\t} );\\n\\t\\n\\t\\toData._aData = aDataIn;\\n\\t\\toSettings.aoData.push( oData );\\n\\t\\n\\t\\t/* Create the cells */\\n\\t\\tvar nTd, sThisType;\\n\\t\\tvar columns = oSettings.aoColumns;\\n\\t\\n\\t\\t// Invalidate the column types as the new data needs to be revalidated\\n\\t\\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tcolumns[i].sType = null;\\n\\t\\t}\\n\\t\\n\\t\\t/* Add to the display array */\\n\\t\\toSettings.aiDisplayMaster.push( iRow );\\n\\t\\n\\t\\tvar id = oSettings.rowIdFn( aDataIn );\\n\\t\\tif ( id !== undefined ) {\\n\\t\\t\\toSettings.aIds[ id ] = oData;\\n\\t\\t}\\n\\t\\n\\t\\t/* Create the DOM information, or register it if already present */\\n\\t\\tif ( nTr || ! oSettings.oFeatures.bDeferRender )\\n\\t\\t{\\n\\t\\t\\t_fnCreateTr( oSettings, iRow, nTr, anTds );\\n\\t\\t}\\n\\t\\n\\t\\treturn iRow;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Add one or more TR elements to the table. Generally we'd expect to\\n\\t * use this for reading data from a DOM sourced table, but it could be\\n\\t * used for an TR element. Note that if a TR is given, it is used (i.e.\\n\\t * it is not cloned).\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {array|node|jQuery} trs The TR element(s) to add to the table\\n\\t * @returns {array} Array of indexes for the added rows\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddTr( settings, trs )\\n\\t{\\n\\t\\tvar row;\\n\\t\\n\\t\\t// Allow an individual node to be passed in\\n\\t\\tif ( ! (trs instanceof $) ) {\\n\\t\\t\\ttrs = $(trs);\\n\\t\\t}\\n\\t\\n\\t\\treturn trs.map( function (i, el) {\\n\\t\\t\\trow = _fnGetRowElements( settings, el );\\n\\t\\t\\treturn _fnAddData( settings, row.data, el, row.cells );\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Take a TR element and convert it to an index in aoData\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {node} n the TR element to find\\n\\t * @returns {int} index if the node is found, null if not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnNodeToDataIndex( oSettings, n )\\n\\t{\\n\\t\\treturn (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Take a TD element and convert it into a column data index (not the visible index)\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iRow The row number the TD/TH can be found in\\n\\t * @param {node} n The TD/TH element to find\\n\\t * @returns {int} index if the node is found, -1 if not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnNodeToColumnIndex( oSettings, iRow, n )\\n\\t{\\n\\t\\treturn $.inArray( n, oSettings.aoData[ iRow ].anCells );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the data for a given cell from the internal cache, taking into account data mapping\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} rowIdx aoData row id\\n\\t * @param {int} colIdx Column index\\n\\t * @param {string} type data get type ('display', 'type' 'filter' 'sort')\\n\\t * @returns {*} Cell data\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetCellData( settings, rowIdx, colIdx, type )\\n\\t{\\n\\t\\tvar draw = settings.iDraw;\\n\\t\\tvar col = settings.aoColumns[colIdx];\\n\\t\\tvar rowData = settings.aoData[rowIdx]._aData;\\n\\t\\tvar defaultContent = col.sDefaultContent;\\n\\t\\tvar cellData = col.fnGetData( rowData, type, {\\n\\t\\t\\tsettings: settings,\\n\\t\\t\\trow: rowIdx,\\n\\t\\t\\tcol: colIdx\\n\\t\\t} );\\n\\t\\n\\t\\tif ( cellData === undefined ) {\\n\\t\\t\\tif ( settings.iDrawError != draw && defaultContent === null ) {\\n\\t\\t\\t\\t_fnLog( settings, 0, \\\"Requested unknown parameter \\\"+\\n\\t\\t\\t\\t\\t(typeof col.mData=='function' ? '{function}' : \\\"'\\\"+col.mData+\\\"'\\\")+\\n\\t\\t\\t\\t\\t\\\" for row \\\"+rowIdx+\\\", column \\\"+colIdx, 4 );\\n\\t\\t\\t\\tsettings.iDrawError = draw;\\n\\t\\t\\t}\\n\\t\\t\\treturn defaultContent;\\n\\t\\t}\\n\\t\\n\\t\\t// When the data source is null and a specific data type is requested (i.e.\\n\\t\\t// not the original data), we can use default column data\\n\\t\\tif ( (cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined ) {\\n\\t\\t\\tcellData = defaultContent;\\n\\t\\t}\\n\\t\\telse if ( typeof cellData === 'function' ) {\\n\\t\\t\\t// If the data source is a function, then we run it and use the return,\\n\\t\\t\\t// executing in the scope of the data object (for instances)\\n\\t\\t\\treturn cellData.call( rowData );\\n\\t\\t}\\n\\t\\n\\t\\tif ( cellData === null && type == 'display' ) {\\n\\t\\t\\treturn '';\\n\\t\\t}\\n\\t\\treturn cellData;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Set the value for a specific cell, into the internal data cache\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} rowIdx aoData row id\\n\\t * @param {int} colIdx Column index\\n\\t * @param {*} val Value to set\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSetCellData( settings, rowIdx, colIdx, val )\\n\\t{\\n\\t\\tvar col = settings.aoColumns[colIdx];\\n\\t\\tvar rowData = settings.aoData[rowIdx]._aData;\\n\\t\\n\\t\\tcol.fnSetData( rowData, val, {\\n\\t\\t\\tsettings: settings,\\n\\t\\t\\trow: rowIdx,\\n\\t\\t\\tcol: colIdx\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t// Private variable that is used to match action syntax in the data property object\\n\\tvar __reArray = /\\\\[.*?\\\\]$/;\\n\\tvar __reFn = /\\\\(\\\\)$/;\\n\\t\\n\\t/**\\n\\t * Split string on periods, taking into account escaped periods\\n\\t * @param {string} str String to split\\n\\t * @return {array} Split string\\n\\t */\\n\\tfunction _fnSplitObjNotation( str )\\n\\t{\\n\\t\\treturn $.map( str.match(/(\\\\\\\\.|[^\\\\.])+/g) || [''], function ( s ) {\\n\\t\\t\\treturn s.replace(/\\\\\\\\\\\\./g, '.');\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return a function that can be used to get data from a source object, taking\\n\\t * into account the ability to use nested objects as a source\\n\\t * @param {string|int|function} mSource The data source for the object\\n\\t * @returns {function} Data get function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetObjectDataFn( mSource )\\n\\t{\\n\\t\\tif ( $.isPlainObject( mSource ) )\\n\\t\\t{\\n\\t\\t\\t/* Build an object of get functions, and wrap them in a single call */\\n\\t\\t\\tvar o = {};\\n\\t\\t\\t$.each( mSource, function (key, val) {\\n\\t\\t\\t\\tif ( val ) {\\n\\t\\t\\t\\t\\to[key] = _fnGetObjectDataFn( val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\treturn function (data, type, row, meta) {\\n\\t\\t\\t\\tvar t = o[type] || o._;\\n\\t\\t\\t\\treturn t !== undefined ?\\n\\t\\t\\t\\t\\tt(data, type, row, meta) :\\n\\t\\t\\t\\t\\tdata;\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( mSource === null )\\n\\t\\t{\\n\\t\\t\\t/* Give an empty string for rendering / sorting etc */\\n\\t\\t\\treturn function (data) { // type, row and meta also passed, but not used\\n\\t\\t\\t\\treturn data;\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'function' )\\n\\t\\t{\\n\\t\\t\\treturn function (data, type, row, meta) {\\n\\t\\t\\t\\treturn mSource( data, type, row, meta );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\\n\\t\\t\\t mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\\n\\t\\t{\\n\\t\\t\\t/* If there is a . in the source string then the data source is in a\\n\\t\\t\\t * nested object so we loop over the data for each level to get the next\\n\\t\\t\\t * level down. On each loop we test for undefined, and if found immediately\\n\\t\\t\\t * return. This allows entire objects to be missing and sDefaultContent to\\n\\t\\t\\t * be used if defined, rather than throwing an error\\n\\t\\t\\t */\\n\\t\\t\\tvar fetchData = function (data, type, src) {\\n\\t\\t\\t\\tvar arrayNotation, funcNotation, out, innerSrc;\\n\\t\\n\\t\\t\\t\\tif ( src !== \\\"\\\" )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tvar a = _fnSplitObjNotation( src );\\n\\t\\n\\t\\t\\t\\t\\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t// Check if we are dealing with special notation\\n\\t\\t\\t\\t\\t\\tarrayNotation = a[i].match(__reArray);\\n\\t\\t\\t\\t\\t\\tfuncNotation = a[i].match(__reFn);\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( arrayNotation )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t// Array notation\\n\\t\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reArray, '');\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// Condition allows simply [] to be passed in\\n\\t\\t\\t\\t\\t\\t\\tif ( a[i] !== \\\"\\\" ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tdata = data[ a[i] ];\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t\\tout = [];\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// Get the remainder of the nested object to get\\n\\t\\t\\t\\t\\t\\t\\ta.splice( 0, i+1 );\\n\\t\\t\\t\\t\\t\\t\\tinnerSrc = a.join('.');\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// Traverse each entry in the array getting the properties requested\\n\\t\\t\\t\\t\\t\\t\\tif ( $.isArray( data ) ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tout.push( fetchData( data[j], type, innerSrc ) );\\n\\t\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// If a string is given in between the array notation indicators, that\\n\\t\\t\\t\\t\\t\\t\\t// is used to join the strings together, otherwise an array is returned\\n\\t\\t\\t\\t\\t\\t\\tvar join = arrayNotation[0].substring(1, arrayNotation[0].length-1);\\n\\t\\t\\t\\t\\t\\t\\tdata = (join===\\\"\\\") ? out : out.join(join);\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t// The inner call to fetchData has already traversed through the remainder\\n\\t\\t\\t\\t\\t\\t\\t// of the source requested, so we exit from the loop\\n\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse if ( funcNotation )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t// Function call\\n\\t\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reFn, '');\\n\\t\\t\\t\\t\\t\\t\\tdata = data[ a[i] ]();\\n\\t\\t\\t\\t\\t\\t\\tcontinue;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( data === null || data[ a[i] ] === undefined )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\treturn undefined;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\tdata = data[ a[i] ];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn data;\\n\\t\\t\\t};\\n\\t\\n\\t\\t\\treturn function (data, type) { // row and meta also passed, but not used\\n\\t\\t\\t\\treturn fetchData( data, type, mSource );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t/* Array or flat object mapping */\\n\\t\\t\\treturn function (data, type) { // row and meta also passed, but not used\\n\\t\\t\\t\\treturn data[mSource];\\n\\t\\t\\t};\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return a function that can be used to set data from a source object, taking\\n\\t * into account the ability to use nested objects as a source\\n\\t * @param {string|int|function} mSource The data source for the object\\n\\t * @returns {function} Data set function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSetObjectDataFn( mSource )\\n\\t{\\n\\t\\tif ( $.isPlainObject( mSource ) )\\n\\t\\t{\\n\\t\\t\\t/* Unlike get, only the underscore (global) option is used for for\\n\\t\\t\\t * setting data since we don't know the type here. This is why an object\\n\\t\\t\\t * option is not documented for `mData` (which is read/write), but it is\\n\\t\\t\\t * for `mRender` which is read only.\\n\\t\\t\\t */\\n\\t\\t\\treturn _fnSetObjectDataFn( mSource._ );\\n\\t\\t}\\n\\t\\telse if ( mSource === null )\\n\\t\\t{\\n\\t\\t\\t/* Nothing to do when the data source is null */\\n\\t\\t\\treturn function () {};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'function' )\\n\\t\\t{\\n\\t\\t\\treturn function (data, val, meta) {\\n\\t\\t\\t\\tmSource( data, 'set', val, meta );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\\n\\t\\t\\t mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\\n\\t\\t{\\n\\t\\t\\t/* Like the get, we need to get data from a nested object */\\n\\t\\t\\tvar setData = function (data, val, src) {\\n\\t\\t\\t\\tvar a = _fnSplitObjNotation( src ), b;\\n\\t\\t\\t\\tvar aLast = a[a.length-1];\\n\\t\\t\\t\\tvar arrayNotation, funcNotation, o, innerSrc;\\n\\t\\n\\t\\t\\t\\tfor ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// Check if we are dealing with an array notation request\\n\\t\\t\\t\\t\\tarrayNotation = a[i].match(__reArray);\\n\\t\\t\\t\\t\\tfuncNotation = a[i].match(__reFn);\\n\\t\\n\\t\\t\\t\\t\\tif ( arrayNotation )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reArray, '');\\n\\t\\t\\t\\t\\t\\tdata[ a[i] ] = [];\\n\\t\\n\\t\\t\\t\\t\\t\\t// Get the remainder of the nested object to set so we can recurse\\n\\t\\t\\t\\t\\t\\tb = a.slice();\\n\\t\\t\\t\\t\\t\\tb.splice( 0, i+1 );\\n\\t\\t\\t\\t\\t\\tinnerSrc = b.join('.');\\n\\t\\n\\t\\t\\t\\t\\t\\t// Traverse each entry in the array setting the properties requested\\n\\t\\t\\t\\t\\t\\tif ( $.isArray( val ) )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\\n\\t\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t\\to = {};\\n\\t\\t\\t\\t\\t\\t\\t\\tsetData( o, val[j], innerSrc );\\n\\t\\t\\t\\t\\t\\t\\t\\tdata[ a[i] ].push( o );\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\t// We've been asked to save data to an array, but it\\n\\t\\t\\t\\t\\t\\t\\t// isn't array data to be saved. Best that can be done\\n\\t\\t\\t\\t\\t\\t\\t// is to just save the value.\\n\\t\\t\\t\\t\\t\\t\\tdata[ a[i] ] = val;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t// The inner call to setData has already traversed through the remainder\\n\\t\\t\\t\\t\\t\\t// of the source and has set the data, thus we can exit here\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( funcNotation )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t// Function call\\n\\t\\t\\t\\t\\t\\ta[i] = a[i].replace(__reFn, '');\\n\\t\\t\\t\\t\\t\\tdata = data[ a[i] ]( val );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// If the nested object doesn't currently exist - since we are\\n\\t\\t\\t\\t\\t// trying to set the value - create it\\n\\t\\t\\t\\t\\tif ( data[ a[i] ] === null || data[ a[i] ] === undefined )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tdata[ a[i] ] = {};\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\tdata = data[ a[i] ];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Last item in the input - i.e, the actual set\\n\\t\\t\\t\\tif ( aLast.match(__reFn ) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// Function call\\n\\t\\t\\t\\t\\tdata = data[ aLast.replace(__reFn, '') ]( val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t// If array notation is used, we just want to strip it and use the property name\\n\\t\\t\\t\\t\\t// and assign the value. If it isn't used, then we get the result we want anyway\\n\\t\\t\\t\\t\\tdata[ aLast.replace(__reArray, '') ] = val;\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\n\\t\\t\\treturn function (data, val) { // meta is also passed in, but not used\\n\\t\\t\\t\\treturn setData( data, val, mSource );\\n\\t\\t\\t};\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t/* Array or flat object mapping */\\n\\t\\t\\treturn function (data, val) { // meta is also passed in, but not used\\n\\t\\t\\t\\tdata[mSource] = val;\\n\\t\\t\\t};\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return an array with the full table data\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns array {array} aData Master data array\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetDataMaster ( settings )\\n\\t{\\n\\t\\treturn _pluck( settings.aoData, '_aData' );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Nuke the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnClearTable( settings )\\n\\t{\\n\\t\\tsettings.aoData.length = 0;\\n\\t\\tsettings.aiDisplayMaster.length = 0;\\n\\t\\tsettings.aiDisplay.length = 0;\\n\\t\\tsettings.aIds = {};\\n\\t}\\n\\t\\n\\t\\n\\t /**\\n\\t * Take an array of integers (index array) and remove a target integer (value - not\\n\\t * the key!)\\n\\t * @param {array} a Index array to target\\n\\t * @param {int} iTarget value to find\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDeleteIndex( a, iTarget, splice )\\n\\t{\\n\\t\\tvar iTargetIndex = -1;\\n\\t\\n\\t\\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tif ( a[i] == iTarget )\\n\\t\\t\\t{\\n\\t\\t\\t\\tiTargetIndex = i;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( a[i] > iTarget )\\n\\t\\t\\t{\\n\\t\\t\\t\\ta[i]--;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tif ( iTargetIndex != -1 && splice === undefined )\\n\\t\\t{\\n\\t\\t\\ta.splice( iTargetIndex, 1 );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Mark cached data as invalid such that a re-read of the data will occur when\\n\\t * the cached data is next requested. Also update from the data source object.\\n\\t *\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {int} rowIdx Row index to invalidate\\n\\t * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'\\n\\t * or 'data'\\n\\t * @param {int} [colIdx] Column index to invalidate. If undefined the whole\\n\\t * row will be invalidated\\n\\t * @memberof DataTable#oApi\\n\\t *\\n\\t * @todo For the modularisation of v1.11 this will need to become a callback, so\\n\\t * the sort and filter methods can subscribe to it. That will required\\n\\t * initialisation options for sorting, which is why it is not already baked in\\n\\t */\\n\\tfunction _fnInvalidate( settings, rowIdx, src, colIdx )\\n\\t{\\n\\t\\tvar row = settings.aoData[ rowIdx ];\\n\\t\\tvar i, ien;\\n\\t\\tvar cellWrite = function ( cell, col ) {\\n\\t\\t\\t// This is very frustrating, but in IE if you just write directly\\n\\t\\t\\t// to innerHTML, and elements that are overwritten are GC'ed,\\n\\t\\t\\t// even if there is a reference to them elsewhere\\n\\t\\t\\twhile ( cell.childNodes.length ) {\\n\\t\\t\\t\\tcell.removeChild( cell.firstChild );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\\n\\t\\t};\\n\\t\\n\\t\\t// Are we reading last data from DOM or the data object?\\n\\t\\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\\n\\t\\t\\t// Read the data from the DOM\\n\\t\\t\\trow._aData = _fnGetRowElements(\\n\\t\\t\\t\\t\\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.data;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Reading from data object, update the DOM\\n\\t\\t\\tvar cells = row.anCells;\\n\\t\\n\\t\\t\\tif ( cells ) {\\n\\t\\t\\t\\tif ( colIdx !== undefined ) {\\n\\t\\t\\t\\t\\tcellWrite( cells[colIdx], colIdx );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t\\tcellWrite( cells[i], i );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// For both row and cell invalidation, the cached data for sorting and\\n\\t\\t// filtering is nulled out\\n\\t\\trow._aSortData = null;\\n\\t\\trow._aFilterData = null;\\n\\t\\n\\t\\t// Invalidate the type for a specific column (if given) or all columns since\\n\\t\\t// the data might have changed\\n\\t\\tvar cols = settings.aoColumns;\\n\\t\\tif ( colIdx !== undefined ) {\\n\\t\\t\\tcols[ colIdx ].sType = null;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tfor ( i=0, ien=cols.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcols[i].sType = null;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Update DataTables special `DT_*` attributes for the row\\n\\t\\t\\t_fnRowAttributes( settings, row );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Build a data source object from an HTML row, reading the contents of the\\n\\t * cells that are in the row.\\n\\t *\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {node|object} TR element from which to read data or existing row\\n\\t * object from which to re-read the data from the cells\\n\\t * @param {int} [colIdx] Optional column index\\n\\t * @param {array|object} [d] Data source object. If `colIdx` is given then this\\n\\t * parameter should also be given and will be used to write the data into.\\n\\t * Only the column in question will be written\\n\\t * @returns {object} Object with two parameters: `data` the data read, in\\n\\t * document order, and `cells` and array of nodes (they can be useful to the\\n\\t * caller, so rather than needing a second traversal to get them, just return\\n\\t * them from here).\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetRowElements( settings, row, colIdx, d )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttds = [],\\n\\t\\t\\ttd = row.firstChild,\\n\\t\\t\\tname, col, o, i=0, contents,\\n\\t\\t\\tcolumns = settings.aoColumns,\\n\\t\\t\\tobjectRead = settings._rowReadObject;\\n\\t\\n\\t\\t// Allow the data object to be passed in, or construct\\n\\t\\td = d !== undefined ?\\n\\t\\t\\td :\\n\\t\\t\\tobjectRead ?\\n\\t\\t\\t\\t{} :\\n\\t\\t\\t\\t[];\\n\\t\\n\\t\\tvar attr = function ( str, td ) {\\n\\t\\t\\tif ( typeof str === 'string' ) {\\n\\t\\t\\t\\tvar idx = str.indexOf('@');\\n\\t\\n\\t\\t\\t\\tif ( idx !== -1 ) {\\n\\t\\t\\t\\t\\tvar attr = str.substring( idx+1 );\\n\\t\\t\\t\\t\\tvar setter = _fnSetObjectDataFn( str );\\n\\t\\t\\t\\t\\tsetter( d, td.getAttribute( attr ) );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\t// Read data from a cell and store into the data object\\n\\t\\tvar cellProcess = function ( cell ) {\\n\\t\\t\\tif ( colIdx === undefined || colIdx === i ) {\\n\\t\\t\\t\\tcol = columns[i];\\n\\t\\t\\t\\tcontents = $.trim(cell.innerHTML);\\n\\t\\n\\t\\t\\t\\tif ( col && col._bAttrSrc ) {\\n\\t\\t\\t\\t\\tvar setter = _fnSetObjectDataFn( col.mData._ );\\n\\t\\t\\t\\t\\tsetter( d, contents );\\n\\t\\n\\t\\t\\t\\t\\tattr( col.mData.sort, cell );\\n\\t\\t\\t\\t\\tattr( col.mData.type, cell );\\n\\t\\t\\t\\t\\tattr( col.mData.filter, cell );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t// Depending on the `data` option for the columns the data can\\n\\t\\t\\t\\t\\t// be read to either an object or an array.\\n\\t\\t\\t\\t\\tif ( objectRead ) {\\n\\t\\t\\t\\t\\t\\tif ( ! col._setter ) {\\n\\t\\t\\t\\t\\t\\t\\t// Cache the setter function\\n\\t\\t\\t\\t\\t\\t\\tcol._setter = _fnSetObjectDataFn( col.mData );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\tcol._setter( d, contents );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\td[i] = contents;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\ti++;\\n\\t\\t};\\n\\t\\n\\t\\tif ( td ) {\\n\\t\\t\\t// `tr` element was passed in\\n\\t\\t\\twhile ( td ) {\\n\\t\\t\\t\\tname = td.nodeName.toUpperCase();\\n\\t\\n\\t\\t\\t\\tif ( name == \\\"TD\\\" || name == \\\"TH\\\" ) {\\n\\t\\t\\t\\t\\tcellProcess( td );\\n\\t\\t\\t\\t\\ttds.push( td );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\ttd = td.nextSibling;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Existing row object passed in\\n\\t\\t\\ttds = row.anCells;\\n\\t\\n\\t\\t\\tfor ( var j=0, jen=tds.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\tcellProcess( tds[j] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// Read the ID from the DOM if present\\n\\t\\tvar rowNode = row.firstChild ? row : row.nTr;\\n\\t\\n\\t\\tif ( rowNode ) {\\n\\t\\t\\tvar id = rowNode.getAttribute( 'id' );\\n\\t\\n\\t\\t\\tif ( id ) {\\n\\t\\t\\t\\t_fnSetObjectDataFn( settings.rowId )( d, id );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn {\\n\\t\\t\\tdata: d,\\n\\t\\t\\tcells: tds\\n\\t\\t};\\n\\t}\\n\\t/**\\n\\t * Create a new TR element (and it's TD children) for a row\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {int} iRow Row to consider\\n\\t * @param {node} [nTrIn] TR element to add to the table - optional. If not given,\\n\\t * DataTables will create a row automatically\\n\\t * @param {array} [anTds] Array of TD|TH elements for the row - must be given\\n\\t * if nTr is.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCreateTr ( oSettings, iRow, nTrIn, anTds )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\trow = oSettings.aoData[iRow],\\n\\t\\t\\trowData = row._aData,\\n\\t\\t\\tcells = [],\\n\\t\\t\\tnTr, nTd, oCol,\\n\\t\\t\\ti, iLen;\\n\\t\\n\\t\\tif ( row.nTr === null )\\n\\t\\t{\\n\\t\\t\\tnTr = nTrIn || document.createElement('tr');\\n\\t\\n\\t\\t\\trow.nTr = nTr;\\n\\t\\t\\trow.anCells = cells;\\n\\t\\n\\t\\t\\t/* Use a private property on the node to allow reserve mapping from the node\\n\\t\\t\\t * to the aoData array for fast look up\\n\\t\\t\\t */\\n\\t\\t\\tnTr._DT_RowIndex = iRow;\\n\\t\\n\\t\\t\\t/* Special parameters can be given by the data source to be used on the row */\\n\\t\\t\\t_fnRowAttributes( oSettings, row );\\n\\t\\n\\t\\t\\t/* Process each column */\\n\\t\\t\\tfor ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\toCol = oSettings.aoColumns[i];\\n\\t\\n\\t\\t\\t\\tnTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );\\n\\t\\t\\t\\tnTd._DT_CellIndex = {\\n\\t\\t\\t\\t\\trow: iRow,\\n\\t\\t\\t\\t\\tcolumn: i\\n\\t\\t\\t\\t};\\n\\t\\t\\t\\t\\n\\t\\t\\t\\tcells.push( nTd );\\n\\t\\n\\t\\t\\t\\t// Need to create the HTML if new, or if a rendering function is defined\\n\\t\\t\\t\\tif ( (!nTrIn || oCol.mRender || oCol.mData !== i) &&\\n\\t\\t\\t\\t\\t (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i+'.display')\\n\\t\\t\\t\\t) {\\n\\t\\t\\t\\t\\tnTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t/* Add user defined class */\\n\\t\\t\\t\\tif ( oCol.sClass )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnTd.className += ' '+oCol.sClass;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Visibility - add or remove as required\\n\\t\\t\\t\\tif ( oCol.bVisible && ! nTrIn )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnTr.appendChild( nTd );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( ! oCol.bVisible && nTrIn )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnTd.parentNode.removeChild( nTd );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tif ( oCol.fnCreatedCell )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\toCol.fnCreatedCell.call( oSettings.oInstance,\\n\\t\\t\\t\\t\\t\\tnTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i\\n\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );\\n\\t\\t}\\n\\t\\n\\t\\t// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved\\n\\t\\t// and deployed\\n\\t\\trow.nTr.setAttribute( 'role', 'row' );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Add attributes to a row based on the special `DT_*` parameters in a data\\n\\t * source object.\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {object} DataTables row object for the row to be modified\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnRowAttributes( settings, row )\\n\\t{\\n\\t\\tvar tr = row.nTr;\\n\\t\\tvar data = row._aData;\\n\\t\\n\\t\\tif ( tr ) {\\n\\t\\t\\tvar id = settings.rowIdFn( data );\\n\\t\\n\\t\\t\\tif ( id ) {\\n\\t\\t\\t\\ttr.id = id;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( data.DT_RowClass ) {\\n\\t\\t\\t\\t// Remove any classes added by DT_RowClass before\\n\\t\\t\\t\\tvar a = data.DT_RowClass.split(' ');\\n\\t\\t\\t\\trow.__rowc = row.__rowc ?\\n\\t\\t\\t\\t\\t_unique( row.__rowc.concat( a ) ) :\\n\\t\\t\\t\\t\\ta;\\n\\t\\n\\t\\t\\t\\t$(tr)\\n\\t\\t\\t\\t\\t.removeClass( row.__rowc.join(' ') )\\n\\t\\t\\t\\t\\t.addClass( data.DT_RowClass );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( data.DT_RowAttr ) {\\n\\t\\t\\t\\t$(tr).attr( data.DT_RowAttr );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( data.DT_RowData ) {\\n\\t\\t\\t\\t$(tr).data( data.DT_RowData );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Create the HTML header for the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnBuildHead( oSettings )\\n\\t{\\n\\t\\tvar i, ien, cell, row, column;\\n\\t\\tvar thead = oSettings.nTHead;\\n\\t\\tvar tfoot = oSettings.nTFoot;\\n\\t\\tvar createHeader = $('th, td', thead).length === 0;\\n\\t\\tvar classes = oSettings.oClasses;\\n\\t\\tvar columns = oSettings.aoColumns;\\n\\t\\n\\t\\tif ( createHeader ) {\\n\\t\\t\\trow = $('<tr/>').appendTo( thead );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\\n\\t\\t\\tcolumn = columns[i];\\n\\t\\t\\tcell = $( column.nTh ).addClass( column.sClass );\\n\\t\\n\\t\\t\\tif ( createHeader ) {\\n\\t\\t\\t\\tcell.appendTo( row );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// 1.11 move into sorting\\n\\t\\t\\tif ( oSettings.oFeatures.bSort ) {\\n\\t\\t\\t\\tcell.addClass( column.sSortingClass );\\n\\t\\n\\t\\t\\t\\tif ( column.bSortable !== false ) {\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.attr( 'tabindex', oSettings.iTabIndex )\\n\\t\\t\\t\\t\\t\\t.attr( 'aria-controls', oSettings.sTableId );\\n\\t\\n\\t\\t\\t\\t\\t_fnSortAttachListener( oSettings, column.nTh, i );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( column.sTitle != cell[0].innerHTML ) {\\n\\t\\t\\t\\tcell.html( column.sTitle );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnRenderer( oSettings, 'header' )(\\n\\t\\t\\t\\toSettings, cell, column, classes\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\tif ( createHeader ) {\\n\\t\\t\\t_fnDetectHeader( oSettings.aoHeader, thead );\\n\\t\\t}\\n\\t\\t\\n\\t\\t/* ARIA role for the rows */\\n\\t \\t$(thead).find('>tr').attr('role', 'row');\\n\\t\\n\\t\\t/* Deal with the footer - add classes if required */\\n\\t\\t$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );\\n\\t\\t$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );\\n\\t\\n\\t\\t// Cache the footer cells. Note that we only take the cells from the first\\n\\t\\t// row in the footer. If there is more than one row the user wants to\\n\\t\\t// interact with, they need to use the table().foot() method. Note also this\\n\\t\\t// allows cells to be used for multiple columns using colspan\\n\\t\\tif ( tfoot !== null ) {\\n\\t\\t\\tvar cells = oSettings.aoFooter[0];\\n\\t\\n\\t\\t\\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcolumn = columns[i];\\n\\t\\t\\t\\tcolumn.nTf = cells[i].cell;\\n\\t\\n\\t\\t\\t\\tif ( column.sClass ) {\\n\\t\\t\\t\\t\\t$(column.nTf).addClass( column.sClass );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Draw the header (or footer) element based on the column visibility states. The\\n\\t * methodology here is to use the layout array from _fnDetectHeader, modified for\\n\\t * the instantaneous column visibility, to construct the new layout. The grid is\\n\\t * traversed over cell at a time in a rows x columns grid fashion, although each\\n\\t * cell insert can cover multiple elements in the grid - which is tracks using the\\n\\t * aApplied array. Cell inserts in the grid will only occur where there isn't\\n\\t * already a cell in that position.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param array {objects} aoSource Layout array from _fnDetectHeader\\n\\t * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDrawHead( oSettings, aoSource, bIncludeHidden )\\n\\t{\\n\\t\\tvar i, iLen, j, jLen, k, kLen, n, nLocalTr;\\n\\t\\tvar aoLocal = [];\\n\\t\\tvar aApplied = [];\\n\\t\\tvar iColumns = oSettings.aoColumns.length;\\n\\t\\tvar iRowspan, iColspan;\\n\\t\\n\\t\\tif ( ! aoSource )\\n\\t\\t{\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( bIncludeHidden === undefined )\\n\\t\\t{\\n\\t\\t\\tbIncludeHidden = false;\\n\\t\\t}\\n\\t\\n\\t\\t/* Make a copy of the master layout array, but without the visible columns in it */\\n\\t\\tfor ( i=0, iLen=aoSource.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\taoLocal[i] = aoSource[i].slice();\\n\\t\\t\\taoLocal[i].nTr = aoSource[i].nTr;\\n\\t\\n\\t\\t\\t/* Remove any columns which are currently hidden */\\n\\t\\t\\tfor ( j=iColumns-1 ; j>=0 ; j-- )\\n\\t\\t\\t{\\n\\t\\t\\t\\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taoLocal[i].splice( j, 1 );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Prep the applied array - it needs an element for each row */\\n\\t\\t\\taApplied.push( [] );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tnLocalTr = aoLocal[i].nTr;\\n\\t\\n\\t\\t\\t/* All cells are going to be replaced, so empty out the row */\\n\\t\\t\\tif ( nLocalTr )\\n\\t\\t\\t{\\n\\t\\t\\t\\twhile( (n = nLocalTr.firstChild) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnLocalTr.removeChild( n );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tfor ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tiRowspan = 1;\\n\\t\\t\\t\\tiColspan = 1;\\n\\t\\n\\t\\t\\t\\t/* Check to see if there is already a cell (row/colspan) covering our target\\n\\t\\t\\t\\t * insert point. If there is, then there is nothing to do.\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\tif ( aApplied[i][j] === undefined )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tnLocalTr.appendChild( aoLocal[i][j].cell );\\n\\t\\t\\t\\t\\taApplied[i][j] = 1;\\n\\t\\n\\t\\t\\t\\t\\t/* Expand the cell to cover as many rows as needed */\\n\\t\\t\\t\\t\\twhile ( aoLocal[i+iRowspan] !== undefined &&\\n\\t\\t\\t\\t\\t aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\taApplied[i+iRowspan][j] = 1;\\n\\t\\t\\t\\t\\t\\tiRowspan++;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* Expand the cell to cover as many columns as needed */\\n\\t\\t\\t\\t\\twhile ( aoLocal[i][j+iColspan] !== undefined &&\\n\\t\\t\\t\\t\\t aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t/* Must update the applied array over the rows for the columns */\\n\\t\\t\\t\\t\\t\\tfor ( k=0 ; k<iRowspan ; k++ )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\taApplied[i+k][j+iColspan] = 1;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\tiColspan++;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* Do the actual expansion in the DOM */\\n\\t\\t\\t\\t\\t$(aoLocal[i][j].cell)\\n\\t\\t\\t\\t\\t\\t.attr('rowspan', iRowspan)\\n\\t\\t\\t\\t\\t\\t.attr('colspan', iColspan);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Insert the required TR nodes into the table for display\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDraw( oSettings )\\n\\t{\\n\\t\\t/* Provide a pre-callback function which can be used to cancel the draw is false is returned */\\n\\t\\tvar aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );\\n\\t\\tif ( $.inArray( false, aPreDraw ) !== -1 )\\n\\t\\t{\\n\\t\\t\\t_fnProcessingDisplay( oSettings, false );\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar i, iLen, n;\\n\\t\\tvar anRows = [];\\n\\t\\tvar iRowCount = 0;\\n\\t\\tvar asStripeClasses = oSettings.asStripeClasses;\\n\\t\\tvar iStripes = asStripeClasses.length;\\n\\t\\tvar iOpenRows = oSettings.aoOpenRows.length;\\n\\t\\tvar oLang = oSettings.oLanguage;\\n\\t\\tvar iInitDisplayStart = oSettings.iInitDisplayStart;\\n\\t\\tvar bServerSide = _fnDataSource( oSettings ) == 'ssp';\\n\\t\\tvar aiDisplay = oSettings.aiDisplay;\\n\\t\\n\\t\\toSettings.bDrawing = true;\\n\\t\\n\\t\\t/* Check and see if we have an initial draw position from state saving */\\n\\t\\tif ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )\\n\\t\\t{\\n\\t\\t\\toSettings._iDisplayStart = bServerSide ?\\n\\t\\t\\t\\tiInitDisplayStart :\\n\\t\\t\\t\\tiInitDisplayStart >= oSettings.fnRecordsDisplay() ?\\n\\t\\t\\t\\t\\t0 :\\n\\t\\t\\t\\t\\tiInitDisplayStart;\\n\\t\\n\\t\\t\\toSettings.iInitDisplayStart = -1;\\n\\t\\t}\\n\\t\\n\\t\\tvar iDisplayStart = oSettings._iDisplayStart;\\n\\t\\tvar iDisplayEnd = oSettings.fnDisplayEnd();\\n\\t\\n\\t\\t/* Server-side processing draw intercept */\\n\\t\\tif ( oSettings.bDeferLoading )\\n\\t\\t{\\n\\t\\t\\toSettings.bDeferLoading = false;\\n\\t\\t\\toSettings.iDraw++;\\n\\t\\t\\t_fnProcessingDisplay( oSettings, false );\\n\\t\\t}\\n\\t\\telse if ( !bServerSide )\\n\\t\\t{\\n\\t\\t\\toSettings.iDraw++;\\n\\t\\t}\\n\\t\\telse if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )\\n\\t\\t{\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( aiDisplay.length !== 0 )\\n\\t\\t{\\n\\t\\t\\tvar iStart = bServerSide ? 0 : iDisplayStart;\\n\\t\\t\\tvar iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;\\n\\t\\n\\t\\t\\tfor ( var j=iStart ; j<iEnd ; j++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tvar iDataIndex = aiDisplay[j];\\n\\t\\t\\t\\tvar aoData = oSettings.aoData[ iDataIndex ];\\n\\t\\t\\t\\tif ( aoData.nTr === null )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t_fnCreateTr( oSettings, iDataIndex );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tvar nRow = aoData.nTr;\\n\\t\\n\\t\\t\\t\\t/* Remove the old striping classes and then add the new one */\\n\\t\\t\\t\\tif ( iStripes !== 0 )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tvar sStripe = asStripeClasses[ iRowCount % iStripes ];\\n\\t\\t\\t\\t\\tif ( aoData._sRowStripe != sStripe )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );\\n\\t\\t\\t\\t\\t\\taoData._sRowStripe = sStripe;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Row callback functions - might want to manipulate the row\\n\\t\\t\\t\\t// iRowCount and j are not currently documented. Are they at all\\n\\t\\t\\t\\t// useful?\\n\\t\\t\\t\\t_fnCallbackFire( oSettings, 'aoRowCallback', null,\\n\\t\\t\\t\\t\\t[nRow, aoData._aData, iRowCount, j] );\\n\\t\\n\\t\\t\\t\\tanRows.push( nRow );\\n\\t\\t\\t\\tiRowCount++;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t/* Table is empty - create a row with an empty message in it */\\n\\t\\t\\tvar sZero = oLang.sZeroRecords;\\n\\t\\t\\tif ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )\\n\\t\\t\\t{\\n\\t\\t\\t\\tsZero = oLang.sLoadingRecords;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )\\n\\t\\t\\t{\\n\\t\\t\\t\\tsZero = oLang.sEmptyTable;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tanRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )\\n\\t\\t\\t\\t.append( $('<td />', {\\n\\t\\t\\t\\t\\t'valign': 'top',\\n\\t\\t\\t\\t\\t'colSpan': _fnVisbleColumns( oSettings ),\\n\\t\\t\\t\\t\\t'class': oSettings.oClasses.sRowEmpty\\n\\t\\t\\t\\t} ).html( sZero ) )[0];\\n\\t\\t}\\n\\t\\n\\t\\t/* Header and footer callbacks */\\n\\t\\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\\n\\t\\t\\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\\n\\t\\n\\t\\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\\n\\t\\t\\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\\n\\t\\n\\t\\tvar body = $(oSettings.nTBody);\\n\\t\\n\\t\\tbody.children().detach();\\n\\t\\tbody.append( $(anRows) );\\n\\t\\n\\t\\t/* Call all required callback functions for the end of a draw */\\n\\t\\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\\n\\t\\n\\t\\t/* Draw is complete, sorting and filtering must be as well */\\n\\t\\toSettings.bSorted = false;\\n\\t\\toSettings.bFiltered = false;\\n\\t\\toSettings.bDrawing = false;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Redraw the table - taking account of the various features which are enabled\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {boolean} [holdPosition] Keep the current paging position. By default\\n\\t * the paging is reset to the first page\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnReDraw( settings, holdPosition )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tfeatures = settings.oFeatures,\\n\\t\\t\\tsort = features.bSort,\\n\\t\\t\\tfilter = features.bFilter;\\n\\t\\n\\t\\tif ( sort ) {\\n\\t\\t\\t_fnSort( settings );\\n\\t\\t}\\n\\t\\n\\t\\tif ( filter ) {\\n\\t\\t\\t_fnFilterComplete( settings, settings.oPreviousSearch );\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// No filtering, so we want to just use the display master\\n\\t\\t\\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\\n\\t\\t}\\n\\t\\n\\t\\tif ( holdPosition !== true ) {\\n\\t\\t\\tsettings._iDisplayStart = 0;\\n\\t\\t}\\n\\t\\n\\t\\t// Let any modules know about the draw hold position state (used by\\n\\t\\t// scrolling internally)\\n\\t\\tsettings._drawHold = holdPosition;\\n\\t\\n\\t\\t_fnDraw( settings );\\n\\t\\n\\t\\tsettings._drawHold = false;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Add the options to the page HTML for the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAddOptionsHtml ( oSettings )\\n\\t{\\n\\t\\tvar classes = oSettings.oClasses;\\n\\t\\tvar table = $(oSettings.nTable);\\n\\t\\tvar holding = $('<div/>').insertBefore( table ); // Holding element for speed\\n\\t\\tvar features = oSettings.oFeatures;\\n\\t\\n\\t\\t// All DataTables are wrapped in a div\\n\\t\\tvar insert = $('<div/>', {\\n\\t\\t\\tid: oSettings.sTableId+'_wrapper',\\n\\t\\t\\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\\n\\t\\t} );\\n\\t\\n\\t\\toSettings.nHolding = holding[0];\\n\\t\\toSettings.nTableWrapper = insert[0];\\n\\t\\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\\n\\t\\n\\t\\t/* Loop over the user set positioning and place the elements as needed */\\n\\t\\tvar aDom = oSettings.sDom.split('');\\n\\t\\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\\n\\t\\tfor ( var i=0 ; i<aDom.length ; i++ )\\n\\t\\t{\\n\\t\\t\\tfeatureNode = null;\\n\\t\\t\\tcOption = aDom[i];\\n\\t\\n\\t\\t\\tif ( cOption == '<' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* New container div */\\n\\t\\t\\t\\tnNewNode = $('<div/>')[0];\\n\\t\\n\\t\\t\\t\\t/* Check to see if we should append an id and/or a class name to the container */\\n\\t\\t\\t\\tcNext = aDom[i+1];\\n\\t\\t\\t\\tif ( cNext == \\\"'\\\" || cNext == '\\\"' )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tsAttr = \\\"\\\";\\n\\t\\t\\t\\t\\tj = 2;\\n\\t\\t\\t\\t\\twhile ( aDom[i+j] != cNext )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tsAttr += aDom[i+j];\\n\\t\\t\\t\\t\\t\\tj++;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* Replace jQuery UI constants @todo depreciated */\\n\\t\\t\\t\\t\\tif ( sAttr == \\\"H\\\" )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tsAttr = classes.sJUIHeader;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( sAttr == \\\"F\\\" )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tsAttr = classes.sJUIFooter;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t/* The attribute can be in the format of \\\"#id.class\\\", \\\"#id\\\" or \\\"class\\\" This logic\\n\\t\\t\\t\\t\\t * breaks the string into parts and applies them as needed\\n\\t\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\tif ( sAttr.indexOf('.') != -1 )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tvar aSplit = sAttr.split('.');\\n\\t\\t\\t\\t\\t\\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\\n\\t\\t\\t\\t\\t\\tnNewNode.className = aSplit[1];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( sAttr.charAt(0) == \\\"#\\\" )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tnNewNode.className = sAttr;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\ti += j; /* Move along the position array */\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tinsert.append( nNewNode );\\n\\t\\t\\t\\tinsert = $(nNewNode);\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == '>' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* End container div */\\n\\t\\t\\t\\tinsert = insert.parent();\\n\\t\\t\\t}\\n\\t\\t\\t// @todo Move options into their own plugins?\\n\\t\\t\\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Length */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlLength( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'f' && features.bFilter )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Filter */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'r' && features.bProcessing )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* pRocessing */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 't' )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Table */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlTable( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'i' && features.bInfo )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Info */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( cOption == 'p' && features.bPaginate )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Pagination */\\n\\t\\t\\t\\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( DataTable.ext.feature.length !== 0 )\\n\\t\\t\\t{\\n\\t\\t\\t\\t/* Plug-in features */\\n\\t\\t\\t\\tvar aoFeatures = DataTable.ext.feature;\\n\\t\\t\\t\\tfor ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tif ( cOption == aoFeatures[k].cFeature )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tfeatureNode = aoFeatures[k].fnInit( oSettings );\\n\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Add to the 2D features array */\\n\\t\\t\\tif ( featureNode )\\n\\t\\t\\t{\\n\\t\\t\\t\\tvar aanFeatures = oSettings.aanFeatures;\\n\\t\\n\\t\\t\\t\\tif ( ! aanFeatures[cOption] )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taanFeatures[cOption] = [];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\taanFeatures[cOption].push( featureNode );\\n\\t\\t\\t\\tinsert.append( featureNode );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* Built our DOM structure - replace the holding div with what we want */\\n\\t\\tholding.replaceWith( insert );\\n\\t\\toSettings.nHolding = null;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Use the DOM source to create up an array of header cells. The idea here is to\\n\\t * create a layout grid (array) of rows x columns, which contains a reference\\n\\t * to the cell that that point in the grid (regardless of col/rowspan), such that\\n\\t * any column / row could be removed and the new grid constructed\\n\\t * @param array {object} aLayout Array to store the calculated layout in\\n\\t * @param {node} nThead The header/footer element for the table\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDetectHeader ( aLayout, nThead )\\n\\t{\\n\\t\\tvar nTrs = $(nThead).children('tr');\\n\\t\\tvar nTr, nCell;\\n\\t\\tvar i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;\\n\\t\\tvar bUnique;\\n\\t\\tvar fnShiftCol = function ( a, i, j ) {\\n\\t\\t\\tvar k = a[i];\\n\\t while ( k[j] ) {\\n\\t\\t\\t\\tj++;\\n\\t\\t\\t}\\n\\t\\t\\treturn j;\\n\\t\\t};\\n\\t\\n\\t\\taLayout.splice( 0, aLayout.length );\\n\\t\\n\\t\\t/* We know how many rows there are in the layout - so prep it */\\n\\t\\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\taLayout.push( [] );\\n\\t\\t}\\n\\t\\n\\t\\t/* Calculate a layout array */\\n\\t\\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tnTr = nTrs[i];\\n\\t\\t\\tiColumn = 0;\\n\\t\\n\\t\\t\\t/* For every cell in the row... */\\n\\t\\t\\tnCell = nTr.firstChild;\\n\\t\\t\\twhile ( nCell ) {\\n\\t\\t\\t\\tif ( nCell.nodeName.toUpperCase() == \\\"TD\\\" ||\\n\\t\\t\\t\\t nCell.nodeName.toUpperCase() == \\\"TH\\\" )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t/* Get the col and rowspan attributes from the DOM and sanitise them */\\n\\t\\t\\t\\t\\tiColspan = nCell.getAttribute('colspan') * 1;\\n\\t\\t\\t\\t\\tiRowspan = nCell.getAttribute('rowspan') * 1;\\n\\t\\t\\t\\t\\tiColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;\\n\\t\\t\\t\\t\\tiRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;\\n\\t\\n\\t\\t\\t\\t\\t/* There might be colspan cells already in this row, so shift our target\\n\\t\\t\\t\\t\\t * accordingly\\n\\t\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\tiColShifted = fnShiftCol( aLayout, i, iColumn );\\n\\t\\n\\t\\t\\t\\t\\t/* Cache calculation for unique columns */\\n\\t\\t\\t\\t\\tbUnique = iColspan === 1 ? true : false;\\n\\t\\n\\t\\t\\t\\t\\t/* If there is col / rowspan, copy the information into the layout grid */\\n\\t\\t\\t\\t\\tfor ( l=0 ; l<iColspan ; l++ )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tfor ( k=0 ; k<iRowspan ; k++ )\\n\\t\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\t\\taLayout[i+k][iColShifted+l] = {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\\"cell\\\": nCell,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\\"unique\\\": bUnique\\n\\t\\t\\t\\t\\t\\t\\t};\\n\\t\\t\\t\\t\\t\\t\\taLayout[i+k].nTr = nTr;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tnCell = nCell.nextSibling;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get an array of unique th elements, one for each column\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {node} nHeader automatically detect the layout from this node - optional\\n\\t * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional\\n\\t * @returns array {node} aReturn list of unique th's\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetUniqueThs ( oSettings, nHeader, aLayout )\\n\\t{\\n\\t\\tvar aReturn = [];\\n\\t\\tif ( !aLayout )\\n\\t\\t{\\n\\t\\t\\taLayout = oSettings.aoHeader;\\n\\t\\t\\tif ( nHeader )\\n\\t\\t\\t{\\n\\t\\t\\t\\taLayout = [];\\n\\t\\t\\t\\t_fnDetectHeader( aLayout, nHeader );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tfor ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tfor ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tif ( aLayout[i][j].unique &&\\n\\t\\t\\t\\t\\t (!aReturn[j] || !oSettings.bSortCellsTop) )\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\taReturn[j] = aLayout[i][j].cell;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn aReturn;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Create an Ajax call based on the table's settings, taking into account that\\n\\t * parameters can have multiple forms, and backwards compatibility.\\n\\t *\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {array} data Data to send to the server, required by\\n\\t * DataTables - may be augmented by developer callbacks\\n\\t * @param {function} fn Callback function to run when data is obtained\\n\\t */\\n\\tfunction _fnBuildAjax( oSettings, data, fn )\\n\\t{\\n\\t\\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\\n\\t\\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\\n\\t\\n\\t\\t// Convert to object based for 1.10+ if using the old array scheme which can\\n\\t\\t// come from server-side processing or serverParams\\n\\t\\tif ( data && $.isArray(data) ) {\\n\\t\\t\\tvar tmp = {};\\n\\t\\t\\tvar rbracket = /(.*?)\\\\[\\\\]$/;\\n\\t\\n\\t\\t\\t$.each( data, function (key, val) {\\n\\t\\t\\t\\tvar match = val.name.match(rbracket);\\n\\t\\n\\t\\t\\t\\tif ( match ) {\\n\\t\\t\\t\\t\\t// Support for arrays\\n\\t\\t\\t\\t\\tvar name = match[0];\\n\\t\\n\\t\\t\\t\\t\\tif ( ! tmp[ name ] ) {\\n\\t\\t\\t\\t\\t\\ttmp[ name ] = [];\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\ttmp[ name ].push( val.value );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\ttmp[val.name] = val.value;\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\t\\tdata = tmp;\\n\\t\\t}\\n\\t\\n\\t\\tvar ajaxData;\\n\\t\\tvar ajax = oSettings.ajax;\\n\\t\\tvar instance = oSettings.oInstance;\\n\\t\\tvar callback = function ( json ) {\\n\\t\\t\\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\\n\\t\\t\\tfn( json );\\n\\t\\t};\\n\\t\\n\\t\\tif ( $.isPlainObject( ajax ) && ajax.data )\\n\\t\\t{\\n\\t\\t\\tajaxData = ajax.data;\\n\\t\\n\\t\\t\\tvar newData = $.isFunction( ajaxData ) ?\\n\\t\\t\\t\\tajaxData( data, oSettings ) : // fn can manipulate data or return\\n\\t\\t\\t\\tajaxData; // an object object or array to merge\\n\\t\\n\\t\\t\\t// If the function returned something, use that alone\\n\\t\\t\\tdata = $.isFunction( ajaxData ) && newData ?\\n\\t\\t\\t\\tnewData :\\n\\t\\t\\t\\t$.extend( true, data, newData );\\n\\t\\n\\t\\t\\t// Remove the data property as we've resolved it already and don't want\\n\\t\\t\\t// jQuery to do it again (it is restored at the end of the function)\\n\\t\\t\\tdelete ajax.data;\\n\\t\\t}\\n\\t\\n\\t\\tvar baseAjax = {\\n\\t\\t\\t\\\"data\\\": data,\\n\\t\\t\\t\\\"success\\\": function (json) {\\n\\t\\t\\t\\tvar error = json.error || json.sError;\\n\\t\\t\\t\\tif ( error ) {\\n\\t\\t\\t\\t\\t_fnLog( oSettings, 0, error );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\toSettings.json = json;\\n\\t\\t\\t\\tcallback( json );\\n\\t\\t\\t},\\n\\t\\t\\t\\\"dataType\\\": \\\"json\\\",\\n\\t\\t\\t\\\"cache\\\": false,\\n\\t\\t\\t\\\"type\\\": oSettings.sServerMethod,\\n\\t\\t\\t\\\"error\\\": function (xhr, error, thrown) {\\n\\t\\t\\t\\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\\n\\t\\n\\t\\t\\t\\tif ( $.inArray( true, ret ) === -1 ) {\\n\\t\\t\\t\\t\\tif ( error == \\\"parsererror\\\" ) {\\n\\t\\t\\t\\t\\t\\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse if ( xhr.readyState === 4 ) {\\n\\t\\t\\t\\t\\t\\t_fnLog( oSettings, 0, 'Ajax error', 7 );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t_fnProcessingDisplay( oSettings, false );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\t// Store the data submitted for the API\\n\\t\\toSettings.oAjaxData = data;\\n\\t\\n\\t\\t// Allow plug-ins and external processes to modify the data\\n\\t\\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\\n\\t\\n\\t\\tif ( oSettings.fnServerData )\\n\\t\\t{\\n\\t\\t\\t// DataTables 1.9- compatibility\\n\\t\\t\\toSettings.fnServerData.call( instance,\\n\\t\\t\\t\\toSettings.sAjaxSource,\\n\\t\\t\\t\\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\\n\\t\\t\\t\\t\\treturn { name: key, value: val };\\n\\t\\t\\t\\t} ),\\n\\t\\t\\t\\tcallback,\\n\\t\\t\\t\\toSettings\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\\n\\t\\t{\\n\\t\\t\\t// DataTables 1.9- compatibility\\n\\t\\t\\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\\n\\t\\t\\t\\turl: ajax || oSettings.sAjaxSource\\n\\t\\t\\t} ) );\\n\\t\\t}\\n\\t\\telse if ( $.isFunction( ajax ) )\\n\\t\\t{\\n\\t\\t\\t// Is a function - let the caller define what needs to be done\\n\\t\\t\\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t// Object to extend the base settings\\n\\t\\t\\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\\n\\t\\n\\t\\t\\t// Restore for next time around\\n\\t\\t\\tajax.data = ajaxData;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Update the table using an Ajax call\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {boolean} Block the table drawing or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAjaxUpdate( settings )\\n\\t{\\n\\t\\tif ( settings.bAjaxDataGet ) {\\n\\t\\t\\tsettings.iDraw++;\\n\\t\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t\\t_fnBuildAjax(\\n\\t\\t\\t\\tsettings,\\n\\t\\t\\t\\t_fnAjaxParameters( settings ),\\n\\t\\t\\t\\tfunction(json) {\\n\\t\\t\\t\\t\\t_fnAjaxUpdateDraw( settings, json );\\n\\t\\t\\t\\t}\\n\\t\\t\\t);\\n\\t\\n\\t\\t\\treturn false;\\n\\t\\t}\\n\\t\\treturn true;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Build up the parameters in an object needed for a server-side processing\\n\\t * request. Note that this is basically done twice, is different ways - a modern\\n\\t * method which is used by default in DataTables 1.10 which uses objects and\\n\\t * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\\n\\t * the sAjaxSource option is used in the initialisation, or the legacyAjax\\n\\t * option is set.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {bool} block the table drawing or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAjaxParameters( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tcolumns = settings.aoColumns,\\n\\t\\t\\tcolumnCount = columns.length,\\n\\t\\t\\tfeatures = settings.oFeatures,\\n\\t\\t\\tpreSearch = settings.oPreviousSearch,\\n\\t\\t\\tpreColSearch = settings.aoPreSearchCols,\\n\\t\\t\\ti, data = [], dataProp, column, columnSearch,\\n\\t\\t\\tsort = _fnSortFlatten( settings ),\\n\\t\\t\\tdisplayStart = settings._iDisplayStart,\\n\\t\\t\\tdisplayLength = features.bPaginate !== false ?\\n\\t\\t\\t\\tsettings._iDisplayLength :\\n\\t\\t\\t\\t-1;\\n\\t\\n\\t\\tvar param = function ( name, value ) {\\n\\t\\t\\tdata.push( { 'name': name, 'value': value } );\\n\\t\\t};\\n\\t\\n\\t\\t// DataTables 1.9- compatible method\\n\\t\\tparam( 'sEcho', settings.iDraw );\\n\\t\\tparam( 'iColumns', columnCount );\\n\\t\\tparam( 'sColumns', _pluck( columns, 'sName' ).join(',') );\\n\\t\\tparam( 'iDisplayStart', displayStart );\\n\\t\\tparam( 'iDisplayLength', displayLength );\\n\\t\\n\\t\\t// DataTables 1.10+ method\\n\\t\\tvar d = {\\n\\t\\t\\tdraw: settings.iDraw,\\n\\t\\t\\tcolumns: [],\\n\\t\\t\\torder: [],\\n\\t\\t\\tstart: displayStart,\\n\\t\\t\\tlength: displayLength,\\n\\t\\t\\tsearch: {\\n\\t\\t\\t\\tvalue: preSearch.sSearch,\\n\\t\\t\\t\\tregex: preSearch.bRegex\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\tfor ( i=0 ; i<columnCount ; i++ ) {\\n\\t\\t\\tcolumn = columns[i];\\n\\t\\t\\tcolumnSearch = preColSearch[i];\\n\\t\\t\\tdataProp = typeof column.mData==\\\"function\\\" ? 'function' : column.mData ;\\n\\t\\n\\t\\t\\td.columns.push( {\\n\\t\\t\\t\\tdata: dataProp,\\n\\t\\t\\t\\tname: column.sName,\\n\\t\\t\\t\\tsearchable: column.bSearchable,\\n\\t\\t\\t\\torderable: column.bSortable,\\n\\t\\t\\t\\tsearch: {\\n\\t\\t\\t\\t\\tvalue: columnSearch.sSearch,\\n\\t\\t\\t\\t\\tregex: columnSearch.bRegex\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tparam( \\\"mDataProp_\\\"+i, dataProp );\\n\\t\\n\\t\\t\\tif ( features.bFilter ) {\\n\\t\\t\\t\\tparam( 'sSearch_'+i, columnSearch.sSearch );\\n\\t\\t\\t\\tparam( 'bRegex_'+i, columnSearch.bRegex );\\n\\t\\t\\t\\tparam( 'bSearchable_'+i, column.bSearchable );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( features.bSort ) {\\n\\t\\t\\t\\tparam( 'bSortable_'+i, column.bSortable );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tif ( features.bFilter ) {\\n\\t\\t\\tparam( 'sSearch', preSearch.sSearch );\\n\\t\\t\\tparam( 'bRegex', preSearch.bRegex );\\n\\t\\t}\\n\\t\\n\\t\\tif ( features.bSort ) {\\n\\t\\t\\t$.each( sort, function ( i, val ) {\\n\\t\\t\\t\\td.order.push( { column: val.col, dir: val.dir } );\\n\\t\\n\\t\\t\\t\\tparam( 'iSortCol_'+i, val.col );\\n\\t\\t\\t\\tparam( 'sSortDir_'+i, val.dir );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tparam( 'iSortingCols', sort.length );\\n\\t\\t}\\n\\t\\n\\t\\t// If the legacy.ajax parameter is null, then we automatically decide which\\n\\t\\t// form to use, based on sAjaxSource\\n\\t\\tvar legacy = DataTable.ext.legacy.ajax;\\n\\t\\tif ( legacy === null ) {\\n\\t\\t\\treturn settings.sAjaxSource ? data : d;\\n\\t\\t}\\n\\t\\n\\t\\t// Otherwise, if legacy has been specified then we use that to decide on the\\n\\t\\t// form\\n\\t\\treturn legacy ? data : d;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Data the data from the server (nuking the old) and redraw the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} json json data return from the server.\\n\\t * @param {string} json.sEcho Tracking flag for DataTables to match requests\\n\\t * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering\\n\\t * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering\\n\\t * @param {array} json.aaData The data to display on this page\\n\\t * @param {string} [json.sColumns] Column ordering (sName, comma separated)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnAjaxUpdateDraw ( settings, json )\\n\\t{\\n\\t\\t// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.\\n\\t\\t// Support both\\n\\t\\tvar compat = function ( old, modern ) {\\n\\t\\t\\treturn json[old] !== undefined ? json[old] : json[modern];\\n\\t\\t};\\n\\t\\n\\t\\tvar data = _fnAjaxDataSrc( settings, json );\\n\\t\\tvar draw = compat( 'sEcho', 'draw' );\\n\\t\\tvar recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );\\n\\t\\tvar recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );\\n\\t\\n\\t\\tif ( draw ) {\\n\\t\\t\\t// Protect against out of sequence returns\\n\\t\\t\\tif ( draw*1 < settings.iDraw ) {\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\tsettings.iDraw = draw * 1;\\n\\t\\t}\\n\\t\\n\\t\\t_fnClearTable( settings );\\n\\t\\tsettings._iRecordsTotal = parseInt(recordsTotal, 10);\\n\\t\\tsettings._iRecordsDisplay = parseInt(recordsFiltered, 10);\\n\\t\\n\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t_fnAddData( settings, data[i] );\\n\\t\\t}\\n\\t\\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\\n\\t\\n\\t\\tsettings.bAjaxDataGet = false;\\n\\t\\t_fnDraw( settings );\\n\\t\\n\\t\\tif ( ! settings._bInitComplete ) {\\n\\t\\t\\t_fnInitComplete( settings, json );\\n\\t\\t}\\n\\t\\n\\t\\tsettings.bAjaxDataGet = true;\\n\\t\\t_fnProcessingDisplay( settings, false );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the data from the JSON data source to use for drawing a table. Using\\n\\t * `_fnGetObjectDataFn` allows the data to be sourced from a property of the\\n\\t * source object, or from a processing function.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} json Data source object / array from the server\\n\\t * @return {array} Array of data to use\\n\\t */\\n\\tfunction _fnAjaxDataSrc ( oSettings, json )\\n\\t{\\n\\t\\tvar dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?\\n\\t\\t\\toSettings.ajax.dataSrc :\\n\\t\\t\\toSettings.sAjaxDataProp; // Compatibility with 1.9-.\\n\\t\\n\\t\\t// Compatibility with 1.9-. In order to read from aaData, check if the\\n\\t\\t// default has been changed, if not, check for aaData\\n\\t\\tif ( dataSrc === 'data' ) {\\n\\t\\t\\treturn json.aaData || json[dataSrc];\\n\\t\\t}\\n\\t\\n\\t\\treturn dataSrc !== \\\"\\\" ?\\n\\t\\t\\t_fnGetObjectDataFn( dataSrc )( json ) :\\n\\t\\t\\tjson;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Generate the node required for filtering text\\n\\t * @returns {node} Filter control element\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlFilter ( settings )\\n\\t{\\n\\t\\tvar classes = settings.oClasses;\\n\\t\\tvar tableId = settings.sTableId;\\n\\t\\tvar language = settings.oLanguage;\\n\\t\\tvar previousSearch = settings.oPreviousSearch;\\n\\t\\tvar features = settings.aanFeatures;\\n\\t\\tvar input = '<input type=\\\"search\\\" class=\\\"'+classes.sFilterInput+'\\\"/>';\\n\\t\\n\\t\\tvar str = language.sSearch;\\n\\t\\tstr = str.match(/_INPUT_/) ?\\n\\t\\t\\tstr.replace('_INPUT_', input) :\\n\\t\\t\\tstr+input;\\n\\t\\n\\t\\tvar filter = $('<div/>', {\\n\\t\\t\\t\\t'id': ! features.f ? tableId+'_filter' : null,\\n\\t\\t\\t\\t'class': classes.sFilter\\n\\t\\t\\t} )\\n\\t\\t\\t.append( $('<label/>' ).append( str ) );\\n\\t\\n\\t\\tvar searchFn = function() {\\n\\t\\t\\t/* Update all other filter input elements for the new display */\\n\\t\\t\\tvar n = features.f;\\n\\t\\t\\tvar val = !this.value ? \\\"\\\" : this.value; // mental IE8 fix :-(\\n\\t\\n\\t\\t\\t/* Now do the filter */\\n\\t\\t\\tif ( val != previousSearch.sSearch ) {\\n\\t\\t\\t\\t_fnFilterComplete( settings, {\\n\\t\\t\\t\\t\\t\\\"sSearch\\\": val,\\n\\t\\t\\t\\t\\t\\\"bRegex\\\": previousSearch.bRegex,\\n\\t\\t\\t\\t\\t\\\"bSmart\\\": previousSearch.bSmart ,\\n\\t\\t\\t\\t\\t\\\"bCaseInsensitive\\\": previousSearch.bCaseInsensitive\\n\\t\\t\\t\\t} );\\n\\t\\n\\t\\t\\t\\t// Need to redraw, without resorting\\n\\t\\t\\t\\tsettings._iDisplayStart = 0;\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\tvar searchDelay = settings.searchDelay !== null ?\\n\\t\\t\\tsettings.searchDelay :\\n\\t\\t\\t_fnDataSource( settings ) === 'ssp' ?\\n\\t\\t\\t\\t400 :\\n\\t\\t\\t\\t0;\\n\\t\\n\\t\\tvar jqFilter = $('input', filter)\\n\\t\\t\\t.val( previousSearch.sSearch )\\n\\t\\t\\t.attr( 'placeholder', language.sSearchPlaceholder )\\n\\t\\t\\t.on(\\n\\t\\t\\t\\t'keyup.DT search.DT input.DT paste.DT cut.DT',\\n\\t\\t\\t\\tsearchDelay ?\\n\\t\\t\\t\\t\\t_fnThrottle( searchFn, searchDelay ) :\\n\\t\\t\\t\\t\\tsearchFn\\n\\t\\t\\t)\\n\\t\\t\\t.on( 'keypress.DT', function(e) {\\n\\t\\t\\t\\t/* Prevent form submission */\\n\\t\\t\\t\\tif ( e.keyCode == 13 ) {\\n\\t\\t\\t\\t\\treturn false;\\n\\t\\t\\t\\t}\\n\\t\\t\\t} )\\n\\t\\t\\t.attr('aria-controls', tableId);\\n\\t\\n\\t\\t// Update the input elements whenever the table is filtered\\n\\t\\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\\n\\t\\t\\tif ( settings === s ) {\\n\\t\\t\\t\\t// IE9 throws an 'unknown error' if document.activeElement is used\\n\\t\\t\\t\\t// inside an iframe or frame...\\n\\t\\t\\t\\ttry {\\n\\t\\t\\t\\t\\tif ( jqFilter[0] !== document.activeElement ) {\\n\\t\\t\\t\\t\\t\\tjqFilter.val( previousSearch.sSearch );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tcatch ( e ) {}\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn filter[0];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Filter the table using both the global filter and column based filtering\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} oSearch search information\\n\\t * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterComplete ( oSettings, oInput, iForce )\\n\\t{\\n\\t\\tvar oPrevSearch = oSettings.oPreviousSearch;\\n\\t\\tvar aoPrevSearch = oSettings.aoPreSearchCols;\\n\\t\\tvar fnSaveFilter = function ( oFilter ) {\\n\\t\\t\\t/* Save the filtering values */\\n\\t\\t\\toPrevSearch.sSearch = oFilter.sSearch;\\n\\t\\t\\toPrevSearch.bRegex = oFilter.bRegex;\\n\\t\\t\\toPrevSearch.bSmart = oFilter.bSmart;\\n\\t\\t\\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\\n\\t\\t};\\n\\t\\tvar fnRegex = function ( o ) {\\n\\t\\t\\t// Backwards compatibility with the bEscapeRegex option\\n\\t\\t\\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\\n\\t\\t};\\n\\t\\n\\t\\t// Resolve any column types that are unknown due to addition or invalidation\\n\\t\\t// @todo As per sort - can this be moved into an event handler?\\n\\t\\t_fnColumnTypes( oSettings );\\n\\t\\n\\t\\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\\n\\t\\tif ( _fnDataSource( oSettings ) != 'ssp' )\\n\\t\\t{\\n\\t\\t\\t/* Global filter */\\n\\t\\t\\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\\n\\t\\t\\tfnSaveFilter( oInput );\\n\\t\\n\\t\\t\\t/* Now do the individual column filter */\\n\\t\\t\\tfor ( var i=0 ; i<aoPrevSearch.length ; i++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\t_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),\\n\\t\\t\\t\\t\\taoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Custom filtering */\\n\\t\\t\\t_fnFilterCustom( oSettings );\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\tfnSaveFilter( oInput );\\n\\t\\t}\\n\\t\\n\\t\\t/* Tell the draw function we have been filtering */\\n\\t\\toSettings.bFiltered = true;\\n\\t\\t_fnCallbackFire( oSettings, null, 'search', [oSettings] );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Apply custom filtering functions\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterCustom( settings )\\n\\t{\\n\\t\\tvar filters = DataTable.ext.search;\\n\\t\\tvar displayRows = settings.aiDisplay;\\n\\t\\tvar row, rowIdx;\\n\\t\\n\\t\\tfor ( var i=0, ien=filters.length ; i<ien ; i++ ) {\\n\\t\\t\\tvar rows = [];\\n\\t\\n\\t\\t\\t// Loop over each row and see if it should be included\\n\\t\\t\\tfor ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\trowIdx = displayRows[ j ];\\n\\t\\t\\t\\trow = settings.aoData[ rowIdx ];\\n\\t\\n\\t\\t\\t\\tif ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {\\n\\t\\t\\t\\t\\trows.push( rowIdx );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// So the array reference doesn't break set the results into the\\n\\t\\t\\t// existing array\\n\\t\\t\\tdisplayRows.length = 0;\\n\\t\\t\\t$.merge( displayRows, rows );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Filter the table on a per-column basis\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {string} sInput string to filter on\\n\\t * @param {int} iColumn column to filter\\n\\t * @param {bool} bRegex treat search string as a regular expression or not\\n\\t * @param {bool} bSmart use smart filtering or not\\n\\t * @param {bool} bCaseInsensitive Do case insenstive matching or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )\\n\\t{\\n\\t\\tif ( searchStr === '' ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar data;\\n\\t\\tvar out = [];\\n\\t\\tvar display = settings.aiDisplay;\\n\\t\\tvar rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );\\n\\t\\n\\t\\tfor ( var i=0 ; i<display.length ; i++ ) {\\n\\t\\t\\tdata = settings.aoData[ display[i] ]._aFilterData[ colIdx ];\\n\\t\\n\\t\\t\\tif ( rpSearch.test( data ) ) {\\n\\t\\t\\t\\tout.push( display[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tsettings.aiDisplay = out;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Filter the data table based on user input and draw the table\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {string} input string to filter on\\n\\t * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)\\n\\t * @param {bool} regex treat as a regular expression or not\\n\\t * @param {bool} smart perform smart filtering or not\\n\\t * @param {bool} caseInsensitive Do case insenstive matching or not\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilter( settings, input, force, regex, smart, caseInsensitive )\\n\\t{\\n\\t\\tvar rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );\\n\\t\\tvar prevSearch = settings.oPreviousSearch.sSearch;\\n\\t\\tvar displayMaster = settings.aiDisplayMaster;\\n\\t\\tvar display, invalidated, i;\\n\\t\\tvar filtered = [];\\n\\t\\n\\t\\t// Need to take account of custom filtering functions - always filter\\n\\t\\tif ( DataTable.ext.search.length !== 0 ) {\\n\\t\\t\\tforce = true;\\n\\t\\t}\\n\\t\\n\\t\\t// Check if any of the rows were invalidated\\n\\t\\tinvalidated = _fnFilterData( settings );\\n\\t\\n\\t\\t// If the input is blank - we just want the full data set\\n\\t\\tif ( input.length <= 0 ) {\\n\\t\\t\\tsettings.aiDisplay = displayMaster.slice();\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// New search - start from the master array\\n\\t\\t\\tif ( invalidated ||\\n\\t\\t\\t\\t force ||\\n\\t\\t\\t\\t prevSearch.length > input.length ||\\n\\t\\t\\t\\t input.indexOf(prevSearch) !== 0 ||\\n\\t\\t\\t\\t settings.bSorted // On resort, the display master needs to be\\n\\t\\t\\t\\t // re-filtered since indexes will have changed\\n\\t\\t\\t) {\\n\\t\\t\\t\\tsettings.aiDisplay = displayMaster.slice();\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Search the display array\\n\\t\\t\\tdisplay = settings.aiDisplay;\\n\\t\\n\\t\\t\\tfor ( i=0 ; i<display.length ; i++ ) {\\n\\t\\t\\t\\tif ( rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {\\n\\t\\t\\t\\t\\tfiltered.push( display[i] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tsettings.aiDisplay = filtered;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Build a regular expression object suitable for searching a table\\n\\t * @param {string} sSearch string to search for\\n\\t * @param {bool} bRegex treat as a regular expression or not\\n\\t * @param {bool} bSmart perform smart filtering or not\\n\\t * @param {bool} bCaseInsensitive Do case insensitive matching or not\\n\\t * @returns {RegExp} constructed object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFilterCreateSearch( search, regex, smart, caseInsensitive )\\n\\t{\\n\\t\\tsearch = regex ?\\n\\t\\t\\tsearch :\\n\\t\\t\\t_fnEscapeRegex( search );\\n\\t\\t\\n\\t\\tif ( smart ) {\\n\\t\\t\\t/* For smart filtering we want to allow the search to work regardless of\\n\\t\\t\\t * word order. We also want double quoted text to be preserved, so word\\n\\t\\t\\t * order is important - a la google. So this is what we want to\\n\\t\\t\\t * generate:\\n\\t\\t\\t * \\n\\t\\t\\t * ^(?=.*?\\\\bone\\\\b)(?=.*?\\\\btwo three\\\\b)(?=.*?\\\\bfour\\\\b).*$\\n\\t\\t\\t */\\n\\t\\t\\tvar a = $.map( search.match( /\\\"[^\\\"]+\\\"|[^ ]+/g ) || [''], function ( word ) {\\n\\t\\t\\t\\tif ( word.charAt(0) === '\\\"' ) {\\n\\t\\t\\t\\t\\tvar m = word.match( /^\\\"(.*)\\\"$/ );\\n\\t\\t\\t\\t\\tword = m ? m[1] : word;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn word.replace('\\\"', '');\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tsearch = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';\\n\\t\\t}\\n\\t\\n\\t\\treturn new RegExp( search, caseInsensitive ? 'i' : '' );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Escape a string such that it can be used in a regular expression\\n\\t * @param {string} sVal string to escape\\n\\t * @returns {string} escaped string\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tvar _fnEscapeRegex = DataTable.util.escapeRegex;\\n\\t\\n\\tvar __filter_div = $('<div>')[0];\\n\\tvar __filter_div_textContent = __filter_div.textContent !== undefined;\\n\\t\\n\\t// Update the filtering data for each row if needed (by invalidation or first run)\\n\\tfunction _fnFilterData ( settings )\\n\\t{\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar column;\\n\\t\\tvar i, j, ien, jen, filterData, cellData, row;\\n\\t\\tvar fomatters = DataTable.ext.type.search;\\n\\t\\tvar wasInvalidated = false;\\n\\t\\n\\t\\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\trow = settings.aoData[i];\\n\\t\\n\\t\\t\\tif ( ! row._aFilterData ) {\\n\\t\\t\\t\\tfilterData = [];\\n\\t\\n\\t\\t\\t\\tfor ( j=0, jen=columns.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\tcolumn = columns[j];\\n\\t\\n\\t\\t\\t\\t\\tif ( column.bSearchable ) {\\n\\t\\t\\t\\t\\t\\tcellData = _fnGetCellData( settings, i, j, 'filter' );\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( fomatters[ column.sType ] ) {\\n\\t\\t\\t\\t\\t\\t\\tcellData = fomatters[ column.sType ]( cellData );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t// Search in DataTables 1.10 is string based. In 1.11 this\\n\\t\\t\\t\\t\\t\\t// should be altered to also allow strict type checking.\\n\\t\\t\\t\\t\\t\\tif ( cellData === null ) {\\n\\t\\t\\t\\t\\t\\t\\tcellData = '';\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( typeof cellData !== 'string' && cellData.toString ) {\\n\\t\\t\\t\\t\\t\\t\\tcellData = cellData.toString();\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tcellData = '';\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// If it looks like there is an HTML entity in the string,\\n\\t\\t\\t\\t\\t// attempt to decode it so sorting works as expected. Note that\\n\\t\\t\\t\\t\\t// we could use a single line of jQuery to do this, but the DOM\\n\\t\\t\\t\\t\\t// method used here is much faster http://jsperf.com/html-decode\\n\\t\\t\\t\\t\\tif ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {\\n\\t\\t\\t\\t\\t\\t__filter_div.innerHTML = cellData;\\n\\t\\t\\t\\t\\t\\tcellData = __filter_div_textContent ?\\n\\t\\t\\t\\t\\t\\t\\t__filter_div.textContent :\\n\\t\\t\\t\\t\\t\\t\\t__filter_div.innerText;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tif ( cellData.replace ) {\\n\\t\\t\\t\\t\\t\\tcellData = cellData.replace(/[\\\\r\\\\n]/g, '');\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tfilterData.push( cellData );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\trow._aFilterData = filterData;\\n\\t\\t\\t\\trow._sFilterRow = filterData.join(' ');\\n\\t\\t\\t\\twasInvalidated = true;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn wasInvalidated;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from the internal Hungarian notation to camelCase for external\\n\\t * interaction\\n\\t * @param {object} obj Object to convert\\n\\t * @returns {object} Inverted object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSearchToCamel ( obj )\\n\\t{\\n\\t\\treturn {\\n\\t\\t\\tsearch: obj.sSearch,\\n\\t\\t\\tsmart: obj.bSmart,\\n\\t\\t\\tregex: obj.bRegex,\\n\\t\\t\\tcaseInsensitive: obj.bCaseInsensitive\\n\\t\\t};\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from camelCase notation to the internal Hungarian. We could use the\\n\\t * Hungarian convert function here, but this is cleaner\\n\\t * @param {object} obj Object to convert\\n\\t * @returns {object} Inverted object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSearchToHung ( obj )\\n\\t{\\n\\t\\treturn {\\n\\t\\t\\tsSearch: obj.search,\\n\\t\\t\\tbSmart: obj.smart,\\n\\t\\t\\tbRegex: obj.regex,\\n\\t\\t\\tbCaseInsensitive: obj.caseInsensitive\\n\\t\\t};\\n\\t}\\n\\t\\n\\t/**\\n\\t * Generate the node required for the info display\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {node} Information element\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlInfo ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttid = settings.sTableId,\\n\\t\\t\\tnodes = settings.aanFeatures.i,\\n\\t\\t\\tn = $('<div/>', {\\n\\t\\t\\t\\t'class': settings.oClasses.sInfo,\\n\\t\\t\\t\\t'id': ! nodes ? tid+'_info' : null\\n\\t\\t\\t} );\\n\\t\\n\\t\\tif ( ! nodes ) {\\n\\t\\t\\t// Update display on each draw\\n\\t\\t\\tsettings.aoDrawCallback.push( {\\n\\t\\t\\t\\t\\\"fn\\\": _fnUpdateInfo,\\n\\t\\t\\t\\t\\\"sName\\\": \\\"information\\\"\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tn\\n\\t\\t\\t\\t.attr( 'role', 'status' )\\n\\t\\t\\t\\t.attr( 'aria-live', 'polite' );\\n\\t\\n\\t\\t\\t// Table is described by our info div\\n\\t\\t\\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\\n\\t\\t}\\n\\t\\n\\t\\treturn n[0];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Update the information elements in the display\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnUpdateInfo ( settings )\\n\\t{\\n\\t\\t/* Show information about the table */\\n\\t\\tvar nodes = settings.aanFeatures.i;\\n\\t\\tif ( nodes.length === 0 ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\tlang = settings.oLanguage,\\n\\t\\t\\tstart = settings._iDisplayStart+1,\\n\\t\\t\\tend = settings.fnDisplayEnd(),\\n\\t\\t\\tmax = settings.fnRecordsTotal(),\\n\\t\\t\\ttotal = settings.fnRecordsDisplay(),\\n\\t\\t\\tout = total ?\\n\\t\\t\\t\\tlang.sInfo :\\n\\t\\t\\t\\tlang.sInfoEmpty;\\n\\t\\n\\t\\tif ( total !== max ) {\\n\\t\\t\\t/* Record set after filtering */\\n\\t\\t\\tout += ' ' + lang.sInfoFiltered;\\n\\t\\t}\\n\\t\\n\\t\\t// Convert the macros\\n\\t\\tout += lang.sInfoPostFix;\\n\\t\\tout = _fnInfoMacros( settings, out );\\n\\t\\n\\t\\tvar callback = lang.fnInfoCallback;\\n\\t\\tif ( callback !== null ) {\\n\\t\\t\\tout = callback.call( settings.oInstance,\\n\\t\\t\\t\\tsettings, start, end, max, total, out\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\t$(nodes).html( out );\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnInfoMacros ( settings, str )\\n\\t{\\n\\t\\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\\n\\t\\t// internally\\n\\t\\tvar\\n\\t\\t\\tformatter = settings.fnFormatNumber,\\n\\t\\t\\tstart = settings._iDisplayStart+1,\\n\\t\\t\\tlen = settings._iDisplayLength,\\n\\t\\t\\tvis = settings.fnRecordsDisplay(),\\n\\t\\t\\tall = len === -1;\\n\\t\\n\\t\\treturn str.\\n\\t\\t\\treplace(/_START_/g, formatter.call( settings, start ) ).\\n\\t\\t\\treplace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).\\n\\t\\t\\treplace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).\\n\\t\\t\\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\\n\\t\\t\\treplace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\\n\\t\\t\\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Draw the table for the first time, adding all required features\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnInitialise ( settings )\\n\\t{\\n\\t\\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\\n\\t\\tvar columns = settings.aoColumns, column;\\n\\t\\tvar features = settings.oFeatures;\\n\\t\\tvar deferLoading = settings.bDeferLoading; // value modified by the draw\\n\\t\\n\\t\\t/* Ensure that the table data is fully initialised */\\n\\t\\tif ( ! settings.bInitialised ) {\\n\\t\\t\\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\t/* Show the display HTML options */\\n\\t\\t_fnAddOptionsHtml( settings );\\n\\t\\n\\t\\t/* Build and draw the header / footer for the table */\\n\\t\\t_fnBuildHead( settings );\\n\\t\\t_fnDrawHead( settings, settings.aoHeader );\\n\\t\\t_fnDrawHead( settings, settings.aoFooter );\\n\\t\\n\\t\\t/* Okay to show that something is going on now */\\n\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t/* Calculate sizes for columns */\\n\\t\\tif ( features.bAutoWidth ) {\\n\\t\\t\\t_fnCalculateColumnWidths( settings );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ ) {\\n\\t\\t\\tcolumn = columns[i];\\n\\t\\n\\t\\t\\tif ( column.sWidth ) {\\n\\t\\t\\t\\tcolumn.nTh.style.width = _fnStringToCss( column.sWidth );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'preInit', [settings] );\\n\\t\\n\\t\\t// If there is default sorting required - let's do it. The sort function\\n\\t\\t// will do the drawing for us. Otherwise we draw the table regardless of the\\n\\t\\t// Ajax source - this allows the table to look initialised for Ajax sourcing\\n\\t\\t// data (show 'loading' message possibly)\\n\\t\\t_fnReDraw( settings );\\n\\t\\n\\t\\t// Server-side processing init complete is done by _fnAjaxUpdateDraw\\n\\t\\tvar dataSrc = _fnDataSource( settings );\\n\\t\\tif ( dataSrc != 'ssp' || deferLoading ) {\\n\\t\\t\\t// if there is an ajax source load the data\\n\\t\\t\\tif ( dataSrc == 'ajax' ) {\\n\\t\\t\\t\\t_fnBuildAjax( settings, [], function(json) {\\n\\t\\t\\t\\t\\tvar aData = _fnAjaxDataSrc( settings, json );\\n\\t\\n\\t\\t\\t\\t\\t// Got the data - add it to the table\\n\\t\\t\\t\\t\\tfor ( i=0 ; i<aData.length ; i++ ) {\\n\\t\\t\\t\\t\\t\\t_fnAddData( settings, aData[i] );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// Reset the init display for cookie saving. We've already done\\n\\t\\t\\t\\t\\t// a filter, and therefore cleared it before. So we need to make\\n\\t\\t\\t\\t\\t// it appear 'fresh'\\n\\t\\t\\t\\t\\tsettings.iInitDisplayStart = iAjaxStart;\\n\\t\\n\\t\\t\\t\\t\\t_fnReDraw( settings );\\n\\t\\n\\t\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t\\t\\t_fnInitComplete( settings, json );\\n\\t\\t\\t\\t}, settings );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t\\t_fnInitComplete( settings );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Draw the table for the first time, adding all required features\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} [json] JSON from the server that completed the table, if using Ajax source\\n\\t * with client-side processing (optional)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnInitComplete ( settings, json )\\n\\t{\\n\\t\\tsettings._bInitComplete = true;\\n\\t\\n\\t\\t// When data was added after the initialisation (data or Ajax) we need to\\n\\t\\t// calculate the column sizing\\n\\t\\tif ( json || settings.oInit.aaData ) {\\n\\t\\t\\t_fnAdjustColumnSizing( settings );\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'plugin-init', [settings, json] );\\n\\t\\t_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnLengthChange ( settings, val )\\n\\t{\\n\\t\\tvar len = parseInt( val, 10 );\\n\\t\\tsettings._iDisplayLength = len;\\n\\t\\n\\t\\t_fnLengthOverflow( settings );\\n\\t\\n\\t\\t// Fire length change event\\n\\t\\t_fnCallbackFire( settings, null, 'length', [settings, len] );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Generate the node required for user display length changing\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {node} Display length feature node\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlLength ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tclasses = settings.oClasses,\\n\\t\\t\\ttableId = settings.sTableId,\\n\\t\\t\\tmenu = settings.aLengthMenu,\\n\\t\\t\\td2 = $.isArray( menu[0] ),\\n\\t\\t\\tlengths = d2 ? menu[0] : menu,\\n\\t\\t\\tlanguage = d2 ? menu[1] : menu;\\n\\t\\n\\t\\tvar select = $('<select/>', {\\n\\t\\t\\t'name': tableId+'_length',\\n\\t\\t\\t'aria-controls': tableId,\\n\\t\\t\\t'class': classes.sLengthSelect\\n\\t\\t} );\\n\\t\\n\\t\\tfor ( var i=0, ien=lengths.length ; i<ien ; i++ ) {\\n\\t\\t\\tselect[0][ i ] = new Option( language[i], lengths[i] );\\n\\t\\t}\\n\\t\\n\\t\\tvar div = $('<div><label/></div>').addClass( classes.sLength );\\n\\t\\tif ( ! settings.aanFeatures.l ) {\\n\\t\\t\\tdiv[0].id = tableId+'_length';\\n\\t\\t}\\n\\t\\n\\t\\tdiv.children().append(\\n\\t\\t\\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\\n\\t\\t);\\n\\t\\n\\t\\t// Can't use `select` variable as user might provide their own and the\\n\\t\\t// reference is broken by the use of outerHTML\\n\\t\\t$('select', div)\\n\\t\\t\\t.val( settings._iDisplayLength )\\n\\t\\t\\t.on( 'change.DT', function(e) {\\n\\t\\t\\t\\t_fnLengthChange( settings, $(this).val() );\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t// Update node value whenever anything changes the table's length\\n\\t\\t$(settings.nTable).on( 'length.dt.DT', function (e, s, len) {\\n\\t\\t\\tif ( settings === s ) {\\n\\t\\t\\t\\t$('select', div).val( len );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn div[0];\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\\t * Note that most of the paging logic is done in\\n\\t * DataTable.ext.pager\\n\\t */\\n\\t\\n\\t/**\\n\\t * Generate the node required for default pagination\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @returns {node} Pagination feature node\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlPaginate ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttype = settings.sPaginationType,\\n\\t\\t\\tplugin = DataTable.ext.pager[ type ],\\n\\t\\t\\tmodern = typeof plugin === 'function',\\n\\t\\t\\tredraw = function( settings ) {\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t},\\n\\t\\t\\tnode = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],\\n\\t\\t\\tfeatures = settings.aanFeatures;\\n\\t\\n\\t\\tif ( ! modern ) {\\n\\t\\t\\tplugin.fnInit( settings, node, redraw );\\n\\t\\t}\\n\\t\\n\\t\\t/* Add a draw callback for the pagination on first instance, to update the paging display */\\n\\t\\tif ( ! features.p )\\n\\t\\t{\\n\\t\\t\\tnode.id = settings.sTableId+'_paginate';\\n\\t\\n\\t\\t\\tsettings.aoDrawCallback.push( {\\n\\t\\t\\t\\t\\\"fn\\\": function( settings ) {\\n\\t\\t\\t\\t\\tif ( modern ) {\\n\\t\\t\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\t\\t\\t\\t\\tlen = settings._iDisplayLength,\\n\\t\\t\\t\\t\\t\\t\\tvisRecords = settings.fnRecordsDisplay(),\\n\\t\\t\\t\\t\\t\\t\\tall = len === -1,\\n\\t\\t\\t\\t\\t\\t\\tpage = all ? 0 : Math.ceil( start / len ),\\n\\t\\t\\t\\t\\t\\t\\tpages = all ? 1 : Math.ceil( visRecords / len ),\\n\\t\\t\\t\\t\\t\\t\\tbuttons = plugin(page, pages),\\n\\t\\t\\t\\t\\t\\t\\ti, ien;\\n\\t\\n\\t\\t\\t\\t\\t\\tfor ( i=0, ien=features.p.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t\\t\\t_fnRenderer( settings, 'pageButton' )(\\n\\t\\t\\t\\t\\t\\t\\t\\tsettings, features.p[i], i, buttons, page, pages\\n\\t\\t\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tplugin.fnUpdate( settings, redraw );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\\"sName\\\": \\\"pagination\\\"\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\treturn node;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Alter the display settings to change the page\\n\\t * @param {object} settings DataTables settings object\\n\\t * @param {string|int} action Paging action to take: \\\"first\\\", \\\"previous\\\",\\n\\t * \\\"next\\\" or \\\"last\\\" or page number to jump to (integer)\\n\\t * @param [bool] redraw Automatically draw the update or not\\n\\t * @returns {bool} true page has changed, false - no change\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnPageChange ( settings, action, redraw )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\tlen = settings._iDisplayLength,\\n\\t\\t\\trecords = settings.fnRecordsDisplay();\\n\\t\\n\\t\\tif ( records === 0 || len === -1 )\\n\\t\\t{\\n\\t\\t\\tstart = 0;\\n\\t\\t}\\n\\t\\telse if ( typeof action === \\\"number\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = action * len;\\n\\t\\n\\t\\t\\tif ( start > records )\\n\\t\\t\\t{\\n\\t\\t\\t\\tstart = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( action == \\\"first\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = 0;\\n\\t\\t}\\n\\t\\telse if ( action == \\\"previous\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = len >= 0 ?\\n\\t\\t\\t\\tstart - len :\\n\\t\\t\\t\\t0;\\n\\t\\n\\t\\t\\tif ( start < 0 )\\n\\t\\t\\t{\\n\\t\\t\\t start = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( action == \\\"next\\\" )\\n\\t\\t{\\n\\t\\t\\tif ( start + len < records )\\n\\t\\t\\t{\\n\\t\\t\\t\\tstart += len;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( action == \\\"last\\\" )\\n\\t\\t{\\n\\t\\t\\tstart = Math.floor( (records-1) / len) * len;\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t_fnLog( settings, 0, \\\"Unknown paging action: \\\"+action, 5 );\\n\\t\\t}\\n\\t\\n\\t\\tvar changed = settings._iDisplayStart !== start;\\n\\t\\tsettings._iDisplayStart = start;\\n\\t\\n\\t\\tif ( changed ) {\\n\\t\\t\\t_fnCallbackFire( settings, null, 'page', [settings] );\\n\\t\\n\\t\\t\\tif ( redraw ) {\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn changed;\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Generate the node required for the processing node\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {node} Processing element\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlProcessing ( settings )\\n\\t{\\n\\t\\treturn $('<div/>', {\\n\\t\\t\\t\\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\\n\\t\\t\\t\\t'class': settings.oClasses.sProcessing\\n\\t\\t\\t} )\\n\\t\\t\\t.html( settings.oLanguage.sProcessing )\\n\\t\\t\\t.insertBefore( settings.nTable )[0];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Display or hide the processing indicator\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {bool} show Show the processing indicator (true) or not (false)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnProcessingDisplay ( settings, show )\\n\\t{\\n\\t\\tif ( settings.oFeatures.bProcessing ) {\\n\\t\\t\\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\\n\\t\\t}\\n\\t\\n\\t\\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\\n\\t}\\n\\t\\n\\t/**\\n\\t * Add any control elements for the table - specifically scrolling\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {node} Node to add to the DOM\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnFeatureHtmlTable ( settings )\\n\\t{\\n\\t\\tvar table = $(settings.nTable);\\n\\t\\n\\t\\t// Add the ARIA grid role to the table\\n\\t\\ttable.attr( 'role', 'grid' );\\n\\t\\n\\t\\t// Scrolling from here on in\\n\\t\\tvar scroll = settings.oScroll;\\n\\t\\n\\t\\tif ( scroll.sX === '' && scroll.sY === '' ) {\\n\\t\\t\\treturn settings.nTable;\\n\\t\\t}\\n\\t\\n\\t\\tvar scrollX = scroll.sX;\\n\\t\\tvar scrollY = scroll.sY;\\n\\t\\tvar classes = settings.oClasses;\\n\\t\\tvar caption = table.children('caption');\\n\\t\\tvar captionSide = caption.length ? caption[0]._captionSide : null;\\n\\t\\tvar headerClone = $( table[0].cloneNode(false) );\\n\\t\\tvar footerClone = $( table[0].cloneNode(false) );\\n\\t\\tvar footer = table.children('tfoot');\\n\\t\\tvar _div = '<div/>';\\n\\t\\tvar size = function ( s ) {\\n\\t\\t\\treturn !s ? null : _fnStringToCss( s );\\n\\t\\t};\\n\\t\\n\\t\\tif ( ! footer.length ) {\\n\\t\\t\\tfooter = null;\\n\\t\\t}\\n\\t\\n\\t\\t/*\\n\\t\\t * The HTML structure that we want to generate in this function is:\\n\\t\\t * div - scroller\\n\\t\\t * div - scroll head\\n\\t\\t * div - scroll head inner\\n\\t\\t * table - scroll head table\\n\\t\\t * thead - thead\\n\\t\\t * div - scroll body\\n\\t\\t * table - table (master table)\\n\\t\\t * thead - thead clone for sizing\\n\\t\\t * tbody - tbody\\n\\t\\t * div - scroll foot\\n\\t\\t * div - scroll foot inner\\n\\t\\t * table - scroll foot table\\n\\t\\t * tfoot - tfoot\\n\\t\\t */\\n\\t\\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\\n\\t\\t\\t.append(\\n\\t\\t\\t\\t$(_div, { 'class': classes.sScrollHead } )\\n\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\toverflow: 'hidden',\\n\\t\\t\\t\\t\\t\\tposition: 'relative',\\n\\t\\t\\t\\t\\t\\tborder: 0,\\n\\t\\t\\t\\t\\t\\twidth: scrollX ? size(scrollX) : '100%'\\n\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t$(_div, { 'class': classes.sScrollHeadInner } )\\n\\t\\t\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\t\\t\\t'box-sizing': 'content-box',\\n\\t\\t\\t\\t\\t\\t\\t\\twidth: scroll.sXInner || '100%'\\n\\t\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\theaderClone\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.removeAttr('id')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.css( 'margin-left', 0 )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append( captionSide === 'top' ? caption : null )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\ttable.children('thead')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t)\\n\\t\\t\\t.append(\\n\\t\\t\\t\\t$(_div, { 'class': classes.sScrollBody } )\\n\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\tposition: 'relative',\\n\\t\\t\\t\\t\\t\\toverflow: 'auto',\\n\\t\\t\\t\\t\\t\\twidth: size( scrollX )\\n\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t.append( table )\\n\\t\\t\\t);\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tscroller.append(\\n\\t\\t\\t\\t$(_div, { 'class': classes.sScrollFoot } )\\n\\t\\t\\t\\t\\t.css( {\\n\\t\\t\\t\\t\\t\\toverflow: 'hidden',\\n\\t\\t\\t\\t\\t\\tborder: 0,\\n\\t\\t\\t\\t\\t\\twidth: scrollX ? size(scrollX) : '100%'\\n\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t$(_div, { 'class': classes.sScrollFootInner } )\\n\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\tfooterClone\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.removeAttr('id')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.css( 'margin-left', 0 )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append( captionSide === 'bottom' ? caption : null )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.append(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\ttable.children('tfoot')\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\tvar children = scroller.children();\\n\\t\\tvar scrollHead = children[0];\\n\\t\\tvar scrollBody = children[1];\\n\\t\\tvar scrollFoot = footer ? children[2] : null;\\n\\t\\n\\t\\t// When the body is scrolled, then we also want to scroll the headers\\n\\t\\tif ( scrollX ) {\\n\\t\\t\\t$(scrollBody).on( 'scroll.DT', function (e) {\\n\\t\\t\\t\\tvar scrollLeft = this.scrollLeft;\\n\\t\\n\\t\\t\\t\\tscrollHead.scrollLeft = scrollLeft;\\n\\t\\n\\t\\t\\t\\tif ( footer ) {\\n\\t\\t\\t\\t\\tscrollFoot.scrollLeft = scrollLeft;\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\t$(scrollBody).css(\\n\\t\\t\\tscrollY && scroll.bCollapse ? 'max-height' : 'height', \\n\\t\\t\\tscrollY\\n\\t\\t);\\n\\t\\n\\t\\tsettings.nScrollHead = scrollHead;\\n\\t\\tsettings.nScrollBody = scrollBody;\\n\\t\\tsettings.nScrollFoot = scrollFoot;\\n\\t\\n\\t\\t// On redraw - align columns\\n\\t\\tsettings.aoDrawCallback.push( {\\n\\t\\t\\t\\\"fn\\\": _fnScrollDraw,\\n\\t\\t\\t\\\"sName\\\": \\\"scrolling\\\"\\n\\t\\t} );\\n\\t\\n\\t\\treturn scroller[0];\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Update the header, footer and body tables for resizing - i.e. column\\n\\t * alignment.\\n\\t *\\n\\t * Welcome to the most horrible function DataTables. The process that this\\n\\t * function follows is basically:\\n\\t * 1. Re-create the table inside the scrolling div\\n\\t * 2. Take live measurements from the DOM\\n\\t * 3. Apply the measurements to align the columns\\n\\t * 4. Clean up\\n\\t *\\n\\t * @param {object} settings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnScrollDraw ( settings )\\n\\t{\\n\\t\\t// Given that this is such a monster function, a lot of variables are use\\n\\t\\t// to try and keep the minimised size as small as possible\\n\\t\\tvar\\n\\t\\t\\tscroll = settings.oScroll,\\n\\t\\t\\tscrollX = scroll.sX,\\n\\t\\t\\tscrollXInner = scroll.sXInner,\\n\\t\\t\\tscrollY = scroll.sY,\\n\\t\\t\\tbarWidth = scroll.iBarWidth,\\n\\t\\t\\tdivHeader = $(settings.nScrollHead),\\n\\t\\t\\tdivHeaderStyle = divHeader[0].style,\\n\\t\\t\\tdivHeaderInner = divHeader.children('div'),\\n\\t\\t\\tdivHeaderInnerStyle = divHeaderInner[0].style,\\n\\t\\t\\tdivHeaderTable = divHeaderInner.children('table'),\\n\\t\\t\\tdivBodyEl = settings.nScrollBody,\\n\\t\\t\\tdivBody = $(divBodyEl),\\n\\t\\t\\tdivBodyStyle = divBodyEl.style,\\n\\t\\t\\tdivFooter = $(settings.nScrollFoot),\\n\\t\\t\\tdivFooterInner = divFooter.children('div'),\\n\\t\\t\\tdivFooterTable = divFooterInner.children('table'),\\n\\t\\t\\theader = $(settings.nTHead),\\n\\t\\t\\ttable = $(settings.nTable),\\n\\t\\t\\ttableEl = table[0],\\n\\t\\t\\ttableStyle = tableEl.style,\\n\\t\\t\\tfooter = settings.nTFoot ? $(settings.nTFoot) : null,\\n\\t\\t\\tbrowser = settings.oBrowser,\\n\\t\\t\\tie67 = browser.bScrollOversize,\\n\\t\\t\\tdtHeaderCells = _pluck( settings.aoColumns, 'nTh' ),\\n\\t\\t\\theaderTrgEls, footerTrgEls,\\n\\t\\t\\theaderSrcEls, footerSrcEls,\\n\\t\\t\\theaderCopy, footerCopy,\\n\\t\\t\\theaderWidths=[], footerWidths=[],\\n\\t\\t\\theaderContent=[], footerContent=[],\\n\\t\\t\\tidx, correction, sanityWidth,\\n\\t\\t\\tzeroOut = function(nSizer) {\\n\\t\\t\\t\\tvar style = nSizer.style;\\n\\t\\t\\t\\tstyle.paddingTop = \\\"0\\\";\\n\\t\\t\\t\\tstyle.paddingBottom = \\\"0\\\";\\n\\t\\t\\t\\tstyle.borderTopWidth = \\\"0\\\";\\n\\t\\t\\t\\tstyle.borderBottomWidth = \\\"0\\\";\\n\\t\\t\\t\\tstyle.height = 0;\\n\\t\\t\\t};\\n\\t\\n\\t\\t// If the scrollbar visibility has changed from the last draw, we need to\\n\\t\\t// adjust the column sizes as the table width will have changed to account\\n\\t\\t// for the scrollbar\\n\\t\\tvar scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;\\n\\t\\t\\n\\t\\tif ( settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined ) {\\n\\t\\t\\tsettings.scrollBarVis = scrollBarVis;\\n\\t\\t\\t_fnAdjustColumnSizing( settings );\\n\\t\\t\\treturn; // adjust column sizing will call this function again\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tsettings.scrollBarVis = scrollBarVis;\\n\\t\\t}\\n\\t\\n\\t\\t/*\\n\\t\\t * 1. Re-create the table inside the scrolling div\\n\\t\\t */\\n\\t\\n\\t\\t// Remove the old minimised thead and tfoot elements in the inner table\\n\\t\\ttable.children('thead, tfoot').remove();\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tfooterCopy = footer.clone().prependTo( table );\\n\\t\\t\\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\\n\\t\\t\\tfooterSrcEls = footerCopy.find('tr');\\n\\t\\t}\\n\\t\\n\\t\\t// Clone the current header and footer elements and then place it into the inner table\\n\\t\\theaderCopy = header.clone().prependTo( table );\\n\\t\\theaderTrgEls = header.find('tr'); // original header is in its own table\\n\\t\\theaderSrcEls = headerCopy.find('tr');\\n\\t\\theaderCopy.find('th, td').removeAttr('tabindex');\\n\\t\\n\\t\\n\\t\\t/*\\n\\t\\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\\n\\t\\t */\\n\\t\\n\\t\\t// Remove old sizing and apply the calculated column widths\\n\\t\\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\\n\\t\\t// calculated sizes to this header\\n\\t\\tif ( ! scrollX )\\n\\t\\t{\\n\\t\\t\\tdivBodyStyle.width = '100%';\\n\\t\\t\\tdivHeader[0].style.width = '100%';\\n\\t\\t}\\n\\t\\n\\t\\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\\n\\t\\t\\tidx = _fnVisibleToColumnIndex( settings, i );\\n\\t\\t\\tel.style.width = settings.aoColumns[idx].sWidth;\\n\\t\\t} );\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\t_fnApplyToChildren( function(n) {\\n\\t\\t\\t\\tn.style.width = \\\"\\\";\\n\\t\\t\\t}, footerSrcEls );\\n\\t\\t}\\n\\t\\n\\t\\t// Size the table as a whole\\n\\t\\tsanityWidth = table.outerWidth();\\n\\t\\tif ( scrollX === \\\"\\\" ) {\\n\\t\\t\\t// No x scrolling\\n\\t\\t\\ttableStyle.width = \\\"100%\\\";\\n\\t\\n\\t\\t\\t// IE7 will make the width of the table when 100% include the scrollbar\\n\\t\\t\\t// - which is shouldn't. When there is a scrollbar we need to take this\\n\\t\\t\\t// into account.\\n\\t\\t\\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\\n\\t\\t\\t\\tdivBody.css('overflow-y') == \\\"scroll\\\")\\n\\t\\t\\t) {\\n\\t\\t\\t\\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Recalculate the sanity width\\n\\t\\t\\tsanityWidth = table.outerWidth();\\n\\t\\t}\\n\\t\\telse if ( scrollXInner !== \\\"\\\" ) {\\n\\t\\t\\t// legacy x scroll inner has been given - use it\\n\\t\\t\\ttableStyle.width = _fnStringToCss(scrollXInner);\\n\\t\\n\\t\\t\\t// Recalculate the sanity width\\n\\t\\t\\tsanityWidth = table.outerWidth();\\n\\t\\t}\\n\\t\\n\\t\\t// Hidden header should have zero height, so remove padding and borders. Then\\n\\t\\t// set the width based on the real headers\\n\\t\\n\\t\\t// Apply all styles in one pass\\n\\t\\t_fnApplyToChildren( zeroOut, headerSrcEls );\\n\\t\\n\\t\\t// Read all widths in next pass\\n\\t\\t_fnApplyToChildren( function(nSizer) {\\n\\t\\t\\theaderContent.push( nSizer.innerHTML );\\n\\t\\t\\theaderWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\\n\\t\\t}, headerSrcEls );\\n\\t\\n\\t\\t// Apply all widths in final pass\\n\\t\\t_fnApplyToChildren( function(nToSize, i) {\\n\\t\\t\\t// Only apply widths to the DataTables detected header cells - this\\n\\t\\t\\t// prevents complex headers from having contradictory sizes applied\\n\\t\\t\\tif ( $.inArray( nToSize, dtHeaderCells ) !== -1 ) {\\n\\t\\t\\t\\tnToSize.style.width = headerWidths[i];\\n\\t\\t\\t}\\n\\t\\t}, headerTrgEls );\\n\\t\\n\\t\\t$(headerSrcEls).height(0);\\n\\t\\n\\t\\t/* Same again with the footer if we have one */\\n\\t\\tif ( footer )\\n\\t\\t{\\n\\t\\t\\t_fnApplyToChildren( zeroOut, footerSrcEls );\\n\\t\\n\\t\\t\\t_fnApplyToChildren( function(nSizer) {\\n\\t\\t\\t\\tfooterContent.push( nSizer.innerHTML );\\n\\t\\t\\t\\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\\n\\t\\t\\t}, footerSrcEls );\\n\\t\\n\\t\\t\\t_fnApplyToChildren( function(nToSize, i) {\\n\\t\\t\\t\\tnToSize.style.width = footerWidths[i];\\n\\t\\t\\t}, footerTrgEls );\\n\\t\\n\\t\\t\\t$(footerSrcEls).height(0);\\n\\t\\t}\\n\\t\\n\\t\\n\\t\\t/*\\n\\t\\t * 3. Apply the measurements\\n\\t\\t */\\n\\t\\n\\t\\t// \\\"Hide\\\" the header and footer that we used for the sizing. We need to keep\\n\\t\\t// the content of the cell so that the width applied to the header and body\\n\\t\\t// both match, but we want to hide it completely. We want to also fix their\\n\\t\\t// width to what they currently are\\n\\t\\t_fnApplyToChildren( function(nSizer, i) {\\n\\t\\t\\tnSizer.innerHTML = '<div class=\\\"dataTables_sizing\\\" style=\\\"height:0;overflow:hidden;\\\">'+headerContent[i]+'</div>';\\n\\t\\t\\tnSizer.style.width = headerWidths[i];\\n\\t\\t}, headerSrcEls );\\n\\t\\n\\t\\tif ( footer )\\n\\t\\t{\\n\\t\\t\\t_fnApplyToChildren( function(nSizer, i) {\\n\\t\\t\\t\\tnSizer.innerHTML = '<div class=\\\"dataTables_sizing\\\" style=\\\"height:0;overflow:hidden;\\\">'+footerContent[i]+'</div>';\\n\\t\\t\\t\\tnSizer.style.width = footerWidths[i];\\n\\t\\t\\t}, footerSrcEls );\\n\\t\\t}\\n\\t\\n\\t\\t// Sanity check that the table is of a sensible width. If not then we are going to get\\n\\t\\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\\n\\t\\tif ( table.outerWidth() < sanityWidth )\\n\\t\\t{\\n\\t\\t\\t// The min width depends upon if we have a vertical scrollbar visible or not */\\n\\t\\t\\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\\n\\t\\t\\t\\tdivBody.css('overflow-y') == \\\"scroll\\\")) ?\\n\\t\\t\\t\\t\\tsanityWidth+barWidth :\\n\\t\\t\\t\\t\\tsanityWidth;\\n\\t\\n\\t\\t\\t// IE6/7 are a law unto themselves...\\n\\t\\t\\tif ( ie67 && (divBodyEl.scrollHeight >\\n\\t\\t\\t\\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \\\"scroll\\\")\\n\\t\\t\\t) {\\n\\t\\t\\t\\ttableStyle.width = _fnStringToCss( correction-barWidth );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// And give the user a warning that we've stopped the table getting too small\\n\\t\\t\\tif ( scrollX === \\\"\\\" || scrollXInner !== \\\"\\\" ) {\\n\\t\\t\\t\\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\tcorrection = '100%';\\n\\t\\t}\\n\\t\\n\\t\\t// Apply to the container elements\\n\\t\\tdivBodyStyle.width = _fnStringToCss( correction );\\n\\t\\tdivHeaderStyle.width = _fnStringToCss( correction );\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\\n\\t\\t}\\n\\t\\n\\t\\n\\t\\t/*\\n\\t\\t * 4. Clean up\\n\\t\\t */\\n\\t\\tif ( ! scrollY ) {\\n\\t\\t\\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\\n\\t\\t\\t * the scrollbar height from the visible display, rather than adding it on. We need to\\n\\t\\t\\t * set the height in order to sort this. Don't want to do it in any other browsers.\\n\\t\\t\\t */\\n\\t\\t\\tif ( ie67 ) {\\n\\t\\t\\t\\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* Finally set the width's of the header and footer tables */\\n\\t\\tvar iOuterWidth = table.outerWidth();\\n\\t\\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\\n\\t\\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\\n\\t\\n\\t\\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\\n\\t\\t// provide a bit more space to allow \\\"overflow\\\" scrolling (i.e. past the scrollbar)\\n\\t\\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \\\"scroll\\\";\\n\\t\\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\\n\\t\\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\\\"px\\\" : \\\"0px\\\";\\n\\t\\n\\t\\tif ( footer ) {\\n\\t\\t\\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\\n\\t\\t\\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\\n\\t\\t\\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\\\"px\\\" : \\\"0px\\\";\\n\\t\\t}\\n\\t\\n\\t\\t// Correct DOM ordering for colgroup - comes before the thead\\n\\t\\ttable.children('colgroup').insertBefore( table.children('thead') );\\n\\t\\n\\t\\t/* Adjust the position of the header in case we loose the y-scrollbar */\\n\\t\\tdivBody.scroll();\\n\\t\\n\\t\\t// If sorting or filtering has occurred, jump the scrolling back to the top\\n\\t\\t// only if we aren't holding the position\\n\\t\\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\\n\\t\\t\\tdivBodyEl.scrollTop = 0;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Apply a given function to the display child nodes of an element array (typically\\n\\t * TD children of TR rows\\n\\t * @param {function} fn Method to apply to the objects\\n\\t * @param array {nodes} an1 List of elements to look through for display children\\n\\t * @param array {nodes} an2 Another list (identical structure to the first) - optional\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnApplyToChildren( fn, an1, an2 )\\n\\t{\\n\\t\\tvar index=0, i=0, iLen=an1.length;\\n\\t\\tvar nNode1, nNode2;\\n\\t\\n\\t\\twhile ( i < iLen ) {\\n\\t\\t\\tnNode1 = an1[i].firstChild;\\n\\t\\t\\tnNode2 = an2 ? an2[i].firstChild : null;\\n\\t\\n\\t\\t\\twhile ( nNode1 ) {\\n\\t\\t\\t\\tif ( nNode1.nodeType === 1 ) {\\n\\t\\t\\t\\t\\tif ( an2 ) {\\n\\t\\t\\t\\t\\t\\tfn( nNode1, nNode2, index );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tfn( nNode1, index );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tindex++;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tnNode1 = nNode1.nextSibling;\\n\\t\\t\\t\\tnNode2 = an2 ? nNode2.nextSibling : null;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\ti++;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\tvar __re_html_remove = /<.*?>/g;\\n\\t\\n\\t\\n\\t/**\\n\\t * Calculate the width of columns for the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCalculateColumnWidths ( oSettings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ttable = oSettings.nTable,\\n\\t\\t\\tcolumns = oSettings.aoColumns,\\n\\t\\t\\tscroll = oSettings.oScroll,\\n\\t\\t\\tscrollY = scroll.sY,\\n\\t\\t\\tscrollX = scroll.sX,\\n\\t\\t\\tscrollXInner = scroll.sXInner,\\n\\t\\t\\tcolumnCount = columns.length,\\n\\t\\t\\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\\n\\t\\t\\theaderCells = $('th', oSettings.nTHead),\\n\\t\\t\\ttableWidthAttr = table.getAttribute('width'), // from DOM element\\n\\t\\t\\ttableContainer = table.parentNode,\\n\\t\\t\\tuserInputs = false,\\n\\t\\t\\ti, column, columnIdx, width, outerWidth,\\n\\t\\t\\tbrowser = oSettings.oBrowser,\\n\\t\\t\\tie67 = browser.bScrollOversize;\\n\\t\\n\\t\\tvar styleWidth = table.style.width;\\n\\t\\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\\n\\t\\t\\ttableWidthAttr = styleWidth;\\n\\t\\t}\\n\\t\\n\\t\\t/* Convert any user input sizes into pixel sizes */\\n\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\tcolumn = columns[ visibleColumns[i] ];\\n\\t\\n\\t\\t\\tif ( column.sWidth !== null ) {\\n\\t\\t\\t\\tcolumn.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );\\n\\t\\n\\t\\t\\t\\tuserInputs = true;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* If the number of columns in the DOM equals the number that we have to\\n\\t\\t * process in DataTables, then we can use the offsets that are created by\\n\\t\\t * the web- browser. No custom sizes can be set in order for this to happen,\\n\\t\\t * nor scrolling used\\n\\t\\t */\\n\\t\\tif ( ie67 || ! userInputs && ! scrollX && ! scrollY &&\\n\\t\\t columnCount == _fnVisbleColumns( oSettings ) &&\\n\\t\\t columnCount == headerCells.length\\n\\t\\t) {\\n\\t\\t\\tfor ( i=0 ; i<columnCount ; i++ ) {\\n\\t\\t\\t\\tvar colIdx = _fnVisibleToColumnIndex( oSettings, i );\\n\\t\\n\\t\\t\\t\\tif ( colIdx !== null ) {\\n\\t\\t\\t\\t\\tcolumns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse\\n\\t\\t{\\n\\t\\t\\t// Otherwise construct a single row, worst case, table with the widest\\n\\t\\t\\t// node in the data, assign any user defined widths, then insert it into\\n\\t\\t\\t// the DOM and allow the browser to do all the hard work of calculating\\n\\t\\t\\t// table widths\\n\\t\\t\\tvar tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table\\n\\t\\t\\t\\t.css( 'visibility', 'hidden' )\\n\\t\\t\\t\\t.removeAttr( 'id' );\\n\\t\\n\\t\\t\\t// Clean up the table body\\n\\t\\t\\ttmpTable.find('tbody tr').remove();\\n\\t\\t\\tvar tr = $('<tr/>').appendTo( tmpTable.find('tbody') );\\n\\t\\n\\t\\t\\t// Clone the table header and footer - we can't use the header / footer\\n\\t\\t\\t// from the cloned table, since if scrolling is active, the table's\\n\\t\\t\\t// real header and footer are contained in different table tags\\n\\t\\t\\ttmpTable.find('thead, tfoot').remove();\\n\\t\\t\\ttmpTable\\n\\t\\t\\t\\t.append( $(oSettings.nTHead).clone() )\\n\\t\\t\\t\\t.append( $(oSettings.nTFoot).clone() );\\n\\t\\n\\t\\t\\t// Remove any assigned widths from the footer (from scrolling)\\n\\t\\t\\ttmpTable.find('tfoot th, tfoot td').css('width', '');\\n\\t\\n\\t\\t\\t// Apply custom sizing to the cloned header\\n\\t\\t\\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\\n\\t\\n\\t\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\t\\tcolumn = columns[ visibleColumns[i] ];\\n\\t\\n\\t\\t\\t\\theaderCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?\\n\\t\\t\\t\\t\\t_fnStringToCss( column.sWidthOrig ) :\\n\\t\\t\\t\\t\\t'';\\n\\t\\n\\t\\t\\t\\t// For scrollX we need to force the column width otherwise the\\n\\t\\t\\t\\t// browser will collapse it. If this width is smaller than the\\n\\t\\t\\t\\t// width the column requires, then it will have no effect\\n\\t\\t\\t\\tif ( column.sWidthOrig && scrollX ) {\\n\\t\\t\\t\\t\\t$( headerCells[i] ).append( $('<div/>').css( {\\n\\t\\t\\t\\t\\t\\twidth: column.sWidthOrig,\\n\\t\\t\\t\\t\\t\\tmargin: 0,\\n\\t\\t\\t\\t\\t\\tpadding: 0,\\n\\t\\t\\t\\t\\t\\tborder: 0,\\n\\t\\t\\t\\t\\t\\theight: 1\\n\\t\\t\\t\\t\\t} ) );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Find the widest cell for each column and put it into the table\\n\\t\\t\\tif ( oSettings.aoData.length ) {\\n\\t\\t\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\t\\t\\tcolumnIdx = visibleColumns[i];\\n\\t\\t\\t\\t\\tcolumn = columns[ columnIdx ];\\n\\t\\n\\t\\t\\t\\t\\t$( _fnGetWidestNode( oSettings, columnIdx ) )\\n\\t\\t\\t\\t\\t\\t.clone( false )\\n\\t\\t\\t\\t\\t\\t.append( column.sContentPadding )\\n\\t\\t\\t\\t\\t\\t.appendTo( tr );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Tidy the temporary table - remove name attributes so there aren't\\n\\t\\t\\t// duplicated in the dom (radio elements for example)\\n\\t\\t\\t$('[name]', tmpTable).removeAttr('name');\\n\\t\\n\\t\\t\\t// Table has been built, attach to the document so we can work with it.\\n\\t\\t\\t// A holding element is used, positioned at the top of the container\\n\\t\\t\\t// with minimal height, so it has no effect on if the container scrolls\\n\\t\\t\\t// or not. Otherwise it might trigger scrolling when it actually isn't\\n\\t\\t\\t// needed\\n\\t\\t\\tvar holder = $('<div/>').css( scrollX || scrollY ?\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\tposition: 'absolute',\\n\\t\\t\\t\\t\\t\\ttop: 0,\\n\\t\\t\\t\\t\\t\\tleft: 0,\\n\\t\\t\\t\\t\\t\\theight: 1,\\n\\t\\t\\t\\t\\t\\tright: 0,\\n\\t\\t\\t\\t\\t\\toverflow: 'hidden'\\n\\t\\t\\t\\t\\t} :\\n\\t\\t\\t\\t\\t{}\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.append( tmpTable )\\n\\t\\t\\t\\t.appendTo( tableContainer );\\n\\t\\n\\t\\t\\t// When scrolling (X or Y) we want to set the width of the table as \\n\\t\\t\\t// appropriate. However, when not scrolling leave the table width as it\\n\\t\\t\\t// is. This results in slightly different, but I think correct behaviour\\n\\t\\t\\tif ( scrollX && scrollXInner ) {\\n\\t\\t\\t\\ttmpTable.width( scrollXInner );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( scrollX ) {\\n\\t\\t\\t\\ttmpTable.css( 'width', 'auto' );\\n\\t\\t\\t\\ttmpTable.removeAttr('width');\\n\\t\\n\\t\\t\\t\\t// If there is no width attribute or style, then allow the table to\\n\\t\\t\\t\\t// collapse\\n\\t\\t\\t\\tif ( tmpTable.width() < tableContainer.clientWidth && tableWidthAttr ) {\\n\\t\\t\\t\\t\\ttmpTable.width( tableContainer.clientWidth );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\telse if ( scrollY ) {\\n\\t\\t\\t\\ttmpTable.width( tableContainer.clientWidth );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( tableWidthAttr ) {\\n\\t\\t\\t\\ttmpTable.width( tableWidthAttr );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Get the width of each column in the constructed table - we need to\\n\\t\\t\\t// know the inner width (so it can be assigned to the other table's\\n\\t\\t\\t// cells) and the outer width so we can calculate the full width of the\\n\\t\\t\\t// table. This is safe since DataTables requires a unique cell for each\\n\\t\\t\\t// column, but if ever a header can span multiple columns, this will\\n\\t\\t\\t// need to be modified.\\n\\t\\t\\tvar total = 0;\\n\\t\\t\\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\\n\\t\\t\\t\\tvar cell = $(headerCells[i]);\\n\\t\\t\\t\\tvar border = cell.outerWidth() - cell.width();\\n\\t\\n\\t\\t\\t\\t// Use getBounding... where possible (not IE8-) because it can give\\n\\t\\t\\t\\t// sub-pixel accuracy, which we then want to round up!\\n\\t\\t\\t\\tvar bounding = browser.bBounding ?\\n\\t\\t\\t\\t\\tMath.ceil( headerCells[i].getBoundingClientRect().width ) :\\n\\t\\t\\t\\t\\tcell.outerWidth();\\n\\t\\n\\t\\t\\t\\t// Total is tracked to remove any sub-pixel errors as the outerWidth\\n\\t\\t\\t\\t// of the table might not equal the total given here (IE!).\\n\\t\\t\\t\\ttotal += bounding;\\n\\t\\n\\t\\t\\t\\t// Width for each column to use\\n\\t\\t\\t\\tcolumns[ visibleColumns[i] ].sWidth = _fnStringToCss( bounding - border );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\ttable.style.width = _fnStringToCss( total );\\n\\t\\n\\t\\t\\t// Finished with the table - ditch it\\n\\t\\t\\tholder.remove();\\n\\t\\t}\\n\\t\\n\\t\\t// If there is a width attr, we want to attach an event listener which\\n\\t\\t// allows the table sizing to automatically adjust when the window is\\n\\t\\t// resized. Use the width attr rather than CSS, since we can't know if the\\n\\t\\t// CSS is a relative value or absolute - DOM read is always px.\\n\\t\\tif ( tableWidthAttr ) {\\n\\t\\t\\ttable.style.width = _fnStringToCss( tableWidthAttr );\\n\\t\\t}\\n\\t\\n\\t\\tif ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {\\n\\t\\t\\tvar bindResize = function () {\\n\\t\\t\\t\\t$(window).on('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {\\n\\t\\t\\t\\t\\t_fnAdjustColumnSizing( oSettings );\\n\\t\\t\\t\\t} ) );\\n\\t\\t\\t};\\n\\t\\n\\t\\t\\t// IE6/7 will crash if we bind a resize event handler on page load.\\n\\t\\t\\t// To be removed in 1.11 which drops IE6/7 support\\n\\t\\t\\tif ( ie67 ) {\\n\\t\\t\\t\\tsetTimeout( bindResize, 1000 );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tbindResize();\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\toSettings._reszEvt = true;\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Throttle the calls to a function. Arguments and context are maintained for\\n\\t * the throttled function\\n\\t * @param {function} fn Function to be called\\n\\t * @param {int} [freq=200] call frequency in mS\\n\\t * @returns {function} wrapped function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tvar _fnThrottle = DataTable.util.throttle;\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert a CSS unit width to pixels (e.g. 2em)\\n\\t * @param {string} width width to be converted\\n\\t * @param {node} parent parent to get the with for (required for relative widths) - optional\\n\\t * @returns {int} width in pixels\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnConvertToWidth ( width, parent )\\n\\t{\\n\\t\\tif ( ! width ) {\\n\\t\\t\\treturn 0;\\n\\t\\t}\\n\\t\\n\\t\\tvar n = $('<div/>')\\n\\t\\t\\t.css( 'width', _fnStringToCss( width ) )\\n\\t\\t\\t.appendTo( parent || document.body );\\n\\t\\n\\t\\tvar val = n[0].offsetWidth;\\n\\t\\tn.remove();\\n\\t\\n\\t\\treturn val;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the widest node\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} colIdx column of interest\\n\\t * @returns {node} widest table node\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetWidestNode( settings, colIdx )\\n\\t{\\n\\t\\tvar idx = _fnGetMaxLenString( settings, colIdx );\\n\\t\\tif ( idx < 0 ) {\\n\\t\\t\\treturn null;\\n\\t\\t}\\n\\t\\n\\t\\tvar data = settings.aoData[ idx ];\\n\\t\\treturn ! data.nTr ? // Might not have been created when deferred rendering\\n\\t\\t\\t$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\\n\\t\\t\\tdata.anCells[ colIdx ];\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the maximum strlen for each data column\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} colIdx column of interest\\n\\t * @returns {string} max string length for each column\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnGetMaxLenString( settings, colIdx )\\n\\t{\\n\\t\\tvar s, max=-1, maxIdx = -1;\\n\\t\\n\\t\\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\ts = _fnGetCellData( settings, i, colIdx, 'display' )+'';\\n\\t\\t\\ts = s.replace( __re_html_remove, '' );\\n\\t\\t\\ts = s.replace( / /g, ' ' );\\n\\t\\n\\t\\t\\tif ( s.length > max ) {\\n\\t\\t\\t\\tmax = s.length;\\n\\t\\t\\t\\tmaxIdx = i;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn maxIdx;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Append a CSS unit (only if required) to a string\\n\\t * @param {string} value to css-ify\\n\\t * @returns {string} value with css unit\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnStringToCss( s )\\n\\t{\\n\\t\\tif ( s === null ) {\\n\\t\\t\\treturn '0px';\\n\\t\\t}\\n\\t\\n\\t\\tif ( typeof s == 'number' ) {\\n\\t\\t\\treturn s < 0 ?\\n\\t\\t\\t\\t'0px' :\\n\\t\\t\\t\\ts+'px';\\n\\t\\t}\\n\\t\\n\\t\\t// Check it has a unit character already\\n\\t\\treturn s.match(/\\\\d$/) ?\\n\\t\\t\\ts+'px' :\\n\\t\\t\\ts;\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\tfunction _fnSortFlatten ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti, iLen, k, kLen,\\n\\t\\t\\taSort = [],\\n\\t\\t\\taiOrig = [],\\n\\t\\t\\taoColumns = settings.aoColumns,\\n\\t\\t\\taDataSort, iCol, sType, srcCol,\\n\\t\\t\\tfixed = settings.aaSortingFixed,\\n\\t\\t\\tfixedObj = $.isPlainObject( fixed ),\\n\\t\\t\\tnestedSort = [],\\n\\t\\t\\tadd = function ( a ) {\\n\\t\\t\\t\\tif ( a.length && ! $.isArray( a[0] ) ) {\\n\\t\\t\\t\\t\\t// 1D array\\n\\t\\t\\t\\t\\tnestedSort.push( a );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t// 2D array\\n\\t\\t\\t\\t\\t$.merge( nestedSort, a );\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\n\\t\\t// Build the sort array, with pre-fix and post-fix options if they have been\\n\\t\\t// specified\\n\\t\\tif ( $.isArray( fixed ) ) {\\n\\t\\t\\tadd( fixed );\\n\\t\\t}\\n\\t\\n\\t\\tif ( fixedObj && fixed.pre ) {\\n\\t\\t\\tadd( fixed.pre );\\n\\t\\t}\\n\\t\\n\\t\\tadd( settings.aaSorting );\\n\\t\\n\\t\\tif (fixedObj && fixed.post ) {\\n\\t\\t\\tadd( fixed.post );\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0 ; i<nestedSort.length ; i++ )\\n\\t\\t{\\n\\t\\t\\tsrcCol = nestedSort[i][0];\\n\\t\\t\\taDataSort = aoColumns[ srcCol ].aDataSort;\\n\\t\\n\\t\\t\\tfor ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )\\n\\t\\t\\t{\\n\\t\\t\\t\\tiCol = aDataSort[k];\\n\\t\\t\\t\\tsType = aoColumns[ iCol ].sType || 'string';\\n\\t\\n\\t\\t\\t\\tif ( nestedSort[i]._idx === undefined ) {\\n\\t\\t\\t\\t\\tnestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\taSort.push( {\\n\\t\\t\\t\\t\\tsrc: srcCol,\\n\\t\\t\\t\\t\\tcol: iCol,\\n\\t\\t\\t\\t\\tdir: nestedSort[i][1],\\n\\t\\t\\t\\t\\tindex: nestedSort[i]._idx,\\n\\t\\t\\t\\t\\ttype: sType,\\n\\t\\t\\t\\t\\tformatter: DataTable.ext.type.order[ sType+\\\"-pre\\\" ]\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn aSort;\\n\\t}\\n\\t\\n\\t/**\\n\\t * Change the order of the table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t * @todo This really needs split up!\\n\\t */\\n\\tfunction _fnSort ( oSettings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti, ien, iLen, j, jLen, k, kLen,\\n\\t\\t\\tsDataType, nTh,\\n\\t\\t\\taiOrig = [],\\n\\t\\t\\toExtSort = DataTable.ext.type.order,\\n\\t\\t\\taoData = oSettings.aoData,\\n\\t\\t\\taoColumns = oSettings.aoColumns,\\n\\t\\t\\taDataSort, data, iCol, sType, oSort,\\n\\t\\t\\tformatters = 0,\\n\\t\\t\\tsortCol,\\n\\t\\t\\tdisplayMaster = oSettings.aiDisplayMaster,\\n\\t\\t\\taSort;\\n\\t\\n\\t\\t// Resolve any column types that are unknown due to addition or invalidation\\n\\t\\t// @todo Can this be moved into a 'data-ready' handler which is called when\\n\\t\\t// data is going to be used in the table?\\n\\t\\t_fnColumnTypes( oSettings );\\n\\t\\n\\t\\taSort = _fnSortFlatten( oSettings );\\n\\t\\n\\t\\tfor ( i=0, ien=aSort.length ; i<ien ; i++ ) {\\n\\t\\t\\tsortCol = aSort[i];\\n\\t\\n\\t\\t\\t// Track if we can use the fast sort algorithm\\n\\t\\t\\tif ( sortCol.formatter ) {\\n\\t\\t\\t\\tformatters++;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Load the data needed for the sort, for each cell\\n\\t\\t\\t_fnSortData( oSettings, sortCol.col );\\n\\t\\t}\\n\\t\\n\\t\\t/* No sorting required if server-side or no sorting array */\\n\\t\\tif ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )\\n\\t\\t{\\n\\t\\t\\t// Create a value - key array of the current row positions such that we can use their\\n\\t\\t\\t// current position during the sort, if values match, in order to perform stable sorting\\n\\t\\t\\tfor ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {\\n\\t\\t\\t\\taiOrig[ displayMaster[i] ] = i;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Do the sort - here we want multi-column sorting based on a given data source (column)\\n\\t\\t\\t * and sorting function (from oSort) in a certain direction. It's reasonably complex to\\n\\t\\t\\t * follow on it's own, but this is what we want (example two column sorting):\\n\\t\\t\\t * fnLocalSorting = function(a,b){\\n\\t\\t\\t * var iTest;\\n\\t\\t\\t * iTest = oSort['string-asc']('data11', 'data12');\\n\\t\\t\\t * if (iTest !== 0)\\n\\t\\t\\t * return iTest;\\n\\t\\t\\t * iTest = oSort['numeric-desc']('data21', 'data22');\\n\\t\\t\\t * if (iTest !== 0)\\n\\t\\t\\t * return iTest;\\n\\t\\t\\t * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );\\n\\t\\t\\t * }\\n\\t\\t\\t * Basically we have a test for each sorting column, if the data in that column is equal,\\n\\t\\t\\t * test the next column. If all columns match, then we use a numeric sort on the row\\n\\t\\t\\t * positions in the original data array to provide a stable sort.\\n\\t\\t\\t *\\n\\t\\t\\t * Note - I know it seems excessive to have two sorting methods, but the first is around\\n\\t\\t\\t * 15% faster, so the second is only maintained for backwards compatibility with sorting\\n\\t\\t\\t * methods which do not have a pre-sort formatting function.\\n\\t\\t\\t */\\n\\t\\t\\tif ( formatters === aSort.length ) {\\n\\t\\t\\t\\t// All sort types have formatting functions\\n\\t\\t\\t\\tdisplayMaster.sort( function ( a, b ) {\\n\\t\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\t\\tx, y, k, test, sort,\\n\\t\\t\\t\\t\\t\\tlen=aSort.length,\\n\\t\\t\\t\\t\\t\\tdataA = aoData[a]._aSortData,\\n\\t\\t\\t\\t\\t\\tdataB = aoData[b]._aSortData;\\n\\t\\n\\t\\t\\t\\t\\tfor ( k=0 ; k<len ; k++ ) {\\n\\t\\t\\t\\t\\t\\tsort = aSort[k];\\n\\t\\n\\t\\t\\t\\t\\t\\tx = dataA[ sort.col ];\\n\\t\\t\\t\\t\\t\\ty = dataB[ sort.col ];\\n\\t\\n\\t\\t\\t\\t\\t\\ttest = x<y ? -1 : x>y ? 1 : 0;\\n\\t\\t\\t\\t\\t\\tif ( test !== 0 ) {\\n\\t\\t\\t\\t\\t\\t\\treturn sort.dir === 'asc' ? test : -test;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tx = aiOrig[a];\\n\\t\\t\\t\\t\\ty = aiOrig[b];\\n\\t\\t\\t\\t\\treturn x<y ? -1 : x>y ? 1 : 0;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Depreciated - remove in 1.11 (providing a plug-in option)\\n\\t\\t\\t\\t// Not all sort types have formatting methods, so we have to call their sorting\\n\\t\\t\\t\\t// methods.\\n\\t\\t\\t\\tdisplayMaster.sort( function ( a, b ) {\\n\\t\\t\\t\\t\\tvar\\n\\t\\t\\t\\t\\t\\tx, y, k, l, test, sort, fn,\\n\\t\\t\\t\\t\\t\\tlen=aSort.length,\\n\\t\\t\\t\\t\\t\\tdataA = aoData[a]._aSortData,\\n\\t\\t\\t\\t\\t\\tdataB = aoData[b]._aSortData;\\n\\t\\n\\t\\t\\t\\t\\tfor ( k=0 ; k<len ; k++ ) {\\n\\t\\t\\t\\t\\t\\tsort = aSort[k];\\n\\t\\n\\t\\t\\t\\t\\t\\tx = dataA[ sort.col ];\\n\\t\\t\\t\\t\\t\\ty = dataB[ sort.col ];\\n\\t\\n\\t\\t\\t\\t\\t\\tfn = oExtSort[ sort.type+\\\"-\\\"+sort.dir ] || oExtSort[ \\\"string-\\\"+sort.dir ];\\n\\t\\t\\t\\t\\t\\ttest = fn( x, y );\\n\\t\\t\\t\\t\\t\\tif ( test !== 0 ) {\\n\\t\\t\\t\\t\\t\\t\\treturn test;\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tx = aiOrig[a];\\n\\t\\t\\t\\t\\ty = aiOrig[b];\\n\\t\\t\\t\\t\\treturn x<y ? -1 : x>y ? 1 : 0;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t/* Tell the draw function that we have sorted the data */\\n\\t\\toSettings.bSorted = true;\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnSortAria ( settings )\\n\\t{\\n\\t\\tvar label;\\n\\t\\tvar nextSort;\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar aSort = _fnSortFlatten( settings );\\n\\t\\tvar oAria = settings.oLanguage.oAria;\\n\\t\\n\\t\\t// ARIA attributes - need to loop all columns, to update all (removing old\\n\\t\\t// attributes as needed)\\n\\t\\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\\n\\t\\t{\\n\\t\\t\\tvar col = columns[i];\\n\\t\\t\\tvar asSorting = col.asSorting;\\n\\t\\t\\tvar sTitle = col.sTitle.replace( /<.*?>/g, \\\"\\\" );\\n\\t\\t\\tvar th = col.nTh;\\n\\t\\n\\t\\t\\t// IE7 is throwing an error when setting these properties with jQuery's\\n\\t\\t\\t// attr() and removeAttr() methods...\\n\\t\\t\\tth.removeAttribute('aria-sort');\\n\\t\\n\\t\\t\\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\\n\\t\\t\\tif ( col.bSortable ) {\\n\\t\\t\\t\\tif ( aSort.length > 0 && aSort[0].col == i ) {\\n\\t\\t\\t\\t\\tth.setAttribute('aria-sort', aSort[0].dir==\\\"asc\\\" ? \\\"ascending\\\" : \\\"descending\\\" );\\n\\t\\t\\t\\t\\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tnextSort = asSorting[0];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tlabel = sTitle + ( nextSort === \\\"asc\\\" ?\\n\\t\\t\\t\\t\\toAria.sSortAscending :\\n\\t\\t\\t\\t\\toAria.sSortDescending\\n\\t\\t\\t\\t);\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tlabel = sTitle;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tth.setAttribute('aria-label', label);\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Function to run on user sort request\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {node} attachTo node to attach the handler to\\n\\t * @param {int} colIdx column sorting index\\n\\t * @param {boolean} [append=false] Append the requested sort to the existing\\n\\t * sort if true (i.e. multi-column sort)\\n\\t * @param {function} [callback] callback function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSortListener ( settings, colIdx, append, callback )\\n\\t{\\n\\t\\tvar col = settings.aoColumns[ colIdx ];\\n\\t\\tvar sorting = settings.aaSorting;\\n\\t\\tvar asSorting = col.asSorting;\\n\\t\\tvar nextSortIdx;\\n\\t\\tvar next = function ( a, overflow ) {\\n\\t\\t\\tvar idx = a._idx;\\n\\t\\t\\tif ( idx === undefined ) {\\n\\t\\t\\t\\tidx = $.inArray( a[1], asSorting );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn idx+1 < asSorting.length ?\\n\\t\\t\\t\\tidx+1 :\\n\\t\\t\\t\\toverflow ?\\n\\t\\t\\t\\t\\tnull :\\n\\t\\t\\t\\t\\t0;\\n\\t\\t};\\n\\t\\n\\t\\t// Convert to 2D array if needed\\n\\t\\tif ( typeof sorting[0] === 'number' ) {\\n\\t\\t\\tsorting = settings.aaSorting = [ sorting ];\\n\\t\\t}\\n\\t\\n\\t\\t// If appending the sort then we are multi-column sorting\\n\\t\\tif ( append && settings.oFeatures.bSortMulti ) {\\n\\t\\t\\t// Are we already doing some kind of sort on this column?\\n\\t\\t\\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\\n\\t\\n\\t\\t\\tif ( sortIdx !== -1 ) {\\n\\t\\t\\t\\t// Yes, modify the sort\\n\\t\\t\\t\\tnextSortIdx = next( sorting[sortIdx], true );\\n\\t\\n\\t\\t\\t\\tif ( nextSortIdx === null && sorting.length === 1 ) {\\n\\t\\t\\t\\t\\tnextSortIdx = 0; // can't remove sorting completely\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tif ( nextSortIdx === null ) {\\n\\t\\t\\t\\t\\tsorting.splice( sortIdx, 1 );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\\n\\t\\t\\t\\t\\tsorting[sortIdx]._idx = nextSortIdx;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// No sort on this column yet\\n\\t\\t\\t\\tsorting.push( [ colIdx, asSorting[0], 0 ] );\\n\\t\\t\\t\\tsorting[sorting.length-1]._idx = 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( sorting.length && sorting[0][0] == colIdx ) {\\n\\t\\t\\t// Single column - already sorting on this column, modify the sort\\n\\t\\t\\tnextSortIdx = next( sorting[0] );\\n\\t\\n\\t\\t\\tsorting.length = 1;\\n\\t\\t\\tsorting[0][1] = asSorting[ nextSortIdx ];\\n\\t\\t\\tsorting[0]._idx = nextSortIdx;\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Single column - sort only on this column\\n\\t\\t\\tsorting.length = 0;\\n\\t\\t\\tsorting.push( [ colIdx, asSorting[0] ] );\\n\\t\\t\\tsorting[0]._idx = 0;\\n\\t\\t}\\n\\t\\n\\t\\t// Run the sort by calling a full redraw\\n\\t\\t_fnReDraw( settings );\\n\\t\\n\\t\\t// callback used for async user interaction\\n\\t\\tif ( typeof callback == 'function' ) {\\n\\t\\t\\tcallback( settings );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Attach a sort handler (click) to a node\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {node} attachTo node to attach the handler to\\n\\t * @param {int} colIdx column sorting index\\n\\t * @param {function} [callback] callback function\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\\n\\t{\\n\\t\\tvar col = settings.aoColumns[ colIdx ];\\n\\t\\n\\t\\t_fnBindAction( attachTo, {}, function (e) {\\n\\t\\t\\t/* If the column is not sortable - don't to anything */\\n\\t\\t\\tif ( col.bSortable === false ) {\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// If processing is enabled use a timeout to allow the processing\\n\\t\\t\\t// display to be shown - otherwise to it synchronously\\n\\t\\t\\tif ( settings.oFeatures.bProcessing ) {\\n\\t\\t\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t\\t\\tsetTimeout( function() {\\n\\t\\t\\t\\t\\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\\n\\t\\n\\t\\t\\t\\t\\t// In server-side processing, the draw callback will remove the\\n\\t\\t\\t\\t\\t// processing display\\n\\t\\t\\t\\t\\tif ( _fnDataSource( settings ) !== 'ssp' ) {\\n\\t\\t\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}, 0 );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Set the sorting classes on table's body, Note: it is safe to call this function\\n\\t * when bSort and bSortClasses are false\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSortingClasses( settings )\\n\\t{\\n\\t\\tvar oldSort = settings.aLastSort;\\n\\t\\tvar sortClass = settings.oClasses.sSortColumn;\\n\\t\\tvar sort = _fnSortFlatten( settings );\\n\\t\\tvar features = settings.oFeatures;\\n\\t\\tvar i, ien, colIdx;\\n\\t\\n\\t\\tif ( features.bSort && features.bSortClasses ) {\\n\\t\\t\\t// Remove old sorting classes\\n\\t\\t\\tfor ( i=0, ien=oldSort.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcolIdx = oldSort[i].src;\\n\\t\\n\\t\\t\\t\\t// Remove column sorting\\n\\t\\t\\t\\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\\n\\t\\t\\t\\t\\t.removeClass( sortClass + (i<2 ? i+1 : 3) );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Add new column sorting\\n\\t\\t\\tfor ( i=0, ien=sort.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tcolIdx = sort[i].src;\\n\\t\\n\\t\\t\\t\\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\\n\\t\\t\\t\\t\\t.addClass( sortClass + (i<2 ? i+1 : 3) );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\tsettings.aLastSort = sort;\\n\\t}\\n\\t\\n\\t\\n\\t// Get the data to sort a column, be it from cache, fresh (populating the\\n\\t// cache), or from a sort formatter\\n\\tfunction _fnSortData( settings, idx )\\n\\t{\\n\\t\\t// Custom sorting function - provided by the sort data type\\n\\t\\tvar column = settings.aoColumns[ idx ];\\n\\t\\tvar customSort = DataTable.ext.order[ column.sSortDataType ];\\n\\t\\tvar customData;\\n\\t\\n\\t\\tif ( customSort ) {\\n\\t\\t\\tcustomData = customSort.call( settings.oInstance, settings, idx,\\n\\t\\t\\t\\t_fnColumnIndexToVisible( settings, idx )\\n\\t\\t\\t);\\n\\t\\t}\\n\\t\\n\\t\\t// Use / populate cache\\n\\t\\tvar row, cellData;\\n\\t\\tvar formatter = DataTable.ext.type.order[ column.sType+\\\"-pre\\\" ];\\n\\t\\n\\t\\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\trow = settings.aoData[i];\\n\\t\\n\\t\\t\\tif ( ! row._aSortData ) {\\n\\t\\t\\t\\trow._aSortData = [];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( ! row._aSortData[idx] || customSort ) {\\n\\t\\t\\t\\tcellData = customSort ?\\n\\t\\t\\t\\t\\tcustomData[i] : // If there was a custom sort function, use data from there\\n\\t\\t\\t\\t\\t_fnGetCellData( settings, i, idx, 'sort' );\\n\\t\\n\\t\\t\\t\\trow._aSortData[ idx ] = formatter ?\\n\\t\\t\\t\\t\\tformatter( cellData ) :\\n\\t\\t\\t\\t\\tcellData;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Save the state of a table\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSaveState ( settings )\\n\\t{\\n\\t\\tif ( !settings.oFeatures.bStateSave || settings.bDestroying )\\n\\t\\t{\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\t/* Store the interesting variables */\\n\\t\\tvar state = {\\n\\t\\t\\ttime: +new Date(),\\n\\t\\t\\tstart: settings._iDisplayStart,\\n\\t\\t\\tlength: settings._iDisplayLength,\\n\\t\\t\\torder: $.extend( true, [], settings.aaSorting ),\\n\\t\\t\\tsearch: _fnSearchToCamel( settings.oPreviousSearch ),\\n\\t\\t\\tcolumns: $.map( settings.aoColumns, function ( col, i ) {\\n\\t\\t\\t\\treturn {\\n\\t\\t\\t\\t\\tvisible: col.bVisible,\\n\\t\\t\\t\\t\\tsearch: _fnSearchToCamel( settings.aoPreSearchCols[i] )\\n\\t\\t\\t\\t};\\n\\t\\t\\t} )\\n\\t\\t};\\n\\t\\n\\t\\t_fnCallbackFire( settings, \\\"aoStateSaveParams\\\", 'stateSaveParams', [settings, state] );\\n\\t\\n\\t\\tsettings.oSavedState = state;\\n\\t\\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, state );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Attempt to load a saved table state\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {object} oInit DataTables init object so we can override settings\\n\\t * @param {function} callback Callback to execute when the state has been loaded\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnLoadState ( settings, oInit, callback )\\n\\t{\\n\\t\\tvar i, ien;\\n\\t\\tvar columns = settings.aoColumns;\\n\\t\\tvar loaded = function ( s ) {\\n\\t\\t\\tif ( ! s || ! s.time ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Allow custom and plug-in manipulation functions to alter the saved data set and\\n\\t\\t\\t// cancelling of loading by returning false\\n\\t\\t\\tvar abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] );\\n\\t\\t\\tif ( $.inArray( false, abStateLoad ) !== -1 ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Reject old data\\n\\t\\t\\tvar duration = settings.iStateDuration;\\n\\t\\t\\tif ( duration > 0 && s.time < +new Date() - (duration*1000) ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Number of columns have changed - all bets are off, no restore of settings\\n\\t\\t\\tif ( s.columns && columns.length !== s.columns.length ) {\\n\\t\\t\\t\\tcallback();\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Store the saved state so it might be accessed at any time\\n\\t\\t\\tsettings.oLoadedState = $.extend( true, {}, s );\\n\\t\\n\\t\\t\\t// Restore key features - todo - for 1.11 this needs to be done by\\n\\t\\t\\t// subscribed events\\n\\t\\t\\tif ( s.start !== undefined ) {\\n\\t\\t\\t\\tsettings._iDisplayStart = s.start;\\n\\t\\t\\t\\tsettings.iInitDisplayStart = s.start;\\n\\t\\t\\t}\\n\\t\\t\\tif ( s.length !== undefined ) {\\n\\t\\t\\t\\tsettings._iDisplayLength = s.length;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Order\\n\\t\\t\\tif ( s.order !== undefined ) {\\n\\t\\t\\t\\tsettings.aaSorting = [];\\n\\t\\t\\t\\t$.each( s.order, function ( i, col ) {\\n\\t\\t\\t\\t\\tsettings.aaSorting.push( col[0] >= columns.length ?\\n\\t\\t\\t\\t\\t\\t[ 0, col[1] ] :\\n\\t\\t\\t\\t\\t\\tcol\\n\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Search\\n\\t\\t\\tif ( s.search !== undefined ) {\\n\\t\\t\\t\\t$.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Columns\\n\\t\\t\\t//\\n\\t\\t\\tif ( s.columns ) {\\n\\t\\t\\t\\tfor ( i=0, ien=s.columns.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\tvar col = s.columns[i];\\n\\t\\n\\t\\t\\t\\t\\t// Visibility\\n\\t\\t\\t\\t\\tif ( col.visible !== undefined ) {\\n\\t\\t\\t\\t\\t\\tcolumns[i].bVisible = col.visible;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t// Search\\n\\t\\t\\t\\t\\tif ( col.search !== undefined ) {\\n\\t\\t\\t\\t\\t\\t$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] );\\n\\t\\t\\tcallback();\\n\\t\\t}\\n\\t\\n\\t\\tif ( ! settings.oFeatures.bStateSave ) {\\n\\t\\t\\tcallback();\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded );\\n\\t\\n\\t\\tif ( state !== undefined ) {\\n\\t\\t\\tloaded( state );\\n\\t\\t}\\n\\t\\t// otherwise, wait for the loaded callback to be executed\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Return the settings object for a particular table\\n\\t * @param {node} table table we are using as a dataTable\\n\\t * @returns {object} Settings object - or null if not found\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnSettingsFromNode ( table )\\n\\t{\\n\\t\\tvar settings = DataTable.settings;\\n\\t\\tvar idx = $.inArray( table, _pluck( settings, 'nTable' ) );\\n\\t\\n\\t\\treturn idx !== -1 ?\\n\\t\\t\\tsettings[ idx ] :\\n\\t\\t\\tnull;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Log an error message\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {int} level log error messages, or display them to the user\\n\\t * @param {string} msg error message\\n\\t * @param {int} tn Technical note id to get more information about the error.\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnLog( settings, level, msg, tn )\\n\\t{\\n\\t\\tmsg = 'DataTables warning: '+\\n\\t\\t\\t(settings ? 'table id='+settings.sTableId+' - ' : '')+msg;\\n\\t\\n\\t\\tif ( tn ) {\\n\\t\\t\\tmsg += '. For more information about this error, please see '+\\n\\t\\t\\t'http://datatables.net/tn/'+tn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( ! level ) {\\n\\t\\t\\t// Backwards compatibility pre 1.10\\n\\t\\t\\tvar ext = DataTable.ext;\\n\\t\\t\\tvar type = ext.sErrMode || ext.errMode;\\n\\t\\n\\t\\t\\tif ( settings ) {\\n\\t\\t\\t\\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( type == 'alert' ) {\\n\\t\\t\\t\\talert( msg );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( type == 'throw' ) {\\n\\t\\t\\t\\tthrow new Error(msg);\\n\\t\\t\\t}\\n\\t\\t\\telse if ( typeof type == 'function' ) {\\n\\t\\t\\t\\ttype( settings, tn, msg );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( window.console && console.log ) {\\n\\t\\t\\tconsole.log( msg );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * See if a property is defined on one object, if so assign it to the other object\\n\\t * @param {object} ret target object\\n\\t * @param {object} src source object\\n\\t * @param {string} name property\\n\\t * @param {string} [mappedName] name to map too - optional, name used if not given\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnMap( ret, src, name, mappedName )\\n\\t{\\n\\t\\tif ( $.isArray( name ) ) {\\n\\t\\t\\t$.each( name, function (i, val) {\\n\\t\\t\\t\\tif ( $.isArray( val ) ) {\\n\\t\\t\\t\\t\\t_fnMap( ret, src, val[0], val[1] );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t_fnMap( ret, src, val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( mappedName === undefined ) {\\n\\t\\t\\tmappedName = name;\\n\\t\\t}\\n\\t\\n\\t\\tif ( src[name] !== undefined ) {\\n\\t\\t\\tret[mappedName] = src[name];\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Extend objects - very similar to jQuery.extend, but deep copy objects, and\\n\\t * shallow copy arrays. The reason we need to do this, is that we don't want to\\n\\t * deep copy array init values (such as aaSorting) since the dev wouldn't be\\n\\t * able to override them, but we do want to deep copy arrays.\\n\\t * @param {object} out Object to extend\\n\\t * @param {object} extender Object from which the properties will be applied to\\n\\t * out\\n\\t * @param {boolean} breakRefs If true, then arrays will be sliced to take an\\n\\t * independent copy with the exception of the `data` or `aaData` parameters\\n\\t * if they are present. This is so you can pass in a collection to\\n\\t * DataTables and have that used as your data source without breaking the\\n\\t * references\\n\\t * @returns {object} out Reference, just for convenience - out === the return.\\n\\t * @memberof DataTable#oApi\\n\\t * @todo This doesn't take account of arrays inside the deep copied objects.\\n\\t */\\n\\tfunction _fnExtend( out, extender, breakRefs )\\n\\t{\\n\\t\\tvar val;\\n\\t\\n\\t\\tfor ( var prop in extender ) {\\n\\t\\t\\tif ( extender.hasOwnProperty(prop) ) {\\n\\t\\t\\t\\tval = extender[prop];\\n\\t\\n\\t\\t\\t\\tif ( $.isPlainObject( val ) ) {\\n\\t\\t\\t\\t\\tif ( ! $.isPlainObject( out[prop] ) ) {\\n\\t\\t\\t\\t\\t\\tout[prop] = {};\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t$.extend( true, out[prop], val );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {\\n\\t\\t\\t\\t\\tout[prop] = val.slice();\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tout[prop] = val;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn out;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Bind an event handers to allow a click or return key to activate the callback.\\n\\t * This is good for accessibility since a return on the keyboard will have the\\n\\t * same effect as a click, if the element has focus.\\n\\t * @param {element} n Element to bind the action to\\n\\t * @param {object} oData Data object to pass to the triggered function\\n\\t * @param {function} fn Callback function for when the event is triggered\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnBindAction( n, oData, fn )\\n\\t{\\n\\t\\t$(n)\\n\\t\\t\\t.on( 'click.DT', oData, function (e) {\\n\\t\\t\\t\\t\\tn.blur(); // Remove focus outline for mouse users\\n\\t\\t\\t\\t\\tfn(e);\\n\\t\\t\\t\\t} )\\n\\t\\t\\t.on( 'keypress.DT', oData, function (e){\\n\\t\\t\\t\\t\\tif ( e.which === 13 ) {\\n\\t\\t\\t\\t\\t\\te.preventDefault();\\n\\t\\t\\t\\t\\t\\tfn(e);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} )\\n\\t\\t\\t.on( 'selectstart.DT', function () {\\n\\t\\t\\t\\t\\t/* Take the brutal approach to cancelling text selection */\\n\\t\\t\\t\\t\\treturn false;\\n\\t\\t\\t\\t} );\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Register a callback function. Easily allows a callback function to be added to\\n\\t * an array store of callback functions that can then all be called together.\\n\\t * @param {object} oSettings dataTables settings object\\n\\t * @param {string} sStore Name of the array storage for the callbacks in oSettings\\n\\t * @param {function} fn Function to be called back\\n\\t * @param {string} sName Identifying name for the callback (i.e. a label)\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCallbackReg( oSettings, sStore, fn, sName )\\n\\t{\\n\\t\\tif ( fn )\\n\\t\\t{\\n\\t\\t\\toSettings[sStore].push( {\\n\\t\\t\\t\\t\\\"fn\\\": fn,\\n\\t\\t\\t\\t\\\"sName\\\": sName\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Fire callback functions and trigger events. Note that the loop over the\\n\\t * callback array store is done backwards! Further note that you do not want to\\n\\t * fire off triggers in time sensitive applications (for example cell creation)\\n\\t * as its slow.\\n\\t * @param {object} settings dataTables settings object\\n\\t * @param {string} callbackArr Name of the array storage for the callbacks in\\n\\t * oSettings\\n\\t * @param {string} eventName Name of the jQuery custom event to trigger. If\\n\\t * null no trigger is fired\\n\\t * @param {array} args Array of arguments to pass to the callback function /\\n\\t * trigger\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnCallbackFire( settings, callbackArr, eventName, args )\\n\\t{\\n\\t\\tvar ret = [];\\n\\t\\n\\t\\tif ( callbackArr ) {\\n\\t\\t\\tret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {\\n\\t\\t\\t\\treturn val.fn.apply( settings.oInstance, args );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\tif ( eventName !== null ) {\\n\\t\\t\\tvar e = $.Event( eventName+'.dt' );\\n\\t\\n\\t\\t\\t$(settings.nTable).trigger( e, args );\\n\\t\\n\\t\\t\\tret.push( e.result );\\n\\t\\t}\\n\\t\\n\\t\\treturn ret;\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnLengthOverflow ( settings )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\tend = settings.fnDisplayEnd(),\\n\\t\\t\\tlen = settings._iDisplayLength;\\n\\t\\n\\t\\t/* If we have space to show extra rows (backing up from the end point - then do so */\\n\\t\\tif ( start >= end )\\n\\t\\t{\\n\\t\\t\\tstart = end - len;\\n\\t\\t}\\n\\t\\n\\t\\t// Keep the start record on the current page\\n\\t\\tstart -= (start % len);\\n\\t\\n\\t\\tif ( len === -1 || start < 0 )\\n\\t\\t{\\n\\t\\t\\tstart = 0;\\n\\t\\t}\\n\\t\\n\\t\\tsettings._iDisplayStart = start;\\n\\t}\\n\\t\\n\\t\\n\\tfunction _fnRenderer( settings, type )\\n\\t{\\n\\t\\tvar renderer = settings.renderer;\\n\\t\\tvar host = DataTable.ext.renderer[type];\\n\\t\\n\\t\\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\\n\\t\\t\\t// Specific renderer for this type. If available use it, otherwise use\\n\\t\\t\\t// the default.\\n\\t\\t\\treturn host[renderer[type]] || host._;\\n\\t\\t}\\n\\t\\telse if ( typeof renderer === 'string' ) {\\n\\t\\t\\t// Common renderer - if there is one available for this type use it,\\n\\t\\t\\t// otherwise use the default\\n\\t\\t\\treturn host[renderer] || host._;\\n\\t\\t}\\n\\t\\n\\t\\t// Use the default\\n\\t\\treturn host._;\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Detect the data source being used for the table. Used to simplify the code\\n\\t * a little (ajax) and to make it compress a little smaller.\\n\\t *\\n\\t * @param {object} settings dataTables settings object\\n\\t * @returns {string} Data source\\n\\t * @memberof DataTable#oApi\\n\\t */\\n\\tfunction _fnDataSource ( settings )\\n\\t{\\n\\t\\tif ( settings.oFeatures.bServerSide ) {\\n\\t\\t\\treturn 'ssp';\\n\\t\\t}\\n\\t\\telse if ( settings.ajax || settings.sAjaxSource ) {\\n\\t\\t\\treturn 'ajax';\\n\\t\\t}\\n\\t\\treturn 'dom';\\n\\t}\\n\\t\\n\\n\\t\\n\\t\\n\\t/**\\n\\t * Computed structure of the DataTables API, defined by the options passed to\\n\\t * `DataTable.Api.register()` when building the API.\\n\\t *\\n\\t * The structure is built in order to speed creation and extension of the Api\\n\\t * objects since the extensions are effectively pre-parsed.\\n\\t *\\n\\t * The array is an array of objects with the following structure, where this\\n\\t * base array represents the Api prototype base:\\n\\t *\\n\\t * [\\n\\t * {\\n\\t * name: 'data' -- string - Property name\\n\\t * val: function () {}, -- function - Api method (or undefined if just an object\\n\\t * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\\n\\t * propExt: [ ... ] -- array - Array of Api object definitions to extend the property\\n\\t * },\\n\\t * {\\n\\t * name: 'row'\\n\\t * val: {},\\n\\t * methodExt: [ ... ],\\n\\t * propExt: [\\n\\t * {\\n\\t * name: 'data'\\n\\t * val: function () {},\\n\\t * methodExt: [ ... ],\\n\\t * propExt: [ ... ]\\n\\t * },\\n\\t * ...\\n\\t * ]\\n\\t * }\\n\\t * ]\\n\\t *\\n\\t * @type {Array}\\n\\t * @ignore\\n\\t */\\n\\tvar __apiStruct = [];\\n\\t\\n\\t\\n\\t/**\\n\\t * `Array.prototype` reference.\\n\\t *\\n\\t * @type object\\n\\t * @ignore\\n\\t */\\n\\tvar __arrayProto = Array.prototype;\\n\\t\\n\\t\\n\\t/**\\n\\t * Abstraction for `context` parameter of the `Api` constructor to allow it to\\n\\t * take several different forms for ease of use.\\n\\t *\\n\\t * Each of the input parameter types will be converted to a DataTables settings\\n\\t * object where possible.\\n\\t *\\n\\t * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one\\n\\t * of:\\n\\t *\\n\\t * * `string` - jQuery selector. Any DataTables' matching the given selector\\n\\t * with be found and used.\\n\\t * * `node` - `TABLE` node which has already been formed into a DataTable.\\n\\t * * `jQuery` - A jQuery object of `TABLE` nodes.\\n\\t * * `object` - DataTables settings object\\n\\t * * `DataTables.Api` - API instance\\n\\t * @return {array|null} Matching DataTables settings objects. `null` or\\n\\t * `undefined` is returned if no matching DataTable is found.\\n\\t * @ignore\\n\\t */\\n\\tvar _toSettings = function ( mixed )\\n\\t{\\n\\t\\tvar idx, jq;\\n\\t\\tvar settings = DataTable.settings;\\n\\t\\tvar tables = $.map( settings, function (el, i) {\\n\\t\\t\\treturn el.nTable;\\n\\t\\t} );\\n\\t\\n\\t\\tif ( ! mixed ) {\\n\\t\\t\\treturn [];\\n\\t\\t}\\n\\t\\telse if ( mixed.nTable && mixed.oApi ) {\\n\\t\\t\\t// DataTables settings object\\n\\t\\t\\treturn [ mixed ];\\n\\t\\t}\\n\\t\\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\\n\\t\\t\\t// Table node\\n\\t\\t\\tidx = $.inArray( mixed, tables );\\n\\t\\t\\treturn idx !== -1 ? [ settings[idx] ] : null;\\n\\t\\t}\\n\\t\\telse if ( mixed && typeof mixed.settings === 'function' ) {\\n\\t\\t\\treturn mixed.settings().toArray();\\n\\t\\t}\\n\\t\\telse if ( typeof mixed === 'string' ) {\\n\\t\\t\\t// jQuery selector\\n\\t\\t\\tjq = $(mixed);\\n\\t\\t}\\n\\t\\telse if ( mixed instanceof $ ) {\\n\\t\\t\\t// jQuery object (also DataTables instance)\\n\\t\\t\\tjq = mixed;\\n\\t\\t}\\n\\t\\n\\t\\tif ( jq ) {\\n\\t\\t\\treturn jq.map( function(i) {\\n\\t\\t\\t\\tidx = $.inArray( this, tables );\\n\\t\\t\\t\\treturn idx !== -1 ? settings[idx] : null;\\n\\t\\t\\t} ).toArray();\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables API class - used to control and interface with one or more\\n\\t * DataTables enhanced tables.\\n\\t *\\n\\t * The API class is heavily based on jQuery, presenting a chainable interface\\n\\t * that you can use to interact with tables. Each instance of the API class has\\n\\t * a \\\"context\\\" - i.e. the tables that it will operate on. This could be a single\\n\\t * table, all tables on a page or a sub-set thereof.\\n\\t *\\n\\t * Additionally the API is designed to allow you to easily work with the data in\\n\\t * the tables, retrieving and manipulating it as required. This is done by\\n\\t * presenting the API class as an array like interface. The contents of the\\n\\t * array depend upon the actions requested by each method (for example\\n\\t * `rows().nodes()` will return an array of nodes, while `rows().data()` will\\n\\t * return an array of objects or arrays depending upon your table's\\n\\t * configuration). The API object has a number of array like methods (`push`,\\n\\t * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\\n\\t * `unique` etc) to assist your working with the data held in a table.\\n\\t *\\n\\t * Most methods (those which return an Api instance) are chainable, which means\\n\\t * the return from a method call also has all of the methods available that the\\n\\t * top level object had. For example, these two calls are equivalent:\\n\\t *\\n\\t * // Not chained\\n\\t * api.row.add( {...} );\\n\\t * api.draw();\\n\\t *\\n\\t * // Chained\\n\\t * api.row.add( {...} ).draw();\\n\\t *\\n\\t * @class DataTable.Api\\n\\t * @param {array|object|string|jQuery} context DataTable identifier. This is\\n\\t * used to define which DataTables enhanced tables this API will operate on.\\n\\t * Can be one of:\\n\\t *\\n\\t * * `string` - jQuery selector. Any DataTables' matching the given selector\\n\\t * with be found and used.\\n\\t * * `node` - `TABLE` node which has already been formed into a DataTable.\\n\\t * * `jQuery` - A jQuery object of `TABLE` nodes.\\n\\t * * `object` - DataTables settings object\\n\\t * @param {array} [data] Data to initialise the Api instance with.\\n\\t *\\n\\t * @example\\n\\t * // Direct initialisation during DataTables construction\\n\\t * var api = $('#example').DataTable();\\n\\t *\\n\\t * @example\\n\\t * // Initialisation using a DataTables jQuery object\\n\\t * var api = $('#example').dataTable().api();\\n\\t *\\n\\t * @example\\n\\t * // Initialisation as a constructor\\n\\t * var api = new $.fn.DataTable.Api( 'table.dataTable' );\\n\\t */\\n\\t_Api = function ( context, data )\\n\\t{\\n\\t\\tif ( ! (this instanceof _Api) ) {\\n\\t\\t\\treturn new _Api( context, data );\\n\\t\\t}\\n\\t\\n\\t\\tvar settings = [];\\n\\t\\tvar ctxSettings = function ( o ) {\\n\\t\\t\\tvar a = _toSettings( o );\\n\\t\\t\\tif ( a ) {\\n\\t\\t\\t\\tsettings = settings.concat( a );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\tif ( $.isArray( context ) ) {\\n\\t\\t\\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tctxSettings( context[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tctxSettings( context );\\n\\t\\t}\\n\\t\\n\\t\\t// Remove duplicates\\n\\t\\tthis.context = _unique( settings );\\n\\t\\n\\t\\t// Initial data\\n\\t\\tif ( data ) {\\n\\t\\t\\t$.merge( this, data );\\n\\t\\t}\\n\\t\\n\\t\\t// selector\\n\\t\\tthis.selector = {\\n\\t\\t\\trows: null,\\n\\t\\t\\tcols: null,\\n\\t\\t\\topts: null\\n\\t\\t};\\n\\t\\n\\t\\t_Api.extend( this, this, __apiStruct );\\n\\t};\\n\\t\\n\\tDataTable.Api = _Api;\\n\\t\\n\\t// Don't destroy the existing prototype, just extend it. Required for jQuery 2's\\n\\t// isPlainObject.\\n\\t$.extend( _Api.prototype, {\\n\\t\\tany: function ()\\n\\t\\t{\\n\\t\\t\\treturn this.count() !== 0;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tconcat: __arrayProto.concat,\\n\\t\\n\\t\\n\\t\\tcontext: [], // array of table settings objects\\n\\t\\n\\t\\n\\t\\tcount: function ()\\n\\t\\t{\\n\\t\\t\\treturn this.flatten().length;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\teach: function ( fn )\\n\\t\\t{\\n\\t\\t\\tfor ( var i=0, ien=this.length ; i<ien; i++ ) {\\n\\t\\t\\t\\tfn.call( this, this[i], i, this );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn this;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\teq: function ( idx )\\n\\t\\t{\\n\\t\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\t\\treturn ctx.length > idx ?\\n\\t\\t\\t\\tnew _Api( ctx[idx], this[idx] ) :\\n\\t\\t\\t\\tnull;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tfilter: function ( fn )\\n\\t\\t{\\n\\t\\t\\tvar a = [];\\n\\t\\n\\t\\t\\tif ( __arrayProto.filter ) {\\n\\t\\t\\t\\ta = __arrayProto.filter.call( this, fn, this );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\\n\\t\\t\\t\\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\tif ( fn.call( this, this[i], i, this ) ) {\\n\\t\\t\\t\\t\\t\\ta.push( this[i] );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn new _Api( this.context, a );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tflatten: function ()\\n\\t\\t{\\n\\t\\t\\tvar a = [];\\n\\t\\t\\treturn new _Api( this.context, a.concat.apply( a, this.toArray() ) );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tjoin: __arrayProto.join,\\n\\t\\n\\t\\n\\t\\tindexOf: __arrayProto.indexOf || function (obj, start)\\n\\t\\t{\\n\\t\\t\\tfor ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( this[i] === obj ) {\\n\\t\\t\\t\\t\\treturn i;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn -1;\\n\\t\\t},\\n\\t\\n\\t\\titerator: function ( flatten, type, fn, alwaysNew ) {\\n\\t\\t\\tvar\\n\\t\\t\\t\\ta = [], ret,\\n\\t\\t\\t\\ti, ien, j, jen,\\n\\t\\t\\t\\tcontext = this.context,\\n\\t\\t\\t\\trows, items, item,\\n\\t\\t\\t\\tselector = this.selector;\\n\\t\\n\\t\\t\\t// Argument shifting\\n\\t\\t\\tif ( typeof flatten === 'string' ) {\\n\\t\\t\\t\\talwaysNew = fn;\\n\\t\\t\\t\\tfn = type;\\n\\t\\t\\t\\ttype = flatten;\\n\\t\\t\\t\\tflatten = false;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tfor ( i=0, ien=context.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tvar apiInst = new _Api( context[i] );\\n\\t\\n\\t\\t\\t\\tif ( type === 'table' ) {\\n\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], i );\\n\\t\\n\\t\\t\\t\\t\\tif ( ret !== undefined ) {\\n\\t\\t\\t\\t\\t\\ta.push( ret );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( type === 'columns' || type === 'rows' ) {\\n\\t\\t\\t\\t\\t// this has same length as context - one entry for each table\\n\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], this[i], i );\\n\\t\\n\\t\\t\\t\\t\\tif ( ret !== undefined ) {\\n\\t\\t\\t\\t\\t\\ta.push( ret );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {\\n\\t\\t\\t\\t\\t// columns and rows share the same structure.\\n\\t\\t\\t\\t\\t// 'this' is an array of column indexes for each context\\n\\t\\t\\t\\t\\titems = this[i];\\n\\t\\n\\t\\t\\t\\t\\tif ( type === 'column-rows' ) {\\n\\t\\t\\t\\t\\t\\trows = _selector_row_indexes( context[i], selector.opts );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tfor ( j=0, jen=items.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\t\\titem = items[j];\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( type === 'cell' ) {\\n\\t\\t\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], item.row, item.column, i, j );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\t\\tret = fn.call( apiInst, context[i], item, i, j, rows );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( ret !== undefined ) {\\n\\t\\t\\t\\t\\t\\t\\ta.push( ret );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( a.length || alwaysNew ) {\\n\\t\\t\\t\\tvar api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );\\n\\t\\t\\t\\tvar apiSelector = api.selector;\\n\\t\\t\\t\\tapiSelector.rows = selector.rows;\\n\\t\\t\\t\\tapiSelector.cols = selector.cols;\\n\\t\\t\\t\\tapiSelector.opts = selector.opts;\\n\\t\\t\\t\\treturn api;\\n\\t\\t\\t}\\n\\t\\t\\treturn this;\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tlastIndexOf: __arrayProto.lastIndexOf || function (obj, start)\\n\\t\\t{\\n\\t\\t\\t// Bit cheeky...\\n\\t\\t\\treturn this.indexOf.apply( this.toArray.reverse(), arguments );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tlength: 0,\\n\\t\\n\\t\\n\\t\\tmap: function ( fn )\\n\\t\\t{\\n\\t\\t\\tvar a = [];\\n\\t\\n\\t\\t\\tif ( __arrayProto.map ) {\\n\\t\\t\\t\\ta = __arrayProto.map.call( this, fn, this );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\\n\\t\\t\\t\\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\ta.push( fn.call( this, this[i], i ) );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn new _Api( this.context, a );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tpluck: function ( prop )\\n\\t\\t{\\n\\t\\t\\treturn this.map( function ( el ) {\\n\\t\\t\\t\\treturn el[ prop ];\\n\\t\\t\\t} );\\n\\t\\t},\\n\\t\\n\\t\\tpop: __arrayProto.pop,\\n\\t\\n\\t\\n\\t\\tpush: __arrayProto.push,\\n\\t\\n\\t\\n\\t\\t// Does not return an API instance\\n\\t\\treduce: __arrayProto.reduce || function ( fn, init )\\n\\t\\t{\\n\\t\\t\\treturn _fnReduce( this, fn, init, 0, this.length, 1 );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\treduceRight: __arrayProto.reduceRight || function ( fn, init )\\n\\t\\t{\\n\\t\\t\\treturn _fnReduce( this, fn, init, this.length-1, -1, -1 );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\treverse: __arrayProto.reverse,\\n\\t\\n\\t\\n\\t\\t// Object with rows, columns and opts\\n\\t\\tselector: null,\\n\\t\\n\\t\\n\\t\\tshift: __arrayProto.shift,\\n\\t\\n\\t\\n\\t\\tslice: function () {\\n\\t\\t\\treturn new _Api( this.context, this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tsort: __arrayProto.sort, // ? name - order?\\n\\t\\n\\t\\n\\t\\tsplice: __arrayProto.splice,\\n\\t\\n\\t\\n\\t\\ttoArray: function ()\\n\\t\\t{\\n\\t\\t\\treturn __arrayProto.slice.call( this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tto$: function ()\\n\\t\\t{\\n\\t\\t\\treturn $( this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\ttoJQuery: function ()\\n\\t\\t{\\n\\t\\t\\treturn $( this );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tunique: function ()\\n\\t\\t{\\n\\t\\t\\treturn new _Api( this.context, _unique(this) );\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\tunshift: __arrayProto.unshift\\n\\t} );\\n\\t\\n\\t\\n\\t_Api.extend = function ( scope, obj, ext )\\n\\t{\\n\\t\\t// Only extend API instances and static properties of the API\\n\\t\\tif ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\ti, ien,\\n\\t\\t\\tj, jen,\\n\\t\\t\\tstruct, inner,\\n\\t\\t\\tmethodScoping = function ( scope, fn, struc ) {\\n\\t\\t\\t\\treturn function () {\\n\\t\\t\\t\\t\\tvar ret = fn.apply( scope, arguments );\\n\\t\\n\\t\\t\\t\\t\\t// Method extension\\n\\t\\t\\t\\t\\t_Api.extend( ret, ret, struc.methodExt );\\n\\t\\t\\t\\t\\treturn ret;\\n\\t\\t\\t\\t};\\n\\t\\t\\t};\\n\\t\\n\\t\\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\\n\\t\\t\\tstruct = ext[i];\\n\\t\\n\\t\\t\\t// Value\\n\\t\\t\\tobj[ struct.name ] = typeof struct.val === 'function' ?\\n\\t\\t\\t\\tmethodScoping( scope, struct.val, struct ) :\\n\\t\\t\\t\\t$.isPlainObject( struct.val ) ?\\n\\t\\t\\t\\t\\t{} :\\n\\t\\t\\t\\t\\tstruct.val;\\n\\t\\n\\t\\t\\tobj[ struct.name ].__dt_wrapper = true;\\n\\t\\n\\t\\t\\t// Property extension\\n\\t\\t\\t_Api.extend( scope, obj[ struct.name ], struct.propExt );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t// @todo - Is there need for an augment function?\\n\\t// _Api.augment = function ( inst, name )\\n\\t// {\\n\\t// \\t// Find src object in the structure from the name\\n\\t// \\tvar parts = name.split('.');\\n\\t\\n\\t// \\t_Api.extend( inst, obj );\\n\\t// };\\n\\t\\n\\t\\n\\t// [\\n\\t// {\\n\\t// name: 'data' -- string - Property name\\n\\t// val: function () {}, -- function - Api method (or undefined if just an object\\n\\t// methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result\\n\\t// propExt: [ ... ] -- array - Array of Api object definitions to extend the property\\n\\t// },\\n\\t// {\\n\\t// name: 'row'\\n\\t// val: {},\\n\\t// methodExt: [ ... ],\\n\\t// propExt: [\\n\\t// {\\n\\t// name: 'data'\\n\\t// val: function () {},\\n\\t// methodExt: [ ... ],\\n\\t// propExt: [ ... ]\\n\\t// },\\n\\t// ...\\n\\t// ]\\n\\t// }\\n\\t// ]\\n\\t\\n\\t_Api.register = _api_register = function ( name, val )\\n\\t{\\n\\t\\tif ( $.isArray( name ) ) {\\n\\t\\t\\tfor ( var j=0, jen=name.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t_Api.register( name[j], val );\\n\\t\\t\\t}\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\ti, ien,\\n\\t\\t\\their = name.split('.'),\\n\\t\\t\\tstruct = __apiStruct,\\n\\t\\t\\tkey, method;\\n\\t\\n\\t\\tvar find = function ( src, name ) {\\n\\t\\t\\tfor ( var i=0, ien=src.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( src[i].name === name ) {\\n\\t\\t\\t\\t\\treturn src[i];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t};\\n\\t\\n\\t\\tfor ( i=0, ien=heir.length ; i<ien ; i++ ) {\\n\\t\\t\\tmethod = heir[i].indexOf('()') !== -1;\\n\\t\\t\\tkey = method ?\\n\\t\\t\\t\\their[i].replace('()', '') :\\n\\t\\t\\t\\their[i];\\n\\t\\n\\t\\t\\tvar src = find( struct, key );\\n\\t\\t\\tif ( ! src ) {\\n\\t\\t\\t\\tsrc = {\\n\\t\\t\\t\\t\\tname: key,\\n\\t\\t\\t\\t\\tval: {},\\n\\t\\t\\t\\t\\tmethodExt: [],\\n\\t\\t\\t\\t\\tpropExt: []\\n\\t\\t\\t\\t};\\n\\t\\t\\t\\tstruct.push( src );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( i === ien-1 ) {\\n\\t\\t\\t\\tsrc.val = val;\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tstruct = method ?\\n\\t\\t\\t\\t\\tsrc.methodExt :\\n\\t\\t\\t\\t\\tsrc.propExt;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {\\n\\t\\t_Api.register( pluralName, val );\\n\\t\\n\\t\\t_Api.register( singularName, function () {\\n\\t\\t\\tvar ret = val.apply( this, arguments );\\n\\t\\n\\t\\t\\tif ( ret === this ) {\\n\\t\\t\\t\\t// Returned item is the API instance that was passed in, return it\\n\\t\\t\\t\\treturn this;\\n\\t\\t\\t}\\n\\t\\t\\telse if ( ret instanceof _Api ) {\\n\\t\\t\\t\\t// New API instance returned, want the value from the first item\\n\\t\\t\\t\\t// in the returned array for the singular result.\\n\\t\\t\\t\\treturn ret.length ?\\n\\t\\t\\t\\t\\t$.isArray( ret[0] ) ?\\n\\t\\t\\t\\t\\t\\tnew _Api( ret.context, ret[0] ) : // Array results are 'enhanced'\\n\\t\\t\\t\\t\\t\\tret[0] :\\n\\t\\t\\t\\t\\tundefined;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Non-API return - just fire it back\\n\\t\\t\\treturn ret;\\n\\t\\t} );\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Selector for HTML tables. Apply the given selector to the give array of\\n\\t * DataTables settings objects.\\n\\t *\\n\\t * @param {string|integer} [selector] jQuery selector string or integer\\n\\t * @param {array} Array of DataTables settings objects to be filtered\\n\\t * @return {array}\\n\\t * @ignore\\n\\t */\\n\\tvar __table_selector = function ( selector, a )\\n\\t{\\n\\t\\t// Integer is used to pick out a table by index\\n\\t\\tif ( typeof selector === 'number' ) {\\n\\t\\t\\treturn [ a[ selector ] ];\\n\\t\\t}\\n\\t\\n\\t\\t// Perform a jQuery selector on the table nodes\\n\\t\\tvar nodes = $.map( a, function (el, i) {\\n\\t\\t\\treturn el.nTable;\\n\\t\\t} );\\n\\t\\n\\t\\treturn $(nodes)\\n\\t\\t\\t.filter( selector )\\n\\t\\t\\t.map( function (i) {\\n\\t\\t\\t\\t// Need to translate back from the table node to the settings\\n\\t\\t\\t\\tvar idx = $.inArray( this, nodes );\\n\\t\\t\\t\\treturn a[ idx ];\\n\\t\\t\\t} )\\n\\t\\t\\t.toArray();\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Context selector for the API's context (i.e. the tables the API instance\\n\\t * refers to.\\n\\t *\\n\\t * @name DataTable.Api#tables\\n\\t * @param {string|integer} [selector] Selector to pick which tables the iterator\\n\\t * should operate on. If not given, all tables in the current context are\\n\\t * used. This can be given as a jQuery selector (for example `':gt(0)'`) to\\n\\t * select multiple tables or as an integer to select a single table.\\n\\t * @returns {DataTable.Api} Returns a new API instance if a selector is given.\\n\\t */\\n\\t_api_register( 'tables()', function ( selector ) {\\n\\t\\t// A new instance is created if there was a selector specified\\n\\t\\treturn selector ?\\n\\t\\t\\tnew _Api( __table_selector( selector, this.context ) ) :\\n\\t\\t\\tthis;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'table()', function ( selector ) {\\n\\t\\tvar tables = this.tables( selector );\\n\\t\\tvar ctx = tables.context;\\n\\t\\n\\t\\t// Truncate to the first matched table\\n\\t\\treturn ctx.length ?\\n\\t\\t\\tnew _Api( ctx[0] ) :\\n\\t\\t\\ttables;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTable;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().body()', 'table().body()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTBody;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().header()', 'table().header()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTHead;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTFoot;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'tables().containers()', 'table().container()' , function () {\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\treturn ctx.nTableWrapper;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Redraw the tables in the current context.\\n\\t */\\n\\t_api_register( 'draw()', function ( paging ) {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( paging === 'page' ) {\\n\\t\\t\\t\\t_fnDraw( settings );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tif ( typeof paging === 'string' ) {\\n\\t\\t\\t\\t\\tpaging = paging === 'full-hold' ?\\n\\t\\t\\t\\t\\t\\tfalse :\\n\\t\\t\\t\\t\\t\\ttrue;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t_fnReDraw( settings, paging===false );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the current page index.\\n\\t *\\n\\t * @return {integer} Current page index (zero based)\\n\\t *//**\\n\\t * Set the current page.\\n\\t *\\n\\t * Note that if you attempt to show a page which does not exist, DataTables will\\n\\t * not throw an error, but rather reset the paging.\\n\\t *\\n\\t * @param {integer|string} action The paging action to take. This can be one of:\\n\\t * * `integer` - The page index to jump to\\n\\t * * `string` - An action to take:\\n\\t * * `first` - Jump to first page.\\n\\t * * `next` - Jump to the next page\\n\\t * * `previous` - Jump to previous page\\n\\t * * `last` - Jump to the last page.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'page()', function ( action ) {\\n\\t\\tif ( action === undefined ) {\\n\\t\\t\\treturn this.page.info().page; // not an expensive call\\n\\t\\t}\\n\\t\\n\\t\\t// else, have an action to take on all tables\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnPageChange( settings, action );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Paging information for the first table in the current context.\\n\\t *\\n\\t * If you require paging information for another table, use the `table()` method\\n\\t * with a suitable selector.\\n\\t *\\n\\t * @return {object} Object with the following properties set:\\n\\t * * `page` - Current page index (zero based - i.e. the first page is `0`)\\n\\t * * `pages` - Total number of pages\\n\\t * * `start` - Display index for the first record shown on the current page\\n\\t * * `end` - Display index for the last record shown on the current page\\n\\t * * `length` - Display length (number of records). Note that generally `start\\n\\t * + length = end`, but this is not always true, for example if there are\\n\\t * only 2 records to show on the final page, with a length of 10.\\n\\t * * `recordsTotal` - Full data set length\\n\\t * * `recordsDisplay` - Data set length once the current filtering criterion\\n\\t * are applied.\\n\\t */\\n\\t_api_register( 'page.info()', function ( action ) {\\n\\t\\tif ( this.context.length === 0 ) {\\n\\t\\t\\treturn undefined;\\n\\t\\t}\\n\\t\\n\\t\\tvar\\n\\t\\t\\tsettings = this.context[0],\\n\\t\\t\\tstart = settings._iDisplayStart,\\n\\t\\t\\tlen = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,\\n\\t\\t\\tvisRecords = settings.fnRecordsDisplay(),\\n\\t\\t\\tall = len === -1;\\n\\t\\n\\t\\treturn {\\n\\t\\t\\t\\\"page\\\": all ? 0 : Math.floor( start / len ),\\n\\t\\t\\t\\\"pages\\\": all ? 1 : Math.ceil( visRecords / len ),\\n\\t\\t\\t\\\"start\\\": start,\\n\\t\\t\\t\\\"end\\\": settings.fnDisplayEnd(),\\n\\t\\t\\t\\\"length\\\": len,\\n\\t\\t\\t\\\"recordsTotal\\\": settings.fnRecordsTotal(),\\n\\t\\t\\t\\\"recordsDisplay\\\": visRecords,\\n\\t\\t\\t\\\"serverSide\\\": _fnDataSource( settings ) === 'ssp'\\n\\t\\t};\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the current page length.\\n\\t *\\n\\t * @return {integer} Current page length. Note `-1` indicates that all records\\n\\t * are to be shown.\\n\\t *//**\\n\\t * Set the current page length.\\n\\t *\\n\\t * @param {integer} Page length to set. Use `-1` to show all records.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'page.len()', function ( len ) {\\n\\t\\t// Note that we can't call this function 'length()' because `length`\\n\\t\\t// is a Javascript property of functions which defines how many arguments\\n\\t\\t// the function expects.\\n\\t\\tif ( len === undefined ) {\\n\\t\\t\\treturn this.context.length !== 0 ?\\n\\t\\t\\t\\tthis.context[0]._iDisplayLength :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// else, set the page length\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnLengthChange( settings, len );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __reload = function ( settings, holdPosition, callback ) {\\n\\t\\t// Use the draw event to trigger a callback\\n\\t\\tif ( callback ) {\\n\\t\\t\\tvar api = new _Api( settings );\\n\\t\\n\\t\\t\\tapi.one( 'draw', function () {\\n\\t\\t\\t\\tcallback( api.ajax.json() );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\tif ( _fnDataSource( settings ) == 'ssp' ) {\\n\\t\\t\\t_fnReDraw( settings, holdPosition );\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t_fnProcessingDisplay( settings, true );\\n\\t\\n\\t\\t\\t// Cancel an existing request\\n\\t\\t\\tvar xhr = settings.jqXHR;\\n\\t\\t\\tif ( xhr && xhr.readyState !== 4 ) {\\n\\t\\t\\t\\txhr.abort();\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Trigger xhr\\n\\t\\t\\t_fnBuildAjax( settings, [], function( json ) {\\n\\t\\t\\t\\t_fnClearTable( settings );\\n\\t\\n\\t\\t\\t\\tvar data = _fnAjaxDataSrc( settings, json );\\n\\t\\t\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t_fnAddData( settings, data[i] );\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t_fnReDraw( settings, holdPosition );\\n\\t\\t\\t\\t_fnProcessingDisplay( settings, false );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the JSON response from the last Ajax request that DataTables made to the\\n\\t * server. Note that this returns the JSON from the first table in the current\\n\\t * context.\\n\\t *\\n\\t * @return {object} JSON received from the server.\\n\\t */\\n\\t_api_register( 'ajax.json()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( ctx.length > 0 ) {\\n\\t\\t\\treturn ctx[0].json;\\n\\t\\t}\\n\\t\\n\\t\\t// else return undefined;\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the data submitted in the last Ajax request\\n\\t */\\n\\t_api_register( 'ajax.params()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( ctx.length > 0 ) {\\n\\t\\t\\treturn ctx[0].oAjaxData;\\n\\t\\t}\\n\\t\\n\\t\\t// else return undefined;\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Reload tables from the Ajax data source. Note that this function will\\n\\t * automatically re-draw the table when the remote data has been loaded.\\n\\t *\\n\\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\\n\\t * position. A full re-sort and re-filter is performed when this method is\\n\\t * called, which is why the pagination reset is the default action.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\\n\\t\\treturn this.iterator( 'table', function (settings) {\\n\\t\\t\\t__reload( settings, resetPaging===false, callback );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Get the current Ajax URL. Note that this returns the URL from the first\\n\\t * table in the current context.\\n\\t *\\n\\t * @return {string} Current Ajax source URL\\n\\t *//**\\n\\t * Set the Ajax URL. Note that this will set the URL for all tables in the\\n\\t * current context.\\n\\t *\\n\\t * @param {string} url URL to set.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'ajax.url()', function ( url ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( url === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\tif ( ctx.length === 0 ) {\\n\\t\\t\\t\\treturn undefined;\\n\\t\\t\\t}\\n\\t\\t\\tctx = ctx[0];\\n\\t\\n\\t\\t\\treturn ctx.ajax ?\\n\\t\\t\\t\\t$.isPlainObject( ctx.ajax ) ?\\n\\t\\t\\t\\t\\tctx.ajax.url :\\n\\t\\t\\t\\t\\tctx.ajax :\\n\\t\\t\\t\\tctx.sAjaxSource;\\n\\t\\t}\\n\\t\\n\\t\\t// set\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( $.isPlainObject( settings.ajax ) ) {\\n\\t\\t\\t\\tsettings.ajax.url = url;\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\tsettings.ajax = url;\\n\\t\\t\\t}\\n\\t\\t\\t// No need to consider sAjaxSource here since DataTables gives priority\\n\\t\\t\\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\\n\\t\\t\\t// value of `sAjaxSource` redundant.\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Load data from the newly set Ajax URL. Note that this method is only\\n\\t * available when `ajax.url()` is used to set a URL. Additionally, this method\\n\\t * has the same effect as calling `ajax.reload()` but is provided for\\n\\t * convenience when setting a new URL. Like `ajax.reload()` it will\\n\\t * automatically redraw the table once the remote data has been loaded.\\n\\t *\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\\n\\t\\t// Same as a reload, but makes sense to present it for easy access after a\\n\\t\\t// url change\\n\\t\\treturn this.iterator( 'table', function ( ctx ) {\\n\\t\\t\\t__reload( ctx, resetPaging===false, callback );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t\\n\\tvar _selector_run = function ( type, selector, selectFn, settings, opts )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tout = [], res,\\n\\t\\t\\ta, i, ien, j, jen,\\n\\t\\t\\tselectorType = typeof selector;\\n\\t\\n\\t\\t// Can't just check for isArray here, as an API or jQuery instance might be\\n\\t\\t// given with their array like look\\n\\t\\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\\n\\t\\t\\tselector = [ selector ];\\n\\t\\t}\\n\\t\\n\\t\\tfor ( i=0, ien=selector.length ; i<ien ; i++ ) {\\n\\t\\t\\t// Only split on simple strings - complex expressions will be jQuery selectors\\n\\t\\t\\ta = selector[i] && selector[i].split && ! selector[i].match(/[\\\\[\\\\(:]/) ?\\n\\t\\t\\t\\tselector[i].split(',') :\\n\\t\\t\\t\\t[ selector[i] ];\\n\\t\\n\\t\\t\\tfor ( j=0, jen=a.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\tres = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );\\n\\t\\n\\t\\t\\t\\tif ( res && res.length ) {\\n\\t\\t\\t\\t\\tout = out.concat( res );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// selector extensions\\n\\t\\tvar ext = _ext.selector[ type ];\\n\\t\\tif ( ext.length ) {\\n\\t\\t\\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tout = ext[i]( settings, opts, out );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn _unique( out );\\n\\t};\\n\\t\\n\\t\\n\\tvar _selector_opts = function ( opts )\\n\\t{\\n\\t\\tif ( ! opts ) {\\n\\t\\t\\topts = {};\\n\\t\\t}\\n\\t\\n\\t\\t// Backwards compatibility for 1.9- which used the terminology filter rather\\n\\t\\t// than search\\n\\t\\tif ( opts.filter && opts.search === undefined ) {\\n\\t\\t\\topts.search = opts.filter;\\n\\t\\t}\\n\\t\\n\\t\\treturn $.extend( {\\n\\t\\t\\tsearch: 'none',\\n\\t\\t\\torder: 'current',\\n\\t\\t\\tpage: 'all'\\n\\t\\t}, opts );\\n\\t};\\n\\t\\n\\t\\n\\tvar _selector_first = function ( inst )\\n\\t{\\n\\t\\t// Reduce the API instance to the first item found\\n\\t\\tfor ( var i=0, ien=inst.length ; i<ien ; i++ ) {\\n\\t\\t\\tif ( inst[i].length > 0 ) {\\n\\t\\t\\t\\t// Assign the first element to the first item in the instance\\n\\t\\t\\t\\t// and truncate the instance and context\\n\\t\\t\\t\\tinst[0] = inst[i];\\n\\t\\t\\t\\tinst[0].length = 1;\\n\\t\\t\\t\\tinst.length = 1;\\n\\t\\t\\t\\tinst.context = [ inst.context[i] ];\\n\\t\\n\\t\\t\\t\\treturn inst;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\t// Not found - return an empty instance\\n\\t\\tinst.length = 0;\\n\\t\\treturn inst;\\n\\t};\\n\\t\\n\\t\\n\\tvar _selector_row_indexes = function ( settings, opts )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\ti, ien, tmp, a=[],\\n\\t\\t\\tdisplayFiltered = settings.aiDisplay,\\n\\t\\t\\tdisplayMaster = settings.aiDisplayMaster;\\n\\t\\n\\t\\tvar\\n\\t\\t\\tsearch = opts.search, // none, applied, removed\\n\\t\\t\\torder = opts.order, // applied, current, index (original - compatibility with 1.9)\\n\\t\\t\\tpage = opts.page; // all, current\\n\\t\\n\\t\\tif ( _fnDataSource( settings ) == 'ssp' ) {\\n\\t\\t\\t// In server-side processing mode, most options are irrelevant since\\n\\t\\t\\t// rows not shown don't exist and the index order is the applied order\\n\\t\\t\\t// Removed is a special case - for consistency just return an empty\\n\\t\\t\\t// array\\n\\t\\t\\treturn search === 'removed' ?\\n\\t\\t\\t\\t[] :\\n\\t\\t\\t\\t_range( 0, displayMaster.length );\\n\\t\\t}\\n\\t\\telse if ( page == 'current' ) {\\n\\t\\t\\t// Current page implies that order=current and fitler=applied, since it is\\n\\t\\t\\t// fairly senseless otherwise, regardless of what order and search actually\\n\\t\\t\\t// are\\n\\t\\t\\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {\\n\\t\\t\\t\\ta.push( displayFiltered[i] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse if ( order == 'current' || order == 'applied' ) {\\n\\t\\t\\ta = search == 'none' ?\\n\\t\\t\\t\\tdisplayMaster.slice() : // no search\\n\\t\\t\\t\\tsearch == 'applied' ?\\n\\t\\t\\t\\t\\tdisplayFiltered.slice() : // applied search\\n\\t\\t\\t\\t\\t$.map( displayMaster, function (el, i) { // removed search\\n\\t\\t\\t\\t\\t\\treturn $.inArray( el, displayFiltered ) === -1 ? el : null;\\n\\t\\t\\t\\t\\t} );\\n\\t\\t}\\n\\t\\telse if ( order == 'index' || order == 'original' ) {\\n\\t\\t\\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tif ( search == 'none' ) {\\n\\t\\t\\t\\t\\ta.push( i );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse { // applied | removed\\n\\t\\t\\t\\t\\ttmp = $.inArray( i, displayFiltered );\\n\\t\\n\\t\\t\\t\\t\\tif ((tmp === -1 && search == 'removed') ||\\n\\t\\t\\t\\t\\t\\t(tmp >= 0 && search == 'applied') )\\n\\t\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\t\\ta.push( i );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn a;\\n\\t};\\n\\t\\n\\t\\n\\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\\t * Rows\\n\\t *\\n\\t * {} - no selector - use all available rows\\n\\t * {integer} - row aoData index\\n\\t * {node} - TR node\\n\\t * {string} - jQuery selector to apply to the TR elements\\n\\t * {array} - jQuery array of nodes, or simply an array of TR nodes\\n\\t *\\n\\t */\\n\\t\\n\\t\\n\\tvar __row_selector = function ( settings, selector, opts )\\n\\t{\\n\\t\\tvar rows;\\n\\t\\tvar run = function ( sel ) {\\n\\t\\t\\tvar selInt = _intVal( sel );\\n\\t\\t\\tvar i, ien;\\n\\t\\n\\t\\t\\t// Short cut - selector is a number and no options provided (default is\\n\\t\\t\\t// all records, so no need to check if the index is in there, since it\\n\\t\\t\\t// must be - dev error if the index doesn't exist).\\n\\t\\t\\tif ( selInt !== null && ! opts ) {\\n\\t\\t\\t\\treturn [ selInt ];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( ! rows ) {\\n\\t\\t\\t\\trows = _selector_row_indexes( settings, opts );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\\n\\t\\t\\t\\t// Selector - integer\\n\\t\\t\\t\\treturn [ selInt ];\\n\\t\\t\\t}\\n\\t\\t\\telse if ( sel === null || sel === undefined || sel === '' ) {\\n\\t\\t\\t\\t// Selector - none\\n\\t\\t\\t\\treturn rows;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - function\\n\\t\\t\\tif ( typeof sel === 'function' ) {\\n\\t\\t\\t\\treturn $.map( rows, function (idx) {\\n\\t\\t\\t\\t\\tvar row = settings.aoData[ idx ];\\n\\t\\t\\t\\t\\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Get nodes in the order from the `rows` array with null values removed\\n\\t\\t\\tvar nodes = _removeEmpty(\\n\\t\\t\\t\\t_pluck_order( settings.aoData, rows, 'nTr' )\\n\\t\\t\\t);\\n\\t\\n\\t\\t\\t// Selector - node\\n\\t\\t\\tif ( sel.nodeName ) {\\n\\t\\t\\t\\tif ( sel._DT_RowIndex !== undefined ) {\\n\\t\\t\\t\\t\\treturn [ sel._DT_RowIndex ]; // Property added by DT for fast lookup\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse if ( sel._DT_CellIndex ) {\\n\\t\\t\\t\\t\\treturn [ sel._DT_CellIndex.row ];\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\tvar host = $(sel).closest('*[data-dt-row]');\\n\\t\\t\\t\\t\\treturn host.length ?\\n\\t\\t\\t\\t\\t\\t[ host.data('dt-row') ] :\\n\\t\\t\\t\\t\\t\\t[];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// ID selector. Want to always be able to select rows by id, regardless\\n\\t\\t\\t// of if the tr element has been created or not, so can't rely upon\\n\\t\\t\\t// jQuery here - hence a custom implementation. This does not match\\n\\t\\t\\t// Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,\\n\\t\\t\\t// but to select it using a CSS selector engine (like Sizzle or\\n\\t\\t\\t// querySelect) it would need to need to be escaped for some characters.\\n\\t\\t\\t// DataTables simplifies this for row selectors since you can select\\n\\t\\t\\t// only a row. A # indicates an id any anything that follows is the id -\\n\\t\\t\\t// unescaped.\\n\\t\\t\\tif ( typeof sel === 'string' && sel.charAt(0) === '#' ) {\\n\\t\\t\\t\\t// get row index from id\\n\\t\\t\\t\\tvar rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];\\n\\t\\t\\t\\tif ( rowObj !== undefined ) {\\n\\t\\t\\t\\t\\treturn [ rowObj.idx ];\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// need to fall through to jQuery in case there is DOM id that\\n\\t\\t\\t\\t// matches\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - jQuery selector string, array of nodes or jQuery object/\\n\\t\\t\\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\\n\\t\\t\\t// it also allows arrays, so this will cope with all three options\\n\\t\\t\\treturn $(nodes)\\n\\t\\t\\t\\t.filter( sel )\\n\\t\\t\\t\\t.map( function () {\\n\\t\\t\\t\\t\\treturn this._DT_RowIndex;\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.toArray();\\n\\t\\t};\\n\\t\\n\\t\\treturn _selector_run( 'row', selector, run, settings, opts );\\n\\t};\\n\\t\\n\\t\\n\\t_api_register( 'rows()', function ( selector, opts ) {\\n\\t\\t// argument shifting\\n\\t\\tif ( selector === undefined ) {\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\telse if ( $.isPlainObject( selector ) ) {\\n\\t\\t\\topts = selector;\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\n\\t\\topts = _selector_opts( opts );\\n\\t\\n\\t\\tvar inst = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\treturn __row_selector( settings, selector, opts );\\n\\t\\t}, 1 );\\n\\t\\n\\t\\t// Want argument shifting here and in __row_selector?\\n\\t\\tinst.selector.rows = selector;\\n\\t\\tinst.selector.opts = opts;\\n\\t\\n\\t\\treturn inst;\\n\\t} );\\n\\t\\n\\t_api_register( 'rows().nodes()', function () {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\treturn settings.aoData[ row ].nTr || undefined;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_register( 'rows().data()', function () {\\n\\t\\treturn this.iterator( true, 'rows', function ( settings, rows ) {\\n\\t\\t\\treturn _pluck_order( settings.aoData, rows, '_aData' );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\tvar r = settings.aoData[ row ];\\n\\t\\t\\treturn type === 'search' ? r._aFilterData : r._aSortData;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\t_fnInvalidate( settings, row, src );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\\n\\t\\treturn this.iterator( 'row', function ( settings, row ) {\\n\\t\\t\\treturn row;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {\\n\\t\\tvar a = [];\\n\\t\\tvar context = this.context;\\n\\t\\n\\t\\t// `iterator` will drop undefined values, but in this case we want them\\n\\t\\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\\n\\t\\t\\tfor ( var j=0, jen=this[i].length ; j<jen ; j++ ) {\\n\\t\\t\\t\\tvar id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );\\n\\t\\t\\t\\ta.push( (hash === true ? '#' : '' )+ id );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn new _Api( context, a );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'rows().remove()', 'row().remove()', function () {\\n\\t\\tvar that = this;\\n\\t\\n\\t\\tthis.iterator( 'row', function ( settings, row, thatIdx ) {\\n\\t\\t\\tvar data = settings.aoData;\\n\\t\\t\\tvar rowData = data[ row ];\\n\\t\\t\\tvar i, ien, j, jen;\\n\\t\\t\\tvar loopRow, loopCells;\\n\\t\\n\\t\\t\\tdata.splice( row, 1 );\\n\\t\\n\\t\\t\\t// Update the cached indexes\\n\\t\\t\\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tloopRow = data[i];\\n\\t\\t\\t\\tloopCells = loopRow.anCells;\\n\\t\\n\\t\\t\\t\\t// Rows\\n\\t\\t\\t\\tif ( loopRow.nTr !== null ) {\\n\\t\\t\\t\\t\\tloopRow.nTr._DT_RowIndex = i;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Cells\\n\\t\\t\\t\\tif ( loopCells !== null ) {\\n\\t\\t\\t\\t\\tfor ( j=0, jen=loopCells.length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\t\\tloopCells[j]._DT_CellIndex.row = i;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Delete from the display arrays\\n\\t\\t\\t_fnDeleteIndex( settings.aiDisplayMaster, row );\\n\\t\\t\\t_fnDeleteIndex( settings.aiDisplay, row );\\n\\t\\t\\t_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes\\n\\t\\n\\t\\t\\t// Check for an 'overflow' they case for displaying the table\\n\\t\\t\\t_fnLengthOverflow( settings );\\n\\t\\n\\t\\t\\t// Remove the row's ID reference if there is one\\n\\t\\t\\tvar id = settings.rowIdFn( rowData._aData );\\n\\t\\t\\tif ( id !== undefined ) {\\n\\t\\t\\t\\tdelete settings.aIds[ id ];\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\tthis.iterator( 'table', function ( settings ) {\\n\\t\\t\\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tsettings.aoData[i].idx = i;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'rows.add()', function ( rows ) {\\n\\t\\tvar newRows = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t\\tvar row, i, ien;\\n\\t\\t\\t\\tvar out = [];\\n\\t\\n\\t\\t\\t\\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\trow = rows[i];\\n\\t\\n\\t\\t\\t\\t\\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\\n\\t\\t\\t\\t\\t\\tout.push( _fnAddTr( settings, row )[0] );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\tout.push( _fnAddData( settings, row ) );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn out;\\n\\t\\t\\t}, 1 );\\n\\t\\n\\t\\t// Return an Api.rows() extended instance, so rows().nodes() etc can be used\\n\\t\\tvar modRows = this.rows( -1 );\\n\\t\\tmodRows.pop();\\n\\t\\t$.merge( modRows, newRows );\\n\\t\\n\\t\\treturn modRows;\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t *\\n\\t */\\n\\t_api_register( 'row()', function ( selector, opts ) {\\n\\t\\treturn _selector_first( this.rows( selector, opts ) );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'row().data()', function ( data ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( data === undefined ) {\\n\\t\\t\\t// Get\\n\\t\\t\\treturn ctx.length && this.length ?\\n\\t\\t\\t\\tctx[0].aoData[ this[0] ]._aData :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// Set\\n\\t\\tctx[0].aoData[ this[0] ]._aData = data;\\n\\t\\n\\t\\t// Automatically invalidate\\n\\t\\t_fnInvalidate( ctx[0], this[0], 'data' );\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'row().node()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\treturn ctx.length && this.length ?\\n\\t\\t\\tctx[0].aoData[ this[0] ].nTr || null :\\n\\t\\t\\tnull;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'row.add()', function ( row ) {\\n\\t\\t// Allow a jQuery object to be passed in - only a single row is added from\\n\\t\\t// it though - the first element in the set\\n\\t\\tif ( row instanceof $ && row.length ) {\\n\\t\\t\\trow = row[0];\\n\\t\\t}\\n\\t\\n\\t\\tvar rows = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\\n\\t\\t\\t\\treturn _fnAddTr( settings, row )[0];\\n\\t\\t\\t}\\n\\t\\t\\treturn _fnAddData( settings, row );\\n\\t\\t} );\\n\\t\\n\\t\\t// Return an Api.rows() extended instance, with the newly added row selected\\n\\t\\treturn this.row( rows[0] );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __details_add = function ( ctx, row, data, klass )\\n\\t{\\n\\t\\t// Convert to array of TR elements\\n\\t\\tvar rows = [];\\n\\t\\tvar addRow = function ( r, k ) {\\n\\t\\t\\t// Recursion to allow for arrays of jQuery objects\\n\\t\\t\\tif ( $.isArray( r ) || r instanceof $ ) {\\n\\t\\t\\t\\tfor ( var i=0, ien=r.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\taddRow( r[i], k );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// If we get a TR element, then just add it directly - up to the dev\\n\\t\\t\\t// to add the correct number of columns etc\\n\\t\\t\\tif ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {\\n\\t\\t\\t\\trows.push( r );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Otherwise create a row with a wrapper\\n\\t\\t\\t\\tvar created = $('<tr><td/></tr>').addClass( k );\\n\\t\\t\\t\\t$('td', created)\\n\\t\\t\\t\\t\\t.addClass( k )\\n\\t\\t\\t\\t\\t.html( r )\\n\\t\\t\\t\\t\\t[0].colSpan = _fnVisbleColumns( ctx );\\n\\t\\n\\t\\t\\t\\trows.push( created[0] );\\n\\t\\t\\t}\\n\\t\\t};\\n\\t\\n\\t\\taddRow( data, klass );\\n\\t\\n\\t\\tif ( row._details ) {\\n\\t\\t\\trow._details.detach();\\n\\t\\t}\\n\\t\\n\\t\\trow._details = $(rows);\\n\\t\\n\\t\\t// If the children were already shown, that state should be retained\\n\\t\\tif ( row._detailsShow ) {\\n\\t\\t\\trow._details.insertAfter( row.nTr );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\tvar __details_remove = function ( api, idx )\\n\\t{\\n\\t\\tvar ctx = api.context;\\n\\t\\n\\t\\tif ( ctx.length ) {\\n\\t\\t\\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\\n\\t\\n\\t\\t\\tif ( row && row._details ) {\\n\\t\\t\\t\\trow._details.remove();\\n\\t\\n\\t\\t\\t\\trow._detailsShow = undefined;\\n\\t\\t\\t\\trow._details = undefined;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\tvar __details_display = function ( api, show ) {\\n\\t\\tvar ctx = api.context;\\n\\t\\n\\t\\tif ( ctx.length && api.length ) {\\n\\t\\t\\tvar row = ctx[0].aoData[ api[0] ];\\n\\t\\n\\t\\t\\tif ( row._details ) {\\n\\t\\t\\t\\trow._detailsShow = show;\\n\\t\\n\\t\\t\\t\\tif ( show ) {\\n\\t\\t\\t\\t\\trow._details.insertAfter( row.nTr );\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\trow._details.detach();\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t__details_events( ctx[0] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\tvar __details_events = function ( settings )\\n\\t{\\n\\t\\tvar api = new _Api( settings );\\n\\t\\tvar namespace = '.dt.DT_details';\\n\\t\\tvar drawEvent = 'draw'+namespace;\\n\\t\\tvar colvisEvent = 'column-visibility'+namespace;\\n\\t\\tvar destroyEvent = 'destroy'+namespace;\\n\\t\\tvar data = settings.aoData;\\n\\t\\n\\t\\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\\n\\t\\n\\t\\tif ( _pluck( data, '_details' ).length > 0 ) {\\n\\t\\t\\t// On each draw, insert the required elements into the document\\n\\t\\t\\tapi.on( drawEvent, function ( e, ctx ) {\\n\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\\n\\t\\t\\t\\t\\t// Internal data grab\\n\\t\\t\\t\\t\\tvar row = data[ idx ];\\n\\t\\n\\t\\t\\t\\t\\tif ( row._detailsShow ) {\\n\\t\\t\\t\\t\\t\\trow._details.insertAfter( row.nTr );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t} );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\t// Column visibility change - update the colspan\\n\\t\\t\\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\\n\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// Update the colspan for the details rows (note, only if it already has\\n\\t\\t\\t\\t// a colspan)\\n\\t\\t\\t\\tvar row, visible = _fnVisbleColumns( ctx );\\n\\t\\n\\t\\t\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\trow = data[i];\\n\\t\\n\\t\\t\\t\\t\\tif ( row._details ) {\\n\\t\\t\\t\\t\\t\\trow._details.children('td[colspan]').attr('colspan', visible );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\t// Table destroyed - nuke any child rows\\n\\t\\t\\tapi.on( destroyEvent, function ( e, ctx ) {\\n\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\tif ( data[i]._details ) {\\n\\t\\t\\t\\t\\t\\t__details_remove( api, i );\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t};\\n\\t\\n\\t// Strings for the method names to help minification\\n\\tvar _emp = '';\\n\\tvar _child_obj = _emp+'row().child';\\n\\tvar _child_mth = _child_obj+'()';\\n\\t\\n\\t// data can be:\\n\\t// tr\\n\\t// string\\n\\t// jQuery or array of any of the above\\n\\t_api_register( _child_mth, function ( data, klass ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( data === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\treturn ctx.length && this.length ?\\n\\t\\t\\t\\tctx[0].aoData[ this[0] ]._details :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\telse if ( data === true ) {\\n\\t\\t\\t// show\\n\\t\\t\\tthis.child.show();\\n\\t\\t}\\n\\t\\telse if ( data === false ) {\\n\\t\\t\\t// remove\\n\\t\\t\\t__details_remove( this );\\n\\t\\t}\\n\\t\\telse if ( ctx.length && this.length ) {\\n\\t\\t\\t// set\\n\\t\\t\\t__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );\\n\\t\\t}\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( [\\n\\t\\t_child_obj+'.show()',\\n\\t\\t_child_mth+'.show()' // only when `child()` was called with parameters (without\\n\\t], function ( show ) { // it returns an object and this method is not executed)\\n\\t\\t__details_display( this, true );\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( [\\n\\t\\t_child_obj+'.hide()',\\n\\t\\t_child_mth+'.hide()' // only when `child()` was called with parameters (without\\n\\t], function () { // it returns an object and this method is not executed)\\n\\t\\t__details_display( this, false );\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( [\\n\\t\\t_child_obj+'.remove()',\\n\\t\\t_child_mth+'.remove()' // only when `child()` was called with parameters (without\\n\\t], function () { // it returns an object and this method is not executed)\\n\\t\\t__details_remove( this );\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( _child_obj+'.isShown()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( ctx.length && this.length ) {\\n\\t\\t\\t// _detailsShown as false or undefined will fall through to return false\\n\\t\\t\\treturn ctx[0].aoData[ this[0] ]._detailsShow || false;\\n\\t\\t}\\n\\t\\treturn false;\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\n\\t * Columns\\n\\t *\\n\\t * {integer} - column index (>=0 count from left, <0 count from right)\\n\\t * \\\"{integer}:visIdx\\\" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)\\n\\t * \\\"{integer}:visible\\\" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)\\n\\t * \\\"{string}:name\\\" - column name\\n\\t * \\\"{string}\\\" - jQuery selector on column header nodes\\n\\t *\\n\\t */\\n\\t\\n\\t// can be an array of these items, comma separated list, or an array of comma\\n\\t// separated lists\\n\\t\\n\\tvar __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;\\n\\t\\n\\t\\n\\t// r1 and r2 are redundant - but it means that the parameters match for the\\n\\t// iterator callback in columns().data()\\n\\tvar __columnData = function ( settings, column, r1, r2, rows ) {\\n\\t\\tvar a = [];\\n\\t\\tfor ( var row=0, ien=rows.length ; row<ien ; row++ ) {\\n\\t\\t\\ta.push( _fnGetCellData( settings, rows[row], column ) );\\n\\t\\t}\\n\\t\\treturn a;\\n\\t};\\n\\t\\n\\t\\n\\tvar __column_selector = function ( settings, selector, opts )\\n\\t{\\n\\t\\tvar\\n\\t\\t\\tcolumns = settings.aoColumns,\\n\\t\\t\\tnames = _pluck( columns, 'sName' ),\\n\\t\\t\\tnodes = _pluck( columns, 'nTh' );\\n\\t\\n\\t\\tvar run = function ( s ) {\\n\\t\\t\\tvar selInt = _intVal( s );\\n\\t\\n\\t\\t\\t// Selector - all\\n\\t\\t\\tif ( s === '' ) {\\n\\t\\t\\t\\treturn _range( columns.length );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - index\\n\\t\\t\\tif ( selInt !== null ) {\\n\\t\\t\\t\\treturn [ selInt >= 0 ?\\n\\t\\t\\t\\t\\tselInt : // Count from left\\n\\t\\t\\t\\t\\tcolumns.length + selInt // Count from right (+ because its a negative value)\\n\\t\\t\\t\\t];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector = function\\n\\t\\t\\tif ( typeof s === 'function' ) {\\n\\t\\t\\t\\tvar rows = _selector_row_indexes( settings, opts );\\n\\t\\n\\t\\t\\t\\treturn $.map( columns, function (col, idx) {\\n\\t\\t\\t\\t\\treturn s(\\n\\t\\t\\t\\t\\t\\t\\tidx,\\n\\t\\t\\t\\t\\t\\t\\t__columnData( settings, idx, 0, 0, rows ),\\n\\t\\t\\t\\t\\t\\t\\tnodes[ idx ]\\n\\t\\t\\t\\t\\t\\t) ? idx : null;\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// jQuery or string selector\\n\\t\\t\\tvar match = typeof s === 'string' ?\\n\\t\\t\\t\\ts.match( __re_column_selector ) :\\n\\t\\t\\t\\t'';\\n\\t\\n\\t\\t\\tif ( match ) {\\n\\t\\t\\t\\tswitch( match[2] ) {\\n\\t\\t\\t\\t\\tcase 'visIdx':\\n\\t\\t\\t\\t\\tcase 'visible':\\n\\t\\t\\t\\t\\t\\tvar idx = parseInt( match[1], 10 );\\n\\t\\t\\t\\t\\t\\t// Visible index given, convert to column index\\n\\t\\t\\t\\t\\t\\tif ( idx < 0 ) {\\n\\t\\t\\t\\t\\t\\t\\t// Counting from the right\\n\\t\\t\\t\\t\\t\\t\\tvar visColumns = $.map( columns, function (col,i) {\\n\\t\\t\\t\\t\\t\\t\\t\\treturn col.bVisible ? i : null;\\n\\t\\t\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t\\t\\t\\treturn [ visColumns[ visColumns.length + idx ] ];\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t// Counting from the left\\n\\t\\t\\t\\t\\t\\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\\n\\t\\n\\t\\t\\t\\t\\tcase 'name':\\n\\t\\t\\t\\t\\t\\t// match by name. `names` is column index complete and in order\\n\\t\\t\\t\\t\\t\\treturn $.map( names, function (name, i) {\\n\\t\\t\\t\\t\\t\\t\\treturn name === match[1] ? i : null;\\n\\t\\t\\t\\t\\t\\t} );\\n\\t\\n\\t\\t\\t\\t\\tdefault:\\n\\t\\t\\t\\t\\t\\treturn [];\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Cell in the table body\\n\\t\\t\\tif ( s.nodeName && s._DT_CellIndex ) {\\n\\t\\t\\t\\treturn [ s._DT_CellIndex.column ];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// jQuery selector on the TH elements for the columns\\n\\t\\t\\tvar jqResult = $( nodes )\\n\\t\\t\\t\\t.filter( s )\\n\\t\\t\\t\\t.map( function () {\\n\\t\\t\\t\\t\\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.toArray();\\n\\t\\n\\t\\t\\tif ( jqResult.length || ! s.nodeName ) {\\n\\t\\t\\t\\treturn jqResult;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Otherwise a node which might have a `dt-column` data attribute, or be\\n\\t\\t\\t// a child or such an element\\n\\t\\t\\tvar host = $(s).closest('*[data-dt-column]');\\n\\t\\t\\treturn host.length ?\\n\\t\\t\\t\\t[ host.data('dt-column') ] :\\n\\t\\t\\t\\t[];\\n\\t\\t};\\n\\t\\n\\t\\treturn _selector_run( 'column', selector, run, settings, opts );\\n\\t};\\n\\t\\n\\t\\n\\tvar __setColumnVis = function ( settings, column, vis ) {\\n\\t\\tvar\\n\\t\\t\\tcols = settings.aoColumns,\\n\\t\\t\\tcol = cols[ column ],\\n\\t\\t\\tdata = settings.aoData,\\n\\t\\t\\trow, cells, i, ien, tr;\\n\\t\\n\\t\\t// Get\\n\\t\\tif ( vis === undefined ) {\\n\\t\\t\\treturn col.bVisible;\\n\\t\\t}\\n\\t\\n\\t\\t// Set\\n\\t\\t// No change\\n\\t\\tif ( col.bVisible === vis ) {\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\n\\t\\tif ( vis ) {\\n\\t\\t\\t// Insert column\\n\\t\\t\\t// Need to decide if we should use appendChild or insertBefore\\n\\t\\t\\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\\n\\t\\n\\t\\t\\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\ttr = data[i].nTr;\\n\\t\\t\\t\\tcells = data[i].anCells;\\n\\t\\n\\t\\t\\t\\tif ( tr ) {\\n\\t\\t\\t\\t\\t// insertBefore can act like appendChild if 2nd arg is null\\n\\t\\t\\t\\t\\ttr.insertBefore( cells[ column ], cells[ insertBefore ] || null );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\t// Remove column\\n\\t\\t\\t$( _pluck( settings.aoData, 'anCells', column ) ).detach();\\n\\t\\t}\\n\\t\\n\\t\\t// Common actions\\n\\t\\tcol.bVisible = vis;\\n\\t\\t_fnDrawHead( settings, settings.aoHeader );\\n\\t\\t_fnDrawHead( settings, settings.aoFooter );\\n\\t\\n\\t\\t_fnSaveState( settings );\\n\\t};\\n\\t\\n\\t\\n\\t_api_register( 'columns()', function ( selector, opts ) {\\n\\t\\t// argument shifting\\n\\t\\tif ( selector === undefined ) {\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\telse if ( $.isPlainObject( selector ) ) {\\n\\t\\t\\topts = selector;\\n\\t\\t\\tselector = '';\\n\\t\\t}\\n\\t\\n\\t\\topts = _selector_opts( opts );\\n\\t\\n\\t\\tvar inst = this.iterator( 'table', function ( settings ) {\\n\\t\\t\\treturn __column_selector( settings, selector, opts );\\n\\t\\t}, 1 );\\n\\t\\n\\t\\t// Want argument shifting here and in _row_selector?\\n\\t\\tinst.selector.cols = selector;\\n\\t\\tinst.selector.opts = opts;\\n\\t\\n\\t\\treturn inst;\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn settings.aoColumns[column].nTh;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn settings.aoColumns[column].nTf;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().data()', 'column().data()', function () {\\n\\t\\treturn this.iterator( 'column-rows', __columnData, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn settings.aoColumns[column].mData;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {\\n\\t\\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\\n\\t\\t\\treturn _pluck_order( settings.aoData, rows,\\n\\t\\t\\t\\ttype === 'search' ? '_aFilterData' : '_aSortData', column\\n\\t\\t\\t);\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {\\n\\t\\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\\n\\t\\t\\treturn _pluck_order( settings.aoData, rows, 'anCells', column ) ;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {\\n\\t\\tvar ret = this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\tif ( vis === undefined ) {\\n\\t\\t\\t\\treturn settings.aoColumns[ column ].bVisible;\\n\\t\\t\\t} // else\\n\\t\\t\\t__setColumnVis( settings, column, vis );\\n\\t\\t} );\\n\\t\\n\\t\\t// Group the column visibility changes\\n\\t\\tif ( vis !== undefined ) {\\n\\t\\t\\t// Second loop once the first is done for events\\n\\t\\t\\tthis.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\t\\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tif ( calc === undefined || calc ) {\\n\\t\\t\\t\\tthis.columns.adjust();\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn ret;\\n\\t} );\\n\\t\\n\\t_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {\\n\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\treturn type === 'visible' ?\\n\\t\\t\\t\\t_fnColumnIndexToVisible( settings, column ) :\\n\\t\\t\\t\\tcolumn;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_register( 'columns.adjust()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnAdjustColumnSizing( settings );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t_api_register( 'column.index()', function ( type, idx ) {\\n\\t\\tif ( this.context.length !== 0 ) {\\n\\t\\t\\tvar ctx = this.context[0];\\n\\t\\n\\t\\t\\tif ( type === 'fromVisible' || type === 'toData' ) {\\n\\t\\t\\t\\treturn _fnVisibleToColumnIndex( ctx, idx );\\n\\t\\t\\t}\\n\\t\\t\\telse if ( type === 'fromData' || type === 'toVisible' ) {\\n\\t\\t\\t\\treturn _fnColumnIndexToVisible( ctx, idx );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t_api_register( 'column()', function ( selector, opts ) {\\n\\t\\treturn _selector_first( this.columns( selector, opts ) );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __cell_selector = function ( settings, selector, opts )\\n\\t{\\n\\t\\tvar data = settings.aoData;\\n\\t\\tvar rows = _selector_row_indexes( settings, opts );\\n\\t\\tvar cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );\\n\\t\\tvar allCells = $( [].concat.apply([], cells) );\\n\\t\\tvar row;\\n\\t\\tvar columns = settings.aoColumns.length;\\n\\t\\tvar a, i, ien, j, o, host;\\n\\t\\n\\t\\tvar run = function ( s ) {\\n\\t\\t\\tvar fnSelector = typeof s === 'function';\\n\\t\\n\\t\\t\\tif ( s === null || s === undefined || fnSelector ) {\\n\\t\\t\\t\\t// All cells and function selectors\\n\\t\\t\\t\\ta = [];\\n\\t\\n\\t\\t\\t\\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\trow = rows[i];\\n\\t\\n\\t\\t\\t\\t\\tfor ( j=0 ; j<columns ; j++ ) {\\n\\t\\t\\t\\t\\t\\to = {\\n\\t\\t\\t\\t\\t\\t\\trow: row,\\n\\t\\t\\t\\t\\t\\t\\tcolumn: j\\n\\t\\t\\t\\t\\t\\t};\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( fnSelector ) {\\n\\t\\t\\t\\t\\t\\t\\t// Selector - function\\n\\t\\t\\t\\t\\t\\t\\thost = data[ row ];\\n\\t\\n\\t\\t\\t\\t\\t\\t\\tif ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {\\n\\t\\t\\t\\t\\t\\t\\t\\ta.push( o );\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\t\\t// Selector - all\\n\\t\\t\\t\\t\\t\\t\\ta.push( o );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\treturn a;\\n\\t\\t\\t}\\n\\t\\t\\t\\n\\t\\t\\t// Selector - index\\n\\t\\t\\tif ( $.isPlainObject( s ) ) {\\n\\t\\t\\t\\treturn [s];\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Selector - jQuery filtered cells\\n\\t\\t\\tvar jqResult = allCells\\n\\t\\t\\t\\t.filter( s )\\n\\t\\t\\t\\t.map( function (i, el) {\\n\\t\\t\\t\\t\\treturn { // use a new object, in case someone changes the values\\n\\t\\t\\t\\t\\t\\trow: el._DT_CellIndex.row,\\n\\t\\t\\t\\t\\t\\tcolumn: el._DT_CellIndex.column\\n\\t \\t\\t\\t\\t};\\n\\t\\t\\t\\t} )\\n\\t\\t\\t\\t.toArray();\\n\\t\\n\\t\\t\\tif ( jqResult.length || ! s.nodeName ) {\\n\\t\\t\\t\\treturn jqResult;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Otherwise the selector is a node, and there is one last option - the\\n\\t\\t\\t// element might be a child of an element which has dt-row and dt-column\\n\\t\\t\\t// data attributes\\n\\t\\t\\thost = $(s).closest('*[data-dt-row]');\\n\\t\\t\\treturn host.length ?\\n\\t\\t\\t\\t[ {\\n\\t\\t\\t\\t\\trow: host.data('dt-row'),\\n\\t\\t\\t\\t\\tcolumn: host.data('dt-column')\\n\\t\\t\\t\\t} ] :\\n\\t\\t\\t\\t[];\\n\\t\\t};\\n\\t\\n\\t\\treturn _selector_run( 'cell', selector, run, settings, opts );\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {\\n\\t\\t// Argument shifting\\n\\t\\tif ( $.isPlainObject( rowSelector ) ) {\\n\\t\\t\\t// Indexes\\n\\t\\t\\tif ( rowSelector.row === undefined ) {\\n\\t\\t\\t\\t// Selector options in first parameter\\n\\t\\t\\t\\topts = rowSelector;\\n\\t\\t\\t\\trowSelector = null;\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\t// Cell index objects in first parameter\\n\\t\\t\\t\\topts = columnSelector;\\n\\t\\t\\t\\tcolumnSelector = null;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif ( $.isPlainObject( columnSelector ) ) {\\n\\t\\t\\topts = columnSelector;\\n\\t\\t\\tcolumnSelector = null;\\n\\t\\t}\\n\\t\\n\\t\\t// Cell selector\\n\\t\\tif ( columnSelector === null || columnSelector === undefined ) {\\n\\t\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t\\treturn __cell_selector( settings, rowSelector, _selector_opts( opts ) );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t\\n\\t\\t// Row + column selector\\n\\t\\tvar columns = this.columns( columnSelector, opts );\\n\\t\\tvar rows = this.rows( rowSelector, opts );\\n\\t\\tvar a, i, ien, j, jen;\\n\\t\\n\\t\\tvar cells = this.iterator( 'table', function ( settings, idx ) {\\n\\t\\t\\ta = [];\\n\\t\\n\\t\\t\\tfor ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {\\n\\t\\t\\t\\tfor ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {\\n\\t\\t\\t\\t\\ta.push( {\\n\\t\\t\\t\\t\\t\\trow: rows[idx][i],\\n\\t\\t\\t\\t\\t\\tcolumn: columns[idx][j]\\n\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\treturn a;\\n\\t\\t}, 1 );\\n\\t\\n\\t\\t$.extend( cells.selector, {\\n\\t\\t\\tcols: columnSelector,\\n\\t\\t\\trows: rowSelector,\\n\\t\\t\\topts: opts\\n\\t\\t} );\\n\\t\\n\\t\\treturn cells;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\tvar data = settings.aoData[ row ];\\n\\t\\n\\t\\t\\treturn data && data.anCells ?\\n\\t\\t\\t\\tdata.anCells[ column ] :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'cells().data()', function () {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn _fnGetCellData( settings, row, column );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {\\n\\t\\ttype = type === 'search' ? '_aFilterData' : '_aSortData';\\n\\t\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn settings.aoData[ row ][ type ][ column ];\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn _fnGetCellData( settings, row, column, type );\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\treturn {\\n\\t\\t\\t\\trow: row,\\n\\t\\t\\t\\tcolumn: column,\\n\\t\\t\\t\\tcolumnVisible: _fnColumnIndexToVisible( settings, column )\\n\\t\\t\\t};\\n\\t\\t}, 1 );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {\\n\\t\\treturn this.iterator( 'cell', function ( settings, row, column ) {\\n\\t\\t\\t_fnInvalidate( settings, row, src, column );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {\\n\\t\\treturn _selector_first( this.cells( rowSelector, columnSelector, opts ) );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'cell().data()', function ( data ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\tvar cell = this[0];\\n\\t\\n\\t\\tif ( data === undefined ) {\\n\\t\\t\\t// Get\\n\\t\\t\\treturn ctx.length && cell.length ?\\n\\t\\t\\t\\t_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// Set\\n\\t\\t_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );\\n\\t\\t_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );\\n\\t\\n\\t\\treturn this;\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Get current ordering (sorting) that has been applied to the table.\\n\\t *\\n\\t * @returns {array} 2D array containing the sorting information for the first\\n\\t * table in the current context. Each element in the parent array represents\\n\\t * a column being sorted upon (i.e. multi-sorting with two columns would have\\n\\t * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is\\n\\t * the column index that the sorting condition applies to, the second is the\\n\\t * direction of the sort (`desc` or `asc`) and, optionally, the third is the\\n\\t * index of the sorting order from the `column.sorting` initialisation array.\\n\\t *//**\\n\\t * Set the ordering for the table.\\n\\t *\\n\\t * @param {integer} order Column index to sort upon.\\n\\t * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)\\n\\t * @returns {DataTables.Api} this\\n\\t *//**\\n\\t * Set the ordering for the table.\\n\\t *\\n\\t * @param {array} order 1D array of sorting information to be applied.\\n\\t * @param {array} [...] Optional additional sorting conditions\\n\\t * @returns {DataTables.Api} this\\n\\t *//**\\n\\t * Set the ordering for the table.\\n\\t *\\n\\t * @param {array} order 2D array of sorting information to be applied.\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'order()', function ( order, dir ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( order === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\treturn ctx.length !== 0 ?\\n\\t\\t\\t\\tctx[0].aaSorting :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// set\\n\\t\\tif ( typeof order === 'number' ) {\\n\\t\\t\\t// Simple column / direction passed in\\n\\t\\t\\torder = [ [ order, dir ] ];\\n\\t\\t}\\n\\t\\telse if ( order.length && ! $.isArray( order[0] ) ) {\\n\\t\\t\\t// Arguments passed in (list of 1D arrays)\\n\\t\\t\\torder = Array.prototype.slice.call( arguments );\\n\\t\\t}\\n\\t\\t// otherwise a 2D array was passed in\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tsettings.aaSorting = order.slice();\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t/**\\n\\t * Attach a sort listener to an element for a given column\\n\\t *\\n\\t * @param {node|jQuery|string} node Identifier for the element(s) to attach the\\n\\t * listener to. This can take the form of a single DOM node, a jQuery\\n\\t * collection of nodes or a jQuery selector which will identify the node(s).\\n\\t * @param {integer} column the column that a click on this node will sort on\\n\\t * @param {function} [callback] callback function when sort is run\\n\\t * @returns {DataTables.Api} this\\n\\t */\\n\\t_api_register( 'order.listener()', function ( node, column, callback ) {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnSortAttachListener( settings, node, column, callback );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'order.fixed()', function ( set ) {\\n\\t\\tif ( ! set ) {\\n\\t\\t\\tvar ctx = this.context;\\n\\t\\t\\tvar fixed = ctx.length ?\\n\\t\\t\\t\\tctx[0].aaSortingFixed :\\n\\t\\t\\t\\tundefined;\\n\\t\\n\\t\\t\\treturn $.isArray( fixed ) ?\\n\\t\\t\\t\\t{ pre: fixed } :\\n\\t\\t\\t\\tfixed;\\n\\t\\t}\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tsettings.aaSortingFixed = $.extend( true, {}, set );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t// Order by the selected column(s)\\n\\t_api_register( [\\n\\t\\t'columns().order()',\\n\\t\\t'column().order()'\\n\\t], function ( dir ) {\\n\\t\\tvar that = this;\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings, i ) {\\n\\t\\t\\tvar sort = [];\\n\\t\\n\\t\\t\\t$.each( that[i], function (j, col) {\\n\\t\\t\\t\\tsort.push( [ col, dir ] );\\n\\t\\t\\t} );\\n\\t\\n\\t\\t\\tsettings.aaSorting = sort;\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t_api_register( 'search()', function ( input, regex, smart, caseInsen ) {\\n\\t\\tvar ctx = this.context;\\n\\t\\n\\t\\tif ( input === undefined ) {\\n\\t\\t\\t// get\\n\\t\\t\\treturn ctx.length !== 0 ?\\n\\t\\t\\t\\tctx[0].oPreviousSearch.sSearch :\\n\\t\\t\\t\\tundefined;\\n\\t\\t}\\n\\t\\n\\t\\t// set\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tif ( ! settings.oFeatures.bFilter ) {\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {\\n\\t\\t\\t\\t\\\"sSearch\\\": input+\\\"\\\",\\n\\t\\t\\t\\t\\\"bRegex\\\": regex === null ? false : regex,\\n\\t\\t\\t\\t\\\"bSmart\\\": smart === null ? true : smart,\\n\\t\\t\\t\\t\\\"bCaseInsensitive\\\": caseInsen === null ? true : caseInsen\\n\\t\\t\\t} ), 1 );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_registerPlural(\\n\\t\\t'columns().search()',\\n\\t\\t'column().search()',\\n\\t\\tfunction ( input, regex, smart, caseInsen ) {\\n\\t\\t\\treturn this.iterator( 'column', function ( settings, column ) {\\n\\t\\t\\t\\tvar preSearch = settings.aoPreSearchCols;\\n\\t\\n\\t\\t\\t\\tif ( input === undefined ) {\\n\\t\\t\\t\\t\\t// get\\n\\t\\t\\t\\t\\treturn preSearch[ column ].sSearch;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t// set\\n\\t\\t\\t\\tif ( ! settings.oFeatures.bFilter ) {\\n\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t$.extend( preSearch[ column ], {\\n\\t\\t\\t\\t\\t\\\"sSearch\\\": input+\\\"\\\",\\n\\t\\t\\t\\t\\t\\\"bRegex\\\": regex === null ? false : regex,\\n\\t\\t\\t\\t\\t\\\"bSmart\\\": smart === null ? true : smart,\\n\\t\\t\\t\\t\\t\\\"bCaseInsensitive\\\": caseInsen === null ? true : caseInsen\\n\\t\\t\\t\\t} );\\n\\t\\n\\t\\t\\t\\t_fnFilterComplete( settings, settings.oPreviousSearch, 1 );\\n\\t\\t\\t} );\\n\\t\\t}\\n\\t);\\n\\t\\n\\t/*\\n\\t * State API methods\\n\\t */\\n\\t\\n\\t_api_register( 'state()', function () {\\n\\t\\treturn this.context.length ?\\n\\t\\t\\tthis.context[0].oSavedState :\\n\\t\\t\\tnull;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'state.clear()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t// Save an empty object\\n\\t\\t\\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, {} );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'state.loaded()', function () {\\n\\t\\treturn this.context.length ?\\n\\t\\t\\tthis.context[0].oLoadedState :\\n\\t\\t\\tnull;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'state.save()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnSaveState( settings );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Provide a common method for plug-ins to check the version of DataTables being\\n\\t * used, in order to ensure compatibility.\\n\\t *\\n\\t * @param {string} version Version string to check for, in the format \\\"X.Y.Z\\\".\\n\\t * Note that the formats \\\"X\\\" and \\\"X.Y\\\" are also acceptable.\\n\\t * @returns {boolean} true if this version of DataTables is greater or equal to\\n\\t * the required version, or false if this version of DataTales is not\\n\\t * suitable\\n\\t * @static\\n\\t * @dtopt API-Static\\n\\t *\\n\\t * @example\\n\\t * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );\\n\\t */\\n\\tDataTable.versionCheck = DataTable.fnVersionCheck = function( version )\\n\\t{\\n\\t\\tvar aThis = DataTable.version.split('.');\\n\\t\\tvar aThat = version.split('.');\\n\\t\\tvar iThis, iThat;\\n\\t\\n\\t\\tfor ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {\\n\\t\\t\\tiThis = parseInt( aThis[i], 10 ) || 0;\\n\\t\\t\\tiThat = parseInt( aThat[i], 10 ) || 0;\\n\\t\\n\\t\\t\\t// Parts are the same, keep comparing\\n\\t\\t\\tif (iThis === iThat) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Parts are different, return immediately\\n\\t\\t\\treturn iThis > iThat;\\n\\t\\t}\\n\\t\\n\\t\\treturn true;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Check if a `<table>` node is a DataTable table already or not.\\n\\t *\\n\\t * @param {node|jquery|string} table Table node, jQuery object or jQuery\\n\\t * selector for the table to test. Note that if more than more than one\\n\\t * table is passed on, only the first will be checked\\n\\t * @returns {boolean} true the table given is a DataTable, or false otherwise\\n\\t * @static\\n\\t * @dtopt API-Static\\n\\t *\\n\\t * @example\\n\\t * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\\n\\t * $('#example').dataTable();\\n\\t * }\\n\\t */\\n\\tDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\\n\\t{\\n\\t\\tvar t = $(table).get(0);\\n\\t\\tvar is = false;\\n\\t\\n\\t\\tif ( table instanceof DataTable.Api ) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\t\\n\\t\\t$.each( DataTable.settings, function (i, o) {\\n\\t\\t\\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\\n\\t\\t\\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\\n\\t\\n\\t\\t\\tif ( o.nTable === t || head === t || foot === t ) {\\n\\t\\t\\t\\tis = true;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn is;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Get all DataTable tables that have been initialised - optionally you can\\n\\t * select to get only currently visible tables.\\n\\t *\\n\\t * @param {boolean} [visible=false] Flag to indicate if you want all (default)\\n\\t * or visible tables only.\\n\\t * @returns {array} Array of `table` nodes (not DataTable instances) which are\\n\\t * DataTables\\n\\t * @static\\n\\t * @dtopt API-Static\\n\\t *\\n\\t * @example\\n\\t * $.each( $.fn.dataTable.tables(true), function () {\\n\\t * $(table).DataTable().columns.adjust();\\n\\t * } );\\n\\t */\\n\\tDataTable.tables = DataTable.fnTables = function ( visible )\\n\\t{\\n\\t\\tvar api = false;\\n\\t\\n\\t\\tif ( $.isPlainObject( visible ) ) {\\n\\t\\t\\tapi = visible.api;\\n\\t\\t\\tvisible = visible.visible;\\n\\t\\t}\\n\\t\\n\\t\\tvar a = $.map( DataTable.settings, function (o) {\\n\\t\\t\\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\\n\\t\\t\\t\\treturn o.nTable;\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t\\n\\t\\treturn api ?\\n\\t\\t\\tnew _Api( a ) :\\n\\t\\t\\ta;\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Convert from camel case parameters to Hungarian notation. This is made public\\n\\t * for the extensions to provide the same ability as DataTables core to accept\\n\\t * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\\n\\t * parameters.\\n\\t *\\n\\t * @param {object} src The model object which holds all parameters that can be\\n\\t * mapped.\\n\\t * @param {object} user The object to convert from camel case to Hungarian.\\n\\t * @param {boolean} force When set to `true`, properties which already have a\\n\\t * Hungarian value in the `user` object will be overwritten. Otherwise they\\n\\t * won't be.\\n\\t */\\n\\tDataTable.camelToHungarian = _fnCamelToHungarian;\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t *\\n\\t */\\n\\t_api_register( '$()', function ( selector, opts ) {\\n\\t\\tvar\\n\\t\\t\\trows = this.rows( opts ).nodes(), // Get all rows\\n\\t\\t\\tjqRows = $(rows);\\n\\t\\n\\t\\treturn $( [].concat(\\n\\t\\t\\tjqRows.filter( selector ).toArray(),\\n\\t\\t\\tjqRows.find( selector ).toArray()\\n\\t\\t) );\\n\\t} );\\n\\t\\n\\t\\n\\t// jQuery functions to operate on the tables\\n\\t$.each( [ 'on', 'one', 'off' ], function (i, key) {\\n\\t\\t_api_register( key+'()', function ( /* event, handler */ ) {\\n\\t\\t\\tvar args = Array.prototype.slice.call(arguments);\\n\\t\\n\\t\\t\\t// Add the `dt` namespace automatically if it isn't already present\\n\\t\\t\\targs[0] = $.map( args[0].split( /\\\\s/ ), function ( e ) {\\n\\t\\t\\t\\treturn ! e.match(/\\\\.dt\\\\b/) ?\\n\\t\\t\\t\\t\\te+'.dt' :\\n\\t\\t\\t\\t\\te;\\n\\t\\t\\t\\t} ).join( ' ' );\\n\\t\\n\\t\\t\\tvar inst = $( this.tables().nodes() );\\n\\t\\t\\tinst[key].apply( inst, args );\\n\\t\\t\\treturn this;\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'clear()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\t_fnClearTable( settings );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'settings()', function () {\\n\\t\\treturn new _Api( this.context, this.context );\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'init()', function () {\\n\\t\\tvar ctx = this.context;\\n\\t\\treturn ctx.length ? ctx[0].oInit : null;\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'data()', function () {\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\treturn _pluck( settings.aoData, '_aData' );\\n\\t\\t} ).flatten();\\n\\t} );\\n\\t\\n\\t\\n\\t_api_register( 'destroy()', function ( remove ) {\\n\\t\\tremove = remove || false;\\n\\t\\n\\t\\treturn this.iterator( 'table', function ( settings ) {\\n\\t\\t\\tvar orig = settings.nTableWrapper.parentNode;\\n\\t\\t\\tvar classes = settings.oClasses;\\n\\t\\t\\tvar table = settings.nTable;\\n\\t\\t\\tvar tbody = settings.nTBody;\\n\\t\\t\\tvar thead = settings.nTHead;\\n\\t\\t\\tvar tfoot = settings.nTFoot;\\n\\t\\t\\tvar jqTable = $(table);\\n\\t\\t\\tvar jqTbody = $(tbody);\\n\\t\\t\\tvar jqWrapper = $(settings.nTableWrapper);\\n\\t\\t\\tvar rows = $.map( settings.aoData, function (r) { return r.nTr; } );\\n\\t\\t\\tvar i, ien;\\n\\t\\n\\t\\t\\t// Flag to note that the table is currently being destroyed - no action\\n\\t\\t\\t// should be taken\\n\\t\\t\\tsettings.bDestroying = true;\\n\\t\\n\\t\\t\\t// Fire off the destroy callbacks for plug-ins etc\\n\\t\\t\\t_fnCallbackFire( settings, \\\"aoDestroyCallback\\\", \\\"destroy\\\", [settings] );\\n\\t\\n\\t\\t\\t// If not being removed from the document, make all columns visible\\n\\t\\t\\tif ( ! remove ) {\\n\\t\\t\\t\\tnew _Api( settings ).columns().visible( true );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t// Blitz all `DT` namespaced events (these are internal events, the\\n\\t\\t\\t// lowercase, `dt` events are user subscribed and they are responsible\\n\\t\\t\\t// for removing them\\n\\t\\t\\tjqWrapper.off('.DT').find(':not(tbody *)').off('.DT');\\n\\t\\t\\t$(window).off('.DT-'+settings.sInstance);\\n\\t\\n\\t\\t\\t// When scrolling we had to break the table up - restore it\\n\\t\\t\\tif ( table != thead.parentNode ) {\\n\\t\\t\\t\\tjqTable.children('thead').detach();\\n\\t\\t\\t\\tjqTable.append( thead );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( tfoot && table != tfoot.parentNode ) {\\n\\t\\t\\t\\tjqTable.children('tfoot').detach();\\n\\t\\t\\t\\tjqTable.append( tfoot );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tsettings.aaSorting = [];\\n\\t\\t\\tsettings.aaSortingFixed = [];\\n\\t\\t\\t_fnSortingClasses( settings );\\n\\t\\n\\t\\t\\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\\n\\t\\n\\t\\t\\t$('th, td', thead).removeClass( classes.sSortable+' '+\\n\\t\\t\\t\\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\\n\\t\\t\\t);\\n\\t\\n\\t\\t\\t// Add the TR elements back into the table in their original order\\n\\t\\t\\tjqTbody.children().detach();\\n\\t\\t\\tjqTbody.append( rows );\\n\\t\\n\\t\\t\\t// Remove the DataTables generated nodes, events and classes\\n\\t\\t\\tvar removedMethod = remove ? 'remove' : 'detach';\\n\\t\\t\\tjqTable[ removedMethod ]();\\n\\t\\t\\tjqWrapper[ removedMethod ]();\\n\\t\\n\\t\\t\\t// If we need to reattach the table to the document\\n\\t\\t\\tif ( ! remove && orig ) {\\n\\t\\t\\t\\t// insertBefore acts like appendChild if !arg[1]\\n\\t\\t\\t\\torig.insertBefore( table, settings.nTableReinsertBefore );\\n\\t\\n\\t\\t\\t\\t// Restore the width of the original table - was read from the style property,\\n\\t\\t\\t\\t// so we can restore directly to that\\n\\t\\t\\t\\tjqTable\\n\\t\\t\\t\\t\\t.css( 'width', settings.sDestroyWidth )\\n\\t\\t\\t\\t\\t.removeClass( classes.sTable );\\n\\t\\n\\t\\t\\t\\t// If the were originally stripe classes - then we add them back here.\\n\\t\\t\\t\\t// Note this is not fool proof (for example if not all rows had stripe\\n\\t\\t\\t\\t// classes - but it's a good effort without getting carried away\\n\\t\\t\\t\\tien = settings.asDestroyStripes.length;\\n\\t\\n\\t\\t\\t\\tif ( ien ) {\\n\\t\\t\\t\\t\\tjqTbody.children().each( function (i) {\\n\\t\\t\\t\\t\\t\\t$(this).addClass( settings.asDestroyStripes[i % ien] );\\n\\t\\t\\t\\t\\t} );\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\t/* Remove the settings object from the settings array */\\n\\t\\t\\tvar idx = $.inArray( settings, DataTable.settings );\\n\\t\\t\\tif ( idx !== -1 ) {\\n\\t\\t\\t\\tDataTable.settings.splice( idx, 1 );\\n\\t\\t\\t}\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t// Add the `every()` method for rows, columns and cells in a compact form\\n\\t$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\\n\\t\\t_api_register( type+'s().every()', function ( fn ) {\\n\\t\\t\\tvar opts = this.selector.opts;\\n\\t\\t\\tvar api = this;\\n\\t\\n\\t\\t\\treturn this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {\\n\\t\\t\\t\\t// Rows and columns:\\n\\t\\t\\t\\t// arg1 - index\\n\\t\\t\\t\\t// arg2 - table counter\\n\\t\\t\\t\\t// arg3 - loop counter\\n\\t\\t\\t\\t// arg4 - undefined\\n\\t\\t\\t\\t// Cells:\\n\\t\\t\\t\\t// arg1 - row index\\n\\t\\t\\t\\t// arg2 - column index\\n\\t\\t\\t\\t// arg3 - table counter\\n\\t\\t\\t\\t// arg4 - loop counter\\n\\t\\t\\t\\tfn.call(\\n\\t\\t\\t\\t\\tapi[ type ](\\n\\t\\t\\t\\t\\t\\targ1,\\n\\t\\t\\t\\t\\t\\ttype==='cell' ? arg2 : opts,\\n\\t\\t\\t\\t\\t\\ttype==='cell' ? opts : undefined\\n\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t\\targ1, arg2, arg3, arg4\\n\\t\\t\\t\\t);\\n\\t\\t\\t} );\\n\\t\\t} );\\n\\t} );\\n\\t\\n\\t\\n\\t// i18n method for extensions to be able to use the language object from the\\n\\t// DataTable\\n\\t_api_register( 'i18n()', function ( token, def, plural ) {\\n\\t\\tvar ctx = this.context[0];\\n\\t\\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\\n\\t\\n\\t\\tif ( resolved === undefined ) {\\n\\t\\t\\tresolved = def;\\n\\t\\t}\\n\\t\\n\\t\\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\\n\\t\\t\\tresolved = resolved[ plural ] !== undefined ?\\n\\t\\t\\t\\tresolved[ plural ] :\\n\\t\\t\\t\\tresolved._;\\n\\t\\t}\\n\\t\\n\\t\\treturn resolved.replace( '%d', plural ); // nb: plural might be undefined,\\n\\t} );\\n\\t/**\\n\\t * Version string for plug-ins to check compatibility. Allowed format is\\n\\t * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\\n\\t * only for non-release builds. See http://semver.org/ for more information.\\n\\t * @member\\n\\t * @type string\\n\\t * @default Version number\\n\\t */\\n\\tDataTable.version = \\\"1.10.16-dev\\\";\\n\\n\\t/**\\n\\t * Private data store, containing all of the settings objects that are\\n\\t * created for the tables on a given page.\\n\\t *\\n\\t * Note that the `DataTable.settings` object is aliased to\\n\\t * `jQuery.fn.dataTableExt` through which it may be accessed and\\n\\t * manipulated, or `jQuery.fn.dataTable.settings`.\\n\\t * @member\\n\\t * @type array\\n\\t * @default []\\n\\t * @private\\n\\t */\\n\\tDataTable.settings = [];\\n\\n\\t/**\\n\\t * Object models container, for the various models that DataTables has\\n\\t * available to it. These models define the objects that are used to hold\\n\\t * the active state and configuration of the table.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models = {};\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Template object for the way in which DataTables holds information about\\n\\t * search information for the global filter and individual column filters.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models.oSearch = {\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the filtering should be case insensitive or not\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t */\\n\\t\\t\\\"bCaseInsensitive\\\": true,\\n\\t\\n\\t\\t/**\\n\\t\\t * Applied search term\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t */\\n\\t\\t\\\"sSearch\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the search term should be interpreted as a\\n\\t\\t * regular expression (true) or not (false) and therefore and special\\n\\t\\t * regex characters escaped.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bRegex\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if DataTables is to use its smart filtering or not.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t */\\n\\t\\t\\\"bSmart\\\": true\\n\\t};\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * Template object for the way in which DataTables holds information about\\n\\t * each individual row. This is the object format used for the settings\\n\\t * aoData array.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models.oRow = {\\n\\t\\t/**\\n\\t\\t * TR element for the row\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTr\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of TD elements for each row. This is null until the row has been\\n\\t\\t * created.\\n\\t\\t * @type array nodes\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"anCells\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Data object from the original data source for the row. This is either\\n\\t\\t * an array if using the traditional form of DataTables, or an object if\\n\\t\\t * using mData options. The exact type will depend on the passed in\\n\\t\\t * data from the data source, or will be an array if using DOM a data\\n\\t\\t * source.\\n\\t\\t * @type array|object\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"_aData\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Sorting data cache - this array is ostensibly the same length as the\\n\\t\\t * number of columns (although each index is generated only as it is\\n\\t\\t * needed), and holds the data that is used for sorting each column in the\\n\\t\\t * row. We do this cache generation at the start of the sort in order that\\n\\t\\t * the formatting of the sort data need be done only once for each cell\\n\\t\\t * per sort. This array should not be read from or written to by anything\\n\\t\\t * other than the master sorting methods.\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_aSortData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Per cell filtering data cache. As per the sort data cache, used to\\n\\t\\t * increase the performance of the filtering in DataTables\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_aFilterData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Filtering data cache. This is the same as the cell filtering cache, but\\n\\t\\t * in this case a string rather than an array. This is easily computed with\\n\\t\\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\\n\\t\\t * needed on every search (memory traded for performance)\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_sFilterRow\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Cache of the class name that DataTables has applied to the row, so we\\n\\t\\t * can quickly look at this variable rather than needing to do a DOM check\\n\\t\\t * on className for the nTr property.\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_sRowStripe\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * Denote if the original data source was from the DOM, or the data source\\n\\t\\t * object. This is used for invalidating data, so DataTables can\\n\\t\\t * automatically read data from the original source, unless uninstructed\\n\\t\\t * otherwise.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"src\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Index in the aoData array. This saves an indexOf lookup when we have the\\n\\t\\t * object, but want to know the index\\n\\t\\t * @type integer\\n\\t\\t * @default -1\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"idx\\\": -1\\n\\t};\\n\\t\\n\\t\\n\\t/**\\n\\t * Template object for the column information object in DataTables. This object\\n\\t * is held in the settings aoColumns array and contains all the information that\\n\\t * DataTables needs about each individual column.\\n\\t *\\n\\t * Note that this object is related to {@link DataTable.defaults.column}\\n\\t * but this one is the internal data store for DataTables's cache of columns.\\n\\t * It should NOT be manipulated outside of DataTables. Any configuration should\\n\\t * be done through the initialisation options.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.models.oColumn = {\\n\\t\\t/**\\n\\t\\t * Column index. This could be worked out on-the-fly with $.inArray, but it\\n\\t\\t * is faster to just hold it as a variable\\n\\t\\t * @type integer\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"idx\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * A list of the columns that sorting should occur on when this column\\n\\t\\t * is sorted. That this property is an array allows multi-column sorting\\n\\t\\t * to be defined for a column (for example first name / last name columns\\n\\t\\t * would benefit from this). The values are integers pointing to the\\n\\t\\t * columns to be sorted on (typically it will be a single integer pointing\\n\\t\\t * at itself, but that doesn't need to be the case).\\n\\t\\t * @type array\\n\\t\\t */\\n\\t\\t\\\"aDataSort\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Define the sorting directions that are applied to the column, in sequence\\n\\t\\t * as the column is repeatedly sorted upon - i.e. the first value is used\\n\\t\\t * as the sorting direction when the column if first sorted (clicked on).\\n\\t\\t * Sort it again (click again) and it will move on to the next index.\\n\\t\\t * Repeat until loop.\\n\\t\\t * @type array\\n\\t\\t */\\n\\t\\t\\\"asSorting\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the column is searchable, and thus should be included\\n\\t\\t * in the filtering or not.\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bSearchable\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the column is sortable or not.\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bSortable\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if the column is currently visible in the table or not\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bVisible\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Store for manual type assignment using the `column.type` option. This\\n\\t\\t * is held in store so we can manipulate the column's `sType` property.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_sManualType\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag to indicate if HTML5 data attributes should be used as the data\\n\\t\\t * source for filtering or sorting. True is either are.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_bAttrSrc\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Developer definable function that is called whenever a cell is created (Ajax source,\\n\\t\\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\\n\\t\\t * allowing you to modify the DOM element (add background colour for example) when the\\n\\t\\t * element is available.\\n\\t\\t * @type function\\n\\t\\t * @param {element} nTd The TD node that has been created\\n\\t\\t * @param {*} sData The Data for the cell\\n\\t\\t * @param {array|object} oData The data for the whole row\\n\\t\\t * @param {int} iRow The row index for the aoData data store\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"fnCreatedCell\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Function to get data from a cell in a column. You should <b>never</b>\\n\\t\\t * access data directly through _aData internally in DataTables - always use\\n\\t\\t * the method attached to this property. It allows mData to function as\\n\\t\\t * required. This function is automatically assigned by the column\\n\\t\\t * initialisation method\\n\\t\\t * @type function\\n\\t\\t * @param {array|object} oData The data array/object for the array\\n\\t\\t * (i.e. aoData[]._aData)\\n\\t\\t * @param {string} sSpecific The specific data type you want to get -\\n\\t\\t * 'display', 'type' 'filter' 'sort'\\n\\t\\t * @returns {*} The data for the cell from the given row's data\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"fnGetData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Function to set data for a cell in the column. You should <b>never</b>\\n\\t\\t * set the data directly to _aData internally in DataTables - always use\\n\\t\\t * this method. It allows mData to function as required. This function\\n\\t\\t * is automatically assigned by the column initialisation method\\n\\t\\t * @type function\\n\\t\\t * @param {array|object} oData The data array/object for the array\\n\\t\\t * (i.e. aoData[]._aData)\\n\\t\\t * @param {*} sValue Value to set\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"fnSetData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Property to read the value for the cells in the column from the data\\n\\t\\t * source array / object. If null, then the default content is used, if a\\n\\t\\t * function is given then the return from the function is used.\\n\\t\\t * @type function|int|string|null\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"mData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Partner property to mData which is used (only when defined) to get\\n\\t\\t * the data - i.e. it is basically the same as mData, but without the\\n\\t\\t * 'set' option, and also the data fed to it is the result from mData.\\n\\t\\t * This is the rendering method to match the data method of mData.\\n\\t\\t * @type function|int|string|null\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"mRender\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique header TH/TD element for this column - this is what the sorting\\n\\t\\t * listener is attached to (if sorting is enabled.)\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTh\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique footer TH/TD element for this column (if there is one). Not used\\n\\t\\t * in DataTables as such, but can be used for plug-ins to reference the\\n\\t\\t * footer for each column.\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTf\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * The class to apply to all TD elements in the table's TBODY for the column\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sClass\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * When DataTables calculates the column widths to assign to each column,\\n\\t\\t * it finds the longest string in each column and then constructs a\\n\\t\\t * temporary table and reads the widths from that. The problem with this\\n\\t\\t * is that \\\"mmm\\\" is much wider then \\\"iiii\\\", but the latter is a longer\\n\\t\\t * string - thus the calculation can go wrong (doing it properly and putting\\n\\t\\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\\n\\t\\t * a \\\"work around\\\" we provide this option. It will append its value to the\\n\\t\\t * text that is found to be the longest string for the column - i.e. padding.\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sContentPadding\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows a default value to be given for a column's data, and will be used\\n\\t\\t * whenever a null data source is encountered (this can be because mData\\n\\t\\t * is set to null, or because the data source itself is null).\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sDefaultContent\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Name for the column, allowing reference to the column by name as well as\\n\\t\\t * by index (needs a lookup to work by name).\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sName\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Custom sorting data type - defines which of the available plug-ins in\\n\\t\\t * afnSortData the custom sorting will use - if any is defined.\\n\\t\\t * @type string\\n\\t\\t * @default std\\n\\t\\t */\\n\\t\\t\\\"sSortDataType\\\": 'std',\\n\\t\\n\\t\\t/**\\n\\t\\t * Class to be applied to the header element when sorting on this column\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sSortingClass\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Class to be applied to the header element when sorting on this column -\\n\\t\\t * when jQuery UI theming is used.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sSortingClassJUI\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Title of the column - what is seen in the TH element (nTh).\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sTitle\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Column sorting and filtering type\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sType\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Width of the column\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sWidth\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Width of the column when it was first \\\"encountered\\\"\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sWidthOrig\\\": null\\n\\t};\\n\\t\\n\\t\\n\\t/*\\n\\t * Developer note: The properties of the object below are given in Hungarian\\n\\t * notation, that was used as the interface for DataTables prior to v1.10, however\\n\\t * from v1.10 onwards the primary interface is camel case. In order to avoid\\n\\t * breaking backwards compatibility utterly with this change, the Hungarian\\n\\t * version is still, internally the primary interface, but is is not documented\\n\\t * - hence the @name tags in each doc comment. This allows a Javascript function\\n\\t * to create a map from Hungarian notation to camel case (going the other direction\\n\\t * would require each property to be listed, which would at around 3K to the size\\n\\t * of DataTables, while this method is about a 0.5K hit.\\n\\t *\\n\\t * Ultimately this does pave the way for Hungarian notation to be dropped\\n\\t * completely, but that is a massive amount of work and will break current\\n\\t * installs (therefore is on-hold until v2).\\n\\t */\\n\\t\\n\\t/**\\n\\t * Initialisation options that can be given to DataTables at initialisation\\n\\t * time.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.defaults = {\\n\\t\\t/**\\n\\t\\t * An array of data to use for the table, passed in at initialisation which\\n\\t\\t * will be used in preference to any data which is already in the DOM. This is\\n\\t\\t * particularly useful for constructing tables purely in Javascript, for\\n\\t\\t * example with a custom Ajax call.\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.data\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using a 2D array data source\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"data\\\": [\\n\\t\\t * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\\n\\t\\t * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\\n\\t\\t * ],\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"title\\\": \\\"Engine\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Browser\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Platform\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Version\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using an array of objects as a data source (`data`)\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"data\\\": [\\n\\t\\t * {\\n\\t\\t * \\\"engine\\\": \\\"Trident\\\",\\n\\t\\t * \\\"browser\\\": \\\"Internet Explorer 4.0\\\",\\n\\t\\t * \\\"platform\\\": \\\"Win 95+\\\",\\n\\t\\t * \\\"version\\\": 4,\\n\\t\\t * \\\"grade\\\": \\\"X\\\"\\n\\t\\t * },\\n\\t\\t * {\\n\\t\\t * \\\"engine\\\": \\\"Trident\\\",\\n\\t\\t * \\\"browser\\\": \\\"Internet Explorer 5.0\\\",\\n\\t\\t * \\\"platform\\\": \\\"Win 95+\\\",\\n\\t\\t * \\\"version\\\": 5,\\n\\t\\t * \\\"grade\\\": \\\"C\\\"\\n\\t\\t * }\\n\\t\\t * ],\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"title\\\": \\\"Engine\\\", \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Browser\\\", \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Platform\\\", \\\"data\\\": \\\"platform\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Version\\\", \\\"data\\\": \\\"version\\\" },\\n\\t\\t * { \\\"title\\\": \\\"Grade\\\", \\\"data\\\": \\\"grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aaData\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * If ordering is enabled, then DataTables will perform a first pass sort on\\n\\t\\t * initialisation. You can define which column(s) the sort is performed\\n\\t\\t * upon, and the sorting direction, with this variable. The `sorting` array\\n\\t\\t * should contain an array for each column to be sorted initially containing\\n\\t\\t * the column's index and a direction string ('asc' or 'desc').\\n\\t\\t * @type array\\n\\t\\t * @default [[0,'asc']]\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.order\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Sort by 3rd column first, and then 4th column\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"order\\\": [[2,'asc'], [3,'desc']]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * // No initial sorting\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"order\\\": []\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aaSorting\\\": [[0,'asc']],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter is basically identical to the `sorting` parameter, but\\n\\t\\t * cannot be overridden by user interaction with the table. What this means\\n\\t\\t * is that you could have a column (visible or hidden) which the sorting\\n\\t\\t * will always be forced on first - any sorting after that (from the user)\\n\\t\\t * will then be performed as required. This can be useful for grouping rows\\n\\t\\t * together.\\n\\t\\t * @type array\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.orderFixed\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderFixed\\\": [[0,'asc']]\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"aaSortingFixed\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables can be instructed to load data to display in the table from a\\n\\t\\t * Ajax source. This option defines how that Ajax call is made and where to.\\n\\t\\t *\\n\\t\\t * The `ajax` property has three different modes of operation, depending on\\n\\t\\t * how it is defined. These are:\\n\\t\\t *\\n\\t\\t * * `string` - Set the URL from where the data should be loaded from.\\n\\t\\t * * `object` - Define properties for `jQuery.ajax`.\\n\\t\\t * * `function` - Custom data get function\\n\\t\\t *\\n\\t\\t * `string`\\n\\t\\t * --------\\n\\t\\t *\\n\\t\\t * As a string, the `ajax` property simply defines the URL from which\\n\\t\\t * DataTables will load data.\\n\\t\\t *\\n\\t\\t * `object`\\n\\t\\t * --------\\n\\t\\t *\\n\\t\\t * As an object, the parameters in the object are passed to\\n\\t\\t * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control\\n\\t\\t * of the Ajax request. DataTables has a number of default parameters which\\n\\t\\t * you can override using this option. Please refer to the jQuery\\n\\t\\t * documentation for a full description of the options available, although\\n\\t\\t * the following parameters provide additional options in DataTables or\\n\\t\\t * require special consideration:\\n\\t\\t *\\n\\t\\t * * `data` - As with jQuery, `data` can be provided as an object, but it\\n\\t\\t * can also be used as a function to manipulate the data DataTables sends\\n\\t\\t * to the server. The function takes a single parameter, an object of\\n\\t\\t * parameters with the values that DataTables has readied for sending. An\\n\\t\\t * object may be returned which will be merged into the DataTables\\n\\t\\t * defaults, or you can add the items to the object that was passed in and\\n\\t\\t * not return anything from the function. This supersedes `fnServerParams`\\n\\t\\t * from DataTables 1.9-.\\n\\t\\t *\\n\\t\\t * * `dataSrc` - By default DataTables will look for the property `data` (or\\n\\t\\t * `aaData` for compatibility with DataTables 1.9-) when obtaining data\\n\\t\\t * from an Ajax source or for server-side processing - this parameter\\n\\t\\t * allows that property to be changed. You can use Javascript dotted\\n\\t\\t * object notation to get a data source for multiple levels of nesting, or\\n\\t\\t * it my be used as a function. As a function it takes a single parameter,\\n\\t\\t * the JSON returned from the server, which can be manipulated as\\n\\t\\t * required, with the returned value being that used by DataTables as the\\n\\t\\t * data source for the table. This supersedes `sAjaxDataProp` from\\n\\t\\t * DataTables 1.9-.\\n\\t\\t *\\n\\t\\t * * `success` - Should not be overridden it is used internally in\\n\\t\\t * DataTables. To manipulate / transform the data returned by the server\\n\\t\\t * use `ajax.dataSrc`, or use `ajax` as a function (see below).\\n\\t\\t *\\n\\t\\t * `function`\\n\\t\\t * ----------\\n\\t\\t *\\n\\t\\t * As a function, making the Ajax call is left up to yourself allowing\\n\\t\\t * complete control of the Ajax request. Indeed, if desired, a method other\\n\\t\\t * than Ajax could be used to obtain the required data, such as Web storage\\n\\t\\t * or an AIR database.\\n\\t\\t *\\n\\t\\t * The function is given four parameters and no return is required. The\\n\\t\\t * parameters are:\\n\\t\\t *\\n\\t\\t * 1. _object_ - Data to send to the server\\n\\t\\t * 2. _function_ - Callback function that must be executed when the required\\n\\t\\t * data has been obtained. That data should be passed into the callback\\n\\t\\t * as the only parameter\\n\\t\\t * 3. _object_ - DataTables settings object for the table\\n\\t\\t *\\n\\t\\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\\n\\t\\t *\\n\\t\\t * @type string|object|function\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.ajax\\n\\t\\t * @since 1.10.0\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get JSON data from a file via Ajax.\\n\\t\\t * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": \\\"data.json\\\"\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get JSON data from a file via Ajax, using `dataSrc` to change\\n\\t\\t * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"dataSrc\\\": \\\"tableData\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get JSON data from a file via Ajax, using `dataSrc` to read data\\n\\t\\t * // from a plain array rather than an array in an object\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"dataSrc\\\": \\\"\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Manipulate the data returned from the server - add a link to data\\n\\t\\t * // (note this can, should, be done using `render` for the column - this\\n\\t\\t * // is just a simple example of how the data can be manipulated).\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"dataSrc\\\": function ( json ) {\\n\\t\\t * for ( var i=0, ien=json.length ; i<ien ; i++ ) {\\n\\t\\t * json[i][0] = '<a href=\\\"/message/'+json[i][0]+'>View message</a>';\\n\\t\\t * }\\n\\t\\t * return json;\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Add data to the request\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"data\\\": function ( d ) {\\n\\t\\t * return {\\n\\t\\t * \\\"extra_search\\\": $('#extra').val()\\n\\t\\t * };\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Send request as POST\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": {\\n\\t\\t * \\\"url\\\": \\\"data.json\\\",\\n\\t\\t * \\\"type\\\": \\\"POST\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Get the data from localStorage (could interface with a form for\\n\\t\\t * // adding, editing and removing rows).\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": function (data, callback, settings) {\\n\\t\\t * callback(\\n\\t\\t * JSON.parse( localStorage.getItem('dataTablesData') )\\n\\t\\t * );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"ajax\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter allows you to readily specify the entries in the length drop\\n\\t\\t * down menu that DataTables shows when pagination is enabled. It can be\\n\\t\\t * either a 1D array of options which will be used for both the displayed\\n\\t\\t * option and the value, or a 2D array which will use the array in the first\\n\\t\\t * position as the value, and the array in the second position as the\\n\\t\\t * displayed options (useful for language strings such as 'All').\\n\\t\\t *\\n\\t\\t * Note that the `pageLength` property will be automatically set to the\\n\\t\\t * first value given in this array, unless `pageLength` is also provided.\\n\\t\\t * @type array\\n\\t\\t * @default [ 10, 25, 50, 100 ]\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.lengthMenu\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"lengthMenu\\\": [[10, 25, 50, -1], [10, 25, 50, \\\"All\\\"]]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aLengthMenu\\\": [ 10, 25, 50, 100 ],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The `columns` option in the initialisation parameter allows you to define\\n\\t\\t * details about the way individual columns behave. For a full list of\\n\\t\\t * column options that can be set, please see\\n\\t\\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\\n\\t\\t * define your columns, you must have an entry in the array for every single\\n\\t\\t * column that you have in your table (these can be null if you don't which\\n\\t\\t * to specify any options).\\n\\t\\t * @member\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column\\n\\t\\t */\\n\\t\\t\\\"aoColumns\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Very similar to `columns`, `columnDefs` allows you to target a specific\\n\\t\\t * column, multiple columns, or all columns, using the `targets` property of\\n\\t\\t * each object in the array. This allows great flexibility when creating\\n\\t\\t * tables, as the `columnDefs` arrays can be of any length, targeting the\\n\\t\\t * columns you specifically want. `columnDefs` may use any of the column\\n\\t\\t * options available: {@link DataTable.defaults.column}, but it _must_\\n\\t\\t * have `targets` defined in each object in the array. Values in the `targets`\\n\\t\\t * array may be:\\n\\t\\t * <ul>\\n\\t\\t * <li>a string - class name will be matched on the TH for the column</li>\\n\\t\\t * <li>0 or a positive integer - column index counting from the left</li>\\n\\t\\t * <li>a negative integer - column index counting from the right</li>\\n\\t\\t * <li>the string \\\"_all\\\" - all columns (i.e. assign a default)</li>\\n\\t\\t * </ul>\\n\\t\\t * @member\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.columnDefs\\n\\t\\t */\\n\\t\\t\\\"aoColumnDefs\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Basically the same as `search`, this parameter defines the individual column\\n\\t\\t * filtering state at initialisation time. The array must be of the same size\\n\\t\\t * as the number of columns, and each element be an object with the parameters\\n\\t\\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\\n\\t\\t * accepted and the default will be used.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.searchCols\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"searchCols\\\": [\\n\\t\\t * null,\\n\\t\\t * { \\\"search\\\": \\\"My filter\\\" },\\n\\t\\t * null,\\n\\t\\t * { \\\"search\\\": \\\"^[0-9]\\\", \\\"escapeRegex\\\": false }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"aoSearchCols\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * An array of CSS classes that should be applied to displayed rows. This\\n\\t\\t * array may be of any length, and DataTables will apply each class\\n\\t\\t * sequentially, looping when required.\\n\\t\\t * @type array\\n\\t\\t * @default null <i>Will take the values determined by the `oClasses.stripe*`\\n\\t\\t * options</i>\\n\\t\\t *\\n\\t\\t * @dtopt Option\\n\\t\\t * @name DataTable.defaults.stripeClasses\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stripeClasses\\\": [ 'strip1', 'strip2', 'strip3' ]\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"asStripeClasses\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable automatic column width calculation. This can be disabled\\n\\t\\t * as an optimisation (it takes some time to calculate the widths) if the\\n\\t\\t * tables widths are passed in using `columns`.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.autoWidth\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"autoWidth\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bAutoWidth\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Deferred rendering can provide DataTables with a huge speed boost when you\\n\\t\\t * are using an Ajax or JS data source for the table. This option, when set to\\n\\t\\t * true, will cause DataTables to defer the creation of the table elements for\\n\\t\\t * each row until they are needed for a draw - saving a significant amount of\\n\\t\\t * time.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.deferRender\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajax\\\": \\\"sources/arrays.txt\\\",\\n\\t\\t * \\\"deferRender\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bDeferRender\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Replace a DataTable which matches the given selector and replace it with\\n\\t\\t * one which has the properties of the new initialisation object passed. If no\\n\\t\\t * table matches the selector, then the new DataTable will be constructed as\\n\\t\\t * per normal.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.destroy\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"srollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"paginate\\\": false\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * // Some time later....\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"filter\\\": false,\\n\\t\\t * \\\"destroy\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bDestroy\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable filtering of data. Filtering in DataTables is \\\"smart\\\" in\\n\\t\\t * that it allows the end user to input multiple words (space separated) and\\n\\t\\t * will match a row containing those words, even if not in the order that was\\n\\t\\t * specified (this allow matching across multiple columns). Note that if you\\n\\t\\t * wish to use filtering in DataTables this must remain 'true' - to remove the\\n\\t\\t * default filtering input box and retain filtering abilities, please use\\n\\t\\t * {@link DataTable.defaults.dom}.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.searching\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"searching\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bFilter\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the table information display. This shows information\\n\\t\\t * about the data that is currently visible on the page, including information\\n\\t\\t * about filtered data if that action is being performed.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.info\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"info\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bInfo\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows the end user to select the size of a formatted page from a select\\n\\t\\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.lengthChange\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"lengthChange\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bLengthChange\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable pagination.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.paging\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"paging\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bPaginate\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the display of a 'processing' indicator when the table is\\n\\t\\t * being processed (e.g. a sort). This is particularly useful for tables with\\n\\t\\t * large amounts of data where it can take a noticeable amount of time to sort\\n\\t\\t * the entries.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.processing\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"processing\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bProcessing\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Retrieve the DataTables object for the given selector. Note that if the\\n\\t\\t * table has already been initialised, this parameter will cause DataTables\\n\\t\\t * to simply return the object that has already been set up - it will not take\\n\\t\\t * account of any changes you might have made to the initialisation object\\n\\t\\t * passed to DataTables (setting this parameter to true is an acknowledgement\\n\\t\\t * that you understand this). `destroy` can be used to reinitialise a table if\\n\\t\\t * you need.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.retrieve\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * initTable();\\n\\t\\t * tableActions();\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * function initTable ()\\n\\t\\t * {\\n\\t\\t * return $('#example').dataTable( {\\n\\t\\t * \\\"scrollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"paginate\\\": false,\\n\\t\\t * \\\"retrieve\\\": true\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t *\\n\\t\\t * function tableActions ()\\n\\t\\t * {\\n\\t\\t * var table = initTable();\\n\\t\\t * // perform API operations with oTable\\n\\t\\t * }\\n\\t\\t */\\n\\t\\t\\\"bRetrieve\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * When vertical (y) scrolling is enabled, DataTables will force the height of\\n\\t\\t * the table's viewport to the given height at all times (useful for layout).\\n\\t\\t * However, this can look odd when filtering data down to a small data set,\\n\\t\\t * and the footer is left \\\"floating\\\" further down. This parameter (when\\n\\t\\t * enabled) will cause DataTables to collapse the table's viewport down when\\n\\t\\t * the result set will fit within the given Y height.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.scrollCollapse\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollY\\\": \\\"200\\\",\\n\\t\\t * \\\"scrollCollapse\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bScrollCollapse\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Configure DataTables to use server-side processing. Note that the\\n\\t\\t * `ajax` parameter must also be given in order to give DataTables a\\n\\t\\t * source to obtain the required data for each draw.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverSide\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"serverSide\\\": true,\\n\\t\\t * \\\"ajax\\\": \\\"xhr.php\\\"\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bServerSide\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable sorting of columns. Sorting of individual columns can be\\n\\t\\t * disabled by the `sortable` option for each column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.ordering\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ordering\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSort\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or display DataTables' ability to sort multiple columns at the\\n\\t\\t * same time (activated by shift-click by the user).\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.orderMulti\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Disable multiple column sorting ability\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderMulti\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortMulti\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows control over whether DataTables should use the top (true) unique\\n\\t\\t * cell that is found for a single column, or the bottom (false - default).\\n\\t\\t * This is useful when using complex headers.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.orderCellsTop\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderCellsTop\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortCellsTop\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the addition of the classes `sorting\\\\_1`, `sorting\\\\_2` and\\n\\t\\t * `sorting\\\\_3` to the columns which are currently being sorted on. This is\\n\\t\\t * presented as a feature switch as it can increase processing time (while\\n\\t\\t * classes are removed and added) so for large data sets you might want to\\n\\t\\t * turn this off.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.orderClasses\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"orderClasses\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortClasses\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\\n\\t\\t * used to save table display information such as pagination information,\\n\\t\\t * display length, filtering and sorting. As such when the end user reloads\\n\\t\\t * the page the display display will match what thy had previously set up.\\n\\t\\t *\\n\\t\\t * Due to the use of `localStorage` the default state saving is not supported\\n\\t\\t * in IE6 or 7. If state saving is required in those browsers, use\\n\\t\\t * `stateSaveCallback` to provide a storage solution such as cookies.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.stateSave\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function () {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bStateSave\\\": false,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function is called when a TR element is created (and all TD child\\n\\t\\t * elements have been inserted), or registered if using a DOM source, allowing\\n\\t\\t * manipulation of the TR element (adding classes etc).\\n\\t\\t * @type function\\n\\t\\t * @param {node} row \\\"TR\\\" element for the current row\\n\\t\\t * @param {array} data Raw data array for this row\\n\\t\\t * @param {int} dataIndex The index of this row in the internal aoData array\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.createdRow\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"createdRow\\\": function( row, data, dataIndex ) {\\n\\t\\t * // Bold the grade for all 'A' grade browsers\\n\\t\\t * if ( data[4] == \\\"A\\\" )\\n\\t\\t * {\\n\\t\\t * $('td:eq(4)', row).html( '<b>A</b>' );\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnCreatedRow\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function is called on every 'draw' event, and allows you to\\n\\t\\t * dynamically modify any aspect you want about the created DOM.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.drawCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"drawCallback\\\": function( settings ) {\\n\\t\\t * alert( 'DataTables has redrawn the table' );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnDrawCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Identical to fnHeaderCallback() but for the table footer this function\\n\\t\\t * allows you to modify the table footer on every 'draw' event.\\n\\t\\t * @type function\\n\\t\\t * @param {node} foot \\\"TR\\\" element for the footer\\n\\t\\t * @param {array} data Full table data (as derived from the original HTML)\\n\\t\\t * @param {int} start Index for the current display starting point in the\\n\\t\\t * display array\\n\\t\\t * @param {int} end Index for the current display ending point in the\\n\\t\\t * display array\\n\\t\\t * @param {array int} display Index array to translate the visual position\\n\\t\\t * to the full data array\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.footerCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"footerCallback\\\": function( tfoot, data, start, end, display ) {\\n\\t\\t * tfoot.getElementsByTagName('th')[0].innerHTML = \\\"Starting index is \\\"+start;\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"fnFooterCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * When rendering large numbers in the information element for the table\\n\\t\\t * (i.e. \\\"Showing 1 to 10 of 57 entries\\\") DataTables will render large numbers\\n\\t\\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\\n\\t\\t * rendered as \\\"1,000,000\\\") to help readability for the end user. This\\n\\t\\t * function will override the default method DataTables uses.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {int} toFormat number to be formatted\\n\\t\\t * @returns {string} formatted string for DataTables to show the number\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.formatNumber\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Format a number using a single quote for the separator (note that\\n\\t\\t * // this can also be done with the language.thousands option)\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"formatNumber\\\": function ( toFormat ) {\\n\\t\\t * return toFormat.toString().replace(\\n\\t\\t * /\\\\B(?=(\\\\d{3})+(?!\\\\d))/g, \\\"'\\\"\\n\\t\\t * );\\n\\t\\t * };\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnFormatNumber\\\": function ( toFormat ) {\\n\\t\\t\\treturn toFormat.toString().replace(\\n\\t\\t\\t\\t/\\\\B(?=(\\\\d{3})+(?!\\\\d))/g,\\n\\t\\t\\t\\tthis.oLanguage.sThousands\\n\\t\\t\\t);\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function is called on every 'draw' event, and allows you to\\n\\t\\t * dynamically modify the header row. This can be used to calculate and\\n\\t\\t * display useful information about the table.\\n\\t\\t * @type function\\n\\t\\t * @param {node} head \\\"TR\\\" element for the header\\n\\t\\t * @param {array} data Full table data (as derived from the original HTML)\\n\\t\\t * @param {int} start Index for the current display starting point in the\\n\\t\\t * display array\\n\\t\\t * @param {int} end Index for the current display ending point in the\\n\\t\\t * display array\\n\\t\\t * @param {array int} display Index array to translate the visual position\\n\\t\\t * to the full data array\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.headerCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"fheaderCallback\\\": function( head, data, start, end, display ) {\\n\\t\\t * head.getElementsByTagName('th')[0].innerHTML = \\\"Displaying \\\"+(end-start)+\\\" records\\\";\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"fnHeaderCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The information element can be used to convey information about the current\\n\\t\\t * state of the table. Although the internationalisation options presented by\\n\\t\\t * DataTables are quite capable of dealing with most customisations, there may\\n\\t\\t * be times where you wish to customise the string further. This callback\\n\\t\\t * allows you to do exactly that.\\n\\t\\t * @type function\\n\\t\\t * @param {object} oSettings DataTables settings object\\n\\t\\t * @param {int} start Starting position in data for the draw\\n\\t\\t * @param {int} end End position in data for the draw\\n\\t\\t * @param {int} max Total number of rows in the table (regardless of\\n\\t\\t * filtering)\\n\\t\\t * @param {int} total Total number of rows in the data set, after filtering\\n\\t\\t * @param {string} pre The string that DataTables has formatted using it's\\n\\t\\t * own rules\\n\\t\\t * @returns {string} The string to be displayed in the information element.\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.infoCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"infoCallback\\\": function( settings, start, end, max, total, pre ) {\\n\\t\\t * return start +\\\" to \\\"+ end;\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnInfoCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Called when the table has been initialised. Normally DataTables will\\n\\t\\t * initialise sequentially and there will be no need for this function,\\n\\t\\t * however, this does not hold true when using external language information\\n\\t\\t * since that is obtained using an async XHR call.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} json The JSON object request from the server - only\\n\\t\\t * present if client-side Ajax sourced data is used\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.initComplete\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"initComplete\\\": function(settings, json) {\\n\\t\\t * alert( 'DataTables has finished its initialisation.' );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"fnInitComplete\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Called at the very start of each table draw and can be used to cancel the\\n\\t\\t * draw by returning false, any other return (including undefined) results in\\n\\t\\t * the full draw occurring).\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @returns {boolean} False will cancel the draw, anything else (including no\\n\\t\\t * return) will allow it to complete.\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.preDrawCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"preDrawCallback\\\": function( settings ) {\\n\\t\\t * if ( $('#test').val() == 1 ) {\\n\\t\\t * return false;\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnPreDrawCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This function allows you to 'post process' each row after it have been\\n\\t\\t * generated for each table draw, but before it is rendered on screen. This\\n\\t\\t * function might be used for setting the row class name etc.\\n\\t\\t * @type function\\n\\t\\t * @param {node} row \\\"TR\\\" element for the current row\\n\\t\\t * @param {array} data Raw data array for this row\\n\\t\\t * @param {int} displayIndex The display index for the current table draw\\n\\t\\t * @param {int} displayIndexFull The index of the data in the full list of\\n\\t\\t * rows (after filtering)\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.rowCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"rowCallback\\\": function( row, data, displayIndex, displayIndexFull ) {\\n\\t\\t * // Bold the grade for all 'A' grade browsers\\n\\t\\t * if ( data[4] == \\\"A\\\" ) {\\n\\t\\t * $('td:eq(4)', row).html( '<b>A</b>' );\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnRowCallback\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * This parameter allows you to override the default function which obtains\\n\\t\\t * the data from the server so something more suitable for your application.\\n\\t\\t * For example you could use POST data, or pull information from a Gears or\\n\\t\\t * AIR database.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {string} source HTTP source to obtain the data from (`ajax`)\\n\\t\\t * @param {array} data A key/value pair object containing the data to send\\n\\t\\t * to the server\\n\\t\\t * @param {function} callback to be called on completion of the data get\\n\\t\\t * process that will draw the data on the page.\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverData\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"fnServerData\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * It is often useful to send extra data to the server when making an Ajax\\n\\t\\t * request - for example custom filtering information, and this callback\\n\\t\\t * function makes it trivial to send extra information to the server. The\\n\\t\\t * passed in parameter is the data set that has been constructed by\\n\\t\\t * DataTables, and you can add to this or modify it as you require.\\n\\t\\t * @type function\\n\\t\\t * @param {array} data Data array (array of objects which are name/value\\n\\t\\t * pairs) that has been constructed by DataTables and will be sent to the\\n\\t\\t * server. In the case of Ajax sourced data with server-side processing\\n\\t\\t * this will be an empty array, for server-side processing there will be a\\n\\t\\t * significant number of parameters!\\n\\t\\t * @returns {undefined} Ensure that you modify the data array passed in,\\n\\t\\t * as this is passed by reference.\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverParams\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"fnServerParams\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Load the table state. With this function you can define from where, and how, the\\n\\t\\t * state of a table is loaded. By default DataTables will load from `localStorage`\\n\\t\\t * but you might wish to use a server-side database or cookies.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} callback Callback that can be executed when done. It\\n\\t\\t * should be passed the loaded state object.\\n\\t\\t * @return {object} The DataTables state object to be loaded\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateLoadCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoadCallback\\\": function (settings, callback) {\\n\\t\\t * $.ajax( {\\n\\t\\t * \\\"url\\\": \\\"/state_load\\\",\\n\\t\\t * \\\"dataType\\\": \\\"json\\\",\\n\\t\\t * \\\"success\\\": function (json) {\\n\\t\\t * callback( json );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateLoadCallback\\\": function ( settings ) {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\treturn JSON.parse(\\n\\t\\t\\t\\t\\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\\n\\t\\t\\t\\t\\t\\t'DataTables_'+settings.sInstance+'_'+location.pathname\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t);\\n\\t\\t\\t} catch (e) {}\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback which allows modification of the saved state prior to loading that state.\\n\\t\\t * This callback is called when the table is loading state from the stored data, but\\n\\t\\t * prior to the settings object being modified by the saved state. Note that for\\n\\t\\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\\n\\t\\t * a plug-in.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object that is to be loaded\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateLoadParams\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Remove a saved filter, so filtering is never loaded\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoadParams\\\": function (settings, data) {\\n\\t\\t * data.oSearch.sSearch = \\\"\\\";\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Disallow state loading by returning false\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoadParams\\\": function (settings, data) {\\n\\t\\t * return false;\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateLoadParams\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback that is called when the state has been loaded from the state saving method\\n\\t\\t * and the DataTables settings object has been modified as a result of the loaded state.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object that was loaded\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateLoaded\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Show an alert with the filtering value that was saved\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateLoaded\\\": function (settings, data) {\\n\\t\\t * alert( 'Saved filter was: '+data.oSearch.sSearch );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateLoaded\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Save the table state. This function allows you to define where and how the state\\n\\t\\t * information for the table is stored By default DataTables will use `localStorage`\\n\\t\\t * but you might wish to use a server-side database or cookies.\\n\\t\\t * @type function\\n\\t\\t * @member\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object to be saved\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateSaveCallback\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateSaveCallback\\\": function (settings, data) {\\n\\t\\t * // Send an Ajax request to the server with the state object\\n\\t\\t * $.ajax( {\\n\\t\\t * \\\"url\\\": \\\"/state_save\\\",\\n\\t\\t * \\\"data\\\": data,\\n\\t\\t * \\\"dataType\\\": \\\"json\\\",\\n\\t\\t * \\\"method\\\": \\\"POST\\\"\\n\\t\\t * \\\"success\\\": function () {}\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateSaveCallback\\\": function ( settings, data ) {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\\n\\t\\t\\t\\t\\t'DataTables_'+settings.sInstance+'_'+location.pathname,\\n\\t\\t\\t\\t\\tJSON.stringify( data )\\n\\t\\t\\t\\t);\\n\\t\\t\\t} catch (e) {}\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback which allows modification of the state to be saved. Called when the table\\n\\t\\t * has changed state a new state save is required. This method allows modification of\\n\\t\\t * the state saving object prior to actually doing the save, including addition or\\n\\t\\t * other state properties or modification. Note that for plug-in authors, you should\\n\\t\\t * use the `stateSaveParams` event to save parameters for a plug-in.\\n\\t\\t * @type function\\n\\t\\t * @param {object} settings DataTables settings object\\n\\t\\t * @param {object} data The state object to be saved\\n\\t\\t *\\n\\t\\t * @dtopt Callbacks\\n\\t\\t * @name DataTable.defaults.stateSaveParams\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Remove a saved filter, so filtering is never saved\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateSave\\\": true,\\n\\t\\t * \\\"stateSaveParams\\\": function (settings, data) {\\n\\t\\t * data.oSearch.sSearch = \\\"\\\";\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnStateSaveParams\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Duration for which the saved state information is considered valid. After this period\\n\\t\\t * has elapsed the state will be returned to the default.\\n\\t\\t * Value is given in seconds.\\n\\t\\t * @type int\\n\\t\\t * @default 7200 <i>(2 hours)</i>\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.stateDuration\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"stateDuration\\\": 60*60*24; // 1 day\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"iStateDuration\\\": 7200,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * When enabled DataTables will not make a request to the server for the first\\n\\t\\t * page draw - rather it will use the data already on the page (no sorting etc\\n\\t\\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\\n\\t\\t * is used to indicate that deferred loading is required, but it is also used\\n\\t\\t * to tell DataTables how many records there are in the full table (allowing\\n\\t\\t * the information element and pagination to be displayed correctly). In the case\\n\\t\\t * where a filtering is applied to the table on initial load, this can be\\n\\t\\t * indicated by giving the parameter as an array, where the first element is\\n\\t\\t * the number of records available after filtering and the second element is the\\n\\t\\t * number of records without filtering (allowing the table information element\\n\\t\\t * to be shown correctly).\\n\\t\\t * @type int | array\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.deferLoading\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // 57 records available in the table, no filtering applied\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"serverSide\\\": true,\\n\\t\\t * \\\"ajax\\\": \\\"scripts/server_processing.php\\\",\\n\\t\\t * \\\"deferLoading\\\": 57\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // 57 records after filtering, 100 without filtering (an initial filter applied)\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"serverSide\\\": true,\\n\\t\\t * \\\"ajax\\\": \\\"scripts/server_processing.php\\\",\\n\\t\\t * \\\"deferLoading\\\": [ 57, 100 ],\\n\\t\\t * \\\"search\\\": {\\n\\t\\t * \\\"search\\\": \\\"my_filter\\\"\\n\\t\\t * }\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"iDeferLoading\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Number of rows to display on a single page when using pagination. If\\n\\t\\t * feature enabled (`lengthChange`) then the end user will be able to override\\n\\t\\t * this to a custom setting using a pop-up menu.\\n\\t\\t * @type int\\n\\t\\t * @default 10\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.pageLength\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"pageLength\\\": 50\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"iDisplayLength\\\": 10,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Define the starting point for data display when using DataTables with\\n\\t\\t * pagination. Note that this parameter is the number of records, rather than\\n\\t\\t * the page number, so if you have 10 records per page and want to start on\\n\\t\\t * the third page, it should be \\\"20\\\".\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.displayStart\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"displayStart\\\": 20\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"iDisplayStart\\\": 0,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\\n\\t\\t * and filtering) by adding a `tabindex` attribute to the required elements. This\\n\\t\\t * allows you to tab through the controls and press the enter key to activate them.\\n\\t\\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\\n\\t\\t * You can overrule this using this parameter if you wish. Use a value of -1 to\\n\\t\\t * disable built-in keyboard navigation.\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.tabIndex\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"tabIndex\\\": 1\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"iTabIndex\\\": 0,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Classes that DataTables assigns to the various components and features\\n\\t\\t * that it adds to the HTML table. This allows classes to be configured\\n\\t\\t * during initialisation in addition to through the static\\n\\t\\t * {@link DataTable.ext.oStdClasses} object).\\n\\t\\t * @namespace\\n\\t\\t * @name DataTable.defaults.classes\\n\\t\\t */\\n\\t\\t\\\"oClasses\\\": {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * All strings that DataTables uses in the user interface that it creates\\n\\t\\t * are defined in this object, allowing you to modified them individually or\\n\\t\\t * completely replace them all as required.\\n\\t\\t * @namespace\\n\\t\\t * @name DataTable.defaults.language\\n\\t\\t */\\n\\t\\t\\\"oLanguage\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * Strings that are used for WAI-ARIA labels and controls only (these are not\\n\\t\\t\\t * actually visible on the page, but will be read by screenreaders, and thus\\n\\t\\t\\t * must be internationalised as well).\\n\\t\\t\\t * @namespace\\n\\t\\t\\t * @name DataTable.defaults.language.aria\\n\\t\\t\\t */\\n\\t\\t\\t\\\"oAria\\\": {\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * ARIA label that is added to the table headers when the column may be\\n\\t\\t\\t\\t * sorted ascending by activing the column (click or return when focused).\\n\\t\\t\\t\\t * Note that the column header is prefixed to this string.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default : activate to sort column ascending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.aria.sortAscending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"aria\\\": {\\n\\t\\t\\t\\t * \\\"sortAscending\\\": \\\" - click/return to sort ascending\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sSortAscending\\\": \\\": activate to sort column ascending\\\",\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * ARIA label that is added to the table headers when the column may be\\n\\t\\t\\t\\t * sorted descending by activing the column (click or return when focused).\\n\\t\\t\\t\\t * Note that the column header is prefixed to this string.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default : activate to sort column ascending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.aria.sortDescending\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"aria\\\": {\\n\\t\\t\\t\\t * \\\"sortDescending\\\": \\\" - click/return to sort descending\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sSortDescending\\\": \\\": activate to sort column descending\\\"\\n\\t\\t\\t},\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Pagination string used by DataTables for the built-in pagination\\n\\t\\t\\t * control types.\\n\\t\\t\\t * @namespace\\n\\t\\t\\t * @name DataTable.defaults.language.paginate\\n\\t\\t\\t */\\n\\t\\t\\t\\\"oPaginate\\\": {\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use when using the 'full_numbers' type of pagination for the\\n\\t\\t\\t\\t * button to take the user to the first page.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default First\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.first\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"first\\\": \\\"First page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sFirst\\\": \\\"First\\\",\\n\\t\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use when using the 'full_numbers' type of pagination for the\\n\\t\\t\\t\\t * button to take the user to the last page.\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default Last\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.last\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"last\\\": \\\"Last page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sLast\\\": \\\"Last\\\",\\n\\t\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use for the 'next' pagination button (to take the user to the\\n\\t\\t\\t\\t * next page).\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default Next\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.next\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"next\\\": \\\"Next page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sNext\\\": \\\"Next\\\",\\n\\t\\n\\t\\n\\t\\t\\t\\t/**\\n\\t\\t\\t\\t * Text to use for the 'previous' pagination button (to take the user to\\n\\t\\t\\t\\t * the previous page).\\n\\t\\t\\t\\t * @type string\\n\\t\\t\\t\\t * @default Previous\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @dtopt Language\\n\\t\\t\\t\\t * @name DataTable.defaults.language.paginate.previous\\n\\t\\t\\t\\t *\\n\\t\\t\\t\\t * @example\\n\\t\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t\\t * \\\"paginate\\\": {\\n\\t\\t\\t\\t * \\\"previous\\\": \\\"Previous page\\\"\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * }\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t * } );\\n\\t\\t\\t\\t */\\n\\t\\t\\t\\t\\\"sPrevious\\\": \\\"Previous\\\"\\n\\t\\t\\t},\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * This string is shown in preference to `zeroRecords` when the table is\\n\\t\\t\\t * empty of data (regardless of filtering). Note that this is an optional\\n\\t\\t\\t * parameter - if it is not given, the value of `zeroRecords` will be used\\n\\t\\t\\t * instead (either the default or given value).\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default No data available in table\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.emptyTable\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"emptyTable\\\": \\\"No data available in table\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sEmptyTable\\\": \\\"No data available in table\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * This string gives information to the end user about the information\\n\\t\\t\\t * that is current on display on the page. The following tokens can be\\n\\t\\t\\t * used in the string and will be dynamically replaced as the table\\n\\t\\t\\t * display updates. This tokens can be placed anywhere in the string, or\\n\\t\\t\\t * removed as needed by the language requires:\\n\\t\\t\\t *\\n\\t\\t\\t * * `\\\\_START\\\\_` - Display index of the first record on the current page\\n\\t\\t\\t * * `\\\\_END\\\\_` - Display index of the last record on the current page\\n\\t\\t\\t * * `\\\\_TOTAL\\\\_` - Number of records in the table after filtering\\n\\t\\t\\t * * `\\\\_MAX\\\\_` - Number of records in the table without filtering\\n\\t\\t\\t * * `\\\\_PAGE\\\\_` - Current page number\\n\\t\\t\\t * * `\\\\_PAGES\\\\_` - Total number of pages of data in the table\\n\\t\\t\\t *\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Showing _START_ to _END_ of _TOTAL_ entries\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.info\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"info\\\": \\\"Showing page _PAGE_ of _PAGES_\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfo\\\": \\\"Showing _START_ to _END_ of _TOTAL_ entries\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Display information string for when the table is empty. Typically the\\n\\t\\t\\t * format of this string should match `info`.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Showing 0 to 0 of 0 entries\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.infoEmpty\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"infoEmpty\\\": \\\"No entries to show\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfoEmpty\\\": \\\"Showing 0 to 0 of 0 entries\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * When a user filters the information in a table, this string is appended\\n\\t\\t\\t * to the information (`info`) to give an idea of how strong the filtering\\n\\t\\t\\t * is. The variable _MAX_ is dynamically updated.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default (filtered from _MAX_ total entries)\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.infoFiltered\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"infoFiltered\\\": \\\" - filtering from _MAX_ records\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfoFiltered\\\": \\\"(filtered from _MAX_ total entries)\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * If can be useful to append extra information to the info string at times,\\n\\t\\t\\t * and this variable does exactly that. This information will be appended to\\n\\t\\t\\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\\n\\t\\t\\t * being used) at all times.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default <i>Empty string</i>\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.infoPostFix\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"infoPostFix\\\": \\\"All records shown are derived from real information.\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sInfoPostFix\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * This decimal place operator is a little different from the other\\n\\t\\t\\t * language options since DataTables doesn't output floating point\\n\\t\\t\\t * numbers, so it won't ever use this for display of a number. Rather,\\n\\t\\t\\t * what this parameter does is modify the sort methods of the table so\\n\\t\\t\\t * that numbers which are in a format which has a character other than\\n\\t\\t\\t * a period (`.`) as a decimal place will be sorted numerically.\\n\\t\\t\\t *\\n\\t\\t\\t * Note that numbers with different decimal places cannot be shown in\\n\\t\\t\\t * the same table and still be sortable, the table must be consistent.\\n\\t\\t\\t * However, multiple different tables on the page can use different\\n\\t\\t\\t * decimal place characters.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default \\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.decimal\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"decimal\\\": \\\",\\\"\\n\\t\\t\\t * \\\"thousands\\\": \\\".\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sDecimal\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * DataTables has a build in number formatter (`formatNumber`) which is\\n\\t\\t\\t * used to format large numbers that are used in the table information.\\n\\t\\t\\t * By default a comma is used, but this can be trivially changed to any\\n\\t\\t\\t * character you wish with this parameter.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default ,\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.thousands\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"thousands\\\": \\\"'\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sThousands\\\": \\\",\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Detail the action that will be taken when the drop down menu for the\\n\\t\\t\\t * pagination length option is changed. The '_MENU_' variable is replaced\\n\\t\\t\\t * with a default select list of 10, 25, 50 and 100, and can be replaced\\n\\t\\t\\t * with a custom select box if required.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Show _MENU_ entries\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.lengthMenu\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Language change only\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"lengthMenu\\\": \\\"Display _MENU_ records\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Language and options change\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"lengthMenu\\\": 'Display <select>'+\\n\\t\\t\\t * '<option value=\\\"10\\\">10</option>'+\\n\\t\\t\\t * '<option value=\\\"20\\\">20</option>'+\\n\\t\\t\\t * '<option value=\\\"30\\\">30</option>'+\\n\\t\\t\\t * '<option value=\\\"40\\\">40</option>'+\\n\\t\\t\\t * '<option value=\\\"50\\\">50</option>'+\\n\\t\\t\\t * '<option value=\\\"-1\\\">All</option>'+\\n\\t\\t\\t * '</select> records'\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sLengthMenu\\\": \\\"Show _MENU_ entries\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * When using Ajax sourced data and during the first draw when DataTables is\\n\\t\\t\\t * gathering the data, this message is shown in an empty row in the table to\\n\\t\\t\\t * indicate to the end user the the data is being loaded. Note that this\\n\\t\\t\\t * parameter is not used when loading data by server-side processing, just\\n\\t\\t\\t * Ajax sourced data with client-side processing.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Loading...\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.loadingRecords\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"loadingRecords\\\": \\\"Please wait - loading...\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sLoadingRecords\\\": \\\"Loading...\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Text which is displayed when the table is processing a user action\\n\\t\\t\\t * (usually a sort command or similar).\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Processing...\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.processing\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"processing\\\": \\\"DataTables is currently busy\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sProcessing\\\": \\\"Processing...\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Details the actions that will be taken when the user types into the\\n\\t\\t\\t * filtering input text box. The variable \\\"_INPUT_\\\", if used in the string,\\n\\t\\t\\t * is replaced with the HTML text box for the filtering input allowing\\n\\t\\t\\t * control over where it appears in the string. If \\\"_INPUT_\\\" is not given\\n\\t\\t\\t * then the input box is appended to the string automatically.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default Search:\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.search\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Input text box will be appended at the end automatically\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"search\\\": \\\"Filter records:\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Specify where the filter should appear\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"search\\\": \\\"Apply filter _INPUT_ to table\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sSearch\\\": \\\"Search:\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Assign a `placeholder` attribute to the search `input` element\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default \\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.searchPlaceholder\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sSearchPlaceholder\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * All of the language information can be stored in a file on the\\n\\t\\t\\t * server-side, which DataTables will look up if this parameter is passed.\\n\\t\\t\\t * It must store the URL of the language file, which is in a JSON format,\\n\\t\\t\\t * and the object has the same properties as the oLanguage object in the\\n\\t\\t\\t * initialiser object (i.e. the above parameters). Please refer to one of\\n\\t\\t\\t * the example language files to see how this works in action.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default <i>Empty string - i.e. disabled</i>\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.url\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"url\\\": \\\"http://www.sprymedia.co.uk/dataTables/lang.txt\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sUrl\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Text shown inside the table records when the is no information to be\\n\\t\\t\\t * displayed after filtering. `emptyTable` is shown when there is simply no\\n\\t\\t\\t * information in the table at all (regardless of filtering).\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @default No matching records found\\n\\t\\t\\t *\\n\\t\\t\\t * @dtopt Language\\n\\t\\t\\t * @name DataTable.defaults.language.zeroRecords\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $(document).ready( function() {\\n\\t\\t\\t * $('#example').dataTable( {\\n\\t\\t\\t * \\\"language\\\": {\\n\\t\\t\\t * \\\"zeroRecords\\\": \\\"No records to display\\\"\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sZeroRecords\\\": \\\"No matching records found\\\"\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter allows you to have define the global filtering state at\\n\\t\\t * initialisation time. As an object the `search` parameter must be\\n\\t\\t * defined, but all other parameters are optional. When `regex` is true,\\n\\t\\t * the search string will be treated as a regular expression, when false\\n\\t\\t * (default) it will be treated as a straight string. When `smart`\\n\\t\\t * DataTables will use it's smart filtering methods (to word match at\\n\\t\\t * any point in the data), when false this will not be done.\\n\\t\\t * @namespace\\n\\t\\t * @extends DataTable.models.oSearch\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.search\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"search\\\": {\\\"search\\\": \\\"Initial search\\\"}\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"oSearch\\\": $.extend( {}, DataTable.models.oSearch ),\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * By default DataTables will look for the property `data` (or `aaData` for\\n\\t\\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\\n\\t\\t * source or for server-side processing - this parameter allows that\\n\\t\\t * property to be changed. You can use Javascript dotted object notation to\\n\\t\\t * get a data source for multiple levels of nesting.\\n\\t\\t * @type string\\n\\t\\t * @default data\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.ajaxDataProp\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"sAjaxDataProp\\\": \\\"data\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * You can instruct DataTables to load data from an external\\n\\t\\t * source using this parameter (use aData if you want to pass data in you\\n\\t\\t * already have). Simply provide a url a JSON object can be obtained from.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.ajaxSource\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"sAjaxSource\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This initialisation variable allows you to specify exactly where in the\\n\\t\\t * DOM you want DataTables to inject the various controls it adds to the page\\n\\t\\t * (for example you might want the pagination controls at the top of the\\n\\t\\t * table). DIV elements (with or without a custom class) can also be added to\\n\\t\\t * aid styling. The follow syntax is used:\\n\\t\\t * <ul>\\n\\t\\t * <li>The following options are allowed:\\n\\t\\t * <ul>\\n\\t\\t * <li>'l' - Length changing</li>\\n\\t\\t * <li>'f' - Filtering input</li>\\n\\t\\t * <li>'t' - The table!</li>\\n\\t\\t * <li>'i' - Information</li>\\n\\t\\t * <li>'p' - Pagination</li>\\n\\t\\t * <li>'r' - pRocessing</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * <li>The following constants are allowed:\\n\\t\\t * <ul>\\n\\t\\t * <li>'H' - jQueryUI theme \\\"header\\\" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>\\n\\t\\t * <li>'F' - jQueryUI theme \\\"footer\\\" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * <li>The following syntax is expected:\\n\\t\\t * <ul>\\n\\t\\t * <li>'<' and '>' - div elements</li>\\n\\t\\t * <li>'<\\\"class\\\" and '>' - div with a class</li>\\n\\t\\t * <li>'<\\\"#id\\\" and '>' - div with an ID</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * <li>Examples:\\n\\t\\t * <ul>\\n\\t\\t * <li>'<\\\"wrapper\\\"flipt>'</li>\\n\\t\\t * <li>'<lf<t>ip>'</li>\\n\\t\\t * </ul>\\n\\t\\t * </li>\\n\\t\\t * </ul>\\n\\t\\t * @type string\\n\\t\\t * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>\\n\\t\\t * <\\\"H\\\"lfr>t<\\\"F\\\"ip> <i>(when `jQueryUI` is true)</i>\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.dom\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"dom\\\": '<\\\"top\\\"i>rt<\\\"bottom\\\"flp><\\\"clear\\\">'\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sDom\\\": \\\"lfrtip\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Search delay option. This will throttle full table searches that use the\\n\\t\\t * DataTables provided search input element (it does not effect calls to\\n\\t\\t * `dt-api search()`, providing a delay before the search is made.\\n\\t\\t * @type integer\\n\\t\\t * @default 0\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.searchDelay\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"searchDelay\\\": 200\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"searchDelay\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables features six different built-in options for the buttons to\\n\\t\\t * display for pagination control:\\n\\t\\t *\\n\\t\\t * * `numbers` - Page number buttons only\\n\\t\\t * * `simple` - 'Previous' and 'Next' buttons only\\n\\t\\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\\n\\t\\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\\n\\t\\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers\\n\\t\\t * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers\\n\\t\\t * \\n\\t\\t * Further methods can be added using {@link DataTable.ext.oPagination}.\\n\\t\\t * @type string\\n\\t\\t * @default simple_numbers\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.pagingType\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"pagingType\\\": \\\"full_numbers\\\"\\n\\t\\t * } );\\n\\t\\t * } )\\n\\t\\t */\\n\\t\\t\\\"sPaginationType\\\": \\\"simple_numbers\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable horizontal scrolling. When a table is too wide to fit into a\\n\\t\\t * certain layout, or you have a large number of columns in the table, you\\n\\t\\t * can enable x-scrolling to show the table in a viewport, which can be\\n\\t\\t * scrolled. This property can be `true` which will allow the table to\\n\\t\\t * scroll horizontally when needed, or any CSS unit, or a number (in which\\n\\t\\t * case it will be treated as a pixel measurement). Setting as simply `true`\\n\\t\\t * is recommended.\\n\\t\\t * @type boolean|string\\n\\t\\t * @default <i>blank string - i.e. disabled</i>\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.scrollX\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollX\\\": true,\\n\\t\\t * \\\"scrollCollapse\\\": true\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sScrollX\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This property can be used to force a DataTable to use more width than it\\n\\t\\t * might otherwise do when x-scrolling is enabled. For example if you have a\\n\\t\\t * table which requires to be well spaced, this parameter is useful for\\n\\t\\t * \\\"over-sizing\\\" the table, and thus forcing scrolling. This property can by\\n\\t\\t * any CSS unit, or a number (in which case it will be treated as a pixel\\n\\t\\t * measurement).\\n\\t\\t * @type string\\n\\t\\t * @default <i>blank string - i.e. disabled</i>\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @name DataTable.defaults.scrollXInner\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollX\\\": \\\"100%\\\",\\n\\t\\t * \\\"scrollXInner\\\": \\\"110%\\\"\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sScrollXInner\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\\n\\t\\t * to the given height, and enable scrolling for any data which overflows the\\n\\t\\t * current viewport. This can be used as an alternative to paging to display\\n\\t\\t * a lot of data in a small area (although paging and scrolling can both be\\n\\t\\t * enabled at the same time). This property can be any CSS unit, or a number\\n\\t\\t * (in which case it will be treated as a pixel measurement).\\n\\t\\t * @type string\\n\\t\\t * @default <i>blank string - i.e. disabled</i>\\n\\t\\t *\\n\\t\\t * @dtopt Features\\n\\t\\t * @name DataTable.defaults.scrollY\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"scrollY\\\": \\\"200px\\\",\\n\\t\\t * \\\"paginate\\\": false\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sScrollY\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * __Deprecated__ The functionality provided by this parameter has now been\\n\\t\\t * superseded by that provided through `ajax`, which should be used instead.\\n\\t\\t *\\n\\t\\t * Set the HTTP method that is used to make the Ajax call for server-side\\n\\t\\t * processing or Ajax sourced data.\\n\\t\\t * @type string\\n\\t\\t * @default GET\\n\\t\\t *\\n\\t\\t * @dtopt Options\\n\\t\\t * @dtopt Server-side\\n\\t\\t * @name DataTable.defaults.serverMethod\\n\\t\\t *\\n\\t\\t * @deprecated 1.10. Please use `ajax` for this functionality now.\\n\\t\\t */\\n\\t\\t\\\"sServerMethod\\\": \\\"GET\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables makes use of renderers when displaying HTML elements for\\n\\t\\t * a table. These renderers can be added or modified by plug-ins to\\n\\t\\t * generate suitable mark-up for a site. For example the Bootstrap\\n\\t\\t * integration plug-in for DataTables uses a paging button renderer to\\n\\t\\t * display pagination buttons in the mark-up required by Bootstrap.\\n\\t\\t *\\n\\t\\t * For further information about the renderers available see\\n\\t\\t * DataTable.ext.renderer\\n\\t\\t * @type string|object\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.renderer\\n\\t\\t *\\n\\t\\t */\\n\\t\\t\\\"renderer\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Set the data property name that DataTables should use to get a row's id\\n\\t\\t * to set as the `id` property in the node.\\n\\t\\t * @type string\\n\\t\\t * @default DT_RowId\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.rowId\\n\\t\\t */\\n\\t\\t\\\"rowId\\\": \\\"DT_RowId\\\"\\n\\t};\\n\\t\\n\\t_fnHungarianMap( DataTable.defaults );\\n\\t\\n\\t\\n\\t\\n\\t/*\\n\\t * Developer note - See note in model.defaults.js about the use of Hungarian\\n\\t * notation and camel case.\\n\\t */\\n\\t\\n\\t/**\\n\\t * Column options that can be given to DataTables at initialisation time.\\n\\t * @namespace\\n\\t */\\n\\tDataTable.defaults.column = {\\n\\t\\t/**\\n\\t\\t * Define which column(s) an order will occur on for this column. This\\n\\t\\t * allows a column's ordering to take multiple columns into account when\\n\\t\\t * doing a sort or use the data from a different column. For example first\\n\\t\\t * name / last name columns make sense to do a multi-column sort over the\\n\\t\\t * two columns.\\n\\t\\t * @type array|int\\n\\t\\t * @default null <i>Takes the value of the column index automatically</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderData\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderData\\\": [ 0, 1 ], \\\"targets\\\": [ 0 ] },\\n\\t\\t * { \\\"orderData\\\": [ 1, 0 ], \\\"targets\\\": [ 1 ] },\\n\\t\\t * { \\\"orderData\\\": 2, \\\"targets\\\": [ 2 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"orderData\\\": [ 0, 1 ] },\\n\\t\\t * { \\\"orderData\\\": [ 1, 0 ] },\\n\\t\\t * { \\\"orderData\\\": 2 },\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"aDataSort\\\": null,\\n\\t\\t\\\"iDataSort\\\": -1,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * You can control the default ordering direction, and even alter the\\n\\t\\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\\n\\t\\t * using this parameter.\\n\\t\\t * @type array\\n\\t\\t * @default [ 'asc', 'desc' ]\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderSequence\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"asc\\\" ], \\\"targets\\\": [ 1 ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\", \\\"asc\\\", \\\"asc\\\" ], \\\"targets\\\": [ 2 ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\" ], \\\"targets\\\": [ 3 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"asc\\\" ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\", \\\"asc\\\", \\\"asc\\\" ] },\\n\\t\\t * { \\\"orderSequence\\\": [ \\\"desc\\\" ] },\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"asSorting\\\": [ 'asc', 'desc' ],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable filtering on the data in this column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.searchable\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"searchable\\\": false, \\\"targets\\\": [ 0 ] }\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"searchable\\\": false },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSearchable\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable ordering on this column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderable\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderable\\\": false, \\\"targets\\\": [ 0 ] }\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"orderable\\\": false },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bSortable\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Enable or disable the display of this column.\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.visible\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"visible\\\": false, \\\"targets\\\": [ 0 ] }\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"visible\\\": false },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ] } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"bVisible\\\": true,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Developer definable function that is called whenever a cell is created (Ajax source,\\n\\t\\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\\n\\t\\t * allowing you to modify the DOM element (add background colour for example) when the\\n\\t\\t * element is available.\\n\\t\\t * @type function\\n\\t\\t * @param {element} td The TD node that has been created\\n\\t\\t * @param {*} cellData The Data for the cell\\n\\t\\t * @param {array|object} rowData The data for the whole row\\n\\t\\t * @param {int} row The row index for the aoData data store\\n\\t\\t * @param {int} col The column index for aoColumns\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.createdCell\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [3],\\n\\t\\t * \\\"createdCell\\\": function (td, cellData, rowData, row, col) {\\n\\t\\t * if ( cellData == \\\"1.7\\\" ) {\\n\\t\\t * $(td).css('color', 'blue')\\n\\t\\t * }\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * });\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"fnCreatedCell\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter has been replaced by `data` in DataTables to ensure naming\\n\\t\\t * consistency. `dataProp` can still be used, as there is backwards\\n\\t\\t * compatibility in DataTables for this option, but it is strongly\\n\\t\\t * recommended that you use `data` in preference to `dataProp`.\\n\\t\\t * @name DataTable.defaults.column.dataProp\\n\\t\\t */\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This property can be used to read data from any data source property,\\n\\t\\t * including deeply nested objects / properties. `data` can be given in a\\n\\t\\t * number of different ways which effect its behaviour:\\n\\t\\t *\\n\\t\\t * * `integer` - treated as an array index for the data source. This is the\\n\\t\\t * default that DataTables uses (incrementally increased for each column).\\n\\t\\t * * `string` - read an object property from the data source. There are\\n\\t\\t * three 'special' options that can be used in the string to alter how\\n\\t\\t * DataTables reads the data from the source object:\\n\\t\\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\\n\\t\\t * Javascript to read from nested objects, so to can the options\\n\\t\\t * specified in `data`. For example: `browser.version` or\\n\\t\\t * `browser.name`. If your object parameter name contains a period, use\\n\\t\\t * `\\\\\\\\` to escape it - i.e. `first\\\\\\\\.name`.\\n\\t\\t * * `[]` - Array notation. DataTables can automatically combine data\\n\\t\\t * from and array source, joining the data with the characters provided\\n\\t\\t * between the two brackets. For example: `name[, ]` would provide a\\n\\t\\t * comma-space separated list from the source array. If no characters\\n\\t\\t * are provided between the brackets, the original array source is\\n\\t\\t * returned.\\n\\t\\t * * `()` - Function notation. Adding `()` to the end of a parameter will\\n\\t\\t * execute a function of the name given. For example: `browser()` for a\\n\\t\\t * simple function on the data source, `browser.version()` for a\\n\\t\\t * function in a nested property or even `browser().version` to get an\\n\\t\\t * object property if the function called returns an object. Note that\\n\\t\\t * function notation is recommended for use in `render` rather than\\n\\t\\t * `data` as it is much simpler to use as a renderer.\\n\\t\\t * * `null` - use the original data source for the row rather than plucking\\n\\t\\t * data directly from it. This action has effects on two other\\n\\t\\t * initialisation options:\\n\\t\\t * * `defaultContent` - When null is given as the `data` option and\\n\\t\\t * `defaultContent` is specified for the column, the value defined by\\n\\t\\t * `defaultContent` will be used for the cell.\\n\\t\\t * * `render` - When null is used for the `data` option and the `render`\\n\\t\\t * option is specified for the column, the whole data source for the\\n\\t\\t * row is used for the renderer.\\n\\t\\t * * `function` - the function given will be executed whenever DataTables\\n\\t\\t * needs to set or get the data for a cell in the column. The function\\n\\t\\t * takes three parameters:\\n\\t\\t * * Parameters:\\n\\t\\t * * `{array|object}` The data source for the row\\n\\t\\t * * `{string}` The type call data requested - this will be 'set' when\\n\\t\\t * setting data or 'filter', 'display', 'type', 'sort' or undefined\\n\\t\\t * when gathering data. Note that when `undefined` is given for the\\n\\t\\t * type DataTables expects to get the raw data for the object back<\\n\\t\\t * * `{*}` Data to set when the second parameter is 'set'.\\n\\t\\t * * Return:\\n\\t\\t * * The return value from the function is not required when 'set' is\\n\\t\\t * the type of call, but otherwise the return is what will be used\\n\\t\\t * for the data requested.\\n\\t\\t *\\n\\t\\t * Note that `data` is a getter and setter option. If you just require\\n\\t\\t * formatting of data for output, you will likely want to use `render` which\\n\\t\\t * is simply a getter and thus simpler to use.\\n\\t\\t *\\n\\t\\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\\n\\t\\t * name change reflects the flexibility of this property and is consistent\\n\\t\\t * with the naming of mRender. If 'mDataProp' is given, then it will still\\n\\t\\t * be used by DataTables, as it automatically maps the old name to the new\\n\\t\\t * if required.\\n\\t\\t *\\n\\t\\t * @type string|int|function|null\\n\\t\\t * @default null <i>Use automatically calculated column index</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.data\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Read table data from objects\\n\\t\\t * // JSON structure for each row:\\n\\t\\t * // {\\n\\t\\t * // \\\"engine\\\": {value},\\n\\t\\t * // \\\"browser\\\": {value},\\n\\t\\t * // \\\"platform\\\": {value},\\n\\t\\t * // \\\"version\\\": {value},\\n\\t\\t * // \\\"grade\\\": {value}\\n\\t\\t * // }\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajaxSource\\\": \\\"sources/objects.txt\\\",\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform\\\" },\\n\\t\\t * { \\\"data\\\": \\\"version\\\" },\\n\\t\\t * { \\\"data\\\": \\\"grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Read information from deeply nested objects\\n\\t\\t * // JSON structure for each row:\\n\\t\\t * // {\\n\\t\\t * // \\\"engine\\\": {value},\\n\\t\\t * // \\\"browser\\\": {value},\\n\\t\\t * // \\\"platform\\\": {\\n\\t\\t * // \\\"inner\\\": {value}\\n\\t\\t * // },\\n\\t\\t * // \\\"details\\\": [\\n\\t\\t * // {value}, {value}\\n\\t\\t * // ]\\n\\t\\t * // }\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajaxSource\\\": \\\"sources/deep.txt\\\",\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform.inner\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform.details.0\\\" },\\n\\t\\t * { \\\"data\\\": \\\"platform.details.1\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `data` as a function to provide different information for\\n\\t\\t * // sorting, filtering and display. In this case, currency (price)\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": function ( source, type, val ) {\\n\\t\\t * if (type === 'set') {\\n\\t\\t * source.price = val;\\n\\t\\t * // Store the computed dislay and filter values for efficiency\\n\\t\\t * source.price_display = val==\\\"\\\" ? \\\"\\\" : \\\"$\\\"+numberFormat(val);\\n\\t\\t * source.price_filter = val==\\\"\\\" ? \\\"\\\" : \\\"$\\\"+numberFormat(val)+\\\" \\\"+val;\\n\\t\\t * return;\\n\\t\\t * }\\n\\t\\t * else if (type === 'display') {\\n\\t\\t * return source.price_display;\\n\\t\\t * }\\n\\t\\t * else if (type === 'filter') {\\n\\t\\t * return source.price_filter;\\n\\t\\t * }\\n\\t\\t * // 'sort', 'type' and undefined all just use the integer\\n\\t\\t * return source.price;\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using default content\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": null,\\n\\t\\t * \\\"defaultContent\\\": \\\"Click to edit\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using array notation - outputting a list from an array\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": \\\"name[, ]\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t */\\n\\t\\t\\\"mData\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This property is the rendering partner to `data` and it is suggested that\\n\\t\\t * when you want to manipulate data for display (including filtering,\\n\\t\\t * sorting etc) without altering the underlying data for the table, use this\\n\\t\\t * property. `render` can be considered to be the the read only companion to\\n\\t\\t * `data` which is read / write (then as such more complex). Like `data`\\n\\t\\t * this option can be given in a number of different ways to effect its\\n\\t\\t * behaviour:\\n\\t\\t *\\n\\t\\t * * `integer` - treated as an array index for the data source. This is the\\n\\t\\t * default that DataTables uses (incrementally increased for each column).\\n\\t\\t * * `string` - read an object property from the data source. There are\\n\\t\\t * three 'special' options that can be used in the string to alter how\\n\\t\\t * DataTables reads the data from the source object:\\n\\t\\t * * `.` - Dotted Javascript notation. Just as you use a `.` in\\n\\t\\t * Javascript to read from nested objects, so to can the options\\n\\t\\t * specified in `data`. For example: `browser.version` or\\n\\t\\t * `browser.name`. If your object parameter name contains a period, use\\n\\t\\t * `\\\\\\\\` to escape it - i.e. `first\\\\\\\\.name`.\\n\\t\\t * * `[]` - Array notation. DataTables can automatically combine data\\n\\t\\t * from and array source, joining the data with the characters provided\\n\\t\\t * between the two brackets. For example: `name[, ]` would provide a\\n\\t\\t * comma-space separated list from the source array. If no characters\\n\\t\\t * are provided between the brackets, the original array source is\\n\\t\\t * returned.\\n\\t\\t * * `()` - Function notation. Adding `()` to the end of a parameter will\\n\\t\\t * execute a function of the name given. For example: `browser()` for a\\n\\t\\t * simple function on the data source, `browser.version()` for a\\n\\t\\t * function in a nested property or even `browser().version` to get an\\n\\t\\t * object property if the function called returns an object.\\n\\t\\t * * `object` - use different data for the different data types requested by\\n\\t\\t * DataTables ('filter', 'display', 'type' or 'sort'). The property names\\n\\t\\t * of the object is the data type the property refers to and the value can\\n\\t\\t * defined using an integer, string or function using the same rules as\\n\\t\\t * `render` normally does. Note that an `_` option _must_ be specified.\\n\\t\\t * This is the default value to use if you haven't specified a value for\\n\\t\\t * the data type requested by DataTables.\\n\\t\\t * * `function` - the function given will be executed whenever DataTables\\n\\t\\t * needs to set or get the data for a cell in the column. The function\\n\\t\\t * takes three parameters:\\n\\t\\t * * Parameters:\\n\\t\\t * * {array|object} The data source for the row (based on `data`)\\n\\t\\t * * {string} The type call data requested - this will be 'filter',\\n\\t\\t * 'display', 'type' or 'sort'.\\n\\t\\t * * {array|object} The full data source for the row (not based on\\n\\t\\t * `data`)\\n\\t\\t * * Return:\\n\\t\\t * * The return value from the function is what will be used for the\\n\\t\\t * data requested.\\n\\t\\t *\\n\\t\\t * @type string|int|function|object|null\\n\\t\\t * @default null Use the data source value.\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.render\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Create a comma separated list from an array of objects\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"ajaxSource\\\": \\\"sources/deep.txt\\\",\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"data\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"data\\\": \\\"browser\\\" },\\n\\t\\t * {\\n\\t\\t * \\\"data\\\": \\\"platform\\\",\\n\\t\\t * \\\"render\\\": \\\"[, ].name\\\"\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Execute a function to obtain data\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": null, // Use the full data source object for the renderer's source\\n\\t\\t * \\\"render\\\": \\\"browserName()\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // As an object, extracting different data for the different types\\n\\t\\t * // This would be used with a data source such as:\\n\\t\\t * // { \\\"phone\\\": 5552368, \\\"phone_filter\\\": \\\"5552368 555-2368\\\", \\\"phone_display\\\": \\\"555-2368\\\" }\\n\\t\\t * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\\n\\t\\t * // (which has both forms) is used for filtering for if a user inputs either format, while\\n\\t\\t * // the formatted phone number is the one that is shown in the table.\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": null, // Use the full data source object for the renderer's source\\n\\t\\t * \\\"render\\\": {\\n\\t\\t * \\\"_\\\": \\\"phone\\\",\\n\\t\\t * \\\"filter\\\": \\\"phone_filter\\\",\\n\\t\\t * \\\"display\\\": \\\"phone_display\\\"\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Use as a function to create a link from the data source\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"data\\\": \\\"download_link\\\",\\n\\t\\t * \\\"render\\\": function ( data, type, full ) {\\n\\t\\t * return '<a href=\\\"'+data+'\\\">Download</a>';\\n\\t\\t * }\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"mRender\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Change the cell type created for the column - either TD cells or TH cells. This\\n\\t\\t * can be useful as TH cells have semantic meaning in the table body, allowing them\\n\\t\\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\\n\\t\\t * @type string\\n\\t\\t * @default td\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.cellType\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Make the first column use TH cells\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [ {\\n\\t\\t * \\\"targets\\\": [ 0 ],\\n\\t\\t * \\\"cellType\\\": \\\"th\\\"\\n\\t\\t * } ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sCellType\\\": \\\"td\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Class to give to each cell in this column.\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.class\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"class\\\": \\\"my_class\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"class\\\": \\\"my_class\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sClass\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * When DataTables calculates the column widths to assign to each column,\\n\\t\\t * it finds the longest string in each column and then constructs a\\n\\t\\t * temporary table and reads the widths from that. The problem with this\\n\\t\\t * is that \\\"mmm\\\" is much wider then \\\"iiii\\\", but the latter is a longer\\n\\t\\t * string - thus the calculation can go wrong (doing it properly and putting\\n\\t\\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\\n\\t\\t * a \\\"work around\\\" we provide this option. It will append its value to the\\n\\t\\t * text that is found to be the longest string for the column - i.e. padding.\\n\\t\\t * Generally you shouldn't need this!\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string<i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.contentPadding\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * {\\n\\t\\t * \\\"contentPadding\\\": \\\"mmm\\\"\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sContentPadding\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Allows a default value to be given for a column's data, and will be used\\n\\t\\t * whenever a null data source is encountered (this can be because `data`\\n\\t\\t * is set to null, or because the data source itself is null).\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.defaultContent\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * {\\n\\t\\t * \\\"data\\\": null,\\n\\t\\t * \\\"defaultContent\\\": \\\"Edit\\\",\\n\\t\\t * \\\"targets\\\": [ -1 ]\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * {\\n\\t\\t * \\\"data\\\": null,\\n\\t\\t * \\\"defaultContent\\\": \\\"Edit\\\"\\n\\t\\t * }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sDefaultContent\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * This parameter is only used in DataTables' server-side processing. It can\\n\\t\\t * be exceptionally useful to know what columns are being displayed on the\\n\\t\\t * client side, and to map these to database fields. When defined, the names\\n\\t\\t * also allow DataTables to reorder information from the server if it comes\\n\\t\\t * back in an unexpected order (i.e. if you switch your columns around on the\\n\\t\\t * client-side, your server-side code does not also need updating).\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.name\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"name\\\": \\\"engine\\\", \\\"targets\\\": [ 0 ] },\\n\\t\\t * { \\\"name\\\": \\\"browser\\\", \\\"targets\\\": [ 1 ] },\\n\\t\\t * { \\\"name\\\": \\\"platform\\\", \\\"targets\\\": [ 2 ] },\\n\\t\\t * { \\\"name\\\": \\\"version\\\", \\\"targets\\\": [ 3 ] },\\n\\t\\t * { \\\"name\\\": \\\"grade\\\", \\\"targets\\\": [ 4 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"name\\\": \\\"engine\\\" },\\n\\t\\t * { \\\"name\\\": \\\"browser\\\" },\\n\\t\\t * { \\\"name\\\": \\\"platform\\\" },\\n\\t\\t * { \\\"name\\\": \\\"version\\\" },\\n\\t\\t * { \\\"name\\\": \\\"grade\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sName\\\": \\\"\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Defines a data source type for the ordering which can be used to read\\n\\t\\t * real-time information from the table (updating the internally cached\\n\\t\\t * version) prior to ordering. This allows ordering to occur on user\\n\\t\\t * editable elements such as form inputs.\\n\\t\\t * @type string\\n\\t\\t * @default std\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.orderDataType\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-text\\\", \\\"targets\\\": [ 2, 3 ] },\\n\\t\\t * { \\\"type\\\": \\\"numeric\\\", \\\"targets\\\": [ 3 ] },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-select\\\", \\\"targets\\\": [ 4 ] },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-checkbox\\\", \\\"targets\\\": [ 5 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-text\\\" },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-text\\\", \\\"type\\\": \\\"numeric\\\" },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-select\\\" },\\n\\t\\t * { \\\"orderDataType\\\": \\\"dom-checkbox\\\" }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sSortDataType\\\": \\\"std\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The title of this column.\\n\\t\\t * @type string\\n\\t\\t * @default null <i>Derived from the 'TH' value for this column in the\\n\\t\\t * original HTML table.</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.title\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"title\\\": \\\"My column title\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"title\\\": \\\"My column title\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sTitle\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * The type allows you to specify how the data for this column will be\\n\\t\\t * ordered. Four types (string, numeric, date and html (which will strip\\n\\t\\t * HTML tags before ordering)) are currently available. Note that only date\\n\\t\\t * formats understood by Javascript's Date() object will be accepted as type\\n\\t\\t * date. For example: \\\"Mar 26, 2008 5:03 PM\\\". May take the values: 'string',\\n\\t\\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\\n\\t\\t * through plug-ins.\\n\\t\\t * @type string\\n\\t\\t * @default null <i>Auto-detected from raw data</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.type\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"type\\\": \\\"html\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"type\\\": \\\"html\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sType\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Defining the width of the column, this parameter may take any CSS value\\n\\t\\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\\n\\t\\t * been given a specific width through this interface ensuring that the table\\n\\t\\t * remains readable.\\n\\t\\t * @type string\\n\\t\\t * @default null <i>Automatic</i>\\n\\t\\t *\\n\\t\\t * @name DataTable.defaults.column.width\\n\\t\\t * @dtopt Columns\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columnDefs`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columnDefs\\\": [\\n\\t\\t * { \\\"width\\\": \\\"20%\\\", \\\"targets\\\": [ 0 ] }\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Using `columns`\\n\\t\\t * $(document).ready( function() {\\n\\t\\t * $('#example').dataTable( {\\n\\t\\t * \\\"columns\\\": [\\n\\t\\t * { \\\"width\\\": \\\"20%\\\" },\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null,\\n\\t\\t * null\\n\\t\\t * ]\\n\\t\\t * } );\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\t\\\"sWidth\\\": null\\n\\t};\\n\\t\\n\\t_fnHungarianMap( DataTable.defaults.column );\\n\\t\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables settings object - this holds all the information needed for a\\n\\t * given table, including configuration, data and current application of the\\n\\t * table options. DataTables does not have a single instance for each DataTable\\n\\t * with the settings attached to that instance, but rather instances of the\\n\\t * DataTable \\\"class\\\" are created on-the-fly as needed (typically by a\\n\\t * $().dataTable() call) and the settings object is then applied to that\\n\\t * instance.\\n\\t *\\n\\t * Note that this object is related to {@link DataTable.defaults} but this\\n\\t * one is the internal data store for DataTables's cache of columns. It should\\n\\t * NOT be manipulated outside of DataTables. Any configuration should be done\\n\\t * through the initialisation options.\\n\\t * @namespace\\n\\t * @todo Really should attach the settings object to individual instances so we\\n\\t * don't need to create new instances on each $().dataTable() call (if the\\n\\t * table already exists). It would also save passing oSettings around and\\n\\t * into every single function. However, this is a very significant\\n\\t * architecture change for DataTables and will almost certainly break\\n\\t * backwards compatibility with older installations. This is something that\\n\\t * will be done in 2.0.\\n\\t */\\n\\tDataTable.models.oSettings = {\\n\\t\\t/**\\n\\t\\t * Primary features of DataTables and their enablement state.\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\t\\\"oFeatures\\\": {\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Flag to say if DataTables should automatically try to calculate the\\n\\t\\t\\t * optimum table and columns widths (true) or not (false).\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bAutoWidth\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Delay the creation of TR and TD elements until they are actually\\n\\t\\t\\t * needed by a driven page draw. This can give a significant speed\\n\\t\\t\\t * increase for Ajax source and Javascript source data, but makes no\\n\\t\\t\\t * difference at all fro DOM and server-side processing tables.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bDeferRender\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Enable filtering on the table or not. Note that if this is disabled\\n\\t\\t\\t * then there is no filtering at all on the table, including fnFilter.\\n\\t\\t\\t * To just remove the filtering input use sDom and remove the 'f' option.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bFilter\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Table information element (the 'Showing x of y records' div) enable\\n\\t\\t\\t * flag.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bInfo\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Present a user control allowing the end user to change the page size\\n\\t\\t\\t * when pagination is enabled.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bLengthChange\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Pagination enabled or not. Note that if this is disabled then length\\n\\t\\t\\t * changing must also be disabled.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bPaginate\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Processing indicator enable flag whenever DataTables is enacting a\\n\\t\\t\\t * user request - typically an Ajax request for server-side processing.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bProcessing\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Server-side processing enabled flag - when enabled DataTables will\\n\\t\\t\\t * get all data from the server for every draw - there is no filtering,\\n\\t\\t\\t * sorting or paging done on the client-side.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bServerSide\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Sorting enablement flag.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bSort\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Multi-column sorting\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bSortMulti\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Apply a class to the columns which are being sorted to provide a\\n\\t\\t\\t * visual highlight or not. This can slow things down when enabled since\\n\\t\\t\\t * there is a lot of DOM interaction.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bSortClasses\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * State saving enablement flag.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bStateSave\\\": null\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Scrolling settings for a table.\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\t\\\"oScroll\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * When the table is shorter in height than sScrollY, collapse the\\n\\t\\t\\t * table container down to the height of the table (when true).\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bCollapse\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Width of the scrollbar for the web-browser's platform. Calculated\\n\\t\\t\\t * during table initialisation.\\n\\t\\t\\t * @type int\\n\\t\\t\\t * @default 0\\n\\t\\t\\t */\\n\\t\\t\\t\\\"iBarWidth\\\": 0,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Viewport width for horizontal scrolling. Horizontal scrolling is\\n\\t\\t\\t * disabled if an empty string.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type string\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sX\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Width to expand the table to when using x-scrolling. Typically you\\n\\t\\t\\t * should not need to use this.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type string\\n\\t\\t\\t * @deprecated\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sXInner\\\": null,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\\n\\t\\t\\t * if an empty string.\\n\\t\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t\\t * @type string\\n\\t\\t\\t */\\n\\t\\t\\t\\\"sY\\\": null\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Language information for the table.\\n\\t\\t * @namespace\\n\\t\\t * @extends DataTable.defaults.oLanguage\\n\\t\\t */\\n\\t\\t\\\"oLanguage\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * Information callback function. See\\n\\t\\t\\t * {@link DataTable.defaults.fnInfoCallback}\\n\\t\\t\\t * @type function\\n\\t\\t\\t * @default null\\n\\t\\t\\t */\\n\\t\\t\\t\\\"fnInfoCallback\\\": null\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Browser support parameters\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\t\\\"oBrowser\\\": {\\n\\t\\t\\t/**\\n\\t\\t\\t * Indicate if the browser incorrectly calculates width:100% inside a\\n\\t\\t\\t * scrolling element (IE6/7)\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default false\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bScrollOversize\\\": false,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Determine if the vertical scrollbar is on the right or left of the\\n\\t\\t\\t * scrolling container - needed for rtl language layout, although not\\n\\t\\t\\t * all browsers move the scrollbar (Safari).\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default false\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bScrollbarLeft\\\": false,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Flag for if `getBoundingClientRect` is fully supported or not\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default false\\n\\t\\t\\t */\\n\\t\\t\\t\\\"bBounding\\\": false,\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Browser scrollbar width\\n\\t\\t\\t * @type integer\\n\\t\\t\\t * @default 0\\n\\t\\t\\t */\\n\\t\\t\\t\\\"barWidth\\\": 0\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t\\\"ajax\\\": null,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Array referencing the nodes which are used for the features. The\\n\\t\\t * parameters of this object match what is allowed by sDom - i.e.\\n\\t\\t * <ul>\\n\\t\\t * <li>'l' - Length changing</li>\\n\\t\\t * <li>'f' - Filtering input</li>\\n\\t\\t * <li>'t' - The table!</li>\\n\\t\\t * <li>'i' - Information</li>\\n\\t\\t * <li>'p' - Pagination</li>\\n\\t\\t * <li>'r' - pRocessing</li>\\n\\t\\t * </ul>\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aanFeatures\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store data information - see {@link DataTable.models.oRow} for detailed\\n\\t\\t * information.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoData\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of indexes which are in the current display (after filtering etc)\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aiDisplay\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of indexes for display - no filtering\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aiDisplayMaster\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Map of row ids to data indexes\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\t\\\"aIds\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Store information about each column that is in use\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoColumns\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store information about the table's header\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoHeader\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store information about the table's footer\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoFooter\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Store the applied global search information in case we want to force a\\n\\t\\t * research or compare the old search to a new one.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @namespace\\n\\t\\t * @extends DataTable.models.oSearch\\n\\t\\t */\\n\\t\\t\\\"oPreviousSearch\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Store the applied search for each column - see\\n\\t\\t * {@link DataTable.models.oSearch} for the format that is used for the\\n\\t\\t * filtering information for each column.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoPreSearchCols\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Sorting that is applied to the table. Note that the inner arrays are\\n\\t\\t * used in the following manner:\\n\\t\\t * <ul>\\n\\t\\t * <li>Index 0 - column number</li>\\n\\t\\t * <li>Index 1 - current sorting direction</li>\\n\\t\\t * </ul>\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @todo These inner arrays should really be objects\\n\\t\\t */\\n\\t\\t\\\"aaSorting\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Sorting that is always applied to the table (i.e. prefixed in front of\\n\\t\\t * aaSorting).\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aaSortingFixed\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Classes to use for the striping of a table.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"asStripeClasses\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * If restoring a table - we should restore its striping classes as well\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"asDestroyStripes\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * If restoring a table - we should restore its width\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"sDestroyWidth\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions array for every time a row is inserted (i.e. on a draw).\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoRowCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions for the header on each draw.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoHeaderCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback function for the footer on each draw.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoFooterCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for draw callback functions\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoDrawCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for row created function\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoRowCreatedCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions for just before the table is redrawn. A return of\\n\\t\\t * false will be used to cancel the draw.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoPreDrawCallback\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callback functions for when the table has been initialised.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoInitComplete\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Callbacks for modifying the settings to be stored for state saving, prior to\\n\\t\\t * saving state.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateSaveParams\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callbacks for modifying the settings that have been stored for state saving\\n\\t\\t * prior to using the stored values to restore the state.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateLoadParams\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Callbacks for operating on the settings object once the saved state has been\\n\\t\\t * loaded\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateLoaded\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Cache the table ID for quick access\\n\\t\\t * @type string\\n\\t\\t * @default <i>Empty string</i>\\n\\t\\t */\\n\\t\\t\\\"sTableId\\\": \\\"\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * The TABLE node for the main table\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTable\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Permanent ref to the thead element\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTHead\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Permanent ref to the tfoot element - if it exists\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTFoot\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Permanent ref to the tbody element\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTBody\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Cache the wrapper node (contains all DataTables controlled elements)\\n\\t\\t * @type node\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"nTableWrapper\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate if when using server-side processing the loading of data\\n\\t\\t * should be deferred until the second draw.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bDeferLoading\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate if all required information has been read in\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bInitialised\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Information about open rows. Each object in the array has the parameters\\n\\t\\t * 'nTr' and 'nParent'\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoOpenRows\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Dictate the positioning of DataTables' control elements - see\\n\\t\\t * {@link DataTable.model.oInit.sDom}.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sDom\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Search delay (in mS)\\n\\t\\t * @type integer\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"searchDelay\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Which type of pagination should be used.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t * @default two_button\\n\\t\\t */\\n\\t\\t\\\"sPaginationType\\\": \\\"two_button\\\",\\n\\t\\n\\t\\t/**\\n\\t\\t * The state duration (for `stateSave`) in seconds.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"iStateDuration\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for state saving. Each array element is an\\n\\t\\t * object with the following parameters:\\n\\t\\t * <ul>\\n\\t\\t * <li>function:fn - function to call. Takes two parameters, oSettings\\n\\t\\t * and the JSON string to save that has been thus far created. Returns\\n\\t\\t * a JSON string to be inserted into a json object\\n\\t\\t * (i.e. '\\\"param\\\": [ 0, 1, 2]')</li>\\n\\t\\t * <li>string:sName - name of callback</li>\\n\\t\\t * </ul>\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateSave\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Array of callback functions for state loading. Each array element is an\\n\\t\\t * object with the following parameters:\\n\\t\\t * <ul>\\n\\t\\t * <li>function:fn - function to call. Takes two parameters, oSettings\\n\\t\\t * and the object stored. May return false to cancel state loading</li>\\n\\t\\t * <li>string:sName - name of callback</li>\\n\\t\\t * </ul>\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoStateLoad\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * State that was saved. Useful for back reference\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oSavedState\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * State that was loaded. Useful for back reference\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oLoadedState\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Source url for AJAX data for the table.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sAjaxSource\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Property from a given object from which to read the table data from. This\\n\\t\\t * can be an empty string (when not server-side processing), in which case\\n\\t\\t * it is assumed an an array is given directly.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sAjaxDataProp\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Note if draw should be blocked while getting data\\n\\t\\t * @type boolean\\n\\t\\t * @default true\\n\\t\\t */\\n\\t\\t\\\"bAjaxDataGet\\\": true,\\n\\t\\n\\t\\t/**\\n\\t\\t * The last jQuery XHR object that was used for server-side data gathering.\\n\\t\\t * This can be used for working with the XHR information in one of the\\n\\t\\t * callbacks\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"jqXHR\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * JSON returned from the server in the last Ajax request\\n\\t\\t * @type object\\n\\t\\t * @default undefined\\n\\t\\t */\\n\\t\\t\\\"json\\\": undefined,\\n\\t\\n\\t\\t/**\\n\\t\\t * Data submitted as part of the last Ajax request\\n\\t\\t * @type object\\n\\t\\t * @default undefined\\n\\t\\t */\\n\\t\\t\\\"oAjaxData\\\": undefined,\\n\\t\\n\\t\\t/**\\n\\t\\t * Function to get the server-side data.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnServerData\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Functions which are called prior to sending an Ajax request so extra\\n\\t\\t * parameters can easily be sent to the server\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoServerParams\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\\n\\t\\t * required).\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\t\\\"sServerMethod\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Format numbers for display.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnFormatNumber\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * List of options that can be used for the user selectable length menu.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aLengthMenu\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Counter for the draws that the table does. Also used as a tracker for\\n\\t\\t * server-side processing\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"iDraw\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate if a redraw is being done - useful for Ajax\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t */\\n\\t\\t\\\"bDrawing\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Draw index (iDraw) of the last error when parsing the returned data\\n\\t\\t * @type int\\n\\t\\t * @default -1\\n\\t\\t */\\n\\t\\t\\\"iDrawError\\\": -1,\\n\\t\\n\\t\\t/**\\n\\t\\t * Paging display length\\n\\t\\t * @type int\\n\\t\\t * @default 10\\n\\t\\t */\\n\\t\\t\\\"_iDisplayLength\\\": 10,\\n\\t\\n\\t\\t/**\\n\\t\\t * Paging start point - aiDisplay index\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t */\\n\\t\\t\\\"_iDisplayStart\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Server-side processing - number of records in the result set\\n\\t\\t * (i.e. before filtering), Use fnRecordsTotal rather than\\n\\t\\t * this property to get the value of the number of records, regardless of\\n\\t\\t * the server-side processing setting.\\n\\t\\t * @type int\\n\\t\\t * @default 0\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_iRecordsTotal\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * Server-side processing - number of records in the current display set\\n\\t\\t * (i.e. after filtering). Use fnRecordsDisplay rather than\\n\\t\\t * this property to get the value of the number of records, regardless of\\n\\t\\t * the server-side processing setting.\\n\\t\\t * @type boolean\\n\\t\\t * @default 0\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t\\\"_iRecordsDisplay\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * The classes to use for the table\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\t\\\"oClasses\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag attached to the settings object so you can check in the draw\\n\\t\\t * callback if filtering has been done in the draw. Deprecated in favour of\\n\\t\\t * events.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t * @deprecated\\n\\t\\t */\\n\\t\\t\\\"bFiltered\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Flag attached to the settings object so you can check in the draw\\n\\t\\t * callback if sorting has been done in the draw. Deprecated in favour of\\n\\t\\t * events.\\n\\t\\t * @type boolean\\n\\t\\t * @default false\\n\\t\\t * @deprecated\\n\\t\\t */\\n\\t\\t\\\"bSorted\\\": false,\\n\\t\\n\\t\\t/**\\n\\t\\t * Indicate that if multiple rows are in the header and there is more than\\n\\t\\t * one unique cell per column, if the top one (true) or bottom one (false)\\n\\t\\t * should be used for sorting / title by DataTables.\\n\\t\\t * Note that this parameter will be set by the initialisation routine. To\\n\\t\\t * set a default use {@link DataTable.defaults}.\\n\\t\\t * @type boolean\\n\\t\\t */\\n\\t\\t\\\"bSortCellsTop\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Initialisation object that is used for the table\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oInit\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Destroy callback functions - for plug-ins to attach themselves to the\\n\\t\\t * destroy so they can clean up markup and events.\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aoDestroyCallback\\\": [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Get the number of records in the current record set, before filtering\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnRecordsTotal\\\": function ()\\n\\t\\t{\\n\\t\\t\\treturn _fnDataSource( this ) == 'ssp' ?\\n\\t\\t\\t\\tthis._iRecordsTotal * 1 :\\n\\t\\t\\t\\tthis.aiDisplayMaster.length;\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Get the number of records in the current record set, after filtering\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnRecordsDisplay\\\": function ()\\n\\t\\t{\\n\\t\\t\\treturn _fnDataSource( this ) == 'ssp' ?\\n\\t\\t\\t\\tthis._iRecordsDisplay * 1 :\\n\\t\\t\\t\\tthis.aiDisplay.length;\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Get the display end point - aiDisplay index\\n\\t\\t * @type function\\n\\t\\t */\\n\\t\\t\\\"fnDisplayEnd\\\": function ()\\n\\t\\t{\\n\\t\\t\\tvar\\n\\t\\t\\t\\tlen = this._iDisplayLength,\\n\\t\\t\\t\\tstart = this._iDisplayStart,\\n\\t\\t\\t\\tcalc = start + len,\\n\\t\\t\\t\\trecords = this.aiDisplay.length,\\n\\t\\t\\t\\tfeatures = this.oFeatures,\\n\\t\\t\\t\\tpaginate = features.bPaginate;\\n\\t\\n\\t\\t\\tif ( features.bServerSide ) {\\n\\t\\t\\t\\treturn paginate === false || len === -1 ?\\n\\t\\t\\t\\t\\tstart + records :\\n\\t\\t\\t\\t\\tMath.min( start+len, this._iRecordsDisplay );\\n\\t\\t\\t}\\n\\t\\t\\telse {\\n\\t\\t\\t\\treturn ! paginate || calc>records || len===-1 ?\\n\\t\\t\\t\\t\\trecords :\\n\\t\\t\\t\\t\\tcalc;\\n\\t\\t\\t}\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * The DataTables object for this table\\n\\t\\t * @type object\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"oInstance\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique identifier for each instance of the DataTables object. If there\\n\\t\\t * is an ID on the table node, then it takes that value, otherwise an\\n\\t\\t * incrementing internal counter is used.\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"sInstance\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * tabindex attribute value that is added to DataTables control elements, allowing\\n\\t\\t * keyboard navigation of the table and its controls.\\n\\t\\t */\\n\\t\\t\\\"iTabIndex\\\": 0,\\n\\t\\n\\t\\t/**\\n\\t\\t * DIV container for the footer scrolling table if scrolling\\n\\t\\t */\\n\\t\\t\\\"nScrollHead\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * DIV container for the footer scrolling table if scrolling\\n\\t\\t */\\n\\t\\t\\\"nScrollFoot\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Last applied sort\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t */\\n\\t\\t\\\"aLastSort\\\": [],\\n\\t\\n\\t\\t/**\\n\\t\\t * Stored plug-in instances\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\t\\\"oPlugins\\\": {},\\n\\t\\n\\t\\t/**\\n\\t\\t * Function used to get a row's id from the row's data\\n\\t\\t * @type function\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"rowIdFn\\\": null,\\n\\t\\n\\t\\t/**\\n\\t\\t * Data location where to store a row's id\\n\\t\\t * @type string\\n\\t\\t * @default null\\n\\t\\t */\\n\\t\\t\\\"rowId\\\": null\\n\\t};\\n\\n\\t/**\\n\\t * Extension object for DataTables that is used to provide all extension\\n\\t * options.\\n\\t *\\n\\t * Note that the `DataTable.ext` object is available through\\n\\t * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\\n\\t * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\\n\\t * @namespace\\n\\t * @extends DataTable.models.ext\\n\\t */\\n\\t\\n\\t\\n\\t/**\\n\\t * DataTables extensions\\n\\t * \\n\\t * This namespace acts as a collection area for plug-ins that can be used to\\n\\t * extend DataTables capabilities. Indeed many of the build in methods\\n\\t * use this method to provide their own capabilities (sorting methods for\\n\\t * example).\\n\\t *\\n\\t * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\\n\\t * reasons\\n\\t *\\n\\t * @namespace\\n\\t */\\n\\tDataTable.ext = _ext = {\\n\\t\\t/**\\n\\t\\t * Buttons. For use with the Buttons extension for DataTables. This is\\n\\t\\t * defined here so other extensions can define buttons regardless of load\\n\\t\\t * order. It is _not_ used by DataTables core.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\tbuttons: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Element class names\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\tclasses: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * DataTables build type (expanded by the download builder)\\n\\t\\t *\\n\\t\\t * @type string\\n\\t\\t */\\n\\t\\tbuilder: \\\"-source-\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Error reporting.\\n\\t\\t * \\n\\t\\t * How should DataTables report an error. Can take the value 'alert',\\n\\t\\t * 'throw', 'none' or a function.\\n\\t\\t *\\n\\t\\t * @type string|function\\n\\t\\t * @default alert\\n\\t\\t */\\n\\t\\terrMode: \\\"alert\\\",\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Feature plug-ins.\\n\\t\\t * \\n\\t\\t * This is an array of objects which describe the feature plug-ins that are\\n\\t\\t * available to DataTables. These feature plug-ins are then available for\\n\\t\\t * use through the `dom` initialisation option.\\n\\t\\t * \\n\\t\\t * Each feature plug-in is described by an object which must have the\\n\\t\\t * following properties:\\n\\t\\t * \\n\\t\\t * * `fnInit` - function that is used to initialise the plug-in,\\n\\t\\t * * `cFeature` - a character so the feature can be enabled by the `dom`\\n\\t\\t * instillation option. This is case sensitive.\\n\\t\\t *\\n\\t\\t * The `fnInit` function has the following input parameters:\\n\\t\\t *\\n\\t\\t * 1. `{object}` DataTables settings object: see\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t *\\n\\t\\t * And the following return is expected:\\n\\t\\t * \\n\\t\\t * * {node|null} The element which contains your feature. Note that the\\n\\t\\t * return may also be void if your plug-in does not require to inject any\\n\\t\\t * DOM elements into DataTables control (`dom`) - for example this might\\n\\t\\t * be useful when developing a plug-in which allows table control via\\n\\t\\t * keyboard entry\\n\\t\\t *\\n\\t\\t * @type array\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * $.fn.dataTable.ext.features.push( {\\n\\t\\t * \\\"fnInit\\\": function( oSettings ) {\\n\\t\\t * return new TableTools( { \\\"oDTSettings\\\": oSettings } );\\n\\t\\t * },\\n\\t\\t * \\\"cFeature\\\": \\\"T\\\"\\n\\t\\t * } );\\n\\t\\t */\\n\\t\\tfeature: [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Row searching.\\n\\t\\t * \\n\\t\\t * This method of searching is complimentary to the default type based\\n\\t\\t * searching, and a lot more comprehensive as it allows you complete control\\n\\t\\t * over the searching logic. Each element in this array is a function\\n\\t\\t * (parameters described below) that is called for every row in the table,\\n\\t\\t * and your logic decides if it should be included in the searching data set\\n\\t\\t * or not.\\n\\t\\t *\\n\\t\\t * Searching functions have the following input parameters:\\n\\t\\t *\\n\\t\\t * 1. `{object}` DataTables settings object: see\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t * 2. `{array|object}` Data for the row to be processed (same as the\\n\\t\\t * original format that was passed in as the data source, or an array\\n\\t\\t * from a DOM data source\\n\\t\\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\\n\\t\\t * can be useful to retrieve the `TR` element if you need DOM interaction.\\n\\t\\t *\\n\\t\\t * And the following return is expected:\\n\\t\\t *\\n\\t\\t * * {boolean} Include the row in the searched result set (true) or not\\n\\t\\t * (false)\\n\\t\\t *\\n\\t\\t * Note that as with the main search ability in DataTables, technically this\\n\\t\\t * is \\\"filtering\\\", since it is subtractive. However, for consistency in\\n\\t\\t * naming we call it searching here.\\n\\t\\t *\\n\\t\\t * @type array\\n\\t\\t * @default []\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // The following example shows custom search being applied to the\\n\\t\\t * // fourth column (i.e. the data[3] index) based on two input values\\n\\t\\t * // from the end-user, matching the data in a certain range.\\n\\t\\t * $.fn.dataTable.ext.search.push(\\n\\t\\t * function( settings, data, dataIndex ) {\\n\\t\\t * var min = document.getElementById('min').value * 1;\\n\\t\\t * var max = document.getElementById('max').value * 1;\\n\\t\\t * var version = data[3] == \\\"-\\\" ? 0 : data[3]*1;\\n\\t\\t *\\n\\t\\t * if ( min == \\\"\\\" && max == \\\"\\\" ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * else if ( min == \\\"\\\" && version < max ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * else if ( min < version && \\\"\\\" == max ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * else if ( min < version && version < max ) {\\n\\t\\t * return true;\\n\\t\\t * }\\n\\t\\t * return false;\\n\\t\\t * }\\n\\t\\t * );\\n\\t\\t */\\n\\t\\tsearch: [],\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Selector extensions\\n\\t\\t *\\n\\t\\t * The `selector` option can be used to extend the options available for the\\n\\t\\t * selector modifier options (`selector-modifier` object data type) that\\n\\t\\t * each of the three built in selector types offer (row, column and cell +\\n\\t\\t * their plural counterparts). For example the Select extension uses this\\n\\t\\t * mechanism to provide an option to select only rows, columns and cells\\n\\t\\t * that have been marked as selected by the end user (`{selected: true}`),\\n\\t\\t * which can be used in conjunction with the existing built in selector\\n\\t\\t * options.\\n\\t\\t *\\n\\t\\t * Each property is an array to which functions can be pushed. The functions\\n\\t\\t * take three attributes:\\n\\t\\t *\\n\\t\\t * * Settings object for the host table\\n\\t\\t * * Options object (`selector-modifier` object type)\\n\\t\\t * * Array of selected item indexes\\n\\t\\t *\\n\\t\\t * The return is an array of the resulting item indexes after the custom\\n\\t\\t * selector has been applied.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t */\\n\\t\\tselector: {\\n\\t\\t\\tcell: [],\\n\\t\\t\\tcolumn: [],\\n\\t\\t\\trow: []\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Internal functions, exposed for used in plug-ins.\\n\\t\\t * \\n\\t\\t * Please note that you should not need to use the internal methods for\\n\\t\\t * anything other than a plug-in (and even then, try to avoid if possible).\\n\\t\\t * The internal function may change between releases.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t */\\n\\t\\tinternal: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Legacy configuration options. Enable and disable legacy options that\\n\\t\\t * are available in DataTables.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t */\\n\\t\\tlegacy: {\\n\\t\\t\\t/**\\n\\t\\t\\t * Enable / disable DataTables 1.9 compatible server-side processing\\n\\t\\t\\t * requests\\n\\t\\t\\t *\\n\\t\\t\\t * @type boolean\\n\\t\\t\\t * @default null\\n\\t\\t\\t */\\n\\t\\t\\tajax: null\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Pagination plug-in methods.\\n\\t\\t * \\n\\t\\t * Each entry in this object is a function and defines which buttons should\\n\\t\\t * be shown by the pagination rendering method that is used for the table:\\n\\t\\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\\n\\t\\t * buttons are displayed in the document, while the functions here tell it\\n\\t\\t * what buttons to display. This is done by returning an array of button\\n\\t\\t * descriptions (what each button will do).\\n\\t\\t *\\n\\t\\t * Pagination types (the four built in options and any additional plug-in\\n\\t\\t * options defined here) can be used through the `paginationType`\\n\\t\\t * initialisation parameter.\\n\\t\\t *\\n\\t\\t * The functions defined take two parameters:\\n\\t\\t *\\n\\t\\t * 1. `{int} page` The current page index\\n\\t\\t * 2. `{int} pages` The number of pages in the table\\n\\t\\t *\\n\\t\\t * Each function is expected to return an array where each element of the\\n\\t\\t * array can be one of:\\n\\t\\t *\\n\\t\\t * * `first` - Jump to first page when activated\\n\\t\\t * * `last` - Jump to last page when activated\\n\\t\\t * * `previous` - Show previous page when activated\\n\\t\\t * * `next` - Show next page when activated\\n\\t\\t * * `{int}` - Show page of the index given\\n\\t\\t * * `{array}` - A nested array containing the above elements to add a\\n\\t\\t * containing 'DIV' element (might be useful for styling).\\n\\t\\t *\\n\\t\\t * Note that DataTables v1.9- used this object slightly differently whereby\\n\\t\\t * an object with two functions would be defined for each plug-in. That\\n\\t\\t * ability is still supported by DataTables 1.10+ to provide backwards\\n\\t\\t * compatibility, but this option of use is now decremented and no longer\\n\\t\\t * documented in DataTables 1.10+.\\n\\t\\t *\\n\\t\\t * @type object\\n\\t\\t * @default {}\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Show previous, next and current page buttons only\\n\\t\\t * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\\n\\t\\t * return [ 'previous', page, 'next' ];\\n\\t\\t * };\\n\\t\\t */\\n\\t\\tpager: {},\\n\\t\\n\\t\\n\\t\\trenderer: {\\n\\t\\t\\tpageButton: {},\\n\\t\\t\\theader: {}\\n\\t\\t},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Ordering plug-ins - custom data source\\n\\t\\t * \\n\\t\\t * The extension options for ordering of data available here is complimentary\\n\\t\\t * to the default type based ordering that DataTables typically uses. It\\n\\t\\t * allows much greater control over the the data that is being used to\\n\\t\\t * order a column, but is necessarily therefore more complex.\\n\\t\\t * \\n\\t\\t * This type of ordering is useful if you want to do ordering based on data\\n\\t\\t * live from the DOM (for example the contents of an 'input' element) rather\\n\\t\\t * than just the static string that DataTables knows of.\\n\\t\\t * \\n\\t\\t * The way these plug-ins work is that you create an array of the values you\\n\\t\\t * wish to be ordering for the column in question and then return that\\n\\t\\t * array. The data in the array much be in the index order of the rows in\\n\\t\\t * the table (not the currently ordering order!). Which order data gathering\\n\\t\\t * function is run here depends on the `dt-init columns.orderDataType`\\n\\t\\t * parameter that is used for the column (if any).\\n\\t\\t *\\n\\t\\t * The functions defined take two parameters:\\n\\t\\t *\\n\\t\\t * 1. `{object}` DataTables settings object: see\\n\\t\\t * {@link DataTable.models.oSettings}\\n\\t\\t * 2. `{int}` Target column index\\n\\t\\t *\\n\\t\\t * Each function is expected to return an array:\\n\\t\\t *\\n\\t\\t * * `{array}` Data for the column to be ordering upon\\n\\t\\t *\\n\\t\\t * @type array\\n\\t\\t *\\n\\t\\t * @example\\n\\t\\t * // Ordering using `input` node values\\n\\t\\t * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )\\n\\t\\t * {\\n\\t\\t * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\\n\\t\\t * return $('input', td).val();\\n\\t\\t * } );\\n\\t\\t * }\\n\\t\\t */\\n\\t\\torder: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Type based plug-ins.\\n\\t\\t *\\n\\t\\t * Each column in DataTables has a type assigned to it, either by automatic\\n\\t\\t * detection or by direct assignment using the `type` option for the column.\\n\\t\\t * The type of a column will effect how it is ordering and search (plug-ins\\n\\t\\t * can also make use of the column type if required).\\n\\t\\t *\\n\\t\\t * @namespace\\n\\t\\t */\\n\\t\\ttype: {\\n\\t\\t\\t/**\\n\\t\\t\\t * Type detection functions.\\n\\t\\t\\t *\\n\\t\\t\\t * The functions defined in this object are used to automatically detect\\n\\t\\t\\t * a column's type, making initialisation of DataTables super easy, even\\n\\t\\t\\t * when complex data is in the table.\\n\\t\\t\\t *\\n\\t\\t\\t * The functions defined take two parameters:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data from the column cell to be analysed\\n\\t\\t * 2. `{settings}` DataTables settings object. This can be used to\\n\\t\\t * perform context specific type detection - for example detection\\n\\t\\t * based on language settings such as using a comma for a decimal\\n\\t\\t * place. Generally speaking the options from the settings will not\\n\\t\\t * be required\\n\\t\\t\\t *\\n\\t\\t\\t * Each function is expected to return:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{string|null}` Data type detected, or null if unknown (and thus\\n\\t\\t\\t * pass it on to the other type detection functions.\\n\\t\\t\\t *\\n\\t\\t\\t * @type array\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Currency type detection plug-in:\\n\\t\\t\\t * $.fn.dataTable.ext.type.detect.push(\\n\\t\\t\\t * function ( data, settings ) {\\n\\t\\t\\t * // Check the numeric part\\n\\t\\t\\t * if ( ! $.isNumeric( data.substring(1) ) ) {\\n\\t\\t\\t * return null;\\n\\t\\t\\t * }\\n\\t\\t\\t *\\n\\t\\t\\t * // Check prefixed by currency\\n\\t\\t\\t * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {\\n\\t\\t\\t * return 'currency';\\n\\t\\t\\t * }\\n\\t\\t\\t * return null;\\n\\t\\t\\t * }\\n\\t\\t\\t * );\\n\\t\\t\\t */\\n\\t\\t\\tdetect: [],\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Type based search formatting.\\n\\t\\t\\t *\\n\\t\\t\\t * The type based searching functions can be used to pre-format the\\n\\t\\t\\t * data to be search on. For example, it can be used to strip HTML\\n\\t\\t\\t * tags or to de-format telephone numbers for numeric only searching.\\n\\t\\t\\t *\\n\\t\\t\\t * Note that is a search is not defined for a column of a given type,\\n\\t\\t\\t * no search formatting will be performed.\\n\\t\\t\\t * \\n\\t\\t\\t * Pre-processing of searching data plug-ins - When you assign the sType\\n\\t\\t\\t * for a column (or have it automatically detected for you by DataTables\\n\\t\\t\\t * or a type detection plug-in), you will typically be using this for\\n\\t\\t\\t * custom sorting, but it can also be used to provide custom searching\\n\\t\\t\\t * by allowing you to pre-processing the data and returning the data in\\n\\t\\t\\t * the format that should be searched upon. This is done by adding\\n\\t\\t\\t * functions this object with a parameter name which matches the sType\\n\\t\\t\\t * for that target column. This is the corollary of <i>afnSortData</i>\\n\\t\\t\\t * for searching data.\\n\\t\\t\\t *\\n\\t\\t\\t * The functions defined take a single parameter:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data from the column cell to be prepared for searching\\n\\t\\t\\t *\\n\\t\\t\\t * Each function is expected to return:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{string|null}` Formatted string that will be used for the searching.\\n\\t\\t\\t *\\n\\t\\t\\t * @type object\\n\\t\\t\\t * @default {}\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\\n\\t\\t\\t * return d.replace(/\\\\n/g,\\\" \\\").replace( /<.*?>/g, \\\"\\\" );\\n\\t\\t\\t * }\\n\\t\\t\\t */\\n\\t\\t\\tsearch: {},\\n\\t\\n\\t\\n\\t\\t\\t/**\\n\\t\\t\\t * Type based ordering.\\n\\t\\t\\t *\\n\\t\\t\\t * The column type tells DataTables what ordering to apply to the table\\n\\t\\t\\t * when a column is sorted upon. The order for each type that is defined,\\n\\t\\t\\t * is defined by the functions available in this object.\\n\\t\\t\\t *\\n\\t\\t\\t * Each ordering option can be described by three properties added to\\n\\t\\t\\t * this object:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{type}-pre` - Pre-formatting function\\n\\t\\t\\t * * `{type}-asc` - Ascending order function\\n\\t\\t\\t * * `{type}-desc` - Descending order function\\n\\t\\t\\t *\\n\\t\\t\\t * All three can be used together, only `{type}-pre` or only\\n\\t\\t\\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\\n\\t\\t\\t * that only `{type}-pre` is used, as this provides the optimal\\n\\t\\t\\t * implementation in terms of speed, although the others are provided\\n\\t\\t\\t * for compatibility with existing Javascript sort functions.\\n\\t\\t\\t *\\n\\t\\t\\t * `{type}-pre`: Functions defined take a single parameter:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data from the column cell to be prepared for ordering\\n\\t\\t\\t *\\n\\t\\t\\t * And return:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{*}` Data to be sorted upon\\n\\t\\t\\t *\\n\\t\\t\\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\\n\\t\\t\\t * functions, taking two parameters:\\n\\t\\t\\t *\\n\\t\\t * 1. `{*}` Data to compare to the second parameter\\n\\t\\t * 2. `{*}` Data to compare to the first parameter\\n\\t\\t\\t *\\n\\t\\t\\t * And returning:\\n\\t\\t\\t *\\n\\t\\t\\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\\n\\t\\t\\t * than the second parameter, ===0 if the two parameters are equal and\\n\\t\\t\\t * >0 if the first parameter should be sorted height than the second\\n\\t\\t\\t * parameter.\\n\\t\\t\\t * \\n\\t\\t\\t * @type object\\n\\t\\t\\t * @default {}\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Numeric ordering of formatted numbers with a pre-formatter\\n\\t\\t\\t * $.extend( $.fn.dataTable.ext.type.order, {\\n\\t\\t\\t * \\\"string-pre\\\": function(x) {\\n\\t\\t\\t * a = (a === \\\"-\\\" || a === \\\"\\\") ? 0 : a.replace( /[^\\\\d\\\\-\\\\.]/g, \\\"\\\" );\\n\\t\\t\\t * return parseFloat( a );\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t *\\n\\t\\t\\t * @example\\n\\t\\t\\t * // Case-sensitive string ordering, with no pre-formatting method\\n\\t\\t\\t * $.extend( $.fn.dataTable.ext.order, {\\n\\t\\t\\t * \\\"string-case-asc\\\": function(x,y) {\\n\\t\\t\\t * return ((x < y) ? -1 : ((x > y) ? 1 : 0));\\n\\t\\t\\t * },\\n\\t\\t\\t * \\\"string-case-desc\\\": function(x,y) {\\n\\t\\t\\t * return ((x < y) ? 1 : ((x > y) ? -1 : 0));\\n\\t\\t\\t * }\\n\\t\\t\\t * } );\\n\\t\\t\\t */\\n\\t\\t\\torder: {}\\n\\t\\t},\\n\\t\\n\\t\\t/**\\n\\t\\t * Unique DataTables instance counter\\n\\t\\t *\\n\\t\\t * @type int\\n\\t\\t * @private\\n\\t\\t */\\n\\t\\t_unique: 0,\\n\\t\\n\\t\\n\\t\\t//\\n\\t\\t// Depreciated\\n\\t\\t// The following properties are retained for backwards compatiblity only.\\n\\t\\t// The should not be used in new projects and will be removed in a future\\n\\t\\t// version\\n\\t\\t//\\n\\t\\n\\t\\t/**\\n\\t\\t * Version check function.\\n\\t\\t * @type function\\n\\t\\t * @depreciated Since 1.10\\n\\t\\t */\\n\\t\\tfnVersionCheck: DataTable.fnVersionCheck,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Index for what 'this' index API functions should use\\n\\t\\t * @type int\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t */\\n\\t\\tiApiIndex: 0,\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * jQuery UI class container\\n\\t\\t * @type object\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t */\\n\\t\\toJUIClasses: {},\\n\\t\\n\\t\\n\\t\\t/**\\n\\t\\t * Software version\\n\\t\\t * @type string\\n\\t\\t * @deprecated Since v1.10\\n\\t\\t */\\n\\t\\tsVersion: DataTable.version\\n\\t};\\n\\t\\n\\t\\n\\t//\\n\\t// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\\n\\t//\\n\\t$.extend( _ext, {\\n\\t\\tafnFiltering: _ext.search,\\n\\t\\taTypes: _ext.type.detect,\\n\\t\\tofnSearch: _ext.type.search,\\n\\t\\toSort: _ext.type.order,\\n\\t\\tafnSortData: _ext.order,\\n\\t\\taoFeatures: _ext.feature,\\n\\t\\toApi: _ext.internal,\\n\\t\\toStdClasses: _ext.classes,\\n\\t\\toPagination: _ext.pager\\n\\t} );\\n\\t\\n\\t\\n\\t$.extend( DataTable.ext.classes, {\\n\\t\\t\\\"sTable\\\": \\\"dataTable\\\",\\n\\t\\t\\\"sNoFooter\\\": \\\"no-footer\\\",\\n\\t\\n\\t\\t/* Paging buttons */\\n\\t\\t\\\"sPageButton\\\": \\\"paginate_button\\\",\\n\\t\\t\\\"sPageButtonActive\\\": \\\"current\\\",\\n\\t\\t\\\"sPageButtonDisabled\\\": \\\"disabled\\\",\\n\\t\\n\\t\\t/* Striping classes */\\n\\t\\t\\\"sStripeOdd\\\": \\\"odd\\\",\\n\\t\\t\\\"sStripeEven\\\": \\\"even\\\",\\n\\t\\n\\t\\t/* Empty row */\\n\\t\\t\\\"sRowEmpty\\\": \\\"dataTables_empty\\\",\\n\\t\\n\\t\\t/* Features */\\n\\t\\t\\\"sWrapper\\\": \\\"dataTables_wrapper\\\",\\n\\t\\t\\\"sFilter\\\": \\\"dataTables_filter\\\",\\n\\t\\t\\\"sInfo\\\": \\\"dataTables_info\\\",\\n\\t\\t\\\"sPaging\\\": \\\"dataTables_paginate paging_\\\", /* Note that the type is postfixed */\\n\\t\\t\\\"sLength\\\": \\\"dataTables_length\\\",\\n\\t\\t\\\"sProcessing\\\": \\\"dataTables_processing\\\",\\n\\t\\n\\t\\t/* Sorting */\\n\\t\\t\\\"sSortAsc\\\": \\\"sorting_asc\\\",\\n\\t\\t\\\"sSortDesc\\\": \\\"sorting_desc\\\",\\n\\t\\t\\\"sSortable\\\": \\\"sorting\\\", /* Sortable in both directions */\\n\\t\\t\\\"sSortableAsc\\\": \\\"sorting_asc_disabled\\\",\\n\\t\\t\\\"sSortableDesc\\\": \\\"sorting_desc_disabled\\\",\\n\\t\\t\\\"sSortableNone\\\": \\\"sorting_disabled\\\",\\n\\t\\t\\\"sSortColumn\\\": \\\"sorting_\\\", /* Note that an int is postfixed for the sorting order */\\n\\t\\n\\t\\t/* Filtering */\\n\\t\\t\\\"sFilterInput\\\": \\\"\\\",\\n\\t\\n\\t\\t/* Page length */\\n\\t\\t\\\"sLengthSelect\\\": \\\"\\\",\\n\\t\\n\\t\\t/* Scrolling */\\n\\t\\t\\\"sScrollWrapper\\\": \\\"dataTables_scroll\\\",\\n\\t\\t\\\"sScrollHead\\\": \\\"dataTables_scrollHead\\\",\\n\\t\\t\\\"sScrollHeadInner\\\": \\\"dataTables_scrollHeadInner\\\",\\n\\t\\t\\\"sScrollBody\\\": \\\"dataTables_scrollBody\\\",\\n\\t\\t\\\"sScrollFoot\\\": \\\"dataTables_scrollFoot\\\",\\n\\t\\t\\\"sScrollFootInner\\\": \\\"dataTables_scrollFootInner\\\",\\n\\t\\n\\t\\t/* Misc */\\n\\t\\t\\\"sHeaderTH\\\": \\\"\\\",\\n\\t\\t\\\"sFooterTH\\\": \\\"\\\",\\n\\t\\n\\t\\t// Deprecated\\n\\t\\t\\\"sSortJUIAsc\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIDesc\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUI\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIAscAllowed\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIDescAllowed\\\": \\\"\\\",\\n\\t\\t\\\"sSortJUIWrapper\\\": \\\"\\\",\\n\\t\\t\\\"sSortIcon\\\": \\\"\\\",\\n\\t\\t\\\"sJUIHeader\\\": \\\"\\\",\\n\\t\\t\\\"sJUIFooter\\\": \\\"\\\"\\n\\t} );\\n\\t\\n\\t\\n\\tvar extPagination = DataTable.ext.pager;\\n\\t\\n\\tfunction _numbers ( page, pages ) {\\n\\t\\tvar\\n\\t\\t\\tnumbers = [],\\n\\t\\t\\tbuttons = extPagination.numbers_length,\\n\\t\\t\\thalf = Math.floor( buttons / 2 ),\\n\\t\\t\\ti = 1;\\n\\t\\n\\t\\tif ( pages <= buttons ) {\\n\\t\\t\\tnumbers = _range( 0, pages );\\n\\t\\t}\\n\\t\\telse if ( page <= half ) {\\n\\t\\t\\tnumbers = _range( 0, buttons-2 );\\n\\t\\t\\tnumbers.push( 'ellipsis' );\\n\\t\\t\\tnumbers.push( pages-1 );\\n\\t\\t}\\n\\t\\telse if ( page >= pages - 1 - half ) {\\n\\t\\t\\tnumbers = _range( pages-(buttons-2), pages );\\n\\t\\t\\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\\n\\t\\t\\tnumbers.splice( 0, 0, 0 );\\n\\t\\t}\\n\\t\\telse {\\n\\t\\t\\tnumbers = _range( page-half+2, page+half-1 );\\n\\t\\t\\tnumbers.push( 'ellipsis' );\\n\\t\\t\\tnumbers.push( pages-1 );\\n\\t\\t\\tnumbers.splice( 0, 0, 'ellipsis' );\\n\\t\\t\\tnumbers.splice( 0, 0, 0 );\\n\\t\\t}\\n\\t\\n\\t\\tnumbers.DT_el = 'span';\\n\\t\\treturn numbers;\\n\\t}\\n\\t\\n\\t\\n\\t$.extend( extPagination, {\\n\\t\\tsimple: function ( page, pages ) {\\n\\t\\t\\treturn [ 'previous', 'next' ];\\n\\t\\t},\\n\\t\\n\\t\\tfull: function ( page, pages ) {\\n\\t\\t\\treturn [ 'first', 'previous', 'next', 'last' ];\\n\\t\\t},\\n\\t\\n\\t\\tnumbers: function ( page, pages ) {\\n\\t\\t\\treturn [ _numbers(page, pages) ];\\n\\t\\t},\\n\\t\\n\\t\\tsimple_numbers: function ( page, pages ) {\\n\\t\\t\\treturn [ 'previous', _numbers(page, pages), 'next' ];\\n\\t\\t},\\n\\t\\n\\t\\tfull_numbers: function ( page, pages ) {\\n\\t\\t\\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\\n\\t\\t},\\n\\t\\t\\n\\t\\tfirst_last_numbers: function (page, pages) {\\n\\t \\t\\treturn ['first', _numbers(page, pages), 'last'];\\n\\t \\t},\\n\\t\\n\\t\\t// For testing and plug-ins to use\\n\\t\\t_numbers: _numbers,\\n\\t\\n\\t\\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\\n\\t\\tnumbers_length: 7\\n\\t} );\\n\\t\\n\\t\\n\\t$.extend( true, DataTable.ext.renderer, {\\n\\t\\tpageButton: {\\n\\t\\t\\t_: function ( settings, host, idx, buttons, page, pages ) {\\n\\t\\t\\t\\tvar classes = settings.oClasses;\\n\\t\\t\\t\\tvar lang = settings.oLanguage.oPaginate;\\n\\t\\t\\t\\tvar aria = settings.oLanguage.oAria.paginate || {};\\n\\t\\t\\t\\tvar btnDisplay, btnClass, counter=0;\\n\\t\\n\\t\\t\\t\\tvar attach = function( container, buttons ) {\\n\\t\\t\\t\\t\\tvar i, ien, node, button;\\n\\t\\t\\t\\t\\tvar clickHandler = function ( e ) {\\n\\t\\t\\t\\t\\t\\t_fnPageChange( settings, e.data.action, true );\\n\\t\\t\\t\\t\\t};\\n\\t\\n\\t\\t\\t\\t\\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\\n\\t\\t\\t\\t\\t\\tbutton = buttons[i];\\n\\t\\n\\t\\t\\t\\t\\t\\tif ( $.isArray( button ) ) {\\n\\t\\t\\t\\t\\t\\t\\tvar inner = $( '<'+(button.DT_el || 'div')+'/>' )\\n\\t\\t\\t\\t\\t\\t\\t\\t.appendTo( container );\\n\\t\\t\\t\\t\\t\\t\\tattach( inner, button );\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\telse {\\n\\t\\t\\t\\t\\t\\t\\tbtnDisplay = null;\\n\\t\\t\\t\\t\\t\\t\\tbtnClass = '';\\n\\t\\n\\t\\t\\t\\t\\t\\t\\tswitch ( button ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'ellipsis':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tcontainer.append('<span class=\\\"ellipsis\\\">…</span>');\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'first':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sFirst;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page > 0 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'previous':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sPrevious;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page > 0 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'next':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sNext;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page < pages-1 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcase 'last':\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = lang.sLast;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = button + (page < pages-1 ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'' : ' '+classes.sPageButtonDisabled);\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tdefault:\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnDisplay = button + 1;\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbtnClass = page === button ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tclasses.sPageButtonActive : '';\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\t\\t\\tif ( btnDisplay !== null ) {\\n\\t\\t\\t\\t\\t\\t\\t\\tnode = $('<a>', {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'class': classes.sPageButton+' '+btnClass,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'aria-controls': settings.sTableId,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'aria-label': aria[ button ],\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'data-dt-idx': counter,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'tabindex': settings.iTabIndex,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t'id': idx === 0 && typeof button === 'string' ?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tsettings.sTableId +'_'+ button :\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tnull\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t} )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.html( btnDisplay )\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t.appendTo( container );\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\t_fnBindAction(\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tnode, {action: button}, clickHandler\\n\\t\\t\\t\\t\\t\\t\\t\\t);\\n\\t\\n\\t\\t\\t\\t\\t\\t\\t\\tcounter++;\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t};\\n\\t\\n\\t\\t\\t\\t// IE9 throws an 'unknown error' if document.activeElement is used\\n\\t\\t\\t\\t// inside an iframe or frame. Try / catch the error. Not good for\\n\\t\\t\\t\\t// accessibility, but neither are frames.\\n\\t\\t\\t\\tvar activeEl;\\n\\t\\n\\t\\t\\t\\ttry {\\n\\t\\t\\t\\t\\t// Because this approach is destroying and recreating the paging\\n\\t\\t\\t\\t\\t// elements, focus is lost on the select button which is bad for\\n\\t\\t\\t\\t\\t// accessibility. So we want to restore focus once the draw has\\n\\t\\t\\t\\t\\t// completed\\n\\t\\t\\t\\t\\tactiveEl = $(host).find(document.activeElement).data('dt-idx');\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tcatch (e) {}\\n\\t\\n\\t\\t\\t\\tattach( $(host).empty(), buttons );\\n\\t\\n\\t\\t\\t\\tif ( activeEl !== undefined ) {\\n\\t\\t\\t\\t\\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\t// Built in type detection. See model.ext.aTypes for information about\\n\\t// what is required from this methods.\\n\\t$.extend( DataTable.ext.type.detect, [\\n\\t\\t// Plain numbers - first since V8 detects some plain numbers as dates\\n\\t\\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// Dates (only those recognised by the browser's Date.parse)\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\t// V8 tries _very_ hard to make a string passed into `Date.parse()`\\n\\t\\t\\t// valid, so we need to use a regex to restrict date formats. Use a\\n\\t\\t\\t// plug-in for anything other than ISO8601 style strings\\n\\t\\t\\tif ( d && !(d instanceof Date) && ! _re_date.test(d) ) {\\n\\t\\t\\t\\treturn null;\\n\\t\\t\\t}\\n\\t\\t\\tvar parsed = Date.parse(d);\\n\\t\\t\\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\\n\\t\\t},\\n\\t\\n\\t\\t// Formatted numbers\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// HTML numeric\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// HTML numeric, formatted\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\tvar decimal = settings.oLanguage.sDecimal;\\n\\t\\t\\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\\n\\t\\t},\\n\\t\\n\\t\\t// HTML (this is strict checking - there must be html)\\n\\t\\tfunction ( d, settings )\\n\\t\\t{\\n\\t\\t\\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\\n\\t\\t\\t\\t'html' : null;\\n\\t\\t}\\n\\t] );\\n\\t\\n\\t\\n\\t\\n\\t// Filter formatting functions. See model.ext.ofnSearch for information about\\n\\t// what is required from these methods.\\n\\t// \\n\\t// Note that additional search methods are added for the html numbers and\\n\\t// html formatted numbers by `_addNumericSort()` when we know what the decimal\\n\\t// place is\\n\\t\\n\\t\\n\\t$.extend( DataTable.ext.type.search, {\\n\\t\\thtml: function ( data ) {\\n\\t\\t\\treturn _empty(data) ?\\n\\t\\t\\t\\tdata :\\n\\t\\t\\t\\ttypeof data === 'string' ?\\n\\t\\t\\t\\t\\tdata\\n\\t\\t\\t\\t\\t\\t.replace( _re_new_lines, \\\" \\\" )\\n\\t\\t\\t\\t\\t\\t.replace( _re_html, \\\"\\\" ) :\\n\\t\\t\\t\\t\\t'';\\n\\t\\t},\\n\\t\\n\\t\\tstring: function ( data ) {\\n\\t\\t\\treturn _empty(data) ?\\n\\t\\t\\t\\tdata :\\n\\t\\t\\t\\ttypeof data === 'string' ?\\n\\t\\t\\t\\t\\tdata.replace( _re_new_lines, \\\" \\\" ) :\\n\\t\\t\\t\\t\\tdata;\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t\\n\\t\\n\\tvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\\n\\t\\tif ( d !== 0 && (!d || d === '-') ) {\\n\\t\\t\\treturn -Infinity;\\n\\t\\t}\\n\\t\\n\\t\\t// If a decimal place other than `.` is used, it needs to be given to the\\n\\t\\t// function so we can detect it and replace with a `.` which is the only\\n\\t\\t// decimal place Javascript recognises - it is not locale aware.\\n\\t\\tif ( decimalPlace ) {\\n\\t\\t\\td = _numToDecimal( d, decimalPlace );\\n\\t\\t}\\n\\t\\n\\t\\tif ( d.replace ) {\\n\\t\\t\\tif ( re1 ) {\\n\\t\\t\\t\\td = d.replace( re1, '' );\\n\\t\\t\\t}\\n\\t\\n\\t\\t\\tif ( re2 ) {\\n\\t\\t\\t\\td = d.replace( re2, '' );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\n\\t\\treturn d * 1;\\n\\t};\\n\\t\\n\\t\\n\\t// Add the numeric 'deformatting' functions for sorting and search. This is done\\n\\t// in a function to provide an easy ability for the language options to add\\n\\t// additional methods if a non-period decimal place is used.\\n\\tfunction _addNumericSort ( decimalPlace ) {\\n\\t\\t$.each(\\n\\t\\t\\t{\\n\\t\\t\\t\\t// Plain numbers\\n\\t\\t\\t\\t\\\"num\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace );\\n\\t\\t\\t\\t},\\n\\t\\n\\t\\t\\t\\t// Formatted numbers\\n\\t\\t\\t\\t\\\"num-fmt\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\\n\\t\\t\\t\\t},\\n\\t\\n\\t\\t\\t\\t// HTML numeric\\n\\t\\t\\t\\t\\\"html-num\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace, _re_html );\\n\\t\\t\\t\\t},\\n\\t\\n\\t\\t\\t\\t// HTML numeric, formatted\\n\\t\\t\\t\\t\\\"html-num-fmt\\\": function ( d ) {\\n\\t\\t\\t\\t\\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\\n\\t\\t\\t\\t}\\n\\t\\t\\t},\\n\\t\\t\\tfunction ( key, fn ) {\\n\\t\\t\\t\\t// Add the ordering method\\n\\t\\t\\t\\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\\n\\t\\n\\t\\t\\t\\t// For HTML types add a search formatter that will strip the HTML\\n\\t\\t\\t\\tif ( key.match(/^html\\\\-/) ) {\\n\\t\\t\\t\\t\\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t);\\n\\t}\\n\\t\\n\\t\\n\\t// Default sort methods\\n\\t$.extend( _ext.type.order, {\\n\\t\\t// Dates\\n\\t\\t\\\"date-pre\\\": function ( d ) {\\n\\t\\t\\treturn Date.parse( d ) || -Infinity;\\n\\t\\t},\\n\\t\\n\\t\\t// html\\n\\t\\t\\\"html-pre\\\": function ( a ) {\\n\\t\\t\\treturn _empty(a) ?\\n\\t\\t\\t\\t'' :\\n\\t\\t\\t\\ta.replace ?\\n\\t\\t\\t\\t\\ta.replace( /<.*?>/g, \\\"\\\" ).toLowerCase() :\\n\\t\\t\\t\\t\\ta+'';\\n\\t\\t},\\n\\t\\n\\t\\t// string\\n\\t\\t\\\"string-pre\\\": function ( a ) {\\n\\t\\t\\t// This is a little complex, but faster than always calling toString,\\n\\t\\t\\t// http://jsperf.com/tostring-v-check\\n\\t\\t\\treturn _empty(a) ?\\n\\t\\t\\t\\t'' :\\n\\t\\t\\t\\ttypeof a === 'string' ?\\n\\t\\t\\t\\t\\ta.toLowerCase() :\\n\\t\\t\\t\\t\\t! a.toString ?\\n\\t\\t\\t\\t\\t\\t'' :\\n\\t\\t\\t\\t\\t\\ta.toString();\\n\\t\\t},\\n\\t\\n\\t\\t// string-asc and -desc are retained only for compatibility with the old\\n\\t\\t// sort methods\\n\\t\\t\\\"string-asc\\\": function ( x, y ) {\\n\\t\\t\\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\\n\\t\\t},\\n\\t\\n\\t\\t\\\"string-desc\\\": function ( x, y ) {\\n\\t\\t\\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t\\n\\t// Numeric sorting types - order doesn't matter here\\n\\t_addNumericSort( '' );\\n\\t\\n\\t\\n\\t$.extend( true, DataTable.ext.renderer, {\\n\\t\\theader: {\\n\\t\\t\\t_: function ( settings, cell, column, classes ) {\\n\\t\\t\\t\\t// No additional mark-up required\\n\\t\\t\\t\\t// Attach a sort listener to update on sort - note that using the\\n\\t\\t\\t\\t// `DT` namespace will allow the event to be removed automatically\\n\\t\\t\\t\\t// on destroy, while the `dt` namespaced event is the one we are\\n\\t\\t\\t\\t// listening for\\n\\t\\t\\t\\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\\n\\t\\t\\t\\t\\tif ( settings !== ctx ) { // need to check this this is the host\\n\\t\\t\\t\\t\\t\\treturn; // table, not a nested one\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tvar colIdx = column.idx;\\n\\t\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.removeClass(\\n\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClass +' '+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortAsc +' '+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortDesc\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t.addClass( columns[ colIdx ] == 'asc' ?\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\\n\\t\\t\\t\\t\\t\\t\\t\\tclasses.sSortDesc :\\n\\t\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClass\\n\\t\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t} );\\n\\t\\t\\t},\\n\\t\\n\\t\\t\\tjqueryui: function ( settings, cell, column, classes ) {\\n\\t\\t\\t\\t$('<div/>')\\n\\t\\t\\t\\t\\t.addClass( classes.sSortJUIWrapper )\\n\\t\\t\\t\\t\\t.append( cell.contents() )\\n\\t\\t\\t\\t\\t.append( $('<span/>')\\n\\t\\t\\t\\t\\t\\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t.appendTo( cell );\\n\\t\\n\\t\\t\\t\\t// Attach a sort listener to update on sort\\n\\t\\t\\t\\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\\n\\t\\t\\t\\t\\tif ( settings !== ctx ) {\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tvar colIdx = column.idx;\\n\\t\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.removeClass( classes.sSortAsc +\\\" \\\"+classes.sSortDesc )\\n\\t\\t\\t\\t\\t\\t.addClass( columns[ colIdx ] == 'asc' ?\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\\n\\t\\t\\t\\t\\t\\t\\t\\tclasses.sSortDesc :\\n\\t\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClass\\n\\t\\t\\t\\t\\t\\t);\\n\\t\\n\\t\\t\\t\\t\\tcell\\n\\t\\t\\t\\t\\t\\t.find( 'span.'+classes.sSortIcon )\\n\\t\\t\\t\\t\\t\\t.removeClass(\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIAsc +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIDesc +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUI +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIAscAllowed +\\\" \\\"+\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIDescAllowed\\n\\t\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t\\t\\t.addClass( columns[ colIdx ] == 'asc' ?\\n\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\\n\\t\\t\\t\\t\\t\\t\\t\\tclasses.sSortJUIDesc :\\n\\t\\t\\t\\t\\t\\t\\t\\tcolumn.sSortingClassJUI\\n\\t\\t\\t\\t\\t\\t);\\n\\t\\t\\t\\t} );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t} );\\n\\t\\n\\t/*\\n\\t * Public helper functions. These aren't used internally by DataTables, or\\n\\t * called by any of the options passed into DataTables, but they can be used\\n\\t * externally by developers working with DataTables. They are helper functions\\n\\t * to make working with DataTables a little bit easier.\\n\\t */\\n\\t\\n\\tvar __htmlEscapeEntities = function ( d ) {\\n\\t\\treturn typeof d === 'string' ?\\n\\t\\t\\td.replace(/</g, '<').replace(/>/g, '>').replace(/\\\"/g, '"') :\\n\\t\\t\\td;\\n\\t};\\n\\t\\n\\t/**\\n\\t * Helpers for `columns.render`.\\n\\t *\\n\\t * The options defined here can be used with the `columns.render` initialisation\\n\\t * option to provide a display renderer. The following functions are defined:\\n\\t *\\n\\t * * `number` - Will format numeric data (defined by `columns.data`) for\\n\\t * display, retaining the original unformatted data for sorting and filtering.\\n\\t * It takes 5 parameters:\\n\\t * * `string` - Thousands grouping separator\\n\\t * * `string` - Decimal point indicator\\n\\t * * `integer` - Number of decimal points to show\\n\\t * * `string` (optional) - Prefix.\\n\\t * * `string` (optional) - Postfix (/suffix).\\n\\t * * `text` - Escape HTML to help prevent XSS attacks. It has no optional\\n\\t * parameters.\\n\\t *\\n\\t * @example\\n\\t * // Column definition using the number renderer\\n\\t * {\\n\\t * data: \\\"salary\\\",\\n\\t * render: $.fn.dataTable.render.number( '\\\\'', '.', 0, '$' )\\n\\t * }\\n\\t *\\n\\t * @namespace\\n\\t */\\n\\tDataTable.render = {\\n\\t\\tnumber: function ( thousands, decimal, precision, prefix, postfix ) {\\n\\t\\t\\treturn {\\n\\t\\t\\t\\tdisplay: function ( d ) {\\n\\t\\t\\t\\t\\tif ( typeof d !== 'number' && typeof d !== 'string' ) {\\n\\t\\t\\t\\t\\t\\treturn d;\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tvar negative = d < 0 ? '-' : '';\\n\\t\\t\\t\\t\\tvar flo = parseFloat( d );\\n\\t\\n\\t\\t\\t\\t\\t// If NaN then there isn't much formatting that we can do - just\\n\\t\\t\\t\\t\\t// return immediately, escaping any HTML (this was supposed to\\n\\t\\t\\t\\t\\t// be a number after all)\\n\\t\\t\\t\\t\\tif ( isNaN( flo ) ) {\\n\\t\\t\\t\\t\\t\\treturn __htmlEscapeEntities( d );\\n\\t\\t\\t\\t\\t}\\n\\t\\n\\t\\t\\t\\t\\tflo = flo.toFixed( precision );\\n\\t\\t\\t\\t\\td = Math.abs( flo );\\n\\t\\n\\t\\t\\t\\t\\tvar intPart = parseInt( d, 10 );\\n\\t\\t\\t\\t\\tvar floatPart = precision ?\\n\\t\\t\\t\\t\\t\\tdecimal+(d - intPart).toFixed( precision ).substring( 2 ):\\n\\t\\t\\t\\t\\t\\t'';\\n\\t\\n\\t\\t\\t\\t\\treturn negative + (prefix||'') +\\n\\t\\t\\t\\t\\t\\tintPart.toString().replace(\\n\\t\\t\\t\\t\\t\\t\\t/\\\\B(?=(\\\\d{3})+(?!\\\\d))/g, thousands\\n\\t\\t\\t\\t\\t\\t) +\\n\\t\\t\\t\\t\\t\\tfloatPart +\\n\\t\\t\\t\\t\\t\\t(postfix||'');\\n\\t\\t\\t\\t}\\n\\t\\t\\t};\\n\\t\\t},\\n\\t\\n\\t\\ttext: function () {\\n\\t\\t\\treturn {\\n\\t\\t\\t\\tdisplay: __htmlEscapeEntities\\n\\t\\t\\t};\\n\\t\\t}\\n\\t};\\n\\t\\n\\t\\n\\t/*\\n\\t * This is really a good bit rubbish this method of exposing the internal methods\\n\\t * publicly... - To be fixed in 2.0 using methods on the prototype\\n\\t */\\n\\t\\n\\t\\n\\t/**\\n\\t * Create a wrapper function for exporting an internal functions to an external API.\\n\\t * @param {string} fn API function name\\n\\t * @returns {function} wrapped function\\n\\t * @memberof DataTable#internal\\n\\t */\\n\\tfunction _fnExternApiFunc (fn)\\n\\t{\\n\\t\\treturn function() {\\n\\t\\t\\tvar args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(\\n\\t\\t\\t\\tArray.prototype.slice.call(arguments)\\n\\t\\t\\t);\\n\\t\\t\\treturn DataTable.ext.internal[fn].apply( this, args );\\n\\t\\t};\\n\\t}\\n\\t\\n\\t\\n\\t/**\\n\\t * Reference to internal functions for use by plug-in developers. Note that\\n\\t * these methods are references to internal functions and are considered to be\\n\\t * private. If you use these methods, be aware that they are liable to change\\n\\t * between versions.\\n\\t * @namespace\\n\\t */\\n\\t$.extend( DataTable.ext.internal, {\\n\\t\\t_fnExternApiFunc: _fnExternApiFunc,\\n\\t\\t_fnBuildAjax: _fnBuildAjax,\\n\\t\\t_fnAjaxUpdate: _fnAjaxUpdate,\\n\\t\\t_fnAjaxParameters: _fnAjaxParameters,\\n\\t\\t_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,\\n\\t\\t_fnAjaxDataSrc: _fnAjaxDataSrc,\\n\\t\\t_fnAddColumn: _fnAddColumn,\\n\\t\\t_fnColumnOptions: _fnColumnOptions,\\n\\t\\t_fnAdjustColumnSizing: _fnAdjustColumnSizing,\\n\\t\\t_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,\\n\\t\\t_fnColumnIndexToVisible: _fnColumnIndexToVisible,\\n\\t\\t_fnVisbleColumns: _fnVisbleColumns,\\n\\t\\t_fnGetColumns: _fnGetColumns,\\n\\t\\t_fnColumnTypes: _fnColumnTypes,\\n\\t\\t_fnApplyColumnDefs: _fnApplyColumnDefs,\\n\\t\\t_fnHungarianMap: _fnHungarianMap,\\n\\t\\t_fnCamelToHungarian: _fnCamelToHungarian,\\n\\t\\t_fnLanguageCompat: _fnLanguageCompat,\\n\\t\\t_fnBrowserDetect: _fnBrowserDetect,\\n\\t\\t_fnAddData: _fnAddData,\\n\\t\\t_fnAddTr: _fnAddTr,\\n\\t\\t_fnNodeToDataIndex: _fnNodeToDataIndex,\\n\\t\\t_fnNodeToColumnIndex: _fnNodeToColumnIndex,\\n\\t\\t_fnGetCellData: _fnGetCellData,\\n\\t\\t_fnSetCellData: _fnSetCellData,\\n\\t\\t_fnSplitObjNotation: _fnSplitObjNotation,\\n\\t\\t_fnGetObjectDataFn: _fnGetObjectDataFn,\\n\\t\\t_fnSetObjectDataFn: _fnSetObjectDataFn,\\n\\t\\t_fnGetDataMaster: _fnGetDataMaster,\\n\\t\\t_fnClearTable: _fnClearTable,\\n\\t\\t_fnDeleteIndex: _fnDeleteIndex,\\n\\t\\t_fnInvalidate: _fnInvalidate,\\n\\t\\t_fnGetRowElements: _fnGetRowElements,\\n\\t\\t_fnCreateTr: _fnCreateTr,\\n\\t\\t_fnBuildHead: _fnBuildHead,\\n\\t\\t_fnDrawHead: _fnDrawHead,\\n\\t\\t_fnDraw: _fnDraw,\\n\\t\\t_fnReDraw: _fnReDraw,\\n\\t\\t_fnAddOptionsHtml: _fnAddOptionsHtml,\\n\\t\\t_fnDetectHeader: _fnDetectHeader,\\n\\t\\t_fnGetUniqueThs: _fnGetUniqueThs,\\n\\t\\t_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,\\n\\t\\t_fnFilterComplete: _fnFilterComplete,\\n\\t\\t_fnFilterCustom: _fnFilterCustom,\\n\\t\\t_fnFilterColumn: _fnFilterColumn,\\n\\t\\t_fnFilter: _fnFilter,\\n\\t\\t_fnFilterCreateSearch: _fnFilterCreateSearch,\\n\\t\\t_fnEscapeRegex: _fnEscapeRegex,\\n\\t\\t_fnFilterData: _fnFilterData,\\n\\t\\t_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,\\n\\t\\t_fnUpdateInfo: _fnUpdateInfo,\\n\\t\\t_fnInfoMacros: _fnInfoMacros,\\n\\t\\t_fnInitialise: _fnInitialise,\\n\\t\\t_fnInitComplete: _fnInitComplete,\\n\\t\\t_fnLengthChange: _fnLengthChange,\\n\\t\\t_fnFeatureHtmlLength: _fnFeatureHtmlLength,\\n\\t\\t_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,\\n\\t\\t_fnPageChange: _fnPageChange,\\n\\t\\t_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,\\n\\t\\t_fnProcessingDisplay: _fnProcessingDisplay,\\n\\t\\t_fnFeatureHtmlTable: _fnFeatureHtmlTable,\\n\\t\\t_fnScrollDraw: _fnScrollDraw,\\n\\t\\t_fnApplyToChildren: _fnApplyToChildren,\\n\\t\\t_fnCalculateColumnWidths: _fnCalculateColumnWidths,\\n\\t\\t_fnThrottle: _fnThrottle,\\n\\t\\t_fnConvertToWidth: _fnConvertToWidth,\\n\\t\\t_fnGetWidestNode: _fnGetWidestNode,\\n\\t\\t_fnGetMaxLenString: _fnGetMaxLenString,\\n\\t\\t_fnStringToCss: _fnStringToCss,\\n\\t\\t_fnSortFlatten: _fnSortFlatten,\\n\\t\\t_fnSort: _fnSort,\\n\\t\\t_fnSortAria: _fnSortAria,\\n\\t\\t_fnSortListener: _fnSortListener,\\n\\t\\t_fnSortAttachListener: _fnSortAttachListener,\\n\\t\\t_fnSortingClasses: _fnSortingClasses,\\n\\t\\t_fnSortData: _fnSortData,\\n\\t\\t_fnSaveState: _fnSaveState,\\n\\t\\t_fnLoadState: _fnLoadState,\\n\\t\\t_fnSettingsFromNode: _fnSettingsFromNode,\\n\\t\\t_fnLog: _fnLog,\\n\\t\\t_fnMap: _fnMap,\\n\\t\\t_fnBindAction: _fnBindAction,\\n\\t\\t_fnCallbackReg: _fnCallbackReg,\\n\\t\\t_fnCallbackFire: _fnCallbackFire,\\n\\t\\t_fnLengthOverflow: _fnLengthOverflow,\\n\\t\\t_fnRenderer: _fnRenderer,\\n\\t\\t_fnDataSource: _fnDataSource,\\n\\t\\t_fnRowAttributes: _fnRowAttributes,\\n\\t\\t_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant\\n\\t\\t // in 1.10, so this dead-end function is\\n\\t\\t // added to prevent errors\\n\\t} );\\n\\t\\n\\n\\t// jQuery access\\n\\t$.fn.dataTable = DataTable;\\n\\n\\t// Provide access to the host jQuery object (circular reference)\\n\\tDataTable.$ = $;\\n\\n\\t// Legacy aliases\\n\\t$.fn.dataTableSettings = DataTable.settings;\\n\\t$.fn.dataTableExt = DataTable.ext;\\n\\n\\t// With a capital `D` we return a DataTables API instance rather than a\\n\\t// jQuery object\\n\\t$.fn.DataTable = function ( opts ) {\\n\\t\\treturn $(this).dataTable( opts ).api();\\n\\t};\\n\\n\\t// All properties that are available to $.fn.dataTable should also be\\n\\t// available on $.fn.DataTable\\n\\t$.each( DataTable, function ( prop, val ) {\\n\\t\\t$.fn.DataTable[ prop ] = val;\\n\\t} );\\n\\n\\n\\t// Information about events fired by DataTables - for documentation.\\n\\t/**\\n\\t * Draw event, fired whenever the table is redrawn on the page, at the same\\n\\t * point as fnDrawCallback. This may be useful for binding events or\\n\\t * performing calculations when the table is altered at all.\\n\\t * @name DataTable#draw.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Search event, fired when the searching applied to the table (using the\\n\\t * built-in global search, or column filters) is altered.\\n\\t * @name DataTable#search.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Page change event, fired when the paging of the table is altered.\\n\\t * @name DataTable#page.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Order event, fired when the ordering applied to the table is altered.\\n\\t * @name DataTable#order.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * DataTables initialisation complete event, fired when the table is fully\\n\\t * drawn, including Ajax data loaded, if Ajax data is required.\\n\\t * @name DataTable#init.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The JSON object request from the server - only\\n\\t * present if client-side Ajax sourced data is used</li></ol>\\n\\t */\\n\\n\\t/**\\n\\t * State save event, fired when the table has changed state a new state save\\n\\t * is required. This event allows modification of the state saving object\\n\\t * prior to actually doing the save, including addition or other state\\n\\t * properties (for plug-ins) or modification of a DataTables core property.\\n\\t * @name DataTable#stateSaveParams.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The state information to be saved\\n\\t */\\n\\n\\t/**\\n\\t * State load event, fired when the table is loading state from the stored\\n\\t * data, but prior to the settings object being modified by the saved state\\n\\t * - allowing modification of the saved state is required or loading of\\n\\t * state for a plug-in.\\n\\t * @name DataTable#stateLoadParams.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The saved state information\\n\\t */\\n\\n\\t/**\\n\\t * State loaded event, fired when state has been loaded from stored data and\\n\\t * the settings object has been modified by the loaded data.\\n\\t * @name DataTable#stateLoaded.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {object} json The saved state information\\n\\t */\\n\\n\\t/**\\n\\t * Processing event, fired when DataTables is doing some kind of processing\\n\\t * (be it, order, searcg or anything else). It can be used to indicate to\\n\\t * the end user that there is something happening, or that something has\\n\\t * finished.\\n\\t * @name DataTable#processing.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} oSettings DataTables settings object\\n\\t * @param {boolean} bShow Flag for if DataTables is doing processing or not\\n\\t */\\n\\n\\t/**\\n\\t * Ajax (XHR) event, fired whenever an Ajax request is completed from a\\n\\t * request to made to the server for new data. This event is called before\\n\\t * DataTables processed the returned data, so it can also be used to pre-\\n\\t * process the data returned from the server, if needed.\\n\\t *\\n\\t * Note that this trigger is called in `fnServerData`, if you override\\n\\t * `fnServerData` and which to use this event, you need to trigger it in you\\n\\t * success function.\\n\\t * @name DataTable#xhr.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t * @param {object} json JSON returned from the server\\n\\t *\\n\\t * @example\\n\\t * // Use a custom property returned from the server in another DOM element\\n\\t * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\\n\\t * $('#status').html( json.status );\\n\\t * } );\\n\\t *\\n\\t * @example\\n\\t * // Pre-process the data returned from the server\\n\\t * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\\n\\t * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {\\n\\t * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;\\n\\t * }\\n\\t * // Note no return - manipulate the data directly in the JSON object.\\n\\t * } );\\n\\t */\\n\\n\\t/**\\n\\t * Destroy event, fired when the DataTable is destroyed by calling fnDestroy\\n\\t * or passing the bDestroy:true parameter in the initialisation object. This\\n\\t * can be used to remove bound events, added DOM nodes, etc.\\n\\t * @name DataTable#destroy.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Page length change event, fired when number of records to show on each\\n\\t * page (the length) is changed.\\n\\t * @name DataTable#length.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t * @param {integer} len New length\\n\\t */\\n\\n\\t/**\\n\\t * Column sizing has changed.\\n\\t * @name DataTable#column-sizing.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t */\\n\\n\\t/**\\n\\t * Column visibility has changed.\\n\\t * @name DataTable#column-visibility.dt\\n\\t * @event\\n\\t * @param {event} e jQuery event object\\n\\t * @param {object} o DataTables settings object {@link DataTable.models.oSettings}\\n\\t * @param {int} column Column index\\n\\t * @param {bool} vis `false` if column now hidden, or `true` if visible\\n\\t */\\n\\n\\treturn $.fn.dataTable;\\n}));\\n\\n /* END jquery.dataTables.js*/\\n\\n\\nvar event = document.createEvent(\\\"HTMLEvents\\\");\\nevent.initEvent(\\\"load_datatables\\\", false, false);\\nwindow.dispatchEvent(event);\\nconsole.log(\\\"Finish loading datatables js files\\\");\\n\\n\\n</script>\\n<style type='text/css'>\\n /* BEGIN jquery.dataTables.css */\\n\\n/*\\n * Table styles\\n */\\ntable.dataTable {\\n width: 100%;\\n margin: 0 auto;\\n clear: both;\\n border-collapse: separate;\\n border-spacing: 0;\\n /*\\n * Header and footer styles\\n */\\n /*\\n * Body styles\\n */\\n}\\ntable.dataTable thead th,\\ntable.dataTable tfoot th {\\n font-weight: bold;\\n}\\ntable.dataTable thead th,\\ntable.dataTable thead td {\\n padding: 10px 18px;\\n border-bottom: 1px solid #111111;\\n}\\ntable.dataTable thead th:active,\\ntable.dataTable thead td:active {\\n outline: none;\\n}\\ntable.dataTable tfoot th,\\ntable.dataTable tfoot td {\\n padding: 10px 18px 6px 18px;\\n border-top: 1px solid #111111;\\n}\\ntable.dataTable thead .sorting,\\ntable.dataTable thead .sorting_asc,\\ntable.dataTable thead .sorting_desc,\\ntable.dataTable thead .sorting_asc_disabled,\\ntable.dataTable thead .sorting_desc_disabled {\\n cursor: pointer;\\n *cursor: hand;\\n background-repeat: no-repeat;\\n background-position: center right;\\n}\\ntable.dataTable thead .sorting {\\n background-image: url(\\\"../images/sort_both.png\\\");\\n}\\ntable.dataTable thead .sorting_asc {\\n background-image: url(\\\"../images/sort_asc.png\\\");\\n}\\ntable.dataTable thead .sorting_desc {\\n background-image: url(\\\"../images/sort_desc.png\\\");\\n}\\ntable.dataTable thead .sorting_asc_disabled {\\n background-image: url(\\\"../images/sort_asc_disabled.png\\\");\\n}\\ntable.dataTable thead .sorting_desc_disabled {\\n background-image: url(\\\"../images/sort_desc_disabled.png\\\");\\n}\\ntable.dataTable tbody tr {\\n background-color: white;\\n}\\ntable.dataTable tbody tr.selected {\\n background-color: #b0bed9;\\n}\\ntable.dataTable tbody th,\\ntable.dataTable tbody td {\\n padding: 8px 10px;\\n}\\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\\n border-top: 1px solid #dddddd;\\n}\\ntable.dataTable.row-border tbody tr:first-child th,\\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\\ntable.dataTable.display tbody tr:first-child td {\\n border-top: none;\\n}\\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\\n border-top: 1px solid #dddddd;\\n border-right: 1px solid #dddddd;\\n}\\ntable.dataTable.cell-border tbody tr th:first-child,\\ntable.dataTable.cell-border tbody tr td:first-child {\\n border-left: 1px solid #dddddd;\\n}\\ntable.dataTable.cell-border tbody tr:first-child th,\\ntable.dataTable.cell-border tbody tr:first-child td {\\n border-top: none;\\n}\\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\\n background-color: #f9f9f9;\\n}\\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\\n background-color: #abb9d3;\\n}\\ntable.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\\n background-color: whitesmoke;\\n}\\ntable.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\\n background-color: #a9b7d1;\\n}\\ntable.dataTable.order-column tbody tr > .sorting_1,\\ntable.dataTable.order-column tbody tr > .sorting_2,\\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\\ntable.dataTable.display tbody tr > .sorting_2,\\ntable.dataTable.display tbody tr > .sorting_3 {\\n background-color: #f9f9f9;\\n}\\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\\ntable.dataTable.display tbody tr.selected > .sorting_2,\\ntable.dataTable.display tbody tr.selected > .sorting_3 {\\n background-color: #acbad4;\\n}\\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\\n background-color: #f1f1f1;\\n}\\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\\n background-color: #f3f3f3;\\n}\\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\\n background-color: whitesmoke;\\n}\\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\\n background-color: #a6b3cd;\\n}\\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\\n background-color: #a7b5ce;\\n}\\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\\n background-color: #a9b6d0;\\n}\\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\\n background-color: #f9f9f9;\\n}\\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\\n background-color: #fbfbfb;\\n}\\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\\n background-color: #fdfdfd;\\n}\\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\\n background-color: #acbad4;\\n}\\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\\n background-color: #adbbd6;\\n}\\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\\n background-color: #afbdd8;\\n}\\ntable.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\\n background-color: #eaeaea;\\n}\\ntable.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\\n background-color: #ebebeb;\\n}\\ntable.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\\n background-color: #eeeeee;\\n}\\ntable.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\\n background-color: #a1aec7;\\n}\\ntable.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\\n background-color: #a2afc8;\\n}\\ntable.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\\n background-color: #a4b2cb;\\n}\\ntable.dataTable.no-footer {\\n border-bottom: 1px solid #111111;\\n}\\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\\n white-space: nowrap;\\n}\\ntable.dataTable.compact thead th,\\ntable.dataTable.compact thead td {\\n padding: 4px 17px 4px 4px;\\n}\\ntable.dataTable.compact tfoot th,\\ntable.dataTable.compact tfoot td {\\n padding: 4px;\\n}\\ntable.dataTable.compact tbody th,\\ntable.dataTable.compact tbody td {\\n padding: 4px;\\n}\\ntable.dataTable th.dt-left,\\ntable.dataTable td.dt-left {\\n text-align: left;\\n}\\ntable.dataTable th.dt-center,\\ntable.dataTable td.dt-center,\\ntable.dataTable td.dataTables_empty {\\n text-align: center;\\n}\\ntable.dataTable th.dt-right,\\ntable.dataTable td.dt-right {\\n text-align: right;\\n}\\ntable.dataTable th.dt-justify,\\ntable.dataTable td.dt-justify {\\n text-align: justify;\\n}\\ntable.dataTable th.dt-nowrap,\\ntable.dataTable td.dt-nowrap {\\n white-space: nowrap;\\n}\\ntable.dataTable thead th.dt-head-left,\\ntable.dataTable thead td.dt-head-left,\\ntable.dataTable tfoot th.dt-head-left,\\ntable.dataTable tfoot td.dt-head-left {\\n text-align: left;\\n}\\ntable.dataTable thead th.dt-head-center,\\ntable.dataTable thead td.dt-head-center,\\ntable.dataTable tfoot th.dt-head-center,\\ntable.dataTable tfoot td.dt-head-center {\\n text-align: center;\\n}\\ntable.dataTable thead th.dt-head-right,\\ntable.dataTable thead td.dt-head-right,\\ntable.dataTable tfoot th.dt-head-right,\\ntable.dataTable tfoot td.dt-head-right {\\n text-align: right;\\n}\\ntable.dataTable thead th.dt-head-justify,\\ntable.dataTable thead td.dt-head-justify,\\ntable.dataTable tfoot th.dt-head-justify,\\ntable.dataTable tfoot td.dt-head-justify {\\n text-align: justify;\\n}\\ntable.dataTable thead th.dt-head-nowrap,\\ntable.dataTable thead td.dt-head-nowrap,\\ntable.dataTable tfoot th.dt-head-nowrap,\\ntable.dataTable tfoot td.dt-head-nowrap {\\n white-space: nowrap;\\n}\\ntable.dataTable tbody th.dt-body-left,\\ntable.dataTable tbody td.dt-body-left {\\n text-align: left;\\n}\\ntable.dataTable tbody th.dt-body-center,\\ntable.dataTable tbody td.dt-body-center {\\n text-align: center;\\n}\\ntable.dataTable tbody th.dt-body-right,\\ntable.dataTable tbody td.dt-body-right {\\n text-align: right;\\n}\\ntable.dataTable tbody th.dt-body-justify,\\ntable.dataTable tbody td.dt-body-justify {\\n text-align: justify;\\n}\\ntable.dataTable tbody th.dt-body-nowrap,\\ntable.dataTable tbody td.dt-body-nowrap {\\n white-space: nowrap;\\n}\\n\\ntable.dataTable,\\ntable.dataTable th,\\ntable.dataTable td {\\n box-sizing: content-box;\\n}\\n\\n/*\\n * Control feature layout\\n */\\n.dataTables_wrapper {\\n position: relative;\\n clear: both;\\n *zoom: 1;\\n zoom: 1;\\n}\\n.dataTables_wrapper .dataTables_length {\\n float: left;\\n}\\n.dataTables_wrapper .dataTables_filter {\\n float: right;\\n text-align: right;\\n}\\n.dataTables_wrapper .dataTables_filter input {\\n margin-left: 0.5em;\\n}\\n.dataTables_wrapper .dataTables_info {\\n clear: both;\\n float: left;\\n padding-top: 0.755em;\\n}\\n.dataTables_wrapper .dataTables_paginate {\\n float: right;\\n text-align: right;\\n padding-top: 0.25em;\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button {\\n box-sizing: border-box;\\n display: inline-block;\\n min-width: 1.5em;\\n padding: 0.5em 1em;\\n margin-left: 2px;\\n text-align: center;\\n text-decoration: none !important;\\n cursor: pointer;\\n *cursor: hand;\\n color: #333333 !important;\\n border: 1px solid transparent;\\n border-radius: 2px;\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\\n color: #333333 !important;\\n border: 1px solid #979797;\\n background-color: white;\\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, gainsboro));\\n /* Chrome,Safari4+ */\\n background: -webkit-linear-gradient(top, white 0%, gainsboro 100%);\\n /* Chrome10+,Safari5.1+ */\\n background: -moz-linear-gradient(top, white 0%, gainsboro 100%);\\n /* FF3.6+ */\\n background: -ms-linear-gradient(top, white 0%, gainsboro 100%);\\n /* IE10+ */\\n background: -o-linear-gradient(top, white 0%, gainsboro 100%);\\n /* Opera 11.10+ */\\n background: linear-gradient(to bottom, white 0%, gainsboro 100%);\\n /* W3C */\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\\n cursor: default;\\n color: #666 !important;\\n border: 1px solid transparent;\\n background: transparent;\\n box-shadow: none;\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button:hover {\\n color: white !important;\\n border: 1px solid #111111;\\n background-color: #585858;\\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111111));\\n /* Chrome,Safari4+ */\\n background: -webkit-linear-gradient(top, #585858 0%, #111111 100%);\\n /* Chrome10+,Safari5.1+ */\\n background: -moz-linear-gradient(top, #585858 0%, #111111 100%);\\n /* FF3.6+ */\\n background: -ms-linear-gradient(top, #585858 0%, #111111 100%);\\n /* IE10+ */\\n background: -o-linear-gradient(top, #585858 0%, #111111 100%);\\n /* Opera 11.10+ */\\n background: linear-gradient(to bottom, #585858 0%, #111111 100%);\\n /* W3C */\\n}\\n.dataTables_wrapper .dataTables_paginate .paginate_button:active {\\n outline: none;\\n background-color: #2b2b2b;\\n background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));\\n /* Chrome,Safari4+ */\\n background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* Chrome10+,Safari5.1+ */\\n background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* FF3.6+ */\\n background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* IE10+ */\\n background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\\n /* Opera 11.10+ */\\n background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);\\n /* W3C */\\n box-shadow: inset 0 0 3px #111;\\n}\\n.dataTables_wrapper .dataTables_paginate .ellipsis {\\n padding: 0 1em;\\n}\\n.dataTables_wrapper .dataTables_processing {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n width: 100%;\\n height: 40px;\\n margin-left: -50%;\\n margin-top: -25px;\\n padding-top: 20px;\\n text-align: center;\\n font-size: 1.2em;\\n background-color: white;\\n background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\\n background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\\n}\\n.dataTables_wrapper .dataTables_length,\\n.dataTables_wrapper .dataTables_filter,\\n.dataTables_wrapper .dataTables_info,\\n.dataTables_wrapper .dataTables_processing,\\n.dataTables_wrapper .dataTables_paginate {\\n color: #333333;\\n}\\n.dataTables_wrapper .dataTables_scroll {\\n clear: both;\\n}\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\\n *margin-top: -1px;\\n -webkit-overflow-scrolling: touch;\\n}\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td {\\n vertical-align: middle;\\n}\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > th > div.dataTables_sizing,\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > thead > tr > td > div.dataTables_sizing, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > th > div.dataTables_sizing,\\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody > table > tbody > tr > td > div.dataTables_sizing {\\n height: 0;\\n overflow: hidden;\\n margin: 0 !important;\\n padding: 0 !important;\\n}\\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\\n border-bottom: 1px solid #111111;\\n}\\n.dataTables_wrapper.no-footer div.dataTables_scrollHead > table,\\n.dataTables_wrapper.no-footer div.dataTables_scrollBody > table {\\n border-bottom: none;\\n}\\n.dataTables_wrapper:after {\\n visibility: hidden;\\n display: block;\\n content: \\\"\\\";\\n clear: both;\\n height: 0;\\n}\\n\\n@media screen and (max-width: 767px) {\\n .dataTables_wrapper .dataTables_info,\\n .dataTables_wrapper .dataTables_paginate {\\n float: none;\\n text-align: center;\\n }\\n .dataTables_wrapper .dataTables_paginate {\\n margin-top: 0.5em;\\n }\\n}\\n@media screen and (max-width: 640px) {\\n .dataTables_wrapper .dataTables_length,\\n .dataTables_wrapper .dataTables_filter {\\n float: none;\\n text-align: center;\\n }\\n .dataTables_wrapper .dataTables_filter {\\n margin-top: 0.5em;\\n }\\n}\\n\\n /* END jquery.dataTables.css*/\\n\\n\\n\\n\\n</style>\"" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# to add style and js in webpage\n", "DataTables.init_script" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "<script type='text/javascript'>\n", " \n", "$(document).ready(function() {\n", "\n", " $('#ec313946-be9a-47ca-aea7-05892929957e').DataTable(\n", " {data: [[1,1,1],[1,2,3],[11,12,13],[1,2,3],[11,12,13],[1,2,3],[11,12,13]], pageLength: 4}\n", " );\n", "\n", "});\n", "</script>\n" ], "text/plain": [ "#<DataTables::DataTable:0x007fd4d1e010c0 @options={:data=>[[1, 1, 1], [1, 2, 3], [11, 12, 13], [1, 2, 3], [11, 12, 13], [1, 2, 3], [11, 12, 13]], :pageLength=>4}>" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t_opts = {\n", " data: [[1,1,1],\n", " [1,2,3],\n", " [11,12,13],\n", " [1,2,3],\n", " [11,12,13],\n", " [1,2,3],\n", " [11,12,13]\n", " ],\n", " pageLength: 4\n", " }\n", " table_from_array = DataTables::DataTable.new(t_opts)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"#<DataTables::DataTable:0x007fd4d1e010c0 @options={:data=>[[1, 1, 1], [1, 2, 3], [11, 12, 13], [1, 2, 3], [11, 12, 13], [1, 2, 3], [11, 12, 13]], :pageLength=>4}>\"" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table_from_array.inspect" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"\\n<script type='text/javascript'>\\n \\n$(document).ready(function() {\\n\\n $('#table_id3').DataTable(\\n {data: [[1,1,1],[1,2,3],[11,12,13],[1,2,3],[11,12,13],[1,2,3],[11,12,13]], pageLength: 4}\\n );\\n\\n});\\n</script>\\n<table class=\\\"display\\\" cellspacing=\\\"0\\\" width=\\\"50%\\\" id=\\\"table_id3\\\">\\n <thead>\\n <tr>\\n <th>Num1 </th>\\n <th>Num2 </th>\\n <th>Num3 </th>\\n </tr>\\n </thead></table>\"" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table_opts = {\n", " class: \"display\",\n", " cellspacing: \"0\",\n", " width: \"50%\",\n", " table_html: \"\n", " <thead>\n", " <tr>\n", " <th>Num1 </th>\n", " <th>Num2 </th>\n", " <th>Num3 </th>\n", " </tr>\n", " </thead>\"\n", " }\n", " options = {\n", " table_options: table_opts\n", " }\n", "html_code_array_sorted = table_from_array.to_html(id='table_id3', options)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "<script type='text/javascript'>\n", " \n", "$(document).ready(function() {\n", "\n", " $('#table_id3').DataTable(\n", " {data: [[1,1,1],[1,2,3],[11,12,13],[1,2,3],[11,12,13],[1,2,3],[11,12,13]], pageLength: 4}\n", " );\n", "\n", "});\n", "</script>\n", "<table class=\"display\" cellspacing=\"0\" width=\"50%\" id=\"table_id3\">\n", " <thead>\n", " <tr>\n", " <th>Num1 </th>\n", " <th>Num2 </th>\n", " <th>Num3 </th>\n", " </tr>\n", " </thead></table>" ], "text/plain": [ "\"\\n<script type='text/javascript'>\\n \\n$(document).ready(function() {\\n\\n $('#table_id3').DataTable(\\n {data: [[1,1,1],[1,2,3],[11,12,13],[1,2,3],[11,12,13],[1,2,3],[11,12,13]], pageLength: 4}\\n );\\n\\n});\\n</script>\\n<table class=\\\"display\\\" cellspacing=\\\"0\\\" width=\\\"50%\\\" id=\\\"table_id3\\\">\\n <thead>\\n <tr>\\n <th>Num1 </th>\\n <th>Num2 </th>\\n <th>Num3 </th>\\n </tr>\\n </thead></table>\"" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "IRuby.html html_code_array_sorted" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\n", "Install the spreadsheet gem version ~>1.1.1 for using spreadsheet functions.\n", "\n", "Install the mechanize gem version ~>2.7.5 for using mechanize functions.\n" ] }, { "data": { "text/plain": [ "true" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "require 'daru'" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "<script type='text/javascript'>\n", " \n", "$(document).ready(function() {\n", "\n", " $('#table_id2').DataTable(\n", " {pageLength: 4}\n", " );\n", "\n", "});\n", "</script>\n", "<table class=\"display\" cellspacing=\"0\" width=\"100%\" id=\"table_id2\"><thead>\n", " \n", " <tr>\n", " <th></th>\n", " \n", " <th>a</th>\n", " \n", " <th>b</th>\n", " \n", " <th>c</th>\n", " \n", " </tr>\n", " \n", "</thead><tbody>\n", " \n", " <tr>\n", " <td>one</td>\n", " \n", " <td>1</td>\n", " \n", " <td>11</td>\n", " \n", " <td>11</td>\n", " \n", " </tr>\n", " \n", " <tr>\n", " <td>two</td>\n", " \n", " <td>2</td>\n", " \n", " <td>12</td>\n", " \n", " <td>22</td>\n", " \n", " </tr>\n", " \n", " <tr>\n", " <td>three</td>\n", " \n", " <td>3</td>\n", " \n", " <td>13</td>\n", " \n", " <td>33</td>\n", " \n", " </tr>\n", " \n", " <tr>\n", " <td>four</td>\n", " \n", " <td>4</td>\n", " \n", " <td>14</td>\n", " \n", " <td>44</td>\n", " \n", " </tr>\n", " \n", " <tr>\n", " <td>five</td>\n", " \n", " <td>5</td>\n", " \n", " <td>15</td>\n", " \n", " <td>55</td>\n", " \n", " </tr>\n", " \n", "\n", " \n", "</tbody></table>" ], "text/plain": [ "\"\\n<script type='text/javascript'>\\n \\n$(document).ready(function() {\\n\\n $('#table_id2').DataTable(\\n {pageLength: 4}\\n );\\n\\n});\\n</script>\\n<table class=\\\"display\\\" cellspacing=\\\"0\\\" width=\\\"100%\\\" id=\\\"table_id2\\\"><thead>\\n \\n <tr>\\n <th></th>\\n \\n <th>a</th>\\n \\n <th>b</th>\\n \\n <th>c</th>\\n \\n </tr>\\n \\n</thead><tbody>\\n \\n <tr>\\n <td>one</td>\\n \\n <td>1</td>\\n \\n <td>11</td>\\n \\n <td>11</td>\\n \\n </tr>\\n \\n <tr>\\n <td>two</td>\\n \\n <td>2</td>\\n \\n <td>12</td>\\n \\n <td>22</td>\\n \\n </tr>\\n \\n <tr>\\n <td>three</td>\\n \\n <td>3</td>\\n \\n <td>13</td>\\n \\n <td>33</td>\\n \\n </tr>\\n \\n <tr>\\n <td>four</td>\\n \\n <td>4</td>\\n \\n <td>14</td>\\n \\n <td>44</td>\\n \\n </tr>\\n \\n <tr>\\n <td>five</td>\\n \\n <td>5</td>\\n \\n <td>15</td>\\n \\n <td>55</td>\\n \\n </tr>\\n \\n\\n \\n</tbody></table>\"" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],\n", " c: [11,22,33,44,55]},\n", " order: [:a, :b, :c],\n", " index: [:one, :two, :three, :four, :five])\n", "t = DataTables::DataTable.new(pageLength: 4)\n", " table_opts = {\n", " class: \"display\",\n", " cellspacing: \"0\",\n", " width: \"100%\"\n", " }\n", " options = {\n", " table_options: table_opts\n", " }\n", " options[:table_options][:table_html] = @df.to_html_thead + @df.to_html_tbody\n", "html_code2 = t.to_html(id='table_id2', options)\n", "IRuby.html html_code2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Ruby 2.3.1", "language": "ruby", "name": "ruby" }, "language_info": { "file_extension": ".rb", "mimetype": "application/x-ruby", "name": "ruby", "version": "2.3.1" } }, "nbformat": 4, "nbformat_minor": 2 }