WP Mail Bank: WordPress SMTP Plugin & Email Logs - Version 2.0.7

Version Description

  • Major Bug Fixed Related to Email Mime Types
  • Js Code Optimized
  • Chinese Language Added
  • Romanian Language Added
  • Arabic Language Added
  • English(Australian) Language Added
Download this release

Release Info

Developer contact-banker
Plugin Icon 128x128 WP Mail Bank: WordPress SMTP Plugin & Email Logs
Version 2.0.7
Comparing to
See all releases

Code changes from version 2.0.6 to 2.0.7

assets/global/plugins/datatables/media/js/jquery.datatables.js CHANGED
@@ -1,15277 +1,3 @@
1
- (/** @lends <global> */function( window, document, undefined ) {
2
-
3
- (function( factory ) {
4
- "use strict";
5
-
6
- if ( typeof define === 'function' && define.amd ) {
7
- // Define as an AMD module if possible
8
- define( 'datatables', ['jquery'], factory );
9
- }
10
- else if ( typeof exports === 'object' ) {
11
- // Node/CommonJS
12
- module.exports = factory( require( 'jquery' ) );
13
- }
14
- else if ( jQuery && !jQuery.fn.dataTable ) {
15
- // Define using browser globals otherwise
16
- // Prevent multiple instantiations if the script is loaded twice
17
- factory( jQuery );
18
- }
19
- }
20
- (/** @lends <global> */function( $ ) {
21
- "use strict";
22
-
23
- /**
24
- * DataTables is a plug-in for the jQuery Javascript library. It is a highly
25
- * flexible tool, based upon the foundations of progressive enhancement,
26
- * which will add advanced interaction controls to any HTML table. For a
27
- * full list of features please refer to
28
- * [DataTables.net](href="http://datatables.net).
29
- *
30
- * Note that the `DataTable` object is not a global variable but is aliased
31
- * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
32
- * be accessed.
33
- *
34
- * @class
35
- * @param {object} [init={}] Configuration object for DataTables. Options
36
- * are defined by {@link DataTable.defaults}
37
- * @requires jQuery 1.7+
38
- *
39
- * @example
40
- * // Basic initialisation
41
- * $(document).ready( function {
42
- * $('#example').dataTable();
43
- * } );
44
- *
45
- * @example
46
- * // Initialisation with configuration options - in this case, disable
47
- * // pagination and sorting.
48
- * $(document).ready( function {
49
- * $('#example').dataTable( {
50
- * "paginate": false,
51
- * "sort": false
52
- * } );
53
- * } );
54
- */
55
- var DataTable;
56
-
57
-
58
- /*
59
- * It is useful to have variables which are scoped locally so only the
60
- * DataTables functions can access them and they don't leak into global space.
61
- * At the same time these functions are often useful over multiple files in the
62
- * core and API, so we list, or at least document, all variables which are used
63
- * by DataTables as private variables here. This also ensures that there is no
64
- * clashing of variable names and that they can easily referenced for reuse.
65
- */
66
-
67
-
68
- // Defined else where
69
- // _selector_run
70
- // _selector_opts
71
- // _selector_first
72
- // _selector_row_indexes
73
-
74
- var _ext; // DataTable.ext
75
- var _Api; // DataTable.Api
76
- var _api_register; // DataTable.Api.register
77
- var _api_registerPlural; // DataTable.Api.registerPlural
78
-
79
- var _re_dic = {};
80
- var _re_new_lines = /[\r\n]/g;
81
- var _re_html = /<.*?>/g;
82
- var _re_date_start = /^[\w\+\-]/;
83
- var _re_date_end = /[\w\+\-]$/;
84
-
85
- // Escape regular expression special characters
86
- var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
87
-
88
- // http://en.wikipedia.org/wiki/Foreign_exchange_market
89
- // - \u20BD - Russian ruble.
90
- // - \u20a9 - South Korean Won
91
- // - \u20BA - Turkish Lira
92
- // - \u20B9 - Indian Rupee
93
- // - R - Brazil (R$) and South Africa
94
- // - fr - Swiss Franc
95
- // - kr - Swedish krona, Norwegian krone and Danish krone
96
- // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
97
- // standards as thousands separators.
98
- var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
99
-
100
-
101
- var _empty = function ( d ) {
102
- return !d || d === true || d === '-' ? true : false;
103
- };
104
-
105
-
106
- var _intVal = function ( s ) {
107
- var integer = parseInt( s, 10 );
108
- return !isNaN(integer) && isFinite(s) ? integer : null;
109
- };
110
-
111
- // Convert from a formatted number with characters other than `.` as the
112
- // decimal place, to a Javascript number
113
- var _numToDecimal = function ( num, decimalPoint ) {
114
- // Cache created regular expressions for speed as this function is called often
115
- if ( ! _re_dic[ decimalPoint ] ) {
116
- _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
117
- }
118
- return typeof num === 'string' && decimalPoint !== '.' ?
119
- num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
120
- num;
121
- };
122
-
123
-
124
- var _isNumber = function ( d, decimalPoint, formatted ) {
125
- var strType = typeof d === 'string';
126
-
127
- // If empty return immediately so there must be a number if it is a
128
- // formatted string (this stops the string "k", or "kr", etc being detected
129
- // as a formatted number for currency
130
- if ( _empty( d ) ) {
131
- return true;
132
- }
133
-
134
- if ( decimalPoint && strType ) {
135
- d = _numToDecimal( d, decimalPoint );
136
- }
137
-
138
- if ( formatted && strType ) {
139
- d = d.replace( _re_formatted_numeric, '' );
140
- }
141
-
142
- return !isNaN( parseFloat(d) ) && isFinite( d );
143
- };
144
-
145
-
146
- // A string without HTML in it can be considered to be HTML still
147
- var _isHtml = function ( d ) {
148
- return _empty( d ) || typeof d === 'string';
149
- };
150
-
151
-
152
- var _htmlNumeric = function ( d, decimalPoint, formatted ) {
153
- if ( _empty( d ) ) {
154
- return true;
155
- }
156
-
157
- var html = _isHtml( d );
158
- return ! html ?
159
- null :
160
- _isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
161
- true :
162
- null;
163
- };
164
-
165
-
166
- var _pluck = function ( a, prop, prop2 ) {
167
- var out = [];
168
- var i=0, ien=a.length;
169
-
170
- // Could have the test in the loop for slightly smaller code, but speed
171
- // is essential here
172
- if ( prop2 !== undefined ) {
173
- for ( ; i<ien ; i++ ) {
174
- if ( a[i] && a[i][ prop ] ) {
175
- out.push( a[i][ prop ][ prop2 ] );
176
- }
177
- }
178
- }
179
- else {
180
- for ( ; i<ien ; i++ ) {
181
- if ( a[i] ) {
182
- out.push( a[i][ prop ] );
183
- }
184
- }
185
- }
186
-
187
- return out;
188
- };
189
-
190
-
191
- // Basically the same as _pluck, but rather than looping over `a` we use `order`
192
- // as the indexes to pick from `a`
193
- var _pluck_order = function ( a, order, prop, prop2 )
194
- {
195
- var out = [];
196
- var i=0, ien=order.length;
197
-
198
- // Could have the test in the loop for slightly smaller code, but speed
199
- // is essential here
200
- if ( prop2 !== undefined ) {
201
- for ( ; i<ien ; i++ ) {
202
- if ( a[ order[i] ][ prop ] ) {
203
- out.push( a[ order[i] ][ prop ][ prop2 ] );
204
- }
205
- }
206
- }
207
- else {
208
- for ( ; i<ien ; i++ ) {
209
- out.push( a[ order[i] ][ prop ] );
210
- }
211
- }
212
-
213
- return out;
214
- };
215
-
216
-
217
- var _range = function ( len, start )
218
- {
219
- var out = [];
220
- var end;
221
-
222
- if ( start === undefined ) {
223
- start = 0;
224
- end = len;
225
- }
226
- else {
227
- end = start;
228
- start = len;
229
- }
230
-
231
- for ( var i=start ; i<end ; i++ ) {
232
- out.push( i );
233
- }
234
-
235
- return out;
236
- };
237
-
238
-
239
- var _removeEmpty = function ( a )
240
- {
241
- var out = [];
242
-
243
- for ( var i=0, ien=a.length ; i<ien ; i++ ) {
244
- if ( a[i] ) { // careful - will remove all falsy values!
245
- out.push( a[i] );
246
- }
247
- }
248
-
249
- return out;
250
- };
251
-
252
-
253
- var _stripHtml = function ( d ) {
254
- return d.replace( _re_html, '' );
255
- };
256
-
257
-
258
- /**
259
- * Find the unique elements in a source array.
260
- *
261
- * @param {array} src Source array
262
- * @return {array} Array of unique items
263
- * @ignore
264
- */
265
- var _unique = function ( src )
266
- {
267
- // A faster unique method is to use object keys to identify used values,
268
- // but this doesn't work with arrays or objects, which we must also
269
- // consider. See jsperf.com/compare-array-unique-versions/4 for more
270
- // information.
271
- var
272
- out = [],
273
- val,
274
- i, ien=src.length,
275
- j, k=0;
276
-
277
- again: for ( i=0 ; i<ien ; i++ ) {
278
- val = src[i];
279
-
280
- for ( j=0 ; j<k ; j++ ) {
281
- if ( out[j] === val ) {
282
- continue again;
283
- }
284
- }
285
-
286
- out.push( val );
287
- k++;
288
- }
289
-
290
- return out;
291
- };
292
-
293
-
294
-
295
- /**
296
- * Create a mapping object that allows camel case parameters to be looked up
297
- * for their Hungarian counterparts. The mapping is stored in a private
298
- * parameter called `_hungarianMap` which can be accessed on the source object.
299
- * @param {object} o
300
- * @memberof DataTable#oApi
301
- */
302
- function _fnHungarianMap ( o )
303
- {
304
- var
305
- hungarian = 'a aa ai ao as b fn i m o s ',
306
- match,
307
- newKey,
308
- map = {};
309
-
310
- $.each( o, function (key, val) {
311
- match = key.match(/^([^A-Z]+?)([A-Z])/);
312
-
313
- if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
314
- {
315
- newKey = key.replace( match[0], match[2].toLowerCase() );
316
- map[ newKey ] = key;
317
-
318
- if ( match[1] === 'o' )
319
- {
320
- _fnHungarianMap( o[key] );
321
- }
322
- }
323
- } );
324
-
325
- o._hungarianMap = map;
326
- }
327
-
328
-
329
- /**
330
- * Convert from camel case parameters to Hungarian, based on a Hungarian map
331
- * created by _fnHungarianMap.
332
- * @param {object} src The model object which holds all parameters that can be
333
- * mapped.
334
- * @param {object} user The object to convert from camel case to Hungarian.
335
- * @param {boolean} force When set to `true`, properties which already have a
336
- * Hungarian value in the `user` object will be overwritten. Otherwise they
337
- * won't be.
338
- * @memberof DataTable#oApi
339
- */
340
- function _fnCamelToHungarian ( src, user, force )
341
- {
342
- if ( ! src._hungarianMap ) {
343
- _fnHungarianMap( src );
344
- }
345
-
346
- var hungarianKey;
347
-
348
- $.each( user, function (key, val) {
349
- hungarianKey = src._hungarianMap[ key ];
350
-
351
- if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
352
- {
353
- // For objects, we need to buzz down into the object to copy parameters
354
- if ( hungarianKey.charAt(0) === 'o' )
355
- {
356
- // Copy the camelCase options over to the hungarian
357
- if ( ! user[ hungarianKey ] ) {
358
- user[ hungarianKey ] = {};
359
- }
360
- $.extend( true, user[hungarianKey], user[key] );
361
-
362
- _fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
363
- }
364
- else {
365
- user[hungarianKey] = user[ key ];
366
- }
367
- }
368
- } );
369
- }
370
-
371
-
372
- /**
373
- * Language compatibility - when certain options are given, and others aren't, we
374
- * need to duplicate the values over, in order to provide backwards compatibility
375
- * with older language files.
376
- * @param {object} oSettings dataTables settings object
377
- * @memberof DataTable#oApi
378
- */
379
- function _fnLanguageCompat( lang )
380
- {
381
- var defaults = DataTable.defaults.oLanguage;
382
- var zeroRecords = lang.sZeroRecords;
383
-
384
- /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
385
- * sZeroRecords - assuming that is given.
386
- */
387
- if ( ! lang.sEmptyTable && zeroRecords &&
388
- defaults.sEmptyTable === "No data available in table" )
389
- {
390
- _fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
391
- }
392
-
393
- /* Likewise with loading records */
394
- if ( ! lang.sLoadingRecords && zeroRecords &&
395
- defaults.sLoadingRecords === "Loading..." )
396
- {
397
- _fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
398
- }
399
-
400
- // Old parameter name of the thousands separator mapped onto the new
401
- if ( lang.sInfoThousands ) {
402
- lang.sThousands = lang.sInfoThousands;
403
- }
404
-
405
- var decimal = lang.sDecimal;
406
- if ( decimal ) {
407
- _addNumericSort( decimal );
408
- }
409
- }
410
-
411
-
412
- /**
413
- * Map one parameter onto another
414
- * @param {object} o Object to map
415
- * @param {*} knew The new parameter name
416
- * @param {*} old The old parameter name
417
- */
418
- var _fnCompatMap = function ( o, knew, old ) {
419
- if ( o[ knew ] !== undefined ) {
420
- o[ old ] = o[ knew ];
421
- }
422
- };
423
-
424
-
425
- /**
426
- * Provide backwards compatibility for the main DT options. Note that the new
427
- * options are mapped onto the old parameters, so this is an external interface
428
- * change only.
429
- * @param {object} init Object to map
430
- */
431
- function _fnCompatOpts ( init )
432
- {
433
- _fnCompatMap( init, 'ordering', 'bSort' );
434
- _fnCompatMap( init, 'orderMulti', 'bSortMulti' );
435
- _fnCompatMap( init, 'orderClasses', 'bSortClasses' );
436
- _fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
437
- _fnCompatMap( init, 'order', 'aaSorting' );
438
- _fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
439
- _fnCompatMap( init, 'paging', 'bPaginate' );
440
- _fnCompatMap( init, 'pagingType', 'sPaginationType' );
441
- _fnCompatMap( init, 'pageLength', 'iDisplayLength' );
442
- _fnCompatMap( init, 'searching', 'bFilter' );
443
-
444
- // Boolean initialisation of x-scrolling
445
- if ( typeof init.sScrollX === 'boolean' ) {
446
- init.sScrollX = init.sScrollX ? '100%' : '';
447
- }
448
-
449
- // Column search objects are in an array, so it needs to be converted
450
- // element by element
451
- var searchCols = init.aoSearchCols;
452
-
453
- if ( searchCols ) {
454
- for ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {
455
- if ( searchCols[i] ) {
456
- _fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );
457
- }
458
- }
459
- }
460
- }
461
-
462
-
463
- /**
464
- * Provide backwards compatibility for column options. Note that the new options
465
- * are mapped onto the old parameters, so this is an external interface change
466
- * only.
467
- * @param {object} init Object to map
468
- */
469
- function _fnCompatCols ( init )
470
- {
471
- _fnCompatMap( init, 'orderable', 'bSortable' );
472
- _fnCompatMap( init, 'orderData', 'aDataSort' );
473
- _fnCompatMap( init, 'orderSequence', 'asSorting' );
474
- _fnCompatMap( init, 'orderDataType', 'sortDataType' );
475
-
476
- // orderData can be given as an integer
477
- var dataSort = init.aDataSort;
478
- if ( dataSort && ! $.isArray( dataSort ) ) {
479
- init.aDataSort = [ dataSort ];
480
- }
481
- }
482
-
483
-
484
- /**
485
- * Browser feature detection for capabilities, quirks
486
- * @param {object} settings dataTables settings object
487
- * @memberof DataTable#oApi
488
- */
489
- function _fnBrowserDetect( settings )
490
- {
491
- // We don't need to do this every time DataTables is constructed, the values
492
- // calculated are specific to the browser and OS configuration which we
493
- // don't expect to change between initialisations
494
- if ( ! DataTable.__browser ) {
495
- var browser = {};
496
- DataTable.__browser = browser;
497
-
498
- // Scrolling feature / quirks detection
499
- var n = $('<div/>')
500
- .css( {
501
- position: 'fixed',
502
- top: 0,
503
- left: 0,
504
- height: 1,
505
- width: 1,
506
- overflow: 'hidden'
507
- } )
508
- .append(
509
- $('<div/>')
510
- .css( {
511
- position: 'absolute',
512
- top: 1,
513
- left: 1,
514
- width: 100,
515
- overflow: 'scroll'
516
- } )
517
- .append(
518
- $('<div/>')
519
- .css( {
520
- width: '100%',
521
- height: 10
522
- } )
523
- )
524
- )
525
- .appendTo( 'body' );
526
-
527
- var outer = n.children();
528
- var inner = outer.children();
529
-
530
- // Numbers below, in order, are:
531
- // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
532
- //
533
- // IE6 XP: 100 100 100 83
534
- // IE7 Vista: 100 100 100 83
535
- // IE 8+ Windows: 83 83 100 83
536
- // Evergreen Windows: 83 83 100 83
537
- // Evergreen Mac with scrollbars: 85 85 100 85
538
- // Evergreen Mac without scrollbars: 100 100 100 100
539
-
540
- // Get scrollbar width
541
- browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
542
-
543
- // IE6/7 will oversize a width 100% element inside a scrolling element, to
544
- // include the width of the scrollbar, while other browsers ensure the inner
545
- // element is contained without forcing scrolling
546
- //console.log( inner.offsetWidth );
547
- browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
548
-
549
- // In rtl text layout, some browsers (most, but not all) will place the
550
- // scrollbar on the left, rather than the right.
551
- browser.bScrollbarLeft = Math.round( inner.offset().left ) !== 1;
552
-
553
- // IE8- don't provide height and width for getBoundingClientRect
554
- browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
555
-
556
- n.remove();
557
- }
558
-
559
- $.extend( settings.oBrowser, DataTable.__browser );
560
- settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
561
- }
562
-
563
-
564
- /**
565
- * Array.prototype reduce[Right] method, used for browsers which don't support
566
- * JS 1.6. Done this way to reduce code size, since we iterate either way
567
- * @param {object} settings dataTables settings object
568
- * @memberof DataTable#oApi
569
- */
570
- function _fnReduce ( that, fn, init, start, end, inc )
571
- {
572
- var
573
- i = start,
574
- value,
575
- isSet = false;
576
-
577
- if ( init !== undefined ) {
578
- value = init;
579
- isSet = true;
580
- }
581
-
582
- while ( i !== end ) {
583
- if ( ! that.hasOwnProperty(i) ) {
584
- continue;
585
- }
586
-
587
- value = isSet ?
588
- fn( value, that[i], i, that ) :
589
- that[i];
590
-
591
- isSet = true;
592
- i += inc;
593
- }
594
-
595
- return value;
596
- }
597
-
598
- /**
599
- * Add a column to the list used for the table with default values
600
- * @param {object} oSettings dataTables settings object
601
- * @param {node} nTh The th element for this column
602
- * @memberof DataTable#oApi
603
- */
604
- function _fnAddColumn( oSettings, nTh )
605
- {
606
- // Add column to aoColumns array
607
- var oDefaults = DataTable.defaults.column;
608
- var iCol = oSettings.aoColumns.length;
609
- var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
610
- "nTh": nTh ? nTh : document.createElement('th'),
611
- "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
612
- "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
613
- "mData": oDefaults.mData ? oDefaults.mData : iCol,
614
- idx: iCol
615
- } );
616
- oSettings.aoColumns.push( oCol );
617
-
618
- // Add search object for column specific search. Note that the `searchCols[ iCol ]`
619
- // passed into extend can be undefined. This allows the user to give a default
620
- // with only some of the parameters defined, and also not give a default
621
- var searchCols = oSettings.aoPreSearchCols;
622
- searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
623
-
624
- // Use the default column options function to initialise classes etc
625
- _fnColumnOptions( oSettings, iCol, $(nTh).data() );
626
- }
627
-
628
-
629
- /**
630
- * Apply options for a column
631
- * @param {object} oSettings dataTables settings object
632
- * @param {int} iCol column index to consider
633
- * @param {object} oOptions object with sType, bVisible and bSearchable etc
634
- * @memberof DataTable#oApi
635
- */
636
- function _fnColumnOptions( oSettings, iCol, oOptions )
637
- {
638
- var oCol = oSettings.aoColumns[ iCol ];
639
- var oClasses = oSettings.oClasses;
640
- var th = $(oCol.nTh);
641
-
642
- // Try to get width information from the DOM. We can't get it from CSS
643
- // as we'd need to parse the CSS stylesheet. `width` option can override
644
- if ( ! oCol.sWidthOrig ) {
645
- // Width attribute
646
- oCol.sWidthOrig = th.attr('width') || null;
647
-
648
- // Style attribute
649
- var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
650
- if ( t ) {
651
- oCol.sWidthOrig = t[1];
652
- }
653
- }
654
-
655
- /* User specified column options */
656
- if ( oOptions !== undefined && oOptions !== null )
657
- {
658
- // Backwards compatibility
659
- _fnCompatCols( oOptions );
660
-
661
- // Map camel case parameters to their Hungarian counterparts
662
- _fnCamelToHungarian( DataTable.defaults.column, oOptions );
663
-
664
- /* Backwards compatibility for mDataProp */
665
- if ( oOptions.mDataProp !== undefined && !oOptions.mData )
666
- {
667
- oOptions.mData = oOptions.mDataProp;
668
- }
669
-
670
- if ( oOptions.sType )
671
- {
672
- oCol._sManualType = oOptions.sType;
673
- }
674
-
675
- // `class` is a reserved word in Javascript, so we need to provide
676
- // the ability to use a valid name for the camel case input
677
- if ( oOptions.className && ! oOptions.sClass )
678
- {
679
- oOptions.sClass = oOptions.className;
680
- }
681
-
682
- $.extend( oCol, oOptions );
683
- _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
684
-
685
- /* iDataSort to be applied (backwards compatibility), but aDataSort will take
686
- * priority if defined
687
- */
688
- if ( oOptions.iDataSort !== undefined )
689
- {
690
- oCol.aDataSort = [ oOptions.iDataSort ];
691
- }
692
- _fnMap( oCol, oOptions, "aDataSort" );
693
- }
694
-
695
- /* Cache the data get and set functions for speed */
696
- var mDataSrc = oCol.mData;
697
- var mData = _fnGetObjectDataFn( mDataSrc );
698
- var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
699
-
700
- var attrTest = function( src ) {
701
- return typeof src === 'string' && src.indexOf('@') !== -1;
702
- };
703
- oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
704
- attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
705
- );
706
-
707
- oCol.fnGetData = function (rowData, type, meta) {
708
- var innerData = mData( rowData, type, undefined, meta );
709
-
710
- return mRender && type ?
711
- mRender( innerData, type, rowData, meta ) :
712
- innerData;
713
- };
714
- oCol.fnSetData = function ( rowData, val, meta ) {
715
- return _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );
716
- };
717
-
718
- // Indicate if DataTables should read DOM data as an object or array
719
- // Used in _fnGetRowElements
720
- if ( typeof mDataSrc !== 'number' ) {
721
- oSettings._rowReadObject = true;
722
- }
723
-
724
- /* Feature sorting overrides column specific when off */
725
- if ( !oSettings.oFeatures.bSort )
726
- {
727
- oCol.bSortable = false;
728
- th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
729
- }
730
-
731
- /* Check that the class assignment is correct for sorting */
732
- var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
733
- var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
734
- if ( !oCol.bSortable || (!bAsc && !bDesc) )
735
- {
736
- oCol.sSortingClass = oClasses.sSortableNone;
737
- oCol.sSortingClassJUI = "";
738
- }
739
- else if ( bAsc && !bDesc )
740
- {
741
- oCol.sSortingClass = oClasses.sSortableAsc;
742
- oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
743
- }
744
- else if ( !bAsc && bDesc )
745
- {
746
- oCol.sSortingClass = oClasses.sSortableDesc;
747
- oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
748
- }
749
- else
750
- {
751
- oCol.sSortingClass = oClasses.sSortable;
752
- oCol.sSortingClassJUI = oClasses.sSortJUI;
753
- }
754
- }
755
-
756
-
757
- /**
758
- * Adjust the table column widths for new data. Note: you would probably want to
759
- * do a redraw after calling this function!
760
- * @param {object} settings dataTables settings object
761
- * @memberof DataTable#oApi
762
- */
763
- function _fnAdjustColumnSizing ( settings )
764
- {
765
- /* Not interested in doing column width calculation if auto-width is disabled */
766
- if ( settings.oFeatures.bAutoWidth !== false )
767
- {
768
- var columns = settings.aoColumns;
769
-
770
- _fnCalculateColumnWidths( settings );
771
- for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
772
- {
773
- columns[i].nTh.style.width = columns[i].sWidth;
774
- }
775
- }
776
-
777
- var scroll = settings.oScroll;
778
- if ( scroll.sY !== '' || scroll.sX !== '')
779
- {
780
- _fnScrollDraw( settings );
781
- }
782
-
783
- _fnCallbackFire( settings, null, 'column-sizing', [settings] );
784
- }
785
-
786
-
787
- /**
788
- * Covert the index of a visible column to the index in the data array (take account
789
- * of hidden columns)
790
- * @param {object} oSettings dataTables settings object
791
- * @param {int} iMatch Visible column index to lookup
792
- * @returns {int} i the data index
793
- * @memberof DataTable#oApi
794
- */
795
- function _fnVisibleToColumnIndex( oSettings, iMatch )
796
- {
797
- var aiVis = _fnGetColumns( oSettings, 'bVisible' );
798
-
799
- return typeof aiVis[iMatch] === 'number' ?
800
- aiVis[iMatch] :
801
- null;
802
- }
803
-
804
-
805
- /**
806
- * Covert the index of an index in the data array and convert it to the visible
807
- * column index (take account of hidden columns)
808
- * @param {int} iMatch Column index to lookup
809
- * @param {object} oSettings dataTables settings object
810
- * @returns {int} i the data index
811
- * @memberof DataTable#oApi
812
- */
813
- function _fnColumnIndexToVisible( oSettings, iMatch )
814
- {
815
- var aiVis = _fnGetColumns( oSettings, 'bVisible' );
816
- var iPos = $.inArray( iMatch, aiVis );
817
-
818
- return iPos !== -1 ? iPos : null;
819
- }
820
-
821
-
822
- /**
823
- * Get the number of visible columns
824
- * @param {object} oSettings dataTables settings object
825
- * @returns {int} i the number of visible columns
826
- * @memberof DataTable#oApi
827
- */
828
- function _fnVisbleColumns( oSettings )
829
- {
830
- return _fnGetColumns( oSettings, 'bVisible' ).length;
831
- }
832
-
833
-
834
- /**
835
- * Get an array of column indexes that match a given property
836
- * @param {object} oSettings dataTables settings object
837
- * @param {string} sParam Parameter in aoColumns to look for - typically
838
- * bVisible or bSearchable
839
- * @returns {array} Array of indexes with matched properties
840
- * @memberof DataTable#oApi
841
- */
842
- function _fnGetColumns( oSettings, sParam )
843
- {
844
- var a = [];
845
-
846
- $.map( oSettings.aoColumns, function(val, i) {
847
- if ( val[sParam] ) {
848
- a.push( i );
849
- }
850
- } );
851
-
852
- return a;
853
- }
854
-
855
-
856
- /**
857
- * Calculate the 'type' of a column
858
- * @param {object} settings dataTables settings object
859
- * @memberof DataTable#oApi
860
- */
861
- function _fnColumnTypes ( settings )
862
- {
863
- var columns = settings.aoColumns;
864
- var data = settings.aoData;
865
- var types = DataTable.ext.type.detect;
866
- var i, ien, j, jen, k, ken;
867
- var col, cell, detectedType, cache;
868
-
869
- // For each column, spin over the
870
- for ( i=0, ien=columns.length ; i<ien ; i++ ) {
871
- col = columns[i];
872
- cache = [];
873
-
874
- if ( ! col.sType && col._sManualType ) {
875
- col.sType = col._sManualType;
876
- }
877
- else if ( ! col.sType ) {
878
- for ( j=0, jen=types.length ; j<jen ; j++ ) {
879
- for ( k=0, ken=data.length ; k<ken ; k++ ) {
880
- // Use a cache array so we only need to get the type data
881
- // from the formatter once (when using multiple detectors)
882
- if ( cache[k] === undefined ) {
883
- cache[k] = _fnGetCellData( settings, k, i, 'type' );
884
- }
885
-
886
- detectedType = types[j]( cache[k], settings );
887
-
888
- // If null, then this type can't apply to this column, so
889
- // rather than testing all cells, break out. There is an
890
- // exception for the last type which is `html`. We need to
891
- // scan all rows since it is possible to mix string and HTML
892
- // types
893
- if ( ! detectedType && j !== types.length-1 ) {
894
- break;
895
- }
896
-
897
- // Only a single match is needed for html type since it is
898
- // bottom of the pile and very similar to string
899
- if ( detectedType === 'html' ) {
900
- break;
901
- }
902
- }
903
-
904
- // Type is valid for all data points in the column - use this
905
- // type
906
- if ( detectedType ) {
907
- col.sType = detectedType;
908
- break;
909
- }
910
- }
911
-
912
- // Fall back - if no type was detected, always use string
913
- if ( ! col.sType ) {
914
- col.sType = 'string';
915
- }
916
- }
917
- }
918
- }
919
-
920
-
921
- /**
922
- * Take the column definitions and static columns arrays and calculate how
923
- * they relate to column indexes. The callback function will then apply the
924
- * definition found for a column to a suitable configuration object.
925
- * @param {object} oSettings dataTables settings object
926
- * @param {array} aoColDefs The aoColumnDefs array that is to be applied
927
- * @param {array} aoCols The aoColumns array that defines columns individually
928
- * @param {function} fn Callback function - takes two parameters, the calculated
929
- * column index and the definition for that column.
930
- * @memberof DataTable#oApi
931
- */
932
- function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
933
- {
934
- var i, iLen, j, jLen, k, kLen, def;
935
- var columns = oSettings.aoColumns;
936
-
937
- // Column definitions with aTargets
938
- if ( aoColDefs )
939
- {
940
- /* Loop over the definitions array - loop in reverse so first instance has priority */
941
- for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
942
- {
943
- def = aoColDefs[i];
944
-
945
- /* Each definition can target multiple columns, as it is an array */
946
- var aTargets = def.targets !== undefined ?
947
- def.targets :
948
- def.aTargets;
949
-
950
- if ( ! $.isArray( aTargets ) )
951
- {
952
- aTargets = [ aTargets ];
953
- }
954
-
955
- for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
956
- {
957
- if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
958
- {
959
- /* Add columns that we don't yet know about */
960
- while( columns.length <= aTargets[j] )
961
- {
962
- _fnAddColumn( oSettings );
963
- }
964
-
965
- /* Integer, basic index */
966
- fn( aTargets[j], def );
967
- }
968
- else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
969
- {
970
- /* Negative integer, right to left column counting */
971
- fn( columns.length+aTargets[j], def );
972
- }
973
- else if ( typeof aTargets[j] === 'string' )
974
- {
975
- /* Class name matching on TH element */
976
- for ( k=0, kLen=columns.length ; k<kLen ; k++ )
977
- {
978
- if ( aTargets[j] == "_all" ||
979
- $(columns[k].nTh).hasClass( aTargets[j] ) )
980
- {
981
- fn( k, def );
982
- }
983
- }
984
- }
985
- }
986
- }
987
- }
988
-
989
- // Statically defined columns array
990
- if ( aoCols )
991
- {
992
- for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
993
- {
994
- fn( i, aoCols[i] );
995
- }
996
- }
997
- }
998
-
999
- /**
1000
- * Add a data array to the table, creating DOM node etc. This is the parallel to
1001
- * _fnGatherData, but for adding rows from a Javascript source, rather than a
1002
- * DOM source.
1003
- * @param {object} oSettings dataTables settings object
1004
- * @param {array} aData data array to be added
1005
- * @param {node} [nTr] TR element to add to the table - optional. If not given,
1006
- * DataTables will create a row automatically
1007
- * @param {array} [anTds] Array of TD|TH elements for the row - must be given
1008
- * if nTr is.
1009
- * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
1010
- * @memberof DataTable#oApi
1011
- */
1012
- function _fnAddData ( oSettings, aDataIn, nTr, anTds )
1013
- {
1014
- /* Create the object for storing information about this new row */
1015
- var iRow = oSettings.aoData.length;
1016
- var oData = $.extend( true, {}, DataTable.models.oRow, {
1017
- src: nTr ? 'dom' : 'data',
1018
- idx: iRow
1019
- } );
1020
-
1021
- oData._aData = aDataIn;
1022
- oSettings.aoData.push( oData );
1023
-
1024
- /* Create the cells */
1025
- var nTd, sThisType;
1026
- var columns = oSettings.aoColumns;
1027
-
1028
- // Invalidate the column types as the new data needs to be revalidated
1029
- for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
1030
- {
1031
- columns[i].sType = null;
1032
- }
1033
-
1034
- /* Add to the display array */
1035
- oSettings.aiDisplayMaster.push( iRow );
1036
-
1037
- var id = oSettings.rowIdFn( aDataIn );
1038
- if ( id !== undefined ) {
1039
- oSettings.aIds[ id ] = oData;
1040
- }
1041
-
1042
- /* Create the DOM information, or register it if already present */
1043
- if ( nTr || ! oSettings.oFeatures.bDeferRender )
1044
- {
1045
- _fnCreateTr( oSettings, iRow, nTr, anTds );
1046
- }
1047
-
1048
- return iRow;
1049
- }
1050
-
1051
-
1052
- /**
1053
- * Add one or more TR elements to the table. Generally we'd expect to
1054
- * use this for reading data from a DOM sourced table, but it could be
1055
- * used for an TR element. Note that if a TR is given, it is used (i.e.
1056
- * it is not cloned).
1057
- * @param {object} settings dataTables settings object
1058
- * @param {array|node|jQuery} trs The TR element(s) to add to the table
1059
- * @returns {array} Array of indexes for the added rows
1060
- * @memberof DataTable#oApi
1061
- */
1062
- function _fnAddTr( settings, trs )
1063
- {
1064
- var row;
1065
-
1066
- // Allow an individual node to be passed in
1067
- if ( ! (trs instanceof $) ) {
1068
- trs = $(trs);
1069
- }
1070
-
1071
- return trs.map( function (i, el) {
1072
- row = _fnGetRowElements( settings, el );
1073
- return _fnAddData( settings, row.data, el, row.cells );
1074
- } );
1075
- }
1076
-
1077
-
1078
- /**
1079
- * Take a TR element and convert it to an index in aoData
1080
- * @param {object} oSettings dataTables settings object
1081
- * @param {node} n the TR element to find
1082
- * @returns {int} index if the node is found, null if not
1083
- * @memberof DataTable#oApi
1084
- */
1085
- function _fnNodeToDataIndex( oSettings, n )
1086
- {
1087
- return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
1088
- }
1089
-
1090
-
1091
- /**
1092
- * Take a TD element and convert it into a column data index (not the visible index)
1093
- * @param {object} oSettings dataTables settings object
1094
- * @param {int} iRow The row number the TD/TH can be found in
1095
- * @param {node} n The TD/TH element to find
1096
- * @returns {int} index if the node is found, -1 if not
1097
- * @memberof DataTable#oApi
1098
- */
1099
- function _fnNodeToColumnIndex( oSettings, iRow, n )
1100
- {
1101
- return $.inArray( n, oSettings.aoData[ iRow ].anCells );
1102
- }
1103
-
1104
-
1105
- /**
1106
- * Get the data for a given cell from the internal cache, taking into account data mapping
1107
- * @param {object} settings dataTables settings object
1108
- * @param {int} rowIdx aoData row id
1109
- * @param {int} colIdx Column index
1110
- * @param {string} type data get type ('display', 'type' 'filter' 'sort')
1111
- * @returns {*} Cell data
1112
- * @memberof DataTable#oApi
1113
- */
1114
- function _fnGetCellData( settings, rowIdx, colIdx, type )
1115
- {
1116
- var draw = settings.iDraw;
1117
- var col = settings.aoColumns[colIdx];
1118
- var rowData = settings.aoData[rowIdx]._aData;
1119
- var defaultContent = col.sDefaultContent;
1120
- var cellData = col.fnGetData( rowData, type, {
1121
- settings: settings,
1122
- row: rowIdx,
1123
- col: colIdx
1124
- } );
1125
-
1126
- if ( cellData === undefined ) {
1127
- if ( settings.iDrawError != draw && defaultContent === null ) {
1128
- _fnLog( settings, 0, "Requested unknown parameter "+
1129
- (typeof col.mData=='function' ? '{function}' : "'"+col.mData+"'")+
1130
- " for row "+rowIdx, 4 );
1131
- settings.iDrawError = draw;
1132
- }
1133
- return defaultContent;
1134
- }
1135
-
1136
- /* When the data source is null, we can use default column data */
1137
- if ( (cellData === rowData || cellData === null) && defaultContent !== null ) {
1138
- cellData = defaultContent;
1139
- }
1140
- else if ( typeof cellData === 'function' ) {
1141
- // If the data source is a function, then we run it and use the return,
1142
- // executing in the scope of the data object (for instances)
1143
- return cellData.call( rowData );
1144
- }
1145
-
1146
- if ( cellData === null && type == 'display' ) {
1147
- return '';
1148
- }
1149
- return cellData;
1150
- }
1151
-
1152
-
1153
- /**
1154
- * Set the value for a specific cell, into the internal data cache
1155
- * @param {object} settings dataTables settings object
1156
- * @param {int} rowIdx aoData row id
1157
- * @param {int} colIdx Column index
1158
- * @param {*} val Value to set
1159
- * @memberof DataTable#oApi
1160
- */
1161
- function _fnSetCellData( settings, rowIdx, colIdx, val )
1162
- {
1163
- var col = settings.aoColumns[colIdx];
1164
- var rowData = settings.aoData[rowIdx]._aData;
1165
-
1166
- col.fnSetData( rowData, val, {
1167
- settings: settings,
1168
- row: rowIdx,
1169
- col: colIdx
1170
- } );
1171
- }
1172
-
1173
-
1174
- // Private variable that is used to match action syntax in the data property object
1175
- var __reArray = /\[.*?\]$/;
1176
- var __reFn = /\(\)$/;
1177
-
1178
- /**
1179
- * Split string on periods, taking into account escaped periods
1180
- * @param {string} str String to split
1181
- * @return {array} Split string
1182
- */
1183
- function _fnSplitObjNotation( str )
1184
- {
1185
- return $.map( str.match(/(\\.|[^\.])+/g) || [''], function ( s ) {
1186
- return s.replace(/\\./g, '.');
1187
- } );
1188
- }
1189
-
1190
-
1191
- /**
1192
- * Return a function that can be used to get data from a source object, taking
1193
- * into account the ability to use nested objects as a source
1194
- * @param {string|int|function} mSource The data source for the object
1195
- * @returns {function} Data get function
1196
- * @memberof DataTable#oApi
1197
- */
1198
- function _fnGetObjectDataFn( mSource )
1199
- {
1200
- if ( $.isPlainObject( mSource ) )
1201
- {
1202
- /* Build an object of get functions, and wrap them in a single call */
1203
- var o = {};
1204
- $.each( mSource, function (key, val) {
1205
- if ( val ) {
1206
- o[key] = _fnGetObjectDataFn( val );
1207
- }
1208
- } );
1209
-
1210
- return function (data, type, row, meta) {
1211
- var t = o[type] || o._;
1212
- return t !== undefined ?
1213
- t(data, type, row, meta) :
1214
- data;
1215
- };
1216
- }
1217
- else if ( mSource === null )
1218
- {
1219
- /* Give an empty string for rendering / sorting etc */
1220
- return function (data) { // type, row and meta also passed, but not used
1221
- return data;
1222
- };
1223
- }
1224
- else if ( typeof mSource === 'function' )
1225
- {
1226
- return function (data, type, row, meta) {
1227
- return mSource( data, type, row, meta );
1228
- };
1229
- }
1230
- else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1231
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
1232
- {
1233
- /* If there is a . in the source string then the data source is in a
1234
- * nested object so we loop over the data for each level to get the next
1235
- * level down. On each loop we test for undefined, and if found immediately
1236
- * return. This allows entire objects to be missing and sDefaultContent to
1237
- * be used if defined, rather than throwing an error
1238
- */
1239
- var fetchData = function (data, type, src) {
1240
- var arrayNotation, funcNotation, out, innerSrc;
1241
-
1242
- if ( src !== "" )
1243
- {
1244
- var a = _fnSplitObjNotation( src );
1245
-
1246
- for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1247
- {
1248
- // Check if we are dealing with special notation
1249
- arrayNotation = a[i].match(__reArray);
1250
- funcNotation = a[i].match(__reFn);
1251
-
1252
- if ( arrayNotation )
1253
- {
1254
- // Array notation
1255
- a[i] = a[i].replace(__reArray, '');
1256
-
1257
- // Condition allows simply [] to be passed in
1258
- if ( a[i] !== "" ) {
1259
- data = data[ a[i] ];
1260
- }
1261
- out = [];
1262
-
1263
- // Get the remainder of the nested object to get
1264
- a.splice( 0, i+1 );
1265
- innerSrc = a.join('.');
1266
-
1267
- // Traverse each entry in the array getting the properties requested
1268
- if ( $.isArray( data ) ) {
1269
- for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
1270
- out.push( fetchData( data[j], type, innerSrc ) );
1271
- }
1272
- }
1273
-
1274
- // If a string is given in between the array notation indicators, that
1275
- // is used to join the strings together, otherwise an array is returned
1276
- var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
1277
- data = (join==="") ? out : out.join(join);
1278
-
1279
- // The inner call to fetchData has already traversed through the remainder
1280
- // of the source requested, so we exit from the loop
1281
- break;
1282
- }
1283
- else if ( funcNotation )
1284
- {
1285
- // Function call
1286
- a[i] = a[i].replace(__reFn, '');
1287
- data = data[ a[i] ]();
1288
- continue;
1289
- }
1290
-
1291
- if ( data === null || data[ a[i] ] === undefined )
1292
- {
1293
- return undefined;
1294
- }
1295
- data = data[ a[i] ];
1296
- }
1297
- }
1298
-
1299
- return data;
1300
- };
1301
-
1302
- return function (data, type) { // row and meta also passed, but not used
1303
- return fetchData( data, type, mSource );
1304
- };
1305
- }
1306
- else
1307
- {
1308
- /* Array or flat object mapping */
1309
- return function (data, type) { // row and meta also passed, but not used
1310
- return data[mSource];
1311
- };
1312
- }
1313
- }
1314
-
1315
-
1316
- /**
1317
- * Return a function that can be used to set data from a source object, taking
1318
- * into account the ability to use nested objects as a source
1319
- * @param {string|int|function} mSource The data source for the object
1320
- * @returns {function} Data set function
1321
- * @memberof DataTable#oApi
1322
- */
1323
- function _fnSetObjectDataFn( mSource )
1324
- {
1325
- if ( $.isPlainObject( mSource ) )
1326
- {
1327
- /* Unlike get, only the underscore (global) option is used for for
1328
- * setting data since we don't know the type here. This is why an object
1329
- * option is not documented for `mData` (which is read/write), but it is
1330
- * for `mRender` which is read only.
1331
- */
1332
- return _fnSetObjectDataFn( mSource._ );
1333
- }
1334
- else if ( mSource === null )
1335
- {
1336
- /* Nothing to do when the data source is null */
1337
- return function () {};
1338
- }
1339
- else if ( typeof mSource === 'function' )
1340
- {
1341
- return function (data, val, meta) {
1342
- mSource( data, 'set', val, meta );
1343
- };
1344
- }
1345
- else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1346
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
1347
- {
1348
- /* Like the get, we need to get data from a nested object */
1349
- var setData = function (data, val, src) {
1350
- var a = _fnSplitObjNotation( src ), b;
1351
- var aLast = a[a.length-1];
1352
- var arrayNotation, funcNotation, o, innerSrc;
1353
-
1354
- for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
1355
- {
1356
- // Check if we are dealing with an array notation request
1357
- arrayNotation = a[i].match(__reArray);
1358
- funcNotation = a[i].match(__reFn);
1359
-
1360
- if ( arrayNotation )
1361
- {
1362
- a[i] = a[i].replace(__reArray, '');
1363
- data[ a[i] ] = [];
1364
-
1365
- // Get the remainder of the nested object to set so we can recurse
1366
- b = a.slice();
1367
- b.splice( 0, i+1 );
1368
- innerSrc = b.join('.');
1369
-
1370
- // Traverse each entry in the array setting the properties requested
1371
- if ( $.isArray( val ) )
1372
- {
1373
- for ( var j=0, jLen=val.length ; j<jLen ; j++ )
1374
- {
1375
- o = {};
1376
- setData( o, val[j], innerSrc );
1377
- data[ a[i] ].push( o );
1378
- }
1379
- }
1380
- else
1381
- {
1382
- // We've been asked to save data to an array, but it
1383
- // isn't array data to be saved. Best that can be done
1384
- // is to just save the value.
1385
- data[ a[i] ] = val;
1386
- }
1387
-
1388
- // The inner call to setData has already traversed through the remainder
1389
- // of the source and has set the data, thus we can exit here
1390
- return;
1391
- }
1392
- else if ( funcNotation )
1393
- {
1394
- // Function call
1395
- a[i] = a[i].replace(__reFn, '');
1396
- data = data[ a[i] ]( val );
1397
- }
1398
-
1399
- // If the nested object doesn't currently exist - since we are
1400
- // trying to set the value - create it
1401
- if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
1402
- {
1403
- data[ a[i] ] = {};
1404
- }
1405
- data = data[ a[i] ];
1406
- }
1407
-
1408
- // Last item in the input - i.e, the actual set
1409
- if ( aLast.match(__reFn ) )
1410
- {
1411
- // Function call
1412
- data = data[ aLast.replace(__reFn, '') ]( val );
1413
- }
1414
- else
1415
- {
1416
- // If array notation is used, we just want to strip it and use the property name
1417
- // and assign the value. If it isn't used, then we get the result we want anyway
1418
- data[ aLast.replace(__reArray, '') ] = val;
1419
- }
1420
- };
1421
-
1422
- return function (data, val) { // meta is also passed in, but not used
1423
- return setData( data, val, mSource );
1424
- };
1425
- }
1426
- else
1427
- {
1428
- /* Array or flat object mapping */
1429
- return function (data, val) { // meta is also passed in, but not used
1430
- data[mSource] = val;
1431
- };
1432
- }
1433
- }
1434
-
1435
-
1436
- /**
1437
- * Return an array with the full table data
1438
- * @param {object} oSettings dataTables settings object
1439
- * @returns array {array} aData Master data array
1440
- * @memberof DataTable#oApi
1441
- */
1442
- function _fnGetDataMaster ( settings )
1443
- {
1444
- return _pluck( settings.aoData, '_aData' );
1445
- }
1446
-
1447
-
1448
- /**
1449
- * Nuke the table
1450
- * @param {object} oSettings dataTables settings object
1451
- * @memberof DataTable#oApi
1452
- */
1453
- function _fnClearTable( settings )
1454
- {
1455
- settings.aoData.length = 0;
1456
- settings.aiDisplayMaster.length = 0;
1457
- settings.aiDisplay.length = 0;
1458
- settings.aIds = {};
1459
- }
1460
-
1461
-
1462
- /**
1463
- * Take an array of integers (index array) and remove a target integer (value - not
1464
- * the key!)
1465
- * @param {array} a Index array to target
1466
- * @param {int} iTarget value to find
1467
- * @memberof DataTable#oApi
1468
- */
1469
- function _fnDeleteIndex( a, iTarget, splice )
1470
- {
1471
- var iTargetIndex = -1;
1472
-
1473
- for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1474
- {
1475
- if ( a[i] == iTarget )
1476
- {
1477
- iTargetIndex = i;
1478
- }
1479
- else if ( a[i] > iTarget )
1480
- {
1481
- a[i]--;
1482
- }
1483
- }
1484
-
1485
- if ( iTargetIndex != -1 && splice === undefined )
1486
- {
1487
- a.splice( iTargetIndex, 1 );
1488
- }
1489
- }
1490
-
1491
-
1492
- /**
1493
- * Mark cached data as invalid such that a re-read of the data will occur when
1494
- * the cached data is next requested. Also update from the data source object.
1495
- *
1496
- * @param {object} settings DataTables settings object
1497
- * @param {int} rowIdx Row index to invalidate
1498
- * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
1499
- * or 'data'
1500
- * @param {int} [colIdx] Column index to invalidate. If undefined the whole
1501
- * row will be invalidated
1502
- * @memberof DataTable#oApi
1503
- *
1504
- * @todo For the modularisation of v1.11 this will need to become a callback, so
1505
- * the sort and filter methods can subscribe to it. That will required
1506
- * initialisation options for sorting, which is why it is not already baked in
1507
- */
1508
- function _fnInvalidate( settings, rowIdx, src, colIdx )
1509
- {
1510
- var row = settings.aoData[ rowIdx ];
1511
- var i, ien;
1512
- var cellWrite = function ( cell, col ) {
1513
- // This is very frustrating, but in IE if you just write directly
1514
- // to innerHTML, and elements that are overwritten are GC'ed,
1515
- // even if there is a reference to them elsewhere
1516
- while ( cell.childNodes.length ) {
1517
- cell.removeChild( cell.firstChild );
1518
- }
1519
-
1520
- cell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );
1521
- };
1522
-
1523
- // Are we reading last data from DOM or the data object?
1524
- if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
1525
- // Read the data from the DOM
1526
- row._aData = _fnGetRowElements(
1527
- settings, row, colIdx, colIdx === undefined ? undefined : row._aData
1528
- )
1529
- .data;
1530
- }
1531
- else {
1532
- // Reading from data object, update the DOM
1533
- var cells = row.anCells;
1534
-
1535
- if ( cells ) {
1536
- if ( colIdx !== undefined ) {
1537
- cellWrite( cells[colIdx], colIdx );
1538
- }
1539
- else {
1540
- for ( i=0, ien=cells.length ; i<ien ; i++ ) {
1541
- cellWrite( cells[i], i );
1542
- }
1543
- }
1544
- }
1545
- }
1546
-
1547
- // For both row and cell invalidation, the cached data for sorting and
1548
- // filtering is nulled out
1549
- row._aSortData = null;
1550
- row._aFilterData = null;
1551
-
1552
- // Invalidate the type for a specific column (if given) or all columns since
1553
- // the data might have changed
1554
- var cols = settings.aoColumns;
1555
- if ( colIdx !== undefined ) {
1556
- cols[ colIdx ].sType = null;
1557
- }
1558
- else {
1559
- for ( i=0, ien=cols.length ; i<ien ; i++ ) {
1560
- cols[i].sType = null;
1561
- }
1562
-
1563
- // Update DataTables special `DT_*` attributes for the row
1564
- _fnRowAttributes( settings, row );
1565
- }
1566
- }
1567
-
1568
-
1569
- /**
1570
- * Build a data source object from an HTML row, reading the contents of the
1571
- * cells that are in the row.
1572
- *
1573
- * @param {object} settings DataTables settings object
1574
- * @param {node|object} TR element from which to read data or existing row
1575
- * object from which to re-read the data from the cells
1576
- * @param {int} [colIdx] Optional column index
1577
- * @param {array|object} [d] Data source object. If `colIdx` is given then this
1578
- * parameter should also be given and will be used to write the data into.
1579
- * Only the column in question will be written
1580
- * @returns {object} Object with two parameters: `data` the data read, in
1581
- * document order, and `cells` and array of nodes (they can be useful to the
1582
- * caller, so rather than needing a second traversal to get them, just return
1583
- * them from here).
1584
- * @memberof DataTable#oApi
1585
- */
1586
- function _fnGetRowElements( settings, row, colIdx, d )
1587
- {
1588
- var
1589
- tds = [],
1590
- td = row.firstChild,
1591
- name, col, o, i=0, contents,
1592
- columns = settings.aoColumns,
1593
- objectRead = settings._rowReadObject;
1594
-
1595
- // Allow the data object to be passed in, or construct
1596
- d = d !== undefined ?
1597
- d :
1598
- objectRead ?
1599
- {} :
1600
- [];
1601
-
1602
- var attr = function ( str, td ) {
1603
- if ( typeof str === 'string' ) {
1604
- var idx = str.indexOf('@');
1605
-
1606
- if ( idx !== -1 ) {
1607
- var attr = str.substring( idx+1 );
1608
- var setter = _fnSetObjectDataFn( str );
1609
- setter( d, td.getAttribute( attr ) );
1610
- }
1611
- }
1612
- };
1613
-
1614
- // Read data from a cell and store into the data object
1615
- var cellProcess = function ( cell ) {
1616
- if ( colIdx === undefined || colIdx === i ) {
1617
- col = columns[i];
1618
- contents = $.trim(cell.innerHTML);
1619
-
1620
- if ( col && col._bAttrSrc ) {
1621
- var setter = _fnSetObjectDataFn( col.mData._ );
1622
- setter( d, contents );
1623
-
1624
- attr( col.mData.sort, cell );
1625
- attr( col.mData.type, cell );
1626
- attr( col.mData.filter, cell );
1627
- }
1628
- else {
1629
- // Depending on the `data` option for the columns the data can
1630
- // be read to either an object or an array.
1631
- if ( objectRead ) {
1632
- if ( ! col._setter ) {
1633
- // Cache the setter function
1634
- col._setter = _fnSetObjectDataFn( col.mData );
1635
- }
1636
- col._setter( d, contents );
1637
- }
1638
- else {
1639
- d[i] = contents;
1640
- }
1641
- }
1642
- }
1643
-
1644
- i++;
1645
- };
1646
-
1647
- if ( td ) {
1648
- // `tr` element was passed in
1649
- while ( td ) {
1650
- name = td.nodeName.toUpperCase();
1651
-
1652
- if ( name == "TD" || name == "TH" ) {
1653
- cellProcess( td );
1654
- tds.push( td );
1655
- }
1656
-
1657
- td = td.nextSibling;
1658
- }
1659
- }
1660
- else {
1661
- // Existing row object passed in
1662
- tds = row.anCells;
1663
-
1664
- for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
1665
- cellProcess( tds[j] );
1666
- }
1667
- }
1668
-
1669
- // Read the ID from the DOM if present
1670
- var rowNode = td ? row : row.nTr;
1671
-
1672
- if ( rowNode ) {
1673
- var id = rowNode.getAttribute( 'id' );
1674
-
1675
- if ( id ) {
1676
- _fnSetObjectDataFn( settings.rowId )( d, id );
1677
- }
1678
- }
1679
-
1680
- return {
1681
- data: d,
1682
- cells: tds
1683
- };
1684
- }
1685
- /**
1686
- * Create a new TR element (and it's TD children) for a row
1687
- * @param {object} oSettings dataTables settings object
1688
- * @param {int} iRow Row to consider
1689
- * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
1690
- * DataTables will create a row automatically
1691
- * @param {array} [anTds] Array of TD|TH elements for the row - must be given
1692
- * if nTr is.
1693
- * @memberof DataTable#oApi
1694
- */
1695
- function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
1696
- {
1697
- var
1698
- row = oSettings.aoData[iRow],
1699
- rowData = row._aData,
1700
- cells = [],
1701
- nTr, nTd, oCol,
1702
- i, iLen;
1703
-
1704
- if ( row.nTr === null )
1705
- {
1706
- nTr = nTrIn || document.createElement('tr');
1707
-
1708
- row.nTr = nTr;
1709
- row.anCells = cells;
1710
-
1711
- /* Use a private property on the node to allow reserve mapping from the node
1712
- * to the aoData array for fast look up
1713
- */
1714
- nTr._DT_RowIndex = iRow;
1715
-
1716
- /* Special parameters can be given by the data source to be used on the row */
1717
- _fnRowAttributes( oSettings, row );
1718
-
1719
- /* Process each column */
1720
- for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1721
- {
1722
- oCol = oSettings.aoColumns[i];
1723
-
1724
- nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
1725
- cells.push( nTd );
1726
-
1727
- // Need to create the HTML if new, or if a rendering function is defined
1728
- if ( !nTrIn || oCol.mRender || oCol.mData !== i )
1729
- {
1730
- nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
1731
- }
1732
-
1733
- /* Add user defined class */
1734
- if ( oCol.sClass )
1735
- {
1736
- nTd.className += ' '+oCol.sClass;
1737
- }
1738
-
1739
- // Visibility - add or remove as required
1740
- if ( oCol.bVisible && ! nTrIn )
1741
- {
1742
- nTr.appendChild( nTd );
1743
- }
1744
- else if ( ! oCol.bVisible && nTrIn )
1745
- {
1746
- nTd.parentNode.removeChild( nTd );
1747
- }
1748
-
1749
- if ( oCol.fnCreatedCell )
1750
- {
1751
- oCol.fnCreatedCell.call( oSettings.oInstance,
1752
- nTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i
1753
- );
1754
- }
1755
- }
1756
-
1757
- _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
1758
- }
1759
-
1760
- // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
1761
- // and deployed
1762
- row.nTr.setAttribute( 'role', 'row' );
1763
- }
1764
-
1765
-
1766
- /**
1767
- * Add attributes to a row based on the special `DT_*` parameters in a data
1768
- * source object.
1769
- * @param {object} settings DataTables settings object
1770
- * @param {object} DataTables row object for the row to be modified
1771
- * @memberof DataTable#oApi
1772
- */
1773
- function _fnRowAttributes( settings, row )
1774
- {
1775
- var tr = row.nTr;
1776
- var data = row._aData;
1777
-
1778
- if ( tr ) {
1779
- var id = settings.rowIdFn( data );
1780
-
1781
- if ( id ) {
1782
- tr.id = id;
1783
- }
1784
-
1785
- if ( data.DT_RowClass ) {
1786
- // Remove any classes added by DT_RowClass before
1787
- var a = data.DT_RowClass.split(' ');
1788
- row.__rowc = row.__rowc ?
1789
- _unique( row.__rowc.concat( a ) ) :
1790
- a;
1791
-
1792
- $(tr)
1793
- .removeClass( row.__rowc.join(' ') )
1794
- .addClass( data.DT_RowClass );
1795
- }
1796
-
1797
- if ( data.DT_RowAttr ) {
1798
- $(tr).attr( data.DT_RowAttr );
1799
- }
1800
-
1801
- if ( data.DT_RowData ) {
1802
- $(tr).data( data.DT_RowData );
1803
- }
1804
- }
1805
- }
1806
-
1807
-
1808
- /**
1809
- * Create the HTML header for the table
1810
- * @param {object} oSettings dataTables settings object
1811
- * @memberof DataTable#oApi
1812
- */
1813
- function _fnBuildHead( oSettings )
1814
- {
1815
- var i, ien, cell, row, column;
1816
- var thead = oSettings.nTHead;
1817
- var tfoot = oSettings.nTFoot;
1818
- var createHeader = $('th, td', thead).length === 0;
1819
- var classes = oSettings.oClasses;
1820
- var columns = oSettings.aoColumns;
1821
-
1822
- if ( createHeader ) {
1823
- row = $('<tr/>').appendTo( thead );
1824
- }
1825
-
1826
- for ( i=0, ien=columns.length ; i<ien ; i++ ) {
1827
- column = columns[i];
1828
- cell = $( column.nTh ).addClass( column.sClass );
1829
-
1830
- if ( createHeader ) {
1831
- cell.appendTo( row );
1832
- }
1833
-
1834
- // 1.11 move into sorting
1835
- if ( oSettings.oFeatures.bSort ) {
1836
- cell.addClass( column.sSortingClass );
1837
-
1838
- if ( column.bSortable !== false ) {
1839
- cell
1840
- .attr( 'tabindex', oSettings.iTabIndex )
1841
- .attr( 'aria-controls', oSettings.sTableId );
1842
-
1843
- _fnSortAttachListener( oSettings, column.nTh, i );
1844
- }
1845
- }
1846
-
1847
- if ( column.sTitle != cell[0].innerHTML ) {
1848
- cell.html( column.sTitle );
1849
- }
1850
-
1851
- _fnRenderer( oSettings, 'header' )(
1852
- oSettings, cell, column, classes
1853
- );
1854
- }
1855
-
1856
- if ( createHeader ) {
1857
- _fnDetectHeader( oSettings.aoHeader, thead );
1858
- }
1859
-
1860
- /* ARIA role for the rows */
1861
- $(thead).find('>tr').attr('role', 'row');
1862
-
1863
- /* Deal with the footer - add classes if required */
1864
- $(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
1865
- $(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
1866
-
1867
- // Cache the footer cells. Note that we only take the cells from the first
1868
- // row in the footer. If there is more than one row the user wants to
1869
- // interact with, they need to use the table().foot() method. Note also this
1870
- // allows cells to be used for multiple columns using colspan
1871
- if ( tfoot !== null ) {
1872
- var cells = oSettings.aoFooter[0];
1873
-
1874
- for ( i=0, ien=cells.length ; i<ien ; i++ ) {
1875
- column = columns[i];
1876
- column.nTf = cells[i].cell;
1877
-
1878
- if ( column.sClass ) {
1879
- $(column.nTf).addClass( column.sClass );
1880
- }
1881
- }
1882
- }
1883
- }
1884
-
1885
-
1886
- /**
1887
- * Draw the header (or footer) element based on the column visibility states. The
1888
- * methodology here is to use the layout array from _fnDetectHeader, modified for
1889
- * the instantaneous column visibility, to construct the new layout. The grid is
1890
- * traversed over cell at a time in a rows x columns grid fashion, although each
1891
- * cell insert can cover multiple elements in the grid - which is tracks using the
1892
- * aApplied array. Cell inserts in the grid will only occur where there isn't
1893
- * already a cell in that position.
1894
- * @param {object} oSettings dataTables settings object
1895
- * @param array {objects} aoSource Layout array from _fnDetectHeader
1896
- * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
1897
- * @memberof DataTable#oApi
1898
- */
1899
- function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
1900
- {
1901
- var i, iLen, j, jLen, k, kLen, n, nLocalTr;
1902
- var aoLocal = [];
1903
- var aApplied = [];
1904
- var iColumns = oSettings.aoColumns.length;
1905
- var iRowspan, iColspan;
1906
-
1907
- if ( ! aoSource )
1908
- {
1909
- return;
1910
- }
1911
-
1912
- if ( bIncludeHidden === undefined )
1913
- {
1914
- bIncludeHidden = false;
1915
- }
1916
-
1917
- /* Make a copy of the master layout array, but without the visible columns in it */
1918
- for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
1919
- {
1920
- aoLocal[i] = aoSource[i].slice();
1921
- aoLocal[i].nTr = aoSource[i].nTr;
1922
-
1923
- /* Remove any columns which are currently hidden */
1924
- for ( j=iColumns-1 ; j>=0 ; j-- )
1925
- {
1926
- if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
1927
- {
1928
- aoLocal[i].splice( j, 1 );
1929
- }
1930
- }
1931
-
1932
- /* Prep the applied array - it needs an element for each row */
1933
- aApplied.push( [] );
1934
- }
1935
-
1936
- for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
1937
- {
1938
- nLocalTr = aoLocal[i].nTr;
1939
-
1940
- /* All cells are going to be replaced, so empty out the row */
1941
- if ( nLocalTr )
1942
- {
1943
- while( (n = nLocalTr.firstChild) )
1944
- {
1945
- nLocalTr.removeChild( n );
1946
- }
1947
- }
1948
-
1949
- for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
1950
- {
1951
- iRowspan = 1;
1952
- iColspan = 1;
1953
-
1954
- /* Check to see if there is already a cell (row/colspan) covering our target
1955
- * insert point. If there is, then there is nothing to do.
1956
- */
1957
- if ( aApplied[i][j] === undefined )
1958
- {
1959
- nLocalTr.appendChild( aoLocal[i][j].cell );
1960
- aApplied[i][j] = 1;
1961
-
1962
- /* Expand the cell to cover as many rows as needed */
1963
- while ( aoLocal[i+iRowspan] !== undefined &&
1964
- aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
1965
- {
1966
- aApplied[i+iRowspan][j] = 1;
1967
- iRowspan++;
1968
- }
1969
-
1970
- /* Expand the cell to cover as many columns as needed */
1971
- while ( aoLocal[i][j+iColspan] !== undefined &&
1972
- aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
1973
- {
1974
- /* Must update the applied array over the rows for the columns */
1975
- for ( k=0 ; k<iRowspan ; k++ )
1976
- {
1977
- aApplied[i+k][j+iColspan] = 1;
1978
- }
1979
- iColspan++;
1980
- }
1981
-
1982
- /* Do the actual expansion in the DOM */
1983
- $(aoLocal[i][j].cell)
1984
- .attr('rowspan', iRowspan)
1985
- .attr('colspan', iColspan);
1986
- }
1987
- }
1988
- }
1989
- }
1990
-
1991
-
1992
- /**
1993
- * Insert the required TR nodes into the table for display
1994
- * @param {object} oSettings dataTables settings object
1995
- * @memberof DataTable#oApi
1996
- */
1997
- function _fnDraw( oSettings )
1998
- {
1999
- /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
2000
- var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
2001
- if ( $.inArray( false, aPreDraw ) !== -1 )
2002
- {
2003
- _fnProcessingDisplay( oSettings, false );
2004
- return;
2005
- }
2006
-
2007
- var i, iLen, n;
2008
- var anRows = [];
2009
- var iRowCount = 0;
2010
- var asStripeClasses = oSettings.asStripeClasses;
2011
- var iStripes = asStripeClasses.length;
2012
- var iOpenRows = oSettings.aoOpenRows.length;
2013
- var oLang = oSettings.oLanguage;
2014
- var iInitDisplayStart = oSettings.iInitDisplayStart;
2015
- var bServerSide = _fnDataSource( oSettings ) == 'ssp';
2016
- var aiDisplay = oSettings.aiDisplay;
2017
-
2018
- oSettings.bDrawing = true;
2019
-
2020
- /* Check and see if we have an initial draw position from state saving */
2021
- if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
2022
- {
2023
- oSettings._iDisplayStart = bServerSide ?
2024
- iInitDisplayStart :
2025
- iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
2026
- 0 :
2027
- iInitDisplayStart;
2028
-
2029
- oSettings.iInitDisplayStart = -1;
2030
- }
2031
-
2032
- var iDisplayStart = oSettings._iDisplayStart;
2033
- var iDisplayEnd = oSettings.fnDisplayEnd();
2034
-
2035
- /* Server-side processing draw intercept */
2036
- if ( oSettings.bDeferLoading )
2037
- {
2038
- oSettings.bDeferLoading = false;
2039
- oSettings.iDraw++;
2040
- _fnProcessingDisplay( oSettings, false );
2041
- }
2042
- else if ( !bServerSide )
2043
- {
2044
- oSettings.iDraw++;
2045
- }
2046
- else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
2047
- {
2048
- return;
2049
- }
2050
-
2051
- if ( aiDisplay.length !== 0 )
2052
- {
2053
- var iStart = bServerSide ? 0 : iDisplayStart;
2054
- var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
2055
-
2056
- for ( var j=iStart ; j<iEnd ; j++ )
2057
- {
2058
- var iDataIndex = aiDisplay[j];
2059
- var aoData = oSettings.aoData[ iDataIndex ];
2060
- if ( aoData.nTr === null )
2061
- {
2062
- _fnCreateTr( oSettings, iDataIndex );
2063
- }
2064
-
2065
- var nRow = aoData.nTr;
2066
-
2067
- /* Remove the old striping classes and then add the new one */
2068
- if ( iStripes !== 0 )
2069
- {
2070
- var sStripe = asStripeClasses[ iRowCount % iStripes ];
2071
- if ( aoData._sRowStripe != sStripe )
2072
- {
2073
- $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
2074
- aoData._sRowStripe = sStripe;
2075
- }
2076
- }
2077
-
2078
- // Row callback functions - might want to manipulate the row
2079
- // iRowCount and j are not currently documented. Are they at all
2080
- // useful?
2081
- _fnCallbackFire( oSettings, 'aoRowCallback', null,
2082
- [nRow, aoData._aData, iRowCount, j] );
2083
-
2084
- anRows.push( nRow );
2085
- iRowCount++;
2086
- }
2087
- }
2088
- else
2089
- {
2090
- /* Table is empty - create a row with an empty message in it */
2091
- var sZero = oLang.sZeroRecords;
2092
- if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
2093
- {
2094
- sZero = oLang.sLoadingRecords;
2095
- }
2096
- else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
2097
- {
2098
- sZero = oLang.sEmptyTable;
2099
- }
2100
-
2101
- anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
2102
- .append( $('<td />', {
2103
- 'valign': 'top',
2104
- 'colSpan': _fnVisbleColumns( oSettings ),
2105
- 'class': oSettings.oClasses.sRowEmpty
2106
- } ).html( sZero ) )[0];
2107
- }
2108
-
2109
- /* Header and footer callbacks */
2110
- _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
2111
- _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
2112
-
2113
- _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
2114
- _fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
2115
-
2116
- var body = $(oSettings.nTBody);
2117
-
2118
- body.children().detach();
2119
- body.append( $(anRows) );
2120
-
2121
- /* Call all required callback functions for the end of a draw */
2122
- _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
2123
-
2124
- /* Draw is complete, sorting and filtering must be as well */
2125
- oSettings.bSorted = false;
2126
- oSettings.bFiltered = false;
2127
- oSettings.bDrawing = false;
2128
- }
2129
-
2130
-
2131
- /**
2132
- * Redraw the table - taking account of the various features which are enabled
2133
- * @param {object} oSettings dataTables settings object
2134
- * @param {boolean} [holdPosition] Keep the current paging position. By default
2135
- * the paging is reset to the first page
2136
- * @memberof DataTable#oApi
2137
- */
2138
- function _fnReDraw( settings, holdPosition )
2139
- {
2140
- var
2141
- features = settings.oFeatures,
2142
- sort = features.bSort,
2143
- filter = features.bFilter;
2144
-
2145
- if ( sort ) {
2146
- _fnSort( settings );
2147
- }
2148
-
2149
- if ( filter ) {
2150
- _fnFilterComplete( settings, settings.oPreviousSearch );
2151
- }
2152
- else {
2153
- // No filtering, so we want to just use the display master
2154
- settings.aiDisplay = settings.aiDisplayMaster.slice();
2155
- }
2156
-
2157
- if ( holdPosition !== true ) {
2158
- settings._iDisplayStart = 0;
2159
- }
2160
-
2161
- // Let any modules know about the draw hold position state (used by
2162
- // scrolling internally)
2163
- settings._drawHold = holdPosition;
2164
-
2165
- _fnDraw( settings );
2166
-
2167
- settings._drawHold = false;
2168
- }
2169
-
2170
-
2171
- /**
2172
- * Add the options to the page HTML for the table
2173
- * @param {object} oSettings dataTables settings object
2174
- * @memberof DataTable#oApi
2175
- */
2176
- function _fnAddOptionsHtml ( oSettings )
2177
- {
2178
- var classes = oSettings.oClasses;
2179
- var table = $(oSettings.nTable);
2180
- var holding = $('<div/>').insertBefore( table ); // Holding element for speed
2181
- var features = oSettings.oFeatures;
2182
-
2183
- // All DataTables are wrapped in a div
2184
- var insert = $('<div/>', {
2185
- id: oSettings.sTableId+'_wrapper',
2186
- 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
2187
- } );
2188
-
2189
- oSettings.nHolding = holding[0];
2190
- oSettings.nTableWrapper = insert[0];
2191
- oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
2192
-
2193
- /* Loop over the user set positioning and place the elements as needed */
2194
- var aDom = oSettings.sDom.split('');
2195
- var featureNode, cOption, nNewNode, cNext, sAttr, j;
2196
- for ( var i=0 ; i<aDom.length ; i++ )
2197
- {
2198
- featureNode = null;
2199
- cOption = aDom[i];
2200
-
2201
- if ( cOption == '<' )
2202
- {
2203
- /* New container div */
2204
- nNewNode = $('<div/>')[0];
2205
-
2206
- /* Check to see if we should append an id and/or a class name to the container */
2207
- cNext = aDom[i+1];
2208
- if ( cNext == "'" || cNext == '"' )
2209
- {
2210
- sAttr = "";
2211
- j = 2;
2212
- while ( aDom[i+j] != cNext )
2213
- {
2214
- sAttr += aDom[i+j];
2215
- j++;
2216
- }
2217
-
2218
- /* Replace jQuery UI constants @todo depreciated */
2219
- if ( sAttr == "H" )
2220
- {
2221
- sAttr = classes.sJUIHeader;
2222
- }
2223
- else if ( sAttr == "F" )
2224
- {
2225
- sAttr = classes.sJUIFooter;
2226
- }
2227
-
2228
- /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
2229
- * breaks the string into parts and applies them as needed
2230
- */
2231
- if ( sAttr.indexOf('.') != -1 )
2232
- {
2233
- var aSplit = sAttr.split('.');
2234
- nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
2235
- nNewNode.className = aSplit[1];
2236
- }
2237
- else if ( sAttr.charAt(0) == "#" )
2238
- {
2239
- nNewNode.id = sAttr.substr(1, sAttr.length-1);
2240
- }
2241
- else
2242
- {
2243
- nNewNode.className = sAttr;
2244
- }
2245
-
2246
- i += j; /* Move along the position array */
2247
- }
2248
-
2249
- insert.append( nNewNode );
2250
- insert = $(nNewNode);
2251
- }
2252
- else if ( cOption == '>' )
2253
- {
2254
- /* End container div */
2255
- insert = insert.parent();
2256
- }
2257
- // @todo Move options into their own plugins?
2258
- else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
2259
- {
2260
- /* Length */
2261
- featureNode = _fnFeatureHtmlLength( oSettings );
2262
- }
2263
- else if ( cOption == 'f' && features.bFilter )
2264
- {
2265
- /* Filter */
2266
- featureNode = _fnFeatureHtmlFilter( oSettings );
2267
- }
2268
- else if ( cOption == 'r' && features.bProcessing )
2269
- {
2270
- /* pRocessing */
2271
- featureNode = _fnFeatureHtmlProcessing( oSettings );
2272
- }
2273
- else if ( cOption == 't' )
2274
- {
2275
- /* Table */
2276
- featureNode = _fnFeatureHtmlTable( oSettings );
2277
- }
2278
- else if ( cOption == 'i' && features.bInfo )
2279
- {
2280
- /* Info */
2281
- featureNode = _fnFeatureHtmlInfo( oSettings );
2282
- }
2283
- else if ( cOption == 'p' && features.bPaginate )
2284
- {
2285
- /* Pagination */
2286
- featureNode = _fnFeatureHtmlPaginate( oSettings );
2287
- }
2288
- else if ( DataTable.ext.feature.length !== 0 )
2289
- {
2290
- /* Plug-in features */
2291
- var aoFeatures = DataTable.ext.feature;
2292
- for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
2293
- {
2294
- if ( cOption == aoFeatures[k].cFeature )
2295
- {
2296
- featureNode = aoFeatures[k].fnInit( oSettings );
2297
- break;
2298
- }
2299
- }
2300
- }
2301
-
2302
- /* Add to the 2D features array */
2303
- if ( featureNode )
2304
- {
2305
- var aanFeatures = oSettings.aanFeatures;
2306
-
2307
- if ( ! aanFeatures[cOption] )
2308
- {
2309
- aanFeatures[cOption] = [];
2310
- }
2311
-
2312
- aanFeatures[cOption].push( featureNode );
2313
- insert.append( featureNode );
2314
- }
2315
- }
2316
-
2317
- /* Built our DOM structure - replace the holding div with what we want */
2318
- holding.replaceWith( insert );
2319
- oSettings.nHolding = null;
2320
- }
2321
-
2322
-
2323
- /**
2324
- * Use the DOM source to create up an array of header cells. The idea here is to
2325
- * create a layout grid (array) of rows x columns, which contains a reference
2326
- * to the cell that that point in the grid (regardless of col/rowspan), such that
2327
- * any column / row could be removed and the new grid constructed
2328
- * @param array {object} aLayout Array to store the calculated layout in
2329
- * @param {node} nThead The header/footer element for the table
2330
- * @memberof DataTable#oApi
2331
- */
2332
- function _fnDetectHeader ( aLayout, nThead )
2333
- {
2334
- var nTrs = $(nThead).children('tr');
2335
- var nTr, nCell;
2336
- var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
2337
- var bUnique;
2338
- var fnShiftCol = function ( a, i, j ) {
2339
- var k = a[i];
2340
- while ( k[j] ) {
2341
- j++;
2342
- }
2343
- return j;
2344
- };
2345
-
2346
- aLayout.splice( 0, aLayout.length );
2347
-
2348
- /* We know how many rows there are in the layout - so prep it */
2349
- for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
2350
- {
2351
- aLayout.push( [] );
2352
- }
2353
-
2354
- /* Calculate a layout array */
2355
- for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
2356
- {
2357
- nTr = nTrs[i];
2358
- iColumn = 0;
2359
-
2360
- /* For every cell in the row... */
2361
- nCell = nTr.firstChild;
2362
- while ( nCell ) {
2363
- if ( nCell.nodeName.toUpperCase() == "TD" ||
2364
- nCell.nodeName.toUpperCase() == "TH" )
2365
- {
2366
- /* Get the col and rowspan attributes from the DOM and sanitise them */
2367
- iColspan = nCell.getAttribute('colspan') * 1;
2368
- iRowspan = nCell.getAttribute('rowspan') * 1;
2369
- iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
2370
- iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
2371
-
2372
- /* There might be colspan cells already in this row, so shift our target
2373
- * accordingly
2374
- */
2375
- iColShifted = fnShiftCol( aLayout, i, iColumn );
2376
-
2377
- /* Cache calculation for unique columns */
2378
- bUnique = iColspan === 1 ? true : false;
2379
-
2380
- /* If there is col / rowspan, copy the information into the layout grid */
2381
- for ( l=0 ; l<iColspan ; l++ )
2382
- {
2383
- for ( k=0 ; k<iRowspan ; k++ )
2384
- {
2385
- aLayout[i+k][iColShifted+l] = {
2386
- "cell": nCell,
2387
- "unique": bUnique
2388
- };
2389
- aLayout[i+k].nTr = nTr;
2390
- }
2391
- }
2392
- }
2393
- nCell = nCell.nextSibling;
2394
- }
2395
- }
2396
- }
2397
-
2398
-
2399
- /**
2400
- * Get an array of unique th elements, one for each column
2401
- * @param {object} oSettings dataTables settings object
2402
- * @param {node} nHeader automatically detect the layout from this node - optional
2403
- * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
2404
- * @returns array {node} aReturn list of unique th's
2405
- * @memberof DataTable#oApi
2406
- */
2407
- function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
2408
- {
2409
- var aReturn = [];
2410
- if ( !aLayout )
2411
- {
2412
- aLayout = oSettings.aoHeader;
2413
- if ( nHeader )
2414
- {
2415
- aLayout = [];
2416
- _fnDetectHeader( aLayout, nHeader );
2417
- }
2418
- }
2419
-
2420
- for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
2421
- {
2422
- for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
2423
- {
2424
- if ( aLayout[i][j].unique &&
2425
- (!aReturn[j] || !oSettings.bSortCellsTop) )
2426
- {
2427
- aReturn[j] = aLayout[i][j].cell;
2428
- }
2429
- }
2430
- }
2431
-
2432
- return aReturn;
2433
- }
2434
-
2435
- /**
2436
- * Create an Ajax call based on the table's settings, taking into account that
2437
- * parameters can have multiple forms, and backwards compatibility.
2438
- *
2439
- * @param {object} oSettings dataTables settings object
2440
- * @param {array} data Data to send to the server, required by
2441
- * DataTables - may be augmented by developer callbacks
2442
- * @param {function} fn Callback function to run when data is obtained
2443
- */
2444
- function _fnBuildAjax( oSettings, data, fn )
2445
- {
2446
- // Compatibility with 1.9-, allow fnServerData and event to manipulate
2447
- _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
2448
-
2449
- // Convert to object based for 1.10+ if using the old array scheme which can
2450
- // come from server-side processing or serverParams
2451
- if ( data && $.isArray(data) ) {
2452
- var tmp = {};
2453
- var rbracket = /(.*?)\[\]$/;
2454
-
2455
- $.each( data, function (key, val) {
2456
- var match = val.name.match(rbracket);
2457
-
2458
- if ( match ) {
2459
- // Support for arrays
2460
- var name = match[0];
2461
-
2462
- if ( ! tmp[ name ] ) {
2463
- tmp[ name ] = [];
2464
- }
2465
- tmp[ name ].push( val.value );
2466
- }
2467
- else {
2468
- tmp[val.name] = val.value;
2469
- }
2470
- } );
2471
- data = tmp;
2472
- }
2473
-
2474
- var ajaxData;
2475
- var ajax = oSettings.ajax;
2476
- var instance = oSettings.oInstance;
2477
- var callback = function ( json ) {
2478
- _fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );
2479
- fn( json );
2480
- };
2481
-
2482
- if ( $.isPlainObject( ajax ) && ajax.data )
2483
- {
2484
- ajaxData = ajax.data;
2485
-
2486
- var newData = $.isFunction( ajaxData ) ?
2487
- ajaxData( data, oSettings ) : // fn can manipulate data or return
2488
- ajaxData; // an object object or array to merge
2489
-
2490
- // If the function returned something, use that alone
2491
- data = $.isFunction( ajaxData ) && newData ?
2492
- newData :
2493
- $.extend( true, data, newData );
2494
-
2495
- // Remove the data property as we've resolved it already and don't want
2496
- // jQuery to do it again (it is restored at the end of the function)
2497
- delete ajax.data;
2498
- }
2499
-
2500
- var baseAjax = {
2501
- "data": data,
2502
- "success": function (json) {
2503
- var error = json.error || json.sError;
2504
- if ( error ) {
2505
- _fnLog( oSettings, 0, error );
2506
- }
2507
-
2508
- oSettings.json = json;
2509
- callback( json );
2510
- },
2511
- "dataType": "json",
2512
- "cache": false,
2513
- "type": oSettings.sServerMethod,
2514
- "error": function (xhr, error, thrown) {
2515
- var ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );
2516
-
2517
- if ( $.inArray( true, ret ) === -1 ) {
2518
- if ( error == "parsererror" ) {
2519
- _fnLog( oSettings, 0, 'Invalid JSON response', 1 );
2520
- }
2521
- else if ( xhr.readyState === 4 ) {
2522
- _fnLog( oSettings, 0, 'Ajax error', 7 );
2523
- }
2524
- }
2525
-
2526
- _fnProcessingDisplay( oSettings, false );
2527
- }
2528
- };
2529
-
2530
- // Store the data submitted for the API
2531
- oSettings.oAjaxData = data;
2532
-
2533
- // Allow plug-ins and external processes to modify the data
2534
- _fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
2535
-
2536
- if ( oSettings.fnServerData )
2537
- {
2538
- // DataTables 1.9- compatibility
2539
- oSettings.fnServerData.call( instance,
2540
- oSettings.sAjaxSource,
2541
- $.map( data, function (val, key) { // Need to convert back to 1.9 trad format
2542
- return { name: key, value: val };
2543
- } ),
2544
- callback,
2545
- oSettings
2546
- );
2547
- }
2548
- else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
2549
- {
2550
- // DataTables 1.9- compatibility
2551
- oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
2552
- url: ajax || oSettings.sAjaxSource
2553
- } ) );
2554
- }
2555
- else if ( $.isFunction( ajax ) )
2556
- {
2557
- // Is a function - let the caller define what needs to be done
2558
- oSettings.jqXHR = ajax.call( instance, data, callback, oSettings );
2559
- }
2560
- else
2561
- {
2562
- // Object to extend the base settings
2563
- oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
2564
-
2565
- // Restore for next time around
2566
- ajax.data = ajaxData;
2567
- }
2568
- }
2569
-
2570
-
2571
- /**
2572
- * Update the table using an Ajax call
2573
- * @param {object} settings dataTables settings object
2574
- * @returns {boolean} Block the table drawing or not
2575
- * @memberof DataTable#oApi
2576
- */
2577
- function _fnAjaxUpdate( settings )
2578
- {
2579
- if ( settings.bAjaxDataGet ) {
2580
- settings.iDraw++;
2581
- _fnProcessingDisplay( settings, true );
2582
-
2583
- _fnBuildAjax(
2584
- settings,
2585
- _fnAjaxParameters( settings ),
2586
- function(json) {
2587
- _fnAjaxUpdateDraw( settings, json );
2588
- }
2589
- );
2590
-
2591
- return false;
2592
- }
2593
- return true;
2594
- }
2595
-
2596
-
2597
- /**
2598
- * Build up the parameters in an object needed for a server-side processing
2599
- * request. Note that this is basically done twice, is different ways - a modern
2600
- * method which is used by default in DataTables 1.10 which uses objects and
2601
- * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
2602
- * the sAjaxSource option is used in the initialisation, or the legacyAjax
2603
- * option is set.
2604
- * @param {object} oSettings dataTables settings object
2605
- * @returns {bool} block the table drawing or not
2606
- * @memberof DataTable#oApi
2607
- */
2608
- function _fnAjaxParameters( settings )
2609
- {
2610
- var
2611
- columns = settings.aoColumns,
2612
- columnCount = columns.length,
2613
- features = settings.oFeatures,
2614
- preSearch = settings.oPreviousSearch,
2615
- preColSearch = settings.aoPreSearchCols,
2616
- i, data = [], dataProp, column, columnSearch,
2617
- sort = _fnSortFlatten( settings ),
2618
- displayStart = settings._iDisplayStart,
2619
- displayLength = features.bPaginate !== false ?
2620
- settings._iDisplayLength :
2621
- -1;
2622
-
2623
- var param = function ( name, value ) {
2624
- data.push( { 'name': name, 'value': value } );
2625
- };
2626
-
2627
- // DataTables 1.9- compatible method
2628
- param( 'sEcho', settings.iDraw );
2629
- param( 'iColumns', columnCount );
2630
- param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
2631
- param( 'iDisplayStart', displayStart );
2632
- param( 'iDisplayLength', displayLength );
2633
-
2634
- // DataTables 1.10+ method
2635
- var d = {
2636
- draw: settings.iDraw,
2637
- columns: [],
2638
- order: [],
2639
- start: displayStart,
2640
- length: displayLength,
2641
- search: {
2642
- value: preSearch.sSearch,
2643
- regex: preSearch.bRegex
2644
- }
2645
- };
2646
-
2647
- for ( i=0 ; i<columnCount ; i++ ) {
2648
- column = columns[i];
2649
- columnSearch = preColSearch[i];
2650
- dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
2651
-
2652
- d.columns.push( {
2653
- data: dataProp,
2654
- name: column.sName,
2655
- searchable: column.bSearchable,
2656
- orderable: column.bSortable,
2657
- search: {
2658
- value: columnSearch.sSearch,
2659
- regex: columnSearch.bRegex
2660
- }
2661
- } );
2662
-
2663
- param( "mDataProp_"+i, dataProp );
2664
-
2665
- if ( features.bFilter ) {
2666
- param( 'sSearch_'+i, columnSearch.sSearch );
2667
- param( 'bRegex_'+i, columnSearch.bRegex );
2668
- param( 'bSearchable_'+i, column.bSearchable );
2669
- }
2670
-
2671
- if ( features.bSort ) {
2672
- param( 'bSortable_'+i, column.bSortable );
2673
- }
2674
- }
2675
-
2676
- if ( features.bFilter ) {
2677
- param( 'sSearch', preSearch.sSearch );
2678
- param( 'bRegex', preSearch.bRegex );
2679
- }
2680
-
2681
- if ( features.bSort ) {
2682
- $.each( sort, function ( i, val ) {
2683
- d.order.push( { column: val.col, dir: val.dir } );
2684
-
2685
- param( 'iSortCol_'+i, val.col );
2686
- param( 'sSortDir_'+i, val.dir );
2687
- } );
2688
-
2689
- param( 'iSortingCols', sort.length );
2690
- }
2691
-
2692
- // If the legacy.ajax parameter is null, then we automatically decide which
2693
- // form to use, based on sAjaxSource
2694
- var legacy = DataTable.ext.legacy.ajax;
2695
- if ( legacy === null ) {
2696
- return settings.sAjaxSource ? data : d;
2697
- }
2698
-
2699
- // Otherwise, if legacy has been specified then we use that to decide on the
2700
- // form
2701
- return legacy ? data : d;
2702
- }
2703
-
2704
-
2705
- /**
2706
- * Data the data from the server (nuking the old) and redraw the table
2707
- * @param {object} oSettings dataTables settings object
2708
- * @param {object} json json data return from the server.
2709
- * @param {string} json.sEcho Tracking flag for DataTables to match requests
2710
- * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
2711
- * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
2712
- * @param {array} json.aaData The data to display on this page
2713
- * @param {string} [json.sColumns] Column ordering (sName, comma separated)
2714
- * @memberof DataTable#oApi
2715
- */
2716
- function _fnAjaxUpdateDraw ( settings, json )
2717
- {
2718
- // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
2719
- // Support both
2720
- var compat = function ( old, modern ) {
2721
- return json[old] !== undefined ? json[old] : json[modern];
2722
- };
2723
-
2724
- var data = _fnAjaxDataSrc( settings, json );
2725
- var draw = compat( 'sEcho', 'draw' );
2726
- var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
2727
- var recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
2728
-
2729
- if ( draw ) {
2730
- // Protect against out of sequence returns
2731
- if ( draw*1 < settings.iDraw ) {
2732
- return;
2733
- }
2734
- settings.iDraw = draw * 1;
2735
- }
2736
-
2737
- _fnClearTable( settings );
2738
- settings._iRecordsTotal = parseInt(recordsTotal, 10);
2739
- settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
2740
-
2741
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
2742
- _fnAddData( settings, data[i] );
2743
- }
2744
- settings.aiDisplay = settings.aiDisplayMaster.slice();
2745
-
2746
- settings.bAjaxDataGet = false;
2747
- _fnDraw( settings );
2748
-
2749
- if ( ! settings._bInitComplete ) {
2750
- _fnInitComplete( settings, json );
2751
- }
2752
-
2753
- settings.bAjaxDataGet = true;
2754
- _fnProcessingDisplay( settings, false );
2755
- }
2756
-
2757
-
2758
- /**
2759
- * Get the data from the JSON data source to use for drawing a table. Using
2760
- * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
2761
- * source object, or from a processing function.
2762
- * @param {object} oSettings dataTables settings object
2763
- * @param {object} json Data source object / array from the server
2764
- * @return {array} Array of data to use
2765
- */
2766
- function _fnAjaxDataSrc ( oSettings, json )
2767
- {
2768
- var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
2769
- oSettings.ajax.dataSrc :
2770
- oSettings.sAjaxDataProp; // Compatibility with 1.9-.
2771
-
2772
- // Compatibility with 1.9-. In order to read from aaData, check if the
2773
- // default has been changed, if not, check for aaData
2774
- if ( dataSrc === 'data' ) {
2775
- return json.aaData || json[dataSrc];
2776
- }
2777
-
2778
- return dataSrc !== "" ?
2779
- _fnGetObjectDataFn( dataSrc )( json ) :
2780
- json;
2781
- }
2782
-
2783
- /**
2784
- * Generate the node required for filtering text
2785
- * @returns {node} Filter control element
2786
- * @param {object} oSettings dataTables settings object
2787
- * @memberof DataTable#oApi
2788
- */
2789
- function _fnFeatureHtmlFilter ( settings )
2790
- {
2791
- var classes = settings.oClasses;
2792
- var tableId = settings.sTableId;
2793
- var language = settings.oLanguage;
2794
- var previousSearch = settings.oPreviousSearch;
2795
- var features = settings.aanFeatures;
2796
- var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
2797
-
2798
- var str = language.sSearch;
2799
- str = str.match(/_INPUT_/) ?
2800
- str.replace('_INPUT_', input) :
2801
- str+input;
2802
-
2803
- var filter = $('<div/>', {
2804
- 'id': ! features.f ? tableId+'_filter' : null,
2805
- 'class': classes.sFilter
2806
- } )
2807
- .append( $('<label/>' ).append( str ) );
2808
-
2809
- var searchFn = function() {
2810
- /* Update all other filter input elements for the new display */
2811
- var n = features.f;
2812
- var val = !this.value ? "" : this.value; // mental IE8 fix :-(
2813
-
2814
- /* Now do the filter */
2815
- if ( val != previousSearch.sSearch ) {
2816
- _fnFilterComplete( settings, {
2817
- "sSearch": val,
2818
- "bRegex": previousSearch.bRegex,
2819
- "bSmart": previousSearch.bSmart ,
2820
- "bCaseInsensitive": previousSearch.bCaseInsensitive
2821
- } );
2822
-
2823
- // Need to redraw, without resorting
2824
- settings._iDisplayStart = 0;
2825
- _fnDraw( settings );
2826
- }
2827
- };
2828
-
2829
- var searchDelay = settings.searchDelay !== null ?
2830
- settings.searchDelay :
2831
- _fnDataSource( settings ) === 'ssp' ?
2832
- 400 :
2833
- 0;
2834
-
2835
- var jqFilter = $('input', filter)
2836
- .val( previousSearch.sSearch )
2837
- .attr( 'placeholder', language.sSearchPlaceholder )
2838
- .bind(
2839
- 'keyup.DT search.DT input.DT paste.DT cut.DT',
2840
- searchDelay ?
2841
- _fnThrottle( searchFn, searchDelay ) :
2842
- searchFn
2843
- )
2844
- .bind( 'keypress.DT', function(e) {
2845
- /* Prevent form submission */
2846
- if ( e.keyCode == 13 ) {
2847
- return false;
2848
- }
2849
- } )
2850
- .attr('aria-controls', tableId);
2851
-
2852
- // Update the input elements whenever the table is filtered
2853
- $(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {
2854
- if ( settings === s ) {
2855
- // IE9 throws an 'unknown error' if document.activeElement is used
2856
- // inside an iframe or frame...
2857
- try {
2858
- if ( jqFilter[0] !== document.activeElement ) {
2859
- jqFilter.val( previousSearch.sSearch );
2860
- }
2861
- }
2862
- catch ( e ) {}
2863
- }
2864
- } );
2865
-
2866
- return filter[0];
2867
- }
2868
-
2869
-
2870
- /**
2871
- * Filter the table using both the global filter and column based filtering
2872
- * @param {object} oSettings dataTables settings object
2873
- * @param {object} oSearch search information
2874
- * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
2875
- * @memberof DataTable#oApi
2876
- */
2877
- function _fnFilterComplete ( oSettings, oInput, iForce )
2878
- {
2879
- var oPrevSearch = oSettings.oPreviousSearch;
2880
- var aoPrevSearch = oSettings.aoPreSearchCols;
2881
- var fnSaveFilter = function ( oFilter ) {
2882
- /* Save the filtering values */
2883
- oPrevSearch.sSearch = oFilter.sSearch;
2884
- oPrevSearch.bRegex = oFilter.bRegex;
2885
- oPrevSearch.bSmart = oFilter.bSmart;
2886
- oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
2887
- };
2888
- var fnRegex = function ( o ) {
2889
- // Backwards compatibility with the bEscapeRegex option
2890
- return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
2891
- };
2892
-
2893
- // Resolve any column types that are unknown due to addition or invalidation
2894
- // @todo As per sort - can this be moved into an event handler?
2895
- _fnColumnTypes( oSettings );
2896
-
2897
- /* In server-side processing all filtering is done by the server, so no point hanging around here */
2898
- if ( _fnDataSource( oSettings ) != 'ssp' )
2899
- {
2900
- /* Global filter */
2901
- _fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
2902
- fnSaveFilter( oInput );
2903
-
2904
- /* Now do the individual column filter */
2905
- for ( var i=0 ; i<aoPrevSearch.length ; i++ )
2906
- {
2907
- _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
2908
- aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
2909
- }
2910
-
2911
- /* Custom filtering */
2912
- _fnFilterCustom( oSettings );
2913
- }
2914
- else
2915
- {
2916
- fnSaveFilter( oInput );
2917
- }
2918
-
2919
- /* Tell the draw function we have been filtering */
2920
- oSettings.bFiltered = true;
2921
- _fnCallbackFire( oSettings, null, 'search', [oSettings] );
2922
- }
2923
-
2924
-
2925
- /**
2926
- * Apply custom filtering functions
2927
- * @param {object} oSettings dataTables settings object
2928
- * @memberof DataTable#oApi
2929
- */
2930
- function _fnFilterCustom( settings )
2931
- {
2932
- var filters = DataTable.ext.search;
2933
- var displayRows = settings.aiDisplay;
2934
- var row, rowIdx;
2935
-
2936
- for ( var i=0, ien=filters.length ; i<ien ; i++ ) {
2937
- var rows = [];
2938
-
2939
- // Loop over each row and see if it should be included
2940
- for ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {
2941
- rowIdx = displayRows[ j ];
2942
- row = settings.aoData[ rowIdx ];
2943
-
2944
- if ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {
2945
- rows.push( rowIdx );
2946
- }
2947
- }
2948
-
2949
- // So the array reference doesn't break set the results into the
2950
- // existing array
2951
- displayRows.length = 0;
2952
- $.merge( displayRows, rows );
2953
- }
2954
- }
2955
-
2956
-
2957
- /**
2958
- * Filter the table on a per-column basis
2959
- * @param {object} oSettings dataTables settings object
2960
- * @param {string} sInput string to filter on
2961
- * @param {int} iColumn column to filter
2962
- * @param {bool} bRegex treat search string as a regular expression or not
2963
- * @param {bool} bSmart use smart filtering or not
2964
- * @param {bool} bCaseInsensitive Do case insenstive matching or not
2965
- * @memberof DataTable#oApi
2966
- */
2967
- function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
2968
- {
2969
- if ( searchStr === '' ) {
2970
- return;
2971
- }
2972
-
2973
- var data;
2974
- var display = settings.aiDisplay;
2975
- var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
2976
-
2977
- for ( var i=display.length-1 ; i>=0 ; i-- ) {
2978
- data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
2979
-
2980
- if ( ! rpSearch.test( data ) ) {
2981
- display.splice( i, 1 );
2982
- }
2983
- }
2984
- }
2985
-
2986
-
2987
- /**
2988
- * Filter the data table based on user input and draw the table
2989
- * @param {object} settings dataTables settings object
2990
- * @param {string} input string to filter on
2991
- * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
2992
- * @param {bool} regex treat as a regular expression or not
2993
- * @param {bool} smart perform smart filtering or not
2994
- * @param {bool} caseInsensitive Do case insenstive matching or not
2995
- * @memberof DataTable#oApi
2996
- */
2997
- function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
2998
- {
2999
- var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
3000
- var prevSearch = settings.oPreviousSearch.sSearch;
3001
- var displayMaster = settings.aiDisplayMaster;
3002
- var display, invalidated, i;
3003
-
3004
- // Need to take account of custom filtering functions - always filter
3005
- if ( DataTable.ext.search.length !== 0 ) {
3006
- force = true;
3007
- }
3008
-
3009
- // Check if any of the rows were invalidated
3010
- invalidated = _fnFilterData( settings );
3011
-
3012
- // If the input is blank - we just want the full data set
3013
- if ( input.length <= 0 ) {
3014
- settings.aiDisplay = displayMaster.slice();
3015
- }
3016
- else {
3017
- // New search - start from the master array
3018
- if ( invalidated ||
3019
- force ||
3020
- prevSearch.length > input.length ||
3021
- input.indexOf(prevSearch) !== 0 ||
3022
- settings.bSorted // On resort, the display master needs to be
3023
- // re-filtered since indexes will have changed
3024
- ) {
3025
- settings.aiDisplay = displayMaster.slice();
3026
- }
3027
-
3028
- // Search the display array
3029
- display = settings.aiDisplay;
3030
-
3031
- for ( i=display.length-1 ; i>=0 ; i-- ) {
3032
- if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
3033
- display.splice( i, 1 );
3034
- }
3035
- }
3036
- }
3037
- }
3038
-
3039
-
3040
- /**
3041
- * Build a regular expression object suitable for searching a table
3042
- * @param {string} sSearch string to search for
3043
- * @param {bool} bRegex treat as a regular expression or not
3044
- * @param {bool} bSmart perform smart filtering or not
3045
- * @param {bool} bCaseInsensitive Do case insensitive matching or not
3046
- * @returns {RegExp} constructed object
3047
- * @memberof DataTable#oApi
3048
- */
3049
- function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
3050
- {
3051
- search = regex ?
3052
- search :
3053
- _fnEscapeRegex( search );
3054
-
3055
- if ( smart ) {
3056
- /* For smart filtering we want to allow the search to work regardless of
3057
- * word order. We also want double quoted text to be preserved, so word
3058
- * order is important - a la google. So this is what we want to
3059
- * generate:
3060
- *
3061
- * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
3062
- */
3063
- var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || [''], function ( word ) {
3064
- if ( word.charAt(0) === '"' ) {
3065
- var m = word.match( /^"(.*)"$/ );
3066
- word = m ? m[1] : word;
3067
- }
3068
-
3069
- return word.replace('"', '');
3070
- } );
3071
-
3072
- search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
3073
- }
3074
-
3075
- return new RegExp( search, caseInsensitive ? 'i' : '' );
3076
- }
3077
-
3078
-
3079
- /**
3080
- * Escape a string such that it can be used in a regular expression
3081
- * @param {string} sVal string to escape
3082
- * @returns {string} escaped string
3083
- * @memberof DataTable#oApi
3084
- */
3085
- function _fnEscapeRegex ( sVal )
3086
- {
3087
- return sVal.replace( _re_escape_regex, '\\$1' );
3088
- }
3089
-
3090
-
3091
-
3092
- var __filter_div = $('<div>')[0];
3093
- var __filter_div_textContent = __filter_div.textContent !== undefined;
3094
-
3095
- // Update the filtering data for each row if needed (by invalidation or first run)
3096
- function _fnFilterData ( settings )
3097
- {
3098
- var columns = settings.aoColumns;
3099
- var column;
3100
- var i, j, ien, jen, filterData, cellData, row;
3101
- var fomatters = DataTable.ext.type.search;
3102
- var wasInvalidated = false;
3103
-
3104
- for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
3105
- row = settings.aoData[i];
3106
-
3107
- if ( ! row._aFilterData ) {
3108
- filterData = [];
3109
-
3110
- for ( j=0, jen=columns.length ; j<jen ; j++ ) {
3111
- column = columns[j];
3112
-
3113
- if ( column.bSearchable ) {
3114
- cellData = _fnGetCellData( settings, i, j, 'filter' );
3115
-
3116
- if ( fomatters[ column.sType ] ) {
3117
- cellData = fomatters[ column.sType ]( cellData );
3118
- }
3119
-
3120
- // Search in DataTables 1.10 is string based. In 1.11 this
3121
- // should be altered to also allow strict type checking.
3122
- if ( cellData === null ) {
3123
- cellData = '';
3124
- }
3125
-
3126
- if ( typeof cellData !== 'string' && cellData.toString ) {
3127
- cellData = cellData.toString();
3128
- }
3129
- }
3130
- else {
3131
- cellData = '';
3132
- }
3133
-
3134
- // If it looks like there is an HTML entity in the string,
3135
- // attempt to decode it so sorting works as expected. Note that
3136
- // we could use a single line of jQuery to do this, but the DOM
3137
- // method used here is much faster http://jsperf.com/html-decode
3138
- if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
3139
- __filter_div.innerHTML = cellData;
3140
- cellData = __filter_div_textContent ?
3141
- __filter_div.textContent :
3142
- __filter_div.innerText;
3143
- }
3144
-
3145
- if ( cellData.replace ) {
3146
- cellData = cellData.replace(/[\r\n]/g, '');
3147
- }
3148
-
3149
- filterData.push( cellData );
3150
- }
3151
-
3152
- row._aFilterData = filterData;
3153
- row._sFilterRow = filterData.join(' ');
3154
- wasInvalidated = true;
3155
- }
3156
- }
3157
-
3158
- return wasInvalidated;
3159
- }
3160
-
3161
-
3162
- /**
3163
- * Convert from the internal Hungarian notation to camelCase for external
3164
- * interaction
3165
- * @param {object} obj Object to convert
3166
- * @returns {object} Inverted object
3167
- * @memberof DataTable#oApi
3168
- */
3169
- function _fnSearchToCamel ( obj )
3170
- {
3171
- return {
3172
- search: obj.sSearch,
3173
- smart: obj.bSmart,
3174
- regex: obj.bRegex,
3175
- caseInsensitive: obj.bCaseInsensitive
3176
- };
3177
- }
3178
-
3179
-
3180
-
3181
- /**
3182
- * Convert from camelCase notation to the internal Hungarian. We could use the
3183
- * Hungarian convert function here, but this is cleaner
3184
- * @param {object} obj Object to convert
3185
- * @returns {object} Inverted object
3186
- * @memberof DataTable#oApi
3187
- */
3188
- function _fnSearchToHung ( obj )
3189
- {
3190
- return {
3191
- sSearch: obj.search,
3192
- bSmart: obj.smart,
3193
- bRegex: obj.regex,
3194
- bCaseInsensitive: obj.caseInsensitive
3195
- };
3196
- }
3197
-
3198
- /**
3199
- * Generate the node required for the info display
3200
- * @param {object} oSettings dataTables settings object
3201
- * @returns {node} Information element
3202
- * @memberof DataTable#oApi
3203
- */
3204
- function _fnFeatureHtmlInfo ( settings )
3205
- {
3206
- var
3207
- tid = settings.sTableId,
3208
- nodes = settings.aanFeatures.i,
3209
- n = $('<div/>', {
3210
- 'class': settings.oClasses.sInfo,
3211
- 'id': ! nodes ? tid+'_info' : null
3212
- } );
3213
-
3214
- if ( ! nodes ) {
3215
- // Update display on each draw
3216
- settings.aoDrawCallback.push( {
3217
- "fn": _fnUpdateInfo,
3218
- "sName": "information"
3219
- } );
3220
-
3221
- n
3222
- .attr( 'role', 'status' )
3223
- .attr( 'aria-live', 'polite' );
3224
-
3225
- // Table is described by our info div
3226
- $(settings.nTable).attr( 'aria-describedby', tid+'_info' );
3227
- }
3228
-
3229
- return n[0];
3230
- }
3231
-
3232
-
3233
- /**
3234
- * Update the information elements in the display
3235
- * @param {object} settings dataTables settings object
3236
- * @memberof DataTable#oApi
3237
- */
3238
- function _fnUpdateInfo ( settings )
3239
- {
3240
- /* Show information about the table */
3241
- var nodes = settings.aanFeatures.i;
3242
- if ( nodes.length === 0 ) {
3243
- return;
3244
- }
3245
-
3246
- var
3247
- lang = settings.oLanguage,
3248
- start = settings._iDisplayStart+1,
3249
- end = settings.fnDisplayEnd(),
3250
- max = settings.fnRecordsTotal(),
3251
- total = settings.fnRecordsDisplay(),
3252
- out = total ?
3253
- lang.sInfo :
3254
- lang.sInfoEmpty;
3255
-
3256
- if ( total !== max ) {
3257
- /* Record set after filtering */
3258
- out += ' ' + lang.sInfoFiltered;
3259
- }
3260
-
3261
- // Convert the macros
3262
- out += lang.sInfoPostFix;
3263
- out = _fnInfoMacros( settings, out );
3264
-
3265
- var callback = lang.fnInfoCallback;
3266
- if ( callback !== null ) {
3267
- out = callback.call( settings.oInstance,
3268
- settings, start, end, max, total, out
3269
- );
3270
- }
3271
-
3272
- $(nodes).html( out );
3273
- }
3274
-
3275
-
3276
- function _fnInfoMacros ( settings, str )
3277
- {
3278
- // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
3279
- // internally
3280
- var
3281
- formatter = settings.fnFormatNumber,
3282
- start = settings._iDisplayStart+1,
3283
- len = settings._iDisplayLength,
3284
- vis = settings.fnRecordsDisplay(),
3285
- all = len === -1;
3286
-
3287
- return str.
3288
- replace(/_START_/g, formatter.call( settings, start ) ).
3289
- replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
3290
- replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
3291
- replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
3292
- replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
3293
- replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
3294
- }
3295
-
3296
-
3297
-
3298
- /**
3299
- * Draw the table for the first time, adding all required features
3300
- * @param {object} settings dataTables settings object
3301
- * @memberof DataTable#oApi
3302
- */
3303
- function _fnInitialise ( settings )
3304
- {
3305
- var i, iLen, iAjaxStart=settings.iInitDisplayStart;
3306
- var columns = settings.aoColumns, column;
3307
- var features = settings.oFeatures;
3308
- var deferLoading = settings.bDeferLoading; // value modified by the draw
3309
-
3310
- /* Ensure that the table data is fully initialised */
3311
- if ( ! settings.bInitialised ) {
3312
- setTimeout( function(){ _fnInitialise( settings ); }, 200 );
3313
- return;
3314
- }
3315
-
3316
- /* Show the display HTML options */
3317
- _fnAddOptionsHtml( settings );
3318
-
3319
- /* Build and draw the header / footer for the table */
3320
- _fnBuildHead( settings );
3321
- _fnDrawHead( settings, settings.aoHeader );
3322
- _fnDrawHead( settings, settings.aoFooter );
3323
-
3324
- /* Okay to show that something is going on now */
3325
- _fnProcessingDisplay( settings, true );
3326
-
3327
- /* Calculate sizes for columns */
3328
- if ( features.bAutoWidth ) {
3329
- _fnCalculateColumnWidths( settings );
3330
- }
3331
-
3332
- for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
3333
- column = columns[i];
3334
-
3335
- if ( column.sWidth ) {
3336
- column.nTh.style.width = _fnStringToCss( column.sWidth );
3337
- }
3338
- }
3339
-
3340
- _fnCallbackFire( settings, null, 'preInit', [settings] );
3341
-
3342
- // If there is default sorting required - let's do it. The sort function
3343
- // will do the drawing for us. Otherwise we draw the table regardless of the
3344
- // Ajax source - this allows the table to look initialised for Ajax sourcing
3345
- // data (show 'loading' message possibly)
3346
- _fnReDraw( settings );
3347
-
3348
- // Server-side processing init complete is done by _fnAjaxUpdateDraw
3349
- var dataSrc = _fnDataSource( settings );
3350
- if ( dataSrc != 'ssp' || deferLoading ) {
3351
- // if there is an ajax source load the data
3352
- if ( dataSrc == 'ajax' ) {
3353
- _fnBuildAjax( settings, [], function(json) {
3354
- var aData = _fnAjaxDataSrc( settings, json );
3355
-
3356
- // Got the data - add it to the table
3357
- for ( i=0 ; i<aData.length ; i++ ) {
3358
- _fnAddData( settings, aData[i] );
3359
- }
3360
-
3361
- // Reset the init display for cookie saving. We've already done
3362
- // a filter, and therefore cleared it before. So we need to make
3363
- // it appear 'fresh'
3364
- settings.iInitDisplayStart = iAjaxStart;
3365
-
3366
- _fnReDraw( settings );
3367
-
3368
- _fnProcessingDisplay( settings, false );
3369
- _fnInitComplete( settings, json );
3370
- }, settings );
3371
- }
3372
- else {
3373
- _fnProcessingDisplay( settings, false );
3374
- _fnInitComplete( settings );
3375
- }
3376
- }
3377
- }
3378
-
3379
-
3380
- /**
3381
- * Draw the table for the first time, adding all required features
3382
- * @param {object} oSettings dataTables settings object
3383
- * @param {object} [json] JSON from the server that completed the table, if using Ajax source
3384
- * with client-side processing (optional)
3385
- * @memberof DataTable#oApi
3386
- */
3387
- function _fnInitComplete ( settings, json )
3388
- {
3389
- settings._bInitComplete = true;
3390
-
3391
- // When data was added after the initialisation (data or Ajax) we need to
3392
- // calculate the column sizing
3393
- if ( json || settings.oInit.aaData ) {
3394
- _fnAdjustColumnSizing( settings );
3395
- }
3396
-
3397
- _fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
3398
- }
3399
-
3400
-
3401
- function _fnLengthChange ( settings, val )
3402
- {
3403
- var len = parseInt( val, 10 );
3404
- settings._iDisplayLength = len;
3405
-
3406
- _fnLengthOverflow( settings );
3407
-
3408
- // Fire length change event
3409
- _fnCallbackFire( settings, null, 'length', [settings, len] );
3410
- }
3411
-
3412
-
3413
- /**
3414
- * Generate the node required for user display length changing
3415
- * @param {object} settings dataTables settings object
3416
- * @returns {node} Display length feature node
3417
- * @memberof DataTable#oApi
3418
- */
3419
- function _fnFeatureHtmlLength ( settings )
3420
- {
3421
- var
3422
- classes = settings.oClasses,
3423
- tableId = settings.sTableId,
3424
- menu = settings.aLengthMenu,
3425
- d2 = $.isArray( menu[0] ),
3426
- lengths = d2 ? menu[0] : menu,
3427
- language = d2 ? menu[1] : menu;
3428
-
3429
- var select = $('<select/>', {
3430
- 'name': tableId+'_length',
3431
- 'aria-controls': tableId,
3432
- 'class': classes.sLengthSelect
3433
- } );
3434
-
3435
- for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
3436
- select[0][ i ] = new Option( language[i], lengths[i] );
3437
- }
3438
-
3439
- var div = $('<div><label/></div>').addClass( classes.sLength );
3440
- if ( ! settings.aanFeatures.l ) {
3441
- div[0].id = tableId+'_length';
3442
- }
3443
-
3444
- div.children().append(
3445
- settings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )
3446
- );
3447
-
3448
- // Can't use `select` variable as user might provide their own and the
3449
- // reference is broken by the use of outerHTML
3450
- $('select', div)
3451
- .val( settings._iDisplayLength )
3452
- .bind( 'change.DT', function(e) {
3453
- _fnLengthChange( settings, $(this).val() );
3454
- _fnDraw( settings );
3455
- } );
3456
-
3457
- // Update node value whenever anything changes the table's length
3458
- $(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
3459
- if ( settings === s ) {
3460
- $('select', div).val( len );
3461
- }
3462
- } );
3463
-
3464
- return div[0];
3465
- }
3466
-
3467
-
3468
-
3469
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3470
- * Note that most of the paging logic is done in
3471
- * DataTable.ext.pager
3472
- */
3473
-
3474
- /**
3475
- * Generate the node required for default pagination
3476
- * @param {object} oSettings dataTables settings object
3477
- * @returns {node} Pagination feature node
3478
- * @memberof DataTable#oApi
3479
- */
3480
- function _fnFeatureHtmlPaginate ( settings )
3481
- {
3482
- var
3483
- type = settings.sPaginationType,
3484
- plugin = DataTable.ext.pager[ type ],
3485
- modern = typeof plugin === 'function',
3486
- redraw = function( settings ) {
3487
- _fnDraw( settings );
3488
- },
3489
- node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
3490
- features = settings.aanFeatures;
3491
-
3492
- if ( ! modern ) {
3493
- plugin.fnInit( settings, node, redraw );
3494
- }
3495
-
3496
- /* Add a draw callback for the pagination on first instance, to update the paging display */
3497
- if ( ! features.p )
3498
- {
3499
- node.id = settings.sTableId+'_paginate';
3500
-
3501
- settings.aoDrawCallback.push( {
3502
- "fn": function( settings ) {
3503
- if ( modern ) {
3504
- var
3505
- start = settings._iDisplayStart,
3506
- len = settings._iDisplayLength,
3507
- visRecords = settings.fnRecordsDisplay(),
3508
- all = len === -1,
3509
- page = all ? 0 : Math.ceil( start / len ),
3510
- pages = all ? 1 : Math.ceil( visRecords / len ),
3511
- buttons = plugin(page, pages),
3512
- i, ien;
3513
-
3514
- for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
3515
- _fnRenderer( settings, 'pageButton' )(
3516
- settings, features.p[i], i, buttons, page, pages
3517
- );
3518
- }
3519
- }
3520
- else {
3521
- plugin.fnUpdate( settings, redraw );
3522
- }
3523
- },
3524
- "sName": "pagination"
3525
- } );
3526
- }
3527
-
3528
- return node;
3529
- }
3530
-
3531
-
3532
- /**
3533
- * Alter the display settings to change the page
3534
- * @param {object} settings DataTables settings object
3535
- * @param {string|int} action Paging action to take: "first", "previous",
3536
- * "next" or "last" or page number to jump to (integer)
3537
- * @param [bool] redraw Automatically draw the update or not
3538
- * @returns {bool} true page has changed, false - no change
3539
- * @memberof DataTable#oApi
3540
- */
3541
- function _fnPageChange ( settings, action, redraw )
3542
- {
3543
- var
3544
- start = settings._iDisplayStart,
3545
- len = settings._iDisplayLength,
3546
- records = settings.fnRecordsDisplay();
3547
-
3548
- if ( records === 0 || len === -1 )
3549
- {
3550
- start = 0;
3551
- }
3552
- else if ( typeof action === "number" )
3553
- {
3554
- start = action * len;
3555
-
3556
- if ( start > records )
3557
- {
3558
- start = 0;
3559
- }
3560
- }
3561
- else if ( action == "first" )
3562
- {
3563
- start = 0;
3564
- }
3565
- else if ( action == "previous" )
3566
- {
3567
- start = len >= 0 ?
3568
- start - len :
3569
- 0;
3570
-
3571
- if ( start < 0 )
3572
- {
3573
- start = 0;
3574
- }
3575
- }
3576
- else if ( action == "next" )
3577
- {
3578
- if ( start + len < records )
3579
- {
3580
- start += len;
3581
- }
3582
- }
3583
- else if ( action == "last" )
3584
- {
3585
- start = Math.floor( (records-1) / len) * len;
3586
- }
3587
- else
3588
- {
3589
- _fnLog( settings, 0, "Unknown paging action: "+action, 5 );
3590
- }
3591
-
3592
- var changed = settings._iDisplayStart !== start;
3593
- settings._iDisplayStart = start;
3594
-
3595
- if ( changed ) {
3596
- _fnCallbackFire( settings, null, 'page', [settings] );
3597
-
3598
- if ( redraw ) {
3599
- _fnDraw( settings );
3600
- }
3601
- }
3602
-
3603
- return changed;
3604
- }
3605
-
3606
-
3607
-
3608
- /**
3609
- * Generate the node required for the processing node
3610
- * @param {object} settings dataTables settings object
3611
- * @returns {node} Processing element
3612
- * @memberof DataTable#oApi
3613
- */
3614
- function _fnFeatureHtmlProcessing ( settings )
3615
- {
3616
- return $('<div/>', {
3617
- 'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
3618
- 'class': settings.oClasses.sProcessing
3619
- } )
3620
- .html( settings.oLanguage.sProcessing )
3621
- .insertBefore( settings.nTable )[0];
3622
- }
3623
-
3624
-
3625
- /**
3626
- * Display or hide the processing indicator
3627
- * @param {object} settings dataTables settings object
3628
- * @param {bool} show Show the processing indicator (true) or not (false)
3629
- * @memberof DataTable#oApi
3630
- */
3631
- function _fnProcessingDisplay ( settings, show )
3632
- {
3633
- if ( settings.oFeatures.bProcessing ) {
3634
- $(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
3635
- }
3636
-
3637
- _fnCallbackFire( settings, null, 'processing', [settings, show] );
3638
- }
3639
-
3640
- /**
3641
- * Add any control elements for the table - specifically scrolling
3642
- * @param {object} settings dataTables settings object
3643
- * @returns {node} Node to add to the DOM
3644
- * @memberof DataTable#oApi
3645
- */
3646
- function _fnFeatureHtmlTable ( settings )
3647
- {
3648
- var table = $(settings.nTable);
3649
-
3650
- // Add the ARIA grid role to the table
3651
- table.attr( 'role', 'grid' );
3652
-
3653
- // Scrolling from here on in
3654
- var scroll = settings.oScroll;
3655
-
3656
- if ( scroll.sX === '' && scroll.sY === '' ) {
3657
- return settings.nTable;
3658
- }
3659
-
3660
- var scrollX = scroll.sX;
3661
- var scrollY = scroll.sY;
3662
- var classes = settings.oClasses;
3663
- var caption = table.children('caption');
3664
- var captionSide = caption.length ? caption[0]._captionSide : null;
3665
- var headerClone = $( table[0].cloneNode(false) );
3666
- var footerClone = $( table[0].cloneNode(false) );
3667
- var footer = table.children('tfoot');
3668
- var _div = '<div/>';
3669
- var size = function ( s ) {
3670
- return !s ? null : _fnStringToCss( s );
3671
- };
3672
-
3673
- // This is fairly messy, but with x scrolling enabled, if the table has a
3674
- // width attribute, regardless of any width applied using the column width
3675
- // options, the browser will shrink or grow the table as needed to fit into
3676
- // that 100%. That would make the width options useless. So we remove it.
3677
- // This is okay, under the assumption that width:100% is applied to the
3678
- // table in CSS (it is in the default stylesheet) which will set the table
3679
- // width as appropriate (the attribute and css behave differently...)
3680
- if ( scroll.sX && table.attr('width') === '100%' ) {
3681
- table.removeAttr('width');
3682
- }
3683
-
3684
- if ( ! footer.length ) {
3685
- footer = null;
3686
- }
3687
-
3688
- /*
3689
- * The HTML structure that we want to generate in this function is:
3690
- * div - scroller
3691
- * div - scroll head
3692
- * div - scroll head inner
3693
- * table - scroll head table
3694
- * thead - thead
3695
- * div - scroll body
3696
- * table - table (master table)
3697
- * thead - thead clone for sizing
3698
- * tbody - tbody
3699
- * div - scroll foot
3700
- * div - scroll foot inner
3701
- * table - scroll foot table
3702
- * tfoot - tfoot
3703
- */
3704
- var scroller = $( _div, { 'class': classes.sScrollWrapper } )
3705
- .append(
3706
- $(_div, { 'class': classes.sScrollHead } )
3707
- .css( {
3708
- overflow: 'hidden',
3709
- position: 'relative',
3710
- border: 0,
3711
- width: scrollX ? size(scrollX) : '100%'
3712
- } )
3713
- .append(
3714
- $(_div, { 'class': classes.sScrollHeadInner } )
3715
- .css( {
3716
- 'box-sizing': 'content-box',
3717
- width: scroll.sXInner || '100%'
3718
- } )
3719
- .append(
3720
- headerClone
3721
- .removeAttr('id')
3722
- .css( 'margin-left', 0 )
3723
- .append( captionSide === 'top' ? caption : null )
3724
- .append(
3725
- table.children('thead')
3726
- )
3727
- )
3728
- )
3729
- )
3730
- .append(
3731
- $(_div, { 'class': classes.sScrollBody } )
3732
- .css( {
3733
- position: 'relative',
3734
- overflow: 'auto',
3735
- width: size( scrollX )
3736
- } )
3737
- .append( table )
3738
- );
3739
-
3740
- if ( footer ) {
3741
- scroller.append(
3742
- $(_div, { 'class': classes.sScrollFoot } )
3743
- .css( {
3744
- overflow: 'hidden',
3745
- border: 0,
3746
- width: scrollX ? size(scrollX) : '100%'
3747
- } )
3748
- .append(
3749
- $(_div, { 'class': classes.sScrollFootInner } )
3750
- .append(
3751
- footerClone
3752
- .removeAttr('id')
3753
- .css( 'margin-left', 0 )
3754
- .append( captionSide === 'bottom' ? caption : null )
3755
- .append(
3756
- table.children('tfoot')
3757
- )
3758
- )
3759
- )
3760
- );
3761
- }
3762
-
3763
- var children = scroller.children();
3764
- var scrollHead = children[0];
3765
- var scrollBody = children[1];
3766
- var scrollFoot = footer ? children[2] : null;
3767
-
3768
- // When the body is scrolled, then we also want to scroll the headers
3769
- if ( scrollX ) {
3770
- $(scrollBody).on( 'scroll.DT', function (e) {
3771
- var scrollLeft = this.scrollLeft;
3772
-
3773
- scrollHead.scrollLeft = scrollLeft;
3774
-
3775
- if ( footer ) {
3776
- scrollFoot.scrollLeft = scrollLeft;
3777
- }
3778
- } );
3779
- }
3780
-
3781
- $(scrollBody).css(
3782
- scrollY && scroll.bCollapse ? 'max-height' : 'height',
3783
- scrollY
3784
- );
3785
-
3786
- settings.nScrollHead = scrollHead;
3787
- settings.nScrollBody = scrollBody;
3788
- settings.nScrollFoot = scrollFoot;
3789
-
3790
- // On redraw - align columns
3791
- settings.aoDrawCallback.push( {
3792
- "fn": _fnScrollDraw,
3793
- "sName": "scrolling"
3794
- } );
3795
-
3796
- return scroller[0];
3797
- }
3798
-
3799
-
3800
-
3801
- /**
3802
- * Update the header, footer and body tables for resizing - i.e. column
3803
- * alignment.
3804
- *
3805
- * Welcome to the most horrible function DataTables. The process that this
3806
- * function follows is basically:
3807
- * 1. Re-create the table inside the scrolling div
3808
- * 2. Take live measurements from the DOM
3809
- * 3. Apply the measurements to align the columns
3810
- * 4. Clean up
3811
- *
3812
- * @param {object} settings dataTables settings object
3813
- * @memberof DataTable#oApi
3814
- */
3815
- function _fnScrollDraw ( settings )
3816
- {
3817
- // Given that this is such a monster function, a lot of variables are use
3818
- // to try and keep the minimised size as small as possible
3819
- var
3820
- scroll = settings.oScroll,
3821
- scrollX = scroll.sX,
3822
- scrollXInner = scroll.sXInner,
3823
- scrollY = scroll.sY,
3824
- barWidth = scroll.iBarWidth,
3825
- divHeader = $(settings.nScrollHead),
3826
- divHeaderStyle = divHeader[0].style,
3827
- divHeaderInner = divHeader.children('div'),
3828
- divHeaderInnerStyle = divHeaderInner[0].style,
3829
- divHeaderTable = divHeaderInner.children('table'),
3830
- divBodyEl = settings.nScrollBody,
3831
- divBody = $(divBodyEl),
3832
- divBodyStyle = divBodyEl.style,
3833
- divFooter = $(settings.nScrollFoot),
3834
- divFooterInner = divFooter.children('div'),
3835
- divFooterTable = divFooterInner.children('table'),
3836
- header = $(settings.nTHead),
3837
- table = $(settings.nTable),
3838
- tableEl = table[0],
3839
- tableStyle = tableEl.style,
3840
- footer = settings.nTFoot ? $(settings.nTFoot) : null,
3841
- browser = settings.oBrowser,
3842
- ie67 = browser.bScrollOversize,
3843
- headerTrgEls, footerTrgEls,
3844
- headerSrcEls, footerSrcEls,
3845
- headerCopy, footerCopy,
3846
- headerWidths=[], footerWidths=[],
3847
- headerContent=[],
3848
- idx, correction, sanityWidth,
3849
- zeroOut = function(nSizer) {
3850
- var style = nSizer.style;
3851
- style.paddingTop = "0";
3852
- style.paddingBottom = "0";
3853
- style.borderTopWidth = "0";
3854
- style.borderBottomWidth = "0";
3855
- style.height = 0;
3856
- };
3857
-
3858
- /*
3859
- * 1. Re-create the table inside the scrolling div
3860
- */
3861
-
3862
- // Remove the old minimised thead and tfoot elements in the inner table
3863
- table.children('thead, tfoot').remove();
3864
-
3865
- // Clone the current header and footer elements and then place it into the inner table
3866
- headerCopy = header.clone().prependTo( table );
3867
- headerTrgEls = header.find('tr'); // original header is in its own table
3868
- headerSrcEls = headerCopy.find('tr');
3869
- headerCopy.find('th, td').removeAttr('tabindex');
3870
-
3871
- if ( footer ) {
3872
- footerCopy = footer.clone().prependTo( table );
3873
- footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
3874
- footerSrcEls = footerCopy.find('tr');
3875
- }
3876
-
3877
-
3878
- /*
3879
- * 2. Take live measurements from the DOM - do not alter the DOM itself!
3880
- */
3881
-
3882
- // Remove old sizing and apply the calculated column widths
3883
- // Get the unique column headers in the newly created (cloned) header. We want to apply the
3884
- // calculated sizes to this header
3885
- if ( ! scrollX )
3886
- {
3887
- divBodyStyle.width = '100%';
3888
- divHeader[0].style.width = '100%';
3889
- }
3890
-
3891
- $.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
3892
- idx = _fnVisibleToColumnIndex( settings, i );
3893
- el.style.width = settings.aoColumns[idx].sWidth;
3894
- } );
3895
-
3896
- if ( footer ) {
3897
- _fnApplyToChildren( function(n) {
3898
- n.style.width = "";
3899
- }, footerSrcEls );
3900
- }
3901
-
3902
- // Size the table as a whole
3903
- sanityWidth = table.outerWidth();
3904
- if ( scrollX === "" ) {
3905
- // No x scrolling
3906
- tableStyle.width = "100%";
3907
-
3908
- // IE7 will make the width of the table when 100% include the scrollbar
3909
- // - which is shouldn't. When there is a scrollbar we need to take this
3910
- // into account.
3911
- if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
3912
- divBody.css('overflow-y') == "scroll")
3913
- ) {
3914
- tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
3915
- }
3916
-
3917
- // Recalculate the sanity width
3918
- sanityWidth = table.outerWidth();
3919
- }
3920
- else if ( scrollXInner !== "" ) {
3921
- // legacy x scroll inner has been given - use it
3922
- tableStyle.width = _fnStringToCss(scrollXInner);
3923
-
3924
- // Recalculate the sanity width
3925
- sanityWidth = table.outerWidth();
3926
- }
3927
-
3928
- // Hidden header should have zero height, so remove padding and borders. Then
3929
- // set the width based on the real headers
3930
-
3931
- // Apply all styles in one pass
3932
- _fnApplyToChildren( zeroOut, headerSrcEls );
3933
-
3934
- // Read all widths in next pass
3935
- _fnApplyToChildren( function(nSizer) {
3936
- headerContent.push( nSizer.innerHTML );
3937
- headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
3938
- }, headerSrcEls );
3939
-
3940
- // Apply all widths in final pass
3941
- _fnApplyToChildren( function(nToSize, i) {
3942
- nToSize.style.width = headerWidths[i];
3943
- }, headerTrgEls );
3944
-
3945
- $(headerSrcEls).height(0);
3946
-
3947
- /* Same again with the footer if we have one */
3948
- if ( footer )
3949
- {
3950
- _fnApplyToChildren( zeroOut, footerSrcEls );
3951
-
3952
- _fnApplyToChildren( function(nSizer) {
3953
- footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
3954
- }, footerSrcEls );
3955
-
3956
- _fnApplyToChildren( function(nToSize, i) {
3957
- nToSize.style.width = footerWidths[i];
3958
- }, footerTrgEls );
3959
-
3960
- $(footerSrcEls).height(0);
3961
- }
3962
-
3963
-
3964
- /*
3965
- * 3. Apply the measurements
3966
- */
3967
-
3968
- // "Hide" the header and footer that we used for the sizing. We need to keep
3969
- // the content of the cell so that the width applied to the header and body
3970
- // both match, but we want to hide it completely. We want to also fix their
3971
- // width to what they currently are
3972
- _fnApplyToChildren( function(nSizer, i) {
3973
- nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
3974
- nSizer.style.width = headerWidths[i];
3975
- }, headerSrcEls );
3976
-
3977
- if ( footer )
3978
- {
3979
- _fnApplyToChildren( function(nSizer, i) {
3980
- nSizer.innerHTML = "";
3981
- nSizer.style.width = footerWidths[i];
3982
- }, footerSrcEls );
3983
- }
3984
-
3985
- // Sanity check that the table is of a sensible width. If not then we are going to get
3986
- // misalignment - try to prevent this by not allowing the table to shrink below its min width
3987
- if ( table.outerWidth() < sanityWidth )
3988
- {
3989
- // The min width depends upon if we have a vertical scrollbar visible or not */
3990
- correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
3991
- divBody.css('overflow-y') == "scroll")) ?
3992
- sanityWidth+barWidth :
3993
- sanityWidth;
3994
-
3995
- // IE6/7 are a law unto themselves...
3996
- if ( ie67 && (divBodyEl.scrollHeight >
3997
- divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
3998
- ) {
3999
- tableStyle.width = _fnStringToCss( correction-barWidth );
4000
- }
4001
-
4002
- // And give the user a warning that we've stopped the table getting too small
4003
- if ( scrollX === "" || scrollXInner !== "" ) {
4004
- _fnLog( settings, 1, 'Possible column misalignment', 6 );
4005
- }
4006
- }
4007
- else
4008
- {
4009
- correction = '100%';
4010
- }
4011
-
4012
- // Apply to the container elements
4013
- divBodyStyle.width = _fnStringToCss( correction );
4014
- divHeaderStyle.width = _fnStringToCss( correction );
4015
-
4016
- if ( footer ) {
4017
- settings.nScrollFoot.style.width = _fnStringToCss( correction );
4018
- }
4019
-
4020
-
4021
- /*
4022
- * 4. Clean up
4023
- */
4024
- if ( ! scrollY ) {
4025
- /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
4026
- * the scrollbar height from the visible display, rather than adding it on. We need to
4027
- * set the height in order to sort this. Don't want to do it in any other browsers.
4028
- */
4029
- if ( ie67 ) {
4030
- divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
4031
- }
4032
- }
4033
-
4034
- /* Finally set the width's of the header and footer tables */
4035
- var iOuterWidth = table.outerWidth();
4036
- divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
4037
- divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
4038
-
4039
- // Figure out if there are scrollbar present - if so then we need a the header and footer to
4040
- // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
4041
- var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
4042
- var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
4043
- divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
4044
-
4045
- if ( footer ) {
4046
- divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
4047
- divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
4048
- divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
4049
- }
4050
-
4051
- /* Adjust the position of the header in case we loose the y-scrollbar */
4052
- divBody.scroll();
4053
-
4054
- // If sorting or filtering has occurred, jump the scrolling back to the top
4055
- // only if we aren't holding the position
4056
- if ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {
4057
- divBodyEl.scrollTop = 0;
4058
- }
4059
- }
4060
-
4061
-
4062
-
4063
- /**
4064
- * Apply a given function to the display child nodes of an element array (typically
4065
- * TD children of TR rows
4066
- * @param {function} fn Method to apply to the objects
4067
- * @param array {nodes} an1 List of elements to look through for display children
4068
- * @param array {nodes} an2 Another list (identical structure to the first) - optional
4069
- * @memberof DataTable#oApi
4070
- */
4071
- function _fnApplyToChildren( fn, an1, an2 )
4072
- {
4073
- var index=0, i=0, iLen=an1.length;
4074
- var nNode1, nNode2;
4075
-
4076
- while ( i < iLen ) {
4077
- nNode1 = an1[i].firstChild;
4078
- nNode2 = an2 ? an2[i].firstChild : null;
4079
-
4080
- while ( nNode1 ) {
4081
- if ( nNode1.nodeType === 1 ) {
4082
- if ( an2 ) {
4083
- fn( nNode1, nNode2, index );
4084
- }
4085
- else {
4086
- fn( nNode1, index );
4087
- }
4088
-
4089
- index++;
4090
- }
4091
-
4092
- nNode1 = nNode1.nextSibling;
4093
- nNode2 = an2 ? nNode2.nextSibling : null;
4094
- }
4095
-
4096
- i++;
4097
- }
4098
- }
4099
-
4100
-
4101
-
4102
- var __re_html_remove = /<.*?>/g;
4103
-
4104
-
4105
- /**
4106
- * Calculate the width of columns for the table
4107
- * @param {object} oSettings dataTables settings object
4108
- * @memberof DataTable#oApi
4109
- */
4110
- function _fnCalculateColumnWidths ( oSettings )
4111
- {
4112
- var
4113
- table = oSettings.nTable,
4114
- columns = oSettings.aoColumns,
4115
- scroll = oSettings.oScroll,
4116
- scrollY = scroll.sY,
4117
- scrollX = scroll.sX,
4118
- scrollXInner = scroll.sXInner,
4119
- columnCount = columns.length,
4120
- visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
4121
- headerCells = $('th', oSettings.nTHead),
4122
- tableWidthAttr = table.getAttribute('width'), // from DOM element
4123
- tableContainer = table.parentNode,
4124
- userInputs = false,
4125
- i, column, columnIdx, width, outerWidth,
4126
- browser = oSettings.oBrowser,
4127
- ie67 = browser.bScrollOversize;
4128
-
4129
- var styleWidth = table.style.width;
4130
- if ( styleWidth && styleWidth.indexOf('%') !== -1 ) {
4131
- tableWidthAttr = styleWidth;
4132
- }
4133
-
4134
- /* Convert any user input sizes into pixel sizes */
4135
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4136
- column = columns[ visibleColumns[i] ];
4137
-
4138
- if ( column.sWidth !== null ) {
4139
- column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
4140
-
4141
- userInputs = true;
4142
- }
4143
- }
4144
-
4145
- /* If the number of columns in the DOM equals the number that we have to
4146
- * process in DataTables, then we can use the offsets that are created by
4147
- * the web- browser. No custom sizes can be set in order for this to happen,
4148
- * nor scrolling used
4149
- */
4150
- if ( ie67 || ! userInputs && ! scrollX && ! scrollY &&
4151
- columnCount == _fnVisbleColumns( oSettings ) &&
4152
- columnCount == headerCells.length
4153
- ) {
4154
- for ( i=0 ; i<columnCount ; i++ ) {
4155
- var colIdx = _fnVisibleToColumnIndex( oSettings, i );
4156
-
4157
- if ( colIdx ) {
4158
- columns[ colIdx ].sWidth = _fnStringToCss( headerCells.eq(i).width() );
4159
- }
4160
- }
4161
- }
4162
- else
4163
- {
4164
- // Otherwise construct a single row, worst case, table with the widest
4165
- // node in the data, assign any user defined widths, then insert it into
4166
- // the DOM and allow the browser to do all the hard work of calculating
4167
- // table widths
4168
- var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
4169
- .css( 'visibility', 'hidden' )
4170
- .removeAttr( 'id' );
4171
-
4172
- // Clean up the table body
4173
- tmpTable.find('tbody tr').remove();
4174
- var tr = $('<tr/>').appendTo( tmpTable.find('tbody') );
4175
-
4176
- // Clone the table header and footer - we can't use the header / footer
4177
- // from the cloned table, since if scrolling is active, the table's
4178
- // real header and footer are contained in different table tags
4179
- tmpTable.find('thead, tfoot').remove();
4180
- tmpTable
4181
- .append( $(oSettings.nTHead).clone() )
4182
- .append( $(oSettings.nTFoot).clone() );
4183
-
4184
- // Remove any assigned widths from the footer (from scrolling)
4185
- tmpTable.find('tfoot th, tfoot td').css('width', '');
4186
-
4187
- // Apply custom sizing to the cloned header
4188
- headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
4189
-
4190
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4191
- column = columns[ visibleColumns[i] ];
4192
-
4193
- headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
4194
- _fnStringToCss( column.sWidthOrig ) :
4195
- '';
4196
- }
4197
-
4198
- // Find the widest cell for each column and put it into the table
4199
- if ( oSettings.aoData.length ) {
4200
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4201
- columnIdx = visibleColumns[i];
4202
- column = columns[ columnIdx ];
4203
-
4204
- $( _fnGetWidestNode( oSettings, columnIdx ) )
4205
- .clone( false )
4206
- .append( column.sContentPadding )
4207
- .appendTo( tr );
4208
- }
4209
- }
4210
-
4211
- // Table has been built, attach to the document so we can work with it.
4212
- // A holding element is used, positioned at the top of the container
4213
- // with minimal height, so it has no effect on if the container scrolls
4214
- // or not. Otherwise it might trigger scrolling when it actually isn't
4215
- // needed
4216
- var holder = $('<div/>').css( scrollX || scrollY ?
4217
- {
4218
- position: 'absolute',
4219
- top: 0,
4220
- left: 0,
4221
- height: 1,
4222
- right: 0,
4223
- overflow: 'hidden'
4224
- } :
4225
- {}
4226
- )
4227
- .append( tmpTable )
4228
- .appendTo( tableContainer );
4229
-
4230
- // When scrolling (X or Y) we want to set the width of the table as
4231
- // appropriate. However, when not scrolling leave the table width as it
4232
- // is. This results in slightly different, but I think correct behaviour
4233
- if ( scrollX && scrollXInner ) {
4234
- tmpTable.width( scrollXInner );
4235
- }
4236
- else if ( scrollX ) {
4237
- tmpTable.css( 'width', 'auto' );
4238
-
4239
- if ( tmpTable.width() < tableContainer.clientWidth ) {
4240
- tmpTable.width( tableContainer.clientWidth );
4241
- }
4242
- }
4243
- else if ( scrollY ) {
4244
- tmpTable.width( tableContainer.clientWidth );
4245
- }
4246
- else if ( tableWidthAttr ) {
4247
- tmpTable.width( tableWidthAttr );
4248
- }
4249
-
4250
- // Browsers need a bit of a hand when a width is assigned to any columns
4251
- // when x-scrolling as they tend to collapse the table to the min-width,
4252
- // even if we sent the column widths. So we need to keep track of what
4253
- // the table width should be by summing the user given values, and the
4254
- // automatic values
4255
- if ( scrollX )
4256
- {
4257
- var total = 0;
4258
-
4259
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4260
- column = columns[ visibleColumns[i] ];
4261
-
4262
- // Much prefer to use getBoundingClientRect due to its sub-pixel
4263
- // resolution, but IE8- do not support the width property.
4264
- outerWidth = browser.bBounding ?
4265
- headerCells[i].getBoundingClientRect().width :
4266
- $(headerCells[i]).outerWidth();
4267
-
4268
- total += column.sWidthOrig === null ?
4269
- outerWidth :
4270
- parseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();
4271
- }
4272
-
4273
- tmpTable.width( _fnStringToCss( total ) );
4274
- table.style.width = _fnStringToCss( total );
4275
- }
4276
-
4277
- // Get the width of each column in the constructed table
4278
- for ( i=0 ; i<visibleColumns.length ; i++ ) {
4279
- column = columns[ visibleColumns[i] ];
4280
- width = $(headerCells[i]).width();
4281
-
4282
- if ( width ) {
4283
- column.sWidth = _fnStringToCss( width );
4284
- }
4285
- }
4286
-
4287
- table.style.width = _fnStringToCss( tmpTable.css('width') );
4288
-
4289
- // Finished with the table - ditch it
4290
- holder.remove();
4291
- }
4292
-
4293
- // If there is a width attr, we want to attach an event listener which
4294
- // allows the table sizing to automatically adjust when the window is
4295
- // resized. Use the width attr rather than CSS, since we can't know if the
4296
- // CSS is a relative value or absolute - DOM read is always px.
4297
- if ( tableWidthAttr ) {
4298
- table.style.width = _fnStringToCss( tableWidthAttr );
4299
- }
4300
-
4301
- if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
4302
- var bindResize = function () {
4303
- $(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
4304
- _fnAdjustColumnSizing( oSettings );
4305
- } ) );
4306
- };
4307
-
4308
- // IE6/7 will crash if we bind a resize event handler on page load.
4309
- // To be removed in 1.11 which drops IE6/7 support
4310
- if ( ie67 ) {
4311
- setTimeout( bindResize, 1000 );
4312
- }
4313
- else {
4314
- bindResize();
4315
- }
4316
-
4317
- oSettings._reszEvt = true;
4318
- }
4319
- }
4320
-
4321
-
4322
- /**
4323
- * Throttle the calls to a function. Arguments and context are maintained for
4324
- * the throttled function
4325
- * @param {function} fn Function to be called
4326
- * @param {int} [freq=200] call frequency in mS
4327
- * @returns {function} wrapped function
4328
- * @memberof DataTable#oApi
4329
- */
4330
- function _fnThrottle( fn, freq ) {
4331
- var
4332
- frequency = freq !== undefined ? freq : 200,
4333
- last,
4334
- timer;
4335
-
4336
- return function () {
4337
- var
4338
- that = this,
4339
- now = +new Date(),
4340
- args = arguments;
4341
-
4342
- if ( last && now < last + frequency ) {
4343
- clearTimeout( timer );
4344
-
4345
- timer = setTimeout( function () {
4346
- last = undefined;
4347
- fn.apply( that, args );
4348
- }, frequency );
4349
- }
4350
- else {
4351
- last = now;
4352
- fn.apply( that, args );
4353
- }
4354
- };
4355
- }
4356
-
4357
-
4358
- /**
4359
- * Convert a CSS unit width to pixels (e.g. 2em)
4360
- * @param {string} width width to be converted
4361
- * @param {node} parent parent to get the with for (required for relative widths) - optional
4362
- * @returns {int} width in pixels
4363
- * @memberof DataTable#oApi
4364
- */
4365
- function _fnConvertToWidth ( width, parent )
4366
- {
4367
- if ( ! width ) {
4368
- return 0;
4369
- }
4370
-
4371
- var n = $('<div/>')
4372
- .css( 'width', _fnStringToCss( width ) )
4373
- .appendTo( parent || document.body );
4374
-
4375
- var val = n[0].offsetWidth;
4376
- n.remove();
4377
-
4378
- return val;
4379
- }
4380
-
4381
-
4382
- /**
4383
- * Get the widest node
4384
- * @param {object} settings dataTables settings object
4385
- * @param {int} colIdx column of interest
4386
- * @returns {node} widest table node
4387
- * @memberof DataTable#oApi
4388
- */
4389
- function _fnGetWidestNode( settings, colIdx )
4390
- {
4391
- var idx = _fnGetMaxLenString( settings, colIdx );
4392
- if ( idx < 0 ) {
4393
- return null;
4394
- }
4395
-
4396
- var data = settings.aoData[ idx ];
4397
- return ! data.nTr ? // Might not have been created when deferred rendering
4398
- $('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
4399
- data.anCells[ colIdx ];
4400
- }
4401
-
4402
-
4403
- /**
4404
- * Get the maximum strlen for each data column
4405
- * @param {object} settings dataTables settings object
4406
- * @param {int} colIdx column of interest
4407
- * @returns {string} max string length for each column
4408
- * @memberof DataTable#oApi
4409
- */
4410
- function _fnGetMaxLenString( settings, colIdx )
4411
- {
4412
- var s, max=-1, maxIdx = -1;
4413
-
4414
- for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4415
- s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
4416
- s = s.replace( __re_html_remove, '' );
4417
-
4418
- if ( s.length > max ) {
4419
- max = s.length;
4420
- maxIdx = i;
4421
- }
4422
- }
4423
-
4424
- return maxIdx;
4425
- }
4426
-
4427
-
4428
- /**
4429
- * Append a CSS unit (only if required) to a string
4430
- * @param {string} value to css-ify
4431
- * @returns {string} value with css unit
4432
- * @memberof DataTable#oApi
4433
- */
4434
- function _fnStringToCss( s )
4435
- {
4436
- if ( s === null ) {
4437
- return '0px';
4438
- }
4439
-
4440
- if ( typeof s == 'number' ) {
4441
- return s < 0 ?
4442
- '0px' :
4443
- s+'px';
4444
- }
4445
-
4446
- // Check it has a unit character already
4447
- return s.match(/\d$/) ?
4448
- s+'px' :
4449
- s;
4450
- }
4451
-
4452
-
4453
-
4454
- function _fnSortFlatten ( settings )
4455
- {
4456
- var
4457
- i, iLen, k, kLen,
4458
- aSort = [],
4459
- aiOrig = [],
4460
- aoColumns = settings.aoColumns,
4461
- aDataSort, iCol, sType, srcCol,
4462
- fixed = settings.aaSortingFixed,
4463
- fixedObj = $.isPlainObject( fixed ),
4464
- nestedSort = [],
4465
- add = function ( a ) {
4466
- if ( a.length && ! $.isArray( a[0] ) ) {
4467
- // 1D array
4468
- nestedSort.push( a );
4469
- }
4470
- else {
4471
- // 2D array
4472
- $.merge( nestedSort, a );
4473
- }
4474
- };
4475
-
4476
- // Build the sort array, with pre-fix and post-fix options if they have been
4477
- // specified
4478
- if ( $.isArray( fixed ) ) {
4479
- add( fixed );
4480
- }
4481
-
4482
- if ( fixedObj && fixed.pre ) {
4483
- add( fixed.pre );
4484
- }
4485
-
4486
- add( settings.aaSorting );
4487
-
4488
- if (fixedObj && fixed.post ) {
4489
- add( fixed.post );
4490
- }
4491
-
4492
- for ( i=0 ; i<nestedSort.length ; i++ )
4493
- {
4494
- srcCol = nestedSort[i][0];
4495
- aDataSort = aoColumns[ srcCol ].aDataSort;
4496
-
4497
- for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
4498
- {
4499
- iCol = aDataSort[k];
4500
- sType = aoColumns[ iCol ].sType || 'string';
4501
-
4502
- if ( nestedSort[i]._idx === undefined ) {
4503
- nestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );
4504
- }
4505
-
4506
- aSort.push( {
4507
- src: srcCol,
4508
- col: iCol,
4509
- dir: nestedSort[i][1],
4510
- index: nestedSort[i]._idx,
4511
- type: sType,
4512
- formatter: DataTable.ext.type.order[ sType+"-pre" ]
4513
- } );
4514
- }
4515
- }
4516
-
4517
- return aSort;
4518
- }
4519
-
4520
- /**
4521
- * Change the order of the table
4522
- * @param {object} oSettings dataTables settings object
4523
- * @memberof DataTable#oApi
4524
- * @todo This really needs split up!
4525
- */
4526
- function _fnSort ( oSettings )
4527
- {
4528
- var
4529
- i, ien, iLen, j, jLen, k, kLen,
4530
- sDataType, nTh,
4531
- aiOrig = [],
4532
- oExtSort = DataTable.ext.type.order,
4533
- aoData = oSettings.aoData,
4534
- aoColumns = oSettings.aoColumns,
4535
- aDataSort, data, iCol, sType, oSort,
4536
- formatters = 0,
4537
- sortCol,
4538
- displayMaster = oSettings.aiDisplayMaster,
4539
- aSort;
4540
-
4541
- // Resolve any column types that are unknown due to addition or invalidation
4542
- // @todo Can this be moved into a 'data-ready' handler which is called when
4543
- // data is going to be used in the table?
4544
- _fnColumnTypes( oSettings );
4545
-
4546
- aSort = _fnSortFlatten( oSettings );
4547
-
4548
- for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
4549
- sortCol = aSort[i];
4550
-
4551
- // Track if we can use the fast sort algorithm
4552
- if ( sortCol.formatter ) {
4553
- formatters++;
4554
- }
4555
-
4556
- // Load the data needed for the sort, for each cell
4557
- _fnSortData( oSettings, sortCol.col );
4558
- }
4559
-
4560
- /* No sorting required if server-side or no sorting array */
4561
- if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
4562
- {
4563
- // Create a value - key array of the current row positions such that we can use their
4564
- // current position during the sort, if values match, in order to perform stable sorting
4565
- for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
4566
- aiOrig[ displayMaster[i] ] = i;
4567
- }
4568
-
4569
- /* Do the sort - here we want multi-column sorting based on a given data source (column)
4570
- * and sorting function (from oSort) in a certain direction. It's reasonably complex to
4571
- * follow on it's own, but this is what we want (example two column sorting):
4572
- * fnLocalSorting = function(a,b){
4573
- * var iTest;
4574
- * iTest = oSort['string-asc']('data11', 'data12');
4575
- * if (iTest !== 0)
4576
- * return iTest;
4577
- * iTest = oSort['numeric-desc']('data21', 'data22');
4578
- * if (iTest !== 0)
4579
- * return iTest;
4580
- * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
4581
- * }
4582
- * Basically we have a test for each sorting column, if the data in that column is equal,
4583
- * test the next column. If all columns match, then we use a numeric sort on the row
4584
- * positions in the original data array to provide a stable sort.
4585
- *
4586
- * Note - I know it seems excessive to have two sorting methods, but the first is around
4587
- * 15% faster, so the second is only maintained for backwards compatibility with sorting
4588
- * methods which do not have a pre-sort formatting function.
4589
- */
4590
- if ( formatters === aSort.length ) {
4591
- // All sort types have formatting functions
4592
- displayMaster.sort( function ( a, b ) {
4593
- var
4594
- x, y, k, test, sort,
4595
- len=aSort.length,
4596
- dataA = aoData[a]._aSortData,
4597
- dataB = aoData[b]._aSortData;
4598
-
4599
- for ( k=0 ; k<len ; k++ ) {
4600
- sort = aSort[k];
4601
-
4602
- x = dataA[ sort.col ];
4603
- y = dataB[ sort.col ];
4604
-
4605
- test = x<y ? -1 : x>y ? 1 : 0;
4606
- if ( test !== 0 ) {
4607
- return sort.dir === 'asc' ? test : -test;
4608
- }
4609
- }
4610
-
4611
- x = aiOrig[a];
4612
- y = aiOrig[b];
4613
- return x<y ? -1 : x>y ? 1 : 0;
4614
- } );
4615
- }
4616
- else {
4617
- // Depreciated - remove in 1.11 (providing a plug-in option)
4618
- // Not all sort types have formatting methods, so we have to call their sorting
4619
- // methods.
4620
- displayMaster.sort( function ( a, b ) {
4621
- var
4622
- x, y, k, l, test, sort, fn,
4623
- len=aSort.length,
4624
- dataA = aoData[a]._aSortData,
4625
- dataB = aoData[b]._aSortData;
4626
-
4627
- for ( k=0 ; k<len ; k++ ) {
4628
- sort = aSort[k];
4629
-
4630
- x = dataA[ sort.col ];
4631
- y = dataB[ sort.col ];
4632
-
4633
- fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
4634
- test = fn( x, y );
4635
- if ( test !== 0 ) {
4636
- return test;
4637
- }
4638
- }
4639
-
4640
- x = aiOrig[a];
4641
- y = aiOrig[b];
4642
- return x<y ? -1 : x>y ? 1 : 0;
4643
- } );
4644
- }
4645
- }
4646
-
4647
- /* Tell the draw function that we have sorted the data */
4648
- oSettings.bSorted = true;
4649
- }
4650
-
4651
-
4652
- function _fnSortAria ( settings )
4653
- {
4654
- var label;
4655
- var nextSort;
4656
- var columns = settings.aoColumns;
4657
- var aSort = _fnSortFlatten( settings );
4658
- var oAria = settings.oLanguage.oAria;
4659
-
4660
- // ARIA attributes - need to loop all columns, to update all (removing old
4661
- // attributes as needed)
4662
- for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
4663
- {
4664
- var col = columns[i];
4665
- var asSorting = col.asSorting;
4666
- var sTitle = col.sTitle.replace( /<.*?>/g, "" );
4667
- var th = col.nTh;
4668
-
4669
- // IE7 is throwing an error when setting these properties with jQuery's
4670
- // attr() and removeAttr() methods...
4671
- th.removeAttribute('aria-sort');
4672
-
4673
- /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
4674
- if ( col.bSortable ) {
4675
- if ( aSort.length > 0 && aSort[0].col == i ) {
4676
- th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
4677
- nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
4678
- }
4679
- else {
4680
- nextSort = asSorting[0];
4681
- }
4682
-
4683
- label = sTitle + ( nextSort === "asc" ?
4684
- oAria.sSortAscending :
4685
- oAria.sSortDescending
4686
- );
4687
- }
4688
- else {
4689
- label = sTitle;
4690
- }
4691
-
4692
- th.setAttribute('aria-label', label);
4693
- }
4694
- }
4695
-
4696
-
4697
- /**
4698
- * Function to run on user sort request
4699
- * @param {object} settings dataTables settings object
4700
- * @param {node} attachTo node to attach the handler to
4701
- * @param {int} colIdx column sorting index
4702
- * @param {boolean} [append=false] Append the requested sort to the existing
4703
- * sort if true (i.e. multi-column sort)
4704
- * @param {function} [callback] callback function
4705
- * @memberof DataTable#oApi
4706
- */
4707
- function _fnSortListener ( settings, colIdx, append, callback )
4708
- {
4709
- var col = settings.aoColumns[ colIdx ];
4710
- var sorting = settings.aaSorting;
4711
- var asSorting = col.asSorting;
4712
- var nextSortIdx;
4713
- var next = function ( a, overflow ) {
4714
- var idx = a._idx;
4715
- if ( idx === undefined ) {
4716
- idx = $.inArray( a[1], asSorting );
4717
- }
4718
-
4719
- return idx+1 < asSorting.length ?
4720
- idx+1 :
4721
- overflow ?
4722
- null :
4723
- 0;
4724
- };
4725
-
4726
- // Convert to 2D array if needed
4727
- if ( typeof sorting[0] === 'number' ) {
4728
- sorting = settings.aaSorting = [ sorting ];
4729
- }
4730
-
4731
- // If appending the sort then we are multi-column sorting
4732
- if ( append && settings.oFeatures.bSortMulti ) {
4733
- // Are we already doing some kind of sort on this column?
4734
- var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
4735
-
4736
- if ( sortIdx !== -1 ) {
4737
- // Yes, modify the sort
4738
- nextSortIdx = next( sorting[sortIdx], true );
4739
-
4740
- if ( nextSortIdx === null && sorting.length === 1 ) {
4741
- nextSortIdx = 0; // can't remove sorting completely
4742
- }
4743
-
4744
- if ( nextSortIdx === null ) {
4745
- sorting.splice( sortIdx, 1 );
4746
- }
4747
- else {
4748
- sorting[sortIdx][1] = asSorting[ nextSortIdx ];
4749
- sorting[sortIdx]._idx = nextSortIdx;
4750
- }
4751
- }
4752
- else {
4753
- // No sort on this column yet
4754
- sorting.push( [ colIdx, asSorting[0], 0 ] );
4755
- sorting[sorting.length-1]._idx = 0;
4756
- }
4757
- }
4758
- else if ( sorting.length && sorting[0][0] == colIdx ) {
4759
- // Single column - already sorting on this column, modify the sort
4760
- nextSortIdx = next( sorting[0] );
4761
-
4762
- sorting.length = 1;
4763
- sorting[0][1] = asSorting[ nextSortIdx ];
4764
- sorting[0]._idx = nextSortIdx;
4765
- }
4766
- else {
4767
- // Single column - sort only on this column
4768
- sorting.length = 0;
4769
- sorting.push( [ colIdx, asSorting[0] ] );
4770
- sorting[0]._idx = 0;
4771
- }
4772
-
4773
- // Run the sort by calling a full redraw
4774
- _fnReDraw( settings );
4775
-
4776
- // callback used for async user interaction
4777
- if ( typeof callback == 'function' ) {
4778
- callback( settings );
4779
- }
4780
- }
4781
-
4782
-
4783
- /**
4784
- * Attach a sort handler (click) to a node
4785
- * @param {object} settings dataTables settings object
4786
- * @param {node} attachTo node to attach the handler to
4787
- * @param {int} colIdx column sorting index
4788
- * @param {function} [callback] callback function
4789
- * @memberof DataTable#oApi
4790
- */
4791
- function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
4792
- {
4793
- var col = settings.aoColumns[ colIdx ];
4794
-
4795
- _fnBindAction( attachTo, {}, function (e) {
4796
- /* If the column is not sortable - don't to anything */
4797
- if ( col.bSortable === false ) {
4798
- return;
4799
- }
4800
-
4801
- // If processing is enabled use a timeout to allow the processing
4802
- // display to be shown - otherwise to it synchronously
4803
- if ( settings.oFeatures.bProcessing ) {
4804
- _fnProcessingDisplay( settings, true );
4805
-
4806
- setTimeout( function() {
4807
- _fnSortListener( settings, colIdx, e.shiftKey, callback );
4808
-
4809
- // In server-side processing, the draw callback will remove the
4810
- // processing display
4811
- if ( _fnDataSource( settings ) !== 'ssp' ) {
4812
- _fnProcessingDisplay( settings, false );
4813
- }
4814
- }, 0 );
4815
- }
4816
- else {
4817
- _fnSortListener( settings, colIdx, e.shiftKey, callback );
4818
- }
4819
- } );
4820
- }
4821
-
4822
-
4823
- /**
4824
- * Set the sorting classes on table's body, Note: it is safe to call this function
4825
- * when bSort and bSortClasses are false
4826
- * @param {object} oSettings dataTables settings object
4827
- * @memberof DataTable#oApi
4828
- */
4829
- function _fnSortingClasses( settings )
4830
- {
4831
- var oldSort = settings.aLastSort;
4832
- var sortClass = settings.oClasses.sSortColumn;
4833
- var sort = _fnSortFlatten( settings );
4834
- var features = settings.oFeatures;
4835
- var i, ien, colIdx;
4836
-
4837
- if ( features.bSort && features.bSortClasses ) {
4838
- // Remove old sorting classes
4839
- for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
4840
- colIdx = oldSort[i].src;
4841
-
4842
- // Remove column sorting
4843
- $( _pluck( settings.aoData, 'anCells', colIdx ) )
4844
- .removeClass( sortClass + (i<2 ? i+1 : 3) );
4845
- }
4846
-
4847
- // Add new column sorting
4848
- for ( i=0, ien=sort.length ; i<ien ; i++ ) {
4849
- colIdx = sort[i].src;
4850
-
4851
- $( _pluck( settings.aoData, 'anCells', colIdx ) )
4852
- .addClass( sortClass + (i<2 ? i+1 : 3) );
4853
- }
4854
- }
4855
-
4856
- settings.aLastSort = sort;
4857
- }
4858
-
4859
-
4860
- // Get the data to sort a column, be it from cache, fresh (populating the
4861
- // cache), or from a sort formatter
4862
- function _fnSortData( settings, idx )
4863
- {
4864
- // Custom sorting function - provided by the sort data type
4865
- var column = settings.aoColumns[ idx ];
4866
- var customSort = DataTable.ext.order[ column.sSortDataType ];
4867
- var customData;
4868
-
4869
- if ( customSort ) {
4870
- customData = customSort.call( settings.oInstance, settings, idx,
4871
- _fnColumnIndexToVisible( settings, idx )
4872
- );
4873
- }
4874
-
4875
- // Use / populate cache
4876
- var row, cellData;
4877
- var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
4878
-
4879
- for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
4880
- row = settings.aoData[i];
4881
-
4882
- if ( ! row._aSortData ) {
4883
- row._aSortData = [];
4884
- }
4885
-
4886
- if ( ! row._aSortData[idx] || customSort ) {
4887
- cellData = customSort ?
4888
- customData[i] : // If there was a custom sort function, use data from there
4889
- _fnGetCellData( settings, i, idx, 'sort' );
4890
-
4891
- row._aSortData[ idx ] = formatter ?
4892
- formatter( cellData ) :
4893
- cellData;
4894
- }
4895
- }
4896
- }
4897
-
4898
-
4899
-
4900
- /**
4901
- * Save the state of a table
4902
- * @param {object} oSettings dataTables settings object
4903
- * @memberof DataTable#oApi
4904
- */
4905
- function _fnSaveState ( settings )
4906
- {
4907
- if ( !settings.oFeatures.bStateSave || settings.bDestroying )
4908
- {
4909
- return;
4910
- }
4911
-
4912
- /* Store the interesting variables */
4913
- var state = {
4914
- time: +new Date(),
4915
- start: settings._iDisplayStart,
4916
- length: settings._iDisplayLength,
4917
- order: $.extend( true, [], settings.aaSorting ),
4918
- search: _fnSearchToCamel( settings.oPreviousSearch ),
4919
- columns: $.map( settings.aoColumns, function ( col, i ) {
4920
- return {
4921
- visible: col.bVisible,
4922
- search: _fnSearchToCamel( settings.aoPreSearchCols[i] )
4923
- };
4924
- } )
4925
- };
4926
-
4927
- _fnCallbackFire( settings, "aoStateSaveParams", 'stateSaveParams', [settings, state] );
4928
-
4929
- settings.oSavedState = state;
4930
- settings.fnStateSaveCallback.call( settings.oInstance, settings, state );
4931
- }
4932
-
4933
-
4934
- /**
4935
- * Attempt to load a saved table state
4936
- * @param {object} oSettings dataTables settings object
4937
- * @param {object} oInit DataTables init object so we can override settings
4938
- * @memberof DataTable#oApi
4939
- */
4940
- function _fnLoadState ( settings, oInit )
4941
- {
4942
- var i, ien;
4943
- var columns = settings.aoColumns;
4944
-
4945
- if ( ! settings.oFeatures.bStateSave ) {
4946
- return;
4947
- }
4948
-
4949
- var state = settings.fnStateLoadCallback.call( settings.oInstance, settings );
4950
- if ( ! state || ! state.time ) {
4951
- return;
4952
- }
4953
-
4954
- /* Allow custom and plug-in manipulation functions to alter the saved data set and
4955
- * cancelling of loading by returning false
4956
- */
4957
- var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );
4958
- if ( $.inArray( false, abStateLoad ) !== -1 ) {
4959
- return;
4960
- }
4961
-
4962
- /* Reject old data */
4963
- var duration = settings.iStateDuration;
4964
- if ( duration > 0 && state.time < +new Date() - (duration*1000) ) {
4965
- return;
4966
- }
4967
-
4968
- // Number of columns have changed - all bets are off, no restore of settings
4969
- if ( columns.length !== state.columns.length ) {
4970
- return;
4971
- }
4972
-
4973
- // Store the saved state so it might be accessed at any time
4974
- settings.oLoadedState = $.extend( true, {}, state );
4975
-
4976
- // Restore key features - todo - for 1.11 this needs to be done by
4977
- // subscribed events
4978
- if ( state.start !== undefined ) {
4979
- settings._iDisplayStart = state.start;
4980
- settings.iInitDisplayStart = state.start;
4981
- }
4982
- if ( state.length !== undefined ) {
4983
- settings._iDisplayLength = state.length;
4984
- }
4985
-
4986
- // Order
4987
- if ( state.order !== undefined ) {
4988
- settings.aaSorting = [];
4989
- $.each( state.order, function ( i, col ) {
4990
- settings.aaSorting.push( col[0] >= columns.length ?
4991
- [ 0, col[1] ] :
4992
- col
4993
- );
4994
- } );
4995
- }
4996
-
4997
- // Search
4998
- if ( state.search !== undefined ) {
4999
- $.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );
5000
- }
5001
-
5002
- // Columns
5003
- for ( i=0, ien=state.columns.length ; i<ien ; i++ ) {
5004
- var col = state.columns[i];
5005
-
5006
- // Visibility
5007
- if ( col.visible !== undefined ) {
5008
- columns[i].bVisible = col.visible;
5009
- }
5010
-
5011
- // Search
5012
- if ( col.search !== undefined ) {
5013
- $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );
5014
- }
5015
- }
5016
-
5017
- _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );
5018
- }
5019
-
5020
-
5021
- /**
5022
- * Return the settings object for a particular table
5023
- * @param {node} table table we are using as a dataTable
5024
- * @returns {object} Settings object - or null if not found
5025
- * @memberof DataTable#oApi
5026
- */
5027
- function _fnSettingsFromNode ( table )
5028
- {
5029
- var settings = DataTable.settings;
5030
- var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
5031
-
5032
- return idx !== -1 ?
5033
- settings[ idx ] :
5034
- null;
5035
- }
5036
-
5037
-
5038
- /**
5039
- * Log an error message
5040
- * @param {object} settings dataTables settings object
5041
- * @param {int} level log error messages, or display them to the user
5042
- * @param {string} msg error message
5043
- * @param {int} tn Technical note id to get more information about the error.
5044
- * @memberof DataTable#oApi
5045
- */
5046
- function _fnLog( settings, level, msg, tn )
5047
- {
5048
- msg = 'DataTables warning: '+
5049
- (settings ? 'table id='+settings.sTableId+' - ' : '')+msg;
5050
-
5051
- if ( tn ) {
5052
- msg += '. For more information about this error, please see '+
5053
- 'http://datatables.net/tn/'+tn;
5054
- }
5055
-
5056
- if ( ! level ) {
5057
- // Backwards compatibility pre 1.10
5058
- var ext = DataTable.ext;
5059
- var type = ext.sErrMode || ext.errMode;
5060
-
5061
- if ( settings ) {
5062
- _fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );
5063
- }
5064
-
5065
- if ( type == 'alert' ) {
5066
- alert( msg );
5067
- }
5068
- else if ( type == 'throw' ) {
5069
- throw new Error(msg);
5070
- }
5071
- else if ( typeof type == 'function' ) {
5072
- type( settings, tn, msg );
5073
- }
5074
- }
5075
- else if ( window.console && console.log ) {
5076
- console.log( msg );
5077
- }
5078
- }
5079
-
5080
-
5081
- /**
5082
- * See if a property is defined on one object, if so assign it to the other object
5083
- * @param {object} ret target object
5084
- * @param {object} src source object
5085
- * @param {string} name property
5086
- * @param {string} [mappedName] name to map too - optional, name used if not given
5087
- * @memberof DataTable#oApi
5088
- */
5089
- function _fnMap( ret, src, name, mappedName )
5090
- {
5091
- if ( $.isArray( name ) ) {
5092
- $.each( name, function (i, val) {
5093
- if ( $.isArray( val ) ) {
5094
- _fnMap( ret, src, val[0], val[1] );
5095
- }
5096
- else {
5097
- _fnMap( ret, src, val );
5098
- }
5099
- } );
5100
-
5101
- return;
5102
- }
5103
-
5104
- if ( mappedName === undefined ) {
5105
- mappedName = name;
5106
- }
5107
-
5108
- if ( src[name] !== undefined ) {
5109
- ret[mappedName] = src[name];
5110
- }
5111
- }
5112
-
5113
-
5114
- /**
5115
- * Extend objects - very similar to jQuery.extend, but deep copy objects, and
5116
- * shallow copy arrays. The reason we need to do this, is that we don't want to
5117
- * deep copy array init values (such as aaSorting) since the dev wouldn't be
5118
- * able to override them, but we do want to deep copy arrays.
5119
- * @param {object} out Object to extend
5120
- * @param {object} extender Object from which the properties will be applied to
5121
- * out
5122
- * @param {boolean} breakRefs If true, then arrays will be sliced to take an
5123
- * independent copy with the exception of the `data` or `aaData` parameters
5124
- * if they are present. This is so you can pass in a collection to
5125
- * DataTables and have that used as your data source without breaking the
5126
- * references
5127
- * @returns {object} out Reference, just for convenience - out === the return.
5128
- * @memberof DataTable#oApi
5129
- * @todo This doesn't take account of arrays inside the deep copied objects.
5130
- */
5131
- function _fnExtend( out, extender, breakRefs )
5132
- {
5133
- var val;
5134
-
5135
- for ( var prop in extender ) {
5136
- if ( extender.hasOwnProperty(prop) ) {
5137
- val = extender[prop];
5138
-
5139
- if ( $.isPlainObject( val ) ) {
5140
- if ( ! $.isPlainObject( out[prop] ) ) {
5141
- out[prop] = {};
5142
- }
5143
- $.extend( true, out[prop], val );
5144
- }
5145
- else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
5146
- out[prop] = val.slice();
5147
- }
5148
- else {
5149
- out[prop] = val;
5150
- }
5151
- }
5152
- }
5153
-
5154
- return out;
5155
- }
5156
-
5157
-
5158
- /**
5159
- * Bind an event handers to allow a click or return key to activate the callback.
5160
- * This is good for accessibility since a return on the keyboard will have the
5161
- * same effect as a click, if the element has focus.
5162
- * @param {element} n Element to bind the action to
5163
- * @param {object} oData Data object to pass to the triggered function
5164
- * @param {function} fn Callback function for when the event is triggered
5165
- * @memberof DataTable#oApi
5166
- */
5167
- function _fnBindAction( n, oData, fn )
5168
- {
5169
- $(n)
5170
- .bind( 'click.DT', oData, function (e) {
5171
- n.blur(); // Remove focus outline for mouse users
5172
- fn(e);
5173
- } )
5174
- .bind( 'keypress.DT', oData, function (e){
5175
- if ( e.which === 13 ) {
5176
- e.preventDefault();
5177
- fn(e);
5178
- }
5179
- } )
5180
- .bind( 'selectstart.DT', function () {
5181
- /* Take the brutal approach to cancelling text selection */
5182
- return false;
5183
- } );
5184
- }
5185
-
5186
-
5187
- /**
5188
- * Register a callback function. Easily allows a callback function to be added to
5189
- * an array store of callback functions that can then all be called together.
5190
- * @param {object} oSettings dataTables settings object
5191
- * @param {string} sStore Name of the array storage for the callbacks in oSettings
5192
- * @param {function} fn Function to be called back
5193
- * @param {string} sName Identifying name for the callback (i.e. a label)
5194
- * @memberof DataTable#oApi
5195
- */
5196
- function _fnCallbackReg( oSettings, sStore, fn, sName )
5197
- {
5198
- if ( fn )
5199
- {
5200
- oSettings[sStore].push( {
5201
- "fn": fn,
5202
- "sName": sName
5203
- } );
5204
- }
5205
- }
5206
-
5207
-
5208
- /**
5209
- * Fire callback functions and trigger events. Note that the loop over the
5210
- * callback array store is done backwards! Further note that you do not want to
5211
- * fire off triggers in time sensitive applications (for example cell creation)
5212
- * as its slow.
5213
- * @param {object} settings dataTables settings object
5214
- * @param {string} callbackArr Name of the array storage for the callbacks in
5215
- * oSettings
5216
- * @param {string} eventName Name of the jQuery custom event to trigger. If
5217
- * null no trigger is fired
5218
- * @param {array} args Array of arguments to pass to the callback function /
5219
- * trigger
5220
- * @memberof DataTable#oApi
5221
- */
5222
- function _fnCallbackFire( settings, callbackArr, eventName, args )
5223
- {
5224
- var ret = [];
5225
-
5226
- if ( callbackArr ) {
5227
- ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
5228
- return val.fn.apply( settings.oInstance, args );
5229
- } );
5230
- }
5231
-
5232
- if ( eventName !== null ) {
5233
- var e = $.Event( eventName+'.dt' );
5234
-
5235
- $(settings.nTable).trigger( e, args );
5236
-
5237
- ret.push( e.result );
5238
- }
5239
-
5240
- return ret;
5241
- }
5242
-
5243
-
5244
- function _fnLengthOverflow ( settings )
5245
- {
5246
- var
5247
- start = settings._iDisplayStart,
5248
- end = settings.fnDisplayEnd(),
5249
- len = settings._iDisplayLength;
5250
-
5251
- /* If we have space to show extra rows (backing up from the end point - then do so */
5252
- if ( start >= end )
5253
- {
5254
- start = end - len;
5255
- }
5256
-
5257
- // Keep the start record on the current page
5258
- start -= (start % len);
5259
-
5260
- if ( len === -1 || start < 0 )
5261
- {
5262
- start = 0;
5263
- }
5264
-
5265
- settings._iDisplayStart = start;
5266
- }
5267
-
5268
-
5269
- function _fnRenderer( settings, type )
5270
- {
5271
- var renderer = settings.renderer;
5272
- var host = DataTable.ext.renderer[type];
5273
-
5274
- if ( $.isPlainObject( renderer ) && renderer[type] ) {
5275
- // Specific renderer for this type. If available use it, otherwise use
5276
- // the default.
5277
- return host[renderer[type]] || host._;
5278
- }
5279
- else if ( typeof renderer === 'string' ) {
5280
- // Common renderer - if there is one available for this type use it,
5281
- // otherwise use the default
5282
- return host[renderer] || host._;
5283
- }
5284
-
5285
- // Use the default
5286
- return host._;
5287
- }
5288
-
5289
-
5290
- /**
5291
- * Detect the data source being used for the table. Used to simplify the code
5292
- * a little (ajax) and to make it compress a little smaller.
5293
- *
5294
- * @param {object} settings dataTables settings object
5295
- * @returns {string} Data source
5296
- * @memberof DataTable#oApi
5297
- */
5298
- function _fnDataSource ( settings )
5299
- {
5300
- if ( settings.oFeatures.bServerSide ) {
5301
- return 'ssp';
5302
- }
5303
- else if ( settings.ajax || settings.sAjaxSource ) {
5304
- return 'ajax';
5305
- }
5306
- return 'dom';
5307
- }
5308
-
5309
-
5310
- DataTable = function( options )
5311
- {
5312
- /**
5313
- * Perform a jQuery selector action on the table's TR elements (from the tbody) and
5314
- * return the resulting jQuery object.
5315
- * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5316
- * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5317
- * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
5318
- * criterion ("applied") or all TR elements (i.e. no filter).
5319
- * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
5320
- * Can be either 'current', whereby the current sorting of the table is used, or
5321
- * 'original' whereby the original order the data was read into the table is used.
5322
- * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5323
- * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5324
- * 'current' and filter is 'applied', regardless of what they might be given as.
5325
- * @returns {object} jQuery object, filtered by the given selector.
5326
- * @dtopt API
5327
- * @deprecated Since v1.10
5328
- *
5329
- * @example
5330
- * $(document).ready(function() {
5331
- * var oTable = $('#example').dataTable();
5332
- *
5333
- * // Highlight every second row
5334
- * oTable.$('tr:odd').css('backgroundColor', 'blue');
5335
- * } );
5336
- *
5337
- * @example
5338
- * $(document).ready(function() {
5339
- * var oTable = $('#example').dataTable();
5340
- *
5341
- * // Filter to rows with 'Webkit' in them, add a background colour and then
5342
- * // remove the filter, thus highlighting the 'Webkit' rows only.
5343
- * oTable.fnFilter('Webkit');
5344
- * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
5345
- * oTable.fnFilter('');
5346
- * } );
5347
- */
5348
- this.$ = function ( sSelector, oOpts )
5349
- {
5350
- return this.api(true).$( sSelector, oOpts );
5351
- };
5352
-
5353
-
5354
- /**
5355
- * Almost identical to $ in operation, but in this case returns the data for the matched
5356
- * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
5357
- * rather than any descendants, so the data can be obtained for the row/cell. If matching
5358
- * rows are found, the data returned is the original data array/object that was used to
5359
- * create the row (or a generated array if from a DOM source).
5360
- *
5361
- * This method is often useful in-combination with $ where both functions are given the
5362
- * same parameters and the array indexes will match identically.
5363
- * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5364
- * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5365
- * @param {string} [oOpts.filter=none] Select elements that meet the current filter
5366
- * criterion ("applied") or all elements (i.e. no filter).
5367
- * @param {string} [oOpts.order=current] Order of the data in the processed array.
5368
- * Can be either 'current', whereby the current sorting of the table is used, or
5369
- * 'original' whereby the original order the data was read into the table is used.
5370
- * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5371
- * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5372
- * 'current' and filter is 'applied', regardless of what they might be given as.
5373
- * @returns {array} Data for the matched elements. If any elements, as a result of the
5374
- * selector, were not TR, TD or TH elements in the DataTable, they will have a null
5375
- * entry in the array.
5376
- * @dtopt API
5377
- * @deprecated Since v1.10
5378
- *
5379
- * @example
5380
- * $(document).ready(function() {
5381
- * var oTable = $('#example').dataTable();
5382
- *
5383
- * // Get the data from the first row in the table
5384
- * var data = oTable._('tr:first');
5385
- *
5386
- * // Do something useful with the data
5387
- * alert( "First cell is: "+data[0] );
5388
- * } );
5389
- *
5390
- * @example
5391
- * $(document).ready(function() {
5392
- * var oTable = $('#example').dataTable();
5393
- *
5394
- * // Filter to 'Webkit' and get all data for
5395
- * oTable.fnFilter('Webkit');
5396
- * var data = oTable._('tr', {"search": "applied"});
5397
- *
5398
- * // Do something with the data
5399
- * alert( data.length+" rows matched the search" );
5400
- * } );
5401
- */
5402
- this._ = function ( sSelector, oOpts )
5403
- {
5404
- return this.api(true).rows( sSelector, oOpts ).data();
5405
- };
5406
-
5407
-
5408
- /**
5409
- * Create a DataTables Api instance, with the currently selected tables for
5410
- * the Api's context.
5411
- * @param {boolean} [traditional=false] Set the API instance's context to be
5412
- * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
5413
- * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
5414
- * or if all tables captured in the jQuery object should be used.
5415
- * @return {DataTables.Api}
5416
- */
5417
- this.api = function ( traditional )
5418
- {
5419
- return traditional ?
5420
- new _Api(
5421
- _fnSettingsFromNode( this[ _ext.iApiIndex ] )
5422
- ) :
5423
- new _Api( this );
5424
- };
5425
-
5426
-
5427
- /**
5428
- * Add a single new row or multiple rows of data to the table. Please note
5429
- * that this is suitable for client-side processing only - if you are using
5430
- * server-side processing (i.e. "bServerSide": true), then to add data, you
5431
- * must add it to the data source, i.e. the server-side, through an Ajax call.
5432
- * @param {array|object} data The data to be added to the table. This can be:
5433
- * <ul>
5434
- * <li>1D array of data - add a single row with the data provided</li>
5435
- * <li>2D array of arrays - add multiple rows in a single call</li>
5436
- * <li>object - data object when using <i>mData</i></li>
5437
- * <li>array of objects - multiple data objects when using <i>mData</i></li>
5438
- * </ul>
5439
- * @param {bool} [redraw=true] redraw the table or not
5440
- * @returns {array} An array of integers, representing the list of indexes in
5441
- * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
5442
- * the table.
5443
- * @dtopt API
5444
- * @deprecated Since v1.10
5445
- *
5446
- * @example
5447
- * // Global var for counter
5448
- * var giCount = 2;
5449
- *
5450
- * $(document).ready(function() {
5451
- * $('#example').dataTable();
5452
- * } );
5453
- *
5454
- * function fnClickAddRow() {
5455
- * $('#example').dataTable().fnAddData( [
5456
- * giCount+".1",
5457
- * giCount+".2",
5458
- * giCount+".3",
5459
- * giCount+".4" ]
5460
- * );
5461
- *
5462
- * giCount++;
5463
- * }
5464
- */
5465
- this.fnAddData = function( data, redraw )
5466
- {
5467
- var api = this.api( true );
5468
-
5469
- /* Check if we want to add multiple rows or not */
5470
- var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
5471
- api.rows.add( data ) :
5472
- api.row.add( data );
5473
-
5474
- if ( redraw === undefined || redraw ) {
5475
- api.draw();
5476
- }
5477
-
5478
- return rows.flatten().toArray();
5479
- };
5480
-
5481
-
5482
- /**
5483
- * This function will make DataTables recalculate the column sizes, based on the data
5484
- * contained in the table and the sizes applied to the columns (in the DOM, CSS or
5485
- * through the sWidth parameter). This can be useful when the width of the table's
5486
- * parent element changes (for example a window resize).
5487
- * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
5488
- * @dtopt API
5489
- * @deprecated Since v1.10
5490
- *
5491
- * @example
5492
- * $(document).ready(function() {
5493
- * var oTable = $('#example').dataTable( {
5494
- * "sScrollY": "200px",
5495
- * "bPaginate": false
5496
- * } );
5497
- *
5498
- * $(window).bind('resize', function () {
5499
- * oTable.fnAdjustColumnSizing();
5500
- * } );
5501
- * } );
5502
- */
5503
- this.fnAdjustColumnSizing = function ( bRedraw )
5504
- {
5505
- var api = this.api( true ).columns.adjust();
5506
- var settings = api.settings()[0];
5507
- var scroll = settings.oScroll;
5508
-
5509
- if ( bRedraw === undefined || bRedraw ) {
5510
- api.draw( false );
5511
- }
5512
- else if ( scroll.sX !== "" || scroll.sY !== "" ) {
5513
- /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
5514
- _fnScrollDraw( settings );
5515
- }
5516
- };
5517
-
5518
-
5519
- /**
5520
- * Quickly and simply clear a table
5521
- * @param {bool} [bRedraw=true] redraw the table or not
5522
- * @dtopt API
5523
- * @deprecated Since v1.10
5524
- *
5525
- * @example
5526
- * $(document).ready(function() {
5527
- * var oTable = $('#example').dataTable();
5528
- *
5529
- * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
5530
- * oTable.fnClearTable();
5531
- * } );
5532
- */
5533
- this.fnClearTable = function( bRedraw )
5534
- {
5535
- var api = this.api( true ).clear();
5536
-
5537
- if ( bRedraw === undefined || bRedraw ) {
5538
- api.draw();
5539
- }
5540
- };
5541
-
5542
-
5543
- /**
5544
- * The exact opposite of 'opening' a row, this function will close any rows which
5545
- * are currently 'open'.
5546
- * @param {node} nTr the table row to 'close'
5547
- * @returns {int} 0 on success, or 1 if failed (can't find the row)
5548
- * @dtopt API
5549
- * @deprecated Since v1.10
5550
- *
5551
- * @example
5552
- * $(document).ready(function() {
5553
- * var oTable;
5554
- *
5555
- * // 'open' an information row when a row is clicked on
5556
- * $('#example tbody tr').click( function () {
5557
- * if ( oTable.fnIsOpen(this) ) {
5558
- * oTable.fnClose( this );
5559
- * } else {
5560
- * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5561
- * }
5562
- * } );
5563
- *
5564
- * oTable = $('#example').dataTable();
5565
- * } );
5566
- */
5567
- this.fnClose = function( nTr )
5568
- {
5569
- this.api( true ).row( nTr ).child.hide();
5570
- };
5571
-
5572
-
5573
- /**
5574
- * Remove a row for the table
5575
- * @param {mixed} target The index of the row from aoData to be deleted, or
5576
- * the TR element you want to delete
5577
- * @param {function|null} [callBack] Callback function
5578
- * @param {bool} [redraw=true] Redraw the table or not
5579
- * @returns {array} The row that was deleted
5580
- * @dtopt API
5581
- * @deprecated Since v1.10
5582
- *
5583
- * @example
5584
- * $(document).ready(function() {
5585
- * var oTable = $('#example').dataTable();
5586
- *
5587
- * // Immediately remove the first row
5588
- * oTable.fnDeleteRow( 0 );
5589
- * } );
5590
- */
5591
- this.fnDeleteRow = function( target, callback, redraw )
5592
- {
5593
- var api = this.api( true );
5594
- var rows = api.rows( target );
5595
- var settings = rows.settings()[0];
5596
- var data = settings.aoData[ rows[0][0] ];
5597
-
5598
- rows.remove();
5599
-
5600
- if ( callback ) {
5601
- callback.call( this, settings, data );
5602
- }
5603
-
5604
- if ( redraw === undefined || redraw ) {
5605
- api.draw();
5606
- }
5607
-
5608
- return data;
5609
- };
5610
-
5611
-
5612
- /**
5613
- * Restore the table to it's original state in the DOM by removing all of DataTables
5614
- * enhancements, alterations to the DOM structure of the table and event listeners.
5615
- * @param {boolean} [remove=false] Completely remove the table from the DOM
5616
- * @dtopt API
5617
- * @deprecated Since v1.10
5618
- *
5619
- * @example
5620
- * $(document).ready(function() {
5621
- * // This example is fairly pointless in reality, but shows how fnDestroy can be used
5622
- * var oTable = $('#example').dataTable();
5623
- * oTable.fnDestroy();
5624
- * } );
5625
- */
5626
- this.fnDestroy = function ( remove )
5627
- {
5628
- this.api( true ).destroy( remove );
5629
- };
5630
-
5631
-
5632
- /**
5633
- * Redraw the table
5634
- * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
5635
- * @dtopt API
5636
- * @deprecated Since v1.10
5637
- *
5638
- * @example
5639
- * $(document).ready(function() {
5640
- * var oTable = $('#example').dataTable();
5641
- *
5642
- * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
5643
- * oTable.fnDraw();
5644
- * } );
5645
- */
5646
- this.fnDraw = function( complete )
5647
- {
5648
- // Note that this isn't an exact match to the old call to _fnDraw - it takes
5649
- // into account the new data, but can hold position.
5650
- this.api( true ).draw( complete );
5651
- };
5652
-
5653
-
5654
- /**
5655
- * Filter the input based on data
5656
- * @param {string} sInput String to filter the table on
5657
- * @param {int|null} [iColumn] Column to limit filtering to
5658
- * @param {bool} [bRegex=false] Treat as regular expression or not
5659
- * @param {bool} [bSmart=true] Perform smart filtering or not
5660
- * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
5661
- * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
5662
- * @dtopt API
5663
- * @deprecated Since v1.10
5664
- *
5665
- * @example
5666
- * $(document).ready(function() {
5667
- * var oTable = $('#example').dataTable();
5668
- *
5669
- * // Sometime later - filter...
5670
- * oTable.fnFilter( 'test string' );
5671
- * } );
5672
- */
5673
- this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
5674
- {
5675
- var api = this.api( true );
5676
-
5677
- if ( iColumn === null || iColumn === undefined ) {
5678
- api.search( sInput, bRegex, bSmart, bCaseInsensitive );
5679
- }
5680
- else {
5681
- api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
5682
- }
5683
-
5684
- api.draw();
5685
- };
5686
-
5687
-
5688
- /**
5689
- * Get the data for the whole table, an individual row or an individual cell based on the
5690
- * provided parameters.
5691
- * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
5692
- * a TR node then the data source for the whole row will be returned. If given as a
5693
- * TD/TH cell node then iCol will be automatically calculated and the data for the
5694
- * cell returned. If given as an integer, then this is treated as the aoData internal
5695
- * data index for the row (see fnGetPosition) and the data for that row used.
5696
- * @param {int} [col] Optional column index that you want the data of.
5697
- * @returns {array|object|string} If mRow is undefined, then the data for all rows is
5698
- * returned. If mRow is defined, just data for that row, and is iCol is
5699
- * defined, only data for the designated cell is returned.
5700
- * @dtopt API
5701
- * @deprecated Since v1.10
5702
- *
5703
- * @example
5704
- * // Row data
5705
- * $(document).ready(function() {
5706
- * oTable = $('#example').dataTable();
5707
- *
5708
- * oTable.$('tr').click( function () {
5709
- * var data = oTable.fnGetData( this );
5710
- * // ... do something with the array / object of data for the row
5711
- * } );
5712
- * } );
5713
- *
5714
- * @example
5715
- * // Individual cell data
5716
- * $(document).ready(function() {
5717
- * oTable = $('#example').dataTable();
5718
- *
5719
- * oTable.$('td').click( function () {
5720
- * var sData = oTable.fnGetData( this );
5721
- * alert( 'The cell clicked on had the value of '+sData );
5722
- * } );
5723
- * } );
5724
- */
5725
- this.fnGetData = function( src, col )
5726
- {
5727
- var api = this.api( true );
5728
-
5729
- if ( src !== undefined ) {
5730
- var type = src.nodeName ? src.nodeName.toLowerCase() : '';
5731
-
5732
- return col !== undefined || type == 'td' || type == 'th' ?
5733
- api.cell( src, col ).data() :
5734
- api.row( src ).data() || null;
5735
- }
5736
-
5737
- return api.data().toArray();
5738
- };
5739
-
5740
-
5741
- /**
5742
- * Get an array of the TR nodes that are used in the table's body. Note that you will
5743
- * typically want to use the '$' API method in preference to this as it is more
5744
- * flexible.
5745
- * @param {int} [iRow] Optional row index for the TR element you want
5746
- * @returns {array|node} If iRow is undefined, returns an array of all TR elements
5747
- * in the table's body, or iRow is defined, just the TR element requested.
5748
- * @dtopt API
5749
- * @deprecated Since v1.10
5750
- *
5751
- * @example
5752
- * $(document).ready(function() {
5753
- * var oTable = $('#example').dataTable();
5754
- *
5755
- * // Get the nodes from the table
5756
- * var nNodes = oTable.fnGetNodes( );
5757
- * } );
5758
- */
5759
- this.fnGetNodes = function( iRow )
5760
- {
5761
- var api = this.api( true );
5762
-
5763
- return iRow !== undefined ?
5764
- api.row( iRow ).node() :
5765
- api.rows().nodes().flatten().toArray();
5766
- };
5767
-
5768
-
5769
- /**
5770
- * Get the array indexes of a particular cell from it's DOM element
5771
- * and column index including hidden columns
5772
- * @param {node} node this can either be a TR, TD or TH in the table's body
5773
- * @returns {int} If nNode is given as a TR, then a single index is returned, or
5774
- * if given as a cell, an array of [row index, column index (visible),
5775
- * column index (all)] is given.
5776
- * @dtopt API
5777
- * @deprecated Since v1.10
5778
- *
5779
- * @example
5780
- * $(document).ready(function() {
5781
- * $('#example tbody td').click( function () {
5782
- * // Get the position of the current data from the node
5783
- * var aPos = oTable.fnGetPosition( this );
5784
- *
5785
- * // Get the data array for this row
5786
- * var aData = oTable.fnGetData( aPos[0] );
5787
- *
5788
- * // Update the data array and return the value
5789
- * aData[ aPos[1] ] = 'clicked';
5790
- * this.innerHTML = 'clicked';
5791
- * } );
5792
- *
5793
- * // Init DataTables
5794
- * oTable = $('#example').dataTable();
5795
- * } );
5796
- */
5797
- this.fnGetPosition = function( node )
5798
- {
5799
- var api = this.api( true );
5800
- var nodeName = node.nodeName.toUpperCase();
5801
-
5802
- if ( nodeName == 'TR' ) {
5803
- return api.row( node ).index();
5804
- }
5805
- else if ( nodeName == 'TD' || nodeName == 'TH' ) {
5806
- var cell = api.cell( node ).index();
5807
-
5808
- return [
5809
- cell.row,
5810
- cell.columnVisible,
5811
- cell.column
5812
- ];
5813
- }
5814
- return null;
5815
- };
5816
-
5817
-
5818
- /**
5819
- * Check to see if a row is 'open' or not.
5820
- * @param {node} nTr the table row to check
5821
- * @returns {boolean} true if the row is currently open, false otherwise
5822
- * @dtopt API
5823
- * @deprecated Since v1.10
5824
- *
5825
- * @example
5826
- * $(document).ready(function() {
5827
- * var oTable;
5828
- *
5829
- * // 'open' an information row when a row is clicked on
5830
- * $('#example tbody tr').click( function () {
5831
- * if ( oTable.fnIsOpen(this) ) {
5832
- * oTable.fnClose( this );
5833
- * } else {
5834
- * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5835
- * }
5836
- * } );
5837
- *
5838
- * oTable = $('#example').dataTable();
5839
- * } );
5840
- */
5841
- this.fnIsOpen = function( nTr )
5842
- {
5843
- return this.api( true ).row( nTr ).child.isShown();
5844
- };
5845
-
5846
-
5847
- /**
5848
- * This function will place a new row directly after a row which is currently
5849
- * on display on the page, with the HTML contents that is passed into the
5850
- * function. This can be used, for example, to ask for confirmation that a
5851
- * particular record should be deleted.
5852
- * @param {node} nTr The table row to 'open'
5853
- * @param {string|node|jQuery} mHtml The HTML to put into the row
5854
- * @param {string} sClass Class to give the new TD cell
5855
- * @returns {node} The row opened. Note that if the table row passed in as the
5856
- * first parameter, is not found in the table, this method will silently
5857
- * return.
5858
- * @dtopt API
5859
- * @deprecated Since v1.10
5860
- *
5861
- * @example
5862
- * $(document).ready(function() {
5863
- * var oTable;
5864
- *
5865
- * // 'open' an information row when a row is clicked on
5866
- * $('#example tbody tr').click( function () {
5867
- * if ( oTable.fnIsOpen(this) ) {
5868
- * oTable.fnClose( this );
5869
- * } else {
5870
- * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5871
- * }
5872
- * } );
5873
- *
5874
- * oTable = $('#example').dataTable();
5875
- * } );
5876
- */
5877
- this.fnOpen = function( nTr, mHtml, sClass )
5878
- {
5879
- return this.api( true )
5880
- .row( nTr )
5881
- .child( mHtml, sClass )
5882
- .show()
5883
- .child()[0];
5884
- };
5885
-
5886
-
5887
- /**
5888
- * Change the pagination - provides the internal logic for pagination in a simple API
5889
- * function. With this function you can have a DataTables table go to the next,
5890
- * previous, first or last pages.
5891
- * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
5892
- * or page number to jump to (integer), note that page 0 is the first page.
5893
- * @param {bool} [bRedraw=true] Redraw the table or not
5894
- * @dtopt API
5895
- * @deprecated Since v1.10
5896
- *
5897
- * @example
5898
- * $(document).ready(function() {
5899
- * var oTable = $('#example').dataTable();
5900
- * oTable.fnPageChange( 'next' );
5901
- * } );
5902
- */
5903
- this.fnPageChange = function ( mAction, bRedraw )
5904
- {
5905
- var api = this.api( true ).page( mAction );
5906
-
5907
- if ( bRedraw === undefined || bRedraw ) {
5908
- api.draw(false);
5909
- }
5910
- };
5911
-
5912
-
5913
- /**
5914
- * Show a particular column
5915
- * @param {int} iCol The column whose display should be changed
5916
- * @param {bool} bShow Show (true) or hide (false) the column
5917
- * @param {bool} [bRedraw=true] Redraw the table or not
5918
- * @dtopt API
5919
- * @deprecated Since v1.10
5920
- *
5921
- * @example
5922
- * $(document).ready(function() {
5923
- * var oTable = $('#example').dataTable();
5924
- *
5925
- * // Hide the second column after initialisation
5926
- * oTable.fnSetColumnVis( 1, false );
5927
- * } );
5928
- */
5929
- this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
5930
- {
5931
- var api = this.api( true ).column( iCol ).visible( bShow );
5932
-
5933
- if ( bRedraw === undefined || bRedraw ) {
5934
- api.columns.adjust().draw();
5935
- }
5936
- };
5937
-
5938
-
5939
- /**
5940
- * Get the settings for a particular table for external manipulation
5941
- * @returns {object} DataTables settings object. See
5942
- * {@link DataTable.models.oSettings}
5943
- * @dtopt API
5944
- * @deprecated Since v1.10
5945
- *
5946
- * @example
5947
- * $(document).ready(function() {
5948
- * var oTable = $('#example').dataTable();
5949
- * var oSettings = oTable.fnSettings();
5950
- *
5951
- * // Show an example parameter from the settings
5952
- * alert( oSettings._iDisplayStart );
5953
- * } );
5954
- */
5955
- this.fnSettings = function()
5956
- {
5957
- return _fnSettingsFromNode( this[_ext.iApiIndex] );
5958
- };
5959
-
5960
-
5961
- /**
5962
- * Sort the table by a particular column
5963
- * @param {int} iCol the data index to sort on. Note that this will not match the
5964
- * 'display index' if you have hidden data entries
5965
- * @dtopt API
5966
- * @deprecated Since v1.10
5967
- *
5968
- * @example
5969
- * $(document).ready(function() {
5970
- * var oTable = $('#example').dataTable();
5971
- *
5972
- * // Sort immediately with columns 0 and 1
5973
- * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
5974
- * } );
5975
- */
5976
- this.fnSort = function( aaSort )
5977
- {
5978
- this.api( true ).order( aaSort ).draw();
5979
- };
5980
-
5981
-
5982
- /**
5983
- * Attach a sort listener to an element for a given column
5984
- * @param {node} nNode the element to attach the sort listener to
5985
- * @param {int} iColumn the column that a click on this node will sort on
5986
- * @param {function} [fnCallback] callback function when sort is run
5987
- * @dtopt API
5988
- * @deprecated Since v1.10
5989
- *
5990
- * @example
5991
- * $(document).ready(function() {
5992
- * var oTable = $('#example').dataTable();
5993
- *
5994
- * // Sort on column 1, when 'sorter' is clicked on
5995
- * oTable.fnSortListener( document.getElementById('sorter'), 1 );
5996
- * } );
5997
- */
5998
- this.fnSortListener = function( nNode, iColumn, fnCallback )
5999
- {
6000
- this.api( true ).order.listener( nNode, iColumn, fnCallback );
6001
- };
6002
-
6003
-
6004
- /**
6005
- * Update a table cell or row - this method will accept either a single value to
6006
- * update the cell with, an array of values with one element for each column or
6007
- * an object in the same format as the original data source. The function is
6008
- * self-referencing in order to make the multi column updates easier.
6009
- * @param {object|array|string} mData Data to update the cell/row with
6010
- * @param {node|int} mRow TR element you want to update or the aoData index
6011
- * @param {int} [iColumn] The column to update, give as null or undefined to
6012
- * update a whole row.
6013
- * @param {bool} [bRedraw=true] Redraw the table or not
6014
- * @param {bool} [bAction=true] Perform pre-draw actions or not
6015
- * @returns {int} 0 on success, 1 on error
6016
- * @dtopt API
6017
- * @deprecated Since v1.10
6018
- *
6019
- * @example
6020
- * $(document).ready(function() {
6021
- * var oTable = $('#example').dataTable();
6022
- * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
6023
- * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
6024
- * } );
6025
- */
6026
- this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
6027
- {
6028
- var api = this.api( true );
6029
-
6030
- if ( iColumn === undefined || iColumn === null ) {
6031
- api.row( mRow ).data( mData );
6032
- }
6033
- else {
6034
- api.cell( mRow, iColumn ).data( mData );
6035
- }
6036
-
6037
- if ( bAction === undefined || bAction ) {
6038
- api.columns.adjust();
6039
- }
6040
-
6041
- if ( bRedraw === undefined || bRedraw ) {
6042
- api.draw();
6043
- }
6044
- return 0;
6045
- };
6046
-
6047
-
6048
- /**
6049
- * Provide a common method for plug-ins to check the version of DataTables being used, in order
6050
- * to ensure compatibility.
6051
- * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
6052
- * formats "X" and "X.Y" are also acceptable.
6053
- * @returns {boolean} true if this version of DataTables is greater or equal to the required
6054
- * version, or false if this version of DataTales is not suitable
6055
- * @method
6056
- * @dtopt API
6057
- * @deprecated Since v1.10
6058
- *
6059
- * @example
6060
- * $(document).ready(function() {
6061
- * var oTable = $('#example').dataTable();
6062
- * alert( oTable.fnVersionCheck( '1.9.0' ) );
6063
- * } );
6064
- */
6065
- this.fnVersionCheck = _ext.fnVersionCheck;
6066
-
6067
-
6068
- var _that = this;
6069
- var emptyInit = options === undefined;
6070
- var len = this.length;
6071
-
6072
- if ( emptyInit ) {
6073
- options = {};
6074
- }
6075
-
6076
- this.oApi = this.internal = _ext.internal;
6077
-
6078
- // Extend with old style plug-in API methods
6079
- for ( var fn in DataTable.ext.internal ) {
6080
- if ( fn ) {
6081
- this[fn] = _fnExternApiFunc(fn);
6082
- }
6083
- }
6084
-
6085
- this.each(function() {
6086
- // For each initialisation we want to give it a clean initialisation
6087
- // object that can be bashed around
6088
- var o = {};
6089
- var oInit = len > 1 ? // optimisation for single table case
6090
- _fnExtend( o, options, true ) :
6091
- options;
6092
-
6093
- /*global oInit,_that,emptyInit*/
6094
- var i=0, iLen, j, jLen, k, kLen;
6095
- var sId = this.getAttribute( 'id' );
6096
- var bInitHandedOff = false;
6097
- var defaults = DataTable.defaults;
6098
- var $this = $(this);
6099
-
6100
-
6101
- /* Sanity check */
6102
- if ( this.nodeName.toLowerCase() != 'table' )
6103
- {
6104
- _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
6105
- return;
6106
- }
6107
-
6108
- /* Backwards compatibility for the defaults */
6109
- _fnCompatOpts( defaults );
6110
- _fnCompatCols( defaults.column );
6111
-
6112
- /* Convert the camel-case defaults to Hungarian */
6113
- _fnCamelToHungarian( defaults, defaults, true );
6114
- _fnCamelToHungarian( defaults.column, defaults.column, true );
6115
-
6116
- /* Setting up the initialisation object */
6117
- _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );
6118
-
6119
-
6120
-
6121
- /* Check to see if we are re-initialising a table */
6122
- var allSettings = DataTable.settings;
6123
- for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
6124
- {
6125
- var s = allSettings[i];
6126
-
6127
- /* Base check on table node */
6128
- if ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )
6129
- {
6130
- var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
6131
- var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
6132
-
6133
- if ( emptyInit || bRetrieve )
6134
- {
6135
- return s.oInstance;
6136
- }
6137
- else if ( bDestroy )
6138
- {
6139
- s.oInstance.fnDestroy();
6140
- break;
6141
- }
6142
- else
6143
- {
6144
- _fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );
6145
- return;
6146
- }
6147
- }
6148
-
6149
- /* If the element we are initialising has the same ID as a table which was previously
6150
- * initialised, but the table nodes don't match (from before) then we destroy the old
6151
- * instance by simply deleting it. This is under the assumption that the table has been
6152
- * destroyed by other methods. Anyone using non-id selectors will need to do this manually
6153
- */
6154
- if ( s.sTableId == this.id )
6155
- {
6156
- allSettings.splice( i, 1 );
6157
- break;
6158
- }
6159
- }
6160
-
6161
- /* Ensure the table has an ID - required for accessibility */
6162
- if ( sId === null || sId === "" )
6163
- {
6164
- sId = "DataTables_Table_"+(DataTable.ext._unique++);
6165
- this.id = sId;
6166
- }
6167
-
6168
- /* Create the settings object for this table and set some of the default parameters */
6169
- var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
6170
- "sDestroyWidth": $this[0].style.width,
6171
- "sInstance": sId,
6172
- "sTableId": sId
6173
- } );
6174
- oSettings.nTable = this;
6175
- oSettings.oApi = _that.internal;
6176
- oSettings.oInit = oInit;
6177
-
6178
- allSettings.push( oSettings );
6179
-
6180
- // Need to add the instance after the instance after the settings object has been added
6181
- // to the settings array, so we can self reference the table instance if more than one
6182
- oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();
6183
-
6184
- // Backwards compatibility, before we apply all the defaults
6185
- _fnCompatOpts( oInit );
6186
-
6187
- if ( oInit.oLanguage )
6188
- {
6189
- _fnLanguageCompat( oInit.oLanguage );
6190
- }
6191
-
6192
- // If the length menu is given, but the init display length is not, use the length menu
6193
- if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
6194
- {
6195
- oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
6196
- oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
6197
- }
6198
-
6199
- // Apply the defaults and init options to make a single init object will all
6200
- // options defined from defaults and instance options.
6201
- oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
6202
-
6203
-
6204
- // Map the initialisation options onto the settings object
6205
- _fnMap( oSettings.oFeatures, oInit, [
6206
- "bPaginate",
6207
- "bLengthChange",
6208
- "bFilter",
6209
- "bSort",
6210
- "bSortMulti",
6211
- "bInfo",
6212
- "bProcessing",
6213
- "bAutoWidth",
6214
- "bSortClasses",
6215
- "bServerSide",
6216
- "bDeferRender"
6217
- ] );
6218
- _fnMap( oSettings, oInit, [
6219
- "asStripeClasses",
6220
- "ajax",
6221
- "fnServerData",
6222
- "fnFormatNumber",
6223
- "sServerMethod",
6224
- "aaSorting",
6225
- "aaSortingFixed",
6226
- "aLengthMenu",
6227
- "sPaginationType",
6228
- "sAjaxSource",
6229
- "sAjaxDataProp",
6230
- "iStateDuration",
6231
- "sDom",
6232
- "bSortCellsTop",
6233
- "iTabIndex",
6234
- "fnStateLoadCallback",
6235
- "fnStateSaveCallback",
6236
- "renderer",
6237
- "searchDelay",
6238
- "rowId",
6239
- [ "iCookieDuration", "iStateDuration" ], // backwards compat
6240
- [ "oSearch", "oPreviousSearch" ],
6241
- [ "aoSearchCols", "aoPreSearchCols" ],
6242
- [ "iDisplayLength", "_iDisplayLength" ],
6243
- [ "bJQueryUI", "bJUI" ]
6244
- ] );
6245
- _fnMap( oSettings.oScroll, oInit, [
6246
- [ "sScrollX", "sX" ],
6247
- [ "sScrollXInner", "sXInner" ],
6248
- [ "sScrollY", "sY" ],
6249
- [ "bScrollCollapse", "bCollapse" ]
6250
- ] );
6251
- _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
6252
-
6253
- /* Callback functions which are array driven */
6254
- _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
6255
- _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
6256
- _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
6257
- _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
6258
- _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
6259
- _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
6260
- _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
6261
- _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
6262
- _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
6263
- _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
6264
- _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
6265
-
6266
- oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId );
6267
-
6268
- /* Browser support detection */
6269
- _fnBrowserDetect( oSettings );
6270
-
6271
- var oClasses = oSettings.oClasses;
6272
-
6273
- // @todo Remove in 1.11
6274
- if ( oInit.bJQueryUI )
6275
- {
6276
- /* Use the JUI classes object for display. You could clone the oStdClasses object if
6277
- * you want to have multiple tables with multiple independent classes
6278
- */
6279
- $.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
6280
-
6281
- if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
6282
- {
6283
- /* Set the DOM to use a layout suitable for jQuery UI's theming */
6284
- oSettings.sDom = '<"H"lfr>t<"F"ip>';
6285
- }
6286
-
6287
- if ( ! oSettings.renderer ) {
6288
- oSettings.renderer = 'jqueryui';
6289
- }
6290
- else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
6291
- oSettings.renderer.header = 'jqueryui';
6292
- }
6293
- }
6294
- else
6295
- {
6296
- $.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
6297
- }
6298
- $this.addClass( oClasses.sTable );
6299
-
6300
-
6301
- if ( oSettings.iInitDisplayStart === undefined )
6302
- {
6303
- /* Display start point, taking into account the save saving */
6304
- oSettings.iInitDisplayStart = oInit.iDisplayStart;
6305
- oSettings._iDisplayStart = oInit.iDisplayStart;
6306
- }
6307
-
6308
- if ( oInit.iDeferLoading !== null )
6309
- {
6310
- oSettings.bDeferLoading = true;
6311
- var tmp = $.isArray( oInit.iDeferLoading );
6312
- oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
6313
- oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
6314
- }
6315
-
6316
- /* Language definitions */
6317
- var oLanguage = oSettings.oLanguage;
6318
- $.extend( true, oLanguage, oInit.oLanguage );
6319
-
6320
- if ( oLanguage.sUrl !== "" )
6321
- {
6322
- /* Get the language definitions from a file - because this Ajax call makes the language
6323
- * get async to the remainder of this function we use bInitHandedOff to indicate that
6324
- * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
6325
- */
6326
- $.ajax( {
6327
- dataType: 'json',
6328
- url: oLanguage.sUrl,
6329
- success: function ( json ) {
6330
- _fnLanguageCompat( json );
6331
- _fnCamelToHungarian( defaults.oLanguage, json );
6332
- $.extend( true, oLanguage, json );
6333
- _fnInitialise( oSettings );
6334
- },
6335
- error: function () {
6336
- // Error occurred loading language file, continue on as best we can
6337
- _fnInitialise( oSettings );
6338
- }
6339
- } );
6340
- bInitHandedOff = true;
6341
- }
6342
-
6343
- /*
6344
- * Stripes
6345
- */
6346
- if ( oInit.asStripeClasses === null )
6347
- {
6348
- oSettings.asStripeClasses =[
6349
- oClasses.sStripeOdd,
6350
- oClasses.sStripeEven
6351
- ];
6352
- }
6353
-
6354
- /* Remove row stripe classes if they are already on the table row */
6355
- var stripeClasses = oSettings.asStripeClasses;
6356
- var rowOne = $this.children('tbody').find('tr').eq(0);
6357
- if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
6358
- return rowOne.hasClass(el);
6359
- } ) ) !== -1 ) {
6360
- $('tbody tr', this).removeClass( stripeClasses.join(' ') );
6361
- oSettings.asDestroyStripes = stripeClasses.slice();
6362
- }
6363
-
6364
- /*
6365
- * Columns
6366
- * See if we should load columns automatically or use defined ones
6367
- */
6368
- var anThs = [];
6369
- var aoColumnsInit;
6370
- var nThead = this.getElementsByTagName('thead');
6371
- if ( nThead.length !== 0 )
6372
- {
6373
- _fnDetectHeader( oSettings.aoHeader, nThead[0] );
6374
- anThs = _fnGetUniqueThs( oSettings );
6375
- }
6376
-
6377
- /* If not given a column array, generate one with nulls */
6378
- if ( oInit.aoColumns === null )
6379
- {
6380
- aoColumnsInit = [];
6381
- for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
6382
- {
6383
- aoColumnsInit.push( null );
6384
- }
6385
- }
6386
- else
6387
- {
6388
- aoColumnsInit = oInit.aoColumns;
6389
- }
6390
-
6391
- /* Add the columns */
6392
- for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
6393
- {
6394
- _fnAddColumn( oSettings, anThs ? anThs[i] : null );
6395
- }
6396
-
6397
- /* Apply the column definitions */
6398
- _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
6399
- _fnColumnOptions( oSettings, iCol, oDef );
6400
- } );
6401
-
6402
- /* HTML5 attribute detection - build an mData object automatically if the
6403
- * attributes are found
6404
- */
6405
- if ( rowOne.length ) {
6406
- var a = function ( cell, name ) {
6407
- return cell.getAttribute( 'data-'+name ) !== null ? name : null;
6408
- };
6409
-
6410
- $( rowOne[0] ).children('th, td').each( function (i, cell) {
6411
- var col = oSettings.aoColumns[i];
6412
-
6413
- if ( col.mData === i ) {
6414
- var sort = a( cell, 'sort' ) || a( cell, 'order' );
6415
- var filter = a( cell, 'filter' ) || a( cell, 'search' );
6416
-
6417
- if ( sort !== null || filter !== null ) {
6418
- col.mData = {
6419
- _: i+'.display',
6420
- sort: sort !== null ? i+'.@data-'+sort : undefined,
6421
- type: sort !== null ? i+'.@data-'+sort : undefined,
6422
- filter: filter !== null ? i+'.@data-'+filter : undefined
6423
- };
6424
-
6425
- _fnColumnOptions( oSettings, i );
6426
- }
6427
- }
6428
- } );
6429
- }
6430
-
6431
- var features = oSettings.oFeatures;
6432
-
6433
- /* Must be done after everything which can be overridden by the state saving! */
6434
- if ( oInit.bStateSave )
6435
- {
6436
- features.bStateSave = true;
6437
- _fnLoadState( oSettings, oInit );
6438
- _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
6439
- }
6440
-
6441
-
6442
- /*
6443
- * Sorting
6444
- * @todo For modularisation (1.11) this needs to do into a sort start up handler
6445
- */
6446
-
6447
- // If aaSorting is not defined, then we use the first indicator in asSorting
6448
- // in case that has been altered, so the default sort reflects that option
6449
- if ( oInit.aaSorting === undefined )
6450
- {
6451
- var sorting = oSettings.aaSorting;
6452
- for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
6453
- {
6454
- sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
6455
- }
6456
- }
6457
-
6458
- /* Do a first pass on the sorting classes (allows any size changes to be taken into
6459
- * account, and also will apply sorting disabled classes if disabled
6460
- */
6461
- _fnSortingClasses( oSettings );
6462
-
6463
- if ( features.bSort )
6464
- {
6465
- _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
6466
- if ( oSettings.bSorted ) {
6467
- var aSort = _fnSortFlatten( oSettings );
6468
- var sortedColumns = {};
6469
-
6470
- $.each( aSort, function (i, val) {
6471
- sortedColumns[ val.src ] = val.dir;
6472
- } );
6473
-
6474
- _fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
6475
- _fnSortAria( oSettings );
6476
- }
6477
- } );
6478
- }
6479
-
6480
- _fnCallbackReg( oSettings, 'aoDrawCallback', function () {
6481
- if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
6482
- _fnSortingClasses( oSettings );
6483
- }
6484
- }, 'sc' );
6485
-
6486
-
6487
- /*
6488
- * Final init
6489
- * Cache the header, body and footer as required, creating them if needed
6490
- */
6491
-
6492
- // Work around for Webkit bug 83867 - store the caption-side before removing from doc
6493
- var captions = $this.children('caption').each( function () {
6494
- this._captionSide = $this.css('caption-side');
6495
- } );
6496
-
6497
- var thead = $this.children('thead');
6498
- if ( thead.length === 0 )
6499
- {
6500
- thead = $('<thead/>').appendTo(this);
6501
- }
6502
- oSettings.nTHead = thead[0];
6503
-
6504
- var tbody = $this.children('tbody');
6505
- if ( tbody.length === 0 )
6506
- {
6507
- tbody = $('<tbody/>').appendTo(this);
6508
- }
6509
- oSettings.nTBody = tbody[0];
6510
-
6511
- var tfoot = $this.children('tfoot');
6512
- if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
6513
- {
6514
- // If we are a scrolling table, and no footer has been given, then we need to create
6515
- // a tfoot element for the caption element to be appended to
6516
- tfoot = $('<tfoot/>').appendTo(this);
6517
- }
6518
-
6519
- if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
6520
- $this.addClass( oClasses.sNoFooter );
6521
- }
6522
- else if ( tfoot.length > 0 ) {
6523
- oSettings.nTFoot = tfoot[0];
6524
- _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
6525
- }
6526
-
6527
- /* Check if there is data passing into the constructor */
6528
- if ( oInit.aaData )
6529
- {
6530
- for ( i=0 ; i<oInit.aaData.length ; i++ )
6531
- {
6532
- _fnAddData( oSettings, oInit.aaData[ i ] );
6533
- }
6534
- }
6535
- else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
6536
- {
6537
- /* Grab the data from the page - only do this when deferred loading or no Ajax
6538
- * source since there is no point in reading the DOM data if we are then going
6539
- * to replace it with Ajax data
6540
- */
6541
- _fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
6542
- }
6543
-
6544
- /* Copy the data index array */
6545
- oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
6546
-
6547
- /* Initialisation complete - table can be drawn */
6548
- oSettings.bInitialised = true;
6549
-
6550
- /* Check if we need to initialise the table (it might not have been handed off to the
6551
- * language processor)
6552
- */
6553
- if ( bInitHandedOff === false )
6554
- {
6555
- _fnInitialise( oSettings );
6556
- }
6557
- } );
6558
- _that = null;
6559
- return this;
6560
- };
6561
-
6562
-
6563
-
6564
- /**
6565
- * Computed structure of the DataTables API, defined by the options passed to
6566
- * `DataTable.Api.register()` when building the API.
6567
- *
6568
- * The structure is built in order to speed creation and extension of the Api
6569
- * objects since the extensions are effectively pre-parsed.
6570
- *
6571
- * The array is an array of objects with the following structure, where this
6572
- * base array represents the Api prototype base:
6573
- *
6574
- * [
6575
- * {
6576
- * name: 'data' -- string - Property name
6577
- * val: function () {}, -- function - Api method (or undefined if just an object
6578
- * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
6579
- * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
6580
- * },
6581
- * {
6582
- * name: 'row'
6583
- * val: {},
6584
- * methodExt: [ ... ],
6585
- * propExt: [
6586
- * {
6587
- * name: 'data'
6588
- * val: function () {},
6589
- * methodExt: [ ... ],
6590
- * propExt: [ ... ]
6591
- * },
6592
- * ...
6593
- * ]
6594
- * }
6595
- * ]
6596
- *
6597
- * @type {Array}
6598
- * @ignore
6599
- */
6600
- var __apiStruct = [];
6601
-
6602
-
6603
- /**
6604
- * `Array.prototype` reference.
6605
- *
6606
- * @type object
6607
- * @ignore
6608
- */
6609
- var __arrayProto = Array.prototype;
6610
-
6611
-
6612
- /**
6613
- * Abstraction for `context` parameter of the `Api` constructor to allow it to
6614
- * take several different forms for ease of use.
6615
- *
6616
- * Each of the input parameter types will be converted to a DataTables settings
6617
- * object where possible.
6618
- *
6619
- * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
6620
- * of:
6621
- *
6622
- * * `string` - jQuery selector. Any DataTables' matching the given selector
6623
- * with be found and used.
6624
- * * `node` - `TABLE` node which has already been formed into a DataTable.
6625
- * * `jQuery` - A jQuery object of `TABLE` nodes.
6626
- * * `object` - DataTables settings object
6627
- * * `DataTables.Api` - API instance
6628
- * @return {array|null} Matching DataTables settings objects. `null` or
6629
- * `undefined` is returned if no matching DataTable is found.
6630
- * @ignore
6631
- */
6632
- var _toSettings = function ( mixed )
6633
- {
6634
- var idx, jq;
6635
- var settings = DataTable.settings;
6636
- var tables = $.map( settings, function (el, i) {
6637
- return el.nTable;
6638
- } );
6639
-
6640
- if ( ! mixed ) {
6641
- return [];
6642
- }
6643
- else if ( mixed.nTable && mixed.oApi ) {
6644
- // DataTables settings object
6645
- return [ mixed ];
6646
- }
6647
- else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
6648
- // Table node
6649
- idx = $.inArray( mixed, tables );
6650
- return idx !== -1 ? [ settings[idx] ] : null;
6651
- }
6652
- else if ( mixed && typeof mixed.settings === 'function' ) {
6653
- return mixed.settings().toArray();
6654
- }
6655
- else if ( typeof mixed === 'string' ) {
6656
- // jQuery selector
6657
- jq = $(mixed);
6658
- }
6659
- else if ( mixed instanceof $ ) {
6660
- // jQuery object (also DataTables instance)
6661
- jq = mixed;
6662
- }
6663
-
6664
- if ( jq ) {
6665
- return jq.map( function(i) {
6666
- idx = $.inArray( this, tables );
6667
- return idx !== -1 ? settings[idx] : null;
6668
- } ).toArray();
6669
- }
6670
- };
6671
-
6672
-
6673
- /**
6674
- * DataTables API class - used to control and interface with one or more
6675
- * DataTables enhanced tables.
6676
- *
6677
- * The API class is heavily based on jQuery, presenting a chainable interface
6678
- * that you can use to interact with tables. Each instance of the API class has
6679
- * a "context" - i.e. the tables that it will operate on. This could be a single
6680
- * table, all tables on a page or a sub-set thereof.
6681
- *
6682
- * Additionally the API is designed to allow you to easily work with the data in
6683
- * the tables, retrieving and manipulating it as required. This is done by
6684
- * presenting the API class as an array like interface. The contents of the
6685
- * array depend upon the actions requested by each method (for example
6686
- * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6687
- * return an array of objects or arrays depending upon your table's
6688
- * configuration). The API object has a number of array like methods (`push`,
6689
- * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6690
- * `unique` etc) to assist your working with the data held in a table.
6691
- *
6692
- * Most methods (those which return an Api instance) are chainable, which means
6693
- * the return from a method call also has all of the methods available that the
6694
- * top level object had. For example, these two calls are equivalent:
6695
- *
6696
- * // Not chained
6697
- * api.row.add( {...} );
6698
- * api.draw();
6699
- *
6700
- * // Chained
6701
- * api.row.add( {...} ).draw();
6702
- *
6703
- * @class DataTable.Api
6704
- * @param {array|object|string|jQuery} context DataTable identifier. This is
6705
- * used to define which DataTables enhanced tables this API will operate on.
6706
- * Can be one of:
6707
- *
6708
- * * `string` - jQuery selector. Any DataTables' matching the given selector
6709
- * with be found and used.
6710
- * * `node` - `TABLE` node which has already been formed into a DataTable.
6711
- * * `jQuery` - A jQuery object of `TABLE` nodes.
6712
- * * `object` - DataTables settings object
6713
- * @param {array} [data] Data to initialise the Api instance with.
6714
- *
6715
- * @example
6716
- * // Direct initialisation during DataTables construction
6717
- * var api = $('#example').DataTable();
6718
- *
6719
- * @example
6720
- * // Initialisation using a DataTables jQuery object
6721
- * var api = $('#example').dataTable().api();
6722
- *
6723
- * @example
6724
- * // Initialisation as a constructor
6725
- * var api = new $.fn.DataTable.Api( 'table.dataTable' );
6726
- */
6727
- _Api = function ( context, data )
6728
- {
6729
- if ( ! (this instanceof _Api) ) {
6730
- return new _Api( context, data );
6731
- }
6732
-
6733
- var settings = [];
6734
- var ctxSettings = function ( o ) {
6735
- var a = _toSettings( o );
6736
- if ( a ) {
6737
- settings = settings.concat( a );
6738
- }
6739
- };
6740
-
6741
- if ( $.isArray( context ) ) {
6742
- for ( var i=0, ien=context.length ; i<ien ; i++ ) {
6743
- ctxSettings( context[i] );
6744
- }
6745
- }
6746
- else {
6747
- ctxSettings( context );
6748
- }
6749
-
6750
- // Remove duplicates
6751
- this.context = _unique( settings );
6752
-
6753
- // Initial data
6754
- if ( data ) {
6755
- $.merge( this, data );
6756
- }
6757
-
6758
- // selector
6759
- this.selector = {
6760
- rows: null,
6761
- cols: null,
6762
- opts: null
6763
- };
6764
-
6765
- _Api.extend( this, this, __apiStruct );
6766
- };
6767
-
6768
- DataTable.Api = _Api;
6769
-
6770
- // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6771
- // isPlainObject.
6772
- $.extend( _Api.prototype, {
6773
- any: function ()
6774
- {
6775
- return this.count() !== 0;
6776
- },
6777
-
6778
-
6779
- concat: __arrayProto.concat,
6780
-
6781
-
6782
- context: [], // array of table settings objects
6783
-
6784
-
6785
- count: function ()
6786
- {
6787
- return this.flatten().length;
6788
- },
6789
-
6790
-
6791
- each: function ( fn )
6792
- {
6793
- for ( var i=0, ien=this.length ; i<ien; i++ ) {
6794
- fn.call( this, this[i], i, this );
6795
- }
6796
-
6797
- return this;
6798
- },
6799
-
6800
-
6801
- eq: function ( idx )
6802
- {
6803
- var ctx = this.context;
6804
-
6805
- return ctx.length > idx ?
6806
- new _Api( ctx[idx], this[idx] ) :
6807
- null;
6808
- },
6809
-
6810
-
6811
- filter: function ( fn )
6812
- {
6813
- var a = [];
6814
-
6815
- if ( __arrayProto.filter ) {
6816
- a = __arrayProto.filter.call( this, fn, this );
6817
- }
6818
- else {
6819
- // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6820
- for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6821
- if ( fn.call( this, this[i], i, this ) ) {
6822
- a.push( this[i] );
6823
- }
6824
- }
6825
- }
6826
-
6827
- return new _Api( this.context, a );
6828
- },
6829
-
6830
-
6831
- flatten: function ()
6832
- {
6833
- var a = [];
6834
- return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
6835
- },
6836
-
6837
-
6838
- join: __arrayProto.join,
6839
-
6840
-
6841
- indexOf: __arrayProto.indexOf || function (obj, start)
6842
- {
6843
- for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
6844
- if ( this[i] === obj ) {
6845
- return i;
6846
- }
6847
- }
6848
- return -1;
6849
- },
6850
-
6851
- iterator: function ( flatten, type, fn, alwaysNew ) {
6852
- var
6853
- a = [], ret,
6854
- i, ien, j, jen,
6855
- context = this.context,
6856
- rows, items, item,
6857
- selector = this.selector;
6858
-
6859
- // Argument shifting
6860
- if ( typeof flatten === 'string' ) {
6861
- alwaysNew = fn;
6862
- fn = type;
6863
- type = flatten;
6864
- flatten = false;
6865
- }
6866
-
6867
- for ( i=0, ien=context.length ; i<ien ; i++ ) {
6868
- var apiInst = new _Api( context[i] );
6869
-
6870
- if ( type === 'table' ) {
6871
- ret = fn.call( apiInst, context[i], i );
6872
-
6873
- if ( ret !== undefined ) {
6874
- a.push( ret );
6875
- }
6876
- }
6877
- else if ( type === 'columns' || type === 'rows' ) {
6878
- // this has same length as context - one entry for each table
6879
- ret = fn.call( apiInst, context[i], this[i], i );
6880
-
6881
- if ( ret !== undefined ) {
6882
- a.push( ret );
6883
- }
6884
- }
6885
- else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
6886
- // columns and rows share the same structure.
6887
- // 'this' is an array of column indexes for each context
6888
- items = this[i];
6889
-
6890
- if ( type === 'column-rows' ) {
6891
- rows = _selector_row_indexes( context[i], selector.opts );
6892
- }
6893
-
6894
- for ( j=0, jen=items.length ; j<jen ; j++ ) {
6895
- item = items[j];
6896
-
6897
- if ( type === 'cell' ) {
6898
- ret = fn.call( apiInst, context[i], item.row, item.column, i, j );
6899
- }
6900
- else {
6901
- ret = fn.call( apiInst, context[i], item, i, j, rows );
6902
- }
6903
-
6904
- if ( ret !== undefined ) {
6905
- a.push( ret );
6906
- }
6907
- }
6908
- }
6909
- }
6910
-
6911
- if ( a.length || alwaysNew ) {
6912
- var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
6913
- var apiSelector = api.selector;
6914
- apiSelector.rows = selector.rows;
6915
- apiSelector.cols = selector.cols;
6916
- apiSelector.opts = selector.opts;
6917
- return api;
6918
- }
6919
- return this;
6920
- },
6921
-
6922
-
6923
- lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
6924
- {
6925
- // Bit cheeky...
6926
- return this.indexOf.apply( this.toArray.reverse(), arguments );
6927
- },
6928
-
6929
-
6930
- length: 0,
6931
-
6932
-
6933
- map: function ( fn )
6934
- {
6935
- var a = [];
6936
-
6937
- if ( __arrayProto.map ) {
6938
- a = __arrayProto.map.call( this, fn, this );
6939
- }
6940
- else {
6941
- // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6942
- for ( var i=0, ien=this.length ; i<ien ; i++ ) {
6943
- a.push( fn.call( this, this[i], i ) );
6944
- }
6945
- }
6946
-
6947
- return new _Api( this.context, a );
6948
- },
6949
-
6950
-
6951
- pluck: function ( prop )
6952
- {
6953
- return this.map( function ( el ) {
6954
- return el[ prop ];
6955
- } );
6956
- },
6957
-
6958
- pop: __arrayProto.pop,
6959
-
6960
-
6961
- push: __arrayProto.push,
6962
-
6963
-
6964
- // Does not return an API instance
6965
- reduce: __arrayProto.reduce || function ( fn, init )
6966
- {
6967
- return _fnReduce( this, fn, init, 0, this.length, 1 );
6968
- },
6969
-
6970
-
6971
- reduceRight: __arrayProto.reduceRight || function ( fn, init )
6972
- {
6973
- return _fnReduce( this, fn, init, this.length-1, -1, -1 );
6974
- },
6975
-
6976
-
6977
- reverse: __arrayProto.reverse,
6978
-
6979
-
6980
- // Object with rows, columns and opts
6981
- selector: null,
6982
-
6983
-
6984
- shift: __arrayProto.shift,
6985
-
6986
-
6987
- sort: __arrayProto.sort, // ? name - order?
6988
-
6989
-
6990
- splice: __arrayProto.splice,
6991
-
6992
-
6993
- toArray: function ()
6994
- {
6995
- return __arrayProto.slice.call( this );
6996
- },
6997
-
6998
-
6999
- to$: function ()
7000
- {
7001
- return $( this );
7002
- },
7003
-
7004
-
7005
- toJQuery: function ()
7006
- {
7007
- return $( this );
7008
- },
7009
-
7010
-
7011
- unique: function ()
7012
- {
7013
- return new _Api( this.context, _unique(this) );
7014
- },
7015
-
7016
-
7017
- unshift: __arrayProto.unshift
7018
- } );
7019
-
7020
-
7021
- _Api.extend = function ( scope, obj, ext )
7022
- {
7023
- // Only extend API instances and static properties of the API
7024
- if ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
7025
- return;
7026
- }
7027
-
7028
- var
7029
- i, ien,
7030
- j, jen,
7031
- struct, inner,
7032
- methodScoping = function ( scope, fn, struc ) {
7033
- return function () {
7034
- var ret = fn.apply( scope, arguments );
7035
-
7036
- // Method extension
7037
- _Api.extend( ret, ret, struc.methodExt );
7038
- return ret;
7039
- };
7040
- };
7041
-
7042
- for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7043
- struct = ext[i];
7044
-
7045
- // Value
7046
- obj[ struct.name ] = typeof struct.val === 'function' ?
7047
- methodScoping( scope, struct.val, struct ) :
7048
- $.isPlainObject( struct.val ) ?
7049
- {} :
7050
- struct.val;
7051
-
7052
- obj[ struct.name ].__dt_wrapper = true;
7053
-
7054
- // Property extension
7055
- _Api.extend( scope, obj[ struct.name ], struct.propExt );
7056
- }
7057
- };
7058
-
7059
-
7060
- // @todo - Is there need for an augment function?
7061
- // _Api.augment = function ( inst, name )
7062
- // {
7063
- // // Find src object in the structure from the name
7064
- // var parts = name.split('.');
7065
-
7066
- // _Api.extend( inst, obj );
7067
- // };
7068
-
7069
-
7070
- // [
7071
- // {
7072
- // name: 'data' -- string - Property name
7073
- // val: function () {}, -- function - Api method (or undefined if just an object
7074
- // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
7075
- // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
7076
- // },
7077
- // {
7078
- // name: 'row'
7079
- // val: {},
7080
- // methodExt: [ ... ],
7081
- // propExt: [
7082
- // {
7083
- // name: 'data'
7084
- // val: function () {},
7085
- // methodExt: [ ... ],
7086
- // propExt: [ ... ]
7087
- // },
7088
- // ...
7089
- // ]
7090
- // }
7091
- // ]
7092
-
7093
- _Api.register = _api_register = function ( name, val )
7094
- {
7095
- if ( $.isArray( name ) ) {
7096
- for ( var j=0, jen=name.length ; j<jen ; j++ ) {
7097
- _Api.register( name[j], val );
7098
- }
7099
- return;
7100
- }
7101
-
7102
- var
7103
- i, ien,
7104
- heir = name.split('.'),
7105
- struct = __apiStruct,
7106
- key, method;
7107
-
7108
- var find = function ( src, name ) {
7109
- for ( var i=0, ien=src.length ; i<ien ; i++ ) {
7110
- if ( src[i].name === name ) {
7111
- return src[i];
7112
- }
7113
- }
7114
- return null;
7115
- };
7116
-
7117
- for ( i=0, ien=heir.length ; i<ien ; i++ ) {
7118
- method = heir[i].indexOf('()') !== -1;
7119
- key = method ?
7120
- heir[i].replace('()', '') :
7121
- heir[i];
7122
-
7123
- var src = find( struct, key );
7124
- if ( ! src ) {
7125
- src = {
7126
- name: key,
7127
- val: {},
7128
- methodExt: [],
7129
- propExt: []
7130
- };
7131
- struct.push( src );
7132
- }
7133
-
7134
- if ( i === ien-1 ) {
7135
- src.val = val;
7136
- }
7137
- else {
7138
- struct = method ?
7139
- src.methodExt :
7140
- src.propExt;
7141
- }
7142
- }
7143
- };
7144
-
7145
-
7146
- _Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
7147
- _Api.register( pluralName, val );
7148
-
7149
- _Api.register( singularName, function () {
7150
- var ret = val.apply( this, arguments );
7151
-
7152
- if ( ret === this ) {
7153
- // Returned item is the API instance that was passed in, return it
7154
- return this;
7155
- }
7156
- else if ( ret instanceof _Api ) {
7157
- // New API instance returned, want the value from the first item
7158
- // in the returned array for the singular result.
7159
- return ret.length ?
7160
- $.isArray( ret[0] ) ?
7161
- new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
7162
- ret[0] :
7163
- undefined;
7164
- }
7165
-
7166
- // Non-API return - just fire it back
7167
- return ret;
7168
- } );
7169
- };
7170
-
7171
-
7172
- /**
7173
- * Selector for HTML tables. Apply the given selector to the give array of
7174
- * DataTables settings objects.
7175
- *
7176
- * @param {string|integer} [selector] jQuery selector string or integer
7177
- * @param {array} Array of DataTables settings objects to be filtered
7178
- * @return {array}
7179
- * @ignore
7180
- */
7181
- var __table_selector = function ( selector, a )
7182
- {
7183
- // Integer is used to pick out a table by index
7184
- if ( typeof selector === 'number' ) {
7185
- return [ a[ selector ] ];
7186
- }
7187
-
7188
- // Perform a jQuery selector on the table nodes
7189
- var nodes = $.map( a, function (el, i) {
7190
- return el.nTable;
7191
- } );
7192
-
7193
- return $(nodes)
7194
- .filter( selector )
7195
- .map( function (i) {
7196
- // Need to translate back from the table node to the settings
7197
- var idx = $.inArray( this, nodes );
7198
- return a[ idx ];
7199
- } )
7200
- .toArray();
7201
- };
7202
-
7203
-
7204
-
7205
- /**
7206
- * Context selector for the API's context (i.e. the tables the API instance
7207
- * refers to.
7208
- *
7209
- * @name DataTable.Api#tables
7210
- * @param {string|integer} [selector] Selector to pick which tables the iterator
7211
- * should operate on. If not given, all tables in the current context are
7212
- * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7213
- * select multiple tables or as an integer to select a single table.
7214
- * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7215
- */
7216
- _api_register( 'tables()', function ( selector ) {
7217
- // A new instance is created if there was a selector specified
7218
- return selector ?
7219
- new _Api( __table_selector( selector, this.context ) ) :
7220
- this;
7221
- } );
7222
-
7223
-
7224
- _api_register( 'table()', function ( selector ) {
7225
- var tables = this.tables( selector );
7226
- var ctx = tables.context;
7227
-
7228
- // Truncate to the first matched table
7229
- return ctx.length ?
7230
- new _Api( ctx[0] ) :
7231
- tables;
7232
- } );
7233
-
7234
-
7235
- _api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
7236
- return this.iterator( 'table', function ( ctx ) {
7237
- return ctx.nTable;
7238
- }, 1 );
7239
- } );
7240
-
7241
-
7242
- _api_registerPlural( 'tables().body()', 'table().body()' , function () {
7243
- return this.iterator( 'table', function ( ctx ) {
7244
- return ctx.nTBody;
7245
- }, 1 );
7246
- } );
7247
-
7248
-
7249
- _api_registerPlural( 'tables().header()', 'table().header()' , function () {
7250
- return this.iterator( 'table', function ( ctx ) {
7251
- return ctx.nTHead;
7252
- }, 1 );
7253
- } );
7254
-
7255
-
7256
- _api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
7257
- return this.iterator( 'table', function ( ctx ) {
7258
- return ctx.nTFoot;
7259
- }, 1 );
7260
- } );
7261
-
7262
-
7263
- _api_registerPlural( 'tables().containers()', 'table().container()' , function () {
7264
- return this.iterator( 'table', function ( ctx ) {
7265
- return ctx.nTableWrapper;
7266
- }, 1 );
7267
- } );
7268
-
7269
-
7270
-
7271
- /**
7272
- * Redraw the tables in the current context.
7273
- */
7274
- _api_register( 'draw()', function ( paging ) {
7275
- return this.iterator( 'table', function ( settings ) {
7276
- if ( paging === 'page' ) {
7277
- _fnDraw( settings );
7278
- }
7279
- else {
7280
- if ( typeof paging === 'string' ) {
7281
- paging = paging === 'full-hold' ?
7282
- false :
7283
- true;
7284
- }
7285
-
7286
- _fnReDraw( settings, paging===false );
7287
- }
7288
- } );
7289
- } );
7290
-
7291
-
7292
-
7293
- /**
7294
- * Get the current page index.
7295
- *
7296
- * @return {integer} Current page index (zero based)
7297
- *//**
7298
- * Set the current page.
7299
- *
7300
- * Note that if you attempt to show a page which does not exist, DataTables will
7301
- * not throw an error, but rather reset the paging.
7302
- *
7303
- * @param {integer|string} action The paging action to take. This can be one of:
7304
- * * `integer` - The page index to jump to
7305
- * * `string` - An action to take:
7306
- * * `first` - Jump to first page.
7307
- * * `next` - Jump to the next page
7308
- * * `previous` - Jump to previous page
7309
- * * `last` - Jump to the last page.
7310
- * @returns {DataTables.Api} this
7311
- */
7312
- _api_register( 'page()', function ( action ) {
7313
- if ( action === undefined ) {
7314
- return this.page.info().page; // not an expensive call
7315
- }
7316
-
7317
- // else, have an action to take on all tables
7318
- return this.iterator( 'table', function ( settings ) {
7319
- _fnPageChange( settings, action );
7320
- } );
7321
- } );
7322
-
7323
-
7324
- /**
7325
- * Paging information for the first table in the current context.
7326
- *
7327
- * If you require paging information for another table, use the `table()` method
7328
- * with a suitable selector.
7329
- *
7330
- * @return {object} Object with the following properties set:
7331
- * * `page` - Current page index (zero based - i.e. the first page is `0`)
7332
- * * `pages` - Total number of pages
7333
- * * `start` - Display index for the first record shown on the current page
7334
- * * `end` - Display index for the last record shown on the current page
7335
- * * `length` - Display length (number of records). Note that generally `start
7336
- * + length = end`, but this is not always true, for example if there are
7337
- * only 2 records to show on the final page, with a length of 10.
7338
- * * `recordsTotal` - Full data set length
7339
- * * `recordsDisplay` - Data set length once the current filtering criterion
7340
- * are applied.
7341
- */
7342
- _api_register( 'page.info()', function ( action ) {
7343
- if ( this.context.length === 0 ) {
7344
- return undefined;
7345
- }
7346
-
7347
- var
7348
- settings = this.context[0],
7349
- start = settings._iDisplayStart,
7350
- len = settings._iDisplayLength,
7351
- visRecords = settings.fnRecordsDisplay(),
7352
- all = len === -1;
7353
-
7354
- return {
7355
- "page": all ? 0 : Math.floor( start / len ),
7356
- "pages": all ? 1 : Math.ceil( visRecords / len ),
7357
- "start": start,
7358
- "end": settings.fnDisplayEnd(),
7359
- "length": len,
7360
- "recordsTotal": settings.fnRecordsTotal(),
7361
- "recordsDisplay": visRecords,
7362
- "serverSide": _fnDataSource( settings ) === 'ssp'
7363
- };
7364
- } );
7365
-
7366
-
7367
- /**
7368
- * Get the current page length.
7369
- *
7370
- * @return {integer} Current page length. Note `-1` indicates that all records
7371
- * are to be shown.
7372
- *//**
7373
- * Set the current page length.
7374
- *
7375
- * @param {integer} Page length to set. Use `-1` to show all records.
7376
- * @returns {DataTables.Api} this
7377
- */
7378
- _api_register( 'page.len()', function ( len ) {
7379
- // Note that we can't call this function 'length()' because `length`
7380
- // is a Javascript property of functions which defines how many arguments
7381
- // the function expects.
7382
- if ( len === undefined ) {
7383
- return this.context.length !== 0 ?
7384
- this.context[0]._iDisplayLength :
7385
- undefined;
7386
- }
7387
-
7388
- // else, set the page length
7389
- return this.iterator( 'table', function ( settings ) {
7390
- _fnLengthChange( settings, len );
7391
- } );
7392
- } );
7393
-
7394
-
7395
-
7396
- var __reload = function ( settings, holdPosition, callback ) {
7397
- // Use the draw event to trigger a callback
7398
- if ( callback ) {
7399
- var api = new _Api( settings );
7400
-
7401
- api.one( 'draw', function () {
7402
- callback( api.ajax.json() );
7403
- } );
7404
- }
7405
-
7406
- if ( _fnDataSource( settings ) == 'ssp' ) {
7407
- _fnReDraw( settings, holdPosition );
7408
- }
7409
- else {
7410
- _fnProcessingDisplay( settings, true );
7411
-
7412
- // Cancel an existing request
7413
- var xhr = settings.jqXHR;
7414
- if ( xhr && xhr.readyState !== 4 ) {
7415
- xhr.abort();
7416
- }
7417
-
7418
- // Trigger xhr
7419
- _fnBuildAjax( settings, [], function( json ) {
7420
- _fnClearTable( settings );
7421
-
7422
- var data = _fnAjaxDataSrc( settings, json );
7423
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7424
- _fnAddData( settings, data[i] );
7425
- }
7426
-
7427
- _fnReDraw( settings, holdPosition );
7428
- _fnProcessingDisplay( settings, false );
7429
- } );
7430
- }
7431
- };
7432
-
7433
-
7434
- /**
7435
- * Get the JSON response from the last Ajax request that DataTables made to the
7436
- * server. Note that this returns the JSON from the first table in the current
7437
- * context.
7438
- *
7439
- * @return {object} JSON received from the server.
7440
- */
7441
- _api_register( 'ajax.json()', function () {
7442
- var ctx = this.context;
7443
-
7444
- if ( ctx.length > 0 ) {
7445
- return ctx[0].json;
7446
- }
7447
-
7448
- // else return undefined;
7449
- } );
7450
-
7451
-
7452
- /**
7453
- * Get the data submitted in the last Ajax request
7454
- */
7455
- _api_register( 'ajax.params()', function () {
7456
- var ctx = this.context;
7457
-
7458
- if ( ctx.length > 0 ) {
7459
- return ctx[0].oAjaxData;
7460
- }
7461
-
7462
- // else return undefined;
7463
- } );
7464
-
7465
-
7466
- /**
7467
- * Reload tables from the Ajax data source. Note that this function will
7468
- * automatically re-draw the table when the remote data has been loaded.
7469
- *
7470
- * @param {boolean} [reset=true] Reset (default) or hold the current paging
7471
- * position. A full re-sort and re-filter is performed when this method is
7472
- * called, which is why the pagination reset is the default action.
7473
- * @returns {DataTables.Api} this
7474
- */
7475
- _api_register( 'ajax.reload()', function ( callback, resetPaging ) {
7476
- return this.iterator( 'table', function (settings) {
7477
- __reload( settings, resetPaging===false, callback );
7478
- } );
7479
- } );
7480
-
7481
-
7482
- /**
7483
- * Get the current Ajax URL. Note that this returns the URL from the first
7484
- * table in the current context.
7485
- *
7486
- * @return {string} Current Ajax source URL
7487
- *//**
7488
- * Set the Ajax URL. Note that this will set the URL for all tables in the
7489
- * current context.
7490
- *
7491
- * @param {string} url URL to set.
7492
- * @returns {DataTables.Api} this
7493
- */
7494
- _api_register( 'ajax.url()', function ( url ) {
7495
- var ctx = this.context;
7496
-
7497
- if ( url === undefined ) {
7498
- // get
7499
- if ( ctx.length === 0 ) {
7500
- return undefined;
7501
- }
7502
- ctx = ctx[0];
7503
-
7504
- return ctx.ajax ?
7505
- $.isPlainObject( ctx.ajax ) ?
7506
- ctx.ajax.url :
7507
- ctx.ajax :
7508
- ctx.sAjaxSource;
7509
- }
7510
-
7511
- // set
7512
- return this.iterator( 'table', function ( settings ) {
7513
- if ( $.isPlainObject( settings.ajax ) ) {
7514
- settings.ajax.url = url;
7515
- }
7516
- else {
7517
- settings.ajax = url;
7518
- }
7519
- // No need to consider sAjaxSource here since DataTables gives priority
7520
- // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7521
- // value of `sAjaxSource` redundant.
7522
- } );
7523
- } );
7524
-
7525
-
7526
- /**
7527
- * Load data from the newly set Ajax URL. Note that this method is only
7528
- * available when `ajax.url()` is used to set a URL. Additionally, this method
7529
- * has the same effect as calling `ajax.reload()` but is provided for
7530
- * convenience when setting a new URL. Like `ajax.reload()` it will
7531
- * automatically redraw the table once the remote data has been loaded.
7532
- *
7533
- * @returns {DataTables.Api} this
7534
- */
7535
- _api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
7536
- // Same as a reload, but makes sense to present it for easy access after a
7537
- // url change
7538
- return this.iterator( 'table', function ( ctx ) {
7539
- __reload( ctx, resetPaging===false, callback );
7540
- } );
7541
- } );
7542
-
7543
-
7544
-
7545
-
7546
- var _selector_run = function ( type, selector, selectFn, settings, opts )
7547
- {
7548
- var
7549
- out = [], res,
7550
- a, i, ien, j, jen,
7551
- selectorType = typeof selector;
7552
-
7553
- // Can't just check for isArray here, as an API or jQuery instance might be
7554
- // given with their array like look
7555
- if ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {
7556
- selector = [ selector ];
7557
- }
7558
-
7559
- for ( i=0, ien=selector.length ; i<ien ; i++ ) {
7560
- a = selector[i] && selector[i].split ?
7561
- selector[i].split(',') :
7562
- [ selector[i] ];
7563
-
7564
- for ( j=0, jen=a.length ; j<jen ; j++ ) {
7565
- res = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
7566
-
7567
- if ( res && res.length ) {
7568
- out = out.concat( res );
7569
- }
7570
- }
7571
- }
7572
-
7573
- // selector extensions
7574
- var ext = _ext.selector[ type ];
7575
- if ( ext.length ) {
7576
- for ( i=0, ien=ext.length ; i<ien ; i++ ) {
7577
- out = ext[i]( settings, opts, out );
7578
- }
7579
- }
7580
-
7581
- return _unique( out );
7582
- };
7583
-
7584
-
7585
- var _selector_opts = function ( opts )
7586
- {
7587
- if ( ! opts ) {
7588
- opts = {};
7589
- }
7590
-
7591
- // Backwards compatibility for 1.9- which used the terminology filter rather
7592
- // than search
7593
- if ( opts.filter && opts.search === undefined ) {
7594
- opts.search = opts.filter;
7595
- }
7596
-
7597
- return $.extend( {
7598
- search: 'none',
7599
- order: 'current',
7600
- page: 'all'
7601
- }, opts );
7602
- };
7603
-
7604
-
7605
- var _selector_first = function ( inst )
7606
- {
7607
- // Reduce the API instance to the first item found
7608
- for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
7609
- if ( inst[i].length > 0 ) {
7610
- // Assign the first element to the first item in the instance
7611
- // and truncate the instance and context
7612
- inst[0] = inst[i];
7613
- inst[0].length = 1;
7614
- inst.length = 1;
7615
- inst.context = [ inst.context[i] ];
7616
-
7617
- return inst;
7618
- }
7619
- }
7620
-
7621
- // Not found - return an empty instance
7622
- inst.length = 0;
7623
- return inst;
7624
- };
7625
-
7626
-
7627
- var _selector_row_indexes = function ( settings, opts )
7628
- {
7629
- var
7630
- i, ien, tmp, a=[],
7631
- displayFiltered = settings.aiDisplay,
7632
- displayMaster = settings.aiDisplayMaster;
7633
-
7634
- var
7635
- search = opts.search, // none, applied, removed
7636
- order = opts.order, // applied, current, index (original - compatibility with 1.9)
7637
- page = opts.page; // all, current
7638
-
7639
- if ( _fnDataSource( settings ) == 'ssp' ) {
7640
- // In server-side processing mode, most options are irrelevant since
7641
- // rows not shown don't exist and the index order is the applied order
7642
- // Removed is a special case - for consistency just return an empty
7643
- // array
7644
- return search === 'removed' ?
7645
- [] :
7646
- _range( 0, displayMaster.length );
7647
- }
7648
- else if ( page == 'current' ) {
7649
- // Current page implies that order=current and fitler=applied, since it is
7650
- // fairly senseless otherwise, regardless of what order and search actually
7651
- // are
7652
- for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
7653
- a.push( displayFiltered[i] );
7654
- }
7655
- }
7656
- else if ( order == 'current' || order == 'applied' ) {
7657
- a = search == 'none' ?
7658
- displayMaster.slice() : // no search
7659
- search == 'applied' ?
7660
- displayFiltered.slice() : // applied search
7661
- $.map( displayMaster, function (el, i) { // removed search
7662
- return $.inArray( el, displayFiltered ) === -1 ? el : null;
7663
- } );
7664
- }
7665
- else if ( order == 'index' || order == 'original' ) {
7666
- for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7667
- if ( search == 'none' ) {
7668
- a.push( i );
7669
- }
7670
- else { // applied | removed
7671
- tmp = $.inArray( i, displayFiltered );
7672
-
7673
- if ((tmp === -1 && search == 'removed') ||
7674
- (tmp >= 0 && search == 'applied') )
7675
- {
7676
- a.push( i );
7677
- }
7678
- }
7679
- }
7680
- }
7681
-
7682
- return a;
7683
- };
7684
-
7685
-
7686
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7687
- * Rows
7688
- *
7689
- * {} - no selector - use all available rows
7690
- * {integer} - row aoData index
7691
- * {node} - TR node
7692
- * {string} - jQuery selector to apply to the TR elements
7693
- * {array} - jQuery array of nodes, or simply an array of TR nodes
7694
- *
7695
- */
7696
-
7697
-
7698
- var __row_selector = function ( settings, selector, opts )
7699
- {
7700
- var run = function ( sel ) {
7701
- var selInt = _intVal( sel );
7702
- var i, ien;
7703
-
7704
- // Short cut - selector is a number and no options provided (default is
7705
- // all records, so no need to check if the index is in there, since it
7706
- // must be - dev error if the index doesn't exist).
7707
- if ( selInt !== null && ! opts ) {
7708
- return [ selInt ];
7709
- }
7710
-
7711
- var rows = _selector_row_indexes( settings, opts );
7712
-
7713
- if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
7714
- // Selector - integer
7715
- return [ selInt ];
7716
- }
7717
- else if ( ! sel ) {
7718
- // Selector - none
7719
- return rows;
7720
- }
7721
-
7722
- // Selector - function
7723
- if ( typeof sel === 'function' ) {
7724
- return $.map( rows, function (idx) {
7725
- var row = settings.aoData[ idx ];
7726
- return sel( idx, row._aData, row.nTr ) ? idx : null;
7727
- } );
7728
- }
7729
-
7730
- // Get nodes in the order from the `rows` array with null values removed
7731
- var nodes = _removeEmpty(
7732
- _pluck_order( settings.aoData, rows, 'nTr' )
7733
- );
7734
-
7735
- // Selector - node
7736
- if ( sel.nodeName ) {
7737
- if ( $.inArray( sel, nodes ) !== -1 ) {
7738
- return [ sel._DT_RowIndex ]; // sel is a TR node that is in the table
7739
- // and DataTables adds a prop for fast lookup
7740
- }
7741
- }
7742
-
7743
- // ID selector. Want to always be able to select rows by id, regardless
7744
- // of if the tr element has been created or not, so can't rely upon
7745
- // jQuery here - hence a custom implementation. This does not match
7746
- // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7747
- // but to select it using a CSS selector engine (like Sizzle or
7748
- // querySelect) it would need to need to be escaped for some characters.
7749
- // DataTables simplifies this for row selectors since you can select
7750
- // only a row. A # indicates an id any anything that follows is the id -
7751
- // unescaped.
7752
- if ( typeof sel === 'string' && sel.charAt(0) === '#' ) {
7753
- // get row index from id
7754
- var rowObj = settings.aIds[ sel.replace( /^#/, '' ) ];
7755
- if ( rowObj !== undefined ) {
7756
- return [ rowObj.idx ];
7757
- }
7758
-
7759
- // need to fall through to jQuery in case there is DOM id that
7760
- // matches
7761
- }
7762
-
7763
- // Selector - jQuery selector string, array of nodes or jQuery object/
7764
- // As jQuery's .filter() allows jQuery objects to be passed in filter,
7765
- // it also allows arrays, so this will cope with all three options
7766
- return $(nodes)
7767
- .filter( sel )
7768
- .map( function () {
7769
- return this._DT_RowIndex;
7770
- } )
7771
- .toArray();
7772
- };
7773
-
7774
- return _selector_run( 'row', selector, run, settings, opts );
7775
- };
7776
-
7777
-
7778
- _api_register( 'rows()', function ( selector, opts ) {
7779
- // argument shifting
7780
- if ( selector === undefined ) {
7781
- selector = '';
7782
- }
7783
- else if ( $.isPlainObject( selector ) ) {
7784
- opts = selector;
7785
- selector = '';
7786
- }
7787
-
7788
- opts = _selector_opts( opts );
7789
-
7790
- var inst = this.iterator( 'table', function ( settings ) {
7791
- return __row_selector( settings, selector, opts );
7792
- }, 1 );
7793
-
7794
- // Want argument shifting here and in __row_selector?
7795
- inst.selector.rows = selector;
7796
- inst.selector.opts = opts;
7797
-
7798
- return inst;
7799
- } );
7800
-
7801
- _api_register( 'rows().nodes()', function () {
7802
- return this.iterator( 'row', function ( settings, row ) {
7803
- return settings.aoData[ row ].nTr || undefined;
7804
- }, 1 );
7805
- } );
7806
-
7807
- _api_register( 'rows().data()', function () {
7808
- return this.iterator( true, 'rows', function ( settings, rows ) {
7809
- return _pluck_order( settings.aoData, rows, '_aData' );
7810
- }, 1 );
7811
- } );
7812
-
7813
- _api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
7814
- return this.iterator( 'row', function ( settings, row ) {
7815
- var r = settings.aoData[ row ];
7816
- return type === 'search' ? r._aFilterData : r._aSortData;
7817
- }, 1 );
7818
- } );
7819
-
7820
- _api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
7821
- return this.iterator( 'row', function ( settings, row ) {
7822
- _fnInvalidate( settings, row, src );
7823
- } );
7824
- } );
7825
-
7826
- _api_registerPlural( 'rows().indexes()', 'row().index()', function () {
7827
- return this.iterator( 'row', function ( settings, row ) {
7828
- return row;
7829
- }, 1 );
7830
- } );
7831
-
7832
- _api_registerPlural( 'rows().ids()', 'row().id()', function ( hash ) {
7833
- var a = [];
7834
- var context = this.context;
7835
-
7836
- // `iterator` will drop undefined values, but in this case we want them
7837
- for ( var i=0, ien=context.length ; i<ien ; i++ ) {
7838
- for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
7839
- var id = context[i].rowIdFn( context[i].aoData[ this[i][j] ]._aData );
7840
- a.push( (hash === true ? '#' : '' )+ id );
7841
- }
7842
- }
7843
-
7844
- return new _Api( context, a );
7845
- } );
7846
-
7847
- _api_registerPlural( 'rows().remove()', 'row().remove()', function () {
7848
- var that = this;
7849
-
7850
- this.iterator( 'row', function ( settings, row, thatIdx ) {
7851
- var data = settings.aoData;
7852
- var rowData = data[ row ];
7853
-
7854
- data.splice( row, 1 );
7855
-
7856
- // Update the _DT_RowIndex parameter on all rows in the table
7857
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
7858
- if ( data[i].nTr !== null ) {
7859
- data[i].nTr._DT_RowIndex = i;
7860
- }
7861
- }
7862
-
7863
- // Delete from the display arrays
7864
- _fnDeleteIndex( settings.aiDisplayMaster, row );
7865
- _fnDeleteIndex( settings.aiDisplay, row );
7866
- _fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
7867
-
7868
- // Check for an 'overflow' they case for displaying the table
7869
- _fnLengthOverflow( settings );
7870
-
7871
- // Remove the row's ID reference if there is one
7872
- var id = settings.rowIdFn( rowData._aData );
7873
- if ( id !== undefined ) {
7874
- delete settings.aIds[ id ];
7875
- }
7876
- } );
7877
-
7878
- this.iterator( 'table', function ( settings ) {
7879
- for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
7880
- settings.aoData[i].idx = i;
7881
- }
7882
- } );
7883
-
7884
- return this;
7885
- } );
7886
-
7887
-
7888
- _api_register( 'rows.add()', function ( rows ) {
7889
- var newRows = this.iterator( 'table', function ( settings ) {
7890
- var row, i, ien;
7891
- var out = [];
7892
-
7893
- for ( i=0, ien=rows.length ; i<ien ; i++ ) {
7894
- row = rows[i];
7895
-
7896
- if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
7897
- out.push( _fnAddTr( settings, row )[0] );
7898
- }
7899
- else {
7900
- out.push( _fnAddData( settings, row ) );
7901
- }
7902
- }
7903
-
7904
- return out;
7905
- }, 1 );
7906
-
7907
- // Return an Api.rows() extended instance, so rows().nodes() etc can be used
7908
- var modRows = this.rows( -1 );
7909
- modRows.pop();
7910
- $.merge( modRows, newRows );
7911
-
7912
- return modRows;
7913
- } );
7914
-
7915
-
7916
-
7917
-
7918
-
7919
- /**
7920
- *
7921
- */
7922
- _api_register( 'row()', function ( selector, opts ) {
7923
- return _selector_first( this.rows( selector, opts ) );
7924
- } );
7925
-
7926
-
7927
- _api_register( 'row().data()', function ( data ) {
7928
- var ctx = this.context;
7929
-
7930
- if ( data === undefined ) {
7931
- // Get
7932
- return ctx.length && this.length ?
7933
- ctx[0].aoData[ this[0] ]._aData :
7934
- undefined;
7935
- }
7936
-
7937
- // Set
7938
- ctx[0].aoData[ this[0] ]._aData = data;
7939
-
7940
- // Automatically invalidate
7941
- _fnInvalidate( ctx[0], this[0], 'data' );
7942
-
7943
- return this;
7944
- } );
7945
-
7946
-
7947
- _api_register( 'row().node()', function () {
7948
- var ctx = this.context;
7949
-
7950
- return ctx.length && this.length ?
7951
- ctx[0].aoData[ this[0] ].nTr || null :
7952
- null;
7953
- } );
7954
-
7955
-
7956
- _api_register( 'row.add()', function ( row ) {
7957
- // Allow a jQuery object to be passed in - only a single row is added from
7958
- // it though - the first element in the set
7959
- if ( row instanceof $ && row.length ) {
7960
- row = row[0];
7961
- }
7962
-
7963
- var rows = this.iterator( 'table', function ( settings ) {
7964
- if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
7965
- return _fnAddTr( settings, row )[0];
7966
- }
7967
- return _fnAddData( settings, row );
7968
- } );
7969
-
7970
- // Return an Api.rows() extended instance, with the newly added row selected
7971
- return this.row( rows[0] );
7972
- } );
7973
-
7974
-
7975
-
7976
- var __details_add = function ( ctx, row, data, klass )
7977
- {
7978
- // Convert to array of TR elements
7979
- var rows = [];
7980
- var addRow = function ( r, k ) {
7981
- // Recursion to allow for arrays of jQuery objects
7982
- if ( $.isArray( r ) || r instanceof $ ) {
7983
- for ( var i=0, ien=r.length ; i<ien ; i++ ) {
7984
- addRow( r[i], k );
7985
- }
7986
- return;
7987
- }
7988
-
7989
- // If we get a TR element, then just add it directly - up to the dev
7990
- // to add the correct number of columns etc
7991
- if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
7992
- rows.push( r );
7993
- }
7994
- else {
7995
- // Otherwise create a row with a wrapper
7996
- var created = $('<tr><td/></tr>').addClass( k );
7997
- $('td', created)
7998
- .addClass( k )
7999
- .html( r )
8000
- [0].colSpan = _fnVisbleColumns( ctx );
8001
-
8002
- rows.push( created[0] );
8003
- }
8004
- };
8005
-
8006
- addRow( data, klass );
8007
-
8008
- if ( row._details ) {
8009
- row._details.remove();
8010
- }
8011
-
8012
- row._details = $(rows);
8013
-
8014
- // If the children were already shown, that state should be retained
8015
- if ( row._detailsShow ) {
8016
- row._details.insertAfter( row.nTr );
8017
- }
8018
- };
8019
-
8020
-
8021
- var __details_remove = function ( api, idx )
8022
- {
8023
- var ctx = api.context;
8024
-
8025
- if ( ctx.length ) {
8026
- var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8027
-
8028
- if ( row && row._details ) {
8029
- row._details.remove();
8030
-
8031
- row._detailsShow = undefined;
8032
- row._details = undefined;
8033
- }
8034
- }
8035
- };
8036
-
8037
-
8038
- var __details_display = function ( api, show ) {
8039
- var ctx = api.context;
8040
-
8041
- if ( ctx.length && api.length ) {
8042
- var row = ctx[0].aoData[ api[0] ];
8043
-
8044
- if ( row._details ) {
8045
- row._detailsShow = show;
8046
-
8047
- if ( show ) {
8048
- row._details.insertAfter( row.nTr );
8049
- }
8050
- else {
8051
- row._details.detach();
8052
- }
8053
-
8054
- __details_events( ctx[0] );
8055
- }
8056
- }
8057
- };
8058
-
8059
-
8060
- var __details_events = function ( settings )
8061
- {
8062
- var api = new _Api( settings );
8063
- var namespace = '.dt.DT_details';
8064
- var drawEvent = 'draw'+namespace;
8065
- var colvisEvent = 'column-visibility'+namespace;
8066
- var destroyEvent = 'destroy'+namespace;
8067
- var data = settings.aoData;
8068
-
8069
- api.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );
8070
-
8071
- if ( _pluck( data, '_details' ).length > 0 ) {
8072
- // On each draw, insert the required elements into the document
8073
- api.on( drawEvent, function ( e, ctx ) {
8074
- if ( settings !== ctx ) {
8075
- return;
8076
- }
8077
-
8078
- api.rows( {page:'current'} ).eq(0).each( function (idx) {
8079
- // Internal data grab
8080
- var row = data[ idx ];
8081
-
8082
- if ( row._detailsShow ) {
8083
- row._details.insertAfter( row.nTr );
8084
- }
8085
- } );
8086
- } );
8087
-
8088
- // Column visibility change - update the colspan
8089
- api.on( colvisEvent, function ( e, ctx, idx, vis ) {
8090
- if ( settings !== ctx ) {
8091
- return;
8092
- }
8093
-
8094
- // Update the colspan for the details rows (note, only if it already has
8095
- // a colspan)
8096
- var row, visible = _fnVisbleColumns( ctx );
8097
-
8098
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8099
- row = data[i];
8100
-
8101
- if ( row._details ) {
8102
- row._details.children('td[colspan]').attr('colspan', visible );
8103
- }
8104
- }
8105
- } );
8106
-
8107
- // Table destroyed - nuke any child rows
8108
- api.on( destroyEvent, function ( e, ctx ) {
8109
- if ( settings !== ctx ) {
8110
- return;
8111
- }
8112
-
8113
- for ( var i=0, ien=data.length ; i<ien ; i++ ) {
8114
- if ( data[i]._details ) {
8115
- __details_remove( api, i );
8116
- }
8117
- }
8118
- } );
8119
- }
8120
- };
8121
-
8122
- // Strings for the method names to help minification
8123
- var _emp = '';
8124
- var _child_obj = _emp+'row().child';
8125
- var _child_mth = _child_obj+'()';
8126
-
8127
- // data can be:
8128
- // tr
8129
- // string
8130
- // jQuery or array of any of the above
8131
- _api_register( _child_mth, function ( data, klass ) {
8132
- var ctx = this.context;
8133
-
8134
- if ( data === undefined ) {
8135
- // get
8136
- return ctx.length && this.length ?
8137
- ctx[0].aoData[ this[0] ]._details :
8138
- undefined;
8139
- }
8140
- else if ( data === true ) {
8141
- // show
8142
- this.child.show();
8143
- }
8144
- else if ( data === false ) {
8145
- // remove
8146
- __details_remove( this );
8147
- }
8148
- else if ( ctx.length && this.length ) {
8149
- // set
8150
- __details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
8151
- }
8152
-
8153
- return this;
8154
- } );
8155
-
8156
-
8157
- _api_register( [
8158
- _child_obj+'.show()',
8159
- _child_mth+'.show()' // only when `child()` was called with parameters (without
8160
- ], function ( show ) { // it returns an object and this method is not executed)
8161
- __details_display( this, true );
8162
- return this;
8163
- } );
8164
-
8165
-
8166
- _api_register( [
8167
- _child_obj+'.hide()',
8168
- _child_mth+'.hide()' // only when `child()` was called with parameters (without
8169
- ], function () { // it returns an object and this method is not executed)
8170
- __details_display( this, false );
8171
- return this;
8172
- } );
8173
-
8174
-
8175
- _api_register( [
8176
- _child_obj+'.remove()',
8177
- _child_mth+'.remove()' // only when `child()` was called with parameters (without
8178
- ], function () { // it returns an object and this method is not executed)
8179
- __details_remove( this );
8180
- return this;
8181
- } );
8182
-
8183
-
8184
- _api_register( _child_obj+'.isShown()', function () {
8185
- var ctx = this.context;
8186
-
8187
- if ( ctx.length && this.length ) {
8188
- // _detailsShown as false or undefined will fall through to return false
8189
- return ctx[0].aoData[ this[0] ]._detailsShow || false;
8190
- }
8191
- return false;
8192
- } );
8193
-
8194
-
8195
-
8196
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8197
- * Columns
8198
- *
8199
- * {integer} - column index (>=0 count from left, <0 count from right)
8200
- * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
8201
- * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
8202
- * "{string}:name" - column name
8203
- * "{string}" - jQuery selector on column header nodes
8204
- *
8205
- */
8206
-
8207
- // can be an array of these items, comma separated list, or an array of comma
8208
- // separated lists
8209
-
8210
- var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
8211
-
8212
-
8213
- // r1 and r2 are redundant - but it means that the parameters match for the
8214
- // iterator callback in columns().data()
8215
- var __columnData = function ( settings, column, r1, r2, rows ) {
8216
- var a = [];
8217
- for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
8218
- a.push( _fnGetCellData( settings, rows[row], column ) );
8219
- }
8220
- return a;
8221
- };
8222
-
8223
-
8224
- var __column_selector = function ( settings, selector, opts )
8225
- {
8226
- var
8227
- columns = settings.aoColumns,
8228
- names = _pluck( columns, 'sName' ),
8229
- nodes = _pluck( columns, 'nTh' );
8230
-
8231
- var run = function ( s ) {
8232
- var selInt = _intVal( s );
8233
-
8234
- // Selector - all
8235
- if ( s === '' ) {
8236
- return _range( columns.length );
8237
- }
8238
-
8239
- // Selector - index
8240
- if ( selInt !== null ) {
8241
- return [ selInt >= 0 ?
8242
- selInt : // Count from left
8243
- columns.length + selInt // Count from right (+ because its a negative value)
8244
- ];
8245
- }
8246
-
8247
- // Selector = function
8248
- if ( typeof s === 'function' ) {
8249
- var rows = _selector_row_indexes( settings, opts );
8250
-
8251
- return $.map( columns, function (col, idx) {
8252
- return s(
8253
- idx,
8254
- __columnData( settings, idx, 0, 0, rows ),
8255
- nodes[ idx ]
8256
- ) ? idx : null;
8257
- } );
8258
- }
8259
-
8260
- // jQuery or string selector
8261
- var match = typeof s === 'string' ?
8262
- s.match( __re_column_selector ) :
8263
- '';
8264
-
8265
- if ( match ) {
8266
- switch( match[2] ) {
8267
- case 'visIdx':
8268
- case 'visible':
8269
- var idx = parseInt( match[1], 10 );
8270
- // Visible index given, convert to column index
8271
- if ( idx < 0 ) {
8272
- // Counting from the right
8273
- var visColumns = $.map( columns, function (col,i) {
8274
- return col.bVisible ? i : null;
8275
- } );
8276
- return [ visColumns[ visColumns.length + idx ] ];
8277
- }
8278
- // Counting from the left
8279
- return [ _fnVisibleToColumnIndex( settings, idx ) ];
8280
-
8281
- case 'name':
8282
- // match by name. `names` is column index complete and in order
8283
- return $.map( names, function (name, i) {
8284
- return name === match[1] ? i : null;
8285
- } );
8286
- }
8287
- }
8288
- else {
8289
- // jQuery selector on the TH elements for the columns
8290
- return $( nodes )
8291
- .filter( s )
8292
- .map( function () {
8293
- return $.inArray( this, nodes ); // `nodes` is column index complete and in order
8294
- } )
8295
- .toArray();
8296
- }
8297
- };
8298
-
8299
- return _selector_run( 'column', selector, run, settings, opts );
8300
- };
8301
-
8302
-
8303
- var __setColumnVis = function ( settings, column, vis, recalc ) {
8304
- var
8305
- cols = settings.aoColumns,
8306
- col = cols[ column ],
8307
- data = settings.aoData,
8308
- row, cells, i, ien, tr;
8309
-
8310
- // Get
8311
- if ( vis === undefined ) {
8312
- return col.bVisible;
8313
- }
8314
-
8315
- // Set
8316
- // No change
8317
- if ( col.bVisible === vis ) {
8318
- return;
8319
- }
8320
-
8321
- if ( vis ) {
8322
- // Insert column
8323
- // Need to decide if we should use appendChild or insertBefore
8324
- var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
8325
-
8326
- for ( i=0, ien=data.length ; i<ien ; i++ ) {
8327
- tr = data[i].nTr;
8328
- cells = data[i].anCells;
8329
-
8330
- if ( tr ) {
8331
- // insertBefore can act like appendChild if 2nd arg is null
8332
- tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
8333
- }
8334
- }
8335
- }
8336
- else {
8337
- // Remove column
8338
- $( _pluck( settings.aoData, 'anCells', column ) ).detach();
8339
- }
8340
-
8341
- // Common actions
8342
- col.bVisible = vis;
8343
- _fnDrawHead( settings, settings.aoHeader );
8344
- _fnDrawHead( settings, settings.aoFooter );
8345
-
8346
- if ( recalc === undefined || recalc ) {
8347
- // Automatically adjust column sizing
8348
- _fnAdjustColumnSizing( settings );
8349
-
8350
- // Realign columns for scrolling
8351
- if ( settings.oScroll.sX || settings.oScroll.sY ) {
8352
- _fnScrollDraw( settings );
8353
- }
8354
- }
8355
-
8356
- _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );
8357
-
8358
- _fnSaveState( settings );
8359
- };
8360
-
8361
-
8362
- _api_register( 'columns()', function ( selector, opts ) {
8363
- // argument shifting
8364
- if ( selector === undefined ) {
8365
- selector = '';
8366
- }
8367
- else if ( $.isPlainObject( selector ) ) {
8368
- opts = selector;
8369
- selector = '';
8370
- }
8371
-
8372
- opts = _selector_opts( opts );
8373
-
8374
- var inst = this.iterator( 'table', function ( settings ) {
8375
- return __column_selector( settings, selector, opts );
8376
- }, 1 );
8377
-
8378
- // Want argument shifting here and in _row_selector?
8379
- inst.selector.cols = selector;
8380
- inst.selector.opts = opts;
8381
-
8382
- return inst;
8383
- } );
8384
-
8385
- _api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
8386
- return this.iterator( 'column', function ( settings, column ) {
8387
- return settings.aoColumns[column].nTh;
8388
- }, 1 );
8389
- } );
8390
-
8391
- _api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
8392
- return this.iterator( 'column', function ( settings, column ) {
8393
- return settings.aoColumns[column].nTf;
8394
- }, 1 );
8395
- } );
8396
-
8397
- _api_registerPlural( 'columns().data()', 'column().data()', function () {
8398
- return this.iterator( 'column-rows', __columnData, 1 );
8399
- } );
8400
-
8401
- _api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {
8402
- return this.iterator( 'column', function ( settings, column ) {
8403
- return settings.aoColumns[column].mData;
8404
- }, 1 );
8405
- } );
8406
-
8407
- _api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
8408
- return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8409
- return _pluck_order( settings.aoData, rows,
8410
- type === 'search' ? '_aFilterData' : '_aSortData', column
8411
- );
8412
- }, 1 );
8413
- } );
8414
-
8415
- _api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
8416
- return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
8417
- return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
8418
- }, 1 );
8419
- } );
8420
-
8421
- _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
8422
- return this.iterator( 'column', function ( settings, column ) {
8423
- if ( vis === undefined ) {
8424
- return settings.aoColumns[ column ].bVisible;
8425
- } // else
8426
- __setColumnVis( settings, column, vis, calc );
8427
- } );
8428
- } );
8429
-
8430
- _api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
8431
- return this.iterator( 'column', function ( settings, column ) {
8432
- return type === 'visible' ?
8433
- _fnColumnIndexToVisible( settings, column ) :
8434
- column;
8435
- }, 1 );
8436
- } );
8437
-
8438
- _api_register( 'columns.adjust()', function () {
8439
- return this.iterator( 'table', function ( settings ) {
8440
- _fnAdjustColumnSizing( settings );
8441
- }, 1 );
8442
- } );
8443
-
8444
- _api_register( 'column.index()', function ( type, idx ) {
8445
- if ( this.context.length !== 0 ) {
8446
- var ctx = this.context[0];
8447
-
8448
- if ( type === 'fromVisible' || type === 'toData' ) {
8449
- return _fnVisibleToColumnIndex( ctx, idx );
8450
- }
8451
- else if ( type === 'fromData' || type === 'toVisible' ) {
8452
- return _fnColumnIndexToVisible( ctx, idx );
8453
- }
8454
- }
8455
- } );
8456
-
8457
- _api_register( 'column()', function ( selector, opts ) {
8458
- return _selector_first( this.columns( selector, opts ) );
8459
- } );
8460
-
8461
-
8462
-
8463
-
8464
- var __cell_selector = function ( settings, selector, opts )
8465
- {
8466
- var data = settings.aoData;
8467
- var rows = _selector_row_indexes( settings, opts );
8468
- var cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );
8469
- var allCells = $( [].concat.apply([], cells) );
8470
- var row;
8471
- var columns = settings.aoColumns.length;
8472
- var a, i, ien, j, o, host;
8473
-
8474
- var run = function ( s ) {
8475
- var fnSelector = typeof s === 'function';
8476
-
8477
- if ( s === null || s === undefined || fnSelector ) {
8478
- // All cells and function selectors
8479
- a = [];
8480
-
8481
- for ( i=0, ien=rows.length ; i<ien ; i++ ) {
8482
- row = rows[i];
8483
-
8484
- for ( j=0 ; j<columns ; j++ ) {
8485
- o = {
8486
- row: row,
8487
- column: j
8488
- };
8489
-
8490
- if ( fnSelector ) {
8491
- // Selector - function
8492
- host = data[ row ];
8493
-
8494
- if ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {
8495
- a.push( o );
8496
- }
8497
- }
8498
- else {
8499
- // Selector - all
8500
- a.push( o );
8501
- }
8502
- }
8503
- }
8504
-
8505
- return a;
8506
- }
8507
-
8508
- // Selector - index
8509
- if ( $.isPlainObject( s ) ) {
8510
- return [s];
8511
- }
8512
-
8513
- // Selector - jQuery filtered cells
8514
- return allCells
8515
- .filter( s )
8516
- .map( function (i, el) {
8517
- if ( el.parentNode ) {
8518
- row = el.parentNode._DT_RowIndex;
8519
- }
8520
- else {
8521
- // If no parent node, then the cell is hidden and we'll need
8522
- // to traverse the array to find it
8523
- for ( i=0, ien=data.length ; i<ien ; i++ ) {
8524
- if ( $.inArray( el, data[i].anCells ) !== -1 ) {
8525
- row = i;
8526
- break;
8527
- }
8528
- }
8529
- }
8530
-
8531
- return {
8532
- row: row,
8533
- column: $.inArray( el, data[ row ].anCells )
8534
- };
8535
- } )
8536
- .toArray();
8537
- };
8538
-
8539
- return _selector_run( 'cell', selector, run, settings, opts );
8540
- };
8541
-
8542
-
8543
-
8544
-
8545
- _api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
8546
- // Argument shifting
8547
- if ( $.isPlainObject( rowSelector ) ) {
8548
- // Indexes
8549
- if ( rowSelector.row === undefined ) {
8550
- // Selector options in first parameter
8551
- opts = rowSelector;
8552
- rowSelector = null;
8553
- }
8554
- else {
8555
- // Cell index objects in first parameter
8556
- opts = columnSelector;
8557
- columnSelector = null;
8558
- }
8559
- }
8560
- if ( $.isPlainObject( columnSelector ) ) {
8561
- opts = columnSelector;
8562
- columnSelector = null;
8563
- }
8564
-
8565
- // Cell selector
8566
- if ( columnSelector === null || columnSelector === undefined ) {
8567
- return this.iterator( 'table', function ( settings ) {
8568
- return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
8569
- } );
8570
- }
8571
-
8572
- // Row + column selector
8573
- var columns = this.columns( columnSelector, opts );
8574
- var rows = this.rows( rowSelector, opts );
8575
- var a, i, ien, j, jen;
8576
-
8577
- var cells = this.iterator( 'table', function ( settings, idx ) {
8578
- a = [];
8579
-
8580
- for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
8581
- for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
8582
- a.push( {
8583
- row: rows[idx][i],
8584
- column: columns[idx][j]
8585
- } );
8586
- }
8587
- }
8588
-
8589
- return a;
8590
- }, 1 );
8591
-
8592
- $.extend( cells.selector, {
8593
- cols: columnSelector,
8594
- rows: rowSelector,
8595
- opts: opts
8596
- } );
8597
-
8598
- return cells;
8599
- } );
8600
-
8601
-
8602
- _api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
8603
- return this.iterator( 'cell', function ( settings, row, column ) {
8604
- var cells = settings.aoData[ row ].anCells;
8605
- return cells ?
8606
- cells[ column ] :
8607
- undefined;
8608
- }, 1 );
8609
- } );
8610
-
8611
-
8612
- _api_register( 'cells().data()', function () {
8613
- return this.iterator( 'cell', function ( settings, row, column ) {
8614
- return _fnGetCellData( settings, row, column );
8615
- }, 1 );
8616
- } );
8617
-
8618
-
8619
- _api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
8620
- type = type === 'search' ? '_aFilterData' : '_aSortData';
8621
-
8622
- return this.iterator( 'cell', function ( settings, row, column ) {
8623
- return settings.aoData[ row ][ type ][ column ];
8624
- }, 1 );
8625
- } );
8626
-
8627
-
8628
- _api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {
8629
- return this.iterator( 'cell', function ( settings, row, column ) {
8630
- return _fnGetCellData( settings, row, column, type );
8631
- }, 1 );
8632
- } );
8633
-
8634
-
8635
- _api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
8636
- return this.iterator( 'cell', function ( settings, row, column ) {
8637
- return {
8638
- row: row,
8639
- column: column,
8640
- columnVisible: _fnColumnIndexToVisible( settings, column )
8641
- };
8642
- }, 1 );
8643
- } );
8644
-
8645
-
8646
- _api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {
8647
- return this.iterator( 'cell', function ( settings, row, column ) {
8648
- _fnInvalidate( settings, row, src, column );
8649
- } );
8650
- } );
8651
-
8652
-
8653
-
8654
- _api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
8655
- return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
8656
- } );
8657
-
8658
-
8659
- _api_register( 'cell().data()', function ( data ) {
8660
- var ctx = this.context;
8661
- var cell = this[0];
8662
-
8663
- if ( data === undefined ) {
8664
- // Get
8665
- return ctx.length && cell.length ?
8666
- _fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
8667
- undefined;
8668
- }
8669
-
8670
- // Set
8671
- _fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
8672
- _fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );
8673
-
8674
- return this;
8675
- } );
8676
-
8677
-
8678
-
8679
- /**
8680
- * Get current ordering (sorting) that has been applied to the table.
8681
- *
8682
- * @returns {array} 2D array containing the sorting information for the first
8683
- * table in the current context. Each element in the parent array represents
8684
- * a column being sorted upon (i.e. multi-sorting with two columns would have
8685
- * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8686
- * the column index that the sorting condition applies to, the second is the
8687
- * direction of the sort (`desc` or `asc`) and, optionally, the third is the
8688
- * index of the sorting order from the `column.sorting` initialisation array.
8689
- *//**
8690
- * Set the ordering for the table.
8691
- *
8692
- * @param {integer} order Column index to sort upon.
8693
- * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8694
- * @returns {DataTables.Api} this
8695
- *//**
8696
- * Set the ordering for the table.
8697
- *
8698
- * @param {array} order 1D array of sorting information to be applied.
8699
- * @param {array} [...] Optional additional sorting conditions
8700
- * @returns {DataTables.Api} this
8701
- *//**
8702
- * Set the ordering for the table.
8703
- *
8704
- * @param {array} order 2D array of sorting information to be applied.
8705
- * @returns {DataTables.Api} this
8706
- */
8707
- _api_register( 'order()', function ( order, dir ) {
8708
- var ctx = this.context;
8709
-
8710
- if ( order === undefined ) {
8711
- // get
8712
- return ctx.length !== 0 ?
8713
- ctx[0].aaSorting :
8714
- undefined;
8715
- }
8716
-
8717
- // set
8718
- if ( typeof order === 'number' ) {
8719
- // Simple column / direction passed in
8720
- order = [ [ order, dir ] ];
8721
- }
8722
- else if ( ! $.isArray( order[0] ) ) {
8723
- // Arguments passed in (list of 1D arrays)
8724
- order = Array.prototype.slice.call( arguments );
8725
- }
8726
- // otherwise a 2D array was passed in
8727
-
8728
- return this.iterator( 'table', function ( settings ) {
8729
- settings.aaSorting = order.slice();
8730
- } );
8731
- } );
8732
-
8733
-
8734
- /**
8735
- * Attach a sort listener to an element for a given column
8736
- *
8737
- * @param {node|jQuery|string} node Identifier for the element(s) to attach the
8738
- * listener to. This can take the form of a single DOM node, a jQuery
8739
- * collection of nodes or a jQuery selector which will identify the node(s).
8740
- * @param {integer} column the column that a click on this node will sort on
8741
- * @param {function} [callback] callback function when sort is run
8742
- * @returns {DataTables.Api} this
8743
- */
8744
- _api_register( 'order.listener()', function ( node, column, callback ) {
8745
- return this.iterator( 'table', function ( settings ) {
8746
- _fnSortAttachListener( settings, node, column, callback );
8747
- } );
8748
- } );
8749
-
8750
-
8751
- // Order by the selected column(s)
8752
- _api_register( [
8753
- 'columns().order()',
8754
- 'column().order()'
8755
- ], function ( dir ) {
8756
- var that = this;
8757
-
8758
- return this.iterator( 'table', function ( settings, i ) {
8759
- var sort = [];
8760
-
8761
- $.each( that[i], function (j, col) {
8762
- sort.push( [ col, dir ] );
8763
- } );
8764
-
8765
- settings.aaSorting = sort;
8766
- } );
8767
- } );
8768
-
8769
-
8770
-
8771
- _api_register( 'search()', function ( input, regex, smart, caseInsen ) {
8772
- var ctx = this.context;
8773
-
8774
- if ( input === undefined ) {
8775
- // get
8776
- return ctx.length !== 0 ?
8777
- ctx[0].oPreviousSearch.sSearch :
8778
- undefined;
8779
- }
8780
-
8781
- // set
8782
- return this.iterator( 'table', function ( settings ) {
8783
- if ( ! settings.oFeatures.bFilter ) {
8784
- return;
8785
- }
8786
-
8787
- _fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
8788
- "sSearch": input+"",
8789
- "bRegex": regex === null ? false : regex,
8790
- "bSmart": smart === null ? true : smart,
8791
- "bCaseInsensitive": caseInsen === null ? true : caseInsen
8792
- } ), 1 );
8793
- } );
8794
- } );
8795
-
8796
-
8797
- _api_registerPlural(
8798
- 'columns().search()',
8799
- 'column().search()',
8800
- function ( input, regex, smart, caseInsen ) {
8801
- return this.iterator( 'column', function ( settings, column ) {
8802
- var preSearch = settings.aoPreSearchCols;
8803
-
8804
- if ( input === undefined ) {
8805
- // get
8806
- return preSearch[ column ].sSearch;
8807
- }
8808
-
8809
- // set
8810
- if ( ! settings.oFeatures.bFilter ) {
8811
- return;
8812
- }
8813
-
8814
- $.extend( preSearch[ column ], {
8815
- "sSearch": input+"",
8816
- "bRegex": regex === null ? false : regex,
8817
- "bSmart": smart === null ? true : smart,
8818
- "bCaseInsensitive": caseInsen === null ? true : caseInsen
8819
- } );
8820
-
8821
- _fnFilterComplete( settings, settings.oPreviousSearch, 1 );
8822
- } );
8823
- }
8824
- );
8825
-
8826
- /*
8827
- * State API methods
8828
- */
8829
-
8830
- _api_register( 'state()', function () {
8831
- return this.context.length ?
8832
- this.context[0].oSavedState :
8833
- null;
8834
- } );
8835
-
8836
-
8837
- _api_register( 'state.clear()', function () {
8838
- return this.iterator( 'table', function ( settings ) {
8839
- // Save an empty object
8840
- settings.fnStateSaveCallback.call( settings.oInstance, settings, {} );
8841
- } );
8842
- } );
8843
-
8844
-
8845
- _api_register( 'state.loaded()', function () {
8846
- return this.context.length ?
8847
- this.context[0].oLoadedState :
8848
- null;
8849
- } );
8850
-
8851
-
8852
- _api_register( 'state.save()', function () {
8853
- return this.iterator( 'table', function ( settings ) {
8854
- _fnSaveState( settings );
8855
- } );
8856
- } );
8857
-
8858
-
8859
-
8860
- /**
8861
- * Provide a common method for plug-ins to check the version of DataTables being
8862
- * used, in order to ensure compatibility.
8863
- *
8864
- * @param {string} version Version string to check for, in the format "X.Y.Z".
8865
- * Note that the formats "X" and "X.Y" are also acceptable.
8866
- * @returns {boolean} true if this version of DataTables is greater or equal to
8867
- * the required version, or false if this version of DataTales is not
8868
- * suitable
8869
- * @static
8870
- * @dtopt API-Static
8871
- *
8872
- * @example
8873
- * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
8874
- */
8875
- DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
8876
- {
8877
- var aThis = DataTable.version.split('.');
8878
- var aThat = version.split('.');
8879
- var iThis, iThat;
8880
-
8881
- for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
8882
- iThis = parseInt( aThis[i], 10 ) || 0;
8883
- iThat = parseInt( aThat[i], 10 ) || 0;
8884
-
8885
- // Parts are the same, keep comparing
8886
- if (iThis === iThat) {
8887
- continue;
8888
- }
8889
-
8890
- // Parts are different, return immediately
8891
- return iThis > iThat;
8892
- }
8893
-
8894
- return true;
8895
- };
8896
-
8897
-
8898
- /**
8899
- * Check if a `<table>` node is a DataTable table already or not.
8900
- *
8901
- * @param {node|jquery|string} table Table node, jQuery object or jQuery
8902
- * selector for the table to test. Note that if more than more than one
8903
- * table is passed on, only the first will be checked
8904
- * @returns {boolean} true the table given is a DataTable, or false otherwise
8905
- * @static
8906
- * @dtopt API-Static
8907
- *
8908
- * @example
8909
- * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
8910
- * $('#example').dataTable();
8911
- * }
8912
- */
8913
- DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
8914
- {
8915
- var t = $(table).get(0);
8916
- var is = false;
8917
-
8918
- $.each( DataTable.settings, function (i, o) {
8919
- var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
8920
- var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
8921
-
8922
- if ( o.nTable === t || head === t || foot === t ) {
8923
- is = true;
8924
- }
8925
- } );
8926
-
8927
- return is;
8928
- };
8929
-
8930
-
8931
- /**
8932
- * Get all DataTable tables that have been initialised - optionally you can
8933
- * select to get only currently visible tables.
8934
- *
8935
- * @param {boolean} [visible=false] Flag to indicate if you want all (default)
8936
- * or visible tables only.
8937
- * @returns {array} Array of `table` nodes (not DataTable instances) which are
8938
- * DataTables
8939
- * @static
8940
- * @dtopt API-Static
8941
- *
8942
- * @example
8943
- * $.each( $.fn.dataTable.tables(true), function () {
8944
- * $(table).DataTable().columns.adjust();
8945
- * } );
8946
- */
8947
- DataTable.tables = DataTable.fnTables = function ( visible )
8948
- {
8949
- var api = false;
8950
-
8951
- if ( $.isPlainObject( visible ) ) {
8952
- api = visible.api;
8953
- visible = visible.visible;
8954
- }
8955
-
8956
- var a = $.map( DataTable.settings, function (o) {
8957
- if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
8958
- return o.nTable;
8959
- }
8960
- } );
8961
-
8962
- return api ?
8963
- new _Api( a ) :
8964
- a;
8965
- };
8966
-
8967
-
8968
- /**
8969
- * DataTables utility methods
8970
- *
8971
- * This namespace provides helper methods that DataTables uses internally to
8972
- * create a DataTable, but which are not exclusively used only for DataTables.
8973
- * These methods can be used by extension authors to save the duplication of
8974
- * code.
8975
- *
8976
- * @namespace
8977
- */
8978
- DataTable.util = {
8979
- /**
8980
- * Throttle the calls to a function. Arguments and context are maintained
8981
- * for the throttled function.
8982
- *
8983
- * @param {function} fn Function to be called
8984
- * @param {integer} freq Call frequency in mS
8985
- * @return {function} Wrapped function
8986
- */
8987
- throttle: _fnThrottle,
8988
-
8989
-
8990
- /**
8991
- * Escape a string such that it can be used in a regular expression
8992
- *
8993
- * @param {string} sVal string to escape
8994
- * @returns {string} escaped string
8995
- */
8996
- escapeRegex: _fnEscapeRegex
8997
- };
8998
-
8999
-
9000
- /**
9001
- * Convert from camel case parameters to Hungarian notation. This is made public
9002
- * for the extensions to provide the same ability as DataTables core to accept
9003
- * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9004
- * parameters.
9005
- *
9006
- * @param {object} src The model object which holds all parameters that can be
9007
- * mapped.
9008
- * @param {object} user The object to convert from camel case to Hungarian.
9009
- * @param {boolean} force When set to `true`, properties which already have a
9010
- * Hungarian value in the `user` object will be overwritten. Otherwise they
9011
- * won't be.
9012
- */
9013
- DataTable.camelToHungarian = _fnCamelToHungarian;
9014
-
9015
-
9016
-
9017
- /**
9018
- *
9019
- */
9020
- _api_register( '$()', function ( selector, opts ) {
9021
- var
9022
- rows = this.rows( opts ).nodes(), // Get all rows
9023
- jqRows = $(rows);
9024
-
9025
- return $( [].concat(
9026
- jqRows.filter( selector ).toArray(),
9027
- jqRows.find( selector ).toArray()
9028
- ) );
9029
- } );
9030
-
9031
-
9032
- // jQuery functions to operate on the tables
9033
- $.each( [ 'on', 'one', 'off' ], function (i, key) {
9034
- _api_register( key+'()', function ( /* event, handler */ ) {
9035
- var args = Array.prototype.slice.call(arguments);
9036
-
9037
- // Add the `dt` namespace automatically if it isn't already present
9038
- if ( ! args[0].match(/\.dt\b/) ) {
9039
- args[0] += '.dt';
9040
- }
9041
-
9042
- var inst = $( this.tables().nodes() );
9043
- inst[key].apply( inst, args );
9044
- return this;
9045
- } );
9046
- } );
9047
-
9048
-
9049
- _api_register( 'clear()', function () {
9050
- return this.iterator( 'table', function ( settings ) {
9051
- _fnClearTable( settings );
9052
- } );
9053
- } );
9054
-
9055
-
9056
- _api_register( 'settings()', function () {
9057
- return new _Api( this.context, this.context );
9058
- } );
9059
-
9060
-
9061
- _api_register( 'init()', function () {
9062
- var ctx = this.context;
9063
- return ctx.length ? ctx[0].oInit : null;
9064
- } );
9065
-
9066
-
9067
- _api_register( 'data()', function () {
9068
- return this.iterator( 'table', function ( settings ) {
9069
- return _pluck( settings.aoData, '_aData' );
9070
- } ).flatten();
9071
- } );
9072
-
9073
-
9074
- _api_register( 'destroy()', function ( remove ) {
9075
- remove = remove || false;
9076
-
9077
- return this.iterator( 'table', function ( settings ) {
9078
- var orig = settings.nTableWrapper.parentNode;
9079
- var classes = settings.oClasses;
9080
- var table = settings.nTable;
9081
- var tbody = settings.nTBody;
9082
- var thead = settings.nTHead;
9083
- var tfoot = settings.nTFoot;
9084
- var jqTable = $(table);
9085
- var jqTbody = $(tbody);
9086
- var jqWrapper = $(settings.nTableWrapper);
9087
- var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
9088
- var i, ien;
9089
-
9090
- // Flag to note that the table is currently being destroyed - no action
9091
- // should be taken
9092
- settings.bDestroying = true;
9093
-
9094
- // Fire off the destroy callbacks for plug-ins etc
9095
- _fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
9096
-
9097
- // If not being removed from the document, make all columns visible
9098
- if ( ! remove ) {
9099
- new _Api( settings ).columns().visible( true );
9100
- }
9101
-
9102
- // Blitz all `DT` namespaced events (these are internal events, the
9103
- // lowercase, `dt` events are user subscribed and they are responsible
9104
- // for removing them
9105
- jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
9106
- $(window).unbind('.DT-'+settings.sInstance);
9107
-
9108
- // When scrolling we had to break the table up - restore it
9109
- if ( table != thead.parentNode ) {
9110
- jqTable.children('thead').detach();
9111
- jqTable.append( thead );
9112
- }
9113
-
9114
- if ( tfoot && table != tfoot.parentNode ) {
9115
- jqTable.children('tfoot').detach();
9116
- jqTable.append( tfoot );
9117
- }
9118
-
9119
- settings.aaSorting = [];
9120
- settings.aaSortingFixed = [];
9121
- _fnSortingClasses( settings );
9122
-
9123
- $( rows ).removeClass( settings.asStripeClasses.join(' ') );
9124
-
9125
- $('th, td', thead).removeClass( classes.sSortable+' '+
9126
- classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
9127
- );
9128
-
9129
- if ( settings.bJUI ) {
9130
- $('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
9131
- $('th, td', thead).each( function () {
9132
- var wrapper = $('div.'+classes.sSortJUIWrapper, this);
9133
- $(this).append( wrapper.contents() );
9134
- wrapper.detach();
9135
- } );
9136
- }
9137
-
9138
- // Add the TR elements back into the table in their original order
9139
- jqTbody.children().detach();
9140
- jqTbody.append( rows );
9141
-
9142
- // Remove the DataTables generated nodes, events and classes
9143
- var removedMethod = remove ? 'remove' : 'detach';
9144
- jqTable[ removedMethod ]();
9145
- jqWrapper[ removedMethod ]();
9146
-
9147
- // If we need to reattach the table to the document
9148
- if ( ! remove && orig ) {
9149
- // insertBefore acts like appendChild if !arg[1]
9150
- orig.insertBefore( table, settings.nTableReinsertBefore );
9151
-
9152
- // Restore the width of the original table - was read from the style property,
9153
- // so we can restore directly to that
9154
- jqTable
9155
- .css( 'width', settings.sDestroyWidth )
9156
- .removeClass( classes.sTable );
9157
-
9158
- // If the were originally stripe classes - then we add them back here.
9159
- // Note this is not fool proof (for example if not all rows had stripe
9160
- // classes - but it's a good effort without getting carried away
9161
- ien = settings.asDestroyStripes.length;
9162
-
9163
- if ( ien ) {
9164
- jqTbody.children().each( function (i) {
9165
- $(this).addClass( settings.asDestroyStripes[i % ien] );
9166
- } );
9167
- }
9168
- }
9169
-
9170
- /* Remove the settings object from the settings array */
9171
- var idx = $.inArray( settings, DataTable.settings );
9172
- if ( idx !== -1 ) {
9173
- DataTable.settings.splice( idx, 1 );
9174
- }
9175
- } );
9176
- } );
9177
-
9178
-
9179
- // Add the `every()` method for rows, columns and cells in a compact form
9180
- $.each( [ 'column', 'row', 'cell' ], function ( i, type ) {
9181
- _api_register( type+'s().every()', function ( fn ) {
9182
- return this.iterator( type, function ( settings, arg1, arg2, arg3, arg4 ) {
9183
- // Rows and columns:
9184
- // arg1 - index
9185
- // arg2 - table counter
9186
- // arg3 - loop counter
9187
- // arg4 - undefined
9188
- // Cells:
9189
- // arg1 - row index
9190
- // arg2 - column index
9191
- // arg3 - table counter
9192
- // arg4 - loop counter
9193
- fn.call(
9194
- new _Api( settings )[ type ]( arg1, type==='cell' ? arg2 : undefined ),
9195
- arg1, arg2, arg3, arg4
9196
- );
9197
- } );
9198
- } );
9199
- } );
9200
-
9201
-
9202
- // i18n method for extensions to be able to use the language object from the
9203
- // DataTable
9204
- _api_register( 'i18n()', function ( token, def, plural ) {
9205
- var ctx = this.context[0];
9206
- var resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );
9207
-
9208
- if ( resolved === undefined ) {
9209
- resolved = def;
9210
- }
9211
-
9212
- if ( plural !== undefined && $.isPlainObject( resolved ) ) {
9213
- resolved = resolved[ plural ] !== undefined ?
9214
- resolved[ plural ] :
9215
- resolved._;
9216
- }
9217
-
9218
- return resolved.replace( '%d', plural ); // nb: plural might be undefined,
9219
- } );
9220
-
9221
- /**
9222
- * Version string for plug-ins to check compatibility. Allowed format is
9223
- * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9224
- * only for non-release builds. See http://semver.org/ for more information.
9225
- * @member
9226
- * @type string
9227
- * @default Version number
9228
- */
9229
- DataTable.version = "1.10.9";
9230
-
9231
- /**
9232
- * Private data store, containing all of the settings objects that are
9233
- * created for the tables on a given page.
9234
- *
9235
- * Note that the `DataTable.settings` object is aliased to
9236
- * `jQuery.fn.dataTableExt` through which it may be accessed and
9237
- * manipulated, or `jQuery.fn.dataTable.settings`.
9238
- * @member
9239
- * @type array
9240
- * @default []
9241
- * @private
9242
- */
9243
- DataTable.settings = [];
9244
-
9245
- /**
9246
- * Object models container, for the various models that DataTables has
9247
- * available to it. These models define the objects that are used to hold
9248
- * the active state and configuration of the table.
9249
- * @namespace
9250
- */
9251
- DataTable.models = {};
9252
-
9253
-
9254
-
9255
- /**
9256
- * Template object for the way in which DataTables holds information about
9257
- * search information for the global filter and individual column filters.
9258
- * @namespace
9259
- */
9260
- DataTable.models.oSearch = {
9261
- /**
9262
- * Flag to indicate if the filtering should be case insensitive or not
9263
- * @type boolean
9264
- * @default true
9265
- */
9266
- "bCaseInsensitive": true,
9267
-
9268
- /**
9269
- * Applied search term
9270
- * @type string
9271
- * @default <i>Empty string</i>
9272
- */
9273
- "sSearch": "",
9274
-
9275
- /**
9276
- * Flag to indicate if the search term should be interpreted as a
9277
- * regular expression (true) or not (false) and therefore and special
9278
- * regex characters escaped.
9279
- * @type boolean
9280
- * @default false
9281
- */
9282
- "bRegex": false,
9283
-
9284
- /**
9285
- * Flag to indicate if DataTables is to use its smart filtering or not.
9286
- * @type boolean
9287
- * @default true
9288
- */
9289
- "bSmart": true
9290
- };
9291
-
9292
-
9293
-
9294
-
9295
- /**
9296
- * Template object for the way in which DataTables holds information about
9297
- * each individual row. This is the object format used for the settings
9298
- * aoData array.
9299
- * @namespace
9300
- */
9301
- DataTable.models.oRow = {
9302
- /**
9303
- * TR element for the row
9304
- * @type node
9305
- * @default null
9306
- */
9307
- "nTr": null,
9308
-
9309
- /**
9310
- * Array of TD elements for each row. This is null until the row has been
9311
- * created.
9312
- * @type array nodes
9313
- * @default []
9314
- */
9315
- "anCells": null,
9316
-
9317
- /**
9318
- * Data object from the original data source for the row. This is either
9319
- * an array if using the traditional form of DataTables, or an object if
9320
- * using mData options. The exact type will depend on the passed in
9321
- * data from the data source, or will be an array if using DOM a data
9322
- * source.
9323
- * @type array|object
9324
- * @default []
9325
- */
9326
- "_aData": [],
9327
-
9328
- /**
9329
- * Sorting data cache - this array is ostensibly the same length as the
9330
- * number of columns (although each index is generated only as it is
9331
- * needed), and holds the data that is used for sorting each column in the
9332
- * row. We do this cache generation at the start of the sort in order that
9333
- * the formatting of the sort data need be done only once for each cell
9334
- * per sort. This array should not be read from or written to by anything
9335
- * other than the master sorting methods.
9336
- * @type array
9337
- * @default null
9338
- * @private
9339
- */
9340
- "_aSortData": null,
9341
-
9342
- /**
9343
- * Per cell filtering data cache. As per the sort data cache, used to
9344
- * increase the performance of the filtering in DataTables
9345
- * @type array
9346
- * @default null
9347
- * @private
9348
- */
9349
- "_aFilterData": null,
9350
-
9351
- /**
9352
- * Filtering data cache. This is the same as the cell filtering cache, but
9353
- * in this case a string rather than an array. This is easily computed with
9354
- * a join on `_aFilterData`, but is provided as a cache so the join isn't
9355
- * needed on every search (memory traded for performance)
9356
- * @type array
9357
- * @default null
9358
- * @private
9359
- */
9360
- "_sFilterRow": null,
9361
-
9362
- /**
9363
- * Cache of the class name that DataTables has applied to the row, so we
9364
- * can quickly look at this variable rather than needing to do a DOM check
9365
- * on className for the nTr property.
9366
- * @type string
9367
- * @default <i>Empty string</i>
9368
- * @private
9369
- */
9370
- "_sRowStripe": "",
9371
-
9372
- /**
9373
- * Denote if the original data source was from the DOM, or the data source
9374
- * object. This is used for invalidating data, so DataTables can
9375
- * automatically read data from the original source, unless uninstructed
9376
- * otherwise.
9377
- * @type string
9378
- * @default null
9379
- * @private
9380
- */
9381
- "src": null,
9382
-
9383
- /**
9384
- * Index in the aoData array. This saves an indexOf lookup when we have the
9385
- * object, but want to know the index
9386
- * @type integer
9387
- * @default -1
9388
- * @private
9389
- */
9390
- "idx": -1
9391
- };
9392
-
9393
-
9394
- /**
9395
- * Template object for the column information object in DataTables. This object
9396
- * is held in the settings aoColumns array and contains all the information that
9397
- * DataTables needs about each individual column.
9398
- *
9399
- * Note that this object is related to {@link DataTable.defaults.column}
9400
- * but this one is the internal data store for DataTables's cache of columns.
9401
- * It should NOT be manipulated outside of DataTables. Any configuration should
9402
- * be done through the initialisation options.
9403
- * @namespace
9404
- */
9405
- DataTable.models.oColumn = {
9406
- /**
9407
- * Column index. This could be worked out on-the-fly with $.inArray, but it
9408
- * is faster to just hold it as a variable
9409
- * @type integer
9410
- * @default null
9411
- */
9412
- "idx": null,
9413
-
9414
- /**
9415
- * A list of the columns that sorting should occur on when this column
9416
- * is sorted. That this property is an array allows multi-column sorting
9417
- * to be defined for a column (for example first name / last name columns
9418
- * would benefit from this). The values are integers pointing to the
9419
- * columns to be sorted on (typically it will be a single integer pointing
9420
- * at itself, but that doesn't need to be the case).
9421
- * @type array
9422
- */
9423
- "aDataSort": null,
9424
-
9425
- /**
9426
- * Define the sorting directions that are applied to the column, in sequence
9427
- * as the column is repeatedly sorted upon - i.e. the first value is used
9428
- * as the sorting direction when the column if first sorted (clicked on).
9429
- * Sort it again (click again) and it will move on to the next index.
9430
- * Repeat until loop.
9431
- * @type array
9432
- */
9433
- "asSorting": null,
9434
-
9435
- /**
9436
- * Flag to indicate if the column is searchable, and thus should be included
9437
- * in the filtering or not.
9438
- * @type boolean
9439
- */
9440
- "bSearchable": null,
9441
-
9442
- /**
9443
- * Flag to indicate if the column is sortable or not.
9444
- * @type boolean
9445
- */
9446
- "bSortable": null,
9447
-
9448
- /**
9449
- * Flag to indicate if the column is currently visible in the table or not
9450
- * @type boolean
9451
- */
9452
- "bVisible": null,
9453
-
9454
- /**
9455
- * Store for manual type assignment using the `column.type` option. This
9456
- * is held in store so we can manipulate the column's `sType` property.
9457
- * @type string
9458
- * @default null
9459
- * @private
9460
- */
9461
- "_sManualType": null,
9462
-
9463
- /**
9464
- * Flag to indicate if HTML5 data attributes should be used as the data
9465
- * source for filtering or sorting. True is either are.
9466
- * @type boolean
9467
- * @default false
9468
- * @private
9469
- */
9470
- "_bAttrSrc": false,
9471
-
9472
- /**
9473
- * Developer definable function that is called whenever a cell is created (Ajax source,
9474
- * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9475
- * allowing you to modify the DOM element (add background colour for example) when the
9476
- * element is available.
9477
- * @type function
9478
- * @param {element} nTd The TD node that has been created
9479
- * @param {*} sData The Data for the cell
9480
- * @param {array|object} oData The data for the whole row
9481
- * @param {int} iRow The row index for the aoData data store
9482
- * @default null
9483
- */
9484
- "fnCreatedCell": null,
9485
-
9486
- /**
9487
- * Function to get data from a cell in a column. You should <b>never</b>
9488
- * access data directly through _aData internally in DataTables - always use
9489
- * the method attached to this property. It allows mData to function as
9490
- * required. This function is automatically assigned by the column
9491
- * initialisation method
9492
- * @type function
9493
- * @param {array|object} oData The data array/object for the array
9494
- * (i.e. aoData[]._aData)
9495
- * @param {string} sSpecific The specific data type you want to get -
9496
- * 'display', 'type' 'filter' 'sort'
9497
- * @returns {*} The data for the cell from the given row's data
9498
- * @default null
9499
- */
9500
- "fnGetData": null,
9501
-
9502
- /**
9503
- * Function to set data for a cell in the column. You should <b>never</b>
9504
- * set the data directly to _aData internally in DataTables - always use
9505
- * this method. It allows mData to function as required. This function
9506
- * is automatically assigned by the column initialisation method
9507
- * @type function
9508
- * @param {array|object} oData The data array/object for the array
9509
- * (i.e. aoData[]._aData)
9510
- * @param {*} sValue Value to set
9511
- * @default null
9512
- */
9513
- "fnSetData": null,
9514
-
9515
- /**
9516
- * Property to read the value for the cells in the column from the data
9517
- * source array / object. If null, then the default content is used, if a
9518
- * function is given then the return from the function is used.
9519
- * @type function|int|string|null
9520
- * @default null
9521
- */
9522
- "mData": null,
9523
-
9524
- /**
9525
- * Partner property to mData which is used (only when defined) to get
9526
- * the data - i.e. it is basically the same as mData, but without the
9527
- * 'set' option, and also the data fed to it is the result from mData.
9528
- * This is the rendering method to match the data method of mData.
9529
- * @type function|int|string|null
9530
- * @default null
9531
- */
9532
- "mRender": null,
9533
-
9534
- /**
9535
- * Unique header TH/TD element for this column - this is what the sorting
9536
- * listener is attached to (if sorting is enabled.)
9537
- * @type node
9538
- * @default null
9539
- */
9540
- "nTh": null,
9541
-
9542
- /**
9543
- * Unique footer TH/TD element for this column (if there is one). Not used
9544
- * in DataTables as such, but can be used for plug-ins to reference the
9545
- * footer for each column.
9546
- * @type node
9547
- * @default null
9548
- */
9549
- "nTf": null,
9550
-
9551
- /**
9552
- * The class to apply to all TD elements in the table's TBODY for the column
9553
- * @type string
9554
- * @default null
9555
- */
9556
- "sClass": null,
9557
-
9558
- /**
9559
- * When DataTables calculates the column widths to assign to each column,
9560
- * it finds the longest string in each column and then constructs a
9561
- * temporary table and reads the widths from that. The problem with this
9562
- * is that "mmm" is much wider then "iiii", but the latter is a longer
9563
- * string - thus the calculation can go wrong (doing it properly and putting
9564
- * it into an DOM object and measuring that is horribly(!) slow). Thus as
9565
- * a "work around" we provide this option. It will append its value to the
9566
- * text that is found to be the longest string for the column - i.e. padding.
9567
- * @type string
9568
- */
9569
- "sContentPadding": null,
9570
-
9571
- /**
9572
- * Allows a default value to be given for a column's data, and will be used
9573
- * whenever a null data source is encountered (this can be because mData
9574
- * is set to null, or because the data source itself is null).
9575
- * @type string
9576
- * @default null
9577
- */
9578
- "sDefaultContent": null,
9579
-
9580
- /**
9581
- * Name for the column, allowing reference to the column by name as well as
9582
- * by index (needs a lookup to work by name).
9583
- * @type string
9584
- */
9585
- "sName": null,
9586
-
9587
- /**
9588
- * Custom sorting data type - defines which of the available plug-ins in
9589
- * afnSortData the custom sorting will use - if any is defined.
9590
- * @type string
9591
- * @default std
9592
- */
9593
- "sSortDataType": 'std',
9594
-
9595
- /**
9596
- * Class to be applied to the header element when sorting on this column
9597
- * @type string
9598
- * @default null
9599
- */
9600
- "sSortingClass": null,
9601
-
9602
- /**
9603
- * Class to be applied to the header element when sorting on this column -
9604
- * when jQuery UI theming is used.
9605
- * @type string
9606
- * @default null
9607
- */
9608
- "sSortingClassJUI": null,
9609
-
9610
- /**
9611
- * Title of the column - what is seen in the TH element (nTh).
9612
- * @type string
9613
- */
9614
- "sTitle": null,
9615
-
9616
- /**
9617
- * Column sorting and filtering type
9618
- * @type string
9619
- * @default null
9620
- */
9621
- "sType": null,
9622
-
9623
- /**
9624
- * Width of the column
9625
- * @type string
9626
- * @default null
9627
- */
9628
- "sWidth": null,
9629
-
9630
- /**
9631
- * Width of the column when it was first "encountered"
9632
- * @type string
9633
- * @default null
9634
- */
9635
- "sWidthOrig": null
9636
- };
9637
-
9638
-
9639
- /*
9640
- * Developer note: The properties of the object below are given in Hungarian
9641
- * notation, that was used as the interface for DataTables prior to v1.10, however
9642
- * from v1.10 onwards the primary interface is camel case. In order to avoid
9643
- * breaking backwards compatibility utterly with this change, the Hungarian
9644
- * version is still, internally the primary interface, but is is not documented
9645
- * - hence the @name tags in each doc comment. This allows a Javascript function
9646
- * to create a map from Hungarian notation to camel case (going the other direction
9647
- * would require each property to be listed, which would at around 3K to the size
9648
- * of DataTables, while this method is about a 0.5K hit.
9649
- *
9650
- * Ultimately this does pave the way for Hungarian notation to be dropped
9651
- * completely, but that is a massive amount of work and will break current
9652
- * installs (therefore is on-hold until v2).
9653
- */
9654
-
9655
- /**
9656
- * Initialisation options that can be given to DataTables at initialisation
9657
- * time.
9658
- * @namespace
9659
- */
9660
- DataTable.defaults = {
9661
- /**
9662
- * An array of data to use for the table, passed in at initialisation which
9663
- * will be used in preference to any data which is already in the DOM. This is
9664
- * particularly useful for constructing tables purely in Javascript, for
9665
- * example with a custom Ajax call.
9666
- * @type array
9667
- * @default null
9668
- *
9669
- * @dtopt Option
9670
- * @name DataTable.defaults.data
9671
- *
9672
- * @example
9673
- * // Using a 2D array data source
9674
- * $(document).ready( function () {
9675
- * $('#example').dataTable( {
9676
- * "data": [
9677
- * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9678
- * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9679
- * ],
9680
- * "columns": [
9681
- * { "title": "Engine" },
9682
- * { "title": "Browser" },
9683
- * { "title": "Platform" },
9684
- * { "title": "Version" },
9685
- * { "title": "Grade" }
9686
- * ]
9687
- * } );
9688
- * } );
9689
- *
9690
- * @example
9691
- * // Using an array of objects as a data source (`data`)
9692
- * $(document).ready( function () {
9693
- * $('#example').dataTable( {
9694
- * "data": [
9695
- * {
9696
- * "engine": "Trident",
9697
- * "browser": "Internet Explorer 4.0",
9698
- * "platform": "Win 95+",
9699
- * "version": 4,
9700
- * "grade": "X"
9701
- * },
9702
- * {
9703
- * "engine": "Trident",
9704
- * "browser": "Internet Explorer 5.0",
9705
- * "platform": "Win 95+",
9706
- * "version": 5,
9707
- * "grade": "C"
9708
- * }
9709
- * ],
9710
- * "columns": [
9711
- * { "title": "Engine", "data": "engine" },
9712
- * { "title": "Browser", "data": "browser" },
9713
- * { "title": "Platform", "data": "platform" },
9714
- * { "title": "Version", "data": "version" },
9715
- * { "title": "Grade", "data": "grade" }
9716
- * ]
9717
- * } );
9718
- * } );
9719
- */
9720
- "aaData": null,
9721
-
9722
-
9723
- /**
9724
- * If ordering is enabled, then DataTables will perform a first pass sort on
9725
- * initialisation. You can define which column(s) the sort is performed
9726
- * upon, and the sorting direction, with this variable. The `sorting` array
9727
- * should contain an array for each column to be sorted initially containing
9728
- * the column's index and a direction string ('asc' or 'desc').
9729
- * @type array
9730
- * @default [[0,'asc']]
9731
- *
9732
- * @dtopt Option
9733
- * @name DataTable.defaults.order
9734
- *
9735
- * @example
9736
- * // Sort by 3rd column first, and then 4th column
9737
- * $(document).ready( function() {
9738
- * $('#example').dataTable( {
9739
- * "order": [[2,'asc'], [3,'desc']]
9740
- * } );
9741
- * } );
9742
- *
9743
- * // No initial sorting
9744
- * $(document).ready( function() {
9745
- * $('#example').dataTable( {
9746
- * "order": []
9747
- * } );
9748
- * } );
9749
- */
9750
- "aaSorting": [[0,'asc']],
9751
-
9752
-
9753
- /**
9754
- * This parameter is basically identical to the `sorting` parameter, but
9755
- * cannot be overridden by user interaction with the table. What this means
9756
- * is that you could have a column (visible or hidden) which the sorting
9757
- * will always be forced on first - any sorting after that (from the user)
9758
- * will then be performed as required. This can be useful for grouping rows
9759
- * together.
9760
- * @type array
9761
- * @default null
9762
- *
9763
- * @dtopt Option
9764
- * @name DataTable.defaults.orderFixed
9765
- *
9766
- * @example
9767
- * $(document).ready( function() {
9768
- * $('#example').dataTable( {
9769
- * "orderFixed": [[0,'asc']]
9770
- * } );
9771
- * } )
9772
- */
9773
- "aaSortingFixed": [],
9774
-
9775
-
9776
- /**
9777
- * DataTables can be instructed to load data to display in the table from a
9778
- * Ajax source. This option defines how that Ajax call is made and where to.
9779
- *
9780
- * The `ajax` property has three different modes of operation, depending on
9781
- * how it is defined. These are:
9782
- *
9783
- * * `string` - Set the URL from where the data should be loaded from.
9784
- * * `object` - Define properties for `jQuery.ajax`.
9785
- * * `function` - Custom data get function
9786
- *
9787
- * `string`
9788
- * --------
9789
- *
9790
- * As a string, the `ajax` property simply defines the URL from which
9791
- * DataTables will load data.
9792
- *
9793
- * `object`
9794
- * --------
9795
- *
9796
- * As an object, the parameters in the object are passed to
9797
- * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
9798
- * of the Ajax request. DataTables has a number of default parameters which
9799
- * you can override using this option. Please refer to the jQuery
9800
- * documentation for a full description of the options available, although
9801
- * the following parameters provide additional options in DataTables or
9802
- * require special consideration:
9803
- *
9804
- * * `data` - As with jQuery, `data` can be provided as an object, but it
9805
- * can also be used as a function to manipulate the data DataTables sends
9806
- * to the server. The function takes a single parameter, an object of
9807
- * parameters with the values that DataTables has readied for sending. An
9808
- * object may be returned which will be merged into the DataTables
9809
- * defaults, or you can add the items to the object that was passed in and
9810
- * not return anything from the function. This supersedes `fnServerParams`
9811
- * from DataTables 1.9-.
9812
- *
9813
- * * `dataSrc` - By default DataTables will look for the property `data` (or
9814
- * `aaData` for compatibility with DataTables 1.9-) when obtaining data
9815
- * from an Ajax source or for server-side processing - this parameter
9816
- * allows that property to be changed. You can use Javascript dotted
9817
- * object notation to get a data source for multiple levels of nesting, or
9818
- * it my be used as a function. As a function it takes a single parameter,
9819
- * the JSON returned from the server, which can be manipulated as
9820
- * required, with the returned value being that used by DataTables as the
9821
- * data source for the table. This supersedes `sAjaxDataProp` from
9822
- * DataTables 1.9-.
9823
- *
9824
- * * `success` - Should not be overridden it is used internally in
9825
- * DataTables. To manipulate / transform the data returned by the server
9826
- * use `ajax.dataSrc`, or use `ajax` as a function (see below).
9827
- *
9828
- * `function`
9829
- * ----------
9830
- *
9831
- * As a function, making the Ajax call is left up to yourself allowing
9832
- * complete control of the Ajax request. Indeed, if desired, a method other
9833
- * than Ajax could be used to obtain the required data, such as Web storage
9834
- * or an AIR database.
9835
- *
9836
- * The function is given four parameters and no return is required. The
9837
- * parameters are:
9838
- *
9839
- * 1. _object_ - Data to send to the server
9840
- * 2. _function_ - Callback function that must be executed when the required
9841
- * data has been obtained. That data should be passed into the callback
9842
- * as the only parameter
9843
- * 3. _object_ - DataTables settings object for the table
9844
- *
9845
- * Note that this supersedes `fnServerData` from DataTables 1.9-.
9846
- *
9847
- * @type string|object|function
9848
- * @default null
9849
- *
9850
- * @dtopt Option
9851
- * @name DataTable.defaults.ajax
9852
- * @since 1.10.0
9853
- *
9854
- * @example
9855
- * // Get JSON data from a file via Ajax.
9856
- * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
9857
- * $('#example').dataTable( {
9858
- * "ajax": "data.json"
9859
- * } );
9860
- *
9861
- * @example
9862
- * // Get JSON data from a file via Ajax, using `dataSrc` to change
9863
- * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
9864
- * $('#example').dataTable( {
9865
- * "ajax": {
9866
- * "url": "data.json",
9867
- * "dataSrc": "tableData"
9868
- * }
9869
- * } );
9870
- *
9871
- * @example
9872
- * // Get JSON data from a file via Ajax, using `dataSrc` to read data
9873
- * // from a plain array rather than an array in an object
9874
- * $('#example').dataTable( {
9875
- * "ajax": {
9876
- * "url": "data.json",
9877
- * "dataSrc": ""
9878
- * }
9879
- * } );
9880
- *
9881
- * @example
9882
- * // Manipulate the data returned from the server - add a link to data
9883
- * // (note this can, should, be done using `render` for the column - this
9884
- * // is just a simple example of how the data can be manipulated).
9885
- * $('#example').dataTable( {
9886
- * "ajax": {
9887
- * "url": "data.json",
9888
- * "dataSrc": function ( json ) {
9889
- * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
9890
- * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
9891
- * }
9892
- * return json;
9893
- * }
9894
- * }
9895
- * } );
9896
- *
9897
- * @example
9898
- * // Add data to the request
9899
- * $('#example').dataTable( {
9900
- * "ajax": {
9901
- * "url": "data.json",
9902
- * "data": function ( d ) {
9903
- * return {
9904
- * "extra_search": $('#extra').val()
9905
- * };
9906
- * }
9907
- * }
9908
- * } );
9909
- *
9910
- * @example
9911
- * // Send request as POST
9912
- * $('#example').dataTable( {
9913
- * "ajax": {
9914
- * "url": "data.json",
9915
- * "type": "POST"
9916
- * }
9917
- * } );
9918
- *
9919
- * @example
9920
- * // Get the data from localStorage (could interface with a form for
9921
- * // adding, editing and removing rows).
9922
- * $('#example').dataTable( {
9923
- * "ajax": function (data, callback, settings) {
9924
- * callback(
9925
- * JSON.parse( localStorage.getItem('dataTablesData') )
9926
- * );
9927
- * }
9928
- * } );
9929
- */
9930
- "ajax": null,
9931
-
9932
-
9933
- /**
9934
- * This parameter allows you to readily specify the entries in the length drop
9935
- * down menu that DataTables shows when pagination is enabled. It can be
9936
- * either a 1D array of options which will be used for both the displayed
9937
- * option and the value, or a 2D array which will use the array in the first
9938
- * position as the value, and the array in the second position as the
9939
- * displayed options (useful for language strings such as 'All').
9940
- *
9941
- * Note that the `pageLength` property will be automatically set to the
9942
- * first value given in this array, unless `pageLength` is also provided.
9943
- * @type array
9944
- * @default [ 10, 25, 50, 100 ]
9945
- *
9946
- * @dtopt Option
9947
- * @name DataTable.defaults.lengthMenu
9948
- *
9949
- * @example
9950
- * $(document).ready( function() {
9951
- * $('#example').dataTable( {
9952
- * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
9953
- * } );
9954
- * } );
9955
- */
9956
- "aLengthMenu": [ 10, 25, 50, 100 ],
9957
-
9958
-
9959
- /**
9960
- * The `columns` option in the initialisation parameter allows you to define
9961
- * details about the way individual columns behave. For a full list of
9962
- * column options that can be set, please see
9963
- * {@link DataTable.defaults.column}. Note that if you use `columns` to
9964
- * define your columns, you must have an entry in the array for every single
9965
- * column that you have in your table (these can be null if you don't which
9966
- * to specify any options).
9967
- * @member
9968
- *
9969
- * @name DataTable.defaults.column
9970
- */
9971
- "aoColumns": null,
9972
-
9973
- /**
9974
- * Very similar to `columns`, `columnDefs` allows you to target a specific
9975
- * column, multiple columns, or all columns, using the `targets` property of
9976
- * each object in the array. This allows great flexibility when creating
9977
- * tables, as the `columnDefs` arrays can be of any length, targeting the
9978
- * columns you specifically want. `columnDefs` may use any of the column
9979
- * options available: {@link DataTable.defaults.column}, but it _must_
9980
- * have `targets` defined in each object in the array. Values in the `targets`
9981
- * array may be:
9982
- * <ul>
9983
- * <li>a string - class name will be matched on the TH for the column</li>
9984
- * <li>0 or a positive integer - column index counting from the left</li>
9985
- * <li>a negative integer - column index counting from the right</li>
9986
- * <li>the string "_all" - all columns (i.e. assign a default)</li>
9987
- * </ul>
9988
- * @member
9989
- *
9990
- * @name DataTable.defaults.columnDefs
9991
- */
9992
- "aoColumnDefs": null,
9993
-
9994
-
9995
- /**
9996
- * Basically the same as `search`, this parameter defines the individual column
9997
- * filtering state at initialisation time. The array must be of the same size
9998
- * as the number of columns, and each element be an object with the parameters
9999
- * `search` and `escapeRegex` (the latter is optional). 'null' is also
10000
- * accepted and the default will be used.
10001
- * @type array
10002
- * @default []
10003
- *
10004
- * @dtopt Option
10005
- * @name DataTable.defaults.searchCols
10006
- *
10007
- * @example
10008
- * $(document).ready( function() {
10009
- * $('#example').dataTable( {
10010
- * "searchCols": [
10011
- * null,
10012
- * { "search": "My filter" },
10013
- * null,
10014
- * { "search": "^[0-9]", "escapeRegex": false }
10015
- * ]
10016
- * } );
10017
- * } )
10018
- */
10019
- "aoSearchCols": [],
10020
-
10021
-
10022
- /**
10023
- * An array of CSS classes that should be applied to displayed rows. This
10024
- * array may be of any length, and DataTables will apply each class
10025
- * sequentially, looping when required.
10026
- * @type array
10027
- * @default null <i>Will take the values determined by the `oClasses.stripe*`
10028
- * options</i>
10029
- *
10030
- * @dtopt Option
10031
- * @name DataTable.defaults.stripeClasses
10032
- *
10033
- * @example
10034
- * $(document).ready( function() {
10035
- * $('#example').dataTable( {
10036
- * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10037
- * } );
10038
- * } )
10039
- */
10040
- "asStripeClasses": null,
10041
-
10042
-
10043
- /**
10044
- * Enable or disable automatic column width calculation. This can be disabled
10045
- * as an optimisation (it takes some time to calculate the widths) if the
10046
- * tables widths are passed in using `columns`.
10047
- * @type boolean
10048
- * @default true
10049
- *
10050
- * @dtopt Features
10051
- * @name DataTable.defaults.autoWidth
10052
- *
10053
- * @example
10054
- * $(document).ready( function () {
10055
- * $('#example').dataTable( {
10056
- * "autoWidth": false
10057
- * } );
10058
- * } );
10059
- */
10060
- "bAutoWidth": true,
10061
-
10062
-
10063
- /**
10064
- * Deferred rendering can provide DataTables with a huge speed boost when you
10065
- * are using an Ajax or JS data source for the table. This option, when set to
10066
- * true, will cause DataTables to defer the creation of the table elements for
10067
- * each row until they are needed for a draw - saving a significant amount of
10068
- * time.
10069
- * @type boolean
10070
- * @default false
10071
- *
10072
- * @dtopt Features
10073
- * @name DataTable.defaults.deferRender
10074
- *
10075
- * @example
10076
- * $(document).ready( function() {
10077
- * $('#example').dataTable( {
10078
- * "ajax": "sources/arrays.txt",
10079
- * "deferRender": true
10080
- * } );
10081
- * } );
10082
- */
10083
- "bDeferRender": false,
10084
-
10085
-
10086
- /**
10087
- * Replace a DataTable which matches the given selector and replace it with
10088
- * one which has the properties of the new initialisation object passed. If no
10089
- * table matches the selector, then the new DataTable will be constructed as
10090
- * per normal.
10091
- * @type boolean
10092
- * @default false
10093
- *
10094
- * @dtopt Options
10095
- * @name DataTable.defaults.destroy
10096
- *
10097
- * @example
10098
- * $(document).ready( function() {
10099
- * $('#example').dataTable( {
10100
- * "srollY": "200px",
10101
- * "paginate": false
10102
- * } );
10103
- *
10104
- * // Some time later....
10105
- * $('#example').dataTable( {
10106
- * "filter": false,
10107
- * "destroy": true
10108
- * } );
10109
- * } );
10110
- */
10111
- "bDestroy": false,
10112
-
10113
-
10114
- /**
10115
- * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10116
- * that it allows the end user to input multiple words (space separated) and
10117
- * will match a row containing those words, even if not in the order that was
10118
- * specified (this allow matching across multiple columns). Note that if you
10119
- * wish to use filtering in DataTables this must remain 'true' - to remove the
10120
- * default filtering input box and retain filtering abilities, please use
10121
- * {@link DataTable.defaults.dom}.
10122
- * @type boolean
10123
- * @default true
10124
- *
10125
- * @dtopt Features
10126
- * @name DataTable.defaults.searching
10127
- *
10128
- * @example
10129
- * $(document).ready( function () {
10130
- * $('#example').dataTable( {
10131
- * "searching": false
10132
- * } );
10133
- * } );
10134
- */
10135
- "bFilter": true,
10136
-
10137
-
10138
- /**
10139
- * Enable or disable the table information display. This shows information
10140
- * about the data that is currently visible on the page, including information
10141
- * about filtered data if that action is being performed.
10142
- * @type boolean
10143
- * @default true
10144
- *
10145
- * @dtopt Features
10146
- * @name DataTable.defaults.info
10147
- *
10148
- * @example
10149
- * $(document).ready( function () {
10150
- * $('#example').dataTable( {
10151
- * "info": false
10152
- * } );
10153
- * } );
10154
- */
10155
- "bInfo": true,
10156
-
10157
-
10158
- /**
10159
- * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
10160
- * slightly different and additional mark-up from what DataTables has
10161
- * traditionally used).
10162
- * @type boolean
10163
- * @default false
10164
- *
10165
- * @dtopt Features
10166
- * @name DataTable.defaults.jQueryUI
10167
- *
10168
- * @example
10169
- * $(document).ready( function() {
10170
- * $('#example').dataTable( {
10171
- * "jQueryUI": true
10172
- * } );
10173
- * } );
10174
- */
10175
- "bJQueryUI": false,
10176
-
10177
-
10178
- /**
10179
- * Allows the end user to select the size of a formatted page from a select
10180
- * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10181
- * @type boolean
10182
- * @default true
10183
- *
10184
- * @dtopt Features
10185
- * @name DataTable.defaults.lengthChange
10186
- *
10187
- * @example
10188
- * $(document).ready( function () {
10189
- * $('#example').dataTable( {
10190
- * "lengthChange": false
10191
- * } );
10192
- * } );
10193
- */
10194
- "bLengthChange": true,
10195
-
10196
-
10197
- /**
10198
- * Enable or disable pagination.
10199
- * @type boolean
10200
- * @default true
10201
- *
10202
- * @dtopt Features
10203
- * @name DataTable.defaults.paging
10204
- *
10205
- * @example
10206
- * $(document).ready( function () {
10207
- * $('#example').dataTable( {
10208
- * "paging": false
10209
- * } );
10210
- * } );
10211
- */
10212
- "bPaginate": true,
10213
-
10214
-
10215
- /**
10216
- * Enable or disable the display of a 'processing' indicator when the table is
10217
- * being processed (e.g. a sort). This is particularly useful for tables with
10218
- * large amounts of data where it can take a noticeable amount of time to sort
10219
- * the entries.
10220
- * @type boolean
10221
- * @default false
10222
- *
10223
- * @dtopt Features
10224
- * @name DataTable.defaults.processing
10225
- *
10226
- * @example
10227
- * $(document).ready( function () {
10228
- * $('#example').dataTable( {
10229
- * "processing": true
10230
- * } );
10231
- * } );
10232
- */
10233
- "bProcessing": false,
10234
-
10235
-
10236
- /**
10237
- * Retrieve the DataTables object for the given selector. Note that if the
10238
- * table has already been initialised, this parameter will cause DataTables
10239
- * to simply return the object that has already been set up - it will not take
10240
- * account of any changes you might have made to the initialisation object
10241
- * passed to DataTables (setting this parameter to true is an acknowledgement
10242
- * that you understand this). `destroy` can be used to reinitialise a table if
10243
- * you need.
10244
- * @type boolean
10245
- * @default false
10246
- *
10247
- * @dtopt Options
10248
- * @name DataTable.defaults.retrieve
10249
- *
10250
- * @example
10251
- * $(document).ready( function() {
10252
- * initTable();
10253
- * tableActions();
10254
- * } );
10255
- *
10256
- * function initTable ()
10257
- * {
10258
- * return $('#example').dataTable( {
10259
- * "scrollY": "200px",
10260
- * "paginate": false,
10261
- * "retrieve": true
10262
- * } );
10263
- * }
10264
- *
10265
- * function tableActions ()
10266
- * {
10267
- * var table = initTable();
10268
- * // perform API operations with oTable
10269
- * }
10270
- */
10271
- "bRetrieve": false,
10272
-
10273
-
10274
- /**
10275
- * When vertical (y) scrolling is enabled, DataTables will force the height of
10276
- * the table's viewport to the given height at all times (useful for layout).
10277
- * However, this can look odd when filtering data down to a small data set,
10278
- * and the footer is left "floating" further down. This parameter (when
10279
- * enabled) will cause DataTables to collapse the table's viewport down when
10280
- * the result set will fit within the given Y height.
10281
- * @type boolean
10282
- * @default false
10283
- *
10284
- * @dtopt Options
10285
- * @name DataTable.defaults.scrollCollapse
10286
- *
10287
- * @example
10288
- * $(document).ready( function() {
10289
- * $('#example').dataTable( {
10290
- * "scrollY": "200",
10291
- * "scrollCollapse": true
10292
- * } );
10293
- * } );
10294
- */
10295
- "bScrollCollapse": false,
10296
-
10297
-
10298
- /**
10299
- * Configure DataTables to use server-side processing. Note that the
10300
- * `ajax` parameter must also be given in order to give DataTables a
10301
- * source to obtain the required data for each draw.
10302
- * @type boolean
10303
- * @default false
10304
- *
10305
- * @dtopt Features
10306
- * @dtopt Server-side
10307
- * @name DataTable.defaults.serverSide
10308
- *
10309
- * @example
10310
- * $(document).ready( function () {
10311
- * $('#example').dataTable( {
10312
- * "serverSide": true,
10313
- * "ajax": "xhr.php"
10314
- * } );
10315
- * } );
10316
- */
10317
- "bServerSide": false,
10318
-
10319
-
10320
- /**
10321
- * Enable or disable sorting of columns. Sorting of individual columns can be
10322
- * disabled by the `sortable` option for each column.
10323
- * @type boolean
10324
- * @default true
10325
- *
10326
- * @dtopt Features
10327
- * @name DataTable.defaults.ordering
10328
- *
10329
- * @example
10330
- * $(document).ready( function () {
10331
- * $('#example').dataTable( {
10332
- * "ordering": false
10333
- * } );
10334
- * } );
10335
- */
10336
- "bSort": true,
10337
-
10338
-
10339
- /**
10340
- * Enable or display DataTables' ability to sort multiple columns at the
10341
- * same time (activated by shift-click by the user).
10342
- * @type boolean
10343
- * @default true
10344
- *
10345
- * @dtopt Options
10346
- * @name DataTable.defaults.orderMulti
10347
- *
10348
- * @example
10349
- * // Disable multiple column sorting ability
10350
- * $(document).ready( function () {
10351
- * $('#example').dataTable( {
10352
- * "orderMulti": false
10353
- * } );
10354
- * } );
10355
- */
10356
- "bSortMulti": true,
10357
-
10358
-
10359
- /**
10360
- * Allows control over whether DataTables should use the top (true) unique
10361
- * cell that is found for a single column, or the bottom (false - default).
10362
- * This is useful when using complex headers.
10363
- * @type boolean
10364
- * @default false
10365
- *
10366
- * @dtopt Options
10367
- * @name DataTable.defaults.orderCellsTop
10368
- *
10369
- * @example
10370
- * $(document).ready( function() {
10371
- * $('#example').dataTable( {
10372
- * "orderCellsTop": true
10373
- * } );
10374
- * } );
10375
- */
10376
- "bSortCellsTop": false,
10377
-
10378
-
10379
- /**
10380
- * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10381
- * `sorting\_3` to the columns which are currently being sorted on. This is
10382
- * presented as a feature switch as it can increase processing time (while
10383
- * classes are removed and added) so for large data sets you might want to
10384
- * turn this off.
10385
- * @type boolean
10386
- * @default true
10387
- *
10388
- * @dtopt Features
10389
- * @name DataTable.defaults.orderClasses
10390
- *
10391
- * @example
10392
- * $(document).ready( function () {
10393
- * $('#example').dataTable( {
10394
- * "orderClasses": false
10395
- * } );
10396
- * } );
10397
- */
10398
- "bSortClasses": true,
10399
-
10400
-
10401
- /**
10402
- * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10403
- * used to save table display information such as pagination information,
10404
- * display length, filtering and sorting. As such when the end user reloads
10405
- * the page the display display will match what thy had previously set up.
10406
- *
10407
- * Due to the use of `localStorage` the default state saving is not supported
10408
- * in IE6 or 7. If state saving is required in those browsers, use
10409
- * `stateSaveCallback` to provide a storage solution such as cookies.
10410
- * @type boolean
10411
- * @default false
10412
- *
10413
- * @dtopt Features
10414
- * @name DataTable.defaults.stateSave
10415
- *
10416
- * @example
10417
- * $(document).ready( function () {
10418
- * $('#example').dataTable( {
10419
- * "stateSave": true
10420
- * } );
10421
- * } );
10422
- */
10423
- "bStateSave": false,
10424
-
10425
-
10426
- /**
10427
- * This function is called when a TR element is created (and all TD child
10428
- * elements have been inserted), or registered if using a DOM source, allowing
10429
- * manipulation of the TR element (adding classes etc).
10430
- * @type function
10431
- * @param {node} row "TR" element for the current row
10432
- * @param {array} data Raw data array for this row
10433
- * @param {int} dataIndex The index of this row in the internal aoData array
10434
- *
10435
- * @dtopt Callbacks
10436
- * @name DataTable.defaults.createdRow
10437
- *
10438
- * @example
10439
- * $(document).ready( function() {
10440
- * $('#example').dataTable( {
10441
- * "createdRow": function( row, data, dataIndex ) {
10442
- * // Bold the grade for all 'A' grade browsers
10443
- * if ( data[4] == "A" )
10444
- * {
10445
- * $('td:eq(4)', row).html( '<b>A</b>' );
10446
- * }
10447
- * }
10448
- * } );
10449
- * } );
10450
- */
10451
- "fnCreatedRow": null,
10452
-
10453
-
10454
- /**
10455
- * This function is called on every 'draw' event, and allows you to
10456
- * dynamically modify any aspect you want about the created DOM.
10457
- * @type function
10458
- * @param {object} settings DataTables settings object
10459
- *
10460
- * @dtopt Callbacks
10461
- * @name DataTable.defaults.drawCallback
10462
- *
10463
- * @example
10464
- * $(document).ready( function() {
10465
- * $('#example').dataTable( {
10466
- * "drawCallback": function( settings ) {
10467
- * alert( 'DataTables has redrawn the table' );
10468
- * }
10469
- * } );
10470
- * } );
10471
- */
10472
- "fnDrawCallback": null,
10473
-
10474
-
10475
- /**
10476
- * Identical to fnHeaderCallback() but for the table footer this function
10477
- * allows you to modify the table footer on every 'draw' event.
10478
- * @type function
10479
- * @param {node} foot "TR" element for the footer
10480
- * @param {array} data Full table data (as derived from the original HTML)
10481
- * @param {int} start Index for the current display starting point in the
10482
- * display array
10483
- * @param {int} end Index for the current display ending point in the
10484
- * display array
10485
- * @param {array int} display Index array to translate the visual position
10486
- * to the full data array
10487
- *
10488
- * @dtopt Callbacks
10489
- * @name DataTable.defaults.footerCallback
10490
- *
10491
- * @example
10492
- * $(document).ready( function() {
10493
- * $('#example').dataTable( {
10494
- * "footerCallback": function( tfoot, data, start, end, display ) {
10495
- * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10496
- * }
10497
- * } );
10498
- * } )
10499
- */
10500
- "fnFooterCallback": null,
10501
-
10502
-
10503
- /**
10504
- * When rendering large numbers in the information element for the table
10505
- * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10506
- * to have a comma separator for the 'thousands' units (e.g. 1 million is
10507
- * rendered as "1,000,000") to help readability for the end user. This
10508
- * function will override the default method DataTables uses.
10509
- * @type function
10510
- * @member
10511
- * @param {int} toFormat number to be formatted
10512
- * @returns {string} formatted string for DataTables to show the number
10513
- *
10514
- * @dtopt Callbacks
10515
- * @name DataTable.defaults.formatNumber
10516
- *
10517
- * @example
10518
- * // Format a number using a single quote for the separator (note that
10519
- * // this can also be done with the language.thousands option)
10520
- * $(document).ready( function() {
10521
- * $('#example').dataTable( {
10522
- * "formatNumber": function ( toFormat ) {
10523
- * return toFormat.toString().replace(
10524
- * /\B(?=(\d{3})+(?!\d))/g, "'"
10525
- * );
10526
- * };
10527
- * } );
10528
- * } );
10529
- */
10530
- "fnFormatNumber": function ( toFormat ) {
10531
- return toFormat.toString().replace(
10532
- /\B(?=(\d{3})+(?!\d))/g,
10533
- this.oLanguage.sThousands
10534
- );
10535
- },
10536
-
10537
-
10538
- /**
10539
- * This function is called on every 'draw' event, and allows you to
10540
- * dynamically modify the header row. This can be used to calculate and
10541
- * display useful information about the table.
10542
- * @type function
10543
- * @param {node} head "TR" element for the header
10544
- * @param {array} data Full table data (as derived from the original HTML)
10545
- * @param {int} start Index for the current display starting point in the
10546
- * display array
10547
- * @param {int} end Index for the current display ending point in the
10548
- * display array
10549
- * @param {array int} display Index array to translate the visual position
10550
- * to the full data array
10551
- *
10552
- * @dtopt Callbacks
10553
- * @name DataTable.defaults.headerCallback
10554
- *
10555
- * @example
10556
- * $(document).ready( function() {
10557
- * $('#example').dataTable( {
10558
- * "fheaderCallback": function( head, data, start, end, display ) {
10559
- * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10560
- * }
10561
- * } );
10562
- * } )
10563
- */
10564
- "fnHeaderCallback": null,
10565
-
10566
-
10567
- /**
10568
- * The information element can be used to convey information about the current
10569
- * state of the table. Although the internationalisation options presented by
10570
- * DataTables are quite capable of dealing with most customisations, there may
10571
- * be times where you wish to customise the string further. This callback
10572
- * allows you to do exactly that.
10573
- * @type function
10574
- * @param {object} oSettings DataTables settings object
10575
- * @param {int} start Starting position in data for the draw
10576
- * @param {int} end End position in data for the draw
10577
- * @param {int} max Total number of rows in the table (regardless of
10578
- * filtering)
10579
- * @param {int} total Total number of rows in the data set, after filtering
10580
- * @param {string} pre The string that DataTables has formatted using it's
10581
- * own rules
10582
- * @returns {string} The string to be displayed in the information element.
10583
- *
10584
- * @dtopt Callbacks
10585
- * @name DataTable.defaults.infoCallback
10586
- *
10587
- * @example
10588
- * $('#example').dataTable( {
10589
- * "infoCallback": function( settings, start, end, max, total, pre ) {
10590
- * return start +" to "+ end;
10591
- * }
10592
- * } );
10593
- */
10594
- "fnInfoCallback": null,
10595
-
10596
-
10597
- /**
10598
- * Called when the table has been initialised. Normally DataTables will
10599
- * initialise sequentially and there will be no need for this function,
10600
- * however, this does not hold true when using external language information
10601
- * since that is obtained using an async XHR call.
10602
- * @type function
10603
- * @param {object} settings DataTables settings object
10604
- * @param {object} json The JSON object request from the server - only
10605
- * present if client-side Ajax sourced data is used
10606
- *
10607
- * @dtopt Callbacks
10608
- * @name DataTable.defaults.initComplete
10609
- *
10610
- * @example
10611
- * $(document).ready( function() {
10612
- * $('#example').dataTable( {
10613
- * "initComplete": function(settings, json) {
10614
- * alert( 'DataTables has finished its initialisation.' );
10615
- * }
10616
- * } );
10617
- * } )
10618
- */
10619
- "fnInitComplete": null,
10620
-
10621
-
10622
- /**
10623
- * Called at the very start of each table draw and can be used to cancel the
10624
- * draw by returning false, any other return (including undefined) results in
10625
- * the full draw occurring).
10626
- * @type function
10627
- * @param {object} settings DataTables settings object
10628
- * @returns {boolean} False will cancel the draw, anything else (including no
10629
- * return) will allow it to complete.
10630
- *
10631
- * @dtopt Callbacks
10632
- * @name DataTable.defaults.preDrawCallback
10633
- *
10634
- * @example
10635
- * $(document).ready( function() {
10636
- * $('#example').dataTable( {
10637
- * "preDrawCallback": function( settings ) {
10638
- * if ( $('#test').val() == 1 ) {
10639
- * return false;
10640
- * }
10641
- * }
10642
- * } );
10643
- * } );
10644
- */
10645
- "fnPreDrawCallback": null,
10646
-
10647
-
10648
- /**
10649
- * This function allows you to 'post process' each row after it have been
10650
- * generated for each table draw, but before it is rendered on screen. This
10651
- * function might be used for setting the row class name etc.
10652
- * @type function
10653
- * @param {node} row "TR" element for the current row
10654
- * @param {array} data Raw data array for this row
10655
- * @param {int} displayIndex The display index for the current table draw
10656
- * @param {int} displayIndexFull The index of the data in the full list of
10657
- * rows (after filtering)
10658
- *
10659
- * @dtopt Callbacks
10660
- * @name DataTable.defaults.rowCallback
10661
- *
10662
- * @example
10663
- * $(document).ready( function() {
10664
- * $('#example').dataTable( {
10665
- * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10666
- * // Bold the grade for all 'A' grade browsers
10667
- * if ( data[4] == "A" ) {
10668
- * $('td:eq(4)', row).html( '<b>A</b>' );
10669
- * }
10670
- * }
10671
- * } );
10672
- * } );
10673
- */
10674
- "fnRowCallback": null,
10675
-
10676
-
10677
- /**
10678
- * __Deprecated__ The functionality provided by this parameter has now been
10679
- * superseded by that provided through `ajax`, which should be used instead.
10680
- *
10681
- * This parameter allows you to override the default function which obtains
10682
- * the data from the server so something more suitable for your application.
10683
- * For example you could use POST data, or pull information from a Gears or
10684
- * AIR database.
10685
- * @type function
10686
- * @member
10687
- * @param {string} source HTTP source to obtain the data from (`ajax`)
10688
- * @param {array} data A key/value pair object containing the data to send
10689
- * to the server
10690
- * @param {function} callback to be called on completion of the data get
10691
- * process that will draw the data on the page.
10692
- * @param {object} settings DataTables settings object
10693
- *
10694
- * @dtopt Callbacks
10695
- * @dtopt Server-side
10696
- * @name DataTable.defaults.serverData
10697
- *
10698
- * @deprecated 1.10. Please use `ajax` for this functionality now.
10699
- */
10700
- "fnServerData": null,
10701
-
10702
-
10703
- /**
10704
- * __Deprecated__ The functionality provided by this parameter has now been
10705
- * superseded by that provided through `ajax`, which should be used instead.
10706
- *
10707
- * It is often useful to send extra data to the server when making an Ajax
10708
- * request - for example custom filtering information, and this callback
10709
- * function makes it trivial to send extra information to the server. The
10710
- * passed in parameter is the data set that has been constructed by
10711
- * DataTables, and you can add to this or modify it as you require.
10712
- * @type function
10713
- * @param {array} data Data array (array of objects which are name/value
10714
- * pairs) that has been constructed by DataTables and will be sent to the
10715
- * server. In the case of Ajax sourced data with server-side processing
10716
- * this will be an empty array, for server-side processing there will be a
10717
- * significant number of parameters!
10718
- * @returns {undefined} Ensure that you modify the data array passed in,
10719
- * as this is passed by reference.
10720
- *
10721
- * @dtopt Callbacks
10722
- * @dtopt Server-side
10723
- * @name DataTable.defaults.serverParams
10724
- *
10725
- * @deprecated 1.10. Please use `ajax` for this functionality now.
10726
- */
10727
- "fnServerParams": null,
10728
-
10729
-
10730
- /**
10731
- * Load the table state. With this function you can define from where, and how, the
10732
- * state of a table is loaded. By default DataTables will load from `localStorage`
10733
- * but you might wish to use a server-side database or cookies.
10734
- * @type function
10735
- * @member
10736
- * @param {object} settings DataTables settings object
10737
- * @return {object} The DataTables state object to be loaded
10738
- *
10739
- * @dtopt Callbacks
10740
- * @name DataTable.defaults.stateLoadCallback
10741
- *
10742
- * @example
10743
- * $(document).ready( function() {
10744
- * $('#example').dataTable( {
10745
- * "stateSave": true,
10746
- * "stateLoadCallback": function (settings) {
10747
- * var o;
10748
- *
10749
- * // Send an Ajax request to the server to get the data. Note that
10750
- * // this is a synchronous request.
10751
- * $.ajax( {
10752
- * "url": "/state_load",
10753
- * "async": false,
10754
- * "dataType": "json",
10755
- * "success": function (json) {
10756
- * o = json;
10757
- * }
10758
- * } );
10759
- *
10760
- * return o;
10761
- * }
10762
- * } );
10763
- * } );
10764
- */
10765
- "fnStateLoadCallback": function ( settings ) {
10766
- try {
10767
- return JSON.parse(
10768
- (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
10769
- 'DataTables_'+settings.sInstance+'_'+location.pathname
10770
- )
10771
- );
10772
- } catch (e) {}
10773
- },
10774
-
10775
-
10776
- /**
10777
- * Callback which allows modification of the saved state prior to loading that state.
10778
- * This callback is called when the table is loading state from the stored data, but
10779
- * prior to the settings object being modified by the saved state. Note that for
10780
- * plug-in authors, you should use the `stateLoadParams` event to load parameters for
10781
- * a plug-in.
10782
- * @type function
10783
- * @param {object} settings DataTables settings object
10784
- * @param {object} data The state object that is to be loaded
10785
- *
10786
- * @dtopt Callbacks
10787
- * @name DataTable.defaults.stateLoadParams
10788
- *
10789
- * @example
10790
- * // Remove a saved filter, so filtering is never loaded
10791
- * $(document).ready( function() {
10792
- * $('#example').dataTable( {
10793
- * "stateSave": true,
10794
- * "stateLoadParams": function (settings, data) {
10795
- * data.oSearch.sSearch = "";
10796
- * }
10797
- * } );
10798
- * } );
10799
- *
10800
- * @example
10801
- * // Disallow state loading by returning false
10802
- * $(document).ready( function() {
10803
- * $('#example').dataTable( {
10804
- * "stateSave": true,
10805
- * "stateLoadParams": function (settings, data) {
10806
- * return false;
10807
- * }
10808
- * } );
10809
- * } );
10810
- */
10811
- "fnStateLoadParams": null,
10812
-
10813
-
10814
- /**
10815
- * Callback that is called when the state has been loaded from the state saving method
10816
- * and the DataTables settings object has been modified as a result of the loaded state.
10817
- * @type function
10818
- * @param {object} settings DataTables settings object
10819
- * @param {object} data The state object that was loaded
10820
- *
10821
- * @dtopt Callbacks
10822
- * @name DataTable.defaults.stateLoaded
10823
- *
10824
- * @example
10825
- * // Show an alert with the filtering value that was saved
10826
- * $(document).ready( function() {
10827
- * $('#example').dataTable( {
10828
- * "stateSave": true,
10829
- * "stateLoaded": function (settings, data) {
10830
- * alert( 'Saved filter was: '+data.oSearch.sSearch );
10831
- * }
10832
- * } );
10833
- * } );
10834
- */
10835
- "fnStateLoaded": null,
10836
-
10837
-
10838
- /**
10839
- * Save the table state. This function allows you to define where and how the state
10840
- * information for the table is stored By default DataTables will use `localStorage`
10841
- * but you might wish to use a server-side database or cookies.
10842
- * @type function
10843
- * @member
10844
- * @param {object} settings DataTables settings object
10845
- * @param {object} data The state object to be saved
10846
- *
10847
- * @dtopt Callbacks
10848
- * @name DataTable.defaults.stateSaveCallback
10849
- *
10850
- * @example
10851
- * $(document).ready( function() {
10852
- * $('#example').dataTable( {
10853
- * "stateSave": true,
10854
- * "stateSaveCallback": function (settings, data) {
10855
- * // Send an Ajax request to the server with the state object
10856
- * $.ajax( {
10857
- * "url": "/state_save",
10858
- * "data": data,
10859
- * "dataType": "json",
10860
- * "method": "POST"
10861
- * "success": function () {}
10862
- * } );
10863
- * }
10864
- * } );
10865
- * } );
10866
- */
10867
- "fnStateSaveCallback": function ( settings, data ) {
10868
- try {
10869
- (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
10870
- 'DataTables_'+settings.sInstance+'_'+location.pathname,
10871
- JSON.stringify( data )
10872
- );
10873
- } catch (e) {}
10874
- },
10875
-
10876
-
10877
- /**
10878
- * Callback which allows modification of the state to be saved. Called when the table
10879
- * has changed state a new state save is required. This method allows modification of
10880
- * the state saving object prior to actually doing the save, including addition or
10881
- * other state properties or modification. Note that for plug-in authors, you should
10882
- * use the `stateSaveParams` event to save parameters for a plug-in.
10883
- * @type function
10884
- * @param {object} settings DataTables settings object
10885
- * @param {object} data The state object to be saved
10886
- *
10887
- * @dtopt Callbacks
10888
- * @name DataTable.defaults.stateSaveParams
10889
- *
10890
- * @example
10891
- * // Remove a saved filter, so filtering is never saved
10892
- * $(document).ready( function() {
10893
- * $('#example').dataTable( {
10894
- * "stateSave": true,
10895
- * "stateSaveParams": function (settings, data) {
10896
- * data.oSearch.sSearch = "";
10897
- * }
10898
- * } );
10899
- * } );
10900
- */
10901
- "fnStateSaveParams": null,
10902
-
10903
-
10904
- /**
10905
- * Duration for which the saved state information is considered valid. After this period
10906
- * has elapsed the state will be returned to the default.
10907
- * Value is given in seconds.
10908
- * @type int
10909
- * @default 7200 <i>(2 hours)</i>
10910
- *
10911
- * @dtopt Options
10912
- * @name DataTable.defaults.stateDuration
10913
- *
10914
- * @example
10915
- * $(document).ready( function() {
10916
- * $('#example').dataTable( {
10917
- * "stateDuration": 60*60*24; // 1 day
10918
- * } );
10919
- * } )
10920
- */
10921
- "iStateDuration": 7200,
10922
-
10923
-
10924
- /**
10925
- * When enabled DataTables will not make a request to the server for the first
10926
- * page draw - rather it will use the data already on the page (no sorting etc
10927
- * will be applied to it), thus saving on an XHR at load time. `deferLoading`
10928
- * is used to indicate that deferred loading is required, but it is also used
10929
- * to tell DataTables how many records there are in the full table (allowing
10930
- * the information element and pagination to be displayed correctly). In the case
10931
- * where a filtering is applied to the table on initial load, this can be
10932
- * indicated by giving the parameter as an array, where the first element is
10933
- * the number of records available after filtering and the second element is the
10934
- * number of records without filtering (allowing the table information element
10935
- * to be shown correctly).
10936
- * @type int | array
10937
- * @default null
10938
- *
10939
- * @dtopt Options
10940
- * @name DataTable.defaults.deferLoading
10941
- *
10942
- * @example
10943
- * // 57 records available in the table, no filtering applied
10944
- * $(document).ready( function() {
10945
- * $('#example').dataTable( {
10946
- * "serverSide": true,
10947
- * "ajax": "scripts/server_processing.php",
10948
- * "deferLoading": 57
10949
- * } );
10950
- * } );
10951
- *
10952
- * @example
10953
- * // 57 records after filtering, 100 without filtering (an initial filter applied)
10954
- * $(document).ready( function() {
10955
- * $('#example').dataTable( {
10956
- * "serverSide": true,
10957
- * "ajax": "scripts/server_processing.php",
10958
- * "deferLoading": [ 57, 100 ],
10959
- * "search": {
10960
- * "search": "my_filter"
10961
- * }
10962
- * } );
10963
- * } );
10964
- */
10965
- "iDeferLoading": null,
10966
-
10967
-
10968
- /**
10969
- * Number of rows to display on a single page when using pagination. If
10970
- * feature enabled (`lengthChange`) then the end user will be able to override
10971
- * this to a custom setting using a pop-up menu.
10972
- * @type int
10973
- * @default 10
10974
- *
10975
- * @dtopt Options
10976
- * @name DataTable.defaults.pageLength
10977
- *
10978
- * @example
10979
- * $(document).ready( function() {
10980
- * $('#example').dataTable( {
10981
- * "pageLength": 50
10982
- * } );
10983
- * } )
10984
- */
10985
- "iDisplayLength": 10,
10986
-
10987
-
10988
- /**
10989
- * Define the starting point for data display when using DataTables with
10990
- * pagination. Note that this parameter is the number of records, rather than
10991
- * the page number, so if you have 10 records per page and want to start on
10992
- * the third page, it should be "20".
10993
- * @type int
10994
- * @default 0
10995
- *
10996
- * @dtopt Options
10997
- * @name DataTable.defaults.displayStart
10998
- *
10999
- * @example
11000
- * $(document).ready( function() {
11001
- * $('#example').dataTable( {
11002
- * "displayStart": 20
11003
- * } );
11004
- * } )
11005
- */
11006
- "iDisplayStart": 0,
11007
-
11008
-
11009
- /**
11010
- * By default DataTables allows keyboard navigation of the table (sorting, paging,
11011
- * and filtering) by adding a `tabindex` attribute to the required elements. This
11012
- * allows you to tab through the controls and press the enter key to activate them.
11013
- * The tabindex is default 0, meaning that the tab follows the flow of the document.
11014
- * You can overrule this using this parameter if you wish. Use a value of -1 to
11015
- * disable built-in keyboard navigation.
11016
- * @type int
11017
- * @default 0
11018
- *
11019
- * @dtopt Options
11020
- * @name DataTable.defaults.tabIndex
11021
- *
11022
- * @example
11023
- * $(document).ready( function() {
11024
- * $('#example').dataTable( {
11025
- * "tabIndex": 1
11026
- * } );
11027
- * } );
11028
- */
11029
- "iTabIndex": 0,
11030
-
11031
-
11032
- /**
11033
- * Classes that DataTables assigns to the various components and features
11034
- * that it adds to the HTML table. This allows classes to be configured
11035
- * during initialisation in addition to through the static
11036
- * {@link DataTable.ext.oStdClasses} object).
11037
- * @namespace
11038
- * @name DataTable.defaults.classes
11039
- */
11040
- "oClasses": {},
11041
-
11042
-
11043
- /**
11044
- * All strings that DataTables uses in the user interface that it creates
11045
- * are defined in this object, allowing you to modified them individually or
11046
- * completely replace them all as required.
11047
- * @namespace
11048
- * @name DataTable.defaults.language
11049
- */
11050
- "oLanguage": {
11051
- /**
11052
- * Strings that are used for WAI-ARIA labels and controls only (these are not
11053
- * actually visible on the page, but will be read by screenreaders, and thus
11054
- * must be internationalised as well).
11055
- * @namespace
11056
- * @name DataTable.defaults.language.aria
11057
- */
11058
- "oAria": {
11059
- /**
11060
- * ARIA label that is added to the table headers when the column may be
11061
- * sorted ascending by activing the column (click or return when focused).
11062
- * Note that the column header is prefixed to this string.
11063
- * @type string
11064
- * @default : activate to sort column ascending
11065
- *
11066
- * @dtopt Language
11067
- * @name DataTable.defaults.language.aria.sortAscending
11068
- *
11069
- * @example
11070
- * $(document).ready( function() {
11071
- * $('#example').dataTable( {
11072
- * "language": {
11073
- * "aria": {
11074
- * "sortAscending": " - click/return to sort ascending"
11075
- * }
11076
- * }
11077
- * } );
11078
- * } );
11079
- */
11080
- "sSortAscending": ": activate to sort column ascending",
11081
-
11082
- /**
11083
- * ARIA label that is added to the table headers when the column may be
11084
- * sorted descending by activing the column (click or return when focused).
11085
- * Note that the column header is prefixed to this string.
11086
- * @type string
11087
- * @default : activate to sort column ascending
11088
- *
11089
- * @dtopt Language
11090
- * @name DataTable.defaults.language.aria.sortDescending
11091
- *
11092
- * @example
11093
- * $(document).ready( function() {
11094
- * $('#example').dataTable( {
11095
- * "language": {
11096
- * "aria": {
11097
- * "sortDescending": " - click/return to sort descending"
11098
- * }
11099
- * }
11100
- * } );
11101
- * } );
11102
- */
11103
- "sSortDescending": ": activate to sort column descending"
11104
- },
11105
-
11106
- /**
11107
- * Pagination string used by DataTables for the built-in pagination
11108
- * control types.
11109
- * @namespace
11110
- * @name DataTable.defaults.language.paginate
11111
- */
11112
- "oPaginate": {
11113
- /**
11114
- * Text to use when using the 'full_numbers' type of pagination for the
11115
- * button to take the user to the first page.
11116
- * @type string
11117
- * @default First
11118
- *
11119
- * @dtopt Language
11120
- * @name DataTable.defaults.language.paginate.first
11121
- *
11122
- * @example
11123
- * $(document).ready( function() {
11124
- * $('#example').dataTable( {
11125
- * "language": {
11126
- * "paginate": {
11127
- * "first": "First page"
11128
- * }
11129
- * }
11130
- * } );
11131
- * } );
11132
- */
11133
- "sFirst": "First",
11134
-
11135
-
11136
- /**
11137
- * Text to use when using the 'full_numbers' type of pagination for the
11138
- * button to take the user to the last page.
11139
- * @type string
11140
- * @default Last
11141
- *
11142
- * @dtopt Language
11143
- * @name DataTable.defaults.language.paginate.last
11144
- *
11145
- * @example
11146
- * $(document).ready( function() {
11147
- * $('#example').dataTable( {
11148
- * "language": {
11149
- * "paginate": {
11150
- * "last": "Last page"
11151
- * }
11152
- * }
11153
- * } );
11154
- * } );
11155
- */
11156
- "sLast": "Last",
11157
-
11158
-
11159
- /**
11160
- * Text to use for the 'next' pagination button (to take the user to the
11161
- * next page).
11162
- * @type string
11163
- * @default Next
11164
- *
11165
- * @dtopt Language
11166
- * @name DataTable.defaults.language.paginate.next
11167
- *
11168
- * @example
11169
- * $(document).ready( function() {
11170
- * $('#example').dataTable( {
11171
- * "language": {
11172
- * "paginate": {
11173
- * "next": "Next page"
11174
- * }
11175
- * }
11176
- * } );
11177
- * } );
11178
- */
11179
- "sNext": "Next",
11180
-
11181
-
11182
- /**
11183
- * Text to use for the 'previous' pagination button (to take the user to
11184
- * the previous page).
11185
- * @type string
11186
- * @default Previous
11187
- *
11188
- * @dtopt Language
11189
- * @name DataTable.defaults.language.paginate.previous
11190
- *
11191
- * @example
11192
- * $(document).ready( function() {
11193
- * $('#example').dataTable( {
11194
- * "language": {
11195
- * "paginate": {
11196
- * "previous": "Previous page"
11197
- * }
11198
- * }
11199
- * } );
11200
- * } );
11201
- */
11202
- "sPrevious": "Previous"
11203
- },
11204
-
11205
- /**
11206
- * This string is shown in preference to `zeroRecords` when the table is
11207
- * empty of data (regardless of filtering). Note that this is an optional
11208
- * parameter - if it is not given, the value of `zeroRecords` will be used
11209
- * instead (either the default or given value).
11210
- * @type string
11211
- * @default No data available in table
11212
- *
11213
- * @dtopt Language
11214
- * @name DataTable.defaults.language.emptyTable
11215
- *
11216
- * @example
11217
- * $(document).ready( function() {
11218
- * $('#example').dataTable( {
11219
- * "language": {
11220
- * "emptyTable": "No data available in table"
11221
- * }
11222
- * } );
11223
- * } );
11224
- */
11225
- "sEmptyTable": "No data available in table",
11226
-
11227
-
11228
- /**
11229
- * This string gives information to the end user about the information
11230
- * that is current on display on the page. The following tokens can be
11231
- * used in the string and will be dynamically replaced as the table
11232
- * display updates. This tokens can be placed anywhere in the string, or
11233
- * removed as needed by the language requires:
11234
- *
11235
- * * `\_START\_` - Display index of the first record on the current page
11236
- * * `\_END\_` - Display index of the last record on the current page
11237
- * * `\_TOTAL\_` - Number of records in the table after filtering
11238
- * * `\_MAX\_` - Number of records in the table without filtering
11239
- * * `\_PAGE\_` - Current page number
11240
- * * `\_PAGES\_` - Total number of pages of data in the table
11241
- *
11242
- * @type string
11243
- * @default Showing _START_ to _END_ of _TOTAL_ entries
11244
- *
11245
- * @dtopt Language
11246
- * @name DataTable.defaults.language.info
11247
- *
11248
- * @example
11249
- * $(document).ready( function() {
11250
- * $('#example').dataTable( {
11251
- * "language": {
11252
- * "info": "Showing page _PAGE_ of _PAGES_"
11253
- * }
11254
- * } );
11255
- * } );
11256
- */
11257
- "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11258
-
11259
-
11260
- /**
11261
- * Display information string for when the table is empty. Typically the
11262
- * format of this string should match `info`.
11263
- * @type string
11264
- * @default Showing 0 to 0 of 0 entries
11265
- *
11266
- * @dtopt Language
11267
- * @name DataTable.defaults.language.infoEmpty
11268
- *
11269
- * @example
11270
- * $(document).ready( function() {
11271
- * $('#example').dataTable( {
11272
- * "language": {
11273
- * "infoEmpty": "No entries to show"
11274
- * }
11275
- * } );
11276
- * } );
11277
- */
11278
- "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11279
-
11280
-
11281
- /**
11282
- * When a user filters the information in a table, this string is appended
11283
- * to the information (`info`) to give an idea of how strong the filtering
11284
- * is. The variable _MAX_ is dynamically updated.
11285
- * @type string
11286
- * @default (filtered from _MAX_ total entries)
11287
- *
11288
- * @dtopt Language
11289
- * @name DataTable.defaults.language.infoFiltered
11290
- *
11291
- * @example
11292
- * $(document).ready( function() {
11293
- * $('#example').dataTable( {
11294
- * "language": {
11295
- * "infoFiltered": " - filtering from _MAX_ records"
11296
- * }
11297
- * } );
11298
- * } );
11299
- */
11300
- "sInfoFiltered": "(filtered from _MAX_ total entries)",
11301
-
11302
-
11303
- /**
11304
- * If can be useful to append extra information to the info string at times,
11305
- * and this variable does exactly that. This information will be appended to
11306
- * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11307
- * being used) at all times.
11308
- * @type string
11309
- * @default <i>Empty string</i>
11310
- *
11311
- * @dtopt Language
11312
- * @name DataTable.defaults.language.infoPostFix
11313
- *
11314
- * @example
11315
- * $(document).ready( function() {
11316
- * $('#example').dataTable( {
11317
- * "language": {
11318
- * "infoPostFix": "All records shown are derived from real information."
11319
- * }
11320
- * } );
11321
- * } );
11322
- */
11323
- "sInfoPostFix": "",
11324
-
11325
-
11326
- /**
11327
- * This decimal place operator is a little different from the other
11328
- * language options since DataTables doesn't output floating point
11329
- * numbers, so it won't ever use this for display of a number. Rather,
11330
- * what this parameter does is modify the sort methods of the table so
11331
- * that numbers which are in a format which has a character other than
11332
- * a period (`.`) as a decimal place will be sorted numerically.
11333
- *
11334
- * Note that numbers with different decimal places cannot be shown in
11335
- * the same table and still be sortable, the table must be consistent.
11336
- * However, multiple different tables on the page can use different
11337
- * decimal place characters.
11338
- * @type string
11339
- * @default
11340
- *
11341
- * @dtopt Language
11342
- * @name DataTable.defaults.language.decimal
11343
- *
11344
- * @example
11345
- * $(document).ready( function() {
11346
- * $('#example').dataTable( {
11347
- * "language": {
11348
- * "decimal": ","
11349
- * "thousands": "."
11350
- * }
11351
- * } );
11352
- * } );
11353
- */
11354
- "sDecimal": "",
11355
-
11356
-
11357
- /**
11358
- * DataTables has a build in number formatter (`formatNumber`) which is
11359
- * used to format large numbers that are used in the table information.
11360
- * By default a comma is used, but this can be trivially changed to any
11361
- * character you wish with this parameter.
11362
- * @type string
11363
- * @default ,
11364
- *
11365
- * @dtopt Language
11366
- * @name DataTable.defaults.language.thousands
11367
- *
11368
- * @example
11369
- * $(document).ready( function() {
11370
- * $('#example').dataTable( {
11371
- * "language": {
11372
- * "thousands": "'"
11373
- * }
11374
- * } );
11375
- * } );
11376
- */
11377
- "sThousands": ",",
11378
-
11379
-
11380
- /**
11381
- * Detail the action that will be taken when the drop down menu for the
11382
- * pagination length option is changed. The '_MENU_' variable is replaced
11383
- * with a default select list of 10, 25, 50 and 100, and can be replaced
11384
- * with a custom select box if required.
11385
- * @type string
11386
- * @default Show _MENU_ entries
11387
- *
11388
- * @dtopt Language
11389
- * @name DataTable.defaults.language.lengthMenu
11390
- *
11391
- * @example
11392
- * // Language change only
11393
- * $(document).ready( function() {
11394
- * $('#example').dataTable( {
11395
- * "language": {
11396
- * "lengthMenu": "Display _MENU_ records"
11397
- * }
11398
- * } );
11399
- * } );
11400
- *
11401
- * @example
11402
- * // Language and options change
11403
- * $(document).ready( function() {
11404
- * $('#example').dataTable( {
11405
- * "language": {
11406
- * "lengthMenu": 'Display <select>'+
11407
- * '<option value="10">10</option>'+
11408
- * '<option value="20">20</option>'+
11409
- * '<option value="30">30</option>'+
11410
- * '<option value="40">40</option>'+
11411
- * '<option value="50">50</option>'+
11412
- * '<option value="-1">All</option>'+
11413
- * '</select> records'
11414
- * }
11415
- * } );
11416
- * } );
11417
- */
11418
- "sLengthMenu": "Show _MENU_ entries",
11419
-
11420
-
11421
- /**
11422
- * When using Ajax sourced data and during the first draw when DataTables is
11423
- * gathering the data, this message is shown in an empty row in the table to
11424
- * indicate to the end user the the data is being loaded. Note that this
11425
- * parameter is not used when loading data by server-side processing, just
11426
- * Ajax sourced data with client-side processing.
11427
- * @type string
11428
- * @default Loading...
11429
- *
11430
- * @dtopt Language
11431
- * @name DataTable.defaults.language.loadingRecords
11432
- *
11433
- * @example
11434
- * $(document).ready( function() {
11435
- * $('#example').dataTable( {
11436
- * "language": {
11437
- * "loadingRecords": "Please wait - loading..."
11438
- * }
11439
- * } );
11440
- * } );
11441
- */
11442
- "sLoadingRecords": "Loading...",
11443
-
11444
-
11445
- /**
11446
- * Text which is displayed when the table is processing a user action
11447
- * (usually a sort command or similar).
11448
- * @type string
11449
- * @default Processing...
11450
- *
11451
- * @dtopt Language
11452
- * @name DataTable.defaults.language.processing
11453
- *
11454
- * @example
11455
- * $(document).ready( function() {
11456
- * $('#example').dataTable( {
11457
- * "language": {
11458
- * "processing": "DataTables is currently busy"
11459
- * }
11460
- * } );
11461
- * } );
11462
- */
11463
- "sProcessing": "Processing...",
11464
-
11465
-
11466
- /**
11467
- * Details the actions that will be taken when the user types into the
11468
- * filtering input text box. The variable "_INPUT_", if used in the string,
11469
- * is replaced with the HTML text box for the filtering input allowing
11470
- * control over where it appears in the string. If "_INPUT_" is not given
11471
- * then the input box is appended to the string automatically.
11472
- * @type string
11473
- * @default Search:
11474
- *
11475
- * @dtopt Language
11476
- * @name DataTable.defaults.language.search
11477
- *
11478
- * @example
11479
- * // Input text box will be appended at the end automatically
11480
- * $(document).ready( function() {
11481
- * $('#example').dataTable( {
11482
- * "language": {
11483
- * "search": "Filter records:"
11484
- * }
11485
- * } );
11486
- * } );
11487
- *
11488
- * @example
11489
- * // Specify where the filter should appear
11490
- * $(document).ready( function() {
11491
- * $('#example').dataTable( {
11492
- * "language": {
11493
- * "search": "Apply filter _INPUT_ to table"
11494
- * }
11495
- * } );
11496
- * } );
11497
- */
11498
- "sSearch": "Search:",
11499
-
11500
-
11501
- /**
11502
- * Assign a `placeholder` attribute to the search `input` element
11503
- * @type string
11504
- * @default
11505
- *
11506
- * @dtopt Language
11507
- * @name DataTable.defaults.language.searchPlaceholder
11508
- */
11509
- "sSearchPlaceholder": "",
11510
-
11511
-
11512
- /**
11513
- * All of the language information can be stored in a file on the
11514
- * server-side, which DataTables will look up if this parameter is passed.
11515
- * It must store the URL of the language file, which is in a JSON format,
11516
- * and the object has the same properties as the oLanguage object in the
11517
- * initialiser object (i.e. the above parameters). Please refer to one of
11518
- * the example language files to see how this works in action.
11519
- * @type string
11520
- * @default <i>Empty string - i.e. disabled</i>
11521
- *
11522
- * @dtopt Language
11523
- * @name DataTable.defaults.language.url
11524
- *
11525
- * @example
11526
- * $(document).ready( function() {
11527
- * $('#example').dataTable( {
11528
- * "language": {
11529
- * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11530
- * }
11531
- * } );
11532
- * } );
11533
- */
11534
- "sUrl": "",
11535
-
11536
-
11537
- /**
11538
- * Text shown inside the table records when the is no information to be
11539
- * displayed after filtering. `emptyTable` is shown when there is simply no
11540
- * information in the table at all (regardless of filtering).
11541
- * @type string
11542
- * @default No matching records found
11543
- *
11544
- * @dtopt Language
11545
- * @name DataTable.defaults.language.zeroRecords
11546
- *
11547
- * @example
11548
- * $(document).ready( function() {
11549
- * $('#example').dataTable( {
11550
- * "language": {
11551
- * "zeroRecords": "No records to display"
11552
- * }
11553
- * } );
11554
- * } );
11555
- */
11556
- "sZeroRecords": "No matching records found"
11557
- },
11558
-
11559
-
11560
- /**
11561
- * This parameter allows you to have define the global filtering state at
11562
- * initialisation time. As an object the `search` parameter must be
11563
- * defined, but all other parameters are optional. When `regex` is true,
11564
- * the search string will be treated as a regular expression, when false
11565
- * (default) it will be treated as a straight string. When `smart`
11566
- * DataTables will use it's smart filtering methods (to word match at
11567
- * any point in the data), when false this will not be done.
11568
- * @namespace
11569
- * @extends DataTable.models.oSearch
11570
- *
11571
- * @dtopt Options
11572
- * @name DataTable.defaults.search
11573
- *
11574
- * @example
11575
- * $(document).ready( function() {
11576
- * $('#example').dataTable( {
11577
- * "search": {"search": "Initial search"}
11578
- * } );
11579
- * } )
11580
- */
11581
- "oSearch": $.extend( {}, DataTable.models.oSearch ),
11582
-
11583
-
11584
- /**
11585
- * __Deprecated__ The functionality provided by this parameter has now been
11586
- * superseded by that provided through `ajax`, which should be used instead.
11587
- *
11588
- * By default DataTables will look for the property `data` (or `aaData` for
11589
- * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11590
- * source or for server-side processing - this parameter allows that
11591
- * property to be changed. You can use Javascript dotted object notation to
11592
- * get a data source for multiple levels of nesting.
11593
- * @type string
11594
- * @default data
11595
- *
11596
- * @dtopt Options
11597
- * @dtopt Server-side
11598
- * @name DataTable.defaults.ajaxDataProp
11599
- *
11600
- * @deprecated 1.10. Please use `ajax` for this functionality now.
11601
- */
11602
- "sAjaxDataProp": "data",
11603
-
11604
-
11605
- /**
11606
- * __Deprecated__ The functionality provided by this parameter has now been
11607
- * superseded by that provided through `ajax`, which should be used instead.
11608
- *
11609
- * You can instruct DataTables to load data from an external
11610
- * source using this parameter (use aData if you want to pass data in you
11611
- * already have). Simply provide a url a JSON object can be obtained from.
11612
- * @type string
11613
- * @default null
11614
- *
11615
- * @dtopt Options
11616
- * @dtopt Server-side
11617
- * @name DataTable.defaults.ajaxSource
11618
- *
11619
- * @deprecated 1.10. Please use `ajax` for this functionality now.
11620
- */
11621
- "sAjaxSource": null,
11622
-
11623
-
11624
- /**
11625
- * This initialisation variable allows you to specify exactly where in the
11626
- * DOM you want DataTables to inject the various controls it adds to the page
11627
- * (for example you might want the pagination controls at the top of the
11628
- * table). DIV elements (with or without a custom class) can also be added to
11629
- * aid styling. The follow syntax is used:
11630
- * <ul>
11631
- * <li>The following options are allowed:
11632
- * <ul>
11633
- * <li>'l' - Length changing</li>
11634
- * <li>'f' - Filtering input</li>
11635
- * <li>'t' - The table!</li>
11636
- * <li>'i' - Information</li>
11637
- * <li>'p' - Pagination</li>
11638
- * <li>'r' - pRocessing</li>
11639
- * </ul>
11640
- * </li>
11641
- * <li>The following constants are allowed:
11642
- * <ul>
11643
- * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11644
- * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11645
- * </ul>
11646
- * </li>
11647
- * <li>The following syntax is expected:
11648
- * <ul>
11649
- * <li>'&lt;' and '&gt;' - div elements</li>
11650
- * <li>'&lt;"class" and '&gt;' - div with a class</li>
11651
- * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11652
- * </ul>
11653
- * </li>
11654
- * <li>Examples:
11655
- * <ul>
11656
- * <li>'&lt;"wrapper"flipt&gt;'</li>
11657
- * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11658
- * </ul>
11659
- * </li>
11660
- * </ul>
11661
- * @type string
11662
- * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11663
- * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11664
- *
11665
- * @dtopt Options
11666
- * @name DataTable.defaults.dom
11667
- *
11668
- * @example
11669
- * $(document).ready( function() {
11670
- * $('#example').dataTable( {
11671
- * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11672
- * } );
11673
- * } );
11674
- */
11675
- "sDom": "lfrtip",
11676
-
11677
-
11678
- /**
11679
- * Search delay option. This will throttle full table searches that use the
11680
- * DataTables provided search input element (it does not effect calls to
11681
- * `dt-api search()`, providing a delay before the search is made.
11682
- * @type integer
11683
- * @default 0
11684
- *
11685
- * @dtopt Options
11686
- * @name DataTable.defaults.searchDelay
11687
- *
11688
- * @example
11689
- * $(document).ready( function() {
11690
- * $('#example').dataTable( {
11691
- * "searchDelay": 200
11692
- * } );
11693
- * } )
11694
- */
11695
- "searchDelay": null,
11696
-
11697
-
11698
- /**
11699
- * DataTables features four different built-in options for the buttons to
11700
- * display for pagination control:
11701
- *
11702
- * * `simple` - 'Previous' and 'Next' buttons only
11703
- * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11704
- * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11705
- * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
11706
- * page numbers
11707
- *
11708
- * Further methods can be added using {@link DataTable.ext.oPagination}.
11709
- * @type string
11710
- * @default simple_numbers
11711
- *
11712
- * @dtopt Options
11713
- * @name DataTable.defaults.pagingType
11714
- *
11715
- * @example
11716
- * $(document).ready( function() {
11717
- * $('#example').dataTable( {
11718
- * "pagingType": "full_numbers"
11719
- * } );
11720
- * } )
11721
- */
11722
- "sPaginationType": "simple_numbers",
11723
-
11724
-
11725
- /**
11726
- * Enable horizontal scrolling. When a table is too wide to fit into a
11727
- * certain layout, or you have a large number of columns in the table, you
11728
- * can enable x-scrolling to show the table in a viewport, which can be
11729
- * scrolled. This property can be `true` which will allow the table to
11730
- * scroll horizontally when needed, or any CSS unit, or a number (in which
11731
- * case it will be treated as a pixel measurement). Setting as simply `true`
11732
- * is recommended.
11733
- * @type boolean|string
11734
- * @default <i>blank string - i.e. disabled</i>
11735
- *
11736
- * @dtopt Features
11737
- * @name DataTable.defaults.scrollX
11738
- *
11739
- * @example
11740
- * $(document).ready( function() {
11741
- * $('#example').dataTable( {
11742
- * "scrollX": true,
11743
- * "scrollCollapse": true
11744
- * } );
11745
- * } );
11746
- */
11747
- "sScrollX": "",
11748
-
11749
-
11750
- /**
11751
- * This property can be used to force a DataTable to use more width than it
11752
- * might otherwise do when x-scrolling is enabled. For example if you have a
11753
- * table which requires to be well spaced, this parameter is useful for
11754
- * "over-sizing" the table, and thus forcing scrolling. This property can by
11755
- * any CSS unit, or a number (in which case it will be treated as a pixel
11756
- * measurement).
11757
- * @type string
11758
- * @default <i>blank string - i.e. disabled</i>
11759
- *
11760
- * @dtopt Options
11761
- * @name DataTable.defaults.scrollXInner
11762
- *
11763
- * @example
11764
- * $(document).ready( function() {
11765
- * $('#example').dataTable( {
11766
- * "scrollX": "100%",
11767
- * "scrollXInner": "110%"
11768
- * } );
11769
- * } );
11770
- */
11771
- "sScrollXInner": "",
11772
-
11773
-
11774
- /**
11775
- * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
11776
- * to the given height, and enable scrolling for any data which overflows the
11777
- * current viewport. This can be used as an alternative to paging to display
11778
- * a lot of data in a small area (although paging and scrolling can both be
11779
- * enabled at the same time). This property can be any CSS unit, or a number
11780
- * (in which case it will be treated as a pixel measurement).
11781
- * @type string
11782
- * @default <i>blank string - i.e. disabled</i>
11783
- *
11784
- * @dtopt Features
11785
- * @name DataTable.defaults.scrollY
11786
- *
11787
- * @example
11788
- * $(document).ready( function() {
11789
- * $('#example').dataTable( {
11790
- * "scrollY": "200px",
11791
- * "paginate": false
11792
- * } );
11793
- * } );
11794
- */
11795
- "sScrollY": "",
11796
-
11797
-
11798
- /**
11799
- * __Deprecated__ The functionality provided by this parameter has now been
11800
- * superseded by that provided through `ajax`, which should be used instead.
11801
- *
11802
- * Set the HTTP method that is used to make the Ajax call for server-side
11803
- * processing or Ajax sourced data.
11804
- * @type string
11805
- * @default GET
11806
- *
11807
- * @dtopt Options
11808
- * @dtopt Server-side
11809
- * @name DataTable.defaults.serverMethod
11810
- *
11811
- * @deprecated 1.10. Please use `ajax` for this functionality now.
11812
- */
11813
- "sServerMethod": "GET",
11814
-
11815
-
11816
- /**
11817
- * DataTables makes use of renderers when displaying HTML elements for
11818
- * a table. These renderers can be added or modified by plug-ins to
11819
- * generate suitable mark-up for a site. For example the Bootstrap
11820
- * integration plug-in for DataTables uses a paging button renderer to
11821
- * display pagination buttons in the mark-up required by Bootstrap.
11822
- *
11823
- * For further information about the renderers available see
11824
- * DataTable.ext.renderer
11825
- * @type string|object
11826
- * @default null
11827
- *
11828
- * @name DataTable.defaults.renderer
11829
- *
11830
- */
11831
- "renderer": null,
11832
-
11833
-
11834
- /**
11835
- * Set the data property name that DataTables should use to get a row's id
11836
- * to set as the `id` property in the node.
11837
- * @type string
11838
- * @default DT_RowId
11839
- *
11840
- * @name DataTable.defaults.rowId
11841
- */
11842
- "rowId": "DT_RowId"
11843
- };
11844
-
11845
- _fnHungarianMap( DataTable.defaults );
11846
-
11847
-
11848
-
11849
- /*
11850
- * Developer note - See note in model.defaults.js about the use of Hungarian
11851
- * notation and camel case.
11852
- */
11853
-
11854
- /**
11855
- * Column options that can be given to DataTables at initialisation time.
11856
- * @namespace
11857
- */
11858
- DataTable.defaults.column = {
11859
- /**
11860
- * Define which column(s) an order will occur on for this column. This
11861
- * allows a column's ordering to take multiple columns into account when
11862
- * doing a sort or use the data from a different column. For example first
11863
- * name / last name columns make sense to do a multi-column sort over the
11864
- * two columns.
11865
- * @type array|int
11866
- * @default null <i>Takes the value of the column index automatically</i>
11867
- *
11868
- * @name DataTable.defaults.column.orderData
11869
- * @dtopt Columns
11870
- *
11871
- * @example
11872
- * // Using `columnDefs`
11873
- * $(document).ready( function() {
11874
- * $('#example').dataTable( {
11875
- * "columnDefs": [
11876
- * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
11877
- * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
11878
- * { "orderData": 2, "targets": [ 2 ] }
11879
- * ]
11880
- * } );
11881
- * } );
11882
- *
11883
- * @example
11884
- * // Using `columns`
11885
- * $(document).ready( function() {
11886
- * $('#example').dataTable( {
11887
- * "columns": [
11888
- * { "orderData": [ 0, 1 ] },
11889
- * { "orderData": [ 1, 0 ] },
11890
- * { "orderData": 2 },
11891
- * null,
11892
- * null
11893
- * ]
11894
- * } );
11895
- * } );
11896
- */
11897
- "aDataSort": null,
11898
- "iDataSort": -1,
11899
-
11900
-
11901
- /**
11902
- * You can control the default ordering direction, and even alter the
11903
- * behaviour of the sort handler (i.e. only allow ascending ordering etc)
11904
- * using this parameter.
11905
- * @type array
11906
- * @default [ 'asc', 'desc' ]
11907
- *
11908
- * @name DataTable.defaults.column.orderSequence
11909
- * @dtopt Columns
11910
- *
11911
- * @example
11912
- * // Using `columnDefs`
11913
- * $(document).ready( function() {
11914
- * $('#example').dataTable( {
11915
- * "columnDefs": [
11916
- * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
11917
- * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
11918
- * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
11919
- * ]
11920
- * } );
11921
- * } );
11922
- *
11923
- * @example
11924
- * // Using `columns`
11925
- * $(document).ready( function() {
11926
- * $('#example').dataTable( {
11927
- * "columns": [
11928
- * null,
11929
- * { "orderSequence": [ "asc" ] },
11930
- * { "orderSequence": [ "desc", "asc", "asc" ] },
11931
- * { "orderSequence": [ "desc" ] },
11932
- * null
11933
- * ]
11934
- * } );
11935
- * } );
11936
- */
11937
- "asSorting": [ 'asc', 'desc' ],
11938
-
11939
-
11940
- /**
11941
- * Enable or disable filtering on the data in this column.
11942
- * @type boolean
11943
- * @default true
11944
- *
11945
- * @name DataTable.defaults.column.searchable
11946
- * @dtopt Columns
11947
- *
11948
- * @example
11949
- * // Using `columnDefs`
11950
- * $(document).ready( function() {
11951
- * $('#example').dataTable( {
11952
- * "columnDefs": [
11953
- * { "searchable": false, "targets": [ 0 ] }
11954
- * ] } );
11955
- * } );
11956
- *
11957
- * @example
11958
- * // Using `columns`
11959
- * $(document).ready( function() {
11960
- * $('#example').dataTable( {
11961
- * "columns": [
11962
- * { "searchable": false },
11963
- * null,
11964
- * null,
11965
- * null,
11966
- * null
11967
- * ] } );
11968
- * } );
11969
- */
11970
- "bSearchable": true,
11971
-
11972
-
11973
- /**
11974
- * Enable or disable ordering on this column.
11975
- * @type boolean
11976
- * @default true
11977
- *
11978
- * @name DataTable.defaults.column.orderable
11979
- * @dtopt Columns
11980
- *
11981
- * @example
11982
- * // Using `columnDefs`
11983
- * $(document).ready( function() {
11984
- * $('#example').dataTable( {
11985
- * "columnDefs": [
11986
- * { "orderable": false, "targets": [ 0 ] }
11987
- * ] } );
11988
- * } );
11989
- *
11990
- * @example
11991
- * // Using `columns`
11992
- * $(document).ready( function() {
11993
- * $('#example').dataTable( {
11994
- * "columns": [
11995
- * { "orderable": false },
11996
- * null,
11997
- * null,
11998
- * null,
11999
- * null
12000
- * ] } );
12001
- * } );
12002
- */
12003
- "bSortable": true,
12004
-
12005
-
12006
- /**
12007
- * Enable or disable the display of this column.
12008
- * @type boolean
12009
- * @default true
12010
- *
12011
- * @name DataTable.defaults.column.visible
12012
- * @dtopt Columns
12013
- *
12014
- * @example
12015
- * // Using `columnDefs`
12016
- * $(document).ready( function() {
12017
- * $('#example').dataTable( {
12018
- * "columnDefs": [
12019
- * { "visible": false, "targets": [ 0 ] }
12020
- * ] } );
12021
- * } );
12022
- *
12023
- * @example
12024
- * // Using `columns`
12025
- * $(document).ready( function() {
12026
- * $('#example').dataTable( {
12027
- * "columns": [
12028
- * { "visible": false },
12029
- * null,
12030
- * null,
12031
- * null,
12032
- * null
12033
- * ] } );
12034
- * } );
12035
- */
12036
- "bVisible": true,
12037
-
12038
-
12039
- /**
12040
- * Developer definable function that is called whenever a cell is created (Ajax source,
12041
- * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12042
- * allowing you to modify the DOM element (add background colour for example) when the
12043
- * element is available.
12044
- * @type function
12045
- * @param {element} td The TD node that has been created
12046
- * @param {*} cellData The Data for the cell
12047
- * @param {array|object} rowData The data for the whole row
12048
- * @param {int} row The row index for the aoData data store
12049
- * @param {int} col The column index for aoColumns
12050
- *
12051
- * @name DataTable.defaults.column.createdCell
12052
- * @dtopt Columns
12053
- *
12054
- * @example
12055
- * $(document).ready( function() {
12056
- * $('#example').dataTable( {
12057
- * "columnDefs": [ {
12058
- * "targets": [3],
12059
- * "createdCell": function (td, cellData, rowData, row, col) {
12060
- * if ( cellData == "1.7" ) {
12061
- * $(td).css('color', 'blue')
12062
- * }
12063
- * }
12064
- * } ]
12065
- * });
12066
- * } );
12067
- */
12068
- "fnCreatedCell": null,
12069
-
12070
-
12071
- /**
12072
- * This parameter has been replaced by `data` in DataTables to ensure naming
12073
- * consistency. `dataProp` can still be used, as there is backwards
12074
- * compatibility in DataTables for this option, but it is strongly
12075
- * recommended that you use `data` in preference to `dataProp`.
12076
- * @name DataTable.defaults.column.dataProp
12077
- */
12078
-
12079
-
12080
- /**
12081
- * This property can be used to read data from any data source property,
12082
- * including deeply nested objects / properties. `data` can be given in a
12083
- * number of different ways which effect its behaviour:
12084
- *
12085
- * * `integer` - treated as an array index for the data source. This is the
12086
- * default that DataTables uses (incrementally increased for each column).
12087
- * * `string` - read an object property from the data source. There are
12088
- * three 'special' options that can be used in the string to alter how
12089
- * DataTables reads the data from the source object:
12090
- * * `.` - Dotted Javascript notation. Just as you use a `.` in
12091
- * Javascript to read from nested objects, so to can the options
12092
- * specified in `data`. For example: `browser.version` or
12093
- * `browser.name`. If your object parameter name contains a period, use
12094
- * `\\` to escape it - i.e. `first\\.name`.
12095
- * * `[]` - Array notation. DataTables can automatically combine data
12096
- * from and array source, joining the data with the characters provided
12097
- * between the two brackets. For example: `name[, ]` would provide a
12098
- * comma-space separated list from the source array. If no characters
12099
- * are provided between the brackets, the original array source is
12100
- * returned.
12101
- * * `()` - Function notation. Adding `()` to the end of a parameter will
12102
- * execute a function of the name given. For example: `browser()` for a
12103
- * simple function on the data source, `browser.version()` for a
12104
- * function in a nested property or even `browser().version` to get an
12105
- * object property if the function called returns an object. Note that
12106
- * function notation is recommended for use in `render` rather than
12107
- * `data` as it is much simpler to use as a renderer.
12108
- * * `null` - use the original data source for the row rather than plucking
12109
- * data directly from it. This action has effects on two other
12110
- * initialisation options:
12111
- * * `defaultContent` - When null is given as the `data` option and
12112
- * `defaultContent` is specified for the column, the value defined by
12113
- * `defaultContent` will be used for the cell.
12114
- * * `render` - When null is used for the `data` option and the `render`
12115
- * option is specified for the column, the whole data source for the
12116
- * row is used for the renderer.
12117
- * * `function` - the function given will be executed whenever DataTables
12118
- * needs to set or get the data for a cell in the column. The function
12119
- * takes three parameters:
12120
- * * Parameters:
12121
- * * `{array|object}` The data source for the row
12122
- * * `{string}` The type call data requested - this will be 'set' when
12123
- * setting data or 'filter', 'display', 'type', 'sort' or undefined
12124
- * when gathering data. Note that when `undefined` is given for the
12125
- * type DataTables expects to get the raw data for the object back<
12126
- * * `{*}` Data to set when the second parameter is 'set'.
12127
- * * Return:
12128
- * * The return value from the function is not required when 'set' is
12129
- * the type of call, but otherwise the return is what will be used
12130
- * for the data requested.
12131
- *
12132
- * Note that `data` is a getter and setter option. If you just require
12133
- * formatting of data for output, you will likely want to use `render` which
12134
- * is simply a getter and thus simpler to use.
12135
- *
12136
- * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12137
- * name change reflects the flexibility of this property and is consistent
12138
- * with the naming of mRender. If 'mDataProp' is given, then it will still
12139
- * be used by DataTables, as it automatically maps the old name to the new
12140
- * if required.
12141
- *
12142
- * @type string|int|function|null
12143
- * @default null <i>Use automatically calculated column index</i>
12144
- *
12145
- * @name DataTable.defaults.column.data
12146
- * @dtopt Columns
12147
- *
12148
- * @example
12149
- * // Read table data from objects
12150
- * // JSON structure for each row:
12151
- * // {
12152
- * // "engine": {value},
12153
- * // "browser": {value},
12154
- * // "platform": {value},
12155
- * // "version": {value},
12156
- * // "grade": {value}
12157
- * // }
12158
- * $(document).ready( function() {
12159
- * $('#example').dataTable( {
12160
- * "ajaxSource": "sources/objects.txt",
12161
- * "columns": [
12162
- * { "data": "engine" },
12163
- * { "data": "browser" },
12164
- * { "data": "platform" },
12165
- * { "data": "version" },
12166
- * { "data": "grade" }
12167
- * ]
12168
- * } );
12169
- * } );
12170
- *
12171
- * @example
12172
- * // Read information from deeply nested objects
12173
- * // JSON structure for each row:
12174
- * // {
12175
- * // "engine": {value},
12176
- * // "browser": {value},
12177
- * // "platform": {
12178
- * // "inner": {value}
12179
- * // },
12180
- * // "details": [
12181
- * // {value}, {value}
12182
- * // ]
12183
- * // }
12184
- * $(document).ready( function() {
12185
- * $('#example').dataTable( {
12186
- * "ajaxSource": "sources/deep.txt",
12187
- * "columns": [
12188
- * { "data": "engine" },
12189
- * { "data": "browser" },
12190
- * { "data": "platform.inner" },
12191
- * { "data": "platform.details.0" },
12192
- * { "data": "platform.details.1" }
12193
- * ]
12194
- * } );
12195
- * } );
12196
- *
12197
- * @example
12198
- * // Using `data` as a function to provide different information for
12199
- * // sorting, filtering and display. In this case, currency (price)
12200
- * $(document).ready( function() {
12201
- * $('#example').dataTable( {
12202
- * "columnDefs": [ {
12203
- * "targets": [ 0 ],
12204
- * "data": function ( source, type, val ) {
12205
- * if (type === 'set') {
12206
- * source.price = val;
12207
- * // Store the computed dislay and filter values for efficiency
12208
- * source.price_display = val=="" ? "" : "$"+numberFormat(val);
12209
- * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12210
- * return;
12211
- * }
12212
- * else if (type === 'display') {
12213
- * return source.price_display;
12214
- * }
12215
- * else if (type === 'filter') {
12216
- * return source.price_filter;
12217
- * }
12218
- * // 'sort', 'type' and undefined all just use the integer
12219
- * return source.price;
12220
- * }
12221
- * } ]
12222
- * } );
12223
- * } );
12224
- *
12225
- * @example
12226
- * // Using default content
12227
- * $(document).ready( function() {
12228
- * $('#example').dataTable( {
12229
- * "columnDefs": [ {
12230
- * "targets": [ 0 ],
12231
- * "data": null,
12232
- * "defaultContent": "Click to edit"
12233
- * } ]
12234
- * } );
12235
- * } );
12236
- *
12237
- * @example
12238
- * // Using array notation - outputting a list from an array
12239
- * $(document).ready( function() {
12240
- * $('#example').dataTable( {
12241
- * "columnDefs": [ {
12242
- * "targets": [ 0 ],
12243
- * "data": "name[, ]"
12244
- * } ]
12245
- * } );
12246
- * } );
12247
- *
12248
- */
12249
- "mData": null,
12250
-
12251
-
12252
- /**
12253
- * This property is the rendering partner to `data` and it is suggested that
12254
- * when you want to manipulate data for display (including filtering,
12255
- * sorting etc) without altering the underlying data for the table, use this
12256
- * property. `render` can be considered to be the the read only companion to
12257
- * `data` which is read / write (then as such more complex). Like `data`
12258
- * this option can be given in a number of different ways to effect its
12259
- * behaviour:
12260
- *
12261
- * * `integer` - treated as an array index for the data source. This is the
12262
- * default that DataTables uses (incrementally increased for each column).
12263
- * * `string` - read an object property from the data source. There are
12264
- * three 'special' options that can be used in the string to alter how
12265
- * DataTables reads the data from the source object:
12266
- * * `.` - Dotted Javascript notation. Just as you use a `.` in
12267
- * Javascript to read from nested objects, so to can the options
12268
- * specified in `data`. For example: `browser.version` or
12269
- * `browser.name`. If your object parameter name contains a period, use
12270
- * `\\` to escape it - i.e. `first\\.name`.
12271
- * * `[]` - Array notation. DataTables can automatically combine data
12272
- * from and array source, joining the data with the characters provided
12273
- * between the two brackets. For example: `name[, ]` would provide a
12274
- * comma-space separated list from the source array. If no characters
12275
- * are provided between the brackets, the original array source is
12276
- * returned.
12277
- * * `()` - Function notation. Adding `()` to the end of a parameter will
12278
- * execute a function of the name given. For example: `browser()` for a
12279
- * simple function on the data source, `browser.version()` for a
12280
- * function in a nested property or even `browser().version` to get an
12281
- * object property if the function called returns an object.
12282
- * * `object` - use different data for the different data types requested by
12283
- * DataTables ('filter', 'display', 'type' or 'sort'). The property names
12284
- * of the object is the data type the property refers to and the value can
12285
- * defined using an integer, string or function using the same rules as
12286
- * `render` normally does. Note that an `_` option _must_ be specified.
12287
- * This is the default value to use if you haven't specified a value for
12288
- * the data type requested by DataTables.
12289
- * * `function` - the function given will be executed whenever DataTables
12290
- * needs to set or get the data for a cell in the column. The function
12291
- * takes three parameters:
12292
- * * Parameters:
12293
- * * {array|object} The data source for the row (based on `data`)
12294
- * * {string} The type call data requested - this will be 'filter',
12295
- * 'display', 'type' or 'sort'.
12296
- * * {array|object} The full data source for the row (not based on
12297
- * `data`)
12298
- * * Return:
12299
- * * The return value from the function is what will be used for the
12300
- * data requested.
12301
- *
12302
- * @type string|int|function|object|null
12303
- * @default null Use the data source value.
12304
- *
12305
- * @name DataTable.defaults.column.render
12306
- * @dtopt Columns
12307
- *
12308
- * @example
12309
- * // Create a comma separated list from an array of objects
12310
- * $(document).ready( function() {
12311
- * $('#example').dataTable( {
12312
- * "ajaxSource": "sources/deep.txt",
12313
- * "columns": [
12314
- * { "data": "engine" },
12315
- * { "data": "browser" },
12316
- * {
12317
- * "data": "platform",
12318
- * "render": "[, ].name"
12319
- * }
12320
- * ]
12321
- * } );
12322
- * } );
12323
- *
12324
- * @example
12325
- * // Execute a function to obtain data
12326
- * $(document).ready( function() {
12327
- * $('#example').dataTable( {
12328
- * "columnDefs": [ {
12329
- * "targets": [ 0 ],
12330
- * "data": null, // Use the full data source object for the renderer's source
12331
- * "render": "browserName()"
12332
- * } ]
12333
- * } );
12334
- * } );
12335
- *
12336
- * @example
12337
- * // As an object, extracting different data for the different types
12338
- * // This would be used with a data source such as:
12339
- * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12340
- * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12341
- * // (which has both forms) is used for filtering for if a user inputs either format, while
12342
- * // the formatted phone number is the one that is shown in the table.
12343
- * $(document).ready( function() {
12344
- * $('#example').dataTable( {
12345
- * "columnDefs": [ {
12346
- * "targets": [ 0 ],
12347
- * "data": null, // Use the full data source object for the renderer's source
12348
- * "render": {
12349
- * "_": "phone",
12350
- * "filter": "phone_filter",
12351
- * "display": "phone_display"
12352
- * }
12353
- * } ]
12354
- * } );
12355
- * } );
12356
- *
12357
- * @example
12358
- * // Use as a function to create a link from the data source
12359
- * $(document).ready( function() {
12360
- * $('#example').dataTable( {
12361
- * "columnDefs": [ {
12362
- * "targets": [ 0 ],
12363
- * "data": "download_link",
12364
- * "render": function ( data, type, full ) {
12365
- * return '<a href="'+data+'">Download</a>';
12366
- * }
12367
- * } ]
12368
- * } );
12369
- * } );
12370
- */
12371
- "mRender": null,
12372
-
12373
-
12374
- /**
12375
- * Change the cell type created for the column - either TD cells or TH cells. This
12376
- * can be useful as TH cells have semantic meaning in the table body, allowing them
12377
- * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12378
- * @type string
12379
- * @default td
12380
- *
12381
- * @name DataTable.defaults.column.cellType
12382
- * @dtopt Columns
12383
- *
12384
- * @example
12385
- * // Make the first column use TH cells
12386
- * $(document).ready( function() {
12387
- * $('#example').dataTable( {
12388
- * "columnDefs": [ {
12389
- * "targets": [ 0 ],
12390
- * "cellType": "th"
12391
- * } ]
12392
- * } );
12393
- * } );
12394
- */
12395
- "sCellType": "td",
12396
-
12397
-
12398
- /**
12399
- * Class to give to each cell in this column.
12400
- * @type string
12401
- * @default <i>Empty string</i>
12402
- *
12403
- * @name DataTable.defaults.column.class
12404
- * @dtopt Columns
12405
- *
12406
- * @example
12407
- * // Using `columnDefs`
12408
- * $(document).ready( function() {
12409
- * $('#example').dataTable( {
12410
- * "columnDefs": [
12411
- * { "class": "my_class", "targets": [ 0 ] }
12412
- * ]
12413
- * } );
12414
- * } );
12415
- *
12416
- * @example
12417
- * // Using `columns`
12418
- * $(document).ready( function() {
12419
- * $('#example').dataTable( {
12420
- * "columns": [
12421
- * { "class": "my_class" },
12422
- * null,
12423
- * null,
12424
- * null,
12425
- * null
12426
- * ]
12427
- * } );
12428
- * } );
12429
- */
12430
- "sClass": "",
12431
-
12432
- /**
12433
- * When DataTables calculates the column widths to assign to each column,
12434
- * it finds the longest string in each column and then constructs a
12435
- * temporary table and reads the widths from that. The problem with this
12436
- * is that "mmm" is much wider then "iiii", but the latter is a longer
12437
- * string - thus the calculation can go wrong (doing it properly and putting
12438
- * it into an DOM object and measuring that is horribly(!) slow). Thus as
12439
- * a "work around" we provide this option. It will append its value to the
12440
- * text that is found to be the longest string for the column - i.e. padding.
12441
- * Generally you shouldn't need this!
12442
- * @type string
12443
- * @default <i>Empty string<i>
12444
- *
12445
- * @name DataTable.defaults.column.contentPadding
12446
- * @dtopt Columns
12447
- *
12448
- * @example
12449
- * // Using `columns`
12450
- * $(document).ready( function() {
12451
- * $('#example').dataTable( {
12452
- * "columns": [
12453
- * null,
12454
- * null,
12455
- * null,
12456
- * {
12457
- * "contentPadding": "mmm"
12458
- * }
12459
- * ]
12460
- * } );
12461
- * } );
12462
- */
12463
- "sContentPadding": "",
12464
-
12465
-
12466
- /**
12467
- * Allows a default value to be given for a column's data, and will be used
12468
- * whenever a null data source is encountered (this can be because `data`
12469
- * is set to null, or because the data source itself is null).
12470
- * @type string
12471
- * @default null
12472
- *
12473
- * @name DataTable.defaults.column.defaultContent
12474
- * @dtopt Columns
12475
- *
12476
- * @example
12477
- * // Using `columnDefs`
12478
- * $(document).ready( function() {
12479
- * $('#example').dataTable( {
12480
- * "columnDefs": [
12481
- * {
12482
- * "data": null,
12483
- * "defaultContent": "Edit",
12484
- * "targets": [ -1 ]
12485
- * }
12486
- * ]
12487
- * } );
12488
- * } );
12489
- *
12490
- * @example
12491
- * // Using `columns`
12492
- * $(document).ready( function() {
12493
- * $('#example').dataTable( {
12494
- * "columns": [
12495
- * null,
12496
- * null,
12497
- * null,
12498
- * {
12499
- * "data": null,
12500
- * "defaultContent": "Edit"
12501
- * }
12502
- * ]
12503
- * } );
12504
- * } );
12505
- */
12506
- "sDefaultContent": null,
12507
-
12508
-
12509
- /**
12510
- * This parameter is only used in DataTables' server-side processing. It can
12511
- * be exceptionally useful to know what columns are being displayed on the
12512
- * client side, and to map these to database fields. When defined, the names
12513
- * also allow DataTables to reorder information from the server if it comes
12514
- * back in an unexpected order (i.e. if you switch your columns around on the
12515
- * client-side, your server-side code does not also need updating).
12516
- * @type string
12517
- * @default <i>Empty string</i>
12518
- *
12519
- * @name DataTable.defaults.column.name
12520
- * @dtopt Columns
12521
- *
12522
- * @example
12523
- * // Using `columnDefs`
12524
- * $(document).ready( function() {
12525
- * $('#example').dataTable( {
12526
- * "columnDefs": [
12527
- * { "name": "engine", "targets": [ 0 ] },
12528
- * { "name": "browser", "targets": [ 1 ] },
12529
- * { "name": "platform", "targets": [ 2 ] },
12530
- * { "name": "version", "targets": [ 3 ] },
12531
- * { "name": "grade", "targets": [ 4 ] }
12532
- * ]
12533
- * } );
12534
- * } );
12535
- *
12536
- * @example
12537
- * // Using `columns`
12538
- * $(document).ready( function() {
12539
- * $('#example').dataTable( {
12540
- * "columns": [
12541
- * { "name": "engine" },
12542
- * { "name": "browser" },
12543
- * { "name": "platform" },
12544
- * { "name": "version" },
12545
- * { "name": "grade" }
12546
- * ]
12547
- * } );
12548
- * } );
12549
- */
12550
- "sName": "",
12551
-
12552
-
12553
- /**
12554
- * Defines a data source type for the ordering which can be used to read
12555
- * real-time information from the table (updating the internally cached
12556
- * version) prior to ordering. This allows ordering to occur on user
12557
- * editable elements such as form inputs.
12558
- * @type string
12559
- * @default std
12560
- *
12561
- * @name DataTable.defaults.column.orderDataType
12562
- * @dtopt Columns
12563
- *
12564
- * @example
12565
- * // Using `columnDefs`
12566
- * $(document).ready( function() {
12567
- * $('#example').dataTable( {
12568
- * "columnDefs": [
12569
- * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12570
- * { "type": "numeric", "targets": [ 3 ] },
12571
- * { "orderDataType": "dom-select", "targets": [ 4 ] },
12572
- * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12573
- * ]
12574
- * } );
12575
- * } );
12576
- *
12577
- * @example
12578
- * // Using `columns`
12579
- * $(document).ready( function() {
12580
- * $('#example').dataTable( {
12581
- * "columns": [
12582
- * null,
12583
- * null,
12584
- * { "orderDataType": "dom-text" },
12585
- * { "orderDataType": "dom-text", "type": "numeric" },
12586
- * { "orderDataType": "dom-select" },
12587
- * { "orderDataType": "dom-checkbox" }
12588
- * ]
12589
- * } );
12590
- * } );
12591
- */
12592
- "sSortDataType": "std",
12593
-
12594
-
12595
- /**
12596
- * The title of this column.
12597
- * @type string
12598
- * @default null <i>Derived from the 'TH' value for this column in the
12599
- * original HTML table.</i>
12600
- *
12601
- * @name DataTable.defaults.column.title
12602
- * @dtopt Columns
12603
- *
12604
- * @example
12605
- * // Using `columnDefs`
12606
- * $(document).ready( function() {
12607
- * $('#example').dataTable( {
12608
- * "columnDefs": [
12609
- * { "title": "My column title", "targets": [ 0 ] }
12610
- * ]
12611
- * } );
12612
- * } );
12613
- *
12614
- * @example
12615
- * // Using `columns`
12616
- * $(document).ready( function() {
12617
- * $('#example').dataTable( {
12618
- * "columns": [
12619
- * { "title": "My column title" },
12620
- * null,
12621
- * null,
12622
- * null,
12623
- * null
12624
- * ]
12625
- * } );
12626
- * } );
12627
- */
12628
- "sTitle": null,
12629
-
12630
-
12631
- /**
12632
- * The type allows you to specify how the data for this column will be
12633
- * ordered. Four types (string, numeric, date and html (which will strip
12634
- * HTML tags before ordering)) are currently available. Note that only date
12635
- * formats understood by Javascript's Date() object will be accepted as type
12636
- * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12637
- * 'numeric', 'date' or 'html' (by default). Further types can be adding
12638
- * through plug-ins.
12639
- * @type string
12640
- * @default null <i>Auto-detected from raw data</i>
12641
- *
12642
- * @name DataTable.defaults.column.type
12643
- * @dtopt Columns
12644
- *
12645
- * @example
12646
- * // Using `columnDefs`
12647
- * $(document).ready( function() {
12648
- * $('#example').dataTable( {
12649
- * "columnDefs": [
12650
- * { "type": "html", "targets": [ 0 ] }
12651
- * ]
12652
- * } );
12653
- * } );
12654
- *
12655
- * @example
12656
- * // Using `columns`
12657
- * $(document).ready( function() {
12658
- * $('#example').dataTable( {
12659
- * "columns": [
12660
- * { "type": "html" },
12661
- * null,
12662
- * null,
12663
- * null,
12664
- * null
12665
- * ]
12666
- * } );
12667
- * } );
12668
- */
12669
- "sType": null,
12670
-
12671
-
12672
- /**
12673
- * Defining the width of the column, this parameter may take any CSS value
12674
- * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12675
- * been given a specific width through this interface ensuring that the table
12676
- * remains readable.
12677
- * @type string
12678
- * @default null <i>Automatic</i>
12679
- *
12680
- * @name DataTable.defaults.column.width
12681
- * @dtopt Columns
12682
- *
12683
- * @example
12684
- * // Using `columnDefs`
12685
- * $(document).ready( function() {
12686
- * $('#example').dataTable( {
12687
- * "columnDefs": [
12688
- * { "width": "20%", "targets": [ 0 ] }
12689
- * ]
12690
- * } );
12691
- * } );
12692
- *
12693
- * @example
12694
- * // Using `columns`
12695
- * $(document).ready( function() {
12696
- * $('#example').dataTable( {
12697
- * "columns": [
12698
- * { "width": "20%" },
12699
- * null,
12700
- * null,
12701
- * null,
12702
- * null
12703
- * ]
12704
- * } );
12705
- * } );
12706
- */
12707
- "sWidth": null
12708
- };
12709
-
12710
- _fnHungarianMap( DataTable.defaults.column );
12711
-
12712
-
12713
-
12714
- /**
12715
- * DataTables settings object - this holds all the information needed for a
12716
- * given table, including configuration, data and current application of the
12717
- * table options. DataTables does not have a single instance for each DataTable
12718
- * with the settings attached to that instance, but rather instances of the
12719
- * DataTable "class" are created on-the-fly as needed (typically by a
12720
- * $().dataTable() call) and the settings object is then applied to that
12721
- * instance.
12722
- *
12723
- * Note that this object is related to {@link DataTable.defaults} but this
12724
- * one is the internal data store for DataTables's cache of columns. It should
12725
- * NOT be manipulated outside of DataTables. Any configuration should be done
12726
- * through the initialisation options.
12727
- * @namespace
12728
- * @todo Really should attach the settings object to individual instances so we
12729
- * don't need to create new instances on each $().dataTable() call (if the
12730
- * table already exists). It would also save passing oSettings around and
12731
- * into every single function. However, this is a very significant
12732
- * architecture change for DataTables and will almost certainly break
12733
- * backwards compatibility with older installations. This is something that
12734
- * will be done in 2.0.
12735
- */
12736
- DataTable.models.oSettings = {
12737
- /**
12738
- * Primary features of DataTables and their enablement state.
12739
- * @namespace
12740
- */
12741
- "oFeatures": {
12742
-
12743
- /**
12744
- * Flag to say if DataTables should automatically try to calculate the
12745
- * optimum table and columns widths (true) or not (false).
12746
- * Note that this parameter will be set by the initialisation routine. To
12747
- * set a default use {@link DataTable.defaults}.
12748
- * @type boolean
12749
- */
12750
- "bAutoWidth": null,
12751
-
12752
- /**
12753
- * Delay the creation of TR and TD elements until they are actually
12754
- * needed by a driven page draw. This can give a significant speed
12755
- * increase for Ajax source and Javascript source data, but makes no
12756
- * difference at all fro DOM and server-side processing tables.
12757
- * Note that this parameter will be set by the initialisation routine. To
12758
- * set a default use {@link DataTable.defaults}.
12759
- * @type boolean
12760
- */
12761
- "bDeferRender": null,
12762
-
12763
- /**
12764
- * Enable filtering on the table or not. Note that if this is disabled
12765
- * then there is no filtering at all on the table, including fnFilter.
12766
- * To just remove the filtering input use sDom and remove the 'f' option.
12767
- * Note that this parameter will be set by the initialisation routine. To
12768
- * set a default use {@link DataTable.defaults}.
12769
- * @type boolean
12770
- */
12771
- "bFilter": null,
12772
-
12773
- /**
12774
- * Table information element (the 'Showing x of y records' div) enable
12775
- * flag.
12776
- * Note that this parameter will be set by the initialisation routine. To
12777
- * set a default use {@link DataTable.defaults}.
12778
- * @type boolean
12779
- */
12780
- "bInfo": null,
12781
-
12782
- /**
12783
- * Present a user control allowing the end user to change the page size
12784
- * when pagination is enabled.
12785
- * Note that this parameter will be set by the initialisation routine. To
12786
- * set a default use {@link DataTable.defaults}.
12787
- * @type boolean
12788
- */
12789
- "bLengthChange": null,
12790
-
12791
- /**
12792
- * Pagination enabled or not. Note that if this is disabled then length
12793
- * changing must also be disabled.
12794
- * Note that this parameter will be set by the initialisation routine. To
12795
- * set a default use {@link DataTable.defaults}.
12796
- * @type boolean
12797
- */
12798
- "bPaginate": null,
12799
-
12800
- /**
12801
- * Processing indicator enable flag whenever DataTables is enacting a
12802
- * user request - typically an Ajax request for server-side processing.
12803
- * Note that this parameter will be set by the initialisation routine. To
12804
- * set a default use {@link DataTable.defaults}.
12805
- * @type boolean
12806
- */
12807
- "bProcessing": null,
12808
-
12809
- /**
12810
- * Server-side processing enabled flag - when enabled DataTables will
12811
- * get all data from the server for every draw - there is no filtering,
12812
- * sorting or paging done on the client-side.
12813
- * Note that this parameter will be set by the initialisation routine. To
12814
- * set a default use {@link DataTable.defaults}.
12815
- * @type boolean
12816
- */
12817
- "bServerSide": null,
12818
-
12819
- /**
12820
- * Sorting enablement flag.
12821
- * Note that this parameter will be set by the initialisation routine. To
12822
- * set a default use {@link DataTable.defaults}.
12823
- * @type boolean
12824
- */
12825
- "bSort": null,
12826
-
12827
- /**
12828
- * Multi-column sorting
12829
- * Note that this parameter will be set by the initialisation routine. To
12830
- * set a default use {@link DataTable.defaults}.
12831
- * @type boolean
12832
- */
12833
- "bSortMulti": null,
12834
-
12835
- /**
12836
- * Apply a class to the columns which are being sorted to provide a
12837
- * visual highlight or not. This can slow things down when enabled since
12838
- * there is a lot of DOM interaction.
12839
- * Note that this parameter will be set by the initialisation routine. To
12840
- * set a default use {@link DataTable.defaults}.
12841
- * @type boolean
12842
- */
12843
- "bSortClasses": null,
12844
-
12845
- /**
12846
- * State saving enablement flag.
12847
- * Note that this parameter will be set by the initialisation routine. To
12848
- * set a default use {@link DataTable.defaults}.
12849
- * @type boolean
12850
- */
12851
- "bStateSave": null
12852
- },
12853
-
12854
-
12855
- /**
12856
- * Scrolling settings for a table.
12857
- * @namespace
12858
- */
12859
- "oScroll": {
12860
- /**
12861
- * When the table is shorter in height than sScrollY, collapse the
12862
- * table container down to the height of the table (when true).
12863
- * Note that this parameter will be set by the initialisation routine. To
12864
- * set a default use {@link DataTable.defaults}.
12865
- * @type boolean
12866
- */
12867
- "bCollapse": null,
12868
-
12869
- /**
12870
- * Width of the scrollbar for the web-browser's platform. Calculated
12871
- * during table initialisation.
12872
- * @type int
12873
- * @default 0
12874
- */
12875
- "iBarWidth": 0,
12876
-
12877
- /**
12878
- * Viewport width for horizontal scrolling. Horizontal scrolling is
12879
- * disabled if an empty string.
12880
- * Note that this parameter will be set by the initialisation routine. To
12881
- * set a default use {@link DataTable.defaults}.
12882
- * @type string
12883
- */
12884
- "sX": null,
12885
-
12886
- /**
12887
- * Width to expand the table to when using x-scrolling. Typically you
12888
- * should not need to use this.
12889
- * Note that this parameter will be set by the initialisation routine. To
12890
- * set a default use {@link DataTable.defaults}.
12891
- * @type string
12892
- * @deprecated
12893
- */
12894
- "sXInner": null,
12895
-
12896
- /**
12897
- * Viewport height for vertical scrolling. Vertical scrolling is disabled
12898
- * if an empty string.
12899
- * Note that this parameter will be set by the initialisation routine. To
12900
- * set a default use {@link DataTable.defaults}.
12901
- * @type string
12902
- */
12903
- "sY": null
12904
- },
12905
-
12906
- /**
12907
- * Language information for the table.
12908
- * @namespace
12909
- * @extends DataTable.defaults.oLanguage
12910
- */
12911
- "oLanguage": {
12912
- /**
12913
- * Information callback function. See
12914
- * {@link DataTable.defaults.fnInfoCallback}
12915
- * @type function
12916
- * @default null
12917
- */
12918
- "fnInfoCallback": null
12919
- },
12920
-
12921
- /**
12922
- * Browser support parameters
12923
- * @namespace
12924
- */
12925
- "oBrowser": {
12926
- /**
12927
- * Indicate if the browser incorrectly calculates width:100% inside a
12928
- * scrolling element (IE6/7)
12929
- * @type boolean
12930
- * @default false
12931
- */
12932
- "bScrollOversize": false,
12933
-
12934
- /**
12935
- * Determine if the vertical scrollbar is on the right or left of the
12936
- * scrolling container - needed for rtl language layout, although not
12937
- * all browsers move the scrollbar (Safari).
12938
- * @type boolean
12939
- * @default false
12940
- */
12941
- "bScrollbarLeft": false,
12942
-
12943
- /**
12944
- * Flag for if `getBoundingClientRect` is fully supported or not
12945
- * @type boolean
12946
- * @default false
12947
- */
12948
- "bBounding": false,
12949
-
12950
- /**
12951
- * Browser scrollbar width
12952
- * @type integer
12953
- * @default 0
12954
- */
12955
- "barWidth": 0
12956
- },
12957
-
12958
-
12959
- "ajax": null,
12960
-
12961
-
12962
- /**
12963
- * Array referencing the nodes which are used for the features. The
12964
- * parameters of this object match what is allowed by sDom - i.e.
12965
- * <ul>
12966
- * <li>'l' - Length changing</li>
12967
- * <li>'f' - Filtering input</li>
12968
- * <li>'t' - The table!</li>
12969
- * <li>'i' - Information</li>
12970
- * <li>'p' - Pagination</li>
12971
- * <li>'r' - pRocessing</li>
12972
- * </ul>
12973
- * @type array
12974
- * @default []
12975
- */
12976
- "aanFeatures": [],
12977
-
12978
- /**
12979
- * Store data information - see {@link DataTable.models.oRow} for detailed
12980
- * information.
12981
- * @type array
12982
- * @default []
12983
- */
12984
- "aoData": [],
12985
-
12986
- /**
12987
- * Array of indexes which are in the current display (after filtering etc)
12988
- * @type array
12989
- * @default []
12990
- */
12991
- "aiDisplay": [],
12992
-
12993
- /**
12994
- * Array of indexes for display - no filtering
12995
- * @type array
12996
- * @default []
12997
- */
12998
- "aiDisplayMaster": [],
12999
-
13000
- /**
13001
- * Map of row ids to data indexes
13002
- * @type object
13003
- * @default {}
13004
- */
13005
- "aIds": {},
13006
-
13007
- /**
13008
- * Store information about each column that is in use
13009
- * @type array
13010
- * @default []
13011
- */
13012
- "aoColumns": [],
13013
-
13014
- /**
13015
- * Store information about the table's header
13016
- * @type array
13017
- * @default []
13018
- */
13019
- "aoHeader": [],
13020
-
13021
- /**
13022
- * Store information about the table's footer
13023
- * @type array
13024
- * @default []
13025
- */
13026
- "aoFooter": [],
13027
-
13028
- /**
13029
- * Store the applied global search information in case we want to force a
13030
- * research or compare the old search to a new one.
13031
- * Note that this parameter will be set by the initialisation routine. To
13032
- * set a default use {@link DataTable.defaults}.
13033
- * @namespace
13034
- * @extends DataTable.models.oSearch
13035
- */
13036
- "oPreviousSearch": {},
13037
-
13038
- /**
13039
- * Store the applied search for each column - see
13040
- * {@link DataTable.models.oSearch} for the format that is used for the
13041
- * filtering information for each column.
13042
- * @type array
13043
- * @default []
13044
- */
13045
- "aoPreSearchCols": [],
13046
-
13047
- /**
13048
- * Sorting that is applied to the table. Note that the inner arrays are
13049
- * used in the following manner:
13050
- * <ul>
13051
- * <li>Index 0 - column number</li>
13052
- * <li>Index 1 - current sorting direction</li>
13053
- * </ul>
13054
- * Note that this parameter will be set by the initialisation routine. To
13055
- * set a default use {@link DataTable.defaults}.
13056
- * @type array
13057
- * @todo These inner arrays should really be objects
13058
- */
13059
- "aaSorting": null,
13060
-
13061
- /**
13062
- * Sorting that is always applied to the table (i.e. prefixed in front of
13063
- * aaSorting).
13064
- * Note that this parameter will be set by the initialisation routine. To
13065
- * set a default use {@link DataTable.defaults}.
13066
- * @type array
13067
- * @default []
13068
- */
13069
- "aaSortingFixed": [],
13070
-
13071
- /**
13072
- * Classes to use for the striping of a table.
13073
- * Note that this parameter will be set by the initialisation routine. To
13074
- * set a default use {@link DataTable.defaults}.
13075
- * @type array
13076
- * @default []
13077
- */
13078
- "asStripeClasses": null,
13079
-
13080
- /**
13081
- * If restoring a table - we should restore its striping classes as well
13082
- * @type array
13083
- * @default []
13084
- */
13085
- "asDestroyStripes": [],
13086
-
13087
- /**
13088
- * If restoring a table - we should restore its width
13089
- * @type int
13090
- * @default 0
13091
- */
13092
- "sDestroyWidth": 0,
13093
-
13094
- /**
13095
- * Callback functions array for every time a row is inserted (i.e. on a draw).
13096
- * @type array
13097
- * @default []
13098
- */
13099
- "aoRowCallback": [],
13100
-
13101
- /**
13102
- * Callback functions for the header on each draw.
13103
- * @type array
13104
- * @default []
13105
- */
13106
- "aoHeaderCallback": [],
13107
-
13108
- /**
13109
- * Callback function for the footer on each draw.
13110
- * @type array
13111
- * @default []
13112
- */
13113
- "aoFooterCallback": [],
13114
-
13115
- /**
13116
- * Array of callback functions for draw callback functions
13117
- * @type array
13118
- * @default []
13119
- */
13120
- "aoDrawCallback": [],
13121
-
13122
- /**
13123
- * Array of callback functions for row created function
13124
- * @type array
13125
- * @default []
13126
- */
13127
- "aoRowCreatedCallback": [],
13128
-
13129
- /**
13130
- * Callback functions for just before the table is redrawn. A return of
13131
- * false will be used to cancel the draw.
13132
- * @type array
13133
- * @default []
13134
- */
13135
- "aoPreDrawCallback": [],
13136
-
13137
- /**
13138
- * Callback functions for when the table has been initialised.
13139
- * @type array
13140
- * @default []
13141
- */
13142
- "aoInitComplete": [],
13143
-
13144
-
13145
- /**
13146
- * Callbacks for modifying the settings to be stored for state saving, prior to
13147
- * saving state.
13148
- * @type array
13149
- * @default []
13150
- */
13151
- "aoStateSaveParams": [],
13152
-
13153
- /**
13154
- * Callbacks for modifying the settings that have been stored for state saving
13155
- * prior to using the stored values to restore the state.
13156
- * @type array
13157
- * @default []
13158
- */
13159
- "aoStateLoadParams": [],
13160
-
13161
- /**
13162
- * Callbacks for operating on the settings object once the saved state has been
13163
- * loaded
13164
- * @type array
13165
- * @default []
13166
- */
13167
- "aoStateLoaded": [],
13168
-
13169
- /**
13170
- * Cache the table ID for quick access
13171
- * @type string
13172
- * @default <i>Empty string</i>
13173
- */
13174
- "sTableId": "",
13175
-
13176
- /**
13177
- * The TABLE node for the main table
13178
- * @type node
13179
- * @default null
13180
- */
13181
- "nTable": null,
13182
-
13183
- /**
13184
- * Permanent ref to the thead element
13185
- * @type node
13186
- * @default null
13187
- */
13188
- "nTHead": null,
13189
-
13190
- /**
13191
- * Permanent ref to the tfoot element - if it exists
13192
- * @type node
13193
- * @default null
13194
- */
13195
- "nTFoot": null,
13196
-
13197
- /**
13198
- * Permanent ref to the tbody element
13199
- * @type node
13200
- * @default null
13201
- */
13202
- "nTBody": null,
13203
-
13204
- /**
13205
- * Cache the wrapper node (contains all DataTables controlled elements)
13206
- * @type node
13207
- * @default null
13208
- */
13209
- "nTableWrapper": null,
13210
-
13211
- /**
13212
- * Indicate if when using server-side processing the loading of data
13213
- * should be deferred until the second draw.
13214
- * Note that this parameter will be set by the initialisation routine. To
13215
- * set a default use {@link DataTable.defaults}.
13216
- * @type boolean
13217
- * @default false
13218
- */
13219
- "bDeferLoading": false,
13220
-
13221
- /**
13222
- * Indicate if all required information has been read in
13223
- * @type boolean
13224
- * @default false
13225
- */
13226
- "bInitialised": false,
13227
-
13228
- /**
13229
- * Information about open rows. Each object in the array has the parameters
13230
- * 'nTr' and 'nParent'
13231
- * @type array
13232
- * @default []
13233
- */
13234
- "aoOpenRows": [],
13235
-
13236
- /**
13237
- * Dictate the positioning of DataTables' control elements - see
13238
- * {@link DataTable.model.oInit.sDom}.
13239
- * Note that this parameter will be set by the initialisation routine. To
13240
- * set a default use {@link DataTable.defaults}.
13241
- * @type string
13242
- * @default null
13243
- */
13244
- "sDom": null,
13245
-
13246
- /**
13247
- * Search delay (in mS)
13248
- * @type integer
13249
- * @default null
13250
- */
13251
- "searchDelay": null,
13252
-
13253
- /**
13254
- * Which type of pagination should be used.
13255
- * Note that this parameter will be set by the initialisation routine. To
13256
- * set a default use {@link DataTable.defaults}.
13257
- * @type string
13258
- * @default two_button
13259
- */
13260
- "sPaginationType": "two_button",
13261
-
13262
- /**
13263
- * The state duration (for `stateSave`) in seconds.
13264
- * Note that this parameter will be set by the initialisation routine. To
13265
- * set a default use {@link DataTable.defaults}.
13266
- * @type int
13267
- * @default 0
13268
- */
13269
- "iStateDuration": 0,
13270
-
13271
- /**
13272
- * Array of callback functions for state saving. Each array element is an
13273
- * object with the following parameters:
13274
- * <ul>
13275
- * <li>function:fn - function to call. Takes two parameters, oSettings
13276
- * and the JSON string to save that has been thus far created. Returns
13277
- * a JSON string to be inserted into a json object
13278
- * (i.e. '"param": [ 0, 1, 2]')</li>
13279
- * <li>string:sName - name of callback</li>
13280
- * </ul>
13281
- * @type array
13282
- * @default []
13283
- */
13284
- "aoStateSave": [],
13285
-
13286
- /**
13287
- * Array of callback functions for state loading. Each array element is an
13288
- * object with the following parameters:
13289
- * <ul>
13290
- * <li>function:fn - function to call. Takes two parameters, oSettings
13291
- * and the object stored. May return false to cancel state loading</li>
13292
- * <li>string:sName - name of callback</li>
13293
- * </ul>
13294
- * @type array
13295
- * @default []
13296
- */
13297
- "aoStateLoad": [],
13298
-
13299
- /**
13300
- * State that was saved. Useful for back reference
13301
- * @type object
13302
- * @default null
13303
- */
13304
- "oSavedState": null,
13305
-
13306
- /**
13307
- * State that was loaded. Useful for back reference
13308
- * @type object
13309
- * @default null
13310
- */
13311
- "oLoadedState": null,
13312
-
13313
- /**
13314
- * Source url for AJAX data for the table.
13315
- * Note that this parameter will be set by the initialisation routine. To
13316
- * set a default use {@link DataTable.defaults}.
13317
- * @type string
13318
- * @default null
13319
- */
13320
- "sAjaxSource": null,
13321
-
13322
- /**
13323
- * Property from a given object from which to read the table data from. This
13324
- * can be an empty string (when not server-side processing), in which case
13325
- * it is assumed an an array is given directly.
13326
- * Note that this parameter will be set by the initialisation routine. To
13327
- * set a default use {@link DataTable.defaults}.
13328
- * @type string
13329
- */
13330
- "sAjaxDataProp": null,
13331
-
13332
- /**
13333
- * Note if draw should be blocked while getting data
13334
- * @type boolean
13335
- * @default true
13336
- */
13337
- "bAjaxDataGet": true,
13338
-
13339
- /**
13340
- * The last jQuery XHR object that was used for server-side data gathering.
13341
- * This can be used for working with the XHR information in one of the
13342
- * callbacks
13343
- * @type object
13344
- * @default null
13345
- */
13346
- "jqXHR": null,
13347
-
13348
- /**
13349
- * JSON returned from the server in the last Ajax request
13350
- * @type object
13351
- * @default undefined
13352
- */
13353
- "json": undefined,
13354
-
13355
- /**
13356
- * Data submitted as part of the last Ajax request
13357
- * @type object
13358
- * @default undefined
13359
- */
13360
- "oAjaxData": undefined,
13361
-
13362
- /**
13363
- * Function to get the server-side data.
13364
- * Note that this parameter will be set by the initialisation routine. To
13365
- * set a default use {@link DataTable.defaults}.
13366
- * @type function
13367
- */
13368
- "fnServerData": null,
13369
-
13370
- /**
13371
- * Functions which are called prior to sending an Ajax request so extra
13372
- * parameters can easily be sent to the server
13373
- * @type array
13374
- * @default []
13375
- */
13376
- "aoServerParams": [],
13377
-
13378
- /**
13379
- * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13380
- * required).
13381
- * Note that this parameter will be set by the initialisation routine. To
13382
- * set a default use {@link DataTable.defaults}.
13383
- * @type string
13384
- */
13385
- "sServerMethod": null,
13386
-
13387
- /**
13388
- * Format numbers for display.
13389
- * Note that this parameter will be set by the initialisation routine. To
13390
- * set a default use {@link DataTable.defaults}.
13391
- * @type function
13392
- */
13393
- "fnFormatNumber": null,
13394
-
13395
- /**
13396
- * List of options that can be used for the user selectable length menu.
13397
- * Note that this parameter will be set by the initialisation routine. To
13398
- * set a default use {@link DataTable.defaults}.
13399
- * @type array
13400
- * @default []
13401
- */
13402
- "aLengthMenu": null,
13403
-
13404
- /**
13405
- * Counter for the draws that the table does. Also used as a tracker for
13406
- * server-side processing
13407
- * @type int
13408
- * @default 0
13409
- */
13410
- "iDraw": 0,
13411
-
13412
- /**
13413
- * Indicate if a redraw is being done - useful for Ajax
13414
- * @type boolean
13415
- * @default false
13416
- */
13417
- "bDrawing": false,
13418
-
13419
- /**
13420
- * Draw index (iDraw) of the last error when parsing the returned data
13421
- * @type int
13422
- * @default -1
13423
- */
13424
- "iDrawError": -1,
13425
-
13426
- /**
13427
- * Paging display length
13428
- * @type int
13429
- * @default 10
13430
- */
13431
- "_iDisplayLength": 10,
13432
-
13433
- /**
13434
- * Paging start point - aiDisplay index
13435
- * @type int
13436
- * @default 0
13437
- */
13438
- "_iDisplayStart": 0,
13439
-
13440
- /**
13441
- * Server-side processing - number of records in the result set
13442
- * (i.e. before filtering), Use fnRecordsTotal rather than
13443
- * this property to get the value of the number of records, regardless of
13444
- * the server-side processing setting.
13445
- * @type int
13446
- * @default 0
13447
- * @private
13448
- */
13449
- "_iRecordsTotal": 0,
13450
-
13451
- /**
13452
- * Server-side processing - number of records in the current display set
13453
- * (i.e. after filtering). Use fnRecordsDisplay rather than
13454
- * this property to get the value of the number of records, regardless of
13455
- * the server-side processing setting.
13456
- * @type boolean
13457
- * @default 0
13458
- * @private
13459
- */
13460
- "_iRecordsDisplay": 0,
13461
-
13462
- /**
13463
- * Flag to indicate if jQuery UI marking and classes should be used.
13464
- * Note that this parameter will be set by the initialisation routine. To
13465
- * set a default use {@link DataTable.defaults}.
13466
- * @type boolean
13467
- */
13468
- "bJUI": null,
13469
-
13470
- /**
13471
- * The classes to use for the table
13472
- * @type object
13473
- * @default {}
13474
- */
13475
- "oClasses": {},
13476
-
13477
- /**
13478
- * Flag attached to the settings object so you can check in the draw
13479
- * callback if filtering has been done in the draw. Deprecated in favour of
13480
- * events.
13481
- * @type boolean
13482
- * @default false
13483
- * @deprecated
13484
- */
13485
- "bFiltered": false,
13486
-
13487
- /**
13488
- * Flag attached to the settings object so you can check in the draw
13489
- * callback if sorting has been done in the draw. Deprecated in favour of
13490
- * events.
13491
- * @type boolean
13492
- * @default false
13493
- * @deprecated
13494
- */
13495
- "bSorted": false,
13496
-
13497
- /**
13498
- * Indicate that if multiple rows are in the header and there is more than
13499
- * one unique cell per column, if the top one (true) or bottom one (false)
13500
- * should be used for sorting / title by DataTables.
13501
- * Note that this parameter will be set by the initialisation routine. To
13502
- * set a default use {@link DataTable.defaults}.
13503
- * @type boolean
13504
- */
13505
- "bSortCellsTop": null,
13506
-
13507
- /**
13508
- * Initialisation object that is used for the table
13509
- * @type object
13510
- * @default null
13511
- */
13512
- "oInit": null,
13513
-
13514
- /**
13515
- * Destroy callback functions - for plug-ins to attach themselves to the
13516
- * destroy so they can clean up markup and events.
13517
- * @type array
13518
- * @default []
13519
- */
13520
- "aoDestroyCallback": [],
13521
-
13522
-
13523
- /**
13524
- * Get the number of records in the current record set, before filtering
13525
- * @type function
13526
- */
13527
- "fnRecordsTotal": function ()
13528
- {
13529
- return _fnDataSource( this ) == 'ssp' ?
13530
- this._iRecordsTotal * 1 :
13531
- this.aiDisplayMaster.length;
13532
- },
13533
-
13534
- /**
13535
- * Get the number of records in the current record set, after filtering
13536
- * @type function
13537
- */
13538
- "fnRecordsDisplay": function ()
13539
- {
13540
- return _fnDataSource( this ) == 'ssp' ?
13541
- this._iRecordsDisplay * 1 :
13542
- this.aiDisplay.length;
13543
- },
13544
-
13545
- /**
13546
- * Get the display end point - aiDisplay index
13547
- * @type function
13548
- */
13549
- "fnDisplayEnd": function ()
13550
- {
13551
- var
13552
- len = this._iDisplayLength,
13553
- start = this._iDisplayStart,
13554
- calc = start + len,
13555
- records = this.aiDisplay.length,
13556
- features = this.oFeatures,
13557
- paginate = features.bPaginate;
13558
-
13559
- if ( features.bServerSide ) {
13560
- return paginate === false || len === -1 ?
13561
- start + records :
13562
- Math.min( start+len, this._iRecordsDisplay );
13563
- }
13564
- else {
13565
- return ! paginate || calc>records || len===-1 ?
13566
- records :
13567
- calc;
13568
- }
13569
- },
13570
-
13571
- /**
13572
- * The DataTables object for this table
13573
- * @type object
13574
- * @default null
13575
- */
13576
- "oInstance": null,
13577
-
13578
- /**
13579
- * Unique identifier for each instance of the DataTables object. If there
13580
- * is an ID on the table node, then it takes that value, otherwise an
13581
- * incrementing internal counter is used.
13582
- * @type string
13583
- * @default null
13584
- */
13585
- "sInstance": null,
13586
-
13587
- /**
13588
- * tabindex attribute value that is added to DataTables control elements, allowing
13589
- * keyboard navigation of the table and its controls.
13590
- */
13591
- "iTabIndex": 0,
13592
-
13593
- /**
13594
- * DIV container for the footer scrolling table if scrolling
13595
- */
13596
- "nScrollHead": null,
13597
-
13598
- /**
13599
- * DIV container for the footer scrolling table if scrolling
13600
- */
13601
- "nScrollFoot": null,
13602
-
13603
- /**
13604
- * Last applied sort
13605
- * @type array
13606
- * @default []
13607
- */
13608
- "aLastSort": [],
13609
-
13610
- /**
13611
- * Stored plug-in instances
13612
- * @type object
13613
- * @default {}
13614
- */
13615
- "oPlugins": {},
13616
-
13617
- /**
13618
- * Function used to get a row's id from the row's data
13619
- * @type function
13620
- * @default null
13621
- */
13622
- "rowIdFn": null,
13623
-
13624
- /**
13625
- * Data location where to store a row's id
13626
- * @type string
13627
- * @default null
13628
- */
13629
- "rowId": null
13630
- };
13631
-
13632
- /**
13633
- * Extension object for DataTables that is used to provide all extension
13634
- * options.
13635
- *
13636
- * Note that the `DataTable.ext` object is available through
13637
- * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13638
- * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13639
- * @namespace
13640
- * @extends DataTable.models.ext
13641
- */
13642
-
13643
-
13644
- /**
13645
- * DataTables extensions
13646
- *
13647
- * This namespace acts as a collection area for plug-ins that can be used to
13648
- * extend DataTables capabilities. Indeed many of the build in methods
13649
- * use this method to provide their own capabilities (sorting methods for
13650
- * example).
13651
- *
13652
- * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13653
- * reasons
13654
- *
13655
- * @namespace
13656
- */
13657
- DataTable.ext = _ext = {
13658
- /**
13659
- * Buttons. For use with the Buttons extension for DataTables. This is
13660
- * defined here so other extensions can define buttons regardless of load
13661
- * order. It is _not_ used by DataTables core.
13662
- *
13663
- * @type object
13664
- * @default {}
13665
- */
13666
- buttons: {},
13667
-
13668
-
13669
- /**
13670
- * Element class names
13671
- *
13672
- * @type object
13673
- * @default {}
13674
- */
13675
- classes: {},
13676
-
13677
-
13678
- /**
13679
- * Error reporting.
13680
- *
13681
- * How should DataTables report an error. Can take the value 'alert',
13682
- * 'throw', 'none' or a function.
13683
- *
13684
- * @type string|function
13685
- * @default alert
13686
- */
13687
- errMode: "alert",
13688
-
13689
-
13690
- /**
13691
- * Feature plug-ins.
13692
- *
13693
- * This is an array of objects which describe the feature plug-ins that are
13694
- * available to DataTables. These feature plug-ins are then available for
13695
- * use through the `dom` initialisation option.
13696
- *
13697
- * Each feature plug-in is described by an object which must have the
13698
- * following properties:
13699
- *
13700
- * * `fnInit` - function that is used to initialise the plug-in,
13701
- * * `cFeature` - a character so the feature can be enabled by the `dom`
13702
- * instillation option. This is case sensitive.
13703
- *
13704
- * The `fnInit` function has the following input parameters:
13705
- *
13706
- * 1. `{object}` DataTables settings object: see
13707
- * {@link DataTable.models.oSettings}
13708
- *
13709
- * And the following return is expected:
13710
- *
13711
- * * {node|null} The element which contains your feature. Note that the
13712
- * return may also be void if your plug-in does not require to inject any
13713
- * DOM elements into DataTables control (`dom`) - for example this might
13714
- * be useful when developing a plug-in which allows table control via
13715
- * keyboard entry
13716
- *
13717
- * @type array
13718
- *
13719
- * @example
13720
- * $.fn.dataTable.ext.features.push( {
13721
- * "fnInit": function( oSettings ) {
13722
- * return new TableTools( { "oDTSettings": oSettings } );
13723
- * },
13724
- * "cFeature": "T"
13725
- * } );
13726
- */
13727
- feature: [],
13728
-
13729
-
13730
- /**
13731
- * Row searching.
13732
- *
13733
- * This method of searching is complimentary to the default type based
13734
- * searching, and a lot more comprehensive as it allows you complete control
13735
- * over the searching logic. Each element in this array is a function
13736
- * (parameters described below) that is called for every row in the table,
13737
- * and your logic decides if it should be included in the searching data set
13738
- * or not.
13739
- *
13740
- * Searching functions have the following input parameters:
13741
- *
13742
- * 1. `{object}` DataTables settings object: see
13743
- * {@link DataTable.models.oSettings}
13744
- * 2. `{array|object}` Data for the row to be processed (same as the
13745
- * original format that was passed in as the data source, or an array
13746
- * from a DOM data source
13747
- * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
13748
- * can be useful to retrieve the `TR` element if you need DOM interaction.
13749
- *
13750
- * And the following return is expected:
13751
- *
13752
- * * {boolean} Include the row in the searched result set (true) or not
13753
- * (false)
13754
- *
13755
- * Note that as with the main search ability in DataTables, technically this
13756
- * is "filtering", since it is subtractive. However, for consistency in
13757
- * naming we call it searching here.
13758
- *
13759
- * @type array
13760
- * @default []
13761
- *
13762
- * @example
13763
- * // The following example shows custom search being applied to the
13764
- * // fourth column (i.e. the data[3] index) based on two input values
13765
- * // from the end-user, matching the data in a certain range.
13766
- * $.fn.dataTable.ext.search.push(
13767
- * function( settings, data, dataIndex ) {
13768
- * var min = document.getElementById('min').value * 1;
13769
- * var max = document.getElementById('max').value * 1;
13770
- * var version = data[3] == "-" ? 0 : data[3]*1;
13771
- *
13772
- * if ( min == "" && max == "" ) {
13773
- * return true;
13774
- * }
13775
- * else if ( min == "" && version < max ) {
13776
- * return true;
13777
- * }
13778
- * else if ( min < version && "" == max ) {
13779
- * return true;
13780
- * }
13781
- * else if ( min < version && version < max ) {
13782
- * return true;
13783
- * }
13784
- * return false;
13785
- * }
13786
- * );
13787
- */
13788
- search: [],
13789
-
13790
-
13791
- /**
13792
- * Selector extensions
13793
- *
13794
- * The `selector` option can be used to extend the options available for the
13795
- * selector modifier options (`selector-modifier` object data type) that
13796
- * each of the three built in selector types offer (row, column and cell +
13797
- * their plural counterparts). For example the Select extension uses this
13798
- * mechanism to provide an option to select only rows, columns and cells
13799
- * that have been marked as selected by the end user (`{selected: true}`),
13800
- * which can be used in conjunction with the existing built in selector
13801
- * options.
13802
- *
13803
- * Each property is an array to which functions can be pushed. The functions
13804
- * take three attributes:
13805
- *
13806
- * * Settings object for the host table
13807
- * * Options object (`selector-modifier` object type)
13808
- * * Array of selected item indexes
13809
- *
13810
- * The return is an array of the resulting item indexes after the custom
13811
- * selector has been applied.
13812
- *
13813
- * @type object
13814
- */
13815
- selector: {
13816
- cell: [],
13817
- column: [],
13818
- row: []
13819
- },
13820
-
13821
-
13822
- /**
13823
- * Internal functions, exposed for used in plug-ins.
13824
- *
13825
- * Please note that you should not need to use the internal methods for
13826
- * anything other than a plug-in (and even then, try to avoid if possible).
13827
- * The internal function may change between releases.
13828
- *
13829
- * @type object
13830
- * @default {}
13831
- */
13832
- internal: {},
13833
-
13834
-
13835
- /**
13836
- * Legacy configuration options. Enable and disable legacy options that
13837
- * are available in DataTables.
13838
- *
13839
- * @type object
13840
- */
13841
- legacy: {
13842
- /**
13843
- * Enable / disable DataTables 1.9 compatible server-side processing
13844
- * requests
13845
- *
13846
- * @type boolean
13847
- * @default null
13848
- */
13849
- ajax: null
13850
- },
13851
-
13852
-
13853
- /**
13854
- * Pagination plug-in methods.
13855
- *
13856
- * Each entry in this object is a function and defines which buttons should
13857
- * be shown by the pagination rendering method that is used for the table:
13858
- * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
13859
- * buttons are displayed in the document, while the functions here tell it
13860
- * what buttons to display. This is done by returning an array of button
13861
- * descriptions (what each button will do).
13862
- *
13863
- * Pagination types (the four built in options and any additional plug-in
13864
- * options defined here) can be used through the `paginationType`
13865
- * initialisation parameter.
13866
- *
13867
- * The functions defined take two parameters:
13868
- *
13869
- * 1. `{int} page` The current page index
13870
- * 2. `{int} pages` The number of pages in the table
13871
- *
13872
- * Each function is expected to return an array where each element of the
13873
- * array can be one of:
13874
- *
13875
- * * `first` - Jump to first page when activated
13876
- * * `last` - Jump to last page when activated
13877
- * * `previous` - Show previous page when activated
13878
- * * `next` - Show next page when activated
13879
- * * `{int}` - Show page of the index given
13880
- * * `{array}` - A nested array containing the above elements to add a
13881
- * containing 'DIV' element (might be useful for styling).
13882
- *
13883
- * Note that DataTables v1.9- used this object slightly differently whereby
13884
- * an object with two functions would be defined for each plug-in. That
13885
- * ability is still supported by DataTables 1.10+ to provide backwards
13886
- * compatibility, but this option of use is now decremented and no longer
13887
- * documented in DataTables 1.10+.
13888
- *
13889
- * @type object
13890
- * @default {}
13891
- *
13892
- * @example
13893
- * // Show previous, next and current page buttons only
13894
- * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
13895
- * return [ 'previous', page, 'next' ];
13896
- * };
13897
- */
13898
- pager: {},
13899
-
13900
-
13901
- renderer: {
13902
- pageButton: {},
13903
- header: {}
13904
- },
13905
-
13906
-
13907
- /**
13908
- * Ordering plug-ins - custom data source
13909
- *
13910
- * The extension options for ordering of data available here is complimentary
13911
- * to the default type based ordering that DataTables typically uses. It
13912
- * allows much greater control over the the data that is being used to
13913
- * order a column, but is necessarily therefore more complex.
13914
- *
13915
- * This type of ordering is useful if you want to do ordering based on data
13916
- * live from the DOM (for example the contents of an 'input' element) rather
13917
- * than just the static string that DataTables knows of.
13918
- *
13919
- * The way these plug-ins work is that you create an array of the values you
13920
- * wish to be ordering for the column in question and then return that
13921
- * array. The data in the array much be in the index order of the rows in
13922
- * the table (not the currently ordering order!). Which order data gathering
13923
- * function is run here depends on the `dt-init columns.orderDataType`
13924
- * parameter that is used for the column (if any).
13925
- *
13926
- * The functions defined take two parameters:
13927
- *
13928
- * 1. `{object}` DataTables settings object: see
13929
- * {@link DataTable.models.oSettings}
13930
- * 2. `{int}` Target column index
13931
- *
13932
- * Each function is expected to return an array:
13933
- *
13934
- * * `{array}` Data for the column to be ordering upon
13935
- *
13936
- * @type array
13937
- *
13938
- * @example
13939
- * // Ordering using `input` node values
13940
- * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
13941
- * {
13942
- * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
13943
- * return $('input', td).val();
13944
- * } );
13945
- * }
13946
- */
13947
- order: {},
13948
-
13949
-
13950
- /**
13951
- * Type based plug-ins.
13952
- *
13953
- * Each column in DataTables has a type assigned to it, either by automatic
13954
- * detection or by direct assignment using the `type` option for the column.
13955
- * The type of a column will effect how it is ordering and search (plug-ins
13956
- * can also make use of the column type if required).
13957
- *
13958
- * @namespace
13959
- */
13960
- type: {
13961
- /**
13962
- * Type detection functions.
13963
- *
13964
- * The functions defined in this object are used to automatically detect
13965
- * a column's type, making initialisation of DataTables super easy, even
13966
- * when complex data is in the table.
13967
- *
13968
- * The functions defined take two parameters:
13969
- *
13970
- * 1. `{*}` Data from the column cell to be analysed
13971
- * 2. `{settings}` DataTables settings object. This can be used to
13972
- * perform context specific type detection - for example detection
13973
- * based on language settings such as using a comma for a decimal
13974
- * place. Generally speaking the options from the settings will not
13975
- * be required
13976
- *
13977
- * Each function is expected to return:
13978
- *
13979
- * * `{string|null}` Data type detected, or null if unknown (and thus
13980
- * pass it on to the other type detection functions.
13981
- *
13982
- * @type array
13983
- *
13984
- * @example
13985
- * // Currency type detection plug-in:
13986
- * $.fn.dataTable.ext.type.detect.push(
13987
- * function ( data, settings ) {
13988
- * // Check the numeric part
13989
- * if ( ! $.isNumeric( data.substring(1) ) ) {
13990
- * return null;
13991
- * }
13992
- *
13993
- * // Check prefixed by currency
13994
- * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
13995
- * return 'currency';
13996
- * }
13997
- * return null;
13998
- * }
13999
- * );
14000
- */
14001
- detect: [],
14002
-
14003
-
14004
- /**
14005
- * Type based search formatting.
14006
- *
14007
- * The type based searching functions can be used to pre-format the
14008
- * data to be search on. For example, it can be used to strip HTML
14009
- * tags or to de-format telephone numbers for numeric only searching.
14010
- *
14011
- * Note that is a search is not defined for a column of a given type,
14012
- * no search formatting will be performed.
14013
- *
14014
- * Pre-processing of searching data plug-ins - When you assign the sType
14015
- * for a column (or have it automatically detected for you by DataTables
14016
- * or a type detection plug-in), you will typically be using this for
14017
- * custom sorting, but it can also be used to provide custom searching
14018
- * by allowing you to pre-processing the data and returning the data in
14019
- * the format that should be searched upon. This is done by adding
14020
- * functions this object with a parameter name which matches the sType
14021
- * for that target column. This is the corollary of <i>afnSortData</i>
14022
- * for searching data.
14023
- *
14024
- * The functions defined take a single parameter:
14025
- *
14026
- * 1. `{*}` Data from the column cell to be prepared for searching
14027
- *
14028
- * Each function is expected to return:
14029
- *
14030
- * * `{string|null}` Formatted string that will be used for the searching.
14031
- *
14032
- * @type object
14033
- * @default {}
14034
- *
14035
- * @example
14036
- * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
14037
- * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
14038
- * }
14039
- */
14040
- search: {},
14041
-
14042
-
14043
- /**
14044
- * Type based ordering.
14045
- *
14046
- * The column type tells DataTables what ordering to apply to the table
14047
- * when a column is sorted upon. The order for each type that is defined,
14048
- * is defined by the functions available in this object.
14049
- *
14050
- * Each ordering option can be described by three properties added to
14051
- * this object:
14052
- *
14053
- * * `{type}-pre` - Pre-formatting function
14054
- * * `{type}-asc` - Ascending order function
14055
- * * `{type}-desc` - Descending order function
14056
- *
14057
- * All three can be used together, only `{type}-pre` or only
14058
- * `{type}-asc` and `{type}-desc` together. It is generally recommended
14059
- * that only `{type}-pre` is used, as this provides the optimal
14060
- * implementation in terms of speed, although the others are provided
14061
- * for compatibility with existing Javascript sort functions.
14062
- *
14063
- * `{type}-pre`: Functions defined take a single parameter:
14064
- *
14065
- * 1. `{*}` Data from the column cell to be prepared for ordering
14066
- *
14067
- * And return:
14068
- *
14069
- * * `{*}` Data to be sorted upon
14070
- *
14071
- * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14072
- * functions, taking two parameters:
14073
- *
14074
- * 1. `{*}` Data to compare to the second parameter
14075
- * 2. `{*}` Data to compare to the first parameter
14076
- *
14077
- * And returning:
14078
- *
14079
- * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14080
- * than the second parameter, ===0 if the two parameters are equal and
14081
- * >0 if the first parameter should be sorted height than the second
14082
- * parameter.
14083
- *
14084
- * @type object
14085
- * @default {}
14086
- *
14087
- * @example
14088
- * // Numeric ordering of formatted numbers with a pre-formatter
14089
- * $.extend( $.fn.dataTable.ext.type.order, {
14090
- * "string-pre": function(x) {
14091
- * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14092
- * return parseFloat( a );
14093
- * }
14094
- * } );
14095
- *
14096
- * @example
14097
- * // Case-sensitive string ordering, with no pre-formatting method
14098
- * $.extend( $.fn.dataTable.ext.order, {
14099
- * "string-case-asc": function(x,y) {
14100
- * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14101
- * },
14102
- * "string-case-desc": function(x,y) {
14103
- * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14104
- * }
14105
- * } );
14106
- */
14107
- order: {}
14108
- },
14109
-
14110
- /**
14111
- * Unique DataTables instance counter
14112
- *
14113
- * @type int
14114
- * @private
14115
- */
14116
- _unique: 0,
14117
-
14118
-
14119
- //
14120
- // Depreciated
14121
- // The following properties are retained for backwards compatiblity only.
14122
- // The should not be used in new projects and will be removed in a future
14123
- // version
14124
- //
14125
-
14126
- /**
14127
- * Version check function.
14128
- * @type function
14129
- * @depreciated Since 1.10
14130
- */
14131
- fnVersionCheck: DataTable.fnVersionCheck,
14132
-
14133
-
14134
- /**
14135
- * Index for what 'this' index API functions should use
14136
- * @type int
14137
- * @deprecated Since v1.10
14138
- */
14139
- iApiIndex: 0,
14140
-
14141
-
14142
- /**
14143
- * jQuery UI class container
14144
- * @type object
14145
- * @deprecated Since v1.10
14146
- */
14147
- oJUIClasses: {},
14148
-
14149
-
14150
- /**
14151
- * Software version
14152
- * @type string
14153
- * @deprecated Since v1.10
14154
- */
14155
- sVersion: DataTable.version
14156
- };
14157
-
14158
-
14159
- //
14160
- // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14161
- //
14162
- $.extend( _ext, {
14163
- afnFiltering: _ext.search,
14164
- aTypes: _ext.type.detect,
14165
- ofnSearch: _ext.type.search,
14166
- oSort: _ext.type.order,
14167
- afnSortData: _ext.order,
14168
- aoFeatures: _ext.feature,
14169
- oApi: _ext.internal,
14170
- oStdClasses: _ext.classes,
14171
- oPagination: _ext.pager
14172
- } );
14173
-
14174
-
14175
- $.extend( DataTable.ext.classes, {
14176
- "sTable": "dataTable",
14177
- "sNoFooter": "no-footer",
14178
-
14179
- /* Paging buttons */
14180
- "sPageButton": "paginate_button",
14181
- "sPageButtonActive": "current",
14182
- "sPageButtonDisabled": "disabled",
14183
-
14184
- /* Striping classes */
14185
- "sStripeOdd": "odd",
14186
- "sStripeEven": "even",
14187
-
14188
- /* Empty row */
14189
- "sRowEmpty": "dataTables_empty",
14190
-
14191
- /* Features */
14192
- "sWrapper": "dataTables_wrapper",
14193
- "sFilter": "dataTables_filter",
14194
- "sInfo": "dataTables_info",
14195
- "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14196
- "sLength": "dataTables_length",
14197
- "sProcessing": "dataTables_processing",
14198
-
14199
- /* Sorting */
14200
- "sSortAsc": "sorting_asc",
14201
- "sSortDesc": "sorting_desc",
14202
- "sSortable": "sorting", /* Sortable in both directions */
14203
- "sSortableAsc": "sorting_asc_disabled",
14204
- "sSortableDesc": "sorting_desc_disabled",
14205
- "sSortableNone": "sorting_disabled",
14206
- "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14207
-
14208
- /* Filtering */
14209
- "sFilterInput": "",
14210
-
14211
- /* Page length */
14212
- "sLengthSelect": "",
14213
-
14214
- /* Scrolling */
14215
- "sScrollWrapper": "dataTables_scroll",
14216
- "sScrollHead": "dataTables_scrollHead",
14217
- "sScrollHeadInner": "dataTables_scrollHeadInner",
14218
- "sScrollBody": "dataTables_scrollBody",
14219
- "sScrollFoot": "dataTables_scrollFoot",
14220
- "sScrollFootInner": "dataTables_scrollFootInner",
14221
-
14222
- /* Misc */
14223
- "sHeaderTH": "",
14224
- "sFooterTH": "",
14225
-
14226
- // Deprecated
14227
- "sSortJUIAsc": "",
14228
- "sSortJUIDesc": "",
14229
- "sSortJUI": "",
14230
- "sSortJUIAscAllowed": "",
14231
- "sSortJUIDescAllowed": "",
14232
- "sSortJUIWrapper": "",
14233
- "sSortIcon": "",
14234
- "sJUIHeader": "",
14235
- "sJUIFooter": ""
14236
- } );
14237
-
14238
-
14239
- (function() {
14240
-
14241
- // Reused strings for better compression. Closure compiler appears to have a
14242
- // weird edge case where it is trying to expand strings rather than use the
14243
- // variable version. This results in about 200 bytes being added, for very
14244
- // little preference benefit since it this run on script load only.
14245
- var _empty = '';
14246
- _empty = '';
14247
-
14248
- var _stateDefault = _empty + 'ui-state-default';
14249
- var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
14250
- var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
14251
-
14252
- $.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
14253
- /* Full numbers paging buttons */
14254
- "sPageButton": "fg-button ui-button "+_stateDefault,
14255
- "sPageButtonActive": "ui-state-disabled",
14256
- "sPageButtonDisabled": "ui-state-disabled",
14257
-
14258
- /* Features */
14259
- "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
14260
- "ui-buttonset-multi paging_", /* Note that the type is postfixed */
14261
-
14262
- /* Sorting */
14263
- "sSortAsc": _stateDefault+" sorting_asc",
14264
- "sSortDesc": _stateDefault+" sorting_desc",
14265
- "sSortable": _stateDefault+" sorting",
14266
- "sSortableAsc": _stateDefault+" sorting_asc_disabled",
14267
- "sSortableDesc": _stateDefault+" sorting_desc_disabled",
14268
- "sSortableNone": _stateDefault+" sorting_disabled",
14269
- "sSortJUIAsc": _sortIcon+"triangle-1-n",
14270
- "sSortJUIDesc": _sortIcon+"triangle-1-s",
14271
- "sSortJUI": _sortIcon+"carat-2-n-s",
14272
- "sSortJUIAscAllowed": _sortIcon+"carat-1-n",
14273
- "sSortJUIDescAllowed": _sortIcon+"carat-1-s",
14274
- "sSortJUIWrapper": "DataTables_sort_wrapper",
14275
- "sSortIcon": "DataTables_sort_icon",
14276
-
14277
- /* Scrolling */
14278
- "sScrollHead": "dataTables_scrollHead "+_stateDefault,
14279
- "sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
14280
-
14281
- /* Misc */
14282
- "sHeaderTH": _stateDefault,
14283
- "sFooterTH": _stateDefault,
14284
- "sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
14285
- "sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
14286
- } );
14287
-
14288
- }());
14289
-
14290
-
14291
-
14292
- var extPagination = DataTable.ext.pager;
14293
-
14294
- function _numbers ( page, pages ) {
14295
- var
14296
- numbers = [],
14297
- buttons = extPagination.numbers_length,
14298
- half = Math.floor( buttons / 2 ),
14299
- i = 1;
14300
-
14301
- if ( pages <= buttons ) {
14302
- numbers = _range( 0, pages );
14303
- }
14304
- else if ( page <= half ) {
14305
- numbers = _range( 0, buttons-2 );
14306
- numbers.push( 'ellipsis' );
14307
- numbers.push( pages-1 );
14308
- }
14309
- else if ( page >= pages - 1 - half ) {
14310
- numbers = _range( pages-(buttons-2), pages );
14311
- numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
14312
- numbers.splice( 0, 0, 0 );
14313
- }
14314
- else {
14315
- numbers = _range( page-half+2, page+half-1 );
14316
- numbers.push( 'ellipsis' );
14317
- numbers.push( pages-1 );
14318
- numbers.splice( 0, 0, 'ellipsis' );
14319
- numbers.splice( 0, 0, 0 );
14320
- }
14321
-
14322
- numbers.DT_el = 'span';
14323
- return numbers;
14324
- }
14325
-
14326
-
14327
- $.extend( extPagination, {
14328
- simple: function ( page, pages ) {
14329
- return [ 'previous', 'next' ];
14330
- },
14331
-
14332
- full: function ( page, pages ) {
14333
- return [ 'first', 'previous', 'next', 'last' ];
14334
- },
14335
-
14336
- numbers: function ( page, pages ) {
14337
- return [ _numbers(page, pages) ];
14338
- },
14339
-
14340
- simple_numbers: function ( page, pages ) {
14341
- return [ 'previous', _numbers(page, pages), 'next' ];
14342
- },
14343
-
14344
- full_numbers: function ( page, pages ) {
14345
- return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
14346
- },
14347
-
14348
- // For testing and plug-ins to use
14349
- _numbers: _numbers,
14350
-
14351
- // Number of number buttons (including ellipsis) to show. _Must be odd!_
14352
- numbers_length: 7
14353
- } );
14354
-
14355
-
14356
- $.extend( true, DataTable.ext.renderer, {
14357
- pageButton: {
14358
- _: function ( settings, host, idx, buttons, page, pages ) {
14359
- var classes = settings.oClasses;
14360
- var lang = settings.oLanguage.oPaginate;
14361
- var btnDisplay, btnClass, counter=0;
14362
-
14363
- var attach = function( container, buttons ) {
14364
- var i, ien, node, button;
14365
- var clickHandler = function ( e ) {
14366
- _fnPageChange( settings, e.data.action, true );
14367
- };
14368
-
14369
- for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
14370
- button = buttons[i];
14371
-
14372
- if ( $.isArray( button ) ) {
14373
- var inner = $( '<'+(button.DT_el || 'div')+'/>' )
14374
- .appendTo( container );
14375
- attach( inner, button );
14376
- }
14377
- else {
14378
- btnDisplay = null;
14379
- btnClass = '';
14380
-
14381
- switch ( button ) {
14382
- case 'ellipsis':
14383
- container.append('<span class="ellipsis">&#x2026;</span>');
14384
- break;
14385
-
14386
- case 'first':
14387
- btnDisplay = lang.sFirst;
14388
- btnClass = button + (page > 0 ?
14389
- '' : ' '+classes.sPageButtonDisabled);
14390
- break;
14391
-
14392
- case 'previous':
14393
- btnDisplay = lang.sPrevious;
14394
- btnClass = button + (page > 0 ?
14395
- '' : ' '+classes.sPageButtonDisabled);
14396
- break;
14397
-
14398
- case 'next':
14399
- btnDisplay = lang.sNext;
14400
- btnClass = button + (page < pages-1 ?
14401
- '' : ' '+classes.sPageButtonDisabled);
14402
- break;
14403
-
14404
- case 'last':
14405
- btnDisplay = lang.sLast;
14406
- btnClass = button + (page < pages-1 ?
14407
- '' : ' '+classes.sPageButtonDisabled);
14408
- break;
14409
-
14410
- default:
14411
- btnDisplay = button + 1;
14412
- btnClass = page === button ?
14413
- classes.sPageButtonActive : '';
14414
- break;
14415
- }
14416
-
14417
- if ( btnDisplay !== null ) {
14418
- node = $('<a>', {
14419
- 'class': classes.sPageButton+' '+btnClass,
14420
- 'aria-controls': settings.sTableId,
14421
- 'data-dt-idx': counter,
14422
- 'tabindex': settings.iTabIndex,
14423
- 'id': idx === 0 && typeof button === 'string' ?
14424
- settings.sTableId +'_'+ button :
14425
- null
14426
- } )
14427
- .html( btnDisplay )
14428
- .appendTo( container );
14429
-
14430
- _fnBindAction(
14431
- node, {action: button}, clickHandler
14432
- );
14433
-
14434
- counter++;
14435
- }
14436
- }
14437
- }
14438
- };
14439
-
14440
- // IE9 throws an 'unknown error' if document.activeElement is used
14441
- // inside an iframe or frame. Try / catch the error. Not good for
14442
- // accessibility, but neither are frames.
14443
- var activeEl;
14444
-
14445
- try {
14446
- // Because this approach is destroying and recreating the paging
14447
- // elements, focus is lost on the select button which is bad for
14448
- // accessibility. So we want to restore focus once the draw has
14449
- // completed
14450
- activeEl = $(host).find(document.activeElement).data('dt-idx');
14451
- }
14452
- catch (e) {}
14453
-
14454
- attach( $(host).empty(), buttons );
14455
-
14456
- if ( activeEl ) {
14457
- $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
14458
- }
14459
- }
14460
- }
14461
- } );
14462
-
14463
-
14464
-
14465
- // Built in type detection. See model.ext.aTypes for information about
14466
- // what is required from this methods.
14467
- $.extend( DataTable.ext.type.detect, [
14468
- // Plain numbers - first since V8 detects some plain numbers as dates
14469
- // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14470
- function ( d, settings )
14471
- {
14472
- var decimal = settings.oLanguage.sDecimal;
14473
- return _isNumber( d, decimal ) ? 'num'+decimal : null;
14474
- },
14475
-
14476
- // Dates (only those recognised by the browser's Date.parse)
14477
- function ( d, settings )
14478
- {
14479
- // V8 will remove any unknown characters at the start and end of the
14480
- // expression, leading to false matches such as `$245.12` or `10%` being
14481
- // a valid date. See forum thread 18941 for detail.
14482
- if ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {
14483
- return null;
14484
- }
14485
- var parsed = Date.parse(d);
14486
- return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14487
- },
14488
-
14489
- // Formatted numbers
14490
- function ( d, settings )
14491
- {
14492
- var decimal = settings.oLanguage.sDecimal;
14493
- return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
14494
- },
14495
-
14496
- // HTML numeric
14497
- function ( d, settings )
14498
- {
14499
- var decimal = settings.oLanguage.sDecimal;
14500
- return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
14501
- },
14502
-
14503
- // HTML numeric, formatted
14504
- function ( d, settings )
14505
- {
14506
- var decimal = settings.oLanguage.sDecimal;
14507
- return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
14508
- },
14509
-
14510
- // HTML (this is strict checking - there must be html)
14511
- function ( d, settings )
14512
- {
14513
- return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14514
- 'html' : null;
14515
- }
14516
- ] );
14517
-
14518
-
14519
-
14520
- // Filter formatting functions. See model.ext.ofnSearch for information about
14521
- // what is required from these methods.
14522
- //
14523
- // Note that additional search methods are added for the html numbers and
14524
- // html formatted numbers by `_addNumericSort()` when we know what the decimal
14525
- // place is
14526
-
14527
-
14528
- $.extend( DataTable.ext.type.search, {
14529
- html: function ( data ) {
14530
- return _empty(data) ?
14531
- data :
14532
- typeof data === 'string' ?
14533
- data
14534
- .replace( _re_new_lines, " " )
14535
- .replace( _re_html, "" ) :
14536
- '';
14537
- },
14538
-
14539
- string: function ( data ) {
14540
- return _empty(data) ?
14541
- data :
14542
- typeof data === 'string' ?
14543
- data.replace( _re_new_lines, " " ) :
14544
- data;
14545
- }
14546
- } );
14547
-
14548
-
14549
-
14550
- var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
14551
- if ( d !== 0 && (!d || d === '-') ) {
14552
- return -Infinity;
14553
- }
14554
-
14555
- // If a decimal place other than `.` is used, it needs to be given to the
14556
- // function so we can detect it and replace with a `.` which is the only
14557
- // decimal place Javascript recognises - it is not locale aware.
14558
- if ( decimalPlace ) {
14559
- d = _numToDecimal( d, decimalPlace );
14560
- }
14561
-
14562
- if ( d.replace ) {
14563
- if ( re1 ) {
14564
- d = d.replace( re1, '' );
14565
- }
14566
-
14567
- if ( re2 ) {
14568
- d = d.replace( re2, '' );
14569
- }
14570
- }
14571
-
14572
- return d * 1;
14573
- };
14574
-
14575
-
14576
- // Add the numeric 'deformatting' functions for sorting and search. This is done
14577
- // in a function to provide an easy ability for the language options to add
14578
- // additional methods if a non-period decimal place is used.
14579
- function _addNumericSort ( decimalPlace ) {
14580
- $.each(
14581
- {
14582
- // Plain numbers
14583
- "num": function ( d ) {
14584
- return __numericReplace( d, decimalPlace );
14585
- },
14586
-
14587
- // Formatted numbers
14588
- "num-fmt": function ( d ) {
14589
- return __numericReplace( d, decimalPlace, _re_formatted_numeric );
14590
- },
14591
-
14592
- // HTML numeric
14593
- "html-num": function ( d ) {
14594
- return __numericReplace( d, decimalPlace, _re_html );
14595
- },
14596
-
14597
- // HTML numeric, formatted
14598
- "html-num-fmt": function ( d ) {
14599
- return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
14600
- }
14601
- },
14602
- function ( key, fn ) {
14603
- // Add the ordering method
14604
- _ext.type.order[ key+decimalPlace+'-pre' ] = fn;
14605
-
14606
- // For HTML types add a search formatter that will strip the HTML
14607
- if ( key.match(/^html\-/) ) {
14608
- _ext.type.search[ key+decimalPlace ] = _ext.type.search.html;
14609
- }
14610
- }
14611
- );
14612
- }
14613
-
14614
-
14615
- // Default sort methods
14616
- $.extend( _ext.type.order, {
14617
- // Dates
14618
- "date-pre": function ( d ) {
14619
- return Date.parse( d ) || 0;
14620
- },
14621
-
14622
- // html
14623
- "html-pre": function ( a ) {
14624
- return _empty(a) ?
14625
- '' :
14626
- a.replace ?
14627
- a.replace( /<.*?>/g, "" ).toLowerCase() :
14628
- a+'';
14629
- },
14630
-
14631
- // string
14632
- "string-pre": function ( a ) {
14633
- // This is a little complex, but faster than always calling toString,
14634
- // http://jsperf.com/tostring-v-check
14635
- return _empty(a) ?
14636
- '' :
14637
- typeof a === 'string' ?
14638
- a.toLowerCase() :
14639
- ! a.toString ?
14640
- '' :
14641
- a.toString();
14642
- },
14643
-
14644
- // string-asc and -desc are retained only for compatibility with the old
14645
- // sort methods
14646
- "string-asc": function ( x, y ) {
14647
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14648
- },
14649
-
14650
- "string-desc": function ( x, y ) {
14651
- return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14652
- }
14653
- } );
14654
-
14655
-
14656
- // Numeric sorting types - order doesn't matter here
14657
- _addNumericSort( '' );
14658
-
14659
-
14660
- $.extend( true, DataTable.ext.renderer, {
14661
- header: {
14662
- _: function ( settings, cell, column, classes ) {
14663
- // No additional mark-up required
14664
- // Attach a sort listener to update on sort - note that using the
14665
- // `DT` namespace will allow the event to be removed automatically
14666
- // on destroy, while the `dt` namespaced event is the one we are
14667
- // listening for
14668
- $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14669
- if ( settings !== ctx ) { // need to check this this is the host
14670
- return; // table, not a nested one
14671
- }
14672
-
14673
- var colIdx = column.idx;
14674
-
14675
- cell
14676
- .removeClass(
14677
- column.sSortingClass +' '+
14678
- classes.sSortAsc +' '+
14679
- classes.sSortDesc
14680
- )
14681
- .addClass( columns[ colIdx ] == 'asc' ?
14682
- classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14683
- classes.sSortDesc :
14684
- column.sSortingClass
14685
- );
14686
- } );
14687
- },
14688
-
14689
- jqueryui: function ( settings, cell, column, classes ) {
14690
- $('<div/>')
14691
- .addClass( classes.sSortJUIWrapper )
14692
- .append( cell.contents() )
14693
- .append( $('<span/>')
14694
- .addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
14695
- )
14696
- .appendTo( cell );
14697
-
14698
- // Attach a sort listener to update on sort
14699
- $(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {
14700
- if ( settings !== ctx ) {
14701
- return;
14702
- }
14703
-
14704
- var colIdx = column.idx;
14705
-
14706
- cell
14707
- .removeClass( classes.sSortAsc +" "+classes.sSortDesc )
14708
- .addClass( columns[ colIdx ] == 'asc' ?
14709
- classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14710
- classes.sSortDesc :
14711
- column.sSortingClass
14712
- );
14713
-
14714
- cell
14715
- .find( 'span.'+classes.sSortIcon )
14716
- .removeClass(
14717
- classes.sSortJUIAsc +" "+
14718
- classes.sSortJUIDesc +" "+
14719
- classes.sSortJUI +" "+
14720
- classes.sSortJUIAscAllowed +" "+
14721
- classes.sSortJUIDescAllowed
14722
- )
14723
- .addClass( columns[ colIdx ] == 'asc' ?
14724
- classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14725
- classes.sSortJUIDesc :
14726
- column.sSortingClassJUI
14727
- );
14728
- } );
14729
- }
14730
- }
14731
- } );
14732
-
14733
- /*
14734
- * Public helper functions. These aren't used internally by DataTables, or
14735
- * called by any of the options passed into DataTables, but they can be used
14736
- * externally by developers working with DataTables. They are helper functions
14737
- * to make working with DataTables a little bit easier.
14738
- */
14739
-
14740
- /**
14741
- * Helpers for `columns.render`.
14742
- *
14743
- * The options defined here can be used with the `columns.render` initialisation
14744
- * option to provide a display renderer. The following functions are defined:
14745
- *
14746
- * * `number` - Will format numeric data (defined by `columns.data`) for
14747
- * display, retaining the original unformatted data for sorting and filtering.
14748
- * It takes 5 parameters:
14749
- * * `string` - Thousands grouping separator
14750
- * * `string` - Decimal point indicator
14751
- * * `integer` - Number of decimal points to show
14752
- * * `string` (optional) - Prefix.
14753
- * * `string` (optional) - Postfix (/suffix).
14754
- *
14755
- * @example
14756
- * // Column definition using the number renderer
14757
- * {
14758
- * data: "salary",
14759
- * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14760
- * }
14761
- *
14762
- * @namespace
14763
- */
14764
- DataTable.render = {
14765
- number: function ( thousands, decimal, precision, prefix, postfix ) {
14766
- return {
14767
- display: function ( d ) {
14768
- if ( typeof d !== 'number' && typeof d !== 'string' ) {
14769
- return d;
14770
- }
14771
-
14772
- var negative = d < 0 ? '-' : '';
14773
- d = Math.abs( parseFloat( d ) );
14774
-
14775
- var intPart = parseInt( d, 10 );
14776
- var floatPart = precision ?
14777
- decimal+(d - intPart).toFixed( precision ).substring( 2 ):
14778
- '';
14779
-
14780
- return negative + (prefix||'') +
14781
- intPart.toString().replace(
14782
- /\B(?=(\d{3})+(?!\d))/g, thousands
14783
- ) +
14784
- floatPart +
14785
- (postfix||'');
14786
- }
14787
- };
14788
- }
14789
- };
14790
-
14791
-
14792
- /*
14793
- * This is really a good bit rubbish this method of exposing the internal methods
14794
- * publicly... - To be fixed in 2.0 using methods on the prototype
14795
- */
14796
-
14797
-
14798
- /**
14799
- * Create a wrapper function for exporting an internal functions to an external API.
14800
- * @param {string} fn API function name
14801
- * @returns {function} wrapped function
14802
- * @memberof DataTable#internal
14803
- */
14804
- function _fnExternApiFunc (fn)
14805
- {
14806
- return function() {
14807
- var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
14808
- Array.prototype.slice.call(arguments)
14809
- );
14810
- return DataTable.ext.internal[fn].apply( this, args );
14811
- };
14812
- }
14813
-
14814
-
14815
- /**
14816
- * Reference to internal functions for use by plug-in developers. Note that
14817
- * these methods are references to internal functions and are considered to be
14818
- * private. If you use these methods, be aware that they are liable to change
14819
- * between versions.
14820
- * @namespace
14821
- */
14822
- $.extend( DataTable.ext.internal, {
14823
- _fnExternApiFunc: _fnExternApiFunc,
14824
- _fnBuildAjax: _fnBuildAjax,
14825
- _fnAjaxUpdate: _fnAjaxUpdate,
14826
- _fnAjaxParameters: _fnAjaxParameters,
14827
- _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
14828
- _fnAjaxDataSrc: _fnAjaxDataSrc,
14829
- _fnAddColumn: _fnAddColumn,
14830
- _fnColumnOptions: _fnColumnOptions,
14831
- _fnAdjustColumnSizing: _fnAdjustColumnSizing,
14832
- _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
14833
- _fnColumnIndexToVisible: _fnColumnIndexToVisible,
14834
- _fnVisbleColumns: _fnVisbleColumns,
14835
- _fnGetColumns: _fnGetColumns,
14836
- _fnColumnTypes: _fnColumnTypes,
14837
- _fnApplyColumnDefs: _fnApplyColumnDefs,
14838
- _fnHungarianMap: _fnHungarianMap,
14839
- _fnCamelToHungarian: _fnCamelToHungarian,
14840
- _fnLanguageCompat: _fnLanguageCompat,
14841
- _fnBrowserDetect: _fnBrowserDetect,
14842
- _fnAddData: _fnAddData,
14843
- _fnAddTr: _fnAddTr,
14844
- _fnNodeToDataIndex: _fnNodeToDataIndex,
14845
- _fnNodeToColumnIndex: _fnNodeToColumnIndex,
14846
- _fnGetCellData: _fnGetCellData,
14847
- _fnSetCellData: _fnSetCellData,
14848
- _fnSplitObjNotation: _fnSplitObjNotation,
14849
- _fnGetObjectDataFn: _fnGetObjectDataFn,
14850
- _fnSetObjectDataFn: _fnSetObjectDataFn,
14851
- _fnGetDataMaster: _fnGetDataMaster,
14852
- _fnClearTable: _fnClearTable,
14853
- _fnDeleteIndex: _fnDeleteIndex,
14854
- _fnInvalidate: _fnInvalidate,
14855
- _fnGetRowElements: _fnGetRowElements,
14856
- _fnCreateTr: _fnCreateTr,
14857
- _fnBuildHead: _fnBuildHead,
14858
- _fnDrawHead: _fnDrawHead,
14859
- _fnDraw: _fnDraw,
14860
- _fnReDraw: _fnReDraw,
14861
- _fnAddOptionsHtml: _fnAddOptionsHtml,
14862
- _fnDetectHeader: _fnDetectHeader,
14863
- _fnGetUniqueThs: _fnGetUniqueThs,
14864
- _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
14865
- _fnFilterComplete: _fnFilterComplete,
14866
- _fnFilterCustom: _fnFilterCustom,
14867
- _fnFilterColumn: _fnFilterColumn,
14868
- _fnFilter: _fnFilter,
14869
- _fnFilterCreateSearch: _fnFilterCreateSearch,
14870
- _fnEscapeRegex: _fnEscapeRegex,
14871
- _fnFilterData: _fnFilterData,
14872
- _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
14873
- _fnUpdateInfo: _fnUpdateInfo,
14874
- _fnInfoMacros: _fnInfoMacros,
14875
- _fnInitialise: _fnInitialise,
14876
- _fnInitComplete: _fnInitComplete,
14877
- _fnLengthChange: _fnLengthChange,
14878
- _fnFeatureHtmlLength: _fnFeatureHtmlLength,
14879
- _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
14880
- _fnPageChange: _fnPageChange,
14881
- _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
14882
- _fnProcessingDisplay: _fnProcessingDisplay,
14883
- _fnFeatureHtmlTable: _fnFeatureHtmlTable,
14884
- _fnScrollDraw: _fnScrollDraw,
14885
- _fnApplyToChildren: _fnApplyToChildren,
14886
- _fnCalculateColumnWidths: _fnCalculateColumnWidths,
14887
- _fnThrottle: _fnThrottle,
14888
- _fnConvertToWidth: _fnConvertToWidth,
14889
- _fnGetWidestNode: _fnGetWidestNode,
14890
- _fnGetMaxLenString: _fnGetMaxLenString,
14891
- _fnStringToCss: _fnStringToCss,
14892
- _fnSortFlatten: _fnSortFlatten,
14893
- _fnSort: _fnSort,
14894
- _fnSortAria: _fnSortAria,
14895
- _fnSortListener: _fnSortListener,
14896
- _fnSortAttachListener: _fnSortAttachListener,
14897
- _fnSortingClasses: _fnSortingClasses,
14898
- _fnSortData: _fnSortData,
14899
- _fnSaveState: _fnSaveState,
14900
- _fnLoadState: _fnLoadState,
14901
- _fnSettingsFromNode: _fnSettingsFromNode,
14902
- _fnLog: _fnLog,
14903
- _fnMap: _fnMap,
14904
- _fnBindAction: _fnBindAction,
14905
- _fnCallbackReg: _fnCallbackReg,
14906
- _fnCallbackFire: _fnCallbackFire,
14907
- _fnLengthOverflow: _fnLengthOverflow,
14908
- _fnRenderer: _fnRenderer,
14909
- _fnDataSource: _fnDataSource,
14910
- _fnRowAttributes: _fnRowAttributes,
14911
- _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
14912
- // in 1.10, so this dead-end function is
14913
- // added to prevent errors
14914
- } );
14915
-
14916
-
14917
- // jQuery access
14918
- $.fn.dataTable = DataTable;
14919
-
14920
- // Legacy aliases
14921
- $.fn.dataTableSettings = DataTable.settings;
14922
- $.fn.dataTableExt = DataTable.ext;
14923
-
14924
- // With a capital `D` we return a DataTables API instance rather than a
14925
- // jQuery object
14926
- $.fn.DataTable = function ( opts ) {
14927
- return $(this).dataTable( opts ).api();
14928
- };
14929
-
14930
- // All properties that are available to $.fn.dataTable should also be
14931
- // available on $.fn.DataTable
14932
- $.each( DataTable, function ( prop, val ) {
14933
- $.fn.DataTable[ prop ] = val;
14934
- } );
14935
-
14936
-
14937
- // Information about events fired by DataTables - for documentation.
14938
- /**
14939
- * Draw event, fired whenever the table is redrawn on the page, at the same
14940
- * point as fnDrawCallback. This may be useful for binding events or
14941
- * performing calculations when the table is altered at all.
14942
- * @name DataTable#draw.dt
14943
- * @event
14944
- * @param {event} e jQuery event object
14945
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14946
- */
14947
-
14948
- /**
14949
- * Search event, fired when the searching applied to the table (using the
14950
- * built-in global search, or column filters) is altered.
14951
- * @name DataTable#search.dt
14952
- * @event
14953
- * @param {event} e jQuery event object
14954
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14955
- */
14956
-
14957
- /**
14958
- * Page change event, fired when the paging of the table is altered.
14959
- * @name DataTable#page.dt
14960
- * @event
14961
- * @param {event} e jQuery event object
14962
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14963
- */
14964
-
14965
- /**
14966
- * Order event, fired when the ordering applied to the table is altered.
14967
- * @name DataTable#order.dt
14968
- * @event
14969
- * @param {event} e jQuery event object
14970
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14971
- */
14972
-
14973
- /**
14974
- * DataTables initialisation complete event, fired when the table is fully
14975
- * drawn, including Ajax data loaded, if Ajax data is required.
14976
- * @name DataTable#init.dt
14977
- * @event
14978
- * @param {event} e jQuery event object
14979
- * @param {object} oSettings DataTables settings object
14980
- * @param {object} json The JSON object request from the server - only
14981
- * present if client-side Ajax sourced data is used</li></ol>
14982
- */
14983
-
14984
- /**
14985
- * State save event, fired when the table has changed state a new state save
14986
- * is required. This event allows modification of the state saving object
14987
- * prior to actually doing the save, including addition or other state
14988
- * properties (for plug-ins) or modification of a DataTables core property.
14989
- * @name DataTable#stateSaveParams.dt
14990
- * @event
14991
- * @param {event} e jQuery event object
14992
- * @param {object} oSettings DataTables settings object
14993
- * @param {object} json The state information to be saved
14994
- */
14995
-
14996
- /**
14997
- * State load event, fired when the table is loading state from the stored
14998
- * data, but prior to the settings object being modified by the saved state
14999
- * - allowing modification of the saved state is required or loading of
15000
- * state for a plug-in.
15001
- * @name DataTable#stateLoadParams.dt
15002
- * @event
15003
- * @param {event} e jQuery event object
15004
- * @param {object} oSettings DataTables settings object
15005
- * @param {object} json The saved state information
15006
- */
15007
-
15008
- /**
15009
- * State loaded event, fired when state has been loaded from stored data and
15010
- * the settings object has been modified by the loaded data.
15011
- * @name DataTable#stateLoaded.dt
15012
- * @event
15013
- * @param {event} e jQuery event object
15014
- * @param {object} oSettings DataTables settings object
15015
- * @param {object} json The saved state information
15016
- */
15017
-
15018
- /**
15019
- * Processing event, fired when DataTables is doing some kind of processing
15020
- * (be it, order, searcg or anything else). It can be used to indicate to
15021
- * the end user that there is something happening, or that something has
15022
- * finished.
15023
- * @name DataTable#processing.dt
15024
- * @event
15025
- * @param {event} e jQuery event object
15026
- * @param {object} oSettings DataTables settings object
15027
- * @param {boolean} bShow Flag for if DataTables is doing processing or not
15028
- */
15029
-
15030
- /**
15031
- * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15032
- * request to made to the server for new data. This event is called before
15033
- * DataTables processed the returned data, so it can also be used to pre-
15034
- * process the data returned from the server, if needed.
15035
- *
15036
- * Note that this trigger is called in `fnServerData`, if you override
15037
- * `fnServerData` and which to use this event, you need to trigger it in you
15038
- * success function.
15039
- * @name DataTable#xhr.dt
15040
- * @event
15041
- * @param {event} e jQuery event object
15042
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15043
- * @param {object} json JSON returned from the server
15044
- *
15045
- * @example
15046
- * // Use a custom property returned from the server in another DOM element
15047
- * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15048
- * $('#status').html( json.status );
15049
- * } );
15050
- *
15051
- * @example
15052
- * // Pre-process the data returned from the server
15053
- * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15054
- * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15055
- * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15056
- * }
15057
- * // Note no return - manipulate the data directly in the JSON object.
15058
- * } );
15059
- */
15060
-
15061
- /**
15062
- * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15063
- * or passing the bDestroy:true parameter in the initialisation object. This
15064
- * can be used to remove bound events, added DOM nodes, etc.
15065
- * @name DataTable#destroy.dt
15066
- * @event
15067
- * @param {event} e jQuery event object
15068
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15069
- */
15070
-
15071
- /**
15072
- * Page length change event, fired when number of records to show on each
15073
- * page (the length) is changed.
15074
- * @name DataTable#length.dt
15075
- * @event
15076
- * @param {event} e jQuery event object
15077
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15078
- * @param {integer} len New length
15079
- */
15080
-
15081
- /**
15082
- * Column sizing has changed.
15083
- * @name DataTable#column-sizing.dt
15084
- * @event
15085
- * @param {event} e jQuery event object
15086
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15087
- */
15088
-
15089
- /**
15090
- * Column visibility has changed.
15091
- * @name DataTable#column-visibility.dt
15092
- * @event
15093
- * @param {event} e jQuery event object
15094
- * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15095
- * @param {int} column Column index
15096
- * @param {bool} vis `false` if column now hidden, or `true` if visible
15097
- */
15098
-
15099
- return $.fn.dataTable;
15100
- }));
15101
-
15102
- }(window, document));
15103
- (function(window, document, undefined){
15104
-
15105
- var factory = function( $, DataTable ) {
15106
- "use strict";
15107
-
15108
- $.extend( true, DataTable.defaults, {
15109
- dom:
15110
- "<'row'<'col-sm-5'><'col-sm-4'f><'col-sm-3'l>>" +
15111
- "<'row'<'col-sm-12'tr>>" +
15112
- "<'row'<'col-sm-5'i><'col-sm-7'p>>",
15113
- renderer: 'bootstrap'
15114
- } );
15115
-
15116
-
15117
- /* Default class modification */
15118
- $.extend( DataTable.ext.classes, {
15119
- sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
15120
- sFilterInput: "form-control input-sm",
15121
- sLengthSelect: "form-control input-sm"
15122
- } );
15123
-
15124
- DataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {
15125
- var api = new DataTable.Api( settings );
15126
- var classes = settings.oClasses;
15127
- var lang = settings.oLanguage.oPaginate;
15128
- var btnDisplay, btnClass, counter=0;
15129
-
15130
- var attach = function( container, buttons ) {
15131
- var i, ien, node, button;
15132
- var clickHandler = function ( e ) {
15133
- e.preventDefault();
15134
- if ( !$(e.currentTarget).hasClass('disabled') ) {
15135
- api.page( e.data.action ).draw( 'page' );
15136
- }
15137
- };
15138
-
15139
- for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
15140
- button = buttons[i];
15141
-
15142
- if ( $.isArray( button ) ) {
15143
- attach( container, button );
15144
- }
15145
- else {
15146
- btnDisplay = '';
15147
- btnClass = '';
15148
-
15149
- switch ( button ) {
15150
- case 'ellipsis':
15151
- btnDisplay = '&hellip;';
15152
- btnClass = 'disabled';
15153
- break;
15154
-
15155
- case 'first':
15156
- btnDisplay = lang.sFirst;
15157
- btnClass = button + (page > 0 ?
15158
- '' : ' disabled');
15159
- break;
15160
-
15161
- case 'previous':
15162
- btnDisplay = lang.sPrevious;
15163
- btnClass = button + (page > 0 ?
15164
- '' : ' disabled');
15165
- break;
15166
-
15167
- case 'next':
15168
- btnDisplay = lang.sNext;
15169
- btnClass = button + (page < pages-1 ?
15170
- '' : ' disabled');
15171
- break;
15172
-
15173
- case 'last':
15174
- btnDisplay = lang.sLast;
15175
- btnClass = button + (page < pages-1 ?
15176
- '' : ' disabled');
15177
- break;
15178
-
15179
- default:
15180
- btnDisplay = button + 1;
15181
- btnClass = page === button ?
15182
- 'active' : '';
15183
- break;
15184
- }
15185
-
15186
- if ( btnDisplay ) {
15187
- node = $('<li>', {
15188
- 'class': classes.sPageButton+' '+btnClass,
15189
- 'id': idx === 0 && typeof button === 'string' ?
15190
- settings.sTableId +'_'+ button :
15191
- null
15192
- } )
15193
- .append( $('<a>', {
15194
- 'href': '#',
15195
- 'aria-controls': settings.sTableId,
15196
- 'data-dt-idx': counter,
15197
- 'tabindex': settings.iTabIndex
15198
- } )
15199
- .html( btnDisplay )
15200
- )
15201
- .appendTo( container );
15202
-
15203
- settings.oApi._fnBindAction(
15204
- node, {action: button}, clickHandler
15205
- );
15206
-
15207
- counter++;
15208
- }
15209
- }
15210
- }
15211
- };
15212
-
15213
- var activeEl;
15214
-
15215
- try {
15216
-
15217
- activeEl = $(host).find(document.activeElement).data('dt-idx');
15218
- }
15219
- catch (e) {}
15220
-
15221
- attach(
15222
- $(host).empty().html('<ul class="pagination"/>').children('ul'),
15223
- buttons
15224
- );
15225
-
15226
- if ( activeEl ) {
15227
- $(host).find( '[data-dt-idx='+activeEl+']' ).focus();
15228
- }
15229
- };
15230
-
15231
-
15232
- if ( DataTable.TableTools ) {
15233
- // Set the classes that TableTools uses to something suitable for Bootstrap
15234
- $.extend( true, DataTable.TableTools.classes, {
15235
- "container": "DTTT btn-group",
15236
- "buttons": {
15237
- "normal": "btn btn-default",
15238
- "disabled": "disabled"
15239
- },
15240
- "collection": {
15241
- "container": "DTTT_dropdown dropdown-menu",
15242
- "buttons": {
15243
- "normal": "",
15244
- "disabled": "disabled"
15245
- }
15246
- },
15247
- "print": {
15248
- "info": "DTTT_print_info"
15249
- },
15250
- "select": {
15251
- "row": "active"
15252
- }
15253
- } );
15254
-
15255
- // Have the collection use a bootstrap compatible drop down
15256
- $.extend( true, DataTable.TableTools.DEFAULTS.oTags, {
15257
- "collection": {
15258
- "container": "ul",
15259
- "button": "li",
15260
- "liner": "a"
15261
- }
15262
- } );
15263
- }
15264
-
15265
- };
15266
- if ( typeof define === 'function' && define.amd ) {
15267
- define( ['jquery', 'datatables'], factory );
15268
- }
15269
- else if ( typeof exports === 'object' ) {
15270
- // Node/CommonJS
15271
- factory( require('jquery'), require('datatables') );
15272
- }
15273
- else if ( jQuery ) {
15274
- // Otherwise simply initialise as normal, stopping multiple evaluation
15275
- factory( jQuery, jQuery.fn.dataTable );
15276
- }
15277
- })(window, document);
1
+ !function(t,e,n){!function(t){"use strict";"function"==typeof define&&define.amd?define("datatables",["jquery"],t):"object"==typeof exports?module.exports=t(require("jquery")):jQuery&&!jQuery.fn.dataTable&&t(jQuery)}(function(a){"use strict";function r(t){var e,n,o="a aa ai ao as b fn i m o s ",i={};a.each(t,function(a,s){e=a.match(/^([^A-Z]+?)([A-Z])/),e&&-1!==o.indexOf(e[1]+" ")&&(n=a.replace(e[0],e[2].toLowerCase()),i[n]=a,"o"===e[1]&&r(t[a]))}),t._hungarianMap=i}function o(t,e,i){t._hungarianMap||r(t);var s;a.each(e,function(r,l){s=t._hungarianMap[r],s===n||!i&&e[s]!==n||("o"===s.charAt(0)?(e[s]||(e[s]={}),a.extend(!0,e[s],e[r]),o(t[s],e[s],i)):e[s]=e[r])})}function i(t){var e=qt.defaults.oLanguage,n=t.sZeroRecords;!t.sEmptyTable&&n&&"No data available in table"===e.sEmptyTable&&Nt(t,t,"sZeroRecords","sEmptyTable"),!t.sLoadingRecords&&n&&"Loading..."===e.sLoadingRecords&&Nt(t,t,"sZeroRecords","sLoadingRecords"),t.sInfoThousands&&(t.sThousands=t.sInfoThousands);var a=t.sDecimal;a&&Xt(a)}function s(t){be(t,"ordering","bSort"),be(t,"orderMulti","bSortMulti"),be(t,"orderClasses","bSortClasses"),be(t,"orderCellsTop","bSortCellsTop"),be(t,"order","aaSorting"),be(t,"orderFixed","aaSortingFixed"),be(t,"paging","bPaginate"),be(t,"pagingType","sPaginationType"),be(t,"pageLength","iDisplayLength"),be(t,"searching","bFilter"),"boolean"==typeof t.sScrollX&&(t.sScrollX=t.sScrollX?"100%":"");var e=t.aoSearchCols;if(e)for(var n=0,a=e.length;a>n;n++)e[n]&&o(qt.models.oSearch,e[n])}function l(t){be(t,"orderable","bSortable"),be(t,"orderData","aDataSort"),be(t,"orderSequence","asSorting"),be(t,"orderDataType","sortDataType");var e=t.aDataSort;e&&!a.isArray(e)&&(t.aDataSort=[e])}function u(t){if(!qt.__browser){var e={};qt.__browser=e;var n=a("<div/>").css({position:"fixed",top:0,left:0,height:1,width:1,overflow:"hidden"}).append(a("<div/>").css({position:"absolute",top:1,left:1,width:100,overflow:"scroll"}).append(a("<div/>").css({width:"100%",height:10}))).appendTo("body"),r=n.children(),o=r.children();e.barWidth=r[0].offsetWidth-r[0].clientWidth,e.bScrollOversize=100===o[0].offsetWidth&&100!==r[0].clientWidth,e.bScrollbarLeft=1!==Math.round(o.offset().left),e.bBounding=n[0].getBoundingClientRect().width?!0:!1,n.remove()}a.extend(t.oBrowser,qt.__browser),t.oScroll.iBarWidth=qt.__browser.barWidth}function c(t,e,a,r,o,i){var s,l=r,u=!1;for(a!==n&&(s=a,u=!0);l!==o;)t.hasOwnProperty(l)&&(s=u?e(s,t[l],l,t):t[l],u=!0,l+=i);return s}function f(t,n){var r=qt.defaults.column,o=t.aoColumns.length,i=a.extend({},qt.models.oColumn,r,{nTh:n?n:e.createElement("th"),sTitle:r.sTitle?r.sTitle:n?n.innerHTML:"",aDataSort:r.aDataSort?r.aDataSort:[o],mData:r.mData?r.mData:o,idx:o});t.aoColumns.push(i);var s=t.aoPreSearchCols;s[o]=a.extend({},qt.models.oSearch,s[o]),d(t,o,a(n).data())}function d(t,e,r){var i=t.aoColumns[e],s=t.oClasses,u=a(i.nTh);if(!i.sWidthOrig){i.sWidthOrig=u.attr("width")||null;var c=(u.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);c&&(i.sWidthOrig=c[1])}r!==n&&null!==r&&(l(r),o(qt.defaults.column,r),r.mDataProp===n||r.mData||(r.mData=r.mDataProp),r.sType&&(i._sManualType=r.sType),r.className&&!r.sClass&&(r.sClass=r.className),a.extend(i,r),Nt(i,r,"sWidth","sWidthOrig"),r.iDataSort!==n&&(i.aDataSort=[r.iDataSort]),Nt(i,r,"aDataSort"));var f=i.mData,d=I(f),h=i.mRender?I(i.mRender):null,p=function(t){return"string"==typeof t&&-1!==t.indexOf("@")};i._bAttrSrc=a.isPlainObject(f)&&(p(f.sort)||p(f.type)||p(f.filter)),i.fnGetData=function(t,e,a){var r=d(t,e,n,a);return h&&e?h(r,e,t,a):r},i.fnSetData=function(t,e,n){return A(f)(t,e,n)},"number"!=typeof f&&(t._rowReadObject=!0),t.oFeatures.bSort||(i.bSortable=!1,u.addClass(s.sSortableNone));var g=-1!==a.inArray("asc",i.asSorting),b=-1!==a.inArray("desc",i.asSorting);i.bSortable&&(g||b)?g&&!b?(i.sSortingClass=s.sSortableAsc,i.sSortingClassJUI=s.sSortJUIAscAllowed):!g&&b?(i.sSortingClass=s.sSortableDesc,i.sSortingClassJUI=s.sSortJUIDescAllowed):(i.sSortingClass=s.sSortable,i.sSortingClassJUI=s.sSortJUI):(i.sSortingClass=s.sSortableNone,i.sSortingClassJUI="")}function h(t){if(t.oFeatures.bAutoWidth!==!1){var e=t.aoColumns;St(t);for(var n=0,a=e.length;a>n;n++)e[n].nTh.style.width=e[n].sWidth}var r=t.oScroll;(""!==r.sY||""!==r.sX)&&bt(t),Wt(t,null,"column-sizing",[t])}function p(t,e){var n=v(t,"bVisible");return"number"==typeof n[e]?n[e]:null}function g(t,e){var n=v(t,"bVisible"),r=a.inArray(e,n);return-1!==r?r:null}function b(t){return v(t,"bVisible").length}function v(t,e){var n=[];return a.map(t.aoColumns,function(t,a){t[e]&&n.push(a)}),n}function S(t){var e,a,r,o,i,s,l,u,c,f=t.aoColumns,d=t.aoData,h=qt.ext.type.detect;for(e=0,a=f.length;a>e;e++)if(l=f[e],c=[],!l.sType&&l._sManualType)l.sType=l._sManualType;else if(!l.sType){for(r=0,o=h.length;o>r;r++){for(i=0,s=d.length;s>i&&(c[i]===n&&(c[i]=w(t,i,e,"type")),u=h[r](c[i],t),u||r===h.length-1)&&"html"!==u;i++);if(u){l.sType=u;break}}l.sType||(l.sType="string")}}function m(t,e,r,o){var i,s,l,u,c,d,h,p=t.aoColumns;if(e)for(i=e.length-1;i>=0;i--){h=e[i];var g=h.targets!==n?h.targets:h.aTargets;for(a.isArray(g)||(g=[g]),l=0,u=g.length;u>l;l++)if("number"==typeof g[l]&&g[l]>=0){for(;p.length<=g[l];)f(t);o(g[l],h)}else if("number"==typeof g[l]&&g[l]<0)o(p.length+g[l],h);else if("string"==typeof g[l])for(c=0,d=p.length;d>c;c++)("_all"==g[l]||a(p[c].nTh).hasClass(g[l]))&&o(c,h)}if(r)for(i=0,s=r.length;s>i;i++)o(i,r[i])}function D(t,e,r,o){var i=t.aoData.length,s=a.extend(!0,{},qt.models.oRow,{src:r?"dom":"data",idx:i});s._aData=e,t.aoData.push(s);for(var l=t.aoColumns,u=0,c=l.length;c>u;u++)l[u].sType=null;t.aiDisplayMaster.push(i);var f=t.rowIdFn(e);return f!==n&&(t.aIds[f]=s),(r||!t.oFeatures.bDeferRender)&&H(t,i,r,o),i}function y(t,e){var n;return e instanceof a||(e=a(e)),e.map(function(e,a){return n=j(t,a),D(t,n.data,a,n.cells)})}function _(t,e){return e._DT_RowIndex!==n?e._DT_RowIndex:null}function T(t,e,n){return a.inArray(n,t.aoData[e].anCells)}function w(t,e,a,r){var o=t.iDraw,i=t.aoColumns[a],s=t.aoData[e]._aData,l=i.sDefaultContent,u=i.fnGetData(s,r,{settings:t,row:e,col:a});if(u===n)return t.iDrawError!=o&&null===l&&(Ht(t,0,"Requested unknown parameter "+("function"==typeof i.mData?"{function}":"'"+i.mData+"'")+" for row "+e,4),t.iDrawError=o),l;if(u!==s&&null!==u||null===l){if("function"==typeof u)return u.call(s)}else u=l;return null===u&&"display"==r?"":u}function C(t,e,n,a){var r=t.aoColumns[n],o=t.aoData[e]._aData;r.fnSetData(o,a,{settings:t,row:e,col:n})}function x(t){return a.map(t.match(/(\\.|[^\.])+/g)||[""],function(t){return t.replace(/\\./g,".")})}function I(t){if(a.isPlainObject(t)){var e={};return a.each(t,function(t,n){n&&(e[t]=I(n))}),function(t,a,r,o){var i=e[a]||e._;return i!==n?i(t,a,r,o):t}}if(null===t)return function(t){return t};if("function"==typeof t)return function(e,n,a,r){return t(e,n,a,r)};if("string"!=typeof t||-1===t.indexOf(".")&&-1===t.indexOf("[")&&-1===t.indexOf("("))return function(e,n){return e[t]};var r=function(t,e,o){var i,s,l,u;if(""!==o)for(var c=x(o),f=0,d=c.length;d>f;f++){if(i=c[f].match(ve),s=c[f].match(Se),i){if(c[f]=c[f].replace(ve,""),""!==c[f]&&(t=t[c[f]]),l=[],c.splice(0,f+1),u=c.join("."),a.isArray(t))for(var h=0,p=t.length;p>h;h++)l.push(r(t[h],e,u));var g=i[0].substring(1,i[0].length-1);t=""===g?l:l.join(g);break}if(s)c[f]=c[f].replace(Se,""),t=t[c[f]]();else{if(null===t||t[c[f]]===n)return n;t=t[c[f]]}}return t};return function(e,n){return r(e,n,t)}}function A(t){if(a.isPlainObject(t))return A(t._);if(null===t)return function(){};if("function"==typeof t)return function(e,n,a){t(e,"set",n,a)};if("string"!=typeof t||-1===t.indexOf(".")&&-1===t.indexOf("[")&&-1===t.indexOf("("))return function(e,n){e[t]=n};var e=function(t,r,o){for(var i,s,l,u,c,f=x(o),d=f[f.length-1],h=0,p=f.length-1;p>h;h++){if(s=f[h].match(ve),l=f[h].match(Se),s){if(f[h]=f[h].replace(ve,""),t[f[h]]=[],i=f.slice(),i.splice(0,h+1),c=i.join("."),a.isArray(r))for(var g=0,b=r.length;b>g;g++)u={},e(u,r[g],c),t[f[h]].push(u);else t[f[h]]=r;return}l&&(f[h]=f[h].replace(Se,""),t=t[f[h]](r)),(null===t[f[h]]||t[f[h]]===n)&&(t[f[h]]={}),t=t[f[h]]}d.match(Se)?t=t[d.replace(Se,"")](r):t[d.replace(ve,"")]=r};return function(n,a){return e(n,a,t)}}function F(t){return ce(t.aoData,"_aData")}function L(t){t.aoData.length=0,t.aiDisplayMaster.length=0,t.aiDisplay.length=0,t.aIds={}}function P(t,e,a){for(var r=-1,o=0,i=t.length;i>o;o++)t[o]==e?r=o:t[o]>e&&t[o]--;-1!=r&&a===n&&t.splice(r,1)}function R(t,e,a,r){var o,i,s=t.aoData[e],l=function(n,a){for(;n.childNodes.length;)n.removeChild(n.firstChild);n.innerHTML=w(t,e,a,"display")};if("dom"!==a&&(a&&"auto"!==a||"dom"!==s.src)){var u=s.anCells;if(u)if(r!==n)l(u[r],r);else for(o=0,i=u.length;i>o;o++)l(u[o],o)}else s._aData=j(t,s,r,r===n?n:s._aData).data;s._aSortData=null,s._aFilterData=null;var c=t.aoColumns;if(r!==n)c[r].sType=null;else{for(o=0,i=c.length;i>o;o++)c[o].sType=null;N(t,s)}}function j(t,e,r,o){var i,s,l,u=[],c=e.firstChild,f=0,d=t.aoColumns,h=t._rowReadObject;o=o!==n?o:h?{}:[];var p=function(t,e){if("string"==typeof t){var n=t.indexOf("@");if(-1!==n){var a=t.substring(n+1),r=A(t);r(o,e.getAttribute(a))}}},g=function(t){if(r===n||r===f)if(s=d[f],l=a.trim(t.innerHTML),s&&s._bAttrSrc){var e=A(s.mData._);e(o,l),p(s.mData.sort,t),p(s.mData.type,t),p(s.mData.filter,t)}else h?(s._setter||(s._setter=A(s.mData)),s._setter(o,l)):o[f]=l;f++};if(c)for(;c;)i=c.nodeName.toUpperCase(),("TD"==i||"TH"==i)&&(g(c),u.push(c)),c=c.nextSibling;else{u=e.anCells;for(var b=0,v=u.length;v>b;b++)g(u[b])}var S=c?e:e.nTr;if(S){var m=S.getAttribute("id");m&&A(t.rowId)(o,m)}return{data:o,cells:u}}function H(t,n,a,r){var o,i,s,l,u,c=t.aoData[n],f=c._aData,d=[];if(null===c.nTr){for(o=a||e.createElement("tr"),c.nTr=o,c.anCells=d,o._DT_RowIndex=n,N(t,c),l=0,u=t.aoColumns.length;u>l;l++)s=t.aoColumns[l],i=a?r[l]:e.createElement(s.sCellType),d.push(i),(!a||s.mRender||s.mData!==l)&&(i.innerHTML=w(t,n,l,"display")),s.sClass&&(i.className+=" "+s.sClass),s.bVisible&&!a?o.appendChild(i):!s.bVisible&&a&&i.parentNode.removeChild(i),s.fnCreatedCell&&s.fnCreatedCell.call(t.oInstance,i,w(t,n,l),f,n,l);Wt(t,"aoRowCreatedCallback",null,[o,f,n])}c.nTr.setAttribute("role","row")}function N(t,e){var n=e.nTr,r=e._aData;if(n){var o=t.rowIdFn(r);if(o&&(n.id=o),r.DT_RowClass){var i=r.DT_RowClass.split(" ");e.__rowc=e.__rowc?ge(e.__rowc.concat(i)):i,a(n).removeClass(e.__rowc.join(" ")).addClass(r.DT_RowClass)}r.DT_RowAttr&&a(n).attr(r.DT_RowAttr),r.DT_RowData&&a(n).data(r.DT_RowData)}}function k(t){var e,n,r,o,i,s=t.nTHead,l=t.nTFoot,u=0===a("th, td",s).length,c=t.oClasses,f=t.aoColumns;for(u&&(o=a("<tr/>").appendTo(s)),e=0,n=f.length;n>e;e++)i=f[e],r=a(i.nTh).addClass(i.sClass),u&&r.appendTo(o),t.oFeatures.bSort&&(r.addClass(i.sSortingClass),i.bSortable!==!1&&(r.attr("tabindex",t.iTabIndex).attr("aria-controls",t.sTableId),At(t,i.nTh,e))),i.sTitle!=r[0].innerHTML&&r.html(i.sTitle),Et(t,"header")(t,r,i,c);if(u&&E(t.aoHeader,s),a(s).find(">tr").attr("role","row"),a(s).find(">tr>th, >tr>td").addClass(c.sHeaderTH),a(l).find(">tr>th, >tr>td").addClass(c.sFooterTH),null!==l){var d=t.aoFooter[0];for(e=0,n=d.length;n>e;e++)i=f[e],i.nTf=d[e].cell,i.sClass&&a(i.nTf).addClass(i.sClass)}}function O(t,e,r){var o,i,s,l,u,c,f,d,h,p=[],g=[],b=t.aoColumns.length;if(e){for(r===n&&(r=!1),o=0,i=e.length;i>o;o++){for(p[o]=e[o].slice(),p[o].nTr=e[o].nTr,s=b-1;s>=0;s--)t.aoColumns[s].bVisible||r||p[o].splice(s,1);g.push([])}for(o=0,i=p.length;i>o;o++){if(f=p[o].nTr)for(;c=f.firstChild;)f.removeChild(c);for(s=0,l=p[o].length;l>s;s++)if(d=1,h=1,g[o][s]===n){for(f.appendChild(p[o][s].cell),g[o][s]=1;p[o+d]!==n&&p[o][s].cell==p[o+d][s].cell;)g[o+d][s]=1,d++;for(;p[o][s+h]!==n&&p[o][s].cell==p[o][s+h].cell;){for(u=0;d>u;u++)g[o+u][s+h]=1;h++}a(p[o][s].cell).attr("rowspan",d).attr("colspan",h)}}}}function M(t){var e=Wt(t,"aoPreDrawCallback","preDraw",[t]);if(-1!==a.inArray(!1,e))return void pt(t,!1);var r=[],o=0,i=t.asStripeClasses,s=i.length,l=(t.aoOpenRows.length,t.oLanguage),u=t.iInitDisplayStart,c="ssp"==Bt(t),f=t.aiDisplay;t.bDrawing=!0,u!==n&&-1!==u&&(t._iDisplayStart=c?u:u>=t.fnRecordsDisplay()?0:u,t.iInitDisplayStart=-1);var d=t._iDisplayStart,h=t.fnDisplayEnd();if(t.bDeferLoading)t.bDeferLoading=!1,t.iDraw++,pt(t,!1);else if(c){if(!t.bDestroying&&!X(t))return}else t.iDraw++;if(0!==f.length)for(var p=c?0:d,g=c?t.aoData.length:h,v=p;g>v;v++){var S=f[v],m=t.aoData[S];null===m.nTr&&H(t,S);var D=m.nTr;if(0!==s){var y=i[o%s];m._sRowStripe!=y&&(a(D).removeClass(m._sRowStripe).addClass(y),m._sRowStripe=y)}Wt(t,"aoRowCallback",null,[D,m._aData,o,v]),r.push(D),o++}else{var _=l.sZeroRecords;1==t.iDraw&&"ajax"==Bt(t)?_=l.sLoadingRecords:l.sEmptyTable&&0===t.fnRecordsTotal()&&(_=l.sEmptyTable),r[0]=a("<tr/>",{"class":s?i[0]:""}).append(a("<td />",{valign:"top",colSpan:b(t),"class":t.oClasses.sRowEmpty}).html(_))[0]}Wt(t,"aoHeaderCallback","header",[a(t.nTHead).children("tr")[0],F(t),d,h,f]),Wt(t,"aoFooterCallback","footer",[a(t.nTFoot).children("tr")[0],F(t),d,h,f]);var T=a(t.nTBody);T.children().detach(),T.append(a(r)),Wt(t,"aoDrawCallback","draw",[t]),t.bSorted=!1,t.bFiltered=!1,t.bDrawing=!1}function W(t,e){var n=t.oFeatures,a=n.bSort,r=n.bFilter;a&&Ct(t),r?z(t,t.oPreviousSearch):t.aiDisplay=t.aiDisplayMaster.slice(),e!==!0&&(t._iDisplayStart=0),t._drawHold=e,M(t),t._drawHold=!1}function U(t){var e=t.oClasses,n=a(t.nTable),r=a("<div/>").insertBefore(n),o=t.oFeatures,i=a("<div/>",{id:t.sTableId+"_wrapper","class":e.sWrapper+(t.nTFoot?"":" "+e.sNoFooter)});t.nHolding=r[0],t.nTableWrapper=i[0],t.nTableReinsertBefore=t.nTable.nextSibling;for(var s,l,u,c,f,d,h=t.sDom.split(""),p=0;p<h.length;p++){if(s=null,l=h[p],"<"==l){if(u=a("<div/>")[0],c=h[p+1],"'"==c||'"'==c){for(f="",d=2;h[p+d]!=c;)f+=h[p+d],d++;if("H"==f?f=e.sJUIHeader:"F"==f&&(f=e.sJUIFooter),-1!=f.indexOf(".")){var g=f.split(".");u.id=g[0].substr(1,g[0].length-1),u.className=g[1]}else"#"==f.charAt(0)?u.id=f.substr(1,f.length-1):u.className=f;p+=d}i.append(u),i=a(u)}else if(">"==l)i=i.parent();else if("l"==l&&o.bPaginate&&o.bLengthChange)s=ct(t);else if("f"==l&&o.bFilter)s=$(t);else if("r"==l&&o.bProcessing)s=ht(t);else if("t"==l)s=gt(t);else if("i"==l&&o.bInfo)s=rt(t);else if("p"==l&&o.bPaginate)s=ft(t);else if(0!==qt.ext.feature.length)for(var b=qt.ext.feature,v=0,S=b.length;S>v;v++)if(l==b[v].cFeature){s=b[v].fnInit(t);break}if(s){var m=t.aanFeatures;m[l]||(m[l]=[]),m[l].push(s),i.append(s)}}r.replaceWith(i),t.nHolding=null}function E(t,e){var n,r,o,i,s,l,u,c,f,d,h,p=a(e).children("tr"),g=function(t,e,n){for(var a=t[e];a[n];)n++;return n};for(t.splice(0,t.length),o=0,l=p.length;l>o;o++)t.push([]);for(o=0,l=p.length;l>o;o++)for(n=p[o],c=0,r=n.firstChild;r;){if("TD"==r.nodeName.toUpperCase()||"TH"==r.nodeName.toUpperCase())for(f=1*r.getAttribute("colspan"),d=1*r.getAttribute("rowspan"),f=f&&0!==f&&1!==f?f:1,d=d&&0!==d&&1!==d?d:1,u=g(t,o,c),h=1===f?!0:!1,s=0;f>s;s++)for(i=0;d>i;i++)t[o+i][u+s]={cell:r,unique:h},t[o+i].nTr=n;r=r.nextSibling}}function B(t,e,n){var a=[];n||(n=t.aoHeader,e&&(n=[],E(n,e)));for(var r=0,o=n.length;o>r;r++)for(var i=0,s=n[r].length;s>i;i++)!n[r][i].unique||a[i]&&t.bSortCellsTop||(a[i]=n[r][i].cell);return a}function J(t,e,n){if(Wt(t,"aoServerParams","serverParams",[e]),e&&a.isArray(e)){var r={},o=/(.*?)\[\]$/;a.each(e,function(t,e){var n=e.name.match(o);if(n){var a=n[0];r[a]||(r[a]=[]),r[a].push(e.value)}else r[e.name]=e.value}),e=r}var i,s=t.ajax,l=t.oInstance,u=function(e){Wt(t,null,"xhr",[t,e,t.jqXHR]),n(e)};if(a.isPlainObject(s)&&s.data){i=s.data;var c=a.isFunction(i)?i(e,t):i;e=a.isFunction(i)&&c?c:a.extend(!0,e,c),delete s.data}var f={data:e,success:function(e){var n=e.error||e.sError;n&&Ht(t,0,n),t.json=e,u(e)},dataType:"json",cache:!1,type:t.sServerMethod,error:function(e,n,r){var o=Wt(t,null,"xhr",[t,null,t.jqXHR]);-1===a.inArray(!0,o)&&("parsererror"==n?Ht(t,0,"Invalid JSON response",1):4===e.readyState&&Ht(t,0,"Ajax error",7)),pt(t,!1)}};t.oAjaxData=e,Wt(t,null,"preXhr",[t,e]),t.fnServerData?t.fnServerData.call(l,t.sAjaxSource,a.map(e,function(t,e){return{name:e,value:t}}),u,t):t.sAjaxSource||"string"==typeof s?t.jqXHR=a.ajax(a.extend(f,{url:s||t.sAjaxSource})):a.isFunction(s)?t.jqXHR=s.call(l,e,u,t):(t.jqXHR=a.ajax(a.extend(f,s)),s.data=i)}function X(t){return t.bAjaxDataGet?(t.iDraw++,pt(t,!0),J(t,V(t),function(e){q(t,e)}),!1):!0}function V(t){var e,n,r,o,i=t.aoColumns,s=i.length,l=t.oFeatures,u=t.oPreviousSearch,c=t.aoPreSearchCols,f=[],d=wt(t),h=t._iDisplayStart,p=l.bPaginate!==!1?t._iDisplayLength:-1,g=function(t,e){f.push({name:t,value:e})};g("sEcho",t.iDraw),g("iColumns",s),g("sColumns",ce(i,"sName").join(",")),g("iDisplayStart",h),g("iDisplayLength",p);var b={draw:t.iDraw,columns:[],order:[],start:h,length:p,search:{value:u.sSearch,regex:u.bRegex}};for(e=0;s>e;e++)r=i[e],o=c[e],n="function"==typeof r.mData?"function":r.mData,b.columns.push({data:n,name:r.sName,searchable:r.bSearchable,orderable:r.bSortable,search:{value:o.sSearch,regex:o.bRegex}}),g("mDataProp_"+e,n),l.bFilter&&(g("sSearch_"+e,o.sSearch),g("bRegex_"+e,o.bRegex),g("bSearchable_"+e,r.bSearchable)),l.bSort&&g("bSortable_"+e,r.bSortable);l.bFilter&&(g("sSearch",u.sSearch),g("bRegex",u.bRegex)),l.bSort&&(a.each(d,function(t,e){b.order.push({column:e.col,dir:e.dir}),g("iSortCol_"+t,e.col),g("sSortDir_"+t,e.dir)}),g("iSortingCols",d.length));var v=qt.ext.legacy.ajax;return null===v?t.sAjaxSource?f:b:v?f:b}function q(t,e){var a=function(t,a){return e[t]!==n?e[t]:e[a]},r=G(t,e),o=a("sEcho","draw"),i=a("iTotalRecords","recordsTotal"),s=a("iTotalDisplayRecords","recordsFiltered");if(o){if(1*o<t.iDraw)return;t.iDraw=1*o}L(t),t._iRecordsTotal=parseInt(i,10),t._iRecordsDisplay=parseInt(s,10);for(var l=0,u=r.length;u>l;l++)D(t,r[l]);t.aiDisplay=t.aiDisplayMaster.slice(),t.bAjaxDataGet=!1,M(t),t._bInitComplete||lt(t,e),t.bAjaxDataGet=!0,pt(t,!1)}function G(t,e){var r=a.isPlainObject(t.ajax)&&t.ajax.dataSrc!==n?t.ajax.dataSrc:t.sAjaxDataProp;return"data"===r?e.aaData||e[r]:""!==r?I(r)(e):e}function $(t){var n=t.oClasses,r=t.sTableId,o=t.oLanguage,i=t.oPreviousSearch,s=t.aanFeatures,l='<input type="search" class="'+n.sFilterInput+'"/>',u=o.sSearch;u=u.match(/_INPUT_/)?u.replace("_INPUT_",l):u+l;var c=a("<div/>",{id:s.f?null:r+"_filter","class":n.sFilter}).append(a("<label/>").append(u)),f=function(){var e=(s.f,this.value?this.value:"");e!=i.sSearch&&(z(t,{sSearch:e,bRegex:i.bRegex,bSmart:i.bSmart,bCaseInsensitive:i.bCaseInsensitive}),t._iDisplayStart=0,M(t))},d=null!==t.searchDelay?t.searchDelay:"ssp"===Bt(t)?400:0,h=a("input",c).val(i.sSearch).attr("placeholder",o.sSearchPlaceholder).bind("keyup.DT search.DT input.DT paste.DT cut.DT",d?mt(f,d):f).bind("keypress.DT",function(t){return 13==t.keyCode?!1:void 0}).attr("aria-controls",r);return a(t.nTable).on("search.dt.DT",function(n,a){if(t===a)try{h[0]!==e.activeElement&&h.val(i.sSearch)}catch(r){}}),c[0]}function z(t,e,a){var r=t.oPreviousSearch,o=t.aoPreSearchCols,i=function(t){r.sSearch=t.sSearch,r.bRegex=t.bRegex,r.bSmart=t.bSmart,r.bCaseInsensitive=t.bCaseInsensitive},s=function(t){return t.bEscapeRegex!==n?!t.bEscapeRegex:t.bRegex};if(S(t),"ssp"!=Bt(t)){Z(t,e.sSearch,a,s(e),e.bSmart,e.bCaseInsensitive),i(e);for(var l=0;l<o.length;l++)Q(t,o[l].sSearch,l,s(o[l]),o[l].bSmart,o[l].bCaseInsensitive);Y(t)}else i(e);t.bFiltered=!0,Wt(t,null,"search",[t])}function Y(t){for(var e,n,r=qt.ext.search,o=t.aiDisplay,i=0,s=r.length;s>i;i++){for(var l=[],u=0,c=o.length;c>u;u++)n=o[u],e=t.aoData[n],r[i](t,e._aFilterData,n,e._aData,u)&&l.push(n);o.length=0,a.merge(o,l)}}function Q(t,e,n,a,r,o){if(""!==e)for(var i,s=t.aiDisplay,l=K(e,a,r,o),u=s.length-1;u>=0;u--)i=t.aoData[s[u]]._aFilterData[n],l.test(i)||s.splice(u,1)}function Z(t,e,n,a,r,o){var i,s,l,u=K(e,a,r,o),c=t.oPreviousSearch.sSearch,f=t.aiDisplayMaster;if(0!==qt.ext.search.length&&(n=!0),s=et(t),e.length<=0)t.aiDisplay=f.slice();else for((s||n||c.length>e.length||0!==e.indexOf(c)||t.bSorted)&&(t.aiDisplay=f.slice()),i=t.aiDisplay,l=i.length-1;l>=0;l--)u.test(t.aoData[i[l]]._sFilterRow)||i.splice(l,1)}function K(t,e,n,r){if(t=e?t:tt(t),n){var o=a.map(t.match(/"[^"]+"|[^ ]+/g)||[""],function(t){if('"'===t.charAt(0)){var e=t.match(/^"(.*)"$/);t=e?e[1]:t}return t.replace('"',"")});t="^(?=.*?"+o.join(")(?=.*?")+").*$"}return new RegExp(t,r?"i":"")}function tt(t){return t.replace(ne,"\\$1")}function et(t){var e,n,a,r,o,i,s,l,u=t.aoColumns,c=qt.ext.type.search,f=!1;for(n=0,r=t.aoData.length;r>n;n++)if(l=t.aoData[n],!l._aFilterData){for(i=[],a=0,o=u.length;o>a;a++)e=u[a],e.bSearchable?(s=w(t,n,a,"filter"),c[e.sType]&&(s=c[e.sType](s)),null===s&&(s=""),"string"!=typeof s&&s.toString&&(s=s.toString())):s="",s.indexOf&&-1!==s.indexOf("&")&&(me.innerHTML=s,s=De?me.textContent:me.innerText),s.replace&&(s=s.replace(/[\r\n]/g,"")),i.push(s);l._aFilterData=i,l._sFilterRow=i.join(" "),f=!0}return f}function nt(t){return{search:t.sSearch,smart:t.bSmart,regex:t.bRegex,caseInsensitive:t.bCaseInsensitive}}function at(t){return{sSearch:t.search,bSmart:t.smart,bRegex:t.regex,bCaseInsensitive:t.caseInsensitive}}function rt(t){var e=t.sTableId,n=t.aanFeatures.i,r=a("<div/>",{"class":t.oClasses.sInfo,id:n?null:e+"_info"});return n||(t.aoDrawCallback.push({fn:ot,sName:"information"}),r.attr("role","status").attr("aria-live","polite"),a(t.nTable).attr("aria-describedby",e+"_info")),r[0]}function ot(t){var e=t.aanFeatures.i;if(0!==e.length){var n=t.oLanguage,r=t._iDisplayStart+1,o=t.fnDisplayEnd(),i=t.fnRecordsTotal(),s=t.fnRecordsDisplay(),l=s?n.sInfo:n.sInfoEmpty;s!==i&&(l+=" "+n.sInfoFiltered),l+=n.sInfoPostFix,l=it(t,l);var u=n.fnInfoCallback;null!==u&&(l=u.call(t.oInstance,t,r,o,i,s,l)),a(e).html(l)}}function it(t,e){var n=t.fnFormatNumber,a=t._iDisplayStart+1,r=t._iDisplayLength,o=t.fnRecordsDisplay(),i=-1===r;return e.replace(/_START_/g,n.call(t,a)).replace(/_END_/g,n.call(t,t.fnDisplayEnd())).replace(/_MAX_/g,n.call(t,t.fnRecordsTotal())).replace(/_TOTAL_/g,n.call(t,o)).replace(/_PAGE_/g,n.call(t,i?1:Math.ceil(a/r))).replace(/_PAGES_/g,n.call(t,i?1:Math.ceil(o/r)))}function st(t){var e,n,a,r=t.iInitDisplayStart,o=t.aoColumns,i=t.oFeatures,s=t.bDeferLoading;if(!t.bInitialised)return void setTimeout(function(){st(t)},200);for(U(t),k(t),O(t,t.aoHeader),O(t,t.aoFooter),pt(t,!0),i.bAutoWidth&&St(t),e=0,n=o.length;n>e;e++)a=o[e],a.sWidth&&(a.nTh.style.width=Tt(a.sWidth));Wt(t,null,"preInit",[t]),W(t);var l=Bt(t);("ssp"!=l||s)&&("ajax"==l?J(t,[],function(n){var a=G(t,n);for(e=0;e<a.length;e++)D(t,a[e]);t.iInitDisplayStart=r,W(t),pt(t,!1),lt(t,n)},t):(pt(t,!1),lt(t)))}function lt(t,e){t._bInitComplete=!0,(e||t.oInit.aaData)&&h(t),Wt(t,"aoInitComplete","init",[t,e])}function ut(t,e){var n=parseInt(e,10);t._iDisplayLength=n,Ut(t),Wt(t,null,"length",[t,n])}function ct(t){for(var e=t.oClasses,n=t.sTableId,r=t.aLengthMenu,o=a.isArray(r[0]),i=o?r[0]:r,s=o?r[1]:r,l=a("<select/>",{name:n+"_length","aria-controls":n,"class":e.sLengthSelect}),u=0,c=i.length;c>u;u++)l[0][u]=new Option(s[u],i[u]);var f=a("<div><label/></div>").addClass(e.sLength);return t.aanFeatures.l||(f[0].id=n+"_length"),f.children().append(t.oLanguage.sLengthMenu.replace("_MENU_",l[0].outerHTML)),a("select",f).val(t._iDisplayLength).bind("change.DT",function(e){ut(t,a(this).val()),M(t)}),a(t.nTable).bind("length.dt.DT",function(e,n,r){t===n&&a("select",f).val(r)}),f[0]}function ft(t){var e=t.sPaginationType,n=qt.ext.pager[e],r="function"==typeof n,o=function(t){M(t)},i=a("<div/>").addClass(t.oClasses.sPaging+e)[0],s=t.aanFeatures;return r||n.fnInit(t,i,o),s.p||(i.id=t.sTableId+"_paginate",t.aoDrawCallback.push({fn:function(t){if(r){var e,a,i=t._iDisplayStart,l=t._iDisplayLength,u=t.fnRecordsDisplay(),c=-1===l,f=c?0:Math.ceil(i/l),d=c?1:Math.ceil(u/l),h=n(f,d);for(e=0,a=s.p.length;a>e;e++)Et(t,"pageButton")(t,s.p[e],e,h,f,d)}else n.fnUpdate(t,o)},sName:"pagination"})),i}function dt(t,e,n){var a=t._iDisplayStart,r=t._iDisplayLength,o=t.fnRecordsDisplay();0===o||-1===r?a=0:"number"==typeof e?(a=e*r,a>o&&(a=0)):"first"==e?a=0:"previous"==e?(a=r>=0?a-r:0,0>a&&(a=0)):"next"==e?o>a+r&&(a+=r):"last"==e?a=Math.floor((o-1)/r)*r:Ht(t,0,"Unknown paging action: "+e,5);var i=t._iDisplayStart!==a;return t._iDisplayStart=a,i&&(Wt(t,null,"page",[t]),n&&M(t)),i}function ht(t){return a("<div/>",{id:t.aanFeatures.r?null:t.sTableId+"_processing","class":t.oClasses.sProcessing}).html(t.oLanguage.sProcessing).insertBefore(t.nTable)[0]}function pt(t,e){t.oFeatures.bProcessing&&a(t.aanFeatures.r).css("display",e?"block":"none"),Wt(t,null,"processing",[t,e])}function gt(t){var e=a(t.nTable);e.attr("role","grid");var n=t.oScroll;if(""===n.sX&&""===n.sY)return t.nTable;var r=n.sX,o=n.sY,i=t.oClasses,s=e.children("caption"),l=s.length?s[0]._captionSide:null,u=a(e[0].cloneNode(!1)),c=a(e[0].cloneNode(!1)),f=e.children("tfoot"),d="<div/>",h=function(t){return t?Tt(t):null};n.sX&&"100%"===e.attr("width")&&e.removeAttr("width"),f.length||(f=null);var p=a(d,{"class":i.sScrollWrapper}).append(a(d,{"class":i.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:r?h(r):"100%"}).append(a(d,{"class":i.sScrollHeadInner}).css({"box-sizing":"content-box",width:n.sXInner||"100%"}).append(u.removeAttr("id").css("margin-left",0).append("top"===l?s:null).append(e.children("thead"))))).append(a(d,{"class":i.sScrollBody}).css({position:"relative",overflow:"auto",width:h(r)}).append(e));f&&p.append(a(d,{"class":i.sScrollFoot}).css({overflow:"hidden",border:0,width:r?h(r):"100%"}).append(a(d,{"class":i.sScrollFootInner}).append(c.removeAttr("id").css("margin-left",0).append("bottom"===l?s:null).append(e.children("tfoot")))));var g=p.children(),b=g[0],v=g[1],S=f?g[2]:null;return r&&a(v).on("scroll.DT",function(t){var e=this.scrollLeft;b.scrollLeft=e,f&&(S.scrollLeft=e)}),a(v).css(o&&n.bCollapse?"max-height":"height",o),t.nScrollHead=b,t.nScrollBody=v,t.nScrollFoot=S,t.aoDrawCallback.push({fn:bt,sName:"scrolling"}),p[0]}function bt(t){var e,n,r,o,i,s,l,u,c,f=t.oScroll,d=f.sX,h=f.sXInner,g=f.sY,b=f.iBarWidth,v=a(t.nScrollHead),S=v[0].style,m=v.children("div"),D=m[0].style,y=m.children("table"),_=t.nScrollBody,T=a(_),w=_.style,C=a(t.nScrollFoot),x=C.children("div"),I=x.children("table"),A=a(t.nTHead),F=a(t.nTable),L=F[0],P=L.style,R=t.nTFoot?a(t.nTFoot):null,j=t.oBrowser,H=j.bScrollOversize,N=[],k=[],O=[],M=function(t){var e=t.style;e.paddingTop="0",e.paddingBottom="0",e.borderTopWidth="0",e.borderBottomWidth="0",e.height=0};F.children("thead, tfoot").remove(),i=A.clone().prependTo(F),e=A.find("tr"),r=i.find("tr"),i.find("th, td").removeAttr("tabindex"),R&&(s=R.clone().prependTo(F),n=R.find("tr"),o=s.find("tr")),d||(w.width="100%",v[0].style.width="100%"),a.each(B(t,i),function(e,n){l=p(t,e),n.style.width=t.aoColumns[l].sWidth}),R&&vt(function(t){t.style.width=""},o),c=F.outerWidth(),""===d?(P.width="100%",H&&(F.find("tbody").height()>_.offsetHeight||"scroll"==T.css("overflow-y"))&&(P.width=Tt(F.outerWidth()-b)),c=F.outerWidth()):""!==h&&(P.width=Tt(h),c=F.outerWidth()),vt(M,r),vt(function(t){O.push(t.innerHTML),N.push(Tt(a(t).css("width")))},r),vt(function(t,e){t.style.width=N[e]},e),a(r).height(0),R&&(vt(M,o),vt(function(t){k.push(Tt(a(t).css("width")))},o),vt(function(t,e){t.style.width=k[e]},n),a(o).height(0)),vt(function(t,e){t.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+O[e]+"</div>",t.style.width=N[e]},r),R&&vt(function(t,e){t.innerHTML="",t.style.width=k[e]},o),F.outerWidth()<c?(u=_.scrollHeight>_.offsetHeight||"scroll"==T.css("overflow-y")?c+b:c,H&&(_.scrollHeight>_.offsetHeight||"scroll"==T.css("overflow-y"))&&(P.width=Tt(u-b)),(""===d||""!==h)&&Ht(t,1,"Possible column misalignment",6)):u="100%",w.width=Tt(u),S.width=Tt(u),R&&(t.nScrollFoot.style.width=Tt(u)),g||H&&(w.height=Tt(L.offsetHeight+b));var W=F.outerWidth();y[0].style.width=Tt(W),D.width=Tt(W);var U=F.height()>_.clientHeight||"scroll"==T.css("overflow-y"),E="padding"+(j.bScrollbarLeft?"Left":"Right");D[E]=U?b+"px":"0px",R&&(I[0].style.width=Tt(W),x[0].style.width=Tt(W),x[0].style[E]=U?b+"px":"0px"),T.scroll(),!t.bSorted&&!t.bFiltered||t._drawHold||(_.scrollTop=0)}function vt(t,e,n){for(var a,r,o=0,i=0,s=e.length;s>i;){for(a=e[i].firstChild,r=n?n[i].firstChild:null;a;)1===a.nodeType&&(n?t(a,r,o):t(a,o),o++),a=a.nextSibling,r=n?r.nextSibling:null;i++}}function St(e){var n,r,o,i,s,l=e.nTable,u=e.aoColumns,c=e.oScroll,f=c.sY,d=c.sX,g=c.sXInner,S=u.length,m=v(e,"bVisible"),D=a("th",e.nTHead),y=l.getAttribute("width"),_=l.parentNode,T=!1,w=e.oBrowser,C=w.bScrollOversize,x=l.style.width;for(x&&-1!==x.indexOf("%")&&(y=x),n=0;n<m.length;n++)r=u[m[n]],null!==r.sWidth&&(r.sWidth=Dt(r.sWidthOrig,_),T=!0);if(C||!T&&!d&&!f&&S==b(e)&&S==D.length)for(n=0;S>n;n++){var I=p(e,n);I&&(u[I].sWidth=Tt(D.eq(n).width()))}else{var A=a(l).clone().css("visibility","hidden").removeAttr("id");A.find("tbody tr").remove();var F=a("<tr/>").appendTo(A.find("tbody"));for(A.find("thead, tfoot").remove(),A.append(a(e.nTHead).clone()).append(a(e.nTFoot).clone()),A.find("tfoot th, tfoot td").css("width",""),D=B(e,A.find("thead")[0]),n=0;n<m.length;n++)r=u[m[n]],D[n].style.width=null!==r.sWidthOrig&&""!==r.sWidthOrig?Tt(r.sWidthOrig):"";if(e.aoData.length)for(n=0;n<m.length;n++)o=m[n],r=u[o],a(yt(e,o)).clone(!1).append(r.sContentPadding).appendTo(F);var L=a("<div/>").css(d||f?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(A).appendTo(_);if(d&&g?A.width(g):d?(A.css("width","auto"),A.width()<_.clientWidth&&A.width(_.clientWidth)):f?A.width(_.clientWidth):y&&A.width(y),d){var P=0;for(n=0;n<m.length;n++)r=u[m[n]],s=w.bBounding?D[n].getBoundingClientRect().width:a(D[n]).outerWidth(),P+=null===r.sWidthOrig?s:parseInt(r.sWidth,10)+s-a(D[n]).width();A.width(Tt(P)),l.style.width=Tt(P)}for(n=0;n<m.length;n++)r=u[m[n]],i=a(D[n]).width(),i&&(r.sWidth=Tt(i));l.style.width=Tt(A.css("width")),L.remove()}if(y&&(l.style.width=Tt(y)),(y||d)&&!e._reszEvt){var R=function(){a(t).bind("resize.DT-"+e.sInstance,mt(function(){h(e)}))};C?setTimeout(R,1e3):R(),e._reszEvt=!0}}function mt(t,e){var a,r,o=e!==n?e:200;return function(){var e=this,i=+new Date,s=arguments;a&&a+o>i?(clearTimeout(r),r=setTimeout(function(){a=n,t.apply(e,s)},o)):(a=i,t.apply(e,s))}}function Dt(t,n){if(!t)return 0;var r=a("<div/>").css("width",Tt(t)).appendTo(n||e.body),o=r[0].offsetWidth;return r.remove(),o}function yt(t,e){var n=_t(t,e);if(0>n)return null;var r=t.aoData[n];return r.nTr?r.anCells[e]:a("<td/>").html(w(t,n,e,"display"))[0]}function _t(t,e){for(var n,a=-1,r=-1,o=0,i=t.aoData.length;i>o;o++)n=w(t,o,e,"display")+"",n=n.replace(ye,""),n.length>a&&(a=n.length,r=o);return r}function Tt(t){return null===t?"0px":"number"==typeof t?0>t?"0px":t+"px":t.match(/\d$/)?t+"px":t}function wt(t){var e,r,o,i,s,l,u,c=[],f=t.aoColumns,d=t.aaSortingFixed,h=a.isPlainObject(d),p=[],g=function(t){t.length&&!a.isArray(t[0])?p.push(t):a.merge(p,t)};for(a.isArray(d)&&g(d),h&&d.pre&&g(d.pre),g(t.aaSorting),h&&d.post&&g(d.post),e=0;e<p.length;e++)for(u=p[e][0],i=f[u].aDataSort,r=0,o=i.length;o>r;r++)s=i[r],l=f[s].sType||"string",p[e]._idx===n&&(p[e]._idx=a.inArray(p[e][1],f[s].asSorting)),c.push({src:u,col:s,dir:p[e][1],index:p[e]._idx,type:l,formatter:qt.ext.type.order[l+"-pre"]});return c}function Ct(t){var e,n,a,r,o,i=[],s=qt.ext.type.order,l=t.aoData,u=(t.aoColumns,0),c=t.aiDisplayMaster;for(S(t),o=wt(t),e=0,n=o.length;n>e;e++)r=o[e],r.formatter&&u++,Lt(t,r.col);if("ssp"!=Bt(t)&&0!==o.length){for(e=0,a=c.length;a>e;e++)i[c[e]]=e;u===o.length?c.sort(function(t,e){var n,a,r,s,u,c=o.length,f=l[t]._aSortData,d=l[e]._aSortData;for(r=0;c>r;r++)if(u=o[r],n=f[u.col],a=d[u.col],s=a>n?-1:n>a?1:0,0!==s)return"asc"===u.dir?s:-s;return n=i[t],a=i[e],a>n?-1:n>a?1:0}):c.sort(function(t,e){var n,a,r,u,c,f,d=o.length,h=l[t]._aSortData,p=l[e]._aSortData;for(r=0;d>r;r++)if(c=o[r],n=h[c.col],a=p[c.col],f=s[c.type+"-"+c.dir]||s["string-"+c.dir],u=f(n,a),0!==u)return u;return n=i[t],a=i[e],a>n?-1:n>a?1:0})}t.bSorted=!0}function xt(t){for(var e,n,a=t.aoColumns,r=wt(t),o=t.oLanguage.oAria,i=0,s=a.length;s>i;i++){var l=a[i],u=l.asSorting,c=l.sTitle.replace(/<.*?>/g,""),f=l.nTh;
2
+ f.removeAttribute("aria-sort"),l.bSortable?(r.length>0&&r[0].col==i?(f.setAttribute("aria-sort","asc"==r[0].dir?"ascending":"descending"),n=u[r[0].index+1]||u[0]):n=u[0],e=c+("asc"===n?o.sSortAscending:o.sSortDescending)):e=c,f.setAttribute("aria-label",e)}}function It(t,e,r,o){var i,s=t.aoColumns[e],l=t.aaSorting,u=s.asSorting,c=function(t,e){var r=t._idx;return r===n&&(r=a.inArray(t[1],u)),r+1<u.length?r+1:e?null:0};if("number"==typeof l[0]&&(l=t.aaSorting=[l]),r&&t.oFeatures.bSortMulti){var f=a.inArray(e,ce(l,"0"));-1!==f?(i=c(l[f],!0),null===i&&1===l.length&&(i=0),null===i?l.splice(f,1):(l[f][1]=u[i],l[f]._idx=i)):(l.push([e,u[0],0]),l[l.length-1]._idx=0)}else l.length&&l[0][0]==e?(i=c(l[0]),l.length=1,l[0][1]=u[i],l[0]._idx=i):(l.length=0,l.push([e,u[0]]),l[0]._idx=0);W(t),"function"==typeof o&&o(t)}function At(t,e,n,a){var r=t.aoColumns[n];Ot(e,{},function(e){r.bSortable!==!1&&(t.oFeatures.bProcessing?(pt(t,!0),setTimeout(function(){It(t,n,e.shiftKey,a),"ssp"!==Bt(t)&&pt(t,!1)},0)):It(t,n,e.shiftKey,a))})}function Ft(t){var e,n,r,o=t.aLastSort,i=t.oClasses.sSortColumn,s=wt(t),l=t.oFeatures;if(l.bSort&&l.bSortClasses){for(e=0,n=o.length;n>e;e++)r=o[e].src,a(ce(t.aoData,"anCells",r)).removeClass(i+(2>e?e+1:3));for(e=0,n=s.length;n>e;e++)r=s[e].src,a(ce(t.aoData,"anCells",r)).addClass(i+(2>e?e+1:3))}t.aLastSort=s}function Lt(t,e){var n,a=t.aoColumns[e],r=qt.ext.order[a.sSortDataType];r&&(n=r.call(t.oInstance,t,e,g(t,e)));for(var o,i,s=qt.ext.type.order[a.sType+"-pre"],l=0,u=t.aoData.length;u>l;l++)o=t.aoData[l],o._aSortData||(o._aSortData=[]),(!o._aSortData[e]||r)&&(i=r?n[l]:w(t,l,e,"sort"),o._aSortData[e]=s?s(i):i)}function Pt(t){if(t.oFeatures.bStateSave&&!t.bDestroying){var e={time:+new Date,start:t._iDisplayStart,length:t._iDisplayLength,order:a.extend(!0,[],t.aaSorting),search:nt(t.oPreviousSearch),columns:a.map(t.aoColumns,function(e,n){return{visible:e.bVisible,search:nt(t.aoPreSearchCols[n])}})};Wt(t,"aoStateSaveParams","stateSaveParams",[t,e]),t.oSavedState=e,t.fnStateSaveCallback.call(t.oInstance,t,e)}}function Rt(t,e){var r,o,i=t.aoColumns;if(t.oFeatures.bStateSave){var s=t.fnStateLoadCallback.call(t.oInstance,t);if(s&&s.time){var l=Wt(t,"aoStateLoadParams","stateLoadParams",[t,s]);if(-1===a.inArray(!1,l)){var u=t.iStateDuration;if(!(u>0&&s.time<+new Date-1e3*u)&&i.length===s.columns.length){for(t.oLoadedState=a.extend(!0,{},s),s.start!==n&&(t._iDisplayStart=s.start,t.iInitDisplayStart=s.start),s.length!==n&&(t._iDisplayLength=s.length),s.order!==n&&(t.aaSorting=[],a.each(s.order,function(e,n){t.aaSorting.push(n[0]>=i.length?[0,n[1]]:n)})),s.search!==n&&a.extend(t.oPreviousSearch,at(s.search)),r=0,o=s.columns.length;o>r;r++){var c=s.columns[r];c.visible!==n&&(i[r].bVisible=c.visible),c.search!==n&&a.extend(t.aoPreSearchCols[r],at(c.search))}Wt(t,"aoStateLoaded","stateLoaded",[t,s])}}}}}function jt(t){var e=qt.settings,n=a.inArray(t,ce(e,"nTable"));return-1!==n?e[n]:null}function Ht(e,n,a,r){if(a="DataTables warning: "+(e?"table id="+e.sTableId+" - ":"")+a,r&&(a+=". For more information about this error, please see http://datatables.net/tn/"+r),n)t.console&&console.log&&console.log(a);else{var o=qt.ext,i=o.sErrMode||o.errMode;if(e&&Wt(e,null,"error",[e,r,a]),"alert"==i)alert(a);else{if("throw"==i)throw new Error(a);"function"==typeof i&&i(e,r,a)}}}function Nt(t,e,r,o){return a.isArray(r)?void a.each(r,function(n,r){a.isArray(r)?Nt(t,e,r[0],r[1]):Nt(t,e,r)}):(o===n&&(o=r),void(e[r]!==n&&(t[o]=e[r])))}function kt(t,e,n){var r;for(var o in e)e.hasOwnProperty(o)&&(r=e[o],a.isPlainObject(r)?(a.isPlainObject(t[o])||(t[o]={}),a.extend(!0,t[o],r)):n&&"data"!==o&&"aaData"!==o&&a.isArray(r)?t[o]=r.slice():t[o]=r);return t}function Ot(t,e,n){a(t).bind("click.DT",e,function(e){t.blur(),n(e)}).bind("keypress.DT",e,function(t){13===t.which&&(t.preventDefault(),n(t))}).bind("selectstart.DT",function(){return!1})}function Mt(t,e,n,a){n&&t[e].push({fn:n,sName:a})}function Wt(t,e,n,r){var o=[];if(e&&(o=a.map(t[e].slice().reverse(),function(e,n){return e.fn.apply(t.oInstance,r)})),null!==n){var i=a.Event(n+".dt");a(t.nTable).trigger(i,r),o.push(i.result)}return o}function Ut(t){var e=t._iDisplayStart,n=t.fnDisplayEnd(),a=t._iDisplayLength;e>=n&&(e=n-a),e-=e%a,(-1===a||0>e)&&(e=0),t._iDisplayStart=e}function Et(t,e){var n=t.renderer,r=qt.ext.renderer[e];return a.isPlainObject(n)&&n[e]?r[n[e]]||r._:"string"==typeof n?r[n]||r._:r._}function Bt(t){return t.oFeatures.bServerSide?"ssp":t.ajax||t.sAjaxSource?"ajax":"dom"}function Jt(t,e){var n=[],a=Xe.numbers_length,r=Math.floor(a/2);return a>=e?n=de(0,e):r>=t?(n=de(0,a-2),n.push("ellipsis"),n.push(e-1)):t>=e-1-r?(n=de(e-(a-2),e),n.splice(0,0,"ellipsis"),n.splice(0,0,0)):(n=de(t-r+2,t+r-1),n.push("ellipsis"),n.push(e-1),n.splice(0,0,"ellipsis"),n.splice(0,0,0)),n.DT_el="span",n}function Xt(t){a.each({num:function(e){return Ve(e,t)},"num-fmt":function(e){return Ve(e,t,ae)},"html-num":function(e){return Ve(e,t,Kt)},"html-num-fmt":function(e){return Ve(e,t,Kt,ae)}},function(e,n){Gt.type.order[e+t+"-pre"]=n,e.match(/^html\-/)&&(Gt.type.search[e+t]=Gt.type.search.html)})}function Vt(t){return function(){var e=[jt(this[qt.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return qt.ext.internal[t].apply(this,e)}}var qt,Gt,$t,zt,Yt,Qt={},Zt=/[\r\n]/g,Kt=/<.*?>/g,te=/^[\w\+\-]/,ee=/[\w\+\-]$/,ne=new RegExp("(\\"+["/",".","*","+","?","|","(",")","[","]","{","}","\\","$","^","-"].join("|\\")+")","g"),ae=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi,re=function(t){return t&&t!==!0&&"-"!==t?!1:!0},oe=function(t){var e=parseInt(t,10);return!isNaN(e)&&isFinite(t)?e:null},ie=function(t,e){return Qt[e]||(Qt[e]=new RegExp(tt(e),"g")),"string"==typeof t&&"."!==e?t.replace(/\./g,"").replace(Qt[e],"."):t},se=function(t,e,n){var a="string"==typeof t;return re(t)?!0:(e&&a&&(t=ie(t,e)),n&&a&&(t=t.replace(ae,"")),!isNaN(parseFloat(t))&&isFinite(t))},le=function(t){return re(t)||"string"==typeof t},ue=function(t,e,n){if(re(t))return!0;var a=le(t);return a&&se(pe(t),e,n)?!0:null},ce=function(t,e,a){var r=[],o=0,i=t.length;if(a!==n)for(;i>o;o++)t[o]&&t[o][e]&&r.push(t[o][e][a]);else for(;i>o;o++)t[o]&&r.push(t[o][e]);return r},fe=function(t,e,a,r){var o=[],i=0,s=e.length;if(r!==n)for(;s>i;i++)t[e[i]][a]&&o.push(t[e[i]][a][r]);else for(;s>i;i++)o.push(t[e[i]][a]);return o},de=function(t,e){var a,r=[];e===n?(e=0,a=t):(a=e,e=t);for(var o=e;a>o;o++)r.push(o);return r},he=function(t){for(var e=[],n=0,a=t.length;a>n;n++)t[n]&&e.push(t[n]);return e},pe=function(t){return t.replace(Kt,"")},ge=function(t){var e,n,a,r=[],o=t.length,i=0;t:for(n=0;o>n;n++){for(e=t[n],a=0;i>a;a++)if(r[a]===e)continue t;r.push(e),i++}return r},be=function(t,e,a){t[e]!==n&&(t[a]=t[e])},ve=/\[.*?\]$/,Se=/\(\)$/,me=a("<div>")[0],De=me.textContent!==n,ye=/<.*?>/g;qt=function(t){this.$=function(t,e){return this.api(!0).$(t,e)},this._=function(t,e){return this.api(!0).rows(t,e).data()},this.api=function(t){return new $t(t?jt(this[Gt.iApiIndex]):this)},this.fnAddData=function(t,e){var r=this.api(!0),o=a.isArray(t)&&(a.isArray(t[0])||a.isPlainObject(t[0]))?r.rows.add(t):r.row.add(t);return(e===n||e)&&r.draw(),o.flatten().toArray()},this.fnAdjustColumnSizing=function(t){var e=this.api(!0).columns.adjust(),a=e.settings()[0],r=a.oScroll;t===n||t?e.draw(!1):(""!==r.sX||""!==r.sY)&&bt(a)},this.fnClearTable=function(t){var e=this.api(!0).clear();(t===n||t)&&e.draw()},this.fnClose=function(t){this.api(!0).row(t).child.hide()},this.fnDeleteRow=function(t,e,a){var r=this.api(!0),o=r.rows(t),i=o.settings()[0],s=i.aoData[o[0][0]];return o.remove(),e&&e.call(this,i,s),(a===n||a)&&r.draw(),s},this.fnDestroy=function(t){this.api(!0).destroy(t)},this.fnDraw=function(t){this.api(!0).draw(t)},this.fnFilter=function(t,e,a,r,o,i){var s=this.api(!0);null===e||e===n?s.search(t,a,r,i):s.column(e).search(t,a,r,i),s.draw()},this.fnGetData=function(t,e){var a=this.api(!0);if(t!==n){var r=t.nodeName?t.nodeName.toLowerCase():"";return e!==n||"td"==r||"th"==r?a.cell(t,e).data():a.row(t).data()||null}return a.data().toArray()},this.fnGetNodes=function(t){var e=this.api(!0);return t!==n?e.row(t).node():e.rows().nodes().flatten().toArray()},this.fnGetPosition=function(t){var e=this.api(!0),n=t.nodeName.toUpperCase();if("TR"==n)return e.row(t).index();if("TD"==n||"TH"==n){var a=e.cell(t).index();return[a.row,a.columnVisible,a.column]}return null},this.fnIsOpen=function(t){return this.api(!0).row(t).child.isShown()},this.fnOpen=function(t,e,n){return this.api(!0).row(t).child(e,n).show().child()[0]},this.fnPageChange=function(t,e){var a=this.api(!0).page(t);(e===n||e)&&a.draw(!1)},this.fnSetColumnVis=function(t,e,a){var r=this.api(!0).column(t).visible(e);(a===n||a)&&r.columns.adjust().draw()},this.fnSettings=function(){return jt(this[Gt.iApiIndex])},this.fnSort=function(t){this.api(!0).order(t).draw()},this.fnSortListener=function(t,e,n){this.api(!0).order.listener(t,e,n)},this.fnUpdate=function(t,e,a,r,o){var i=this.api(!0);return a===n||null===a?i.row(e).data(t):i.cell(e,a).data(t),(o===n||o)&&i.columns.adjust(),(r===n||r)&&i.draw(),0},this.fnVersionCheck=Gt.fnVersionCheck;var e=this,r=t===n,c=this.length;r&&(t={}),this.oApi=this.internal=Gt.internal;for(var h in qt.ext.internal)h&&(this[h]=Vt(h));return this.each(function(){var h,p={},g=c>1?kt(p,t,!0):t,b=0,v=this.getAttribute("id"),S=!1,_=qt.defaults,T=a(this);if("table"!=this.nodeName.toLowerCase())return void Ht(null,0,"Non-table node initialisation ("+this.nodeName+")",2);s(_),l(_.column),o(_,_,!0),o(_.column,_.column,!0),o(_,a.extend(g,T.data()));var w=qt.settings;for(b=0,h=w.length;h>b;b++){var C=w[b];if(C.nTable==this||C.nTHead.parentNode==this||C.nTFoot&&C.nTFoot.parentNode==this){var x=g.bRetrieve!==n?g.bRetrieve:_.bRetrieve,A=g.bDestroy!==n?g.bDestroy:_.bDestroy;if(r||x)return C.oInstance;if(A){C.oInstance.fnDestroy();break}return void Ht(C,0,"Cannot reinitialise DataTable",3)}if(C.sTableId==this.id){w.splice(b,1);break}}(null===v||""===v)&&(v="DataTables_Table_"+qt.ext._unique++,this.id=v);var F=a.extend(!0,{},qt.models.oSettings,{sDestroyWidth:T[0].style.width,sInstance:v,sTableId:v});F.nTable=this,F.oApi=e.internal,F.oInit=g,w.push(F),F.oInstance=1===e.length?e:T.dataTable(),s(g),g.oLanguage&&i(g.oLanguage),g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=a.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]),g=kt(a.extend(!0,{},_),g),Nt(F.oFeatures,g,["bPaginate","bLengthChange","bFilter","bSort","bSortMulti","bInfo","bProcessing","bAutoWidth","bSortClasses","bServerSide","bDeferRender"]),Nt(F,g,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"],["bJQueryUI","bJUI"]]),Nt(F.oScroll,g,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]),Nt(F.oLanguage,g,"fnInfoCallback"),Mt(F,"aoDrawCallback",g.fnDrawCallback,"user"),Mt(F,"aoServerParams",g.fnServerParams,"user"),Mt(F,"aoStateSaveParams",g.fnStateSaveParams,"user"),Mt(F,"aoStateLoadParams",g.fnStateLoadParams,"user"),Mt(F,"aoStateLoaded",g.fnStateLoaded,"user"),Mt(F,"aoRowCallback",g.fnRowCallback,"user"),Mt(F,"aoRowCreatedCallback",g.fnCreatedRow,"user"),Mt(F,"aoHeaderCallback",g.fnHeaderCallback,"user"),Mt(F,"aoFooterCallback",g.fnFooterCallback,"user"),Mt(F,"aoInitComplete",g.fnInitComplete,"user"),Mt(F,"aoPreDrawCallback",g.fnPreDrawCallback,"user"),F.rowIdFn=I(g.rowId),u(F);var L=F.oClasses;if(g.bJQueryUI?(a.extend(L,qt.ext.oJUIClasses,g.oClasses),g.sDom===_.sDom&&"lfrtip"===_.sDom&&(F.sDom='<"H"lfr>t<"F"ip>'),F.renderer?a.isPlainObject(F.renderer)&&!F.renderer.header&&(F.renderer.header="jqueryui"):F.renderer="jqueryui"):a.extend(L,qt.ext.classes,g.oClasses),T.addClass(L.sTable),F.iInitDisplayStart===n&&(F.iInitDisplayStart=g.iDisplayStart,F._iDisplayStart=g.iDisplayStart),null!==g.iDeferLoading){F.bDeferLoading=!0;var P=a.isArray(g.iDeferLoading);F._iRecordsDisplay=P?g.iDeferLoading[0]:g.iDeferLoading,F._iRecordsTotal=P?g.iDeferLoading[1]:g.iDeferLoading}var R=F.oLanguage;a.extend(!0,R,g.oLanguage),""!==R.sUrl&&(a.ajax({dataType:"json",url:R.sUrl,success:function(t){i(t),o(_.oLanguage,t),a.extend(!0,R,t),st(F)},error:function(){st(F)}}),S=!0),null===g.asStripeClasses&&(F.asStripeClasses=[L.sStripeOdd,L.sStripeEven]);var j=F.asStripeClasses,H=T.children("tbody").find("tr").eq(0);-1!==a.inArray(!0,a.map(j,function(t,e){return H.hasClass(t)}))&&(a("tbody tr",this).removeClass(j.join(" ")),F.asDestroyStripes=j.slice());var N,k=[],O=this.getElementsByTagName("thead");if(0!==O.length&&(E(F.aoHeader,O[0]),k=B(F)),null===g.aoColumns)for(N=[],b=0,h=k.length;h>b;b++)N.push(null);else N=g.aoColumns;for(b=0,h=N.length;h>b;b++)f(F,k?k[b]:null);if(m(F,g.aoColumnDefs,N,function(t,e){d(F,t,e)}),H.length){var M=function(t,e){return null!==t.getAttribute("data-"+e)?e:null};a(H[0]).children("th, td").each(function(t,e){var a=F.aoColumns[t];if(a.mData===t){var r=M(e,"sort")||M(e,"order"),o=M(e,"filter")||M(e,"search");(null!==r||null!==o)&&(a.mData={_:t+".display",sort:null!==r?t+".@data-"+r:n,type:null!==r?t+".@data-"+r:n,filter:null!==o?t+".@data-"+o:n},d(F,t))}})}var W=F.oFeatures;if(g.bStateSave&&(W.bStateSave=!0,Rt(F,g),Mt(F,"aoDrawCallback",Pt,"state_save")),g.aaSorting===n){var U=F.aaSorting;for(b=0,h=U.length;h>b;b++)U[b][1]=F.aoColumns[b].asSorting[0]}Ft(F),W.bSort&&Mt(F,"aoDrawCallback",function(){if(F.bSorted){var t=wt(F),e={};a.each(t,function(t,n){e[n.src]=n.dir}),Wt(F,null,"order",[F,t,e]),xt(F)}}),Mt(F,"aoDrawCallback",function(){(F.bSorted||"ssp"===Bt(F)||W.bDeferRender)&&Ft(F)},"sc");var J=T.children("caption").each(function(){this._captionSide=T.css("caption-side")}),X=T.children("thead");0===X.length&&(X=a("<thead/>").appendTo(this)),F.nTHead=X[0];var V=T.children("tbody");0===V.length&&(V=a("<tbody/>").appendTo(this)),F.nTBody=V[0];var q=T.children("tfoot");if(0===q.length&&J.length>0&&(""!==F.oScroll.sX||""!==F.oScroll.sY)&&(q=a("<tfoot/>").appendTo(this)),0===q.length||0===q.children().length?T.addClass(L.sNoFooter):q.length>0&&(F.nTFoot=q[0],E(F.aoFooter,F.nTFoot)),g.aaData)for(b=0;b<g.aaData.length;b++)D(F,g.aaData[b]);else(F.bDeferLoading||"dom"==Bt(F))&&y(F,a(F.nTBody).children("tr"));F.aiDisplay=F.aiDisplayMaster.slice(),F.bInitialised=!0,S===!1&&st(F)}),e=null,this};var _e=[],Te=Array.prototype,we=function(t){var e,n,r=qt.settings,o=a.map(r,function(t,e){return t.nTable});return t?t.nTable&&t.oApi?[t]:t.nodeName&&"table"===t.nodeName.toLowerCase()?(e=a.inArray(t,o),-1!==e?[r[e]]:null):t&&"function"==typeof t.settings?t.settings().toArray():("string"==typeof t?n=a(t):t instanceof a&&(n=t),n?n.map(function(t){return e=a.inArray(this,o),-1!==e?r[e]:null}).toArray():void 0):[]};$t=function(t,e){if(!(this instanceof $t))return new $t(t,e);var n=[],r=function(t){var e=we(t);e&&(n=n.concat(e))};if(a.isArray(t))for(var o=0,i=t.length;i>o;o++)r(t[o]);else r(t);this.context=ge(n),e&&a.merge(this,e),this.selector={rows:null,cols:null,opts:null},$t.extend(this,this,_e)},qt.Api=$t,a.extend($t.prototype,{any:function(){return 0!==this.count()},concat:Te.concat,context:[],count:function(){return this.flatten().length},each:function(t){for(var e=0,n=this.length;n>e;e++)t.call(this,this[e],e,this);return this},eq:function(t){var e=this.context;return e.length>t?new $t(e[t],this[t]):null},filter:function(t){var e=[];if(Te.filter)e=Te.filter.call(this,t,this);else for(var n=0,a=this.length;a>n;n++)t.call(this,this[n],n,this)&&e.push(this[n]);return new $t(this.context,e)},flatten:function(){var t=[];return new $t(this.context,t.concat.apply(t,this.toArray()))},join:Te.join,indexOf:Te.indexOf||function(t,e){for(var n=e||0,a=this.length;a>n;n++)if(this[n]===t)return n;return-1},iterator:function(t,e,a,r){var o,i,s,l,u,c,f,d,h=[],p=this.context,g=this.selector;for("string"==typeof t&&(r=a,a=e,e=t,t=!1),i=0,s=p.length;s>i;i++){var b=new $t(p[i]);if("table"===e)o=a.call(b,p[i],i),o!==n&&h.push(o);else if("columns"===e||"rows"===e)o=a.call(b,p[i],this[i],i),o!==n&&h.push(o);else if("column"===e||"column-rows"===e||"row"===e||"cell"===e)for(f=this[i],"column-rows"===e&&(c=Le(p[i],g.opts)),l=0,u=f.length;u>l;l++)d=f[l],o="cell"===e?a.call(b,p[i],d.row,d.column,i,l):a.call(b,p[i],d,i,l,c),o!==n&&h.push(o)}if(h.length||r){var v=new $t(p,t?h.concat.apply([],h):h),S=v.selector;return S.rows=g.rows,S.cols=g.cols,S.opts=g.opts,v}return this},lastIndexOf:Te.lastIndexOf||function(t,e){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(t){var e=[];if(Te.map)e=Te.map.call(this,t,this);else for(var n=0,a=this.length;a>n;n++)e.push(t.call(this,this[n],n));return new $t(this.context,e)},pluck:function(t){return this.map(function(e){return e[t]})},pop:Te.pop,push:Te.push,reduce:Te.reduce||function(t,e){return c(this,t,e,0,this.length,1)},reduceRight:Te.reduceRight||function(t,e){return c(this,t,e,this.length-1,-1,-1)},reverse:Te.reverse,selector:null,shift:Te.shift,sort:Te.sort,splice:Te.splice,toArray:function(){return Te.slice.call(this)},to$:function(){return a(this)},toJQuery:function(){return a(this)},unique:function(){return new $t(this.context,ge(this))},unshift:Te.unshift}),$t.extend=function(t,e,n){if(n.length&&e&&(e instanceof $t||e.__dt_wrapper)){var r,o,i,s=function(t,e,n){return function(){var a=e.apply(t,arguments);return $t.extend(a,a,n.methodExt),a}};for(r=0,o=n.length;o>r;r++)i=n[r],e[i.name]="function"==typeof i.val?s(t,i.val,i):a.isPlainObject(i.val)?{}:i.val,e[i.name].__dt_wrapper=!0,$t.extend(t,e[i.name],i.propExt)}},$t.register=zt=function(t,e){if(a.isArray(t))for(var n=0,r=t.length;r>n;n++)$t.register(t[n],e);else{var o,i,s,l,u=t.split("."),c=_e,f=function(t,e){for(var n=0,a=t.length;a>n;n++)if(t[n].name===e)return t[n];return null};for(o=0,i=u.length;i>o;o++){l=-1!==u[o].indexOf("()"),s=l?u[o].replace("()",""):u[o];var d=f(c,s);d||(d={name:s,val:{},methodExt:[],propExt:[]},c.push(d)),o===i-1?d.val=e:c=l?d.methodExt:d.propExt}}},$t.registerPlural=Yt=function(t,e,r){$t.register(t,r),$t.register(e,function(){var t=r.apply(this,arguments);return t===this?this:t instanceof $t?t.length?a.isArray(t[0])?new $t(t.context,t[0]):t[0]:n:t})};var Ce=function(t,e){if("number"==typeof t)return[e[t]];var n=a.map(e,function(t,e){return t.nTable});return a(n).filter(t).map(function(t){var r=a.inArray(this,n);return e[r]}).toArray()};zt("tables()",function(t){return t?new $t(Ce(t,this.context)):this}),zt("table()",function(t){var e=this.tables(t),n=e.context;return n.length?new $t(n[0]):e}),Yt("tables().nodes()","table().node()",function(){return this.iterator("table",function(t){return t.nTable},1)}),Yt("tables().body()","table().body()",function(){return this.iterator("table",function(t){return t.nTBody},1)}),Yt("tables().header()","table().header()",function(){return this.iterator("table",function(t){return t.nTHead},1)}),Yt("tables().footer()","table().footer()",function(){return this.iterator("table",function(t){return t.nTFoot},1)}),Yt("tables().containers()","table().container()",function(){return this.iterator("table",function(t){return t.nTableWrapper},1)}),zt("draw()",function(t){return this.iterator("table",function(e){"page"===t?M(e):("string"==typeof t&&(t="full-hold"===t?!1:!0),W(e,t===!1))})}),zt("page()",function(t){return t===n?this.page.info().page:this.iterator("table",function(e){dt(e,t)})}),zt("page.info()",function(t){if(0===this.context.length)return n;var e=this.context[0],a=e._iDisplayStart,r=e._iDisplayLength,o=e.fnRecordsDisplay(),i=-1===r;return{page:i?0:Math.floor(a/r),pages:i?1:Math.ceil(o/r),start:a,end:e.fnDisplayEnd(),length:r,recordsTotal:e.fnRecordsTotal(),recordsDisplay:o,serverSide:"ssp"===Bt(e)}}),zt("page.len()",function(t){return t===n?0!==this.context.length?this.context[0]._iDisplayLength:n:this.iterator("table",function(e){ut(e,t)})});var xe=function(t,e,n){if(n){var a=new $t(t);a.one("draw",function(){n(a.ajax.json())})}if("ssp"==Bt(t))W(t,e);else{pt(t,!0);var r=t.jqXHR;r&&4!==r.readyState&&r.abort(),J(t,[],function(n){L(t);for(var a=G(t,n),r=0,o=a.length;o>r;r++)D(t,a[r]);W(t,e),pt(t,!1)})}};zt("ajax.json()",function(){var t=this.context;return t.length>0?t[0].json:void 0}),zt("ajax.params()",function(){var t=this.context;return t.length>0?t[0].oAjaxData:void 0}),zt("ajax.reload()",function(t,e){return this.iterator("table",function(n){xe(n,e===!1,t)})}),zt("ajax.url()",function(t){var e=this.context;return t===n?0===e.length?n:(e=e[0],e.ajax?a.isPlainObject(e.ajax)?e.ajax.url:e.ajax:e.sAjaxSource):this.iterator("table",function(e){a.isPlainObject(e.ajax)?e.ajax.url=t:e.ajax=t})}),zt("ajax.url().load()",function(t,e){return this.iterator("table",function(n){xe(n,e===!1,t)})});var Ie=function(t,e,r,o,i){var s,l,u,c,f,d,h=[],p=typeof e;for(e&&"string"!==p&&"function"!==p&&e.length!==n||(e=[e]),u=0,c=e.length;c>u;u++)for(l=e[u]&&e[u].split?e[u].split(","):[e[u]],f=0,d=l.length;d>f;f++)s=r("string"==typeof l[f]?a.trim(l[f]):l[f]),s&&s.length&&(h=h.concat(s));var g=Gt.selector[t];if(g.length)for(u=0,c=g.length;c>u;u++)h=g[u](o,i,h);return ge(h)},Ae=function(t){return t||(t={}),t.filter&&t.search===n&&(t.search=t.filter),a.extend({search:"none",order:"current",page:"all"},t)},Fe=function(t){for(var e=0,n=t.length;n>e;e++)if(t[e].length>0)return t[0]=t[e],t[0].length=1,t.length=1,t.context=[t.context[e]],t;return t.length=0,t},Le=function(t,e){var n,r,o,i=[],s=t.aiDisplay,l=t.aiDisplayMaster,u=e.search,c=e.order,f=e.page;if("ssp"==Bt(t))return"removed"===u?[]:de(0,l.length);if("current"==f)for(n=t._iDisplayStart,r=t.fnDisplayEnd();r>n;n++)i.push(s[n]);else if("current"==c||"applied"==c)i="none"==u?l.slice():"applied"==u?s.slice():a.map(l,function(t,e){return-1===a.inArray(t,s)?t:null});else if("index"==c||"original"==c)for(n=0,r=t.aoData.length;r>n;n++)"none"==u?i.push(n):(o=a.inArray(n,s),(-1===o&&"removed"==u||o>=0&&"applied"==u)&&i.push(n));return i},Pe=function(t,e,r){var o=function(e){var o=oe(e);if(null!==o&&!r)return[o];var i=Le(t,r);if(null!==o&&-1!==a.inArray(o,i))return[o];if(!e)return i;if("function"==typeof e)return a.map(i,function(n){var a=t.aoData[n];return e(n,a._aData,a.nTr)?n:null});var s=he(fe(t.aoData,i,"nTr"));if(e.nodeName&&-1!==a.inArray(e,s))return[e._DT_RowIndex];if("string"==typeof e&&"#"===e.charAt(0)){var l=t.aIds[e.replace(/^#/,"")];if(l!==n)return[l.idx]}return a(s).filter(e).map(function(){return this._DT_RowIndex}).toArray()};return Ie("row",e,o,t,r)};zt("rows()",function(t,e){t===n?t="":a.isPlainObject(t)&&(e=t,t=""),e=Ae(e);var r=this.iterator("table",function(n){return Pe(n,t,e)},1);return r.selector.rows=t,r.selector.opts=e,r}),zt("rows().nodes()",function(){return this.iterator("row",function(t,e){return t.aoData[e].nTr||n},1)}),zt("rows().data()",function(){return this.iterator(!0,"rows",function(t,e){return fe(t.aoData,e,"_aData")},1)}),Yt("rows().cache()","row().cache()",function(t){return this.iterator("row",function(e,n){var a=e.aoData[n];return"search"===t?a._aFilterData:a._aSortData},1)}),Yt("rows().invalidate()","row().invalidate()",function(t){return this.iterator("row",function(e,n){R(e,n,t)})}),Yt("rows().indexes()","row().index()",function(){return this.iterator("row",function(t,e){return e},1)}),Yt("rows().ids()","row().id()",function(t){for(var e=[],n=this.context,a=0,r=n.length;r>a;a++)for(var o=0,i=this[a].length;i>o;o++){var s=n[a].rowIdFn(n[a].aoData[this[a][o]]._aData);e.push((t===!0?"#":"")+s)}return new $t(n,e)}),Yt("rows().remove()","row().remove()",function(){var t=this;return this.iterator("row",function(e,a,r){var o=e.aoData,i=o[a];o.splice(a,1);for(var s=0,l=o.length;l>s;s++)null!==o[s].nTr&&(o[s].nTr._DT_RowIndex=s);P(e.aiDisplayMaster,a),P(e.aiDisplay,a),P(t[r],a,!1),Ut(e);var u=e.rowIdFn(i._aData);u!==n&&delete e.aIds[u]}),this.iterator("table",function(t){for(var e=0,n=t.aoData.length;n>e;e++)t.aoData[e].idx=e}),this}),zt("rows.add()",function(t){var e=this.iterator("table",function(e){var n,a,r,o=[];for(a=0,r=t.length;r>a;a++)n=t[a],n.nodeName&&"TR"===n.nodeName.toUpperCase()?o.push(y(e,n)[0]):o.push(D(e,n));return o},1),n=this.rows(-1);return n.pop(),a.merge(n,e),n}),zt("row()",function(t,e){return Fe(this.rows(t,e))}),zt("row().data()",function(t){var e=this.context;return t===n?e.length&&this.length?e[0].aoData[this[0]]._aData:n:(e[0].aoData[this[0]]._aData=t,R(e[0],this[0],"data"),this)}),zt("row().node()",function(){var t=this.context;return t.length&&this.length?t[0].aoData[this[0]].nTr||null:null}),zt("row.add()",function(t){t instanceof a&&t.length&&(t=t[0]);var e=this.iterator("table",function(e){return t.nodeName&&"TR"===t.nodeName.toUpperCase()?y(e,t)[0]:D(e,t)});return this.row(e[0])});var Re=function(t,e,n,r){var o=[],i=function(e,n){if(a.isArray(e)||e instanceof a)for(var r=0,s=e.length;s>r;r++)i(e[r],n);else if(e.nodeName&&"tr"===e.nodeName.toLowerCase())o.push(e);else{var l=a("<tr><td/></tr>").addClass(n);a("td",l).addClass(n).html(e)[0].colSpan=b(t),o.push(l[0])}};i(n,r),e._details&&e._details.remove(),e._details=a(o),e._detailsShow&&e._details.insertAfter(e.nTr)},je=function(t,e){var a=t.context;if(a.length){var r=a[0].aoData[e!==n?e:t[0]];r&&r._details&&(r._details.remove(),r._detailsShow=n,r._details=n)}},He=function(t,e){var n=t.context;if(n.length&&t.length){var a=n[0].aoData[t[0]];a._details&&(a._detailsShow=e,e?a._details.insertAfter(a.nTr):a._details.detach(),Ne(n[0]))}},Ne=function(t){var e=new $t(t),n=".dt.DT_details",a="draw"+n,r="column-visibility"+n,o="destroy"+n,i=t.aoData;e.off(a+" "+r+" "+o),ce(i,"_details").length>0&&(e.on(a,function(n,a){t===a&&e.rows({page:"current"}).eq(0).each(function(t){var e=i[t];e._detailsShow&&e._details.insertAfter(e.nTr)})}),e.on(r,function(e,n,a,r){if(t===n)for(var o,s=b(n),l=0,u=i.length;u>l;l++)o=i[l],o._details&&o._details.children("td[colspan]").attr("colspan",s)}),e.on(o,function(n,a){if(t===a)for(var r=0,o=i.length;o>r;r++)i[r]._details&&je(e,r)}))},ke="",Oe=ke+"row().child",Me=Oe+"()";zt(Me,function(t,e){var a=this.context;return t===n?a.length&&this.length?a[0].aoData[this[0]]._details:n:(t===!0?this.child.show():t===!1?je(this):a.length&&this.length&&Re(a[0],a[0].aoData[this[0]],t,e),this)}),zt([Oe+".show()",Me+".show()"],function(t){return He(this,!0),this}),zt([Oe+".hide()",Me+".hide()"],function(){return He(this,!1),this}),zt([Oe+".remove()",Me+".remove()"],function(){return je(this),this}),zt(Oe+".isShown()",function(){var t=this.context;return t.length&&this.length?t[0].aoData[this[0]]._detailsShow||!1:!1});var We=/^(.+):(name|visIdx|visible)$/,Ue=function(t,e,n,a,r){for(var o=[],i=0,s=r.length;s>i;i++)o.push(w(t,r[i],e));return o},Ee=function(t,e,n){var r=t.aoColumns,o=ce(r,"sName"),i=ce(r,"nTh"),s=function(e){var s=oe(e);if(""===e)return de(r.length);if(null!==s)return[s>=0?s:r.length+s];if("function"==typeof e){var l=Le(t,n);return a.map(r,function(n,a){return e(a,Ue(t,a,0,0,l),i[a])?a:null})}var u="string"==typeof e?e.match(We):"";if(!u)return a(i).filter(e).map(function(){return a.inArray(this,i)}).toArray();switch(u[2]){case"visIdx":case"visible":var c=parseInt(u[1],10);if(0>c){var f=a.map(r,function(t,e){return t.bVisible?e:null});return[f[f.length+c]]}return[p(t,c)];case"name":return a.map(o,function(t,e){return t===u[1]?e:null})}};return Ie("column",e,s,t,n)},Be=function(t,e,r,o){var i,s,l,u,c=t.aoColumns,f=c[e],d=t.aoData;if(r===n)return f.bVisible;if(f.bVisible!==r){if(r){var p=a.inArray(!0,ce(c,"bVisible"),e+1);for(s=0,l=d.length;l>s;s++)u=d[s].nTr,i=d[s].anCells,u&&u.insertBefore(i[e],i[p]||null)}else a(ce(t.aoData,"anCells",e)).detach();f.bVisible=r,O(t,t.aoHeader),O(t,t.aoFooter),(o===n||o)&&(h(t),(t.oScroll.sX||t.oScroll.sY)&&bt(t)),Wt(t,null,"column-visibility",[t,e,r]),Pt(t)}};zt("columns()",function(t,e){t===n?t="":a.isPlainObject(t)&&(e=t,t=""),e=Ae(e);var r=this.iterator("table",function(n){return Ee(n,t,e)},1);return r.selector.cols=t,r.selector.opts=e,r}),Yt("columns().header()","column().header()",function(t,e){return this.iterator("column",function(t,e){return t.aoColumns[e].nTh},1)}),Yt("columns().footer()","column().footer()",function(t,e){return this.iterator("column",function(t,e){return t.aoColumns[e].nTf},1)}),Yt("columns().data()","column().data()",function(){return this.iterator("column-rows",Ue,1)}),Yt("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(t,e){return t.aoColumns[e].mData},1)}),Yt("columns().cache()","column().cache()",function(t){return this.iterator("column-rows",function(e,n,a,r,o){return fe(e.aoData,o,"search"===t?"_aFilterData":"_aSortData",n)},1)}),Yt("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(t,e,n,a,r){return fe(t.aoData,r,"anCells",e)},1)}),Yt("columns().visible()","column().visible()",function(t,e){return this.iterator("column",function(a,r){return t===n?a.aoColumns[r].bVisible:void Be(a,r,t,e)})}),Yt("columns().indexes()","column().index()",function(t){return this.iterator("column",function(e,n){return"visible"===t?g(e,n):n},1)}),zt("columns.adjust()",function(){return this.iterator("table",function(t){h(t)},1)}),zt("column.index()",function(t,e){if(0!==this.context.length){var n=this.context[0];if("fromVisible"===t||"toData"===t)return p(n,e);if("fromData"===t||"toVisible"===t)return g(n,e)}}),zt("column()",function(t,e){return Fe(this.columns(t,e))});var Je=function(t,e,r){var o,i,s,l,u,c,f,d=t.aoData,h=Le(t,r),p=he(fe(d,h,"anCells")),g=a([].concat.apply([],p)),b=t.aoColumns.length,v=function(e){var r="function"==typeof e;if(null===e||e===n||r){for(i=[],s=0,l=h.length;l>s;s++)for(o=h[s],u=0;b>u;u++)c={row:o,column:u},r?(f=d[o],e(c,w(t,o,u),f.anCells?f.anCells[u]:null)&&i.push(c)):i.push(c);return i}return a.isPlainObject(e)?[e]:g.filter(e).map(function(t,e){if(e.parentNode)o=e.parentNode._DT_RowIndex;else for(t=0,l=d.length;l>t;t++)if(-1!==a.inArray(e,d[t].anCells)){o=t;break}return{row:o,column:a.inArray(e,d[o].anCells)}}).toArray()};return Ie("cell",e,v,t,r)};zt("cells()",function(t,e,r){if(a.isPlainObject(t)&&(t.row===n?(r=t,t=null):(r=e,e=null)),a.isPlainObject(e)&&(r=e,e=null),null===e||e===n)return this.iterator("table",function(e){return Je(e,t,Ae(r))});var o,i,s,l,u,c=this.columns(e,r),f=this.rows(t,r),d=this.iterator("table",function(t,e){for(o=[],i=0,s=f[e].length;s>i;i++)for(l=0,u=c[e].length;u>l;l++)o.push({row:f[e][i],column:c[e][l]});return o},1);return a.extend(d.selector,{cols:e,rows:t,opts:r}),d}),Yt("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(t,e,a){var r=t.aoData[e].anCells;return r?r[a]:n},1)}),zt("cells().data()",function(){return this.iterator("cell",function(t,e,n){return w(t,e,n)},1)}),Yt("cells().cache()","cell().cache()",function(t){return t="search"===t?"_aFilterData":"_aSortData",this.iterator("cell",function(e,n,a){return e.aoData[n][t][a]},1)}),Yt("cells().render()","cell().render()",function(t){return this.iterator("cell",function(e,n,a){return w(e,n,a,t)},1)}),Yt("cells().indexes()","cell().index()",function(){return this.iterator("cell",function(t,e,n){return{row:e,column:n,columnVisible:g(t,n)}},1)}),Yt("cells().invalidate()","cell().invalidate()",function(t){return this.iterator("cell",function(e,n,a){R(e,n,t,a)})}),zt("cell()",function(t,e,n){return Fe(this.cells(t,e,n))}),zt("cell().data()",function(t){var e=this.context,a=this[0];return t===n?e.length&&a.length?w(e[0],a[0].row,a[0].column):n:(C(e[0],a[0].row,a[0].column,t),R(e[0],a[0].row,"data",a[0].column),this)}),zt("order()",function(t,e){var r=this.context;return t===n?0!==r.length?r[0].aaSorting:n:("number"==typeof t?t=[[t,e]]:a.isArray(t[0])||(t=Array.prototype.slice.call(arguments)),this.iterator("table",function(e){e.aaSorting=t.slice()}))}),zt("order.listener()",function(t,e,n){return this.iterator("table",function(a){
3
+ At(a,t,e,n)})}),zt(["columns().order()","column().order()"],function(t){var e=this;return this.iterator("table",function(n,r){var o=[];a.each(e[r],function(e,n){o.push([n,t])}),n.aaSorting=o})}),zt("search()",function(t,e,r,o){var i=this.context;return t===n?0!==i.length?i[0].oPreviousSearch.sSearch:n:this.iterator("table",function(n){n.oFeatures.bFilter&&z(n,a.extend({},n.oPreviousSearch,{sSearch:t+"",bRegex:null===e?!1:e,bSmart:null===r?!0:r,bCaseInsensitive:null===o?!0:o}),1)})}),Yt("columns().search()","column().search()",function(t,e,r,o){return this.iterator("column",function(i,s){var l=i.aoPreSearchCols;return t===n?l[s].sSearch:void(i.oFeatures.bFilter&&(a.extend(l[s],{sSearch:t+"",bRegex:null===e?!1:e,bSmart:null===r?!0:r,bCaseInsensitive:null===o?!0:o}),z(i,i.oPreviousSearch,1)))})}),zt("state()",function(){return this.context.length?this.context[0].oSavedState:null}),zt("state.clear()",function(){return this.iterator("table",function(t){t.fnStateSaveCallback.call(t.oInstance,t,{})})}),zt("state.loaded()",function(){return this.context.length?this.context[0].oLoadedState:null}),zt("state.save()",function(){return this.iterator("table",function(t){Pt(t)})}),qt.versionCheck=qt.fnVersionCheck=function(t){for(var e,n,a=qt.version.split("."),r=t.split("."),o=0,i=r.length;i>o;o++)if(e=parseInt(a[o],10)||0,n=parseInt(r[o],10)||0,e!==n)return e>n;return!0},qt.isDataTable=qt.fnIsDataTable=function(t){var e=a(t).get(0),n=!1;return a.each(qt.settings,function(t,r){var o=r.nScrollHead?a("table",r.nScrollHead)[0]:null,i=r.nScrollFoot?a("table",r.nScrollFoot)[0]:null;(r.nTable===e||o===e||i===e)&&(n=!0)}),n},qt.tables=qt.fnTables=function(t){var e=!1;a.isPlainObject(t)&&(e=t.api,t=t.visible);var n=a.map(qt.settings,function(e){return!t||t&&a(e.nTable).is(":visible")?e.nTable:void 0});return e?new $t(n):n},qt.util={throttle:mt,escapeRegex:tt},qt.camelToHungarian=o,zt("$()",function(t,e){var n=this.rows(e).nodes(),r=a(n);return a([].concat(r.filter(t).toArray(),r.find(t).toArray()))}),a.each(["on","one","off"],function(t,e){zt(e+"()",function(){var t=Array.prototype.slice.call(arguments);t[0].match(/\.dt\b/)||(t[0]+=".dt");var n=a(this.tables().nodes());return n[e].apply(n,t),this})}),zt("clear()",function(){return this.iterator("table",function(t){L(t)})}),zt("settings()",function(){return new $t(this.context,this.context)}),zt("init()",function(){var t=this.context;return t.length?t[0].oInit:null}),zt("data()",function(){return this.iterator("table",function(t){return ce(t.aoData,"_aData")}).flatten()}),zt("destroy()",function(e){return e=e||!1,this.iterator("table",function(n){var r,o=n.nTableWrapper.parentNode,i=n.oClasses,s=n.nTable,l=n.nTBody,u=n.nTHead,c=n.nTFoot,f=a(s),d=a(l),h=a(n.nTableWrapper),p=a.map(n.aoData,function(t){return t.nTr});n.bDestroying=!0,Wt(n,"aoDestroyCallback","destroy",[n]),e||new $t(n).columns().visible(!0),h.unbind(".DT").find(":not(tbody *)").unbind(".DT"),a(t).unbind(".DT-"+n.sInstance),s!=u.parentNode&&(f.children("thead").detach(),f.append(u)),c&&s!=c.parentNode&&(f.children("tfoot").detach(),f.append(c)),n.aaSorting=[],n.aaSortingFixed=[],Ft(n),a(p).removeClass(n.asStripeClasses.join(" ")),a("th, td",u).removeClass(i.sSortable+" "+i.sSortableAsc+" "+i.sSortableDesc+" "+i.sSortableNone),n.bJUI&&(a("th span."+i.sSortIcon+", td span."+i.sSortIcon,u).detach(),a("th, td",u).each(function(){var t=a("div."+i.sSortJUIWrapper,this);a(this).append(t.contents()),t.detach()})),d.children().detach(),d.append(p);var g=e?"remove":"detach";f[g](),h[g](),!e&&o&&(o.insertBefore(s,n.nTableReinsertBefore),f.css("width",n.sDestroyWidth).removeClass(i.sTable),r=n.asDestroyStripes.length,r&&d.children().each(function(t){a(this).addClass(n.asDestroyStripes[t%r])}));var b=a.inArray(n,qt.settings);-1!==b&&qt.settings.splice(b,1)})}),a.each(["column","row","cell"],function(t,e){zt(e+"s().every()",function(t){return this.iterator(e,function(a,r,o,i,s){t.call(new $t(a)[e](r,"cell"===e?o:n),r,o,i,s)})})}),zt("i18n()",function(t,e,r){var o=this.context[0],i=I(t)(o.oLanguage);return i===n&&(i=e),r!==n&&a.isPlainObject(i)&&(i=i[r]!==n?i[r]:i._),i.replace("%d",r)}),qt.version="1.10.9",qt.settings=[],qt.models={},qt.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0},qt.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1},qt.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null},qt.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(t){try{return JSON.parse((-1===t.iStateDuration?sessionStorage:localStorage).getItem("DataTables_"+t.sInstance+"_"+location.pathname))}catch(e){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(t,e){try{(-1===t.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+t.sInstance+"_"+location.pathname,JSON.stringify(e))}catch(n){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},oSearch:a.extend({},qt.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"},r(qt.defaults),qt.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null},r(qt.defaults.column),qt.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:n,oAjaxData:n,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==Bt(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==Bt(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var t=this._iDisplayLength,e=this._iDisplayStart,n=e+t,a=this.aiDisplay.length,r=this.oFeatures,o=r.bPaginate;return r.bServerSide?o===!1||-1===t?e+a:Math.min(e+t,this._iRecordsDisplay):!o||n>a||-1===t?a:n},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null},qt.ext=Gt={buttons:{},classes:{},errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:qt.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:qt.version},a.extend(Gt,{afnFiltering:Gt.search,aTypes:Gt.type.detect,ofnSearch:Gt.type.search,oSort:Gt.type.order,afnSortData:Gt.order,aoFeatures:Gt.feature,oApi:Gt.internal,oStdClasses:Gt.classes,oPagination:Gt.pager}),a.extend(qt.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""}),function(){var t="";t="";var e=t+"ui-state-default",n=t+"css_right ui-icon ui-icon-",r=t+"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix";a.extend(qt.ext.oJUIClasses,qt.ext.classes,{sPageButton:"fg-button ui-button "+e,sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:e+" sorting_asc",sSortDesc:e+" sorting_desc",sSortable:e+" sorting",sSortableAsc:e+" sorting_asc_disabled",sSortableDesc:e+" sorting_desc_disabled",sSortableNone:e+" sorting_disabled",sSortJUIAsc:n+"triangle-1-n",sSortJUIDesc:n+"triangle-1-s",sSortJUI:n+"carat-2-n-s",sSortJUIAscAllowed:n+"carat-1-n",sSortJUIDescAllowed:n+"carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead "+e,sScrollFoot:"dataTables_scrollFoot "+e,sHeaderTH:e,sFooterTH:e,sJUIHeader:r+" ui-corner-tl ui-corner-tr",sJUIFooter:r+" ui-corner-bl ui-corner-br"})}();var Xe=qt.ext.pager;a.extend(Xe,{simple:function(t,e){return["previous","next"]},full:function(t,e){return["first","previous","next","last"]},numbers:function(t,e){return[Jt(t,e)]},simple_numbers:function(t,e){return["previous",Jt(t,e),"next"]},full_numbers:function(t,e){return["first","previous",Jt(t,e),"next","last"]},_numbers:Jt,numbers_length:7}),a.extend(!0,qt.ext.renderer,{pageButton:{_:function(t,n,r,o,i,s){var l,u,c,f=t.oClasses,d=t.oLanguage.oPaginate,h=0,p=function(e,n){var o,c,g,b,v=function(e){dt(t,e.data.action,!0)};for(o=0,c=n.length;c>o;o++)if(b=n[o],a.isArray(b)){var S=a("<"+(b.DT_el||"div")+"/>").appendTo(e);p(S,b)}else{switch(l=null,u="",b){case"ellipsis":e.append('<span class="ellipsis">&#x2026;</span>');break;case"first":l=d.sFirst,u=b+(i>0?"":" "+f.sPageButtonDisabled);break;case"previous":l=d.sPrevious,u=b+(i>0?"":" "+f.sPageButtonDisabled);break;case"next":l=d.sNext,u=b+(s-1>i?"":" "+f.sPageButtonDisabled);break;case"last":l=d.sLast,u=b+(s-1>i?"":" "+f.sPageButtonDisabled);break;default:l=b+1,u=i===b?f.sPageButtonActive:""}null!==l&&(g=a("<a>",{"class":f.sPageButton+" "+u,"aria-controls":t.sTableId,"data-dt-idx":h,tabindex:t.iTabIndex,id:0===r&&"string"==typeof b?t.sTableId+"_"+b:null}).html(l).appendTo(e),Ot(g,{action:b},v),h++)}};try{c=a(n).find(e.activeElement).data("dt-idx")}catch(g){}p(a(n).empty(),o),c&&a(n).find("[data-dt-idx="+c+"]").focus()}}}),a.extend(qt.ext.type.detect,[function(t,e){var n=e.oLanguage.sDecimal;return se(t,n)?"num"+n:null},function(t,e){if(t&&!(t instanceof Date)&&(!te.test(t)||!ee.test(t)))return null;var n=Date.parse(t);return null!==n&&!isNaN(n)||re(t)?"date":null},function(t,e){var n=e.oLanguage.sDecimal;return se(t,n,!0)?"num-fmt"+n:null},function(t,e){var n=e.oLanguage.sDecimal;return ue(t,n)?"html-num"+n:null},function(t,e){var n=e.oLanguage.sDecimal;return ue(t,n,!0)?"html-num-fmt"+n:null},function(t,e){return re(t)||"string"==typeof t&&-1!==t.indexOf("<")?"html":null}]),a.extend(qt.ext.type.search,{html:function(t){return re(t)?t:"string"==typeof t?t.replace(Zt," ").replace(Kt,""):""},string:function(t){return re(t)?t:"string"==typeof t?t.replace(Zt," "):t}});var Ve=function(t,e,n,a){return 0===t||t&&"-"!==t?(e&&(t=ie(t,e)),t.replace&&(n&&(t=t.replace(n,"")),a&&(t=t.replace(a,""))),1*t):-(1/0)};return a.extend(Gt.type.order,{"date-pre":function(t){return Date.parse(t)||0},"html-pre":function(t){return re(t)?"":t.replace?t.replace(/<.*?>/g,"").toLowerCase():t+""},"string-pre":function(t){return re(t)?"":"string"==typeof t?t.toLowerCase():t.toString?t.toString():""},"string-asc":function(t,e){return e>t?-1:t>e?1:0},"string-desc":function(t,e){return e>t?1:t>e?-1:0}}),Xt(""),a.extend(!0,qt.ext.renderer,{header:{_:function(t,e,n,r){a(t.nTable).on("order.dt.DT",function(a,o,i,s){if(t===o){var l=n.idx;e.removeClass(n.sSortingClass+" "+r.sSortAsc+" "+r.sSortDesc).addClass("asc"==s[l]?r.sSortAsc:"desc"==s[l]?r.sSortDesc:n.sSortingClass)}})},jqueryui:function(t,e,n,r){a("<div/>").addClass(r.sSortJUIWrapper).append(e.contents()).append(a("<span/>").addClass(r.sSortIcon+" "+n.sSortingClassJUI)).appendTo(e),a(t.nTable).on("order.dt.DT",function(a,o,i,s){if(t===o){var l=n.idx;e.removeClass(r.sSortAsc+" "+r.sSortDesc).addClass("asc"==s[l]?r.sSortAsc:"desc"==s[l]?r.sSortDesc:n.sSortingClass),e.find("span."+r.sSortIcon).removeClass(r.sSortJUIAsc+" "+r.sSortJUIDesc+" "+r.sSortJUI+" "+r.sSortJUIAscAllowed+" "+r.sSortJUIDescAllowed).addClass("asc"==s[l]?r.sSortJUIAsc:"desc"==s[l]?r.sSortJUIDesc:n.sSortingClassJUI)}})}}}),qt.render={number:function(t,e,n,a,r){return{display:function(o){if("number"!=typeof o&&"string"!=typeof o)return o;var i=0>o?"-":"";o=Math.abs(parseFloat(o));var s=parseInt(o,10),l=n?e+(o-s).toFixed(n).substring(2):"";return i+(a||"")+s.toString().replace(/\B(?=(\d{3})+(?!\d))/g,t)+l+(r||"")}}}},a.extend(qt.ext.internal,{_fnExternApiFunc:Vt,_fnBuildAjax:J,_fnAjaxUpdate:X,_fnAjaxParameters:V,_fnAjaxUpdateDraw:q,_fnAjaxDataSrc:G,_fnAddColumn:f,_fnColumnOptions:d,_fnAdjustColumnSizing:h,_fnVisibleToColumnIndex:p,_fnColumnIndexToVisible:g,_fnVisbleColumns:b,_fnGetColumns:v,_fnColumnTypes:S,_fnApplyColumnDefs:m,_fnHungarianMap:r,_fnCamelToHungarian:o,_fnLanguageCompat:i,_fnBrowserDetect:u,_fnAddData:D,_fnAddTr:y,_fnNodeToDataIndex:_,_fnNodeToColumnIndex:T,_fnGetCellData:w,_fnSetCellData:C,_fnSplitObjNotation:x,_fnGetObjectDataFn:I,_fnSetObjectDataFn:A,_fnGetDataMaster:F,_fnClearTable:L,_fnDeleteIndex:P,_fnInvalidate:R,_fnGetRowElements:j,_fnCreateTr:H,_fnBuildHead:k,_fnDrawHead:O,_fnDraw:M,_fnReDraw:W,_fnAddOptionsHtml:U,_fnDetectHeader:E,_fnGetUniqueThs:B,_fnFeatureHtmlFilter:$,_fnFilterComplete:z,_fnFilterCustom:Y,_fnFilterColumn:Q,_fnFilter:Z,_fnFilterCreateSearch:K,_fnEscapeRegex:tt,_fnFilterData:et,_fnFeatureHtmlInfo:rt,_fnUpdateInfo:ot,_fnInfoMacros:it,_fnInitialise:st,_fnInitComplete:lt,_fnLengthChange:ut,_fnFeatureHtmlLength:ct,_fnFeatureHtmlPaginate:ft,_fnPageChange:dt,_fnFeatureHtmlProcessing:ht,_fnProcessingDisplay:pt,_fnFeatureHtmlTable:gt,_fnScrollDraw:bt,_fnApplyToChildren:vt,_fnCalculateColumnWidths:St,_fnThrottle:mt,_fnConvertToWidth:Dt,_fnGetWidestNode:yt,_fnGetMaxLenString:_t,_fnStringToCss:Tt,_fnSortFlatten:wt,_fnSort:Ct,_fnSortAria:xt,_fnSortListener:It,_fnSortAttachListener:At,_fnSortingClasses:Ft,_fnSortData:Lt,_fnSaveState:Pt,_fnLoadState:Rt,_fnSettingsFromNode:jt,_fnLog:Ht,_fnMap:Nt,_fnBindAction:Ot,_fnCallbackReg:Mt,_fnCallbackFire:Wt,_fnLengthOverflow:Ut,_fnRenderer:Et,_fnDataSource:Bt,_fnRowAttributes:N,_fnCalculateEnd:function(){}}),a.fn.dataTable=qt,a.fn.dataTableSettings=qt.settings,a.fn.dataTableExt=qt.ext,a.fn.DataTable=function(t){return a(this).dataTable(t).api()},a.each(qt,function(t,e){a.fn.DataTable[t]=e}),a.fn.dataTable})}(window,document),function(t,e,n){var a=function(t,n){"use strict";t.extend(!0,n.defaults,{dom:"<'row'<'col-sm-5'><'col-sm-4'f><'col-sm-3'l>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"}),t.extend(n.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm"}),n.ext.renderer.pageButton.bootstrap=function(a,r,o,i,s,l){var u,c,f,d=new n.Api(a),h=a.oClasses,p=a.oLanguage.oPaginate,g=0,b=function(e,n){var r,i,f,v,S=function(e){e.preventDefault(),t(e.currentTarget).hasClass("disabled")||d.page(e.data.action).draw("page")};for(r=0,i=n.length;i>r;r++)if(v=n[r],t.isArray(v))b(e,v);else{switch(u="",c="",v){case"ellipsis":u="&hellip;",c="disabled";break;case"first":u=p.sFirst,c=v+(s>0?"":" disabled");break;case"previous":u=p.sPrevious,c=v+(s>0?"":" disabled");break;case"next":u=p.sNext,c=v+(l-1>s?"":" disabled");break;case"last":u=p.sLast,c=v+(l-1>s?"":" disabled");break;default:u=v+1,c=s===v?"active":""}u&&(f=t("<li>",{"class":h.sPageButton+" "+c,id:0===o&&"string"==typeof v?a.sTableId+"_"+v:null}).append(t("<a>",{href:"#","aria-controls":a.sTableId,"data-dt-idx":g,tabindex:a.iTabIndex}).html(u)).appendTo(e),a.oApi._fnBindAction(f,{action:v},S),g++)}};try{f=t(r).find(e.activeElement).data("dt-idx")}catch(v){}b(t(r).empty().html('<ul class="pagination"/>').children("ul"),i),f&&t(r).find("[data-dt-idx="+f+"]").focus()},n.TableTools&&(t.extend(!0,n.TableTools.classes,{container:"DTTT btn-group",buttons:{normal:"btn btn-default",disabled:"disabled"},collection:{container:"DTTT_dropdown dropdown-menu",buttons:{normal:"",disabled:"disabled"}},print:{info:"DTTT_print_info"},select:{row:"active"}}),t.extend(!0,n.TableTools.DEFAULTS.oTags,{collection:{container:"ul",button:"li",liner:"a"}}))};"function"==typeof define&&define.amd?define(["jquery","datatables"],a):"object"==typeof exports?a(require("jquery"),require("datatables")):jQuery&&a(jQuery,jQuery.fn.dataTable)}(window,document);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/mail-bank-manage-email.php CHANGED
@@ -67,7 +67,7 @@ if(!class_exists("mail_bank_manage_email"))
67
 
68
  $body = $this->mb_get_body();
69
  $content_type = $this->mb_get_content_type();
70
- if(empty($content_type) || substr($content_type,0,9) === "text/html")
71
  {
72
  $this->mb_set_body_htmlPart($body);
73
  }
67
 
68
  $body = $this->mb_get_body();
69
  $content_type = $this->mb_get_content_type();
70
+ if(substr($content_type,0,9) === "text/html")
71
  {
72
  $this->mb_set_body_htmlPart($body);
73
  }
includes/translations.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
  /**
3
  * This file is used for translation strings.
4
  *
@@ -35,7 +35,6 @@ else
35
  $wp_langs["sq"] = "Shqip";
36
  $wp_langs["arq"] = "الدارجة الجزايرية";
37
  $wp_langs["am"] = "አማርኛ";
38
- $wp_langs["ar"] = "العربية";
39
  $wp_langs["hy"] = "Հայերեն";
40
  $wp_langs["rup_mk"] = "Armãneashce";
41
  $wp_langs["frp"] = "Arpitan";
@@ -54,7 +53,6 @@ else
54
  $wp_langs["ca"] = "Català";
55
  $wp_langs["bal"] = "Català (Balear)";
56
  $wp_langs["ceb"] = "Cebuano";
57
- $wp_langs["zh_cn"] = "简体中文";
58
  $wp_langs["zh_hk"] = "香港中文版 ";
59
  $wp_langs["zh_tw"] = "繁體中文";
60
  $wp_langs["co"] = "Corsu";
@@ -65,7 +63,6 @@ else
65
  $wp_langs["nl_nl"] = "Nederlands";
66
  $wp_langs["nl_be"] = "Nederlands (België)";
67
  $wp_langs["dzo"] = "རྫོང་ཁ";
68
- $wp_langs["en_au"] = "English (Australia)";
69
  $wp_langs["en_ca"] = "English (Canada)";
70
  $wp_langs["en_nz"] = "English (New Zealand)";
71
  $wp_langs["en_za"] = "English (South Africa)";
@@ -138,7 +135,6 @@ else
138
  $wp_langs["pt_pt"] = "Português";
139
  $wp_langs["pa_in"] = "ਪੰਜਾਬੀ";
140
  $wp_langs["rhg"] = "Ruáinga";
141
- $wp_langs["ro_ro"] = "Română";
142
  $wp_langs["roh"] = "Rumantsch Vallader";
143
  $wp_langs["ru_ru"] = "Русский";
144
  $wp_langs["rue"] = "Русиньскый";
1
+ <?php
2
  /**
3
  * This file is used for translation strings.
4
  *
35
  $wp_langs["sq"] = "Shqip";
36
  $wp_langs["arq"] = "الدارجة الجزايرية";
37
  $wp_langs["am"] = "አማርኛ";
 
38
  $wp_langs["hy"] = "Հայերեն";
39
  $wp_langs["rup_mk"] = "Armãneashce";
40
  $wp_langs["frp"] = "Arpitan";
53
  $wp_langs["ca"] = "Català";
54
  $wp_langs["bal"] = "Català (Balear)";
55
  $wp_langs["ceb"] = "Cebuano";
 
56
  $wp_langs["zh_hk"] = "香港中文版 ";
57
  $wp_langs["zh_tw"] = "繁體中文";
58
  $wp_langs["co"] = "Corsu";
63
  $wp_langs["nl_nl"] = "Nederlands";
64
  $wp_langs["nl_be"] = "Nederlands (België)";
65
  $wp_langs["dzo"] = "རྫོང་ཁ";
 
66
  $wp_langs["en_ca"] = "English (Canada)";
67
  $wp_langs["en_nz"] = "English (New Zealand)";
68
  $wp_langs["en_za"] = "English (South Africa)";
135
  $wp_langs["pt_pt"] = "Português";
136
  $wp_langs["pa_in"] = "ਪੰਜਾਬੀ";
137
  $wp_langs["rhg"] = "Ruáinga";
 
138
  $wp_langs["roh"] = "Rumantsch Vallader";
139
  $wp_langs["ru_ru"] = "Русский";
140
  $wp_langs["rue"] = "Русиньскый";
languages/wp-mail-bank-ar.mo ADDED
Binary file
languages/wp-mail-bank-ar.po ADDED
@@ -0,0 +1,1074 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Mail Bank\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2016-11-04 16:40+0530\n"
6
+ "PO-Revision-Date: 2016-11-04 16:40+0530\n"
7
+ "Last-Translator: Tech Banker\n"
8
+ "Language-Team: Arabic (Saudi Arabia)\n"
9
+ "Language: ar_SA\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100 >= 3 "
14
+ "&& n%100<=10 ? 3 : n%100 >= 11 && n%100<=99 ? 4 : 5;\n"
15
+ "X-Generator: Poedit 1.8.9\n"
16
+ "X-Loco-Source-Locale: en-US\n"
17
+ "X-Loco-Project-Id: 18545\n"
18
+ "X-Loco-Api-Version: 1.0.15 20161010-2\n"
19
+ "X-Poedit-KeywordsList: __\n"
20
+ "X-Poedit-Basepath: ..\n"
21
+ "X-Poedit-SearchPath-0: .\n"
22
+
23
+ #: includes/translations.php:192
24
+ msgid "If you would like to translate in "
25
+ msgstr "إذا كنت ترغب بترجمة الإضافة إلى "
26
+
27
+ #: includes/translations.php:193
28
+ msgid ""
29
+ " & help us, we will reward you with a free Personal Edition License of Mail "
30
+ "Bank. If Interested, Kindly click "
31
+ msgstr ""
32
+ "وساعدتنا بذلك، ستحصل على نسخة شخصية مجانية من Mail Bank، إذا كنت مهتمًا رجاءً "
33
+ "انقر"
34
+
35
+ #: includes/translations.php:195
36
+ msgid "here"
37
+ msgstr "هنا"
38
+
39
+ #: includes/translations.php:203
40
+ msgid "Are you sure you want to close without sending Translation Request?"
41
+ msgstr "هل انت متأكد من الإغلاق دون إرسال طلب الترجمة؟"
42
+
43
+ #: includes/translations.php:204
44
+ msgid "Translation Request"
45
+ msgstr "طلب ترجمة"
46
+
47
+ #: includes/translations.php:205
48
+ msgid "Language Interested to Translate"
49
+ msgstr "لة تهتم بترجمتها"
50
+
51
+ #: includes/translations.php:206
52
+ msgid "Please choose a language which you want to translate"
53
+ msgstr "اختر اللغة التي تريد ترجمتها"
54
+
55
+ #: includes/translations.php:207
56
+ msgid "Please provide a language"
57
+ msgstr "اختر اللغة"
58
+
59
+ #: includes/translations.php:208
60
+ msgid "Query"
61
+ msgstr "المحتوى"
62
+
63
+ #: includes/translations.php:209 includes/translations.php:210
64
+ msgid "Please provide your query"
65
+ msgstr "أضف محتوى"
66
+
67
+ #: includes/translations.php:211 includes/translations.php:427
68
+ msgid "Please provide your Name"
69
+ msgstr "رجاءً ادخل اسمك"
70
+
71
+ #: includes/translations.php:212
72
+ msgid "Please provide your Email"
73
+ msgstr "أضف بريدك"
74
+
75
+ #: includes/translations.php:213 includes/translations.php:374
76
+ msgid "Close"
77
+ msgstr "إغلاق"
78
+
79
+ #: includes/translations.php:214
80
+ msgid "Send Request"
81
+ msgstr "إرسال الطلب"
82
+
83
+ #: includes/translations.php:217
84
+ msgid ""
85
+ "This feature is available only in Premium Editions! <br> Kindly Purchase to "
86
+ "unlock it!"
87
+ msgstr "تتوفر هذه الميزة فقط في الإصدارات المتميزة! <BR> يرجى شراء لفتحه!"
88
+
89
+ #: includes/translations.php:218
90
+ msgid "* Click "
91
+ msgstr "*انقر"
92
+
93
+ #: includes/translations.php:219
94
+ msgid "here "
95
+ msgstr "هنا"
96
+
97
+ #: includes/translations.php:220
98
+ msgid " to see Premium Edition Features in detail"
99
+ msgstr "لكي ترى تفاصيل مميزات الإصدار المميز"
100
+
101
+ #: includes/translations.php:221
102
+ msgid "* For Mail Bank Demos, click "
103
+ msgstr "*للحصول على النسخة التجربة انقر"
104
+
105
+ #: includes/translations.php:222
106
+ msgid "* For Mail Bank User Guide for this page, click "
107
+ msgstr "*للإطلاع على دليل الإستخدام لهذه الصفحة انقر"
108
+
109
+ #: includes/translations.php:223 includes/translations.php:265
110
+ msgid "Important Disclaimer!"
111
+ msgstr "إخلاء مسؤولية!"
112
+
113
+ #: includes/translations.php:224 includes/translations.php:253
114
+ msgid "Your request email has been sent Successfully"
115
+ msgstr "تم إرسال طلبك بالبريد بنجاح"
116
+
117
+ #: includes/translations.php:225
118
+ msgid "* Filters "
119
+ msgstr "*الفلاتر"
120
+
121
+ #: includes/translations.php:226
122
+ msgid "* Reply to, Cc and Bcc Fields "
123
+ msgstr "*حقول إرسال رد ونسخة إلى ونسخة مخفية"
124
+
125
+ #: includes/translations.php:227
126
+ msgid "* Deleting Email Logs "
127
+ msgstr "*حذف السجل"
128
+
129
+ #: includes/translations.php:228
130
+ msgid "* Debugging Output"
131
+ msgstr "*إنشاء سجل"
132
+
133
+ #: includes/translations.php:229
134
+ msgid "* Email Logs Details "
135
+ msgstr "*تفاصيل سجلات الإرسال"
136
+
137
+ #: includes/translations.php:230
138
+ msgid "* Saving Roles & Capabilities "
139
+ msgstr "*الصلاحيات والمميزات"
140
+
141
+ #: includes/translations.php:231
142
+ msgid " Premium Edition Features :"
143
+ msgstr "مميزات الإصدار الممتاز:"
144
+
145
+ #: includes/translations.php:234
146
+ msgid "Basic Info"
147
+ msgstr "معلومات أساسية"
148
+
149
+ #: includes/translations.php:235
150
+ msgid "Account Setup"
151
+ msgstr "إعداد الحساب"
152
+
153
+ #: includes/translations.php:236
154
+ msgid "Confirm"
155
+ msgstr "تأكيد"
156
+
157
+ #: includes/translations.php:239
158
+ msgid "Mail Bank"
159
+ msgstr "Mail Bank"
160
+
161
+ #: includes/translations.php:240
162
+ msgid "Email Setup"
163
+ msgstr "إعداد البريد"
164
+
165
+ #: includes/translations.php:241
166
+ msgid "Email Logs"
167
+ msgstr "سجلات البريد"
168
+
169
+ #: includes/translations.php:242
170
+ msgid "Email Log Details"
171
+ msgstr "تفاصيل سجلات البريد"
172
+
173
+ #: includes/translations.php:243 includes/translations.php:287
174
+ msgid "Test Email"
175
+ msgstr "بريد تجريبي"
176
+
177
+ #: includes/translations.php:244
178
+ msgid "Plugin Settings"
179
+ msgstr "إعدادات الإضافة"
180
+
181
+ #: includes/translations.php:245
182
+ msgid "Feedbacks"
183
+ msgstr "طلبات وآراء"
184
+
185
+ #: includes/translations.php:246
186
+ msgid "Roles & Capabilities"
187
+ msgstr "صلاحيات ومميزات"
188
+
189
+ #: includes/translations.php:247
190
+ msgid "System Information"
191
+ msgstr "بيانات النظام"
192
+
193
+ #: includes/translations.php:250
194
+ msgid "Success!"
195
+ msgstr "نجاح!"
196
+
197
+ #: includes/translations.php:251
198
+ msgid "Email Setup has been updated Successfully"
199
+ msgstr "إعداد البريد قم تم بنجاح"
200
+
201
+ #: includes/translations.php:252
202
+ msgid "Your Feedback has been sent Successfully"
203
+ msgstr "تم إرسال طلبك بنجاح"
204
+
205
+ #: includes/translations.php:254
206
+ msgid "Test Email was sent Successfully!"
207
+ msgstr "تم إرسال البريد التجريبي بنجاح"
208
+
209
+ #: includes/translations.php:255
210
+ msgid "Test Email was not sent!"
211
+ msgstr "لم يتم إرسال البريد التجريبي"
212
+
213
+ #: includes/translations.php:256
214
+ msgid "Plugin Settings have been updated Successfully"
215
+ msgstr "تم تحديث إعدادات الإضافة بنجاح"
216
+
217
+ #: includes/translations.php:257
218
+ msgid "Please choose an Action from Dropdown!"
219
+ msgstr "اختر امرًا من القائمة المنسدلة"
220
+
221
+ #: includes/translations.php:258
222
+ msgid ""
223
+ "The OAuth is not supported by providing SMTP Host, kindly provide username "
224
+ "and password"
225
+ msgstr "لا يمكن دعم OAuth بإستخدام SMTP، يرجى إستخدام إسم ورقم سري "
226
+
227
+ #: includes/translations.php:259
228
+ msgid "Invalid Secret Key. Please rectify and try again!"
229
+ msgstr "خطأ في Secret Key، يرجى التحقق منه والمحاولة مرة أخرى"
230
+
231
+ #: includes/translations.php:260
232
+ msgid "Premium Editions"
233
+ msgstr "طبعات مميزة"
234
+
235
+ #: includes/translations.php:263
236
+ msgid "Sent"
237
+ msgstr "تم الإرسال"
238
+
239
+ #: includes/translations.php:264
240
+ msgid "Not Sent"
241
+ msgstr "فشل الإرسال"
242
+
243
+ #: includes/translations.php:266
244
+ msgid ""
245
+ "You don't have Sufficient Access to this Page. Kindly contact the "
246
+ "Administrator for more Privileges"
247
+ msgstr "لا تملك التصاريح الكافية للولوج إلى هذه الصفحة، رجاءً تواصل مع المدير"
248
+
249
+ #: includes/translations.php:267
250
+ msgid "Enable"
251
+ msgstr "تفعيل"
252
+
253
+ #: includes/translations.php:268
254
+ msgid "Disable"
255
+ msgstr "تعطيل"
256
+
257
+ #: includes/translations.php:269
258
+ msgid "Override"
259
+ msgstr "إستبدال"
260
+
261
+ #: includes/translations.php:270
262
+ msgid "Don't Override"
263
+ msgstr "عدم استبدال"
264
+
265
+ #: includes/translations.php:271
266
+ msgid "Save Settings"
267
+ msgstr "حفظ الإعدادات"
268
+
269
+ #: includes/translations.php:272
270
+ msgid "Subject"
271
+ msgstr "العنوان"
272
+
273
+ #: includes/translations.php:273
274
+ msgid "Next Step"
275
+ msgstr "الخطوة التالية"
276
+
277
+ #: includes/translations.php:274
278
+ msgid "Previous Step"
279
+ msgstr "الخطوة السابقة"
280
+
281
+ #: includes/translations.php:275
282
+ msgid "Settings"
283
+ msgstr "إعدادات"
284
+
285
+ #: includes/translations.php:276
286
+ msgid "Not available"
287
+ msgstr "غير متوفر"
288
+
289
+ #: includes/translations.php:277
290
+ msgid ""
291
+ "The following php extensions are not found on your server or are currently "
292
+ "disabled. These might create few problems in configuring Mail Bank. Please "
293
+ "contact your WebHost to setup these extensions on your server."
294
+ msgstr ""
295
+ "هذه الإضافات (Extensions) غير موجودة في الخادم او غير مفعلة، وبسبب ذلك قد "
296
+ "تظهر لديك بعض الأخطاء في إعداد Mail Bank. لذلك نرجو من التواصل مع المستضيف "
297
+ "للتأكد من تجهيز هذه الإضافات لك."
298
+
299
+ #: includes/translations.php:280
300
+ msgid "Cc"
301
+ msgstr "نسخة"
302
+
303
+ #: includes/translations.php:281
304
+ msgid "Bcc"
305
+ msgstr "نسخة مخفية"
306
+
307
+ #: includes/translations.php:282
308
+ msgid "Please provide valid Cc Email Address"
309
+ msgstr "رجاءً أدخل عنوان بريد صحيح للنُسخ"
310
+
311
+ #: includes/translations.php:283
312
+ msgid "Please provide valid Bcc Email Address"
313
+ msgstr "رجاءً أدخل عنوان بريد مخفي صحيح"
314
+
315
+ #: includes/translations.php:284
316
+ msgid "Please provide Cc Email"
317
+ msgstr "رجاءً اكتب بريد مخصص للنُسخ"
318
+
319
+ #: includes/translations.php:285
320
+ msgid "Please provide Bcc Email"
321
+ msgstr "رجاءً اكتب بريد مخصص للنُسخ المخفية"
322
+
323
+ #: includes/translations.php:286
324
+ msgid "Mailer Settings"
325
+ msgstr "إعدادات خادم الإرسال"
326
+
327
+ #: includes/translations.php:288
328
+ msgid "From Name"
329
+ msgstr "إسم المرسل"
330
+
331
+ #: includes/translations.php:289
332
+ msgid ""
333
+ "From Name is the inbox field that tells your recipient who sent the messages. "
334
+ "If you would like to override the pre-configured From Name, then you would "
335
+ "need to insert the name in the inbox field"
336
+ msgstr ""
337
+ "اسم المُرسل هو الإسم الذي سيظهر للمستقبلين بأنه من قام بإرسال الرسائل البريدية "
338
+ "لهم، إذا كنت ترغب بتعميمه على كل الرسائل فيجب عليك إدخال اسم مُرسل في الخانة "
339
+ "المخصصة."
340
+
341
+ #: includes/translations.php:290
342
+ msgid "Please provide From Name"
343
+ msgstr "رجاءً أدخل اسم المُرسل"
344
+
345
+ #: includes/translations.php:291
346
+ msgid "From Email"
347
+ msgstr "بريد المُرسل"
348
+
349
+ #: includes/translations.php:292
350
+ msgid ""
351
+ "From Email is the inbox field that tells your recipient from which Email "
352
+ "Address the messages are coming. If you would like to override the pre-"
353
+ "configured From Email, then you would need to insert an Email Address in the "
354
+ "inbox field"
355
+ msgstr ""
356
+ "بريد المُرسل هو البريد الذي سيظهر للمستقبلين بأنه من قام بإرسال الرسائل "
357
+ "البريدية لهم، إذا كنت ترغب بتعميمه على كل الرسائل فيجب عليك إدخال بريد "
358
+ "إلكتروني في الخانة المخصصة."
359
+
360
+ #: includes/translations.php:293
361
+ msgid "Please provide From Email Address"
362
+ msgstr "رجاءً أدخل عنوان بريد المُرسل"
363
+
364
+ #: includes/translations.php:294
365
+ msgid "Mailer Type"
366
+ msgstr "نوع خادم الإرسال"
367
+
368
+ #: includes/translations.php:295
369
+ msgid ""
370
+ "This field provides you an ability to choose a specific option for Mailer "
371
+ "Type. If you would like to send an Email via SMTP mailer, you would need to "
372
+ "select Send Email via SMTP from the drop down or you could use PHP mail () "
373
+ "Function"
374
+ msgstr ""
375
+ "هذه الخانة تتيح لك إختيار الخادم المسؤول عن إرسال رسائل البريد، إذا كنت ترغب "
376
+ "في إستخدام خادم SMTP فقم بإختياره من القائمة المنسدلة، او يمكنك إستخدام "
377
+ "الخادم الإفتراضي لـ PHP وهو mail() function"
378
+
379
+ #: includes/translations.php:296
380
+ msgid "Send Email via SMTP"
381
+ msgstr "إرسال عبر خادم SMTP"
382
+
383
+ #: includes/translations.php:297
384
+ msgid "Use The PHP mail() Function"
385
+ msgstr "إرسال عبر الخادم الإفتراضي لـ PHP وهو mail() function"
386
+
387
+ #: includes/translations.php:298
388
+ msgid "SMTP Host"
389
+ msgstr "خادم SMTP"
390
+
391
+ #: includes/translations.php:299
392
+ msgid ""
393
+ "If you would like to send an Email via different host, you would need to "
394
+ "insert that specific host name like smtp.gmail.com in the inbox field"
395
+ msgstr ""
396
+ "إذا كنت تريد إرسال الرسائل عبر خادم SMTP فيمكنك القيام بذلك بإضافة اسم الخادم "
397
+ "هنا مثل smtp.gmail.com"
398
+
399
+ #: includes/translations.php:300
400
+ msgid "Please provide SMTP Host"
401
+ msgstr "رجاءً اكتب عنوان خادم SMTP"
402
+
403
+ #: includes/translations.php:301
404
+ msgid "SMTP Port"
405
+ msgstr "منفذ SMTP"
406
+
407
+ #: includes/translations.php:302
408
+ msgid ""
409
+ "This inbox field is specified to provide a valid SMTP Port for authentication"
410
+ msgstr "تحتاج إلى إضافة منفذ SMTP المخصص للمصادقة في هذه الخانة"
411
+
412
+ #: includes/translations.php:303
413
+ msgid "Please provide SMTP Port"
414
+ msgstr "رجاءً اكتب منفذ SMTP"
415
+
416
+ #: includes/translations.php:304
417
+ msgid "Encryption"
418
+ msgstr "التشفير"
419
+
420
+ #: includes/translations.php:305
421
+ msgid ""
422
+ "It provides you an ability to choose a specific option for Encryption. If you "
423
+ "would like to send an Email with TLS encryption, you would need to select Use "
424
+ "TLS Encryption from the drop down or you could use SSL Encryption. For that "
425
+ "you would need to select Use SSL Encryption from the drop down. If you would "
426
+ "like to send an Email without encryption, you would need to select No "
427
+ "Encryption from the drop down"
428
+ msgstr ""
429
+ "يمكنك إختيار طريقة التشغير من الخيارات المتاحة لك، إذا كنت تريد إستخدام تشفير "
430
+ "TLS فقم بإختيار \"استخدم تشفير TLS\" من القائمة المنسدلة، نفس الشيء ينطبق على "
431
+ "تشغير SSL فيمكنك إختياره من نفس القائمة المنسدلة، أما إذا كنت ترغب بإرسال "
432
+ "الرسائل بدون استخدام اي تشفير، فعندها قم بإختيار \"بدون تشغير\" من القائمة "
433
+ "المنسدلة"
434
+
435
+ #: includes/translations.php:306
436
+ msgid "No Encryption"
437
+ msgstr "بدون تشفير"
438
+
439
+ #: includes/translations.php:307
440
+ msgid "Use SSL Encryption"
441
+ msgstr "استخدم تشفير SSL"
442
+
443
+ #: includes/translations.php:308
444
+ msgid "Use TLS Encryption"
445
+ msgstr "استخدم تشفير TLS"
446
+
447
+ #: includes/translations.php:309
448
+ msgid "Authentication"
449
+ msgstr "المصادقة"
450
+
451
+ #: includes/translations.php:310
452
+ msgid ""
453
+ "This inbox field allows you to choose an appropriate option for "
454
+ "authentication. It provides you the Two-way authentication factor; If you "
455
+ "would like to authenticate yourself via Username and Password, you would need "
456
+ "to select Use Username and Password from the drop down. You can also "
457
+ "authenticate by an OAuth 2.0 protocol, which requires Client Id and Secret "
458
+ "Key, for that you would need to select Use OAuth (Client ID and Secret Key) "
459
+ "from the drop down. You can easily get Client Id and Secret Key from "
460
+ "respective SMTP Server Developers section"
461
+ msgstr ""
462
+ "في هذه الخانة يمكنك إختيار طريقة المصادقة المناسبة لك، يمكنك إختيار \"عملية "
463
+ "التحقق بخطوتين\" في حالة رغبتك بإستخدام اسم ورقم سري، لإستخدامها اختر "
464
+ "\"استخدم الإسم والرقم السري\" من القائمة المنسدلة، يمكنك أيضًا استخدام "
465
+ "بروتوكول OAuth 2.0 والذي يتطلب منك الحصول على Client Id و Secret Key، إذا "
466
+ "اردت استخدام OAuth فيمكنك إختيار \"استخدم OAuth (يلزم توفير Client Id و "
467
+ "Secret Key)\" من القائمة المنسدلة، ويمكنك الحصول على Client Id و Secret Key "
468
+ "من مزود خادم SMTP الخاص بك"
469
+
470
+ #: includes/translations.php:311
471
+ msgid "Use SMTP Authentication"
472
+ msgstr "استخدم مصادقة SMTP"
473
+
474
+ #: includes/translations.php:312
475
+ msgid "Don't Use SMTP Authentication"
476
+ msgstr "لا تستخدم مصادقة SMTP"
477
+
478
+ #: includes/translations.php:313
479
+ msgid "Test Email Address"
480
+ msgstr "عنوان البريد التجريبي"
481
+
482
+ #: includes/translations.php:314
483
+ msgid ""
484
+ "In this field, you would need to provide a valid Email Address in the inbox "
485
+ "field on which you would like to receive Test email"
486
+ msgstr "يجب عليك إدخال بريد صحيح في هذه الخانة لإستقبال رسالة البريد التجريبية"
487
+
488
+ #: includes/translations.php:315
489
+ msgid "Please provide Test Email Address"
490
+ msgstr "رجاءً ادخل عنوان بريد لإستقبال الرسالة التجريبية"
491
+
492
+ #: includes/translations.php:316
493
+ msgid "In this field, you would need to provide a subject for Test Email"
494
+ msgstr "يجب عليك إدخال عنوان في هذه الخانة لرسالة البريد التجريبية"
495
+
496
+ #: includes/translations.php:317
497
+ msgid "Please provide Subject"
498
+ msgstr "رجاءً ادخل عنوانًا للرسالة"
499
+
500
+ #: includes/translations.php:318
501
+ msgid "Email Content"
502
+ msgstr "محتوى الرسالة"
503
+
504
+ #: includes/translations.php:319
505
+ msgid "In this field, you would need to provide the content for Test Email"
506
+ msgstr "يجب عليك إدخال محتوى في هذه الخانة لرسالة البريد التجريبية"
507
+
508
+ #: includes/translations.php:320
509
+ msgid "Send Test Email"
510
+ msgstr "إرسل الرسالة التجريبية"
511
+
512
+ #: includes/translations.php:321
513
+ msgid "SMTP Debugging Output"
514
+ msgstr "معالجة مخرجات SMTP"
515
+
516
+ #: includes/translations.php:322
517
+ msgid "Checking your settings"
518
+ msgstr "فحص إعداداتك"
519
+
520
+ #: includes/translations.php:323
521
+ msgid "Result"
522
+ msgstr "النتائج"
523
+
524
+ #: includes/translations.php:324
525
+ msgid "Send Another Test Email"
526
+ msgstr "إرسالة رسالة تجريبية أخرى"
527
+
528
+ #: includes/translations.php:325
529
+ msgid "From Name Configuration"
530
+ msgstr "إعدادات إسم المرسل"
531
+
532
+ #: includes/translations.php:326
533
+ msgid ""
534
+ "If you would like to override the pre-configured name which will be used "
535
+ "while sending Emails, then you would need to choose Override from the drop "
536
+ "down and vice-versa"
537
+ msgstr ""
538
+ "إذا كنت تريد إستبدال إسم المرسل اثناء إرسال الرسائل البريدية فيجب عليك إختيار "
539
+ "\"إستبدال\" من القائمة المنسدلة والعكس صحيح"
540
+
541
+ #: includes/translations.php:327
542
+ msgid "From Email Configuration"
543
+ msgstr "إعداد بريد المُرسل"
544
+
545
+ #: includes/translations.php:328
546
+ msgid ""
547
+ "If you would like to override your pre-configured Email Address which will be "
548
+ "used while sending Emails, then you would need to choose Override from the "
549
+ "drop down and vice-versa"
550
+ msgstr ""
551
+ "إذا كنت تريد إستبدال البريد المُرسل أثناء إرسال الرسائل البريدية فيجب عليك "
552
+ "إختيار \"إستبدال\" من القائمة المنسدلة والعكس صحيح"
553
+
554
+ #: includes/translations.php:329
555
+ msgid "Username"
556
+ msgstr "إسم المستخدم"
557
+
558
+ #: includes/translations.php:330
559
+ msgid ""
560
+ "In this field, you would need to provide a username to authenticate your SMTP "
561
+ "details"
562
+ msgstr ""
563
+ "يجب عليك إدخال إسم مستخدم صحيح في هذه الخانة من أجل مصادقة SMTP بشكل صحيح"
564
+
565
+ #: includes/translations.php:331
566
+ msgid "Please provide username"
567
+ msgstr "رجاءً أدخل إسم المستخدم"
568
+
569
+ #: includes/translations.php:332
570
+ msgid "Password"
571
+ msgstr "الرقم السري"
572
+
573
+ #: includes/translations.php:333
574
+ msgid ""
575
+ "In this field, you would need to provide a password to authenticate your SMTP "
576
+ "details"
577
+ msgstr "يجب عليك إدخال رقم سري صحيح في هذه الخانة من أجل مصادقة SMTP بشكل صحيح"
578
+
579
+ #: includes/translations.php:334
580
+ msgid "Please provide password"
581
+ msgstr "رجاءً أدخل الرقم السري"
582
+
583
+ #: includes/translations.php:335
584
+ msgid "Redirect URI"
585
+ msgstr "URI إعادة التحويل"
586
+
587
+ #: includes/translations.php:336
588
+ msgid ""
589
+ "Please copy this Redirect URI and Paste into Redirect URI field when creating "
590
+ "your app"
591
+ msgstr "رجاءً إنسخ عنوان URI هذا والصقه في خانة URI عند إ،شاء تطبيقك"
592
+
593
+ #: includes/translations.php:337
594
+ msgid "Use OAuth (Client Id and Secret Key required)"
595
+ msgstr "استخدم OAuth (يلزم توفير Client Id و Secret Key)"
596
+
597
+ #: includes/translations.php:338
598
+ msgid "Plain Authentication"
599
+ msgstr "مصادقة عادية"
600
+
601
+ #: includes/translations.php:339
602
+ msgid "Cram-MD5"
603
+ msgstr "Cram-MD5"
604
+
605
+ #: includes/translations.php:340
606
+ msgid "Login"
607
+ msgstr "حساب"
608
+
609
+ #: includes/translations.php:341
610
+ msgid "Client Id"
611
+ msgstr "Client Id"
612
+
613
+ #: includes/translations.php:342
614
+ msgid "Secret Key"
615
+ msgstr "Secret Key"
616
+
617
+ #: includes/translations.php:343
618
+ msgid "Please provide valid Client Id issued by your SMTP Host"
619
+ msgstr "رجاءً أدخل Client Id المستخدم في مستضيف SMTP"
620
+
621
+ #: includes/translations.php:344
622
+ msgid "Please provide valid Secret Key issued by your SMTP Host"
623
+ msgstr "رجاءً أدخل Secret Key المستخدم في مستضيف SMTP"
624
+
625
+ #: includes/translations.php:345
626
+ msgid "Please provide Client Id"
627
+ msgstr "أدخل Client Id"
628
+
629
+ #: includes/translations.php:346
630
+ msgid "Please provide Secret Key"
631
+ msgstr "أدخل Secret Key"
632
+
633
+ #: includes/translations.php:347
634
+ msgid ""
635
+ "Yes, automatically send a Test Email upon clicking on the Next Step Button to "
636
+ "verify settings"
637
+ msgstr ""
638
+ "قم بإرسال رسالة تجريبية عند النقر على \"التالي\" للتأكد من سلامة الإعدادات"
639
+
640
+ #: includes/translations.php:348
641
+ msgid "Email Address"
642
+ msgstr "عنوان البريد الإلكتروني"
643
+
644
+ #: includes/translations.php:349
645
+ msgid ""
646
+ "In this field, you would need to add a valid Email Address in the inbox field "
647
+ "from which you would like to send Emails"
648
+ msgstr "يجب عليك إدخال عنوان بريد صحيح في هذه الخانة ليكون عنوان بريد المُرسل"
649
+
650
+ #: includes/translations.php:350
651
+ msgid "Please provide valid Email Address"
652
+ msgstr "رجاءً أدخل عنوان بريد صحيح"
653
+
654
+ #: includes/translations.php:351
655
+ msgid "Reply To"
656
+ msgstr "رد إلى"
657
+
658
+ #: includes/translations.php:352
659
+ msgid ""
660
+ "In this field, you would need to add a valid Email Address that is "
661
+ "automatically inserted into the Reply To field when a user replies to an "
662
+ "email message"
663
+ msgstr "يجب عليك إدخال عنوان بريد صحيح"
664
+
665
+ #: includes/translations.php:353
666
+ msgid "Please provide Reply To Email Address"
667
+ msgstr "رجاءً أدخل عنوان بريد الرد"
668
+
669
+ #: includes/translations.php:354
670
+ msgid "Get Google Client Id and Secret Key"
671
+ msgstr "احصل على Client Id و Secret Key من Google"
672
+
673
+ #: includes/translations.php:355
674
+ msgid "Get Microsoft Client Id and Secret Key"
675
+ msgstr "احصل على Client Id و Secret Key من Microsoft"
676
+
677
+ #: includes/translations.php:356
678
+ msgid "Get Yahoo Client Id and Secret Key"
679
+ msgstr "احصل على Client Id و Secret Key من Yahoo"
680
+
681
+ #: includes/translations.php:359
682
+ msgid "Start Date"
683
+ msgstr "من تاريخ"
684
+
685
+ #: includes/translations.php:360
686
+ msgid "Please provide Start Date"
687
+ msgstr "رجاءً أخل ميعاد البدء"
688
+
689
+ #: includes/translations.php:361
690
+ msgid "This field shows starting date of Email Logs"
691
+ msgstr "هذه الخانة تعرض التاريخ الذي تود البدء منه في البحث"
692
+
693
+ #: includes/translations.php:362
694
+ msgid "End Date"
695
+ msgstr "إلى تاريخ"
696
+
697
+ #: includes/translations.php:363
698
+ msgid "Please provide End Date"
699
+ msgstr "رجاءً أدخل التاريخ الذي تود الوقوف عنده"
700
+
701
+ #: includes/translations.php:364
702
+ msgid "This field shows ending date of Email Logs"
703
+ msgstr "هذه الخانة تعرض التاريخ الذي تود آخر تاريخ للبحث فيه"
704
+
705
+ #: includes/translations.php:365
706
+ msgid "Submit"
707
+ msgstr "إرسال"
708
+
709
+ #: includes/translations.php:366
710
+ msgid "Bulk Action"
711
+ msgstr "تنفيذ أمر"
712
+
713
+ #: includes/translations.php:367
714
+ msgid "Delete"
715
+ msgstr "حذف"
716
+
717
+ #: includes/translations.php:368
718
+ msgid "Apply"
719
+ msgstr "تطبيق"
720
+
721
+ #: includes/translations.php:369
722
+ msgid "Email To"
723
+ msgstr "المُستقبِل"
724
+
725
+ #: includes/translations.php:370
726
+ msgid "Action"
727
+ msgstr "أمر"
728
+
729
+ #: includes/translations.php:371
730
+ msgid "Show Details"
731
+ msgstr "عرض التفاصيل"
732
+
733
+ #: includes/translations.php:372
734
+ msgid "Email Details"
735
+ msgstr "تفاصيل البريد"
736
+
737
+ #: includes/translations.php:373
738
+ msgid "Email Debugging output"
739
+ msgstr "معالجة مخرجات البريد"
740
+
741
+ #: includes/translations.php:375
742
+ msgid "Debugging Output"
743
+ msgstr "المُخرجات"
744
+
745
+ #: includes/translations.php:376
746
+ msgid "Show Debugging Output"
747
+ msgstr "عرض المُخرجات"
748
+
749
+ #: includes/translations.php:377
750
+ msgid "Email Sent To"
751
+ msgstr "إرسل إلى"
752
+
753
+ #: includes/translations.php:378
754
+ msgid "Date/Time"
755
+ msgstr "التاريخ/الوقت"
756
+
757
+ #: includes/translations.php:379
758
+ msgid "Status"
759
+ msgstr "الحالة"
760
+
761
+ #: includes/translations.php:380
762
+ msgid "From"
763
+ msgstr "مِن"
764
+
765
+ #: includes/translations.php:381
766
+ msgid "Back to Email Logs"
767
+ msgstr "العودة إلى سجلات البريد"
768
+
769
+ #: includes/translations.php:384
770
+ msgid "Automatic Plugin Updates"
771
+ msgstr "تحديث تلقائي للإضافة"
772
+
773
+ #: includes/translations.php:385
774
+ msgid ""
775
+ "Please choose a specific option whether to allow Automatic Plugin Updates"
776
+ msgstr "رجاءً إختر إذا ما كنت تريد السماح بتحديث الإضافة تلقائيًا"
777
+
778
+ #: includes/translations.php:386
779
+ msgid "Debug Mode"
780
+ msgstr "وضع المعالجة"
781
+
782
+ #: includes/translations.php:387
783
+ msgid "Please choose a specific option for Debug Mode"
784
+ msgstr "رجاءً إختر وضع المعالجة"
785
+
786
+ #: includes/translations.php:388
787
+ msgid "Remove Tables at Uninstall"
788
+ msgstr "حذف الجداول عند إزالة الإضافة"
789
+
790
+ #: includes/translations.php:389
791
+ msgid ""
792
+ "Please choose a specific option whether to allow Remove Tables at Uninstall"
793
+ msgstr "رجاءً إختر ما إذا تريد السماح بحذف الجداول عند حذف الإضافة"
794
+
795
+ #: includes/translations.php:390
796
+ msgid "Monitoring Email Logs"
797
+ msgstr "تتبع سجلات البريد"
798
+
799
+ #: includes/translations.php:391
800
+ msgid "This field is used to allow Email Logs to monitor or not"
801
+ msgstr "هذه الخانة مخصصة للسماع بتتبع سجلات البريد او منعه"
802
+
803
+ #: includes/translations.php:394
804
+ msgid "Show Mail Bank Menu"
805
+ msgstr "عرض قائمة Mail Bank"
806
+
807
+ #: includes/translations.php:395
808
+ msgid "Please choose a specific role who can see Sidebar Menu"
809
+ msgstr "رجاءً إختر من يمكنه رؤية قوائم الإضافة"
810
+
811
+ #: includes/translations.php:396
812
+ msgid "Administrator"
813
+ msgstr "مدير"
814
+
815
+ #: includes/translations.php:397
816
+ msgid "Author"
817
+ msgstr "كاتب"
818
+
819
+ #: includes/translations.php:398
820
+ msgid "Editor"
821
+ msgstr "محرر"
822
+
823
+ #: includes/translations.php:399
824
+ msgid "Contributor"
825
+ msgstr "مساهم"
826
+
827
+ #: includes/translations.php:400
828
+ msgid "Subscriber"
829
+ msgstr "مشارك"
830
+
831
+ #: includes/translations.php:401
832
+ msgid "Others"
833
+ msgstr "آخرون"
834
+
835
+ #: includes/translations.php:402
836
+ msgid "Show Mail Bank Top Bar Menu"
837
+ msgstr "عرض خيار Mail Bank في القائمة العلوية"
838
+
839
+ #: includes/translations.php:403
840
+ msgid "Please choose a specific option from Mail Bank Top Bar Menu"
841
+ msgstr "رجاءً إختر حالة عرض قائمة Mail Bank في القائمة العلوية"
842
+
843
+ #: includes/translations.php:404
844
+ msgid "An Administrator Role can do the following "
845
+ msgstr "بصلاحيات المدير يمكن عمل الآتي"
846
+
847
+ #: includes/translations.php:405
848
+ msgid "Please choose specific page available for the Administrator Access"
849
+ msgstr "رجاءً إختر ما يمكن ان يفعله من يملك صلاحيات المدير"
850
+
851
+ #: includes/translations.php:406
852
+ msgid "Full Control"
853
+ msgstr "تحكم كامل"
854
+
855
+ #: includes/translations.php:407
856
+ msgid "An Author Role can do the following "
857
+ msgstr "بصلاحيات الكاتب يمكن عمل الآتي"
858
+
859
+ #: includes/translations.php:408
860
+ msgid "Please choose specific page available for Author Access"
861
+ msgstr "رجاءً إختر ما يمكن ان يفعله من يملك صلاحيات الكاتب"
862
+
863
+ #: includes/translations.php:409
864
+ msgid "An Editor Role can do the following "
865
+ msgstr "بصلاحيات المحرر يمكن عمل الآتي"
866
+
867
+ #: includes/translations.php:410
868
+ msgid "Please choose specific page available for Editor Access"
869
+ msgstr "رجاءً إختر ما يمكن ان يفعله من يملك صلاحيات المحرر"
870
+
871
+ #: includes/translations.php:411
872
+ msgid "A Contributor Role can do the following "
873
+ msgstr "بصلاحيات المساهم يمكن عمل الآتي"
874
+
875
+ #: includes/translations.php:412
876
+ msgid "Please choose specific page available for Contributor Access"
877
+ msgstr "رجاءً إختر ما يمكن ان يفعله من يملك صلاحيات المساهم"
878
+
879
+ #: includes/translations.php:413
880
+ msgid "Other Roles can do the following "
881
+ msgstr "لمن يملكون صلاحيات أخرى يمكنهم عمل الآتي"
882
+
883
+ #: includes/translations.php:414
884
+ msgid "Please choose specific page available for Others Role Access"
885
+ msgstr "رجاءً إختر ما يمكن ان يفعله من يملك صلاحيات أخرى"
886
+
887
+ #: includes/translations.php:415
888
+ msgid "Please tick the appropriate capabilities for security purposes "
889
+ msgstr "يرجى تحديد صلاحيات معينة لأسباب أمنية"
890
+
891
+ #: includes/translations.php:416
892
+ msgid "Only users with these capabilities can access Mail Bank"
893
+ msgstr "من يملكون هذه الصلاحيات هم فقط القادرون على إستخدام Mail Bank"
894
+
895
+ #: includes/translations.php:417
896
+ msgid "A Subscriber Role can do the following"
897
+ msgstr "بصلاحيات المشترك يمكن عمل الآتي"
898
+
899
+ #: includes/translations.php:418
900
+ msgid "Please choose specific page available for Subscriber Access"
901
+ msgstr "رجاءً إختر ما يمكن ان يفعله من يملك صلاحيات المشترك"
902
+
903
+ #: includes/translations.php:421
904
+ msgid "Thank You!"
905
+ msgstr "شكرًا لك!"
906
+
907
+ #: includes/translations.php:422
908
+ msgid ""
909
+ "Kindly fill in the below form, if you would like to suggest some features "
910
+ "which are not in the Plugin"
911
+ msgstr ""
912
+ "إذا كنت تريد إقتراح إضافة بعض المميزات في التطبيق، فمن فضلك قم بملء الإستمارة "
913
+ "أدناه"
914
+
915
+ #: includes/translations.php:423
916
+ msgid ""
917
+ "If you also have any suggestion/complaint, you can use the same form below"
918
+ msgstr "إذا كنت تملك إقتراحات او شكاوي فيمكنك إستخدام نفس الإستمارة"
919
+
920
+ #: includes/translations.php:424
921
+ msgid "You can also write us on"
922
+ msgstr "يمكن مراسلتنا على"
923
+
924
+ #: includes/translations.php:425
925
+ msgid "Your Name"
926
+ msgstr "اسمك"
927
+
928
+ #: includes/translations.php:426
929
+ msgid "Please provide your Name which will be sent along with your Feedback"
930
+ msgstr "رجاءً أدخل إسمك الذي سيتم إرفاقه مع طلبك"
931
+
932
+ #: includes/translations.php:428
933
+ msgid "Your Email"
934
+ msgstr "بريدك الإلكتروني"
935
+
936
+ #: includes/translations.php:429
937
+ msgid ""
938
+ "Please provide your Email Address which will be sent along with your Feedback"
939
+ msgstr "رجاءً أدخل عنوان بريدك الذي سيتم إرفاقه مع طلبك"
940
+
941
+ #: includes/translations.php:430
942
+ msgid "Please provide your Email Address"
943
+ msgstr "رجاءً أدخل عنوان بريدك"
944
+
945
+ #: includes/translations.php:431
946
+ msgid "Please provide your Feedback which will be sent along"
947
+ msgstr "رجاءً أرفقك طلبك الذي سيتم إرساله"
948
+
949
+ #: includes/translations.php:432
950
+ msgid "Please provide your Feedback"
951
+ msgstr "رجاءً أرفقك طلبك"
952
+
953
+ #: includes/translations.php:433
954
+ msgid "Send Feedback"
955
+ msgstr "إرسال الطلب"
956
+
957
+ #: includes/translations.php:436
958
+ msgid "Sending Test Email to"
959
+ msgstr "إرسال البريد التجريبي إلى"
960
+
961
+ #: includes/translations.php:437
962
+ msgid "Email Status"
963
+ msgstr "حالة البريد"
964
+
965
+ #~ msgid "Roles & Capabilities have been updated Successfully"
966
+ #~ msgstr "تم حفظ الصلاحيات والمميزات بنجاح"
967
+
968
+ #~ msgid "Please choose at least 1 record to delete!"
969
+ #~ msgstr "قم بتحديد خيار واحد على الأقل للحذف!"
970
+
971
+ #~ msgid "Are you sure you want to delete Email Logs?"
972
+ #~ msgstr "هل انت متأكد من رغبتك بحذف سجلات البريد؟"
973
+
974
+ #~ msgid "Selected Logs have been deleted Successfully"
975
+ #~ msgstr "تم حذف السجلات المحددة بنجاح"
976
+
977
+ #~ msgid "Are you sure you want to delete Email Log?"
978
+ #~ msgstr "هل انت متأكد من رغبتك بحذف سجل البريد؟"
979
+
980
+ #~ msgid "Email Log has been deleted Successfully"
981
+ #~ msgstr "تم حذف سجل البريد بنجاح"
982
+
983
+ #~ msgid "Licensing"
984
+ #~ msgstr "ترخيص"
985
+
986
+ #~ msgid "Your License has been activated Successfully"
987
+ #~ msgstr "تم تفعيل رخصتك بنجاح"
988
+
989
+ #~ msgid "* Openssl extension not found or disabled"
990
+ #~ msgstr "*إضافة Openssl غير مفعلة او غير موجودة"
991
+
992
+ #~ msgid "Important Notice!"
993
+ #~ msgstr "تنبيه مهم!"
994
+
995
+ #~ msgid ""
996
+ #~ "Congratulations! You have recently purchased Mail Bank Business Edition "
997
+ #~ "and now you would need to activate the license in order to unlock it!"
998
+ #~ msgstr ""
999
+ #~ "تهانينا! لقد قمت بشراء النسخة التجارية من Mail Bank، كل ما تحتاجه الآن هو "
1000
+ #~ "تفعيل رخصتك لفتح المميزات."
1001
+
1002
+ #~ msgid ""
1003
+ #~ "Kindly fill in the required details and click on Validate License to "
1004
+ #~ "unlock it"
1005
+ #~ msgstr ""
1006
+ #~ "رجاءً قم بتعبئة الحقول المطلوبة ثم انقر على تفعيل الرخصة لفتح المميزات"
1007
+
1008
+ #~ msgid "If you face any issues activating the license, you may contact us at "
1009
+ #~ msgstr "إذا واجهت أي مشكلة في تفعيل رخصتك فيمكنك التواصل معنا"
1010
+
1011
+ #~ msgid "Product Name"
1012
+ #~ msgstr "اسم المنتج"
1013
+
1014
+ #~ msgid "Current Version"
1015
+ #~ msgstr "الإصدار"
1016
+
1017
+ #~ msgid "Website URL"
1018
+ #~ msgstr "رابط الموقع"
1019
+
1020
+ #~ msgid "Order ID"
1021
+ #~ msgstr "Order ID"
1022
+
1023
+ #~ msgid "API KEY"
1024
+ #~ msgstr "API KEY"
1025
+
1026
+ #~ msgid "Validate License"
1027
+ #~ msgstr "رخصة التفعيل"
1028
+
1029
+ #~ msgid "This field shows your Installed Product"
1030
+ #~ msgstr "سيظهر لك اسم المنتج في هذا الحقل"
1031
+
1032
+ #~ msgid "This field shows your Installed Product Version"
1033
+ #~ msgstr "سيظهر لك إصدار المنتج في هذا الحقل"
1034
+
1035
+ #~ msgid "This field shows your Website URL"
1036
+ #~ msgstr "سيظهر لك رابط الموقع في هذا الحقل"
1037
+
1038
+ #~ msgid ""
1039
+ #~ "Please provide your Order ID which you have received after purchasing the "
1040
+ #~ "Product. This will be used for Validating the License"
1041
+ #~ msgstr ""
1042
+ #~ "اكتب رقم الطلب (Order ID) الذي حصلت عليه بعد شراء المنتج من اجل تفعيل رخصتك"
1043
+
1044
+ #~ msgid ""
1045
+ #~ "Please provide your API Key which you have received after purchasing the "
1046
+ #~ "Product. This will be used for Validating the License"
1047
+ #~ msgstr ""
1048
+ #~ "اكتب مفتاح الربط (API KEY) الذي حصلت عليه بعد شراء المنتج من اجل تفعيل "
1049
+ #~ "رخصتك"
1050
+
1051
+ #~ msgid "Please provide Order ID received after making the purchase"
1052
+ #~ msgstr "من فضلك اكتب رقم الطلب (Order ID) الذي حصلت عليه بعد شراء المنتج"
1053
+
1054
+ #~ msgid "Please provide API Key received after making the purchase"
1055
+ #~ msgstr "من فضلك اكتب مفتاح الربط (API Key) الذي حصلت عليه بعد شراء المنتج"
1056
+
1057
+ #~ msgid "Use Username And Password"
1058
+ #~ msgstr "استخدم الإسم والرقم السري"
1059
+
1060
+ #~ msgid " Features available in Business and Developer Editions :"
1061
+ #~ msgstr "المميزات المتوفرة في الإصدار التجاري وإصدار المطورين:"
1062
+
1063
+ #~ msgid ""
1064
+ #~ "This feature is only available in Business and Developer Editions! <br> "
1065
+ #~ "Kindly Purchase to unlock it!."
1066
+ #~ msgstr ""
1067
+ #~ "هذه الميزة متوفرة فقط في الإصدار التجاري وإصدار المطورين<br> للحصول عليها "
1068
+ #~ "من فضلك قم بشراء التطبيق."
1069
+
1070
+ #~ msgid "* Bulk Delete "
1071
+ #~ msgstr "*أمر حذف"
1072
+
1073
+ #~ msgid "* Debugging Output "
1074
+ #~ msgstr "*معالجة المخرجات"
languages/wp-mail-bank-en_AU.mo ADDED
Binary file
languages/wp-mail-bank-en_AU.po ADDED
@@ -0,0 +1,1192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Mail Bank\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2016-11-04 17:06+0530\n"
6
+ "PO-Revision-Date: 2016-11-04 17:06+0530\n"
7
+ "Last-Translator: Tech Banker\n"
8
+ "Language-Team: English (Australia)\n"
9
+ "Language: en_AU\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Generator: Poedit 1.8.9\n"
15
+ "X-Loco-Source-Locale: en-US\n"
16
+ "X-Loco-Project-Id: 18546\n"
17
+ "X-Loco-Api-Version: 1.0.15 20161010-2\n"
18
+ "X-Poedit-KeywordsList: __\n"
19
+ "X-Poedit-Basepath: ..\n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+
22
+ #: includes/translations.php:192
23
+ msgid "If you would like to translate in "
24
+ msgstr "If you would like to translate in"
25
+
26
+ #: includes/translations.php:193
27
+ msgid ""
28
+ " & help us, we will reward you with a free Personal Edition License of Mail "
29
+ "Bank. If Interested, Kindly click "
30
+ msgstr ""
31
+ " & help us, we will reward you with a free Personal Edition License of Mail "
32
+ "Bank. If Interested, Kindly click "
33
+
34
+ #: includes/translations.php:195
35
+ msgid "here"
36
+ msgstr "here"
37
+
38
+ #: includes/translations.php:203
39
+ msgid "Are you sure you want to close without sending Translation Request?"
40
+ msgstr "Are you sure you want to close without sending Translation Request?"
41
+
42
+ #: includes/translations.php:204
43
+ msgid "Translation Request"
44
+ msgstr "Translation Request"
45
+
46
+ #: includes/translations.php:205
47
+ msgid "Language Interested to Translate"
48
+ msgstr "Language Interested to Translate"
49
+
50
+ #: includes/translations.php:206
51
+ msgid "Please choose a language which you want to translate"
52
+ msgstr "Please choose a language which you want to translate"
53
+
54
+ #: includes/translations.php:207
55
+ msgid "Please provide a language"
56
+ msgstr "Please provide a language"
57
+
58
+ #: includes/translations.php:208
59
+ msgid "Query"
60
+ msgstr "Query"
61
+
62
+ #: includes/translations.php:209 includes/translations.php:210
63
+ msgid "Please provide your query"
64
+ msgstr "Please provide your query"
65
+
66
+ #: includes/translations.php:211 includes/translations.php:427
67
+ msgid "Please provide your Name"
68
+ msgstr "Please provide your Name"
69
+
70
+ #: includes/translations.php:212
71
+ msgid "Please provide your Email"
72
+ msgstr "Please provide your Email"
73
+
74
+ #: includes/translations.php:213 includes/translations.php:374
75
+ msgid "Close"
76
+ msgstr "Close"
77
+
78
+ #: includes/translations.php:214
79
+ msgid "Send Request"
80
+ msgstr "Send Request"
81
+
82
+ #: includes/translations.php:217
83
+ msgid ""
84
+ "This feature is available only in Premium Editions! <br> Kindly Purchase to "
85
+ "unlock it!"
86
+ msgstr ""
87
+ "This feature is available only in Premium Editions! <br> Kindly Purchase to "
88
+ "unlock it!"
89
+
90
+ #: includes/translations.php:218
91
+ msgid "* Click "
92
+ msgstr "* Click"
93
+
94
+ #: includes/translations.php:219
95
+ msgid "here "
96
+ msgstr "here"
97
+
98
+ #: includes/translations.php:220
99
+ msgid " to see Premium Edition Features in detail"
100
+ msgstr "to see Premium Edition Features in detail"
101
+
102
+ #: includes/translations.php:221
103
+ msgid "* For Mail Bank Demos, click "
104
+ msgstr "* For Mail Bank Demos, click "
105
+
106
+ #: includes/translations.php:222
107
+ msgid "* For Mail Bank User Guide for this page, click "
108
+ msgstr "* For Mail Bank User Guide for this page, click "
109
+
110
+ #: includes/translations.php:223 includes/translations.php:265
111
+ msgid "Important Disclaimer!"
112
+ msgstr "Important Disclaimer!"
113
+
114
+ #: includes/translations.php:224 includes/translations.php:253
115
+ msgid "Your request email has been sent Successfully"
116
+ msgstr "Your request email has been sent Successfully"
117
+
118
+ #: includes/translations.php:225
119
+ msgid "* Filters "
120
+ msgstr "* Filters"
121
+
122
+ #: includes/translations.php:226
123
+ msgid "* Reply to, Cc and Bcc Fields "
124
+ msgstr "* Reply to, Cc and Bcc Fields"
125
+
126
+ #: includes/translations.php:227
127
+ msgid "* Deleting Email Logs "
128
+ msgstr "* Deleting Email Logs"
129
+
130
+ #: includes/translations.php:228
131
+ msgid "* Debugging Output"
132
+ msgstr "* Debugging Output"
133
+
134
+ #: includes/translations.php:229
135
+ msgid "* Email Logs Details "
136
+ msgstr "* Email Logs Details"
137
+
138
+ #: includes/translations.php:230
139
+ msgid "* Saving Roles & Capabilities "
140
+ msgstr "* Saving Roles & Capabilities"
141
+
142
+ #: includes/translations.php:231
143
+ msgid " Premium Edition Features :"
144
+ msgstr "Premium Edition Features :"
145
+
146
+ #: includes/translations.php:234
147
+ msgid "Basic Info"
148
+ msgstr "Basic Info"
149
+
150
+ #: includes/translations.php:235
151
+ msgid "Account Setup"
152
+ msgstr "Account Setup"
153
+
154
+ #: includes/translations.php:236
155
+ msgid "Confirm"
156
+ msgstr "Confirm"
157
+
158
+ #: includes/translations.php:239
159
+ msgid "Mail Bank"
160
+ msgstr "Mail Bank"
161
+
162
+ #: includes/translations.php:240
163
+ msgid "Email Setup"
164
+ msgstr "Email Setup"
165
+
166
+ #: includes/translations.php:241
167
+ msgid "Email Logs"
168
+ msgstr "Email Logs"
169
+
170
+ #: includes/translations.php:242
171
+ msgid "Email Log Details"
172
+ msgstr "Email Log Details"
173
+
174
+ #: includes/translations.php:243 includes/translations.php:287
175
+ msgid "Test Email"
176
+ msgstr "Test Email"
177
+
178
+ #: includes/translations.php:244
179
+ msgid "Plugin Settings"
180
+ msgstr "Plugin Settings"
181
+
182
+ #: includes/translations.php:245
183
+ msgid "Feedbacks"
184
+ msgstr "Feedbacks"
185
+
186
+ #: includes/translations.php:246
187
+ msgid "Roles & Capabilities"
188
+ msgstr "Roles & Capabilities"
189
+
190
+ #: includes/translations.php:247
191
+ msgid "System Information"
192
+ msgstr "System Information"
193
+
194
+ #: includes/translations.php:250
195
+ msgid "Success!"
196
+ msgstr "Success!"
197
+
198
+ #: includes/translations.php:251
199
+ msgid "Email Setup has been updated Successfully"
200
+ msgstr "Email Setup has been updated Successfully"
201
+
202
+ #: includes/translations.php:252
203
+ msgid "Your Feedback has been sent Successfully"
204
+ msgstr "Your Feedback has been sent Successfully"
205
+
206
+ #: includes/translations.php:254
207
+ msgid "Test Email was sent Successfully!"
208
+ msgstr "Test Email was sent Successfully!"
209
+
210
+ #: includes/translations.php:255
211
+ msgid "Test Email was not sent!"
212
+ msgstr "Test Email was not sent!"
213
+
214
+ #: includes/translations.php:256
215
+ msgid "Plugin Settings have been updated Successfully"
216
+ msgstr "Plugin Settings have been updated Successfully"
217
+
218
+ #: includes/translations.php:257
219
+ msgid "Please choose an Action from Dropdown!"
220
+ msgstr "Please choose an Action from Dropdown!"
221
+
222
+ #: includes/translations.php:258
223
+ msgid ""
224
+ "The OAuth is not supported by providing SMTP Host, kindly provide username "
225
+ "and password"
226
+ msgstr ""
227
+ "The OAuth is not supported by providing SMTP Host, kindly provide username "
228
+ "and password"
229
+
230
+ #: includes/translations.php:259
231
+ msgid "Invalid Secret Key. Please rectify and try again!"
232
+ msgstr "Invalid Secret Key. Please rectify and try again!"
233
+
234
+ #: includes/translations.php:260
235
+ msgid "Premium Editions"
236
+ msgstr "Premium Editions"
237
+
238
+ #: includes/translations.php:263
239
+ msgid "Sent"
240
+ msgstr "Sent"
241
+
242
+ #: includes/translations.php:264
243
+ msgid "Not Sent"
244
+ msgstr "Not Sent"
245
+
246
+ #: includes/translations.php:266
247
+ msgid ""
248
+ "You don't have Sufficient Access to this Page. Kindly contact the "
249
+ "Administrator for more Privileges"
250
+ msgstr ""
251
+ "You don't have Sufficient Access to this Page. Kindly contact the "
252
+ "Administrator for more Privileges"
253
+
254
+ #: includes/translations.php:267
255
+ msgid "Enable"
256
+ msgstr "Enable"
257
+
258
+ #: includes/translations.php:268
259
+ msgid "Disable"
260
+ msgstr "Disable"
261
+
262
+ #: includes/translations.php:269
263
+ msgid "Override"
264
+ msgstr "Override"
265
+
266
+ #: includes/translations.php:270
267
+ msgid "Don't Override"
268
+ msgstr "Don't Override"
269
+
270
+ #: includes/translations.php:271
271
+ msgid "Save Settings"
272
+ msgstr "Save Settings"
273
+
274
+ #: includes/translations.php:272
275
+ msgid "Subject"
276
+ msgstr "Subject"
277
+
278
+ #: includes/translations.php:273
279
+ msgid "Next Step"
280
+ msgstr "Next Step"
281
+
282
+ #: includes/translations.php:274
283
+ msgid "Previous Step"
284
+ msgstr "Previous Step"
285
+
286
+ #: includes/translations.php:275
287
+ msgid "Settings"
288
+ msgstr "Settings"
289
+
290
+ #: includes/translations.php:276
291
+ msgid "Not available"
292
+ msgstr "Not available"
293
+
294
+ #: includes/translations.php:277
295
+ msgid ""
296
+ "The following php extensions are not found on your server or are currently "
297
+ "disabled. These might create few problems in configuring Mail Bank. Please "
298
+ "contact your WebHost to setup these extensions on your server."
299
+ msgstr ""
300
+ "The following php extensions are not found on your server or are currently "
301
+ "disabled. These might create few problems in configuring Mail Bank. Please "
302
+ "contact your WebHost to setup these extensions on your server."
303
+
304
+ #: includes/translations.php:280
305
+ msgid "Cc"
306
+ msgstr "Cc"
307
+
308
+ #: includes/translations.php:281
309
+ msgid "Bcc"
310
+ msgstr "Bcc"
311
+
312
+ #: includes/translations.php:282
313
+ msgid "Please provide valid Cc Email Address"
314
+ msgstr "Please provide valid Cc Email Address"
315
+
316
+ #: includes/translations.php:283
317
+ msgid "Please provide valid Bcc Email Address"
318
+ msgstr "Please provide valid Bcc Email Address"
319
+
320
+ #: includes/translations.php:284
321
+ msgid "Please provide Cc Email"
322
+ msgstr "Please provide Cc Email"
323
+
324
+ #: includes/translations.php:285
325
+ msgid "Please provide Bcc Email"
326
+ msgstr "Please provide Bcc Email"
327
+
328
+ #: includes/translations.php:286
329
+ msgid "Mailer Settings"
330
+ msgstr "Mailer Settings"
331
+
332
+ #: includes/translations.php:288
333
+ msgid "From Name"
334
+ msgstr "From Name"
335
+
336
+ #: includes/translations.php:289
337
+ msgid ""
338
+ "From Name is the inbox field that tells your recipient who sent the "
339
+ "messages. If you would like to override the pre-configured From Name, then "
340
+ "you would need to insert the name in the inbox field"
341
+ msgstr ""
342
+ "From Name is the inbox field that tells your recipient who sent the "
343
+ "messages. If you would like to override the pre-configured From Name, then "
344
+ "you would need to insert the name in the inbox field"
345
+
346
+ #: includes/translations.php:290
347
+ msgid "Please provide From Name"
348
+ msgstr "Please provide From Name"
349
+
350
+ #: includes/translations.php:291
351
+ msgid "From Email"
352
+ msgstr "From Email"
353
+
354
+ #: includes/translations.php:292
355
+ msgid ""
356
+ "From Email is the inbox field that tells your recipient from which Email "
357
+ "Address the messages are coming. If you would like to override the pre-"
358
+ "configured From Email, then you would need to insert an Email Address in the "
359
+ "inbox field"
360
+ msgstr ""
361
+ "From Email is the inbox field that tells your recipient from which Email "
362
+ "Address the messages are coming. If you would like to override the pre-"
363
+ "configured From Email, then you would need to insert an Email Address in the "
364
+ "inbox field"
365
+
366
+ #: includes/translations.php:293
367
+ msgid "Please provide From Email Address"
368
+ msgstr "Please provide From Email Address"
369
+
370
+ #: includes/translations.php:294
371
+ msgid "Mailer Type"
372
+ msgstr "Mailer Type"
373
+
374
+ #: includes/translations.php:295
375
+ msgid ""
376
+ "This field provides you an ability to choose a specific option for Mailer "
377
+ "Type. If you would like to send an Email via SMTP mailer, you would need to "
378
+ "select Send Email via SMTP from the drop down or you could use PHP mail () "
379
+ "Function"
380
+ msgstr ""
381
+ "This field provides you an ability to choose a specific option for Mailer "
382
+ "Type. If you would like to send an Email via SMTP mailer, you would need to "
383
+ "select Send Email via SMTP from the drop-down or you could use PHP mail () "
384
+ "Function"
385
+
386
+ #: includes/translations.php:296
387
+ msgid "Send Email via SMTP"
388
+ msgstr "Send Email via SMTP"
389
+
390
+ #: includes/translations.php:297
391
+ msgid "Use The PHP mail() Function"
392
+ msgstr "Use The PHP mail() Function"
393
+
394
+ #: includes/translations.php:298
395
+ msgid "SMTP Host"
396
+ msgstr "SMTP Host"
397
+
398
+ #: includes/translations.php:299
399
+ msgid ""
400
+ "If you would like to send an Email via different host, you would need to "
401
+ "insert that specific host name like smtp.gmail.com in the inbox field"
402
+ msgstr ""
403
+ "If you would like to send an Email via different host, you would need to "
404
+ "insert that specific host name like smtp.gmail.com in the inbox field"
405
+
406
+ #: includes/translations.php:300
407
+ msgid "Please provide SMTP Host"
408
+ msgstr "Please provide SMTP Host"
409
+
410
+ #: includes/translations.php:301
411
+ msgid "SMTP Port"
412
+ msgstr "SMTP Port"
413
+
414
+ #: includes/translations.php:302
415
+ msgid ""
416
+ "This inbox field is specified to provide a valid SMTP Port for authentication"
417
+ msgstr ""
418
+ "This inbox field is specified to provide a valid SMTP Port for authentication"
419
+
420
+ #: includes/translations.php:303
421
+ msgid "Please provide SMTP Port"
422
+ msgstr "Please provide SMTP Port"
423
+
424
+ #: includes/translations.php:304
425
+ msgid "Encryption"
426
+ msgstr "Encryption"
427
+
428
+ #: includes/translations.php:305
429
+ msgid ""
430
+ "It provides you an ability to choose a specific option for Encryption. If "
431
+ "you would like to send an Email with TLS encryption, you would need to "
432
+ "select Use TLS Encryption from the drop down or you could use SSL "
433
+ "Encryption. For that you would need to select Use SSL Encryption from the "
434
+ "drop down. If you would like to send an Email without encryption, you would "
435
+ "need to select No Encryption from the drop down"
436
+ msgstr ""
437
+ "It provides you an ability to choose a specific option for Encryption. If "
438
+ "you would like to send an Email with TLS encryption, you would need to "
439
+ "select Use TLS Encryption from the drop-down or you could use SSL "
440
+ "Encryption. For that you would need to select Use SSL Encryption from the "
441
+ "drop-down. If you would like to send an Email without encryption, you would "
442
+ "need to select No Encryption from the drop-down "
443
+
444
+ #: includes/translations.php:306
445
+ msgid "No Encryption"
446
+ msgstr "No Encryption"
447
+
448
+ #: includes/translations.php:307
449
+ msgid "Use SSL Encryption"
450
+ msgstr "Use SSL Encryption"
451
+
452
+ #: includes/translations.php:308
453
+ msgid "Use TLS Encryption"
454
+ msgstr "Use TLS Encryption"
455
+
456
+ #: includes/translations.php:309
457
+ msgid "Authentication"
458
+ msgstr "Authentication"
459
+
460
+ #: includes/translations.php:310
461
+ msgid ""
462
+ "This inbox field allows you to choose an appropriate option for "
463
+ "authentication. It provides you the Two-way authentication factor; If you "
464
+ "would like to authenticate yourself via Username and Password, you would "
465
+ "need to select Use Username and Password from the drop down. You can also "
466
+ "authenticate by an OAuth 2.0 protocol, which requires Client Id and Secret "
467
+ "Key, for that you would need to select Use OAuth (Client ID and Secret Key) "
468
+ "from the drop down. You can easily get Client Id and Secret Key from "
469
+ "respective SMTP Server Developers section"
470
+ msgstr ""
471
+ "This inbox field allows you to choose an appropriate option for "
472
+ "authentication. It provides you the Two-way authentication factor; If you "
473
+ "would like to authenticate yourself via Username and Password, you would "
474
+ "need to select Use Username and Password from the drop-down. You can also "
475
+ "authenticate by an OAuth 2.0 protocol, which requires Client Id and Secret "
476
+ "Key, for that you would need to select Use OAuth (Client Id and Secret Key) "
477
+ "from the drop-down. You can easily get Client Id and Secret Key from "
478
+ "respective SMTP Server Developers section"
479
+
480
+ #: includes/translations.php:311
481
+ msgid "Use SMTP Authentication"
482
+ msgstr "Use SMTP Authentication"
483
+
484
+ #: includes/translations.php:312
485
+ msgid "Don't Use SMTP Authentication"
486
+ msgstr "Don't Use SMTP Authentication"
487
+
488
+ #: includes/translations.php:313
489
+ msgid "Test Email Address"
490
+ msgstr "Test Email Address"
491
+
492
+ #: includes/translations.php:314
493
+ msgid ""
494
+ "In this field, you would need to provide a valid Email Address in the inbox "
495
+ "field on which you would like to receive Test email"
496
+ msgstr ""
497
+ "In this field, you would need to provide a valid Email Address in the inbox "
498
+ "field on which you would like to receive Test email"
499
+
500
+ #: includes/translations.php:315
501
+ msgid "Please provide Test Email Address"
502
+ msgstr "Please provide Test Email Address"
503
+
504
+ #: includes/translations.php:316
505
+ msgid "In this field, you would need to provide a subject for Test Email"
506
+ msgstr "In this field, you would need to provide a subject for Test Email"
507
+
508
+ #: includes/translations.php:317
509
+ msgid "Please provide Subject"
510
+ msgstr "Please provide Subject"
511
+
512
+ #: includes/translations.php:318
513
+ msgid "Email Content"
514
+ msgstr "Email Content"
515
+
516
+ #: includes/translations.php:319
517
+ msgid "In this field, you would need to provide the content for Test Email"
518
+ msgstr "In this field, you would need to provide the content for Test Email"
519
+
520
+ #: includes/translations.php:320
521
+ msgid "Send Test Email"
522
+ msgstr "Send Test Email"
523
+
524
+ #: includes/translations.php:321
525
+ msgid "SMTP Debugging Output"
526
+ msgstr "SMTP Debugging Output"
527
+
528
+ #: includes/translations.php:322
529
+ msgid "Checking your settings"
530
+ msgstr "Checking your settings"
531
+
532
+ #: includes/translations.php:323
533
+ msgid "Result"
534
+ msgstr "Result"
535
+
536
+ #: includes/translations.php:324
537
+ msgid "Send Another Test Email"
538
+ msgstr "Send Another Test Email"
539
+
540
+ #: includes/translations.php:325
541
+ msgid "From Name Configuration"
542
+ msgstr "From Name Configuration"
543
+
544
+ #: includes/translations.php:326
545
+ msgid ""
546
+ "If you would like to override the pre-configured name which will be used "
547
+ "while sending Emails, then you would need to choose Override from the drop "
548
+ "down and vice-versa"
549
+ msgstr ""
550
+ "If you would like to override the pre-configured name which will be used "
551
+ "while sending Emails, then you would need to choose Override from the drop-"
552
+ "down and vice-versa"
553
+
554
+ #: includes/translations.php:327
555
+ msgid "From Email Configuration"
556
+ msgstr "From Email Configuration"
557
+
558
+ #: includes/translations.php:328
559
+ msgid ""
560
+ "If you would like to override your pre-configured Email Address which will "
561
+ "be used while sending Emails, then you would need to choose Override from "
562
+ "the drop down and vice-versa"
563
+ msgstr ""
564
+ "If you would like to override your pre-configured Email Address which will "
565
+ "be used while sending Emails, then you would need to choose Override from "
566
+ "the drop-down and vice-versa"
567
+
568
+ #: includes/translations.php:329
569
+ msgid "Username"
570
+ msgstr "Username"
571
+
572
+ #: includes/translations.php:330
573
+ msgid ""
574
+ "In this field, you would need to provide a username to authenticate your "
575
+ "SMTP details"
576
+ msgstr ""
577
+ "In this field, you would need to provide a username to authenticate your "
578
+ "SMTP details"
579
+
580
+ #: includes/translations.php:331
581
+ msgid "Please provide username"
582
+ msgstr "Please provide username"
583
+
584
+ #: includes/translations.php:332
585
+ msgid "Password"
586
+ msgstr "Password"
587
+
588
+ #: includes/translations.php:333
589
+ msgid ""
590
+ "In this field, you would need to provide a password to authenticate your "
591
+ "SMTP details"
592
+ msgstr ""
593
+ "In this field, you would need to provide a password to authenticate your "
594
+ "SMTP details"
595
+
596
+ #: includes/translations.php:334
597
+ msgid "Please provide password"
598
+ msgstr "Please provide password"
599
+
600
+ #: includes/translations.php:335
601
+ msgid "Redirect URI"
602
+ msgstr "Redirect URI"
603
+
604
+ #: includes/translations.php:336
605
+ msgid ""
606
+ "Please copy this Redirect URI and Paste into Redirect URI field when "
607
+ "creating your app"
608
+ msgstr ""
609
+ "Please copy this Redirect URI and Paste into Redirect URI field when "
610
+ "creating your app"
611
+
612
+ #: includes/translations.php:337
613
+ msgid "Use OAuth (Client Id and Secret Key required)"
614
+ msgstr "Use OAuth (Client Id and Secret Key required)"
615
+
616
+ #: includes/translations.php:338
617
+ msgid "Plain Authentication"
618
+ msgstr "Plain Authentication"
619
+
620
+ #: includes/translations.php:339
621
+ msgid "Cram-MD5"
622
+ msgstr "Cram-MD5"
623
+
624
+ #: includes/translations.php:340
625
+ msgid "Login"
626
+ msgstr "Login"
627
+
628
+ #: includes/translations.php:341
629
+ msgid "Client Id"
630
+ msgstr "Client Id"
631
+
632
+ #: includes/translations.php:342
633
+ msgid "Secret Key"
634
+ msgstr "Secret Key"
635
+
636
+ #: includes/translations.php:343
637
+ msgid "Please provide valid Client Id issued by your SMTP Host"
638
+ msgstr "Please provide valid Client Id issued by your SMTP Host"
639
+
640
+ #: includes/translations.php:344
641
+ msgid "Please provide valid Secret Key issued by your SMTP Host"
642
+ msgstr "Please provide valid Secret Key issued by your SMTP Host"
643
+
644
+ #: includes/translations.php:345
645
+ msgid "Please provide Client Id"
646
+ msgstr "Please provide Client Id"
647
+
648
+ #: includes/translations.php:346
649
+ msgid "Please provide Secret Key"
650
+ msgstr "Please provide Secret Key"
651
+
652
+ #: includes/translations.php:347
653
+ msgid ""
654
+ "Yes, automatically send a Test Email upon clicking on the Next Step Button "
655
+ "to verify settings"
656
+ msgstr ""
657
+ "Yes, automatically send a Test Email upon clicking on the Next Step Button "
658
+ "to verify settings"
659
+
660
+ #: includes/translations.php:348
661
+ msgid "Email Address"
662
+ msgstr "Email Address"
663
+
664
+ #: includes/translations.php:349
665
+ msgid ""
666
+ "In this field, you would need to add a valid Email Address in the inbox "
667
+ "field from which you would like to send Emails"
668
+ msgstr ""
669
+ "In this field, you would need to add a valid Email Address in the inbox "
670
+ "field from which you would like to send Emails"
671
+
672
+ #: includes/translations.php:350
673
+ msgid "Please provide valid Email Address"
674
+ msgstr "Please provide valid Email Address"
675
+
676
+ #: includes/translations.php:351
677
+ msgid "Reply To"
678
+ msgstr "Reply To"
679
+
680
+ #: includes/translations.php:352
681
+ msgid ""
682
+ "In this field, you would need to add a valid Email Address that is "
683
+ "automatically inserted into the Reply To field when a user replies to an "
684
+ "email message"
685
+ msgstr ""
686
+ "In this field, you would need to add a valid Email Address that is "
687
+ "automatically inserted into the Reply To field when a user replies to an "
688
+ "email message"
689
+
690
+ #: includes/translations.php:353
691
+ msgid "Please provide Reply To Email Address"
692
+ msgstr "Please provide Reply To Email Address"
693
+
694
+ #: includes/translations.php:354
695
+ msgid "Get Google Client Id and Secret Key"
696
+ msgstr "Get Google Client Id and Secret Key"
697
+
698
+ #: includes/translations.php:355
699
+ msgid "Get Microsoft Client Id and Secret Key"
700
+ msgstr "Get Microsoft Client Id and Secret Key"
701
+
702
+ #: includes/translations.php:356
703
+ msgid "Get Yahoo Client Id and Secret Key"
704
+ msgstr "Get Yahoo Client Id and Secret Key"
705
+
706
+ #: includes/translations.php:359
707
+ msgid "Start Date"
708
+ msgstr "Start Date"
709
+
710
+ #: includes/translations.php:360
711
+ msgid "Please provide Start Date"
712
+ msgstr "Please provide Start Date"
713
+
714
+ #: includes/translations.php:361
715
+ msgid "This field shows starting date of Email Logs"
716
+ msgstr "This field shows starting date of Email Logs"
717
+
718
+ #: includes/translations.php:362
719
+ msgid "End Date"
720
+ msgstr "End Date"
721
+
722
+ #: includes/translations.php:363
723
+ msgid "Please provide End Date"
724
+ msgstr "Please provide End Date"
725
+
726
+ #: includes/translations.php:364
727
+ msgid "This field shows ending date of Email Logs"
728
+ msgstr "This field shows ending date of Email Logs"
729
+
730
+ #: includes/translations.php:365
731
+ msgid "Submit"
732
+ msgstr "Submit"
733
+
734
+ #: includes/translations.php:366
735
+ msgid "Bulk Action"
736
+ msgstr "Bulk Action"
737
+
738
+ #: includes/translations.php:367
739
+ msgid "Delete"
740
+ msgstr "Delete"
741
+
742
+ #: includes/translations.php:368
743
+ msgid "Apply"
744
+ msgstr "Apply"
745
+
746
+ #: includes/translations.php:369
747
+ msgid "Email To"
748
+ msgstr "Email To"
749
+
750
+ #: includes/translations.php:370
751
+ msgid "Action"
752
+ msgstr "Action"
753
+
754
+ #: includes/translations.php:371
755
+ msgid "Show Details"
756
+ msgstr "Show Details"
757
+
758
+ #: includes/translations.php:372
759
+ msgid "Email Details"
760
+ msgstr "Email Details"
761
+
762
+ #: includes/translations.php:373
763
+ msgid "Email Debugging output"
764
+ msgstr "Email Debugging output"
765
+
766
+ #: includes/translations.php:375
767
+ msgid "Debugging Output"
768
+ msgstr "Debugging Output"
769
+
770
+ #: includes/translations.php:376
771
+ msgid "Show Debugging Output"
772
+ msgstr "Show Debugging Output"
773
+
774
+ #: includes/translations.php:377
775
+ msgid "Email Sent To"
776
+ msgstr "Email Sent To"
777
+
778
+ #: includes/translations.php:378
779
+ msgid "Date/Time"
780
+ msgstr "Date/Time"
781
+
782
+ #: includes/translations.php:379
783
+ msgid "Status"
784
+ msgstr "Status"
785
+
786
+ #: includes/translations.php:380
787
+ msgid "From"
788
+ msgstr "From"
789
+
790
+ #: includes/translations.php:381
791
+ msgid "Back to Email Logs"
792
+ msgstr "Back to Email Logs"
793
+
794
+ #: includes/translations.php:384
795
+ msgid "Automatic Plugin Updates"
796
+ msgstr "Automatic Plugin Updates"
797
+
798
+ #: includes/translations.php:385
799
+ msgid ""
800
+ "Please choose a specific option whether to allow Automatic Plugin Updates"
801
+ msgstr ""
802
+ "Please choose a specific option whether to allow Automatic Plugin Updates"
803
+
804
+ #: includes/translations.php:386
805
+ msgid "Debug Mode"
806
+ msgstr "Debug Mode"
807
+
808
+ #: includes/translations.php:387
809
+ msgid "Please choose a specific option for Debug Mode"
810
+ msgstr "Please choose a specific option for Debug Mode"
811
+
812
+ #: includes/translations.php:388
813
+ msgid "Remove Tables at Uninstall"
814
+ msgstr "Remove Tables at Uninstall"
815
+
816
+ #: includes/translations.php:389
817
+ msgid ""
818
+ "Please choose a specific option whether to allow Remove Tables at Uninstall"
819
+ msgstr ""
820
+ "Please choose a specific option whether to allow Remove Tables at Uninstall"
821
+
822
+ #: includes/translations.php:390
823
+ msgid "Monitoring Email Logs"
824
+ msgstr "Monitoring Email Logs"
825
+
826
+ #: includes/translations.php:391
827
+ msgid "This field is used to allow Email Logs to monitor or not"
828
+ msgstr "This field is used to allow Email Logs to monitor or not"
829
+
830
+ #: includes/translations.php:394
831
+ msgid "Show Mail Bank Menu"
832
+ msgstr "Show Mail Bank Menu"
833
+
834
+ #: includes/translations.php:395
835
+ msgid "Please choose a specific role who can see Sidebar Menu"
836
+ msgstr "Please choose a specific role who can see Sidebar Menu"
837
+
838
+ #: includes/translations.php:396
839
+ msgid "Administrator"
840
+ msgstr "Administrator"
841
+
842
+ #: includes/translations.php:397
843
+ msgid "Author"
844
+ msgstr "Author"
845
+
846
+ #: includes/translations.php:398
847
+ msgid "Editor"
848
+ msgstr "Editor"
849
+
850
+ #: includes/translations.php:399
851
+ msgid "Contributor"
852
+ msgstr "Contributor"
853
+
854
+ #: includes/translations.php:400
855
+ msgid "Subscriber"
856
+ msgstr "Subscriber"
857
+
858
+ #: includes/translations.php:401
859
+ msgid "Others"
860
+ msgstr "Others"
861
+
862
+ #: includes/translations.php:402
863
+ msgid "Show Mail Bank Top Bar Menu"
864
+ msgstr "Show Mail Bank Top Bar Menu"
865
+
866
+ #: includes/translations.php:403
867
+ msgid "Please choose a specific option from Mail Bank Top Bar Menu"
868
+ msgstr "Please choose a specific option from Mail Bank Top Bar Menu"
869
+
870
+ #: includes/translations.php:404
871
+ msgid "An Administrator Role can do the following "
872
+ msgstr "An Administrator Role can do the following"
873
+
874
+ #: includes/translations.php:405
875
+ msgid "Please choose specific page available for the Administrator Access"
876
+ msgstr "Please choose specific page available for the Administrator Access"
877
+
878
+ #: includes/translations.php:406
879
+ msgid "Full Control"
880
+ msgstr "Full Control"
881
+
882
+ #: includes/translations.php:407
883
+ msgid "An Author Role can do the following "
884
+ msgstr "An Author Role can do the following"
885
+
886
+ #: includes/translations.php:408
887
+ msgid "Please choose specific page available for Author Access"
888
+ msgstr "Please choose specific page available for Author Access"
889
+
890
+ #: includes/translations.php:409
891
+ msgid "An Editor Role can do the following "
892
+ msgstr "An Editor Role can do the following"
893
+
894
+ #: includes/translations.php:410
895
+ msgid "Please choose specific page available for Editor Access"
896
+ msgstr "Please choose specific page available for Editor Access"
897
+
898
+ #: includes/translations.php:411
899
+ msgid "A Contributor Role can do the following "
900
+ msgstr "A Contributor Role can do the following"
901
+
902
+ #: includes/translations.php:412
903
+ msgid "Please choose specific page available for Contributor Access"
904
+ msgstr "Please choose specific page available for Contributor Access"
905
+
906
+ #: includes/translations.php:413
907
+ msgid "Other Roles can do the following "
908
+ msgstr "Other Roles can do the following"
909
+
910
+ #: includes/translations.php:414
911
+ msgid "Please choose specific page available for Others Role Access"
912
+ msgstr "Please choose specific page available for Others Role Access"
913
+
914
+ #: includes/translations.php:415
915
+ msgid "Please tick the appropriate capabilities for security purposes "
916
+ msgstr "Please tick the appropriate capabilities for security purposes"
917
+
918
+ #: includes/translations.php:416
919
+ msgid "Only users with these capabilities can access Mail Bank"
920
+ msgstr "Only users with these capabilities can access Mail Bank"
921
+
922
+ #: includes/translations.php:417
923
+ msgid "A Subscriber Role can do the following"
924
+ msgstr "A Subscriber Role can do the following"
925
+
926
+ #: includes/translations.php:418
927
+ msgid "Please choose specific page available for Subscriber Access"
928
+ msgstr "Please choose specific page available for Subscriber Access"
929
+
930
+ #: includes/translations.php:421
931
+ msgid "Thank You!"
932
+ msgstr "Thank You!"
933
+
934
+ #: includes/translations.php:422
935
+ msgid ""
936
+ "Kindly fill in the below form, if you would like to suggest some features "
937
+ "which are not in the Plugin"
938
+ msgstr ""
939
+ "Kindly fill in the below form, if you would like to suggest some features "
940
+ "which are not in the Plugin"
941
+
942
+ #: includes/translations.php:423
943
+ msgid ""
944
+ "If you also have any suggestion/complaint, you can use the same form below"
945
+ msgstr ""
946
+ "If you also have any suggestion/complaint, you can use the same form below"
947
+
948
+ #: includes/translations.php:424
949
+ msgid "You can also write us on"
950
+ msgstr "You can also write us on"
951
+
952
+ #: includes/translations.php:425
953
+ msgid "Your Name"
954
+ msgstr "Your Name"
955
+
956
+ #: includes/translations.php:426
957
+ msgid "Please provide your Name which will be sent along with your Feedback"
958
+ msgstr "Please provide your Name which will be sent along with your Feedback"
959
+
960
+ #: includes/translations.php:428
961
+ msgid "Your Email"
962
+ msgstr "Your Email"
963
+
964
+ #: includes/translations.php:429
965
+ msgid ""
966
+ "Please provide your Email Address which will be sent along with your Feedback"
967
+ msgstr ""
968
+ "Please provide your Email Address which will be sent along with your Feedback"
969
+
970
+ #: includes/translations.php:430
971
+ msgid "Please provide your Email Address"
972
+ msgstr "Please provide your Email Address"
973
+
974
+ #: includes/translations.php:431
975
+ msgid "Please provide your Feedback which will be sent along"
976
+ msgstr "Please provide your Feedback which will be sent along"
977
+
978
+ #: includes/translations.php:432
979
+ msgid "Please provide your Feedback"
980
+ msgstr "Please provide your Feedback"
981
+
982
+ #: includes/translations.php:433
983
+ msgid "Send Feedback"
984
+ msgstr "Send Feedback"
985
+
986
+ #: includes/translations.php:436
987
+ msgid "Sending Test Email to"
988
+ msgstr "Sending Test Email to"
989
+
990
+ #: includes/translations.php:437
991
+ msgid "Email Status"
992
+ msgstr "Email Status"
993
+
994
+ #~ msgid "WP Mail Booster"
995
+ #~ msgstr "WP Mail Booster"
996
+
997
+ #~ msgid "Email Configuration"
998
+ #~ msgstr "Email Configuration"
999
+
1000
+ #~ msgid "Email Configuration has been saved Successfully"
1001
+ #~ msgstr "Email Configuration has been saved Successfully"
1002
+
1003
+ #~ msgid "Roles & Capabilities have been saved Successfully"
1004
+ #~ msgstr "Roles & Capabilities have been saved Successfully"
1005
+
1006
+ #~ msgid "Plugin Settings have been saved Successfully"
1007
+ #~ msgstr "Plugin Settings have been saved Successfully"
1008
+
1009
+ #~ msgid "Please choose at least 1 record to delete!"
1010
+ #~ msgstr "Please choose at least 1 record to delete!"
1011
+
1012
+ #~ msgid "Are you sure you want to delete Email Logs?"
1013
+ #~ msgstr "Are you sure you want to delete Email Logs?"
1014
+
1015
+ #~ msgid "Selected Logs has been deleted Successfully"
1016
+ #~ msgstr "Selected Logs has been deleted Successfully"
1017
+
1018
+ #~ msgid "Are you sure you want to delete Email Log?"
1019
+ #~ msgstr "Are you sure you want to delete Email Log?"
1020
+
1021
+ #~ msgid "Email Log has been deleted Successfully"
1022
+ #~ msgstr "Email Log has been deleted Successfully"
1023
+
1024
+ #~ msgid "Licensing"
1025
+ #~ msgstr "Licensing"
1026
+
1027
+ #~ msgid "Your License has been activated Successfully"
1028
+ #~ msgstr "Your License has been activated Successfully"
1029
+
1030
+ #~ msgid "* Openssl extension not found or disabled"
1031
+ #~ msgstr "* Openssl extension not found or disabled"
1032
+
1033
+ #~ msgid ""
1034
+ #~ "Please Copy this Redirect URI and Paste into Redirect URI field when "
1035
+ #~ "creating your app"
1036
+ #~ msgstr ""
1037
+ #~ "Please Copy this Redirect URI and Paste into Redirect URI field when "
1038
+ #~ "creating your app"
1039
+
1040
+ #~ msgid "Use Username and Password"
1041
+ #~ msgstr "Use Username and Password"
1042
+
1043
+ #~ msgid "Show Mail Booster Menu"
1044
+ #~ msgstr "Show Mail Booster Menu"
1045
+
1046
+ #~ msgid "Other Roles"
1047
+ #~ msgstr "Other Roles"
1048
+
1049
+ #~ msgid "Show Mail Booster Top Bar Menu"
1050
+ #~ msgstr "Show Mail Booster Top Bar Menu"
1051
+
1052
+ #~ msgid "Please choose a specific option from Mail Booster Top Bar Menu"
1053
+ #~ msgstr "Please choose a specific option from Mail Booster Top Bar Menu"
1054
+
1055
+ #~ msgid " Please choose specific page available for Subscriber Access"
1056
+ #~ msgstr "Please choose specific page available for Subscriber Access"
1057
+
1058
+ #~ msgid "Other Roles can do the following"
1059
+ #~ msgstr "Other Roles can do the following"
1060
+
1061
+ #~ msgid ""
1062
+ #~ "From here you can select the specific page available for the Other Users "
1063
+ #~ "Access."
1064
+ #~ msgstr ""
1065
+ #~ "From here you can select the specific page available for the Other Users "
1066
+ #~ "Access."
1067
+
1068
+ #~ msgid ""
1069
+ #~ "Please provide Email Address which will be sent along with your Feedback"
1070
+ #~ msgstr ""
1071
+ #~ "Please provide Email Address which will be sent along with your Feedback"
1072
+
1073
+ #~ msgid "Important Notice!"
1074
+ #~ msgstr "Important Notice!"
1075
+
1076
+ #~ msgid ""
1077
+ #~ "Congratulations! You have recently purchased WP Mail Booster Business "
1078
+ #~ "Edition and now you would need to activate the license in order to unlock "
1079
+ #~ "it!"
1080
+ #~ msgstr ""
1081
+ #~ "Congratulations! You have recently purchased WP Mail Booster Business "
1082
+ #~ "Edition and now you would need to activate the license in order to unlock "
1083
+ #~ "it!"
1084
+
1085
+ #~ msgid ""
1086
+ #~ "Kindly fill in the required details and click on Validate License to "
1087
+ #~ "unlock it"
1088
+ #~ msgstr ""
1089
+ #~ "Kindly fill in the required details and click on Validate License to "
1090
+ #~ "unlock it"
1091
+
1092
+ #~ msgid ""
1093
+ #~ "If you face any issues activating the license, you may contact us at "
1094
+ #~ msgstr ""
1095
+ #~ "If you face any issues activating the license, you may contact us at"
1096
+
1097
+ #~ msgid "Product Name"
1098
+ #~ msgstr "Product Name"
1099
+
1100
+ #~ msgid "Current Version"
1101
+ #~ msgstr "Current Version"
1102
+
1103
+ #~ msgid "Website URL"
1104
+ #~ msgstr "Website URL"
1105
+
1106
+ #~ msgid "Order ID"
1107
+ #~ msgstr "Order ID"
1108
+
1109
+ #~ msgid "API KEY"
1110
+ #~ msgstr "API KEY"
1111
+
1112
+ #~ msgid "Validate License"
1113
+ #~ msgstr "Validate License"
1114
+
1115
+ #~ msgid "This field shows your Installed Product"
1116
+ #~ msgstr "This field shows your Installed Product"
1117
+
1118
+ #~ msgid "This field shows your Installed Product Version"
1119
+ #~ msgstr "This field shows your Installed Product Version"
1120
+
1121
+ #~ msgid "This field shows your Website URL"
1122
+ #~ msgstr "This field shows your Website URL"
1123
+
1124
+ #~ msgid ""
1125
+ #~ "Please provide your Order ID which you have received after purchasing "
1126
+ #~ "the Product. This will be used for Validating the License"
1127
+ #~ msgstr ""
1128
+ #~ "Please provide your Order ID which you have received after purchasing the "
1129
+ #~ "Product. This will be used for Validating the License"
1130
+
1131
+ #~ msgid ""
1132
+ #~ "Please provide your API Key which you have received after purchasing the "
1133
+ #~ "Product. This will be used for Validating the License"
1134
+ #~ msgstr ""
1135
+ #~ "Please provide your API Key which you have received after purchasing the "
1136
+ #~ "Product. This will be used for Validating the License"
1137
+
1138
+ #~ msgid "Please provide Order ID received after making the purchase"
1139
+ #~ msgstr "Please provide Order ID received after making the purchase"
1140
+
1141
+ #~ msgid "Please provide API Key received after making the purchase"
1142
+ #~ msgstr "Please provide API Key received after making the purchase"
1143
+
1144
+ #~ msgid ""
1145
+ #~ "Please provide your Order ID which you have received after purchasing the "
1146
+ #~ "Product. This will be used for Validating the License"
1147
+ #~ msgstr ""
1148
+ #~ "Please provide your Order ID which you have received after purchasing the "
1149
+ #~ "Product. This will be used for Validation the License"
1150
+
1151
+ #~ msgid ""
1152
+ #~ "The following php extensions are not found on your server or are "
1153
+ #~ "currently disabled. These might create few problems in configuring Mail "
1154
+ #~ "Booster. Please contact your WebHost to setup these extensions on your "
1155
+ #~ "server."
1156
+ #~ msgstr ""
1157
+ #~ "The following php extensions are not found on your server or are "
1158
+ #~ "currently disabled. These might create a few problems in configuring Mail "
1159
+ #~ "Booster. Please contact your WebHost to setup these extensions on your "
1160
+ #~ "server."
1161
+
1162
+ #~ msgid "Only users with these capabilities can access Mail Booster"
1163
+ #~ msgstr "Only users with these capabilities can access Mail Booster"
1164
+
1165
+ #~ msgid ""
1166
+ #~ " & help us, we will reward you with a free Personal Edition License of "
1167
+ #~ "Mail Booster. If Interested, Kindly click "
1168
+ #~ msgstr ""
1169
+ #~ "& help us, we will reward you with a free Personal Edition License of "
1170
+ #~ "Mail Booster. If interested, Kindy click"
1171
+
1172
+ #~ msgid "* For Mail Booster Demos, click "
1173
+ #~ msgstr "* For Mail Booster Demos, click"
1174
+
1175
+ #~ msgid "* For Mail Booster User Guide for this page, click "
1176
+ #~ msgstr "* For Mail Booster User Guide for this page, click"
1177
+
1178
+ #~ msgid " Features available in Business and Developer Editions :"
1179
+ #~ msgstr "Features available in Business and Developer Editions :"
1180
+
1181
+ #~ msgid ""
1182
+ #~ "This feature is only available in Business and Developer Editions! <br> "
1183
+ #~ "Kindly Purchase to unlock it!"
1184
+ #~ msgstr ""
1185
+ #~ "This feature is only available in Business and Developer Editions! Kindly "
1186
+ #~ "purchase to unlock it!"
1187
+
1188
+ #~ msgid "* Bulk Delete "
1189
+ #~ msgstr "* Bulk Delete"
1190
+
1191
+ #~ msgid "* Debugging Output "
1192
+ #~ msgstr "* Debugging Output"
languages/wp-mail-bank-ro_RO.mo ADDED
Binary file
languages/wp-mail-bank-ro_RO.po ADDED
@@ -0,0 +1,1117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Mail Bank\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2016-11-01 16:33+0530\n"
6
+ "PO-Revision-Date: 2016-11-01 16:35+0530\n"
7
+ "Last-Translator: Tech Banker\n"
8
+ "Language-Team: Romanian (Romania)\n"
9
+ "Language: ro_RO\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=3; plural=(n==1 ? 0 :(((n%100>19)||(( n%100==0)&&(n!"
14
+ "=0)))? 2 : 1));\n"
15
+ "X-Generator: Poedit 1.8.9\n"
16
+ "X-Loco-Source-Locale: en-US\n"
17
+ "X-Loco-Project-Id: 18545\n"
18
+ "X-Loco-Api-Version: 1.0.15 20161010-2\n"
19
+ "X-Poedit-KeywordsList: __\n"
20
+ "X-Poedit-Basepath: ..\n"
21
+ "X-Poedit-SearchPath-0: .\n"
22
+
23
+ #: includes/translations.php:193
24
+ msgid "If you would like to translate in "
25
+ msgstr "Dacă doreşti să traduci în limba"
26
+
27
+ #: includes/translations.php:194
28
+ msgid ""
29
+ " & help us, we will reward you with a free Personal Edition License of Mail "
30
+ "Bank. If Interested, Kindly click "
31
+ msgstr ""
32
+ "& poţi ajuta, noi te vom răsplăti cu o licenţă Personală gratuită a "
33
+ "modulului Mail Bank. Dacă eşti interesat, click"
34
+
35
+ #: includes/translations.php:196
36
+ msgid "here"
37
+ msgstr "aici"
38
+
39
+ #: includes/translations.php:204
40
+ msgid "Are you sure you want to close without sending Translation Request?"
41
+ msgstr "Eşti sigur că vrei să închizi fără să trimiţi cererea de traducere?"
42
+
43
+ #: includes/translations.php:205
44
+ msgid "Translation Request"
45
+ msgstr "Cerere de traducere"
46
+
47
+ #: includes/translations.php:206
48
+ msgid "Language Interested to Translate"
49
+ msgstr "Limba în care eşti interesat să traduci"
50
+
51
+ #: includes/translations.php:207
52
+ msgid "Please choose a language which you want to translate"
53
+ msgstr "Te rugăm să alegi o limbă"
54
+
55
+ #: includes/translations.php:208
56
+ msgid "Please provide a language"
57
+ msgstr "Alege limba"
58
+
59
+ #: includes/translations.php:209
60
+ msgid "Query"
61
+ msgstr "Cerere"
62
+
63
+ #: includes/translations.php:210 includes/translations.php:211
64
+ msgid "Please provide your query"
65
+ msgstr "Introdu cererea"
66
+
67
+ #: includes/translations.php:212 includes/translations.php:428
68
+ msgid "Please provide your Name"
69
+ msgstr "Te rugăm să introduci numele"
70
+
71
+ #: includes/translations.php:213
72
+ msgid "Please provide your Email"
73
+ msgstr "Introdu adresa de Email"
74
+
75
+ #: includes/translations.php:214 includes/translations.php:375
76
+ msgid "Close"
77
+ msgstr "Închide"
78
+
79
+ #: includes/translations.php:215
80
+ msgid "Send Request"
81
+ msgstr "Trimite cererea"
82
+
83
+ #: includes/translations.php:218
84
+ msgid ""
85
+ "This feature is available only in Premium Editions! <br> Kindly Purchase to "
86
+ "unlock it!"
87
+ msgstr ""
88
+ "Această facilitate este disponibilă doar în Ediţiile Premium! <br> Te rugăm "
89
+ "să le achiziţionezi."
90
+
91
+ #: includes/translations.php:219
92
+ msgid "* Click "
93
+ msgstr "* Click"
94
+
95
+ #: includes/translations.php:220
96
+ msgid "here "
97
+ msgstr "aici"
98
+
99
+ #: includes/translations.php:221
100
+ msgid " to see Premium Edition Features in detail"
101
+ msgstr "pentru a vedea detaliile Ediţiei Premium"
102
+
103
+ #: includes/translations.php:222
104
+ msgid "* For Mail Bank Demos, click "
105
+ msgstr "* Pentru demonstraţii ale modulului Mail Bank, click"
106
+
107
+ #: includes/translations.php:223
108
+ msgid "* For Mail Bank User Guide for this page, click "
109
+ msgstr "* Pentru ghidul utilizatorului, click"
110
+
111
+ #: includes/translations.php:224 includes/translations.php:266
112
+ msgid "Important Disclaimer!"
113
+ msgstr "Disclaimer important!"
114
+
115
+ #: includes/translations.php:225 includes/translations.php:254
116
+ msgid "Your request email has been sent Successfully"
117
+ msgstr "Mesajul cu cererea ta a fost transmis"
118
+
119
+ #: includes/translations.php:226
120
+ msgid "* Filters "
121
+ msgstr "* Filtre"
122
+
123
+ #: includes/translations.php:227
124
+ msgid "* Reply to, Cc and Bcc Fields "
125
+ msgstr "* Câmpurile Răspunde la, Cc şi Bcc"
126
+
127
+ #: includes/translations.php:228
128
+ msgid "* Deleting Email Logs "
129
+ msgstr "* Ştergerea jurnalelor de email"
130
+
131
+ #: includes/translations.php:229
132
+ msgid "* Debugging Output"
133
+ msgstr "* Mesajele depanării"
134
+
135
+ #: includes/translations.php:230
136
+ msgid "* Email Logs Details "
137
+ msgstr "* Detalii ale jurnalelor de email"
138
+
139
+ #: includes/translations.php:231
140
+ msgid "* Saving Roles & Capabilities "
141
+ msgstr "* Salvare Roluri & Capabilităţi"
142
+
143
+ #: includes/translations.php:232
144
+ msgid " Premium Edition Features :"
145
+ msgstr "Facilităţi ale Ediţiei Premium :"
146
+
147
+ #: includes/translations.php:235
148
+ msgid "Basic Info"
149
+ msgstr "Informaţii de bază"
150
+
151
+ #: includes/translations.php:236
152
+ msgid "Account Setup"
153
+ msgstr "Setarea contului"
154
+
155
+ #: includes/translations.php:237
156
+ msgid "Confirm"
157
+ msgstr "Confirmă"
158
+
159
+ #: includes/translations.php:240
160
+ msgid "Mail Bank"
161
+ msgstr "Mail Bank"
162
+
163
+ #: includes/translations.php:241
164
+ msgid "Email Setup"
165
+ msgstr "Setări email"
166
+
167
+ #: includes/translations.php:242
168
+ msgid "Email Logs"
169
+ msgstr "Jurnale de email"
170
+
171
+ #: includes/translations.php:243
172
+ msgid "Email Log Details"
173
+ msgstr "Detaliile jurnalelor de email"
174
+
175
+ #: includes/translations.php:244 includes/translations.php:288
176
+ msgid "Test Email"
177
+ msgstr "Email de test"
178
+
179
+ #: includes/translations.php:245
180
+ msgid "Plugin Settings"
181
+ msgstr "Setările modulului"
182
+
183
+ #: includes/translations.php:246
184
+ msgid "Feedbacks"
185
+ msgstr "Feedback"
186
+
187
+ #: includes/translations.php:247
188
+ msgid "Roles & Capabilities"
189
+ msgstr "Roluri şi Capabilităţi"
190
+
191
+ #: includes/translations.php:248
192
+ msgid "System Information"
193
+ msgstr "Informaţii de sistem"
194
+
195
+ #: includes/translations.php:251
196
+ msgid "Success!"
197
+ msgstr "Succes!"
198
+
199
+ #: includes/translations.php:252
200
+ msgid "Email Setup has been updated Successfully"
201
+ msgstr "Setările de email au fost actualizate"
202
+
203
+ #: includes/translations.php:253
204
+ msgid "Your Feedback has been sent Successfully"
205
+ msgstr "Feedback-ul tău a fost trimis"
206
+
207
+ #: includes/translations.php:255
208
+ msgid "Test Email was sent Successfully!"
209
+ msgstr "Email-ul de test a fost trimis!"
210
+
211
+ #: includes/translations.php:256
212
+ msgid "Test Email was not sent!"
213
+ msgstr "Email-ul de test NU a fost trimis!"
214
+
215
+ #: includes/translations.php:257
216
+ msgid "Plugin Settings have been updated Successfully"
217
+ msgstr "Setările modulului au fost actualizate"
218
+
219
+ #: includes/translations.php:258
220
+ msgid "Please choose an Action from Dropdown!"
221
+ msgstr "Te rugăm să alegi o acţiune din listă!"
222
+
223
+ #: includes/translations.php:259
224
+ msgid ""
225
+ "The OAuth is not supported by providing SMTP Host, kindly provide username "
226
+ "and password"
227
+ msgstr ""
228
+ "Sistemul OAuth nu suportă Host SMTP, te rugăm să introduci numele de "
229
+ "utilizator şi parola"
230
+
231
+ #: includes/translations.php:260
232
+ msgid "Invalid Secret Key. Please rectify and try again!"
233
+ msgstr "Cheie secretă invalidă. Rectifică şi încearcă din nou!"
234
+
235
+ #: includes/translations.php:261
236
+ msgid "Premium Editions"
237
+ msgstr "Edițiile Premium"
238
+
239
+ #: includes/translations.php:264
240
+ msgid "Sent"
241
+ msgstr "Trimis"
242
+
243
+ #: includes/translations.php:265
244
+ msgid "Not Sent"
245
+ msgstr "Ne-trimis"
246
+
247
+ #: includes/translations.php:267
248
+ msgid ""
249
+ "You don't have Sufficient Access to this Page. Kindly contact the "
250
+ "Administrator for more Privileges"
251
+ msgstr ""
252
+ "Nu ai acces la această pagină. Contactează administratorul pentru privilegii."
253
+
254
+ #: includes/translations.php:268
255
+ msgid "Enable"
256
+ msgstr "Activează"
257
+
258
+ #: includes/translations.php:269
259
+ msgid "Disable"
260
+ msgstr "Dezactivează"
261
+
262
+ #: includes/translations.php:270
263
+ msgid "Override"
264
+ msgstr "Suprascrie"
265
+
266
+ #: includes/translations.php:271
267
+ msgid "Don't Override"
268
+ msgstr "Nu suprascrie"
269
+
270
+ #: includes/translations.php:272
271
+ msgid "Save Settings"
272
+ msgstr "Salvează setările"
273
+
274
+ #: includes/translations.php:273
275
+ msgid "Subject"
276
+ msgstr "Subiect"
277
+
278
+ #: includes/translations.php:274
279
+ msgid "Next Step"
280
+ msgstr "Pasul următor"
281
+
282
+ #: includes/translations.php:275
283
+ msgid "Previous Step"
284
+ msgstr "Pasul anterior"
285
+
286
+ #: includes/translations.php:276
287
+ msgid "Settings"
288
+ msgstr "Setări"
289
+
290
+ #: includes/translations.php:277
291
+ msgid "Not available"
292
+ msgstr "Indisponibil"
293
+
294
+ #: includes/translations.php:278
295
+ msgid ""
296
+ "The following php extensions are not found on your server or are currently "
297
+ "disabled. These might create few problems in configuring Mail Bank. Please "
298
+ "contact your WebHost to setup these extensions on your server."
299
+ msgstr ""
300
+ "Următoarele extensii php nu se găsesc pe server sau sunt dezactivate. "
301
+ "Acestea pot crea probleme de configurare în modulul Mail Bank. Te rugăm să "
302
+ "contactezi administratorul serverului de găzduire pentru remediere."
303
+
304
+ #: includes/translations.php:281
305
+ msgid "Cc"
306
+ msgstr "Cc"
307
+
308
+ #: includes/translations.php:282
309
+ msgid "Bcc"
310
+ msgstr "Bcc"
311
+
312
+ #: includes/translations.php:283
313
+ msgid "Please provide valid Cc Email Address"
314
+ msgstr "Scrie o adresă de email validă pentru câmpul Cc"
315
+
316
+ #: includes/translations.php:284
317
+ msgid "Please provide valid Bcc Email Address"
318
+ msgstr "Scrie o adresă de email validă pentru câmpul BCc"
319
+
320
+ #: includes/translations.php:285
321
+ msgid "Please provide Cc Email"
322
+ msgstr "Scrie adresa de email în câmpul Cc"
323
+
324
+ #: includes/translations.php:286
325
+ msgid "Please provide Bcc Email"
326
+ msgstr "Scrie adresa de email în câmpul BCc"
327
+
328
+ #: includes/translations.php:287
329
+ msgid "Mailer Settings"
330
+ msgstr "Setări Mailer"
331
+
332
+ #: includes/translations.php:289
333
+ msgid "From Name"
334
+ msgstr "De la (nume)"
335
+
336
+ #: includes/translations.php:290
337
+ msgid ""
338
+ "From Name is the inbox field that tells your recipient who sent the "
339
+ "messages. If you would like to override the pre-configured From Name, then "
340
+ "you would need to insert the name in the inbox field"
341
+ msgstr ""
342
+ "De la (nume) este câmpul care îi spune recipientului cine i-a trimis "
343
+ "mesajul. Dacă doreşti să suprascrii valorile implicite, atunci va trebui să "
344
+ "introduci un nume în câmpul respectiv."
345
+
346
+ #: includes/translations.php:291
347
+ msgid "Please provide From Name"
348
+ msgstr "Te rugăm să introduci numele"
349
+
350
+ #: includes/translations.php:292
351
+ msgid "From Email"
352
+ msgstr "De la (email)"
353
+
354
+ #: includes/translations.php:293
355
+ msgid ""
356
+ "From Email is the inbox field that tells your recipient from which Email "
357
+ "Address the messages are coming. If you would like to override the pre-"
358
+ "configured From Email, then you would need to insert an Email Address in the "
359
+ "inbox field"
360
+ msgstr ""
361
+ "De la (email) este câmpul care îi spune recipientului de la ce adresă de "
362
+ "email a primit mesajul. Dacă doreşti să suprascrii valorile implicite, "
363
+ "atunci va trebui să introduci o adresă de email în câmpul respectiv."
364
+
365
+ #: includes/translations.php:294
366
+ msgid "Please provide From Email Address"
367
+ msgstr "Te rugăm să introduci adresa de email"
368
+
369
+ #: includes/translations.php:295
370
+ msgid "Mailer Type"
371
+ msgstr "Tipul Mailer-ului"
372
+
373
+ #: includes/translations.php:296
374
+ msgid ""
375
+ "This field provides you an ability to choose a specific option for Mailer "
376
+ "Type. If you would like to send an Email via SMTP mailer, you would need to "
377
+ "select Send Email via SMTP from the drop down or you could use PHP mail () "
378
+ "Function"
379
+ msgstr ""
380
+ "Aici poţi alege o opţiune specifică pentru tipul mailer-ului. Dacă vrei să "
381
+ "trimiţi email-uri prin intermediul SMTP, atunci selectează opţiunea "
382
+ "corespunzătoare din listă, sau poţi alege să trimiţi mesaje cu ajutorul "
383
+ "funcţiei php mail."
384
+
385
+ #: includes/translations.php:297
386
+ msgid "Send Email via SMTP"
387
+ msgstr "Trimite email prin SMTP"
388
+
389
+ #: includes/translations.php:298
390
+ msgid "Use The PHP mail() Function"
391
+ msgstr "Foloseşte funcţia PHP mail"
392
+
393
+ #: includes/translations.php:299
394
+ msgid "SMTP Host"
395
+ msgstr "Gazda SMTP"
396
+
397
+ #: includes/translations.php:300
398
+ msgid ""
399
+ "If you would like to send an Email via different host, you would need to "
400
+ "insert that specific host name like smtp.gmail.com in the inbox field"
401
+ msgstr ""
402
+ "Dacă vei trimite email-uri folosind altă gazdă, trebuie să introduci numele "
403
+ "specific al gazdei în câmpul Inbox, ca de exemplu smtp.gmail.com"
404
+
405
+ #: includes/translations.php:301
406
+ msgid "Please provide SMTP Host"
407
+ msgstr "Introdu Gazda SMTP"
408
+
409
+ #: includes/translations.php:302
410
+ msgid "SMTP Port"
411
+ msgstr "Port SMTP"
412
+
413
+ #: includes/translations.php:303
414
+ msgid ""
415
+ "This inbox field is specified to provide a valid SMTP Port for authentication"
416
+ msgstr ""
417
+ "Acest câmp de inbox este folosit pentru a furniza o autentificare validă SMTP"
418
+
419
+ #: includes/translations.php:304
420
+ msgid "Please provide SMTP Port"
421
+ msgstr "Introdu Portul SMTP"
422
+
423
+ #: includes/translations.php:305
424
+ msgid "Encryption"
425
+ msgstr "Criptare"
426
+
427
+ #: includes/translations.php:306
428
+ msgid ""
429
+ "It provides you an ability to choose a specific option for Encryption. If "
430
+ "you would like to send an Email with TLS encryption, you would need to "
431
+ "select Use TLS Encryption from the drop down or you could use SSL "
432
+ "Encryption. For that you would need to select Use SSL Encryption from the "
433
+ "drop down. If you would like to send an Email without encryption, you would "
434
+ "need to select No Encryption from the drop down"
435
+ msgstr ""
436
+ "Aici poţi alege o opţiune specifică pentru criptare. Din listă ai "
437
+ "următoarele opţiuni: Criptare TLS sau Criptare SSL, sau poţi selecta "
438
+ "opţiunea Fără criptare ca să trimiţi email-uri necriptate."
439
+
440
+ #: includes/translations.php:307
441
+ msgid "No Encryption"
442
+ msgstr "Fără criptare"
443
+
444
+ #: includes/translations.php:308
445
+ msgid "Use SSL Encryption"
446
+ msgstr "Criptare SSL"
447
+
448
+ #: includes/translations.php:309
449
+ msgid "Use TLS Encryption"
450
+ msgstr "Criptare TLS"
451
+
452
+ #: includes/translations.php:310
453
+ msgid "Authentication"
454
+ msgstr "Autentificare"
455
+
456
+ #: includes/translations.php:311
457
+ msgid ""
458
+ "This inbox field allows you to choose an appropriate option for "
459
+ "authentication. It provides you the Two-way authentication factor; If you "
460
+ "would like to authenticate yourself via Username and Password, you would "
461
+ "need to select Use Username and Password from the drop down. You can also "
462
+ "authenticate by an OAuth 2.0 protocol, which requires Client Id and Secret "
463
+ "Key, for that you would need to select Use OAuth (Client ID and Secret Key) "
464
+ "from the drop down. You can easily get Client Id and Secret Key from "
465
+ "respective SMTP Server Developers section"
466
+ msgstr ""
467
+ "Acest câmp este folosit pentru a alege o opţiune corespunzătoare de "
468
+ "autentificare. Poţi alege autentificarea Two-way şi atunci va fi necesară "
469
+ "introducerea de nume de utilizator şi parolă. Te poţi de asemenea "
470
+ "autentifica prin protocolul OAuth 2.0, care necesită Client ID şi Secret "
471
+ "Key, pe care le poţi obţine uşor de la Serverul SMTP, în secţiunea pentru "
472
+ "dezvoltatori."
473
+
474
+ #: includes/translations.php:312
475
+ msgid "Use SMTP Authentication"
476
+ msgstr "Autentificare SMTP"
477
+
478
+ #: includes/translations.php:313
479
+ msgid "Don't Use SMTP Authentication"
480
+ msgstr "Fără autentificare"
481
+
482
+ #: includes/translations.php:314
483
+ msgid "Test Email Address"
484
+ msgstr "Adresa de email pentru test"
485
+
486
+ #: includes/translations.php:315
487
+ msgid ""
488
+ "In this field, you would need to provide a valid Email Address in the inbox "
489
+ "field on which you would like to receive Test email"
490
+ msgstr ""
491
+ "În acest câmp trebuie să furnizezi o adresă de email validă pe care doreşti "
492
+ "să primeşti mesajul de test"
493
+
494
+ #: includes/translations.php:316
495
+ msgid "Please provide Test Email Address"
496
+ msgstr "Te rugăm să introduci adresa de email pentru test"
497
+
498
+ #: includes/translations.php:317
499
+ msgid "In this field, you would need to provide a subject for Test Email"
500
+ msgstr "Aici trebuie să scrii subiectul email-ului de test"
501
+
502
+ #: includes/translations.php:318
503
+ msgid "Please provide Subject"
504
+ msgstr "Te rugăm să introduci subiectul"
505
+
506
+ #: includes/translations.php:319
507
+ msgid "Email Content"
508
+ msgstr "Conţinutul email-ului"
509
+
510
+ #: includes/translations.php:320
511
+ msgid "In this field, you would need to provide the content for Test Email"
512
+ msgstr "Aici trebuie să scrii conţinutul email-ului de test"
513
+
514
+ #: includes/translations.php:321
515
+ msgid "Send Test Email"
516
+ msgstr "Trimite email-ul de test"
517
+
518
+ #: includes/translations.php:322
519
+ msgid "SMTP Debugging Output"
520
+ msgstr "Depanare SMTP"
521
+
522
+ #: includes/translations.php:323
523
+ msgid "Checking your settings"
524
+ msgstr "Se verifică setările"
525
+
526
+ #: includes/translations.php:324
527
+ msgid "Result"
528
+ msgstr "Rezultat"
529
+
530
+ #: includes/translations.php:325
531
+ msgid "Send Another Test Email"
532
+ msgstr "Trimite alt email de test"
533
+
534
+ #: includes/translations.php:326
535
+ msgid "From Name Configuration"
536
+ msgstr "Se trimite email de la (nume)"
537
+
538
+ #: includes/translations.php:327
539
+ msgid ""
540
+ "If you would like to override the pre-configured name which will be used "
541
+ "while sending Emails, then you would need to choose Override from the drop "
542
+ "down and vice-versa"
543
+ msgstr ""
544
+ "Dacă se doreşte introducerea altui nume decât cel preconfigurat atunci când "
545
+ "se trimit email-uri, atunci se alege opţiunea specifică din listă."
546
+
547
+ #: includes/translations.php:328
548
+ msgid "From Email Configuration"
549
+ msgstr "Se trimite email de la (email)"
550
+
551
+ #: includes/translations.php:329
552
+ msgid ""
553
+ "If you would like to override your pre-configured Email Address which will "
554
+ "be used while sending Emails, then you would need to choose Override from "
555
+ "the drop down and vice-versa"
556
+ msgstr ""
557
+ "Dacă se doreşte introducerea altei adrese de email decât cea preconfigurată "
558
+ "atunci când se trimit email-uri, atunci se alege opţiunea specifică din "
559
+ "listă."
560
+
561
+ #: includes/translations.php:330
562
+ msgid "Username"
563
+ msgstr "Nume de utilizator"
564
+
565
+ #: includes/translations.php:331
566
+ msgid ""
567
+ "In this field, you would need to provide a username to authenticate your "
568
+ "SMTP details"
569
+ msgstr ""
570
+ "Aici trebuie să introduci un nume de utilizator pentru autentificarea SMTP"
571
+
572
+ #: includes/translations.php:332
573
+ msgid "Please provide username"
574
+ msgstr "Te rugăm să introduci numele de utilizator"
575
+
576
+ #: includes/translations.php:333
577
+ msgid "Password"
578
+ msgstr "Parola"
579
+
580
+ #: includes/translations.php:334
581
+ msgid ""
582
+ "In this field, you would need to provide a password to authenticate your "
583
+ "SMTP details"
584
+ msgstr "Aici trebuie să introduci parola pentru autentificarea SMTP"
585
+
586
+ #: includes/translations.php:335
587
+ msgid "Please provide password"
588
+ msgstr "Te rugăm să introduci parola"
589
+
590
+ #: includes/translations.php:336
591
+ msgid "Redirect URI"
592
+ msgstr "Adresa URI pentru redirijare"
593
+
594
+ #: includes/translations.php:337
595
+ msgid ""
596
+ "Please copy this Redirect URI and Paste into Redirect URI field when "
597
+ "creating your app"
598
+ msgstr ""
599
+ "Copiază adresa de redirijare URI în caseta de redirijare atunci când creezi "
600
+ "o aplicaţie"
601
+
602
+ #: includes/translations.php:338
603
+ msgid "Use OAuth (Client Id and Secret Key required)"
604
+ msgstr "Foloseşte OAuth (Client ID şi Secret Key sunt necesare)"
605
+
606
+ #: includes/translations.php:339
607
+ msgid "Plain Authentication"
608
+ msgstr "Autentificare simplă"
609
+
610
+ #: includes/translations.php:340
611
+ msgid "Cram-MD5"
612
+ msgstr "Cram-MD5"
613
+
614
+ #: includes/translations.php:341
615
+ msgid "Login"
616
+ msgstr "Login"
617
+
618
+ #: includes/translations.php:342
619
+ msgid "Client Id"
620
+ msgstr "Client ID"
621
+
622
+ #: includes/translations.php:343
623
+ msgid "Secret Key"
624
+ msgstr "Secret Key"
625
+
626
+ #: includes/translations.php:344
627
+ msgid "Please provide valid Client Id issued by your SMTP Host"
628
+ msgstr "Te rugăm să introduci un id client valid furnizat de gazda ta SMTP"
629
+
630
+ #: includes/translations.php:345
631
+ msgid "Please provide valid Secret Key issued by your SMTP Host"
632
+ msgstr ""
633
+ "Te rugăm să introduci o cheie secretă validă furnizată de gazda ta SMTP"
634
+
635
+ #: includes/translations.php:346
636
+ msgid "Please provide Client Id"
637
+ msgstr "Te rugăm să introduci ID-ul de Client"
638
+
639
+ #: includes/translations.php:347
640
+ msgid "Please provide Secret Key"
641
+ msgstr "Te rugăm să introduci cheia secretă"
642
+
643
+ #: includes/translations.php:348
644
+ msgid ""
645
+ "Yes, automatically send a Test Email upon clicking on the Next Step Button "
646
+ "to verify settings"
647
+ msgstr ""
648
+ "Da, trimite automat un email de test atunci când mergi la pasul următor "
649
+ "pentru verificarea setărilor"
650
+
651
+ #: includes/translations.php:349
652
+ msgid "Email Address"
653
+ msgstr "Adresa de email"
654
+
655
+ #: includes/translations.php:350
656
+ msgid ""
657
+ "In this field, you would need to add a valid Email Address in the inbox "
658
+ "field from which you would like to send Emails"
659
+ msgstr ""
660
+ "Aici trebuie să introduci o adresă de email validă de la care doreşti să "
661
+ "trimiţi email-urile"
662
+
663
+ #: includes/translations.php:351
664
+ msgid "Please provide valid Email Address"
665
+ msgstr "Te rugăm să introduci o adresă de email validă"
666
+
667
+ #: includes/translations.php:352
668
+ msgid "Reply To"
669
+ msgstr "Răspunde la"
670
+
671
+ #: includes/translations.php:353
672
+ msgid ""
673
+ "In this field, you would need to add a valid Email Address that is "
674
+ "automatically inserted into the Reply To field when a user replies to an "
675
+ "email message"
676
+ msgstr ""
677
+ "Aici trebuie să adaugi o adresă de email validă care va fi automat inserată "
678
+ "în câmpul \"Răspunde la\" atunci când un utilizator doreşte să răspundă la "
679
+ "mesajul tău"
680
+
681
+ #: includes/translations.php:354
682
+ msgid "Please provide Reply To Email Address"
683
+ msgstr "Te rugăm să introduci adresa de email la care să se răspundă"
684
+
685
+ #: includes/translations.php:355
686
+ msgid "Get Google Client Id and Secret Key"
687
+ msgstr "Primeşte Client ID şi Secret Key de la Google"
688
+
689
+ #: includes/translations.php:356
690
+ msgid "Get Microsoft Client Id and Secret Key"
691
+ msgstr "Primeşte Client ID şi Secret Key de la Microsoft"
692
+
693
+ #: includes/translations.php:357
694
+ msgid "Get Yahoo Client Id and Secret Key"
695
+ msgstr "Primeşte Client ID şi Secret Key de la Yahoo"
696
+
697
+ #: includes/translations.php:360
698
+ msgid "Start Date"
699
+ msgstr "Data de start"
700
+
701
+ #: includes/translations.php:361
702
+ msgid "Please provide Start Date"
703
+ msgstr "Te rugăm să introduci data de start"
704
+
705
+ #: includes/translations.php:362
706
+ msgid "This field shows starting date of Email Logs"
707
+ msgstr "Aici se afişează data de start a jurnalelor de email"
708
+
709
+ #: includes/translations.php:363
710
+ msgid "End Date"
711
+ msgstr "Data de stop"
712
+
713
+ #: includes/translations.php:364
714
+ msgid "Please provide End Date"
715
+ msgstr "Te rugăm să introduci data de stop"
716
+
717
+ #: includes/translations.php:365
718
+ msgid "This field shows ending date of Email Logs"
719
+ msgstr "Aici se afişează data de stop a jurnalelor de email"
720
+
721
+ #: includes/translations.php:366
722
+ msgid "Submit"
723
+ msgstr "Trimite"
724
+
725
+ #: includes/translations.php:367
726
+ msgid "Bulk Action"
727
+ msgstr "Acţiunea de bulk"
728
+
729
+ #: includes/translations.php:368
730
+ msgid "Delete"
731
+ msgstr "Şterge"
732
+
733
+ #: includes/translations.php:369
734
+ msgid "Apply"
735
+ msgstr "Aplică"
736
+
737
+ #: includes/translations.php:370
738
+ msgid "Email To"
739
+ msgstr "Email către"
740
+
741
+ #: includes/translations.php:371
742
+ msgid "Action"
743
+ msgstr "Acţiune"
744
+
745
+ #: includes/translations.php:372
746
+ msgid "Show Details"
747
+ msgstr "Arată detaliile"
748
+
749
+ #: includes/translations.php:373
750
+ msgid "Email Details"
751
+ msgstr "Detaliile email-ului"
752
+
753
+ #: includes/translations.php:374
754
+ msgid "Email Debugging output"
755
+ msgstr "Depanarea email-urilor"
756
+
757
+ #: includes/translations.php:376
758
+ msgid "Debugging Output"
759
+ msgstr "Depanare"
760
+
761
+ #: includes/translations.php:377
762
+ msgid "Show Debugging Output"
763
+ msgstr "Arată datele depanării"
764
+
765
+ #: includes/translations.php:378
766
+ msgid "Email Sent To"
767
+ msgstr "Email trimis către"
768
+
769
+ #: includes/translations.php:379
770
+ msgid "Date/Time"
771
+ msgstr "Data/Ora"
772
+
773
+ #: includes/translations.php:380
774
+ msgid "Status"
775
+ msgstr "Stare"
776
+
777
+ #: includes/translations.php:381
778
+ msgid "From"
779
+ msgstr "De la"
780
+
781
+ #: includes/translations.php:382
782
+ msgid "Back to Email Logs"
783
+ msgstr "Înapoi la jurnalele de email"
784
+
785
+ #: includes/translations.php:385
786
+ msgid "Automatic Plugin Updates"
787
+ msgstr "Actualizare automată a modulului"
788
+
789
+ #: includes/translations.php:386
790
+ msgid ""
791
+ "Please choose a specific option whether to allow Automatic Plugin Updates"
792
+ msgstr "Te rugăm să alegi dacă modulul se va actualiza automat sau nu"
793
+
794
+ #: includes/translations.php:387
795
+ msgid "Debug Mode"
796
+ msgstr "Modul Depanare"
797
+
798
+ #: includes/translations.php:388
799
+ msgid "Please choose a specific option for Debug Mode"
800
+ msgstr "Alege o opţiune specifică depanării"
801
+
802
+ #: includes/translations.php:389
803
+ msgid "Remove Tables at Uninstall"
804
+ msgstr "Şterge tabelele la dezinstalarea modulului"
805
+
806
+ #: includes/translations.php:390
807
+ msgid ""
808
+ "Please choose a specific option whether to allow Remove Tables at Uninstall"
809
+ msgstr "Alege opţiunea dorită cu privire la păstrarea sau ştergerea tabelelor"
810
+
811
+ #: includes/translations.php:391
812
+ msgid "Monitoring Email Logs"
813
+ msgstr "Monitorizează jurnalele de email"
814
+
815
+ #: includes/translations.php:392
816
+ msgid "This field is used to allow Email Logs to monitor or not"
817
+ msgstr ""
818
+ "Acest câmp este folosit pentru a permite monitorizarea jurnalelor de email"
819
+
820
+ #: includes/translations.php:395
821
+ msgid "Show Mail Bank Menu"
822
+ msgstr "Arată Mail Bank în meniul lateral"
823
+
824
+ #: includes/translations.php:396
825
+ msgid "Please choose a specific role who can see Sidebar Menu"
826
+ msgstr ""
827
+ "Alege rolurile specifice care pot vedea meniul Mail Bank în bara laterală"
828
+
829
+ #: includes/translations.php:397
830
+ msgid "Administrator"
831
+ msgstr "Administrator"
832
+
833
+ #: includes/translations.php:398
834
+ msgid "Author"
835
+ msgstr "Autor"
836
+
837
+ #: includes/translations.php:399
838
+ msgid "Editor"
839
+ msgstr "Editor"
840
+
841
+ #: includes/translations.php:400
842
+ msgid "Contributor"
843
+ msgstr "Contribuitor"
844
+
845
+ #: includes/translations.php:401
846
+ msgid "Subscriber"
847
+ msgstr "Abonat"
848
+
849
+ #: includes/translations.php:402
850
+ msgid "Others"
851
+ msgstr "Altele"
852
+
853
+ #: includes/translations.php:403
854
+ msgid "Show Mail Bank Top Bar Menu"
855
+ msgstr "Arată Mail Bank în meniul de sus"
856
+
857
+ #: includes/translations.php:404
858
+ msgid "Please choose a specific option from Mail Bank Top Bar Menu"
859
+ msgstr "Alege o opţiune specifică din meniul Mail Bank de sus"
860
+
861
+ #: includes/translations.php:405
862
+ msgid "An Administrator Role can do the following "
863
+ msgstr "Un rol de Administrator are următoarele permisiuni"
864
+
865
+ #: includes/translations.php:406
866
+ msgid "Please choose specific page available for the Administrator Access"
867
+ msgstr "Alege o pagină dedicată accesului pentru Administrator"
868
+
869
+ #: includes/translations.php:407
870
+ msgid "Full Control"
871
+ msgstr "Control complet"
872
+
873
+ #: includes/translations.php:408
874
+ msgid "An Author Role can do the following "
875
+ msgstr "Un rol de Autor are următoarele permisiuni"
876
+
877
+ #: includes/translations.php:409
878
+ msgid "Please choose specific page available for Author Access"
879
+ msgstr "Alege o pagină dedicată accesului pentru Autor"
880
+
881
+ #: includes/translations.php:410
882
+ msgid "An Editor Role can do the following "
883
+ msgstr "Un rol de Editor are următoarele permisiuni"
884
+
885
+ #: includes/translations.php:411
886
+ msgid "Please choose specific page available for Editor Access"
887
+ msgstr "Alege o pagină dedicată accesului pentru Editor"
888
+
889
+ #: includes/translations.php:412
890
+ msgid "A Contributor Role can do the following "
891
+ msgstr "Un rol de Contribuitor are următoarele permisiuni"
892
+
893
+ #: includes/translations.php:413
894
+ msgid "Please choose specific page available for Contributor Access"
895
+ msgstr "Alege o pagină dedicată accesului pentru Contribuitor"
896
+
897
+ #: includes/translations.php:414
898
+ msgid "Other Roles can do the following "
899
+ msgstr "Un alt rol are următoarele permisiuni"
900
+
901
+ #: includes/translations.php:415
902
+ msgid "Please choose specific page available for Others Role Access"
903
+ msgstr "Alege o pagină dedicată accesului pentru Alte roluri"
904
+
905
+ #: includes/translations.php:416
906
+ msgid "Please tick the appropriate capabilities for security purposes "
907
+ msgstr "Bifează capabilităţile potrivite, din motive de securitate"
908
+
909
+ #: includes/translations.php:417
910
+ msgid "Only users with these capabilities can access Mail Bank"
911
+ msgstr "Doar utilizatorii cu aceste capabilităţi pot accesa Mail Bank"
912
+
913
+ #: includes/translations.php:418
914
+ msgid "A Subscriber Role can do the following"
915
+ msgstr "Un rol de Abonat are următoarele permisiuni"
916
+
917
+ #: includes/translations.php:419
918
+ msgid "Please choose specific page available for Subscriber Access"
919
+ msgstr "Alege o pagină dedicată accesului pentru Abonat"
920
+
921
+ #: includes/translations.php:422
922
+ msgid "Thank You!"
923
+ msgstr "Îţi mulţumim!"
924
+
925
+ #: includes/translations.php:423
926
+ msgid ""
927
+ "Kindly fill in the below form, if you would like to suggest some features "
928
+ "which are not in the Plugin"
929
+ msgstr ""
930
+ "Te rugăm să completezi formularul de mai jos, dacă vrei să sugerezi "
931
+ "îmbunătăţiri ale modulului nostru"
932
+
933
+ #: includes/translations.php:424
934
+ msgid ""
935
+ "If you also have any suggestion/complaint, you can use the same form below"
936
+ msgstr ""
937
+ "Dacă ai probleme sau nemulţumiri, poţi folosi acelaşi formular de mai jos"
938
+
939
+ #: includes/translations.php:425
940
+ msgid "You can also write us on"
941
+ msgstr "Poţi să ne scrii la"
942
+
943
+ #: includes/translations.php:426
944
+ msgid "Your Name"
945
+ msgstr "Numele tău"
946
+
947
+ #: includes/translations.php:427
948
+ msgid "Please provide your Name which will be sent along with your Feedback"
949
+ msgstr ""
950
+ "Te rugăm să scrii numele tău, care va fi transmis împreună cu mesajul tău"
951
+
952
+ #: includes/translations.php:429
953
+ msgid "Your Email"
954
+ msgstr "Adresa ta de email"
955
+
956
+ #: includes/translations.php:430
957
+ msgid ""
958
+ "Please provide your Email Address which will be sent along with your Feedback"
959
+ msgstr ""
960
+ "Te rugăm să scrii adresa ta de email, care va fi transmisă împreună cu "
961
+ "mesajul tău"
962
+
963
+ #: includes/translations.php:431
964
+ msgid "Please provide your Email Address"
965
+ msgstr "Te rugăm să introduci adresa ta de email"
966
+
967
+ #: includes/translations.php:432
968
+ msgid "Please provide your Feedback which will be sent along"
969
+ msgstr "Scrie aici mesajul tău"
970
+
971
+ #: includes/translations.php:433
972
+ msgid "Please provide your Feedback"
973
+ msgstr "Te rugăm să introduci mesajul"
974
+
975
+ #: includes/translations.php:434
976
+ msgid "Send Feedback"
977
+ msgstr "Trimite feedback"
978
+
979
+ #: includes/translations.php:437
980
+ msgid "Sending Test Email to"
981
+ msgstr "Se trimite email-ul de test către"
982
+
983
+ #: includes/translations.php:438
984
+ msgid "Email Status"
985
+ msgstr "Stare email"
986
+
987
+ #~ msgid "Roles & Capabilities have been updated Successfully"
988
+ #~ msgstr "Rolurile şi Capabilităţile au fost actualizate"
989
+
990
+ #~ msgid "Please choose at least 1 record to delete!"
991
+ #~ msgstr "Alege cel puţin o înregistrare pentru a fi ştearsă!"
992
+
993
+ #~ msgid "Are you sure you want to delete Email Logs?"
994
+ #~ msgstr "Eşti sigur că vrei să ştergi jurnalele de email?"
995
+
996
+ #~ msgid "Selected Logs have been deleted Successfully"
997
+ #~ msgstr "Jurnalele selectate au fost şterse"
998
+
999
+ #~ msgid "Are you sure you want to delete Email Log?"
1000
+ #~ msgstr "Eşti sigur că vrei să ştergi jurnalele de email?"
1001
+
1002
+ #~ msgid "Email Log has been deleted Successfully"
1003
+ #~ msgstr "Jurnalele selectate au fost şterse"
1004
+
1005
+ #~ msgid "Licensing"
1006
+ #~ msgstr "Licenţiere"
1007
+
1008
+ #~ msgid "Your License has been activated Successfully"
1009
+ #~ msgstr "Licenţa a fost activată"
1010
+
1011
+ #~ msgid "Important Notice!"
1012
+ #~ msgstr "Notificare importantă!"
1013
+
1014
+ #~ msgid ""
1015
+ #~ "Congratulations! You have recently purchased Mail Bank Developer Edition "
1016
+ #~ "and now you would need to activate the license in order to unlock it!"
1017
+ #~ msgstr ""
1018
+ #~ "Felicitări! Ai achiziţionat Ediţia Developer a modulului Mail Bank, iar "
1019
+ #~ "acum trebuie să activezi licenţa pentru a debloca modulul."
1020
+
1021
+ #~ msgid ""
1022
+ #~ "Kindly fill in the required details and click on Validate License to "
1023
+ #~ "unlock it"
1024
+ #~ msgstr ""
1025
+ #~ "Completează detaliile necesare şi apoi fă clic pe Validare Licenţă pentru "
1026
+ #~ "deblocare"
1027
+
1028
+ #~ msgid ""
1029
+ #~ "If you face any issues activating the license, you may contact us at "
1030
+ #~ msgstr "Dacă întâmpini probleme, ne poţi contacta la"
1031
+
1032
+ #~ msgid "Product Name"
1033
+ #~ msgstr "Numele Produsului"
1034
+
1035
+ #~ msgid "Current Version"
1036
+ #~ msgstr "Versiunea Curentă"
1037
+
1038
+ #~ msgid "Website URL"
1039
+ #~ msgstr "URL Website"
1040
+
1041
+ #~ msgid "Order ID"
1042
+ #~ msgstr "ID comandă"
1043
+
1044
+ #~ msgid "API KEY"
1045
+ #~ msgstr "Cheia API"
1046
+
1047
+ #~ msgid "Validate License"
1048
+ #~ msgstr "Validare Licenţă"
1049
+
1050
+ #~ msgid "This field shows your Installed Product"
1051
+ #~ msgstr "Aici se afişează Produsul instalat"
1052
+
1053
+ #~ msgid "This field shows your Installed Product Version"
1054
+ #~ msgstr "Aici se afişează versiunea Produsului instalat"
1055
+
1056
+ #~ msgid "This field shows your Website URL"
1057
+ #~ msgstr "Aici este adresa website-ului tău"
1058
+
1059
+ #~ msgid ""
1060
+ #~ "Please provide your Order ID which you have received after purchasing "
1061
+ #~ "the Product. This will be used for Validating the License"
1062
+ #~ msgstr ""
1063
+ #~ "Te rugăm să furnizezi Order ID pe care l-ai primit după ce ai "
1064
+ #~ "achiziţionat produsul. Acesta este folosit pentru a valida licenţa"
1065
+
1066
+ #~ msgid ""
1067
+ #~ "Please provide your API Key which you have received after purchasing the "
1068
+ #~ "Product. This will be used for Validating the License"
1069
+ #~ msgstr ""
1070
+ #~ "Te rugăm să furnizezi API Key pe care ai primit-o după ce ai achiziţionat "
1071
+ #~ "produsul. Aceasta este folosită pentru a valida licenţa"
1072
+
1073
+ #~ msgid "Please provide Order ID received after making the purchase"
1074
+ #~ msgstr ""
1075
+ #~ "Te rugăm să furnizezi Order ID pe care l-ai primit după ce ai "
1076
+ #~ "achiziţionat produsul"
1077
+
1078
+ #~ msgid "Please provide API Key received after making the purchase"
1079
+ #~ msgstr ""
1080
+ #~ "Te rugăm să furnizezi API Key pe care ai primit-o după ce ai achiziţionat "
1081
+ #~ "produsul"
1082
+
1083
+ #~ msgid ""
1084
+ #~ "Congratulations! You have recently purchased Mail Bank Personal Edition "
1085
+ #~ "and now you would need to activate the license in order to unlock it!"
1086
+ #~ msgstr ""
1087
+ #~ "Felicitări! Ai achiziţionat Ediţia Personal a modulului Mail Bank, iar "
1088
+ #~ "acum trebuie să activezi licenţa pentru a debloca modulul."
1089
+
1090
+ #~ msgid " Features available in Business and Developer Editions :"
1091
+ #~ msgstr "Facilităţi disponibile în Ediţiile Business şi Dezvoltator :"
1092
+
1093
+ #~ msgid ""
1094
+ #~ "This feature is only available in Business and Developer Editions! <br> "
1095
+ #~ "Kindly Purchase to unlock it!."
1096
+ #~ msgstr ""
1097
+ #~ "Această facilitate este disponibilă doar în Ediţiile Business şi "
1098
+ #~ "Dezvoltator! <br> Te rugăm să le achiziţionezi."
1099
+
1100
+ #~ msgid "* Bulk Delete "
1101
+ #~ msgstr "* Ştergere Bulk"
1102
+
1103
+ #~ msgid "* Debugging Output "
1104
+ #~ msgstr "* Mesajele depanării"
1105
+
1106
+ #~ msgid ""
1107
+ #~ "Congratulations! You have recently purchased Mail Bank Business Edition "
1108
+ #~ "and now you would need to activate the license in order to unlock it!"
1109
+ #~ msgstr ""
1110
+ #~ "Felicitări! Ai achiziţionat Ediţia Business a modulului Mail Bank, iar "
1111
+ #~ "acum trebuie să activezi licenţa pentru a debloca modulul."
1112
+
1113
+ #~ msgid "* Openssl extension not found or disabled"
1114
+ #~ msgstr "* Extensia openssl este inexistentă sau dezactivată"
1115
+
1116
+ #~ msgid "Use Username And Password"
1117
+ #~ msgstr "Foloseşte nume de utilizator şi parolă"
languages/wp-mail-bank-zh_CN.mo ADDED
Binary file
languages/wp-mail-bank-zh_CN.po ADDED
@@ -0,0 +1,1063 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Mail Bank\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2016-11-01 11:55+0530\n"
6
+ "PO-Revision-Date: 2016-11-01 11:58+0530\n"
7
+ "Last-Translator: Tech Banker\n"
8
+ "Language-Team: Chinese (China)\n"
9
+ "Language: zh_CN\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
13
+ "Plural-Forms: nplurals=1; plural=0;\n"
14
+ "X-Generator: Poedit 1.8.9\n"
15
+ "X-Loco-Source-Locale: en-US\n"
16
+ "X-Loco-Project-Id: 18545\n"
17
+ "X-Loco-Api-Version: 1.0.15 20161010-2\n"
18
+ "X-Poedit-KeywordsList: __\n"
19
+ "X-Poedit-Basepath: ..\n"
20
+ "X-Poedit-SearchPath-0: .\n"
21
+
22
+ #: includes/translations.php:193
23
+ msgid "If you would like to translate in "
24
+ msgstr "如果你想翻译"
25
+
26
+ #: includes/translations.php:194
27
+ msgid ""
28
+ " & help us, we will reward you with a free Personal Edition License of Mail "
29
+ "Bank. If Interested, Kindly click "
30
+ msgstr ""
31
+ "帮助我们,我们会免费奖励你一套Mail Bank个人版授权。如果你有兴趣,请点击"
32
+
33
+ #: includes/translations.php:196
34
+ msgid "here"
35
+ msgstr "这里"
36
+
37
+ #: includes/translations.php:204
38
+ msgid "Are you sure you want to close without sending Translation Request?"
39
+ msgstr "你确定关闭而不发送翻译请求?"
40
+
41
+ #: includes/translations.php:205
42
+ msgid "Translation Request"
43
+ msgstr "翻译请求"
44
+
45
+ #: includes/translations.php:206
46
+ msgid "Language Interested to Translate"
47
+ msgstr "翻译感兴趣的语言"
48
+
49
+ #: includes/translations.php:207
50
+ msgid "Please choose a language which you want to translate"
51
+ msgstr "请选择您要翻译的语言"
52
+
53
+ #: includes/translations.php:208
54
+ msgid "Please provide a language"
55
+ msgstr "请提供一种语言"
56
+
57
+ #: includes/translations.php:209
58
+ msgid "Query"
59
+ msgstr "查询"
60
+
61
+ #: includes/translations.php:210 includes/translations.php:211
62
+ msgid "Please provide your query"
63
+ msgstr "请提供你的查询"
64
+
65
+ #: includes/translations.php:212 includes/translations.php:428
66
+ msgid "Please provide your Name"
67
+ msgstr "请提供你的姓名"
68
+
69
+ #: includes/translations.php:213
70
+ msgid "Please provide your Email"
71
+ msgstr "请提供你的Email"
72
+
73
+ #: includes/translations.php:214 includes/translations.php:375
74
+ msgid "Close"
75
+ msgstr "关闭"
76
+
77
+ #: includes/translations.php:215
78
+ msgid "Send Request"
79
+ msgstr "发送请求"
80
+
81
+ #: includes/translations.php:218
82
+ msgid ""
83
+ "This feature is available only in Premium Editions! <br> Kindly Purchase to "
84
+ "unlock it!"
85
+ msgstr "此功能仅在高级版中可用! <br>请购买解锁!"
86
+
87
+ #: includes/translations.php:219
88
+ msgid "* Click "
89
+ msgstr "点击"
90
+
91
+ #: includes/translations.php:220
92
+ msgid "here "
93
+ msgstr "这里"
94
+
95
+ #: includes/translations.php:221
96
+ msgid " to see Premium Edition Features in detail"
97
+ msgstr "查看高级版功能"
98
+
99
+ #: includes/translations.php:222
100
+ msgid "* For Mail Bank Demos, click "
101
+ msgstr "Mail Bank演示,点击查看"
102
+
103
+ #: includes/translations.php:223
104
+ msgid "* For Mail Bank User Guide for this page, click "
105
+ msgstr "Mail Bank用户手册(本页面),点击查看"
106
+
107
+ #: includes/translations.php:224 includes/translations.php:266
108
+ msgid "Important Disclaimer!"
109
+ msgstr "重要免责声明"
110
+
111
+ #: includes/translations.php:225 includes/translations.php:254
112
+ msgid "Your request email has been sent Successfully"
113
+ msgstr "您的请求邮件已经发送成功"
114
+
115
+ #: includes/translations.php:226
116
+ msgid "* Filters "
117
+ msgstr "筛选"
118
+
119
+ #: includes/translations.php:227
120
+ msgid "* Reply to, Cc and Bcc Fields "
121
+ msgstr "回复给,抄送 和 私密发送 字段"
122
+
123
+ #: includes/translations.php:228
124
+ msgid "* Deleting Email Logs "
125
+ msgstr "删除邮件日志"
126
+
127
+ #: includes/translations.php:229
128
+ msgid "* Debugging Output"
129
+ msgstr "调试输出"
130
+
131
+ #: includes/translations.php:230
132
+ msgid "* Email Logs Details "
133
+ msgstr "详细Email日志"
134
+
135
+ #: includes/translations.php:231
136
+ msgid "* Saving Roles & Capabilities "
137
+ msgstr "保存角色和权限"
138
+
139
+ #: includes/translations.php:232
140
+ msgid " Premium Edition Features :"
141
+ msgstr "高级版功能:"
142
+
143
+ #: includes/translations.php:235
144
+ msgid "Basic Info"
145
+ msgstr "基本信息"
146
+
147
+ #: includes/translations.php:236
148
+ msgid "Account Setup"
149
+ msgstr "账户设定"
150
+
151
+ #: includes/translations.php:237
152
+ msgid "Confirm"
153
+ msgstr "确认"
154
+
155
+ #: includes/translations.php:240
156
+ msgid "Mail Bank"
157
+ msgstr "Mail Bank"
158
+
159
+ #: includes/translations.php:241
160
+ msgid "Email Setup"
161
+ msgstr "邮箱向导"
162
+
163
+ #: includes/translations.php:242
164
+ msgid "Email Logs"
165
+ msgstr "邮箱日志"
166
+
167
+ #: includes/translations.php:243
168
+ msgid "Email Log Details"
169
+ msgstr "详细邮箱日志"
170
+
171
+ #: includes/translations.php:244 includes/translations.php:288
172
+ msgid "Test Email"
173
+ msgstr "测试邮箱"
174
+
175
+ #: includes/translations.php:245
176
+ msgid "Plugin Settings"
177
+ msgstr "插件设置"
178
+
179
+ #: includes/translations.php:246
180
+ msgid "Feedbacks"
181
+ msgstr "反馈"
182
+
183
+ #: includes/translations.php:247
184
+ msgid "Roles & Capabilities"
185
+ msgstr "角色和权限"
186
+
187
+ #: includes/translations.php:248
188
+ msgid "System Information"
189
+ msgstr "系统信息"
190
+
191
+ #: includes/translations.php:251
192
+ msgid "Success!"
193
+ msgstr "成功!"
194
+
195
+ #: includes/translations.php:252
196
+ msgid "Email Setup has been updated Successfully"
197
+ msgstr "更新邮箱设置成功"
198
+
199
+ #: includes/translations.php:253
200
+ msgid "Your Feedback has been sent Successfully"
201
+ msgstr "您的反馈已经发送成功"
202
+
203
+ #: includes/translations.php:255
204
+ msgid "Test Email was sent Successfully!"
205
+ msgstr "测试邮件发送成功"
206
+
207
+ #: includes/translations.php:256
208
+ msgid "Test Email was not sent!"
209
+ msgstr "测试邮件为发送"
210
+
211
+ #: includes/translations.php:257
212
+ msgid "Plugin Settings have been updated Successfully"
213
+ msgstr "插件设置已经更新成功"
214
+
215
+ #: includes/translations.php:258
216
+ msgid "Please choose an Action from Dropdown!"
217
+ msgstr "请从下拉列表中选择操作"
218
+
219
+ #: includes/translations.php:259
220
+ msgid ""
221
+ "The OAuth is not supported by providing SMTP Host, kindly provide username "
222
+ "and password"
223
+ msgstr "提供的SMTP主机不支持OAuth验证,请提供用户名和密码"
224
+
225
+ #: includes/translations.php:260
226
+ msgid "Invalid Secret Key. Please rectify and try again!"
227
+ msgstr "密钥无效,请纠正后重试。"
228
+
229
+ #: includes/translations.php:261
230
+ msgid "Premium Editions"
231
+ msgstr "高级版"
232
+
233
+ #: includes/translations.php:264
234
+ msgid "Sent"
235
+ msgstr "发送"
236
+
237
+ #: includes/translations.php:265
238
+ msgid "Not Sent"
239
+ msgstr "未发送"
240
+
241
+ #: includes/translations.php:267
242
+ msgid ""
243
+ "You don't have Sufficient Access to this Page. Kindly contact the "
244
+ "Administrator for more Privileges"
245
+ msgstr "你没有足够权限访问此页面,请联系管理员获取更多权限。"
246
+
247
+ #: includes/translations.php:268
248
+ msgid "Enable"
249
+ msgstr "启用"
250
+
251
+ #: includes/translations.php:269
252
+ msgid "Disable"
253
+ msgstr "禁用"
254
+
255
+ #: includes/translations.php:270
256
+ msgid "Override"
257
+ msgstr "覆盖"
258
+
259
+ #: includes/translations.php:271
260
+ msgid "Don't Override"
261
+ msgstr "不覆盖"
262
+
263
+ #: includes/translations.php:272
264
+ msgid "Save Settings"
265
+ msgstr "保存设置"
266
+
267
+ #: includes/translations.php:273
268
+ msgid "Subject"
269
+ msgstr "主题"
270
+
271
+ #: includes/translations.php:274
272
+ msgid "Next Step"
273
+ msgstr "下一步"
274
+
275
+ #: includes/translations.php:275
276
+ msgid "Previous Step"
277
+ msgstr "上一步"
278
+
279
+ #: includes/translations.php:276
280
+ msgid "Settings"
281
+ msgstr "设置"
282
+
283
+ #: includes/translations.php:277
284
+ msgid "Not available"
285
+ msgstr "不可用"
286
+
287
+ #: includes/translations.php:278
288
+ msgid ""
289
+ "The following php extensions are not found on your server or are currently "
290
+ "disabled. These might create few problems in configuring Mail Bank. Please "
291
+ "contact your WebHost to setup these extensions on your server."
292
+ msgstr ""
293
+ "在您的服务器找不到以下PHP扩展或扩展被禁用,这将会导致MailBank配置过程中出现一"
294
+ "些问题,请联系您的空间提供商安装相关扩展。"
295
+
296
+ #: includes/translations.php:281
297
+ msgid "Cc"
298
+ msgstr "抄送"
299
+
300
+ #: includes/translations.php:282
301
+ msgid "Bcc"
302
+ msgstr "秘密抄送"
303
+
304
+ #: includes/translations.php:283
305
+ msgid "Please provide valid Cc Email Address"
306
+ msgstr "请提供有效的抄送邮箱"
307
+
308
+ #: includes/translations.php:284
309
+ msgid "Please provide valid Bcc Email Address"
310
+ msgstr "请提供有效的秘密抄送邮箱"
311
+
312
+ #: includes/translations.php:285
313
+ msgid "Please provide Cc Email"
314
+ msgstr "请提供抄送邮箱"
315
+
316
+ #: includes/translations.php:286
317
+ msgid "Please provide Bcc Email"
318
+ msgstr "请提供秘密抄送邮箱"
319
+
320
+ #: includes/translations.php:287
321
+ msgid "Mailer Settings"
322
+ msgstr "邮件设置"
323
+
324
+ #: includes/translations.php:289
325
+ msgid "From Name"
326
+ msgstr "发件人名称"
327
+
328
+ #: includes/translations.php:290
329
+ msgid ""
330
+ "From Name is the inbox field that tells your recipient who sent the "
331
+ "messages. If you would like to override the pre-configured From Name, then "
332
+ "you would need to insert the name in the inbox field"
333
+ msgstr ""
334
+ "发件人名称是告知收件人谁给你发送了邮件。如果要覆盖预先配置的名称,则需要在字"
335
+ "段中插入名称。"
336
+
337
+ #: includes/translations.php:291
338
+ msgid "Please provide From Name"
339
+ msgstr "请提供发件人名称"
340
+
341
+ #: includes/translations.php:292
342
+ msgid "From Email"
343
+ msgstr "发件人地址"
344
+
345
+ #: includes/translations.php:293
346
+ msgid ""
347
+ "From Email is the inbox field that tells your recipient from which Email "
348
+ "Address the messages are coming. If you would like to override the pre-"
349
+ "configured From Email, then you would need to insert an Email Address in the "
350
+ "inbox field"
351
+ msgstr ""
352
+ "发件人地址是告知接收人邮件来自哪个邮箱地址发送的。如果要覆盖预先配置的名称,"
353
+ "则需要在字段中插入邮箱地址。"
354
+
355
+ #: includes/translations.php:294
356
+ msgid "Please provide From Email Address"
357
+ msgstr "请提供发件人地址"
358
+
359
+ #: includes/translations.php:295
360
+ msgid "Mailer Type"
361
+ msgstr "邮件类型"
362
+
363
+ #: includes/translations.php:296
364
+ msgid ""
365
+ "This field provides you an ability to choose a specific option for Mailer "
366
+ "Type. If you would like to send an Email via SMTP mailer, you would need to "
367
+ "select Send Email via SMTP from the drop down or you could use PHP mail () "
368
+ "Function"
369
+ msgstr ""
370
+ "这个字段给您提供邮件类型进行选择,如果您想通过SMTP方式发送电子邮件,您需要从"
371
+ "下拉列表中选择通过SMTP发送电子邮件,或者您也可以使用PHP mail()方法发送电子邮"
372
+ "件。"
373
+
374
+ #: includes/translations.php:297
375
+ msgid "Send Email via SMTP"
376
+ msgstr "通过SMTP发送邮件"
377
+
378
+ #: includes/translations.php:298
379
+ msgid "Use The PHP mail() Function"
380
+ msgstr "使用PHP mail()方法"
381
+
382
+ #: includes/translations.php:299
383
+ msgid "SMTP Host"
384
+ msgstr "SMTP主机"
385
+
386
+ #: includes/translations.php:300
387
+ msgid ""
388
+ "If you would like to send an Email via different host, you would need to "
389
+ "insert that specific host name like smtp.gmail.com in the inbox field"
390
+ msgstr ""
391
+ "如果您想通过不同的主机发送电子邮件,则需要在字段中插入特定的主机名(如smtp."
392
+ "gamil.com)"
393
+
394
+ #: includes/translations.php:301
395
+ msgid "Please provide SMTP Host"
396
+ msgstr "请提供SMTP主机"
397
+
398
+ #: includes/translations.php:302
399
+ msgid "SMTP Port"
400
+ msgstr "SMTP端口"
401
+
402
+ #: includes/translations.php:303
403
+ msgid ""
404
+ "This inbox field is specified to provide a valid SMTP Port for authentication"
405
+ msgstr "此字段提供用于认证的有效SMTP端口"
406
+
407
+ #: includes/translations.php:304
408
+ msgid "Please provide SMTP Port"
409
+ msgstr "请填写SMTP端口"
410
+
411
+ #: includes/translations.php:305
412
+ msgid "Encryption"
413
+ msgstr "加密"
414
+
415
+ #: includes/translations.php:306
416
+ msgid ""
417
+ "It provides you an ability to choose a specific option for Encryption. If "
418
+ "you would like to send an Email with TLS encryption, you would need to "
419
+ "select Use TLS Encryption from the drop down or you could use SSL "
420
+ "Encryption. For that you would need to select Use SSL Encryption from the "
421
+ "drop down. If you would like to send an Email without encryption, you would "
422
+ "need to select No Encryption from the drop down"
423
+ msgstr ""
424
+ "它为您提供了选择一个特定的选项用于加密的能力。如果您想发送TLS加密的电子邮件,"
425
+ "则需要从下拉列表中选择使用TLS加密,或者您想使用SSL加密。 请从下拉列表中选择使"
426
+ "用SSL加密。如果您想要发送没有加密的电子邮件,则需要从下拉列表中选择不加密。"
427
+
428
+ #: includes/translations.php:307
429
+ msgid "No Encryption"
430
+ msgstr "不加密"
431
+
432
+ #: includes/translations.php:308
433
+ msgid "Use SSL Encryption"
434
+ msgstr "使用SSL加密"
435
+
436
+ #: includes/translations.php:309
437
+ msgid "Use TLS Encryption"
438
+ msgstr "使用TLS加密"
439
+
440
+ #: includes/translations.php:310
441
+ msgid "Authentication"
442
+ msgstr "认证"
443
+
444
+ #: includes/translations.php:311
445
+ msgid ""
446
+ "This inbox field allows you to choose an appropriate option for "
447
+ "authentication. It provides you the Two-way authentication factor; If you "
448
+ "would like to authenticate yourself via Username and Password, you would "
449
+ "need to select Use Username and Password from the drop down. You can also "
450
+ "authenticate by an OAuth 2.0 protocol, which requires Client Id and Secret "
451
+ "Key, for that you would need to select Use OAuth (Client ID and Secret Key) "
452
+ "from the drop down. You can easily get Client Id and Secret Key from "
453
+ "respective SMTP Server Developers section"
454
+ msgstr ""
455
+ "这个字段允许您选择一个适当的选项进行身份验证。它提供双向身份验证因素; 如果您"
456
+ "想通过用户名和密码验证,您需要从下拉列表中选择使用用户名和密码。您也可以通过"
457
+ "OAuth 2.0验证,这需要Client ID和Secret Key,您需要请从下拉列表中选择使用"
458
+ "OAuth(Client ID和Secret Key),您可以从相应的SMTP服务商中轻松获取到Client ID和"
459
+ "Secret Key。"
460
+
461
+ #: includes/translations.php:312
462
+ msgid "Use SMTP Authentication"
463
+ msgstr "使用SMTP认证"
464
+
465
+ #: includes/translations.php:313
466
+ msgid "Don't Use SMTP Authentication"
467
+ msgstr "禁用SMTP认证"
468
+
469
+ #: includes/translations.php:314
470
+ msgid "Test Email Address"
471
+ msgstr "测试电子邮件地址"
472
+
473
+ #: includes/translations.php:315
474
+ msgid ""
475
+ "In this field, you would need to provide a valid Email Address in the inbox "
476
+ "field on which you would like to receive Test email"
477
+ msgstr "在此输入接收测试邮件的E-Mail地址"
478
+
479
+ #: includes/translations.php:316
480
+ msgid "Please provide Test Email Address"
481
+ msgstr "请输入测试邮件地址"
482
+
483
+ #: includes/translations.php:317
484
+ msgid "In this field, you would need to provide a subject for Test Email"
485
+ msgstr "在此输入测试邮件标题"
486
+
487
+ #: includes/translations.php:318
488
+ msgid "Please provide Subject"
489
+ msgstr "请填写邮件标题"
490
+
491
+ #: includes/translations.php:319
492
+ msgid "Email Content"
493
+ msgstr "邮件内容"
494
+
495
+ #: includes/translations.php:320
496
+ msgid "In this field, you would need to provide the content for Test Email"
497
+ msgstr "此区域输入测试邮件内容"
498
+
499
+ #: includes/translations.php:321
500
+ msgid "Send Test Email"
501
+ msgstr "发送测试邮件"
502
+
503
+ #: includes/translations.php:322
504
+ msgid "SMTP Debugging Output"
505
+ msgstr "SMTP调试信息"
506
+
507
+ #: includes/translations.php:323
508
+ msgid "Checking your settings"
509
+ msgstr "检查你的设定"
510
+
511
+ #: includes/translations.php:324
512
+ msgid "Result"
513
+ msgstr "结果"
514
+
515
+ #: includes/translations.php:325
516
+ msgid "Send Another Test Email"
517
+ msgstr "再次发送测试邮件"
518
+
519
+ #: includes/translations.php:326
520
+ msgid "From Name Configuration"
521
+ msgstr "从名称配置"
522
+
523
+ #: includes/translations.php:327
524
+ msgid ""
525
+ "If you would like to override the pre-configured name which will be used "
526
+ "while sending Emails, then you would need to choose Override from the drop "
527
+ "down and vice-versa"
528
+ msgstr ""
529
+ "如果您想覆盖发送电子邮件时使用的预先配置的名称,需要从下拉列表中选择覆盖。"
530
+
531
+ #: includes/translations.php:328
532
+ msgid "From Email Configuration"
533
+ msgstr "从Email配置"
534
+
535
+ #: includes/translations.php:329
536
+ msgid ""
537
+ "If you would like to override your pre-configured Email Address which will "
538
+ "be used while sending Emails, then you would need to choose Override from "
539
+ "the drop down and vice-versa"
540
+ msgstr ""
541
+ "如果您想覆盖发送电子邮件时使用的预先配置的邮箱地址,需要从下拉列表中选择覆"
542
+ "盖。"
543
+
544
+ #: includes/translations.php:330
545
+ msgid "Username"
546
+ msgstr "用户名"
547
+
548
+ #: includes/translations.php:331
549
+ msgid ""
550
+ "In this field, you would need to provide a username to authenticate your "
551
+ "SMTP details"
552
+ msgstr "在这个字段,您需要提供用户名用于验证SMTP详细信息"
553
+
554
+ #: includes/translations.php:332
555
+ msgid "Please provide username"
556
+ msgstr "请填写用户名"
557
+
558
+ #: includes/translations.php:333
559
+ msgid "Password"
560
+ msgstr "密码"
561
+
562
+ #: includes/translations.php:334
563
+ msgid ""
564
+ "In this field, you would need to provide a password to authenticate your "
565
+ "SMTP details"
566
+ msgstr "在这个字段,您需要提供密码用于验证SMTP详细信息"
567
+
568
+ #: includes/translations.php:335
569
+ msgid "Please provide password"
570
+ msgstr "请填写密码"
571
+
572
+ #: includes/translations.php:336
573
+ msgid "Redirect URI"
574
+ msgstr "重定向URI"
575
+
576
+ #: includes/translations.php:337
577
+ msgid ""
578
+ "Please copy this Redirect URI and Paste into Redirect URI field when "
579
+ "creating your app"
580
+ msgstr "请复制这个重定向URI并在创建你的应用时粘贴至重定向URI字段"
581
+
582
+ #: includes/translations.php:338
583
+ msgid "Use OAuth (Client Id and Secret Key required)"
584
+ msgstr "使用OAuth(Client Id和Secret Key必填)"
585
+
586
+ #: includes/translations.php:339
587
+ msgid "Plain Authentication"
588
+ msgstr "简单验证"
589
+
590
+ #: includes/translations.php:340
591
+ msgid "Cram-MD5"
592
+ msgstr "Cram-MD5"
593
+
594
+ #: includes/translations.php:341
595
+ msgid "Login"
596
+ msgstr "登录"
597
+
598
+ #: includes/translations.php:342
599
+ msgid "Client Id"
600
+ msgstr "Client Id"
601
+
602
+ #: includes/translations.php:343
603
+ msgid "Secret Key"
604
+ msgstr "Secret Key"
605
+
606
+ #: includes/translations.php:344
607
+ msgid "Please provide valid Client Id issued by your SMTP Host"
608
+ msgstr "请提供您的SMTP主机发出的有效Client Id"
609
+
610
+ #: includes/translations.php:345
611
+ msgid "Please provide valid Secret Key issued by your SMTP Host"
612
+ msgstr "请提供您的SMTP主机发出的有效Secret Key"
613
+
614
+ #: includes/translations.php:346
615
+ msgid "Please provide Client Id"
616
+ msgstr "请提供Client Id"
617
+
618
+ #: includes/translations.php:347
619
+ msgid "Please provide Secret Key"
620
+ msgstr "请提供Secret Key"
621
+
622
+ #: includes/translations.php:348
623
+ msgid ""
624
+ "Yes, automatically send a Test Email upon clicking on the Next Step Button "
625
+ "to verify settings"
626
+ msgstr "是,当点击下一步按钮验证设置时,自动发送测试电子邮件"
627
+
628
+ #: includes/translations.php:349
629
+ msgid "Email Address"
630
+ msgstr "邮件地址"
631
+
632
+ #: includes/translations.php:350
633
+ msgid ""
634
+ "In this field, you would need to add a valid Email Address in the inbox "
635
+ "field from which you would like to send Emails"
636
+ msgstr "在这个字段,你需要在收件人字段中添加有效的邮箱"
637
+
638
+ #: includes/translations.php:351
639
+ msgid "Please provide valid Email Address"
640
+ msgstr "请提供有效的邮箱"
641
+
642
+ #: includes/translations.php:352
643
+ msgid "Reply To"
644
+ msgstr "回复给"
645
+
646
+ #: includes/translations.php:353
647
+ msgid ""
648
+ "In this field, you would need to add a valid Email Address that is "
649
+ "automatically inserted into the Reply To field when a user replies to an "
650
+ "email message"
651
+ msgstr ""
652
+ "在这个字段,你需要添加一个有效的邮箱,当用户回复电子邮件时,该邮箱会自动插入"
653
+ "回复字段中"
654
+
655
+ #: includes/translations.php:354
656
+ msgid "Please provide Reply To Email Address"
657
+ msgstr "请提供要回复的邮箱"
658
+
659
+ #: includes/translations.php:355
660
+ msgid "Get Google Client Id and Secret Key"
661
+ msgstr "获取 Google Client Id 和 Secret Key"
662
+
663
+ #: includes/translations.php:356
664
+ msgid "Get Microsoft Client Id and Secret Key"
665
+ msgstr "获取 Microsoft Client Id 和 Secret Key"
666
+
667
+ #: includes/translations.php:357
668
+ msgid "Get Yahoo Client Id and Secret Key"
669
+ msgstr "获取Yahoo Client Id和Secret Key"
670
+
671
+ #: includes/translations.php:360
672
+ msgid "Start Date"
673
+ msgstr "开始日期"
674
+
675
+ #: includes/translations.php:361
676
+ msgid "Please provide Start Date"
677
+ msgstr "请提供开始日期"
678
+
679
+ #: includes/translations.php:362
680
+ msgid "This field shows starting date of Email Logs"
681
+ msgstr "这个字段显示Email日志的开始日期"
682
+
683
+ #: includes/translations.php:363
684
+ msgid "End Date"
685
+ msgstr "结束日期"
686
+
687
+ #: includes/translations.php:364
688
+ msgid "Please provide End Date"
689
+ msgstr "请提供结束日期"
690
+
691
+ #: includes/translations.php:365
692
+ msgid "This field shows ending date of Email Logs"
693
+ msgstr "这个字段显示Email日志的结束日期"
694
+
695
+ #: includes/translations.php:366
696
+ msgid "Submit"
697
+ msgstr "提交"
698
+
699
+ #: includes/translations.php:367
700
+ msgid "Bulk Action"
701
+ msgstr "批量操作"
702
+
703
+ #: includes/translations.php:368
704
+ msgid "Delete"
705
+ msgstr "删除"
706
+
707
+ #: includes/translations.php:369
708
+ msgid "Apply"
709
+ msgstr "应用"
710
+
711
+ #: includes/translations.php:370
712
+ msgid "Email To"
713
+ msgstr "Email To"
714
+
715
+ #: includes/translations.php:371
716
+ msgid "Action"
717
+ msgstr "操作"
718
+
719
+ #: includes/translations.php:372
720
+ msgid "Show Details"
721
+ msgstr "显示详细信息"
722
+
723
+ #: includes/translations.php:373
724
+ msgid "Email Details"
725
+ msgstr "Email详情"
726
+
727
+ #: includes/translations.php:374
728
+ msgid "Email Debugging output"
729
+ msgstr "Email调试输出"
730
+
731
+ #: includes/translations.php:376
732
+ msgid "Debugging Output"
733
+ msgstr "调试输出"
734
+
735
+ #: includes/translations.php:377
736
+ msgid "Show Debugging Output"
737
+ msgstr "显示调试输出"
738
+
739
+ #: includes/translations.php:378
740
+ msgid "Email Sent To"
741
+ msgstr "邮件发送给"
742
+
743
+ #: includes/translations.php:379
744
+ msgid "Date/Time"
745
+ msgstr "日期/时间"
746
+
747
+ #: includes/translations.php:380
748
+ msgid "Status"
749
+ msgstr "状态"
750
+
751
+ #: includes/translations.php:381
752
+ msgid "From"
753
+ msgstr "来自"
754
+
755
+ #: includes/translations.php:382
756
+ msgid "Back to Email Logs"
757
+ msgstr "返回Email日志"
758
+
759
+ #: includes/translations.php:385
760
+ msgid "Automatic Plugin Updates"
761
+ msgstr "自动更新插件"
762
+
763
+ #: includes/translations.php:386
764
+ msgid ""
765
+ "Please choose a specific option whether to allow Automatic Plugin Updates"
766
+ msgstr "请选择是否允许自动更新插件"
767
+
768
+ #: includes/translations.php:387
769
+ msgid "Debug Mode"
770
+ msgstr "debug模式"
771
+
772
+ #: includes/translations.php:388
773
+ msgid "Please choose a specific option for Debug Mode"
774
+ msgstr "请选择debug模式"
775
+
776
+ #: includes/translations.php:389
777
+ msgid "Remove Tables at Uninstall"
778
+ msgstr "卸载时移除表"
779
+
780
+ #: includes/translations.php:390
781
+ msgid ""
782
+ "Please choose a specific option whether to allow Remove Tables at Uninstall"
783
+ msgstr "请选择是否在卸载时删除表"
784
+
785
+ #: includes/translations.php:391
786
+ msgid "Monitoring Email Logs"
787
+ msgstr "监控Email日志"
788
+
789
+ #: includes/translations.php:392
790
+ msgid "This field is used to allow Email Logs to monitor or not"
791
+ msgstr "这个字段用于是否监控Email日志"
792
+
793
+ #: includes/translations.php:395
794
+ msgid "Show Mail Bank Menu"
795
+ msgstr "显示Mail Bank菜单"
796
+
797
+ #: includes/translations.php:396
798
+ msgid "Please choose a specific role who can see Sidebar Menu"
799
+ msgstr "请选择一个特定的角色谁可以看到侧边栏菜单"
800
+
801
+ #: includes/translations.php:397
802
+ msgid "Administrator"
803
+ msgstr "Administrator"
804
+
805
+ #: includes/translations.php:398
806
+ msgid "Author"
807
+ msgstr "作者"
808
+
809
+ #: includes/translations.php:399
810
+ msgid "Editor"
811
+ msgstr "编辑"
812
+
813
+ #: includes/translations.php:400
814
+ msgid "Contributor"
815
+ msgstr "贡献人"
816
+
817
+ #: includes/translations.php:401
818
+ msgid "Subscriber"
819
+ msgstr "订阅"
820
+
821
+ #: includes/translations.php:402
822
+ msgid "Others"
823
+ msgstr "其他"
824
+
825
+ #: includes/translations.php:403
826
+ msgid "Show Mail Bank Top Bar Menu"
827
+ msgstr "显示Mail Bank顶部菜单"
828
+
829
+ #: includes/translations.php:404
830
+ msgid "Please choose a specific option from Mail Bank Top Bar Menu"
831
+ msgstr "请从Mail Bank顶部菜单选择一个选项"
832
+
833
+ #: includes/translations.php:405
834
+ msgid "An Administrator Role can do the following "
835
+ msgstr "管理员角色可以执行以下操作"
836
+
837
+ #: includes/translations.php:406
838
+ msgid "Please choose specific page available for the Administrator Access"
839
+ msgstr "请选择供管理员账户访问的特定页面"
840
+
841
+ #: includes/translations.php:407
842
+ msgid "Full Control"
843
+ msgstr "完全控制"
844
+
845
+ #: includes/translations.php:408
846
+ msgid "An Author Role can do the following "
847
+ msgstr "作者角色可以执行以下操作"
848
+
849
+ #: includes/translations.php:409
850
+ msgid "Please choose specific page available for Author Access"
851
+ msgstr "请选择供作者账户访问的特定页面"
852
+
853
+ #: includes/translations.php:410
854
+ msgid "An Editor Role can do the following "
855
+ msgstr "编辑角色可以执行以下操作"
856
+
857
+ #: includes/translations.php:411
858
+ msgid "Please choose specific page available for Editor Access"
859
+ msgstr "请选择供编辑账户访问的特定页面"
860
+
861
+ #: includes/translations.php:412
862
+ msgid "A Contributor Role can do the following "
863
+ msgstr "贡献人角色可以执行以下操作"
864
+
865
+ #: includes/translations.php:413
866
+ msgid "Please choose specific page available for Contributor Access"
867
+ msgstr "请选择供贡献人账户访问的特定页面"
868
+
869
+ #: includes/translations.php:414
870
+ msgid "Other Roles can do the following "
871
+ msgstr "其他角色可以执行以下操作"
872
+
873
+ #: includes/translations.php:415
874
+ msgid "Please choose specific page available for Others Role Access"
875
+ msgstr "请选择供其他角色账户访问的特定页面"
876
+
877
+ #: includes/translations.php:416
878
+ msgid "Please tick the appropriate capabilities for security purposes "
879
+ msgstr "请从安全角度勾选适当的功能"
880
+
881
+ #: includes/translations.php:417
882
+ msgid "Only users with these capabilities can access Mail Bank"
883
+ msgstr "只有具有这些功能的用户才能访问Mail Bank"
884
+
885
+ #: includes/translations.php:418
886
+ msgid "A Subscriber Role can do the following"
887
+ msgstr "订阅角色可以执行以下操作"
888
+
889
+ #: includes/translations.php:419
890
+ msgid "Please choose specific page available for Subscriber Access"
891
+ msgstr "请选择供订阅账户访问的特定页面"
892
+
893
+ #: includes/translations.php:422
894
+ msgid "Thank You!"
895
+ msgstr "谢谢!"
896
+
897
+ #: includes/translations.php:423
898
+ msgid ""
899
+ "Kindly fill in the below form, if you would like to suggest some features "
900
+ "which are not in the Plugin"
901
+ msgstr ""
902
+ "如果你没有在插件中没有发现你想要的功能,请填写下面的表格给我们提建议(开发组跪"
903
+ "求"
904
+
905
+ #: includes/translations.php:424
906
+ msgid ""
907
+ "If you also have any suggestion/complaint, you can use the same form below"
908
+ msgstr "如果你有任何建议/投诉,你可以使用下面同样的表格"
909
+
910
+ #: includes/translations.php:425
911
+ msgid "You can also write us on"
912
+ msgstr "你也可以在(@weibo)上面告诉我们"
913
+
914
+ #: includes/translations.php:426
915
+ msgid "Your Name"
916
+ msgstr "你的姓名"
917
+
918
+ #: includes/translations.php:427
919
+ msgid "Please provide your Name which will be sent along with your Feedback"
920
+ msgstr "请提供你的姓名,这将与你的反馈一起发送"
921
+
922
+ #: includes/translations.php:429
923
+ msgid "Your Email"
924
+ msgstr "你的邮件地址"
925
+
926
+ #: includes/translations.php:430
927
+ msgid ""
928
+ "Please provide your Email Address which will be sent along with your Feedback"
929
+ msgstr "请提供你的邮箱地址,这将与你的反馈一起发送"
930
+
931
+ #: includes/translations.php:431
932
+ msgid "Please provide your Email Address"
933
+ msgstr "请提供你的邮件地址"
934
+
935
+ #: includes/translations.php:432
936
+ msgid "Please provide your Feedback which will be sent along"
937
+ msgstr "请提供你的反馈,以便发送"
938
+
939
+ #: includes/translations.php:433
940
+ msgid "Please provide your Feedback"
941
+ msgstr "请填写你的反馈"
942
+
943
+ #: includes/translations.php:434
944
+ msgid "Send Feedback"
945
+ msgstr "发送反馈"
946
+
947
+ #: includes/translations.php:437
948
+ msgid "Sending Test Email to"
949
+ msgstr "发送测试邮件到"
950
+
951
+ #: includes/translations.php:438
952
+ msgid "Email Status"
953
+ msgstr "邮件状态"
954
+
955
+ #~ msgid "Roles & Capabilities have been updated Successfully"
956
+ #~ msgstr "更新角色和权限成功"
957
+
958
+ #~ msgid "Please choose at least 1 record to delete!"
959
+ #~ msgstr "请至少选择1条记录进行删除!"
960
+
961
+ #~ msgid "Are you sure you want to delete Email Logs?"
962
+ #~ msgstr "您确定要删除电子邮件日志?"
963
+
964
+ #~ msgid "Selected Logs have been deleted Successfully"
965
+ #~ msgstr "选择的日志已经删除成功。"
966
+
967
+ #~ msgid "Are you sure you want to delete Email Log?"
968
+ #~ msgstr "您确定要删除全部电子邮件日志?"
969
+
970
+ #~ msgid "Email Log has been deleted Successfully"
971
+ #~ msgstr "电子邮箱日志已经删除成功。"
972
+
973
+ #~ msgid "Licensing"
974
+ #~ msgstr "许可"
975
+
976
+ #~ msgid "Your License has been activated Successfully"
977
+ #~ msgstr "您的许可证已成功激活"
978
+
979
+ #~ msgid "Important Notice!"
980
+ #~ msgstr "重要提醒!"
981
+
982
+ #~ msgid ""
983
+ #~ "Congratulations! You have recently purchased Mail Bank Developer Edition "
984
+ #~ "and now you would need to activate the license in order to unlock it!"
985
+ #~ msgstr "祝贺! 您最近购买了Mail Bank,现在您需要激活许可证才能解锁它。"
986
+
987
+ #~ msgid ""
988
+ #~ "Kindly fill in the required details and click on Validate License to "
989
+ #~ "unlock it"
990
+ #~ msgstr "请填写所需的详细信息,然后点击验证许可证来解锁它"
991
+
992
+ #~ msgid ""
993
+ #~ "If you face any issues activating the license, you may contact us at "
994
+ #~ msgstr "如果您在激活许可证时遇到任何问题,您可以通过....与我们联系"
995
+
996
+ #~ msgid "Product Name"
997
+ #~ msgstr "产品名称"
998
+
999
+ #~ msgid "Current Version"
1000
+ #~ msgstr "当前版本"
1001
+
1002
+ #~ msgid "Website URL"
1003
+ #~ msgstr "网站地址"
1004
+
1005
+ #~ msgid "Order ID"
1006
+ #~ msgstr "订单号"
1007
+
1008
+ #~ msgid "API KEY"
1009
+ #~ msgstr "API KEY"
1010
+
1011
+ #~ msgid "Validate License"
1012
+ #~ msgstr "验证授权"
1013
+
1014
+ #~ msgid "This field shows your Installed Product"
1015
+ #~ msgstr "这个字段显示你已安装的产品"
1016
+
1017
+ #~ msgid "This field shows your Installed Product Version"
1018
+ #~ msgstr "这个字段显示你已安装的产品版本"
1019
+
1020
+ #~ msgid "This field shows your Website URL"
1021
+ #~ msgstr "这个字段显示你的网站地址"
1022
+
1023
+ #~ msgid ""
1024
+ #~ "Please provide your Order ID which you have received after purchasing "
1025
+ #~ "the Product. This will be used for Validating the License"
1026
+ #~ msgstr "请提供您在购买产品后收到的订单号,这将用于验证许可证"
1027
+
1028
+ #~ msgid ""
1029
+ #~ "Please provide your API Key which you have received after purchasing the "
1030
+ #~ "Product. This will be used for Validating the License"
1031
+ #~ msgstr "请提供您在购买产品后收到的API Key,这将用于验证许可证"
1032
+
1033
+ #~ msgid "Please provide Order ID received after making the purchase"
1034
+ #~ msgstr "请在购买后提供订单号"
1035
+
1036
+ #~ msgid "Please provide API Key received after making the purchase"
1037
+ #~ msgstr "请在购买后提供API Key"
1038
+
1039
+ #~ msgid ""
1040
+ #~ "Congratulations! You have recently purchased Mail Bank Business Edition "
1041
+ #~ "and now you would need to activate the license in order to unlock it!"
1042
+ #~ msgstr ""
1043
+ #~ "祝贺! 您最近购买了Mail Bank商业版,现在您需要激活许可证才能解锁它。"
1044
+
1045
+ #~ msgid "* Openssl extension not found or disabled"
1046
+ #~ msgstr "Openssl扩展不存在或禁用"
1047
+
1048
+ #~ msgid "Use Username And Password"
1049
+ #~ msgstr "使用用户名和密码"
1050
+
1051
+ #~ msgid " Features available in Business and Developer Editions :"
1052
+ #~ msgstr "功能可用于商业和开发版本:"
1053
+
1054
+ #~ msgid ""
1055
+ #~ "This feature is only available in Business and Developer Editions! <br> "
1056
+ #~ "Kindly Purchase to unlock it!."
1057
+ #~ msgstr "这个功能仅商业和开发版本可用,请购买解锁。"
1058
+
1059
+ #~ msgid "* Bulk Delete "
1060
+ #~ msgstr "批量删除"
1061
+
1062
+ #~ msgid "* Debugging Output "
1063
+ #~ msgstr "调试输出"
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: contact-banker, Gallery-Bank, wordpress-empire
3
  Tags: email, gmail, mail, mail smtp, mailer, outgoing mail, phpmailer, sendmail, smtp, ssl, tls, WordPress smtp, wp smtp, wp-phpmailer, wp_mail, wp mail, mailer, mail bank
4
  Requires at least: 2.7
5
  Tested up to: 4.6.1
6
- Stable tag: 2.0.6
7
 
8
  Mail Bank reconfigures the Mail Function and provides sophisticated SMTP settings to send and log emails from your WordPress site.
9
 
@@ -365,6 +365,15 @@ If any problem occurs, please contact us at [support@tech-banker.com](mailto:sup
365
 
366
  == Changelog ==
367
 
 
 
 
 
 
 
 
 
 
368
  = 2.0.6 =
369
 
370
  * Security Patch Added
3
  Tags: email, gmail, mail, mail smtp, mailer, outgoing mail, phpmailer, sendmail, smtp, ssl, tls, WordPress smtp, wp smtp, wp-phpmailer, wp_mail, wp mail, mailer, mail bank
4
  Requires at least: 2.7
5
  Tested up to: 4.6.1
6
+ Stable tag: 2.0.7
7
 
8
  Mail Bank reconfigures the Mail Function and provides sophisticated SMTP settings to send and log emails from your WordPress site.
9
 
365
 
366
  == Changelog ==
367
 
368
+ = 2.0.7 =
369
+
370
+ * Major Bug Fixed Related to Email Mime Types
371
+ * Js Code Optimized
372
+ * Chinese Language Added
373
+ * Romanian Language Added
374
+ * Arabic Language Added
375
+ * English(Australian) Language Added
376
+
377
  = 2.0.6 =
378
 
379
  * Security Patch Added
views/system-information/system-information.php CHANGED
@@ -3,7 +3,7 @@
3
  * This Template is used for displaying system information.
4
  *
5
  * @author Tech Banker
6
- * @package wp-mail-bank-business-edition/views/system-information
7
  * @version 2.0.0
8
  */
9
  if(!defined("ABSPATH")) exit; // Exit if accessed directly
@@ -59,15 +59,15 @@ else
59
  <div class="portlet-body form">
60
  <form id="ux_frm_system_information">
61
  <div class="form-body">
62
- <?php
63
- if(isset($extension_not_found) && count($extension_not_found) > 0)
64
- {
65
- ?>
66
- <div class="note note-danger">
67
- <h4 class="block">
68
- <?php echo $mb_important_disclaimer; ?>
69
- </h4>
70
- <ul>
71
  <li><?php echo $mb_contact_to_host; ?></li>
72
  <?php
73
  foreach($extension_not_found as $extension)
@@ -76,12 +76,20 @@ else
76
  <li>* <?php echo $extension; ?></li>
77
  <?php
78
  }
79
- ?>
80
- </ul>
81
- </div>
 
 
82
  <?php
83
- }
84
- ?>
 
 
 
 
 
 
85
  <div class="layout-system-report" id="ux_system_information">
86
  <textarea id="ux_txtarea_system_information" name="ux_txtarea_system_information" readonly="readonly"></textarea>
87
  </div>
@@ -434,9 +442,12 @@ else
434
  <td>
435
  <span>
436
  <?php
437
- foreach(get_loaded_extensions() as $extension)
438
  {
439
- echo $extension.", ";
 
 
 
440
  }
441
  ?>
442
  </span>
@@ -449,9 +460,12 @@ else
449
  <td>
450
  <span>
451
  <?php
452
- foreach(apache_get_modules() as $module)
453
  {
454
- echo $module.", ";
 
 
 
455
  }
456
  ?>
457
  </span>
3
  * This Template is used for displaying system information.
4
  *
5
  * @author Tech Banker
6
+ * @package wp-mail-bank/views/system-information
7
  * @version 2.0.0
8
  */
9
  if(!defined("ABSPATH")) exit; // Exit if accessed directly
59
  <div class="portlet-body form">
60
  <form id="ux_frm_system_information">
61
  <div class="form-body">
62
+ <div class="note note-danger">
63
+ <h4 class="block">
64
+ <?php echo $mb_important_disclaimer; ?>
65
+ </h4>
66
+ <ul>
67
+ <?php
68
+ if(isset($extension_not_found) && count($extension_not_found) > 0)
69
+ {
70
+ ?>
71
  <li><?php echo $mb_contact_to_host; ?></li>
72
  <?php
73
  foreach($extension_not_found as $extension)
76
  <li>* <?php echo $extension; ?></li>
77
  <?php
78
  }
79
+ }
80
+ ?>
81
+ <li><?php echo $mb_demos_disclaimer ?><a href="http://beta.tech-banker.com/products/mail-bank/demos/" target="_blank" class="custom_links"><?php echo $mb_here_disclaimer ?></a>.</li>
82
+ <li><?php echo $mb_manual_disclaimer ?><a href="http://beta.tech-banker.com/products/mail-bank/user-guide/system-information/" target="_blank" class="custom_links"><?php echo $mb_here_disclaimer ?></a>.</li>
83
+ </ul>
84
  <?php
85
+ if($mb_message_translate_help != "")
86
+ {
87
+ ?>
88
+ <strong><?php echo $mb_message_translate_help;?><a href="javascript:void(0);" data-popup-open="ux_open_popup" class="custom_links" onclick="show_pop_up_mail_bank();"><?php echo $mb_message_translate_here; ?></a></strong>
89
+ <?php
90
+ }
91
+ ?>
92
+ </div>
93
  <div class="layout-system-report" id="ux_system_information">
94
  <textarea id="ux_txtarea_system_information" name="ux_txtarea_system_information" readonly="readonly"></textarea>
95
  </div>
442
  <td>
443
  <span>
444
  <?php
445
+ if(function_exists("get_loaded_extensions"))
446
  {
447
+ foreach(get_loaded_extensions() as $extension)
448
+ {
449
+ echo $extension.", ";
450
+ }
451
  }
452
  ?>
453
  </span>
460
  <td>
461
  <span>
462
  <?php
463
+ if(function_exists("apache_get_modules"))
464
  {
465
+ foreach(apache_get_modules() as $module)
466
+ {
467
+ echo $module.", ";
468
+ }
469
  }
470
  ?>
471
  </span>
wp-mail-bank.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://beta.tech-banker.com
5
  Description: Mail Bank reconfigures the wp_mail() function and make it more enhanced.
6
  Author: Tech Banker
7
  Author URI: http://beta.tech-banker.com
8
- Version: 2.0.6
9
  License: GPLv3
10
  */
11
 
5
  Description: Mail Bank reconfigures the wp_mail() function and make it more enhanced.
6
  Author: Tech Banker
7
  Author URI: http://beta.tech-banker.com
8
+ Version: 2.0.7
9
  License: GPLv3
10
  */
11