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

Version Description

  • FIX: Major Bugs
  • TWEAK: Code Optimized
  • TWEAK: Overview Page Added
  • TWEAK: Wizard Page Removed
Download this release

Release Info

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

Code changes from version 3.0.9 to 3.0.10

assets/admin/layout/css/mail-bank-custom.css CHANGED
@@ -197,4 +197,187 @@
197
  .premium-editions:hover
198
  {
199
  text-decoration: underline !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
197
  .premium-editions:hover
198
  {
199
  text-decoration: underline !important;
200
+ }
201
+ .tabbable-custom
202
+ {
203
+ margin-bottom: 15px;
204
+ padding: 0px;
205
+ overflow: hidden;
206
+ /* justified tabs */
207
+ /* boxless tabs */
208
+ /* below justified tabs */
209
+ /* full width tabs */
210
+ /* below tabs */
211
+ }
212
+ .tabbable-custom > .nav-tabs
213
+ {
214
+ border: none;
215
+ margin: 0px;
216
+ }
217
+ .tabbable-custom > .nav-tabs > li
218
+ {
219
+ margin-right: 2px;
220
+ border-top: 2px solid transparent;
221
+ }
222
+ .tabbable-custom > .nav-tabs > li > a
223
+ {
224
+ margin-right: 0;
225
+ -webkit-border-radius: 0;
226
+ -moz-border-radius: 0;
227
+ -ms-border-radius: 0;
228
+ -o-border-radius: 0;
229
+ border-radius: 0;
230
+ }
231
+ .tabbable-custom > .nav-tabs > li > a:hover
232
+ {
233
+ background: none;
234
+ border-color: transparent;
235
+ }
236
+ .tabbable-custom > .nav-tabs > li.active
237
+ {
238
+ border-top: 3px solid #a4cd39;
239
+ margin-top: 0;
240
+ position: relative;
241
+ }
242
+ .tabbable-custom > .nav-tabs > li.active > a
243
+ {
244
+ border-top: none !important;
245
+ font-weight: 400;
246
+ -webkit-border-radius: 0;
247
+ -moz-border-radius: 0;
248
+ -ms-border-radius: 0;
249
+ -o-border-radius: 0;
250
+ border-radius: 0;
251
+ }
252
+ .tabbable-custom > .nav-tabs > li.active > a:hover
253
+ {
254
+ -webkit-border-radius: 0;
255
+ -moz-border-radius: 0;
256
+ -ms-border-radius: 0;
257
+ -o-border-radius: 0;
258
+ border-radius: 0;
259
+ border-top: none;
260
+ background: #fff;
261
+ border-color: #d4d4d4 #d4d4d4 transparent;
262
+ }
263
+ .tabbable-custom > .tab-content
264
+ {
265
+ background-color: #fff;
266
+ border: 1px solid #ddd;
267
+ padding: 10px;
268
+ -webkit-border-radius: 0 0 4px 4px;
269
+ -moz-border-radius: 0 0 4px 4px;
270
+ -ms-border-radius: 0 0 4px 4px;
271
+ -o-border-radius: 0 0 4px 4px;
272
+ border-radius: 0 0 4px 4px;
273
+ }
274
+ .nav-tabs > li > a:focus
275
+ {
276
+ color: #ddd;
277
+ -webkit-box-shadow: none;
278
+ box-shadow: none;
279
+ }
280
+ .portlet > .portlet-title > .nav-tabs > li
281
+ {
282
+ background: none;
283
+ margin: 0;
284
+ border: 0;
285
+ }
286
+ .portlet > .portlet-title > .nav-tabs > li > a
287
+ {
288
+ background: none;
289
+ margin: 5px 0 0 1px;
290
+ border: 0;
291
+ padding: 8px 10px;
292
+ color: #fff;
293
+ }
294
+ .portlet > .portlet-title > .nav-tabs > li.active > a, .portlet > .portlet-title > .nav-tabs > li:hover > a
295
+ {
296
+ color: #333;
297
+ background: #fff;
298
+ border: 0;
299
+ }
300
+ .nav
301
+ {
302
+ padding-left: 0;
303
+ margin-bottom: 0;
304
+ list-style: none;
305
+ }
306
+ .nav > li
307
+ {
308
+ position: relative;
309
+ display: block;
310
+ }
311
+ .nav > li > a
312
+ {
313
+ position: relative;
314
+ display: block;
315
+ padding: 10px 15px;
316
+ }
317
+ .nav > li > a:hover,.nav > li > a:focus
318
+ {
319
+ text-decoration: none;
320
+ background-color: #eee;
321
+ }
322
+ .nav > li.disabled > a
323
+ {
324
+ color: #777;
325
+ }
326
+ .nav > li.disabled > a:hover,
327
+ .nav > li.disabled > a:focus
328
+ {
329
+ color: #777;
330
+ text-decoration: none;
331
+ cursor: not-allowed;
332
+ background-color: transparent;
333
+ }
334
+ .nav .open > a,.nav .open > a:hover,.nav .open > a:focus
335
+ {
336
+ background-color: #eee;
337
+ border-color: #337ab7;
338
+ }
339
+ .nav > li > a > img
340
+ {
341
+ max-width: none;
342
+ }
343
+ .nav-tabs > li > a:focus
344
+ {
345
+ color: #ddd;
346
+ -webkit-box-shadow: none;
347
+ box-shadow: none;
348
+ outline: none !important;
349
+ }
350
+ .nav-tabs > li
351
+ {
352
+ float: left;
353
+ margin-bottom: -1px;
354
+ }
355
+ .nav-tabs > li > a
356
+ {
357
+ margin-right: 2px;
358
+ line-height: 1.42857143;
359
+ border: 1px solid transparent;
360
+ border-radius: 4px 4px 0 0;
361
+ }
362
+ .nav-tabs > li > a:hover
363
+ {
364
+ border-color: #eee #eee #ddd;
365
+ }
366
+ .nav-tabs > li.active > a,.nav-tabs > li.active > a:hover,.nav-tabs > li.active > a:focus
367
+ {
368
+ color: #555;
369
+ cursor: default;
370
+ background-color: #fff;
371
+ border: 1px solid #ddd;
372
+ border-bottom-color: transparent;
373
+ }
374
+ .nav-tabs .dropdown-menu
375
+ {
376
+ margin-top: -1px;
377
+ border-top-left-radius: 0;
378
+ border-top-right-radius: 0;
379
+ }
380
+ .tabbable-custom ul > li > a
381
+ {
382
+ text-decoration:none;
383
  }
assets/global/img/mail-bank-banner.png DELETED
Binary file
assets/global/plugins/custom/css/custom-rtl.css CHANGED
@@ -901,6 +901,21 @@
901
  {
902
  display: table-row-group;
903
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
  .caret
905
  {
906
  display: inline-block;
@@ -1135,6 +1150,32 @@
1135
  {
1136
  clear: both;
1137
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1138
  div.dataTables_length label
1139
  {
1140
  font-weight: normal;
@@ -1403,4 +1444,4 @@ div.FixedHeader_Cloned table
1403
  .pull-left
1404
  {
1405
  float: left !important;
1406
- }
901
  {
902
  display: table-row-group;
903
  }
904
+ .collapsing
905
+ {
906
+ position: relative;
907
+ height: 0;
908
+ overflow: hidden;
909
+ -webkit-transition-timing-function: ease;
910
+ o-transition-timing-function: ease;
911
+ transition-timing-function: ease;
912
+ -webkit-transition-duration: .35s;
913
+ -o-transition-duration: .35s;
914
+ transition-duration: .35s;
915
+ -webkit-transition-property: height, visibility;
916
+ -o-transition-property: height, visibility;
917
+ transition-property: height, visibility;
918
+ }
919
  .caret
920
  {
921
  display: inline-block;
1150
  {
1151
  clear: both;
1152
  }
1153
+ .center-block
1154
+ {
1155
+ display: block;
1156
+ margin-right: auto;
1157
+ margin-left: auto;
1158
+ }
1159
+ .hide
1160
+ {
1161
+ display: none !important;
1162
+ }
1163
+ .show
1164
+ {
1165
+ display: block !important;
1166
+ }
1167
+ .invisible
1168
+ {
1169
+ visibility: hidden;
1170
+ }
1171
+ .text-hide
1172
+ {
1173
+ font: 0/0 a;
1174
+ color: transparent;
1175
+ text-shadow: none;
1176
+ background-color: transparent;
1177
+ border: 0;
1178
+ }
1179
  div.dataTables_length label
1180
  {
1181
  font-weight: normal;
1444
  .pull-left
1445
  {
1446
  float: left !important;
1447
+ }
assets/global/plugins/custom/css/custom.css CHANGED
@@ -900,6 +900,21 @@
900
  {
901
  display: table-row-group;
902
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
903
  .caret
904
  {
905
  display: inline-block;
@@ -1152,6 +1167,26 @@
1152
  margin-right: auto;
1153
  margin-left: auto;
1154
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1155
  div.dataTables_length label
1156
  {
1157
  font-weight: normal;
@@ -1420,4 +1455,4 @@ div.FixedHeader_Cloned table
1420
  .pull-left
1421
  {
1422
  float: left !important;
1423
- }
900
  {
901
  display: table-row-group;
902
  }
903
+ .collapsing
904
+ {
905
+ position: relative;
906
+ height: 0;
907
+ overflow: hidden;
908
+ -webkit-transition-timing-function: ease;
909
+ o-transition-timing-function: ease;
910
+ transition-timing-function: ease;
911
+ -webkit-transition-duration: .35s;
912
+ -o-transition-duration: .35s;
913
+ transition-duration: .35s;
914
+ -webkit-transition-property: height, visibility;
915
+ -o-transition-property: height, visibility;
916
+ transition-property: height, visibility;
917
+ }
918
  .caret
919
  {
920
  display: inline-block;
1167
  margin-right: auto;
1168
  margin-left: auto;
1169
  }
1170
+ .hide
1171
+ {
1172
+ display: none !important;
1173
+ }
1174
+ .show
1175
+ {
1176
+ display: block !important;
1177
+ }
1178
+ .invisible
1179
+ {
1180
+ visibility: hidden;
1181
+ }
1182
+ .text-hide
1183
+ {
1184
+ font: 0/0 a;
1185
+ color: transparent;
1186
+ text-shadow: none;
1187
+ background-color: transparent;
1188
+ border: 0;
1189
+ }
1190
  div.dataTables_length label
1191
  {
1192
  font-weight: normal;
1455
  .pull-left
1456
  {
1457
  float: left !important;
1458
+ }
assets/global/plugins/custom/js/bootstrap-hover-dropdown.js ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ !function (e, n) {
2
+ var o = e();
3
+ e.fn.dropdownHover = function (t) {
4
+ return "ontouchstart" in document ? this : (o = o.add(this.parent()), this.each(function () {
5
+ var i, r = e(this),
6
+ s = r.parent(),
7
+ d = {
8
+ delay: 500,
9
+ instantlyCloseOthers: !0
10
+ },
11
+ a = {
12
+ delay: e(this).data("delay"),
13
+ instantlyCloseOthers: e(this).data("close-others")
14
+ },
15
+ h = "show.bs.dropdown",
16
+ u = "hide.bs.dropdown",
17
+ l = e.extend(!0, {}, d, t, a);
18
+ s.hover(function (e) {
19
+ return s.hasClass("open") || r.is(e.target) ? (o.find(":focus").blur(), l.instantlyCloseOthers === !0 && o.removeClass("open"), n.clearTimeout(i), s.addClass("open"), void r.trigger(h)) : !0
20
+ }, function () {
21
+ i = n.setTimeout(function () {
22
+ s.removeClass("open"), r.trigger(u)
23
+ }, l.delay)
24
+ }), r.hover(function () {
25
+ o.find(":focus").blur(), l.instantlyCloseOthers === !0 && o.removeClass("open"), n.clearTimeout(i), s.addClass("open"), r.trigger(h)
26
+ }), s.find(".dropdown-submenu").each(function () {
27
+ var o, t = e(this);
28
+ t.hover(function () {
29
+ n.clearTimeout(o), t.children(".dropdown-menu").show(), t.siblings().children(".dropdown-menu").hide()
30
+ }, function () {
31
+ var e = t.children(".dropdown-menu");
32
+ o = n.setTimeout(function () {
33
+ e.hide()
34
+ }, l.delay)
35
+ })
36
+ })
37
+ }))
38
+ }, e(document).ready(function () {
39
+ e('[data-hover="dropdown"]').not(".hover-initialized").each(function () {
40
+ e(this).dropdownHover(), e(this).addClass("hover-initialized")
41
+ })
42
+ })
43
+ }(jQuery, this);
assets/global/plugins/custom/js/custom.js CHANGED
@@ -1,14 +1,11 @@
1
- !function ($)
2
- {
3
 
4
  "use strict"; // jshint ;_;
5
 
6
-
7
  /* TOOLTIP PUBLIC CLASS DEFINITION
8
  * =============================== */
9
 
10
- var Tooltip = function (element, options)
11
- {
12
  this.init('tooltip_tip', element, options)
13
  }
14
 
@@ -16,21 +13,18 @@
16
 
17
  constructor: Tooltip
18
 
19
- , init: function (type, element, options)
20
- {
21
- var eventIn
22
- , eventOut
23
 
24
  this.type = type
25
  this.$element = $(element)
26
  this.options = this.getOptions(options)
27
  this.enabled = true
28
 
29
- if (this.options.trigger == 'click')
30
- {
31
  this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
32
- } else if (this.options.trigger != 'manual')
33
- {
34
  eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
35
  eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
36
  this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
@@ -38,27 +32,29 @@
38
  }
39
 
40
  this.options.selector ?
41
- (this._options = $.extend({}, this.options, {trigger: 'manual', selector: ''})) :
 
 
 
42
  this.fixTitle()
43
  }
44
 
45
- , getOptions: function (options)
46
- {
47
  options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
48
 
49
- if (options.delay && typeof options.delay == 'number')
50
- {
51
  options.delay = {
52
- show: options.delay
53
- , hide: options.delay
54
  }
55
  }
56
 
57
  return options
58
  }
59
 
60
- , enter: function (e)
61
- {
62
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
63
 
64
  if (!self.options.delay || !self.options.delay.show)
@@ -66,15 +62,14 @@
66
 
67
  clearTimeout(this.timeout)
68
  self.hoverState = 'in'
69
- this.timeout = setTimeout(function ()
70
- {
71
  if (self.hoverState == 'in')
72
  self.show()
73
  }, self.options.delay.show)
74
  }
75
 
76
- , leave: function (e)
77
- {
78
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
79
 
80
  if (this.timeout)
@@ -83,30 +78,21 @@
83
  return self.hide()
84
 
85
  self.hoverState = 'out'
86
- this.timeout = setTimeout(function ()
87
- {
88
  if (self.hoverState == 'out')
89
  self.hide()
90
  }, self.options.delay.hide)
91
  }
92
 
93
- , show: function ()
94
- {
95
- var $tip
96
- , inside
97
- , pos
98
- , actualWidth
99
- , actualHeight
100
- , placement
101
- , tp
102
-
103
- if (this.hasContent() && this.enabled)
104
- {
105
  $tip = this.tip()
106
  this.setContent()
107
 
108
- if (this.options.animation)
109
- {
110
  $tip.addClass('fade')
111
  }
112
 
@@ -118,7 +104,11 @@
118
 
119
  $tip
120
  .detach()
121
- .css({top: 0, left: 0, display: 'block'})
 
 
 
 
122
  .insertAfter(this.$element)
123
 
124
  pos = this.getPosition(inside)
@@ -126,19 +116,30 @@
126
  actualWidth = $tip[0].offsetWidth
127
  actualHeight = $tip[0].offsetHeight
128
 
129
- switch (inside ? placement.split(' ')[1] : placement)
130
- {
131
  case 'bottom':
132
- tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
 
 
 
133
  break
134
  case 'top':
135
- tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
 
 
 
136
  break
137
  case 'left':
138
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
 
 
 
139
  break
140
  case 'right':
141
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
 
 
 
142
  break
143
  }
144
 
@@ -149,31 +150,28 @@
149
  }
150
  }
151
 
152
- , setContent: function ()
153
- {
154
- var $tip = this.tip()
155
- , title = this.getTitle()
156
 
157
  $tip.find('.tooltip_tip-inner')[this.options.html ? 'html' : 'text'](title)
158
  $tip.removeClass('fade in top bottom left right')
159
  }
160
 
161
- , hide: function ()
162
- {
163
- var that = this
164
- , $tip = this.tip()
165
 
166
  $tip.removeClass('in')
167
 
168
- function removeWithAnimation()
169
- {
170
- var timeout = setTimeout(function ()
171
- {
172
  $tip.off($.support.transition.end).detach()
173
  }, 500)
174
 
175
- $tip.one($.support.transition.end, function ()
176
- {
177
  clearTimeout(timeout)
178
  $tip.detach()
179
  })
@@ -186,97 +184,92 @@
186
  return this
187
  }
188
 
189
- , fixTitle: function ()
190
- {
191
  var $e = this.$element
192
- if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string')
193
- {
194
  $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
195
  }
196
  }
197
 
198
- , hasContent: function ()
199
- {
200
  return this.getTitle()
201
  }
202
 
203
- , getPosition: function (inside)
204
- {
205
- return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()),
206
- {
207
- width: this.$element[0].offsetWidth
208
- , height: this.$element[0].offsetHeight
209
- })
 
 
210
  }
211
 
212
- , getTitle: function ()
213
- {
214
- var title
215
- , $e = this.$element
216
- , o = this.options
217
 
218
- title = $e.attr('data-original-title')
219
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
220
 
221
  return title
222
  }
223
 
224
- , tip: function ()
225
- {
226
  return this.$tip = this.$tip || $(this.options.template)
227
  }
228
 
229
- , validate: function ()
230
- {
231
- if (!this.$element[0].parentNode)
232
- {
233
  this.hide()
234
  this.$element = null
235
  this.options = null
236
  }
237
  }
238
 
239
- , enable: function ()
240
- {
241
  this.enabled = true
242
  }
243
 
244
- , disable: function ()
245
- {
246
  this.enabled = false
247
  }
248
 
249
- , toggleEnabled: function ()
250
- {
251
  this.enabled = !this.enabled
252
  }
253
 
254
- , toggle: function (e)
255
- {
256
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
257
  self[self.tip().hasClass('in') ? 'hide' : 'show']()
258
  }
259
 
260
- , destroy: function ()
261
- {
262
  this.hide().$element.off('.' + this.type).removeData(this.type)
263
  }
264
 
265
  }
266
 
267
-
268
  /* TOOLTIP PLUGIN DEFINITION
269
  * ========================= */
270
 
271
  var old = $.fn.tooltip_tip
272
 
273
- $.fn.tooltip_tip = function (option)
274
- {
275
- return this.each(function ()
276
- {
277
- var $this = $(this)
278
- , data = $this.data('tooltip_tip')
279
- , options = typeof option == 'object' && option
280
  if (!data)
281
  $this.data('tooltip_tip', (data = new Tooltip(this, options)))
282
  if (typeof option == 'string')
@@ -287,38 +280,33 @@
287
  $.fn.tooltip_tip.Constructor = Tooltip
288
 
289
  $.fn.tooltip_tip.defaults = {
290
- animation: true
291
- , placement: 'top'
292
- , selector: false
293
- , template: '<div class="tooltip_tip"><div class="tooltip_tip-arrow"></div><div class="tooltip_tip-inner"></div></div>'
294
- , trigger: 'hover'
295
- , title: ''
296
- , delay: 0
297
- , html: false
298
  }
299
 
300
-
301
  /* TOOLTIP NO CONFLICT
302
  * =================== */
303
 
304
- $.fn.tooltip_tip.noConflict = function ()
305
- {
306
  $.fn.tooltip_tip = old
307
  return this
308
  }
309
 
310
  }(window.jQuery);
311
 
312
-
313
- +function ($)
314
- {
315
  'use strict';
316
 
317
  // TAB CLASS DEFINITION
318
  // ====================
319
 
320
- var Tab = function (element)
321
- {
322
  // jscs:disable requireDollarBeforejQueryAssignment
323
  this.element = $(element)
324
  // jscs:enable requireDollarBeforejQueryAssignment
@@ -328,14 +316,12 @@
328
 
329
  Tab.TRANSITION_DURATION = 150
330
 
331
- Tab.prototype.show = function ()
332
- {
333
  var $this = this.element
334
  var $ul = $this.closest('ul:not(.dropdown-menu)')
335
  var selector = $this.data('target')
336
 
337
- if (!selector)
338
- {
339
  selector = $this.attr('href')
340
  selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
341
  }
@@ -344,14 +330,12 @@
344
  return
345
 
346
  var $previous = $ul.find('.active:last a')
347
- var hideEvent = $.Event('hide.bs.tab',
348
- {
349
- relatedTarget: $this[0]
350
- })
351
- var showEvent = $.Event('show.bs.tab',
352
- {
353
- relatedTarget: $previous[0]
354
- })
355
 
356
  $previous.trigger(hideEvent)
357
  $this.trigger(showEvent)
@@ -362,30 +346,23 @@
362
  var $target = $(selector)
363
 
364
  this.activate($this.closest('li'), $ul)
365
- this.activate($target, $target.parent(), function ()
366
- {
367
- $previous.trigger
368
- ({
369
- type: 'hidden.bs.tab',
370
- relatedTarget: $this[0]
371
- })
372
- $this.trigger(
373
- {
374
- type: 'shown.bs.tab',
375
- relatedTarget: $previous[0]
376
- })
377
  })
378
  }
379
 
380
- Tab.prototype.activate = function (element, container, callback)
381
- {
382
  var $active = container.find('> .active')
383
- var transition = callback
384
- && $.support.transition
385
- && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
386
 
387
- function next()
388
- {
389
  $active
390
  .removeClass('active')
391
  .find('> .dropdown-menu > .active')
@@ -399,17 +376,14 @@
399
  .find('[data-toggle="tab"]')
400
  .attr('aria-expanded', true)
401
 
402
- if (transition)
403
- {
404
  element[0].offsetWidth // reflow for transition
405
  element.addClass('in')
406
- } else
407
- {
408
  element.removeClass('fade')
409
  }
410
 
411
- if (element.parent('.dropdown-menu').length)
412
- {
413
  element
414
  .closest('li.dropdown')
415
  .addClass('active')
@@ -430,14 +404,11 @@
430
  $active.removeClass('in')
431
  }
432
 
433
-
434
  // TAB PLUGIN DEFINITION
435
  // =====================
436
 
437
- function Plugin(option)
438
- {
439
- return this.each(function ()
440
- {
441
  var $this = $(this)
442
  var data = $this.data('bs.tab')
443
 
@@ -453,22 +424,18 @@
453
  $.fn.tab = Plugin
454
  $.fn.tab.Constructor = Tab
455
 
456
-
457
  // TAB NO CONFLICT
458
  // ===============
459
 
460
- $.fn.tab.noConflict = function ()
461
- {
462
  $.fn.tab = old
463
  return this
464
  }
465
 
466
-
467
  // TAB DATA-API
468
  // ============
469
 
470
- var clickHandler = function (e)
471
- {
472
  e.preventDefault()
473
  Plugin.call($(this), 'show')
474
  }
@@ -477,4 +444,4 @@
477
  .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
478
  .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
479
 
480
- }(jQuery);
1
+ !function ($) {
 
2
 
3
  "use strict"; // jshint ;_;
4
 
 
5
  /* TOOLTIP PUBLIC CLASS DEFINITION
6
  * =============================== */
7
 
8
+ var Tooltip = function (element, options) {
 
9
  this.init('tooltip_tip', element, options)
10
  }
11
 
13
 
14
  constructor: Tooltip
15
 
16
+ ,
17
+ init: function (type, element, options) {
18
+ var eventIn, eventOut
 
19
 
20
  this.type = type
21
  this.$element = $(element)
22
  this.options = this.getOptions(options)
23
  this.enabled = true
24
 
25
+ if (this.options.trigger == 'click') {
 
26
  this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
27
+ } else if (this.options.trigger != 'manual') {
 
28
  eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
29
  eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
30
  this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
32
  }
33
 
34
  this.options.selector ?
35
+ (this._options = $.extend({}, this.options, {
36
+ trigger: 'manual',
37
+ selector: ''
38
+ })) :
39
  this.fixTitle()
40
  }
41
 
42
+ ,
43
+ getOptions: function (options) {
44
  options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
45
 
46
+ if (options.delay && typeof options.delay == 'number') {
 
47
  options.delay = {
48
+ show: options.delay,
49
+ hide: options.delay
50
  }
51
  }
52
 
53
  return options
54
  }
55
 
56
+ ,
57
+ enter: function (e) {
58
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
59
 
60
  if (!self.options.delay || !self.options.delay.show)
62
 
63
  clearTimeout(this.timeout)
64
  self.hoverState = 'in'
65
+ this.timeout = setTimeout(function () {
 
66
  if (self.hoverState == 'in')
67
  self.show()
68
  }, self.options.delay.show)
69
  }
70
 
71
+ ,
72
+ leave: function (e) {
73
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
74
 
75
  if (this.timeout)
78
  return self.hide()
79
 
80
  self.hoverState = 'out'
81
+ this.timeout = setTimeout(function () {
 
82
  if (self.hoverState == 'out')
83
  self.hide()
84
  }, self.options.delay.hide)
85
  }
86
 
87
+ ,
88
+ show: function () {
89
+ var $tip, inside, pos, actualWidth, actualHeight, placement, tp
90
+
91
+ if (this.hasContent() && this.enabled) {
 
 
 
 
 
 
 
92
  $tip = this.tip()
93
  this.setContent()
94
 
95
+ if (this.options.animation) {
 
96
  $tip.addClass('fade')
97
  }
98
 
104
 
105
  $tip
106
  .detach()
107
+ .css({
108
+ top: 0,
109
+ left: 0,
110
+ display: 'block'
111
+ })
112
  .insertAfter(this.$element)
113
 
114
  pos = this.getPosition(inside)
116
  actualWidth = $tip[0].offsetWidth
117
  actualHeight = $tip[0].offsetHeight
118
 
119
+ switch (inside ? placement.split(' ')[1] : placement) {
 
120
  case 'bottom':
121
+ tp = {
122
+ top: pos.top + pos.height,
123
+ left: pos.left + pos.width / 2 - actualWidth / 2
124
+ }
125
  break
126
  case 'top':
127
+ tp = {
128
+ top: pos.top - actualHeight,
129
+ left: pos.left + pos.width / 2 - actualWidth / 2
130
+ }
131
  break
132
  case 'left':
133
+ tp = {
134
+ top: pos.top + pos.height / 2 - actualHeight / 2,
135
+ left: pos.left - actualWidth
136
+ }
137
  break
138
  case 'right':
139
+ tp = {
140
+ top: pos.top + pos.height / 2 - actualHeight / 2,
141
+ left: pos.left + pos.width
142
+ }
143
  break
144
  }
145
 
150
  }
151
  }
152
 
153
+ ,
154
+ setContent: function () {
155
+ var $tip = this.tip(),
156
+ title = this.getTitle()
157
 
158
  $tip.find('.tooltip_tip-inner')[this.options.html ? 'html' : 'text'](title)
159
  $tip.removeClass('fade in top bottom left right')
160
  }
161
 
162
+ ,
163
+ hide: function () {
164
+ var that = this,
165
+ $tip = this.tip()
166
 
167
  $tip.removeClass('in')
168
 
169
+ function removeWithAnimation() {
170
+ var timeout = setTimeout(function () {
 
 
171
  $tip.off($.support.transition.end).detach()
172
  }, 500)
173
 
174
+ $tip.one($.support.transition.end, function () {
 
175
  clearTimeout(timeout)
176
  $tip.detach()
177
  })
184
  return this
185
  }
186
 
187
+ ,
188
+ fixTitle: function () {
189
  var $e = this.$element
190
+ if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
 
191
  $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
192
  }
193
  }
194
 
195
+ ,
196
+ hasContent: function () {
197
  return this.getTitle()
198
  }
199
 
200
+ ,
201
+ getPosition: function (inside) {
202
+ return $.extend({}, (inside ? {
203
+ top: 0,
204
+ left: 0
205
+ } : this.$element.offset()), {
206
+ width: this.$element[0].offsetWidth,
207
+ height: this.$element[0].offsetHeight
208
+ })
209
  }
210
 
211
+ ,
212
+ getTitle: function () {
213
+ var title, $e = this.$element,
214
+ o = this.options
 
215
 
216
+ title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
 
217
 
218
  return title
219
  }
220
 
221
+ ,
222
+ tip: function () {
223
  return this.$tip = this.$tip || $(this.options.template)
224
  }
225
 
226
+ ,
227
+ validate: function () {
228
+ if (!this.$element[0].parentNode) {
 
229
  this.hide()
230
  this.$element = null
231
  this.options = null
232
  }
233
  }
234
 
235
+ ,
236
+ enable: function () {
237
  this.enabled = true
238
  }
239
 
240
+ ,
241
+ disable: function () {
242
  this.enabled = false
243
  }
244
 
245
+ ,
246
+ toggleEnabled: function () {
247
  this.enabled = !this.enabled
248
  }
249
 
250
+ ,
251
+ toggle: function (e) {
252
  var self = $(e.currentTarget)[this.type](this._options).data(this.type)
253
  self[self.tip().hasClass('in') ? 'hide' : 'show']()
254
  }
255
 
256
+ ,
257
+ destroy: function () {
258
  this.hide().$element.off('.' + this.type).removeData(this.type)
259
  }
260
 
261
  }
262
 
 
263
  /* TOOLTIP PLUGIN DEFINITION
264
  * ========================= */
265
 
266
  var old = $.fn.tooltip_tip
267
 
268
+ $.fn.tooltip_tip = function (option) {
269
+ return this.each(function () {
270
+ var $this = $(this),
271
+ data = $this.data('tooltip_tip'),
272
+ options = typeof option == 'object' && option
 
 
273
  if (!data)
274
  $this.data('tooltip_tip', (data = new Tooltip(this, options)))
275
  if (typeof option == 'string')
280
  $.fn.tooltip_tip.Constructor = Tooltip
281
 
282
  $.fn.tooltip_tip.defaults = {
283
+ animation: true,
284
+ placement: 'top',
285
+ selector: false,
286
+ template: '<div class="tooltip_tip"><div class="tooltip_tip-arrow"></div><div class="tooltip_tip-inner"></div></div>',
287
+ trigger: 'hover',
288
+ title: '',
289
+ delay: 0,
290
+ html: false
291
  }
292
 
 
293
  /* TOOLTIP NO CONFLICT
294
  * =================== */
295
 
296
+ $.fn.tooltip_tip.noConflict = function () {
 
297
  $.fn.tooltip_tip = old
298
  return this
299
  }
300
 
301
  }(window.jQuery);
302
 
303
+ +function ($) {
 
 
304
  'use strict';
305
 
306
  // TAB CLASS DEFINITION
307
  // ====================
308
 
309
+ var Tab = function (element) {
 
310
  // jscs:disable requireDollarBeforejQueryAssignment
311
  this.element = $(element)
312
  // jscs:enable requireDollarBeforejQueryAssignment
316
 
317
  Tab.TRANSITION_DURATION = 150
318
 
319
+ Tab.prototype.show = function () {
 
320
  var $this = this.element
321
  var $ul = $this.closest('ul:not(.dropdown-menu)')
322
  var selector = $this.data('target')
323
 
324
+ if (!selector) {
 
325
  selector = $this.attr('href')
326
  selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
327
  }
330
  return
331
 
332
  var $previous = $ul.find('.active:last a')
333
+ var hideEvent = $.Event('hide.bs.tab', {
334
+ relatedTarget: $this[0]
335
+ })
336
+ var showEvent = $.Event('show.bs.tab', {
337
+ relatedTarget: $previous[0]
338
+ })
 
 
339
 
340
  $previous.trigger(hideEvent)
341
  $this.trigger(showEvent)
346
  var $target = $(selector)
347
 
348
  this.activate($this.closest('li'), $ul)
349
+ this.activate($target, $target.parent(), function () {
350
+ $previous.trigger({
351
+ type: 'hidden.bs.tab',
352
+ relatedTarget: $this[0]
353
+ })
354
+ $this.trigger({
355
+ type: 'shown.bs.tab',
356
+ relatedTarget: $previous[0]
357
+ })
 
 
 
358
  })
359
  }
360
 
361
+ Tab.prototype.activate = function (element, container, callback) {
 
362
  var $active = container.find('> .active')
363
+ var transition = callback && $.support.transition && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
 
 
364
 
365
+ function next() {
 
366
  $active
367
  .removeClass('active')
368
  .find('> .dropdown-menu > .active')
376
  .find('[data-toggle="tab"]')
377
  .attr('aria-expanded', true)
378
 
379
+ if (transition) {
 
380
  element[0].offsetWidth // reflow for transition
381
  element.addClass('in')
382
+ } else {
 
383
  element.removeClass('fade')
384
  }
385
 
386
+ if (element.parent('.dropdown-menu').length) {
 
387
  element
388
  .closest('li.dropdown')
389
  .addClass('active')
404
  $active.removeClass('in')
405
  }
406
 
 
407
  // TAB PLUGIN DEFINITION
408
  // =====================
409
 
410
+ function Plugin(option) {
411
+ return this.each(function () {
 
 
412
  var $this = $(this)
413
  var data = $this.data('bs.tab')
414
 
424
  $.fn.tab = Plugin
425
  $.fn.tab.Constructor = Tab
426
 
 
427
  // TAB NO CONFLICT
428
  // ===============
429
 
430
+ $.fn.tab.noConflict = function () {
 
431
  $.fn.tab = old
432
  return this
433
  }
434
 
 
435
  // TAB DATA-API
436
  // ============
437
 
438
+ var clickHandler = function (e) {
 
439
  e.preventDefault()
440
  Plugin.call($(this), 'show')
441
  }
444
  .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
445
  .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
446
 
447
+ }(jQuery);
assets/global/plugins/datatables/media/css/datatables.foundation.css CHANGED
@@ -138,4 +138,4 @@ div.dataTables_scrollFoot table
138
  {
139
  margin-top: 0 !important;
140
  border-top: none;
141
- }
138
  {
139
  margin-top: 0 !important;
140
  border-top: none;
141
+ }
assets/global/plugins/datatables/media/js/buttons.html5.js ADDED
@@ -0,0 +1,419 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function (g) {
2
+ "function" === typeof define && define.amd ? define(["jquery", "datatables.net", "datatables.net-buttons"], function (d) {
3
+ return g(d, window, document);
4
+ }) : "object" === typeof exports ? module.exports = function (d, f) {
5
+ d || (d = window);
6
+ if (!f || !f.fn.dataTable)
7
+ f = require("datatables.net")(d, f).$;
8
+ f.fn.dataTable.Buttons || require("datatables.net-buttons")(d, f);
9
+ return g(f, d, d.document);
10
+ } : g(jQuery, window, document);
11
+ })(function (g, d, f, k) {
12
+ var l = g.fn.dataTable,
13
+ j;
14
+ if ("undefined" !== typeof navigator && /MSIE [1-9]\./.test(navigator.userAgent))
15
+ j =
16
+ void 0;
17
+ else {
18
+ var x = d.document,
19
+ q = x.createElementNS("http://www.w3.org/1999/xhtml", "a"),
20
+ E = "download" in q,
21
+ r = d.webkitRequestFileSystem,
22
+ y = d.requestFileSystem || r || d.mozRequestFileSystem,
23
+ F = function (a) {
24
+ (d.setImmediate || d.setTimeout)(function () {
25
+ throw a;
26
+ }, 0);
27
+ },
28
+ s = 0,
29
+ t = function (a) {
30
+ var b = function () {
31
+ "string" === typeof a ? (d.URL || d.webkitURL || d).revokeObjectURL(a) : a.remove();
32
+ };
33
+ d.chrome ? b() : setTimeout(b, 500);
34
+ },
35
+ u = function (a, b, e) {
36
+ for (var b = [].concat(b), c = b.length; c--; ) {
37
+ var d = a["on" + b[c]];
38
+ if ("function" === typeof d)
39
+ try {
40
+ d.call(a,
41
+ e || a);
42
+ } catch (i) {
43
+ F(i);
44
+ }
45
+ }
46
+ },
47
+ A = function (a) {
48
+ return /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type) ? new Blob(["", a], {
49
+ type: a.type
50
+ }) : a;
51
+ },
52
+ B = function (a, b) {
53
+ var a = A(a),
54
+ e = this,
55
+ c = a.type,
56
+ z = !1,
57
+ i, g, m = function () {
58
+ u(e, ["writestart", "progress", "write", "writeend"]);
59
+ },
60
+ o = function () {
61
+ if (z || !i)
62
+ i = (d.URL || d.webkitURL || d).createObjectURL(a);
63
+ g ? g.location.href = i : d.open(i, "_blank") === k && "undefined" !== typeof safari && (d.location.href = i);
64
+ e.readyState = e.DONE;
65
+ m();
66
+ t(i);
67
+ },
68
+ n = function (a) {
69
+ return function () {
70
+ if (e.readyState !==
71
+ e.DONE)
72
+ return a.apply(this, arguments);
73
+ };
74
+ },
75
+ f = {
76
+ create: !0,
77
+ exclusive: !1
78
+ },
79
+ h;
80
+ e.readyState = e.INIT;
81
+ b || (b = "download");
82
+ if (E)
83
+ i = (d.URL || d.webkitURL || d).createObjectURL(a), q.href = i, q.download = b, c = x.createEvent("MouseEvents"), c.initMouseEvent("click", !0, !1, d, 0, 0, 0, 0, 0, !1, !1, !1, !1, 0, null), q.dispatchEvent(c), e.readyState = e.DONE, m(), t(i);
84
+ else {
85
+ d.chrome && (c && "application/octet-stream" !== c) && (h = a.slice || a.webkitSlice, a = h.call(a, 0, a.size, "application/octet-stream"), z = !0);
86
+ r && "download" !== b && (b += ".download");
87
+ if ("application/octet-stream" ===
88
+ c || r)
89
+ g = d;
90
+ y ? (s += a.size, y(d.TEMPORARY, s, n(function (c) {
91
+ c.root.getDirectory("saved", f, n(function (c) {
92
+ var d = function () {
93
+ c.getFile(b, f, n(function (b) {
94
+ b.createWriter(n(function (c) {
95
+ c.onwriteend = function (a) {
96
+ g.location.href = b.toURL();
97
+ e.readyState = e.DONE;
98
+ u(e, "writeend", a);
99
+ t(b);
100
+ };
101
+ c.onerror = function () {
102
+ var a = c.error;
103
+ a.code !== a.ABORT_ERR && o();
104
+ };
105
+ ["writestart", "progress", "write", "abort"].forEach(function (a) {
106
+ c["on" + a] = e["on" + a];
107
+ });
108
+ c.write(a);
109
+ e.abort = function () {
110
+ c.abort();
111
+ e.readyState = e.DONE;
112
+ };
113
+ e.readyState = e.WRITING;
114
+ }), o);
115
+ }),
116
+ o);
117
+ };
118
+ c.getFile(b, {
119
+ create: false
120
+ }, n(function (a) {
121
+ a.remove();
122
+ d();
123
+ }), n(function (a) {
124
+ a.code === a.NOT_FOUND_ERR ? d() : o();
125
+ }));
126
+ }), o);
127
+ }), o)) : o();
128
+ }
129
+ },
130
+ h = B.prototype;
131
+ "undefined" !== typeof navigator && navigator.msSaveOrOpenBlob ? j = function (a, b) {
132
+ return navigator.msSaveOrOpenBlob(A(a), b);
133
+ } : (h.abort = function () {
134
+ this.readyState = this.DONE;
135
+ u(this, "abort");
136
+ }, h.readyState = h.INIT = 0, h.WRITING = 1, h.DONE = 2, h.error = h.onwritestart = h.onprogress = h.onwrite = h.onabort = h.onerror = h.onwriteend = null, j = function (a, b) {
137
+ return new B(a, b);
138
+ });
139
+ }
140
+ var v = function (a,
141
+ b) {
142
+ var e = "*" === a.filename && "*" !== a.title && a.title !== k ? a.title : a.filename;
143
+ "function" === typeof e && (e = e());
144
+ -1 !== e.indexOf("*") && (e = e.replace("*", g("title").text()));
145
+ e = e.replace(/[^a-zA-Z0-9_\u00A1-\uFFFF\.,\-_ !\(\)]/g, "");
146
+ return b === k || !0 === b ? e + a.extension : e;
147
+ },
148
+ G = function (a) {
149
+ var b = "Sheet1";
150
+ a.sheetName && (b = a.sheetName.replace(/[\[\]\*\/\\\?\:]/g, ""));
151
+ return b;
152
+ },
153
+ H = function (a) {
154
+ a = a.title;
155
+ "function" === typeof a && (a = a());
156
+ return -1 !== a.indexOf("*") ? a.replace("*", g("title").text()) : a;
157
+ },
158
+ w = function (a) {
159
+ return a.newline ?
160
+ a.newline : navigator.userAgent.match(/Windows/) ? "\r\n" : "\n";
161
+ },
162
+ C = function (a, b) {
163
+ for (var e = w(b), c = a.buttons.exportData(b.exportOptions), d = b.fieldBoundary, i = b.fieldSeparator, g = RegExp(d, "g"), m = b.escapeChar !== k ? b.escapeChar : "\\", f = function (a) {
164
+ for (var b = "", c = 0, e = a.length; c < e; c++)
165
+ 0 < c && (b += i), b += d ? d + ("" + a[c]).replace(g, m + d) + d : a[c];
166
+ return b;
167
+ }, n = b.header ? f(c.header) + e : "", h = b.footer && c.footer ? e + f(c.footer) : "", j = [], l = 0, p = c.body.length; l < p; l++)
168
+ j.push(f(c.body[l]));
169
+ return {
170
+ str: n + j.join(e) + h,
171
+ rows: j.length
172
+ };
173
+ },
174
+ D = function () {
175
+ return -1 !==
176
+ navigator.userAgent.indexOf("Safari") && -1 === navigator.userAgent.indexOf("Chrome") && -1 === navigator.userAgent.indexOf("Opera");
177
+ },
178
+ p = {
179
+ "_rels/.rels": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\t<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>',
180
+ "xl/_rels/workbook.xml.rels": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\t<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/></Relationships>',
181
+ "[Content_Types].xml": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">\t<Default Extension="xml" ContentType="application/xml"/>\t<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\t<Default Extension="jpeg" ContentType="image/jpeg"/>\t<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>\t<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/></Types>',
182
+ "xl/workbook.xml": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">\t<fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="24816"/>\t<workbookPr showInkAnnotation="0" autoCompressPictures="0"/>\t<bookViews>\t\t<workbookView xWindow="0" yWindow="0" windowWidth="25600" windowHeight="19020" tabRatio="500"/>\t</bookViews>\t<sheets>\t\t<sheet name="__SHEET_NAME__" sheetId="1" r:id="rId1"/>\t</sheets></workbook>',
183
+ "xl/worksheets/sheet1.xml": '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">\t<sheetData>\t\t__DATA__\t</sheetData></worksheet>'
184
+ };
185
+ l.ext.buttons.copyHtml5 = {
186
+ className: "buttons-copy buttons-html5",
187
+ text: function (a) {
188
+ return a.i18n("buttons.copy", "Copy");
189
+ },
190
+ action: function (a, b, e, c) {
191
+ var a = C(b, c),
192
+ d = a.str,
193
+ e = g("<div/>").css({
194
+ height: 1,
195
+ width: 1,
196
+ overflow: "hidden",
197
+ position: "fixed",
198
+ top: 0,
199
+ left: 0
200
+ });
201
+ c.customize && (d = c.customize(d, c));
202
+ c = g("<textarea readonly/>").val(d).appendTo(e);
203
+ if (f.queryCommandSupported("copy")) {
204
+ e.appendTo(b.table().container());
205
+ c[0].focus();
206
+ c[0].select();
207
+ try {
208
+ f.execCommand("copy");
209
+ e.remove();
210
+ b.buttons.info(b.i18n("buttons.copyTitle", "Copy to clipboard"), b.i18n("buttons.copySuccess", {
211
+ 1: "Copied one row to clipboard",
212
+ _: "Copied %d rows to clipboard"
213
+ }, a.rows), 2E3);
214
+ return;
215
+ } catch (i) {
216
+ }
217
+ }
218
+ a = g("<span>" + b.i18n("buttons.copyKeys", "Press <i>ctrl</i> or <i>⌘</i> + <i>C</i> to copy the table data<br>to your system clipboard.<br><br>To cancel, click this message or press escape.") + "</span>").append(e);
219
+ b.buttons.info(b.i18n("buttons.copyTitle", "Copy to clipboard"), a, 0);
220
+ c[0].focus();
221
+ c[0].select();
222
+ var h = g(a).closest(".dt-button-info"),
223
+ m = function () {
224
+ h.off("click.buttons-copy");
225
+ g(f).off(".buttons-copy");
226
+ b.buttons.info(!1);
227
+ };
228
+ h.on("click.buttons-copy",
229
+ m);
230
+ g(f).on("keydown.buttons-copy", function (a) {
231
+ 27 === a.keyCode && m();
232
+ }).on("copy.buttons-copy cut.buttons-copy", function () {
233
+ m();
234
+ });
235
+ },
236
+ exportOptions: {},
237
+ fieldSeparator: "\t",
238
+ fieldBoundary: "",
239
+ header: !0,
240
+ footer: !1
241
+ };
242
+ l.ext.buttons.csvHtml5 = {
243
+ className: "buttons-csv buttons-html5",
244
+ available: function () {
245
+ return d.FileReader !== k && d.Blob;
246
+ },
247
+ text: function (a) {
248
+ return a.i18n("buttons.csv", "CSV");
249
+ },
250
+ action: function (a, b, d, c) {
251
+ w(c);
252
+ a = C(b, c).str;
253
+ b = c.charset;
254
+ c.customize && (a = c.customize(a, c));
255
+ !1 !== b ? (b || (b = f.characterSet || f.charset), b &&
256
+ (b = ";charset=" + b)) : b = "";
257
+ j(new Blob([a], {
258
+ type: "text/csv" + b
259
+ }), v(c));
260
+ },
261
+ filename: "*",
262
+ extension: ".csv",
263
+ exportOptions: {},
264
+ fieldSeparator: ",",
265
+ fieldBoundary: '"',
266
+ escapeChar: '"',
267
+ charset: null,
268
+ header: !0,
269
+ footer: !1
270
+ };
271
+ l.ext.buttons.excelHtml5 = {
272
+ className: "buttons-excel buttons-html5",
273
+ available: function () {
274
+ return d.FileReader !== k && d.JSZip !== k && !D();
275
+ },
276
+ text: function (a) {
277
+ return a.i18n("buttons.excel", "Export To Excel");
278
+ },
279
+ action: function (a, b, e, c) {
280
+ a = "";
281
+ b = b.buttons.exportData(c.exportOptions);
282
+ e = function (a) {
283
+ for (var b = [], c = 0, d = a.length; c <
284
+ d; c++) {
285
+ if (null === a[c] || a[c] === k)
286
+ a[c] = "";
287
+ b.push("number" === typeof a[c] || a[c].match && g.trim(a[c]).match(/^-?\d+(\.\d+)?$/) && "0" !== a[c].charAt(0) ? '<c t="n"><v>' + a[c] + "</v></c>" : '<c t="inlineStr"><is><t>' + (!a[c].replace ? a[c] : a[c].replace(/&(?!amp;)/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, "")) + "</t></is></c>");
288
+ }
289
+ return "<row>" + b.join("") + "</row>";
290
+ };
291
+ c.header && (a += e(b.header));
292
+ for (var f = 0, i = b.body.length; f < i; f++)
293
+ a += e(b.body[f]);
294
+ c.footer && (a += e(b.footer));
295
+ var b = new d.JSZip,
296
+ e = b.folder("_rels"),
297
+ f = b.folder("xl"),
298
+ i = b.folder("xl/_rels"),
299
+ h = b.folder("xl/worksheets");
300
+ b.file("[Content_Types].xml", p["[Content_Types].xml"]);
301
+ e.file(".rels", p["_rels/.rels"]);
302
+ f.file("workbook.xml", p["xl/workbook.xml"].replace("__SHEET_NAME__", G(c)));
303
+ i.file("workbook.xml.rels", p["xl/_rels/workbook.xml.rels"]);
304
+ h.file("sheet1.xml", p["xl/worksheets/sheet1.xml"].replace("__DATA__", a));
305
+ j(b.generate({
306
+ type: "blob",
307
+ mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
308
+ }),
309
+ v(c));
310
+ },
311
+ filename: "*",
312
+ extension: ".xlsx",
313
+ exportOptions: {},
314
+ header: !0,
315
+ footer: !1
316
+ };
317
+ l.ext.buttons.pdfHtml5 = {
318
+ className: "buttons-pdf buttons-html5",
319
+ available: function () {
320
+ return d.FileReader !== k && d.pdfMake;
321
+ },
322
+ text: function (a) {
323
+ return a.i18n("buttons.pdf", "PDF");
324
+ },
325
+ action: function (a, b, e, c) {
326
+ w(c);
327
+ a = b.buttons.exportData(c.exportOptions);
328
+ b = [];
329
+ c.header && b.push(g.map(a.header, function (a) {
330
+ return {
331
+ text: "string" === typeof a ? a : a + "",
332
+ style: "tableHeader"
333
+ };
334
+ }));
335
+ for (var f = 0, e = a.body.length; f < e; f++)
336
+ b.push(g.map(a.body[f], function (a) {
337
+ return {
338
+ text: "string" ===
339
+ typeof a ? a : a + "",
340
+ style: f % 2 ? "tableBodyEven" : "tableBodyOdd"
341
+ };
342
+ }));
343
+ c.footer && b.push(g.map(a.footer, function (a) {
344
+ return {
345
+ text: "string" === typeof a ? a : a + "",
346
+ style: "tableFooter"
347
+ };
348
+ }));
349
+ a = {
350
+ pageSize: c.pageSize,
351
+ pageOrientation: c.orientation,
352
+ content: [{
353
+ table: {
354
+ headerRows: 1,
355
+ body: b
356
+ },
357
+ layout: "noBorders"
358
+ }],
359
+ styles: {
360
+ tableHeader: {
361
+ bold: !0,
362
+ fontSize: 11,
363
+ color: "white",
364
+ fillColor: "#2d4154",
365
+ alignment: "center"
366
+ },
367
+ tableBodyEven: {},
368
+ tableBodyOdd: {
369
+ fillColor: "#f3f3f3"
370
+ },
371
+ tableFooter: {
372
+ bold: !0,
373
+ fontSize: 11,
374
+ color: "white",
375
+ fillColor: "#2d4154"
376
+ },
377
+ title: {
378
+ alignment: "center",
379
+ fontSize: 15
380
+ },
381
+ message: {}
382
+ },
383
+ defaultStyle: {
384
+ fontSize: 10
385
+ }
386
+ };
387
+ c.message && a.content.unshift({
388
+ text: c.message,
389
+ style: "message",
390
+ margin: [0, 0, 0, 12]
391
+ });
392
+ c.title && a.content.unshift({
393
+ text: H(c, !1),
394
+ style: "title",
395
+ margin: [0, 0, 0, 12]
396
+ });
397
+ c.customize && c.customize(a, c);
398
+ a = d.pdfMake.createPdf(a);
399
+ "open" === c.download && !D() ? a.open() : a.getBuffer(function (a) {
400
+ a = new Blob([a], {
401
+ type: "application/pdf"
402
+ });
403
+ j(a, v(c));
404
+ });
405
+ },
406
+ title: "*",
407
+ filename: "*",
408
+ extension: ".pdf",
409
+ exportOptions: {},
410
+ orientation: "portrait",
411
+ pageSize: "A4",
412
+ header: !0,
413
+ footer: !1,
414
+ message: null,
415
+ customize: null,
416
+ download: "download"
417
+ };
418
+ return l.Buttons;
419
+ });
assets/global/plugins/datatables/media/js/datatables.buttons.js ADDED
@@ -0,0 +1,570 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ !function (t) {
2
+ "function" === typeof define && define.amd ? define(["jquery", "datatables.net"], function (n) {
3
+ return t(n, window, document);
4
+ }) : "object" === typeof exports ? module.exports = function (n, e) {
5
+ return n || (n = window), e && e.fn.dataTable || (e = require("datatables.net")(n, e).$), t(e, n, n.document);
6
+ } : t(jQuery, window, document);
7
+ }(function (t, n, e, o) {
8
+ var i = t.fn.dataTable,
9
+ s = 0,
10
+ r = 0,
11
+ a = i.ext.buttons,
12
+ u = function (n, e) {
13
+ !0 === e && (e = {}), t.isArray(e) && (e = {
14
+ buttons: e
15
+ }), this.c = t.extend(!0, {}, u.defaults, e), e.buttons && (this.c.buttons = e.buttons), this.s = {
16
+ dt: new i.Api(n),
17
+ buttons: [],
18
+ subButtons: [],
19
+ listenKeys: "",
20
+ namespace: "dtb" + s++
21
+ }, this.dom = {
22
+ container: t("<" + this.c.dom.container.tag + "/>").addClass(this.c.dom.container.className)
23
+ }, this._constructor();
24
+ };
25
+ t.extend(u.prototype, {
26
+ action: function (t, n) {
27
+ var e = this._indexToButton(t).conf;
28
+ return n === o ? e.action : (e.action = n, this);
29
+ },
30
+ active: function (t, n) {
31
+ var e = this._indexToButton(t),
32
+ i = this.c.dom.button.active;
33
+ return n === o ? e.node.hasClass(i) : (e.node.toggleClass(i, n === o ? !0 : n), this);
34
+ },
35
+ add: function (t, n) {
36
+ if ("string" === typeof t && -1 !== t.indexOf("-")) {
37
+ var e = t.split("-");
38
+ this.c.buttons[1 * e[0]].buttons.splice(1 * e[1], 0, n);
39
+ } else
40
+ this.c.buttons.splice(1 * t, 0, n);
41
+ return this.dom.container.empty(), this._buildButtons(this.c.buttons), this;
42
+ },
43
+ container: function () {
44
+ return this.dom.container;
45
+ },
46
+ disable: function (t) {
47
+ return this._indexToButton(t).node.addClass(this.c.dom.button.disabled), this;
48
+ },
49
+ destroy: function () {
50
+ t("body").off("keyup." + this.s.namespace);
51
+ var n, e, o, i = this.s.buttons,
52
+ s = this.s.subButtons;
53
+ for (n = 0, i = i.length; i > n; n++)
54
+ for (this.removePrep(n), e = 0, o = s[n].length; o > e; e++)
55
+ this.removePrep(n + "-" + e);
56
+ for (this.removeCommit(), this.dom.container.remove(), s = this.s.dt.settings()[0], n = 0, i = s.length; i > n; n++)
57
+ if (s.inst === this) {
58
+ s.splice(n, 1);
59
+ break
60
+ }
61
+ return this;
62
+ },
63
+ enable: function (t, n) {
64
+ return !1 === n ? this.disable(t) : (this._indexToButton(t).node.removeClass(this.c.dom.button.disabled), this);
65
+ },
66
+ name: function () {
67
+ return this.c.name;
68
+ },
69
+ node: function (t) {
70
+ return this._indexToButton(t).node;
71
+ },
72
+ removeCommit: function () {
73
+ var t, n, e = this.s.buttons,
74
+ o = this.s.subButtons;
75
+ for (t = e.length - 1; t >= 0; t--)
76
+ null === e[t] && (e.splice(t, 1), o.splice(t, 1), this.c.buttons.splice(t, 1));
77
+ for (t = 0, e = o.length; e > t; t++)
78
+ for (n = o[t].length - 1; n >= 0; n--)
79
+ null === o[t][n] && (o[t].splice(n, 1), this.c.buttons[t].buttons.splice(n, 1));
80
+ return this;
81
+ },
82
+ removePrep: function (t) {
83
+ var n, e = this.s.dt;
84
+ if ("number" == typeof t || -1 === t.indexOf("-"))
85
+ n = this.s.buttons[1 * t], n.conf.destroy && n.conf.destroy.call(e.button(t), e, n, n.conf), n.node.remove(), this._removeKey(n.conf), this.s.buttons[1 * t] = null;
86
+ else {
87
+ var o = t.split("-");
88
+ n = this.s.subButtons[1 * o[0]][1 * o[1]], n.conf.destroy && n.conf.destroy.call(e.button(t), e, n, n.conf), n.node.remove(), this._removeKey(n.conf), this.s.subButtons[1 * o[0]][1 * o[1]] = null;
89
+ }
90
+ return this;
91
+ },
92
+ text: function (t, n) {
93
+ var e = this._indexToButton(t),
94
+ i = this.c.dom.collection.buttonLiner,
95
+ i = "string" === typeof t && -1 !== t.indexOf("-") && i && i.tag ? i.tag : this.c.dom.buttonLiner.tag,
96
+ s = this.s.dt,
97
+ r = function (t) {
98
+ return "function" === typeof t ? t(s, e.node, e.conf) : t;
99
+ };
100
+ return n === o ? r(e.conf.text) : (e.conf.text = n, i ? e.node.children(i).html(r(n)) : e.node.html(r(n)), this);
101
+ },
102
+ toIndex: function (t) {
103
+ var n, e, o, i;
104
+ o = this.s.buttons;
105
+ var s = this.s.subButtons;
106
+ for (n = 0, e = o.length; e > n; n++)
107
+ if (o[n].node[0] === t)
108
+ return n + "";
109
+ for (n = 0, e = s.length; e > n; n++)
110
+ for (o = 0, i = s[n].length; i > o; o++)
111
+ if (s[n][o].node[0] === t)
112
+ return n + "-" + o;
113
+ },
114
+ _constructor: function () {
115
+ var n = this,
116
+ o = this.s.dt,
117
+ i = o.settings()[0];
118
+ i._buttons || (i._buttons = []), i._buttons.push({
119
+ inst: this,
120
+ name: this.c.name
121
+ }), this._buildButtons(this.c.buttons), o.on("destroy", function () {
122
+ n.destroy();
123
+ }), t("body").on("keyup." + this.s.namespace, function (t) {
124
+ if (!e.activeElement || e.activeElement === e.body) {
125
+ var o = String.fromCharCode(t.keyCode).toLowerCase();
126
+ -1 !== n.s.listenKeys.toLowerCase().indexOf(o) && n._keypress(o, t);
127
+ }
128
+ });
129
+ },
130
+ _addKey: function (n) {
131
+ n.key && (this.s.listenKeys += t.isPlainObject(n.key) ? n.key.key : n.key);
132
+ },
133
+ _buildButtons: function (n, e, i) {
134
+ var s = this.s.dt,
135
+ r = 0;
136
+ e || (e = this.dom.container, this.s.buttons = [], this.s.subButtons = []);
137
+ for (var a = 0, u = n.length; u > a; a++) {
138
+ var c = this._resolveExtends(n[a]);
139
+ if (c)
140
+ if (t.isArray(c))
141
+ this._buildButtons(c, e, i);
142
+ else {
143
+ var l = this._buildButton(c, i !== o ? !0 : !1);
144
+ if (l) {
145
+ var d = l.node;
146
+ e.append(l.inserter), i === o ? (this.s.buttons.push({
147
+ node: d,
148
+ conf: c,
149
+ inserter: l.inserter
150
+ }), this.s.subButtons.push([])) : this.s.subButtons[i].push({
151
+ node: d,
152
+ conf: c,
153
+ inserter: l.inserter
154
+ }), c.buttons && (l = this.c.dom.collection, c._collection = t("<" + l.tag + "/>").addClass(l.className), this._buildButtons(c.buttons, c._collection, r)), c.init && c.init.call(s.button(d), s, d, c), r++;
155
+ }
156
+ }
157
+ }
158
+ },
159
+ _buildButton: function (n, e) {
160
+ var o = this.c.dom.button,
161
+ i = this.c.dom.buttonLiner,
162
+ s = this.c.dom.collection,
163
+ a = this.s.dt,
164
+ u = function (t) {
165
+ return "function" == typeof t ? t(a, l, n) : t;
166
+ };
167
+ if (e && s.button && (o = s.button), e && s.buttonLiner && (i = s.buttonLiner), n.available && !n.available(a, n))
168
+ return !1;
169
+ var c = function (n, e, o, i) {
170
+ i.action.call(e.button(o), n, e, o, i), t(e.table().node()).triggerHandler("buttons-action.dt", [e.button(o), e, o, i]);
171
+ },
172
+ l = t("<" + o.tag + "/>").addClass(o.className).attr("tabindex", this.s.dt.settings()[0].iTabIndex).attr("aria-controls", this.s.dt.table().node().id).on("click.dtb", function (t) {
173
+ t.preventDefault(), !l.hasClass(o.disabled) && n.action && c(t, a, l, n), l.blur();
174
+ }).on("keyup.dtb", function (t) {
175
+ 13 === t.keyCode && !l.hasClass(o.disabled) && n.action && c(t, a, l, n);
176
+ });
177
+ return i.tag ? l.append(t("<" + i.tag + "/>").html(u(n.text)).addClass(i.className)) : l.html(u(n.text)), !1 === n.enabled && l.addClass(o.disabled), n.className && l.addClass(n.className), n.titleAttr && l.attr("title", n.titleAttr), n.namespace || (n.namespace = ".dt-button-" + r++), i = (i = this.c.dom.buttonContainer) && i.tag ? t("<" + i.tag + "/>").addClass(i.className).append(l) : l, this._addKey(n), {
178
+ node: l,
179
+ inserter: i
180
+ };
181
+ },
182
+ _indexToButton: function (t) {
183
+ return "number" === typeof t || -1 === t.indexOf("-") ? this.s.buttons[1 * t] : (t = t.split("-"), this.s.subButtons[1 * t[0]][1 * t[1]]);
184
+ },
185
+ _keypress: function (n, e) {
186
+ var o, i, s, r;
187
+ s = this.s.buttons;
188
+ var a = this.s.subButtons,
189
+ u = function (o, i) {
190
+ o.key && (o.key === n ? i.click() : !t.isPlainObject(o.key) || o.key.key !== n || o.key.shiftKey && !e.shiftKey || (!o.key.altKey || e.altKey) && (!o.key.ctrlKey || e.ctrlKey) && (!o.key.metaKey || e.metaKey) && i.click());
191
+ };
192
+ for (o = 0, i = s.length; i > o; o++)
193
+ u(s[o].conf, s[o].node);
194
+ for (o = 0, i = a.length; i > o; o++)
195
+ for (s = 0, r = a[o].length; r > s; s++)
196
+ u(a[o][s].conf, a[o][s].node);
197
+ },
198
+ _removeKey: function (n) {
199
+ if (n.key) {
200
+ var e = t.isPlainObject(n.key) ? n.key.key : n.key,
201
+ n = this.s.listenKeys.split(""),
202
+ e = t.inArray(e, n);
203
+ n.splice(e, 1), this.s.listenKeys = n.join("");
204
+ }
205
+ },
206
+ _resolveExtends: function (n) {
207
+ for (var e, i, s = this.s.dt, r = function (e) {
208
+ for (var i = 0; !t.isPlainObject(e) && !t.isArray(e); ) {
209
+ if (e === o)
210
+ return;
211
+ if ("function" === typeof e) {
212
+ if (e = e(s, n), !e)
213
+ return !1;
214
+ } else if ("string" === typeof e) {
215
+ if (!a[e])
216
+ throw "Unknown button type: " + e;
217
+ e = a[e];
218
+ }
219
+ if (i++, i > 30)
220
+ throw "Buttons: Too many iterations";
221
+ }
222
+ return t.isArray(e) ? e : t.extend({}, e);
223
+ }, n = r(n); n && n.extend; ) {
224
+ if (!a[n.extend])
225
+ throw "Cannot extend unknown button type: " + n.extend;
226
+ var u = r(a[n.extend]);
227
+ if (t.isArray(u))
228
+ return u;
229
+ if (!u)
230
+ return !1;
231
+ e = u.className, n = t.extend({}, u, n), e && n.className !== e && (n.className = e + " " + n.className);
232
+ var c = n.postfixButtons;
233
+ if (c) {
234
+ for (n.buttons || (n.buttons = []), e = 0, i = c.length; i > e; e++)
235
+ n.buttons.push(c[e]);
236
+ n.postfixButtons = null;
237
+ }
238
+ if (c = n.prefixButtons) {
239
+ for (n.buttons || (n.buttons = []), e = 0, i = c.length; i > e; e++)
240
+ n.buttons.splice(e, 0, c[e]);
241
+ n.prefixButtons = null;
242
+ }
243
+ n.extend = u.extend;
244
+ }
245
+ return n;
246
+ }
247
+ }), u.background = function (n, e, i) {
248
+ i === o && (i = 400), n ? t("<div/>").addClass(e).css("display", "none").appendTo("body").fadeIn(i) : t("body > div." + e).fadeOut(i, function () {
249
+ t(this).remove();
250
+ });
251
+ }, u.instanceSelector = function (n, e) {
252
+ if (!n)
253
+ return t.map(e, function (t) {
254
+ return t.inst;
255
+ });
256
+ var o = [],
257
+ i = t.map(e, function (t) {
258
+ return t.name;
259
+ }),
260
+ s = function (n) {
261
+ if (t.isArray(n))
262
+ for (var r = 0, a = n.length; a > r; r++)
263
+ s(n[r]);
264
+ else
265
+ "string" === typeof n ? -1 !== n.indexOf(",") ? s(n.split(",")) : (n = t.inArray(t.trim(n), i), -1 !== n && o.push(e[n].inst)) : "number" === typeof n && o.push(e[n].inst);
266
+ };
267
+ return s(n), o;
268
+ }, u.buttonSelector = function (n, e) {
269
+ for (var i = [], s = function (n, e) {
270
+ var r, a, u = [];
271
+ if (t.each(e.s.buttons, function (t, n) {
272
+ null !== n && u.push({
273
+ node: n.node[0],
274
+ name: n.conf.name
275
+ });
276
+ }), t.each(e.s.subButtons, function (n, e) {
277
+ t.each(e, function (t, n) {
278
+ null !== n && u.push({
279
+ node: n.node[0],
280
+ name: n.conf.name
281
+ });
282
+ });
283
+ }), r = t.map(u, function (t) {
284
+ return t.node;
285
+ }), t.isArray(n) || n instanceof t)
286
+ for (r = 0, a = n.length; a > r; r++)
287
+ s(n[r], e);
288
+ else if (null === n || n === o || "*" === n)
289
+ for (r = 0, a = u.length; a > r; r++)
290
+ i.push({
291
+ inst: e,
292
+ idx: e.toIndex(u[r].node)
293
+ });
294
+ else if ("number" === typeof n)
295
+ i.push({
296
+ inst: e,
297
+ idx: n
298
+ });
299
+ else if ("string" === typeof n)
300
+ if (-1 !== n.indexOf(",")) {
301
+ var c = n.split(",");
302
+ for (r = 0, a = c.length; a > r; r++)
303
+ s(t.trim(c[r]), e);
304
+ } else if (n.match(/^\d+(\-\d+)?$/))
305
+ i.push({
306
+ inst: e,
307
+ idx: n
308
+ });
309
+ else if (-1 !== n.indexOf(":name"))
310
+ for (c = n.replace(":name", ""), r = 0, a = u.length; a > r; r++)
311
+ u[r].name === c && i.push({
312
+ inst: e,
313
+ idx: e.toIndex(u[r].node)
314
+ });
315
+ else
316
+ t(r).filter(n).each(function () {
317
+ i.push({
318
+ inst: e,
319
+ idx: e.toIndex(this)
320
+ });
321
+ });
322
+ else
323
+ "object" === typeof n && n.nodeName && (a = t.inArray(n, r), -1 !== a && i.push({
324
+ inst: e,
325
+ idx: e.toIndex(r[a])
326
+ }));
327
+ }, r = 0, a = n.length; a > r; r++)
328
+ s(e, n[r]);
329
+ return i;
330
+ }, u.defaults = {
331
+ buttons: ["copy", "Excel", "csv", "pdf", "print"],
332
+ name: "main",
333
+ tabIndex: 0,
334
+ dom: {
335
+ container: {
336
+ tag: "div",
337
+ className: "dt-buttons"
338
+ },
339
+ collection: {
340
+ tag: "div",
341
+ className: "dt-button-collection"
342
+ },
343
+ button: {
344
+ tag: "a",
345
+ className: "dt-button",
346
+ active: "active",
347
+ disabled: "disabled"
348
+ },
349
+ buttonLiner: {
350
+ tag: "span",
351
+ className: ""
352
+ }
353
+ }
354
+ }, u.version = "1.1.2", t.extend(a, {
355
+ collection: {
356
+ text: function (t) {
357
+ return t.i18n("buttons.collection", "Collection");
358
+ },
359
+ className: "buttons-collection",
360
+ action: function (o, i, s, r) {
361
+ var o = s.offset(),
362
+ a = t(i.table().container()),
363
+ c = !1;
364
+ t("div.dt-button-background").length && (c = t("div.dt-button-collection").offset(), t(e).trigger("click.dtb-collection")), r._collection.addClass(r.collectionLayout).css("display", "none").appendTo("body").fadeIn(r.fade);
365
+ var l = r._collection.css("position");
366
+ c && "absolute" === l ? r._collection.css({
367
+ top: c.top + 5,
368
+ left: c.left + 5
369
+ }) : "absolute" === l ? (r._collection.css({
370
+ top: o.top + s.outerHeight(),
371
+ left: o.left
372
+ }), s = o.left + r._collection.outerWidth(), a = a.offset().left + a.width(), s > a && r._collection.css("left", o.left - (s - a))) : (o = r._collection.height() / 2, o > t(n).height() / 2 && (o = t(n).height() / 2), r._collection.css("marginTop", -1 * o)), r.background && u.background(!0, r.backgroundClassName, r.fade), setTimeout(function () {
373
+ t("div.dt-button-background").on("click.dtb-collection", function () {}), t("body").on("click.dtb-collection", function (n) {
374
+ t(n.target).parents().andSelf().filter(r._collection).length || (r._collection.fadeOut(r.fade, function () {
375
+ r._collection.detach();
376
+ }), t("div.dt-button-background").off("click.dtb-collection"), u.background(!1, r.backgroundClassName, r.fade), t("body").off("click.dtb-collection"), i.off("buttons-action.b-internal"));
377
+ });
378
+ }, 10), r.autoClose && i.on("buttons-action.b-internal", function () {
379
+ t("div.dt-button-background").click();
380
+ });
381
+ },
382
+ background: !0,
383
+ collectionLayout: "",
384
+ backgroundClassName: "dt-button-background",
385
+ autoClose: !1,
386
+ fade: 400
387
+ },
388
+ copy: function (t, n) {
389
+ return a.copyHtml5 ? "copyHtml5" : a.copyFlash && a.copyFlash.available(t, n) ? "copyFlash" : void 0;
390
+ },
391
+ csv: function (t, n) {
392
+ return a.csvHtml5 && a.csvHtml5.available(t, n) ? "csvHtml5" : a.csvFlash && a.csvFlash.available(t, n) ? "csvFlash" : void 0;
393
+ },
394
+ excel: function (t, n) {
395
+ return a.excelHtml5 && a.excelHtml5.available(t, n) ? "excelHtml5" : a.excelFlash && a.excelFlash.available(t, n) ? "excelFlash" : void 0;
396
+ },
397
+ pdf: function (t, n) {
398
+ return a.pdfHtml5 && a.pdfHtml5.available(t, n) ? "pdfHtml5" : a.pdfFlash && a.pdfFlash.available(t, n) ? "pdfFlash" : void 0;
399
+ },
400
+ pageLength: function (n) {
401
+ var n = n.settings()[0].aLengthMenu,
402
+ e = t.isArray(n[0]) ? n[0] : n,
403
+ o = t.isArray(n[0]) ? n[1] : n,
404
+ i = function (t) {
405
+ return t.i18n("buttons.pageLength", {
406
+ "-1": "Show all rows",
407
+ _: "Show %d rows"
408
+ }, t.page.len());
409
+ };
410
+ return {
411
+ extend: "collection",
412
+ text: i,
413
+ className: "buttons-page-length",
414
+ autoClose: !0,
415
+ buttons: t.map(e, function (t, n) {
416
+ return {
417
+ text: o[n],
418
+ action: function (n, e) {
419
+ e.page.len(t).draw();
420
+ },
421
+ init: function (n, e, o) {
422
+ var i = this,
423
+ e = function () {
424
+ i.active(n.page.len() === t);
425
+ };
426
+ n.on("length.dt" + o.namespace, e), e();
427
+ },
428
+ destroy: function (t, n, e) {
429
+ t.off("length.dt" + e.namespace);
430
+ }
431
+ };
432
+ }),
433
+ init: function (t, n, e) {
434
+ var o = this;
435
+ t.on("length.dt" + e.namespace, function () {
436
+ o.text(i(t));
437
+ });
438
+ },
439
+ destroy: function (t, n, e) {
440
+ t.off("length.dt" + e.namespace);
441
+ }
442
+ };
443
+ }
444
+ }), i.Api.register("buttons()", function (t, n) {
445
+ return n === o && (n = t, t = o), this.iterator(!0, "table", function (e) {
446
+ return e._buttons ? u.buttonSelector(u.instanceSelector(t, e._buttons), n) : void 0;
447
+ }, !0);
448
+ }), i.Api.register("button()", function (t, n) {
449
+ var e = this.buttons(t, n);
450
+ return 1 < e.length && e.splice(1, e.length), e;
451
+ }), i.Api.registerPlural("buttons().active()", "button().active()", function (t) {
452
+ return t === o ? this.map(function (t) {
453
+ return t.inst.active(t.idx);
454
+ }) : this.each(function (n) {
455
+ n.inst.active(n.idx, t);
456
+ });
457
+ }), i.Api.registerPlural("buttons().action()", "button().action()", function (t) {
458
+ return t === o ? this.map(function (t) {
459
+ return t.inst.action(t.idx);
460
+ }) : this.each(function (n) {
461
+ n.inst.action(n.idx, t);
462
+ });
463
+ }), i.Api.register(["buttons().enable()", "button().enable()"], function (t) {
464
+ return this.each(function (n) {
465
+ n.inst.enable(n.idx, t);
466
+ });
467
+ }), i.Api.register(["buttons().disable()", "button().disable()"], function () {
468
+ return this.each(function (t) {
469
+ t.inst.disable(t.idx);
470
+ });
471
+ }), i.Api.registerPlural("buttons().nodes()", "button().node()", function () {
472
+ var n = t();
473
+ return t(this.each(function (t) {
474
+ n = n.add(t.inst.node(t.idx));
475
+ })), n;
476
+ }), i.Api.registerPlural("buttons().text()", "button().text()", function (t) {
477
+ return t === o ? this.map(function (t) {
478
+ return t.inst.text(t.idx);
479
+ }) : this.each(function (n) {
480
+ n.inst.text(n.idx, t);
481
+ });
482
+ }), i.Api.registerPlural("buttons().trigger()", "button().trigger()", function () {
483
+ return this.each(function (t) {
484
+ t.inst.node(t.idx).trigger("click");
485
+ });
486
+ }), i.Api.registerPlural("buttons().containers()", "buttons().container()", function () {
487
+ var n = t();
488
+ return t(this.each(function (t) {
489
+ n = n.add(t.inst.container());
490
+ })), n;
491
+ }), i.Api.register("button().add()", function (t, n) {
492
+ return 1 === this.length && this[0].inst.add(t, n), this.button(t);
493
+ }), i.Api.register("buttons().destroy()", function () {
494
+ return this.pluck("inst").unique().each(function (t) {
495
+ t.destroy();
496
+ }), this;
497
+ }), i.Api.registerPlural("buttons().remove()", "buttons().remove()", function () {
498
+ return this.each(function (t) {
499
+ t.inst.removePrep(t.idx);
500
+ }), this.pluck("inst").unique().each(function (t) {
501
+ t.removeCommit();
502
+ }), this;
503
+ });
504
+ var c;
505
+ i.Api.register("buttons.info()", function (n, e, i) {
506
+ var s = this;
507
+ return !1 === n ? (t("#datatables_buttons_info").fadeOut(function () {
508
+ t(this).remove();
509
+ }), clearTimeout(c), c = null, this) : (c && clearTimeout(c), t("#datatables_buttons_info").length && t("#datatables_buttons_info").remove(), t('<div id="datatables_buttons_info" class="dt-button-info"/>').html(n ? "<h2>" + n + "</h2>" : "").append(t("<div/>")["string" === typeof e ? "html" : "append"](e)).css("display", "none").appendTo("body").fadeIn(), i !== o && 0 !== i && (c = setTimeout(function () {
510
+ s.buttons.info(!1);
511
+ }, i)), this);
512
+ }), i.Api.register("buttons.exportData()", function (n) {
513
+ if (this.context.length) {
514
+ for (var e = new i.Api(this.context[0]), o = t.extend(!0, {}, {
515
+ rows: null,
516
+ columns: "",
517
+ modifier: {
518
+ search: "applied",
519
+ order: "applied"
520
+ },
521
+ orthogonal: "display",
522
+ stripHtml: !0,
523
+ stripNewlines: !0,
524
+ decodeEntities: !0,
525
+ trim: !0,
526
+ format: {
527
+ header: function (t) {
528
+ return s(t);
529
+ },
530
+ footer: function (t) {
531
+ return s(t);
532
+ },
533
+ body: function (t) {
534
+ return s(t);
535
+ }
536
+ }
537
+ }, n), s = function (t) {
538
+ return "string" !== typeof t ? t : (o.stripHtml && (t = t.replace(/<.*?>/g, "")), o.trim && (t = t.replace(/^\s+|\s+$/g, "")), o.stripNewlines && (t = t.replace(/\n/g, " ")), o.decodeEntities && (l.innerHTML = t, t = l.value), t);
539
+ }, n = e.columns(o.columns).indexes().map(function (t) {
540
+ return o.format.header(e.column(t).header().innerHTML, t);
541
+ }).toArray(), r = e.table().footer() ? e.columns(o.columns).indexes().map(function (t) {
542
+ var n = e.column(t).footer();
543
+ return o.format.footer(n ? n.innerHTML : "", t);
544
+ }).toArray() : null, a = e.rows(o.rows, o.modifier).indexes().toArray(), a = e.cells(a, o.columns).render(o.orthogonal).toArray(), u = n.length, c = u > 0 ? a.length / u : 0, d = Array(c), f = 0, h = 0; c > h; h++) {
545
+ for (var b = Array(u), p = 0; u > p; p++)
546
+ b[p] = o.format.body(a[f], p, h), f++;
547
+ d[h] = b;
548
+ }
549
+ return {
550
+ header: n,
551
+ footer: r,
552
+ body: d
553
+ };
554
+ }
555
+ });
556
+ var l = t("<textarea/>")[0];
557
+ return t.fn.dataTable.Buttons = u, t.fn.DataTable.Buttons = u, t(e).on("init.dt plugin-init.dt", function (t, n) {
558
+ if ("dt" === t.namespace) {
559
+ var e = n.oInit.buttons || i.defaults.buttons;
560
+ e && !n._buttons && new u(n, e).container();
561
+ }
562
+ }), i.ext.feature.push({
563
+ fnInit: function (t) {
564
+ var t = new i.Api(t),
565
+ n = t.init().buttons || i.defaults.buttons;
566
+ return new u(t, n).container();
567
+ },
568
+ cFeature: "B"
569
+ }), u;
570
+ });
assets/global/plugins/datatables/media/js/fngetfilterednodes.js CHANGED
@@ -1,10 +1,8 @@
1
- jQuery.fn.dataTableExt.oApi.fnGetFilteredNodes = function (oSettings)
2
- {
3
  var anRows = [];
4
- for (var i = 0, iLen = oSettings.aiDisplay.length; i < iLen; i++)
5
- {
6
- var nRow = oSettings.aoData[ oSettings.aiDisplay[i] ].nTr;
7
  anRows.push(nRow);
8
  }
9
  return anRows;
10
- };
1
+ jQuery.fn.dataTableExt.oApi.fnGetFilteredNodes = function (oSettings) {
 
2
  var anRows = [];
3
+ for (var i = 0, iLen = oSettings.aiDisplay.length; i < iLen; i++) {
4
+ var nRow = oSettings.aoData[oSettings.aiDisplay[i]].nTr;
 
5
  anRows.push(nRow);
6
  }
7
  return anRows;
8
+ };
assets/global/plugins/datatables/media/js/jquery.datatables.js CHANGED
@@ -1,3 +1,15240 @@
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);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! DataTables 1.10.15
2
+ * ©2008-2017 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * @summary DataTables
7
+ * @description Paginate, search and order HTML tables
8
+ * @version 1.10.15
9
+ * @file jquery.dataTables.js
10
+ * @author SpryMedia Ltd
11
+ * @contact www.datatables.net
12
+ * @copyright Copyright 2008-2017 SpryMedia Ltd.
13
+ *
14
+ * This source file is free software, available under the following license:
15
+ * MIT license - http://datatables.net/license
16
+ *
17
+ * This source file is distributed in the hope that it will be useful, but
18
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20
+ *
21
+ * For details please refer to: http://www.datatables.net
22
+ */
23
+
24
+ /*jslint evil: true, undef: true, browser: true */
25
+ /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
26
+
27
+ (function (factory) {
28
+ "use strict";
29
+
30
+ if (typeof define === 'function' && define.amd) {
31
+ // AMD
32
+ define(['jquery'], function ($) {
33
+ return factory($, window, document);
34
+ });
35
+ } else if (typeof exports === 'object') {
36
+ // CommonJS
37
+ module.exports = function (root, $) {
38
+ if (!root) {
39
+ // CommonJS environments without a window global must pass a
40
+ // root. This will give an error otherwise
41
+ root = window;
42
+ }
43
+
44
+ if (!$) {
45
+ $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
46
+ require('jquery') :
47
+ require('jquery')(root);
48
+ }
49
+
50
+ return factory($, root, root.document);
51
+ };
52
+ } else {
53
+ // Browser
54
+ factory(jQuery, window, document);
55
+ }
56
+ }
57
+ (function ($, window, document, undefined) {
58
+ "use strict";
59
+
60
+ /**
61
+ * DataTables is a plug-in for the jQuery Javascript library. It is a highly
62
+ * flexible tool, based upon the foundations of progressive enhancement,
63
+ * which will add advanced interaction controls to any HTML table. For a
64
+ * full list of features please refer to
65
+ * [DataTables.net](href="http://datatables.net).
66
+ *
67
+ * Note that the `DataTable` object is not a global variable but is aliased
68
+ * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
69
+ * be accessed.
70
+ *
71
+ * @class
72
+ * @param {object} [init={}] Configuration object for DataTables. Options
73
+ * are defined by {@link DataTable.defaults}
74
+ * @requires jQuery 1.7+
75
+ *
76
+ * @example
77
+ * // Basic initialisation
78
+ * $(document).ready( function {
79
+ * $('#example').dataTable();
80
+ * } );
81
+ *
82
+ * @example
83
+ * // Initialisation with configuration options - in this case, disable
84
+ * // pagination and sorting.
85
+ * $(document).ready( function {
86
+ * $('#example').dataTable( {
87
+ * "paginate": false,
88
+ * "sort": false
89
+ * } );
90
+ * } );
91
+ */
92
+ var DataTable = function (options)
93
+ {
94
+ /**
95
+ * Perform a jQuery selector action on the table's TR elements (from the tbody) and
96
+ * return the resulting jQuery object.
97
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
98
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
99
+ * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
100
+ * criterion ("applied") or all TR elements (i.e. no filter).
101
+ * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
102
+ * Can be either 'current', whereby the current sorting of the table is used, or
103
+ * 'original' whereby the original order the data was read into the table is used.
104
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
105
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
106
+ * 'current' and filter is 'applied', regardless of what they might be given as.
107
+ * @returns {object} jQuery object, filtered by the given selector.
108
+ * @dtopt API
109
+ * @deprecated Since v1.10
110
+ *
111
+ * @example
112
+ * $(document).ready(function() {
113
+ * var oTable = $('#example').dataTable();
114
+ *
115
+ * // Highlight every second row
116
+ * oTable.$('tr:odd').css('backgroundColor', 'blue');
117
+ * } );
118
+ *
119
+ * @example
120
+ * $(document).ready(function() {
121
+ * var oTable = $('#example').dataTable();
122
+ *
123
+ * // Filter to rows with 'Webkit' in them, add a background colour and then
124
+ * // remove the filter, thus highlighting the 'Webkit' rows only.
125
+ * oTable.fnFilter('Webkit');
126
+ * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
127
+ * oTable.fnFilter('');
128
+ * } );
129
+ */
130
+ this.$ = function (sSelector, oOpts)
131
+ {
132
+ return this.api(true).$(sSelector, oOpts);
133
+ };
134
+
135
+
136
+ /**
137
+ * Almost identical to $ in operation, but in this case returns the data for the matched
138
+ * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
139
+ * rather than any descendants, so the data can be obtained for the row/cell. If matching
140
+ * rows are found, the data returned is the original data array/object that was used to
141
+ * create the row (or a generated array if from a DOM source).
142
+ *
143
+ * This method is often useful in-combination with $ where both functions are given the
144
+ * same parameters and the array indexes will match identically.
145
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
146
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
147
+ * @param {string} [oOpts.filter=none] Select elements that meet the current filter
148
+ * criterion ("applied") or all elements (i.e. no filter).
149
+ * @param {string} [oOpts.order=current] Order of the data in the processed array.
150
+ * Can be either 'current', whereby the current sorting of the table is used, or
151
+ * 'original' whereby the original order the data was read into the table is used.
152
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
153
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
154
+ * 'current' and filter is 'applied', regardless of what they might be given as.
155
+ * @returns {array} Data for the matched elements. If any elements, as a result of the
156
+ * selector, were not TR, TD or TH elements in the DataTable, they will have a null
157
+ * entry in the array.
158
+ * @dtopt API
159
+ * @deprecated Since v1.10
160
+ *
161
+ * @example
162
+ * $(document).ready(function() {
163
+ * var oTable = $('#example').dataTable();
164
+ *
165
+ * // Get the data from the first row in the table
166
+ * var data = oTable._('tr:first');
167
+ *
168
+ * // Do something useful with the data
169
+ * alert( "First cell is: "+data[0] );
170
+ * } );
171
+ *
172
+ * @example
173
+ * $(document).ready(function() {
174
+ * var oTable = $('#example').dataTable();
175
+ *
176
+ * // Filter to 'Webkit' and get all data for
177
+ * oTable.fnFilter('Webkit');
178
+ * var data = oTable._('tr', {"search": "applied"});
179
+ *
180
+ * // Do something with the data
181
+ * alert( data.length+" rows matched the search" );
182
+ * } );
183
+ */
184
+ this._ = function (sSelector, oOpts)
185
+ {
186
+ return this.api(true).rows(sSelector, oOpts).data();
187
+ };
188
+
189
+
190
+ /**
191
+ * Create a DataTables Api instance, with the currently selected tables for
192
+ * the Api's context.
193
+ * @param {boolean} [traditional=false] Set the API instance's context to be
194
+ * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
195
+ * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
196
+ * or if all tables captured in the jQuery object should be used.
197
+ * @return {DataTables.Api}
198
+ */
199
+ this.api = function (traditional)
200
+ {
201
+ return traditional ?
202
+ new _Api(
203
+ _fnSettingsFromNode(this[ _ext.iApiIndex ])
204
+ ) :
205
+ new _Api(this);
206
+ };
207
+
208
+
209
+ /**
210
+ * Add a single new row or multiple rows of data to the table. Please note
211
+ * that this is suitable for client-side processing only - if you are using
212
+ * server-side processing (i.e. "bServerSide": true), then to add data, you
213
+ * must add it to the data source, i.e. the server-side, through an Ajax call.
214
+ * @param {array|object} data The data to be added to the table. This can be:
215
+ * <ul>
216
+ * <li>1D array of data - add a single row with the data provided</li>
217
+ * <li>2D array of arrays - add multiple rows in a single call</li>
218
+ * <li>object - data object when using <i>mData</i></li>
219
+ * <li>array of objects - multiple data objects when using <i>mData</i></li>
220
+ * </ul>
221
+ * @param {bool} [redraw=true] redraw the table or not
222
+ * @returns {array} An array of integers, representing the list of indexes in
223
+ * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
224
+ * the table.
225
+ * @dtopt API
226
+ * @deprecated Since v1.10
227
+ *
228
+ * @example
229
+ * // Global var for counter
230
+ * var giCount = 2;
231
+ *
232
+ * $(document).ready(function() {
233
+ * $('#example').dataTable();
234
+ * } );
235
+ *
236
+ * function fnClickAddRow() {
237
+ * $('#example').dataTable().fnAddData( [
238
+ * giCount+".1",
239
+ * giCount+".2",
240
+ * giCount+".3",
241
+ * giCount+".4" ]
242
+ * );
243
+ *
244
+ * giCount++;
245
+ * }
246
+ */
247
+ this.fnAddData = function (data, redraw)
248
+ {
249
+ var api = this.api(true);
250
+
251
+ /* Check if we want to add multiple rows or not */
252
+ var rows = $.isArray(data) && ($.isArray(data[0]) || $.isPlainObject(data[0])) ?
253
+ api.rows.add(data) :
254
+ api.row.add(data);
255
+
256
+ if (redraw === undefined || redraw) {
257
+ api.draw();
258
+ }
259
+
260
+ return rows.flatten().toArray();
261
+ };
262
+
263
+
264
+ /**
265
+ * This function will make DataTables recalculate the column sizes, based on the data
266
+ * contained in the table and the sizes applied to the columns (in the DOM, CSS or
267
+ * through the sWidth parameter). This can be useful when the width of the table's
268
+ * parent element changes (for example a window resize).
269
+ * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
270
+ * @dtopt API
271
+ * @deprecated Since v1.10
272
+ *
273
+ * @example
274
+ * $(document).ready(function() {
275
+ * var oTable = $('#example').dataTable( {
276
+ * "sScrollY": "200px",
277
+ * "bPaginate": false
278
+ * } );
279
+ *
280
+ * $(window).on('resize', function () {
281
+ * oTable.fnAdjustColumnSizing();
282
+ * } );
283
+ * } );
284
+ */
285
+ this.fnAdjustColumnSizing = function (bRedraw)
286
+ {
287
+ var api = this.api(true).columns.adjust();
288
+ var settings = api.settings()[0];
289
+ var scroll = settings.oScroll;
290
+
291
+ if (bRedraw === undefined || bRedraw) {
292
+ api.draw(false);
293
+ } else if (scroll.sX !== "" || scroll.sY !== "") {
294
+ /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
295
+ _fnScrollDraw(settings);
296
+ }
297
+ };
298
+
299
+
300
+ /**
301
+ * Quickly and simply clear a table
302
+ * @param {bool} [bRedraw=true] redraw the table or not
303
+ * @dtopt API
304
+ * @deprecated Since v1.10
305
+ *
306
+ * @example
307
+ * $(document).ready(function() {
308
+ * var oTable = $('#example').dataTable();
309
+ *
310
+ * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
311
+ * oTable.fnClearTable();
312
+ * } );
313
+ */
314
+ this.fnClearTable = function (bRedraw)
315
+ {
316
+ var api = this.api(true).clear();
317
+
318
+ if (bRedraw === undefined || bRedraw) {
319
+ api.draw();
320
+ }
321
+ };
322
+
323
+
324
+ /**
325
+ * The exact opposite of 'opening' a row, this function will close any rows which
326
+ * are currently 'open'.
327
+ * @param {node} nTr the table row to 'close'
328
+ * @returns {int} 0 on success, or 1 if failed (can't find the row)
329
+ * @dtopt API
330
+ * @deprecated Since v1.10
331
+ *
332
+ * @example
333
+ * $(document).ready(function() {
334
+ * var oTable;
335
+ *
336
+ * // 'open' an information row when a row is clicked on
337
+ * $('#example tbody tr').click( function () {
338
+ * if ( oTable.fnIsOpen(this) ) {
339
+ * oTable.fnClose( this );
340
+ * } else {
341
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
342
+ * }
343
+ * } );
344
+ *
345
+ * oTable = $('#example').dataTable();
346
+ * } );
347
+ */
348
+ this.fnClose = function (nTr)
349
+ {
350
+ this.api(true).row(nTr).child.hide();
351
+ };
352
+
353
+
354
+ /**
355
+ * Remove a row for the table
356
+ * @param {mixed} target The index of the row from aoData to be deleted, or
357
+ * the TR element you want to delete
358
+ * @param {function|null} [callBack] Callback function
359
+ * @param {bool} [redraw=true] Redraw the table or not
360
+ * @returns {array} The row that was deleted
361
+ * @dtopt API
362
+ * @deprecated Since v1.10
363
+ *
364
+ * @example
365
+ * $(document).ready(function() {
366
+ * var oTable = $('#example').dataTable();
367
+ *
368
+ * // Immediately remove the first row
369
+ * oTable.fnDeleteRow( 0 );
370
+ * } );
371
+ */
372
+ this.fnDeleteRow = function (target, callback, redraw)
373
+ {
374
+ var api = this.api(true);
375
+ var rows = api.rows(target);
376
+ var settings = rows.settings()[0];
377
+ var data = settings.aoData[ rows[0][0] ];
378
+
379
+ rows.remove();
380
+
381
+ if (callback) {
382
+ callback.call(this, settings, data);
383
+ }
384
+
385
+ if (redraw === undefined || redraw) {
386
+ api.draw();
387
+ }
388
+
389
+ return data;
390
+ };
391
+
392
+
393
+ /**
394
+ * Restore the table to it's original state in the DOM by removing all of DataTables
395
+ * enhancements, alterations to the DOM structure of the table and event listeners.
396
+ * @param {boolean} [remove=false] Completely remove the table from the DOM
397
+ * @dtopt API
398
+ * @deprecated Since v1.10
399
+ *
400
+ * @example
401
+ * $(document).ready(function() {
402
+ * // This example is fairly pointless in reality, but shows how fnDestroy can be used
403
+ * var oTable = $('#example').dataTable();
404
+ * oTable.fnDestroy();
405
+ * } );
406
+ */
407
+ this.fnDestroy = function (remove)
408
+ {
409
+ this.api(true).destroy(remove);
410
+ };
411
+
412
+
413
+ /**
414
+ * Redraw the table
415
+ * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
416
+ * @dtopt API
417
+ * @deprecated Since v1.10
418
+ *
419
+ * @example
420
+ * $(document).ready(function() {
421
+ * var oTable = $('#example').dataTable();
422
+ *
423
+ * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
424
+ * oTable.fnDraw();
425
+ * } );
426
+ */
427
+ this.fnDraw = function (complete)
428
+ {
429
+ // Note that this isn't an exact match to the old call to _fnDraw - it takes
430
+ // into account the new data, but can hold position.
431
+ this.api(true).draw(complete);
432
+ };
433
+
434
+
435
+ /**
436
+ * Filter the input based on data
437
+ * @param {string} sInput String to filter the table on
438
+ * @param {int|null} [iColumn] Column to limit filtering to
439
+ * @param {bool} [bRegex=false] Treat as regular expression or not
440
+ * @param {bool} [bSmart=true] Perform smart filtering or not
441
+ * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
442
+ * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
443
+ * @dtopt API
444
+ * @deprecated Since v1.10
445
+ *
446
+ * @example
447
+ * $(document).ready(function() {
448
+ * var oTable = $('#example').dataTable();
449
+ *
450
+ * // Sometime later - filter...
451
+ * oTable.fnFilter( 'test string' );
452
+ * } );
453
+ */
454
+ this.fnFilter = function (sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive)
455
+ {
456
+ var api = this.api(true);
457
+
458
+ if (iColumn === null || iColumn === undefined) {
459
+ api.search(sInput, bRegex, bSmart, bCaseInsensitive);
460
+ } else {
461
+ api.column(iColumn).search(sInput, bRegex, bSmart, bCaseInsensitive);
462
+ }
463
+
464
+ api.draw();
465
+ };
466
+
467
+
468
+ /**
469
+ * Get the data for the whole table, an individual row or an individual cell based on the
470
+ * provided parameters.
471
+ * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
472
+ * a TR node then the data source for the whole row will be returned. If given as a
473
+ * TD/TH cell node then iCol will be automatically calculated and the data for the
474
+ * cell returned. If given as an integer, then this is treated as the aoData internal
475
+ * data index for the row (see fnGetPosition) and the data for that row used.
476
+ * @param {int} [col] Optional column index that you want the data of.
477
+ * @returns {array|object|string} If mRow is undefined, then the data for all rows is
478
+ * returned. If mRow is defined, just data for that row, and is iCol is
479
+ * defined, only data for the designated cell is returned.
480
+ * @dtopt API
481
+ * @deprecated Since v1.10
482
+ *
483
+ * @example
484
+ * // Row data
485
+ * $(document).ready(function() {
486
+ * oTable = $('#example').dataTable();
487
+ *
488
+ * oTable.$('tr').click( function () {
489
+ * var data = oTable.fnGetData( this );
490
+ * // ... do something with the array / object of data for the row
491
+ * } );
492
+ * } );
493
+ *
494
+ * @example
495
+ * // Individual cell data
496
+ * $(document).ready(function() {
497
+ * oTable = $('#example').dataTable();
498
+ *
499
+ * oTable.$('td').click( function () {
500
+ * var sData = oTable.fnGetData( this );
501
+ * alert( 'The cell clicked on had the value of '+sData );
502
+ * } );
503
+ * } );
504
+ */
505
+ this.fnGetData = function (src, col)
506
+ {
507
+ var api = this.api(true);
508
+
509
+ if (src !== undefined) {
510
+ var type = src.nodeName ? src.nodeName.toLowerCase() : '';
511
+
512
+ return col !== undefined || type == 'td' || type == 'th' ?
513
+ api.cell(src, col).data() :
514
+ api.row(src).data() || null;
515
+ }
516
+
517
+ return api.data().toArray();
518
+ };
519
+
520
+
521
+ /**
522
+ * Get an array of the TR nodes that are used in the table's body. Note that you will
523
+ * typically want to use the '$' API method in preference to this as it is more
524
+ * flexible.
525
+ * @param {int} [iRow] Optional row index for the TR element you want
526
+ * @returns {array|node} If iRow is undefined, returns an array of all TR elements
527
+ * in the table's body, or iRow is defined, just the TR element requested.
528
+ * @dtopt API
529
+ * @deprecated Since v1.10
530
+ *
531
+ * @example
532
+ * $(document).ready(function() {
533
+ * var oTable = $('#example').dataTable();
534
+ *
535
+ * // Get the nodes from the table
536
+ * var nNodes = oTable.fnGetNodes( );
537
+ * } );
538
+ */
539
+ this.fnGetNodes = function (iRow)
540
+ {
541
+ var api = this.api(true);
542
+
543
+ return iRow !== undefined ?
544
+ api.row(iRow).node() :
545
+ api.rows().nodes().flatten().toArray();
546
+ };
547
+
548
+
549
+ /**
550
+ * Get the array indexes of a particular cell from it's DOM element
551
+ * and column index including hidden columns
552
+ * @param {node} node this can either be a TR, TD or TH in the table's body
553
+ * @returns {int} If nNode is given as a TR, then a single index is returned, or
554
+ * if given as a cell, an array of [row index, column index (visible),
555
+ * column index (all)] is given.
556
+ * @dtopt API
557
+ * @deprecated Since v1.10
558
+ *
559
+ * @example
560
+ * $(document).ready(function() {
561
+ * $('#example tbody td').click( function () {
562
+ * // Get the position of the current data from the node
563
+ * var aPos = oTable.fnGetPosition( this );
564
+ *
565
+ * // Get the data array for this row
566
+ * var aData = oTable.fnGetData( aPos[0] );
567
+ *
568
+ * // Update the data array and return the value
569
+ * aData[ aPos[1] ] = 'clicked';
570
+ * this.innerHTML = 'clicked';
571
+ * } );
572
+ *
573
+ * // Init DataTables
574
+ * oTable = $('#example').dataTable();
575
+ * } );
576
+ */
577
+ this.fnGetPosition = function (node)
578
+ {
579
+ var api = this.api(true);
580
+ var nodeName = node.nodeName.toUpperCase();
581
+
582
+ if (nodeName == 'TR') {
583
+ return api.row(node).index();
584
+ } else if (nodeName == 'TD' || nodeName == 'TH') {
585
+ var cell = api.cell(node).index();
586
+
587
+ return [
588
+ cell.row,
589
+ cell.columnVisible,
590
+ cell.column
591
+ ];
592
+ }
593
+ return null;
594
+ };
595
+
596
+
597
+ /**
598
+ * Check to see if a row is 'open' or not.
599
+ * @param {node} nTr the table row to check
600
+ * @returns {boolean} true if the row is currently open, false otherwise
601
+ * @dtopt API
602
+ * @deprecated Since v1.10
603
+ *
604
+ * @example
605
+ * $(document).ready(function() {
606
+ * var oTable;
607
+ *
608
+ * // 'open' an information row when a row is clicked on
609
+ * $('#example tbody tr').click( function () {
610
+ * if ( oTable.fnIsOpen(this) ) {
611
+ * oTable.fnClose( this );
612
+ * } else {
613
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
614
+ * }
615
+ * } );
616
+ *
617
+ * oTable = $('#example').dataTable();
618
+ * } );
619
+ */
620
+ this.fnIsOpen = function (nTr)
621
+ {
622
+ return this.api(true).row(nTr).child.isShown();
623
+ };
624
+
625
+
626
+ /**
627
+ * This function will place a new row directly after a row which is currently
628
+ * on display on the page, with the HTML contents that is passed into the
629
+ * function. This can be used, for example, to ask for confirmation that a
630
+ * particular record should be deleted.
631
+ * @param {node} nTr The table row to 'open'
632
+ * @param {string|node|jQuery} mHtml The HTML to put into the row
633
+ * @param {string} sClass Class to give the new TD cell
634
+ * @returns {node} The row opened. Note that if the table row passed in as the
635
+ * first parameter, is not found in the table, this method will silently
636
+ * return.
637
+ * @dtopt API
638
+ * @deprecated Since v1.10
639
+ *
640
+ * @example
641
+ * $(document).ready(function() {
642
+ * var oTable;
643
+ *
644
+ * // 'open' an information row when a row is clicked on
645
+ * $('#example tbody tr').click( function () {
646
+ * if ( oTable.fnIsOpen(this) ) {
647
+ * oTable.fnClose( this );
648
+ * } else {
649
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
650
+ * }
651
+ * } );
652
+ *
653
+ * oTable = $('#example').dataTable();
654
+ * } );
655
+ */
656
+ this.fnOpen = function (nTr, mHtml, sClass)
657
+ {
658
+ return this.api(true)
659
+ .row(nTr)
660
+ .child(mHtml, sClass)
661
+ .show()
662
+ .child()[0];
663
+ };
664
+
665
+
666
+ /**
667
+ * Change the pagination - provides the internal logic for pagination in a simple API
668
+ * function. With this function you can have a DataTables table go to the next,
669
+ * previous, first or last pages.
670
+ * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
671
+ * or page number to jump to (integer), note that page 0 is the first page.
672
+ * @param {bool} [bRedraw=true] Redraw the table or not
673
+ * @dtopt API
674
+ * @deprecated Since v1.10
675
+ *
676
+ * @example
677
+ * $(document).ready(function() {
678
+ * var oTable = $('#example').dataTable();
679
+ * oTable.fnPageChange( 'next' );
680
+ * } );
681
+ */
682
+ this.fnPageChange = function (mAction, bRedraw)
683
+ {
684
+ var api = this.api(true).page(mAction);
685
+
686
+ if (bRedraw === undefined || bRedraw) {
687
+ api.draw(false);
688
+ }
689
+ };
690
+
691
+
692
+ /**
693
+ * Show a particular column
694
+ * @param {int} iCol The column whose display should be changed
695
+ * @param {bool} bShow Show (true) or hide (false) the column
696
+ * @param {bool} [bRedraw=true] Redraw the table or not
697
+ * @dtopt API
698
+ * @deprecated Since v1.10
699
+ *
700
+ * @example
701
+ * $(document).ready(function() {
702
+ * var oTable = $('#example').dataTable();
703
+ *
704
+ * // Hide the second column after initialisation
705
+ * oTable.fnSetColumnVis( 1, false );
706
+ * } );
707
+ */
708
+ this.fnSetColumnVis = function (iCol, bShow, bRedraw)
709
+ {
710
+ var api = this.api(true).column(iCol).visible(bShow);
711
+
712
+ if (bRedraw === undefined || bRedraw) {
713
+ api.columns.adjust().draw();
714
+ }
715
+ };
716
+
717
+
718
+ /**
719
+ * Get the settings for a particular table for external manipulation
720
+ * @returns {object} DataTables settings object. See
721
+ * {@link DataTable.models.oSettings}
722
+ * @dtopt API
723
+ * @deprecated Since v1.10
724
+ *
725
+ * @example
726
+ * $(document).ready(function() {
727
+ * var oTable = $('#example').dataTable();
728
+ * var oSettings = oTable.fnSettings();
729
+ *
730
+ * // Show an example parameter from the settings
731
+ * alert( oSettings._iDisplayStart );
732
+ * } );
733
+ */
734
+ this.fnSettings = function ()
735
+ {
736
+ return _fnSettingsFromNode(this[_ext.iApiIndex]);
737
+ };
738
+
739
+
740
+ /**
741
+ * Sort the table by a particular column
742
+ * @param {int} iCol the data index to sort on. Note that this will not match the
743
+ * 'display index' if you have hidden data entries
744
+ * @dtopt API
745
+ * @deprecated Since v1.10
746
+ *
747
+ * @example
748
+ * $(document).ready(function() {
749
+ * var oTable = $('#example').dataTable();
750
+ *
751
+ * // Sort immediately with columns 0 and 1
752
+ * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
753
+ * } );
754
+ */
755
+ this.fnSort = function (aaSort)
756
+ {
757
+ this.api(true).order(aaSort).draw();
758
+ };
759
+
760
+
761
+ /**
762
+ * Attach a sort listener to an element for a given column
763
+ * @param {node} nNode the element to attach the sort listener to
764
+ * @param {int} iColumn the column that a click on this node will sort on
765
+ * @param {function} [fnCallback] callback function when sort is run
766
+ * @dtopt API
767
+ * @deprecated Since v1.10
768
+ *
769
+ * @example
770
+ * $(document).ready(function() {
771
+ * var oTable = $('#example').dataTable();
772
+ *
773
+ * // Sort on column 1, when 'sorter' is clicked on
774
+ * oTable.fnSortListener( document.getElementById('sorter'), 1 );
775
+ * } );
776
+ */
777
+ this.fnSortListener = function (nNode, iColumn, fnCallback)
778
+ {
779
+ this.api(true).order.listener(nNode, iColumn, fnCallback);
780
+ };
781
+
782
+
783
+ /**
784
+ * Update a table cell or row - this method will accept either a single value to
785
+ * update the cell with, an array of values with one element for each column or
786
+ * an object in the same format as the original data source. The function is
787
+ * self-referencing in order to make the multi column updates easier.
788
+ * @param {object|array|string} mData Data to update the cell/row with
789
+ * @param {node|int} mRow TR element you want to update or the aoData index
790
+ * @param {int} [iColumn] The column to update, give as null or undefined to
791
+ * update a whole row.
792
+ * @param {bool} [bRedraw=true] Redraw the table or not
793
+ * @param {bool} [bAction=true] Perform pre-draw actions or not
794
+ * @returns {int} 0 on success, 1 on error
795
+ * @dtopt API
796
+ * @deprecated Since v1.10
797
+ *
798
+ * @example
799
+ * $(document).ready(function() {
800
+ * var oTable = $('#example').dataTable();
801
+ * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
802
+ * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
803
+ * } );
804
+ */
805
+ this.fnUpdate = function (mData, mRow, iColumn, bRedraw, bAction)
806
+ {
807
+ var api = this.api(true);
808
+
809
+ if (iColumn === undefined || iColumn === null) {
810
+ api.row(mRow).data(mData);
811
+ } else {
812
+ api.cell(mRow, iColumn).data(mData);
813
+ }
814
+
815
+ if (bAction === undefined || bAction) {
816
+ api.columns.adjust();
817
+ }
818
+
819
+ if (bRedraw === undefined || bRedraw) {
820
+ api.draw();
821
+ }
822
+ return 0;
823
+ };
824
+
825
+
826
+ /**
827
+ * Provide a common method for plug-ins to check the version of DataTables being used, in order
828
+ * to ensure compatibility.
829
+ * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
830
+ * formats "X" and "X.Y" are also acceptable.
831
+ * @returns {boolean} true if this version of DataTables is greater or equal to the required
832
+ * version, or false if this version of DataTales is not suitable
833
+ * @method
834
+ * @dtopt API
835
+ * @deprecated Since v1.10
836
+ *
837
+ * @example
838
+ * $(document).ready(function() {
839
+ * var oTable = $('#example').dataTable();
840
+ * alert( oTable.fnVersionCheck( '1.9.0' ) );
841
+ * } );
842
+ */
843
+ this.fnVersionCheck = _ext.fnVersionCheck;
844
+
845
+
846
+ var _that = this;
847
+ var emptyInit = options === undefined;
848
+ var len = this.length;
849
+
850
+ if (emptyInit) {
851
+ options = {};
852
+ }
853
+
854
+ this.oApi = this.internal = _ext.internal;
855
+
856
+ // Extend with old style plug-in API methods
857
+ for (var fn in DataTable.ext.internal) {
858
+ if (fn) {
859
+ this[fn] = _fnExternApiFunc(fn);
860
+ }
861
+ }
862
+
863
+ this.each(function () {
864
+ // For each initialisation we want to give it a clean initialisation
865
+ // object that can be bashed around
866
+ var o = {};
867
+ var oInit = len > 1 ? // optimisation for single table case
868
+ _fnExtend(o, options, true) :
869
+ options;
870
+
871
+ /*global oInit,_that,emptyInit*/
872
+ var i = 0, iLen, j, jLen, k, kLen;
873
+ var sId = this.getAttribute('id');
874
+ var bInitHandedOff = false;
875
+ var defaults = DataTable.defaults;
876
+ var $this = $(this);
877
+
878
+
879
+ /* Sanity check */
880
+ if (this.nodeName.toLowerCase() != 'table')
881
+ {
882
+ _fnLog(null, 0, 'Non-table node initialisation (' + this.nodeName + ')', 2);
883
+ return;
884
+ }
885
+
886
+ /* Backwards compatibility for the defaults */
887
+ _fnCompatOpts(defaults);
888
+ _fnCompatCols(defaults.column);
889
+
890
+ /* Convert the camel-case defaults to Hungarian */
891
+ _fnCamelToHungarian(defaults, defaults, true);
892
+ _fnCamelToHungarian(defaults.column, defaults.column, true);
893
+
894
+ /* Setting up the initialisation object */
895
+ _fnCamelToHungarian(defaults, $.extend(oInit, $this.data()));
896
+
897
+
898
+
899
+ /* Check to see if we are re-initialising a table */
900
+ var allSettings = DataTable.settings;
901
+ for (i = 0, iLen = allSettings.length; i < iLen; i++)
902
+ {
903
+ var s = allSettings[i];
904
+
905
+ /* Base check on table node */
906
+ if (s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this))
907
+ {
908
+ var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
909
+ var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
910
+
911
+ if (emptyInit || bRetrieve)
912
+ {
913
+ return s.oInstance;
914
+ } else if (bDestroy)
915
+ {
916
+ s.oInstance.fnDestroy();
917
+ break;
918
+ } else
919
+ {
920
+ _fnLog(s, 0, 'Cannot reinitialise DataTable', 3);
921
+ return;
922
+ }
923
+ }
924
+
925
+ /* If the element we are initialising has the same ID as a table which was previously
926
+ * initialised, but the table nodes don't match (from before) then we destroy the old
927
+ * instance by simply deleting it. This is under the assumption that the table has been
928
+ * destroyed by other methods. Anyone using non-id selectors will need to do this manually
929
+ */
930
+ if (s.sTableId == this.id)
931
+ {
932
+ allSettings.splice(i, 1);
933
+ break;
934
+ }
935
+ }
936
+
937
+ /* Ensure the table has an ID - required for accessibility */
938
+ if (sId === null || sId === "")
939
+ {
940
+ sId = "DataTables_Table_" + (DataTable.ext._unique++);
941
+ this.id = sId;
942
+ }
943
+
944
+ /* Create the settings object for this table and set some of the default parameters */
945
+ var oSettings = $.extend(true, {}, DataTable.models.oSettings, {
946
+ "sDestroyWidth": $this[0].style.width,
947
+ "sInstance": sId,
948
+ "sTableId": sId
949
+ });
950
+ oSettings.nTable = this;
951
+ oSettings.oApi = _that.internal;
952
+ oSettings.oInit = oInit;
953
+
954
+ allSettings.push(oSettings);
955
+
956
+ // Need to add the instance after the instance after the settings object has been added
957
+ // to the settings array, so we can self reference the table instance if more than one
958
+ oSettings.oInstance = (_that.length === 1) ? _that : $this.dataTable();
959
+
960
+ // Backwards compatibility, before we apply all the defaults
961
+ _fnCompatOpts(oInit);
962
+
963
+ if (oInit.oLanguage)
964
+ {
965
+ _fnLanguageCompat(oInit.oLanguage);
966
+ }
967
+
968
+ // If the length menu is given, but the init display length is not, use the length menu
969
+ if (oInit.aLengthMenu && !oInit.iDisplayLength)
970
+ {
971
+ oInit.iDisplayLength = $.isArray(oInit.aLengthMenu[0]) ?
972
+ oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
973
+ }
974
+
975
+ // Apply the defaults and init options to make a single init object will all
976
+ // options defined from defaults and instance options.
977
+ oInit = _fnExtend($.extend(true, {}, defaults), oInit);
978
+
979
+
980
+ // Map the initialisation options onto the settings object
981
+ _fnMap(oSettings.oFeatures, oInit, [
982
+ "bPaginate",
983
+ "bLengthChange",
984
+ "bFilter",
985
+ "bSort",
986
+ "bSortMulti",
987
+ "bInfo",
988
+ "bProcessing",
989
+ "bAutoWidth",
990
+ "bSortClasses",
991
+ "bServerSide",
992
+ "bDeferRender"
993
+ ]);
994
+ _fnMap(oSettings, oInit, [
995
+ "asStripeClasses",
996
+ "ajax",
997
+ "fnServerData",
998
+ "fnFormatNumber",
999
+ "sServerMethod",
1000
+ "aaSorting",
1001
+ "aaSortingFixed",
1002
+ "aLengthMenu",
1003
+ "sPaginationType",
1004
+ "sAjaxSource",
1005
+ "sAjaxDataProp",
1006
+ "iStateDuration",
1007
+ "sDom",
1008
+ "bSortCellsTop",
1009
+ "iTabIndex",
1010
+ "fnStateLoadCallback",
1011
+ "fnStateSaveCallback",
1012
+ "renderer",
1013
+ "searchDelay",
1014
+ "rowId",
1015
+ ["iCookieDuration", "iStateDuration"], // backwards compat
1016
+ ["oSearch", "oPreviousSearch"],
1017
+ ["aoSearchCols", "aoPreSearchCols"],
1018
+ ["iDisplayLength", "_iDisplayLength"],
1019
+ ["bJQueryUI", "bJUI"]
1020
+ ]);
1021
+ _fnMap(oSettings.oScroll, oInit, [
1022
+ ["sScrollX", "sX"],
1023
+ ["sScrollXInner", "sXInner"],
1024
+ ["sScrollY", "sY"],
1025
+ ["bScrollCollapse", "bCollapse"]
1026
+ ]);
1027
+ _fnMap(oSettings.oLanguage, oInit, "fnInfoCallback");
1028
+
1029
+ /* Callback functions which are array driven */
1030
+ _fnCallbackReg(oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user');
1031
+ _fnCallbackReg(oSettings, 'aoServerParams', oInit.fnServerParams, 'user');
1032
+ _fnCallbackReg(oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user');
1033
+ _fnCallbackReg(oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user');
1034
+ _fnCallbackReg(oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user');
1035
+ _fnCallbackReg(oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user');
1036
+ _fnCallbackReg(oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user');
1037
+ _fnCallbackReg(oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user');
1038
+ _fnCallbackReg(oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user');
1039
+ _fnCallbackReg(oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user');
1040
+ _fnCallbackReg(oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user');
1041
+
1042
+ oSettings.rowIdFn = _fnGetObjectDataFn(oInit.rowId);
1043
+
1044
+ /* Browser support detection */
1045
+ _fnBrowserDetect(oSettings);
1046
+
1047
+ var oClasses = oSettings.oClasses;
1048
+
1049
+ // @todo Remove in 1.11
1050
+ if (oInit.bJQueryUI)
1051
+ {
1052
+ /* Use the JUI classes object for display. You could clone the oStdClasses object if
1053
+ * you want to have multiple tables with multiple independent classes
1054
+ */
1055
+ $.extend(oClasses, DataTable.ext.oJUIClasses, oInit.oClasses);
1056
+
1057
+ if (oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip")
1058
+ {
1059
+ /* Set the DOM to use a layout suitable for jQuery UI's theming */
1060
+ oSettings.sDom = '<"H"lfr>t<"F"ip>';
1061
+ }
1062
+
1063
+ if (!oSettings.renderer) {
1064
+ oSettings.renderer = 'jqueryui';
1065
+ } else if ($.isPlainObject(oSettings.renderer) && !oSettings.renderer.header) {
1066
+ oSettings.renderer.header = 'jqueryui';
1067
+ }
1068
+ } else
1069
+ {
1070
+ $.extend(oClasses, DataTable.ext.classes, oInit.oClasses);
1071
+ }
1072
+ $this.addClass(oClasses.sTable);
1073
+
1074
+
1075
+ if (oSettings.iInitDisplayStart === undefined)
1076
+ {
1077
+ /* Display start point, taking into account the save saving */
1078
+ oSettings.iInitDisplayStart = oInit.iDisplayStart;
1079
+ oSettings._iDisplayStart = oInit.iDisplayStart;
1080
+ }
1081
+
1082
+ if (oInit.iDeferLoading !== null)
1083
+ {
1084
+ oSettings.bDeferLoading = true;
1085
+ var tmp = $.isArray(oInit.iDeferLoading);
1086
+ oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
1087
+ oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
1088
+ }
1089
+
1090
+ /* Language definitions */
1091
+ var oLanguage = oSettings.oLanguage;
1092
+ $.extend(true, oLanguage, oInit.oLanguage);
1093
+
1094
+ if (oLanguage.sUrl)
1095
+ {
1096
+ /* Get the language definitions from a file - because this Ajax call makes the language
1097
+ * get async to the remainder of this function we use bInitHandedOff to indicate that
1098
+ * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
1099
+ */
1100
+ $.ajax({
1101
+ dataType: 'json',
1102
+ url: oLanguage.sUrl,
1103
+ success: function (json) {
1104
+ _fnLanguageCompat(json);
1105
+ _fnCamelToHungarian(defaults.oLanguage, json);
1106
+ $.extend(true, oLanguage, json);
1107
+ _fnInitialise(oSettings);
1108
+ },
1109
+ error: function () {
1110
+ // Error occurred loading language file, continue on as best we can
1111
+ _fnInitialise(oSettings);
1112
+ }
1113
+ });
1114
+ bInitHandedOff = true;
1115
+ }
1116
+
1117
+ /*
1118
+ * Stripes
1119
+ */
1120
+ if (oInit.asStripeClasses === null)
1121
+ {
1122
+ oSettings.asStripeClasses = [
1123
+ oClasses.sStripeOdd,
1124
+ oClasses.sStripeEven
1125
+ ];
1126
+ }
1127
+
1128
+ /* Remove row stripe classes if they are already on the table row */
1129
+ var stripeClasses = oSettings.asStripeClasses;
1130
+ var rowOne = $this.children('tbody').find('tr').eq(0);
1131
+ if ($.inArray(true, $.map(stripeClasses, function (el, i) {
1132
+ return rowOne.hasClass(el);
1133
+ })) !== -1) {
1134
+ $('tbody tr', this).removeClass(stripeClasses.join(' '));
1135
+ oSettings.asDestroyStripes = stripeClasses.slice();
1136
+ }
1137
+
1138
+ /*
1139
+ * Columns
1140
+ * See if we should load columns automatically or use defined ones
1141
+ */
1142
+ var anThs = [];
1143
+ var aoColumnsInit;
1144
+ var nThead = this.getElementsByTagName('thead');
1145
+ if (nThead.length !== 0)
1146
+ {
1147
+ _fnDetectHeader(oSettings.aoHeader, nThead[0]);
1148
+ anThs = _fnGetUniqueThs(oSettings);
1149
+ }
1150
+
1151
+ /* If not given a column array, generate one with nulls */
1152
+ if (oInit.aoColumns === null)
1153
+ {
1154
+ aoColumnsInit = [];
1155
+ for (i = 0, iLen = anThs.length; i < iLen; i++)
1156
+ {
1157
+ aoColumnsInit.push(null);
1158
+ }
1159
+ } else
1160
+ {
1161
+ aoColumnsInit = oInit.aoColumns;
1162
+ }
1163
+
1164
+ /* Add the columns */
1165
+ for (i = 0, iLen = aoColumnsInit.length; i < iLen; i++)
1166
+ {
1167
+ _fnAddColumn(oSettings, anThs ? anThs[i] : null);
1168
+ }
1169
+
1170
+ /* Apply the column definitions */
1171
+ _fnApplyColumnDefs(oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
1172
+ _fnColumnOptions(oSettings, iCol, oDef);
1173
+ });
1174
+
1175
+ /* HTML5 attribute detection - build an mData object automatically if the
1176
+ * attributes are found
1177
+ */
1178
+ if (rowOne.length) {
1179
+ var a = function (cell, name) {
1180
+ return cell.getAttribute('data-' + name) !== null ? name : null;
1181
+ };
1182
+
1183
+ $(rowOne[0]).children('th, td').each(function (i, cell) {
1184
+ var col = oSettings.aoColumns[i];
1185
+
1186
+ if (col.mData === i) {
1187
+ var sort = a(cell, 'sort') || a(cell, 'order');
1188
+ var filter = a(cell, 'filter') || a(cell, 'search');
1189
+
1190
+ if (sort !== null || filter !== null) {
1191
+ col.mData = {
1192
+ _: i + '.display',
1193
+ sort: sort !== null ? i + '.@data-' + sort : undefined,
1194
+ type: sort !== null ? i + '.@data-' + sort : undefined,
1195
+ filter: filter !== null ? i + '.@data-' + filter : undefined
1196
+ };
1197
+
1198
+ _fnColumnOptions(oSettings, i);
1199
+ }
1200
+ }
1201
+ });
1202
+ }
1203
+
1204
+ var features = oSettings.oFeatures;
1205
+ var loadedInit = function () {
1206
+ /*
1207
+ * Sorting
1208
+ * @todo For modularisation (1.11) this needs to do into a sort start up handler
1209
+ */
1210
+
1211
+ // If aaSorting is not defined, then we use the first indicator in asSorting
1212
+ // in case that has been altered, so the default sort reflects that option
1213
+ if (oInit.aaSorting === undefined) {
1214
+ var sorting = oSettings.aaSorting;
1215
+ for (i = 0, iLen = sorting.length; i < iLen; i++) {
1216
+ sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1217
+ }
1218
+ }
1219
+
1220
+ /* Do a first pass on the sorting classes (allows any size changes to be taken into
1221
+ * account, and also will apply sorting disabled classes if disabled
1222
+ */
1223
+ _fnSortingClasses(oSettings);
1224
+
1225
+ if (features.bSort) {
1226
+ _fnCallbackReg(oSettings, 'aoDrawCallback', function () {
1227
+ if (oSettings.bSorted) {
1228
+ var aSort = _fnSortFlatten(oSettings);
1229
+ var sortedColumns = {};
1230
+
1231
+ $.each(aSort, function (i, val) {
1232
+ sortedColumns[ val.src ] = val.dir;
1233
+ });
1234
+
1235
+ _fnCallbackFire(oSettings, null, 'order', [oSettings, aSort, sortedColumns]);
1236
+ _fnSortAria(oSettings);
1237
+ }
1238
+ });
1239
+ }
1240
+
1241
+ _fnCallbackReg(oSettings, 'aoDrawCallback', function () {
1242
+ if (oSettings.bSorted || _fnDataSource(oSettings) === 'ssp' || features.bDeferRender) {
1243
+ _fnSortingClasses(oSettings);
1244
+ }
1245
+ }, 'sc');
1246
+
1247
+
1248
+ /*
1249
+ * Final init
1250
+ * Cache the header, body and footer as required, creating them if needed
1251
+ */
1252
+
1253
+ // Work around for Webkit bug 83867 - store the caption-side before removing from doc
1254
+ var captions = $this.children('caption').each(function () {
1255
+ this._captionSide = $(this).css('caption-side');
1256
+ });
1257
+
1258
+ var thead = $this.children('thead');
1259
+ if (thead.length === 0) {
1260
+ thead = $('<thead/>').appendTo($this);
1261
+ }
1262
+ oSettings.nTHead = thead[0];
1263
+
1264
+ var tbody = $this.children('tbody');
1265
+ if (tbody.length === 0) {
1266
+ tbody = $('<tbody/>').appendTo($this);
1267
+ }
1268
+ oSettings.nTBody = tbody[0];
1269
+
1270
+ var tfoot = $this.children('tfoot');
1271
+ if (tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "")) {
1272
+ // If we are a scrolling table, and no footer has been given, then we need to create
1273
+ // a tfoot element for the caption element to be appended to
1274
+ tfoot = $('<tfoot/>').appendTo($this);
1275
+ }
1276
+
1277
+ if (tfoot.length === 0 || tfoot.children().length === 0) {
1278
+ $this.addClass(oClasses.sNoFooter);
1279
+ } else if (tfoot.length > 0) {
1280
+ oSettings.nTFoot = tfoot[0];
1281
+ _fnDetectHeader(oSettings.aoFooter, oSettings.nTFoot);
1282
+ }
1283
+
1284
+ /* Check if there is data passing into the constructor */
1285
+ if (oInit.aaData) {
1286
+ for (i = 0; i < oInit.aaData.length; i++) {
1287
+ _fnAddData(oSettings, oInit.aaData[ i ]);
1288
+ }
1289
+ } else if (oSettings.bDeferLoading || _fnDataSource(oSettings) == 'dom') {
1290
+ /* Grab the data from the page - only do this when deferred loading or no Ajax
1291
+ * source since there is no point in reading the DOM data if we are then going
1292
+ * to replace it with Ajax data
1293
+ */
1294
+ _fnAddTr(oSettings, $(oSettings.nTBody).children('tr'));
1295
+ }
1296
+
1297
+ /* Copy the data index array */
1298
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1299
+
1300
+ /* Initialisation complete - table can be drawn */
1301
+ oSettings.bInitialised = true;
1302
+
1303
+ /* Check if we need to initialise the table (it might not have been handed off to the
1304
+ * language processor)
1305
+ */
1306
+ if (bInitHandedOff === false) {
1307
+ _fnInitialise(oSettings);
1308
+ }
1309
+ };
1310
+
1311
+ /* Must be done after everything which can be overridden by the state saving! */
1312
+ if (oInit.bStateSave)
1313
+ {
1314
+ features.bStateSave = true;
1315
+ _fnCallbackReg(oSettings, 'aoDrawCallback', _fnSaveState, 'state_save');
1316
+ _fnLoadState(oSettings, oInit, loadedInit);
1317
+ } else {
1318
+ loadedInit();
1319
+ }
1320
+
1321
+ });
1322
+ _that = null;
1323
+ return this;
1324
+ };
1325
+
1326
+
1327
+ /*
1328
+ * It is useful to have variables which are scoped locally so only the
1329
+ * DataTables functions can access them and they don't leak into global space.
1330
+ * At the same time these functions are often useful over multiple files in the
1331
+ * core and API, so we list, or at least document, all variables which are used
1332
+ * by DataTables as private variables here. This also ensures that there is no
1333
+ * clashing of variable names and that they can easily referenced for reuse.
1334
+ */
1335
+
1336
+
1337
+ // Defined else where
1338
+ // _selector_run
1339
+ // _selector_opts
1340
+ // _selector_first
1341
+ // _selector_row_indexes
1342
+
1343
+ var _ext; // DataTable.ext
1344
+ var _Api; // DataTable.Api
1345
+ var _api_register; // DataTable.Api.register
1346
+ var _api_registerPlural; // DataTable.Api.registerPlural
1347
+
1348
+ var _re_dic = {};
1349
+ var _re_new_lines = /[\r\n]/g;
1350
+ var _re_html = /<.*?>/g;
1351
+
1352
+ // This is not strict ISO8601 - Date.parse() is quite lax, although
1353
+ // implementations differ between browsers.
1354
+ var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
1355
+
1356
+ // Escape regular expression special characters
1357
+ var _re_escape_regex = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-'].join('|\\') + ')', 'g');
1358
+
1359
+ // http://en.wikipedia.org/wiki/Foreign_exchange_market
1360
+ // - \u20BD - Russian ruble.
1361
+ // - \u20a9 - South Korean Won
1362
+ // - \u20BA - Turkish Lira
1363
+ // - \u20B9 - Indian Rupee
1364
+ // - R - Brazil (R$) and South Africa
1365
+ // - fr - Swiss Franc
1366
+ // - kr - Swedish krona, Norwegian krone and Danish krone
1367
+ // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
1368
+ // standards as thousands separators.
1369
+ var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
1370
+
1371
+
1372
+ var _empty = function (d) {
1373
+ return !d || d === true || d === '-' ? true : false;
1374
+ };
1375
+
1376
+
1377
+ var _intVal = function (s) {
1378
+ var integer = parseInt(s, 10);
1379
+ return !isNaN(integer) && isFinite(s) ? integer : null;
1380
+ };
1381
+
1382
+ // Convert from a formatted number with characters other than `.` as the
1383
+ // decimal place, to a Javascript number
1384
+ var _numToDecimal = function (num, decimalPoint) {
1385
+ // Cache created regular expressions for speed as this function is called often
1386
+ if (!_re_dic[ decimalPoint ]) {
1387
+ _re_dic[ decimalPoint ] = new RegExp(_fnEscapeRegex(decimalPoint), 'g');
1388
+ }
1389
+ return typeof num === 'string' && decimalPoint !== '.' ?
1390
+ num.replace(/\./g, '').replace(_re_dic[ decimalPoint ], '.') :
1391
+ num;
1392
+ };
1393
+
1394
+
1395
+ var _isNumber = function (d, decimalPoint, formatted) {
1396
+ var strType = typeof d === 'string';
1397
+
1398
+ // If empty return immediately so there must be a number if it is a
1399
+ // formatted string (this stops the string "k", or "kr", etc being detected
1400
+ // as a formatted number for currency
1401
+ if (_empty(d)) {
1402
+ return true;
1403
+ }
1404
+
1405
+ if (decimalPoint && strType) {
1406
+ d = _numToDecimal(d, decimalPoint);
1407
+ }
1408
+
1409
+ if (formatted && strType) {
1410
+ d = d.replace(_re_formatted_numeric, '');
1411
+ }
1412
+
1413
+ return !isNaN(parseFloat(d)) && isFinite(d);
1414
+ };
1415
+
1416
+
1417
+ // A string without HTML in it can be considered to be HTML still
1418
+ var _isHtml = function (d) {
1419
+ return _empty(d) || typeof d === 'string';
1420
+ };
1421
+
1422
+
1423
+ var _htmlNumeric = function (d, decimalPoint, formatted) {
1424
+ if (_empty(d)) {
1425
+ return true;
1426
+ }
1427
+
1428
+ var html = _isHtml(d);
1429
+ return !html ?
1430
+ null :
1431
+ _isNumber(_stripHtml(d), decimalPoint, formatted) ?
1432
+ true :
1433
+ null;
1434
+ };
1435
+
1436
+
1437
+ var _pluck = function (a, prop, prop2) {
1438
+ var out = [];
1439
+ var i = 0, ien = a.length;
1440
+
1441
+ // Could have the test in the loop for slightly smaller code, but speed
1442
+ // is essential here
1443
+ if (prop2 !== undefined) {
1444
+ for (; i < ien; i++) {
1445
+ if (a[i] && a[i][ prop ]) {
1446
+ out.push(a[i][ prop ][ prop2 ]);
1447
+ }
1448
+ }
1449
+ } else {
1450
+ for (; i < ien; i++) {
1451
+ if (a[i]) {
1452
+ out.push(a[i][ prop ]);
1453
+ }
1454
+ }
1455
+ }
1456
+
1457
+ return out;
1458
+ };
1459
+
1460
+
1461
+ // Basically the same as _pluck, but rather than looping over `a` we use `order`
1462
+ // as the indexes to pick from `a`
1463
+ var _pluck_order = function (a, order, prop, prop2)
1464
+ {
1465
+ var out = [];
1466
+ var i = 0, ien = order.length;
1467
+
1468
+ // Could have the test in the loop for slightly smaller code, but speed
1469
+ // is essential here
1470
+ if (prop2 !== undefined) {
1471
+ for (; i < ien; i++) {
1472
+ if (a[ order[i] ][ prop ]) {
1473
+ out.push(a[ order[i] ][ prop ][ prop2 ]);
1474
+ }
1475
+ }
1476
+ } else {
1477
+ for (; i < ien; i++) {
1478
+ out.push(a[ order[i] ][ prop ]);
1479
+ }
1480
+ }
1481
+
1482
+ return out;
1483
+ };
1484
+
1485
+
1486
+ var _range = function (len, start)
1487
+ {
1488
+ var out = [];
1489
+ var end;
1490
+
1491
+ if (start === undefined) {
1492
+ start = 0;
1493
+ end = len;
1494
+ } else {
1495
+ end = start;
1496
+ start = len;
1497
+ }
1498
+
1499
+ for (var i = start; i < end; i++) {
1500
+ out.push(i);
1501
+ }
1502
+
1503
+ return out;
1504
+ };
1505
+
1506
+
1507
+ var _removeEmpty = function (a)
1508
+ {
1509
+ var out = [];
1510
+
1511
+ for (var i = 0, ien = a.length; i < ien; i++) {
1512
+ if (a[i]) { // careful - will remove all falsy values!
1513
+ out.push(a[i]);
1514
+ }
1515
+ }
1516
+
1517
+ return out;
1518
+ };
1519
+
1520
+
1521
+ var _stripHtml = function (d) {
1522
+ return d.replace(_re_html, '');
1523
+ };
1524
+
1525
+
1526
+ /**
1527
+ * Determine if all values in the array are unique. This means we can short
1528
+ * cut the _unique method at the cost of a single loop. A sorted array is used
1529
+ * to easily check the values.
1530
+ *
1531
+ * @param {array} src Source array
1532
+ * @return {boolean} true if all unique, false otherwise
1533
+ * @ignore
1534
+ */
1535
+ var _areAllUnique = function (src) {
1536
+ if (src.length < 2) {
1537
+ return true;
1538
+ }
1539
+
1540
+ var sorted = src.slice().sort();
1541
+ var last = sorted[0];
1542
+
1543
+ for (var i = 1, ien = sorted.length; i < ien; i++) {
1544
+ if (sorted[i] === last) {
1545
+ return false;
1546
+ }
1547
+
1548
+ last = sorted[i];
1549
+ }
1550
+
1551
+ return true;
1552
+ };
1553
+
1554
+
1555
+ /**
1556
+ * Find the unique elements in a source array.
1557
+ *
1558
+ * @param {array} src Source array
1559
+ * @return {array} Array of unique items
1560
+ * @ignore
1561
+ */
1562
+ var _unique = function (src)
1563
+ {
1564
+ if (_areAllUnique(src)) {
1565
+ return src.slice();
1566
+ }
1567
+
1568
+ // A faster unique method is to use object keys to identify used values,
1569
+ // but this doesn't work with arrays or objects, which we must also
1570
+ // consider. See jsperf.com/compare-array-unique-versions/4 for more
1571
+ // information.
1572
+ var
1573
+ out = [],
1574
+ val,
1575
+ i, ien = src.length,
1576
+ j, k = 0;
1577
+
1578
+ again: for (i = 0; i < ien; i++) {
1579
+ val = src[i];
1580
+
1581
+ for (j = 0; j < k; j++) {
1582
+ if (out[j] === val) {
1583
+ continue again;
1584
+ }
1585
+ }
1586
+
1587
+ out.push(val);
1588
+ k++;
1589
+ }
1590
+
1591
+ return out;
1592
+ };
1593
+
1594
+
1595
+ /**
1596
+ * DataTables utility methods
1597
+ *
1598
+ * This namespace provides helper methods that DataTables uses internally to
1599
+ * create a DataTable, but which are not exclusively used only for DataTables.
1600
+ * These methods can be used by extension authors to save the duplication of
1601
+ * code.
1602
+ *
1603
+ * @namespace
1604
+ */
1605
+ DataTable.util = {
1606
+ /**
1607
+ * Throttle the calls to a function. Arguments and context are maintained
1608
+ * for the throttled function.
1609
+ *
1610
+ * @param {function} fn Function to be called
1611
+ * @param {integer} freq Call frequency in mS
1612
+ * @return {function} Wrapped function
1613
+ */
1614
+ throttle: function (fn, freq) {
1615
+ var
1616
+ frequency = freq !== undefined ? freq : 200,
1617
+ last,
1618
+ timer;
1619
+
1620
+ return function () {
1621
+ var
1622
+ that = this,
1623
+ now = +new Date(),
1624
+ args = arguments;
1625
+
1626
+ if (last && now < last + frequency) {
1627
+ clearTimeout(timer);
1628
+
1629
+ timer = setTimeout(function () {
1630
+ last = undefined;
1631
+ fn.apply(that, args);
1632
+ }, frequency);
1633
+ } else {
1634
+ last = now;
1635
+ fn.apply(that, args);
1636
+ }
1637
+ };
1638
+ },
1639
+
1640
+ /**
1641
+ * Escape a string such that it can be used in a regular expression
1642
+ *
1643
+ * @param {string} val string to escape
1644
+ * @returns {string} escaped string
1645
+ */
1646
+ escapeRegex: function (val) {
1647
+ return val.replace(_re_escape_regex, '\\$1');
1648
+ }
1649
+ };
1650
+
1651
+
1652
+
1653
+ /**
1654
+ * Create a mapping object that allows camel case parameters to be looked up
1655
+ * for their Hungarian counterparts. The mapping is stored in a private
1656
+ * parameter called `_hungarianMap` which can be accessed on the source object.
1657
+ * @param {object} o
1658
+ * @memberof DataTable#oApi
1659
+ */
1660
+ function _fnHungarianMap(o)
1661
+ {
1662
+ var
1663
+ hungarian = 'a aa ai ao as b fn i m o s ',
1664
+ match,
1665
+ newKey,
1666
+ map = {};
1667
+
1668
+ $.each(o, function (key, val) {
1669
+ match = key.match(/^([^A-Z]+?)([A-Z])/);
1670
+
1671
+ if (match && hungarian.indexOf(match[1] + ' ') !== -1)
1672
+ {
1673
+ newKey = key.replace(match[0], match[2].toLowerCase());
1674
+ map[ newKey ] = key;
1675
+
1676
+ if (match[1] === 'o')
1677
+ {
1678
+ _fnHungarianMap(o[key]);
1679
+ }
1680
+ }
1681
+ });
1682
+
1683
+ o._hungarianMap = map;
1684
+ }
1685
+
1686
+
1687
+ /**
1688
+ * Convert from camel case parameters to Hungarian, based on a Hungarian map
1689
+ * created by _fnHungarianMap.
1690
+ * @param {object} src The model object which holds all parameters that can be
1691
+ * mapped.
1692
+ * @param {object} user The object to convert from camel case to Hungarian.
1693
+ * @param {boolean} force When set to `true`, properties which already have a
1694
+ * Hungarian value in the `user` object will be overwritten. Otherwise they
1695
+ * won't be.
1696
+ * @memberof DataTable#oApi
1697
+ */
1698
+ function _fnCamelToHungarian(src, user, force)
1699
+ {
1700
+ if (!src._hungarianMap) {
1701
+ _fnHungarianMap(src);
1702
+ }
1703
+
1704
+ var hungarianKey;
1705
+
1706
+ $.each(user, function (key, val) {
1707
+ hungarianKey = src._hungarianMap[ key ];
1708
+
1709
+ if (hungarianKey !== undefined && (force || user[hungarianKey] === undefined))
1710
+ {
1711
+ // For objects, we need to buzz down into the object to copy parameters
1712
+ if (hungarianKey.charAt(0) === 'o')
1713
+ {
1714
+ // Copy the camelCase options over to the hungarian
1715
+ if (!user[ hungarianKey ]) {
1716
+ user[ hungarianKey ] = {};
1717
+ }
1718
+ $.extend(true, user[hungarianKey], user[key]);
1719
+
1720
+ _fnCamelToHungarian(src[hungarianKey], user[hungarianKey], force);
1721
+ } else {
1722
+ user[hungarianKey] = user[ key ];
1723
+ }
1724
+ }
1725
+ });
1726
+ }
1727
+
1728
+
1729
+ /**
1730
+ * Language compatibility - when certain options are given, and others aren't, we
1731
+ * need to duplicate the values over, in order to provide backwards compatibility
1732
+ * with older language files.
1733
+ * @param {object} oSettings dataTables settings object
1734
+ * @memberof DataTable#oApi
1735
+ */
1736
+ function _fnLanguageCompat(lang)
1737
+ {
1738
+ var defaults = DataTable.defaults.oLanguage;
1739
+ var zeroRecords = lang.sZeroRecords;
1740
+
1741
+ /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
1742
+ * sZeroRecords - assuming that is given.
1743
+ */
1744
+ if (!lang.sEmptyTable && zeroRecords &&
1745
+ defaults.sEmptyTable === "No data available in table")
1746
+ {
1747
+ _fnMap(lang, lang, 'sZeroRecords', 'sEmptyTable');
1748
+ }
1749
+
1750
+ /* Likewise with loading records */
1751
+ if (!lang.sLoadingRecords && zeroRecords &&
1752
+ defaults.sLoadingRecords === "Loading...")
1753
+ {
1754
+ _fnMap(lang, lang, 'sZeroRecords', 'sLoadingRecords');
1755
+ }
1756
+
1757
+ // Old parameter name of the thousands separator mapped onto the new
1758
+ if (lang.sInfoThousands) {
1759
+ lang.sThousands = lang.sInfoThousands;
1760
+ }
1761
+
1762
+ var decimal = lang.sDecimal;
1763
+ if (decimal) {
1764
+ _addNumericSort(decimal);
1765
+ }
1766
+ }
1767
+
1768
+
1769
+ /**
1770
+ * Map one parameter onto another
1771
+ * @param {object} o Object to map
1772
+ * @param {*} knew The new parameter name
1773
+ * @param {*} old The old parameter name
1774
+ */
1775
+ var _fnCompatMap = function (o, knew, old) {
1776
+ if (o[ knew ] !== undefined) {
1777
+ o[ old ] = o[ knew ];
1778
+ }
1779
+ };
1780
+
1781
+
1782
+ /**
1783
+ * Provide backwards compatibility for the main DT options. Note that the new
1784
+ * options are mapped onto the old parameters, so this is an external interface
1785
+ * change only.
1786
+ * @param {object} init Object to map
1787
+ */
1788
+ function _fnCompatOpts(init)
1789
+ {
1790
+ _fnCompatMap(init, 'ordering', 'bSort');
1791
+ _fnCompatMap(init, 'orderMulti', 'bSortMulti');
1792
+ _fnCompatMap(init, 'orderClasses', 'bSortClasses');
1793
+ _fnCompatMap(init, 'orderCellsTop', 'bSortCellsTop');
1794
+ _fnCompatMap(init, 'order', 'aaSorting');
1795
+ _fnCompatMap(init, 'orderFixed', 'aaSortingFixed');
1796
+ _fnCompatMap(init, 'paging', 'bPaginate');
1797
+ _fnCompatMap(init, 'pagingType', 'sPaginationType');
1798
+ _fnCompatMap(init, 'pageLength', 'iDisplayLength');
1799
+ _fnCompatMap(init, 'searching', 'bFilter');
1800
+
1801
+ // Boolean initialisation of x-scrolling
1802
+ if (typeof init.sScrollX === 'boolean') {
1803
+ init.sScrollX = init.sScrollX ? '100%' : '';
1804
+ }
1805
+ if (typeof init.scrollX === 'boolean') {
1806
+ init.scrollX = init.scrollX ? '100%' : '';
1807
+ }
1808
+
1809
+ // Column search objects are in an array, so it needs to be converted
1810
+ // element by element
1811
+ var searchCols = init.aoSearchCols;
1812
+
1813
+ if (searchCols) {
1814
+ for (var i = 0, ien = searchCols.length; i < ien; i++) {
1815
+ if (searchCols[i]) {
1816
+ _fnCamelToHungarian(DataTable.models.oSearch, searchCols[i]);
1817
+ }
1818
+ }
1819
+ }
1820
+ }
1821
+
1822
+
1823
+ /**
1824
+ * Provide backwards compatibility for column options. Note that the new options
1825
+ * are mapped onto the old parameters, so this is an external interface change
1826
+ * only.
1827
+ * @param {object} init Object to map
1828
+ */
1829
+ function _fnCompatCols(init)
1830
+ {
1831
+ _fnCompatMap(init, 'orderable', 'bSortable');
1832
+ _fnCompatMap(init, 'orderData', 'aDataSort');
1833
+ _fnCompatMap(init, 'orderSequence', 'asSorting');
1834
+ _fnCompatMap(init, 'orderDataType', 'sortDataType');
1835
+
1836
+ // orderData can be given as an integer
1837
+ var dataSort = init.aDataSort;
1838
+ if (typeof dataSort === 'number' && !$.isArray(dataSort)) {
1839
+ init.aDataSort = [dataSort];
1840
+ }
1841
+ }
1842
+
1843
+
1844
+ /**
1845
+ * Browser feature detection for capabilities, quirks
1846
+ * @param {object} settings dataTables settings object
1847
+ * @memberof DataTable#oApi
1848
+ */
1849
+ function _fnBrowserDetect(settings)
1850
+ {
1851
+ // We don't need to do this every time DataTables is constructed, the values
1852
+ // calculated are specific to the browser and OS configuration which we
1853
+ // don't expect to change between initialisations
1854
+ if (!DataTable.__browser) {
1855
+ var browser = {};
1856
+ DataTable.__browser = browser;
1857
+
1858
+ // Scrolling feature / quirks detection
1859
+ var n = $('<div/>')
1860
+ .css({
1861
+ position: 'fixed',
1862
+ top: 0,
1863
+ left: $(window).scrollLeft() * -1, // allow for scrolling
1864
+ height: 1,
1865
+ width: 1,
1866
+ overflow: 'hidden'
1867
+ })
1868
+ .append(
1869
+ $('<div/>')
1870
+ .css({
1871
+ position: 'absolute',
1872
+ top: 1,
1873
+ left: 1,
1874
+ width: 100,
1875
+ overflow: 'scroll'
1876
+ })
1877
+ .append(
1878
+ $('<div/>')
1879
+ .css({
1880
+ width: '100%',
1881
+ height: 10
1882
+ })
1883
+ )
1884
+ )
1885
+ .appendTo('body');
1886
+
1887
+ var outer = n.children();
1888
+ var inner = outer.children();
1889
+
1890
+ // Numbers below, in order, are:
1891
+ // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
1892
+ //
1893
+ // IE6 XP: 100 100 100 83
1894
+ // IE7 Vista: 100 100 100 83
1895
+ // IE 8+ Windows: 83 83 100 83
1896
+ // Evergreen Windows: 83 83 100 83
1897
+ // Evergreen Mac with scrollbars: 85 85 100 85
1898
+ // Evergreen Mac without scrollbars: 100 100 100 100
1899
+
1900
+ // Get scrollbar width
1901
+ browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
1902
+
1903
+ // IE6/7 will oversize a width 100% element inside a scrolling element, to
1904
+ // include the width of the scrollbar, while other browsers ensure the inner
1905
+ // element is contained without forcing scrolling
1906
+ browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
1907
+
1908
+ // In rtl text layout, some browsers (most, but not all) will place the
1909
+ // scrollbar on the left, rather than the right.
1910
+ browser.bScrollbarLeft = Math.round(inner.offset().left) !== 1;
1911
+
1912
+ // IE8- don't provide height and width for getBoundingClientRect
1913
+ browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
1914
+
1915
+ n.remove();
1916
+ }
1917
+
1918
+ $.extend(settings.oBrowser, DataTable.__browser);
1919
+ settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
1920
+ }
1921
+
1922
+
1923
+ /**
1924
+ * Array.prototype reduce[Right] method, used for browsers which don't support
1925
+ * JS 1.6. Done this way to reduce code size, since we iterate either way
1926
+ * @param {object} settings dataTables settings object
1927
+ * @memberof DataTable#oApi
1928
+ */
1929
+ function _fnReduce(that, fn, init, start, end, inc)
1930
+ {
1931
+ var
1932
+ i = start,
1933
+ value,
1934
+ isSet = false;
1935
+
1936
+ if (init !== undefined) {
1937
+ value = init;
1938
+ isSet = true;
1939
+ }
1940
+
1941
+ while (i !== end) {
1942
+ if (!that.hasOwnProperty(i)) {
1943
+ continue;
1944
+ }
1945
+
1946
+ value = isSet ?
1947
+ fn(value, that[i], i, that) :
1948
+ that[i];
1949
+
1950
+ isSet = true;
1951
+ i += inc;
1952
+ }
1953
+
1954
+ return value;
1955
+ }
1956
+
1957
+ /**
1958
+ * Add a column to the list used for the table with default values
1959
+ * @param {object} oSettings dataTables settings object
1960
+ * @param {node} nTh The th element for this column
1961
+ * @memberof DataTable#oApi
1962
+ */
1963
+ function _fnAddColumn(oSettings, nTh)
1964
+ {
1965
+ // Add column to aoColumns array
1966
+ var oDefaults = DataTable.defaults.column;
1967
+ var iCol = oSettings.aoColumns.length;
1968
+ var oCol = $.extend({}, DataTable.models.oColumn, oDefaults, {
1969
+ "nTh": nTh ? nTh : document.createElement('th'),
1970
+ "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
1971
+ "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
1972
+ "mData": oDefaults.mData ? oDefaults.mData : iCol,
1973
+ idx: iCol
1974
+ });
1975
+ oSettings.aoColumns.push(oCol);
1976
+
1977
+ // Add search object for column specific search. Note that the `searchCols[ iCol ]`
1978
+ // passed into extend can be undefined. This allows the user to give a default
1979
+ // with only some of the parameters defined, and also not give a default
1980
+ var searchCols = oSettings.aoPreSearchCols;
1981
+ searchCols[ iCol ] = $.extend({}, DataTable.models.oSearch, searchCols[ iCol ]);
1982
+
1983
+ // Use the default column options function to initialise classes etc
1984
+ _fnColumnOptions(oSettings, iCol, $(nTh).data());
1985
+ }
1986
+
1987
+
1988
+ /**
1989
+ * Apply options for a column
1990
+ * @param {object} oSettings dataTables settings object
1991
+ * @param {int} iCol column index to consider
1992
+ * @param {object} oOptions object with sType, bVisible and bSearchable etc
1993
+ * @memberof DataTable#oApi
1994
+ */
1995
+ function _fnColumnOptions(oSettings, iCol, oOptions)
1996
+ {
1997
+ var oCol = oSettings.aoColumns[ iCol ];
1998
+ var oClasses = oSettings.oClasses;
1999
+ var th = $(oCol.nTh);
2000
+
2001
+ // Try to get width information from the DOM. We can't get it from CSS
2002
+ // as we'd need to parse the CSS stylesheet. `width` option can override
2003
+ if (!oCol.sWidthOrig) {
2004
+ // Width attribute
2005
+ oCol.sWidthOrig = th.attr('width') || null;
2006
+
2007
+ // Style attribute
2008
+ var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
2009
+ if (t) {
2010
+ oCol.sWidthOrig = t[1];
2011
+ }
2012
+ }
2013
+
2014
+ /* User specified column options */
2015
+ if (oOptions !== undefined && oOptions !== null)
2016
+ {
2017
+ // Backwards compatibility
2018
+ _fnCompatCols(oOptions);
2019
+
2020
+ // Map camel case parameters to their Hungarian counterparts
2021
+ _fnCamelToHungarian(DataTable.defaults.column, oOptions);
2022
+
2023
+ /* Backwards compatibility for mDataProp */
2024
+ if (oOptions.mDataProp !== undefined && !oOptions.mData)
2025
+ {
2026
+ oOptions.mData = oOptions.mDataProp;
2027
+ }
2028
+
2029
+ if (oOptions.sType)
2030
+ {
2031
+ oCol._sManualType = oOptions.sType;
2032
+ }
2033
+
2034
+ // `class` is a reserved word in Javascript, so we need to provide
2035
+ // the ability to use a valid name for the camel case input
2036
+ if (oOptions.className && !oOptions.sClass)
2037
+ {
2038
+ oOptions.sClass = oOptions.className;
2039
+ }
2040
+
2041
+ $.extend(oCol, oOptions);
2042
+ _fnMap(oCol, oOptions, "sWidth", "sWidthOrig");
2043
+
2044
+ /* iDataSort to be applied (backwards compatibility), but aDataSort will take
2045
+ * priority if defined
2046
+ */
2047
+ if (oOptions.iDataSort !== undefined)
2048
+ {
2049
+ oCol.aDataSort = [oOptions.iDataSort];
2050
+ }
2051
+ _fnMap(oCol, oOptions, "aDataSort");
2052
+ }
2053
+
2054
+ /* Cache the data get and set functions for speed */
2055
+ var mDataSrc = oCol.mData;
2056
+ var mData = _fnGetObjectDataFn(mDataSrc);
2057
+ var mRender = oCol.mRender ? _fnGetObjectDataFn(oCol.mRender) : null;
2058
+
2059
+ var attrTest = function (src) {
2060
+ return typeof src === 'string' && src.indexOf('@') !== -1;
2061
+ };
2062
+ oCol._bAttrSrc = $.isPlainObject(mDataSrc) && (
2063
+ attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
2064
+ );
2065
+ oCol._setter = null;
2066
+
2067
+ oCol.fnGetData = function (rowData, type, meta) {
2068
+ var innerData = mData(rowData, type, undefined, meta);
2069
+
2070
+ return mRender && type ?
2071
+ mRender(innerData, type, rowData, meta) :
2072
+ innerData;
2073
+ };
2074
+ oCol.fnSetData = function (rowData, val, meta) {
2075
+ return _fnSetObjectDataFn(mDataSrc)(rowData, val, meta);
2076
+ };
2077
+
2078
+ // Indicate if DataTables should read DOM data as an object or array
2079
+ // Used in _fnGetRowElements
2080
+ if (typeof mDataSrc !== 'number') {
2081
+ oSettings._rowReadObject = true;
2082
+ }
2083
+
2084
+ /* Feature sorting overrides column specific when off */
2085
+ if (!oSettings.oFeatures.bSort)
2086
+ {
2087
+ oCol.bSortable = false;
2088
+ th.addClass(oClasses.sSortableNone); // Have to add class here as order event isn't called
2089
+ }
2090
+
2091
+ /* Check that the class assignment is correct for sorting */
2092
+ var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
2093
+ var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
2094
+ if (!oCol.bSortable || (!bAsc && !bDesc))
2095
+ {
2096
+ oCol.sSortingClass = oClasses.sSortableNone;
2097
+ oCol.sSortingClassJUI = "";
2098
+ } else if (bAsc && !bDesc)
2099
+ {
2100
+ oCol.sSortingClass = oClasses.sSortableAsc;
2101
+ oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
2102
+ } else if (!bAsc && bDesc)
2103
+ {
2104
+ oCol.sSortingClass = oClasses.sSortableDesc;
2105
+ oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
2106
+ } else
2107
+ {
2108
+ oCol.sSortingClass = oClasses.sSortable;
2109
+ oCol.sSortingClassJUI = oClasses.sSortJUI;
2110
+ }
2111
+ }
2112
+
2113
+
2114
+ /**
2115
+ * Adjust the table column widths for new data. Note: you would probably want to
2116
+ * do a redraw after calling this function!
2117
+ * @param {object} settings dataTables settings object
2118
+ * @memberof DataTable#oApi
2119
+ */
2120
+ function _fnAdjustColumnSizing(settings)
2121
+ {
2122
+ /* Not interested in doing column width calculation if auto-width is disabled */
2123
+ if (settings.oFeatures.bAutoWidth !== false)
2124
+ {
2125
+ var columns = settings.aoColumns;
2126
+
2127
+ _fnCalculateColumnWidths(settings);
2128
+ for (var i = 0, iLen = columns.length; i < iLen; i++)
2129
+ {
2130
+ columns[i].nTh.style.width = columns[i].sWidth;
2131
+ }
2132
+ }
2133
+
2134
+ var scroll = settings.oScroll;
2135
+ if (scroll.sY !== '' || scroll.sX !== '')
2136
+ {
2137
+ _fnScrollDraw(settings);
2138
+ }
2139
+
2140
+ _fnCallbackFire(settings, null, 'column-sizing', [settings]);
2141
+ }
2142
+
2143
+
2144
+ /**
2145
+ * Covert the index of a visible column to the index in the data array (take account
2146
+ * of hidden columns)
2147
+ * @param {object} oSettings dataTables settings object
2148
+ * @param {int} iMatch Visible column index to lookup
2149
+ * @returns {int} i the data index
2150
+ * @memberof DataTable#oApi
2151
+ */
2152
+ function _fnVisibleToColumnIndex(oSettings, iMatch)
2153
+ {
2154
+ var aiVis = _fnGetColumns(oSettings, 'bVisible');
2155
+
2156
+ return typeof aiVis[iMatch] === 'number' ?
2157
+ aiVis[iMatch] :
2158
+ null;
2159
+ }
2160
+
2161
+
2162
+ /**
2163
+ * Covert the index of an index in the data array and convert it to the visible
2164
+ * column index (take account of hidden columns)
2165
+ * @param {int} iMatch Column index to lookup
2166
+ * @param {object} oSettings dataTables settings object
2167
+ * @returns {int} i the data index
2168
+ * @memberof DataTable#oApi
2169
+ */
2170
+ function _fnColumnIndexToVisible(oSettings, iMatch)
2171
+ {
2172
+ var aiVis = _fnGetColumns(oSettings, 'bVisible');
2173
+ var iPos = $.inArray(iMatch, aiVis);
2174
+
2175
+ return iPos !== -1 ? iPos : null;
2176
+ }
2177
+
2178
+
2179
+ /**
2180
+ * Get the number of visible columns
2181
+ * @param {object} oSettings dataTables settings object
2182
+ * @returns {int} i the number of visible columns
2183
+ * @memberof DataTable#oApi
2184
+ */
2185
+ function _fnVisbleColumns(oSettings)
2186
+ {
2187
+ var vis = 0;
2188
+
2189
+ // No reduce in IE8, use a loop for now
2190
+ $.each(oSettings.aoColumns, function (i, col) {
2191
+ if (col.bVisible && $(col.nTh).css('display') !== 'none') {
2192
+ vis++;
2193
+ }
2194
+ });
2195
+
2196
+ return vis;
2197
+ }
2198
+
2199
+
2200
+ /**
2201
+ * Get an array of column indexes that match a given property
2202
+ * @param {object} oSettings dataTables settings object
2203
+ * @param {string} sParam Parameter in aoColumns to look for - typically
2204
+ * bVisible or bSearchable
2205
+ * @returns {array} Array of indexes with matched properties
2206
+ * @memberof DataTable#oApi
2207
+ */
2208
+ function _fnGetColumns(oSettings, sParam)
2209
+ {
2210
+ var a = [];
2211
+
2212
+ $.map(oSettings.aoColumns, function (val, i) {
2213
+ if (val[sParam]) {
2214
+ a.push(i);
2215
+ }
2216
+ });
2217
+
2218
+ return a;
2219
+ }
2220
+
2221
+
2222
+ /**
2223
+ * Calculate the 'type' of a column
2224
+ * @param {object} settings dataTables settings object
2225
+ * @memberof DataTable#oApi
2226
+ */
2227
+ function _fnColumnTypes(settings)
2228
+ {
2229
+ var columns = settings.aoColumns;
2230
+ var data = settings.aoData;
2231
+ var types = DataTable.ext.type.detect;
2232
+ var i, ien, j, jen, k, ken;
2233
+ var col, cell, detectedType, cache;
2234
+
2235
+ // For each column, spin over the
2236
+ for (i = 0, ien = columns.length; i < ien; i++) {
2237
+ col = columns[i];
2238
+ cache = [];
2239
+
2240
+ if (!col.sType && col._sManualType) {
2241
+ col.sType = col._sManualType;
2242
+ } else if (!col.sType) {
2243
+ for (j = 0, jen = types.length; j < jen; j++) {
2244
+ for (k = 0, ken = data.length; k < ken; k++) {
2245
+ // Use a cache array so we only need to get the type data
2246
+ // from the formatter once (when using multiple detectors)
2247
+ if (cache[k] === undefined) {
2248
+ cache[k] = _fnGetCellData(settings, k, i, 'type');
2249
+ }
2250
+
2251
+ detectedType = types[j](cache[k], settings);
2252
+
2253
+ // If null, then this type can't apply to this column, so
2254
+ // rather than testing all cells, break out. There is an
2255
+ // exception for the last type which is `html`. We need to
2256
+ // scan all rows since it is possible to mix string and HTML
2257
+ // types
2258
+ if (!detectedType && j !== types.length - 1) {
2259
+ break;
2260
+ }
2261
+
2262
+ // Only a single match is needed for html type since it is
2263
+ // bottom of the pile and very similar to string
2264
+ if (detectedType === 'html') {
2265
+ break;
2266
+ }
2267
+ }
2268
+
2269
+ // Type is valid for all data points in the column - use this
2270
+ // type
2271
+ if (detectedType) {
2272
+ col.sType = detectedType;
2273
+ break;
2274
+ }
2275
+ }
2276
+
2277
+ // Fall back - if no type was detected, always use string
2278
+ if (!col.sType) {
2279
+ col.sType = 'string';
2280
+ }
2281
+ }
2282
+ }
2283
+ }
2284
+
2285
+
2286
+ /**
2287
+ * Take the column definitions and static columns arrays and calculate how
2288
+ * they relate to column indexes. The callback function will then apply the
2289
+ * definition found for a column to a suitable configuration object.
2290
+ * @param {object} oSettings dataTables settings object
2291
+ * @param {array} aoColDefs The aoColumnDefs array that is to be applied
2292
+ * @param {array} aoCols The aoColumns array that defines columns individually
2293
+ * @param {function} fn Callback function - takes two parameters, the calculated
2294
+ * column index and the definition for that column.
2295
+ * @memberof DataTable#oApi
2296
+ */
2297
+ function _fnApplyColumnDefs(oSettings, aoColDefs, aoCols, fn)
2298
+ {
2299
+ var i, iLen, j, jLen, k, kLen, def;
2300
+ var columns = oSettings.aoColumns;
2301
+
2302
+ // Column definitions with aTargets
2303
+ if (aoColDefs)
2304
+ {
2305
+ /* Loop over the definitions array - loop in reverse so first instance has priority */
2306
+ for (i = aoColDefs.length - 1; i >= 0; i--)
2307
+ {
2308
+ def = aoColDefs[i];
2309
+
2310
+ /* Each definition can target multiple columns, as it is an array */
2311
+ var aTargets = def.targets !== undefined ?
2312
+ def.targets :
2313
+ def.aTargets;
2314
+
2315
+ if (!$.isArray(aTargets))
2316
+ {
2317
+ aTargets = [aTargets];
2318
+ }
2319
+
2320
+ for (j = 0, jLen = aTargets.length; j < jLen; j++)
2321
+ {
2322
+ if (typeof aTargets[j] === 'number' && aTargets[j] >= 0)
2323
+ {
2324
+ /* Add columns that we don't yet know about */
2325
+ while (columns.length <= aTargets[j])
2326
+ {
2327
+ _fnAddColumn(oSettings);
2328
+ }
2329
+
2330
+ /* Integer, basic index */
2331
+ fn(aTargets[j], def);
2332
+ } else if (typeof aTargets[j] === 'number' && aTargets[j] < 0)
2333
+ {
2334
+ /* Negative integer, right to left column counting */
2335
+ fn(columns.length + aTargets[j], def);
2336
+ } else if (typeof aTargets[j] === 'string')
2337
+ {
2338
+ /* Class name matching on TH element */
2339
+ for (k = 0, kLen = columns.length; k < kLen; k++)
2340
+ {
2341
+ if (aTargets[j] == "_all" ||
2342
+ $(columns[k].nTh).hasClass(aTargets[j]))
2343
+ {
2344
+ fn(k, def);
2345
+ }
2346
+ }
2347
+ }
2348
+ }
2349
+ }
2350
+ }
2351
+
2352
+ // Statically defined columns array
2353
+ if (aoCols)
2354
+ {
2355
+ for (i = 0, iLen = aoCols.length; i < iLen; i++)
2356
+ {
2357
+ fn(i, aoCols[i]);
2358
+ }
2359
+ }
2360
+ }
2361
+
2362
+ /**
2363
+ * Add a data array to the table, creating DOM node etc. This is the parallel to
2364
+ * _fnGatherData, but for adding rows from a Javascript source, rather than a
2365
+ * DOM source.
2366
+ * @param {object} oSettings dataTables settings object
2367
+ * @param {array} aData data array to be added
2368
+ * @param {node} [nTr] TR element to add to the table - optional. If not given,
2369
+ * DataTables will create a row automatically
2370
+ * @param {array} [anTds] Array of TD|TH elements for the row - must be given
2371
+ * if nTr is.
2372
+ * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
2373
+ * @memberof DataTable#oApi
2374
+ */
2375
+ function _fnAddData(oSettings, aDataIn, nTr, anTds)
2376
+ {
2377
+ /* Create the object for storing information about this new row */
2378
+ var iRow = oSettings.aoData.length;
2379
+ var oData = $.extend(true, {}, DataTable.models.oRow, {
2380
+ src: nTr ? 'dom' : 'data',
2381
+ idx: iRow
2382
+ });
2383
+
2384
+ oData._aData = aDataIn;
2385
+ oSettings.aoData.push(oData);
2386
+
2387
+ /* Create the cells */
2388
+ var nTd, sThisType;
2389
+ var columns = oSettings.aoColumns;
2390
+
2391
+ // Invalidate the column types as the new data needs to be revalidated
2392
+ for (var i = 0, iLen = columns.length; i < iLen; i++)
2393
+ {
2394
+ columns[i].sType = null;
2395
+ }
2396
+
2397
+ /* Add to the display array */
2398
+ oSettings.aiDisplayMaster.push(iRow);
2399
+
2400
+ var id = oSettings.rowIdFn(aDataIn);
2401
+ if (id !== undefined) {
2402
+ oSettings.aIds[ id ] = oData;
2403
+ }
2404
+
2405
+ /* Create the DOM information, or register it if already present */
2406
+ if (nTr || !oSettings.oFeatures.bDeferRender)
2407
+ {
2408
+ _fnCreateTr(oSettings, iRow, nTr, anTds);
2409
+ }
2410
+
2411
+ return iRow;
2412
+ }
2413
+
2414
+
2415
+ /**
2416
+ * Add one or more TR elements to the table. Generally we'd expect to
2417
+ * use this for reading data from a DOM sourced table, but it could be
2418
+ * used for an TR element. Note that if a TR is given, it is used (i.e.
2419
+ * it is not cloned).
2420
+ * @param {object} settings dataTables settings object
2421
+ * @param {array|node|jQuery} trs The TR element(s) to add to the table
2422
+ * @returns {array} Array of indexes for the added rows
2423
+ * @memberof DataTable#oApi
2424
+ */
2425
+ function _fnAddTr(settings, trs)
2426
+ {
2427
+ var row;
2428
+
2429
+ // Allow an individual node to be passed in
2430
+ if (!(trs instanceof $)) {
2431
+ trs = $(trs);
2432
+ }
2433
+
2434
+ return trs.map(function (i, el) {
2435
+ row = _fnGetRowElements(settings, el);
2436
+ return _fnAddData(settings, row.data, el, row.cells);
2437
+ });
2438
+ }
2439
+
2440
+
2441
+ /**
2442
+ * Take a TR element and convert it to an index in aoData
2443
+ * @param {object} oSettings dataTables settings object
2444
+ * @param {node} n the TR element to find
2445
+ * @returns {int} index if the node is found, null if not
2446
+ * @memberof DataTable#oApi
2447
+ */
2448
+ function _fnNodeToDataIndex(oSettings, n)
2449
+ {
2450
+ return (n._DT_RowIndex !== undefined) ? n._DT_RowIndex : null;
2451
+ }
2452
+
2453
+
2454
+ /**
2455
+ * Take a TD element and convert it into a column data index (not the visible index)
2456
+ * @param {object} oSettings dataTables settings object
2457
+ * @param {int} iRow The row number the TD/TH can be found in
2458
+ * @param {node} n The TD/TH element to find
2459
+ * @returns {int} index if the node is found, -1 if not
2460
+ * @memberof DataTable#oApi
2461
+ */
2462
+ function _fnNodeToColumnIndex(oSettings, iRow, n)
2463
+ {
2464
+ return $.inArray(n, oSettings.aoData[ iRow ].anCells);
2465
+ }
2466
+
2467
+
2468
+ /**
2469
+ * Get the data for a given cell from the internal cache, taking into account data mapping
2470
+ * @param {object} settings dataTables settings object
2471
+ * @param {int} rowIdx aoData row id
2472
+ * @param {int} colIdx Column index
2473
+ * @param {string} type data get type ('display', 'type' 'filter' 'sort')
2474
+ * @returns {*} Cell data
2475
+ * @memberof DataTable#oApi
2476
+ */
2477
+ function _fnGetCellData(settings, rowIdx, colIdx, type)
2478
+ {
2479
+ var draw = settings.iDraw;
2480
+ var col = settings.aoColumns[colIdx];
2481
+ var rowData = settings.aoData[rowIdx]._aData;
2482
+ var defaultContent = col.sDefaultContent;
2483
+ var cellData = col.fnGetData(rowData, type, {
2484
+ settings: settings,
2485
+ row: rowIdx,
2486
+ col: colIdx
2487
+ });
2488
+
2489
+ if (cellData === undefined) {
2490
+ if (settings.iDrawError != draw && defaultContent === null) {
2491
+ _fnLog(settings, 0, "Requested unknown parameter " +
2492
+ (typeof col.mData == 'function' ? '{function}' : "'" + col.mData + "'") +
2493
+ " for row " + rowIdx + ", column " + colIdx, 4);
2494
+ settings.iDrawError = draw;
2495
+ }
2496
+ return defaultContent;
2497
+ }
2498
+
2499
+ // When the data source is null and a specific data type is requested (i.e.
2500
+ // not the original data), we can use default column data
2501
+ if ((cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined) {
2502
+ cellData = defaultContent;
2503
+ } else if (typeof cellData === 'function') {
2504
+ // If the data source is a function, then we run it and use the return,
2505
+ // executing in the scope of the data object (for instances)
2506
+ return cellData.call(rowData);
2507
+ }
2508
+
2509
+ if (cellData === null && type == 'display') {
2510
+ return '';
2511
+ }
2512
+ return cellData;
2513
+ }
2514
+
2515
+
2516
+ /**
2517
+ * Set the value for a specific cell, into the internal data cache
2518
+ * @param {object} settings dataTables settings object
2519
+ * @param {int} rowIdx aoData row id
2520
+ * @param {int} colIdx Column index
2521
+ * @param {*} val Value to set
2522
+ * @memberof DataTable#oApi
2523
+ */
2524
+ function _fnSetCellData(settings, rowIdx, colIdx, val)
2525
+ {
2526
+ var col = settings.aoColumns[colIdx];
2527
+ var rowData = settings.aoData[rowIdx]._aData;
2528
+
2529
+ col.fnSetData(rowData, val, {
2530
+ settings: settings,
2531
+ row: rowIdx,
2532
+ col: colIdx
2533
+ });
2534
+ }
2535
+
2536
+
2537
+ // Private variable that is used to match action syntax in the data property object
2538
+ var __reArray = /\[.*?\]$/;
2539
+ var __reFn = /\(\)$/;
2540
+
2541
+ /**
2542
+ * Split string on periods, taking into account escaped periods
2543
+ * @param {string} str String to split
2544
+ * @return {array} Split string
2545
+ */
2546
+ function _fnSplitObjNotation(str)
2547
+ {
2548
+ return $.map(str.match(/(\\.|[^\.])+/g) || [''], function (s) {
2549
+ return s.replace(/\\\./g, '.');
2550
+ });
2551
+ }
2552
+
2553
+
2554
+ /**
2555
+ * Return a function that can be used to get data from a source object, taking
2556
+ * into account the ability to use nested objects as a source
2557
+ * @param {string|int|function} mSource The data source for the object
2558
+ * @returns {function} Data get function
2559
+ * @memberof DataTable#oApi
2560
+ */
2561
+ function _fnGetObjectDataFn(mSource)
2562
+ {
2563
+ if ($.isPlainObject(mSource))
2564
+ {
2565
+ /* Build an object of get functions, and wrap them in a single call */
2566
+ var o = {};
2567
+ $.each(mSource, function (key, val) {
2568
+ if (val) {
2569
+ o[key] = _fnGetObjectDataFn(val);
2570
+ }
2571
+ });
2572
+
2573
+ return function (data, type, row, meta) {
2574
+ var t = o[type] || o._;
2575
+ return t !== undefined ?
2576
+ t(data, type, row, meta) :
2577
+ data;
2578
+ };
2579
+ } else if (mSource === null)
2580
+ {
2581
+ /* Give an empty string for rendering / sorting etc */
2582
+ return function (data) { // type, row and meta also passed, but not used
2583
+ return data;
2584
+ };
2585
+ } else if (typeof mSource === 'function')
2586
+ {
2587
+ return function (data, type, row, meta) {
2588
+ return mSource(data, type, row, meta);
2589
+ };
2590
+ } else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2591
+ mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1))
2592
+ {
2593
+ /* If there is a . in the source string then the data source is in a
2594
+ * nested object so we loop over the data for each level to get the next
2595
+ * level down. On each loop we test for undefined, and if found immediately
2596
+ * return. This allows entire objects to be missing and sDefaultContent to
2597
+ * be used if defined, rather than throwing an error
2598
+ */
2599
+ var fetchData = function (data, type, src) {
2600
+ var arrayNotation, funcNotation, out, innerSrc;
2601
+
2602
+ if (src !== "")
2603
+ {
2604
+ var a = _fnSplitObjNotation(src);
2605
+
2606
+ for (var i = 0, iLen = a.length; i < iLen; i++)
2607
+ {
2608
+ // Check if we are dealing with special notation
2609
+ arrayNotation = a[i].match(__reArray);
2610
+ funcNotation = a[i].match(__reFn);
2611
+
2612
+ if (arrayNotation)
2613
+ {
2614
+ // Array notation
2615
+ a[i] = a[i].replace(__reArray, '');
2616
+
2617
+ // Condition allows simply [] to be passed in
2618
+ if (a[i] !== "") {
2619
+ data = data[ a[i] ];
2620
+ }
2621
+ out = [];
2622
+
2623
+ // Get the remainder of the nested object to get
2624
+ a.splice(0, i + 1);
2625
+ innerSrc = a.join('.');
2626
+
2627
+ // Traverse each entry in the array getting the properties requested
2628
+ if ($.isArray(data)) {
2629
+ for (var j = 0, jLen = data.length; j < jLen; j++) {
2630
+ out.push(fetchData(data[j], type, innerSrc));
2631
+ }
2632
+ }
2633
+
2634
+ // If a string is given in between the array notation indicators, that
2635
+ // is used to join the strings together, otherwise an array is returned
2636
+ var join = arrayNotation[0].substring(1, arrayNotation[0].length - 1);
2637
+ data = (join === "") ? out : out.join(join);
2638
+
2639
+ // The inner call to fetchData has already traversed through the remainder
2640
+ // of the source requested, so we exit from the loop
2641
+ break;
2642
+ } else if (funcNotation)
2643
+ {
2644
+ // Function call
2645
+ a[i] = a[i].replace(__reFn, '');
2646
+ data = data[ a[i] ]();
2647
+ continue;
2648
+ }
2649
+
2650
+ if (data === null || data[ a[i] ] === undefined)
2651
+ {
2652
+ return undefined;
2653
+ }
2654
+ data = data[ a[i] ];
2655
+ }
2656
+ }
2657
+
2658
+ return data;
2659
+ };
2660
+
2661
+ return function (data, type) { // row and meta also passed, but not used
2662
+ return fetchData(data, type, mSource);
2663
+ };
2664
+ } else
2665
+ {
2666
+ /* Array or flat object mapping */
2667
+ return function (data, type) { // row and meta also passed, but not used
2668
+ return data[mSource];
2669
+ };
2670
+ }
2671
+ }
2672
+
2673
+
2674
+ /**
2675
+ * Return a function that can be used to set data from a source object, taking
2676
+ * into account the ability to use nested objects as a source
2677
+ * @param {string|int|function} mSource The data source for the object
2678
+ * @returns {function} Data set function
2679
+ * @memberof DataTable#oApi
2680
+ */
2681
+ function _fnSetObjectDataFn(mSource)
2682
+ {
2683
+ if ($.isPlainObject(mSource))
2684
+ {
2685
+ /* Unlike get, only the underscore (global) option is used for for
2686
+ * setting data since we don't know the type here. This is why an object
2687
+ * option is not documented for `mData` (which is read/write), but it is
2688
+ * for `mRender` which is read only.
2689
+ */
2690
+ return _fnSetObjectDataFn(mSource._);
2691
+ } else if (mSource === null)
2692
+ {
2693
+ /* Nothing to do when the data source is null */
2694
+ return function () {};
2695
+ } else if (typeof mSource === 'function')
2696
+ {
2697
+ return function (data, val, meta) {
2698
+ mSource(data, 'set', val, meta);
2699
+ };
2700
+ } else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2701
+ mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1))
2702
+ {
2703
+ /* Like the get, we need to get data from a nested object */
2704
+ var setData = function (data, val, src) {
2705
+ var a = _fnSplitObjNotation(src), b;
2706
+ var aLast = a[a.length - 1];
2707
+ var arrayNotation, funcNotation, o, innerSrc;
2708
+
2709
+ for (var i = 0, iLen = a.length - 1; i < iLen; i++)
2710
+ {
2711
+ // Check if we are dealing with an array notation request
2712
+ arrayNotation = a[i].match(__reArray);
2713
+ funcNotation = a[i].match(__reFn);
2714
+
2715
+ if (arrayNotation)
2716
+ {
2717
+ a[i] = a[i].replace(__reArray, '');
2718
+ data[ a[i] ] = [];
2719
+
2720
+ // Get the remainder of the nested object to set so we can recurse
2721
+ b = a.slice();
2722
+ b.splice(0, i + 1);
2723
+ innerSrc = b.join('.');
2724
+
2725
+ // Traverse each entry in the array setting the properties requested
2726
+ if ($.isArray(val))
2727
+ {
2728
+ for (var j = 0, jLen = val.length; j < jLen; j++)
2729
+ {
2730
+ o = {};
2731
+ setData(o, val[j], innerSrc);
2732
+ data[ a[i] ].push(o);
2733
+ }
2734
+ } else
2735
+ {
2736
+ // We've been asked to save data to an array, but it
2737
+ // isn't array data to be saved. Best that can be done
2738
+ // is to just save the value.
2739
+ data[ a[i] ] = val;
2740
+ }
2741
+
2742
+ // The inner call to setData has already traversed through the remainder
2743
+ // of the source and has set the data, thus we can exit here
2744
+ return;
2745
+ } else if (funcNotation)
2746
+ {
2747
+ // Function call
2748
+ a[i] = a[i].replace(__reFn, '');
2749
+ data = data[ a[i] ](val);
2750
+ }
2751
+
2752
+ // If the nested object doesn't currently exist - since we are
2753
+ // trying to set the value - create it
2754
+ if (data[ a[i] ] === null || data[ a[i] ] === undefined)
2755
+ {
2756
+ data[ a[i] ] = {};
2757
+ }
2758
+ data = data[ a[i] ];
2759
+ }
2760
+
2761
+ // Last item in the input - i.e, the actual set
2762
+ if (aLast.match(__reFn))
2763
+ {
2764
+ // Function call
2765
+ data = data[ aLast.replace(__reFn, '') ](val);
2766
+ } else
2767
+ {
2768
+ // If array notation is used, we just want to strip it and use the property name
2769
+ // and assign the value. If it isn't used, then we get the result we want anyway
2770
+ data[ aLast.replace(__reArray, '') ] = val;
2771
+ }
2772
+ };
2773
+
2774
+ return function (data, val) { // meta is also passed in, but not used
2775
+ return setData(data, val, mSource);
2776
+ };
2777
+ } else
2778
+ {
2779
+ /* Array or flat object mapping */
2780
+ return function (data, val) { // meta is also passed in, but not used
2781
+ data[mSource] = val;
2782
+ };
2783
+ }
2784
+ }
2785
+
2786
+
2787
+ /**
2788
+ * Return an array with the full table data
2789
+ * @param {object} oSettings dataTables settings object
2790
+ * @returns array {array} aData Master data array
2791
+ * @memberof DataTable#oApi
2792
+ */
2793
+ function _fnGetDataMaster(settings)
2794
+ {
2795
+ return _pluck(settings.aoData, '_aData');
2796
+ }
2797
+
2798
+
2799
+ /**
2800
+ * Nuke the table
2801
+ * @param {object} oSettings dataTables settings object
2802
+ * @memberof DataTable#oApi
2803
+ */
2804
+ function _fnClearTable(settings)
2805
+ {
2806
+ settings.aoData.length = 0;
2807
+ settings.aiDisplayMaster.length = 0;
2808
+ settings.aiDisplay.length = 0;
2809
+ settings.aIds = {};
2810
+ }
2811
+
2812
+
2813
+ /**
2814
+ * Take an array of integers (index array) and remove a target integer (value - not
2815
+ * the key!)
2816
+ * @param {array} a Index array to target
2817
+ * @param {int} iTarget value to find
2818
+ * @memberof DataTable#oApi
2819
+ */
2820
+ function _fnDeleteIndex(a, iTarget, splice)
2821
+ {
2822
+ var iTargetIndex = -1;
2823
+
2824
+ for (var i = 0, iLen = a.length; i < iLen; i++)
2825
+ {
2826
+ if (a[i] == iTarget)
2827
+ {
2828
+ iTargetIndex = i;
2829
+ } else if (a[i] > iTarget)
2830
+ {
2831
+ a[i]--;
2832
+ }
2833
+ }
2834
+
2835
+ if (iTargetIndex != -1 && splice === undefined)
2836
+ {
2837
+ a.splice(iTargetIndex, 1);
2838
+ }
2839
+ }
2840
+
2841
+
2842
+ /**
2843
+ * Mark cached data as invalid such that a re-read of the data will occur when
2844
+ * the cached data is next requested. Also update from the data source object.
2845
+ *
2846
+ * @param {object} settings DataTables settings object
2847
+ * @param {int} rowIdx Row index to invalidate
2848
+ * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
2849
+ * or 'data'
2850
+ * @param {int} [colIdx] Column index to invalidate. If undefined the whole
2851
+ * row will be invalidated
2852
+ * @memberof DataTable#oApi
2853
+ *
2854
+ * @todo For the modularisation of v1.11 this will need to become a callback, so
2855
+ * the sort and filter methods can subscribe to it. That will required
2856
+ * initialisation options for sorting, which is why it is not already baked in
2857
+ */
2858
+ function _fnInvalidate(settings, rowIdx, src, colIdx)
2859
+ {
2860
+ var row = settings.aoData[ rowIdx ];
2861
+ var i, ien;
2862
+ var cellWrite = function (cell, col) {
2863
+ // This is very frustrating, but in IE if you just write directly
2864
+ // to innerHTML, and elements that are overwritten are GC'ed,
2865
+ // even if there is a reference to them elsewhere
2866
+ while (cell.childNodes.length) {
2867
+ cell.removeChild(cell.firstChild);
2868
+ }
2869
+
2870
+ cell.innerHTML = _fnGetCellData(settings, rowIdx, col, 'display');
2871
+ };
2872
+
2873
+ // Are we reading last data from DOM or the data object?
2874
+ if (src === 'dom' || ((!src || src === 'auto') && row.src === 'dom')) {
2875
+ // Read the data from the DOM
2876
+ row._aData = _fnGetRowElements(
2877
+ settings, row, colIdx, colIdx === undefined ? undefined : row._aData
2878
+ )
2879
+ .data;
2880
+ } else {
2881
+ // Reading from data object, update the DOM
2882
+ var cells = row.anCells;
2883
+
2884
+ if (cells) {
2885
+ if (colIdx !== undefined) {
2886
+ cellWrite(cells[colIdx], colIdx);
2887
+ } else {
2888
+ for (i = 0, ien = cells.length; i < ien; i++) {
2889
+ cellWrite(cells[i], i);
2890
+ }
2891
+ }
2892
+ }
2893
+ }
2894
+
2895
+ // For both row and cell invalidation, the cached data for sorting and
2896
+ // filtering is nulled out
2897
+ row._aSortData = null;
2898
+ row._aFilterData = null;
2899
+
2900
+ // Invalidate the type for a specific column (if given) or all columns since
2901
+ // the data might have changed
2902
+ var cols = settings.aoColumns;
2903
+ if (colIdx !== undefined) {
2904
+ cols[ colIdx ].sType = null;
2905
+ } else {
2906
+ for (i = 0, ien = cols.length; i < ien; i++) {
2907
+ cols[i].sType = null;
2908
+ }
2909
+
2910
+ // Update DataTables special `DT_*` attributes for the row
2911
+ _fnRowAttributes(settings, row);
2912
+ }
2913
+ }
2914
+
2915
+
2916
+ /**
2917
+ * Build a data source object from an HTML row, reading the contents of the
2918
+ * cells that are in the row.
2919
+ *
2920
+ * @param {object} settings DataTables settings object
2921
+ * @param {node|object} TR element from which to read data or existing row
2922
+ * object from which to re-read the data from the cells
2923
+ * @param {int} [colIdx] Optional column index
2924
+ * @param {array|object} [d] Data source object. If `colIdx` is given then this
2925
+ * parameter should also be given and will be used to write the data into.
2926
+ * Only the column in question will be written
2927
+ * @returns {object} Object with two parameters: `data` the data read, in
2928
+ * document order, and `cells` and array of nodes (they can be useful to the
2929
+ * caller, so rather than needing a second traversal to get them, just return
2930
+ * them from here).
2931
+ * @memberof DataTable#oApi
2932
+ */
2933
+ function _fnGetRowElements(settings, row, colIdx, d)
2934
+ {
2935
+ var
2936
+ tds = [],
2937
+ td = row.firstChild,
2938
+ name, col, o, i = 0, contents,
2939
+ columns = settings.aoColumns,
2940
+ objectRead = settings._rowReadObject;
2941
+
2942
+ // Allow the data object to be passed in, or construct
2943
+ d = d !== undefined ?
2944
+ d :
2945
+ objectRead ?
2946
+ {} :
2947
+ [];
2948
+
2949
+ var attr = function (str, td) {
2950
+ if (typeof str === 'string') {
2951
+ var idx = str.indexOf('@');
2952
+
2953
+ if (idx !== -1) {
2954
+ var attr = str.substring(idx + 1);
2955
+ var setter = _fnSetObjectDataFn(str);
2956
+ setter(d, td.getAttribute(attr));
2957
+ }
2958
+ }
2959
+ };
2960
+
2961
+ // Read data from a cell and store into the data object
2962
+ var cellProcess = function (cell) {
2963
+ if (colIdx === undefined || colIdx === i) {
2964
+ col = columns[i];
2965
+ contents = $.trim(cell.innerHTML);
2966
+
2967
+ if (col && col._bAttrSrc) {
2968
+ var setter = _fnSetObjectDataFn(col.mData._);
2969
+ setter(d, contents);
2970
+
2971
+ attr(col.mData.sort, cell);
2972
+ attr(col.mData.type, cell);
2973
+ attr(col.mData.filter, cell);
2974
+ } else {
2975
+ // Depending on the `data` option for the columns the data can
2976
+ // be read to either an object or an array.
2977
+ if (objectRead) {
2978
+ if (!col._setter) {
2979
+ // Cache the setter function
2980
+ col._setter = _fnSetObjectDataFn(col.mData);
2981
+ }
2982
+ col._setter(d, contents);
2983
+ } else {
2984
+ d[i] = contents;
2985
+ }
2986
+ }
2987
+ }
2988
+
2989
+ i++;
2990
+ };
2991
+
2992
+ if (td) {
2993
+ // `tr` element was passed in
2994
+ while (td) {
2995
+ name = td.nodeName.toUpperCase();
2996
+
2997
+ if (name == "TD" || name == "TH") {
2998
+ cellProcess(td);
2999
+ tds.push(td);
3000
+ }
3001
+
3002
+ td = td.nextSibling;
3003
+ }
3004
+ } else {
3005
+ // Existing row object passed in
3006
+ tds = row.anCells;
3007
+
3008
+ for (var j = 0, jen = tds.length; j < jen; j++) {
3009
+ cellProcess(tds[j]);
3010
+ }
3011
+ }
3012
+
3013
+ // Read the ID from the DOM if present
3014
+ var rowNode = row.firstChild ? row : row.nTr;
3015
+
3016
+ if (rowNode) {
3017
+ var id = rowNode.getAttribute('id');
3018
+
3019
+ if (id) {
3020
+ _fnSetObjectDataFn(settings.rowId)(d, id);
3021
+ }
3022
+ }
3023
+
3024
+ return {
3025
+ data: d,
3026
+ cells: tds
3027
+ };
3028
+ }
3029
+ /**
3030
+ * Create a new TR element (and it's TD children) for a row
3031
+ * @param {object} oSettings dataTables settings object
3032
+ * @param {int} iRow Row to consider
3033
+ * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
3034
+ * DataTables will create a row automatically
3035
+ * @param {array} [anTds] Array of TD|TH elements for the row - must be given
3036
+ * if nTr is.
3037
+ * @memberof DataTable#oApi
3038
+ */
3039
+ function _fnCreateTr(oSettings, iRow, nTrIn, anTds)
3040
+ {
3041
+ var
3042
+ row = oSettings.aoData[iRow],
3043
+ rowData = row._aData,
3044
+ cells = [],
3045
+ nTr, nTd, oCol,
3046
+ i, iLen;
3047
+
3048
+ if (row.nTr === null)
3049
+ {
3050
+ nTr = nTrIn || document.createElement('tr');
3051
+
3052
+ row.nTr = nTr;
3053
+ row.anCells = cells;
3054
+
3055
+ /* Use a private property on the node to allow reserve mapping from the node
3056
+ * to the aoData array for fast look up
3057
+ */
3058
+ nTr._DT_RowIndex = iRow;
3059
+
3060
+ /* Special parameters can be given by the data source to be used on the row */
3061
+ _fnRowAttributes(oSettings, row);
3062
+
3063
+ /* Process each column */
3064
+ for (i = 0, iLen = oSettings.aoColumns.length; i < iLen; i++)
3065
+ {
3066
+ oCol = oSettings.aoColumns[i];
3067
+
3068
+ nTd = nTrIn ? anTds[i] : document.createElement(oCol.sCellType);
3069
+ nTd._DT_CellIndex = {
3070
+ row: iRow,
3071
+ column: i
3072
+ };
3073
+
3074
+ cells.push(nTd);
3075
+
3076
+ // Need to create the HTML if new, or if a rendering function is defined
3077
+ if ((!nTrIn || oCol.mRender || oCol.mData !== i) &&
3078
+ (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i + '.display')
3079
+ ) {
3080
+ nTd.innerHTML = _fnGetCellData(oSettings, iRow, i, 'display');
3081
+ }
3082
+
3083
+ /* Add user defined class */
3084
+ if (oCol.sClass)
3085
+ {
3086
+ nTd.className += ' ' + oCol.sClass;
3087
+ }
3088
+
3089
+ // Visibility - add or remove as required
3090
+ if (oCol.bVisible && !nTrIn)
3091
+ {
3092
+ nTr.appendChild(nTd);
3093
+ } else if (!oCol.bVisible && nTrIn)
3094
+ {
3095
+ nTd.parentNode.removeChild(nTd);
3096
+ }
3097
+
3098
+ if (oCol.fnCreatedCell)
3099
+ {
3100
+ oCol.fnCreatedCell.call(oSettings.oInstance,
3101
+ nTd, _fnGetCellData(oSettings, iRow, i), rowData, iRow, i
3102
+ );
3103
+ }
3104
+ }
3105
+
3106
+ _fnCallbackFire(oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow]);
3107
+ }
3108
+
3109
+ // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
3110
+ // and deployed
3111
+ row.nTr.setAttribute('role', 'row');
3112
+ }
3113
+
3114
+
3115
+ /**
3116
+ * Add attributes to a row based on the special `DT_*` parameters in a data
3117
+ * source object.
3118
+ * @param {object} settings DataTables settings object
3119
+ * @param {object} DataTables row object for the row to be modified
3120
+ * @memberof DataTable#oApi
3121
+ */
3122
+ function _fnRowAttributes(settings, row)
3123
+ {
3124
+ var tr = row.nTr;
3125
+ var data = row._aData;
3126
+
3127
+ if (tr) {
3128
+ var id = settings.rowIdFn(data);
3129
+
3130
+ if (id) {
3131
+ tr.id = id;
3132
+ }
3133
+
3134
+ if (data.DT_RowClass) {
3135
+ // Remove any classes added by DT_RowClass before
3136
+ var a = data.DT_RowClass.split(' ');
3137
+ row.__rowc = row.__rowc ?
3138
+ _unique(row.__rowc.concat(a)) :
3139
+ a;
3140
+
3141
+ $(tr)
3142
+ .removeClass(row.__rowc.join(' '))
3143
+ .addClass(data.DT_RowClass);
3144
+ }
3145
+
3146
+ if (data.DT_RowAttr) {
3147
+ $(tr).attr(data.DT_RowAttr);
3148
+ }
3149
+
3150
+ if (data.DT_RowData) {
3151
+ $(tr).data(data.DT_RowData);
3152
+ }
3153
+ }
3154
+ }
3155
+
3156
+
3157
+ /**
3158
+ * Create the HTML header for the table
3159
+ * @param {object} oSettings dataTables settings object
3160
+ * @memberof DataTable#oApi
3161
+ */
3162
+ function _fnBuildHead(oSettings)
3163
+ {
3164
+ var i, ien, cell, row, column;
3165
+ var thead = oSettings.nTHead;
3166
+ var tfoot = oSettings.nTFoot;
3167
+ var createHeader = $('th, td', thead).length === 0;
3168
+ var classes = oSettings.oClasses;
3169
+ var columns = oSettings.aoColumns;
3170
+
3171
+ if (createHeader) {
3172
+ row = $('<tr/>').appendTo(thead);
3173
+ }
3174
+
3175
+ for (i = 0, ien = columns.length; i < ien; i++) {
3176
+ column = columns[i];
3177
+ cell = $(column.nTh).addClass(column.sClass);
3178
+
3179
+ if (createHeader) {
3180
+ cell.appendTo(row);
3181
+ }
3182
+
3183
+ // 1.11 move into sorting
3184
+ if (oSettings.oFeatures.bSort) {
3185
+ cell.addClass(column.sSortingClass);
3186
+
3187
+ if (column.bSortable !== false) {
3188
+ cell
3189
+ .attr('tabindex', oSettings.iTabIndex)
3190
+ .attr('aria-controls', oSettings.sTableId);
3191
+
3192
+ _fnSortAttachListener(oSettings, column.nTh, i);
3193
+ }
3194
+ }
3195
+
3196
+ if (column.sTitle != cell[0].innerHTML) {
3197
+ cell.html(column.sTitle);
3198
+ }
3199
+
3200
+ _fnRenderer(oSettings, 'header')(
3201
+ oSettings, cell, column, classes
3202
+ );
3203
+ }
3204
+
3205
+ if (createHeader) {
3206
+ _fnDetectHeader(oSettings.aoHeader, thead);
3207
+ }
3208
+
3209
+ /* ARIA role for the rows */
3210
+ $(thead).find('>tr').attr('role', 'row');
3211
+
3212
+ /* Deal with the footer - add classes if required */
3213
+ $(thead).find('>tr>th, >tr>td').addClass(classes.sHeaderTH);
3214
+ $(tfoot).find('>tr>th, >tr>td').addClass(classes.sFooterTH);
3215
+
3216
+ // Cache the footer cells. Note that we only take the cells from the first
3217
+ // row in the footer. If there is more than one row the user wants to
3218
+ // interact with, they need to use the table().foot() method. Note also this
3219
+ // allows cells to be used for multiple columns using colspan
3220
+ if (tfoot !== null) {
3221
+ var cells = oSettings.aoFooter[0];
3222
+
3223
+ for (i = 0, ien = cells.length; i < ien; i++) {
3224
+ column = columns[i];
3225
+ column.nTf = cells[i].cell;
3226
+
3227
+ if (column.sClass) {
3228
+ $(column.nTf).addClass(column.sClass);
3229
+ }
3230
+ }
3231
+ }
3232
+ }
3233
+
3234
+
3235
+ /**
3236
+ * Draw the header (or footer) element based on the column visibility states. The
3237
+ * methodology here is to use the layout array from _fnDetectHeader, modified for
3238
+ * the instantaneous column visibility, to construct the new layout. The grid is
3239
+ * traversed over cell at a time in a rows x columns grid fashion, although each
3240
+ * cell insert can cover multiple elements in the grid - which is tracks using the
3241
+ * aApplied array. Cell inserts in the grid will only occur where there isn't
3242
+ * already a cell in that position.
3243
+ * @param {object} oSettings dataTables settings object
3244
+ * @param array {objects} aoSource Layout array from _fnDetectHeader
3245
+ * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
3246
+ * @memberof DataTable#oApi
3247
+ */
3248
+ function _fnDrawHead(oSettings, aoSource, bIncludeHidden)
3249
+ {
3250
+ var i, iLen, j, jLen, k, kLen, n, nLocalTr;
3251
+ var aoLocal = [];
3252
+ var aApplied = [];
3253
+ var iColumns = oSettings.aoColumns.length;
3254
+ var iRowspan, iColspan;
3255
+
3256
+ if (!aoSource)
3257
+ {
3258
+ return;
3259
+ }
3260
+
3261
+ if (bIncludeHidden === undefined)
3262
+ {
3263
+ bIncludeHidden = false;
3264
+ }
3265
+
3266
+ /* Make a copy of the master layout array, but without the visible columns in it */
3267
+ for (i = 0, iLen = aoSource.length; i < iLen; i++)
3268
+ {
3269
+ aoLocal[i] = aoSource[i].slice();
3270
+ aoLocal[i].nTr = aoSource[i].nTr;
3271
+
3272
+ /* Remove any columns which are currently hidden */
3273
+ for (j = iColumns - 1; j >= 0; j--)
3274
+ {
3275
+ if (!oSettings.aoColumns[j].bVisible && !bIncludeHidden)
3276
+ {
3277
+ aoLocal[i].splice(j, 1);
3278
+ }
3279
+ }
3280
+
3281
+ /* Prep the applied array - it needs an element for each row */
3282
+ aApplied.push([]);
3283
+ }
3284
+
3285
+ for (i = 0, iLen = aoLocal.length; i < iLen; i++)
3286
+ {
3287
+ nLocalTr = aoLocal[i].nTr;
3288
+
3289
+ /* All cells are going to be replaced, so empty out the row */
3290
+ if (nLocalTr)
3291
+ {
3292
+ while ((n = nLocalTr.firstChild))
3293
+ {
3294
+ nLocalTr.removeChild(n);
3295
+ }
3296
+ }
3297
+
3298
+ for (j = 0, jLen = aoLocal[i].length; j < jLen; j++)
3299
+ {
3300
+ iRowspan = 1;
3301
+ iColspan = 1;
3302
+
3303
+ /* Check to see if there is already a cell (row/colspan) covering our target
3304
+ * insert point. If there is, then there is nothing to do.
3305
+ */
3306
+ if (aApplied[i][j] === undefined)
3307
+ {
3308
+ nLocalTr.appendChild(aoLocal[i][j].cell);
3309
+ aApplied[i][j] = 1;
3310
+
3311
+ /* Expand the cell to cover as many rows as needed */
3312
+ while (aoLocal[i + iRowspan] !== undefined &&
3313
+ aoLocal[i][j].cell == aoLocal[i + iRowspan][j].cell)
3314
+ {
3315
+ aApplied[i + iRowspan][j] = 1;
3316
+ iRowspan++;
3317
+ }
3318
+
3319
+ /* Expand the cell to cover as many columns as needed */
3320
+ while (aoLocal[i][j + iColspan] !== undefined &&
3321
+ aoLocal[i][j].cell == aoLocal[i][j + iColspan].cell)
3322
+ {
3323
+ /* Must update the applied array over the rows for the columns */
3324
+ for (k = 0; k < iRowspan; k++)
3325
+ {
3326
+ aApplied[i + k][j + iColspan] = 1;
3327
+ }
3328
+ iColspan++;
3329
+ }
3330
+
3331
+ /* Do the actual expansion in the DOM */
3332
+ $(aoLocal[i][j].cell)
3333
+ .attr('rowspan', iRowspan)
3334
+ .attr('colspan', iColspan);
3335
+ }
3336
+ }
3337
+ }
3338
+ }
3339
+
3340
+
3341
+ /**
3342
+ * Insert the required TR nodes into the table for display
3343
+ * @param {object} oSettings dataTables settings object
3344
+ * @memberof DataTable#oApi
3345
+ */
3346
+ function _fnDraw(oSettings)
3347
+ {
3348
+ /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
3349
+ var aPreDraw = _fnCallbackFire(oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings]);
3350
+ if ($.inArray(false, aPreDraw) !== -1)
3351
+ {
3352
+ _fnProcessingDisplay(oSettings, false);
3353
+ return;
3354
+ }
3355
+
3356
+ var i, iLen, n;
3357
+ var anRows = [];
3358
+ var iRowCount = 0;
3359
+ var asStripeClasses = oSettings.asStripeClasses;
3360
+ var iStripes = asStripeClasses.length;
3361
+ var iOpenRows = oSettings.aoOpenRows.length;
3362
+ var oLang = oSettings.oLanguage;
3363
+ var iInitDisplayStart = oSettings.iInitDisplayStart;
3364
+ var bServerSide = _fnDataSource(oSettings) == 'ssp';
3365
+ var aiDisplay = oSettings.aiDisplay;
3366
+
3367
+ oSettings.bDrawing = true;
3368
+
3369
+ /* Check and see if we have an initial draw position from state saving */
3370
+ if (iInitDisplayStart !== undefined && iInitDisplayStart !== -1)
3371
+ {
3372
+ oSettings._iDisplayStart = bServerSide ?
3373
+ iInitDisplayStart :
3374
+ iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
3375
+ 0 :
3376
+ iInitDisplayStart;
3377
+
3378
+ oSettings.iInitDisplayStart = -1;
3379
+ }
3380
+
3381
+ var iDisplayStart = oSettings._iDisplayStart;
3382
+ var iDisplayEnd = oSettings.fnDisplayEnd();
3383
+
3384
+ /* Server-side processing draw intercept */
3385
+ if (oSettings.bDeferLoading)
3386
+ {
3387
+ oSettings.bDeferLoading = false;
3388
+ oSettings.iDraw++;
3389
+ _fnProcessingDisplay(oSettings, false);
3390
+ } else if (!bServerSide)
3391
+ {
3392
+ oSettings.iDraw++;
3393
+ } else if (!oSettings.bDestroying && !_fnAjaxUpdate(oSettings))
3394
+ {
3395
+ return;
3396
+ }
3397
+
3398
+ if (aiDisplay.length !== 0)
3399
+ {
3400
+ var iStart = bServerSide ? 0 : iDisplayStart;
3401
+ var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
3402
+
3403
+ for (var j = iStart; j < iEnd; j++)
3404
+ {
3405
+ var iDataIndex = aiDisplay[j];
3406
+ var aoData = oSettings.aoData[ iDataIndex ];
3407
+ if (aoData.nTr === null)
3408
+ {
3409
+ _fnCreateTr(oSettings, iDataIndex);
3410
+ }
3411
+
3412
+ var nRow = aoData.nTr;
3413
+
3414
+ /* Remove the old striping classes and then add the new one */
3415
+ if (iStripes !== 0)
3416
+ {
3417
+ var sStripe = asStripeClasses[ iRowCount % iStripes ];
3418
+ if (aoData._sRowStripe != sStripe)
3419
+ {
3420
+ $(nRow).removeClass(aoData._sRowStripe).addClass(sStripe);
3421
+ aoData._sRowStripe = sStripe;
3422
+ }
3423
+ }
3424
+
3425
+ // Row callback functions - might want to manipulate the row
3426
+ // iRowCount and j are not currently documented. Are they at all
3427
+ // useful?
3428
+ _fnCallbackFire(oSettings, 'aoRowCallback', null,
3429
+ [nRow, aoData._aData, iRowCount, j]);
3430
+
3431
+ anRows.push(nRow);
3432
+ iRowCount++;
3433
+ }
3434
+ } else
3435
+ {
3436
+ /* Table is empty - create a row with an empty message in it */
3437
+ var sZero = oLang.sZeroRecords;
3438
+ if (oSettings.iDraw == 1 && _fnDataSource(oSettings) == 'ajax')
3439
+ {
3440
+ sZero = oLang.sLoadingRecords;
3441
+ } else if (oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0)
3442
+ {
3443
+ sZero = oLang.sEmptyTable;
3444
+ }
3445
+
3446
+ anRows[ 0 ] = $('<tr/>', {'class': iStripes ? asStripeClasses[0] : ''})
3447
+ .append($('<td />', {
3448
+ 'valign': 'top',
3449
+ 'colSpan': _fnVisbleColumns(oSettings),
3450
+ 'class': oSettings.oClasses.sRowEmpty
3451
+ }).html(sZero))[0];
3452
+ }
3453
+
3454
+ /* Header and footer callbacks */
3455
+ _fnCallbackFire(oSettings, 'aoHeaderCallback', 'header', [$(oSettings.nTHead).children('tr')[0],
3456
+ _fnGetDataMaster(oSettings), iDisplayStart, iDisplayEnd, aiDisplay]);
3457
+
3458
+ _fnCallbackFire(oSettings, 'aoFooterCallback', 'footer', [$(oSettings.nTFoot).children('tr')[0],
3459
+ _fnGetDataMaster(oSettings), iDisplayStart, iDisplayEnd, aiDisplay]);
3460
+
3461
+ var body = $(oSettings.nTBody);
3462
+
3463
+ body.children().detach();
3464
+ body.append($(anRows));
3465
+
3466
+ /* Call all required callback functions for the end of a draw */
3467
+ _fnCallbackFire(oSettings, 'aoDrawCallback', 'draw', [oSettings]);
3468
+
3469
+ /* Draw is complete, sorting and filtering must be as well */
3470
+ oSettings.bSorted = false;
3471
+ oSettings.bFiltered = false;
3472
+ oSettings.bDrawing = false;
3473
+ }
3474
+
3475
+
3476
+ /**
3477
+ * Redraw the table - taking account of the various features which are enabled
3478
+ * @param {object} oSettings dataTables settings object
3479
+ * @param {boolean} [holdPosition] Keep the current paging position. By default
3480
+ * the paging is reset to the first page
3481
+ * @memberof DataTable#oApi
3482
+ */
3483
+ function _fnReDraw(settings, holdPosition)
3484
+ {
3485
+ var
3486
+ features = settings.oFeatures,
3487
+ sort = features.bSort,
3488
+ filter = features.bFilter;
3489
+
3490
+ if (sort) {
3491
+ _fnSort(settings);
3492
+ }
3493
+
3494
+ if (filter) {
3495
+ _fnFilterComplete(settings, settings.oPreviousSearch);
3496
+ } else {
3497
+ // No filtering, so we want to just use the display master
3498
+ settings.aiDisplay = settings.aiDisplayMaster.slice();
3499
+ }
3500
+
3501
+ if (holdPosition !== true) {
3502
+ settings._iDisplayStart = 0;
3503
+ }
3504
+
3505
+ // Let any modules know about the draw hold position state (used by
3506
+ // scrolling internally)
3507
+ settings._drawHold = holdPosition;
3508
+
3509
+ _fnDraw(settings);
3510
+
3511
+ settings._drawHold = false;
3512
+ }
3513
+
3514
+
3515
+ /**
3516
+ * Add the options to the page HTML for the table
3517
+ * @param {object} oSettings dataTables settings object
3518
+ * @memberof DataTable#oApi
3519
+ */
3520
+ function _fnAddOptionsHtml(oSettings)
3521
+ {
3522
+ var classes = oSettings.oClasses;
3523
+ var table = $(oSettings.nTable);
3524
+ var holding = $('<div/>').insertBefore(table); // Holding element for speed
3525
+ var features = oSettings.oFeatures;
3526
+
3527
+ // All DataTables are wrapped in a div
3528
+ var insert = $('<div/>', {
3529
+ id: oSettings.sTableId + '_wrapper',
3530
+ 'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' ' + classes.sNoFooter)
3531
+ });
3532
+
3533
+ oSettings.nHolding = holding[0];
3534
+ oSettings.nTableWrapper = insert[0];
3535
+ oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
3536
+
3537
+ /* Loop over the user set positioning and place the elements as needed */
3538
+ var aDom = oSettings.sDom.split('');
3539
+ var featureNode, cOption, nNewNode, cNext, sAttr, j;
3540
+ for (var i = 0; i < aDom.length; i++)
3541
+ {
3542
+ featureNode = null;
3543
+ cOption = aDom[i];
3544
+
3545
+ if (cOption == '<')
3546
+ {
3547
+ /* New container div */
3548
+ nNewNode = $('<div/>')[0];
3549
+
3550
+ /* Check to see if we should append an id and/or a class name to the container */
3551
+ cNext = aDom[i + 1];
3552
+ if (cNext == "'" || cNext == '"')
3553
+ {
3554
+ sAttr = "";
3555
+ j = 2;
3556
+ while (aDom[i + j] != cNext)
3557
+ {
3558
+ sAttr += aDom[i + j];
3559
+ j++;
3560
+ }
3561
+
3562
+ /* Replace jQuery UI constants @todo depreciated */
3563
+ if (sAttr == "H")
3564
+ {
3565
+ sAttr = classes.sJUIHeader;
3566
+ } else if (sAttr == "F")
3567
+ {
3568
+ sAttr = classes.sJUIFooter;
3569
+ }
3570
+
3571
+ /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
3572
+ * breaks the string into parts and applies them as needed
3573
+ */
3574
+ if (sAttr.indexOf('.') != -1)
3575
+ {
3576
+ var aSplit = sAttr.split('.');
3577
+ nNewNode.id = aSplit[0].substr(1, aSplit[0].length - 1);
3578
+ nNewNode.className = aSplit[1];
3579
+ } else if (sAttr.charAt(0) == "#")
3580
+ {
3581
+ nNewNode.id = sAttr.substr(1, sAttr.length - 1);
3582
+ } else
3583
+ {
3584
+ nNewNode.className = sAttr;
3585
+ }
3586
+
3587
+ i += j; /* Move along the position array */
3588
+ }
3589
+
3590
+ insert.append(nNewNode);
3591
+ insert = $(nNewNode);
3592
+ } else if (cOption == '>')
3593
+ {
3594
+ /* End container div */
3595
+ insert = insert.parent();
3596
+ }
3597
+ // @todo Move options into their own plugins?
3598
+ else if (cOption == 'l' && features.bPaginate && features.bLengthChange)
3599
+ {
3600
+ /* Length */
3601
+ featureNode = _fnFeatureHtmlLength(oSettings);
3602
+ } else if (cOption == 'f' && features.bFilter)
3603
+ {
3604
+ /* Filter */
3605
+ featureNode = _fnFeatureHtmlFilter(oSettings);
3606
+ } else if (cOption == 'r' && features.bProcessing)
3607
+ {
3608
+ /* pRocessing */
3609
+ featureNode = _fnFeatureHtmlProcessing(oSettings);
3610
+ } else if (cOption == 't')
3611
+ {
3612
+ /* Table */
3613
+ featureNode = _fnFeatureHtmlTable(oSettings);
3614
+ } else if (cOption == 'i' && features.bInfo)
3615
+ {
3616
+ /* Info */
3617
+ featureNode = _fnFeatureHtmlInfo(oSettings);
3618
+ } else if (cOption == 'p' && features.bPaginate)
3619
+ {
3620
+ /* Pagination */
3621
+ featureNode = _fnFeatureHtmlPaginate(oSettings);
3622
+ } else if (DataTable.ext.feature.length !== 0)
3623
+ {
3624
+ /* Plug-in features */
3625
+ var aoFeatures = DataTable.ext.feature;
3626
+ for (var k = 0, kLen = aoFeatures.length; k < kLen; k++)
3627
+ {
3628
+ if (cOption == aoFeatures[k].cFeature)
3629
+ {
3630
+ featureNode = aoFeatures[k].fnInit(oSettings);
3631
+ break;
3632
+ }
3633
+ }
3634
+ }
3635
+
3636
+ /* Add to the 2D features array */
3637
+ if (featureNode)
3638
+ {
3639
+ var aanFeatures = oSettings.aanFeatures;
3640
+
3641
+ if (!aanFeatures[cOption])
3642
+ {
3643
+ aanFeatures[cOption] = [];
3644
+ }
3645
+
3646
+ aanFeatures[cOption].push(featureNode);
3647
+ insert.append(featureNode);
3648
+ }
3649
+ }
3650
+
3651
+ /* Built our DOM structure - replace the holding div with what we want */
3652
+ holding.replaceWith(insert);
3653
+ oSettings.nHolding = null;
3654
+ }
3655
+
3656
+
3657
+ /**
3658
+ * Use the DOM source to create up an array of header cells. The idea here is to
3659
+ * create a layout grid (array) of rows x columns, which contains a reference
3660
+ * to the cell that that point in the grid (regardless of col/rowspan), such that
3661
+ * any column / row could be removed and the new grid constructed
3662
+ * @param array {object} aLayout Array to store the calculated layout in
3663
+ * @param {node} nThead The header/footer element for the table
3664
+ * @memberof DataTable#oApi
3665
+ */
3666
+ function _fnDetectHeader(aLayout, nThead)
3667
+ {
3668
+ var nTrs = $(nThead).children('tr');
3669
+ var nTr, nCell;
3670
+ var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
3671
+ var bUnique;
3672
+ var fnShiftCol = function (a, i, j) {
3673
+ var k = a[i];
3674
+ while (k[j]) {
3675
+ j++;
3676
+ }
3677
+ return j;
3678
+ };
3679
+
3680
+ aLayout.splice(0, aLayout.length);
3681
+
3682
+ /* We know how many rows there are in the layout - so prep it */
3683
+ for (i = 0, iLen = nTrs.length; i < iLen; i++)
3684
+ {
3685
+ aLayout.push([]);
3686
+ }
3687
+
3688
+ /* Calculate a layout array */
3689
+ for (i = 0, iLen = nTrs.length; i < iLen; i++)
3690
+ {
3691
+ nTr = nTrs[i];
3692
+ iColumn = 0;
3693
+
3694
+ /* For every cell in the row... */
3695
+ nCell = nTr.firstChild;
3696
+ while (nCell) {
3697
+ if (nCell.nodeName.toUpperCase() == "TD" ||
3698
+ nCell.nodeName.toUpperCase() == "TH")
3699
+ {
3700
+ /* Get the col and rowspan attributes from the DOM and sanitise them */
3701
+ iColspan = nCell.getAttribute('colspan') * 1;
3702
+ iRowspan = nCell.getAttribute('rowspan') * 1;
3703
+ iColspan = (!iColspan || iColspan === 0 || iColspan === 1) ? 1 : iColspan;
3704
+ iRowspan = (!iRowspan || iRowspan === 0 || iRowspan === 1) ? 1 : iRowspan;
3705
+
3706
+ /* There might be colspan cells already in this row, so shift our target
3707
+ * accordingly
3708
+ */
3709
+ iColShifted = fnShiftCol(aLayout, i, iColumn);
3710
+
3711
+ /* Cache calculation for unique columns */
3712
+ bUnique = iColspan === 1 ? true : false;
3713
+
3714
+ /* If there is col / rowspan, copy the information into the layout grid */
3715
+ for (l = 0; l < iColspan; l++)
3716
+ {
3717
+ for (k = 0; k < iRowspan; k++)
3718
+ {
3719
+ aLayout[i + k][iColShifted + l] = {
3720
+ "cell": nCell,
3721
+ "unique": bUnique
3722
+ };
3723
+ aLayout[i + k].nTr = nTr;
3724
+ }
3725
+ }
3726
+ }
3727
+ nCell = nCell.nextSibling;
3728
+ }
3729
+ }
3730
+ }
3731
+
3732
+
3733
+ /**
3734
+ * Get an array of unique th elements, one for each column
3735
+ * @param {object} oSettings dataTables settings object
3736
+ * @param {node} nHeader automatically detect the layout from this node - optional
3737
+ * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
3738
+ * @returns array {node} aReturn list of unique th's
3739
+ * @memberof DataTable#oApi
3740
+ */
3741
+ function _fnGetUniqueThs(oSettings, nHeader, aLayout)
3742
+ {
3743
+ var aReturn = [];
3744
+ if (!aLayout)
3745
+ {
3746
+ aLayout = oSettings.aoHeader;
3747
+ if (nHeader)
3748
+ {
3749
+ aLayout = [];
3750
+ _fnDetectHeader(aLayout, nHeader);
3751
+ }
3752
+ }
3753
+
3754
+ for (var i = 0, iLen = aLayout.length; i < iLen; i++)
3755
+ {
3756
+ for (var j = 0, jLen = aLayout[i].length; j < jLen; j++)
3757
+ {
3758
+ if (aLayout[i][j].unique &&
3759
+ (!aReturn[j] || !oSettings.bSortCellsTop))
3760
+ {
3761
+ aReturn[j] = aLayout[i][j].cell;
3762
+ }
3763
+ }
3764
+ }
3765
+
3766
+ return aReturn;
3767
+ }
3768
+
3769
+ /**
3770
+ * Create an Ajax call based on the table's settings, taking into account that
3771
+ * parameters can have multiple forms, and backwards compatibility.
3772
+ *
3773
+ * @param {object} oSettings dataTables settings object
3774
+ * @param {array} data Data to send to the server, required by
3775
+ * DataTables - may be augmented by developer callbacks
3776
+ * @param {function} fn Callback function to run when data is obtained
3777
+ */
3778
+ function _fnBuildAjax(oSettings, data, fn)
3779
+ {
3780
+ // Compatibility with 1.9-, allow fnServerData and event to manipulate
3781
+ _fnCallbackFire(oSettings, 'aoServerParams', 'serverParams', [data]);
3782
+
3783
+ // Convert to object based for 1.10+ if using the old array scheme which can
3784
+ // come from server-side processing or serverParams
3785
+ if (data && $.isArray(data)) {
3786
+ var tmp = {};
3787
+ var rbracket = /(.*?)\[\]$/;
3788
+
3789
+ $.each(data, function (key, val) {
3790
+ var match = val.name.match(rbracket);
3791
+
3792
+ if (match) {
3793
+ // Support for arrays
3794
+ var name = match[0];
3795
+
3796
+ if (!tmp[ name ]) {
3797
+ tmp[ name ] = [];
3798
+ }
3799
+ tmp[ name ].push(val.value);
3800
+ } else {
3801
+ tmp[val.name] = val.value;
3802
+ }
3803
+ });
3804
+ data = tmp;
3805
+ }
3806
+
3807
+ var ajaxData;
3808
+ var ajax = oSettings.ajax;
3809
+ var instance = oSettings.oInstance;
3810
+ var callback = function (json) {
3811
+ _fnCallbackFire(oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR]);
3812
+ fn(json);
3813
+ };
3814
+
3815
+ if ($.isPlainObject(ajax) && ajax.data)
3816
+ {
3817
+ ajaxData = ajax.data;
3818
+
3819
+ var newData = $.isFunction(ajaxData) ?
3820
+ ajaxData(data, oSettings) : // fn can manipulate data or return
3821
+ ajaxData; // an object object or array to merge
3822
+
3823
+ // If the function returned something, use that alone
3824
+ data = $.isFunction(ajaxData) && newData ?
3825
+ newData :
3826
+ $.extend(true, data, newData);
3827
+
3828
+ // Remove the data property as we've resolved it already and don't want
3829
+ // jQuery to do it again (it is restored at the end of the function)
3830
+ delete ajax.data;
3831
+ }
3832
+
3833
+ var baseAjax = {
3834
+ "data": data,
3835
+ "success": function (json) {
3836
+ var error = json.error || json.sError;
3837
+ if (error) {
3838
+ _fnLog(oSettings, 0, error);
3839
+ }
3840
+
3841
+ oSettings.json = json;
3842
+ callback(json);
3843
+ },
3844
+ "dataType": "json",
3845
+ "cache": false,
3846
+ "type": oSettings.sServerMethod,
3847
+ "error": function (xhr, error, thrown) {
3848
+ var ret = _fnCallbackFire(oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR]);
3849
+
3850
+ if ($.inArray(true, ret) === -1) {
3851
+ if (error == "parsererror") {
3852
+ _fnLog(oSettings, 0, 'Invalid JSON response', 1);
3853
+ } else if (xhr.readyState === 4) {
3854
+ _fnLog(oSettings, 0, 'Ajax error', 7);
3855
+ }
3856
+ }
3857
+
3858
+ _fnProcessingDisplay(oSettings, false);
3859
+ }
3860
+ };
3861
+
3862
+ // Store the data submitted for the API
3863
+ oSettings.oAjaxData = data;
3864
+
3865
+ // Allow plug-ins and external processes to modify the data
3866
+ _fnCallbackFire(oSettings, null, 'preXhr', [oSettings, data]);
3867
+
3868
+ if (oSettings.fnServerData)
3869
+ {
3870
+ // DataTables 1.9- compatibility
3871
+ oSettings.fnServerData.call(instance,
3872
+ oSettings.sAjaxSource,
3873
+ $.map(data, function (val, key) { // Need to convert back to 1.9 trad format
3874
+ return {name: key, value: val};
3875
+ }),
3876
+ callback,
3877
+ oSettings
3878
+ );
3879
+ } else if (oSettings.sAjaxSource || typeof ajax === 'string')
3880
+ {
3881
+ // DataTables 1.9- compatibility
3882
+ oSettings.jqXHR = $.ajax($.extend(baseAjax, {
3883
+ url: ajax || oSettings.sAjaxSource
3884
+ }));
3885
+ } else if ($.isFunction(ajax))
3886
+ {
3887
+ // Is a function - let the caller define what needs to be done
3888
+ oSettings.jqXHR = ajax.call(instance, data, callback, oSettings);
3889
+ } else
3890
+ {
3891
+ // Object to extend the base settings
3892
+ oSettings.jqXHR = $.ajax($.extend(baseAjax, ajax));
3893
+
3894
+ // Restore for next time around
3895
+ ajax.data = ajaxData;
3896
+ }
3897
+ }
3898
+
3899
+
3900
+ /**
3901
+ * Update the table using an Ajax call
3902
+ * @param {object} settings dataTables settings object
3903
+ * @returns {boolean} Block the table drawing or not
3904
+ * @memberof DataTable#oApi
3905
+ */
3906
+ function _fnAjaxUpdate(settings)
3907
+ {
3908
+ if (settings.bAjaxDataGet) {
3909
+ settings.iDraw++;
3910
+ _fnProcessingDisplay(settings, true);
3911
+
3912
+ _fnBuildAjax(
3913
+ settings,
3914
+ _fnAjaxParameters(settings),
3915
+ function (json) {
3916
+ _fnAjaxUpdateDraw(settings, json);
3917
+ }
3918
+ );
3919
+
3920
+ return false;
3921
+ }
3922
+ return true;
3923
+ }
3924
+
3925
+
3926
+ /**
3927
+ * Build up the parameters in an object needed for a server-side processing
3928
+ * request. Note that this is basically done twice, is different ways - a modern
3929
+ * method which is used by default in DataTables 1.10 which uses objects and
3930
+ * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
3931
+ * the sAjaxSource option is used in the initialisation, or the legacyAjax
3932
+ * option is set.
3933
+ * @param {object} oSettings dataTables settings object
3934
+ * @returns {bool} block the table drawing or not
3935
+ * @memberof DataTable#oApi
3936
+ */
3937
+ function _fnAjaxParameters(settings)
3938
+ {
3939
+ var
3940
+ columns = settings.aoColumns,
3941
+ columnCount = columns.length,
3942
+ features = settings.oFeatures,
3943
+ preSearch = settings.oPreviousSearch,
3944
+ preColSearch = settings.aoPreSearchCols,
3945
+ i, data = [], dataProp, column, columnSearch,
3946
+ sort = _fnSortFlatten(settings),
3947
+ displayStart = settings._iDisplayStart,
3948
+ displayLength = features.bPaginate !== false ?
3949
+ settings._iDisplayLength :
3950
+ -1;
3951
+
3952
+ var param = function (name, value) {
3953
+ data.push({'name': name, 'value': value});
3954
+ };
3955
+
3956
+ // DataTables 1.9- compatible method
3957
+ param('sEcho', settings.iDraw);
3958
+ param('iColumns', columnCount);
3959
+ param('sColumns', _pluck(columns, 'sName').join(','));
3960
+ param('iDisplayStart', displayStart);
3961
+ param('iDisplayLength', displayLength);
3962
+
3963
+ // DataTables 1.10+ method
3964
+ var d = {
3965
+ draw: settings.iDraw,
3966
+ columns: [],
3967
+ order: [],
3968
+ start: displayStart,
3969
+ length: displayLength,
3970
+ search: {
3971
+ value: preSearch.sSearch,
3972
+ regex: preSearch.bRegex
3973
+ }
3974
+ };
3975
+
3976
+ for (i = 0; i < columnCount; i++) {
3977
+ column = columns[i];
3978
+ columnSearch = preColSearch[i];
3979
+ dataProp = typeof column.mData == "function" ? 'function' : column.mData;
3980
+
3981
+ d.columns.push({
3982
+ data: dataProp,
3983
+ name: column.sName,
3984
+ searchable: column.bSearchable,
3985
+ orderable: column.bSortable,
3986
+ search: {
3987
+ value: columnSearch.sSearch,
3988
+ regex: columnSearch.bRegex
3989
+ }
3990
+ });
3991
+
3992
+ param("mDataProp_" + i, dataProp);
3993
+
3994
+ if (features.bFilter) {
3995
+ param('sSearch_' + i, columnSearch.sSearch);
3996
+ param('bRegex_' + i, columnSearch.bRegex);
3997
+ param('bSearchable_' + i, column.bSearchable);
3998
+ }
3999
+
4000
+ if (features.bSort) {
4001
+ param('bSortable_' + i, column.bSortable);
4002
+ }
4003
+ }
4004
+
4005
+ if (features.bFilter) {
4006
+ param('sSearch', preSearch.sSearch);
4007
+ param('bRegex', preSearch.bRegex);
4008
+ }
4009
+
4010
+ if (features.bSort) {
4011
+ $.each(sort, function (i, val) {
4012
+ d.order.push({column: val.col, dir: val.dir});
4013
+
4014
+ param('iSortCol_' + i, val.col);
4015
+ param('sSortDir_' + i, val.dir);
4016
+ });
4017
+
4018
+ param('iSortingCols', sort.length);
4019
+ }
4020
+
4021
+ // If the legacy.ajax parameter is null, then we automatically decide which
4022
+ // form to use, based on sAjaxSource
4023
+ var legacy = DataTable.ext.legacy.ajax;
4024
+ if (legacy === null) {
4025
+ return settings.sAjaxSource ? data : d;
4026
+ }
4027
+
4028
+ // Otherwise, if legacy has been specified then we use that to decide on the
4029
+ // form
4030
+ return legacy ? data : d;
4031
+ }
4032
+
4033
+
4034
+ /**
4035
+ * Data the data from the server (nuking the old) and redraw the table
4036
+ * @param {object} oSettings dataTables settings object
4037
+ * @param {object} json json data return from the server.
4038
+ * @param {string} json.sEcho Tracking flag for DataTables to match requests
4039
+ * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
4040
+ * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
4041
+ * @param {array} json.aaData The data to display on this page
4042
+ * @param {string} [json.sColumns] Column ordering (sName, comma separated)
4043
+ * @memberof DataTable#oApi
4044
+ */
4045
+ function _fnAjaxUpdateDraw(settings, json)
4046
+ {
4047
+ // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
4048
+ // Support both
4049
+ var compat = function (old, modern) {
4050
+ return json[old] !== undefined ? json[old] : json[modern];
4051
+ };
4052
+
4053
+ var data = _fnAjaxDataSrc(settings, json);
4054
+ var draw = compat('sEcho', 'draw');
4055
+ var recordsTotal = compat('iTotalRecords', 'recordsTotal');
4056
+ var recordsFiltered = compat('iTotalDisplayRecords', 'recordsFiltered');
4057
+
4058
+ if (draw) {
4059
+ // Protect against out of sequence returns
4060
+ if (draw * 1 < settings.iDraw) {
4061
+ return;
4062
+ }
4063
+ settings.iDraw = draw * 1;
4064
+ }
4065
+
4066
+ _fnClearTable(settings);
4067
+ settings._iRecordsTotal = parseInt(recordsTotal, 10);
4068
+ settings._iRecordsDisplay = parseInt(recordsFiltered, 10);
4069
+
4070
+ for (var i = 0, ien = data.length; i < ien; i++) {
4071
+ _fnAddData(settings, data[i]);
4072
+ }
4073
+ settings.aiDisplay = settings.aiDisplayMaster.slice();
4074
+
4075
+ settings.bAjaxDataGet = false;
4076
+ _fnDraw(settings);
4077
+
4078
+ if (!settings._bInitComplete) {
4079
+ _fnInitComplete(settings, json);
4080
+ }
4081
+
4082
+ settings.bAjaxDataGet = true;
4083
+ _fnProcessingDisplay(settings, false);
4084
+ }
4085
+
4086
+
4087
+ /**
4088
+ * Get the data from the JSON data source to use for drawing a table. Using
4089
+ * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
4090
+ * source object, or from a processing function.
4091
+ * @param {object} oSettings dataTables settings object
4092
+ * @param {object} json Data source object / array from the server
4093
+ * @return {array} Array of data to use
4094
+ */
4095
+ function _fnAjaxDataSrc(oSettings, json)
4096
+ {
4097
+ var dataSrc = $.isPlainObject(oSettings.ajax) && oSettings.ajax.dataSrc !== undefined ?
4098
+ oSettings.ajax.dataSrc :
4099
+ oSettings.sAjaxDataProp; // Compatibility with 1.9-.
4100
+
4101
+ // Compatibility with 1.9-. In order to read from aaData, check if the
4102
+ // default has been changed, if not, check for aaData
4103
+ if (dataSrc === 'data') {
4104
+ return json.aaData || json[dataSrc];
4105
+ }
4106
+
4107
+ return dataSrc !== "" ?
4108
+ _fnGetObjectDataFn(dataSrc)(json) :
4109
+ json;
4110
+ }
4111
+
4112
+ /**
4113
+ * Generate the node required for filtering text
4114
+ * @returns {node} Filter control element
4115
+ * @param {object} oSettings dataTables settings object
4116
+ * @memberof DataTable#oApi
4117
+ */
4118
+ function _fnFeatureHtmlFilter(settings)
4119
+ {
4120
+ var classes = settings.oClasses;
4121
+ var tableId = settings.sTableId;
4122
+ var language = settings.oLanguage;
4123
+ var previousSearch = settings.oPreviousSearch;
4124
+ var features = settings.aanFeatures;
4125
+ var input = '<input type="search" class="' + classes.sFilterInput + '"/>';
4126
+
4127
+ var str = language.sSearch;
4128
+ str = str.match(/_INPUT_/) ?
4129
+ str.replace('_INPUT_', input) :
4130
+ str + input;
4131
+
4132
+ var filter = $('<div/>', {
4133
+ 'id': !features.f ? tableId + '_filter' : null,
4134
+ 'class': classes.sFilter
4135
+ })
4136
+ .append($('<label/>').append(str));
4137
+
4138
+ var searchFn = function () {
4139
+ /* Update all other filter input elements for the new display */
4140
+ var n = features.f;
4141
+ var val = !this.value ? "" : this.value; // mental IE8 fix :-(
4142
+
4143
+ /* Now do the filter */
4144
+ if (val != previousSearch.sSearch) {
4145
+ _fnFilterComplete(settings, {
4146
+ "sSearch": val,
4147
+ "bRegex": previousSearch.bRegex,
4148
+ "bSmart": previousSearch.bSmart,
4149
+ "bCaseInsensitive": previousSearch.bCaseInsensitive
4150
+ });
4151
+
4152
+ // Need to redraw, without resorting
4153
+ settings._iDisplayStart = 0;
4154
+ _fnDraw(settings);
4155
+ }
4156
+ };
4157
+
4158
+ var searchDelay = settings.searchDelay !== null ?
4159
+ settings.searchDelay :
4160
+ _fnDataSource(settings) === 'ssp' ?
4161
+ 400 :
4162
+ 0;
4163
+
4164
+ var jqFilter = $('input', filter)
4165
+ .val(previousSearch.sSearch)
4166
+ .attr('placeholder', language.sSearchPlaceholder)
4167
+ .on(
4168
+ 'keyup.DT search.DT input.DT paste.DT cut.DT',
4169
+ searchDelay ?
4170
+ _fnThrottle(searchFn, searchDelay) :
4171
+ searchFn
4172
+ )
4173
+ .on('keypress.DT', function (e) {
4174
+ /* Prevent form submission */
4175
+ if (e.keyCode == 13) {
4176
+ return false;
4177
+ }
4178
+ })
4179
+ .attr('aria-controls', tableId);
4180
+
4181
+ // Update the input elements whenever the table is filtered
4182
+ $(settings.nTable).on('search.dt.DT', function (ev, s) {
4183
+ if (settings === s) {
4184
+ // IE9 throws an 'unknown error' if document.activeElement is used
4185
+ // inside an iframe or frame...
4186
+ try {
4187
+ if (jqFilter[0] !== document.activeElement) {
4188
+ jqFilter.val(previousSearch.sSearch);
4189
+ }
4190
+ } catch (e) {
4191
+ }
4192
+ }
4193
+ });
4194
+
4195
+ return filter[0];
4196
+ }
4197
+
4198
+
4199
+ /**
4200
+ * Filter the table using both the global filter and column based filtering
4201
+ * @param {object} oSettings dataTables settings object
4202
+ * @param {object} oSearch search information
4203
+ * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
4204
+ * @memberof DataTable#oApi
4205
+ */
4206
+ function _fnFilterComplete(oSettings, oInput, iForce)
4207
+ {
4208
+ var oPrevSearch = oSettings.oPreviousSearch;
4209
+ var aoPrevSearch = oSettings.aoPreSearchCols;
4210
+ var fnSaveFilter = function (oFilter) {
4211
+ /* Save the filtering values */
4212
+ oPrevSearch.sSearch = oFilter.sSearch;
4213
+ oPrevSearch.bRegex = oFilter.bRegex;
4214
+ oPrevSearch.bSmart = oFilter.bSmart;
4215
+ oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
4216
+ };
4217
+ var fnRegex = function (o) {
4218
+ // Backwards compatibility with the bEscapeRegex option
4219
+ return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
4220
+ };
4221
+
4222
+ // Resolve any column types that are unknown due to addition or invalidation
4223
+ // @todo As per sort - can this be moved into an event handler?
4224
+ _fnColumnTypes(oSettings);
4225
+
4226
+ /* In server-side processing all filtering is done by the server, so no point hanging around here */
4227
+ if (_fnDataSource(oSettings) != 'ssp')
4228
+ {
4229
+ /* Global filter */
4230
+ _fnFilter(oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive);
4231
+ fnSaveFilter(oInput);
4232
+
4233
+ /* Now do the individual column filter */
4234
+ for (var i = 0; i < aoPrevSearch.length; i++)
4235
+ {
4236
+ _fnFilterColumn(oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
4237
+ aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive);
4238
+ }
4239
+
4240
+ /* Custom filtering */
4241
+ _fnFilterCustom(oSettings);
4242
+ } else
4243
+ {
4244
+ fnSaveFilter(oInput);
4245
+ }
4246
+
4247
+ /* Tell the draw function we have been filtering */
4248
+ oSettings.bFiltered = true;
4249
+ _fnCallbackFire(oSettings, null, 'search', [oSettings]);
4250
+ }
4251
+
4252
+
4253
+ /**
4254
+ * Apply custom filtering functions
4255
+ * @param {object} oSettings dataTables settings object
4256
+ * @memberof DataTable#oApi
4257
+ */
4258
+ function _fnFilterCustom(settings)
4259
+ {
4260
+ var filters = DataTable.ext.search;
4261
+ var displayRows = settings.aiDisplay;
4262
+ var row, rowIdx;
4263
+
4264
+ for (var i = 0, ien = filters.length; i < ien; i++) {
4265
+ var rows = [];
4266
+
4267
+ // Loop over each row and see if it should be included
4268
+ for (var j = 0, jen = displayRows.length; j < jen; j++) {
4269
+ rowIdx = displayRows[ j ];
4270
+ row = settings.aoData[ rowIdx ];
4271
+
4272
+ if (filters[i](settings, row._aFilterData, rowIdx, row._aData, j)) {
4273
+ rows.push(rowIdx);
4274
+ }
4275
+ }
4276
+
4277
+ // So the array reference doesn't break set the results into the
4278
+ // existing array
4279
+ displayRows.length = 0;
4280
+ $.merge(displayRows, rows);
4281
+ }
4282
+ }
4283
+
4284
+
4285
+ /**
4286
+ * Filter the table on a per-column basis
4287
+ * @param {object} oSettings dataTables settings object
4288
+ * @param {string} sInput string to filter on
4289
+ * @param {int} iColumn column to filter
4290
+ * @param {bool} bRegex treat search string as a regular expression or not
4291
+ * @param {bool} bSmart use smart filtering or not
4292
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
4293
+ * @memberof DataTable#oApi
4294
+ */
4295
+ function _fnFilterColumn(settings, searchStr, colIdx, regex, smart, caseInsensitive)
4296
+ {
4297
+ if (searchStr === '') {
4298
+ return;
4299
+ }
4300
+
4301
+ var data;
4302
+ var out = [];
4303
+ var display = settings.aiDisplay;
4304
+ var rpSearch = _fnFilterCreateSearch(searchStr, regex, smart, caseInsensitive);
4305
+
4306
+ for (var i = 0; i < display.length; i++) {
4307
+ data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
4308
+
4309
+ if (rpSearch.test(data)) {
4310
+ out.push(display[i]);
4311
+ }
4312
+ }
4313
+
4314
+ settings.aiDisplay = out;
4315
+ }
4316
+
4317
+
4318
+ /**
4319
+ * Filter the data table based on user input and draw the table
4320
+ * @param {object} settings dataTables settings object
4321
+ * @param {string} input string to filter on
4322
+ * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
4323
+ * @param {bool} regex treat as a regular expression or not
4324
+ * @param {bool} smart perform smart filtering or not
4325
+ * @param {bool} caseInsensitive Do case insenstive matching or not
4326
+ * @memberof DataTable#oApi
4327
+ */
4328
+ function _fnFilter(settings, input, force, regex, smart, caseInsensitive)
4329
+ {
4330
+ var rpSearch = _fnFilterCreateSearch(input, regex, smart, caseInsensitive);
4331
+ var prevSearch = settings.oPreviousSearch.sSearch;
4332
+ var displayMaster = settings.aiDisplayMaster;
4333
+ var display, invalidated, i;
4334
+ var filtered = [];
4335
+
4336
+ // Need to take account of custom filtering functions - always filter
4337
+ if (DataTable.ext.search.length !== 0) {
4338
+ force = true;
4339
+ }
4340
+
4341
+ // Check if any of the rows were invalidated
4342
+ invalidated = _fnFilterData(settings);
4343
+
4344
+ // If the input is blank - we just want the full data set
4345
+ if (input.length <= 0) {
4346
+ settings.aiDisplay = displayMaster.slice();
4347
+ } else {
4348
+ // New search - start from the master array
4349
+ if (invalidated ||
4350
+ force ||
4351
+ prevSearch.length > input.length ||
4352
+ input.indexOf(prevSearch) !== 0 ||
4353
+ settings.bSorted // On resort, the display master needs to be
4354
+ // re-filtered since indexes will have changed
4355
+ ) {
4356
+ settings.aiDisplay = displayMaster.slice();
4357
+ }
4358
+
4359
+ // Search the display array
4360
+ display = settings.aiDisplay;
4361
+
4362
+ for (i = 0; i < display.length; i++) {
4363
+ if (rpSearch.test(settings.aoData[ display[i] ]._sFilterRow)) {
4364
+ filtered.push(display[i]);
4365
+ }
4366
+ }
4367
+
4368
+ settings.aiDisplay = filtered;
4369
+ }
4370
+ }
4371
+
4372
+
4373
+ /**
4374
+ * Build a regular expression object suitable for searching a table
4375
+ * @param {string} sSearch string to search for
4376
+ * @param {bool} bRegex treat as a regular expression or not
4377
+ * @param {bool} bSmart perform smart filtering or not
4378
+ * @param {bool} bCaseInsensitive Do case insensitive matching or not
4379
+ * @returns {RegExp} constructed object
4380
+ * @memberof DataTable#oApi
4381
+ */
4382
+ function _fnFilterCreateSearch(search, regex, smart, caseInsensitive)
4383
+ {
4384
+ search = regex ?
4385
+ search :
4386
+ _fnEscapeRegex(search);
4387
+
4388
+ if (smart) {
4389
+ /* For smart filtering we want to allow the search to work regardless of
4390
+ * word order. We also want double quoted text to be preserved, so word
4391
+ * order is important - a la google. So this is what we want to
4392
+ * generate:
4393
+ *
4394
+ * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
4395
+ */
4396
+ var a = $.map(search.match(/"[^"]+"|[^ ]+/g) || [''], function (word) {
4397
+ if (word.charAt(0) === '"') {
4398
+ var m = word.match(/^"(.*)"$/);
4399
+ word = m ? m[1] : word;
4400
+ }
4401
+
4402
+ return word.replace('"', '');
4403
+ });
4404
+
4405
+ search = '^(?=.*?' + a.join(')(?=.*?') + ').*$';
4406
+ }
4407
+
4408
+ return new RegExp(search, caseInsensitive ? 'i' : '');
4409
+ }
4410
+
4411
+
4412
+ /**
4413
+ * Escape a string such that it can be used in a regular expression
4414
+ * @param {string} sVal string to escape
4415
+ * @returns {string} escaped string
4416
+ * @memberof DataTable#oApi
4417
+ */
4418
+ var _fnEscapeRegex = DataTable.util.escapeRegex;
4419
+
4420
+ var __filter_div = $('<div>')[0];
4421
+ var __filter_div_textContent = __filter_div.textContent !== undefined;
4422
+
4423
+ // Update the filtering data for each row if needed (by invalidation or first run)
4424
+ function _fnFilterData(settings)
4425
+ {
4426
+ var columns = settings.aoColumns;
4427
+ var column;
4428
+ var i, j, ien, jen, filterData, cellData, row;
4429
+ var fomatters = DataTable.ext.type.search;
4430
+ var wasInvalidated = false;
4431
+
4432
+ for (i = 0, ien = settings.aoData.length; i < ien; i++) {
4433
+ row = settings.aoData[i];
4434
+
4435
+ if (!row._aFilterData) {
4436
+ filterData = [];
4437
+
4438
+ for (j = 0, jen = columns.length; j < jen; j++) {
4439
+ column = columns[j];
4440
+
4441
+ if (column.bSearchable) {
4442
+ cellData = _fnGetCellData(settings, i, j, 'filter');
4443
+
4444
+ if (fomatters[ column.sType ]) {
4445
+ cellData = fomatters[ column.sType ](cellData);
4446
+ }
4447
+
4448
+ // Search in DataTables 1.10 is string based. In 1.11 this
4449
+ // should be altered to also allow strict type checking.
4450
+ if (cellData === null) {
4451
+ cellData = '';
4452
+ }
4453
+
4454
+ if (typeof cellData !== 'string' && cellData.toString) {
4455
+ cellData = cellData.toString();
4456
+ }
4457
+ } else {
4458
+ cellData = '';
4459
+ }
4460
+
4461
+ // If it looks like there is an HTML entity in the string,
4462
+ // attempt to decode it so sorting works as expected. Note that
4463
+ // we could use a single line of jQuery to do this, but the DOM
4464
+ // method used here is much faster http://jsperf.com/html-decode
4465
+ if (cellData.indexOf && cellData.indexOf('&') !== -1) {
4466
+ __filter_div.innerHTML = cellData;
4467
+ cellData = __filter_div_textContent ?
4468
+ __filter_div.textContent :
4469
+ __filter_div.innerText;
4470
+ }
4471
+
4472
+ if (cellData.replace) {
4473
+ cellData = cellData.replace(/[\r\n]/g, '');
4474
+ }
4475
+
4476
+ filterData.push(cellData);
4477
+ }
4478
+
4479
+ row._aFilterData = filterData;
4480
+ row._sFilterRow = filterData.join(' ');
4481
+ wasInvalidated = true;
4482
+ }
4483
+ }
4484
+
4485
+ return wasInvalidated;
4486
+ }
4487
+
4488
+
4489
+ /**
4490
+ * Convert from the internal Hungarian notation to camelCase for external
4491
+ * interaction
4492
+ * @param {object} obj Object to convert
4493
+ * @returns {object} Inverted object
4494
+ * @memberof DataTable#oApi
4495
+ */
4496
+ function _fnSearchToCamel(obj)
4497
+ {
4498
+ return {
4499
+ search: obj.sSearch,
4500
+ smart: obj.bSmart,
4501
+ regex: obj.bRegex,
4502
+ caseInsensitive: obj.bCaseInsensitive
4503
+ };
4504
+ }
4505
+
4506
+
4507
+
4508
+ /**
4509
+ * Convert from camelCase notation to the internal Hungarian. We could use the
4510
+ * Hungarian convert function here, but this is cleaner
4511
+ * @param {object} obj Object to convert
4512
+ * @returns {object} Inverted object
4513
+ * @memberof DataTable#oApi
4514
+ */
4515
+ function _fnSearchToHung(obj)
4516
+ {
4517
+ return {
4518
+ sSearch: obj.search,
4519
+ bSmart: obj.smart,
4520
+ bRegex: obj.regex,
4521
+ bCaseInsensitive: obj.caseInsensitive
4522
+ };
4523
+ }
4524
+
4525
+ /**
4526
+ * Generate the node required for the info display
4527
+ * @param {object} oSettings dataTables settings object
4528
+ * @returns {node} Information element
4529
+ * @memberof DataTable#oApi
4530
+ */
4531
+ function _fnFeatureHtmlInfo(settings)
4532
+ {
4533
+ var
4534
+ tid = settings.sTableId,
4535
+ nodes = settings.aanFeatures.i,
4536
+ n = $('<div/>', {
4537
+ 'class': settings.oClasses.sInfo,
4538
+ 'id': !nodes ? tid + '_info' : null
4539
+ });
4540
+
4541
+ if (!nodes) {
4542
+ // Update display on each draw
4543
+ settings.aoDrawCallback.push({
4544
+ "fn": _fnUpdateInfo,
4545
+ "sName": "information"
4546
+ });
4547
+
4548
+ n
4549
+ .attr('role', 'status')
4550
+ .attr('aria-live', 'polite');
4551
+
4552
+ // Table is described by our info div
4553
+ $(settings.nTable).attr('aria-describedby', tid + '_info');
4554
+ }
4555
+
4556
+ return n[0];
4557
+ }
4558
+
4559
+
4560
+ /**
4561
+ * Update the information elements in the display
4562
+ * @param {object} settings dataTables settings object
4563
+ * @memberof DataTable#oApi
4564
+ */
4565
+ function _fnUpdateInfo(settings)
4566
+ {
4567
+ /* Show information about the table */
4568
+ var nodes = settings.aanFeatures.i;
4569
+ if (nodes.length === 0) {
4570
+ return;
4571
+ }
4572
+
4573
+ var
4574
+ lang = settings.oLanguage,
4575
+ start = settings._iDisplayStart + 1,
4576
+ end = settings.fnDisplayEnd(),
4577
+ max = settings.fnRecordsTotal(),
4578
+ total = settings.fnRecordsDisplay(),
4579
+ out = total ?
4580
+ lang.sInfo :
4581
+ lang.sInfoEmpty;
4582
+
4583
+ if (total !== max) {
4584
+ /* Record set after filtering */
4585
+ out += ' ' + lang.sInfoFiltered;
4586
+ }
4587
+
4588
+ // Convert the macros
4589
+ out += lang.sInfoPostFix;
4590
+ out = _fnInfoMacros(settings, out);
4591
+
4592
+ var callback = lang.fnInfoCallback;
4593
+ if (callback !== null) {
4594
+ out = callback.call(settings.oInstance,
4595
+ settings, start, end, max, total, out
4596
+ );
4597
+ }
4598
+
4599
+ $(nodes).html(out);
4600
+ }
4601
+
4602
+
4603
+ function _fnInfoMacros(settings, str)
4604
+ {
4605
+ // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
4606
+ // internally
4607
+ var
4608
+ formatter = settings.fnFormatNumber,
4609
+ start = settings._iDisplayStart + 1,
4610
+ len = settings._iDisplayLength,
4611
+ vis = settings.fnRecordsDisplay(),
4612
+ all = len === -1;
4613
+
4614
+ return str.
4615
+ replace(/_START_/g, formatter.call(settings, start)).
4616
+ replace(/_END_/g, formatter.call(settings, settings.fnDisplayEnd())).
4617
+ replace(/_MAX_/g, formatter.call(settings, settings.fnRecordsTotal())).
4618
+ replace(/_TOTAL_/g, formatter.call(settings, vis)).
4619
+ replace(/_PAGE_/g, formatter.call(settings, all ? 1 : Math.ceil(start / len))).
4620
+ replace(/_PAGES_/g, formatter.call(settings, all ? 1 : Math.ceil(vis / len)));
4621
+ }
4622
+
4623
+
4624
+
4625
+ /**
4626
+ * Draw the table for the first time, adding all required features
4627
+ * @param {object} settings dataTables settings object
4628
+ * @memberof DataTable#oApi
4629
+ */
4630
+ function _fnInitialise(settings)
4631
+ {
4632
+ var i, iLen, iAjaxStart = settings.iInitDisplayStart;
4633
+ var columns = settings.aoColumns, column;
4634
+ var features = settings.oFeatures;
4635
+ var deferLoading = settings.bDeferLoading; // value modified by the draw
4636
+
4637
+ /* Ensure that the table data is fully initialised */
4638
+ if (!settings.bInitialised) {
4639
+ setTimeout(function () {
4640
+ _fnInitialise(settings);
4641
+ }, 200);
4642
+ return;
4643
+ }
4644
+
4645
+ /* Show the display HTML options */
4646
+ _fnAddOptionsHtml(settings);
4647
+
4648
+ /* Build and draw the header / footer for the table */
4649
+ _fnBuildHead(settings);
4650
+ _fnDrawHead(settings, settings.aoHeader);
4651
+ _fnDrawHead(settings, settings.aoFooter);
4652
+
4653
+ /* Okay to show that something is going on now */
4654
+ _fnProcessingDisplay(settings, true);
4655
+
4656
+ /* Calculate sizes for columns */
4657
+ if (features.bAutoWidth) {
4658
+ _fnCalculateColumnWidths(settings);
4659
+ }
4660
+
4661
+ for (i = 0, iLen = columns.length; i < iLen; i++) {
4662
+ column = columns[i];
4663
+
4664
+ if (column.sWidth) {
4665
+ column.nTh.style.width = _fnStringToCss(column.sWidth);
4666
+ }
4667
+ }
4668
+
4669
+ _fnCallbackFire(settings, null, 'preInit', [settings]);
4670
+
4671
+ // If there is default sorting required - let's do it. The sort function
4672
+ // will do the drawing for us. Otherwise we draw the table regardless of the
4673
+ // Ajax source - this allows the table to look initialised for Ajax sourcing
4674
+ // data (show 'loading' message possibly)
4675
+ _fnReDraw(settings);
4676
+
4677
+ // Server-side processing init complete is done by _fnAjaxUpdateDraw
4678
+ var dataSrc = _fnDataSource(settings);
4679
+ if (dataSrc != 'ssp' || deferLoading) {
4680
+ // if there is an ajax source load the data
4681
+ if (dataSrc == 'ajax') {
4682
+ _fnBuildAjax(settings, [], function (json) {
4683
+ var aData = _fnAjaxDataSrc(settings, json);
4684
+
4685
+ // Got the data - add it to the table
4686
+ for (i = 0; i < aData.length; i++) {
4687
+ _fnAddData(settings, aData[i]);
4688
+ }
4689
+
4690
+ // Reset the init display for cookie saving. We've already done
4691
+ // a filter, and therefore cleared it before. So we need to make
4692
+ // it appear 'fresh'
4693
+ settings.iInitDisplayStart = iAjaxStart;
4694
+
4695
+ _fnReDraw(settings);
4696
+
4697
+ _fnProcessingDisplay(settings, false);
4698
+ _fnInitComplete(settings, json);
4699
+ }, settings);
4700
+ } else {
4701
+ _fnProcessingDisplay(settings, false);
4702
+ _fnInitComplete(settings);
4703
+ }
4704
+ }
4705
+ }
4706
+
4707
+
4708
+ /**
4709
+ * Draw the table for the first time, adding all required features
4710
+ * @param {object} oSettings dataTables settings object
4711
+ * @param {object} [json] JSON from the server that completed the table, if using Ajax source
4712
+ * with client-side processing (optional)
4713
+ * @memberof DataTable#oApi
4714
+ */
4715
+ function _fnInitComplete(settings, json)
4716
+ {
4717
+ settings._bInitComplete = true;
4718
+
4719
+ // When data was added after the initialisation (data or Ajax) we need to
4720
+ // calculate the column sizing
4721
+ if (json || settings.oInit.aaData) {
4722
+ _fnAdjustColumnSizing(settings);
4723
+ }
4724
+
4725
+ _fnCallbackFire(settings, null, 'plugin-init', [settings, json]);
4726
+ _fnCallbackFire(settings, 'aoInitComplete', 'init', [settings, json]);
4727
+ }
4728
+
4729
+
4730
+ function _fnLengthChange(settings, val)
4731
+ {
4732
+ var len = parseInt(val, 10);
4733
+ settings._iDisplayLength = len;
4734
+
4735
+ _fnLengthOverflow(settings);
4736
+
4737
+ // Fire length change event
4738
+ _fnCallbackFire(settings, null, 'length', [settings, len]);
4739
+ }
4740
+
4741
+
4742
+ /**
4743
+ * Generate the node required for user display length changing
4744
+ * @param {object} settings dataTables settings object
4745
+ * @returns {node} Display length feature node
4746
+ * @memberof DataTable#oApi
4747
+ */
4748
+ function _fnFeatureHtmlLength(settings)
4749
+ {
4750
+ var
4751
+ classes = settings.oClasses,
4752
+ tableId = settings.sTableId,
4753
+ menu = settings.aLengthMenu,
4754
+ d2 = $.isArray(menu[0]),
4755
+ lengths = d2 ? menu[0] : menu,
4756
+ language = d2 ? menu[1] : menu;
4757
+
4758
+ var select = $('<select/>', {
4759
+ 'name': tableId + '_length',
4760
+ 'aria-controls': tableId,
4761
+ 'class': classes.sLengthSelect
4762
+ });
4763
+
4764
+ for (var i = 0, ien = lengths.length; i < ien; i++) {
4765
+ select[0][ i ] = new Option(language[i], lengths[i]);
4766
+ }
4767
+
4768
+ var div = $('<div><label/></div>').addClass(classes.sLength);
4769
+ if (!settings.aanFeatures.l) {
4770
+ div[0].id = tableId + '_length';
4771
+ }
4772
+
4773
+ div.children().append(
4774
+ settings.oLanguage.sLengthMenu.replace('_MENU_', select[0].outerHTML)
4775
+ );
4776
+
4777
+ // Can't use `select` variable as user might provide their own and the
4778
+ // reference is broken by the use of outerHTML
4779
+ $('select', div)
4780
+ .val(settings._iDisplayLength)
4781
+ .on('change.DT', function (e) {
4782
+ _fnLengthChange(settings, $(this).val());
4783
+ _fnDraw(settings);
4784
+ });
4785
+
4786
+ // Update node value whenever anything changes the table's length
4787
+ $(settings.nTable).on('length.dt.DT', function (e, s, len) {
4788
+ if (settings === s) {
4789
+ $('select', div).val(len);
4790
+ }
4791
+ });
4792
+
4793
+ return div[0];
4794
+ }
4795
+
4796
+
4797
+
4798
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4799
+ * Note that most of the paging logic is done in
4800
+ * DataTable.ext.pager
4801
+ */
4802
+
4803
+ /**
4804
+ * Generate the node required for default pagination
4805
+ * @param {object} oSettings dataTables settings object
4806
+ * @returns {node} Pagination feature node
4807
+ * @memberof DataTable#oApi
4808
+ */
4809
+ function _fnFeatureHtmlPaginate(settings)
4810
+ {
4811
+ var
4812
+ type = settings.sPaginationType,
4813
+ plugin = DataTable.ext.pager[ type ],
4814
+ modern = typeof plugin === 'function',
4815
+ redraw = function (settings) {
4816
+ _fnDraw(settings);
4817
+ },
4818
+ node = $('<div/>').addClass(settings.oClasses.sPaging + type)[0],
4819
+ features = settings.aanFeatures;
4820
+
4821
+ if (!modern) {
4822
+ plugin.fnInit(settings, node, redraw);
4823
+ }
4824
+
4825
+ /* Add a draw callback for the pagination on first instance, to update the paging display */
4826
+ if (!features.p)
4827
+ {
4828
+ node.id = settings.sTableId + '_paginate';
4829
+
4830
+ settings.aoDrawCallback.push({
4831
+ "fn": function (settings) {
4832
+ if (modern) {
4833
+ var
4834
+ start = settings._iDisplayStart,
4835
+ len = settings._iDisplayLength,
4836
+ visRecords = settings.fnRecordsDisplay(),
4837
+ all = len === -1,
4838
+ page = all ? 0 : Math.ceil(start / len),
4839
+ pages = all ? 1 : Math.ceil(visRecords / len),
4840
+ buttons = plugin(page, pages),
4841
+ i, ien;
4842
+
4843
+ for (i = 0, ien = features.p.length; i < ien; i++) {
4844
+ _fnRenderer(settings, 'pageButton')(
4845
+ settings, features.p[i], i, buttons, page, pages
4846
+ );
4847
+ }
4848
+ } else {
4849
+ plugin.fnUpdate(settings, redraw);
4850
+ }
4851
+ },
4852
+ "sName": "pagination"
4853
+ });
4854
+ }
4855
+
4856
+ return node;
4857
+ }
4858
+
4859
+
4860
+ /**
4861
+ * Alter the display settings to change the page
4862
+ * @param {object} settings DataTables settings object
4863
+ * @param {string|int} action Paging action to take: "first", "previous",
4864
+ * "next" or "last" or page number to jump to (integer)
4865
+ * @param [bool] redraw Automatically draw the update or not
4866
+ * @returns {bool} true page has changed, false - no change
4867
+ * @memberof DataTable#oApi
4868
+ */
4869
+ function _fnPageChange(settings, action, redraw)
4870
+ {
4871
+ var
4872
+ start = settings._iDisplayStart,
4873
+ len = settings._iDisplayLength,
4874
+ records = settings.fnRecordsDisplay();
4875
+
4876
+ if (records === 0 || len === -1)
4877
+ {
4878
+ start = 0;
4879
+ } else if (typeof action === "number")
4880
+ {
4881
+ start = action * len;
4882
+
4883
+ if (start > records)
4884
+ {
4885
+ start = 0;
4886
+ }
4887
+ } else if (action == "first")
4888
+ {
4889
+ start = 0;
4890
+ } else if (action == "previous")
4891
+ {
4892
+ start = len >= 0 ?
4893
+ start - len :
4894
+ 0;
4895
+
4896
+ if (start < 0)
4897
+ {
4898
+ start = 0;
4899
+ }
4900
+ } else if (action == "next")
4901
+ {
4902
+ if (start + len < records)
4903
+ {
4904
+ start += len;
4905
+ }
4906
+ } else if (action == "last")
4907
+ {
4908
+ start = Math.floor((records - 1) / len) * len;
4909
+ } else
4910
+ {
4911
+ _fnLog(settings, 0, "Unknown paging action: " + action, 5);
4912
+ }
4913
+
4914
+ var changed = settings._iDisplayStart !== start;
4915
+ settings._iDisplayStart = start;
4916
+
4917
+ if (changed) {
4918
+ _fnCallbackFire(settings, null, 'page', [settings]);
4919
+
4920
+ if (redraw) {
4921
+ _fnDraw(settings);
4922
+ }
4923
+ }
4924
+
4925
+ return changed;
4926
+ }
4927
+
4928
+
4929
+
4930
+ /**
4931
+ * Generate the node required for the processing node
4932
+ * @param {object} settings dataTables settings object
4933
+ * @returns {node} Processing element
4934
+ * @memberof DataTable#oApi
4935
+ */
4936
+ function _fnFeatureHtmlProcessing(settings)
4937
+ {
4938
+ return $('<div/>', {
4939
+ 'id': !settings.aanFeatures.r ? settings.sTableId + '_processing' : null,
4940
+ 'class': settings.oClasses.sProcessing
4941
+ })
4942
+ .html(settings.oLanguage.sProcessing)
4943
+ .insertBefore(settings.nTable)[0];
4944
+ }
4945
+
4946
+
4947
+ /**
4948
+ * Display or hide the processing indicator
4949
+ * @param {object} settings dataTables settings object
4950
+ * @param {bool} show Show the processing indicator (true) or not (false)
4951
+ * @memberof DataTable#oApi
4952
+ */
4953
+ function _fnProcessingDisplay(settings, show)
4954
+ {
4955
+ if (settings.oFeatures.bProcessing) {
4956
+ $(settings.aanFeatures.r).css('display', show ? 'block' : 'none');
4957
+ }
4958
+
4959
+ _fnCallbackFire(settings, null, 'processing', [settings, show]);
4960
+ }
4961
+
4962
+ /**
4963
+ * Add any control elements for the table - specifically scrolling
4964
+ * @param {object} settings dataTables settings object
4965
+ * @returns {node} Node to add to the DOM
4966
+ * @memberof DataTable#oApi
4967
+ */
4968
+ function _fnFeatureHtmlTable(settings)
4969
+ {
4970
+ var table = $(settings.nTable);
4971
+
4972
+ // Add the ARIA grid role to the table
4973
+ table.attr('role', 'grid');
4974
+
4975
+ // Scrolling from here on in
4976
+ var scroll = settings.oScroll;
4977
+
4978
+ if (scroll.sX === '' && scroll.sY === '') {
4979
+ return settings.nTable;
4980
+ }
4981
+
4982
+ var scrollX = scroll.sX;
4983
+ var scrollY = scroll.sY;
4984
+ var classes = settings.oClasses;
4985
+ var caption = table.children('caption');
4986
+ var captionSide = caption.length ? caption[0]._captionSide : null;
4987
+ var headerClone = $(table[0].cloneNode(false));
4988
+ var footerClone = $(table[0].cloneNode(false));
4989
+ var footer = table.children('tfoot');
4990
+ var _div = '<div/>';
4991
+ var size = function (s) {
4992
+ return !s ? null : _fnStringToCss(s);
4993
+ };
4994
+
4995
+ if (!footer.length) {
4996
+ footer = null;
4997
+ }
4998
+
4999
+ /*
5000
+ * The HTML structure that we want to generate in this function is:
5001
+ * div - scroller
5002
+ * div - scroll head
5003
+ * div - scroll head inner
5004
+ * table - scroll head table
5005
+ * thead - thead
5006
+ * div - scroll body
5007
+ * table - table (master table)
5008
+ * thead - thead clone for sizing
5009
+ * tbody - tbody
5010
+ * div - scroll foot
5011
+ * div - scroll foot inner
5012
+ * table - scroll foot table
5013
+ * tfoot - tfoot
5014
+ */
5015
+ var scroller = $(_div, {'class': classes.sScrollWrapper})
5016
+ .append(
5017
+ $(_div, {'class': classes.sScrollHead})
5018
+ .css({
5019
+ overflow: 'hidden',
5020
+ position: 'relative',
5021
+ border: 0,
5022
+ width: scrollX ? size(scrollX) : '100%'
5023
+ })
5024
+ .append(
5025
+ $(_div, {'class': classes.sScrollHeadInner})
5026
+ .css({
5027
+ 'box-sizing': 'content-box',
5028
+ width: scroll.sXInner || '100%'
5029
+ })
5030
+ .append(
5031
+ headerClone
5032
+ .removeAttr('id')
5033
+ .css('margin-left', 0)
5034
+ .append(captionSide === 'top' ? caption : null)
5035
+ .append(
5036
+ table.children('thead')
5037
+ )
5038
+ )
5039
+ )
5040
+ )
5041
+ .append(
5042
+ $(_div, {'class': classes.sScrollBody})
5043
+ .css({
5044
+ position: 'relative',
5045
+ overflow: 'auto',
5046
+ width: size(scrollX)
5047
+ })
5048
+ .append(table)
5049
+ );
5050
+
5051
+ if (footer) {
5052
+ scroller.append(
5053
+ $(_div, {'class': classes.sScrollFoot})
5054
+ .css({
5055
+ overflow: 'hidden',
5056
+ border: 0,
5057
+ width: scrollX ? size(scrollX) : '100%'
5058
+ })
5059
+ .append(
5060
+ $(_div, {'class': classes.sScrollFootInner})
5061
+ .append(
5062
+ footerClone
5063
+ .removeAttr('id')
5064
+ .css('margin-left', 0)
5065
+ .append(captionSide === 'bottom' ? caption : null)
5066
+ .append(
5067
+ table.children('tfoot')
5068
+ )
5069
+ )
5070
+ )
5071
+ );
5072
+ }
5073
+
5074
+ var children = scroller.children();
5075
+ var scrollHead = children[0];
5076
+ var scrollBody = children[1];
5077
+ var scrollFoot = footer ? children[2] : null;
5078
+
5079
+ // When the body is scrolled, then we also want to scroll the headers
5080
+ if (scrollX) {
5081
+ $(scrollBody).on('scroll.DT', function (e) {
5082
+ var scrollLeft = this.scrollLeft;
5083
+
5084
+ scrollHead.scrollLeft = scrollLeft;
5085
+
5086
+ if (footer) {
5087
+ scrollFoot.scrollLeft = scrollLeft;
5088
+ }
5089
+ });
5090
+ }
5091
+
5092
+ $(scrollBody).css(
5093
+ scrollY && scroll.bCollapse ? 'max-height' : 'height',
5094
+ scrollY
5095
+ );
5096
+
5097
+ settings.nScrollHead = scrollHead;
5098
+ settings.nScrollBody = scrollBody;
5099
+ settings.nScrollFoot = scrollFoot;
5100
+
5101
+ // On redraw - align columns
5102
+ settings.aoDrawCallback.push({
5103
+ "fn": _fnScrollDraw,
5104
+ "sName": "scrolling"
5105
+ });
5106
+
5107
+ return scroller[0];
5108
+ }
5109
+
5110
+
5111
+
5112
+ /**
5113
+ * Update the header, footer and body tables for resizing - i.e. column
5114
+ * alignment.
5115
+ *
5116
+ * Welcome to the most horrible function DataTables. The process that this
5117
+ * function follows is basically:
5118
+ * 1. Re-create the table inside the scrolling div
5119
+ * 2. Take live measurements from the DOM
5120
+ * 3. Apply the measurements to align the columns
5121
+ * 4. Clean up
5122
+ *
5123
+ * @param {object} settings dataTables settings object
5124
+ * @memberof DataTable#oApi
5125
+ */
5126
+ function _fnScrollDraw(settings)
5127
+ {
5128
+ // Given that this is such a monster function, a lot of variables are use
5129
+ // to try and keep the minimised size as small as possible
5130
+ var
5131
+ scroll = settings.oScroll,
5132
+ scrollX = scroll.sX,
5133
+ scrollXInner = scroll.sXInner,
5134
+ scrollY = scroll.sY,
5135
+ barWidth = scroll.iBarWidth,
5136
+ divHeader = $(settings.nScrollHead),
5137
+ divHeaderStyle = divHeader[0].style,
5138
+ divHeaderInner = divHeader.children('div'),
5139
+ divHeaderInnerStyle = divHeaderInner[0].style,
5140
+ divHeaderTable = divHeaderInner.children('table'),
5141
+ divBodyEl = settings.nScrollBody,
5142
+ divBody = $(divBodyEl),
5143
+ divBodyStyle = divBodyEl.style,
5144
+ divFooter = $(settings.nScrollFoot),
5145
+ divFooterInner = divFooter.children('div'),
5146
+ divFooterTable = divFooterInner.children('table'),
5147
+ header = $(settings.nTHead),
5148
+ table = $(settings.nTable),
5149
+ tableEl = table[0],
5150
+ tableStyle = tableEl.style,
5151
+ footer = settings.nTFoot ? $(settings.nTFoot) : null,
5152
+ browser = settings.oBrowser,
5153
+ ie67 = browser.bScrollOversize,
5154
+ dtHeaderCells = _pluck(settings.aoColumns, 'nTh'),
5155
+ headerTrgEls, footerTrgEls,
5156
+ headerSrcEls, footerSrcEls,
5157
+ headerCopy, footerCopy,
5158
+ headerWidths = [], footerWidths = [],
5159
+ headerContent = [], footerContent = [],
5160
+ idx, correction, sanityWidth,
5161
+ zeroOut = function (nSizer) {
5162
+ var style = nSizer.style;
5163
+ style.paddingTop = "0";
5164
+ style.paddingBottom = "0";
5165
+ style.borderTopWidth = "0";
5166
+ style.borderBottomWidth = "0";
5167
+ style.height = 0;
5168
+ };
5169
+
5170
+ // If the scrollbar visibility has changed from the last draw, we need to
5171
+ // adjust the column sizes as the table width will have changed to account
5172
+ // for the scrollbar
5173
+ var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
5174
+
5175
+ if (settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined) {
5176
+ settings.scrollBarVis = scrollBarVis;
5177
+ _fnAdjustColumnSizing(settings);
5178
+ return; // adjust column sizing will call this function again
5179
+ } else {
5180
+ settings.scrollBarVis = scrollBarVis;
5181
+ }
5182
+
5183
+ /*
5184
+ * 1. Re-create the table inside the scrolling div
5185
+ */
5186
+
5187
+ // Remove the old minimised thead and tfoot elements in the inner table
5188
+ table.children('thead, tfoot').remove();
5189
+
5190
+ if (footer) {
5191
+ footerCopy = footer.clone().prependTo(table);
5192
+ footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
5193
+ footerSrcEls = footerCopy.find('tr');
5194
+ }
5195
+
5196
+ // Clone the current header and footer elements and then place it into the inner table
5197
+ headerCopy = header.clone().prependTo(table);
5198
+ headerTrgEls = header.find('tr'); // original header is in its own table
5199
+ headerSrcEls = headerCopy.find('tr');
5200
+ headerCopy.find('th, td').removeAttr('tabindex');
5201
+
5202
+
5203
+ /*
5204
+ * 2. Take live measurements from the DOM - do not alter the DOM itself!
5205
+ */
5206
+
5207
+ // Remove old sizing and apply the calculated column widths
5208
+ // Get the unique column headers in the newly created (cloned) header. We want to apply the
5209
+ // calculated sizes to this header
5210
+ if (!scrollX)
5211
+ {
5212
+ divBodyStyle.width = '100%';
5213
+ divHeader[0].style.width = '100%';
5214
+ }
5215
+
5216
+ $.each(_fnGetUniqueThs(settings, headerCopy), function (i, el) {
5217
+ idx = _fnVisibleToColumnIndex(settings, i);
5218
+ el.style.width = settings.aoColumns[idx].sWidth;
5219
+ });
5220
+
5221
+ if (footer) {
5222
+ _fnApplyToChildren(function (n) {
5223
+ n.style.width = "";
5224
+ }, footerSrcEls);
5225
+ }
5226
+
5227
+ // Size the table as a whole
5228
+ sanityWidth = table.outerWidth();
5229
+ if (scrollX === "") {
5230
+ // No x scrolling
5231
+ tableStyle.width = "100%";
5232
+
5233
+ // IE7 will make the width of the table when 100% include the scrollbar
5234
+ // - which is shouldn't. When there is a scrollbar we need to take this
5235
+ // into account.
5236
+ if (ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
5237
+ divBody.css('overflow-y') == "scroll")
5238
+ ) {
5239
+ tableStyle.width = _fnStringToCss(table.outerWidth() - barWidth);
5240
+ }
5241
+
5242
+ // Recalculate the sanity width
5243
+ sanityWidth = table.outerWidth();
5244
+ } else if (scrollXInner !== "") {
5245
+ // legacy x scroll inner has been given - use it
5246
+ tableStyle.width = _fnStringToCss(scrollXInner);
5247
+
5248
+ // Recalculate the sanity width
5249
+ sanityWidth = table.outerWidth();
5250
+ }
5251
+
5252
+ // Hidden header should have zero height, so remove padding and borders. Then
5253
+ // set the width based on the real headers
5254
+
5255
+ // Apply all styles in one pass
5256
+ _fnApplyToChildren(zeroOut, headerSrcEls);
5257
+
5258
+ // Read all widths in next pass
5259
+ _fnApplyToChildren(function (nSizer) {
5260
+ headerContent.push(nSizer.innerHTML);
5261
+ headerWidths.push(_fnStringToCss($(nSizer).css('width')));
5262
+ }, headerSrcEls);
5263
+
5264
+ // Apply all widths in final pass
5265
+ _fnApplyToChildren(function (nToSize, i) {
5266
+ // Only apply widths to the DataTables detected header cells - this
5267
+ // prevents complex headers from having contradictory sizes applied
5268
+ if ($.inArray(nToSize, dtHeaderCells) !== -1) {
5269
+ nToSize.style.width = headerWidths[i];
5270
+ }
5271
+ }, headerTrgEls);
5272
+
5273
+ $(headerSrcEls).height(0);
5274
+
5275
+ /* Same again with the footer if we have one */
5276
+ if (footer)
5277
+ {
5278
+ _fnApplyToChildren(zeroOut, footerSrcEls);
5279
+
5280
+ _fnApplyToChildren(function (nSizer) {
5281
+ footerContent.push(nSizer.innerHTML);
5282
+ footerWidths.push(_fnStringToCss($(nSizer).css('width')));
5283
+ }, footerSrcEls);
5284
+
5285
+ _fnApplyToChildren(function (nToSize, i) {
5286
+ nToSize.style.width = footerWidths[i];
5287
+ }, footerTrgEls);
5288
+
5289
+ $(footerSrcEls).height(0);
5290
+ }
5291
+
5292
+
5293
+ /*
5294
+ * 3. Apply the measurements
5295
+ */
5296
+
5297
+ // "Hide" the header and footer that we used for the sizing. We need to keep
5298
+ // the content of the cell so that the width applied to the header and body
5299
+ // both match, but we want to hide it completely. We want to also fix their
5300
+ // width to what they currently are
5301
+ _fnApplyToChildren(function (nSizer, i) {
5302
+ nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">' + headerContent[i] + '</div>';
5303
+ nSizer.style.width = headerWidths[i];
5304
+ }, headerSrcEls);
5305
+
5306
+ if (footer)
5307
+ {
5308
+ _fnApplyToChildren(function (nSizer, i) {
5309
+ nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">' + footerContent[i] + '</div>';
5310
+ nSizer.style.width = footerWidths[i];
5311
+ }, footerSrcEls);
5312
+ }
5313
+
5314
+ // Sanity check that the table is of a sensible width. If not then we are going to get
5315
+ // misalignment - try to prevent this by not allowing the table to shrink below its min width
5316
+ if (table.outerWidth() < sanityWidth)
5317
+ {
5318
+ // The min width depends upon if we have a vertical scrollbar visible or not */
5319
+ correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
5320
+ divBody.css('overflow-y') == "scroll")) ?
5321
+ sanityWidth + barWidth :
5322
+ sanityWidth;
5323
+
5324
+ // IE6/7 are a law unto themselves...
5325
+ if (ie67 && (divBodyEl.scrollHeight >
5326
+ divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
5327
+ ) {
5328
+ tableStyle.width = _fnStringToCss(correction - barWidth);
5329
+ }
5330
+
5331
+ // And give the user a warning that we've stopped the table getting too small
5332
+ if (scrollX === "" || scrollXInner !== "") {
5333
+ _fnLog(settings, 1, 'Possible column misalignment', 6);
5334
+ }
5335
+ } else
5336
+ {
5337
+ correction = '100%';
5338
+ }
5339
+
5340
+ // Apply to the container elements
5341
+ divBodyStyle.width = _fnStringToCss(correction);
5342
+ divHeaderStyle.width = _fnStringToCss(correction);
5343
+
5344
+ if (footer) {
5345
+ settings.nScrollFoot.style.width = _fnStringToCss(correction);
5346
+ }
5347
+
5348
+
5349
+ /*
5350
+ * 4. Clean up
5351
+ */
5352
+ if (!scrollY) {
5353
+ /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
5354
+ * the scrollbar height from the visible display, rather than adding it on. We need to
5355
+ * set the height in order to sort this. Don't want to do it in any other browsers.
5356
+ */
5357
+ if (ie67) {
5358
+ divBodyStyle.height = _fnStringToCss(tableEl.offsetHeight + barWidth);
5359
+ }
5360
+ }
5361
+
5362
+ /* Finally set the width's of the header and footer tables */
5363
+ var iOuterWidth = table.outerWidth();
5364
+ divHeaderTable[0].style.width = _fnStringToCss(iOuterWidth);
5365
+ divHeaderInnerStyle.width = _fnStringToCss(iOuterWidth);
5366
+
5367
+ // Figure out if there are scrollbar present - if so then we need a the header and footer to
5368
+ // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
5369
+ var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
5370
+ var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right');
5371
+ divHeaderInnerStyle[ padding ] = bScrolling ? barWidth + "px" : "0px";
5372
+
5373
+ if (footer) {
5374
+ divFooterTable[0].style.width = _fnStringToCss(iOuterWidth);
5375
+ divFooterInner[0].style.width = _fnStringToCss(iOuterWidth);
5376
+ divFooterInner[0].style[padding] = bScrolling ? barWidth + "px" : "0px";
5377
+ }
5378
+
5379
+ // Correct DOM ordering for colgroup - comes before the thead
5380
+ table.children('colgroup').insertBefore(table.children('thead'));
5381
+
5382
+ /* Adjust the position of the header in case we loose the y-scrollbar */
5383
+ divBody.scroll();
5384
+
5385
+ // If sorting or filtering has occurred, jump the scrolling back to the top
5386
+ // only if we aren't holding the position
5387
+ if ((settings.bSorted || settings.bFiltered) && !settings._drawHold) {
5388
+ divBodyEl.scrollTop = 0;
5389
+ }
5390
+ }
5391
+
5392
+
5393
+
5394
+ /**
5395
+ * Apply a given function to the display child nodes of an element array (typically
5396
+ * TD children of TR rows
5397
+ * @param {function} fn Method to apply to the objects
5398
+ * @param array {nodes} an1 List of elements to look through for display children
5399
+ * @param array {nodes} an2 Another list (identical structure to the first) - optional
5400
+ * @memberof DataTable#oApi
5401
+ */
5402
+ function _fnApplyToChildren(fn, an1, an2)
5403
+ {
5404
+ var index = 0, i = 0, iLen = an1.length;
5405
+ var nNode1, nNode2;
5406
+
5407
+ while (i < iLen) {
5408
+ nNode1 = an1[i].firstChild;
5409
+ nNode2 = an2 ? an2[i].firstChild : null;
5410
+
5411
+ while (nNode1) {
5412
+ if (nNode1.nodeType === 1) {
5413
+ if (an2) {
5414
+ fn(nNode1, nNode2, index);
5415
+ } else {
5416
+ fn(nNode1, index);
5417
+ }
5418
+
5419
+ index++;
5420
+ }
5421
+
5422
+ nNode1 = nNode1.nextSibling;
5423
+ nNode2 = an2 ? nNode2.nextSibling : null;
5424
+ }
5425
+
5426
+ i++;
5427
+ }
5428
+ }
5429
+
5430
+
5431
+
5432
+ var __re_html_remove = /<.*?>/g;
5433
+
5434
+
5435
+ /**
5436
+ * Calculate the width of columns for the table
5437
+ * @param {object} oSettings dataTables settings object
5438
+ * @memberof DataTable#oApi
5439
+ */
5440
+ function _fnCalculateColumnWidths(oSettings)
5441
+ {
5442
+ var
5443
+ table = oSettings.nTable,
5444
+ columns = oSettings.aoColumns,
5445
+ scroll = oSettings.oScroll,
5446
+ scrollY = scroll.sY,
5447
+ scrollX = scroll.sX,
5448
+ scrollXInner = scroll.sXInner,
5449
+ columnCount = columns.length,
5450
+ visibleColumns = _fnGetColumns(oSettings, 'bVisible'),
5451
+ headerCells = $('th', oSettings.nTHead),
5452
+ tableWidthAttr = table.getAttribute('width'), // from DOM element
5453
+ tableContainer = table.parentNode,
5454
+ userInputs = false,
5455
+ i, column, columnIdx, width, outerWidth,
5456
+ browser = oSettings.oBrowser,
5457
+ ie67 = browser.bScrollOversize;
5458
+
5459
+ var styleWidth = table.style.width;
5460
+ if (styleWidth && styleWidth.indexOf('%') !== -1) {
5461
+ tableWidthAttr = styleWidth;
5462
+ }
5463
+
5464
+ /* Convert any user input sizes into pixel sizes */
5465
+ for (i = 0; i < visibleColumns.length; i++) {
5466
+ column = columns[ visibleColumns[i] ];
5467
+
5468
+ if (column.sWidth !== null) {
5469
+ column.sWidth = _fnConvertToWidth(column.sWidthOrig, tableContainer);
5470
+
5471
+ userInputs = true;
5472
+ }
5473
+ }
5474
+
5475
+ /* If the number of columns in the DOM equals the number that we have to
5476
+ * process in DataTables, then we can use the offsets that are created by
5477
+ * the web- browser. No custom sizes can be set in order for this to happen,
5478
+ * nor scrolling used
5479
+ */
5480
+ if (ie67 || !userInputs && !scrollX && !scrollY &&
5481
+ columnCount == _fnVisbleColumns(oSettings) &&
5482
+ columnCount == headerCells.length
5483
+ ) {
5484
+ for (i = 0; i < columnCount; i++) {
5485
+ var colIdx = _fnVisibleToColumnIndex(oSettings, i);
5486
+
5487
+ if (colIdx !== null) {
5488
+ columns[ colIdx ].sWidth = _fnStringToCss(headerCells.eq(i).width());
5489
+ }
5490
+ }
5491
+ } else
5492
+ {
5493
+ // Otherwise construct a single row, worst case, table with the widest
5494
+ // node in the data, assign any user defined widths, then insert it into
5495
+ // the DOM and allow the browser to do all the hard work of calculating
5496
+ // table widths
5497
+ var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
5498
+ .css('visibility', 'hidden')
5499
+ .removeAttr('id');
5500
+
5501
+ // Clean up the table body
5502
+ tmpTable.find('tbody tr').remove();
5503
+ var tr = $('<tr/>').appendTo(tmpTable.find('tbody'));
5504
+
5505
+ // Clone the table header and footer - we can't use the header / footer
5506
+ // from the cloned table, since if scrolling is active, the table's
5507
+ // real header and footer are contained in different table tags
5508
+ tmpTable.find('thead, tfoot').remove();
5509
+ tmpTable
5510
+ .append($(oSettings.nTHead).clone())
5511
+ .append($(oSettings.nTFoot).clone());
5512
+
5513
+ // Remove any assigned widths from the footer (from scrolling)
5514
+ tmpTable.find('tfoot th, tfoot td').css('width', '');
5515
+
5516
+ // Apply custom sizing to the cloned header
5517
+ headerCells = _fnGetUniqueThs(oSettings, tmpTable.find('thead')[0]);
5518
+
5519
+ for (i = 0; i < visibleColumns.length; i++) {
5520
+ column = columns[ visibleColumns[i] ];
5521
+
5522
+ headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
5523
+ _fnStringToCss(column.sWidthOrig) :
5524
+ '';
5525
+
5526
+ // For scrollX we need to force the column width otherwise the
5527
+ // browser will collapse it. If this width is smaller than the
5528
+ // width the column requires, then it will have no effect
5529
+ if (column.sWidthOrig && scrollX) {
5530
+ $(headerCells[i]).append($('<div/>').css({
5531
+ width: column.sWidthOrig,
5532
+ margin: 0,
5533
+ padding: 0,
5534
+ border: 0,
5535
+ height: 1
5536
+ }));
5537
+ }
5538
+ }
5539
+
5540
+ // Find the widest cell for each column and put it into the table
5541
+ if (oSettings.aoData.length) {
5542
+ for (i = 0; i < visibleColumns.length; i++) {
5543
+ columnIdx = visibleColumns[i];
5544
+ column = columns[ columnIdx ];
5545
+
5546
+ $(_fnGetWidestNode(oSettings, columnIdx))
5547
+ .clone(false)
5548
+ .append(column.sContentPadding)
5549
+ .appendTo(tr);
5550
+ }
5551
+ }
5552
+
5553
+ // Tidy the temporary table - remove name attributes so there aren't
5554
+ // duplicated in the dom (radio elements for example)
5555
+ $('[name]', tmpTable).removeAttr('name');
5556
+
5557
+ // Table has been built, attach to the document so we can work with it.
5558
+ // A holding element is used, positioned at the top of the container
5559
+ // with minimal height, so it has no effect on if the container scrolls
5560
+ // or not. Otherwise it might trigger scrolling when it actually isn't
5561
+ // needed
5562
+ var holder = $('<div/>').css(scrollX || scrollY ?
5563
+ {
5564
+ position: 'absolute',
5565
+ top: 0,
5566
+ left: 0,
5567
+ height: 1,
5568
+ right: 0,
5569
+ overflow: 'hidden'
5570
+ } :
5571
+ {}
5572
+ )
5573
+ .append(tmpTable)
5574
+ .appendTo(tableContainer);
5575
+
5576
+ // When scrolling (X or Y) we want to set the width of the table as
5577
+ // appropriate. However, when not scrolling leave the table width as it
5578
+ // is. This results in slightly different, but I think correct behaviour
5579
+ if (scrollX && scrollXInner) {
5580
+ tmpTable.width(scrollXInner);
5581
+ } else if (scrollX) {
5582
+ tmpTable.css('width', 'auto');
5583
+ tmpTable.removeAttr('width');
5584
+
5585
+ // If there is no width attribute or style, then allow the table to
5586
+ // collapse
5587
+ if (tmpTable.width() < tableContainer.clientWidth && tableWidthAttr) {
5588
+ tmpTable.width(tableContainer.clientWidth);
5589
+ }
5590
+ } else if (scrollY) {
5591
+ tmpTable.width(tableContainer.clientWidth);
5592
+ } else if (tableWidthAttr) {
5593
+ tmpTable.width(tableWidthAttr);
5594
+ }
5595
+
5596
+ // Get the width of each column in the constructed table - we need to
5597
+ // know the inner width (so it can be assigned to the other table's
5598
+ // cells) and the outer width so we can calculate the full width of the
5599
+ // table. This is safe since DataTables requires a unique cell for each
5600
+ // column, but if ever a header can span multiple columns, this will
5601
+ // need to be modified.
5602
+ var total = 0;
5603
+ for (i = 0; i < visibleColumns.length; i++) {
5604
+ var cell = $(headerCells[i]);
5605
+ var border = cell.outerWidth() - cell.width();
5606
+
5607
+ // Use getBounding... where possible (not IE8-) because it can give
5608
+ // sub-pixel accuracy, which we then want to round up!
5609
+ var bounding = browser.bBounding ?
5610
+ Math.ceil(headerCells[i].getBoundingClientRect().width) :
5611
+ cell.outerWidth();
5612
+
5613
+ // Total is tracked to remove any sub-pixel errors as the outerWidth
5614
+ // of the table might not equal the total given here (IE!).
5615
+ total += bounding;
5616
+
5617
+ // Width for each column to use
5618
+ columns[ visibleColumns[i] ].sWidth = _fnStringToCss(bounding - border);
5619
+ }
5620
+
5621
+ table.style.width = _fnStringToCss(total);
5622
+
5623
+ // Finished with the table - ditch it
5624
+ holder.remove();
5625
+ }
5626
+
5627
+ // If there is a width attr, we want to attach an event listener which
5628
+ // allows the table sizing to automatically adjust when the window is
5629
+ // resized. Use the width attr rather than CSS, since we can't know if the
5630
+ // CSS is a relative value or absolute - DOM read is always px.
5631
+ if (tableWidthAttr) {
5632
+ table.style.width = _fnStringToCss(tableWidthAttr);
5633
+ }
5634
+
5635
+ if ((tableWidthAttr || scrollX) && !oSettings._reszEvt) {
5636
+ var bindResize = function () {
5637
+ $(window).on('resize.DT-' + oSettings.sInstance, _fnThrottle(function () {
5638
+ _fnAdjustColumnSizing(oSettings);
5639
+ }));
5640
+ };
5641
+
5642
+ // IE6/7 will crash if we bind a resize event handler on page load.
5643
+ // To be removed in 1.11 which drops IE6/7 support
5644
+ if (ie67) {
5645
+ setTimeout(bindResize, 1000);
5646
+ } else {
5647
+ bindResize();
5648
+ }
5649
+
5650
+ oSettings._reszEvt = true;
5651
+ }
5652
+ }
5653
+
5654
+
5655
+ /**
5656
+ * Throttle the calls to a function. Arguments and context are maintained for
5657
+ * the throttled function
5658
+ * @param {function} fn Function to be called
5659
+ * @param {int} [freq=200] call frequency in mS
5660
+ * @returns {function} wrapped function
5661
+ * @memberof DataTable#oApi
5662
+ */
5663
+ var _fnThrottle = DataTable.util.throttle;
5664
+
5665
+
5666
+ /**
5667
+ * Convert a CSS unit width to pixels (e.g. 2em)
5668
+ * @param {string} width width to be converted
5669
+ * @param {node} parent parent to get the with for (required for relative widths) - optional
5670
+ * @returns {int} width in pixels
5671
+ * @memberof DataTable#oApi
5672
+ */
5673
+ function _fnConvertToWidth(width, parent)
5674
+ {
5675
+ if (!width) {
5676
+ return 0;
5677
+ }
5678
+
5679
+ var n = $('<div/>')
5680
+ .css('width', _fnStringToCss(width))
5681
+ .appendTo(parent || document.body);
5682
+
5683
+ var val = n[0].offsetWidth;
5684
+ n.remove();
5685
+
5686
+ return val;
5687
+ }
5688
+
5689
+
5690
+ /**
5691
+ * Get the widest node
5692
+ * @param {object} settings dataTables settings object
5693
+ * @param {int} colIdx column of interest
5694
+ * @returns {node} widest table node
5695
+ * @memberof DataTable#oApi
5696
+ */
5697
+ function _fnGetWidestNode(settings, colIdx)
5698
+ {
5699
+ var idx = _fnGetMaxLenString(settings, colIdx);
5700
+ if (idx < 0) {
5701
+ return null;
5702
+ }
5703
+
5704
+ var data = settings.aoData[ idx ];
5705
+ return !data.nTr ? // Might not have been created when deferred rendering
5706
+ $('<td/>').html(_fnGetCellData(settings, idx, colIdx, 'display'))[0] :
5707
+ data.anCells[ colIdx ];
5708
+ }
5709
+
5710
+
5711
+ /**
5712
+ * Get the maximum strlen for each data column
5713
+ * @param {object} settings dataTables settings object
5714
+ * @param {int} colIdx column of interest
5715
+ * @returns {string} max string length for each column
5716
+ * @memberof DataTable#oApi
5717
+ */
5718
+ function _fnGetMaxLenString(settings, colIdx)
5719
+ {
5720
+ var s, max = -1, maxIdx = -1;
5721
+
5722
+ for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
5723
+ s = _fnGetCellData(settings, i, colIdx, 'display') + '';
5724
+ s = s.replace(__re_html_remove, '');
5725
+ s = s.replace(/&nbsp;/g, ' ');
5726
+
5727
+ if (s.length > max) {
5728
+ max = s.length;
5729
+ maxIdx = i;
5730
+ }
5731
+ }
5732
+
5733
+ return maxIdx;
5734
+ }
5735
+
5736
+
5737
+ /**
5738
+ * Append a CSS unit (only if required) to a string
5739
+ * @param {string} value to css-ify
5740
+ * @returns {string} value with css unit
5741
+ * @memberof DataTable#oApi
5742
+ */
5743
+ function _fnStringToCss(s)
5744
+ {
5745
+ if (s === null) {
5746
+ return '0px';
5747
+ }
5748
+
5749
+ if (typeof s == 'number') {
5750
+ return s < 0 ?
5751
+ '0px' :
5752
+ s + 'px';
5753
+ }
5754
+
5755
+ // Check it has a unit character already
5756
+ return s.match(/\d$/) ?
5757
+ s + 'px' :
5758
+ s;
5759
+ }
5760
+
5761
+
5762
+
5763
+ function _fnSortFlatten(settings)
5764
+ {
5765
+ var
5766
+ i, iLen, k, kLen,
5767
+ aSort = [],
5768
+ aiOrig = [],
5769
+ aoColumns = settings.aoColumns,
5770
+ aDataSort, iCol, sType, srcCol,
5771
+ fixed = settings.aaSortingFixed,
5772
+ fixedObj = $.isPlainObject(fixed),
5773
+ nestedSort = [],
5774
+ add = function (a) {
5775
+ if (a.length && !$.isArray(a[0])) {
5776
+ // 1D array
5777
+ nestedSort.push(a);
5778
+ } else {
5779
+ // 2D array
5780
+ $.merge(nestedSort, a);
5781
+ }
5782
+ };
5783
+
5784
+ // Build the sort array, with pre-fix and post-fix options if they have been
5785
+ // specified
5786
+ if ($.isArray(fixed)) {
5787
+ add(fixed);
5788
+ }
5789
+
5790
+ if (fixedObj && fixed.pre) {
5791
+ add(fixed.pre);
5792
+ }
5793
+
5794
+ add(settings.aaSorting);
5795
+
5796
+ if (fixedObj && fixed.post) {
5797
+ add(fixed.post);
5798
+ }
5799
+
5800
+ for (i = 0; i < nestedSort.length; i++)
5801
+ {
5802
+ srcCol = nestedSort[i][0];
5803
+ aDataSort = aoColumns[ srcCol ].aDataSort;
5804
+
5805
+ for (k = 0, kLen = aDataSort.length; k < kLen; k++)
5806
+ {
5807
+ iCol = aDataSort[k];
5808
+ sType = aoColumns[ iCol ].sType || 'string';
5809
+
5810
+ if (nestedSort[i]._idx === undefined) {
5811
+ nestedSort[i]._idx = $.inArray(nestedSort[i][1], aoColumns[iCol].asSorting);
5812
+ }
5813
+
5814
+ aSort.push({
5815
+ src: srcCol,
5816
+ col: iCol,
5817
+ dir: nestedSort[i][1],
5818
+ index: nestedSort[i]._idx,
5819
+ type: sType,
5820
+ formatter: DataTable.ext.type.order[ sType + "-pre" ]
5821
+ });
5822
+ }
5823
+ }
5824
+
5825
+ return aSort;
5826
+ }
5827
+
5828
+ /**
5829
+ * Change the order of the table
5830
+ * @param {object} oSettings dataTables settings object
5831
+ * @memberof DataTable#oApi
5832
+ * @todo This really needs split up!
5833
+ */
5834
+ function _fnSort(oSettings)
5835
+ {
5836
+ var
5837
+ i, ien, iLen, j, jLen, k, kLen,
5838
+ sDataType, nTh,
5839
+ aiOrig = [],
5840
+ oExtSort = DataTable.ext.type.order,
5841
+ aoData = oSettings.aoData,
5842
+ aoColumns = oSettings.aoColumns,
5843
+ aDataSort, data, iCol, sType, oSort,
5844
+ formatters = 0,
5845
+ sortCol,
5846
+ displayMaster = oSettings.aiDisplayMaster,
5847
+ aSort;
5848
+
5849
+ // Resolve any column types that are unknown due to addition or invalidation
5850
+ // @todo Can this be moved into a 'data-ready' handler which is called when
5851
+ // data is going to be used in the table?
5852
+ _fnColumnTypes(oSettings);
5853
+
5854
+ aSort = _fnSortFlatten(oSettings);
5855
+
5856
+ for (i = 0, ien = aSort.length; i < ien; i++) {
5857
+ sortCol = aSort[i];
5858
+
5859
+ // Track if we can use the fast sort algorithm
5860
+ if (sortCol.formatter) {
5861
+ formatters++;
5862
+ }
5863
+
5864
+ // Load the data needed for the sort, for each cell
5865
+ _fnSortData(oSettings, sortCol.col);
5866
+ }
5867
+
5868
+ /* No sorting required if server-side or no sorting array */
5869
+ if (_fnDataSource(oSettings) != 'ssp' && aSort.length !== 0)
5870
+ {
5871
+ // Create a value - key array of the current row positions such that we can use their
5872
+ // current position during the sort, if values match, in order to perform stable sorting
5873
+ for (i = 0, iLen = displayMaster.length; i < iLen; i++) {
5874
+ aiOrig[ displayMaster[i] ] = i;
5875
+ }
5876
+
5877
+ /* Do the sort - here we want multi-column sorting based on a given data source (column)
5878
+ * and sorting function (from oSort) in a certain direction. It's reasonably complex to
5879
+ * follow on it's own, but this is what we want (example two column sorting):
5880
+ * fnLocalSorting = function(a,b){
5881
+ * var iTest;
5882
+ * iTest = oSort['string-asc']('data11', 'data12');
5883
+ * if (iTest !== 0)
5884
+ * return iTest;
5885
+ * iTest = oSort['numeric-desc']('data21', 'data22');
5886
+ * if (iTest !== 0)
5887
+ * return iTest;
5888
+ * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
5889
+ * }
5890
+ * Basically we have a test for each sorting column, if the data in that column is equal,
5891
+ * test the next column. If all columns match, then we use a numeric sort on the row
5892
+ * positions in the original data array to provide a stable sort.
5893
+ *
5894
+ * Note - I know it seems excessive to have two sorting methods, but the first is around
5895
+ * 15% faster, so the second is only maintained for backwards compatibility with sorting
5896
+ * methods which do not have a pre-sort formatting function.
5897
+ */
5898
+ if (formatters === aSort.length) {
5899
+ // All sort types have formatting functions
5900
+ displayMaster.sort(function (a, b) {
5901
+ var
5902
+ x, y, k, test, sort,
5903
+ len = aSort.length,
5904
+ dataA = aoData[a]._aSortData,
5905
+ dataB = aoData[b]._aSortData;
5906
+
5907
+ for (k = 0; k < len; k++) {
5908
+ sort = aSort[k];
5909
+
5910
+ x = dataA[ sort.col ];
5911
+ y = dataB[ sort.col ];
5912
+
5913
+ test = x < y ? -1 : x > y ? 1 : 0;
5914
+ if (test !== 0) {
5915
+ return sort.dir === 'asc' ? test : -test;
5916
+ }
5917
+ }
5918
+
5919
+ x = aiOrig[a];
5920
+ y = aiOrig[b];
5921
+ return x < y ? -1 : x > y ? 1 : 0;
5922
+ });
5923
+ } else {
5924
+ // Depreciated - remove in 1.11 (providing a plug-in option)
5925
+ // Not all sort types have formatting methods, so we have to call their sorting
5926
+ // methods.
5927
+ displayMaster.sort(function (a, b) {
5928
+ var
5929
+ x, y, k, l, test, sort, fn,
5930
+ len = aSort.length,
5931
+ dataA = aoData[a]._aSortData,
5932
+ dataB = aoData[b]._aSortData;
5933
+
5934
+ for (k = 0; k < len; k++) {
5935
+ sort = aSort[k];
5936
+
5937
+ x = dataA[ sort.col ];
5938
+ y = dataB[ sort.col ];
5939
+
5940
+ fn = oExtSort[ sort.type + "-" + sort.dir ] || oExtSort[ "string-" + sort.dir ];
5941
+ test = fn(x, y);
5942
+ if (test !== 0) {
5943
+ return test;
5944
+ }
5945
+ }
5946
+
5947
+ x = aiOrig[a];
5948
+ y = aiOrig[b];
5949
+ return x < y ? -1 : x > y ? 1 : 0;
5950
+ });
5951
+ }
5952
+ }
5953
+
5954
+ /* Tell the draw function that we have sorted the data */
5955
+ oSettings.bSorted = true;
5956
+ }
5957
+
5958
+
5959
+ function _fnSortAria(settings)
5960
+ {
5961
+ var label;
5962
+ var nextSort;
5963
+ var columns = settings.aoColumns;
5964
+ var aSort = _fnSortFlatten(settings);
5965
+ var oAria = settings.oLanguage.oAria;
5966
+
5967
+ // ARIA attributes - need to loop all columns, to update all (removing old
5968
+ // attributes as needed)
5969
+ for (var i = 0, iLen = columns.length; i < iLen; i++)
5970
+ {
5971
+ var col = columns[i];
5972
+ var asSorting = col.asSorting;
5973
+ var sTitle = col.sTitle.replace(/<.*?>/g, "");
5974
+ var th = col.nTh;
5975
+
5976
+ // IE7 is throwing an error when setting these properties with jQuery's
5977
+ // attr() and removeAttr() methods...
5978
+ th.removeAttribute('aria-sort');
5979
+
5980
+ /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
5981
+ if (col.bSortable) {
5982
+ if (aSort.length > 0 && aSort[0].col == i) {
5983
+ th.setAttribute('aria-sort', aSort[0].dir == "asc" ? "ascending" : "descending");
5984
+ nextSort = asSorting[ aSort[0].index + 1 ] || asSorting[0];
5985
+ } else {
5986
+ nextSort = asSorting[0];
5987
+ }
5988
+
5989
+ label = sTitle + (nextSort === "asc" ?
5990
+ oAria.sSortAscending :
5991
+ oAria.sSortDescending
5992
+ );
5993
+ } else {
5994
+ label = sTitle;
5995
+ }
5996
+
5997
+ th.setAttribute('aria-label', label);
5998
+ }
5999
+ }
6000
+
6001
+
6002
+ /**
6003
+ * Function to run on user sort request
6004
+ * @param {object} settings dataTables settings object
6005
+ * @param {node} attachTo node to attach the handler to
6006
+ * @param {int} colIdx column sorting index
6007
+ * @param {boolean} [append=false] Append the requested sort to the existing
6008
+ * sort if true (i.e. multi-column sort)
6009
+ * @param {function} [callback] callback function
6010
+ * @memberof DataTable#oApi
6011
+ */
6012
+ function _fnSortListener(settings, colIdx, append, callback)
6013
+ {
6014
+ var col = settings.aoColumns[ colIdx ];
6015
+ var sorting = settings.aaSorting;
6016
+ var asSorting = col.asSorting;
6017
+ var nextSortIdx;
6018
+ var next = function (a, overflow) {
6019
+ var idx = a._idx;
6020
+ if (idx === undefined) {
6021
+ idx = $.inArray(a[1], asSorting);
6022
+ }
6023
+
6024
+ return idx + 1 < asSorting.length ?
6025
+ idx + 1 :
6026
+ overflow ?
6027
+ null :
6028
+ 0;
6029
+ };
6030
+
6031
+ // Convert to 2D array if needed
6032
+ if (typeof sorting[0] === 'number') {
6033
+ sorting = settings.aaSorting = [sorting];
6034
+ }
6035
+
6036
+ // If appending the sort then we are multi-column sorting
6037
+ if (append && settings.oFeatures.bSortMulti) {
6038
+ // Are we already doing some kind of sort on this column?
6039
+ var sortIdx = $.inArray(colIdx, _pluck(sorting, '0'));
6040
+
6041
+ if (sortIdx !== -1) {
6042
+ // Yes, modify the sort
6043
+ nextSortIdx = next(sorting[sortIdx], true);
6044
+
6045
+ if (nextSortIdx === null && sorting.length === 1) {
6046
+ nextSortIdx = 0; // can't remove sorting completely
6047
+ }
6048
+
6049
+ if (nextSortIdx === null) {
6050
+ sorting.splice(sortIdx, 1);
6051
+ } else {
6052
+ sorting[sortIdx][1] = asSorting[ nextSortIdx ];
6053
+ sorting[sortIdx]._idx = nextSortIdx;
6054
+ }
6055
+ } else {
6056
+ // No sort on this column yet
6057
+ sorting.push([colIdx, asSorting[0], 0]);
6058
+ sorting[sorting.length - 1]._idx = 0;
6059
+ }
6060
+ } else if (sorting.length && sorting[0][0] == colIdx) {
6061
+ // Single column - already sorting on this column, modify the sort
6062
+ nextSortIdx = next(sorting[0]);
6063
+
6064
+ sorting.length = 1;
6065
+ sorting[0][1] = asSorting[ nextSortIdx ];
6066
+ sorting[0]._idx = nextSortIdx;
6067
+ } else {
6068
+ // Single column - sort only on this column
6069
+ sorting.length = 0;
6070
+ sorting.push([colIdx, asSorting[0]]);
6071
+ sorting[0]._idx = 0;
6072
+ }
6073
+
6074
+ // Run the sort by calling a full redraw
6075
+ _fnReDraw(settings);
6076
+
6077
+ // callback used for async user interaction
6078
+ if (typeof callback == 'function') {
6079
+ callback(settings);
6080
+ }
6081
+ }
6082
+
6083
+
6084
+ /**
6085
+ * Attach a sort handler (click) to a node
6086
+ * @param {object} settings dataTables settings object
6087
+ * @param {node} attachTo node to attach the handler to
6088
+ * @param {int} colIdx column sorting index
6089
+ * @param {function} [callback] callback function
6090
+ * @memberof DataTable#oApi
6091
+ */
6092
+ function _fnSortAttachListener(settings, attachTo, colIdx, callback)
6093
+ {
6094
+ var col = settings.aoColumns[ colIdx ];
6095
+
6096
+ _fnBindAction(attachTo, {}, function (e) {
6097
+ /* If the column is not sortable - don't to anything */
6098
+ if (col.bSortable === false) {
6099
+ return;
6100
+ }
6101
+
6102
+ // If processing is enabled use a timeout to allow the processing
6103
+ // display to be shown - otherwise to it synchronously
6104
+ if (settings.oFeatures.bProcessing) {
6105
+ _fnProcessingDisplay(settings, true);
6106
+
6107
+ setTimeout(function () {
6108
+ _fnSortListener(settings, colIdx, e.shiftKey, callback);
6109
+
6110
+ // In server-side processing, the draw callback will remove the
6111
+ // processing display
6112
+ if (_fnDataSource(settings) !== 'ssp') {
6113
+ _fnProcessingDisplay(settings, false);
6114
+ }
6115
+ }, 0);
6116
+ } else {
6117
+ _fnSortListener(settings, colIdx, e.shiftKey, callback);
6118
+ }
6119
+ });
6120
+ }
6121
+
6122
+
6123
+ /**
6124
+ * Set the sorting classes on table's body, Note: it is safe to call this function
6125
+ * when bSort and bSortClasses are false
6126
+ * @param {object} oSettings dataTables settings object
6127
+ * @memberof DataTable#oApi
6128
+ */
6129
+ function _fnSortingClasses(settings)
6130
+ {
6131
+ var oldSort = settings.aLastSort;
6132
+ var sortClass = settings.oClasses.sSortColumn;
6133
+ var sort = _fnSortFlatten(settings);
6134
+ var features = settings.oFeatures;
6135
+ var i, ien, colIdx;
6136
+
6137
+ if (features.bSort && features.bSortClasses) {
6138
+ // Remove old sorting classes
6139
+ for (i = 0, ien = oldSort.length; i < ien; i++) {
6140
+ colIdx = oldSort[i].src;
6141
+
6142
+ // Remove column sorting
6143
+ $(_pluck(settings.aoData, 'anCells', colIdx))
6144
+ .removeClass(sortClass + (i < 2 ? i + 1 : 3));
6145
+ }
6146
+
6147
+ // Add new column sorting
6148
+ for (i = 0, ien = sort.length; i < ien; i++) {
6149
+ colIdx = sort[i].src;
6150
+
6151
+ $(_pluck(settings.aoData, 'anCells', colIdx))
6152
+ .addClass(sortClass + (i < 2 ? i + 1 : 3));
6153
+ }
6154
+ }
6155
+
6156
+ settings.aLastSort = sort;
6157
+ }
6158
+
6159
+
6160
+ // Get the data to sort a column, be it from cache, fresh (populating the
6161
+ // cache), or from a sort formatter
6162
+ function _fnSortData(settings, idx)
6163
+ {
6164
+ // Custom sorting function - provided by the sort data type
6165
+ var column = settings.aoColumns[ idx ];
6166
+ var customSort = DataTable.ext.order[ column.sSortDataType ];
6167
+ var customData;
6168
+
6169
+ if (customSort) {
6170
+ customData = customSort.call(settings.oInstance, settings, idx,
6171
+ _fnColumnIndexToVisible(settings, idx)
6172
+ );
6173
+ }
6174
+
6175
+ // Use / populate cache
6176
+ var row, cellData;
6177
+ var formatter = DataTable.ext.type.order[ column.sType + "-pre" ];
6178
+
6179
+ for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
6180
+ row = settings.aoData[i];
6181
+
6182
+ if (!row._aSortData) {
6183
+ row._aSortData = [];
6184
+ }
6185
+
6186
+ if (!row._aSortData[idx] || customSort) {
6187
+ cellData = customSort ?
6188
+ customData[i] : // If there was a custom sort function, use data from there
6189
+ _fnGetCellData(settings, i, idx, 'sort');
6190
+
6191
+ row._aSortData[ idx ] = formatter ?
6192
+ formatter(cellData) :
6193
+ cellData;
6194
+ }
6195
+ }
6196
+ }
6197
+
6198
+
6199
+
6200
+ /**
6201
+ * Save the state of a table
6202
+ * @param {object} oSettings dataTables settings object
6203
+ * @memberof DataTable#oApi
6204
+ */
6205
+ function _fnSaveState(settings)
6206
+ {
6207
+ if (!settings.oFeatures.bStateSave || settings.bDestroying)
6208
+ {
6209
+ return;
6210
+ }
6211
+
6212
+ /* Store the interesting variables */
6213
+ var state = {
6214
+ time: +new Date(),
6215
+ start: settings._iDisplayStart,
6216
+ length: settings._iDisplayLength,
6217
+ order: $.extend(true, [], settings.aaSorting),
6218
+ search: _fnSearchToCamel(settings.oPreviousSearch),
6219
+ columns: $.map(settings.aoColumns, function (col, i) {
6220
+ return {
6221
+ visible: col.bVisible,
6222
+ search: _fnSearchToCamel(settings.aoPreSearchCols[i])
6223
+ };
6224
+ })
6225
+ };
6226
+
6227
+ _fnCallbackFire(settings, "aoStateSaveParams", 'stateSaveParams', [settings, state]);
6228
+
6229
+ settings.oSavedState = state;
6230
+ settings.fnStateSaveCallback.call(settings.oInstance, settings, state);
6231
+ }
6232
+
6233
+
6234
+ /**
6235
+ * Attempt to load a saved table state
6236
+ * @param {object} oSettings dataTables settings object
6237
+ * @param {object} oInit DataTables init object so we can override settings
6238
+ * @param {function} callback Callback to execute when the state has been loaded
6239
+ * @memberof DataTable#oApi
6240
+ */
6241
+ function _fnLoadState(settings, oInit, callback)
6242
+ {
6243
+ var i, ien;
6244
+ var columns = settings.aoColumns;
6245
+ var loaded = function (s) {
6246
+ if (!s || !s.time) {
6247
+ callback();
6248
+ return;
6249
+ }
6250
+
6251
+ // Allow custom and plug-in manipulation functions to alter the saved data set and
6252
+ // cancelling of loading by returning false
6253
+ var abStateLoad = _fnCallbackFire(settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s]);
6254
+ if ($.inArray(false, abStateLoad) !== -1) {
6255
+ callback();
6256
+ return;
6257
+ }
6258
+
6259
+ // Reject old data
6260
+ var duration = settings.iStateDuration;
6261
+ if (duration > 0 && s.time < +new Date() - (duration * 1000)) {
6262
+ callback();
6263
+ return;
6264
+ }
6265
+
6266
+ // Number of columns have changed - all bets are off, no restore of settings
6267
+ if (s.columns && columns.length !== s.columns.length) {
6268
+ callback();
6269
+ return;
6270
+ }
6271
+
6272
+ // Store the saved state so it might be accessed at any time
6273
+ settings.oLoadedState = $.extend(true, {}, s);
6274
+
6275
+ // Restore key features - todo - for 1.11 this needs to be done by
6276
+ // subscribed events
6277
+ if (s.start !== undefined) {
6278
+ settings._iDisplayStart = s.start;
6279
+ settings.iInitDisplayStart = s.start;
6280
+ }
6281
+ if (s.length !== undefined) {
6282
+ settings._iDisplayLength = s.length;
6283
+ }
6284
+
6285
+ // Order
6286
+ if (s.order !== undefined) {
6287
+ settings.aaSorting = [];
6288
+ $.each(s.order, function (i, col) {
6289
+ settings.aaSorting.push(col[0] >= columns.length ?
6290
+ [0, col[1]] :
6291
+ col
6292
+ );
6293
+ });
6294
+ }
6295
+
6296
+ // Search
6297
+ if (s.search !== undefined) {
6298
+ $.extend(settings.oPreviousSearch, _fnSearchToHung(s.search));
6299
+ }
6300
+
6301
+ // Columns
6302
+ //
6303
+ if (s.columns) {
6304
+ for (i = 0, ien = s.columns.length; i < ien; i++) {
6305
+ var col = s.columns[i];
6306
+
6307
+ // Visibility
6308
+ if (col.visible !== undefined) {
6309
+ columns[i].bVisible = col.visible;
6310
+ }
6311
+
6312
+ // Search
6313
+ if (col.search !== undefined) {
6314
+ $.extend(settings.aoPreSearchCols[i], _fnSearchToHung(col.search));
6315
+ }
6316
+ }
6317
+ }
6318
+
6319
+ _fnCallbackFire(settings, 'aoStateLoaded', 'stateLoaded', [settings, s]);
6320
+ callback();
6321
+ }
6322
+
6323
+ if (!settings.oFeatures.bStateSave) {
6324
+ callback();
6325
+ return;
6326
+ }
6327
+
6328
+ var state = settings.fnStateLoadCallback.call(settings.oInstance, settings, loaded);
6329
+
6330
+ if (state !== undefined) {
6331
+ loaded(state);
6332
+ }
6333
+ // otherwise, wait for the loaded callback to be executed
6334
+ }
6335
+
6336
+
6337
+ /**
6338
+ * Return the settings object for a particular table
6339
+ * @param {node} table table we are using as a dataTable
6340
+ * @returns {object} Settings object - or null if not found
6341
+ * @memberof DataTable#oApi
6342
+ */
6343
+ function _fnSettingsFromNode(table)
6344
+ {
6345
+ var settings = DataTable.settings;
6346
+ var idx = $.inArray(table, _pluck(settings, 'nTable'));
6347
+
6348
+ return idx !== -1 ?
6349
+ settings[ idx ] :
6350
+ null;
6351
+ }
6352
+
6353
+
6354
+ /**
6355
+ * Log an error message
6356
+ * @param {object} settings dataTables settings object
6357
+ * @param {int} level log error messages, or display them to the user
6358
+ * @param {string} msg error message
6359
+ * @param {int} tn Technical note id to get more information about the error.
6360
+ * @memberof DataTable#oApi
6361
+ */
6362
+ function _fnLog(settings, level, msg, tn)
6363
+ {
6364
+ msg = 'DataTables warning: ' +
6365
+ (settings ? 'table id=' + settings.sTableId + ' - ' : '') + msg;
6366
+
6367
+ if (tn) {
6368
+ msg += '. For more information about this error, please see ' +
6369
+ 'http://datatables.net/tn/' + tn;
6370
+ }
6371
+
6372
+ if (!level) {
6373
+ // Backwards compatibility pre 1.10
6374
+ var ext = DataTable.ext;
6375
+ var type = ext.sErrMode || ext.errMode;
6376
+
6377
+ if (settings) {
6378
+ _fnCallbackFire(settings, null, 'error', [settings, tn, msg]);
6379
+ }
6380
+
6381
+ if (type == 'alert') {
6382
+ alert(msg);
6383
+ } else if (type == 'throw') {
6384
+ throw new Error(msg);
6385
+ } else if (typeof type == 'function') {
6386
+ type(settings, tn, msg);
6387
+ }
6388
+ } else if (window.console && console.log) {
6389
+ console.log(msg);
6390
+ }
6391
+ }
6392
+
6393
+
6394
+ /**
6395
+ * See if a property is defined on one object, if so assign it to the other object
6396
+ * @param {object} ret target object
6397
+ * @param {object} src source object
6398
+ * @param {string} name property
6399
+ * @param {string} [mappedName] name to map too - optional, name used if not given
6400
+ * @memberof DataTable#oApi
6401
+ */
6402
+ function _fnMap(ret, src, name, mappedName)
6403
+ {
6404
+ if ($.isArray(name)) {
6405
+ $.each(name, function (i, val) {
6406
+ if ($.isArray(val)) {
6407
+ _fnMap(ret, src, val[0], val[1]);
6408
+ } else {
6409
+ _fnMap(ret, src, val);
6410
+ }
6411
+ });
6412
+
6413
+ return;
6414
+ }
6415
+
6416
+ if (mappedName === undefined) {
6417
+ mappedName = name;
6418
+ }
6419
+
6420
+ if (src[name] !== undefined) {
6421
+ ret[mappedName] = src[name];
6422
+ }
6423
+ }
6424
+
6425
+
6426
+ /**
6427
+ * Extend objects - very similar to jQuery.extend, but deep copy objects, and
6428
+ * shallow copy arrays. The reason we need to do this, is that we don't want to
6429
+ * deep copy array init values (such as aaSorting) since the dev wouldn't be
6430
+ * able to override them, but we do want to deep copy arrays.
6431
+ * @param {object} out Object to extend
6432
+ * @param {object} extender Object from which the properties will be applied to
6433
+ * out
6434
+ * @param {boolean} breakRefs If true, then arrays will be sliced to take an
6435
+ * independent copy with the exception of the `data` or `aaData` parameters
6436
+ * if they are present. This is so you can pass in a collection to
6437
+ * DataTables and have that used as your data source without breaking the
6438
+ * references
6439
+ * @returns {object} out Reference, just for convenience - out === the return.
6440
+ * @memberof DataTable#oApi
6441
+ * @todo This doesn't take account of arrays inside the deep copied objects.
6442
+ */
6443
+ function _fnExtend(out, extender, breakRefs)
6444
+ {
6445
+ var val;
6446
+
6447
+ for (var prop in extender) {
6448
+ if (extender.hasOwnProperty(prop)) {
6449
+ val = extender[prop];
6450
+
6451
+ if ($.isPlainObject(val)) {
6452
+ if (!$.isPlainObject(out[prop])) {
6453
+ out[prop] = {};
6454
+ }
6455
+ $.extend(true, out[prop], val);
6456
+ } else if (breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val)) {
6457
+ out[prop] = val.slice();
6458
+ } else {
6459
+ out[prop] = val;
6460
+ }
6461
+ }
6462
+ }
6463
+
6464
+ return out;
6465
+ }
6466
+
6467
+
6468
+ /**
6469
+ * Bind an event handers to allow a click or return key to activate the callback.
6470
+ * This is good for accessibility since a return on the keyboard will have the
6471
+ * same effect as a click, if the element has focus.
6472
+ * @param {element} n Element to bind the action to
6473
+ * @param {object} oData Data object to pass to the triggered function
6474
+ * @param {function} fn Callback function for when the event is triggered
6475
+ * @memberof DataTable#oApi
6476
+ */
6477
+ function _fnBindAction(n, oData, fn)
6478
+ {
6479
+ $(n)
6480
+ .on('click.DT', oData, function (e) {
6481
+ n.blur(); // Remove focus outline for mouse users
6482
+ fn(e);
6483
+ })
6484
+ .on('keypress.DT', oData, function (e) {
6485
+ if (e.which === 13) {
6486
+ e.preventDefault();
6487
+ fn(e);
6488
+ }
6489
+ })
6490
+ .on('selectstart.DT', function () {
6491
+ /* Take the brutal approach to cancelling text selection */
6492
+ return false;
6493
+ });
6494
+ }
6495
+
6496
+
6497
+ /**
6498
+ * Register a callback function. Easily allows a callback function to be added to
6499
+ * an array store of callback functions that can then all be called together.
6500
+ * @param {object} oSettings dataTables settings object
6501
+ * @param {string} sStore Name of the array storage for the callbacks in oSettings
6502
+ * @param {function} fn Function to be called back
6503
+ * @param {string} sName Identifying name for the callback (i.e. a label)
6504
+ * @memberof DataTable#oApi
6505
+ */
6506
+ function _fnCallbackReg(oSettings, sStore, fn, sName)
6507
+ {
6508
+ if (fn)
6509
+ {
6510
+ oSettings[sStore].push({
6511
+ "fn": fn,
6512
+ "sName": sName
6513
+ });
6514
+ }
6515
+ }
6516
+
6517
+
6518
+ /**
6519
+ * Fire callback functions and trigger events. Note that the loop over the
6520
+ * callback array store is done backwards! Further note that you do not want to
6521
+ * fire off triggers in time sensitive applications (for example cell creation)
6522
+ * as its slow.
6523
+ * @param {object} settings dataTables settings object
6524
+ * @param {string} callbackArr Name of the array storage for the callbacks in
6525
+ * oSettings
6526
+ * @param {string} eventName Name of the jQuery custom event to trigger. If
6527
+ * null no trigger is fired
6528
+ * @param {array} args Array of arguments to pass to the callback function /
6529
+ * trigger
6530
+ * @memberof DataTable#oApi
6531
+ */
6532
+ function _fnCallbackFire(settings, callbackArr, eventName, args)
6533
+ {
6534
+ var ret = [];
6535
+
6536
+ if (callbackArr) {
6537
+ ret = $.map(settings[callbackArr].slice().reverse(), function (val, i) {
6538
+ return val.fn.apply(settings.oInstance, args);
6539
+ });
6540
+ }
6541
+
6542
+ if (eventName !== null) {
6543
+ var e = $.Event(eventName + '.dt');
6544
+
6545
+ $(settings.nTable).trigger(e, args);
6546
+
6547
+ ret.push(e.result);
6548
+ }
6549
+
6550
+ return ret;
6551
+ }
6552
+
6553
+
6554
+ function _fnLengthOverflow(settings)
6555
+ {
6556
+ var
6557
+ start = settings._iDisplayStart,
6558
+ end = settings.fnDisplayEnd(),
6559
+ len = settings._iDisplayLength;
6560
+
6561
+ /* If we have space to show extra rows (backing up from the end point - then do so */
6562
+ if (start >= end)
6563
+ {
6564
+ start = end - len;
6565
+ }
6566
+
6567
+ // Keep the start record on the current page
6568
+ start -= (start % len);
6569
+
6570
+ if (len === -1 || start < 0)
6571
+ {
6572
+ start = 0;
6573
+ }
6574
+
6575
+ settings._iDisplayStart = start;
6576
+ }
6577
+
6578
+
6579
+ function _fnRenderer(settings, type)
6580
+ {
6581
+ var renderer = settings.renderer;
6582
+ var host = DataTable.ext.renderer[type];
6583
+
6584
+ if ($.isPlainObject(renderer) && renderer[type]) {
6585
+ // Specific renderer for this type. If available use it, otherwise use
6586
+ // the default.
6587
+ return host[renderer[type]] || host._;
6588
+ } else if (typeof renderer === 'string') {
6589
+ // Common renderer - if there is one available for this type use it,
6590
+ // otherwise use the default
6591
+ return host[renderer] || host._;
6592
+ }
6593
+
6594
+ // Use the default
6595
+ return host._;
6596
+ }
6597
+
6598
+
6599
+ /**
6600
+ * Detect the data source being used for the table. Used to simplify the code
6601
+ * a little (ajax) and to make it compress a little smaller.
6602
+ *
6603
+ * @param {object} settings dataTables settings object
6604
+ * @returns {string} Data source
6605
+ * @memberof DataTable#oApi
6606
+ */
6607
+ function _fnDataSource(settings)
6608
+ {
6609
+ if (settings.oFeatures.bServerSide) {
6610
+ return 'ssp';
6611
+ } else if (settings.ajax || settings.sAjaxSource) {
6612
+ return 'ajax';
6613
+ }
6614
+ return 'dom';
6615
+ }
6616
+
6617
+
6618
+
6619
+
6620
+ /**
6621
+ * Computed structure of the DataTables API, defined by the options passed to
6622
+ * `DataTable.Api.register()` when building the API.
6623
+ *
6624
+ * The structure is built in order to speed creation and extension of the Api
6625
+ * objects since the extensions are effectively pre-parsed.
6626
+ *
6627
+ * The array is an array of objects with the following structure, where this
6628
+ * base array represents the Api prototype base:
6629
+ *
6630
+ * [
6631
+ * {
6632
+ * name: 'data' -- string - Property name
6633
+ * val: function () {}, -- function - Api method (or undefined if just an object
6634
+ * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
6635
+ * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
6636
+ * },
6637
+ * {
6638
+ * name: 'row'
6639
+ * val: {},
6640
+ * methodExt: [ ... ],
6641
+ * propExt: [
6642
+ * {
6643
+ * name: 'data'
6644
+ * val: function () {},
6645
+ * methodExt: [ ... ],
6646
+ * propExt: [ ... ]
6647
+ * },
6648
+ * ...
6649
+ * ]
6650
+ * }
6651
+ * ]
6652
+ *
6653
+ * @type {Array}
6654
+ * @ignore
6655
+ */
6656
+ var __apiStruct = [];
6657
+
6658
+
6659
+ /**
6660
+ * `Array.prototype` reference.
6661
+ *
6662
+ * @type object
6663
+ * @ignore
6664
+ */
6665
+ var __arrayProto = Array.prototype;
6666
+
6667
+
6668
+ /**
6669
+ * Abstraction for `context` parameter of the `Api` constructor to allow it to
6670
+ * take several different forms for ease of use.
6671
+ *
6672
+ * Each of the input parameter types will be converted to a DataTables settings
6673
+ * object where possible.
6674
+ *
6675
+ * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
6676
+ * of:
6677
+ *
6678
+ * * `string` - jQuery selector. Any DataTables' matching the given selector
6679
+ * with be found and used.
6680
+ * * `node` - `TABLE` node which has already been formed into a DataTable.
6681
+ * * `jQuery` - A jQuery object of `TABLE` nodes.
6682
+ * * `object` - DataTables settings object
6683
+ * * `DataTables.Api` - API instance
6684
+ * @return {array|null} Matching DataTables settings objects. `null` or
6685
+ * `undefined` is returned if no matching DataTable is found.
6686
+ * @ignore
6687
+ */
6688
+ var _toSettings = function (mixed)
6689
+ {
6690
+ var idx, jq;
6691
+ var settings = DataTable.settings;
6692
+ var tables = $.map(settings, function (el, i) {
6693
+ return el.nTable;
6694
+ });
6695
+
6696
+ if (!mixed) {
6697
+ return [];
6698
+ } else if (mixed.nTable && mixed.oApi) {
6699
+ // DataTables settings object
6700
+ return [mixed];
6701
+ } else if (mixed.nodeName && mixed.nodeName.toLowerCase() === 'table') {
6702
+ // Table node
6703
+ idx = $.inArray(mixed, tables);
6704
+ return idx !== -1 ? [settings[idx]] : null;
6705
+ } else if (mixed && typeof mixed.settings === 'function') {
6706
+ return mixed.settings().toArray();
6707
+ } else if (typeof mixed === 'string') {
6708
+ // jQuery selector
6709
+ jq = $(mixed);
6710
+ } else if (mixed instanceof $) {
6711
+ // jQuery object (also DataTables instance)
6712
+ jq = mixed;
6713
+ }
6714
+
6715
+ if (jq) {
6716
+ return jq.map(function (i) {
6717
+ idx = $.inArray(this, tables);
6718
+ return idx !== -1 ? settings[idx] : null;
6719
+ }).toArray();
6720
+ }
6721
+ };
6722
+
6723
+
6724
+ /**
6725
+ * DataTables API class - used to control and interface with one or more
6726
+ * DataTables enhanced tables.
6727
+ *
6728
+ * The API class is heavily based on jQuery, presenting a chainable interface
6729
+ * that you can use to interact with tables. Each instance of the API class has
6730
+ * a "context" - i.e. the tables that it will operate on. This could be a single
6731
+ * table, all tables on a page or a sub-set thereof.
6732
+ *
6733
+ * Additionally the API is designed to allow you to easily work with the data in
6734
+ * the tables, retrieving and manipulating it as required. This is done by
6735
+ * presenting the API class as an array like interface. The contents of the
6736
+ * array depend upon the actions requested by each method (for example
6737
+ * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6738
+ * return an array of objects or arrays depending upon your table's
6739
+ * configuration). The API object has a number of array like methods (`push`,
6740
+ * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6741
+ * `unique` etc) to assist your working with the data held in a table.
6742
+ *
6743
+ * Most methods (those which return an Api instance) are chainable, which means
6744
+ * the return from a method call also has all of the methods available that the
6745
+ * top level object had. For example, these two calls are equivalent:
6746
+ *
6747
+ * // Not chained
6748
+ * api.row.add( {...} );
6749
+ * api.draw();
6750
+ *
6751
+ * // Chained
6752
+ * api.row.add( {...} ).draw();
6753
+ *
6754
+ * @class DataTable.Api
6755
+ * @param {array|object|string|jQuery} context DataTable identifier. This is
6756
+ * used to define which DataTables enhanced tables this API will operate on.
6757
+ * Can be one of:
6758
+ *
6759
+ * * `string` - jQuery selector. Any DataTables' matching the given selector
6760
+ * with be found and used.
6761
+ * * `node` - `TABLE` node which has already been formed into a DataTable.
6762
+ * * `jQuery` - A jQuery object of `TABLE` nodes.
6763
+ * * `object` - DataTables settings object
6764
+ * @param {array} [data] Data to initialise the Api instance with.
6765
+ *
6766
+ * @example
6767
+ * // Direct initialisation during DataTables construction
6768
+ * var api = $('#example').DataTable();
6769
+ *
6770
+ * @example
6771
+ * // Initialisation using a DataTables jQuery object
6772
+ * var api = $('#example').dataTable().api();
6773
+ *
6774
+ * @example
6775
+ * // Initialisation as a constructor
6776
+ * var api = new $.fn.DataTable.Api( 'table.dataTable' );
6777
+ */
6778
+ _Api = function (context, data)
6779
+ {
6780
+ if (!(this instanceof _Api)) {
6781
+ return new _Api(context, data);
6782
+ }
6783
+
6784
+ var settings = [];
6785
+ var ctxSettings = function (o) {
6786
+ var a = _toSettings(o);
6787
+ if (a) {
6788
+ settings = settings.concat(a);
6789
+ }
6790
+ };
6791
+
6792
+ if ($.isArray(context)) {
6793
+ for (var i = 0, ien = context.length; i < ien; i++) {
6794
+ ctxSettings(context[i]);
6795
+ }
6796
+ } else {
6797
+ ctxSettings(context);
6798
+ }
6799
+
6800
+ // Remove duplicates
6801
+ this.context = _unique(settings);
6802
+
6803
+ // Initial data
6804
+ if (data) {
6805
+ $.merge(this, data);
6806
+ }
6807
+
6808
+ // selector
6809
+ this.selector = {
6810
+ rows: null,
6811
+ cols: null,
6812
+ opts: null
6813
+ };
6814
+
6815
+ _Api.extend(this, this, __apiStruct);
6816
+ };
6817
+
6818
+ DataTable.Api = _Api;
6819
+
6820
+ // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6821
+ // isPlainObject.
6822
+ $.extend(_Api.prototype, {
6823
+ any: function ()
6824
+ {
6825
+ return this.count() !== 0;
6826
+ },
6827
+
6828
+ concat: __arrayProto.concat,
6829
+
6830
+ context: [], // array of table settings objects
6831
+
6832
+
6833
+ count: function ()
6834
+ {
6835
+ return this.flatten().length;
6836
+ },
6837
+
6838
+ each: function (fn)
6839
+ {
6840
+ for (var i = 0, ien = this.length; i < ien; i++) {
6841
+ fn.call(this, this[i], i, this);
6842
+ }
6843
+
6844
+ return this;
6845
+ },
6846
+
6847
+ eq: function (idx)
6848
+ {
6849
+ var ctx = this.context;
6850
+
6851
+ return ctx.length > idx ?
6852
+ new _Api(ctx[idx], this[idx]) :
6853
+ null;
6854
+ },
6855
+
6856
+ filter: function (fn)
6857
+ {
6858
+ var a = [];
6859
+
6860
+ if (__arrayProto.filter) {
6861
+ a = __arrayProto.filter.call(this, fn, this);
6862
+ } else {
6863
+ // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6864
+ for (var i = 0, ien = this.length; i < ien; i++) {
6865
+ if (fn.call(this, this[i], i, this)) {
6866
+ a.push(this[i]);
6867
+ }
6868
+ }
6869
+ }
6870
+
6871
+ return new _Api(this.context, a);
6872
+ },
6873
+
6874
+ flatten: function ()
6875
+ {
6876
+ var a = [];
6877
+ return new _Api(this.context, a.concat.apply(a, this.toArray()));
6878
+ },
6879
+
6880
+ join: __arrayProto.join,
6881
+
6882
+ indexOf: __arrayProto.indexOf || function (obj, start)
6883
+ {
6884
+ for (var i = (start || 0), ien = this.length; i < ien; i++) {
6885
+ if (this[i] === obj) {
6886
+ return i;
6887
+ }
6888
+ }
6889
+ return -1;
6890
+ },
6891
+
6892
+ iterator: function (flatten, type, fn, alwaysNew) {
6893
+ var
6894
+ a = [], ret,
6895
+ i, ien, j, jen,
6896
+ context = this.context,
6897
+ rows, items, item,
6898
+ selector = this.selector;
6899
+
6900
+ // Argument shifting
6901
+ if (typeof flatten === 'string') {
6902
+ alwaysNew = fn;
6903
+ fn = type;
6904
+ type = flatten;
6905
+ flatten = false;
6906
+ }
6907
+
6908
+ for (i = 0, ien = context.length; i < ien; i++) {
6909
+ var apiInst = new _Api(context[i]);
6910
+
6911
+ if (type === 'table') {
6912
+ ret = fn.call(apiInst, context[i], i);
6913
+
6914
+ if (ret !== undefined) {
6915
+ a.push(ret);
6916
+ }
6917
+ } else if (type === 'columns' || type === 'rows') {
6918
+ // this has same length as context - one entry for each table
6919
+ ret = fn.call(apiInst, context[i], this[i], i);
6920
+
6921
+ if (ret !== undefined) {
6922
+ a.push(ret);
6923
+ }
6924
+ } else if (type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell') {
6925
+ // columns and rows share the same structure.
6926
+ // 'this' is an array of column indexes for each context
6927
+ items = this[i];
6928
+
6929
+ if (type === 'column-rows') {
6930
+ rows = _selector_row_indexes(context[i], selector.opts);
6931
+ }
6932
+
6933
+ for (j = 0, jen = items.length; j < jen; j++) {
6934
+ item = items[j];
6935
+
6936
+ if (type === 'cell') {
6937
+ ret = fn.call(apiInst, context[i], item.row, item.column, i, j);
6938
+ } else {
6939
+ ret = fn.call(apiInst, context[i], item, i, j, rows);
6940
+ }
6941
+
6942
+ if (ret !== undefined) {
6943
+ a.push(ret);
6944
+ }
6945
+ }
6946
+ }
6947
+ }
6948
+
6949
+ if (a.length || alwaysNew) {
6950
+ var api = new _Api(context, flatten ? a.concat.apply([], a) : a);
6951
+ var apiSelector = api.selector;
6952
+ apiSelector.rows = selector.rows;
6953
+ apiSelector.cols = selector.cols;
6954
+ apiSelector.opts = selector.opts;
6955
+ return api;
6956
+ }
6957
+ return this;
6958
+ },
6959
+
6960
+ lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
6961
+ {
6962
+ // Bit cheeky...
6963
+ return this.indexOf.apply(this.toArray.reverse(), arguments);
6964
+ },
6965
+
6966
+ length: 0,
6967
+
6968
+ map: function (fn)
6969
+ {
6970
+ var a = [];
6971
+
6972
+ if (__arrayProto.map) {
6973
+ a = __arrayProto.map.call(this, fn, this);
6974
+ } else {
6975
+ // Compatibility for browsers without EMCA-252-5 (JS 1.6)
6976
+ for (var i = 0, ien = this.length; i < ien; i++) {
6977
+ a.push(fn.call(this, this[i], i));
6978
+ }
6979
+ }
6980
+
6981
+ return new _Api(this.context, a);
6982
+ },
6983
+
6984
+ pluck: function (prop)
6985
+ {
6986
+ return this.map(function (el) {
6987
+ return el[ prop ];
6988
+ });
6989
+ },
6990
+
6991
+ pop: __arrayProto.pop,
6992
+
6993
+ push: __arrayProto.push,
6994
+
6995
+ // Does not return an API instance
6996
+ reduce: __arrayProto.reduce || function (fn, init)
6997
+ {
6998
+ return _fnReduce(this, fn, init, 0, this.length, 1);
6999
+ },
7000
+
7001
+ reduceRight: __arrayProto.reduceRight || function (fn, init)
7002
+ {
7003
+ return _fnReduce(this, fn, init, this.length - 1, -1, -1);
7004
+ },
7005
+
7006
+ reverse: __arrayProto.reverse,
7007
+
7008
+ // Object with rows, columns and opts
7009
+ selector: null,
7010
+
7011
+ shift: __arrayProto.shift,
7012
+
7013
+ slice: function () {
7014
+ return new _Api(this.context, this);
7015
+ },
7016
+
7017
+ sort: __arrayProto.sort, // ? name - order?
7018
+
7019
+
7020
+ splice: __arrayProto.splice,
7021
+
7022
+ toArray: function ()
7023
+ {
7024
+ return __arrayProto.slice.call(this);
7025
+ },
7026
+
7027
+ to$: function ()
7028
+ {
7029
+ return $(this);
7030
+ },
7031
+
7032
+ toJQuery: function ()
7033
+ {
7034
+ return $(this);
7035
+ },
7036
+
7037
+ unique: function ()
7038
+ {
7039
+ return new _Api(this.context, _unique(this));
7040
+ },
7041
+
7042
+ unshift: __arrayProto.unshift
7043
+ });
7044
+
7045
+
7046
+ _Api.extend = function (scope, obj, ext)
7047
+ {
7048
+ // Only extend API instances and static properties of the API
7049
+ if (!ext.length || !obj || (!(obj instanceof _Api) && !obj.__dt_wrapper)) {
7050
+ return;
7051
+ }
7052
+
7053
+ var
7054
+ i, ien,
7055
+ j, jen,
7056
+ struct, inner,
7057
+ methodScoping = function (scope, fn, struc) {
7058
+ return function () {
7059
+ var ret = fn.apply(scope, arguments);
7060
+
7061
+ // Method extension
7062
+ _Api.extend(ret, ret, struc.methodExt);
7063
+ return ret;
7064
+ };
7065
+ };
7066
+
7067
+ for (i = 0, ien = ext.length; i < ien; i++) {
7068
+ struct = ext[i];
7069
+
7070
+ // Value
7071
+ obj[ struct.name ] = typeof struct.val === 'function' ?
7072
+ methodScoping(scope, struct.val, struct) :
7073
+ $.isPlainObject(struct.val) ?
7074
+ {} :
7075
+ struct.val;
7076
+
7077
+ obj[ struct.name ].__dt_wrapper = true;
7078
+
7079
+ // Property extension
7080
+ _Api.extend(scope, obj[ struct.name ], struct.propExt);
7081
+ }
7082
+ };
7083
+
7084
+
7085
+ // @todo - Is there need for an augment function?
7086
+ // _Api.augment = function ( inst, name )
7087
+ // {
7088
+ // // Find src object in the structure from the name
7089
+ // var parts = name.split('.');
7090
+
7091
+ // _Api.extend( inst, obj );
7092
+ // };
7093
+
7094
+
7095
+ // [
7096
+ // {
7097
+ // name: 'data' -- string - Property name
7098
+ // val: function () {}, -- function - Api method (or undefined if just an object
7099
+ // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
7100
+ // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
7101
+ // },
7102
+ // {
7103
+ // name: 'row'
7104
+ // val: {},
7105
+ // methodExt: [ ... ],
7106
+ // propExt: [
7107
+ // {
7108
+ // name: 'data'
7109
+ // val: function () {},
7110
+ // methodExt: [ ... ],
7111
+ // propExt: [ ... ]
7112
+ // },
7113
+ // ...
7114
+ // ]
7115
+ // }
7116
+ // ]
7117
+
7118
+ _Api.register = _api_register = function (name, val)
7119
+ {
7120
+ if ($.isArray(name)) {
7121
+ for (var j = 0, jen = name.length; j < jen; j++) {
7122
+ _Api.register(name[j], val);
7123
+ }
7124
+ return;
7125
+ }
7126
+
7127
+ var
7128
+ i, ien,
7129
+ heir = name.split('.'),
7130
+ struct = __apiStruct,
7131
+ key, method;
7132
+
7133
+ var find = function (src, name) {
7134
+ for (var i = 0, ien = src.length; i < ien; i++) {
7135
+ if (src[i].name === name) {
7136
+ return src[i];
7137
+ }
7138
+ }
7139
+ return null;
7140
+ };
7141
+
7142
+ for (i = 0, ien = heir.length; i < ien; i++) {
7143
+ method = heir[i].indexOf('()') !== -1;
7144
+ key = method ?
7145
+ heir[i].replace('()', '') :
7146
+ heir[i];
7147
+
7148
+ var src = find(struct, key);
7149
+ if (!src) {
7150
+ src = {
7151
+ name: key,
7152
+ val: {},
7153
+ methodExt: [],
7154
+ propExt: []
7155
+ };
7156
+ struct.push(src);
7157
+ }
7158
+
7159
+ if (i === ien - 1) {
7160
+ src.val = val;
7161
+ } else {
7162
+ struct = method ?
7163
+ src.methodExt :
7164
+ src.propExt;
7165
+ }
7166
+ }
7167
+ };
7168
+
7169
+
7170
+ _Api.registerPlural = _api_registerPlural = function (pluralName, singularName, val) {
7171
+ _Api.register(pluralName, val);
7172
+
7173
+ _Api.register(singularName, function () {
7174
+ var ret = val.apply(this, arguments);
7175
+
7176
+ if (ret === this) {
7177
+ // Returned item is the API instance that was passed in, return it
7178
+ return this;
7179
+ } else if (ret instanceof _Api) {
7180
+ // New API instance returned, want the value from the first item
7181
+ // in the returned array for the singular result.
7182
+ return ret.length ?
7183
+ $.isArray(ret[0]) ?
7184
+ new _Api(ret.context, ret[0]) : // Array results are 'enhanced'
7185
+ ret[0] :
7186
+ undefined;
7187
+ }
7188
+
7189
+ // Non-API return - just fire it back
7190
+ return ret;
7191
+ });
7192
+ };
7193
+
7194
+
7195
+ /**
7196
+ * Selector for HTML tables. Apply the given selector to the give array of
7197
+ * DataTables settings objects.
7198
+ *
7199
+ * @param {string|integer} [selector] jQuery selector string or integer
7200
+ * @param {array} Array of DataTables settings objects to be filtered
7201
+ * @return {array}
7202
+ * @ignore
7203
+ */
7204
+ var __table_selector = function (selector, a)
7205
+ {
7206
+ // Integer is used to pick out a table by index
7207
+ if (typeof selector === 'number') {
7208
+ return [a[ selector ]];
7209
+ }
7210
+
7211
+ // Perform a jQuery selector on the table nodes
7212
+ var nodes = $.map(a, function (el, i) {
7213
+ return el.nTable;
7214
+ });
7215
+
7216
+ return $(nodes)
7217
+ .filter(selector)
7218
+ .map(function (i) {
7219
+ // Need to translate back from the table node to the settings
7220
+ var idx = $.inArray(this, nodes);
7221
+ return a[ idx ];
7222
+ })
7223
+ .toArray();
7224
+ };
7225
+
7226
+
7227
+
7228
+ /**
7229
+ * Context selector for the API's context (i.e. the tables the API instance
7230
+ * refers to.
7231
+ *
7232
+ * @name DataTable.Api#tables
7233
+ * @param {string|integer} [selector] Selector to pick which tables the iterator
7234
+ * should operate on. If not given, all tables in the current context are
7235
+ * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7236
+ * select multiple tables or as an integer to select a single table.
7237
+ * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7238
+ */
7239
+ _api_register('tables()', function (selector) {
7240
+ // A new instance is created if there was a selector specified
7241
+ return selector ?
7242
+ new _Api(__table_selector(selector, this.context)) :
7243
+ this;
7244
+ });
7245
+
7246
+
7247
+ _api_register('table()', function (selector) {
7248
+ var tables = this.tables(selector);
7249
+ var ctx = tables.context;
7250
+
7251
+ // Truncate to the first matched table
7252
+ return ctx.length ?
7253
+ new _Api(ctx[0]) :
7254
+ tables;
7255
+ });
7256
+
7257
+
7258
+ _api_registerPlural('tables().nodes()', 'table().node()', function () {
7259
+ return this.iterator('table', function (ctx) {
7260
+ return ctx.nTable;
7261
+ }, 1);
7262
+ });
7263
+
7264
+
7265
+ _api_registerPlural('tables().body()', 'table().body()', function () {
7266
+ return this.iterator('table', function (ctx) {
7267
+ return ctx.nTBody;
7268
+ }, 1);
7269
+ });
7270
+
7271
+
7272
+ _api_registerPlural('tables().header()', 'table().header()', function () {
7273
+ return this.iterator('table', function (ctx) {
7274
+ return ctx.nTHead;
7275
+ }, 1);
7276
+ });
7277
+
7278
+
7279
+ _api_registerPlural('tables().footer()', 'table().footer()', function () {
7280
+ return this.iterator('table', function (ctx) {
7281
+ return ctx.nTFoot;
7282
+ }, 1);
7283
+ });
7284
+
7285
+
7286
+ _api_registerPlural('tables().containers()', 'table().container()', function () {
7287
+ return this.iterator('table', function (ctx) {
7288
+ return ctx.nTableWrapper;
7289
+ }, 1);
7290
+ });
7291
+
7292
+
7293
+
7294
+ /**
7295
+ * Redraw the tables in the current context.
7296
+ */
7297
+ _api_register('draw()', function (paging) {
7298
+ return this.iterator('table', function (settings) {
7299
+ if (paging === 'page') {
7300
+ _fnDraw(settings);
7301
+ } else {
7302
+ if (typeof paging === 'string') {
7303
+ paging = paging === 'full-hold' ?
7304
+ false :
7305
+ true;
7306
+ }
7307
+
7308
+ _fnReDraw(settings, paging === false);
7309
+ }
7310
+ });
7311
+ });
7312
+
7313
+
7314
+
7315
+ /**
7316
+ * Get the current page index.
7317
+ *
7318
+ * @return {integer} Current page index (zero based)
7319
+ *//**
7320
+ * Set the current page.
7321
+ *
7322
+ * Note that if you attempt to show a page which does not exist, DataTables will
7323
+ * not throw an error, but rather reset the paging.
7324
+ *
7325
+ * @param {integer|string} action The paging action to take. This can be one of:
7326
+ * * `integer` - The page index to jump to
7327
+ * * `string` - An action to take:
7328
+ * * `first` - Jump to first page.
7329
+ * * `next` - Jump to the next page
7330
+ * * `previous` - Jump to previous page
7331
+ * * `last` - Jump to the last page.
7332
+ * @returns {DataTables.Api} this
7333
+ */
7334
+ _api_register('page()', function (action) {
7335
+ if (action === undefined) {
7336
+ return this.page.info().page; // not an expensive call
7337
+ }
7338
+
7339
+ // else, have an action to take on all tables
7340
+ return this.iterator('table', function (settings) {
7341
+ _fnPageChange(settings, action);
7342
+ });
7343
+ });
7344
+
7345
+
7346
+ /**
7347
+ * Paging information for the first table in the current context.
7348
+ *
7349
+ * If you require paging information for another table, use the `table()` method
7350
+ * with a suitable selector.
7351
+ *
7352
+ * @return {object} Object with the following properties set:
7353
+ * * `page` - Current page index (zero based - i.e. the first page is `0`)
7354
+ * * `pages` - Total number of pages
7355
+ * * `start` - Display index for the first record shown on the current page
7356
+ * * `end` - Display index for the last record shown on the current page
7357
+ * * `length` - Display length (number of records). Note that generally `start
7358
+ * + length = end`, but this is not always true, for example if there are
7359
+ * only 2 records to show on the final page, with a length of 10.
7360
+ * * `recordsTotal` - Full data set length
7361
+ * * `recordsDisplay` - Data set length once the current filtering criterion
7362
+ * are applied.
7363
+ */
7364
+ _api_register('page.info()', function (action) {
7365
+ if (this.context.length === 0) {
7366
+ return undefined;
7367
+ }
7368
+
7369
+ var
7370
+ settings = this.context[0],
7371
+ start = settings._iDisplayStart,
7372
+ len = settings.oFeatures.bPaginate ? settings._iDisplayLength : -1,
7373
+ visRecords = settings.fnRecordsDisplay(),
7374
+ all = len === -1;
7375
+
7376
+ return {
7377
+ "page": all ? 0 : Math.floor(start / len),
7378
+ "pages": all ? 1 : Math.ceil(visRecords / len),
7379
+ "start": start,
7380
+ "end": settings.fnDisplayEnd(),
7381
+ "length": len,
7382
+ "recordsTotal": settings.fnRecordsTotal(),
7383
+ "recordsDisplay": visRecords,
7384
+ "serverSide": _fnDataSource(settings) === 'ssp'
7385
+ };
7386
+ });
7387
+
7388
+
7389
+ /**
7390
+ * Get the current page length.
7391
+ *
7392
+ * @return {integer} Current page length. Note `-1` indicates that all records
7393
+ * are to be shown.
7394
+ *//**
7395
+ * Set the current page length.
7396
+ *
7397
+ * @param {integer} Page length to set. Use `-1` to show all records.
7398
+ * @returns {DataTables.Api} this
7399
+ */
7400
+ _api_register('page.len()', function (len) {
7401
+ // Note that we can't call this function 'length()' because `length`
7402
+ // is a Javascript property of functions which defines how many arguments
7403
+ // the function expects.
7404
+ if (len === undefined) {
7405
+ return this.context.length !== 0 ?
7406
+ this.context[0]._iDisplayLength :
7407
+ undefined;
7408
+ }
7409
+
7410
+ // else, set the page length
7411
+ return this.iterator('table', function (settings) {
7412
+ _fnLengthChange(settings, len);
7413
+ });
7414
+ });
7415
+
7416
+
7417
+
7418
+ var __reload = function (settings, holdPosition, callback) {
7419
+ // Use the draw event to trigger a callback
7420
+ if (callback) {
7421
+ var api = new _Api(settings);
7422
+
7423
+ api.one('draw', function () {
7424
+ callback(api.ajax.json());
7425
+ });
7426
+ }
7427
+
7428
+ if (_fnDataSource(settings) == 'ssp') {
7429
+ _fnReDraw(settings, holdPosition);
7430
+ } else {
7431
+ _fnProcessingDisplay(settings, true);
7432
+
7433
+ // Cancel an existing request
7434
+ var xhr = settings.jqXHR;
7435
+ if (xhr && xhr.readyState !== 4) {
7436
+ xhr.abort();
7437
+ }
7438
+
7439
+ // Trigger xhr
7440
+ _fnBuildAjax(settings, [], function (json) {
7441
+ _fnClearTable(settings);
7442
+
7443
+ var data = _fnAjaxDataSrc(settings, json);
7444
+ for (var i = 0, ien = data.length; i < ien; i++) {
7445
+ _fnAddData(settings, data[i]);
7446
+ }
7447
+
7448
+ _fnReDraw(settings, holdPosition);
7449
+ _fnProcessingDisplay(settings, false);
7450
+ });
7451
+ }
7452
+ };
7453
+
7454
+
7455
+ /**
7456
+ * Get the JSON response from the last Ajax request that DataTables made to the
7457
+ * server. Note that this returns the JSON from the first table in the current
7458
+ * context.
7459
+ *
7460
+ * @return {object} JSON received from the server.
7461
+ */
7462
+ _api_register('ajax.json()', function () {
7463
+ var ctx = this.context;
7464
+
7465
+ if (ctx.length > 0) {
7466
+ return ctx[0].json;
7467
+ }
7468
+
7469
+ // else return undefined;
7470
+ });
7471
+
7472
+
7473
+ /**
7474
+ * Get the data submitted in the last Ajax request
7475
+ */
7476
+ _api_register('ajax.params()', function () {
7477
+ var ctx = this.context;
7478
+
7479
+ if (ctx.length > 0) {
7480
+ return ctx[0].oAjaxData;
7481
+ }
7482
+
7483
+ // else return undefined;
7484
+ });
7485
+
7486
+
7487
+ /**
7488
+ * Reload tables from the Ajax data source. Note that this function will
7489
+ * automatically re-draw the table when the remote data has been loaded.
7490
+ *
7491
+ * @param {boolean} [reset=true] Reset (default) or hold the current paging
7492
+ * position. A full re-sort and re-filter is performed when this method is
7493
+ * called, which is why the pagination reset is the default action.
7494
+ * @returns {DataTables.Api} this
7495
+ */
7496
+ _api_register('ajax.reload()', function (callback, resetPaging) {
7497
+ return this.iterator('table', function (settings) {
7498
+ __reload(settings, resetPaging === false, callback);
7499
+ });
7500
+ });
7501
+
7502
+
7503
+ /**
7504
+ * Get the current Ajax URL. Note that this returns the URL from the first
7505
+ * table in the current context.
7506
+ *
7507
+ * @return {string} Current Ajax source URL
7508
+ *//**
7509
+ * Set the Ajax URL. Note that this will set the URL for all tables in the
7510
+ * current context.
7511
+ *
7512
+ * @param {string} url URL to set.
7513
+ * @returns {DataTables.Api} this
7514
+ */
7515
+ _api_register('ajax.url()', function (url) {
7516
+ var ctx = this.context;
7517
+
7518
+ if (url === undefined) {
7519
+ // get
7520
+ if (ctx.length === 0) {
7521
+ return undefined;
7522
+ }
7523
+ ctx = ctx[0];
7524
+
7525
+ return ctx.ajax ?
7526
+ $.isPlainObject(ctx.ajax) ?
7527
+ ctx.ajax.url :
7528
+ ctx.ajax :
7529
+ ctx.sAjaxSource;
7530
+ }
7531
+
7532
+ // set
7533
+ return this.iterator('table', function (settings) {
7534
+ if ($.isPlainObject(settings.ajax)) {
7535
+ settings.ajax.url = url;
7536
+ } else {
7537
+ settings.ajax = url;
7538
+ }
7539
+ // No need to consider sAjaxSource here since DataTables gives priority
7540
+ // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7541
+ // value of `sAjaxSource` redundant.
7542
+ });
7543
+ });
7544
+
7545
+
7546
+ /**
7547
+ * Load data from the newly set Ajax URL. Note that this method is only
7548
+ * available when `ajax.url()` is used to set a URL. Additionally, this method
7549
+ * has the same effect as calling `ajax.reload()` but is provided for
7550
+ * convenience when setting a new URL. Like `ajax.reload()` it will
7551
+ * automatically redraw the table once the remote data has been loaded.
7552
+ *
7553
+ * @returns {DataTables.Api} this
7554
+ */
7555
+ _api_register('ajax.url().load()', function (callback, resetPaging) {
7556
+ // Same as a reload, but makes sense to present it for easy access after a
7557
+ // url change
7558
+ return this.iterator('table', function (ctx) {
7559
+ __reload(ctx, resetPaging === false, callback);
7560
+ });
7561
+ });
7562
+
7563
+
7564
+
7565
+
7566
+ var _selector_run = function (type, selector, selectFn, settings, opts)
7567
+ {
7568
+ var
7569
+ out = [], res,
7570
+ a, i, ien, j, jen,
7571
+ selectorType = typeof selector;
7572
+
7573
+ // Can't just check for isArray here, as an API or jQuery instance might be
7574
+ // given with their array like look
7575
+ if (!selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined) {
7576
+ selector = [selector];
7577
+ }
7578
+
7579
+ for (i = 0, ien = selector.length; i < ien; i++) {
7580
+ // Only split on simple strings - complex expressions will be jQuery selectors
7581
+ a = selector[i] && selector[i].split && !selector[i].match(/[\[\(:]/) ?
7582
+ selector[i].split(',') :
7583
+ [selector[i]];
7584
+
7585
+ for (j = 0, jen = a.length; j < jen; j++) {
7586
+ res = selectFn(typeof a[j] === 'string' ? $.trim(a[j]) : a[j]);
7587
+
7588
+ if (res && res.length) {
7589
+ out = out.concat(res);
7590
+ }
7591
+ }
7592
+ }
7593
+
7594
+ // selector extensions
7595
+ var ext = _ext.selector[ type ];
7596
+ if (ext.length) {
7597
+ for (i = 0, ien = ext.length; i < ien; i++) {
7598
+ out = ext[i](settings, opts, out);
7599
+ }
7600
+ }
7601
+
7602
+ return _unique(out);
7603
+ };
7604
+
7605
+
7606
+ var _selector_opts = function (opts)
7607
+ {
7608
+ if (!opts) {
7609
+ opts = {};
7610
+ }
7611
+
7612
+ // Backwards compatibility for 1.9- which used the terminology filter rather
7613
+ // than search
7614
+ if (opts.filter && opts.search === undefined) {
7615
+ opts.search = opts.filter;
7616
+ }
7617
+
7618
+ return $.extend({
7619
+ search: 'none',
7620
+ order: 'current',
7621
+ page: 'all'
7622
+ }, opts);
7623
+ };
7624
+
7625
+
7626
+ var _selector_first = function (inst)
7627
+ {
7628
+ // Reduce the API instance to the first item found
7629
+ for (var i = 0, ien = inst.length; i < ien; i++) {
7630
+ if (inst[i].length > 0) {
7631
+ // Assign the first element to the first item in the instance
7632
+ // and truncate the instance and context
7633
+ inst[0] = inst[i];
7634
+ inst[0].length = 1;
7635
+ inst.length = 1;
7636
+ inst.context = [inst.context[i]];
7637
+
7638
+ return inst;
7639
+ }
7640
+ }
7641
+
7642
+ // Not found - return an empty instance
7643
+ inst.length = 0;
7644
+ return inst;
7645
+ };
7646
+
7647
+
7648
+ var _selector_row_indexes = function (settings, opts)
7649
+ {
7650
+ var
7651
+ i, ien, tmp, a = [],
7652
+ displayFiltered = settings.aiDisplay,
7653
+ displayMaster = settings.aiDisplayMaster;
7654
+
7655
+ var
7656
+ search = opts.search, // none, applied, removed
7657
+ order = opts.order, // applied, current, index (original - compatibility with 1.9)
7658
+ page = opts.page; // all, current
7659
+
7660
+ if (_fnDataSource(settings) == 'ssp') {
7661
+ // In server-side processing mode, most options are irrelevant since
7662
+ // rows not shown don't exist and the index order is the applied order
7663
+ // Removed is a special case - for consistency just return an empty
7664
+ // array
7665
+ return search === 'removed' ?
7666
+ [] :
7667
+ _range(0, displayMaster.length);
7668
+ } else if (page == 'current') {
7669
+ // Current page implies that order=current and fitler=applied, since it is
7670
+ // fairly senseless otherwise, regardless of what order and search actually
7671
+ // are
7672
+ for (i = settings._iDisplayStart, ien = settings.fnDisplayEnd(); i < ien; i++) {
7673
+ a.push(displayFiltered[i]);
7674
+ }
7675
+ } else if (order == 'current' || order == 'applied') {
7676
+ a = search == 'none' ?
7677
+ displayMaster.slice() : // no search
7678
+ search == 'applied' ?
7679
+ displayFiltered.slice() : // applied search
7680
+ $.map(displayMaster, function (el, i) { // removed search
7681
+ return $.inArray(el, displayFiltered) === -1 ? el : null;
7682
+ });
7683
+ } else if (order == 'index' || order == 'original') {
7684
+ for (i = 0, ien = settings.aoData.length; i < ien; i++) {
7685
+ if (search == 'none') {
7686
+ a.push(i);
7687
+ } else { // applied | removed
7688
+ tmp = $.inArray(i, displayFiltered);
7689
+
7690
+ if ((tmp === -1 && search == 'removed') ||
7691
+ (tmp >= 0 && search == 'applied'))
7692
+ {
7693
+ a.push(i);
7694
+ }
7695
+ }
7696
+ }
7697
+ }
7698
+
7699
+ return a;
7700
+ };
7701
+
7702
+
7703
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7704
+ * Rows
7705
+ *
7706
+ * {} - no selector - use all available rows
7707
+ * {integer} - row aoData index
7708
+ * {node} - TR node
7709
+ * {string} - jQuery selector to apply to the TR elements
7710
+ * {array} - jQuery array of nodes, or simply an array of TR nodes
7711
+ *
7712
+ */
7713
+
7714
+
7715
+ var __row_selector = function (settings, selector, opts)
7716
+ {
7717
+ var rows;
7718
+ var run = function (sel) {
7719
+ var selInt = _intVal(sel);
7720
+ var i, ien;
7721
+
7722
+ // Short cut - selector is a number and no options provided (default is
7723
+ // all records, so no need to check if the index is in there, since it
7724
+ // must be - dev error if the index doesn't exist).
7725
+ if (selInt !== null && !opts) {
7726
+ return [selInt];
7727
+ }
7728
+
7729
+ if (!rows) {
7730
+ rows = _selector_row_indexes(settings, opts);
7731
+ }
7732
+
7733
+ if (selInt !== null && $.inArray(selInt, rows) !== -1) {
7734
+ // Selector - integer
7735
+ return [selInt];
7736
+ } else if (sel === null || sel === undefined || sel === '') {
7737
+ // Selector - none
7738
+ return rows;
7739
+ }
7740
+
7741
+ // Selector - function
7742
+ if (typeof sel === 'function') {
7743
+ return $.map(rows, function (idx) {
7744
+ var row = settings.aoData[ idx ];
7745
+ return sel(idx, row._aData, row.nTr) ? idx : null;
7746
+ });
7747
+ }
7748
+
7749
+ // Get nodes in the order from the `rows` array with null values removed
7750
+ var nodes = _removeEmpty(
7751
+ _pluck_order(settings.aoData, rows, 'nTr')
7752
+ );
7753
+
7754
+ // Selector - node
7755
+ if (sel.nodeName) {
7756
+ if (sel._DT_RowIndex !== undefined) {
7757
+ return [sel._DT_RowIndex]; // Property added by DT for fast lookup
7758
+ } else if (sel._DT_CellIndex) {
7759
+ return [sel._DT_CellIndex.row];
7760
+ } else {
7761
+ var host = $(sel).closest('*[data-dt-row]');
7762
+ return host.length ?
7763
+ [host.data('dt-row')] :
7764
+ [];
7765
+ }
7766
+ }
7767
+
7768
+ // ID selector. Want to always be able to select rows by id, regardless
7769
+ // of if the tr element has been created or not, so can't rely upon
7770
+ // jQuery here - hence a custom implementation. This does not match
7771
+ // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7772
+ // but to select it using a CSS selector engine (like Sizzle or
7773
+ // querySelect) it would need to need to be escaped for some characters.
7774
+ // DataTables simplifies this for row selectors since you can select
7775
+ // only a row. A # indicates an id any anything that follows is the id -
7776
+ // unescaped.
7777
+ if (typeof sel === 'string' && sel.charAt(0) === '#') {
7778
+ // get row index from id
7779
+ var rowObj = settings.aIds[ sel.replace(/^#/, '') ];
7780
+ if (rowObj !== undefined) {
7781
+ return [rowObj.idx];
7782
+ }
7783
+
7784
+ // need to fall through to jQuery in case there is DOM id that
7785
+ // matches
7786
+ }
7787
+
7788
+ // Selector - jQuery selector string, array of nodes or jQuery object/
7789
+ // As jQuery's .filter() allows jQuery objects to be passed in filter,
7790
+ // it also allows arrays, so this will cope with all three options
7791
+ return $(nodes)
7792
+ .filter(sel)
7793
+ .map(function () {
7794
+ return this._DT_RowIndex;
7795
+ })
7796
+ .toArray();
7797
+ };
7798
+
7799
+ return _selector_run('row', selector, run, settings, opts);
7800
+ };
7801
+
7802
+
7803
+ _api_register('rows()', function (selector, opts) {
7804
+ // argument shifting
7805
+ if (selector === undefined) {
7806
+ selector = '';
7807
+ } else if ($.isPlainObject(selector)) {
7808
+ opts = selector;
7809
+ selector = '';
7810
+ }
7811
+
7812
+ opts = _selector_opts(opts);
7813
+
7814
+ var inst = this.iterator('table', function (settings) {
7815
+ return __row_selector(settings, selector, opts);
7816
+ }, 1);
7817
+
7818
+ // Want argument shifting here and in __row_selector?
7819
+ inst.selector.rows = selector;
7820
+ inst.selector.opts = opts;
7821
+
7822
+ return inst;
7823
+ });
7824
+
7825
+ _api_register('rows().nodes()', function () {
7826
+ return this.iterator('row', function (settings, row) {
7827
+ return settings.aoData[ row ].nTr || undefined;
7828
+ }, 1);
7829
+ });
7830
+
7831
+ _api_register('rows().data()', function () {
7832
+ return this.iterator(true, 'rows', function (settings, rows) {
7833
+ return _pluck_order(settings.aoData, rows, '_aData');
7834
+ }, 1);
7835
+ });
7836
+
7837
+ _api_registerPlural('rows().cache()', 'row().cache()', function (type) {
7838
+ return this.iterator('row', function (settings, row) {
7839
+ var r = settings.aoData[ row ];
7840
+ return type === 'search' ? r._aFilterData : r._aSortData;
7841
+ }, 1);
7842
+ });
7843
+
7844
+ _api_registerPlural('rows().invalidate()', 'row().invalidate()', function (src) {
7845
+ return this.iterator('row', function (settings, row) {
7846
+ _fnInvalidate(settings, row, src);
7847
+ });
7848
+ });
7849
+
7850
+ _api_registerPlural('rows().indexes()', 'row().index()', function () {
7851
+ return this.iterator('row', function (settings, row) {
7852
+ return row;
7853
+ }, 1);
7854
+ });
7855
+
7856
+ _api_registerPlural('rows().ids()', 'row().id()', function (hash) {
7857
+ var a = [];
7858
+ var context = this.context;
7859
+
7860
+ // `iterator` will drop undefined values, but in this case we want them
7861
+ for (var i = 0, ien = context.length; i < ien; i++) {
7862
+ for (var j = 0, jen = this[i].length; j < jen; j++) {
7863
+ var id = context[i].rowIdFn(context[i].aoData[ this[i][j] ]._aData);
7864
+ a.push((hash === true ? '#' : '') + id);
7865
+ }
7866
+ }
7867
+
7868
+ return new _Api(context, a);
7869
+ });
7870
+
7871
+ _api_registerPlural('rows().remove()', 'row().remove()', function () {
7872
+ var that = this;
7873
+
7874
+ this.iterator('row', function (settings, row, thatIdx) {
7875
+ var data = settings.aoData;
7876
+ var rowData = data[ row ];
7877
+ var i, ien, j, jen;
7878
+ var loopRow, loopCells;
7879
+
7880
+ data.splice(row, 1);
7881
+
7882
+ // Update the cached indexes
7883
+ for (i = 0, ien = data.length; i < ien; i++) {
7884
+ loopRow = data[i];
7885
+ loopCells = loopRow.anCells;
7886
+
7887
+ // Rows
7888
+ if (loopRow.nTr !== null) {
7889
+ loopRow.nTr._DT_RowIndex = i;
7890
+ }
7891
+
7892
+ // Cells
7893
+ if (loopCells !== null) {
7894
+ for (j = 0, jen = loopCells.length; j < jen; j++) {
7895
+ loopCells[j]._DT_CellIndex.row = i;
7896
+ }
7897
+ }
7898
+ }
7899
+
7900
+ // Delete from the display arrays
7901
+ _fnDeleteIndex(settings.aiDisplayMaster, row);
7902
+ _fnDeleteIndex(settings.aiDisplay, row);
7903
+ _fnDeleteIndex(that[ thatIdx ], row, false); // maintain local indexes
7904
+
7905
+ // Check for an 'overflow' they case for displaying the table
7906
+ _fnLengthOverflow(settings);
7907
+
7908
+ // Remove the row's ID reference if there is one
7909
+ var id = settings.rowIdFn(rowData._aData);
7910
+ if (id !== undefined) {
7911
+ delete settings.aIds[ id ];
7912
+ }
7913
+ });
7914
+
7915
+ this.iterator('table', function (settings) {
7916
+ for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
7917
+ settings.aoData[i].idx = i;
7918
+ }
7919
+ });
7920
+
7921
+ return this;
7922
+ });
7923
+
7924
+
7925
+ _api_register('rows.add()', function (rows) {
7926
+ var newRows = this.iterator('table', function (settings) {
7927
+ var row, i, ien;
7928
+ var out = [];
7929
+
7930
+ for (i = 0, ien = rows.length; i < ien; i++) {
7931
+ row = rows[i];
7932
+
7933
+ if (row.nodeName && row.nodeName.toUpperCase() === 'TR') {
7934
+ out.push(_fnAddTr(settings, row)[0]);
7935
+ } else {
7936
+ out.push(_fnAddData(settings, row));
7937
+ }
7938
+ }
7939
+
7940
+ return out;
7941
+ }, 1);
7942
+
7943
+ // Return an Api.rows() extended instance, so rows().nodes() etc can be used
7944
+ var modRows = this.rows(-1);
7945
+ modRows.pop();
7946
+ $.merge(modRows, newRows);
7947
+
7948
+ return modRows;
7949
+ });
7950
+
7951
+
7952
+
7953
+
7954
+
7955
+ /**
7956
+ *
7957
+ */
7958
+ _api_register('row()', function (selector, opts) {
7959
+ return _selector_first(this.rows(selector, opts));
7960
+ });
7961
+
7962
+
7963
+ _api_register('row().data()', function (data) {
7964
+ var ctx = this.context;
7965
+
7966
+ if (data === undefined) {
7967
+ // Get
7968
+ return ctx.length && this.length ?
7969
+ ctx[0].aoData[ this[0] ]._aData :
7970
+ undefined;
7971
+ }
7972
+
7973
+ // Set
7974
+ ctx[0].aoData[ this[0] ]._aData = data;
7975
+
7976
+ // Automatically invalidate
7977
+ _fnInvalidate(ctx[0], this[0], 'data');
7978
+
7979
+ return this;
7980
+ });
7981
+
7982
+
7983
+ _api_register('row().node()', function () {
7984
+ var ctx = this.context;
7985
+
7986
+ return ctx.length && this.length ?
7987
+ ctx[0].aoData[ this[0] ].nTr || null :
7988
+ null;
7989
+ });
7990
+
7991
+
7992
+ _api_register('row.add()', function (row) {
7993
+ // Allow a jQuery object to be passed in - only a single row is added from
7994
+ // it though - the first element in the set
7995
+ if (row instanceof $ && row.length) {
7996
+ row = row[0];
7997
+ }
7998
+
7999
+ var rows = this.iterator('table', function (settings) {
8000
+ if (row.nodeName && row.nodeName.toUpperCase() === 'TR') {
8001
+ return _fnAddTr(settings, row)[0];
8002
+ }
8003
+ return _fnAddData(settings, row);
8004
+ });
8005
+
8006
+ // Return an Api.rows() extended instance, with the newly added row selected
8007
+ return this.row(rows[0]);
8008
+ });
8009
+
8010
+
8011
+
8012
+ var __details_add = function (ctx, row, data, klass)
8013
+ {
8014
+ // Convert to array of TR elements
8015
+ var rows = [];
8016
+ var addRow = function (r, k) {
8017
+ // Recursion to allow for arrays of jQuery objects
8018
+ if ($.isArray(r) || r instanceof $) {
8019
+ for (var i = 0, ien = r.length; i < ien; i++) {
8020
+ addRow(r[i], k);
8021
+ }
8022
+ return;
8023
+ }
8024
+
8025
+ // If we get a TR element, then just add it directly - up to the dev
8026
+ // to add the correct number of columns etc
8027
+ if (r.nodeName && r.nodeName.toLowerCase() === 'tr') {
8028
+ rows.push(r);
8029
+ } else {
8030
+ // Otherwise create a row with a wrapper
8031
+ var created = $('<tr><td/></tr>').addClass(k);
8032
+ $('td', created)
8033
+ .addClass(k)
8034
+ .html(r)
8035
+ [0].colSpan = _fnVisbleColumns(ctx);
8036
+
8037
+ rows.push(created[0]);
8038
+ }
8039
+ };
8040
+
8041
+ addRow(data, klass);
8042
+
8043
+ if (row._details) {
8044
+ row._details.detach();
8045
+ }
8046
+
8047
+ row._details = $(rows);
8048
+
8049
+ // If the children were already shown, that state should be retained
8050
+ if (row._detailsShow) {
8051
+ row._details.insertAfter(row.nTr);
8052
+ }
8053
+ };
8054
+
8055
+
8056
+ var __details_remove = function (api, idx)
8057
+ {
8058
+ var ctx = api.context;
8059
+
8060
+ if (ctx.length) {
8061
+ var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8062
+
8063
+ if (row && row._details) {
8064
+ row._details.remove();
8065
+
8066
+ row._detailsShow = undefined;
8067
+ row._details = undefined;
8068
+ }
8069
+ }
8070
+ };
8071
+
8072
+
8073
+ var __details_display = function (api, show) {
8074
+ var ctx = api.context;
8075
+
8076
+ if (ctx.length && api.length) {
8077
+ var row = ctx[0].aoData[ api[0] ];
8078
+
8079
+ if (row._details) {
8080
+ row._detailsShow = show;
8081
+
8082
+ if (show) {
8083
+ row._details.insertAfter(row.nTr);
8084
+ } else {
8085
+ row._details.detach();
8086
+ }
8087
+
8088
+ __details_events(ctx[0]);
8089
+ }
8090
+ }
8091
+ };
8092
+
8093
+
8094
+ var __details_events = function (settings)
8095
+ {
8096
+ var api = new _Api(settings);
8097
+ var namespace = '.dt.DT_details';
8098
+ var drawEvent = 'draw' + namespace;
8099
+ var colvisEvent = 'column-visibility' + namespace;
8100
+ var destroyEvent = 'destroy' + namespace;
8101
+ var data = settings.aoData;
8102
+
8103
+ api.off(drawEvent + ' ' + colvisEvent + ' ' + destroyEvent);
8104
+
8105
+ if (_pluck(data, '_details').length > 0) {
8106
+ // On each draw, insert the required elements into the document
8107
+ api.on(drawEvent, function (e, ctx) {
8108
+ if (settings !== ctx) {
8109
+ return;
8110
+ }
8111
+
8112
+ api.rows({page: 'current'}).eq(0).each(function (idx) {
8113
+ // Internal data grab
8114
+ var row = data[ idx ];
8115
+
8116
+ if (row._detailsShow) {
8117
+ row._details.insertAfter(row.nTr);
8118
+ }
8119
+ });
8120
+ });
8121
+
8122
+ // Column visibility change - update the colspan
8123
+ api.on(colvisEvent, function (e, ctx, idx, vis) {
8124
+ if (settings !== ctx) {
8125
+ return;
8126
+ }
8127
+
8128
+ // Update the colspan for the details rows (note, only if it already has
8129
+ // a colspan)
8130
+ var row, visible = _fnVisbleColumns(ctx);
8131
+
8132
+ for (var i = 0, ien = data.length; i < ien; i++) {
8133
+ row = data[i];
8134
+
8135
+ if (row._details) {
8136
+ row._details.children('td[colspan]').attr('colspan', visible);
8137
+ }
8138
+ }
8139
+ });
8140
+
8141
+ // Table destroyed - nuke any child rows
8142
+ api.on(destroyEvent, function (e, ctx) {
8143
+ if (settings !== ctx) {
8144
+ return;
8145
+ }
8146
+
8147
+ for (var i = 0, ien = data.length; i < ien; i++) {
8148
+ if (data[i]._details) {
8149
+ __details_remove(api, i);
8150
+ }
8151
+ }
8152
+ });
8153
+ }
8154
+ };
8155
+
8156
+ // Strings for the method names to help minification
8157
+ var _emp = '';
8158
+ var _child_obj = _emp + 'row().child';
8159
+ var _child_mth = _child_obj + '()';
8160
+
8161
+ // data can be:
8162
+ // tr
8163
+ // string
8164
+ // jQuery or array of any of the above
8165
+ _api_register(_child_mth, function (data, klass) {
8166
+ var ctx = this.context;
8167
+
8168
+ if (data === undefined) {
8169
+ // get
8170
+ return ctx.length && this.length ?
8171
+ ctx[0].aoData[ this[0] ]._details :
8172
+ undefined;
8173
+ } else if (data === true) {
8174
+ // show
8175
+ this.child.show();
8176
+ } else if (data === false) {
8177
+ // remove
8178
+ __details_remove(this);
8179
+ } else if (ctx.length && this.length) {
8180
+ // set
8181
+ __details_add(ctx[0], ctx[0].aoData[ this[0] ], data, klass);
8182
+ }
8183
+
8184
+ return this;
8185
+ });
8186
+
8187
+
8188
+ _api_register([
8189
+ _child_obj + '.show()',
8190
+ _child_mth + '.show()' // only when `child()` was called with parameters (without
8191
+ ], function (show) { // it returns an object and this method is not executed)
8192
+ __details_display(this, true);
8193
+ return this;
8194
+ });
8195
+
8196
+
8197
+ _api_register([
8198
+ _child_obj + '.hide()',
8199
+ _child_mth + '.hide()' // only when `child()` was called with parameters (without
8200
+ ], function () { // it returns an object and this method is not executed)
8201
+ __details_display(this, false);
8202
+ return this;
8203
+ });
8204
+
8205
+
8206
+ _api_register([
8207
+ _child_obj + '.remove()',
8208
+ _child_mth + '.remove()' // only when `child()` was called with parameters (without
8209
+ ], function () { // it returns an object and this method is not executed)
8210
+ __details_remove(this);
8211
+ return this;
8212
+ });
8213
+
8214
+
8215
+ _api_register(_child_obj + '.isShown()', function () {
8216
+ var ctx = this.context;
8217
+
8218
+ if (ctx.length && this.length) {
8219
+ // _detailsShown as false or undefined will fall through to return false
8220
+ return ctx[0].aoData[ this[0] ]._detailsShow || false;
8221
+ }
8222
+ return false;
8223
+ });
8224
+
8225
+
8226
+
8227
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8228
+ * Columns
8229
+ *
8230
+ * {integer} - column index (>=0 count from left, <0 count from right)
8231
+ * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
8232
+ * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
8233
+ * "{string}:name" - column name
8234
+ * "{string}" - jQuery selector on column header nodes
8235
+ *
8236
+ */
8237
+
8238
+ // can be an array of these items, comma separated list, or an array of comma
8239
+ // separated lists
8240
+
8241
+ var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
8242
+
8243
+
8244
+ // r1 and r2 are redundant - but it means that the parameters match for the
8245
+ // iterator callback in columns().data()
8246
+ var __columnData = function (settings, column, r1, r2, rows) {
8247
+ var a = [];
8248
+ for (var row = 0, ien = rows.length; row < ien; row++) {
8249
+ a.push(_fnGetCellData(settings, rows[row], column));
8250
+ }
8251
+ return a;
8252
+ };
8253
+
8254
+
8255
+ var __column_selector = function (settings, selector, opts)
8256
+ {
8257
+ var
8258
+ columns = settings.aoColumns,
8259
+ names = _pluck(columns, 'sName'),
8260
+ nodes = _pluck(columns, 'nTh');
8261
+
8262
+ var run = function (s) {
8263
+ var selInt = _intVal(s);
8264
+
8265
+ // Selector - all
8266
+ if (s === '') {
8267
+ return _range(columns.length);
8268
+ }
8269
+
8270
+ // Selector - index
8271
+ if (selInt !== null) {
8272
+ return [selInt >= 0 ?
8273
+ selInt : // Count from left
8274
+ columns.length + selInt // Count from right (+ because its a negative value)
8275
+ ];
8276
+ }
8277
+
8278
+ // Selector = function
8279
+ if (typeof s === 'function') {
8280
+ var rows = _selector_row_indexes(settings, opts);
8281
+
8282
+ return $.map(columns, function (col, idx) {
8283
+ return s(
8284
+ idx,
8285
+ __columnData(settings, idx, 0, 0, rows),
8286
+ nodes[ idx ]
8287
+ ) ? idx : null;
8288
+ });
8289
+ }
8290
+
8291
+ // jQuery or string selector
8292
+ var match = typeof s === 'string' ?
8293
+ s.match(__re_column_selector) :
8294
+ '';
8295
+
8296
+ if (match) {
8297
+ switch (match[2]) {
8298
+ case 'visIdx':
8299
+ case 'visible':
8300
+ var idx = parseInt(match[1], 10);
8301
+ // Visible index given, convert to column index
8302
+ if (idx < 0) {
8303
+ // Counting from the right
8304
+ var visColumns = $.map(columns, function (col, i) {
8305
+ return col.bVisible ? i : null;
8306
+ });
8307
+ return [visColumns[ visColumns.length + idx ]];
8308
+ }
8309
+ // Counting from the left
8310
+ return [_fnVisibleToColumnIndex(settings, idx)];
8311
+
8312
+ case 'name':
8313
+ // match by name. `names` is column index complete and in order
8314
+ return $.map(names, function (name, i) {
8315
+ return name === match[1] ? i : null;
8316
+ });
8317
+
8318
+ default:
8319
+ return [];
8320
+ }
8321
+ }
8322
+
8323
+ // Cell in the table body
8324
+ if (s.nodeName && s._DT_CellIndex) {
8325
+ return [s._DT_CellIndex.column];
8326
+ }
8327
+
8328
+ // jQuery selector on the TH elements for the columns
8329
+ var jqResult = $(nodes)
8330
+ .filter(s)
8331
+ .map(function () {
8332
+ return $.inArray(this, nodes); // `nodes` is column index complete and in order
8333
+ })
8334
+ .toArray();
8335
+
8336
+ if (jqResult.length || !s.nodeName) {
8337
+ return jqResult;
8338
+ }
8339
+
8340
+ // Otherwise a node which might have a `dt-column` data attribute, or be
8341
+ // a child or such an element
8342
+ var host = $(s).closest('*[data-dt-column]');
8343
+ return host.length ?
8344
+ [host.data('dt-column')] :
8345
+ [];
8346
+ };
8347
+
8348
+ return _selector_run('column', selector, run, settings, opts);
8349
+ };
8350
+
8351
+
8352
+ var __setColumnVis = function (settings, column, vis) {
8353
+ var
8354
+ cols = settings.aoColumns,
8355
+ col = cols[ column ],
8356
+ data = settings.aoData,
8357
+ row, cells, i, ien, tr;
8358
+
8359
+ // Get
8360
+ if (vis === undefined) {
8361
+ return col.bVisible;
8362
+ }
8363
+
8364
+ // Set
8365
+ // No change
8366
+ if (col.bVisible === vis) {
8367
+ return;
8368
+ }
8369
+
8370
+ if (vis) {
8371
+ // Insert column
8372
+ // Need to decide if we should use appendChild or insertBefore
8373
+ var insertBefore = $.inArray(true, _pluck(cols, 'bVisible'), column + 1);
8374
+
8375
+ for (i = 0, ien = data.length; i < ien; i++) {
8376
+ tr = data[i].nTr;
8377
+ cells = data[i].anCells;
8378
+
8379
+ if (tr) {
8380
+ // insertBefore can act like appendChild if 2nd arg is null
8381
+ tr.insertBefore(cells[ column ], cells[ insertBefore ] || null);
8382
+ }
8383
+ }
8384
+ } else {
8385
+ // Remove column
8386
+ $(_pluck(settings.aoData, 'anCells', column)).detach();
8387
+ }
8388
+
8389
+ // Common actions
8390
+ col.bVisible = vis;
8391
+ _fnDrawHead(settings, settings.aoHeader);
8392
+ _fnDrawHead(settings, settings.aoFooter);
8393
+
8394
+ _fnSaveState(settings);
8395
+ };
8396
+
8397
+
8398
+ _api_register('columns()', function (selector, opts) {
8399
+ // argument shifting
8400
+ if (selector === undefined) {
8401
+ selector = '';
8402
+ } else if ($.isPlainObject(selector)) {
8403
+ opts = selector;
8404
+ selector = '';
8405
+ }
8406
+
8407
+ opts = _selector_opts(opts);
8408
+
8409
+ var inst = this.iterator('table', function (settings) {
8410
+ return __column_selector(settings, selector, opts);
8411
+ }, 1);
8412
+
8413
+ // Want argument shifting here and in _row_selector?
8414
+ inst.selector.cols = selector;
8415
+ inst.selector.opts = opts;
8416
+
8417
+ return inst;
8418
+ });
8419
+
8420
+ _api_registerPlural('columns().header()', 'column().header()', function (selector, opts) {
8421
+ return this.iterator('column', function (settings, column) {
8422
+ return settings.aoColumns[column].nTh;
8423
+ }, 1);
8424
+ });
8425
+
8426
+ _api_registerPlural('columns().footer()', 'column().footer()', function (selector, opts) {
8427
+ return this.iterator('column', function (settings, column) {
8428
+ return settings.aoColumns[column].nTf;
8429
+ }, 1);
8430
+ });
8431
+
8432
+ _api_registerPlural('columns().data()', 'column().data()', function () {
8433
+ return this.iterator('column-rows', __columnData, 1);
8434
+ });
8435
+
8436
+ _api_registerPlural('columns().dataSrc()', 'column().dataSrc()', function () {
8437
+ return this.iterator('column', function (settings, column) {
8438
+ return settings.aoColumns[column].mData;
8439
+ }, 1);
8440
+ });
8441
+
8442
+ _api_registerPlural('columns().cache()', 'column().cache()', function (type) {
8443
+ return this.iterator('column-rows', function (settings, column, i, j, rows) {
8444
+ return _pluck_order(settings.aoData, rows,
8445
+ type === 'search' ? '_aFilterData' : '_aSortData', column
8446
+ );
8447
+ }, 1);
8448
+ });
8449
+
8450
+ _api_registerPlural('columns().nodes()', 'column().nodes()', function () {
8451
+ return this.iterator('column-rows', function (settings, column, i, j, rows) {
8452
+ return _pluck_order(settings.aoData, rows, 'anCells', column);
8453
+ }, 1);
8454
+ });
8455
+
8456
+ _api_registerPlural('columns().visible()', 'column().visible()', function (vis, calc) {
8457
+ var ret = this.iterator('column', function (settings, column) {
8458
+ if (vis === undefined) {
8459
+ return settings.aoColumns[ column ].bVisible;
8460
+ } // else
8461
+ __setColumnVis(settings, column, vis);
8462
+ });
8463
+
8464
+ // Group the column visibility changes
8465
+ if (vis !== undefined) {
8466
+ // Second loop once the first is done for events
8467
+ this.iterator('column', function (settings, column) {
8468
+ _fnCallbackFire(settings, null, 'column-visibility', [settings, column, vis, calc]);
8469
+ });
8470
+
8471
+ if (calc === undefined || calc) {
8472
+ this.columns.adjust();
8473
+ }
8474
+ }
8475
+
8476
+ return ret;
8477
+ });
8478
+
8479
+ _api_registerPlural('columns().indexes()', 'column().index()', function (type) {
8480
+ return this.iterator('column', function (settings, column) {
8481
+ return type === 'visible' ?
8482
+ _fnColumnIndexToVisible(settings, column) :
8483
+ column;
8484
+ }, 1);
8485
+ });
8486
+
8487
+ _api_register('columns.adjust()', function () {
8488
+ return this.iterator('table', function (settings) {
8489
+ _fnAdjustColumnSizing(settings);
8490
+ }, 1);
8491
+ });
8492
+
8493
+ _api_register('column.index()', function (type, idx) {
8494
+ if (this.context.length !== 0) {
8495
+ var ctx = this.context[0];
8496
+
8497
+ if (type === 'fromVisible' || type === 'toData') {
8498
+ return _fnVisibleToColumnIndex(ctx, idx);
8499
+ } else if (type === 'fromData' || type === 'toVisible') {
8500
+ return _fnColumnIndexToVisible(ctx, idx);
8501
+ }
8502
+ }
8503
+ });
8504
+
8505
+ _api_register('column()', function (selector, opts) {
8506
+ return _selector_first(this.columns(selector, opts));
8507
+ });
8508
+
8509
+
8510
+
8511
+ var __cell_selector = function (settings, selector, opts)
8512
+ {
8513
+ var data = settings.aoData;
8514
+ var rows = _selector_row_indexes(settings, opts);
8515
+ var cells = _removeEmpty(_pluck_order(data, rows, 'anCells'));
8516
+ var allCells = $([].concat.apply([], cells));
8517
+ var row;
8518
+ var columns = settings.aoColumns.length;
8519
+ var a, i, ien, j, o, host;
8520
+
8521
+ var run = function (s) {
8522
+ var fnSelector = typeof s === 'function';
8523
+
8524
+ if (s === null || s === undefined || fnSelector) {
8525
+ // All cells and function selectors
8526
+ a = [];
8527
+
8528
+ for (i = 0, ien = rows.length; i < ien; i++) {
8529
+ row = rows[i];
8530
+
8531
+ for (j = 0; j < columns; j++) {
8532
+ o = {
8533
+ row: row,
8534
+ column: j
8535
+ };
8536
+
8537
+ if (fnSelector) {
8538
+ // Selector - function
8539
+ host = data[ row ];
8540
+
8541
+ if (s(o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null)) {
8542
+ a.push(o);
8543
+ }
8544
+ } else {
8545
+ // Selector - all
8546
+ a.push(o);
8547
+ }
8548
+ }
8549
+ }
8550
+
8551
+ return a;
8552
+ }
8553
+
8554
+ // Selector - index
8555
+ if ($.isPlainObject(s)) {
8556
+ return [s];
8557
+ }
8558
+
8559
+ // Selector - jQuery filtered cells
8560
+ var jqResult = allCells
8561
+ .filter(s)
8562
+ .map(function (i, el) {
8563
+ return {// use a new object, in case someone changes the values
8564
+ row: el._DT_CellIndex.row,
8565
+ column: el._DT_CellIndex.column
8566
+ };
8567
+ })
8568
+ .toArray();
8569
+
8570
+ if (jqResult.length || !s.nodeName) {
8571
+ return jqResult;
8572
+ }
8573
+
8574
+ // Otherwise the selector is a node, and there is one last option - the
8575
+ // element might be a child of an element which has dt-row and dt-column
8576
+ // data attributes
8577
+ host = $(s).closest('*[data-dt-row]');
8578
+ return host.length ?
8579
+ [{
8580
+ row: host.data('dt-row'),
8581
+ column: host.data('dt-column')
8582
+ }] :
8583
+ [];
8584
+ };
8585
+
8586
+ return _selector_run('cell', selector, run, settings, opts);
8587
+ };
8588
+
8589
+
8590
+
8591
+
8592
+ _api_register('cells()', function (rowSelector, columnSelector, opts) {
8593
+ // Argument shifting
8594
+ if ($.isPlainObject(rowSelector)) {
8595
+ // Indexes
8596
+ if (rowSelector.row === undefined) {
8597
+ // Selector options in first parameter
8598
+ opts = rowSelector;
8599
+ rowSelector = null;
8600
+ } else {
8601
+ // Cell index objects in first parameter
8602
+ opts = columnSelector;
8603
+ columnSelector = null;
8604
+ }
8605
+ }
8606
+ if ($.isPlainObject(columnSelector)) {
8607
+ opts = columnSelector;
8608
+ columnSelector = null;
8609
+ }
8610
+
8611
+ // Cell selector
8612
+ if (columnSelector === null || columnSelector === undefined) {
8613
+ return this.iterator('table', function (settings) {
8614
+ return __cell_selector(settings, rowSelector, _selector_opts(opts));
8615
+ });
8616
+ }
8617
+
8618
+ // Row + column selector
8619
+ var columns = this.columns(columnSelector, opts);
8620
+ var rows = this.rows(rowSelector, opts);
8621
+ var a, i, ien, j, jen;
8622
+
8623
+ var cells = this.iterator('table', function (settings, idx) {
8624
+ a = [];
8625
+
8626
+ for (i = 0, ien = rows[idx].length; i < ien; i++) {
8627
+ for (j = 0, jen = columns[idx].length; j < jen; j++) {
8628
+ a.push({
8629
+ row: rows[idx][i],
8630
+ column: columns[idx][j]
8631
+ });
8632
+ }
8633
+ }
8634
+
8635
+ return a;
8636
+ }, 1);
8637
+
8638
+ $.extend(cells.selector, {
8639
+ cols: columnSelector,
8640
+ rows: rowSelector,
8641
+ opts: opts
8642
+ });
8643
+
8644
+ return cells;
8645
+ });
8646
+
8647
+
8648
+ _api_registerPlural('cells().nodes()', 'cell().node()', function () {
8649
+ return this.iterator('cell', function (settings, row, column) {
8650
+ var data = settings.aoData[ row ];
8651
+
8652
+ return data && data.anCells ?
8653
+ data.anCells[ column ] :
8654
+ undefined;
8655
+ }, 1);
8656
+ });
8657
+
8658
+
8659
+ _api_register('cells().data()', function () {
8660
+ return this.iterator('cell', function (settings, row, column) {
8661
+ return _fnGetCellData(settings, row, column);
8662
+ }, 1);
8663
+ });
8664
+
8665
+
8666
+ _api_registerPlural('cells().cache()', 'cell().cache()', function (type) {
8667
+ type = type === 'search' ? '_aFilterData' : '_aSortData';
8668
+
8669
+ return this.iterator('cell', function (settings, row, column) {
8670
+ return settings.aoData[ row ][ type ][ column ];
8671
+ }, 1);
8672
+ });
8673
+
8674
+
8675
+ _api_registerPlural('cells().render()', 'cell().render()', function (type) {
8676
+ return this.iterator('cell', function (settings, row, column) {
8677
+ return _fnGetCellData(settings, row, column, type);
8678
+ }, 1);
8679
+ });
8680
+
8681
+
8682
+ _api_registerPlural('cells().indexes()', 'cell().index()', function () {
8683
+ return this.iterator('cell', function (settings, row, column) {
8684
+ return {
8685
+ row: row,
8686
+ column: column,
8687
+ columnVisible: _fnColumnIndexToVisible(settings, column)
8688
+ };
8689
+ }, 1);
8690
+ });
8691
+
8692
+
8693
+ _api_registerPlural('cells().invalidate()', 'cell().invalidate()', function (src) {
8694
+ return this.iterator('cell', function (settings, row, column) {
8695
+ _fnInvalidate(settings, row, src, column);
8696
+ });
8697
+ });
8698
+
8699
+
8700
+
8701
+ _api_register('cell()', function (rowSelector, columnSelector, opts) {
8702
+ return _selector_first(this.cells(rowSelector, columnSelector, opts));
8703
+ });
8704
+
8705
+
8706
+ _api_register('cell().data()', function (data) {
8707
+ var ctx = this.context;
8708
+ var cell = this[0];
8709
+
8710
+ if (data === undefined) {
8711
+ // Get
8712
+ return ctx.length && cell.length ?
8713
+ _fnGetCellData(ctx[0], cell[0].row, cell[0].column) :
8714
+ undefined;
8715
+ }
8716
+
8717
+ // Set
8718
+ _fnSetCellData(ctx[0], cell[0].row, cell[0].column, data);
8719
+ _fnInvalidate(ctx[0], cell[0].row, 'data', cell[0].column);
8720
+
8721
+ return this;
8722
+ });
8723
+
8724
+
8725
+
8726
+ /**
8727
+ * Get current ordering (sorting) that has been applied to the table.
8728
+ *
8729
+ * @returns {array} 2D array containing the sorting information for the first
8730
+ * table in the current context. Each element in the parent array represents
8731
+ * a column being sorted upon (i.e. multi-sorting with two columns would have
8732
+ * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8733
+ * the column index that the sorting condition applies to, the second is the
8734
+ * direction of the sort (`desc` or `asc`) and, optionally, the third is the
8735
+ * index of the sorting order from the `column.sorting` initialisation array.
8736
+ *//**
8737
+ * Set the ordering for the table.
8738
+ *
8739
+ * @param {integer} order Column index to sort upon.
8740
+ * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8741
+ * @returns {DataTables.Api} this
8742
+ *//**
8743
+ * Set the ordering for the table.
8744
+ *
8745
+ * @param {array} order 1D array of sorting information to be applied.
8746
+ * @param {array} [...] Optional additional sorting conditions
8747
+ * @returns {DataTables.Api} this
8748
+ *//**
8749
+ * Set the ordering for the table.
8750
+ *
8751
+ * @param {array} order 2D array of sorting information to be applied.
8752
+ * @returns {DataTables.Api} this
8753
+ */
8754
+ _api_register('order()', function (order, dir) {
8755
+ var ctx = this.context;
8756
+
8757
+ if (order === undefined) {
8758
+ // get
8759
+ return ctx.length !== 0 ?
8760
+ ctx[0].aaSorting :
8761
+ undefined;
8762
+ }
8763
+
8764
+ // set
8765
+ if (typeof order === 'number') {
8766
+ // Simple column / direction passed in
8767
+ order = [[order, dir]];
8768
+ } else if (order.length && !$.isArray(order[0])) {
8769
+ // Arguments passed in (list of 1D arrays)
8770
+ order = Array.prototype.slice.call(arguments);
8771
+ }
8772
+ // otherwise a 2D array was passed in
8773
+
8774
+ return this.iterator('table', function (settings) {
8775
+ settings.aaSorting = order.slice();
8776
+ });
8777
+ });
8778
+
8779
+
8780
+ /**
8781
+ * Attach a sort listener to an element for a given column
8782
+ *
8783
+ * @param {node|jQuery|string} node Identifier for the element(s) to attach the
8784
+ * listener to. This can take the form of a single DOM node, a jQuery
8785
+ * collection of nodes or a jQuery selector which will identify the node(s).
8786
+ * @param {integer} column the column that a click on this node will sort on
8787
+ * @param {function} [callback] callback function when sort is run
8788
+ * @returns {DataTables.Api} this
8789
+ */
8790
+ _api_register('order.listener()', function (node, column, callback) {
8791
+ return this.iterator('table', function (settings) {
8792
+ _fnSortAttachListener(settings, node, column, callback);
8793
+ });
8794
+ });
8795
+
8796
+
8797
+ _api_register('order.fixed()', function (set) {
8798
+ if (!set) {
8799
+ var ctx = this.context;
8800
+ var fixed = ctx.length ?
8801
+ ctx[0].aaSortingFixed :
8802
+ undefined;
8803
+
8804
+ return $.isArray(fixed) ?
8805
+ {pre: fixed} :
8806
+ fixed;
8807
+ }
8808
+
8809
+ return this.iterator('table', function (settings) {
8810
+ settings.aaSortingFixed = $.extend(true, {}, set);
8811
+ });
8812
+ });
8813
+
8814
+
8815
+ // Order by the selected column(s)
8816
+ _api_register([
8817
+ 'columns().order()',
8818
+ 'column().order()'
8819
+ ], function (dir) {
8820
+ var that = this;
8821
+
8822
+ return this.iterator('table', function (settings, i) {
8823
+ var sort = [];
8824
+
8825
+ $.each(that[i], function (j, col) {
8826
+ sort.push([col, dir]);
8827
+ });
8828
+
8829
+ settings.aaSorting = sort;
8830
+ });
8831
+ });
8832
+
8833
+
8834
+
8835
+ _api_register('search()', function (input, regex, smart, caseInsen) {
8836
+ var ctx = this.context;
8837
+
8838
+ if (input === undefined) {
8839
+ // get
8840
+ return ctx.length !== 0 ?
8841
+ ctx[0].oPreviousSearch.sSearch :
8842
+ undefined;
8843
+ }
8844
+
8845
+ // set
8846
+ return this.iterator('table', function (settings) {
8847
+ if (!settings.oFeatures.bFilter) {
8848
+ return;
8849
+ }
8850
+
8851
+ _fnFilterComplete(settings, $.extend({}, settings.oPreviousSearch, {
8852
+ "sSearch": input + "",
8853
+ "bRegex": regex === null ? false : regex,
8854
+ "bSmart": smart === null ? true : smart,
8855
+ "bCaseInsensitive": caseInsen === null ? true : caseInsen
8856
+ }), 1);
8857
+ });
8858
+ });
8859
+
8860
+
8861
+ _api_registerPlural(
8862
+ 'columns().search()',
8863
+ 'column().search()',
8864
+ function (input, regex, smart, caseInsen) {
8865
+ return this.iterator('column', function (settings, column) {
8866
+ var preSearch = settings.aoPreSearchCols;
8867
+
8868
+ if (input === undefined) {
8869
+ // get
8870
+ return preSearch[ column ].sSearch;
8871
+ }
8872
+
8873
+ // set
8874
+ if (!settings.oFeatures.bFilter) {
8875
+ return;
8876
+ }
8877
+
8878
+ $.extend(preSearch[ column ], {
8879
+ "sSearch": input + "",
8880
+ "bRegex": regex === null ? false : regex,
8881
+ "bSmart": smart === null ? true : smart,
8882
+ "bCaseInsensitive": caseInsen === null ? true : caseInsen
8883
+ });
8884
+
8885
+ _fnFilterComplete(settings, settings.oPreviousSearch, 1);
8886
+ });
8887
+ }
8888
+ );
8889
+
8890
+ /*
8891
+ * State API methods
8892
+ */
8893
+
8894
+ _api_register('state()', function () {
8895
+ return this.context.length ?
8896
+ this.context[0].oSavedState :
8897
+ null;
8898
+ });
8899
+
8900
+
8901
+ _api_register('state.clear()', function () {
8902
+ return this.iterator('table', function (settings) {
8903
+ // Save an empty object
8904
+ settings.fnStateSaveCallback.call(settings.oInstance, settings, {});
8905
+ });
8906
+ });
8907
+
8908
+
8909
+ _api_register('state.loaded()', function () {
8910
+ return this.context.length ?
8911
+ this.context[0].oLoadedState :
8912
+ null;
8913
+ });
8914
+
8915
+
8916
+ _api_register('state.save()', function () {
8917
+ return this.iterator('table', function (settings) {
8918
+ _fnSaveState(settings);
8919
+ });
8920
+ });
8921
+
8922
+
8923
+
8924
+ /**
8925
+ * Provide a common method for plug-ins to check the version of DataTables being
8926
+ * used, in order to ensure compatibility.
8927
+ *
8928
+ * @param {string} version Version string to check for, in the format "X.Y.Z".
8929
+ * Note that the formats "X" and "X.Y" are also acceptable.
8930
+ * @returns {boolean} true if this version of DataTables is greater or equal to
8931
+ * the required version, or false if this version of DataTales is not
8932
+ * suitable
8933
+ * @static
8934
+ * @dtopt API-Static
8935
+ *
8936
+ * @example
8937
+ * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
8938
+ */
8939
+ DataTable.versionCheck = DataTable.fnVersionCheck = function (version)
8940
+ {
8941
+ var aThis = DataTable.version.split('.');
8942
+ var aThat = version.split('.');
8943
+ var iThis, iThat;
8944
+
8945
+ for (var i = 0, iLen = aThat.length; i < iLen; i++) {
8946
+ iThis = parseInt(aThis[i], 10) || 0;
8947
+ iThat = parseInt(aThat[i], 10) || 0;
8948
+
8949
+ // Parts are the same, keep comparing
8950
+ if (iThis === iThat) {
8951
+ continue;
8952
+ }
8953
+
8954
+ // Parts are different, return immediately
8955
+ return iThis > iThat;
8956
+ }
8957
+
8958
+ return true;
8959
+ };
8960
+
8961
+
8962
+ /**
8963
+ * Check if a `<table>` node is a DataTable table already or not.
8964
+ *
8965
+ * @param {node|jquery|string} table Table node, jQuery object or jQuery
8966
+ * selector for the table to test. Note that if more than more than one
8967
+ * table is passed on, only the first will be checked
8968
+ * @returns {boolean} true the table given is a DataTable, or false otherwise
8969
+ * @static
8970
+ * @dtopt API-Static
8971
+ *
8972
+ * @example
8973
+ * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
8974
+ * $('#example').dataTable();
8975
+ * }
8976
+ */
8977
+ DataTable.isDataTable = DataTable.fnIsDataTable = function (table)
8978
+ {
8979
+ var t = $(table).get(0);
8980
+ var is = false;
8981
+
8982
+ if (table instanceof DataTable.Api) {
8983
+ return true;
8984
+ }
8985
+
8986
+ $.each(DataTable.settings, function (i, o) {
8987
+ var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
8988
+ var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
8989
+
8990
+ if (o.nTable === t || head === t || foot === t) {
8991
+ is = true;
8992
+ }
8993
+ });
8994
+
8995
+ return is;
8996
+ };
8997
+
8998
+
8999
+ /**
9000
+ * Get all DataTable tables that have been initialised - optionally you can
9001
+ * select to get only currently visible tables.
9002
+ *
9003
+ * @param {boolean} [visible=false] Flag to indicate if you want all (default)
9004
+ * or visible tables only.
9005
+ * @returns {array} Array of `table` nodes (not DataTable instances) which are
9006
+ * DataTables
9007
+ * @static
9008
+ * @dtopt API-Static
9009
+ *
9010
+ * @example
9011
+ * $.each( $.fn.dataTable.tables(true), function () {
9012
+ * $(table).DataTable().columns.adjust();
9013
+ * } );
9014
+ */
9015
+ DataTable.tables = DataTable.fnTables = function (visible)
9016
+ {
9017
+ var api = false;
9018
+
9019
+ if ($.isPlainObject(visible)) {
9020
+ api = visible.api;
9021
+ visible = visible.visible;
9022
+ }
9023
+
9024
+ var a = $.map(DataTable.settings, function (o) {
9025
+ if (!visible || (visible && $(o.nTable).is(':visible'))) {
9026
+ return o.nTable;
9027
+ }
9028
+ });
9029
+
9030
+ return api ?
9031
+ new _Api(a) :
9032
+ a;
9033
+ };
9034
+
9035
+
9036
+ /**
9037
+ * Convert from camel case parameters to Hungarian notation. This is made public
9038
+ * for the extensions to provide the same ability as DataTables core to accept
9039
+ * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9040
+ * parameters.
9041
+ *
9042
+ * @param {object} src The model object which holds all parameters that can be
9043
+ * mapped.
9044
+ * @param {object} user The object to convert from camel case to Hungarian.
9045
+ * @param {boolean} force When set to `true`, properties which already have a
9046
+ * Hungarian value in the `user` object will be overwritten. Otherwise they
9047
+ * won't be.
9048
+ */
9049
+ DataTable.camelToHungarian = _fnCamelToHungarian;
9050
+
9051
+
9052
+
9053
+ /**
9054
+ *
9055
+ */
9056
+ _api_register('$()', function (selector, opts) {
9057
+ var
9058
+ rows = this.rows(opts).nodes(), // Get all rows
9059
+ jqRows = $(rows);
9060
+
9061
+ return $([].concat(
9062
+ jqRows.filter(selector).toArray(),
9063
+ jqRows.find(selector).toArray()
9064
+ ));
9065
+ });
9066
+
9067
+
9068
+ // jQuery functions to operate on the tables
9069
+ $.each(['on', 'one', 'off'], function (i, key) {
9070
+ _api_register(key + '()', function ( /* event, handler */ ) {
9071
+ var args = Array.prototype.slice.call(arguments);
9072
+
9073
+ // Add the `dt` namespace automatically if it isn't already present
9074
+ args[0] = $.map(args[0].split(/\s/), function (e) {
9075
+ return !e.match(/\.dt\b/) ?
9076
+ e + '.dt' :
9077
+ e;
9078
+ }).join(' ');
9079
+
9080
+ var inst = $(this.tables().nodes());
9081
+ inst[key].apply(inst, args);
9082
+ return this;
9083
+ });
9084
+ });
9085
+
9086
+
9087
+ _api_register('clear()', function () {
9088
+ return this.iterator('table', function (settings) {
9089
+ _fnClearTable(settings);
9090
+ });
9091
+ });
9092
+
9093
+
9094
+ _api_register('settings()', function () {
9095
+ return new _Api(this.context, this.context);
9096
+ });
9097
+
9098
+
9099
+ _api_register('init()', function () {
9100
+ var ctx = this.context;
9101
+ return ctx.length ? ctx[0].oInit : null;
9102
+ });
9103
+
9104
+
9105
+ _api_register('data()', function () {
9106
+ return this.iterator('table', function (settings) {
9107
+ return _pluck(settings.aoData, '_aData');
9108
+ }).flatten();
9109
+ });
9110
+
9111
+
9112
+ _api_register('destroy()', function (remove) {
9113
+ remove = remove || false;
9114
+
9115
+ return this.iterator('table', function (settings) {
9116
+ var orig = settings.nTableWrapper.parentNode;
9117
+ var classes = settings.oClasses;
9118
+ var table = settings.nTable;
9119
+ var tbody = settings.nTBody;
9120
+ var thead = settings.nTHead;
9121
+ var tfoot = settings.nTFoot;
9122
+ var jqTable = $(table);
9123
+ var jqTbody = $(tbody);
9124
+ var jqWrapper = $(settings.nTableWrapper);
9125
+ var rows = $.map(settings.aoData, function (r) {
9126
+ return r.nTr;
9127
+ });
9128
+ var i, ien;
9129
+
9130
+ // Flag to note that the table is currently being destroyed - no action
9131
+ // should be taken
9132
+ settings.bDestroying = true;
9133
+
9134
+ // Fire off the destroy callbacks for plug-ins etc
9135
+ _fnCallbackFire(settings, "aoDestroyCallback", "destroy", [settings]);
9136
+
9137
+ // If not being removed from the document, make all columns visible
9138
+ if (!remove) {
9139
+ new _Api(settings).columns().visible(true);
9140
+ }
9141
+
9142
+ // Blitz all `DT` namespaced events (these are internal events, the
9143
+ // lowercase, `dt` events are user subscribed and they are responsible
9144
+ // for removing them
9145
+ jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
9146
+ $(window).off('.DT-' + settings.sInstance);
9147
+
9148
+ // When scrolling we had to break the table up - restore it
9149
+ if (table != thead.parentNode) {
9150
+ jqTable.children('thead').detach();
9151
+ jqTable.append(thead);
9152
+ }
9153
+
9154
+ if (tfoot && table != tfoot.parentNode) {
9155
+ jqTable.children('tfoot').detach();
9156
+ jqTable.append(tfoot);
9157
+ }
9158
+
9159
+ settings.aaSorting = [];
9160
+ settings.aaSortingFixed = [];
9161
+ _fnSortingClasses(settings);
9162
+
9163
+ $(rows).removeClass(settings.asStripeClasses.join(' '));
9164
+
9165
+ $('th, td', thead).removeClass(classes.sSortable + ' ' +
9166
+ classes.sSortableAsc + ' ' + classes.sSortableDesc + ' ' + classes.sSortableNone
9167
+ );
9168
+
9169
+ if (settings.bJUI) {
9170
+ $('th span.' + classes.sSortIcon + ', td span.' + classes.sSortIcon, thead).detach();
9171
+ $('th, td', thead).each(function () {
9172
+ var wrapper = $('div.' + classes.sSortJUIWrapper, this);
9173
+ $(this).append(wrapper.contents());
9174
+ wrapper.detach();
9175
+ });
9176
+ }
9177
+
9178
+ // Add the TR elements back into the table in their original order
9179
+ jqTbody.children().detach();
9180
+ jqTbody.append(rows);
9181
+
9182
+ // Remove the DataTables generated nodes, events and classes
9183
+ var removedMethod = remove ? 'remove' : 'detach';
9184
+ jqTable[ removedMethod ]();
9185
+ jqWrapper[ removedMethod ]();
9186
+
9187
+ // If we need to reattach the table to the document
9188
+ if (!remove && orig) {
9189
+ // insertBefore acts like appendChild if !arg[1]
9190
+ orig.insertBefore(table, settings.nTableReinsertBefore);
9191
+
9192
+ // Restore the width of the original table - was read from the style property,
9193
+ // so we can restore directly to that
9194
+ jqTable
9195
+ .css('width', settings.sDestroyWidth)
9196
+ .removeClass(classes.sTable);
9197
+
9198
+ // If the were originally stripe classes - then we add them back here.
9199
+ // Note this is not fool proof (for example if not all rows had stripe
9200
+ // classes - but it's a good effort without getting carried away
9201
+ ien = settings.asDestroyStripes.length;
9202
+
9203
+ if (ien) {
9204
+ jqTbody.children().each(function (i) {
9205
+ $(this).addClass(settings.asDestroyStripes[i % ien]);
9206
+ });
9207
+ }
9208
+ }
9209
+
9210
+ /* Remove the settings object from the settings array */
9211
+ var idx = $.inArray(settings, DataTable.settings);
9212
+ if (idx !== -1) {
9213
+ DataTable.settings.splice(idx, 1);
9214
+ }
9215
+ });
9216
+ });
9217
+
9218
+
9219
+ // Add the `every()` method for rows, columns and cells in a compact form
9220
+ $.each(['column', 'row', 'cell'], function (i, type) {
9221
+ _api_register(type + 's().every()', function (fn) {
9222
+ var opts = this.selector.opts;
9223
+ var api = this;
9224
+
9225
+ return this.iterator(type, function (settings, arg1, arg2, arg3, arg4) {
9226
+ // Rows and columns:
9227
+ // arg1 - index
9228
+ // arg2 - table counter
9229
+ // arg3 - loop counter
9230
+ // arg4 - undefined
9231
+ // Cells:
9232
+ // arg1 - row index
9233
+ // arg2 - column index
9234
+ // arg3 - table counter
9235
+ // arg4 - loop counter
9236
+ fn.call(
9237
+ api[ type ](
9238
+ arg1,
9239
+ type === 'cell' ? arg2 : opts,
9240
+ type === 'cell' ? opts : undefined
9241
+ ),
9242
+ arg1, arg2, arg3, arg4
9243
+ );
9244
+ });
9245
+ });
9246
+ });
9247
+
9248
+
9249
+ // i18n method for extensions to be able to use the language object from the
9250
+ // DataTable
9251
+ _api_register('i18n()', function (token, def, plural) {
9252
+ var ctx = this.context[0];
9253
+ var resolved = _fnGetObjectDataFn(token)(ctx.oLanguage);
9254
+
9255
+ if (resolved === undefined) {
9256
+ resolved = def;
9257
+ }
9258
+
9259
+ if (plural !== undefined && $.isPlainObject(resolved)) {
9260
+ resolved = resolved[ plural ] !== undefined ?
9261
+ resolved[ plural ] :
9262
+ resolved._;
9263
+ }
9264
+
9265
+ return resolved.replace('%d', plural); // nb: plural might be undefined,
9266
+ });
9267
+
9268
+ /**
9269
+ * Version string for plug-ins to check compatibility. Allowed format is
9270
+ * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9271
+ * only for non-release builds. See http://semver.org/ for more information.
9272
+ * @member
9273
+ * @type string
9274
+ * @default Version number
9275
+ */
9276
+ DataTable.version = "1.10.15";
9277
+
9278
+ /**
9279
+ * Private data store, containing all of the settings objects that are
9280
+ * created for the tables on a given page.
9281
+ *
9282
+ * Note that the `DataTable.settings` object is aliased to
9283
+ * `jQuery.fn.dataTableExt` through which it may be accessed and
9284
+ * manipulated, or `jQuery.fn.dataTable.settings`.
9285
+ * @member
9286
+ * @type array
9287
+ * @default []
9288
+ * @private
9289
+ */
9290
+ DataTable.settings = [];
9291
+
9292
+ /**
9293
+ * Object models container, for the various models that DataTables has
9294
+ * available to it. These models define the objects that are used to hold
9295
+ * the active state and configuration of the table.
9296
+ * @namespace
9297
+ */
9298
+ DataTable.models = {};
9299
+
9300
+
9301
+
9302
+ /**
9303
+ * Template object for the way in which DataTables holds information about
9304
+ * search information for the global filter and individual column filters.
9305
+ * @namespace
9306
+ */
9307
+ DataTable.models.oSearch = {
9308
+ /**
9309
+ * Flag to indicate if the filtering should be case insensitive or not
9310
+ * @type boolean
9311
+ * @default true
9312
+ */
9313
+ "bCaseInsensitive": true,
9314
+
9315
+ /**
9316
+ * Applied search term
9317
+ * @type string
9318
+ * @default <i>Empty string</i>
9319
+ */
9320
+ "sSearch": "",
9321
+
9322
+ /**
9323
+ * Flag to indicate if the search term should be interpreted as a
9324
+ * regular expression (true) or not (false) and therefore and special
9325
+ * regex characters escaped.
9326
+ * @type boolean
9327
+ * @default false
9328
+ */
9329
+ "bRegex": false,
9330
+
9331
+ /**
9332
+ * Flag to indicate if DataTables is to use its smart filtering or not.
9333
+ * @type boolean
9334
+ * @default true
9335
+ */
9336
+ "bSmart": true
9337
+ };
9338
+
9339
+
9340
+
9341
+
9342
+ /**
9343
+ * Template object for the way in which DataTables holds information about
9344
+ * each individual row. This is the object format used for the settings
9345
+ * aoData array.
9346
+ * @namespace
9347
+ */
9348
+ DataTable.models.oRow = {
9349
+ /**
9350
+ * TR element for the row
9351
+ * @type node
9352
+ * @default null
9353
+ */
9354
+ "nTr": null,
9355
+
9356
+ /**
9357
+ * Array of TD elements for each row. This is null until the row has been
9358
+ * created.
9359
+ * @type array nodes
9360
+ * @default []
9361
+ */
9362
+ "anCells": null,
9363
+
9364
+ /**
9365
+ * Data object from the original data source for the row. This is either
9366
+ * an array if using the traditional form of DataTables, or an object if
9367
+ * using mData options. The exact type will depend on the passed in
9368
+ * data from the data source, or will be an array if using DOM a data
9369
+ * source.
9370
+ * @type array|object
9371
+ * @default []
9372
+ */
9373
+ "_aData": [],
9374
+
9375
+ /**
9376
+ * Sorting data cache - this array is ostensibly the same length as the
9377
+ * number of columns (although each index is generated only as it is
9378
+ * needed), and holds the data that is used for sorting each column in the
9379
+ * row. We do this cache generation at the start of the sort in order that
9380
+ * the formatting of the sort data need be done only once for each cell
9381
+ * per sort. This array should not be read from or written to by anything
9382
+ * other than the master sorting methods.
9383
+ * @type array
9384
+ * @default null
9385
+ * @private
9386
+ */
9387
+ "_aSortData": null,
9388
+
9389
+ /**
9390
+ * Per cell filtering data cache. As per the sort data cache, used to
9391
+ * increase the performance of the filtering in DataTables
9392
+ * @type array
9393
+ * @default null
9394
+ * @private
9395
+ */
9396
+ "_aFilterData": null,
9397
+
9398
+ /**
9399
+ * Filtering data cache. This is the same as the cell filtering cache, but
9400
+ * in this case a string rather than an array. This is easily computed with
9401
+ * a join on `_aFilterData`, but is provided as a cache so the join isn't
9402
+ * needed on every search (memory traded for performance)
9403
+ * @type array
9404
+ * @default null
9405
+ * @private
9406
+ */
9407
+ "_sFilterRow": null,
9408
+
9409
+ /**
9410
+ * Cache of the class name that DataTables has applied to the row, so we
9411
+ * can quickly look at this variable rather than needing to do a DOM check
9412
+ * on className for the nTr property.
9413
+ * @type string
9414
+ * @default <i>Empty string</i>
9415
+ * @private
9416
+ */
9417
+ "_sRowStripe": "",
9418
+
9419
+ /**
9420
+ * Denote if the original data source was from the DOM, or the data source
9421
+ * object. This is used for invalidating data, so DataTables can
9422
+ * automatically read data from the original source, unless uninstructed
9423
+ * otherwise.
9424
+ * @type string
9425
+ * @default null
9426
+ * @private
9427
+ */
9428
+ "src": null,
9429
+
9430
+ /**
9431
+ * Index in the aoData array. This saves an indexOf lookup when we have the
9432
+ * object, but want to know the index
9433
+ * @type integer
9434
+ * @default -1
9435
+ * @private
9436
+ */
9437
+ "idx": -1
9438
+ };
9439
+
9440
+
9441
+ /**
9442
+ * Template object for the column information object in DataTables. This object
9443
+ * is held in the settings aoColumns array and contains all the information that
9444
+ * DataTables needs about each individual column.
9445
+ *
9446
+ * Note that this object is related to {@link DataTable.defaults.column}
9447
+ * but this one is the internal data store for DataTables's cache of columns.
9448
+ * It should NOT be manipulated outside of DataTables. Any configuration should
9449
+ * be done through the initialisation options.
9450
+ * @namespace
9451
+ */
9452
+ DataTable.models.oColumn = {
9453
+ /**
9454
+ * Column index. This could be worked out on-the-fly with $.inArray, but it
9455
+ * is faster to just hold it as a variable
9456
+ * @type integer
9457
+ * @default null
9458
+ */
9459
+ "idx": null,
9460
+
9461
+ /**
9462
+ * A list of the columns that sorting should occur on when this column
9463
+ * is sorted. That this property is an array allows multi-column sorting
9464
+ * to be defined for a column (for example first name / last name columns
9465
+ * would benefit from this). The values are integers pointing to the
9466
+ * columns to be sorted on (typically it will be a single integer pointing
9467
+ * at itself, but that doesn't need to be the case).
9468
+ * @type array
9469
+ */
9470
+ "aDataSort": null,
9471
+
9472
+ /**
9473
+ * Define the sorting directions that are applied to the column, in sequence
9474
+ * as the column is repeatedly sorted upon - i.e. the first value is used
9475
+ * as the sorting direction when the column if first sorted (clicked on).
9476
+ * Sort it again (click again) and it will move on to the next index.
9477
+ * Repeat until loop.
9478
+ * @type array
9479
+ */
9480
+ "asSorting": null,
9481
+
9482
+ /**
9483
+ * Flag to indicate if the column is searchable, and thus should be included
9484
+ * in the filtering or not.
9485
+ * @type boolean
9486
+ */
9487
+ "bSearchable": null,
9488
+
9489
+ /**
9490
+ * Flag to indicate if the column is sortable or not.
9491
+ * @type boolean
9492
+ */
9493
+ "bSortable": null,
9494
+
9495
+ /**
9496
+ * Flag to indicate if the column is currently visible in the table or not
9497
+ * @type boolean
9498
+ */
9499
+ "bVisible": null,
9500
+
9501
+ /**
9502
+ * Store for manual type assignment using the `column.type` option. This
9503
+ * is held in store so we can manipulate the column's `sType` property.
9504
+ * @type string
9505
+ * @default null
9506
+ * @private
9507
+ */
9508
+ "_sManualType": null,
9509
+
9510
+ /**
9511
+ * Flag to indicate if HTML5 data attributes should be used as the data
9512
+ * source for filtering or sorting. True is either are.
9513
+ * @type boolean
9514
+ * @default false
9515
+ * @private
9516
+ */
9517
+ "_bAttrSrc": false,
9518
+
9519
+ /**
9520
+ * Developer definable function that is called whenever a cell is created (Ajax source,
9521
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9522
+ * allowing you to modify the DOM element (add background colour for example) when the
9523
+ * element is available.
9524
+ * @type function
9525
+ * @param {element} nTd The TD node that has been created
9526
+ * @param {*} sData The Data for the cell
9527
+ * @param {array|object} oData The data for the whole row
9528
+ * @param {int} iRow The row index for the aoData data store
9529
+ * @default null
9530
+ */
9531
+ "fnCreatedCell": null,
9532
+
9533
+ /**
9534
+ * Function to get data from a cell in a column. You should <b>never</b>
9535
+ * access data directly through _aData internally in DataTables - always use
9536
+ * the method attached to this property. It allows mData to function as
9537
+ * required. This function is automatically assigned by the column
9538
+ * initialisation method
9539
+ * @type function
9540
+ * @param {array|object} oData The data array/object for the array
9541
+ * (i.e. aoData[]._aData)
9542
+ * @param {string} sSpecific The specific data type you want to get -
9543
+ * 'display', 'type' 'filter' 'sort'
9544
+ * @returns {*} The data for the cell from the given row's data
9545
+ * @default null
9546
+ */
9547
+ "fnGetData": null,
9548
+
9549
+ /**
9550
+ * Function to set data for a cell in the column. You should <b>never</b>
9551
+ * set the data directly to _aData internally in DataTables - always use
9552
+ * this method. It allows mData to function as required. This function
9553
+ * is automatically assigned by the column initialisation method
9554
+ * @type function
9555
+ * @param {array|object} oData The data array/object for the array
9556
+ * (i.e. aoData[]._aData)
9557
+ * @param {*} sValue Value to set
9558
+ * @default null
9559
+ */
9560
+ "fnSetData": null,
9561
+
9562
+ /**
9563
+ * Property to read the value for the cells in the column from the data
9564
+ * source array / object. If null, then the default content is used, if a
9565
+ * function is given then the return from the function is used.
9566
+ * @type function|int|string|null
9567
+ * @default null
9568
+ */
9569
+ "mData": null,
9570
+
9571
+ /**
9572
+ * Partner property to mData which is used (only when defined) to get
9573
+ * the data - i.e. it is basically the same as mData, but without the
9574
+ * 'set' option, and also the data fed to it is the result from mData.
9575
+ * This is the rendering method to match the data method of mData.
9576
+ * @type function|int|string|null
9577
+ * @default null
9578
+ */
9579
+ "mRender": null,
9580
+
9581
+ /**
9582
+ * Unique header TH/TD element for this column - this is what the sorting
9583
+ * listener is attached to (if sorting is enabled.)
9584
+ * @type node
9585
+ * @default null
9586
+ */
9587
+ "nTh": null,
9588
+
9589
+ /**
9590
+ * Unique footer TH/TD element for this column (if there is one). Not used
9591
+ * in DataTables as such, but can be used for plug-ins to reference the
9592
+ * footer for each column.
9593
+ * @type node
9594
+ * @default null
9595
+ */
9596
+ "nTf": null,
9597
+
9598
+ /**
9599
+ * The class to apply to all TD elements in the table's TBODY for the column
9600
+ * @type string
9601
+ * @default null
9602
+ */
9603
+ "sClass": null,
9604
+
9605
+ /**
9606
+ * When DataTables calculates the column widths to assign to each column,
9607
+ * it finds the longest string in each column and then constructs a
9608
+ * temporary table and reads the widths from that. The problem with this
9609
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
9610
+ * string - thus the calculation can go wrong (doing it properly and putting
9611
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
9612
+ * a "work around" we provide this option. It will append its value to the
9613
+ * text that is found to be the longest string for the column - i.e. padding.
9614
+ * @type string
9615
+ */
9616
+ "sContentPadding": null,
9617
+
9618
+ /**
9619
+ * Allows a default value to be given for a column's data, and will be used
9620
+ * whenever a null data source is encountered (this can be because mData
9621
+ * is set to null, or because the data source itself is null).
9622
+ * @type string
9623
+ * @default null
9624
+ */
9625
+ "sDefaultContent": null,
9626
+
9627
+ /**
9628
+ * Name for the column, allowing reference to the column by name as well as
9629
+ * by index (needs a lookup to work by name).
9630
+ * @type string
9631
+ */
9632
+ "sName": null,
9633
+
9634
+ /**
9635
+ * Custom sorting data type - defines which of the available plug-ins in
9636
+ * afnSortData the custom sorting will use - if any is defined.
9637
+ * @type string
9638
+ * @default std
9639
+ */
9640
+ "sSortDataType": 'std',
9641
+
9642
+ /**
9643
+ * Class to be applied to the header element when sorting on this column
9644
+ * @type string
9645
+ * @default null
9646
+ */
9647
+ "sSortingClass": null,
9648
+
9649
+ /**
9650
+ * Class to be applied to the header element when sorting on this column -
9651
+ * when jQuery UI theming is used.
9652
+ * @type string
9653
+ * @default null
9654
+ */
9655
+ "sSortingClassJUI": null,
9656
+
9657
+ /**
9658
+ * Title of the column - what is seen in the TH element (nTh).
9659
+ * @type string
9660
+ */
9661
+ "sTitle": null,
9662
+
9663
+ /**
9664
+ * Column sorting and filtering type
9665
+ * @type string
9666
+ * @default null
9667
+ */
9668
+ "sType": null,
9669
+
9670
+ /**
9671
+ * Width of the column
9672
+ * @type string
9673
+ * @default null
9674
+ */
9675
+ "sWidth": null,
9676
+
9677
+ /**
9678
+ * Width of the column when it was first "encountered"
9679
+ * @type string
9680
+ * @default null
9681
+ */
9682
+ "sWidthOrig": null
9683
+ };
9684
+
9685
+
9686
+ /*
9687
+ * Developer note: The properties of the object below are given in Hungarian
9688
+ * notation, that was used as the interface for DataTables prior to v1.10, however
9689
+ * from v1.10 onwards the primary interface is camel case. In order to avoid
9690
+ * breaking backwards compatibility utterly with this change, the Hungarian
9691
+ * version is still, internally the primary interface, but is is not documented
9692
+ * - hence the @name tags in each doc comment. This allows a Javascript function
9693
+ * to create a map from Hungarian notation to camel case (going the other direction
9694
+ * would require each property to be listed, which would at around 3K to the size
9695
+ * of DataTables, while this method is about a 0.5K hit.
9696
+ *
9697
+ * Ultimately this does pave the way for Hungarian notation to be dropped
9698
+ * completely, but that is a massive amount of work and will break current
9699
+ * installs (therefore is on-hold until v2).
9700
+ */
9701
+
9702
+ /**
9703
+ * Initialisation options that can be given to DataTables at initialisation
9704
+ * time.
9705
+ * @namespace
9706
+ */
9707
+ DataTable.defaults = {
9708
+ /**
9709
+ * An array of data to use for the table, passed in at initialisation which
9710
+ * will be used in preference to any data which is already in the DOM. This is
9711
+ * particularly useful for constructing tables purely in Javascript, for
9712
+ * example with a custom Ajax call.
9713
+ * @type array
9714
+ * @default null
9715
+ *
9716
+ * @dtopt Option
9717
+ * @name DataTable.defaults.data
9718
+ *
9719
+ * @example
9720
+ * // Using a 2D array data source
9721
+ * $(document).ready( function () {
9722
+ * $('#example').dataTable( {
9723
+ * "data": [
9724
+ * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9725
+ * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9726
+ * ],
9727
+ * "columns": [
9728
+ * { "title": "Engine" },
9729
+ * { "title": "Browser" },
9730
+ * { "title": "Platform" },
9731
+ * { "title": "Version" },
9732
+ * { "title": "Grade" }
9733
+ * ]
9734
+ * } );
9735
+ * } );
9736
+ *
9737
+ * @example
9738
+ * // Using an array of objects as a data source (`data`)
9739
+ * $(document).ready( function () {
9740
+ * $('#example').dataTable( {
9741
+ * "data": [
9742
+ * {
9743
+ * "engine": "Trident",
9744
+ * "browser": "Internet Explorer 4.0",
9745
+ * "platform": "Win 95+",
9746
+ * "version": 4,
9747
+ * "grade": "X"
9748
+ * },
9749
+ * {
9750
+ * "engine": "Trident",
9751
+ * "browser": "Internet Explorer 5.0",
9752
+ * "platform": "Win 95+",
9753
+ * "version": 5,
9754
+ * "grade": "C"
9755
+ * }
9756
+ * ],
9757
+ * "columns": [
9758
+ * { "title": "Engine", "data": "engine" },
9759
+ * { "title": "Browser", "data": "browser" },
9760
+ * { "title": "Platform", "data": "platform" },
9761
+ * { "title": "Version", "data": "version" },
9762
+ * { "title": "Grade", "data": "grade" }
9763
+ * ]
9764
+ * } );
9765
+ * } );
9766
+ */
9767
+ "aaData": null,
9768
+
9769
+ /**
9770
+ * If ordering is enabled, then DataTables will perform a first pass sort on
9771
+ * initialisation. You can define which column(s) the sort is performed
9772
+ * upon, and the sorting direction, with this variable. The `sorting` array
9773
+ * should contain an array for each column to be sorted initially containing
9774
+ * the column's index and a direction string ('asc' or 'desc').
9775
+ * @type array
9776
+ * @default [[0,'asc']]
9777
+ *
9778
+ * @dtopt Option
9779
+ * @name DataTable.defaults.order
9780
+ *
9781
+ * @example
9782
+ * // Sort by 3rd column first, and then 4th column
9783
+ * $(document).ready( function() {
9784
+ * $('#example').dataTable( {
9785
+ * "order": [[2,'asc'], [3,'desc']]
9786
+ * } );
9787
+ * } );
9788
+ *
9789
+ * // No initial sorting
9790
+ * $(document).ready( function() {
9791
+ * $('#example').dataTable( {
9792
+ * "order": []
9793
+ * } );
9794
+ * } );
9795
+ */
9796
+ "aaSorting": [[0, 'asc']],
9797
+
9798
+ /**
9799
+ * This parameter is basically identical to the `sorting` parameter, but
9800
+ * cannot be overridden by user interaction with the table. What this means
9801
+ * is that you could have a column (visible or hidden) which the sorting
9802
+ * will always be forced on first - any sorting after that (from the user)
9803
+ * will then be performed as required. This can be useful for grouping rows
9804
+ * together.
9805
+ * @type array
9806
+ * @default null
9807
+ *
9808
+ * @dtopt Option
9809
+ * @name DataTable.defaults.orderFixed
9810
+ *
9811
+ * @example
9812
+ * $(document).ready( function() {
9813
+ * $('#example').dataTable( {
9814
+ * "orderFixed": [[0,'asc']]
9815
+ * } );
9816
+ * } )
9817
+ */
9818
+ "aaSortingFixed": [],
9819
+
9820
+ /**
9821
+ * DataTables can be instructed to load data to display in the table from a
9822
+ * Ajax source. This option defines how that Ajax call is made and where to.
9823
+ *
9824
+ * The `ajax` property has three different modes of operation, depending on
9825
+ * how it is defined. These are:
9826
+ *
9827
+ * * `string` - Set the URL from where the data should be loaded from.
9828
+ * * `object` - Define properties for `jQuery.ajax`.
9829
+ * * `function` - Custom data get function
9830
+ *
9831
+ * `string`
9832
+ * --------
9833
+ *
9834
+ * As a string, the `ajax` property simply defines the URL from which
9835
+ * DataTables will load data.
9836
+ *
9837
+ * `object`
9838
+ * --------
9839
+ *
9840
+ * As an object, the parameters in the object are passed to
9841
+ * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
9842
+ * of the Ajax request. DataTables has a number of default parameters which
9843
+ * you can override using this option. Please refer to the jQuery
9844
+ * documentation for a full description of the options available, although
9845
+ * the following parameters provide additional options in DataTables or
9846
+ * require special consideration:
9847
+ *
9848
+ * * `data` - As with jQuery, `data` can be provided as an object, but it
9849
+ * can also be used as a function to manipulate the data DataTables sends
9850
+ * to the server. The function takes a single parameter, an object of
9851
+ * parameters with the values that DataTables has readied for sending. An
9852
+ * object may be returned which will be merged into the DataTables
9853
+ * defaults, or you can add the items to the object that was passed in and
9854
+ * not return anything from the function. This supersedes `fnServerParams`
9855
+ * from DataTables 1.9-.
9856
+ *
9857
+ * * `dataSrc` - By default DataTables will look for the property `data` (or
9858
+ * `aaData` for compatibility with DataTables 1.9-) when obtaining data
9859
+ * from an Ajax source or for server-side processing - this parameter
9860
+ * allows that property to be changed. You can use Javascript dotted
9861
+ * object notation to get a data source for multiple levels of nesting, or
9862
+ * it my be used as a function. As a function it takes a single parameter,
9863
+ * the JSON returned from the server, which can be manipulated as
9864
+ * required, with the returned value being that used by DataTables as the
9865
+ * data source for the table. This supersedes `sAjaxDataProp` from
9866
+ * DataTables 1.9-.
9867
+ *
9868
+ * * `success` - Should not be overridden it is used internally in
9869
+ * DataTables. To manipulate / transform the data returned by the server
9870
+ * use `ajax.dataSrc`, or use `ajax` as a function (see below).
9871
+ *
9872
+ * `function`
9873
+ * ----------
9874
+ *
9875
+ * As a function, making the Ajax call is left up to yourself allowing
9876
+ * complete control of the Ajax request. Indeed, if desired, a method other
9877
+ * than Ajax could be used to obtain the required data, such as Web storage
9878
+ * or an AIR database.
9879
+ *
9880
+ * The function is given four parameters and no return is required. The
9881
+ * parameters are:
9882
+ *
9883
+ * 1. _object_ - Data to send to the server
9884
+ * 2. _function_ - Callback function that must be executed when the required
9885
+ * data has been obtained. That data should be passed into the callback
9886
+ * as the only parameter
9887
+ * 3. _object_ - DataTables settings object for the table
9888
+ *
9889
+ * Note that this supersedes `fnServerData` from DataTables 1.9-.
9890
+ *
9891
+ * @type string|object|function
9892
+ * @default null
9893
+ *
9894
+ * @dtopt Option
9895
+ * @name DataTable.defaults.ajax
9896
+ * @since 1.10.0
9897
+ *
9898
+ * @example
9899
+ * // Get JSON data from a file via Ajax.
9900
+ * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
9901
+ * $('#example').dataTable( {
9902
+ * "ajax": "data.json"
9903
+ * } );
9904
+ *
9905
+ * @example
9906
+ * // Get JSON data from a file via Ajax, using `dataSrc` to change
9907
+ * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
9908
+ * $('#example').dataTable( {
9909
+ * "ajax": {
9910
+ * "url": "data.json",
9911
+ * "dataSrc": "tableData"
9912
+ * }
9913
+ * } );
9914
+ *
9915
+ * @example
9916
+ * // Get JSON data from a file via Ajax, using `dataSrc` to read data
9917
+ * // from a plain array rather than an array in an object
9918
+ * $('#example').dataTable( {
9919
+ * "ajax": {
9920
+ * "url": "data.json",
9921
+ * "dataSrc": ""
9922
+ * }
9923
+ * } );
9924
+ *
9925
+ * @example
9926
+ * // Manipulate the data returned from the server - add a link to data
9927
+ * // (note this can, should, be done using `render` for the column - this
9928
+ * // is just a simple example of how the data can be manipulated).
9929
+ * $('#example').dataTable( {
9930
+ * "ajax": {
9931
+ * "url": "data.json",
9932
+ * "dataSrc": function ( json ) {
9933
+ * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
9934
+ * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
9935
+ * }
9936
+ * return json;
9937
+ * }
9938
+ * }
9939
+ * } );
9940
+ *
9941
+ * @example
9942
+ * // Add data to the request
9943
+ * $('#example').dataTable( {
9944
+ * "ajax": {
9945
+ * "url": "data.json",
9946
+ * "data": function ( d ) {
9947
+ * return {
9948
+ * "extra_search": $('#extra').val()
9949
+ * };
9950
+ * }
9951
+ * }
9952
+ * } );
9953
+ *
9954
+ * @example
9955
+ * // Send request as POST
9956
+ * $('#example').dataTable( {
9957
+ * "ajax": {
9958
+ * "url": "data.json",
9959
+ * "type": "POST"
9960
+ * }
9961
+ * } );
9962
+ *
9963
+ * @example
9964
+ * // Get the data from localStorage (could interface with a form for
9965
+ * // adding, editing and removing rows).
9966
+ * $('#example').dataTable( {
9967
+ * "ajax": function (data, callback, settings) {
9968
+ * callback(
9969
+ * JSON.parse( localStorage.getItem('dataTablesData') )
9970
+ * );
9971
+ * }
9972
+ * } );
9973
+ */
9974
+ "ajax": null,
9975
+
9976
+ /**
9977
+ * This parameter allows you to readily specify the entries in the length drop
9978
+ * down menu that DataTables shows when pagination is enabled. It can be
9979
+ * either a 1D array of options which will be used for both the displayed
9980
+ * option and the value, or a 2D array which will use the array in the first
9981
+ * position as the value, and the array in the second position as the
9982
+ * displayed options (useful for language strings such as 'All').
9983
+ *
9984
+ * Note that the `pageLength` property will be automatically set to the
9985
+ * first value given in this array, unless `pageLength` is also provided.
9986
+ * @type array
9987
+ * @default [ 10, 25, 50, 100 ]
9988
+ *
9989
+ * @dtopt Option
9990
+ * @name DataTable.defaults.lengthMenu
9991
+ *
9992
+ * @example
9993
+ * $(document).ready( function() {
9994
+ * $('#example').dataTable( {
9995
+ * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
9996
+ * } );
9997
+ * } );
9998
+ */
9999
+ "aLengthMenu": [10, 25, 50, 100],
10000
+
10001
+ /**
10002
+ * The `columns` option in the initialisation parameter allows you to define
10003
+ * details about the way individual columns behave. For a full list of
10004
+ * column options that can be set, please see
10005
+ * {@link DataTable.defaults.column}. Note that if you use `columns` to
10006
+ * define your columns, you must have an entry in the array for every single
10007
+ * column that you have in your table (these can be null if you don't which
10008
+ * to specify any options).
10009
+ * @member
10010
+ *
10011
+ * @name DataTable.defaults.column
10012
+ */
10013
+ "aoColumns": null,
10014
+
10015
+ /**
10016
+ * Very similar to `columns`, `columnDefs` allows you to target a specific
10017
+ * column, multiple columns, or all columns, using the `targets` property of
10018
+ * each object in the array. This allows great flexibility when creating
10019
+ * tables, as the `columnDefs` arrays can be of any length, targeting the
10020
+ * columns you specifically want. `columnDefs` may use any of the column
10021
+ * options available: {@link DataTable.defaults.column}, but it _must_
10022
+ * have `targets` defined in each object in the array. Values in the `targets`
10023
+ * array may be:
10024
+ * <ul>
10025
+ * <li>a string - class name will be matched on the TH for the column</li>
10026
+ * <li>0 or a positive integer - column index counting from the left</li>
10027
+ * <li>a negative integer - column index counting from the right</li>
10028
+ * <li>the string "_all" - all columns (i.e. assign a default)</li>
10029
+ * </ul>
10030
+ * @member
10031
+ *
10032
+ * @name DataTable.defaults.columnDefs
10033
+ */
10034
+ "aoColumnDefs": null,
10035
+
10036
+ /**
10037
+ * Basically the same as `search`, this parameter defines the individual column
10038
+ * filtering state at initialisation time. The array must be of the same size
10039
+ * as the number of columns, and each element be an object with the parameters
10040
+ * `search` and `escapeRegex` (the latter is optional). 'null' is also
10041
+ * accepted and the default will be used.
10042
+ * @type array
10043
+ * @default []
10044
+ *
10045
+ * @dtopt Option
10046
+ * @name DataTable.defaults.searchCols
10047
+ *
10048
+ * @example
10049
+ * $(document).ready( function() {
10050
+ * $('#example').dataTable( {
10051
+ * "searchCols": [
10052
+ * null,
10053
+ * { "search": "My filter" },
10054
+ * null,
10055
+ * { "search": "^[0-9]", "escapeRegex": false }
10056
+ * ]
10057
+ * } );
10058
+ * } )
10059
+ */
10060
+ "aoSearchCols": [],
10061
+
10062
+ /**
10063
+ * An array of CSS classes that should be applied to displayed rows. This
10064
+ * array may be of any length, and DataTables will apply each class
10065
+ * sequentially, looping when required.
10066
+ * @type array
10067
+ * @default null <i>Will take the values determined by the `oClasses.stripe*`
10068
+ * options</i>
10069
+ *
10070
+ * @dtopt Option
10071
+ * @name DataTable.defaults.stripeClasses
10072
+ *
10073
+ * @example
10074
+ * $(document).ready( function() {
10075
+ * $('#example').dataTable( {
10076
+ * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10077
+ * } );
10078
+ * } )
10079
+ */
10080
+ "asStripeClasses": null,
10081
+
10082
+ /**
10083
+ * Enable or disable automatic column width calculation. This can be disabled
10084
+ * as an optimisation (it takes some time to calculate the widths) if the
10085
+ * tables widths are passed in using `columns`.
10086
+ * @type boolean
10087
+ * @default true
10088
+ *
10089
+ * @dtopt Features
10090
+ * @name DataTable.defaults.autoWidth
10091
+ *
10092
+ * @example
10093
+ * $(document).ready( function () {
10094
+ * $('#example').dataTable( {
10095
+ * "autoWidth": false
10096
+ * } );
10097
+ * } );
10098
+ */
10099
+ "bAutoWidth": true,
10100
+
10101
+ /**
10102
+ * Deferred rendering can provide DataTables with a huge speed boost when you
10103
+ * are using an Ajax or JS data source for the table. This option, when set to
10104
+ * true, will cause DataTables to defer the creation of the table elements for
10105
+ * each row until they are needed for a draw - saving a significant amount of
10106
+ * time.
10107
+ * @type boolean
10108
+ * @default false
10109
+ *
10110
+ * @dtopt Features
10111
+ * @name DataTable.defaults.deferRender
10112
+ *
10113
+ * @example
10114
+ * $(document).ready( function() {
10115
+ * $('#example').dataTable( {
10116
+ * "ajax": "sources/arrays.txt",
10117
+ * "deferRender": true
10118
+ * } );
10119
+ * } );
10120
+ */
10121
+ "bDeferRender": false,
10122
+
10123
+ /**
10124
+ * Replace a DataTable which matches the given selector and replace it with
10125
+ * one which has the properties of the new initialisation object passed. If no
10126
+ * table matches the selector, then the new DataTable will be constructed as
10127
+ * per normal.
10128
+ * @type boolean
10129
+ * @default false
10130
+ *
10131
+ * @dtopt Options
10132
+ * @name DataTable.defaults.destroy
10133
+ *
10134
+ * @example
10135
+ * $(document).ready( function() {
10136
+ * $('#example').dataTable( {
10137
+ * "srollY": "200px",
10138
+ * "paginate": false
10139
+ * } );
10140
+ *
10141
+ * // Some time later....
10142
+ * $('#example').dataTable( {
10143
+ * "filter": false,
10144
+ * "destroy": true
10145
+ * } );
10146
+ * } );
10147
+ */
10148
+ "bDestroy": false,
10149
+
10150
+ /**
10151
+ * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10152
+ * that it allows the end user to input multiple words (space separated) and
10153
+ * will match a row containing those words, even if not in the order that was
10154
+ * specified (this allow matching across multiple columns). Note that if you
10155
+ * wish to use filtering in DataTables this must remain 'true' - to remove the
10156
+ * default filtering input box and retain filtering abilities, please use
10157
+ * {@link DataTable.defaults.dom}.
10158
+ * @type boolean
10159
+ * @default true
10160
+ *
10161
+ * @dtopt Features
10162
+ * @name DataTable.defaults.searching
10163
+ *
10164
+ * @example
10165
+ * $(document).ready( function () {
10166
+ * $('#example').dataTable( {
10167
+ * "searching": false
10168
+ * } );
10169
+ * } );
10170
+ */
10171
+ "bFilter": true,
10172
+
10173
+ /**
10174
+ * Enable or disable the table information display. This shows information
10175
+ * about the data that is currently visible on the page, including information
10176
+ * about filtered data if that action is being performed.
10177
+ * @type boolean
10178
+ * @default true
10179
+ *
10180
+ * @dtopt Features
10181
+ * @name DataTable.defaults.info
10182
+ *
10183
+ * @example
10184
+ * $(document).ready( function () {
10185
+ * $('#example').dataTable( {
10186
+ * "info": false
10187
+ * } );
10188
+ * } );
10189
+ */
10190
+ "bInfo": true,
10191
+
10192
+ /**
10193
+ * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
10194
+ * slightly different and additional mark-up from what DataTables has
10195
+ * traditionally used).
10196
+ * @type boolean
10197
+ * @default false
10198
+ *
10199
+ * @dtopt Features
10200
+ * @name DataTable.defaults.jQueryUI
10201
+ *
10202
+ * @example
10203
+ * $(document).ready( function() {
10204
+ * $('#example').dataTable( {
10205
+ * "jQueryUI": true
10206
+ * } );
10207
+ * } );
10208
+ */
10209
+ "bJQueryUI": false,
10210
+
10211
+ /**
10212
+ * Allows the end user to select the size of a formatted page from a select
10213
+ * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10214
+ * @type boolean
10215
+ * @default true
10216
+ *
10217
+ * @dtopt Features
10218
+ * @name DataTable.defaults.lengthChange
10219
+ *
10220
+ * @example
10221
+ * $(document).ready( function () {
10222
+ * $('#example').dataTable( {
10223
+ * "lengthChange": false
10224
+ * } );
10225
+ * } );
10226
+ */
10227
+ "bLengthChange": true,
10228
+
10229
+ /**
10230
+ * Enable or disable pagination.
10231
+ * @type boolean
10232
+ * @default true
10233
+ *
10234
+ * @dtopt Features
10235
+ * @name DataTable.defaults.paging
10236
+ *
10237
+ * @example
10238
+ * $(document).ready( function () {
10239
+ * $('#example').dataTable( {
10240
+ * "paging": false
10241
+ * } );
10242
+ * } );
10243
+ */
10244
+ "bPaginate": true,
10245
+
10246
+ /**
10247
+ * Enable or disable the display of a 'processing' indicator when the table is
10248
+ * being processed (e.g. a sort). This is particularly useful for tables with
10249
+ * large amounts of data where it can take a noticeable amount of time to sort
10250
+ * the entries.
10251
+ * @type boolean
10252
+ * @default false
10253
+ *
10254
+ * @dtopt Features
10255
+ * @name DataTable.defaults.processing
10256
+ *
10257
+ * @example
10258
+ * $(document).ready( function () {
10259
+ * $('#example').dataTable( {
10260
+ * "processing": true
10261
+ * } );
10262
+ * } );
10263
+ */
10264
+ "bProcessing": false,
10265
+
10266
+ /**
10267
+ * Retrieve the DataTables object for the given selector. Note that if the
10268
+ * table has already been initialised, this parameter will cause DataTables
10269
+ * to simply return the object that has already been set up - it will not take
10270
+ * account of any changes you might have made to the initialisation object
10271
+ * passed to DataTables (setting this parameter to true is an acknowledgement
10272
+ * that you understand this). `destroy` can be used to reinitialise a table if
10273
+ * you need.
10274
+ * @type boolean
10275
+ * @default false
10276
+ *
10277
+ * @dtopt Options
10278
+ * @name DataTable.defaults.retrieve
10279
+ *
10280
+ * @example
10281
+ * $(document).ready( function() {
10282
+ * initTable();
10283
+ * tableActions();
10284
+ * } );
10285
+ *
10286
+ * function initTable ()
10287
+ * {
10288
+ * return $('#example').dataTable( {
10289
+ * "scrollY": "200px",
10290
+ * "paginate": false,
10291
+ * "retrieve": true
10292
+ * } );
10293
+ * }
10294
+ *
10295
+ * function tableActions ()
10296
+ * {
10297
+ * var table = initTable();
10298
+ * // perform API operations with oTable
10299
+ * }
10300
+ */
10301
+ "bRetrieve": false,
10302
+
10303
+ /**
10304
+ * When vertical (y) scrolling is enabled, DataTables will force the height of
10305
+ * the table's viewport to the given height at all times (useful for layout).
10306
+ * However, this can look odd when filtering data down to a small data set,
10307
+ * and the footer is left "floating" further down. This parameter (when
10308
+ * enabled) will cause DataTables to collapse the table's viewport down when
10309
+ * the result set will fit within the given Y height.
10310
+ * @type boolean
10311
+ * @default false
10312
+ *
10313
+ * @dtopt Options
10314
+ * @name DataTable.defaults.scrollCollapse
10315
+ *
10316
+ * @example
10317
+ * $(document).ready( function() {
10318
+ * $('#example').dataTable( {
10319
+ * "scrollY": "200",
10320
+ * "scrollCollapse": true
10321
+ * } );
10322
+ * } );
10323
+ */
10324
+ "bScrollCollapse": false,
10325
+
10326
+ /**
10327
+ * Configure DataTables to use server-side processing. Note that the
10328
+ * `ajax` parameter must also be given in order to give DataTables a
10329
+ * source to obtain the required data for each draw.
10330
+ * @type boolean
10331
+ * @default false
10332
+ *
10333
+ * @dtopt Features
10334
+ * @dtopt Server-side
10335
+ * @name DataTable.defaults.serverSide
10336
+ *
10337
+ * @example
10338
+ * $(document).ready( function () {
10339
+ * $('#example').dataTable( {
10340
+ * "serverSide": true,
10341
+ * "ajax": "xhr.php"
10342
+ * } );
10343
+ * } );
10344
+ */
10345
+ "bServerSide": false,
10346
+
10347
+ /**
10348
+ * Enable or disable sorting of columns. Sorting of individual columns can be
10349
+ * disabled by the `sortable` option for each column.
10350
+ * @type boolean
10351
+ * @default true
10352
+ *
10353
+ * @dtopt Features
10354
+ * @name DataTable.defaults.ordering
10355
+ *
10356
+ * @example
10357
+ * $(document).ready( function () {
10358
+ * $('#example').dataTable( {
10359
+ * "ordering": false
10360
+ * } );
10361
+ * } );
10362
+ */
10363
+ "bSort": true,
10364
+
10365
+ /**
10366
+ * Enable or display DataTables' ability to sort multiple columns at the
10367
+ * same time (activated by shift-click by the user).
10368
+ * @type boolean
10369
+ * @default true
10370
+ *
10371
+ * @dtopt Options
10372
+ * @name DataTable.defaults.orderMulti
10373
+ *
10374
+ * @example
10375
+ * // Disable multiple column sorting ability
10376
+ * $(document).ready( function () {
10377
+ * $('#example').dataTable( {
10378
+ * "orderMulti": false
10379
+ * } );
10380
+ * } );
10381
+ */
10382
+ "bSortMulti": true,
10383
+
10384
+ /**
10385
+ * Allows control over whether DataTables should use the top (true) unique
10386
+ * cell that is found for a single column, or the bottom (false - default).
10387
+ * This is useful when using complex headers.
10388
+ * @type boolean
10389
+ * @default false
10390
+ *
10391
+ * @dtopt Options
10392
+ * @name DataTable.defaults.orderCellsTop
10393
+ *
10394
+ * @example
10395
+ * $(document).ready( function() {
10396
+ * $('#example').dataTable( {
10397
+ * "orderCellsTop": true
10398
+ * } );
10399
+ * } );
10400
+ */
10401
+ "bSortCellsTop": false,
10402
+
10403
+ /**
10404
+ * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10405
+ * `sorting\_3` to the columns which are currently being sorted on. This is
10406
+ * presented as a feature switch as it can increase processing time (while
10407
+ * classes are removed and added) so for large data sets you might want to
10408
+ * turn this off.
10409
+ * @type boolean
10410
+ * @default true
10411
+ *
10412
+ * @dtopt Features
10413
+ * @name DataTable.defaults.orderClasses
10414
+ *
10415
+ * @example
10416
+ * $(document).ready( function () {
10417
+ * $('#example').dataTable( {
10418
+ * "orderClasses": false
10419
+ * } );
10420
+ * } );
10421
+ */
10422
+ "bSortClasses": true,
10423
+
10424
+ /**
10425
+ * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10426
+ * used to save table display information such as pagination information,
10427
+ * display length, filtering and sorting. As such when the end user reloads
10428
+ * the page the display display will match what thy had previously set up.
10429
+ *
10430
+ * Due to the use of `localStorage` the default state saving is not supported
10431
+ * in IE6 or 7. If state saving is required in those browsers, use
10432
+ * `stateSaveCallback` to provide a storage solution such as cookies.
10433
+ * @type boolean
10434
+ * @default false
10435
+ *
10436
+ * @dtopt Features
10437
+ * @name DataTable.defaults.stateSave
10438
+ *
10439
+ * @example
10440
+ * $(document).ready( function () {
10441
+ * $('#example').dataTable( {
10442
+ * "stateSave": true
10443
+ * } );
10444
+ * } );
10445
+ */
10446
+ "bStateSave": false,
10447
+
10448
+ /**
10449
+ * This function is called when a TR element is created (and all TD child
10450
+ * elements have been inserted), or registered if using a DOM source, allowing
10451
+ * manipulation of the TR element (adding classes etc).
10452
+ * @type function
10453
+ * @param {node} row "TR" element for the current row
10454
+ * @param {array} data Raw data array for this row
10455
+ * @param {int} dataIndex The index of this row in the internal aoData array
10456
+ *
10457
+ * @dtopt Callbacks
10458
+ * @name DataTable.defaults.createdRow
10459
+ *
10460
+ * @example
10461
+ * $(document).ready( function() {
10462
+ * $('#example').dataTable( {
10463
+ * "createdRow": function( row, data, dataIndex ) {
10464
+ * // Bold the grade for all 'A' grade browsers
10465
+ * if ( data[4] == "A" )
10466
+ * {
10467
+ * $('td:eq(4)', row).html( '<b>A</b>' );
10468
+ * }
10469
+ * }
10470
+ * } );
10471
+ * } );
10472
+ */
10473
+ "fnCreatedRow": null,
10474
+
10475
+ /**
10476
+ * This function is called on every 'draw' event, and allows you to
10477
+ * dynamically modify any aspect you want about the created DOM.
10478
+ * @type function
10479
+ * @param {object} settings DataTables settings object
10480
+ *
10481
+ * @dtopt Callbacks
10482
+ * @name DataTable.defaults.drawCallback
10483
+ *
10484
+ * @example
10485
+ * $(document).ready( function() {
10486
+ * $('#example').dataTable( {
10487
+ * "drawCallback": function( settings ) {
10488
+ * alert( 'DataTables has redrawn the table' );
10489
+ * }
10490
+ * } );
10491
+ * } );
10492
+ */
10493
+ "fnDrawCallback": null,
10494
+
10495
+ /**
10496
+ * Identical to fnHeaderCallback() but for the table footer this function
10497
+ * allows you to modify the table footer on every 'draw' event.
10498
+ * @type function
10499
+ * @param {node} foot "TR" element for the footer
10500
+ * @param {array} data Full table data (as derived from the original HTML)
10501
+ * @param {int} start Index for the current display starting point in the
10502
+ * display array
10503
+ * @param {int} end Index for the current display ending point in the
10504
+ * display array
10505
+ * @param {array int} display Index array to translate the visual position
10506
+ * to the full data array
10507
+ *
10508
+ * @dtopt Callbacks
10509
+ * @name DataTable.defaults.footerCallback
10510
+ *
10511
+ * @example
10512
+ * $(document).ready( function() {
10513
+ * $('#example').dataTable( {
10514
+ * "footerCallback": function( tfoot, data, start, end, display ) {
10515
+ * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10516
+ * }
10517
+ * } );
10518
+ * } )
10519
+ */
10520
+ "fnFooterCallback": null,
10521
+
10522
+ /**
10523
+ * When rendering large numbers in the information element for the table
10524
+ * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10525
+ * to have a comma separator for the 'thousands' units (e.g. 1 million is
10526
+ * rendered as "1,000,000") to help readability for the end user. This
10527
+ * function will override the default method DataTables uses.
10528
+ * @type function
10529
+ * @member
10530
+ * @param {int} toFormat number to be formatted
10531
+ * @returns {string} formatted string for DataTables to show the number
10532
+ *
10533
+ * @dtopt Callbacks
10534
+ * @name DataTable.defaults.formatNumber
10535
+ *
10536
+ * @example
10537
+ * // Format a number using a single quote for the separator (note that
10538
+ * // this can also be done with the language.thousands option)
10539
+ * $(document).ready( function() {
10540
+ * $('#example').dataTable( {
10541
+ * "formatNumber": function ( toFormat ) {
10542
+ * return toFormat.toString().replace(
10543
+ * /\B(?=(\d{3})+(?!\d))/g, "'"
10544
+ * );
10545
+ * };
10546
+ * } );
10547
+ * } );
10548
+ */
10549
+ "fnFormatNumber": function (toFormat) {
10550
+ return toFormat.toString().replace(
10551
+ /\B(?=(\d{3})+(?!\d))/g,
10552
+ this.oLanguage.sThousands
10553
+ );
10554
+ },
10555
+
10556
+ /**
10557
+ * This function is called on every 'draw' event, and allows you to
10558
+ * dynamically modify the header row. This can be used to calculate and
10559
+ * display useful information about the table.
10560
+ * @type function
10561
+ * @param {node} head "TR" element for the header
10562
+ * @param {array} data Full table data (as derived from the original HTML)
10563
+ * @param {int} start Index for the current display starting point in the
10564
+ * display array
10565
+ * @param {int} end Index for the current display ending point in the
10566
+ * display array
10567
+ * @param {array int} display Index array to translate the visual position
10568
+ * to the full data array
10569
+ *
10570
+ * @dtopt Callbacks
10571
+ * @name DataTable.defaults.headerCallback
10572
+ *
10573
+ * @example
10574
+ * $(document).ready( function() {
10575
+ * $('#example').dataTable( {
10576
+ * "fheaderCallback": function( head, data, start, end, display ) {
10577
+ * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10578
+ * }
10579
+ * } );
10580
+ * } )
10581
+ */
10582
+ "fnHeaderCallback": null,
10583
+
10584
+ /**
10585
+ * The information element can be used to convey information about the current
10586
+ * state of the table. Although the internationalisation options presented by
10587
+ * DataTables are quite capable of dealing with most customisations, there may
10588
+ * be times where you wish to customise the string further. This callback
10589
+ * allows you to do exactly that.
10590
+ * @type function
10591
+ * @param {object} oSettings DataTables settings object
10592
+ * @param {int} start Starting position in data for the draw
10593
+ * @param {int} end End position in data for the draw
10594
+ * @param {int} max Total number of rows in the table (regardless of
10595
+ * filtering)
10596
+ * @param {int} total Total number of rows in the data set, after filtering
10597
+ * @param {string} pre The string that DataTables has formatted using it's
10598
+ * own rules
10599
+ * @returns {string} The string to be displayed in the information element.
10600
+ *
10601
+ * @dtopt Callbacks
10602
+ * @name DataTable.defaults.infoCallback
10603
+ *
10604
+ * @example
10605
+ * $('#example').dataTable( {
10606
+ * "infoCallback": function( settings, start, end, max, total, pre ) {
10607
+ * return start +" to "+ end;
10608
+ * }
10609
+ * } );
10610
+ */
10611
+ "fnInfoCallback": null,
10612
+
10613
+ /**
10614
+ * Called when the table has been initialised. Normally DataTables will
10615
+ * initialise sequentially and there will be no need for this function,
10616
+ * however, this does not hold true when using external language information
10617
+ * since that is obtained using an async XHR call.
10618
+ * @type function
10619
+ * @param {object} settings DataTables settings object
10620
+ * @param {object} json The JSON object request from the server - only
10621
+ * present if client-side Ajax sourced data is used
10622
+ *
10623
+ * @dtopt Callbacks
10624
+ * @name DataTable.defaults.initComplete
10625
+ *
10626
+ * @example
10627
+ * $(document).ready( function() {
10628
+ * $('#example').dataTable( {
10629
+ * "initComplete": function(settings, json) {
10630
+ * alert( 'DataTables has finished its initialisation.' );
10631
+ * }
10632
+ * } );
10633
+ * } )
10634
+ */
10635
+ "fnInitComplete": null,
10636
+
10637
+ /**
10638
+ * Called at the very start of each table draw and can be used to cancel the
10639
+ * draw by returning false, any other return (including undefined) results in
10640
+ * the full draw occurring).
10641
+ * @type function
10642
+ * @param {object} settings DataTables settings object
10643
+ * @returns {boolean} False will cancel the draw, anything else (including no
10644
+ * return) will allow it to complete.
10645
+ *
10646
+ * @dtopt Callbacks
10647
+ * @name DataTable.defaults.preDrawCallback
10648
+ *
10649
+ * @example
10650
+ * $(document).ready( function() {
10651
+ * $('#example').dataTable( {
10652
+ * "preDrawCallback": function( settings ) {
10653
+ * if ( $('#test').val() == 1 ) {
10654
+ * return false;
10655
+ * }
10656
+ * }
10657
+ * } );
10658
+ * } );
10659
+ */
10660
+ "fnPreDrawCallback": null,
10661
+
10662
+ /**
10663
+ * This function allows you to 'post process' each row after it have been
10664
+ * generated for each table draw, but before it is rendered on screen. This
10665
+ * function might be used for setting the row class name etc.
10666
+ * @type function
10667
+ * @param {node} row "TR" element for the current row
10668
+ * @param {array} data Raw data array for this row
10669
+ * @param {int} displayIndex The display index for the current table draw
10670
+ * @param {int} displayIndexFull The index of the data in the full list of
10671
+ * rows (after filtering)
10672
+ *
10673
+ * @dtopt Callbacks
10674
+ * @name DataTable.defaults.rowCallback
10675
+ *
10676
+ * @example
10677
+ * $(document).ready( function() {
10678
+ * $('#example').dataTable( {
10679
+ * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10680
+ * // Bold the grade for all 'A' grade browsers
10681
+ * if ( data[4] == "A" ) {
10682
+ * $('td:eq(4)', row).html( '<b>A</b>' );
10683
+ * }
10684
+ * }
10685
+ * } );
10686
+ * } );
10687
+ */
10688
+ "fnRowCallback": null,
10689
+
10690
+ /**
10691
+ * __Deprecated__ The functionality provided by this parameter has now been
10692
+ * superseded by that provided through `ajax`, which should be used instead.
10693
+ *
10694
+ * This parameter allows you to override the default function which obtains
10695
+ * the data from the server so something more suitable for your application.
10696
+ * For example you could use POST data, or pull information from a Gears or
10697
+ * AIR database.
10698
+ * @type function
10699
+ * @member
10700
+ * @param {string} source HTTP source to obtain the data from (`ajax`)
10701
+ * @param {array} data A key/value pair object containing the data to send
10702
+ * to the server
10703
+ * @param {function} callback to be called on completion of the data get
10704
+ * process that will draw the data on the page.
10705
+ * @param {object} settings DataTables settings object
10706
+ *
10707
+ * @dtopt Callbacks
10708
+ * @dtopt Server-side
10709
+ * @name DataTable.defaults.serverData
10710
+ *
10711
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
10712
+ */
10713
+ "fnServerData": null,
10714
+
10715
+ /**
10716
+ * __Deprecated__ The functionality provided by this parameter has now been
10717
+ * superseded by that provided through `ajax`, which should be used instead.
10718
+ *
10719
+ * It is often useful to send extra data to the server when making an Ajax
10720
+ * request - for example custom filtering information, and this callback
10721
+ * function makes it trivial to send extra information to the server. The
10722
+ * passed in parameter is the data set that has been constructed by
10723
+ * DataTables, and you can add to this or modify it as you require.
10724
+ * @type function
10725
+ * @param {array} data Data array (array of objects which are name/value
10726
+ * pairs) that has been constructed by DataTables and will be sent to the
10727
+ * server. In the case of Ajax sourced data with server-side processing
10728
+ * this will be an empty array, for server-side processing there will be a
10729
+ * significant number of parameters!
10730
+ * @returns {undefined} Ensure that you modify the data array passed in,
10731
+ * as this is passed by reference.
10732
+ *
10733
+ * @dtopt Callbacks
10734
+ * @dtopt Server-side
10735
+ * @name DataTable.defaults.serverParams
10736
+ *
10737
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
10738
+ */
10739
+ "fnServerParams": null,
10740
+
10741
+ /**
10742
+ * Load the table state. With this function you can define from where, and how, the
10743
+ * state of a table is loaded. By default DataTables will load from `localStorage`
10744
+ * but you might wish to use a server-side database or cookies.
10745
+ * @type function
10746
+ * @member
10747
+ * @param {object} settings DataTables settings object
10748
+ * @param {object} callback Callback that can be executed when done. It
10749
+ * should be passed the loaded state object.
10750
+ * @return {object} The DataTables state object to be loaded
10751
+ *
10752
+ * @dtopt Callbacks
10753
+ * @name DataTable.defaults.stateLoadCallback
10754
+ *
10755
+ * @example
10756
+ * $(document).ready( function() {
10757
+ * $('#example').dataTable( {
10758
+ * "stateSave": true,
10759
+ * "stateLoadCallback": function (settings, callback) {
10760
+ * $.ajax( {
10761
+ * "url": "/state_load",
10762
+ * "dataType": "json",
10763
+ * "success": function (json) {
10764
+ * callback( json );
10765
+ * }
10766
+ * } );
10767
+ * }
10768
+ * } );
10769
+ * } );
10770
+ */
10771
+ "fnStateLoadCallback": function (settings) {
10772
+ try {
10773
+ return JSON.parse(
10774
+ (settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
10775
+ 'DataTables_' + settings.sInstance + '_' + location.pathname
10776
+ )
10777
+ );
10778
+ } catch (e) {
10779
+ }
10780
+ },
10781
+
10782
+ /**
10783
+ * Callback which allows modification of the saved state prior to loading that state.
10784
+ * This callback is called when the table is loading state from the stored data, but
10785
+ * prior to the settings object being modified by the saved state. Note that for
10786
+ * plug-in authors, you should use the `stateLoadParams` event to load parameters for
10787
+ * a plug-in.
10788
+ * @type function
10789
+ * @param {object} settings DataTables settings object
10790
+ * @param {object} data The state object that is to be loaded
10791
+ *
10792
+ * @dtopt Callbacks
10793
+ * @name DataTable.defaults.stateLoadParams
10794
+ *
10795
+ * @example
10796
+ * // Remove a saved filter, so filtering is never loaded
10797
+ * $(document).ready( function() {
10798
+ * $('#example').dataTable( {
10799
+ * "stateSave": true,
10800
+ * "stateLoadParams": function (settings, data) {
10801
+ * data.oSearch.sSearch = "";
10802
+ * }
10803
+ * } );
10804
+ * } );
10805
+ *
10806
+ * @example
10807
+ * // Disallow state loading by returning false
10808
+ * $(document).ready( function() {
10809
+ * $('#example').dataTable( {
10810
+ * "stateSave": true,
10811
+ * "stateLoadParams": function (settings, data) {
10812
+ * return false;
10813
+ * }
10814
+ * } );
10815
+ * } );
10816
+ */
10817
+ "fnStateLoadParams": null,
10818
+
10819
+ /**
10820
+ * Callback that is called when the state has been loaded from the state saving method
10821
+ * and the DataTables settings object has been modified as a result of the loaded state.
10822
+ * @type function
10823
+ * @param {object} settings DataTables settings object
10824
+ * @param {object} data The state object that was loaded
10825
+ *
10826
+ * @dtopt Callbacks
10827
+ * @name DataTable.defaults.stateLoaded
10828
+ *
10829
+ * @example
10830
+ * // Show an alert with the filtering value that was saved
10831
+ * $(document).ready( function() {
10832
+ * $('#example').dataTable( {
10833
+ * "stateSave": true,
10834
+ * "stateLoaded": function (settings, data) {
10835
+ * alert( 'Saved filter was: '+data.oSearch.sSearch );
10836
+ * }
10837
+ * } );
10838
+ * } );
10839
+ */
10840
+ "fnStateLoaded": null,
10841
+
10842
+ /**
10843
+ * Save the table state. This function allows you to define where and how the state
10844
+ * information for the table is stored By default DataTables will use `localStorage`
10845
+ * but you might wish to use a server-side database or cookies.
10846
+ * @type function
10847
+ * @member
10848
+ * @param {object} settings DataTables settings object
10849
+ * @param {object} data The state object to be saved
10850
+ *
10851
+ * @dtopt Callbacks
10852
+ * @name DataTable.defaults.stateSaveCallback
10853
+ *
10854
+ * @example
10855
+ * $(document).ready( function() {
10856
+ * $('#example').dataTable( {
10857
+ * "stateSave": true,
10858
+ * "stateSaveCallback": function (settings, data) {
10859
+ * // Send an Ajax request to the server with the state object
10860
+ * $.ajax( {
10861
+ * "url": "/state_save",
10862
+ * "data": data,
10863
+ * "dataType": "json",
10864
+ * "method": "POST"
10865
+ * "success": function () {}
10866
+ * } );
10867
+ * }
10868
+ * } );
10869
+ * } );
10870
+ */
10871
+ "fnStateSaveCallback": function (settings, data) {
10872
+ try {
10873
+ (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
10874
+ 'DataTables_' + settings.sInstance + '_' + location.pathname,
10875
+ JSON.stringify(data)
10876
+ );
10877
+ } catch (e) {
10878
+ }
10879
+ },
10880
+
10881
+ /**
10882
+ * Callback which allows modification of the state to be saved. Called when the table
10883
+ * has changed state a new state save is required. This method allows modification of
10884
+ * the state saving object prior to actually doing the save, including addition or
10885
+ * other state properties or modification. Note that for plug-in authors, you should
10886
+ * use the `stateSaveParams` event to save parameters for a plug-in.
10887
+ * @type function
10888
+ * @param {object} settings DataTables settings object
10889
+ * @param {object} data The state object to be saved
10890
+ *
10891
+ * @dtopt Callbacks
10892
+ * @name DataTable.defaults.stateSaveParams
10893
+ *
10894
+ * @example
10895
+ * // Remove a saved filter, so filtering is never saved
10896
+ * $(document).ready( function() {
10897
+ * $('#example').dataTable( {
10898
+ * "stateSave": true,
10899
+ * "stateSaveParams": function (settings, data) {
10900
+ * data.oSearch.sSearch = "";
10901
+ * }
10902
+ * } );
10903
+ * } );
10904
+ */
10905
+ "fnStateSaveParams": null,
10906
+
10907
+ /**
10908
+ * Duration for which the saved state information is considered valid. After this period
10909
+ * has elapsed the state will be returned to the default.
10910
+ * Value is given in seconds.
10911
+ * @type int
10912
+ * @default 7200 <i>(2 hours)</i>
10913
+ *
10914
+ * @dtopt Options
10915
+ * @name DataTable.defaults.stateDuration
10916
+ *
10917
+ * @example
10918
+ * $(document).ready( function() {
10919
+ * $('#example').dataTable( {
10920
+ * "stateDuration": 60*60*24; // 1 day
10921
+ * } );
10922
+ * } )
10923
+ */
10924
+ "iStateDuration": 7200,
10925
+
10926
+ /**
10927
+ * When enabled DataTables will not make a request to the server for the first
10928
+ * page draw - rather it will use the data already on the page (no sorting etc
10929
+ * will be applied to it), thus saving on an XHR at load time. `deferLoading`
10930
+ * is used to indicate that deferred loading is required, but it is also used
10931
+ * to tell DataTables how many records there are in the full table (allowing
10932
+ * the information element and pagination to be displayed correctly). In the case
10933
+ * where a filtering is applied to the table on initial load, this can be
10934
+ * indicated by giving the parameter as an array, where the first element is
10935
+ * the number of records available after filtering and the second element is the
10936
+ * number of records without filtering (allowing the table information element
10937
+ * to be shown correctly).
10938
+ * @type int | array
10939
+ * @default null
10940
+ *
10941
+ * @dtopt Options
10942
+ * @name DataTable.defaults.deferLoading
10943
+ *
10944
+ * @example
10945
+ * // 57 records available in the table, no filtering applied
10946
+ * $(document).ready( function() {
10947
+ * $('#example').dataTable( {
10948
+ * "serverSide": true,
10949
+ * "ajax": "scripts/server_processing.php",
10950
+ * "deferLoading": 57
10951
+ * } );
10952
+ * } );
10953
+ *
10954
+ * @example
10955
+ * // 57 records after filtering, 100 without filtering (an initial filter applied)
10956
+ * $(document).ready( function() {
10957
+ * $('#example').dataTable( {
10958
+ * "serverSide": true,
10959
+ * "ajax": "scripts/server_processing.php",
10960
+ * "deferLoading": [ 57, 100 ],
10961
+ * "search": {
10962
+ * "search": "my_filter"
10963
+ * }
10964
+ * } );
10965
+ * } );
10966
+ */
10967
+ "iDeferLoading": null,
10968
+
10969
+ /**
10970
+ * Number of rows to display on a single page when using pagination. If
10971
+ * feature enabled (`lengthChange`) then the end user will be able to override
10972
+ * this to a custom setting using a pop-up menu.
10973
+ * @type int
10974
+ * @default 10
10975
+ *
10976
+ * @dtopt Options
10977
+ * @name DataTable.defaults.pageLength
10978
+ *
10979
+ * @example
10980
+ * $(document).ready( function() {
10981
+ * $('#example').dataTable( {
10982
+ * "pageLength": 50
10983
+ * } );
10984
+ * } )
10985
+ */
10986
+ "iDisplayLength": 10,
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
+ * By default DataTables allows keyboard navigation of the table (sorting, paging,
11010
+ * and filtering) by adding a `tabindex` attribute to the required elements. This
11011
+ * allows you to tab through the controls and press the enter key to activate them.
11012
+ * The tabindex is default 0, meaning that the tab follows the flow of the document.
11013
+ * You can overrule this using this parameter if you wish. Use a value of -1 to
11014
+ * disable built-in keyboard navigation.
11015
+ * @type int
11016
+ * @default 0
11017
+ *
11018
+ * @dtopt Options
11019
+ * @name DataTable.defaults.tabIndex
11020
+ *
11021
+ * @example
11022
+ * $(document).ready( function() {
11023
+ * $('#example').dataTable( {
11024
+ * "tabIndex": 1
11025
+ * } );
11026
+ * } );
11027
+ */
11028
+ "iTabIndex": 0,
11029
+
11030
+ /**
11031
+ * Classes that DataTables assigns to the various components and features
11032
+ * that it adds to the HTML table. This allows classes to be configured
11033
+ * during initialisation in addition to through the static
11034
+ * {@link DataTable.ext.oStdClasses} object).
11035
+ * @namespace
11036
+ * @name DataTable.defaults.classes
11037
+ */
11038
+ "oClasses": {},
11039
+
11040
+ /**
11041
+ * All strings that DataTables uses in the user interface that it creates
11042
+ * are defined in this object, allowing you to modified them individually or
11043
+ * completely replace them all as required.
11044
+ * @namespace
11045
+ * @name DataTable.defaults.language
11046
+ */
11047
+ "oLanguage": {
11048
+ /**
11049
+ * Strings that are used for WAI-ARIA labels and controls only (these are not
11050
+ * actually visible on the page, but will be read by screenreaders, and thus
11051
+ * must be internationalised as well).
11052
+ * @namespace
11053
+ * @name DataTable.defaults.language.aria
11054
+ */
11055
+ "oAria": {
11056
+ /**
11057
+ * ARIA label that is added to the table headers when the column may be
11058
+ * sorted ascending by activing the column (click or return when focused).
11059
+ * Note that the column header is prefixed to this string.
11060
+ * @type string
11061
+ * @default : activate to sort column ascending
11062
+ *
11063
+ * @dtopt Language
11064
+ * @name DataTable.defaults.language.aria.sortAscending
11065
+ *
11066
+ * @example
11067
+ * $(document).ready( function() {
11068
+ * $('#example').dataTable( {
11069
+ * "language": {
11070
+ * "aria": {
11071
+ * "sortAscending": " - click/return to sort ascending"
11072
+ * }
11073
+ * }
11074
+ * } );
11075
+ * } );
11076
+ */
11077
+ "sSortAscending": ": activate to sort column ascending",
11078
+
11079
+ /**
11080
+ * ARIA label that is added to the table headers when the column may be
11081
+ * sorted descending by activing the column (click or return when focused).
11082
+ * Note that the column header is prefixed to this string.
11083
+ * @type string
11084
+ * @default : activate to sort column ascending
11085
+ *
11086
+ * @dtopt Language
11087
+ * @name DataTable.defaults.language.aria.sortDescending
11088
+ *
11089
+ * @example
11090
+ * $(document).ready( function() {
11091
+ * $('#example').dataTable( {
11092
+ * "language": {
11093
+ * "aria": {
11094
+ * "sortDescending": " - click/return to sort descending"
11095
+ * }
11096
+ * }
11097
+ * } );
11098
+ * } );
11099
+ */
11100
+ "sSortDescending": ": activate to sort column descending"
11101
+ },
11102
+
11103
+ /**
11104
+ * Pagination string used by DataTables for the built-in pagination
11105
+ * control types.
11106
+ * @namespace
11107
+ * @name DataTable.defaults.language.paginate
11108
+ */
11109
+ "oPaginate": {
11110
+ /**
11111
+ * Text to use when using the 'full_numbers' type of pagination for the
11112
+ * button to take the user to the first page.
11113
+ * @type string
11114
+ * @default First
11115
+ *
11116
+ * @dtopt Language
11117
+ * @name DataTable.defaults.language.paginate.first
11118
+ *
11119
+ * @example
11120
+ * $(document).ready( function() {
11121
+ * $('#example').dataTable( {
11122
+ * "language": {
11123
+ * "paginate": {
11124
+ * "first": "First page"
11125
+ * }
11126
+ * }
11127
+ * } );
11128
+ * } );
11129
+ */
11130
+ "sFirst": "First",
11131
+
11132
+ /**
11133
+ * Text to use when using the 'full_numbers' type of pagination for the
11134
+ * button to take the user to the last page.
11135
+ * @type string
11136
+ * @default Last
11137
+ *
11138
+ * @dtopt Language
11139
+ * @name DataTable.defaults.language.paginate.last
11140
+ *
11141
+ * @example
11142
+ * $(document).ready( function() {
11143
+ * $('#example').dataTable( {
11144
+ * "language": {
11145
+ * "paginate": {
11146
+ * "last": "Last page"
11147
+ * }
11148
+ * }
11149
+ * } );
11150
+ * } );
11151
+ */
11152
+ "sLast": "Last",
11153
+
11154
+ /**
11155
+ * Text to use for the 'next' pagination button (to take the user to the
11156
+ * next page).
11157
+ * @type string
11158
+ * @default Next
11159
+ *
11160
+ * @dtopt Language
11161
+ * @name DataTable.defaults.language.paginate.next
11162
+ *
11163
+ * @example
11164
+ * $(document).ready( function() {
11165
+ * $('#example').dataTable( {
11166
+ * "language": {
11167
+ * "paginate": {
11168
+ * "next": "Next page"
11169
+ * }
11170
+ * }
11171
+ * } );
11172
+ * } );
11173
+ */
11174
+ "sNext": "Next",
11175
+
11176
+ /**
11177
+ * Text to use for the 'previous' pagination button (to take the user to
11178
+ * the previous page).
11179
+ * @type string
11180
+ * @default Previous
11181
+ *
11182
+ * @dtopt Language
11183
+ * @name DataTable.defaults.language.paginate.previous
11184
+ *
11185
+ * @example
11186
+ * $(document).ready( function() {
11187
+ * $('#example').dataTable( {
11188
+ * "language": {
11189
+ * "paginate": {
11190
+ * "previous": "Previous page"
11191
+ * }
11192
+ * }
11193
+ * } );
11194
+ * } );
11195
+ */
11196
+ "sPrevious": "Previous"
11197
+ },
11198
+
11199
+ /**
11200
+ * This string is shown in preference to `zeroRecords` when the table is
11201
+ * empty of data (regardless of filtering). Note that this is an optional
11202
+ * parameter - if it is not given, the value of `zeroRecords` will be used
11203
+ * instead (either the default or given value).
11204
+ * @type string
11205
+ * @default No data available in table
11206
+ *
11207
+ * @dtopt Language
11208
+ * @name DataTable.defaults.language.emptyTable
11209
+ *
11210
+ * @example
11211
+ * $(document).ready( function() {
11212
+ * $('#example').dataTable( {
11213
+ * "language": {
11214
+ * "emptyTable": "No data available in table"
11215
+ * }
11216
+ * } );
11217
+ * } );
11218
+ */
11219
+ "sEmptyTable": "No data available in table",
11220
+
11221
+ /**
11222
+ * This string gives information to the end user about the information
11223
+ * that is current on display on the page. The following tokens can be
11224
+ * used in the string and will be dynamically replaced as the table
11225
+ * display updates. This tokens can be placed anywhere in the string, or
11226
+ * removed as needed by the language requires:
11227
+ *
11228
+ * * `\_START\_` - Display index of the first record on the current page
11229
+ * * `\_END\_` - Display index of the last record on the current page
11230
+ * * `\_TOTAL\_` - Number of records in the table after filtering
11231
+ * * `\_MAX\_` - Number of records in the table without filtering
11232
+ * * `\_PAGE\_` - Current page number
11233
+ * * `\_PAGES\_` - Total number of pages of data in the table
11234
+ *
11235
+ * @type string
11236
+ * @default Showing _START_ to _END_ of _TOTAL_ entries
11237
+ *
11238
+ * @dtopt Language
11239
+ * @name DataTable.defaults.language.info
11240
+ *
11241
+ * @example
11242
+ * $(document).ready( function() {
11243
+ * $('#example').dataTable( {
11244
+ * "language": {
11245
+ * "info": "Showing page _PAGE_ of _PAGES_"
11246
+ * }
11247
+ * } );
11248
+ * } );
11249
+ */
11250
+ "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11251
+
11252
+ /**
11253
+ * Display information string for when the table is empty. Typically the
11254
+ * format of this string should match `info`.
11255
+ * @type string
11256
+ * @default Showing 0 to 0 of 0 entries
11257
+ *
11258
+ * @dtopt Language
11259
+ * @name DataTable.defaults.language.infoEmpty
11260
+ *
11261
+ * @example
11262
+ * $(document).ready( function() {
11263
+ * $('#example').dataTable( {
11264
+ * "language": {
11265
+ * "infoEmpty": "No entries to show"
11266
+ * }
11267
+ * } );
11268
+ * } );
11269
+ */
11270
+ "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11271
+
11272
+ /**
11273
+ * When a user filters the information in a table, this string is appended
11274
+ * to the information (`info`) to give an idea of how strong the filtering
11275
+ * is. The variable _MAX_ is dynamically updated.
11276
+ * @type string
11277
+ * @default (filtered from _MAX_ total entries)
11278
+ *
11279
+ * @dtopt Language
11280
+ * @name DataTable.defaults.language.infoFiltered
11281
+ *
11282
+ * @example
11283
+ * $(document).ready( function() {
11284
+ * $('#example').dataTable( {
11285
+ * "language": {
11286
+ * "infoFiltered": " - filtering from _MAX_ records"
11287
+ * }
11288
+ * } );
11289
+ * } );
11290
+ */
11291
+ "sInfoFiltered": "(filtered from _MAX_ total entries)",
11292
+
11293
+ /**
11294
+ * If can be useful to append extra information to the info string at times,
11295
+ * and this variable does exactly that. This information will be appended to
11296
+ * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11297
+ * being used) at all times.
11298
+ * @type string
11299
+ * @default <i>Empty string</i>
11300
+ *
11301
+ * @dtopt Language
11302
+ * @name DataTable.defaults.language.infoPostFix
11303
+ *
11304
+ * @example
11305
+ * $(document).ready( function() {
11306
+ * $('#example').dataTable( {
11307
+ * "language": {
11308
+ * "infoPostFix": "All records shown are derived from real information."
11309
+ * }
11310
+ * } );
11311
+ * } );
11312
+ */
11313
+ "sInfoPostFix": "",
11314
+
11315
+ /**
11316
+ * This decimal place operator is a little different from the other
11317
+ * language options since DataTables doesn't output floating point
11318
+ * numbers, so it won't ever use this for display of a number. Rather,
11319
+ * what this parameter does is modify the sort methods of the table so
11320
+ * that numbers which are in a format which has a character other than
11321
+ * a period (`.`) as a decimal place will be sorted numerically.
11322
+ *
11323
+ * Note that numbers with different decimal places cannot be shown in
11324
+ * the same table and still be sortable, the table must be consistent.
11325
+ * However, multiple different tables on the page can use different
11326
+ * decimal place characters.
11327
+ * @type string
11328
+ * @default
11329
+ *
11330
+ * @dtopt Language
11331
+ * @name DataTable.defaults.language.decimal
11332
+ *
11333
+ * @example
11334
+ * $(document).ready( function() {
11335
+ * $('#example').dataTable( {
11336
+ * "language": {
11337
+ * "decimal": ","
11338
+ * "thousands": "."
11339
+ * }
11340
+ * } );
11341
+ * } );
11342
+ */
11343
+ "sDecimal": "",
11344
+
11345
+ /**
11346
+ * DataTables has a build in number formatter (`formatNumber`) which is
11347
+ * used to format large numbers that are used in the table information.
11348
+ * By default a comma is used, but this can be trivially changed to any
11349
+ * character you wish with this parameter.
11350
+ * @type string
11351
+ * @default ,
11352
+ *
11353
+ * @dtopt Language
11354
+ * @name DataTable.defaults.language.thousands
11355
+ *
11356
+ * @example
11357
+ * $(document).ready( function() {
11358
+ * $('#example').dataTable( {
11359
+ * "language": {
11360
+ * "thousands": "'"
11361
+ * }
11362
+ * } );
11363
+ * } );
11364
+ */
11365
+ "sThousands": ",",
11366
+
11367
+ /**
11368
+ * Detail the action that will be taken when the drop down menu for the
11369
+ * pagination length option is changed. The '_MENU_' variable is replaced
11370
+ * with a default select list of 10, 25, 50 and 100, and can be replaced
11371
+ * with a custom select box if required.
11372
+ * @type string
11373
+ * @default Show _MENU_ entries
11374
+ *
11375
+ * @dtopt Language
11376
+ * @name DataTable.defaults.language.lengthMenu
11377
+ *
11378
+ * @example
11379
+ * // Language change only
11380
+ * $(document).ready( function() {
11381
+ * $('#example').dataTable( {
11382
+ * "language": {
11383
+ * "lengthMenu": "Display _MENU_ records"
11384
+ * }
11385
+ * } );
11386
+ * } );
11387
+ *
11388
+ * @example
11389
+ * // Language and options change
11390
+ * $(document).ready( function() {
11391
+ * $('#example').dataTable( {
11392
+ * "language": {
11393
+ * "lengthMenu": 'Display <select>'+
11394
+ * '<option value="10">10</option>'+
11395
+ * '<option value="20">20</option>'+
11396
+ * '<option value="30">30</option>'+
11397
+ * '<option value="40">40</option>'+
11398
+ * '<option value="50">50</option>'+
11399
+ * '<option value="-1">All</option>'+
11400
+ * '</select> records'
11401
+ * }
11402
+ * } );
11403
+ * } );
11404
+ */
11405
+ "sLengthMenu": "Show _MENU_ entries",
11406
+
11407
+ /**
11408
+ * When using Ajax sourced data and during the first draw when DataTables is
11409
+ * gathering the data, this message is shown in an empty row in the table to
11410
+ * indicate to the end user the the data is being loaded. Note that this
11411
+ * parameter is not used when loading data by server-side processing, just
11412
+ * Ajax sourced data with client-side processing.
11413
+ * @type string
11414
+ * @default Loading...
11415
+ *
11416
+ * @dtopt Language
11417
+ * @name DataTable.defaults.language.loadingRecords
11418
+ *
11419
+ * @example
11420
+ * $(document).ready( function() {
11421
+ * $('#example').dataTable( {
11422
+ * "language": {
11423
+ * "loadingRecords": "Please wait - loading..."
11424
+ * }
11425
+ * } );
11426
+ * } );
11427
+ */
11428
+ "sLoadingRecords": "Loading...",
11429
+
11430
+ /**
11431
+ * Text which is displayed when the table is processing a user action
11432
+ * (usually a sort command or similar).
11433
+ * @type string
11434
+ * @default Processing...
11435
+ *
11436
+ * @dtopt Language
11437
+ * @name DataTable.defaults.language.processing
11438
+ *
11439
+ * @example
11440
+ * $(document).ready( function() {
11441
+ * $('#example').dataTable( {
11442
+ * "language": {
11443
+ * "processing": "DataTables is currently busy"
11444
+ * }
11445
+ * } );
11446
+ * } );
11447
+ */
11448
+ "sProcessing": "Processing...",
11449
+
11450
+ /**
11451
+ * Details the actions that will be taken when the user types into the
11452
+ * filtering input text box. The variable "_INPUT_", if used in the string,
11453
+ * is replaced with the HTML text box for the filtering input allowing
11454
+ * control over where it appears in the string. If "_INPUT_" is not given
11455
+ * then the input box is appended to the string automatically.
11456
+ * @type string
11457
+ * @default Search:
11458
+ *
11459
+ * @dtopt Language
11460
+ * @name DataTable.defaults.language.search
11461
+ *
11462
+ * @example
11463
+ * // Input text box will be appended at the end automatically
11464
+ * $(document).ready( function() {
11465
+ * $('#example').dataTable( {
11466
+ * "language": {
11467
+ * "search": "Filter records:"
11468
+ * }
11469
+ * } );
11470
+ * } );
11471
+ *
11472
+ * @example
11473
+ * // Specify where the filter should appear
11474
+ * $(document).ready( function() {
11475
+ * $('#example').dataTable( {
11476
+ * "language": {
11477
+ * "search": "Apply filter _INPUT_ to table"
11478
+ * }
11479
+ * } );
11480
+ * } );
11481
+ */
11482
+ "sSearch": "Search:",
11483
+
11484
+ /**
11485
+ * Assign a `placeholder` attribute to the search `input` element
11486
+ * @type string
11487
+ * @default
11488
+ *
11489
+ * @dtopt Language
11490
+ * @name DataTable.defaults.language.searchPlaceholder
11491
+ */
11492
+ "sSearchPlaceholder": "",
11493
+
11494
+ /**
11495
+ * All of the language information can be stored in a file on the
11496
+ * server-side, which DataTables will look up if this parameter is passed.
11497
+ * It must store the URL of the language file, which is in a JSON format,
11498
+ * and the object has the same properties as the oLanguage object in the
11499
+ * initialiser object (i.e. the above parameters). Please refer to one of
11500
+ * the example language files to see how this works in action.
11501
+ * @type string
11502
+ * @default <i>Empty string - i.e. disabled</i>
11503
+ *
11504
+ * @dtopt Language
11505
+ * @name DataTable.defaults.language.url
11506
+ *
11507
+ * @example
11508
+ * $(document).ready( function() {
11509
+ * $('#example').dataTable( {
11510
+ * "language": {
11511
+ * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11512
+ * }
11513
+ * } );
11514
+ * } );
11515
+ */
11516
+ "sUrl": "",
11517
+
11518
+ /**
11519
+ * Text shown inside the table records when the is no information to be
11520
+ * displayed after filtering. `emptyTable` is shown when there is simply no
11521
+ * information in the table at all (regardless of filtering).
11522
+ * @type string
11523
+ * @default No matching records found
11524
+ *
11525
+ * @dtopt Language
11526
+ * @name DataTable.defaults.language.zeroRecords
11527
+ *
11528
+ * @example
11529
+ * $(document).ready( function() {
11530
+ * $('#example').dataTable( {
11531
+ * "language": {
11532
+ * "zeroRecords": "No records to display"
11533
+ * }
11534
+ * } );
11535
+ * } );
11536
+ */
11537
+ "sZeroRecords": "No matching records found"
11538
+ },
11539
+
11540
+ /**
11541
+ * This parameter allows you to have define the global filtering state at
11542
+ * initialisation time. As an object the `search` parameter must be
11543
+ * defined, but all other parameters are optional. When `regex` is true,
11544
+ * the search string will be treated as a regular expression, when false
11545
+ * (default) it will be treated as a straight string. When `smart`
11546
+ * DataTables will use it's smart filtering methods (to word match at
11547
+ * any point in the data), when false this will not be done.
11548
+ * @namespace
11549
+ * @extends DataTable.models.oSearch
11550
+ *
11551
+ * @dtopt Options
11552
+ * @name DataTable.defaults.search
11553
+ *
11554
+ * @example
11555
+ * $(document).ready( function() {
11556
+ * $('#example').dataTable( {
11557
+ * "search": {"search": "Initial search"}
11558
+ * } );
11559
+ * } )
11560
+ */
11561
+ "oSearch": $.extend({}, DataTable.models.oSearch),
11562
+
11563
+ /**
11564
+ * __Deprecated__ The functionality provided by this parameter has now been
11565
+ * superseded by that provided through `ajax`, which should be used instead.
11566
+ *
11567
+ * By default DataTables will look for the property `data` (or `aaData` for
11568
+ * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11569
+ * source or for server-side processing - this parameter allows that
11570
+ * property to be changed. You can use Javascript dotted object notation to
11571
+ * get a data source for multiple levels of nesting.
11572
+ * @type string
11573
+ * @default data
11574
+ *
11575
+ * @dtopt Options
11576
+ * @dtopt Server-side
11577
+ * @name DataTable.defaults.ajaxDataProp
11578
+ *
11579
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11580
+ */
11581
+ "sAjaxDataProp": "data",
11582
+
11583
+ /**
11584
+ * __Deprecated__ The functionality provided by this parameter has now been
11585
+ * superseded by that provided through `ajax`, which should be used instead.
11586
+ *
11587
+ * You can instruct DataTables to load data from an external
11588
+ * source using this parameter (use aData if you want to pass data in you
11589
+ * already have). Simply provide a url a JSON object can be obtained from.
11590
+ * @type string
11591
+ * @default null
11592
+ *
11593
+ * @dtopt Options
11594
+ * @dtopt Server-side
11595
+ * @name DataTable.defaults.ajaxSource
11596
+ *
11597
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11598
+ */
11599
+ "sAjaxSource": null,
11600
+
11601
+ /**
11602
+ * This initialisation variable allows you to specify exactly where in the
11603
+ * DOM you want DataTables to inject the various controls it adds to the page
11604
+ * (for example you might want the pagination controls at the top of the
11605
+ * table). DIV elements (with or without a custom class) can also be added to
11606
+ * aid styling. The follow syntax is used:
11607
+ * <ul>
11608
+ * <li>The following options are allowed:
11609
+ * <ul>
11610
+ * <li>'l' - Length changing</li>
11611
+ * <li>'f' - Filtering input</li>
11612
+ * <li>'t' - The table!</li>
11613
+ * <li>'i' - Information</li>
11614
+ * <li>'p' - Pagination</li>
11615
+ * <li>'r' - pRocessing</li>
11616
+ * </ul>
11617
+ * </li>
11618
+ * <li>The following constants are allowed:
11619
+ * <ul>
11620
+ * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11621
+ * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11622
+ * </ul>
11623
+ * </li>
11624
+ * <li>The following syntax is expected:
11625
+ * <ul>
11626
+ * <li>'&lt;' and '&gt;' - div elements</li>
11627
+ * <li>'&lt;"class" and '&gt;' - div with a class</li>
11628
+ * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11629
+ * </ul>
11630
+ * </li>
11631
+ * <li>Examples:
11632
+ * <ul>
11633
+ * <li>'&lt;"wrapper"flipt&gt;'</li>
11634
+ * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11635
+ * </ul>
11636
+ * </li>
11637
+ * </ul>
11638
+ * @type string
11639
+ * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11640
+ * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11641
+ *
11642
+ * @dtopt Options
11643
+ * @name DataTable.defaults.dom
11644
+ *
11645
+ * @example
11646
+ * $(document).ready( function() {
11647
+ * $('#example').dataTable( {
11648
+ * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11649
+ * } );
11650
+ * } );
11651
+ */
11652
+ "sDom": "lfrtip",
11653
+
11654
+ /**
11655
+ * Search delay option. This will throttle full table searches that use the
11656
+ * DataTables provided search input element (it does not effect calls to
11657
+ * `dt-api search()`, providing a delay before the search is made.
11658
+ * @type integer
11659
+ * @default 0
11660
+ *
11661
+ * @dtopt Options
11662
+ * @name DataTable.defaults.searchDelay
11663
+ *
11664
+ * @example
11665
+ * $(document).ready( function() {
11666
+ * $('#example').dataTable( {
11667
+ * "searchDelay": 200
11668
+ * } );
11669
+ * } )
11670
+ */
11671
+ "searchDelay": null,
11672
+
11673
+ /**
11674
+ * DataTables features six different built-in options for the buttons to
11675
+ * display for pagination control:
11676
+ *
11677
+ * * `numbers` - Page number buttons only
11678
+ * * `simple` - 'Previous' and 'Next' buttons only
11679
+ * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11680
+ * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11681
+ * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
11682
+ * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
11683
+ *
11684
+ * Further methods can be added using {@link DataTable.ext.oPagination}.
11685
+ * @type string
11686
+ * @default simple_numbers
11687
+ *
11688
+ * @dtopt Options
11689
+ * @name DataTable.defaults.pagingType
11690
+ *
11691
+ * @example
11692
+ * $(document).ready( function() {
11693
+ * $('#example').dataTable( {
11694
+ * "pagingType": "full_numbers"
11695
+ * } );
11696
+ * } )
11697
+ */
11698
+ "sPaginationType": "simple_numbers",
11699
+
11700
+ /**
11701
+ * Enable horizontal scrolling. When a table is too wide to fit into a
11702
+ * certain layout, or you have a large number of columns in the table, you
11703
+ * can enable x-scrolling to show the table in a viewport, which can be
11704
+ * scrolled. This property can be `true` which will allow the table to
11705
+ * scroll horizontally when needed, or any CSS unit, or a number (in which
11706
+ * case it will be treated as a pixel measurement). Setting as simply `true`
11707
+ * is recommended.
11708
+ * @type boolean|string
11709
+ * @default <i>blank string - i.e. disabled</i>
11710
+ *
11711
+ * @dtopt Features
11712
+ * @name DataTable.defaults.scrollX
11713
+ *
11714
+ * @example
11715
+ * $(document).ready( function() {
11716
+ * $('#example').dataTable( {
11717
+ * "scrollX": true,
11718
+ * "scrollCollapse": true
11719
+ * } );
11720
+ * } );
11721
+ */
11722
+ "sScrollX": "",
11723
+
11724
+ /**
11725
+ * This property can be used to force a DataTable to use more width than it
11726
+ * might otherwise do when x-scrolling is enabled. For example if you have a
11727
+ * table which requires to be well spaced, this parameter is useful for
11728
+ * "over-sizing" the table, and thus forcing scrolling. This property can by
11729
+ * any CSS unit, or a number (in which case it will be treated as a pixel
11730
+ * measurement).
11731
+ * @type string
11732
+ * @default <i>blank string - i.e. disabled</i>
11733
+ *
11734
+ * @dtopt Options
11735
+ * @name DataTable.defaults.scrollXInner
11736
+ *
11737
+ * @example
11738
+ * $(document).ready( function() {
11739
+ * $('#example').dataTable( {
11740
+ * "scrollX": "100%",
11741
+ * "scrollXInner": "110%"
11742
+ * } );
11743
+ * } );
11744
+ */
11745
+ "sScrollXInner": "",
11746
+
11747
+ /**
11748
+ * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
11749
+ * to the given height, and enable scrolling for any data which overflows the
11750
+ * current viewport. This can be used as an alternative to paging to display
11751
+ * a lot of data in a small area (although paging and scrolling can both be
11752
+ * enabled at the same time). This property can be any CSS unit, or a number
11753
+ * (in which case it will be treated as a pixel measurement).
11754
+ * @type string
11755
+ * @default <i>blank string - i.e. disabled</i>
11756
+ *
11757
+ * @dtopt Features
11758
+ * @name DataTable.defaults.scrollY
11759
+ *
11760
+ * @example
11761
+ * $(document).ready( function() {
11762
+ * $('#example').dataTable( {
11763
+ * "scrollY": "200px",
11764
+ * "paginate": false
11765
+ * } );
11766
+ * } );
11767
+ */
11768
+ "sScrollY": "",
11769
+
11770
+ /**
11771
+ * __Deprecated__ The functionality provided by this parameter has now been
11772
+ * superseded by that provided through `ajax`, which should be used instead.
11773
+ *
11774
+ * Set the HTTP method that is used to make the Ajax call for server-side
11775
+ * processing or Ajax sourced data.
11776
+ * @type string
11777
+ * @default GET
11778
+ *
11779
+ * @dtopt Options
11780
+ * @dtopt Server-side
11781
+ * @name DataTable.defaults.serverMethod
11782
+ *
11783
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11784
+ */
11785
+ "sServerMethod": "GET",
11786
+
11787
+ /**
11788
+ * DataTables makes use of renderers when displaying HTML elements for
11789
+ * a table. These renderers can be added or modified by plug-ins to
11790
+ * generate suitable mark-up for a site. For example the Bootstrap
11791
+ * integration plug-in for DataTables uses a paging button renderer to
11792
+ * display pagination buttons in the mark-up required by Bootstrap.
11793
+ *
11794
+ * For further information about the renderers available see
11795
+ * DataTable.ext.renderer
11796
+ * @type string|object
11797
+ * @default null
11798
+ *
11799
+ * @name DataTable.defaults.renderer
11800
+ *
11801
+ */
11802
+ "renderer": null,
11803
+
11804
+ /**
11805
+ * Set the data property name that DataTables should use to get a row's id
11806
+ * to set as the `id` property in the node.
11807
+ * @type string
11808
+ * @default DT_RowId
11809
+ *
11810
+ * @name DataTable.defaults.rowId
11811
+ */
11812
+ "rowId": "DT_RowId"
11813
+ };
11814
+
11815
+ _fnHungarianMap(DataTable.defaults);
11816
+
11817
+
11818
+
11819
+ /*
11820
+ * Developer note - See note in model.defaults.js about the use of Hungarian
11821
+ * notation and camel case.
11822
+ */
11823
+
11824
+ /**
11825
+ * Column options that can be given to DataTables at initialisation time.
11826
+ * @namespace
11827
+ */
11828
+ DataTable.defaults.column = {
11829
+ /**
11830
+ * Define which column(s) an order will occur on for this column. This
11831
+ * allows a column's ordering to take multiple columns into account when
11832
+ * doing a sort or use the data from a different column. For example first
11833
+ * name / last name columns make sense to do a multi-column sort over the
11834
+ * two columns.
11835
+ * @type array|int
11836
+ * @default null <i>Takes the value of the column index automatically</i>
11837
+ *
11838
+ * @name DataTable.defaults.column.orderData
11839
+ * @dtopt Columns
11840
+ *
11841
+ * @example
11842
+ * // Using `columnDefs`
11843
+ * $(document).ready( function() {
11844
+ * $('#example').dataTable( {
11845
+ * "columnDefs": [
11846
+ * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
11847
+ * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
11848
+ * { "orderData": 2, "targets": [ 2 ] }
11849
+ * ]
11850
+ * } );
11851
+ * } );
11852
+ *
11853
+ * @example
11854
+ * // Using `columns`
11855
+ * $(document).ready( function() {
11856
+ * $('#example').dataTable( {
11857
+ * "columns": [
11858
+ * { "orderData": [ 0, 1 ] },
11859
+ * { "orderData": [ 1, 0 ] },
11860
+ * { "orderData": 2 },
11861
+ * null,
11862
+ * null
11863
+ * ]
11864
+ * } );
11865
+ * } );
11866
+ */
11867
+ "aDataSort": null,
11868
+ "iDataSort": -1,
11869
+
11870
+ /**
11871
+ * You can control the default ordering direction, and even alter the
11872
+ * behaviour of the sort handler (i.e. only allow ascending ordering etc)
11873
+ * using this parameter.
11874
+ * @type array
11875
+ * @default [ 'asc', 'desc' ]
11876
+ *
11877
+ * @name DataTable.defaults.column.orderSequence
11878
+ * @dtopt Columns
11879
+ *
11880
+ * @example
11881
+ * // Using `columnDefs`
11882
+ * $(document).ready( function() {
11883
+ * $('#example').dataTable( {
11884
+ * "columnDefs": [
11885
+ * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
11886
+ * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
11887
+ * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
11888
+ * ]
11889
+ * } );
11890
+ * } );
11891
+ *
11892
+ * @example
11893
+ * // Using `columns`
11894
+ * $(document).ready( function() {
11895
+ * $('#example').dataTable( {
11896
+ * "columns": [
11897
+ * null,
11898
+ * { "orderSequence": [ "asc" ] },
11899
+ * { "orderSequence": [ "desc", "asc", "asc" ] },
11900
+ * { "orderSequence": [ "desc" ] },
11901
+ * null
11902
+ * ]
11903
+ * } );
11904
+ * } );
11905
+ */
11906
+ "asSorting": ['asc', 'desc'],
11907
+
11908
+ /**
11909
+ * Enable or disable filtering on the data in this column.
11910
+ * @type boolean
11911
+ * @default true
11912
+ *
11913
+ * @name DataTable.defaults.column.searchable
11914
+ * @dtopt Columns
11915
+ *
11916
+ * @example
11917
+ * // Using `columnDefs`
11918
+ * $(document).ready( function() {
11919
+ * $('#example').dataTable( {
11920
+ * "columnDefs": [
11921
+ * { "searchable": false, "targets": [ 0 ] }
11922
+ * ] } );
11923
+ * } );
11924
+ *
11925
+ * @example
11926
+ * // Using `columns`
11927
+ * $(document).ready( function() {
11928
+ * $('#example').dataTable( {
11929
+ * "columns": [
11930
+ * { "searchable": false },
11931
+ * null,
11932
+ * null,
11933
+ * null,
11934
+ * null
11935
+ * ] } );
11936
+ * } );
11937
+ */
11938
+ "bSearchable": true,
11939
+
11940
+ /**
11941
+ * Enable or disable ordering on this column.
11942
+ * @type boolean
11943
+ * @default true
11944
+ *
11945
+ * @name DataTable.defaults.column.orderable
11946
+ * @dtopt Columns
11947
+ *
11948
+ * @example
11949
+ * // Using `columnDefs`
11950
+ * $(document).ready( function() {
11951
+ * $('#example').dataTable( {
11952
+ * "columnDefs": [
11953
+ * { "orderable": false, "targets": [ 0 ] }
11954
+ * ] } );
11955
+ * } );
11956
+ *
11957
+ * @example
11958
+ * // Using `columns`
11959
+ * $(document).ready( function() {
11960
+ * $('#example').dataTable( {
11961
+ * "columns": [
11962
+ * { "orderable": false },
11963
+ * null,
11964
+ * null,
11965
+ * null,
11966
+ * null
11967
+ * ] } );
11968
+ * } );
11969
+ */
11970
+ "bSortable": true,
11971
+
11972
+ /**
11973
+ * Enable or disable the display of this column.
11974
+ * @type boolean
11975
+ * @default true
11976
+ *
11977
+ * @name DataTable.defaults.column.visible
11978
+ * @dtopt Columns
11979
+ *
11980
+ * @example
11981
+ * // Using `columnDefs`
11982
+ * $(document).ready( function() {
11983
+ * $('#example').dataTable( {
11984
+ * "columnDefs": [
11985
+ * { "visible": false, "targets": [ 0 ] }
11986
+ * ] } );
11987
+ * } );
11988
+ *
11989
+ * @example
11990
+ * // Using `columns`
11991
+ * $(document).ready( function() {
11992
+ * $('#example').dataTable( {
11993
+ * "columns": [
11994
+ * { "visible": false },
11995
+ * null,
11996
+ * null,
11997
+ * null,
11998
+ * null
11999
+ * ] } );
12000
+ * } );
12001
+ */
12002
+ "bVisible": true,
12003
+
12004
+ /**
12005
+ * Developer definable function that is called whenever a cell is created (Ajax source,
12006
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12007
+ * allowing you to modify the DOM element (add background colour for example) when the
12008
+ * element is available.
12009
+ * @type function
12010
+ * @param {element} td The TD node that has been created
12011
+ * @param {*} cellData The Data for the cell
12012
+ * @param {array|object} rowData The data for the whole row
12013
+ * @param {int} row The row index for the aoData data store
12014
+ * @param {int} col The column index for aoColumns
12015
+ *
12016
+ * @name DataTable.defaults.column.createdCell
12017
+ * @dtopt Columns
12018
+ *
12019
+ * @example
12020
+ * $(document).ready( function() {
12021
+ * $('#example').dataTable( {
12022
+ * "columnDefs": [ {
12023
+ * "targets": [3],
12024
+ * "createdCell": function (td, cellData, rowData, row, col) {
12025
+ * if ( cellData == "1.7" ) {
12026
+ * $(td).css('color', 'blue')
12027
+ * }
12028
+ * }
12029
+ * } ]
12030
+ * });
12031
+ * } );
12032
+ */
12033
+ "fnCreatedCell": null,
12034
+
12035
+ /**
12036
+ * This parameter has been replaced by `data` in DataTables to ensure naming
12037
+ * consistency. `dataProp` can still be used, as there is backwards
12038
+ * compatibility in DataTables for this option, but it is strongly
12039
+ * recommended that you use `data` in preference to `dataProp`.
12040
+ * @name DataTable.defaults.column.dataProp
12041
+ */
12042
+
12043
+
12044
+ /**
12045
+ * This property can be used to read data from any data source property,
12046
+ * including deeply nested objects / properties. `data` can be given in a
12047
+ * number of different ways which effect its behaviour:
12048
+ *
12049
+ * * `integer` - treated as an array index for the data source. This is the
12050
+ * default that DataTables uses (incrementally increased for each column).
12051
+ * * `string` - read an object property from the data source. There are
12052
+ * three 'special' options that can be used in the string to alter how
12053
+ * DataTables reads the data from the source object:
12054
+ * * `.` - Dotted Javascript notation. Just as you use a `.` in
12055
+ * Javascript to read from nested objects, so to can the options
12056
+ * specified in `data`. For example: `browser.version` or
12057
+ * `browser.name`. If your object parameter name contains a period, use
12058
+ * `\\` to escape it - i.e. `first\\.name`.
12059
+ * * `[]` - Array notation. DataTables can automatically combine data
12060
+ * from and array source, joining the data with the characters provided
12061
+ * between the two brackets. For example: `name[, ]` would provide a
12062
+ * comma-space separated list from the source array. If no characters
12063
+ * are provided between the brackets, the original array source is
12064
+ * returned.
12065
+ * * `()` - Function notation. Adding `()` to the end of a parameter will
12066
+ * execute a function of the name given. For example: `browser()` for a
12067
+ * simple function on the data source, `browser.version()` for a
12068
+ * function in a nested property or even `browser().version` to get an
12069
+ * object property if the function called returns an object. Note that
12070
+ * function notation is recommended for use in `render` rather than
12071
+ * `data` as it is much simpler to use as a renderer.
12072
+ * * `null` - use the original data source for the row rather than plucking
12073
+ * data directly from it. This action has effects on two other
12074
+ * initialisation options:
12075
+ * * `defaultContent` - When null is given as the `data` option and
12076
+ * `defaultContent` is specified for the column, the value defined by
12077
+ * `defaultContent` will be used for the cell.
12078
+ * * `render` - When null is used for the `data` option and the `render`
12079
+ * option is specified for the column, the whole data source for the
12080
+ * row is used for the renderer.
12081
+ * * `function` - the function given will be executed whenever DataTables
12082
+ * needs to set or get the data for a cell in the column. The function
12083
+ * takes three parameters:
12084
+ * * Parameters:
12085
+ * * `{array|object}` The data source for the row
12086
+ * * `{string}` The type call data requested - this will be 'set' when
12087
+ * setting data or 'filter', 'display', 'type', 'sort' or undefined
12088
+ * when gathering data. Note that when `undefined` is given for the
12089
+ * type DataTables expects to get the raw data for the object back<
12090
+ * * `{*}` Data to set when the second parameter is 'set'.
12091
+ * * Return:
12092
+ * * The return value from the function is not required when 'set' is
12093
+ * the type of call, but otherwise the return is what will be used
12094
+ * for the data requested.
12095
+ *
12096
+ * Note that `data` is a getter and setter option. If you just require
12097
+ * formatting of data for output, you will likely want to use `render` which
12098
+ * is simply a getter and thus simpler to use.
12099
+ *
12100
+ * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12101
+ * name change reflects the flexibility of this property and is consistent
12102
+ * with the naming of mRender. If 'mDataProp' is given, then it will still
12103
+ * be used by DataTables, as it automatically maps the old name to the new
12104
+ * if required.
12105
+ *
12106
+ * @type string|int|function|null
12107
+ * @default null <i>Use automatically calculated column index</i>
12108
+ *
12109
+ * @name DataTable.defaults.column.data
12110
+ * @dtopt Columns
12111
+ *
12112
+ * @example
12113
+ * // Read table data from objects
12114
+ * // JSON structure for each row:
12115
+ * // {
12116
+ * // "engine": {value},
12117
+ * // "browser": {value},
12118
+ * // "platform": {value},
12119
+ * // "version": {value},
12120
+ * // "grade": {value}
12121
+ * // }
12122
+ * $(document).ready( function() {
12123
+ * $('#example').dataTable( {
12124
+ * "ajaxSource": "sources/objects.txt",
12125
+ * "columns": [
12126
+ * { "data": "engine" },
12127
+ * { "data": "browser" },
12128
+ * { "data": "platform" },
12129
+ * { "data": "version" },
12130
+ * { "data": "grade" }
12131
+ * ]
12132
+ * } );
12133
+ * } );
12134
+ *
12135
+ * @example
12136
+ * // Read information from deeply nested objects
12137
+ * // JSON structure for each row:
12138
+ * // {
12139
+ * // "engine": {value},
12140
+ * // "browser": {value},
12141
+ * // "platform": {
12142
+ * // "inner": {value}
12143
+ * // },
12144
+ * // "details": [
12145
+ * // {value}, {value}
12146
+ * // ]
12147
+ * // }
12148
+ * $(document).ready( function() {
12149
+ * $('#example').dataTable( {
12150
+ * "ajaxSource": "sources/deep.txt",
12151
+ * "columns": [
12152
+ * { "data": "engine" },
12153
+ * { "data": "browser" },
12154
+ * { "data": "platform.inner" },
12155
+ * { "data": "platform.details.0" },
12156
+ * { "data": "platform.details.1" }
12157
+ * ]
12158
+ * } );
12159
+ * } );
12160
+ *
12161
+ * @example
12162
+ * // Using `data` as a function to provide different information for
12163
+ * // sorting, filtering and display. In this case, currency (price)
12164
+ * $(document).ready( function() {
12165
+ * $('#example').dataTable( {
12166
+ * "columnDefs": [ {
12167
+ * "targets": [ 0 ],
12168
+ * "data": function ( source, type, val ) {
12169
+ * if (type === 'set') {
12170
+ * source.price = val;
12171
+ * // Store the computed dislay and filter values for efficiency
12172
+ * source.price_display = val=="" ? "" : "$"+numberFormat(val);
12173
+ * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12174
+ * return;
12175
+ * }
12176
+ * else if (type === 'display') {
12177
+ * return source.price_display;
12178
+ * }
12179
+ * else if (type === 'filter') {
12180
+ * return source.price_filter;
12181
+ * }
12182
+ * // 'sort', 'type' and undefined all just use the integer
12183
+ * return source.price;
12184
+ * }
12185
+ * } ]
12186
+ * } );
12187
+ * } );
12188
+ *
12189
+ * @example
12190
+ * // Using default content
12191
+ * $(document).ready( function() {
12192
+ * $('#example').dataTable( {
12193
+ * "columnDefs": [ {
12194
+ * "targets": [ 0 ],
12195
+ * "data": null,
12196
+ * "defaultContent": "Click to edit"
12197
+ * } ]
12198
+ * } );
12199
+ * } );
12200
+ *
12201
+ * @example
12202
+ * // Using array notation - outputting a list from an array
12203
+ * $(document).ready( function() {
12204
+ * $('#example').dataTable( {
12205
+ * "columnDefs": [ {
12206
+ * "targets": [ 0 ],
12207
+ * "data": "name[, ]"
12208
+ * } ]
12209
+ * } );
12210
+ * } );
12211
+ *
12212
+ */
12213
+ "mData": null,
12214
+
12215
+ /**
12216
+ * This property is the rendering partner to `data` and it is suggested that
12217
+ * when you want to manipulate data for display (including filtering,
12218
+ * sorting etc) without altering the underlying data for the table, use this
12219
+ * property. `render` can be considered to be the the read only companion to
12220
+ * `data` which is read / write (then as such more complex). Like `data`
12221
+ * this option can be given in a number of different ways to effect its
12222
+ * behaviour:
12223
+ *
12224
+ * * `integer` - treated as an array index for the data source. This is the
12225
+ * default that DataTables uses (incrementally increased for each column).
12226
+ * * `string` - read an object property from the data source. There are
12227
+ * three 'special' options that can be used in the string to alter how
12228
+ * DataTables reads the data from the source object:
12229
+ * * `.` - Dotted Javascript notation. Just as you use a `.` in
12230
+ * Javascript to read from nested objects, so to can the options
12231
+ * specified in `data`. For example: `browser.version` or
12232
+ * `browser.name`. If your object parameter name contains a period, use
12233
+ * `\\` to escape it - i.e. `first\\.name`.
12234
+ * * `[]` - Array notation. DataTables can automatically combine data
12235
+ * from and array source, joining the data with the characters provided
12236
+ * between the two brackets. For example: `name[, ]` would provide a
12237
+ * comma-space separated list from the source array. If no characters
12238
+ * are provided between the brackets, the original array source is
12239
+ * returned.
12240
+ * * `()` - Function notation. Adding `()` to the end of a parameter will
12241
+ * execute a function of the name given. For example: `browser()` for a
12242
+ * simple function on the data source, `browser.version()` for a
12243
+ * function in a nested property or even `browser().version` to get an
12244
+ * object property if the function called returns an object.
12245
+ * * `object` - use different data for the different data types requested by
12246
+ * DataTables ('filter', 'display', 'type' or 'sort'). The property names
12247
+ * of the object is the data type the property refers to and the value can
12248
+ * defined using an integer, string or function using the same rules as
12249
+ * `render` normally does. Note that an `_` option _must_ be specified.
12250
+ * This is the default value to use if you haven't specified a value for
12251
+ * the data type requested by DataTables.
12252
+ * * `function` - the function given will be executed whenever DataTables
12253
+ * needs to set or get the data for a cell in the column. The function
12254
+ * takes three parameters:
12255
+ * * Parameters:
12256
+ * * {array|object} The data source for the row (based on `data`)
12257
+ * * {string} The type call data requested - this will be 'filter',
12258
+ * 'display', 'type' or 'sort'.
12259
+ * * {array|object} The full data source for the row (not based on
12260
+ * `data`)
12261
+ * * Return:
12262
+ * * The return value from the function is what will be used for the
12263
+ * data requested.
12264
+ *
12265
+ * @type string|int|function|object|null
12266
+ * @default null Use the data source value.
12267
+ *
12268
+ * @name DataTable.defaults.column.render
12269
+ * @dtopt Columns
12270
+ *
12271
+ * @example
12272
+ * // Create a comma separated list from an array of objects
12273
+ * $(document).ready( function() {
12274
+ * $('#example').dataTable( {
12275
+ * "ajaxSource": "sources/deep.txt",
12276
+ * "columns": [
12277
+ * { "data": "engine" },
12278
+ * { "data": "browser" },
12279
+ * {
12280
+ * "data": "platform",
12281
+ * "render": "[, ].name"
12282
+ * }
12283
+ * ]
12284
+ * } );
12285
+ * } );
12286
+ *
12287
+ * @example
12288
+ * // Execute a function to obtain data
12289
+ * $(document).ready( function() {
12290
+ * $('#example').dataTable( {
12291
+ * "columnDefs": [ {
12292
+ * "targets": [ 0 ],
12293
+ * "data": null, // Use the full data source object for the renderer's source
12294
+ * "render": "browserName()"
12295
+ * } ]
12296
+ * } );
12297
+ * } );
12298
+ *
12299
+ * @example
12300
+ * // As an object, extracting different data for the different types
12301
+ * // This would be used with a data source such as:
12302
+ * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12303
+ * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12304
+ * // (which has both forms) is used for filtering for if a user inputs either format, while
12305
+ * // the formatted phone number is the one that is shown in the table.
12306
+ * $(document).ready( function() {
12307
+ * $('#example').dataTable( {
12308
+ * "columnDefs": [ {
12309
+ * "targets": [ 0 ],
12310
+ * "data": null, // Use the full data source object for the renderer's source
12311
+ * "render": {
12312
+ * "_": "phone",
12313
+ * "filter": "phone_filter",
12314
+ * "display": "phone_display"
12315
+ * }
12316
+ * } ]
12317
+ * } );
12318
+ * } );
12319
+ *
12320
+ * @example
12321
+ * // Use as a function to create a link from the data source
12322
+ * $(document).ready( function() {
12323
+ * $('#example').dataTable( {
12324
+ * "columnDefs": [ {
12325
+ * "targets": [ 0 ],
12326
+ * "data": "download_link",
12327
+ * "render": function ( data, type, full ) {
12328
+ * return '<a href="'+data+'">Download</a>';
12329
+ * }
12330
+ * } ]
12331
+ * } );
12332
+ * } );
12333
+ */
12334
+ "mRender": null,
12335
+
12336
+ /**
12337
+ * Change the cell type created for the column - either TD cells or TH cells. This
12338
+ * can be useful as TH cells have semantic meaning in the table body, allowing them
12339
+ * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12340
+ * @type string
12341
+ * @default td
12342
+ *
12343
+ * @name DataTable.defaults.column.cellType
12344
+ * @dtopt Columns
12345
+ *
12346
+ * @example
12347
+ * // Make the first column use TH cells
12348
+ * $(document).ready( function() {
12349
+ * $('#example').dataTable( {
12350
+ * "columnDefs": [ {
12351
+ * "targets": [ 0 ],
12352
+ * "cellType": "th"
12353
+ * } ]
12354
+ * } );
12355
+ * } );
12356
+ */
12357
+ "sCellType": "td",
12358
+
12359
+ /**
12360
+ * Class to give to each cell in this column.
12361
+ * @type string
12362
+ * @default <i>Empty string</i>
12363
+ *
12364
+ * @name DataTable.defaults.column.class
12365
+ * @dtopt Columns
12366
+ *
12367
+ * @example
12368
+ * // Using `columnDefs`
12369
+ * $(document).ready( function() {
12370
+ * $('#example').dataTable( {
12371
+ * "columnDefs": [
12372
+ * { "class": "my_class", "targets": [ 0 ] }
12373
+ * ]
12374
+ * } );
12375
+ * } );
12376
+ *
12377
+ * @example
12378
+ * // Using `columns`
12379
+ * $(document).ready( function() {
12380
+ * $('#example').dataTable( {
12381
+ * "columns": [
12382
+ * { "class": "my_class" },
12383
+ * null,
12384
+ * null,
12385
+ * null,
12386
+ * null
12387
+ * ]
12388
+ * } );
12389
+ * } );
12390
+ */
12391
+ "sClass": "",
12392
+
12393
+ /**
12394
+ * When DataTables calculates the column widths to assign to each column,
12395
+ * it finds the longest string in each column and then constructs a
12396
+ * temporary table and reads the widths from that. The problem with this
12397
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
12398
+ * string - thus the calculation can go wrong (doing it properly and putting
12399
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
12400
+ * a "work around" we provide this option. It will append its value to the
12401
+ * text that is found to be the longest string for the column - i.e. padding.
12402
+ * Generally you shouldn't need this!
12403
+ * @type string
12404
+ * @default <i>Empty string<i>
12405
+ *
12406
+ * @name DataTable.defaults.column.contentPadding
12407
+ * @dtopt Columns
12408
+ *
12409
+ * @example
12410
+ * // Using `columns`
12411
+ * $(document).ready( function() {
12412
+ * $('#example').dataTable( {
12413
+ * "columns": [
12414
+ * null,
12415
+ * null,
12416
+ * null,
12417
+ * {
12418
+ * "contentPadding": "mmm"
12419
+ * }
12420
+ * ]
12421
+ * } );
12422
+ * } );
12423
+ */
12424
+ "sContentPadding": "",
12425
+
12426
+ /**
12427
+ * Allows a default value to be given for a column's data, and will be used
12428
+ * whenever a null data source is encountered (this can be because `data`
12429
+ * is set to null, or because the data source itself is null).
12430
+ * @type string
12431
+ * @default null
12432
+ *
12433
+ * @name DataTable.defaults.column.defaultContent
12434
+ * @dtopt Columns
12435
+ *
12436
+ * @example
12437
+ * // Using `columnDefs`
12438
+ * $(document).ready( function() {
12439
+ * $('#example').dataTable( {
12440
+ * "columnDefs": [
12441
+ * {
12442
+ * "data": null,
12443
+ * "defaultContent": "Edit",
12444
+ * "targets": [ -1 ]
12445
+ * }
12446
+ * ]
12447
+ * } );
12448
+ * } );
12449
+ *
12450
+ * @example
12451
+ * // Using `columns`
12452
+ * $(document).ready( function() {
12453
+ * $('#example').dataTable( {
12454
+ * "columns": [
12455
+ * null,
12456
+ * null,
12457
+ * null,
12458
+ * {
12459
+ * "data": null,
12460
+ * "defaultContent": "Edit"
12461
+ * }
12462
+ * ]
12463
+ * } );
12464
+ * } );
12465
+ */
12466
+ "sDefaultContent": null,
12467
+
12468
+ /**
12469
+ * This parameter is only used in DataTables' server-side processing. It can
12470
+ * be exceptionally useful to know what columns are being displayed on the
12471
+ * client side, and to map these to database fields. When defined, the names
12472
+ * also allow DataTables to reorder information from the server if it comes
12473
+ * back in an unexpected order (i.e. if you switch your columns around on the
12474
+ * client-side, your server-side code does not also need updating).
12475
+ * @type string
12476
+ * @default <i>Empty string</i>
12477
+ *
12478
+ * @name DataTable.defaults.column.name
12479
+ * @dtopt Columns
12480
+ *
12481
+ * @example
12482
+ * // Using `columnDefs`
12483
+ * $(document).ready( function() {
12484
+ * $('#example').dataTable( {
12485
+ * "columnDefs": [
12486
+ * { "name": "engine", "targets": [ 0 ] },
12487
+ * { "name": "browser", "targets": [ 1 ] },
12488
+ * { "name": "platform", "targets": [ 2 ] },
12489
+ * { "name": "version", "targets": [ 3 ] },
12490
+ * { "name": "grade", "targets": [ 4 ] }
12491
+ * ]
12492
+ * } );
12493
+ * } );
12494
+ *
12495
+ * @example
12496
+ * // Using `columns`
12497
+ * $(document).ready( function() {
12498
+ * $('#example').dataTable( {
12499
+ * "columns": [
12500
+ * { "name": "engine" },
12501
+ * { "name": "browser" },
12502
+ * { "name": "platform" },
12503
+ * { "name": "version" },
12504
+ * { "name": "grade" }
12505
+ * ]
12506
+ * } );
12507
+ * } );
12508
+ */
12509
+ "sName": "",
12510
+
12511
+ /**
12512
+ * Defines a data source type for the ordering which can be used to read
12513
+ * real-time information from the table (updating the internally cached
12514
+ * version) prior to ordering. This allows ordering to occur on user
12515
+ * editable elements such as form inputs.
12516
+ * @type string
12517
+ * @default std
12518
+ *
12519
+ * @name DataTable.defaults.column.orderDataType
12520
+ * @dtopt Columns
12521
+ *
12522
+ * @example
12523
+ * // Using `columnDefs`
12524
+ * $(document).ready( function() {
12525
+ * $('#example').dataTable( {
12526
+ * "columnDefs": [
12527
+ * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12528
+ * { "type": "numeric", "targets": [ 3 ] },
12529
+ * { "orderDataType": "dom-select", "targets": [ 4 ] },
12530
+ * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12531
+ * ]
12532
+ * } );
12533
+ * } );
12534
+ *
12535
+ * @example
12536
+ * // Using `columns`
12537
+ * $(document).ready( function() {
12538
+ * $('#example').dataTable( {
12539
+ * "columns": [
12540
+ * null,
12541
+ * null,
12542
+ * { "orderDataType": "dom-text" },
12543
+ * { "orderDataType": "dom-text", "type": "numeric" },
12544
+ * { "orderDataType": "dom-select" },
12545
+ * { "orderDataType": "dom-checkbox" }
12546
+ * ]
12547
+ * } );
12548
+ * } );
12549
+ */
12550
+ "sSortDataType": "std",
12551
+
12552
+ /**
12553
+ * The title of this column.
12554
+ * @type string
12555
+ * @default null <i>Derived from the 'TH' value for this column in the
12556
+ * original HTML table.</i>
12557
+ *
12558
+ * @name DataTable.defaults.column.title
12559
+ * @dtopt Columns
12560
+ *
12561
+ * @example
12562
+ * // Using `columnDefs`
12563
+ * $(document).ready( function() {
12564
+ * $('#example').dataTable( {
12565
+ * "columnDefs": [
12566
+ * { "title": "My column title", "targets": [ 0 ] }
12567
+ * ]
12568
+ * } );
12569
+ * } );
12570
+ *
12571
+ * @example
12572
+ * // Using `columns`
12573
+ * $(document).ready( function() {
12574
+ * $('#example').dataTable( {
12575
+ * "columns": [
12576
+ * { "title": "My column title" },
12577
+ * null,
12578
+ * null,
12579
+ * null,
12580
+ * null
12581
+ * ]
12582
+ * } );
12583
+ * } );
12584
+ */
12585
+ "sTitle": null,
12586
+
12587
+ /**
12588
+ * The type allows you to specify how the data for this column will be
12589
+ * ordered. Four types (string, numeric, date and html (which will strip
12590
+ * HTML tags before ordering)) are currently available. Note that only date
12591
+ * formats understood by Javascript's Date() object will be accepted as type
12592
+ * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12593
+ * 'numeric', 'date' or 'html' (by default). Further types can be adding
12594
+ * through plug-ins.
12595
+ * @type string
12596
+ * @default null <i>Auto-detected from raw data</i>
12597
+ *
12598
+ * @name DataTable.defaults.column.type
12599
+ * @dtopt Columns
12600
+ *
12601
+ * @example
12602
+ * // Using `columnDefs`
12603
+ * $(document).ready( function() {
12604
+ * $('#example').dataTable( {
12605
+ * "columnDefs": [
12606
+ * { "type": "html", "targets": [ 0 ] }
12607
+ * ]
12608
+ * } );
12609
+ * } );
12610
+ *
12611
+ * @example
12612
+ * // Using `columns`
12613
+ * $(document).ready( function() {
12614
+ * $('#example').dataTable( {
12615
+ * "columns": [
12616
+ * { "type": "html" },
12617
+ * null,
12618
+ * null,
12619
+ * null,
12620
+ * null
12621
+ * ]
12622
+ * } );
12623
+ * } );
12624
+ */
12625
+ "sType": null,
12626
+
12627
+ /**
12628
+ * Defining the width of the column, this parameter may take any CSS value
12629
+ * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12630
+ * been given a specific width through this interface ensuring that the table
12631
+ * remains readable.
12632
+ * @type string
12633
+ * @default null <i>Automatic</i>
12634
+ *
12635
+ * @name DataTable.defaults.column.width
12636
+ * @dtopt Columns
12637
+ *
12638
+ * @example
12639
+ * // Using `columnDefs`
12640
+ * $(document).ready( function() {
12641
+ * $('#example').dataTable( {
12642
+ * "columnDefs": [
12643
+ * { "width": "20%", "targets": [ 0 ] }
12644
+ * ]
12645
+ * } );
12646
+ * } );
12647
+ *
12648
+ * @example
12649
+ * // Using `columns`
12650
+ * $(document).ready( function() {
12651
+ * $('#example').dataTable( {
12652
+ * "columns": [
12653
+ * { "width": "20%" },
12654
+ * null,
12655
+ * null,
12656
+ * null,
12657
+ * null
12658
+ * ]
12659
+ * } );
12660
+ * } );
12661
+ */
12662
+ "sWidth": null
12663
+ };
12664
+
12665
+ _fnHungarianMap(DataTable.defaults.column);
12666
+
12667
+
12668
+
12669
+ /**
12670
+ * DataTables settings object - this holds all the information needed for a
12671
+ * given table, including configuration, data and current application of the
12672
+ * table options. DataTables does not have a single instance for each DataTable
12673
+ * with the settings attached to that instance, but rather instances of the
12674
+ * DataTable "class" are created on-the-fly as needed (typically by a
12675
+ * $().dataTable() call) and the settings object is then applied to that
12676
+ * instance.
12677
+ *
12678
+ * Note that this object is related to {@link DataTable.defaults} but this
12679
+ * one is the internal data store for DataTables's cache of columns. It should
12680
+ * NOT be manipulated outside of DataTables. Any configuration should be done
12681
+ * through the initialisation options.
12682
+ * @namespace
12683
+ * @todo Really should attach the settings object to individual instances so we
12684
+ * don't need to create new instances on each $().dataTable() call (if the
12685
+ * table already exists). It would also save passing oSettings around and
12686
+ * into every single function. However, this is a very significant
12687
+ * architecture change for DataTables and will almost certainly break
12688
+ * backwards compatibility with older installations. This is something that
12689
+ * will be done in 2.0.
12690
+ */
12691
+ DataTable.models.oSettings = {
12692
+ /**
12693
+ * Primary features of DataTables and their enablement state.
12694
+ * @namespace
12695
+ */
12696
+ "oFeatures": {
12697
+
12698
+ /**
12699
+ * Flag to say if DataTables should automatically try to calculate the
12700
+ * optimum table and columns widths (true) or not (false).
12701
+ * Note that this parameter will be set by the initialisation routine. To
12702
+ * set a default use {@link DataTable.defaults}.
12703
+ * @type boolean
12704
+ */
12705
+ "bAutoWidth": null,
12706
+
12707
+ /**
12708
+ * Delay the creation of TR and TD elements until they are actually
12709
+ * needed by a driven page draw. This can give a significant speed
12710
+ * increase for Ajax source and Javascript source data, but makes no
12711
+ * difference at all fro DOM and server-side processing tables.
12712
+ * Note that this parameter will be set by the initialisation routine. To
12713
+ * set a default use {@link DataTable.defaults}.
12714
+ * @type boolean
12715
+ */
12716
+ "bDeferRender": null,
12717
+
12718
+ /**
12719
+ * Enable filtering on the table or not. Note that if this is disabled
12720
+ * then there is no filtering at all on the table, including fnFilter.
12721
+ * To just remove the filtering input use sDom and remove the 'f' option.
12722
+ * Note that this parameter will be set by the initialisation routine. To
12723
+ * set a default use {@link DataTable.defaults}.
12724
+ * @type boolean
12725
+ */
12726
+ "bFilter": null,
12727
+
12728
+ /**
12729
+ * Table information element (the 'Showing x of y records' div) enable
12730
+ * flag.
12731
+ * Note that this parameter will be set by the initialisation routine. To
12732
+ * set a default use {@link DataTable.defaults}.
12733
+ * @type boolean
12734
+ */
12735
+ "bInfo": null,
12736
+
12737
+ /**
12738
+ * Present a user control allowing the end user to change the page size
12739
+ * when pagination is enabled.
12740
+ * Note that this parameter will be set by the initialisation routine. To
12741
+ * set a default use {@link DataTable.defaults}.
12742
+ * @type boolean
12743
+ */
12744
+ "bLengthChange": null,
12745
+
12746
+ /**
12747
+ * Pagination enabled or not. Note that if this is disabled then length
12748
+ * changing must also be disabled.
12749
+ * Note that this parameter will be set by the initialisation routine. To
12750
+ * set a default use {@link DataTable.defaults}.
12751
+ * @type boolean
12752
+ */
12753
+ "bPaginate": null,
12754
+
12755
+ /**
12756
+ * Processing indicator enable flag whenever DataTables is enacting a
12757
+ * user request - typically an Ajax request for server-side processing.
12758
+ * Note that this parameter will be set by the initialisation routine. To
12759
+ * set a default use {@link DataTable.defaults}.
12760
+ * @type boolean
12761
+ */
12762
+ "bProcessing": null,
12763
+
12764
+ /**
12765
+ * Server-side processing enabled flag - when enabled DataTables will
12766
+ * get all data from the server for every draw - there is no filtering,
12767
+ * sorting or paging done on the client-side.
12768
+ * Note that this parameter will be set by the initialisation routine. To
12769
+ * set a default use {@link DataTable.defaults}.
12770
+ * @type boolean
12771
+ */
12772
+ "bServerSide": null,
12773
+
12774
+ /**
12775
+ * Sorting enablement 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
+ "bSort": null,
12781
+
12782
+ /**
12783
+ * Multi-column sorting
12784
+ * Note that this parameter will be set by the initialisation routine. To
12785
+ * set a default use {@link DataTable.defaults}.
12786
+ * @type boolean
12787
+ */
12788
+ "bSortMulti": null,
12789
+
12790
+ /**
12791
+ * Apply a class to the columns which are being sorted to provide a
12792
+ * visual highlight or not. This can slow things down when enabled since
12793
+ * there is a lot of DOM interaction.
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
+ "bSortClasses": null,
12799
+
12800
+ /**
12801
+ * State saving enablement flag.
12802
+ * Note that this parameter will be set by the initialisation routine. To
12803
+ * set a default use {@link DataTable.defaults}.
12804
+ * @type boolean
12805
+ */
12806
+ "bStateSave": null
12807
+ },
12808
+
12809
+ /**
12810
+ * Scrolling settings for a table.
12811
+ * @namespace
12812
+ */
12813
+ "oScroll": {
12814
+ /**
12815
+ * When the table is shorter in height than sScrollY, collapse the
12816
+ * table container down to the height of the table (when true).
12817
+ * Note that this parameter will be set by the initialisation routine. To
12818
+ * set a default use {@link DataTable.defaults}.
12819
+ * @type boolean
12820
+ */
12821
+ "bCollapse": null,
12822
+
12823
+ /**
12824
+ * Width of the scrollbar for the web-browser's platform. Calculated
12825
+ * during table initialisation.
12826
+ * @type int
12827
+ * @default 0
12828
+ */
12829
+ "iBarWidth": 0,
12830
+
12831
+ /**
12832
+ * Viewport width for horizontal scrolling. Horizontal scrolling is
12833
+ * disabled if an empty string.
12834
+ * Note that this parameter will be set by the initialisation routine. To
12835
+ * set a default use {@link DataTable.defaults}.
12836
+ * @type string
12837
+ */
12838
+ "sX": null,
12839
+
12840
+ /**
12841
+ * Width to expand the table to when using x-scrolling. Typically you
12842
+ * should not need to use this.
12843
+ * Note that this parameter will be set by the initialisation routine. To
12844
+ * set a default use {@link DataTable.defaults}.
12845
+ * @type string
12846
+ * @deprecated
12847
+ */
12848
+ "sXInner": null,
12849
+
12850
+ /**
12851
+ * Viewport height for vertical scrolling. Vertical scrolling is disabled
12852
+ * if an empty string.
12853
+ * Note that this parameter will be set by the initialisation routine. To
12854
+ * set a default use {@link DataTable.defaults}.
12855
+ * @type string
12856
+ */
12857
+ "sY": null
12858
+ },
12859
+
12860
+ /**
12861
+ * Language information for the table.
12862
+ * @namespace
12863
+ * @extends DataTable.defaults.oLanguage
12864
+ */
12865
+ "oLanguage": {
12866
+ /**
12867
+ * Information callback function. See
12868
+ * {@link DataTable.defaults.fnInfoCallback}
12869
+ * @type function
12870
+ * @default null
12871
+ */
12872
+ "fnInfoCallback": null
12873
+ },
12874
+
12875
+ /**
12876
+ * Browser support parameters
12877
+ * @namespace
12878
+ */
12879
+ "oBrowser": {
12880
+ /**
12881
+ * Indicate if the browser incorrectly calculates width:100% inside a
12882
+ * scrolling element (IE6/7)
12883
+ * @type boolean
12884
+ * @default false
12885
+ */
12886
+ "bScrollOversize": false,
12887
+
12888
+ /**
12889
+ * Determine if the vertical scrollbar is on the right or left of the
12890
+ * scrolling container - needed for rtl language layout, although not
12891
+ * all browsers move the scrollbar (Safari).
12892
+ * @type boolean
12893
+ * @default false
12894
+ */
12895
+ "bScrollbarLeft": false,
12896
+
12897
+ /**
12898
+ * Flag for if `getBoundingClientRect` is fully supported or not
12899
+ * @type boolean
12900
+ * @default false
12901
+ */
12902
+ "bBounding": false,
12903
+
12904
+ /**
12905
+ * Browser scrollbar width
12906
+ * @type integer
12907
+ * @default 0
12908
+ */
12909
+ "barWidth": 0
12910
+ },
12911
+
12912
+ "ajax": null,
12913
+
12914
+ /**
12915
+ * Array referencing the nodes which are used for the features. The
12916
+ * parameters of this object match what is allowed by sDom - i.e.
12917
+ * <ul>
12918
+ * <li>'l' - Length changing</li>
12919
+ * <li>'f' - Filtering input</li>
12920
+ * <li>'t' - The table!</li>
12921
+ * <li>'i' - Information</li>
12922
+ * <li>'p' - Pagination</li>
12923
+ * <li>'r' - pRocessing</li>
12924
+ * </ul>
12925
+ * @type array
12926
+ * @default []
12927
+ */
12928
+ "aanFeatures": [],
12929
+
12930
+ /**
12931
+ * Store data information - see {@link DataTable.models.oRow} for detailed
12932
+ * information.
12933
+ * @type array
12934
+ * @default []
12935
+ */
12936
+ "aoData": [],
12937
+
12938
+ /**
12939
+ * Array of indexes which are in the current display (after filtering etc)
12940
+ * @type array
12941
+ * @default []
12942
+ */
12943
+ "aiDisplay": [],
12944
+
12945
+ /**
12946
+ * Array of indexes for display - no filtering
12947
+ * @type array
12948
+ * @default []
12949
+ */
12950
+ "aiDisplayMaster": [],
12951
+
12952
+ /**
12953
+ * Map of row ids to data indexes
12954
+ * @type object
12955
+ * @default {}
12956
+ */
12957
+ "aIds": {},
12958
+
12959
+ /**
12960
+ * Store information about each column that is in use
12961
+ * @type array
12962
+ * @default []
12963
+ */
12964
+ "aoColumns": [],
12965
+
12966
+ /**
12967
+ * Store information about the table's header
12968
+ * @type array
12969
+ * @default []
12970
+ */
12971
+ "aoHeader": [],
12972
+
12973
+ /**
12974
+ * Store information about the table's footer
12975
+ * @type array
12976
+ * @default []
12977
+ */
12978
+ "aoFooter": [],
12979
+
12980
+ /**
12981
+ * Store the applied global search information in case we want to force a
12982
+ * research or compare the old search to a new one.
12983
+ * Note that this parameter will be set by the initialisation routine. To
12984
+ * set a default use {@link DataTable.defaults}.
12985
+ * @namespace
12986
+ * @extends DataTable.models.oSearch
12987
+ */
12988
+ "oPreviousSearch": {},
12989
+
12990
+ /**
12991
+ * Store the applied search for each column - see
12992
+ * {@link DataTable.models.oSearch} for the format that is used for the
12993
+ * filtering information for each column.
12994
+ * @type array
12995
+ * @default []
12996
+ */
12997
+ "aoPreSearchCols": [],
12998
+
12999
+ /**
13000
+ * Sorting that is applied to the table. Note that the inner arrays are
13001
+ * used in the following manner:
13002
+ * <ul>
13003
+ * <li>Index 0 - column number</li>
13004
+ * <li>Index 1 - current sorting direction</li>
13005
+ * </ul>
13006
+ * Note that this parameter will be set by the initialisation routine. To
13007
+ * set a default use {@link DataTable.defaults}.
13008
+ * @type array
13009
+ * @todo These inner arrays should really be objects
13010
+ */
13011
+ "aaSorting": null,
13012
+
13013
+ /**
13014
+ * Sorting that is always applied to the table (i.e. prefixed in front of
13015
+ * aaSorting).
13016
+ * Note that this parameter will be set by the initialisation routine. To
13017
+ * set a default use {@link DataTable.defaults}.
13018
+ * @type array
13019
+ * @default []
13020
+ */
13021
+ "aaSortingFixed": [],
13022
+
13023
+ /**
13024
+ * Classes to use for the striping of a table.
13025
+ * Note that this parameter will be set by the initialisation routine. To
13026
+ * set a default use {@link DataTable.defaults}.
13027
+ * @type array
13028
+ * @default []
13029
+ */
13030
+ "asStripeClasses": null,
13031
+
13032
+ /**
13033
+ * If restoring a table - we should restore its striping classes as well
13034
+ * @type array
13035
+ * @default []
13036
+ */
13037
+ "asDestroyStripes": [],
13038
+
13039
+ /**
13040
+ * If restoring a table - we should restore its width
13041
+ * @type int
13042
+ * @default 0
13043
+ */
13044
+ "sDestroyWidth": 0,
13045
+
13046
+ /**
13047
+ * Callback functions array for every time a row is inserted (i.e. on a draw).
13048
+ * @type array
13049
+ * @default []
13050
+ */
13051
+ "aoRowCallback": [],
13052
+
13053
+ /**
13054
+ * Callback functions for the header on each draw.
13055
+ * @type array
13056
+ * @default []
13057
+ */
13058
+ "aoHeaderCallback": [],
13059
+
13060
+ /**
13061
+ * Callback function for the footer on each draw.
13062
+ * @type array
13063
+ * @default []
13064
+ */
13065
+ "aoFooterCallback": [],
13066
+
13067
+ /**
13068
+ * Array of callback functions for draw callback functions
13069
+ * @type array
13070
+ * @default []
13071
+ */
13072
+ "aoDrawCallback": [],
13073
+
13074
+ /**
13075
+ * Array of callback functions for row created function
13076
+ * @type array
13077
+ * @default []
13078
+ */
13079
+ "aoRowCreatedCallback": [],
13080
+
13081
+ /**
13082
+ * Callback functions for just before the table is redrawn. A return of
13083
+ * false will be used to cancel the draw.
13084
+ * @type array
13085
+ * @default []
13086
+ */
13087
+ "aoPreDrawCallback": [],
13088
+
13089
+ /**
13090
+ * Callback functions for when the table has been initialised.
13091
+ * @type array
13092
+ * @default []
13093
+ */
13094
+ "aoInitComplete": [],
13095
+
13096
+ /**
13097
+ * Callbacks for modifying the settings to be stored for state saving, prior to
13098
+ * saving state.
13099
+ * @type array
13100
+ * @default []
13101
+ */
13102
+ "aoStateSaveParams": [],
13103
+
13104
+ /**
13105
+ * Callbacks for modifying the settings that have been stored for state saving
13106
+ * prior to using the stored values to restore the state.
13107
+ * @type array
13108
+ * @default []
13109
+ */
13110
+ "aoStateLoadParams": [],
13111
+
13112
+ /**
13113
+ * Callbacks for operating on the settings object once the saved state has been
13114
+ * loaded
13115
+ * @type array
13116
+ * @default []
13117
+ */
13118
+ "aoStateLoaded": [],
13119
+
13120
+ /**
13121
+ * Cache the table ID for quick access
13122
+ * @type string
13123
+ * @default <i>Empty string</i>
13124
+ */
13125
+ "sTableId": "",
13126
+
13127
+ /**
13128
+ * The TABLE node for the main table
13129
+ * @type node
13130
+ * @default null
13131
+ */
13132
+ "nTable": null,
13133
+
13134
+ /**
13135
+ * Permanent ref to the thead element
13136
+ * @type node
13137
+ * @default null
13138
+ */
13139
+ "nTHead": null,
13140
+
13141
+ /**
13142
+ * Permanent ref to the tfoot element - if it exists
13143
+ * @type node
13144
+ * @default null
13145
+ */
13146
+ "nTFoot": null,
13147
+
13148
+ /**
13149
+ * Permanent ref to the tbody element
13150
+ * @type node
13151
+ * @default null
13152
+ */
13153
+ "nTBody": null,
13154
+
13155
+ /**
13156
+ * Cache the wrapper node (contains all DataTables controlled elements)
13157
+ * @type node
13158
+ * @default null
13159
+ */
13160
+ "nTableWrapper": null,
13161
+
13162
+ /**
13163
+ * Indicate if when using server-side processing the loading of data
13164
+ * should be deferred until the second draw.
13165
+ * Note that this parameter will be set by the initialisation routine. To
13166
+ * set a default use {@link DataTable.defaults}.
13167
+ * @type boolean
13168
+ * @default false
13169
+ */
13170
+ "bDeferLoading": false,
13171
+
13172
+ /**
13173
+ * Indicate if all required information has been read in
13174
+ * @type boolean
13175
+ * @default false
13176
+ */
13177
+ "bInitialised": false,
13178
+
13179
+ /**
13180
+ * Information about open rows. Each object in the array has the parameters
13181
+ * 'nTr' and 'nParent'
13182
+ * @type array
13183
+ * @default []
13184
+ */
13185
+ "aoOpenRows": [],
13186
+
13187
+ /**
13188
+ * Dictate the positioning of DataTables' control elements - see
13189
+ * {@link DataTable.model.oInit.sDom}.
13190
+ * Note that this parameter will be set by the initialisation routine. To
13191
+ * set a default use {@link DataTable.defaults}.
13192
+ * @type string
13193
+ * @default null
13194
+ */
13195
+ "sDom": null,
13196
+
13197
+ /**
13198
+ * Search delay (in mS)
13199
+ * @type integer
13200
+ * @default null
13201
+ */
13202
+ "searchDelay": null,
13203
+
13204
+ /**
13205
+ * Which type of pagination should be used.
13206
+ * Note that this parameter will be set by the initialisation routine. To
13207
+ * set a default use {@link DataTable.defaults}.
13208
+ * @type string
13209
+ * @default two_button
13210
+ */
13211
+ "sPaginationType": "two_button",
13212
+
13213
+ /**
13214
+ * The state duration (for `stateSave`) in seconds.
13215
+ * Note that this parameter will be set by the initialisation routine. To
13216
+ * set a default use {@link DataTable.defaults}.
13217
+ * @type int
13218
+ * @default 0
13219
+ */
13220
+ "iStateDuration": 0,
13221
+
13222
+ /**
13223
+ * Array of callback functions for state saving. Each array element is an
13224
+ * object with the following parameters:
13225
+ * <ul>
13226
+ * <li>function:fn - function to call. Takes two parameters, oSettings
13227
+ * and the JSON string to save that has been thus far created. Returns
13228
+ * a JSON string to be inserted into a json object
13229
+ * (i.e. '"param": [ 0, 1, 2]')</li>
13230
+ * <li>string:sName - name of callback</li>
13231
+ * </ul>
13232
+ * @type array
13233
+ * @default []
13234
+ */
13235
+ "aoStateSave": [],
13236
+
13237
+ /**
13238
+ * Array of callback functions for state loading. Each array element is an
13239
+ * object with the following parameters:
13240
+ * <ul>
13241
+ * <li>function:fn - function to call. Takes two parameters, oSettings
13242
+ * and the object stored. May return false to cancel state loading</li>
13243
+ * <li>string:sName - name of callback</li>
13244
+ * </ul>
13245
+ * @type array
13246
+ * @default []
13247
+ */
13248
+ "aoStateLoad": [],
13249
+
13250
+ /**
13251
+ * State that was saved. Useful for back reference
13252
+ * @type object
13253
+ * @default null
13254
+ */
13255
+ "oSavedState": null,
13256
+
13257
+ /**
13258
+ * State that was loaded. Useful for back reference
13259
+ * @type object
13260
+ * @default null
13261
+ */
13262
+ "oLoadedState": null,
13263
+
13264
+ /**
13265
+ * Source url for AJAX data for the table.
13266
+ * Note that this parameter will be set by the initialisation routine. To
13267
+ * set a default use {@link DataTable.defaults}.
13268
+ * @type string
13269
+ * @default null
13270
+ */
13271
+ "sAjaxSource": null,
13272
+
13273
+ /**
13274
+ * Property from a given object from which to read the table data from. This
13275
+ * can be an empty string (when not server-side processing), in which case
13276
+ * it is assumed an an array is given directly.
13277
+ * Note that this parameter will be set by the initialisation routine. To
13278
+ * set a default use {@link DataTable.defaults}.
13279
+ * @type string
13280
+ */
13281
+ "sAjaxDataProp": null,
13282
+
13283
+ /**
13284
+ * Note if draw should be blocked while getting data
13285
+ * @type boolean
13286
+ * @default true
13287
+ */
13288
+ "bAjaxDataGet": true,
13289
+
13290
+ /**
13291
+ * The last jQuery XHR object that was used for server-side data gathering.
13292
+ * This can be used for working with the XHR information in one of the
13293
+ * callbacks
13294
+ * @type object
13295
+ * @default null
13296
+ */
13297
+ "jqXHR": null,
13298
+
13299
+ /**
13300
+ * JSON returned from the server in the last Ajax request
13301
+ * @type object
13302
+ * @default undefined
13303
+ */
13304
+ "json": undefined,
13305
+
13306
+ /**
13307
+ * Data submitted as part of the last Ajax request
13308
+ * @type object
13309
+ * @default undefined
13310
+ */
13311
+ "oAjaxData": undefined,
13312
+
13313
+ /**
13314
+ * Function to get the server-side data.
13315
+ * Note that this parameter will be set by the initialisation routine. To
13316
+ * set a default use {@link DataTable.defaults}.
13317
+ * @type function
13318
+ */
13319
+ "fnServerData": null,
13320
+
13321
+ /**
13322
+ * Functions which are called prior to sending an Ajax request so extra
13323
+ * parameters can easily be sent to the server
13324
+ * @type array
13325
+ * @default []
13326
+ */
13327
+ "aoServerParams": [],
13328
+
13329
+ /**
13330
+ * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13331
+ * required).
13332
+ * Note that this parameter will be set by the initialisation routine. To
13333
+ * set a default use {@link DataTable.defaults}.
13334
+ * @type string
13335
+ */
13336
+ "sServerMethod": null,
13337
+
13338
+ /**
13339
+ * Format numbers for display.
13340
+ * Note that this parameter will be set by the initialisation routine. To
13341
+ * set a default use {@link DataTable.defaults}.
13342
+ * @type function
13343
+ */
13344
+ "fnFormatNumber": null,
13345
+
13346
+ /**
13347
+ * List of options that can be used for the user selectable length menu.
13348
+ * Note that this parameter will be set by the initialisation routine. To
13349
+ * set a default use {@link DataTable.defaults}.
13350
+ * @type array
13351
+ * @default []
13352
+ */
13353
+ "aLengthMenu": null,
13354
+
13355
+ /**
13356
+ * Counter for the draws that the table does. Also used as a tracker for
13357
+ * server-side processing
13358
+ * @type int
13359
+ * @default 0
13360
+ */
13361
+ "iDraw": 0,
13362
+
13363
+ /**
13364
+ * Indicate if a redraw is being done - useful for Ajax
13365
+ * @type boolean
13366
+ * @default false
13367
+ */
13368
+ "bDrawing": false,
13369
+
13370
+ /**
13371
+ * Draw index (iDraw) of the last error when parsing the returned data
13372
+ * @type int
13373
+ * @default -1
13374
+ */
13375
+ "iDrawError": -1,
13376
+
13377
+ /**
13378
+ * Paging display length
13379
+ * @type int
13380
+ * @default 10
13381
+ */
13382
+ "_iDisplayLength": 10,
13383
+
13384
+ /**
13385
+ * Paging start point - aiDisplay index
13386
+ * @type int
13387
+ * @default 0
13388
+ */
13389
+ "_iDisplayStart": 0,
13390
+
13391
+ /**
13392
+ * Server-side processing - number of records in the result set
13393
+ * (i.e. before filtering), Use fnRecordsTotal rather than
13394
+ * this property to get the value of the number of records, regardless of
13395
+ * the server-side processing setting.
13396
+ * @type int
13397
+ * @default 0
13398
+ * @private
13399
+ */
13400
+ "_iRecordsTotal": 0,
13401
+
13402
+ /**
13403
+ * Server-side processing - number of records in the current display set
13404
+ * (i.e. after filtering). Use fnRecordsDisplay rather than
13405
+ * this property to get the value of the number of records, regardless of
13406
+ * the server-side processing setting.
13407
+ * @type boolean
13408
+ * @default 0
13409
+ * @private
13410
+ */
13411
+ "_iRecordsDisplay": 0,
13412
+
13413
+ /**
13414
+ * Flag to indicate if jQuery UI marking and classes should be used.
13415
+ * Note that this parameter will be set by the initialisation routine. To
13416
+ * set a default use {@link DataTable.defaults}.
13417
+ * @type boolean
13418
+ */
13419
+ "bJUI": null,
13420
+
13421
+ /**
13422
+ * The classes to use for the table
13423
+ * @type object
13424
+ * @default {}
13425
+ */
13426
+ "oClasses": {},
13427
+
13428
+ /**
13429
+ * Flag attached to the settings object so you can check in the draw
13430
+ * callback if filtering has been done in the draw. Deprecated in favour of
13431
+ * events.
13432
+ * @type boolean
13433
+ * @default false
13434
+ * @deprecated
13435
+ */
13436
+ "bFiltered": false,
13437
+
13438
+ /**
13439
+ * Flag attached to the settings object so you can check in the draw
13440
+ * callback if sorting has been done in the draw. Deprecated in favour of
13441
+ * events.
13442
+ * @type boolean
13443
+ * @default false
13444
+ * @deprecated
13445
+ */
13446
+ "bSorted": false,
13447
+
13448
+ /**
13449
+ * Indicate that if multiple rows are in the header and there is more than
13450
+ * one unique cell per column, if the top one (true) or bottom one (false)
13451
+ * should be used for sorting / title by DataTables.
13452
+ * Note that this parameter will be set by the initialisation routine. To
13453
+ * set a default use {@link DataTable.defaults}.
13454
+ * @type boolean
13455
+ */
13456
+ "bSortCellsTop": null,
13457
+
13458
+ /**
13459
+ * Initialisation object that is used for the table
13460
+ * @type object
13461
+ * @default null
13462
+ */
13463
+ "oInit": null,
13464
+
13465
+ /**
13466
+ * Destroy callback functions - for plug-ins to attach themselves to the
13467
+ * destroy so they can clean up markup and events.
13468
+ * @type array
13469
+ * @default []
13470
+ */
13471
+ "aoDestroyCallback": [],
13472
+
13473
+ /**
13474
+ * Get the number of records in the current record set, before filtering
13475
+ * @type function
13476
+ */
13477
+ "fnRecordsTotal": function ()
13478
+ {
13479
+ return _fnDataSource(this) == 'ssp' ?
13480
+ this._iRecordsTotal * 1 :
13481
+ this.aiDisplayMaster.length;
13482
+ },
13483
+
13484
+ /**
13485
+ * Get the number of records in the current record set, after filtering
13486
+ * @type function
13487
+ */
13488
+ "fnRecordsDisplay": function ()
13489
+ {
13490
+ return _fnDataSource(this) == 'ssp' ?
13491
+ this._iRecordsDisplay * 1 :
13492
+ this.aiDisplay.length;
13493
+ },
13494
+
13495
+ /**
13496
+ * Get the display end point - aiDisplay index
13497
+ * @type function
13498
+ */
13499
+ "fnDisplayEnd": function ()
13500
+ {
13501
+ var
13502
+ len = this._iDisplayLength,
13503
+ start = this._iDisplayStart,
13504
+ calc = start + len,
13505
+ records = this.aiDisplay.length,
13506
+ features = this.oFeatures,
13507
+ paginate = features.bPaginate;
13508
+
13509
+ if (features.bServerSide) {
13510
+ return paginate === false || len === -1 ?
13511
+ start + records :
13512
+ Math.min(start + len, this._iRecordsDisplay);
13513
+ } else {
13514
+ return !paginate || calc > records || len === -1 ?
13515
+ records :
13516
+ calc;
13517
+ }
13518
+ },
13519
+
13520
+ /**
13521
+ * The DataTables object for this table
13522
+ * @type object
13523
+ * @default null
13524
+ */
13525
+ "oInstance": null,
13526
+
13527
+ /**
13528
+ * Unique identifier for each instance of the DataTables object. If there
13529
+ * is an ID on the table node, then it takes that value, otherwise an
13530
+ * incrementing internal counter is used.
13531
+ * @type string
13532
+ * @default null
13533
+ */
13534
+ "sInstance": null,
13535
+
13536
+ /**
13537
+ * tabindex attribute value that is added to DataTables control elements, allowing
13538
+ * keyboard navigation of the table and its controls.
13539
+ */
13540
+ "iTabIndex": 0,
13541
+
13542
+ /**
13543
+ * DIV container for the footer scrolling table if scrolling
13544
+ */
13545
+ "nScrollHead": null,
13546
+
13547
+ /**
13548
+ * DIV container for the footer scrolling table if scrolling
13549
+ */
13550
+ "nScrollFoot": null,
13551
+
13552
+ /**
13553
+ * Last applied sort
13554
+ * @type array
13555
+ * @default []
13556
+ */
13557
+ "aLastSort": [],
13558
+
13559
+ /**
13560
+ * Stored plug-in instances
13561
+ * @type object
13562
+ * @default {}
13563
+ */
13564
+ "oPlugins": {},
13565
+
13566
+ /**
13567
+ * Function used to get a row's id from the row's data
13568
+ * @type function
13569
+ * @default null
13570
+ */
13571
+ "rowIdFn": null,
13572
+
13573
+ /**
13574
+ * Data location where to store a row's id
13575
+ * @type string
13576
+ * @default null
13577
+ */
13578
+ "rowId": null
13579
+ };
13580
+
13581
+ /**
13582
+ * Extension object for DataTables that is used to provide all extension
13583
+ * options.
13584
+ *
13585
+ * Note that the `DataTable.ext` object is available through
13586
+ * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13587
+ * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13588
+ * @namespace
13589
+ * @extends DataTable.models.ext
13590
+ */
13591
+
13592
+
13593
+ /**
13594
+ * DataTables extensions
13595
+ *
13596
+ * This namespace acts as a collection area for plug-ins that can be used to
13597
+ * extend DataTables capabilities. Indeed many of the build in methods
13598
+ * use this method to provide their own capabilities (sorting methods for
13599
+ * example).
13600
+ *
13601
+ * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13602
+ * reasons
13603
+ *
13604
+ * @namespace
13605
+ */
13606
+ DataTable.ext = _ext = {
13607
+ /**
13608
+ * Buttons. For use with the Buttons extension for DataTables. This is
13609
+ * defined here so other extensions can define buttons regardless of load
13610
+ * order. It is _not_ used by DataTables core.
13611
+ *
13612
+ * @type object
13613
+ * @default {}
13614
+ */
13615
+ buttons: {},
13616
+
13617
+ /**
13618
+ * Element class names
13619
+ *
13620
+ * @type object
13621
+ * @default {}
13622
+ */
13623
+ classes: {},
13624
+
13625
+ /**
13626
+ * DataTables build type (expanded by the download builder)
13627
+ *
13628
+ * @type string
13629
+ */
13630
+ builder: "-source-",
13631
+
13632
+ /**
13633
+ * Error reporting.
13634
+ *
13635
+ * How should DataTables report an error. Can take the value 'alert',
13636
+ * 'throw', 'none' or a function.
13637
+ *
13638
+ * @type string|function
13639
+ * @default alert
13640
+ */
13641
+ errMode: "alert",
13642
+
13643
+ /**
13644
+ * Feature plug-ins.
13645
+ *
13646
+ * This is an array of objects which describe the feature plug-ins that are
13647
+ * available to DataTables. These feature plug-ins are then available for
13648
+ * use through the `dom` initialisation option.
13649
+ *
13650
+ * Each feature plug-in is described by an object which must have the
13651
+ * following properties:
13652
+ *
13653
+ * * `fnInit` - function that is used to initialise the plug-in,
13654
+ * * `cFeature` - a character so the feature can be enabled by the `dom`
13655
+ * instillation option. This is case sensitive.
13656
+ *
13657
+ * The `fnInit` function has the following input parameters:
13658
+ *
13659
+ * 1. `{object}` DataTables settings object: see
13660
+ * {@link DataTable.models.oSettings}
13661
+ *
13662
+ * And the following return is expected:
13663
+ *
13664
+ * * {node|null} The element which contains your feature. Note that the
13665
+ * return may also be void if your plug-in does not require to inject any
13666
+ * DOM elements into DataTables control (`dom`) - for example this might
13667
+ * be useful when developing a plug-in which allows table control via
13668
+ * keyboard entry
13669
+ *
13670
+ * @type array
13671
+ *
13672
+ * @example
13673
+ * $.fn.dataTable.ext.features.push( {
13674
+ * "fnInit": function( oSettings ) {
13675
+ * return new TableTools( { "oDTSettings": oSettings } );
13676
+ * },
13677
+ * "cFeature": "T"
13678
+ * } );
13679
+ */
13680
+ feature: [],
13681
+
13682
+ /**
13683
+ * Row searching.
13684
+ *
13685
+ * This method of searching is complimentary to the default type based
13686
+ * searching, and a lot more comprehensive as it allows you complete control
13687
+ * over the searching logic. Each element in this array is a function
13688
+ * (parameters described below) that is called for every row in the table,
13689
+ * and your logic decides if it should be included in the searching data set
13690
+ * or not.
13691
+ *
13692
+ * Searching functions have the following input parameters:
13693
+ *
13694
+ * 1. `{object}` DataTables settings object: see
13695
+ * {@link DataTable.models.oSettings}
13696
+ * 2. `{array|object}` Data for the row to be processed (same as the
13697
+ * original format that was passed in as the data source, or an array
13698
+ * from a DOM data source
13699
+ * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
13700
+ * can be useful to retrieve the `TR` element if you need DOM interaction.
13701
+ *
13702
+ * And the following return is expected:
13703
+ *
13704
+ * * {boolean} Include the row in the searched result set (true) or not
13705
+ * (false)
13706
+ *
13707
+ * Note that as with the main search ability in DataTables, technically this
13708
+ * is "filtering", since it is subtractive. However, for consistency in
13709
+ * naming we call it searching here.
13710
+ *
13711
+ * @type array
13712
+ * @default []
13713
+ *
13714
+ * @example
13715
+ * // The following example shows custom search being applied to the
13716
+ * // fourth column (i.e. the data[3] index) based on two input values
13717
+ * // from the end-user, matching the data in a certain range.
13718
+ * $.fn.dataTable.ext.search.push(
13719
+ * function( settings, data, dataIndex ) {
13720
+ * var min = document.getElementById('min').value * 1;
13721
+ * var max = document.getElementById('max').value * 1;
13722
+ * var version = data[3] == "-" ? 0 : data[3]*1;
13723
+ *
13724
+ * if ( min == "" && max == "" ) {
13725
+ * return true;
13726
+ * }
13727
+ * else if ( min == "" && version < max ) {
13728
+ * return true;
13729
+ * }
13730
+ * else if ( min < version && "" == max ) {
13731
+ * return true;
13732
+ * }
13733
+ * else if ( min < version && version < max ) {
13734
+ * return true;
13735
+ * }
13736
+ * return false;
13737
+ * }
13738
+ * );
13739
+ */
13740
+ search: [],
13741
+
13742
+ /**
13743
+ * Selector extensions
13744
+ *
13745
+ * The `selector` option can be used to extend the options available for the
13746
+ * selector modifier options (`selector-modifier` object data type) that
13747
+ * each of the three built in selector types offer (row, column and cell +
13748
+ * their plural counterparts). For example the Select extension uses this
13749
+ * mechanism to provide an option to select only rows, columns and cells
13750
+ * that have been marked as selected by the end user (`{selected: true}`),
13751
+ * which can be used in conjunction with the existing built in selector
13752
+ * options.
13753
+ *
13754
+ * Each property is an array to which functions can be pushed. The functions
13755
+ * take three attributes:
13756
+ *
13757
+ * * Settings object for the host table
13758
+ * * Options object (`selector-modifier` object type)
13759
+ * * Array of selected item indexes
13760
+ *
13761
+ * The return is an array of the resulting item indexes after the custom
13762
+ * selector has been applied.
13763
+ *
13764
+ * @type object
13765
+ */
13766
+ selector: {
13767
+ cell: [],
13768
+ column: [],
13769
+ row: []
13770
+ },
13771
+
13772
+ /**
13773
+ * Internal functions, exposed for used in plug-ins.
13774
+ *
13775
+ * Please note that you should not need to use the internal methods for
13776
+ * anything other than a plug-in (and even then, try to avoid if possible).
13777
+ * The internal function may change between releases.
13778
+ *
13779
+ * @type object
13780
+ * @default {}
13781
+ */
13782
+ internal: {},
13783
+
13784
+ /**
13785
+ * Legacy configuration options. Enable and disable legacy options that
13786
+ * are available in DataTables.
13787
+ *
13788
+ * @type object
13789
+ */
13790
+ legacy: {
13791
+ /**
13792
+ * Enable / disable DataTables 1.9 compatible server-side processing
13793
+ * requests
13794
+ *
13795
+ * @type boolean
13796
+ * @default null
13797
+ */
13798
+ ajax: null
13799
+ },
13800
+
13801
+ /**
13802
+ * Pagination plug-in methods.
13803
+ *
13804
+ * Each entry in this object is a function and defines which buttons should
13805
+ * be shown by the pagination rendering method that is used for the table:
13806
+ * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
13807
+ * buttons are displayed in the document, while the functions here tell it
13808
+ * what buttons to display. This is done by returning an array of button
13809
+ * descriptions (what each button will do).
13810
+ *
13811
+ * Pagination types (the four built in options and any additional plug-in
13812
+ * options defined here) can be used through the `paginationType`
13813
+ * initialisation parameter.
13814
+ *
13815
+ * The functions defined take two parameters:
13816
+ *
13817
+ * 1. `{int} page` The current page index
13818
+ * 2. `{int} pages` The number of pages in the table
13819
+ *
13820
+ * Each function is expected to return an array where each element of the
13821
+ * array can be one of:
13822
+ *
13823
+ * * `first` - Jump to first page when activated
13824
+ * * `last` - Jump to last page when activated
13825
+ * * `previous` - Show previous page when activated
13826
+ * * `next` - Show next page when activated
13827
+ * * `{int}` - Show page of the index given
13828
+ * * `{array}` - A nested array containing the above elements to add a
13829
+ * containing 'DIV' element (might be useful for styling).
13830
+ *
13831
+ * Note that DataTables v1.9- used this object slightly differently whereby
13832
+ * an object with two functions would be defined for each plug-in. That
13833
+ * ability is still supported by DataTables 1.10+ to provide backwards
13834
+ * compatibility, but this option of use is now decremented and no longer
13835
+ * documented in DataTables 1.10+.
13836
+ *
13837
+ * @type object
13838
+ * @default {}
13839
+ *
13840
+ * @example
13841
+ * // Show previous, next and current page buttons only
13842
+ * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
13843
+ * return [ 'previous', page, 'next' ];
13844
+ * };
13845
+ */
13846
+ pager: {},
13847
+
13848
+ renderer: {
13849
+ pageButton: {},
13850
+ header: {}
13851
+ },
13852
+
13853
+ /**
13854
+ * Ordering plug-ins - custom data source
13855
+ *
13856
+ * The extension options for ordering of data available here is complimentary
13857
+ * to the default type based ordering that DataTables typically uses. It
13858
+ * allows much greater control over the the data that is being used to
13859
+ * order a column, but is necessarily therefore more complex.
13860
+ *
13861
+ * This type of ordering is useful if you want to do ordering based on data
13862
+ * live from the DOM (for example the contents of an 'input' element) rather
13863
+ * than just the static string that DataTables knows of.
13864
+ *
13865
+ * The way these plug-ins work is that you create an array of the values you
13866
+ * wish to be ordering for the column in question and then return that
13867
+ * array. The data in the array much be in the index order of the rows in
13868
+ * the table (not the currently ordering order!). Which order data gathering
13869
+ * function is run here depends on the `dt-init columns.orderDataType`
13870
+ * parameter that is used for the column (if any).
13871
+ *
13872
+ * The functions defined take two parameters:
13873
+ *
13874
+ * 1. `{object}` DataTables settings object: see
13875
+ * {@link DataTable.models.oSettings}
13876
+ * 2. `{int}` Target column index
13877
+ *
13878
+ * Each function is expected to return an array:
13879
+ *
13880
+ * * `{array}` Data for the column to be ordering upon
13881
+ *
13882
+ * @type array
13883
+ *
13884
+ * @example
13885
+ * // Ordering using `input` node values
13886
+ * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
13887
+ * {
13888
+ * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
13889
+ * return $('input', td).val();
13890
+ * } );
13891
+ * }
13892
+ */
13893
+ order: {},
13894
+
13895
+ /**
13896
+ * Type based plug-ins.
13897
+ *
13898
+ * Each column in DataTables has a type assigned to it, either by automatic
13899
+ * detection or by direct assignment using the `type` option for the column.
13900
+ * The type of a column will effect how it is ordering and search (plug-ins
13901
+ * can also make use of the column type if required).
13902
+ *
13903
+ * @namespace
13904
+ */
13905
+ type: {
13906
+ /**
13907
+ * Type detection functions.
13908
+ *
13909
+ * The functions defined in this object are used to automatically detect
13910
+ * a column's type, making initialisation of DataTables super easy, even
13911
+ * when complex data is in the table.
13912
+ *
13913
+ * The functions defined take two parameters:
13914
+ *
13915
+ * 1. `{*}` Data from the column cell to be analysed
13916
+ * 2. `{settings}` DataTables settings object. This can be used to
13917
+ * perform context specific type detection - for example detection
13918
+ * based on language settings such as using a comma for a decimal
13919
+ * place. Generally speaking the options from the settings will not
13920
+ * be required
13921
+ *
13922
+ * Each function is expected to return:
13923
+ *
13924
+ * * `{string|null}` Data type detected, or null if unknown (and thus
13925
+ * pass it on to the other type detection functions.
13926
+ *
13927
+ * @type array
13928
+ *
13929
+ * @example
13930
+ * // Currency type detection plug-in:
13931
+ * $.fn.dataTable.ext.type.detect.push(
13932
+ * function ( data, settings ) {
13933
+ * // Check the numeric part
13934
+ * if ( ! $.isNumeric( data.substring(1) ) ) {
13935
+ * return null;
13936
+ * }
13937
+ *
13938
+ * // Check prefixed by currency
13939
+ * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
13940
+ * return 'currency';
13941
+ * }
13942
+ * return null;
13943
+ * }
13944
+ * );
13945
+ */
13946
+ detect: [],
13947
+
13948
+ /**
13949
+ * Type based search formatting.
13950
+ *
13951
+ * The type based searching functions can be used to pre-format the
13952
+ * data to be search on. For example, it can be used to strip HTML
13953
+ * tags or to de-format telephone numbers for numeric only searching.
13954
+ *
13955
+ * Note that is a search is not defined for a column of a given type,
13956
+ * no search formatting will be performed.
13957
+ *
13958
+ * Pre-processing of searching data plug-ins - When you assign the sType
13959
+ * for a column (or have it automatically detected for you by DataTables
13960
+ * or a type detection plug-in), you will typically be using this for
13961
+ * custom sorting, but it can also be used to provide custom searching
13962
+ * by allowing you to pre-processing the data and returning the data in
13963
+ * the format that should be searched upon. This is done by adding
13964
+ * functions this object with a parameter name which matches the sType
13965
+ * for that target column. This is the corollary of <i>afnSortData</i>
13966
+ * for searching data.
13967
+ *
13968
+ * The functions defined take a single parameter:
13969
+ *
13970
+ * 1. `{*}` Data from the column cell to be prepared for searching
13971
+ *
13972
+ * Each function is expected to return:
13973
+ *
13974
+ * * `{string|null}` Formatted string that will be used for the searching.
13975
+ *
13976
+ * @type object
13977
+ * @default {}
13978
+ *
13979
+ * @example
13980
+ * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
13981
+ * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
13982
+ * }
13983
+ */
13984
+ search: {},
13985
+
13986
+ /**
13987
+ * Type based ordering.
13988
+ *
13989
+ * The column type tells DataTables what ordering to apply to the table
13990
+ * when a column is sorted upon. The order for each type that is defined,
13991
+ * is defined by the functions available in this object.
13992
+ *
13993
+ * Each ordering option can be described by three properties added to
13994
+ * this object:
13995
+ *
13996
+ * * `{type}-pre` - Pre-formatting function
13997
+ * * `{type}-asc` - Ascending order function
13998
+ * * `{type}-desc` - Descending order function
13999
+ *
14000
+ * All three can be used together, only `{type}-pre` or only
14001
+ * `{type}-asc` and `{type}-desc` together. It is generally recommended
14002
+ * that only `{type}-pre` is used, as this provides the optimal
14003
+ * implementation in terms of speed, although the others are provided
14004
+ * for compatibility with existing Javascript sort functions.
14005
+ *
14006
+ * `{type}-pre`: Functions defined take a single parameter:
14007
+ *
14008
+ * 1. `{*}` Data from the column cell to be prepared for ordering
14009
+ *
14010
+ * And return:
14011
+ *
14012
+ * * `{*}` Data to be sorted upon
14013
+ *
14014
+ * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14015
+ * functions, taking two parameters:
14016
+ *
14017
+ * 1. `{*}` Data to compare to the second parameter
14018
+ * 2. `{*}` Data to compare to the first parameter
14019
+ *
14020
+ * And returning:
14021
+ *
14022
+ * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14023
+ * than the second parameter, ===0 if the two parameters are equal and
14024
+ * >0 if the first parameter should be sorted height than the second
14025
+ * parameter.
14026
+ *
14027
+ * @type object
14028
+ * @default {}
14029
+ *
14030
+ * @example
14031
+ * // Numeric ordering of formatted numbers with a pre-formatter
14032
+ * $.extend( $.fn.dataTable.ext.type.order, {
14033
+ * "string-pre": function(x) {
14034
+ * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14035
+ * return parseFloat( a );
14036
+ * }
14037
+ * } );
14038
+ *
14039
+ * @example
14040
+ * // Case-sensitive string ordering, with no pre-formatting method
14041
+ * $.extend( $.fn.dataTable.ext.order, {
14042
+ * "string-case-asc": function(x,y) {
14043
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14044
+ * },
14045
+ * "string-case-desc": function(x,y) {
14046
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14047
+ * }
14048
+ * } );
14049
+ */
14050
+ order: {}
14051
+ },
14052
+
14053
+ /**
14054
+ * Unique DataTables instance counter
14055
+ *
14056
+ * @type int
14057
+ * @private
14058
+ */
14059
+ _unique: 0,
14060
+
14061
+ //
14062
+ // Depreciated
14063
+ // The following properties are retained for backwards compatiblity only.
14064
+ // The should not be used in new projects and will be removed in a future
14065
+ // version
14066
+ //
14067
+
14068
+ /**
14069
+ * Version check function.
14070
+ * @type function
14071
+ * @depreciated Since 1.10
14072
+ */
14073
+ fnVersionCheck: DataTable.fnVersionCheck,
14074
+
14075
+ /**
14076
+ * Index for what 'this' index API functions should use
14077
+ * @type int
14078
+ * @deprecated Since v1.10
14079
+ */
14080
+ iApiIndex: 0,
14081
+
14082
+ /**
14083
+ * jQuery UI class container
14084
+ * @type object
14085
+ * @deprecated Since v1.10
14086
+ */
14087
+ oJUIClasses: {},
14088
+
14089
+ /**
14090
+ * Software version
14091
+ * @type string
14092
+ * @deprecated Since v1.10
14093
+ */
14094
+ sVersion: DataTable.version
14095
+ };
14096
+
14097
+
14098
+ //
14099
+ // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14100
+ //
14101
+ $.extend(_ext, {
14102
+ afnFiltering: _ext.search,
14103
+ aTypes: _ext.type.detect,
14104
+ ofnSearch: _ext.type.search,
14105
+ oSort: _ext.type.order,
14106
+ afnSortData: _ext.order,
14107
+ aoFeatures: _ext.feature,
14108
+ oApi: _ext.internal,
14109
+ oStdClasses: _ext.classes,
14110
+ oPagination: _ext.pager
14111
+ });
14112
+
14113
+
14114
+ $.extend(DataTable.ext.classes, {
14115
+ "sTable": "dataTable",
14116
+ "sNoFooter": "no-footer",
14117
+
14118
+ /* Paging buttons */
14119
+ "sPageButton": "paginate_button",
14120
+ "sPageButtonActive": "current",
14121
+ "sPageButtonDisabled": "disabled",
14122
+
14123
+ /* Striping classes */
14124
+ "sStripeOdd": "odd",
14125
+ "sStripeEven": "even",
14126
+
14127
+ /* Empty row */
14128
+ "sRowEmpty": "dataTables_empty",
14129
+
14130
+ /* Features */
14131
+ "sWrapper": "dataTables_wrapper",
14132
+ "sFilter": "dataTables_filter",
14133
+ "sInfo": "dataTables_info",
14134
+ "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
14135
+ "sLength": "dataTables_length",
14136
+ "sProcessing": "dataTables_processing",
14137
+
14138
+ /* Sorting */
14139
+ "sSortAsc": "sorting_asc",
14140
+ "sSortDesc": "sorting_desc",
14141
+ "sSortable": "sorting", /* Sortable in both directions */
14142
+ "sSortableAsc": "sorting_asc_disabled",
14143
+ "sSortableDesc": "sorting_desc_disabled",
14144
+ "sSortableNone": "sorting_disabled",
14145
+ "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14146
+
14147
+ /* Filtering */
14148
+ "sFilterInput": "",
14149
+
14150
+ /* Page length */
14151
+ "sLengthSelect": "",
14152
+
14153
+ /* Scrolling */
14154
+ "sScrollWrapper": "dataTables_scroll",
14155
+ "sScrollHead": "dataTables_scrollHead",
14156
+ "sScrollHeadInner": "dataTables_scrollHeadInner",
14157
+ "sScrollBody": "dataTables_scrollBody",
14158
+ "sScrollFoot": "dataTables_scrollFoot",
14159
+ "sScrollFootInner": "dataTables_scrollFootInner",
14160
+
14161
+ /* Misc */
14162
+ "sHeaderTH": "",
14163
+ "sFooterTH": "",
14164
+
14165
+ // Deprecated
14166
+ "sSortJUIAsc": "",
14167
+ "sSortJUIDesc": "",
14168
+ "sSortJUI": "",
14169
+ "sSortJUIAscAllowed": "",
14170
+ "sSortJUIDescAllowed": "",
14171
+ "sSortJUIWrapper": "",
14172
+ "sSortIcon": "",
14173
+ "sJUIHeader": "",
14174
+ "sJUIFooter": ""
14175
+ });
14176
+
14177
+
14178
+ (function () {
14179
+
14180
+ // Reused strings for better compression. Closure compiler appears to have a
14181
+ // weird edge case where it is trying to expand strings rather than use the
14182
+ // variable version. This results in about 200 bytes being added, for very
14183
+ // little preference benefit since it this run on script load only.
14184
+ var _empty = '';
14185
+ _empty = '';
14186
+
14187
+ var _stateDefault = _empty + 'ui-state-default';
14188
+ var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
14189
+ var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
14190
+
14191
+ $.extend(DataTable.ext.oJUIClasses, DataTable.ext.classes, {
14192
+ /* Full numbers paging buttons */
14193
+ "sPageButton": "fg-button ui-button " + _stateDefault,
14194
+ "sPageButtonActive": "ui-state-disabled",
14195
+ "sPageButtonDisabled": "ui-state-disabled",
14196
+
14197
+ /* Features */
14198
+ "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi " +
14199
+ "ui-buttonset-multi paging_", /* Note that the type is postfixed */
14200
+
14201
+ /* Sorting */
14202
+ "sSortAsc": _stateDefault + " sorting_asc",
14203
+ "sSortDesc": _stateDefault + " sorting_desc",
14204
+ "sSortable": _stateDefault + " sorting",
14205
+ "sSortableAsc": _stateDefault + " sorting_asc_disabled",
14206
+ "sSortableDesc": _stateDefault + " sorting_desc_disabled",
14207
+ "sSortableNone": _stateDefault + " sorting_disabled",
14208
+ "sSortJUIAsc": _sortIcon + "triangle-1-n",
14209
+ "sSortJUIDesc": _sortIcon + "triangle-1-s",
14210
+ "sSortJUI": _sortIcon + "carat-2-n-s",
14211
+ "sSortJUIAscAllowed": _sortIcon + "carat-1-n",
14212
+ "sSortJUIDescAllowed": _sortIcon + "carat-1-s",
14213
+ "sSortJUIWrapper": "DataTables_sort_wrapper",
14214
+ "sSortIcon": "DataTables_sort_icon",
14215
+
14216
+ /* Scrolling */
14217
+ "sScrollHead": "dataTables_scrollHead " + _stateDefault,
14218
+ "sScrollFoot": "dataTables_scrollFoot " + _stateDefault,
14219
+
14220
+ /* Misc */
14221
+ "sHeaderTH": _stateDefault,
14222
+ "sFooterTH": _stateDefault,
14223
+ "sJUIHeader": _headerFooter + " ui-corner-tl ui-corner-tr",
14224
+ "sJUIFooter": _headerFooter + " ui-corner-bl ui-corner-br"
14225
+ });
14226
+
14227
+ }());
14228
+
14229
+
14230
+
14231
+ var extPagination = DataTable.ext.pager;
14232
+
14233
+ function _numbers(page, pages) {
14234
+ var
14235
+ numbers = [],
14236
+ buttons = extPagination.numbers_length,
14237
+ half = Math.floor(buttons / 2),
14238
+ i = 1;
14239
+
14240
+ if (pages <= buttons) {
14241
+ numbers = _range(0, pages);
14242
+ } else if (page <= half) {
14243
+ numbers = _range(0, buttons - 2);
14244
+ numbers.push('ellipsis');
14245
+ numbers.push(pages - 1);
14246
+ } else if (page >= pages - 1 - half) {
14247
+ numbers = _range(pages - (buttons - 2), pages);
14248
+ numbers.splice(0, 0, 'ellipsis'); // no unshift in ie6
14249
+ numbers.splice(0, 0, 0);
14250
+ } else {
14251
+ numbers = _range(page - half + 2, page + half - 1);
14252
+ numbers.push('ellipsis');
14253
+ numbers.push(pages - 1);
14254
+ numbers.splice(0, 0, 'ellipsis');
14255
+ numbers.splice(0, 0, 0);
14256
+ }
14257
+
14258
+ numbers.DT_el = 'span';
14259
+ return numbers;
14260
+ }
14261
+
14262
+
14263
+ $.extend(extPagination, {
14264
+ simple: function (page, pages) {
14265
+ return ['previous', 'next'];
14266
+ },
14267
+
14268
+ full: function (page, pages) {
14269
+ return ['first', 'previous', 'next', 'last'];
14270
+ },
14271
+
14272
+ numbers: function (page, pages) {
14273
+ return [_numbers(page, pages)];
14274
+ },
14275
+
14276
+ simple_numbers: function (page, pages) {
14277
+ return ['previous', _numbers(page, pages), 'next'];
14278
+ },
14279
+
14280
+ full_numbers: function (page, pages) {
14281
+ return ['first', 'previous', _numbers(page, pages), 'next', 'last'];
14282
+ },
14283
+
14284
+ first_last_numbers: function (page, pages) {
14285
+ return ['first', _numbers(page, pages), 'last'];
14286
+ },
14287
+
14288
+ // For testing and plug-ins to use
14289
+ _numbers: _numbers,
14290
+
14291
+ // Number of number buttons (including ellipsis) to show. _Must be odd!_
14292
+ numbers_length: 7
14293
+ });
14294
+
14295
+
14296
+ $.extend(true, DataTable.ext.renderer, {
14297
+ pageButton: {
14298
+ _: function (settings, host, idx, buttons, page, pages) {
14299
+ var classes = settings.oClasses;
14300
+ var lang = settings.oLanguage.oPaginate;
14301
+ var aria = settings.oLanguage.oAria.paginate || {};
14302
+ var btnDisplay, btnClass, counter = 0;
14303
+
14304
+ var attach = function (container, buttons) {
14305
+ var i, ien, node, button;
14306
+ var clickHandler = function (e) {
14307
+ _fnPageChange(settings, e.data.action, true);
14308
+ };
14309
+
14310
+ for (i = 0, ien = buttons.length; i < ien; i++) {
14311
+ button = buttons[i];
14312
+
14313
+ if ($.isArray(button)) {
14314
+ var inner = $('<' + (button.DT_el || 'div') + '/>')
14315
+ .appendTo(container);
14316
+ attach(inner, button);
14317
+ } else {
14318
+ btnDisplay = null;
14319
+ btnClass = '';
14320
+
14321
+ switch (button) {
14322
+ case 'ellipsis':
14323
+ container.append('<span class="ellipsis">&#x2026;</span>');
14324
+ break;
14325
+
14326
+ case 'first':
14327
+ btnDisplay = lang.sFirst;
14328
+ btnClass = button + (page > 0 ?
14329
+ '' : ' ' + classes.sPageButtonDisabled);
14330
+ break;
14331
+
14332
+ case 'previous':
14333
+ btnDisplay = lang.sPrevious;
14334
+ btnClass = button + (page > 0 ?
14335
+ '' : ' ' + classes.sPageButtonDisabled);
14336
+ break;
14337
+
14338
+ case 'next':
14339
+ btnDisplay = lang.sNext;
14340
+ btnClass = button + (page < pages - 1 ?
14341
+ '' : ' ' + classes.sPageButtonDisabled);
14342
+ break;
14343
+
14344
+ case 'last':
14345
+ btnDisplay = lang.sLast;
14346
+ btnClass = button + (page < pages - 1 ?
14347
+ '' : ' ' + classes.sPageButtonDisabled);
14348
+ break;
14349
+
14350
+ default:
14351
+ btnDisplay = button + 1;
14352
+ btnClass = page === button ?
14353
+ classes.sPageButtonActive : '';
14354
+ break;
14355
+ }
14356
+
14357
+ if (btnDisplay !== null) {
14358
+ node = $('<a>', {
14359
+ 'class': classes.sPageButton + ' ' + btnClass,
14360
+ 'aria-controls': settings.sTableId,
14361
+ 'aria-label': aria[ button ],
14362
+ 'data-dt-idx': counter,
14363
+ 'tabindex': settings.iTabIndex,
14364
+ 'id': idx === 0 && typeof button === 'string' ?
14365
+ settings.sTableId + '_' + button :
14366
+ null
14367
+ })
14368
+ .html(btnDisplay)
14369
+ .appendTo(container);
14370
+
14371
+ _fnBindAction(
14372
+ node, {action: button}, clickHandler
14373
+ );
14374
+
14375
+ counter++;
14376
+ }
14377
+ }
14378
+ }
14379
+ };
14380
+
14381
+ // IE9 throws an 'unknown error' if document.activeElement is used
14382
+ // inside an iframe or frame. Try / catch the error. Not good for
14383
+ // accessibility, but neither are frames.
14384
+ var activeEl;
14385
+
14386
+ try {
14387
+ // Because this approach is destroying and recreating the paging
14388
+ // elements, focus is lost on the select button which is bad for
14389
+ // accessibility. So we want to restore focus once the draw has
14390
+ // completed
14391
+ activeEl = $(host).find(document.activeElement).data('dt-idx');
14392
+ } catch (e) {
14393
+ }
14394
+
14395
+ attach($(host).empty(), buttons);
14396
+
14397
+ if (activeEl !== undefined) {
14398
+ $(host).find('[data-dt-idx=' + activeEl + ']').focus();
14399
+ }
14400
+ }
14401
+ }
14402
+ });
14403
+
14404
+
14405
+
14406
+ // Built in type detection. See model.ext.aTypes for information about
14407
+ // what is required from this methods.
14408
+ $.extend(DataTable.ext.type.detect, [
14409
+ // Plain numbers - first since V8 detects some plain numbers as dates
14410
+ // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14411
+ function (d, settings)
14412
+ {
14413
+ var decimal = settings.oLanguage.sDecimal;
14414
+ return _isNumber(d, decimal) ? 'num' + decimal : null;
14415
+ },
14416
+
14417
+ // Dates (only those recognised by the browser's Date.parse)
14418
+ function (d, settings)
14419
+ {
14420
+ // V8 tries _very_ hard to make a string passed into `Date.parse()`
14421
+ // valid, so we need to use a regex to restrict date formats. Use a
14422
+ // plug-in for anything other than ISO8601 style strings
14423
+ if (d && !(d instanceof Date) && !_re_date.test(d)) {
14424
+ return null;
14425
+ }
14426
+ var parsed = Date.parse(d);
14427
+ return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
14428
+ },
14429
+
14430
+ // Formatted numbers
14431
+ function (d, settings)
14432
+ {
14433
+ var decimal = settings.oLanguage.sDecimal;
14434
+ return _isNumber(d, decimal, true) ? 'num-fmt' + decimal : null;
14435
+ },
14436
+
14437
+ // HTML numeric
14438
+ function (d, settings)
14439
+ {
14440
+ var decimal = settings.oLanguage.sDecimal;
14441
+ return _htmlNumeric(d, decimal) ? 'html-num' + decimal : null;
14442
+ },
14443
+
14444
+ // HTML numeric, formatted
14445
+ function (d, settings)
14446
+ {
14447
+ var decimal = settings.oLanguage.sDecimal;
14448
+ return _htmlNumeric(d, decimal, true) ? 'html-num-fmt' + decimal : null;
14449
+ },
14450
+
14451
+ // HTML (this is strict checking - there must be html)
14452
+ function (d, settings)
14453
+ {
14454
+ return _empty(d) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14455
+ 'html' : null;
14456
+ }
14457
+ ]);
14458
+
14459
+
14460
+
14461
+ // Filter formatting functions. See model.ext.ofnSearch for information about
14462
+ // what is required from these methods.
14463
+ //
14464
+ // Note that additional search methods are added for the html numbers and
14465
+ // html formatted numbers by `_addNumericSort()` when we know what the decimal
14466
+ // place is
14467
+
14468
+
14469
+ $.extend(DataTable.ext.type.search, {
14470
+ html: function (data) {
14471
+ return _empty(data) ?
14472
+ data :
14473
+ typeof data === 'string' ?
14474
+ data
14475
+ .replace(_re_new_lines, " ")
14476
+ .replace(_re_html, "") :
14477
+ '';
14478
+ },
14479
+
14480
+ string: function (data) {
14481
+ return _empty(data) ?
14482
+ data :
14483
+ typeof data === 'string' ?
14484
+ data.replace(_re_new_lines, " ") :
14485
+ data;
14486
+ }
14487
+ });
14488
+
14489
+
14490
+
14491
+ var __numericReplace = function (d, decimalPlace, re1, re2) {
14492
+ if (d !== 0 && (!d || d === '-')) {
14493
+ return -Infinity;
14494
+ }
14495
+
14496
+ // If a decimal place other than `.` is used, it needs to be given to the
14497
+ // function so we can detect it and replace with a `.` which is the only
14498
+ // decimal place Javascript recognises - it is not locale aware.
14499
+ if (decimalPlace) {
14500
+ d = _numToDecimal(d, decimalPlace);
14501
+ }
14502
+
14503
+ if (d.replace) {
14504
+ if (re1) {
14505
+ d = d.replace(re1, '');
14506
+ }
14507
+
14508
+ if (re2) {
14509
+ d = d.replace(re2, '');
14510
+ }
14511
+ }
14512
+
14513
+ return d * 1;
14514
+ };
14515
+
14516
+
14517
+ // Add the numeric 'deformatting' functions for sorting and search. This is done
14518
+ // in a function to provide an easy ability for the language options to add
14519
+ // additional methods if a non-period decimal place is used.
14520
+ function _addNumericSort(decimalPlace) {
14521
+ $.each(
14522
+ {
14523
+ // Plain numbers
14524
+ "num": function (d) {
14525
+ return __numericReplace(d, decimalPlace);
14526
+ },
14527
+
14528
+ // Formatted numbers
14529
+ "num-fmt": function (d) {
14530
+ return __numericReplace(d, decimalPlace, _re_formatted_numeric);
14531
+ },
14532
+
14533
+ // HTML numeric
14534
+ "html-num": function (d) {
14535
+ return __numericReplace(d, decimalPlace, _re_html);
14536
+ },
14537
+
14538
+ // HTML numeric, formatted
14539
+ "html-num-fmt": function (d) {
14540
+ return __numericReplace(d, decimalPlace, _re_html, _re_formatted_numeric);
14541
+ }
14542
+ },
14543
+ function (key, fn) {
14544
+ // Add the ordering method
14545
+ _ext.type.order[ key + decimalPlace + '-pre' ] = fn;
14546
+
14547
+ // For HTML types add a search formatter that will strip the HTML
14548
+ if (key.match(/^html\-/)) {
14549
+ _ext.type.search[ key + decimalPlace ] = _ext.type.search.html;
14550
+ }
14551
+ }
14552
+ );
14553
+ }
14554
+
14555
+
14556
+ // Default sort methods
14557
+ $.extend(_ext.type.order, {
14558
+ // Dates
14559
+ "date-pre": function (d) {
14560
+ return Date.parse(d) || -Infinity;
14561
+ },
14562
+
14563
+ // html
14564
+ "html-pre": function (a) {
14565
+ return _empty(a) ?
14566
+ '' :
14567
+ a.replace ?
14568
+ a.replace(/<.*?>/g, "").toLowerCase() :
14569
+ a + '';
14570
+ },
14571
+
14572
+ // string
14573
+ "string-pre": function (a) {
14574
+ // This is a little complex, but faster than always calling toString,
14575
+ // http://jsperf.com/tostring-v-check
14576
+ return _empty(a) ?
14577
+ '' :
14578
+ typeof a === 'string' ?
14579
+ a.toLowerCase() :
14580
+ !a.toString ?
14581
+ '' :
14582
+ a.toString();
14583
+ },
14584
+
14585
+ // string-asc and -desc are retained only for compatibility with the old
14586
+ // sort methods
14587
+ "string-asc": function (x, y) {
14588
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14589
+ },
14590
+
14591
+ "string-desc": function (x, y) {
14592
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14593
+ }
14594
+ });
14595
+
14596
+
14597
+ // Numeric sorting types - order doesn't matter here
14598
+ _addNumericSort('');
14599
+
14600
+
14601
+ $.extend(true, DataTable.ext.renderer, {
14602
+ header: {
14603
+ _: function (settings, cell, column, classes) {
14604
+ // No additional mark-up required
14605
+ // Attach a sort listener to update on sort - note that using the
14606
+ // `DT` namespace will allow the event to be removed automatically
14607
+ // on destroy, while the `dt` namespaced event is the one we are
14608
+ // listening for
14609
+ $(settings.nTable).on('order.dt.DT', function (e, ctx, sorting, columns) {
14610
+ if (settings !== ctx) { // need to check this this is the host
14611
+ return; // table, not a nested one
14612
+ }
14613
+
14614
+ var colIdx = column.idx;
14615
+
14616
+ cell
14617
+ .removeClass(
14618
+ column.sSortingClass + ' ' +
14619
+ classes.sSortAsc + ' ' +
14620
+ classes.sSortDesc
14621
+ )
14622
+ .addClass(columns[ colIdx ] == 'asc' ?
14623
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14624
+ classes.sSortDesc :
14625
+ column.sSortingClass
14626
+ );
14627
+ });
14628
+ },
14629
+
14630
+ jqueryui: function (settings, cell, column, classes) {
14631
+ $('<div/>')
14632
+ .addClass(classes.sSortJUIWrapper)
14633
+ .append(cell.contents())
14634
+ .append($('<span/>')
14635
+ .addClass(classes.sSortIcon + ' ' + column.sSortingClassJUI)
14636
+ )
14637
+ .appendTo(cell);
14638
+
14639
+ // Attach a sort listener to update on sort
14640
+ $(settings.nTable).on('order.dt.DT', function (e, ctx, sorting, columns) {
14641
+ if (settings !== ctx) {
14642
+ return;
14643
+ }
14644
+
14645
+ var colIdx = column.idx;
14646
+
14647
+ cell
14648
+ .removeClass(classes.sSortAsc + " " + classes.sSortDesc)
14649
+ .addClass(columns[ colIdx ] == 'asc' ?
14650
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14651
+ classes.sSortDesc :
14652
+ column.sSortingClass
14653
+ );
14654
+
14655
+ cell
14656
+ .find('span.' + classes.sSortIcon)
14657
+ .removeClass(
14658
+ classes.sSortJUIAsc + " " +
14659
+ classes.sSortJUIDesc + " " +
14660
+ classes.sSortJUI + " " +
14661
+ classes.sSortJUIAscAllowed + " " +
14662
+ classes.sSortJUIDescAllowed
14663
+ )
14664
+ .addClass(columns[ colIdx ] == 'asc' ?
14665
+ classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14666
+ classes.sSortJUIDesc :
14667
+ column.sSortingClassJUI
14668
+ );
14669
+ });
14670
+ }
14671
+ }
14672
+ });
14673
+
14674
+ /*
14675
+ * Public helper functions. These aren't used internally by DataTables, or
14676
+ * called by any of the options passed into DataTables, but they can be used
14677
+ * externally by developers working with DataTables. They are helper functions
14678
+ * to make working with DataTables a little bit easier.
14679
+ */
14680
+
14681
+ var __htmlEscapeEntities = function (d) {
14682
+ return typeof d === 'string' ?
14683
+ d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
14684
+ d;
14685
+ };
14686
+
14687
+ /**
14688
+ * Helpers for `columns.render`.
14689
+ *
14690
+ * The options defined here can be used with the `columns.render` initialisation
14691
+ * option to provide a display renderer. The following functions are defined:
14692
+ *
14693
+ * * `number` - Will format numeric data (defined by `columns.data`) for
14694
+ * display, retaining the original unformatted data for sorting and filtering.
14695
+ * It takes 5 parameters:
14696
+ * * `string` - Thousands grouping separator
14697
+ * * `string` - Decimal point indicator
14698
+ * * `integer` - Number of decimal points to show
14699
+ * * `string` (optional) - Prefix.
14700
+ * * `string` (optional) - Postfix (/suffix).
14701
+ * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
14702
+ * parameters.
14703
+ *
14704
+ * @example
14705
+ * // Column definition using the number renderer
14706
+ * {
14707
+ * data: "salary",
14708
+ * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14709
+ * }
14710
+ *
14711
+ * @namespace
14712
+ */
14713
+ DataTable.render = {
14714
+ number: function (thousands, decimal, precision, prefix, postfix) {
14715
+ return {
14716
+ display: function (d) {
14717
+ if (typeof d !== 'number' && typeof d !== 'string') {
14718
+ return d;
14719
+ }
14720
+
14721
+ var negative = d < 0 ? '-' : '';
14722
+ var flo = parseFloat(d);
14723
+
14724
+ // If NaN then there isn't much formatting that we can do - just
14725
+ // return immediately, escaping any HTML (this was supposed to
14726
+ // be a number after all)
14727
+ if (isNaN(flo)) {
14728
+ return __htmlEscapeEntities(d);
14729
+ }
14730
+
14731
+ flo = flo.toFixed(precision);
14732
+ d = Math.abs(flo);
14733
+
14734
+ var intPart = parseInt(d, 10);
14735
+ var floatPart = precision ?
14736
+ decimal + (d - intPart).toFixed(precision).substring(2) :
14737
+ '';
14738
+
14739
+ return negative + (prefix || '') +
14740
+ intPart.toString().replace(
14741
+ /\B(?=(\d{3})+(?!\d))/g, thousands
14742
+ ) +
14743
+ floatPart +
14744
+ (postfix || '');
14745
+ }
14746
+ };
14747
+ },
14748
+
14749
+ text: function () {
14750
+ return {
14751
+ display: __htmlEscapeEntities
14752
+ };
14753
+ }
14754
+ };
14755
+
14756
+
14757
+ /*
14758
+ * This is really a good bit rubbish this method of exposing the internal methods
14759
+ * publicly... - To be fixed in 2.0 using methods on the prototype
14760
+ */
14761
+
14762
+
14763
+ /**
14764
+ * Create a wrapper function for exporting an internal functions to an external API.
14765
+ * @param {string} fn API function name
14766
+ * @returns {function} wrapped function
14767
+ * @memberof DataTable#internal
14768
+ */
14769
+ function _fnExternApiFunc(fn)
14770
+ {
14771
+ return function () {
14772
+ var args = [_fnSettingsFromNode(this[DataTable.ext.iApiIndex])].concat(
14773
+ Array.prototype.slice.call(arguments)
14774
+ );
14775
+ return DataTable.ext.internal[fn].apply(this, args);
14776
+ };
14777
+ }
14778
+
14779
+
14780
+ /**
14781
+ * Reference to internal functions for use by plug-in developers. Note that
14782
+ * these methods are references to internal functions and are considered to be
14783
+ * private. If you use these methods, be aware that they are liable to change
14784
+ * between versions.
14785
+ * @namespace
14786
+ */
14787
+ $.extend(DataTable.ext.internal, {
14788
+ _fnExternApiFunc: _fnExternApiFunc,
14789
+ _fnBuildAjax: _fnBuildAjax,
14790
+ _fnAjaxUpdate: _fnAjaxUpdate,
14791
+ _fnAjaxParameters: _fnAjaxParameters,
14792
+ _fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
14793
+ _fnAjaxDataSrc: _fnAjaxDataSrc,
14794
+ _fnAddColumn: _fnAddColumn,
14795
+ _fnColumnOptions: _fnColumnOptions,
14796
+ _fnAdjustColumnSizing: _fnAdjustColumnSizing,
14797
+ _fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
14798
+ _fnColumnIndexToVisible: _fnColumnIndexToVisible,
14799
+ _fnVisbleColumns: _fnVisbleColumns,
14800
+ _fnGetColumns: _fnGetColumns,
14801
+ _fnColumnTypes: _fnColumnTypes,
14802
+ _fnApplyColumnDefs: _fnApplyColumnDefs,
14803
+ _fnHungarianMap: _fnHungarianMap,
14804
+ _fnCamelToHungarian: _fnCamelToHungarian,
14805
+ _fnLanguageCompat: _fnLanguageCompat,
14806
+ _fnBrowserDetect: _fnBrowserDetect,
14807
+ _fnAddData: _fnAddData,
14808
+ _fnAddTr: _fnAddTr,
14809
+ _fnNodeToDataIndex: _fnNodeToDataIndex,
14810
+ _fnNodeToColumnIndex: _fnNodeToColumnIndex,
14811
+ _fnGetCellData: _fnGetCellData,
14812
+ _fnSetCellData: _fnSetCellData,
14813
+ _fnSplitObjNotation: _fnSplitObjNotation,
14814
+ _fnGetObjectDataFn: _fnGetObjectDataFn,
14815
+ _fnSetObjectDataFn: _fnSetObjectDataFn,
14816
+ _fnGetDataMaster: _fnGetDataMaster,
14817
+ _fnClearTable: _fnClearTable,
14818
+ _fnDeleteIndex: _fnDeleteIndex,
14819
+ _fnInvalidate: _fnInvalidate,
14820
+ _fnGetRowElements: _fnGetRowElements,
14821
+ _fnCreateTr: _fnCreateTr,
14822
+ _fnBuildHead: _fnBuildHead,
14823
+ _fnDrawHead: _fnDrawHead,
14824
+ _fnDraw: _fnDraw,
14825
+ _fnReDraw: _fnReDraw,
14826
+ _fnAddOptionsHtml: _fnAddOptionsHtml,
14827
+ _fnDetectHeader: _fnDetectHeader,
14828
+ _fnGetUniqueThs: _fnGetUniqueThs,
14829
+ _fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
14830
+ _fnFilterComplete: _fnFilterComplete,
14831
+ _fnFilterCustom: _fnFilterCustom,
14832
+ _fnFilterColumn: _fnFilterColumn,
14833
+ _fnFilter: _fnFilter,
14834
+ _fnFilterCreateSearch: _fnFilterCreateSearch,
14835
+ _fnEscapeRegex: _fnEscapeRegex,
14836
+ _fnFilterData: _fnFilterData,
14837
+ _fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
14838
+ _fnUpdateInfo: _fnUpdateInfo,
14839
+ _fnInfoMacros: _fnInfoMacros,
14840
+ _fnInitialise: _fnInitialise,
14841
+ _fnInitComplete: _fnInitComplete,
14842
+ _fnLengthChange: _fnLengthChange,
14843
+ _fnFeatureHtmlLength: _fnFeatureHtmlLength,
14844
+ _fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
14845
+ _fnPageChange: _fnPageChange,
14846
+ _fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
14847
+ _fnProcessingDisplay: _fnProcessingDisplay,
14848
+ _fnFeatureHtmlTable: _fnFeatureHtmlTable,
14849
+ _fnScrollDraw: _fnScrollDraw,
14850
+ _fnApplyToChildren: _fnApplyToChildren,
14851
+ _fnCalculateColumnWidths: _fnCalculateColumnWidths,
14852
+ _fnThrottle: _fnThrottle,
14853
+ _fnConvertToWidth: _fnConvertToWidth,
14854
+ _fnGetWidestNode: _fnGetWidestNode,
14855
+ _fnGetMaxLenString: _fnGetMaxLenString,
14856
+ _fnStringToCss: _fnStringToCss,
14857
+ _fnSortFlatten: _fnSortFlatten,
14858
+ _fnSort: _fnSort,
14859
+ _fnSortAria: _fnSortAria,
14860
+ _fnSortListener: _fnSortListener,
14861
+ _fnSortAttachListener: _fnSortAttachListener,
14862
+ _fnSortingClasses: _fnSortingClasses,
14863
+ _fnSortData: _fnSortData,
14864
+ _fnSaveState: _fnSaveState,
14865
+ _fnLoadState: _fnLoadState,
14866
+ _fnSettingsFromNode: _fnSettingsFromNode,
14867
+ _fnLog: _fnLog,
14868
+ _fnMap: _fnMap,
14869
+ _fnBindAction: _fnBindAction,
14870
+ _fnCallbackReg: _fnCallbackReg,
14871
+ _fnCallbackFire: _fnCallbackFire,
14872
+ _fnLengthOverflow: _fnLengthOverflow,
14873
+ _fnRenderer: _fnRenderer,
14874
+ _fnDataSource: _fnDataSource,
14875
+ _fnRowAttributes: _fnRowAttributes,
14876
+ _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
14877
+ // in 1.10, so this dead-end function is
14878
+ // added to prevent errors
14879
+ });
14880
+
14881
+
14882
+ // jQuery access
14883
+ $.fn.dataTable = DataTable;
14884
+
14885
+ // Provide access to the host jQuery object (circular reference)
14886
+ DataTable.$ = $;
14887
+
14888
+ // Legacy aliases
14889
+ $.fn.dataTableSettings = DataTable.settings;
14890
+ $.fn.dataTableExt = DataTable.ext;
14891
+
14892
+ // With a capital `D` we return a DataTables API instance rather than a
14893
+ // jQuery object
14894
+ $.fn.DataTable = function (opts) {
14895
+ return $(this).dataTable(opts).api();
14896
+ };
14897
+
14898
+ // All properties that are available to $.fn.dataTable should also be
14899
+ // available on $.fn.DataTable
14900
+ $.each(DataTable, function (prop, val) {
14901
+ $.fn.DataTable[ prop ] = val;
14902
+ });
14903
+
14904
+
14905
+ // Information about events fired by DataTables - for documentation.
14906
+ /**
14907
+ * Draw event, fired whenever the table is redrawn on the page, at the same
14908
+ * point as fnDrawCallback. This may be useful for binding events or
14909
+ * performing calculations when the table is altered at all.
14910
+ * @name DataTable#draw.dt
14911
+ * @event
14912
+ * @param {event} e jQuery event object
14913
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14914
+ */
14915
+
14916
+ /**
14917
+ * Search event, fired when the searching applied to the table (using the
14918
+ * built-in global search, or column filters) is altered.
14919
+ * @name DataTable#search.dt
14920
+ * @event
14921
+ * @param {event} e jQuery event object
14922
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14923
+ */
14924
+
14925
+ /**
14926
+ * Page change event, fired when the paging of the table is altered.
14927
+ * @name DataTable#page.dt
14928
+ * @event
14929
+ * @param {event} e jQuery event object
14930
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14931
+ */
14932
+
14933
+ /**
14934
+ * Order event, fired when the ordering applied to the table is altered.
14935
+ * @name DataTable#order.dt
14936
+ * @event
14937
+ * @param {event} e jQuery event object
14938
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14939
+ */
14940
+
14941
+ /**
14942
+ * DataTables initialisation complete event, fired when the table is fully
14943
+ * drawn, including Ajax data loaded, if Ajax data is required.
14944
+ * @name DataTable#init.dt
14945
+ * @event
14946
+ * @param {event} e jQuery event object
14947
+ * @param {object} oSettings DataTables settings object
14948
+ * @param {object} json The JSON object request from the server - only
14949
+ * present if client-side Ajax sourced data is used</li></ol>
14950
+ */
14951
+
14952
+ /**
14953
+ * State save event, fired when the table has changed state a new state save
14954
+ * is required. This event allows modification of the state saving object
14955
+ * prior to actually doing the save, including addition or other state
14956
+ * properties (for plug-ins) or modification of a DataTables core property.
14957
+ * @name DataTable#stateSaveParams.dt
14958
+ * @event
14959
+ * @param {event} e jQuery event object
14960
+ * @param {object} oSettings DataTables settings object
14961
+ * @param {object} json The state information to be saved
14962
+ */
14963
+
14964
+ /**
14965
+ * State load event, fired when the table is loading state from the stored
14966
+ * data, but prior to the settings object being modified by the saved state
14967
+ * - allowing modification of the saved state is required or loading of
14968
+ * state for a plug-in.
14969
+ * @name DataTable#stateLoadParams.dt
14970
+ * @event
14971
+ * @param {event} e jQuery event object
14972
+ * @param {object} oSettings DataTables settings object
14973
+ * @param {object} json The saved state information
14974
+ */
14975
+
14976
+ /**
14977
+ * State loaded event, fired when state has been loaded from stored data and
14978
+ * the settings object has been modified by the loaded data.
14979
+ * @name DataTable#stateLoaded.dt
14980
+ * @event
14981
+ * @param {event} e jQuery event object
14982
+ * @param {object} oSettings DataTables settings object
14983
+ * @param {object} json The saved state information
14984
+ */
14985
+
14986
+ /**
14987
+ * Processing event, fired when DataTables is doing some kind of processing
14988
+ * (be it, order, searcg or anything else). It can be used to indicate to
14989
+ * the end user that there is something happening, or that something has
14990
+ * finished.
14991
+ * @name DataTable#processing.dt
14992
+ * @event
14993
+ * @param {event} e jQuery event object
14994
+ * @param {object} oSettings DataTables settings object
14995
+ * @param {boolean} bShow Flag for if DataTables is doing processing or not
14996
+ */
14997
+
14998
+ /**
14999
+ * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15000
+ * request to made to the server for new data. This event is called before
15001
+ * DataTables processed the returned data, so it can also be used to pre-
15002
+ * process the data returned from the server, if needed.
15003
+ *
15004
+ * Note that this trigger is called in `fnServerData`, if you override
15005
+ * `fnServerData` and which to use this event, you need to trigger it in you
15006
+ * success function.
15007
+ * @name DataTable#xhr.dt
15008
+ * @event
15009
+ * @param {event} e jQuery event object
15010
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15011
+ * @param {object} json JSON returned from the server
15012
+ *
15013
+ * @example
15014
+ * // Use a custom property returned from the server in another DOM element
15015
+ * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15016
+ * $('#status').html( json.status );
15017
+ * } );
15018
+ *
15019
+ * @example
15020
+ * // Pre-process the data returned from the server
15021
+ * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15022
+ * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15023
+ * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15024
+ * }
15025
+ * // Note no return - manipulate the data directly in the JSON object.
15026
+ * } );
15027
+ */
15028
+
15029
+ /**
15030
+ * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15031
+ * or passing the bDestroy:true parameter in the initialisation object. This
15032
+ * can be used to remove bound events, added DOM nodes, etc.
15033
+ * @name DataTable#destroy.dt
15034
+ * @event
15035
+ * @param {event} e jQuery event object
15036
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15037
+ */
15038
+
15039
+ /**
15040
+ * Page length change event, fired when number of records to show on each
15041
+ * page (the length) is changed.
15042
+ * @name DataTable#length.dt
15043
+ * @event
15044
+ * @param {event} e jQuery event object
15045
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15046
+ * @param {integer} len New length
15047
+ */
15048
+
15049
+ /**
15050
+ * Column sizing has changed.
15051
+ * @name DataTable#column-sizing.dt
15052
+ * @event
15053
+ * @param {event} e jQuery event object
15054
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15055
+ */
15056
+
15057
+ /**
15058
+ * Column visibility has changed.
15059
+ * @name DataTable#column-visibility.dt
15060
+ * @event
15061
+ * @param {event} e jQuery event object
15062
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15063
+ * @param {int} column Column index
15064
+ * @param {bool} vis `false` if column now hidden, or `true` if visible
15065
+ */
15066
+
15067
+ return $.fn.dataTable;
15068
+ }));
15069
+
15070
+
15071
+ (function (window, document, undefined) {
15072
+
15073
+ var factory = function ($, DataTable) {
15074
+ "use strict";
15075
+
15076
+ $.extend(true, DataTable.defaults, {
15077
+ dom: "<'row'<'col-sm-5'><'col-sm-4'f><'col-sm-3'l>>" +
15078
+ "<'row'<'col-sm-12'tr>>" +
15079
+ "<'row'<'col-sm-5'i><'col-sm-7'p>>",
15080
+ renderer: 'bootstrap'
15081
+ });
15082
+
15083
+ /* Default class modification */
15084
+ $.extend(DataTable.ext.classes, {
15085
+ sWrapper: "dataTables_wrapper form-inline dt-bootstrap",
15086
+ sFilterInput: "form-control input-sm",
15087
+ sLengthSelect: "form-control input-sm"
15088
+ });
15089
+
15090
+ DataTable.ext.renderer.pageButton.bootstrap = function (settings, host, idx, buttons, page, pages) {
15091
+ var api = new DataTable.Api(settings);
15092
+ var classes = settings.oClasses;
15093
+ var lang = settings.oLanguage.oPaginate;
15094
+ var btnDisplay, btnClass, counter = 0;
15095
+
15096
+ var attach = function (container, buttons) {
15097
+ var i, ien, node, button;
15098
+ var clickHandler = function (e) {
15099
+ e.preventDefault();
15100
+ if (!$(e.currentTarget).hasClass('disabled')) {
15101
+ api.page(e.data.action).draw('page');
15102
+ }
15103
+ };
15104
+
15105
+ for (i = 0, ien = buttons.length; i < ien; i++) {
15106
+ button = buttons[i];
15107
+
15108
+ if ($.isArray(button)) {
15109
+ attach(container, button);
15110
+ } else {
15111
+ btnDisplay = '';
15112
+ btnClass = '';
15113
+
15114
+ switch (button) {
15115
+ case 'ellipsis':
15116
+ btnDisplay = '&hellip;';
15117
+ btnClass = 'disabled';
15118
+ break;
15119
+
15120
+ case 'first':
15121
+ btnDisplay = lang.sFirst;
15122
+ btnClass = button + (page > 0 ?
15123
+ '' : ' disabled');
15124
+ break;
15125
+
15126
+ case 'previous':
15127
+ btnDisplay = lang.sPrevious;
15128
+ btnClass = button + (page > 0 ?
15129
+ '' : ' disabled');
15130
+ break;
15131
+
15132
+ case 'next':
15133
+ btnDisplay = lang.sNext;
15134
+ btnClass = button + (page < pages - 1 ?
15135
+ '' : ' disabled');
15136
+ break;
15137
+
15138
+ case 'last':
15139
+ btnDisplay = lang.sLast;
15140
+ btnClass = button + (page < pages - 1 ?
15141
+ '' : ' disabled');
15142
+ break;
15143
+
15144
+ default:
15145
+ btnDisplay = button + 1;
15146
+ btnClass = page === button ?
15147
+ 'active' : '';
15148
+ break;
15149
+ }
15150
+
15151
+ if (btnDisplay) {
15152
+ node = $('<li>', {
15153
+ 'class': classes.sPageButton + ' ' + btnClass,
15154
+ 'id': idx === 0 && typeof button === 'string' ?
15155
+ settings.sTableId + '_' + button : null
15156
+ })
15157
+ .append($('<a>', {
15158
+ 'href': '#',
15159
+ 'aria-controls': settings.sTableId,
15160
+ 'data-dt-idx': counter,
15161
+ 'tabindex': settings.iTabIndex
15162
+ })
15163
+ .html(btnDisplay)
15164
+ )
15165
+ .appendTo(container);
15166
+
15167
+ settings.oApi._fnBindAction(
15168
+ node, {
15169
+ action: button
15170
+ }, clickHandler
15171
+ );
15172
+
15173
+ counter++;
15174
+ }
15175
+ }
15176
+ }
15177
+ };
15178
+
15179
+ var activeEl;
15180
+
15181
+ try {
15182
+
15183
+ activeEl = $(host).find(document.activeElement).data('dt-idx');
15184
+ } catch (e) {
15185
+ }
15186
+
15187
+ attach(
15188
+ $(host).empty().html('<ul class="pagination"/>').children('ul'),
15189
+ buttons
15190
+ );
15191
+
15192
+ if (activeEl) {
15193
+ $(host).find('[data-dt-idx=' + activeEl + ']').focus();
15194
+ }
15195
+ };
15196
+
15197
+ if (DataTable.TableTools) {
15198
+ // Set the classes that TableTools uses to something suitable for Bootstrap
15199
+ $.extend(true, DataTable.TableTools.classes, {
15200
+ "container": "DTTT btn-group",
15201
+ "buttons": {
15202
+ "normal": "btn btn-default",
15203
+ "disabled": "disabled"
15204
+ },
15205
+ "collection": {
15206
+ "container": "DTTT_dropdown dropdown-menu",
15207
+ "buttons": {
15208
+ "normal": "",
15209
+ "disabled": "disabled"
15210
+ }
15211
+ },
15212
+ "print": {
15213
+ "info": "DTTT_print_info"
15214
+ },
15215
+ "select": {
15216
+ "row": "active"
15217
+ }
15218
+ });
15219
+
15220
+ // Have the collection use a bootstrap compatible drop down
15221
+ $.extend(true, DataTable.TableTools.DEFAULTS.oTags, {
15222
+ "collection": {
15223
+ "container": "ul",
15224
+ "button": "li",
15225
+ "liner": "a"
15226
+ }
15227
+ });
15228
+ }
15229
+
15230
+ };
15231
+ if (typeof define === 'function' && define.amd) {
15232
+ define(['jquery', 'datatables'], factory);
15233
+ } else if (typeof exports === 'object') {
15234
+ // Node/CommonJS
15235
+ factory(require('jquery'), require('datatables'));
15236
+ } else if (jQuery) {
15237
+ // Otherwise simply initialise as normal, stopping multiple evaluation
15238
+ factory(jQuery, jQuery.fn.dataTable);
15239
+ }
15240
+ })(window, document);
assets/global/plugins/datatables/media/js/jszip.min.js ADDED
@@ -0,0 +1,2766 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+
3
+ JSZip - A Javascript class for generating and reading zip files
4
+ <http://stuartk.com/jszip>
5
+
6
+ (c) 2009-2014 Stuart Knightley <stuart [at] stuartk.com>
7
+ Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.
8
+
9
+ JSZip uses the library pako released under the MIT license :
10
+ https://github.com/nodeca/pako/blob/master/LICENSE
11
+ */
12
+ !function (a) {
13
+ if ("object" == typeof exports && "undefined" != typeof module)
14
+ module.exports = a();
15
+ else if ("function" == typeof define && define.amd)
16
+ define([], a);
17
+ else {
18
+ var b;
19
+ "undefined" != typeof window ? b = window : "undefined" != typeof global ? b = global : "undefined" != typeof self && (b = self), b.JSZip = a()
20
+ }
21
+ }(function () {
22
+ return function a(b, c, d) {
23
+ function e(g, h) {
24
+ if (!c[g]) {
25
+ if (!b[g]) {
26
+ var i = "function" == typeof require && require;
27
+ if (!h && i)
28
+ return i(g, !0);
29
+ if (f)
30
+ return f(g, !0);
31
+ throw new Error("Cannot find module '" + g + "'")
32
+ }
33
+ var j = c[g] = {
34
+ exports: {}
35
+ };
36
+ b[g][0].call(j.exports, function (a) {
37
+ var c = b[g][1][a];
38
+ return e(c ? c : a)
39
+ }, j, j.exports, a, b, c, d)
40
+ }
41
+ return c[g].exports
42
+ }
43
+ for (var f = "function" == typeof require && require, g = 0; g < d.length; g++)
44
+ e(d[g]);
45
+ return e
46
+ }({
47
+ 1: [function (a, b, c) {
48
+ "use strict";
49
+ var d = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
50
+ c.encode = function (a) {
51
+ for (var b, c, e, f, g, h, i, j = "", k = 0; k < a.length; )
52
+ b = a.charCodeAt(k++), c = a.charCodeAt(k++), e = a.charCodeAt(k++), f = b >> 2, g = (3 & b) << 4 | c >> 4, h = (15 & c) << 2 | e >> 6, i = 63 & e, isNaN(c) ? h = i = 64 : isNaN(e) && (i = 64), j = j + d.charAt(f) + d.charAt(g) + d.charAt(h) + d.charAt(i);
53
+ return j
54
+ }, c.decode = function (a) {
55
+ var b, c, e, f, g, h, i, j = "",
56
+ k = 0;
57
+ for (a = a.replace(/[^A-Za-z0-9\+\/\=]/g, ""); k < a.length; )
58
+ f = d.indexOf(a.charAt(k++)), g = d.indexOf(a.charAt(k++)), h = d.indexOf(a.charAt(k++)), i = d.indexOf(a.charAt(k++)), b = f << 2 | g >> 4, c = (15 & g) << 4 | h >> 2, e = (3 & h) << 6 | i, j += String.fromCharCode(b), 64 != h && (j += String.fromCharCode(c)), 64 != i && (j += String.fromCharCode(e));
59
+ return j
60
+ }
61
+ }, {}],
62
+ 2: [function (a, b) {
63
+ "use strict";
64
+
65
+ function c() {
66
+ this.compressedSize = 0, this.uncompressedSize = 0, this.crc32 = 0, this.compressionMethod = null, this.compressedContent = null
67
+ }
68
+ c.prototype = {
69
+ getContent: function () {
70
+ return null
71
+ },
72
+ getCompressedContent: function () {
73
+ return null
74
+ }
75
+ }, b.exports = c
76
+ }, {}],
77
+ 3: [function (a, b, c) {
78
+ "use strict";
79
+ c.STORE = {
80
+ magic: "\x00\x00",
81
+ compress: function (a) {
82
+ return a
83
+ },
84
+ uncompress: function (a) {
85
+ return a
86
+ },
87
+ compressInputType: null,
88
+ uncompressInputType: null
89
+ }, c.DEFLATE = a("./flate")
90
+ }, {
91
+ "./flate": 8
92
+ }],
93
+ 4: [function (a, b) {
94
+ "use strict";
95
+ var c = a("./utils"),
96
+ d = [0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918e3, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117];
97
+ b.exports = function (a, b) {
98
+ if ("undefined" == typeof a || !a.length)
99
+ return 0;
100
+ var e = "string" !== c.getTypeOf(a);
101
+ "undefined" == typeof b && (b = 0);
102
+ var f = 0,
103
+ g = 0,
104
+ h = 0;
105
+ b = -1 ^ b;
106
+ for (var i = 0, j = a.length; j > i; i++)
107
+ h = e ? a[i] : a.charCodeAt(i), g = 255 & (b ^ h), f = d[g], b = b >>> 8 ^ f;
108
+ return -1 ^ b
109
+ }
110
+ }, {
111
+ "./utils": 21
112
+ }],
113
+ 5: [function (a, b) {
114
+ "use strict";
115
+
116
+ function c() {
117
+ this.data = null, this.length = 0, this.index = 0
118
+ }
119
+ var d = a("./utils");
120
+ c.prototype = {
121
+ checkOffset: function (a) {
122
+ this.checkIndex(this.index + a)
123
+ },
124
+ checkIndex: function (a) {
125
+ if (this.length < a || 0 > a)
126
+ throw new Error("End of data reached (data length = " + this.length + ", asked index = " + a + "). Corrupted zip ?")
127
+ },
128
+ setIndex: function (a) {
129
+ this.checkIndex(a), this.index = a
130
+ },
131
+ skip: function (a) {
132
+ this.setIndex(this.index + a)
133
+ },
134
+ byteAt: function () {},
135
+ readInt: function (a) {
136
+ var b, c = 0;
137
+ for (this.checkOffset(a), b = this.index + a - 1; b >= this.index; b--)
138
+ c = (c << 8) + this.byteAt(b);
139
+ return this.index += a, c
140
+ },
141
+ readString: function (a) {
142
+ return d.transformTo("string", this.readData(a))
143
+ },
144
+ readData: function () {},
145
+ lastIndexOfSignature: function () {},
146
+ readDate: function () {
147
+ var a = this.readInt(4);
148
+ return new Date((a >> 25 & 127) + 1980, (a >> 21 & 15) - 1, a >> 16 & 31, a >> 11 & 31, a >> 5 & 63, (31 & a) << 1)
149
+ }
150
+ }, b.exports = c
151
+ }, {
152
+ "./utils": 21
153
+ }],
154
+ 6: [function (a, b, c) {
155
+ "use strict";
156
+ c.base64 = !1, c.binary = !1, c.dir = !1, c.createFolders = !1, c.date = null, c.compression = null, c.compressionOptions = null, c.comment = null, c.unixPermissions = null, c.dosPermissions = null
157
+ }, {}],
158
+ 7: [function (a, b, c) {
159
+ "use strict";
160
+ var d = a("./utils");
161
+ c.string2binary = function (a) {
162
+ return d.string2binary(a)
163
+ }, c.string2Uint8Array = function (a) {
164
+ return d.transformTo("uint8array", a)
165
+ }, c.uint8Array2String = function (a) {
166
+ return d.transformTo("string", a)
167
+ }, c.string2Blob = function (a) {
168
+ var b = d.transformTo("arraybuffer", a);
169
+ return d.arrayBuffer2Blob(b)
170
+ }, c.arrayBuffer2Blob = function (a) {
171
+ return d.arrayBuffer2Blob(a)
172
+ }, c.transformTo = function (a, b) {
173
+ return d.transformTo(a, b)
174
+ }, c.getTypeOf = function (a) {
175
+ return d.getTypeOf(a)
176
+ }, c.checkSupport = function (a) {
177
+ return d.checkSupport(a)
178
+ }, c.MAX_VALUE_16BITS = d.MAX_VALUE_16BITS, c.MAX_VALUE_32BITS = d.MAX_VALUE_32BITS, c.pretty = function (a) {
179
+ return d.pretty(a)
180
+ }, c.findCompression = function (a) {
181
+ return d.findCompression(a)
182
+ }, c.isRegExp = function (a) {
183
+ return d.isRegExp(a)
184
+ }
185
+ }, {
186
+ "./utils": 21
187
+ }],
188
+ 8: [function (a, b, c) {
189
+ "use strict";
190
+ var d = "undefined" != typeof Uint8Array && "undefined" != typeof Uint16Array && "undefined" != typeof Uint32Array,
191
+ e = a("pako");
192
+ c.uncompressInputType = d ? "uint8array" : "array", c.compressInputType = d ? "uint8array" : "array", c.magic = "\b\x00", c.compress = function (a, b) {
193
+ return e.deflateRaw(a, {
194
+ level: b.level || -1
195
+ })
196
+ }, c.uncompress = function (a) {
197
+ return e.inflateRaw(a)
198
+ }
199
+ }, {
200
+ pako: 24
201
+ }],
202
+ 9: [function (a, b) {
203
+ "use strict";
204
+
205
+ function c(a, b) {
206
+ return this instanceof c ? (this.files = {}, this.comment = null, this.root = "", a && this.load(a, b), void(this.clone = function () {
207
+ var a = new c;
208
+ for (var b in this)
209
+ "function" != typeof this[b] && (a[b] = this[b]);
210
+ return a
211
+ })) : new c(a, b)
212
+ }
213
+ var d = a("./base64");
214
+ c.prototype = a("./object"), c.prototype.load = a("./load"), c.support = a("./support"), c.defaults = a("./defaults"), c.utils = a("./deprecatedPublicUtils"), c.base64 = {
215
+ encode: function (a) {
216
+ return d.encode(a)
217
+ },
218
+ decode: function (a) {
219
+ return d.decode(a)
220
+ }
221
+ }, c.compressions = a("./compressions"), b.exports = c
222
+ }, {
223
+ "./base64": 1,
224
+ "./compressions": 3,
225
+ "./defaults": 6,
226
+ "./deprecatedPublicUtils": 7,
227
+ "./load": 10,
228
+ "./object": 13,
229
+ "./support": 17
230
+ }],
231
+ 10: [function (a, b) {
232
+ "use strict";
233
+ var c = a("./base64"),
234
+ d = a("./zipEntries");
235
+ b.exports = function (a, b) {
236
+ var e, f, g, h;
237
+ for (b = b || {}, b.base64 && (a = c.decode(a)), f = new d(a, b), e = f.files, g = 0; g < e.length; g++)
238
+ h = e[g], this.file(h.fileName, h.decompressed, {
239
+ binary: !0,
240
+ optimizedBinaryString: !0,
241
+ date: h.date,
242
+ dir: h.dir,
243
+ comment: h.fileComment.length ? h.fileComment : null,
244
+ unixPermissions: h.unixPermissions,
245
+ dosPermissions: h.dosPermissions,
246
+ createFolders: b.createFolders
247
+ });
248
+ return f.zipComment.length && (this.comment = f.zipComment), this
249
+ }
250
+ }, {
251
+ "./base64": 1,
252
+ "./zipEntries": 22
253
+ }],
254
+ 11: [function (a, b) {
255
+ (function (a) {
256
+ "use strict";
257
+ b.exports = function (b, c) {
258
+ return new a(b, c)
259
+ }, b.exports.test = function (b) {
260
+ return a.isBuffer(b)
261
+ }
262
+ }).call(this, "undefined" != typeof Buffer ? Buffer : void 0)
263
+ }, {}],
264
+ 12: [function (a, b) {
265
+ "use strict";
266
+
267
+ function c(a) {
268
+ this.data = a, this.length = this.data.length, this.index = 0
269
+ }
270
+ var d = a("./uint8ArrayReader");
271
+ c.prototype = new d, c.prototype.readData = function (a) {
272
+ this.checkOffset(a);
273
+ var b = this.data.slice(this.index, this.index + a);
274
+ return this.index += a, b
275
+ }, b.exports = c
276
+ }, {
277
+ "./uint8ArrayReader": 18
278
+ }],
279
+ 13: [function (a, b) {
280
+ "use strict";
281
+ var c = a("./support"),
282
+ d = a("./utils"),
283
+ e = a("./crc32"),
284
+ f = a("./signature"),
285
+ g = a("./defaults"),
286
+ h = a("./base64"),
287
+ i = a("./compressions"),
288
+ j = a("./compressedObject"),
289
+ k = a("./nodeBuffer"),
290
+ l = a("./utf8"),
291
+ m = a("./stringWriter"),
292
+ n = a("./uint8ArrayWriter"),
293
+ o = function (a) {
294
+ if (a._data instanceof j && (a._data = a._data.getContent(), a.options.binary = !0, a.options.base64 = !1, "uint8array" === d.getTypeOf(a._data))) {
295
+ var b = a._data;
296
+ a._data = new Uint8Array(b.length), 0 !== b.length && a._data.set(b, 0)
297
+ }
298
+ return a._data
299
+ },
300
+ p = function (a) {
301
+ var b = o(a),
302
+ e = d.getTypeOf(b);
303
+ return "string" === e ? !a.options.binary && c.nodebuffer ? k(b, "utf-8") : a.asBinary() : b
304
+ },
305
+ q = function (a) {
306
+ var b = o(this);
307
+ return null === b || "undefined" == typeof b ? "" : (this.options.base64 && (b = h.decode(b)), b = a && this.options.binary ? D.utf8decode(b) : d.transformTo("string", b), a || this.options.binary || (b = d.transformTo("string", D.utf8encode(b))), b)
308
+ },
309
+ r = function (a, b, c) {
310
+ this.name = a, this.dir = c.dir, this.date = c.date, this.comment = c.comment, this.unixPermissions = c.unixPermissions, this.dosPermissions = c.dosPermissions, this._data = b, this.options = c, this._initialMetadata = {
311
+ dir: c.dir,
312
+ date: c.date
313
+ }
314
+ };
315
+ r.prototype = {
316
+ asText: function () {
317
+ return q.call(this, !0)
318
+ },
319
+ asBinary: function () {
320
+ return q.call(this, !1)
321
+ },
322
+ asNodeBuffer: function () {
323
+ var a = p(this);
324
+ return d.transformTo("nodebuffer", a)
325
+ },
326
+ asUint8Array: function () {
327
+ var a = p(this);
328
+ return d.transformTo("uint8array", a)
329
+ },
330
+ asArrayBuffer: function () {
331
+ return this.asUint8Array().buffer
332
+ }
333
+ };
334
+ var s = function (a, b) {
335
+ var c, d = "";
336
+ for (c = 0; b > c; c++)
337
+ d += String.fromCharCode(255 & a), a >>>= 8;
338
+ return d
339
+ },
340
+ t = function () {
341
+ var a, b, c = {};
342
+ for (a = 0; a < arguments.length; a++)
343
+ for (b in arguments[a])
344
+ arguments[a].hasOwnProperty(b) && "undefined" == typeof c[b] && (c[b] = arguments[a][b]);
345
+ return c
346
+ },
347
+ u = function (a) {
348
+ return a = a || {}, a.base64 !== !0 || null !== a.binary && void 0 !== a.binary || (a.binary = !0), a = t(a, g), a.date = a.date || new Date, null !== a.compression && (a.compression = a.compression.toUpperCase()), a
349
+ },
350
+ v = function (a, b, c) {
351
+ var e, f = d.getTypeOf(b);
352
+ if (c = u(c), "string" == typeof c.unixPermissions && (c.unixPermissions = parseInt(c.unixPermissions, 8)), c.unixPermissions && 16384 & c.unixPermissions && (c.dir = !0), c.dosPermissions && 16 & c.dosPermissions && (c.dir = !0), c.dir && (a = x(a)), c.createFolders && (e = w(a)) && y.call(this, e, !0), c.dir || null === b || "undefined" == typeof b)
353
+ c.base64 = !1, c.binary = !1, b = null, f = null;
354
+ else if ("string" === f)
355
+ c.binary && !c.base64 && c.optimizedBinaryString !== !0 && (b = d.string2binary(b));
356
+ else {
357
+ if (c.base64 = !1, c.binary = !0, !(f || b instanceof j))
358
+ throw new Error("The data of '" + a + "' is in an unsupported format !");
359
+ "arraybuffer" === f && (b = d.transformTo("uint8array", b))
360
+ }
361
+ var g = new r(a, b, c);
362
+ return this.files[a] = g, g
363
+ },
364
+ w = function (a) {
365
+ "/" == a.slice(-1) && (a = a.substring(0, a.length - 1));
366
+ var b = a.lastIndexOf("/");
367
+ return b > 0 ? a.substring(0, b) : ""
368
+ },
369
+ x = function (a) {
370
+ return "/" != a.slice(-1) && (a += "/"), a
371
+ },
372
+ y = function (a, b) {
373
+ return b = "undefined" != typeof b ? b : !1, a = x(a), this.files[a] || v.call(this, a, null, {
374
+ dir: !0,
375
+ createFolders: b
376
+ }), this.files[a]
377
+ },
378
+ z = function (a, b, c) {
379
+ var f, g = new j;
380
+ return a._data instanceof j ? (g.uncompressedSize = a._data.uncompressedSize, g.crc32 = a._data.crc32, 0 === g.uncompressedSize || a.dir ? (b = i.STORE, g.compressedContent = "", g.crc32 = 0) : a._data.compressionMethod === b.magic ? g.compressedContent = a._data.getCompressedContent() : (f = a._data.getContent(), g.compressedContent = b.compress(d.transformTo(b.compressInputType, f), c))) : (f = p(a), (!f || 0 === f.length || a.dir) && (b = i.STORE, f = ""), g.uncompressedSize = f.length, g.crc32 = e(f), g.compressedContent = b.compress(d.transformTo(b.compressInputType, f), c)), g.compressedSize = g.compressedContent.length, g.compressionMethod = b.magic, g
381
+ },
382
+ A = function (a, b) {
383
+ var c = a;
384
+ return a || (c = b ? 16893 : 33204), (65535 & c) << 16
385
+ },
386
+ B = function (a) {
387
+ return 63 & (a || 0)
388
+ },
389
+ C = function (a, b, c, g, h) {
390
+ var i, j, k, m, n = (c.compressedContent, d.transformTo("string", l.utf8encode(b.name))),
391
+ o = b.comment || "",
392
+ p = d.transformTo("string", l.utf8encode(o)),
393
+ q = n.length !== b.name.length,
394
+ r = p.length !== o.length,
395
+ t = b.options,
396
+ u = "",
397
+ v = "",
398
+ w = "";
399
+ k = b._initialMetadata.dir !== b.dir ? b.dir : t.dir, m = b._initialMetadata.date !== b.date ? b.date : t.date;
400
+ var x = 0,
401
+ y = 0;
402
+ k && (x |= 16), "UNIX" === h ? (y = 798, x |= A(b.unixPermissions, k)) : (y = 20, x |= B(b.dosPermissions, k)), i = m.getHours(), i <<= 6, i |= m.getMinutes(), i <<= 5, i |= m.getSeconds() / 2, j = m.getFullYear() - 1980, j <<= 4, j |= m.getMonth() + 1, j <<= 5, j |= m.getDate(), q && (v = s(1, 1) + s(e(n), 4) + n, u += "up" + s(v.length, 2) + v), r && (w = s(1, 1) + s(this.crc32(p), 4) + p, u += "uc" + s(w.length, 2) + w);
403
+ var z = "";
404
+ z += "\n\x00", z += q || r ? "\x00\b" : "\x00\x00", z += c.compressionMethod, z += s(i, 2), z += s(j, 2), z += s(c.crc32, 4), z += s(c.compressedSize, 4), z += s(c.uncompressedSize, 4), z += s(n.length, 2), z += s(u.length, 2);
405
+ var C = f.LOCAL_FILE_HEADER + z + n + u,
406
+ D = f.CENTRAL_FILE_HEADER + s(y, 2) + z + s(p.length, 2) + "\x00\x00\x00\x00" + s(x, 4) + s(g, 4) + n + u + p;
407
+ return {
408
+ fileRecord: C,
409
+ dirRecord: D,
410
+ compressedObject: c
411
+ }
412
+ },
413
+ D = {
414
+ load: function () {
415
+ throw new Error("Load method is not defined. Is the file jszip-load.js included ?")
416
+ },
417
+ filter: function (a) {
418
+ var b, c, d, e, f = [];
419
+ for (b in this.files)
420
+ this.files.hasOwnProperty(b) && (d = this.files[b], e = new r(d.name, d._data, t(d.options)), c = b.slice(this.root.length, b.length), b.slice(0, this.root.length) === this.root && a(c, e) && f.push(e));
421
+ return f
422
+ },
423
+ file: function (a, b, c) {
424
+ if (1 === arguments.length) {
425
+ if (d.isRegExp(a)) {
426
+ var e = a;
427
+ return this.filter(function (a, b) {
428
+ return !b.dir && e.test(a)
429
+ })
430
+ }
431
+ return this.filter(function (b, c) {
432
+ return !c.dir && b === a
433
+ })[0] || null
434
+ }
435
+ return a = this.root + a, v.call(this, a, b, c), this
436
+ },
437
+ folder: function (a) {
438
+ if (!a)
439
+ return this;
440
+ if (d.isRegExp(a))
441
+ return this.filter(function (b, c) {
442
+ return c.dir && a.test(b)
443
+ });
444
+ var b = this.root + a,
445
+ c = y.call(this, b),
446
+ e = this.clone();
447
+ return e.root = c.name, e
448
+ },
449
+ remove: function (a) {
450
+ a = this.root + a;
451
+ var b = this.files[a];
452
+ if (b || ("/" != a.slice(-1) && (a += "/"), b = this.files[a]), b && !b.dir)
453
+ delete this.files[a];
454
+ else
455
+ for (var c = this.filter(function (b, c) {
456
+ return c.name.slice(0, a.length) === a
457
+ }), d = 0; d < c.length; d++)
458
+ delete this.files[c[d].name];
459
+ return this
460
+ },
461
+ generate: function (a) {
462
+ a = t(a || {}, {
463
+ base64: !0,
464
+ compression: "STORE",
465
+ compressionOptions: null,
466
+ type: "base64",
467
+ platform: "DOS",
468
+ comment: null,
469
+ mimeType: "application/zip"
470
+ }), d.checkSupport(a.type), ("darwin" === a.platform || "freebsd" === a.platform || "linux" === a.platform || "sunos" === a.platform) && (a.platform = "UNIX"), "win32" === a.platform && (a.platform = "DOS");
471
+ var b, c, e = [],
472
+ g = 0,
473
+ j = 0,
474
+ k = d.transformTo("string", this.utf8encode(a.comment || this.comment || ""));
475
+ for (var l in this.files)
476
+ if (this.files.hasOwnProperty(l)) {
477
+ var o = this.files[l],
478
+ p = o.options.compression || a.compression.toUpperCase(),
479
+ q = i[p];
480
+ if (!q)
481
+ throw new Error(p + " is not a valid compression method !");
482
+ var r = o.options.compressionOptions || a.compressionOptions || {},
483
+ u = z.call(this, o, q, r),
484
+ v = C.call(this, l, o, u, g, a.platform);
485
+ g += v.fileRecord.length + u.compressedSize, j += v.dirRecord.length, e.push(v)
486
+ }
487
+ var w = "";
488
+ w = f.CENTRAL_DIRECTORY_END + "\x00\x00\x00\x00" + s(e.length, 2) + s(e.length, 2) + s(j, 4) + s(g, 4) + s(k.length, 2) + k;
489
+ var x = a.type.toLowerCase();
490
+ for (b = "uint8array" === x || "arraybuffer" === x || "blob" === x || "nodebuffer" === x ? new n(g + j + w.length) : new m(g + j + w.length), c = 0; c < e.length; c++)
491
+ b.append(e[c].fileRecord), b.append(e[c].compressedObject.compressedContent);
492
+ for (c = 0; c < e.length; c++)
493
+ b.append(e[c].dirRecord);
494
+ b.append(w);
495
+ var y = b.finalize();
496
+ switch (a.type.toLowerCase()) {
497
+ case "uint8array":
498
+ case "arraybuffer":
499
+ case "nodebuffer":
500
+ return d.transformTo(a.type.toLowerCase(), y);
501
+ case "blob":
502
+ return d.arrayBuffer2Blob(d.transformTo("arraybuffer", y), a.mimeType);
503
+ case "base64":
504
+ return a.base64 ? h.encode(y) : y;
505
+ default:
506
+ return y
507
+ }
508
+ },
509
+ crc32: function (a, b) {
510
+ return e(a, b)
511
+ },
512
+ utf8encode: function (a) {
513
+ return d.transformTo("string", l.utf8encode(a))
514
+ },
515
+ utf8decode: function (a) {
516
+ return l.utf8decode(a)
517
+ }
518
+ };
519
+ b.exports = D
520
+ }, {
521
+ "./base64": 1,
522
+ "./compressedObject": 2,
523
+ "./compressions": 3,
524
+ "./crc32": 4,
525
+ "./defaults": 6,
526
+ "./nodeBuffer": 11,
527
+ "./signature": 14,
528
+ "./stringWriter": 16,
529
+ "./support": 17,
530
+ "./uint8ArrayWriter": 19,
531
+ "./utf8": 20,
532
+ "./utils": 21
533
+ }],
534
+ 14: [function (a, b, c) {
535
+ "use strict";
536
+ c.LOCAL_FILE_HEADER = "PK", c.CENTRAL_FILE_HEADER = "PK", c.CENTRAL_DIRECTORY_END = "PK", c.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK", c.ZIP64_CENTRAL_DIRECTORY_END = "PK", c.DATA_DESCRIPTOR = "PK\b"
537
+ }, {}],
538
+ 15: [function (a, b) {
539
+ "use strict";
540
+
541
+ function c(a, b) {
542
+ this.data = a, b || (this.data = e.string2binary(this.data)), this.length = this.data.length, this.index = 0
543
+ }
544
+ var d = a("./dataReader"),
545
+ e = a("./utils");
546
+ c.prototype = new d, c.prototype.byteAt = function (a) {
547
+ return this.data.charCodeAt(a)
548
+ }, c.prototype.lastIndexOfSignature = function (a) {
549
+ return this.data.lastIndexOf(a)
550
+ }, c.prototype.readData = function (a) {
551
+ this.checkOffset(a);
552
+ var b = this.data.slice(this.index, this.index + a);
553
+ return this.index += a, b
554
+ }, b.exports = c
555
+ }, {
556
+ "./dataReader": 5,
557
+ "./utils": 21
558
+ }],
559
+ 16: [function (a, b) {
560
+ "use strict";
561
+ var c = a("./utils"),
562
+ d = function () {
563
+ this.data = []
564
+ };
565
+ d.prototype = {
566
+ append: function (a) {
567
+ a = c.transformTo("string", a), this.data.push(a)
568
+ },
569
+ finalize: function () {
570
+ return this.data.join("")
571
+ }
572
+ }, b.exports = d
573
+ }, {
574
+ "./utils": 21
575
+ }],
576
+ 17: [function (a, b, c) {
577
+ (function (a) {
578
+ "use strict";
579
+ if (c.base64 = !0, c.array = !0, c.string = !0, c.arraybuffer = "undefined" != typeof ArrayBuffer && "undefined" != typeof Uint8Array, c.nodebuffer = "undefined" != typeof a, c.uint8array = "undefined" != typeof Uint8Array, "undefined" == typeof ArrayBuffer)
580
+ c.blob = !1;
581
+ else {
582
+ var b = new ArrayBuffer(0);
583
+ try {
584
+ c.blob = 0 === new Blob([b], {
585
+ type: "application/zip"
586
+ }).size
587
+ } catch (d) {
588
+ try {
589
+ var e = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder,
590
+ f = new e;
591
+ f.append(b), c.blob = 0 === f.getBlob("application/zip").size
592
+ } catch (d) {
593
+ c.blob = !1
594
+ }
595
+ }
596
+ }
597
+ }).call(this, "undefined" != typeof Buffer ? Buffer : void 0)
598
+ }, {}],
599
+ 18: [function (a, b) {
600
+ "use strict";
601
+
602
+ function c(a) {
603
+ a && (this.data = a, this.length = this.data.length, this.index = 0)
604
+ }
605
+ var d = a("./dataReader");
606
+ c.prototype = new d, c.prototype.byteAt = function (a) {
607
+ return this.data[a]
608
+ }, c.prototype.lastIndexOfSignature = function (a) {
609
+ for (var b = a.charCodeAt(0), c = a.charCodeAt(1), d = a.charCodeAt(2), e = a.charCodeAt(3), f = this.length - 4; f >= 0; --f)
610
+ if (this.data[f] === b && this.data[f + 1] === c && this.data[f + 2] === d && this.data[f + 3] === e)
611
+ return f;
612
+ return -1
613
+ }, c.prototype.readData = function (a) {
614
+ if (this.checkOffset(a), 0 === a)
615
+ return new Uint8Array(0);
616
+ var b = this.data.subarray(this.index, this.index + a);
617
+ return this.index += a, b
618
+ }, b.exports = c
619
+ }, {
620
+ "./dataReader": 5
621
+ }],
622
+ 19: [function (a, b) {
623
+ "use strict";
624
+ var c = a("./utils"),
625
+ d = function (a) {
626
+ this.data = new Uint8Array(a), this.index = 0
627
+ };
628
+ d.prototype = {
629
+ append: function (a) {
630
+ 0 !== a.length && (a = c.transformTo("uint8array", a), this.data.set(a, this.index), this.index += a.length)
631
+ },
632
+ finalize: function () {
633
+ return this.data
634
+ }
635
+ }, b.exports = d
636
+ }, {
637
+ "./utils": 21
638
+ }],
639
+ 20: [function (a, b, c) {
640
+ "use strict";
641
+ for (var d = a("./utils"), e = a("./support"), f = a("./nodeBuffer"), g = new Array(256), h = 0; 256 > h; h++)
642
+ g[h] = h >= 252 ? 6 : h >= 248 ? 5 : h >= 240 ? 4 : h >= 224 ? 3 : h >= 192 ? 2 : 1;
643
+ g[254] = g[254] = 1;
644
+ var i = function (a) {
645
+ var b, c, d, f, g, h = a.length,
646
+ i = 0;
647
+ for (f = 0; h > f; f++)
648
+ c = a.charCodeAt(f), 55296 === (64512 & c) && h > f + 1 && (d = a.charCodeAt(f + 1), 56320 === (64512 & d) && (c = 65536 + (c - 55296 << 10) + (d - 56320), f++)), i += 128 > c ? 1 : 2048 > c ? 2 : 65536 > c ? 3 : 4;
649
+ for (b = e.uint8array ? new Uint8Array(i) : new Array(i), g = 0, f = 0; i > g; f++)
650
+ c = a.charCodeAt(f), 55296 === (64512 & c) && h > f + 1 && (d = a.charCodeAt(f + 1), 56320 === (64512 & d) && (c = 65536 + (c - 55296 << 10) + (d - 56320), f++)), 128 > c ? b[g++] = c : 2048 > c ? (b[g++] = 192 | c >>> 6, b[g++] = 128 | 63 & c) : 65536 > c ? (b[g++] = 224 | c >>> 12, b[g++] = 128 | c >>> 6 & 63, b[g++] = 128 | 63 & c) : (b[g++] = 240 | c >>> 18, b[g++] = 128 | c >>> 12 & 63, b[g++] = 128 | c >>> 6 & 63, b[g++] = 128 | 63 & c);
651
+ return b
652
+ },
653
+ j = function (a, b) {
654
+ var c;
655
+ for (b = b || a.length, b > a.length && (b = a.length), c = b - 1; c >= 0 && 128 === (192 & a[c]); )
656
+ c--;
657
+ return 0 > c ? b : 0 === c ? b : c + g[a[c]] > b ? c : b
658
+ },
659
+ k = function (a) {
660
+ var b, c, e, f, h = a.length,
661
+ i = new Array(2 * h);
662
+ for (c = 0, b = 0; h > b; )
663
+ if (e = a[b++], 128 > e)
664
+ i[c++] = e;
665
+ else if (f = g[e], f > 4)
666
+ i[c++] = 65533, b += f - 1;
667
+ else {
668
+ for (e &= 2 === f ? 31 : 3 === f ? 15 : 7; f > 1 && h > b; )
669
+ e = e << 6 | 63 & a[b++], f--;
670
+ f > 1 ? i[c++] = 65533 : 65536 > e ? i[c++] = e : (e -= 65536, i[c++] = 55296 | e >> 10 & 1023, i[c++] = 56320 | 1023 & e)
671
+ }
672
+ return i.length !== c && (i.subarray ? i = i.subarray(0, c) : i.length = c), d.applyFromCharCode(i)
673
+ };
674
+ c.utf8encode = function (a) {
675
+ return e.nodebuffer ? f(a, "utf-8") : i(a)
676
+ }, c.utf8decode = function (a) {
677
+ if (e.nodebuffer)
678
+ return d.transformTo("nodebuffer", a).toString("utf-8");
679
+ a = d.transformTo(e.uint8array ? "uint8array" : "array", a);
680
+ for (var b = [], c = 0, f = a.length, g = 65536; f > c; ) {
681
+ var h = j(a, Math.min(c + g, f));
682
+ b.push(e.uint8array ? k(a.subarray(c, h)) : k(a.slice(c, h))), c = h
683
+ }
684
+ return b.join("")
685
+ }
686
+ }, {
687
+ "./nodeBuffer": 11,
688
+ "./support": 17,
689
+ "./utils": 21
690
+ }],
691
+ 21: [function (a, b, c) {
692
+ "use strict";
693
+
694
+ function d(a) {
695
+ return a
696
+ }
697
+
698
+ function e(a, b) {
699
+ for (var c = 0; c < a.length; ++c)
700
+ b[c] = 255 & a.charCodeAt(c);
701
+ return b
702
+ }
703
+
704
+ function f(a) {
705
+ var b = 65536,
706
+ d = [],
707
+ e = a.length,
708
+ f = c.getTypeOf(a),
709
+ g = 0,
710
+ h = !0;
711
+ try {
712
+ switch (f) {
713
+ case "uint8array":
714
+ String.fromCharCode.apply(null, new Uint8Array(0));
715
+ break;
716
+ case "nodebuffer":
717
+ String.fromCharCode.apply(null, j(0))
718
+ }
719
+ } catch (i) {
720
+ h = !1
721
+ }
722
+ if (!h) {
723
+ for (var k = "", l = 0; l < a.length; l++)
724
+ k += String.fromCharCode(a[l]);
725
+ return k
726
+ }
727
+ for (; e > g && b > 1; )
728
+ try {
729
+ d.push("array" === f || "nodebuffer" === f ? String.fromCharCode.apply(null, a.slice(g, Math.min(g + b, e))) : String.fromCharCode.apply(null, a.subarray(g, Math.min(g + b, e)))), g += b
730
+ } catch (i) {
731
+ b = Math.floor(b / 2)
732
+ }
733
+ return d.join("")
734
+ }
735
+
736
+ function g(a, b) {
737
+ for (var c = 0; c < a.length; c++)
738
+ b[c] = a[c];
739
+ return b
740
+ }
741
+ var h = a("./support"),
742
+ i = a("./compressions"),
743
+ j = a("./nodeBuffer");
744
+ c.string2binary = function (a) {
745
+ for (var b = "", c = 0; c < a.length; c++)
746
+ b += String.fromCharCode(255 & a.charCodeAt(c));
747
+ return b
748
+ }, c.arrayBuffer2Blob = function (a, b) {
749
+ c.checkSupport("blob"), b = b || "application/zip";
750
+ try {
751
+ return new Blob([a], {
752
+ type: b
753
+ })
754
+ } catch (d) {
755
+ try {
756
+ var e = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder,
757
+ f = new e;
758
+ return f.append(a), f.getBlob(b)
759
+ } catch (d) {
760
+ throw new Error("Bug : can't construct the Blob.")
761
+ }
762
+ }
763
+ }, c.applyFromCharCode = f;
764
+ var k = {};
765
+ k.string = {
766
+ string: d,
767
+ array: function (a) {
768
+ return e(a, new Array(a.length))
769
+ },
770
+ arraybuffer: function (a) {
771
+ return k.string.uint8array(a).buffer
772
+ },
773
+ uint8array: function (a) {
774
+ return e(a, new Uint8Array(a.length))
775
+ },
776
+ nodebuffer: function (a) {
777
+ return e(a, j(a.length))
778
+ }
779
+ }, k.array = {
780
+ string: f,
781
+ array: d,
782
+ arraybuffer: function (a) {
783
+ return new Uint8Array(a).buffer
784
+ },
785
+ uint8array: function (a) {
786
+ return new Uint8Array(a)
787
+ },
788
+ nodebuffer: function (a) {
789
+ return j(a)
790
+ }
791
+ }, k.arraybuffer = {
792
+ string: function (a) {
793
+ return f(new Uint8Array(a))
794
+ },
795
+ array: function (a) {
796
+ return g(new Uint8Array(a), new Array(a.byteLength))
797
+ },
798
+ arraybuffer: d,
799
+ uint8array: function (a) {
800
+ return new Uint8Array(a)
801
+ },
802
+ nodebuffer: function (a) {
803
+ return j(new Uint8Array(a))
804
+ }
805
+ }, k.uint8array = {
806
+ string: f,
807
+ array: function (a) {
808
+ return g(a, new Array(a.length))
809
+ },
810
+ arraybuffer: function (a) {
811
+ return a.buffer
812
+ },
813
+ uint8array: d,
814
+ nodebuffer: function (a) {
815
+ return j(a)
816
+ }
817
+ }, k.nodebuffer = {
818
+ string: f,
819
+ array: function (a) {
820
+ return g(a, new Array(a.length))
821
+ },
822
+ arraybuffer: function (a) {
823
+ return k.nodebuffer.uint8array(a).buffer
824
+ },
825
+ uint8array: function (a) {
826
+ return g(a, new Uint8Array(a.length))
827
+ },
828
+ nodebuffer: d
829
+ }, c.transformTo = function (a, b) {
830
+ if (b || (b = ""), !a)
831
+ return b;
832
+ c.checkSupport(a);
833
+ var d = c.getTypeOf(b),
834
+ e = k[d][a](b);
835
+ return e
836
+ }, c.getTypeOf = function (a) {
837
+ return "string" == typeof a ? "string" : "[object Array]" === Object.prototype.toString.call(a) ? "array" : h.nodebuffer && j.test(a) ? "nodebuffer" : h.uint8array && a instanceof Uint8Array ? "uint8array" : h.arraybuffer && a instanceof ArrayBuffer ? "arraybuffer" : void 0
838
+ }, c.checkSupport = function (a) {
839
+ var b = h[a.toLowerCase()];
840
+ if (!b)
841
+ throw new Error(a + " is not supported by this browser")
842
+ }, c.MAX_VALUE_16BITS = 65535, c.MAX_VALUE_32BITS = -1, c.pretty = function (a) {
843
+ var b, c, d = "";
844
+ for (c = 0; c < (a || "").length; c++)
845
+ b = a.charCodeAt(c), d += "\\x" + (16 > b ? "0" : "") + b.toString(16).toUpperCase();
846
+ return d
847
+ }, c.findCompression = function (a) {
848
+ for (var b in i)
849
+ if (i.hasOwnProperty(b) && i[b].magic === a)
850
+ return i[b];
851
+ return null
852
+ }, c.isRegExp = function (a) {
853
+ return "[object RegExp]" === Object.prototype.toString.call(a)
854
+ }
855
+ }, {
856
+ "./compressions": 3,
857
+ "./nodeBuffer": 11,
858
+ "./support": 17
859
+ }],
860
+ 22: [function (a, b) {
861
+ "use strict";
862
+
863
+ function c(a, b) {
864
+ this.files = [], this.loadOptions = b, a && this.load(a)
865
+ }
866
+ var d = a("./stringReader"),
867
+ e = a("./nodeBufferReader"),
868
+ f = a("./uint8ArrayReader"),
869
+ g = a("./utils"),
870
+ h = a("./signature"),
871
+ i = a("./zipEntry"),
872
+ j = a("./support"),
873
+ k = a("./object");
874
+ c.prototype = {
875
+ checkSignature: function (a) {
876
+ var b = this.reader.readString(4);
877
+ if (b !== a)
878
+ throw new Error("Corrupted zip or bug : unexpected signature (" + g.pretty(b) + ", expected " + g.pretty(a) + ")")
879
+ },
880
+ readBlockEndOfCentral: function () {
881
+ this.diskNumber = this.reader.readInt(2), this.diskWithCentralDirStart = this.reader.readInt(2), this.centralDirRecordsOnThisDisk = this.reader.readInt(2), this.centralDirRecords = this.reader.readInt(2), this.centralDirSize = this.reader.readInt(4), this.centralDirOffset = this.reader.readInt(4), this.zipCommentLength = this.reader.readInt(2), this.zipComment = this.reader.readString(this.zipCommentLength), this.zipComment = k.utf8decode(this.zipComment)
882
+ },
883
+ readBlockZip64EndOfCentral: function () {
884
+ this.zip64EndOfCentralSize = this.reader.readInt(8), this.versionMadeBy = this.reader.readString(2), this.versionNeeded = this.reader.readInt(2), this.diskNumber = this.reader.readInt(4), this.diskWithCentralDirStart = this.reader.readInt(4), this.centralDirRecordsOnThisDisk = this.reader.readInt(8), this.centralDirRecords = this.reader.readInt(8), this.centralDirSize = this.reader.readInt(8), this.centralDirOffset = this.reader.readInt(8), this.zip64ExtensibleData = {};
885
+ for (var a, b, c, d = this.zip64EndOfCentralSize - 44, e = 0; d > e; )
886
+ a = this.reader.readInt(2), b = this.reader.readInt(4), c = this.reader.readString(b), this.zip64ExtensibleData[a] = {
887
+ id: a,
888
+ length: b,
889
+ value: c
890
+ }
891
+ },
892
+ readBlockZip64EndOfCentralLocator: function () {
893
+ if (this.diskWithZip64CentralDirStart = this.reader.readInt(4), this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8), this.disksCount = this.reader.readInt(4), this.disksCount > 1)
894
+ throw new Error("Multi-volumes zip are not supported")
895
+ },
896
+ readLocalFiles: function () {
897
+ var a, b;
898
+ for (a = 0; a < this.files.length; a++)
899
+ b = this.files[a], this.reader.setIndex(b.localHeaderOffset), this.checkSignature(h.LOCAL_FILE_HEADER), b.readLocalPart(this.reader), b.handleUTF8(), b.processAttributes()
900
+ },
901
+ readCentralDir: function () {
902
+ var a;
903
+ for (this.reader.setIndex(this.centralDirOffset); this.reader.readString(4) === h.CENTRAL_FILE_HEADER; )
904
+ a = new i({
905
+ zip64: this.zip64
906
+ }, this.loadOptions), a.readCentralPart(this.reader), this.files.push(a)
907
+ },
908
+ readEndOfCentral: function () {
909
+ var a = this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);
910
+ if (-1 === a) {
911
+ var b = !0;
912
+ try {
913
+ this.reader.setIndex(0), this.checkSignature(h.LOCAL_FILE_HEADER), b = !1
914
+ } catch (c) {
915
+ }
916
+ throw new Error(b ? "Can't find end of central directory : is this a zip file ? If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html" : "Corrupted zip : can't find end of central directory")
917
+ }
918
+ if (this.reader.setIndex(a), this.checkSignature(h.CENTRAL_DIRECTORY_END), this.readBlockEndOfCentral(), this.diskNumber === g.MAX_VALUE_16BITS || this.diskWithCentralDirStart === g.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === g.MAX_VALUE_16BITS || this.centralDirRecords === g.MAX_VALUE_16BITS || this.centralDirSize === g.MAX_VALUE_32BITS || this.centralDirOffset === g.MAX_VALUE_32BITS) {
919
+ if (this.zip64 = !0, a = this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR), -1 === a)
920
+ throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");
921
+ this.reader.setIndex(a), this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR), this.readBlockZip64EndOfCentralLocator(), this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir), this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END), this.readBlockZip64EndOfCentral()
922
+ }
923
+ },
924
+ prepareReader: function (a) {
925
+ var b = g.getTypeOf(a);
926
+ this.reader = "string" !== b || j.uint8array ? "nodebuffer" === b ? new e(a) : new f(g.transformTo("uint8array", a)) : new d(a, this.loadOptions.optimizedBinaryString)
927
+ },
928
+ load: function (a) {
929
+ this.prepareReader(a), this.readEndOfCentral(), this.readCentralDir(), this.readLocalFiles()
930
+ }
931
+ }, b.exports = c
932
+ }, {
933
+ "./nodeBufferReader": 12,
934
+ "./object": 13,
935
+ "./signature": 14,
936
+ "./stringReader": 15,
937
+ "./support": 17,
938
+ "./uint8ArrayReader": 18,
939
+ "./utils": 21,
940
+ "./zipEntry": 23
941
+ }],
942
+ 23: [function (a, b) {
943
+ "use strict";
944
+
945
+ function c(a, b) {
946
+ this.options = a, this.loadOptions = b
947
+ }
948
+ var d = a("./stringReader"),
949
+ e = a("./utils"),
950
+ f = a("./compressedObject"),
951
+ g = a("./object"),
952
+ h = 0,
953
+ i = 3;
954
+ c.prototype = {
955
+ isEncrypted: function () {
956
+ return 1 === (1 & this.bitFlag)
957
+ },
958
+ useUTF8: function () {
959
+ return 2048 === (2048 & this.bitFlag)
960
+ },
961
+ prepareCompressedContent: function (a, b, c) {
962
+ return function () {
963
+ var d = a.index;
964
+ a.setIndex(b);
965
+ var e = a.readData(c);
966
+ return a.setIndex(d), e
967
+ }
968
+ },
969
+ prepareContent: function (a, b, c, d, f) {
970
+ return function () {
971
+ var a = e.transformTo(d.uncompressInputType, this.getCompressedContent()),
972
+ b = d.uncompress(a);
973
+ if (b.length !== f)
974
+ throw new Error("Bug : uncompressed data size mismatch");
975
+ return b
976
+ }
977
+ },
978
+ readLocalPart: function (a) {
979
+ var b, c;
980
+ if (a.skip(22), this.fileNameLength = a.readInt(2), c = a.readInt(2), this.fileName = a.readString(this.fileNameLength), a.skip(c), -1 == this.compressedSize || -1 == this.uncompressedSize)
981
+ throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");
982
+ if (b = e.findCompression(this.compressionMethod), null === b)
983
+ throw new Error("Corrupted zip : compression " + e.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")");
984
+ if (this.decompressed = new f, this.decompressed.compressedSize = this.compressedSize, this.decompressed.uncompressedSize = this.uncompressedSize, this.decompressed.crc32 = this.crc32, this.decompressed.compressionMethod = this.compressionMethod, this.decompressed.getCompressedContent = this.prepareCompressedContent(a, a.index, this.compressedSize, b), this.decompressed.getContent = this.prepareContent(a, a.index, this.compressedSize, b, this.uncompressedSize), this.loadOptions.checkCRC32 && (this.decompressed = e.transformTo("string", this.decompressed.getContent()), g.crc32(this.decompressed) !== this.crc32))
985
+ throw new Error("Corrupted zip : CRC32 mismatch")
986
+ },
987
+ readCentralPart: function (a) {
988
+ if (this.versionMadeBy = a.readInt(2), this.versionNeeded = a.readInt(2), this.bitFlag = a.readInt(2), this.compressionMethod = a.readString(2), this.date = a.readDate(), this.crc32 = a.readInt(4), this.compressedSize = a.readInt(4), this.uncompressedSize = a.readInt(4), this.fileNameLength = a.readInt(2), this.extraFieldsLength = a.readInt(2), this.fileCommentLength = a.readInt(2), this.diskNumberStart = a.readInt(2), this.internalFileAttributes = a.readInt(2), this.externalFileAttributes = a.readInt(4), this.localHeaderOffset = a.readInt(4), this.isEncrypted())
989
+ throw new Error("Encrypted zip are not supported");
990
+ this.fileName = a.readString(this.fileNameLength), this.readExtraFields(a), this.parseZIP64ExtraField(a), this.fileComment = a.readString(this.fileCommentLength)
991
+ },
992
+ processAttributes: function () {
993
+ this.unixPermissions = null, this.dosPermissions = null;
994
+ var a = this.versionMadeBy >> 8;
995
+ this.dir = 16 & this.externalFileAttributes ? !0 : !1, a === h && (this.dosPermissions = 63 & this.externalFileAttributes), a === i && (this.unixPermissions = this.externalFileAttributes >> 16 & 65535), this.dir || "/" !== this.fileName.slice(-1) || (this.dir = !0)
996
+ },
997
+ parseZIP64ExtraField: function () {
998
+ if (this.extraFields[1]) {
999
+ var a = new d(this.extraFields[1].value);
1000
+ this.uncompressedSize === e.MAX_VALUE_32BITS && (this.uncompressedSize = a.readInt(8)), this.compressedSize === e.MAX_VALUE_32BITS && (this.compressedSize = a.readInt(8)), this.localHeaderOffset === e.MAX_VALUE_32BITS && (this.localHeaderOffset = a.readInt(8)), this.diskNumberStart === e.MAX_VALUE_32BITS && (this.diskNumberStart = a.readInt(4))
1001
+ }
1002
+ },
1003
+ readExtraFields: function (a) {
1004
+ var b, c, d, e = a.index;
1005
+ for (this.extraFields = this.extraFields || {}; a.index < e + this.extraFieldsLength; )
1006
+ b = a.readInt(2), c = a.readInt(2), d = a.readString(c), this.extraFields[b] = {
1007
+ id: b,
1008
+ length: c,
1009
+ value: d
1010
+ }
1011
+ },
1012
+ handleUTF8: function () {
1013
+ if (this.useUTF8())
1014
+ this.fileName = g.utf8decode(this.fileName), this.fileComment = g.utf8decode(this.fileComment);
1015
+ else {
1016
+ var a = this.findExtraFieldUnicodePath();
1017
+ null !== a && (this.fileName = a);
1018
+ var b = this.findExtraFieldUnicodeComment();
1019
+ null !== b && (this.fileComment = b)
1020
+ }
1021
+ },
1022
+ findExtraFieldUnicodePath: function () {
1023
+ var a = this.extraFields[28789];
1024
+ if (a) {
1025
+ var b = new d(a.value);
1026
+ return 1 !== b.readInt(1) ? null : g.crc32(this.fileName) !== b.readInt(4) ? null : g.utf8decode(b.readString(a.length - 5))
1027
+ }
1028
+ return null
1029
+ },
1030
+ findExtraFieldUnicodeComment: function () {
1031
+ var a = this.extraFields[25461];
1032
+ if (a) {
1033
+ var b = new d(a.value);
1034
+ return 1 !== b.readInt(1) ? null : g.crc32(this.fileComment) !== b.readInt(4) ? null : g.utf8decode(b.readString(a.length - 5))
1035
+ }
1036
+ return null
1037
+ }
1038
+ }, b.exports = c
1039
+ }, {
1040
+ "./compressedObject": 2,
1041
+ "./object": 13,
1042
+ "./stringReader": 15,
1043
+ "./utils": 21
1044
+ }],
1045
+ 24: [function (a, b) {
1046
+ "use strict";
1047
+ var c = a("./lib/utils/common").assign,
1048
+ d = a("./lib/deflate"),
1049
+ e = a("./lib/inflate"),
1050
+ f = a("./lib/zlib/constants"),
1051
+ g = {};
1052
+ c(g, d, e, f), b.exports = g
1053
+ }, {
1054
+ "./lib/deflate": 25,
1055
+ "./lib/inflate": 26,
1056
+ "./lib/utils/common": 27,
1057
+ "./lib/zlib/constants": 30
1058
+ }],
1059
+ 25: [function (a, b, c) {
1060
+ "use strict";
1061
+
1062
+ function d(a, b) {
1063
+ var c = new s(b);
1064
+ if (c.push(a, !0), c.err)
1065
+ throw c.msg;
1066
+ return c.result
1067
+ }
1068
+
1069
+ function e(a, b) {
1070
+ return b = b || {}, b.raw = !0, d(a, b)
1071
+ }
1072
+
1073
+ function f(a, b) {
1074
+ return b = b || {}, b.gzip = !0, d(a, b)
1075
+ }
1076
+ var g = a("./zlib/deflate.js"),
1077
+ h = a("./utils/common"),
1078
+ i = a("./utils/strings"),
1079
+ j = a("./zlib/messages"),
1080
+ k = a("./zlib/zstream"),
1081
+ l = 0,
1082
+ m = 4,
1083
+ n = 0,
1084
+ o = 1,
1085
+ p = -1,
1086
+ q = 0,
1087
+ r = 8,
1088
+ s = function (a) {
1089
+ this.options = h.assign({
1090
+ level: p,
1091
+ method: r,
1092
+ chunkSize: 16384,
1093
+ windowBits: 15,
1094
+ memLevel: 8,
1095
+ strategy: q,
1096
+ to: ""
1097
+ }, a || {});
1098
+ var b = this.options;
1099
+ b.raw && b.windowBits > 0 ? b.windowBits = -b.windowBits : b.gzip && b.windowBits > 0 && b.windowBits < 16 && (b.windowBits += 16), this.err = 0, this.msg = "", this.ended = !1, this.chunks = [], this.strm = new k, this.strm.avail_out = 0;
1100
+ var c = g.deflateInit2(this.strm, b.level, b.method, b.windowBits, b.memLevel, b.strategy);
1101
+ if (c !== n)
1102
+ throw new Error(j[c]);
1103
+ b.header && g.deflateSetHeader(this.strm, b.header)
1104
+ };
1105
+ s.prototype.push = function (a, b) {
1106
+ var c, d, e = this.strm,
1107
+ f = this.options.chunkSize;
1108
+ if (this.ended)
1109
+ return !1;
1110
+ d = b === ~~b ? b : b === !0 ? m : l, e.input = "string" == typeof a ? i.string2buf(a) : a, e.next_in = 0, e.avail_in = e.input.length;
1111
+ do {
1112
+ if (0 === e.avail_out && (e.output = new h.Buf8(f), e.next_out = 0, e.avail_out = f), c = g.deflate(e, d), c !== o && c !== n)
1113
+ return this.onEnd(c), this.ended = !0, !1;
1114
+ (0 === e.avail_out || 0 === e.avail_in && d === m) && this.onData("string" === this.options.to ? i.buf2binstring(h.shrinkBuf(e.output, e.next_out)) : h.shrinkBuf(e.output, e.next_out))
1115
+ } while ((e.avail_in > 0 || 0 === e.avail_out) && c !== o);
1116
+ return d === m ? (c = g.deflateEnd(this.strm), this.onEnd(c), this.ended = !0, c === n) : !0
1117
+ }, s.prototype.onData = function (a) {
1118
+ this.chunks.push(a)
1119
+ }, s.prototype.onEnd = function (a) {
1120
+ a === n && (this.result = "string" === this.options.to ? this.chunks.join("") : h.flattenChunks(this.chunks)), this.chunks = [], this.err = a, this.msg = this.strm.msg
1121
+ }, c.Deflate = s, c.deflate = d, c.deflateRaw = e, c.gzip = f
1122
+ }, {
1123
+ "./utils/common": 27,
1124
+ "./utils/strings": 28,
1125
+ "./zlib/deflate.js": 32,
1126
+ "./zlib/messages": 37,
1127
+ "./zlib/zstream": 39
1128
+ }],
1129
+ 26: [function (a, b, c) {
1130
+ "use strict";
1131
+
1132
+ function d(a, b) {
1133
+ var c = new m(b);
1134
+ if (c.push(a, !0), c.err)
1135
+ throw c.msg;
1136
+ return c.result
1137
+ }
1138
+
1139
+ function e(a, b) {
1140
+ return b = b || {}, b.raw = !0, d(a, b)
1141
+ }
1142
+ var f = a("./zlib/inflate.js"),
1143
+ g = a("./utils/common"),
1144
+ h = a("./utils/strings"),
1145
+ i = a("./zlib/constants"),
1146
+ j = a("./zlib/messages"),
1147
+ k = a("./zlib/zstream"),
1148
+ l = a("./zlib/gzheader"),
1149
+ m = function (a) {
1150
+ this.options = g.assign({
1151
+ chunkSize: 16384,
1152
+ windowBits: 0,
1153
+ to: ""
1154
+ }, a || {});
1155
+ var b = this.options;
1156
+ b.raw && b.windowBits >= 0 && b.windowBits < 16 && (b.windowBits = -b.windowBits, 0 === b.windowBits && (b.windowBits = -15)), !(b.windowBits >= 0 && b.windowBits < 16) || a && a.windowBits || (b.windowBits += 32), b.windowBits > 15 && b.windowBits < 48 && 0 === (15 & b.windowBits) && (b.windowBits |= 15), this.err = 0, this.msg = "", this.ended = !1, this.chunks = [], this.strm = new k, this.strm.avail_out = 0;
1157
+ var c = f.inflateInit2(this.strm, b.windowBits);
1158
+ if (c !== i.Z_OK)
1159
+ throw new Error(j[c]);
1160
+ this.header = new l, f.inflateGetHeader(this.strm, this.header)
1161
+ };
1162
+ m.prototype.push = function (a, b) {
1163
+ var c, d, e, j, k, l = this.strm,
1164
+ m = this.options.chunkSize;
1165
+ if (this.ended)
1166
+ return !1;
1167
+ d = b === ~~b ? b : b === !0 ? i.Z_FINISH : i.Z_NO_FLUSH, l.input = "string" == typeof a ? h.binstring2buf(a) : a, l.next_in = 0, l.avail_in = l.input.length;
1168
+ do {
1169
+ if (0 === l.avail_out && (l.output = new g.Buf8(m), l.next_out = 0, l.avail_out = m), c = f.inflate(l, i.Z_NO_FLUSH), c !== i.Z_STREAM_END && c !== i.Z_OK)
1170
+ return this.onEnd(c), this.ended = !0, !1;
1171
+ l.next_out && (0 === l.avail_out || c === i.Z_STREAM_END || 0 === l.avail_in && d === i.Z_FINISH) && ("string" === this.options.to ? (e = h.utf8border(l.output, l.next_out), j = l.next_out - e, k = h.buf2string(l.output, e), l.next_out = j, l.avail_out = m - j, j && g.arraySet(l.output, l.output, e, j, 0), this.onData(k)) : this.onData(g.shrinkBuf(l.output, l.next_out)))
1172
+ } while (l.avail_in > 0 && c !== i.Z_STREAM_END);
1173
+ return c === i.Z_STREAM_END && (d = i.Z_FINISH), d === i.Z_FINISH ? (c = f.inflateEnd(this.strm), this.onEnd(c), this.ended = !0, c === i.Z_OK) : !0
1174
+ }, m.prototype.onData = function (a) {
1175
+ this.chunks.push(a)
1176
+ }, m.prototype.onEnd = function (a) {
1177
+ a === i.Z_OK && (this.result = "string" === this.options.to ? this.chunks.join("") : g.flattenChunks(this.chunks)), this.chunks = [], this.err = a, this.msg = this.strm.msg
1178
+ }, c.Inflate = m, c.inflate = d, c.inflateRaw = e, c.ungzip = d
1179
+ }, {
1180
+ "./utils/common": 27,
1181
+ "./utils/strings": 28,
1182
+ "./zlib/constants": 30,
1183
+ "./zlib/gzheader": 33,
1184
+ "./zlib/inflate.js": 35,
1185
+ "./zlib/messages": 37,
1186
+ "./zlib/zstream": 39
1187
+ }],
1188
+ 27: [function (a, b, c) {
1189
+ "use strict";
1190
+ var d = "undefined" != typeof Uint8Array && "undefined" != typeof Uint16Array && "undefined" != typeof Int32Array;
1191
+ c.assign = function (a) {
1192
+ for (var b = Array.prototype.slice.call(arguments, 1); b.length; ) {
1193
+ var c = b.shift();
1194
+ if (c) {
1195
+ if ("object" != typeof c)
1196
+ throw new TypeError(c + "must be non-object");
1197
+ for (var d in c)
1198
+ c.hasOwnProperty(d) && (a[d] = c[d])
1199
+ }
1200
+ }
1201
+ return a
1202
+ }, c.shrinkBuf = function (a, b) {
1203
+ return a.length === b ? a : a.subarray ? a.subarray(0, b) : (a.length = b, a)
1204
+ };
1205
+ var e = {
1206
+ arraySet: function (a, b, c, d, e) {
1207
+ if (b.subarray && a.subarray)
1208
+ return void a.set(b.subarray(c, c + d), e);
1209
+ for (var f = 0; d > f; f++)
1210
+ a[e + f] = b[c + f]
1211
+ },
1212
+ flattenChunks: function (a) {
1213
+ var b, c, d, e, f, g;
1214
+ for (d = 0, b = 0, c = a.length; c > b; b++)
1215
+ d += a[b].length;
1216
+ for (g = new Uint8Array(d), e = 0, b = 0, c = a.length; c > b; b++)
1217
+ f = a[b], g.set(f, e), e += f.length;
1218
+ return g
1219
+ }
1220
+ },
1221
+ f = {
1222
+ arraySet: function (a, b, c, d, e) {
1223
+ for (var f = 0; d > f; f++)
1224
+ a[e + f] = b[c + f]
1225
+ },
1226
+ flattenChunks: function (a) {
1227
+ return [].concat.apply([], a)
1228
+ }
1229
+ };
1230
+ c.setTyped = function (a) {
1231
+ a ? (c.Buf8 = Uint8Array, c.Buf16 = Uint16Array, c.Buf32 = Int32Array, c.assign(c, e)) : (c.Buf8 = Array, c.Buf16 = Array, c.Buf32 = Array, c.assign(c, f))
1232
+ }, c.setTyped(d)
1233
+ }, {}],
1234
+ 28: [function (a, b, c) {
1235
+ "use strict";
1236
+
1237
+ function d(a, b) {
1238
+ if (65537 > b && (a.subarray && g || !a.subarray && f))
1239
+ return String.fromCharCode.apply(null, e.shrinkBuf(a, b));
1240
+ for (var c = "", d = 0; b > d; d++)
1241
+ c += String.fromCharCode(a[d]);
1242
+ return c
1243
+ }
1244
+ var e = a("./common"),
1245
+ f = !0,
1246
+ g = !0;
1247
+ try {
1248
+ String.fromCharCode.apply(null, [0])
1249
+ } catch (h) {
1250
+ f = !1
1251
+ }
1252
+ try {
1253
+ String.fromCharCode.apply(null, new Uint8Array(1))
1254
+ } catch (h) {
1255
+ g = !1
1256
+ }
1257
+ for (var i = new e.Buf8(256), j = 0; 256 > j; j++)
1258
+ i[j] = j >= 252 ? 6 : j >= 248 ? 5 : j >= 240 ? 4 : j >= 224 ? 3 : j >= 192 ? 2 : 1;
1259
+ i[254] = i[254] = 1, c.string2buf = function (a) {
1260
+ var b, c, d, f, g, h = a.length,
1261
+ i = 0;
1262
+ for (f = 0; h > f; f++)
1263
+ c = a.charCodeAt(f), 55296 === (64512 & c) && h > f + 1 && (d = a.charCodeAt(f + 1), 56320 === (64512 & d) && (c = 65536 + (c - 55296 << 10) + (d - 56320), f++)), i += 128 > c ? 1 : 2048 > c ? 2 : 65536 > c ? 3 : 4;
1264
+ for (b = new e.Buf8(i), g = 0, f = 0; i > g; f++)
1265
+ c = a.charCodeAt(f), 55296 === (64512 & c) && h > f + 1 && (d = a.charCodeAt(f + 1), 56320 === (64512 & d) && (c = 65536 + (c - 55296 << 10) + (d - 56320), f++)), 128 > c ? b[g++] = c : 2048 > c ? (b[g++] = 192 | c >>> 6, b[g++] = 128 | 63 & c) : 65536 > c ? (b[g++] = 224 | c >>> 12, b[g++] = 128 | c >>> 6 & 63, b[g++] = 128 | 63 & c) : (b[g++] = 240 | c >>> 18, b[g++] = 128 | c >>> 12 & 63, b[g++] = 128 | c >>> 6 & 63, b[g++] = 128 | 63 & c);
1266
+ return b
1267
+ }, c.buf2binstring = function (a) {
1268
+ return d(a, a.length)
1269
+ }, c.binstring2buf = function (a) {
1270
+ for (var b = new e.Buf8(a.length), c = 0, d = b.length; d > c; c++)
1271
+ b[c] = a.charCodeAt(c);
1272
+ return b
1273
+ }, c.buf2string = function (a, b) {
1274
+ var c, e, f, g, h = b || a.length,
1275
+ j = new Array(2 * h);
1276
+ for (e = 0, c = 0; h > c; )
1277
+ if (f = a[c++], 128 > f)
1278
+ j[e++] = f;
1279
+ else if (g = i[f], g > 4)
1280
+ j[e++] = 65533, c += g - 1;
1281
+ else {
1282
+ for (f &= 2 === g ? 31 : 3 === g ? 15 : 7; g > 1 && h > c; )
1283
+ f = f << 6 | 63 & a[c++], g--;
1284
+ g > 1 ? j[e++] = 65533 : 65536 > f ? j[e++] = f : (f -= 65536, j[e++] = 55296 | f >> 10 & 1023, j[e++] = 56320 | 1023 & f)
1285
+ }
1286
+ return d(j, e)
1287
+ }, c.utf8border = function (a, b) {
1288
+ var c;
1289
+ for (b = b || a.length, b > a.length && (b = a.length), c = b - 1; c >= 0 && 128 === (192 & a[c]); )
1290
+ c--;
1291
+ return 0 > c ? b : 0 === c ? b : c + i[a[c]] > b ? c : b
1292
+ }
1293
+ }, {
1294
+ "./common": 27
1295
+ }],
1296
+ 29: [function (a, b) {
1297
+ "use strict";
1298
+
1299
+ function c(a, b, c, d) {
1300
+ for (var e = 65535 & a | 0, f = a >>> 16 & 65535 | 0, g = 0; 0 !== c; ) {
1301
+ g = c > 2e3 ? 2e3 : c, c -= g;
1302
+ do
1303
+ e = e + b[d++] | 0, f = f + e | 0;
1304
+ while (--g);
1305
+ e %= 65521, f %= 65521
1306
+ }
1307
+ return e | f << 16 | 0
1308
+ }
1309
+ b.exports = c
1310
+ }, {}],
1311
+ 30: [function (a, b) {
1312
+ b.exports = {
1313
+ Z_NO_FLUSH: 0,
1314
+ Z_PARTIAL_FLUSH: 1,
1315
+ Z_SYNC_FLUSH: 2,
1316
+ Z_FULL_FLUSH: 3,
1317
+ Z_FINISH: 4,
1318
+ Z_BLOCK: 5,
1319
+ Z_TREES: 6,
1320
+ Z_OK: 0,
1321
+ Z_STREAM_END: 1,
1322
+ Z_NEED_DICT: 2,
1323
+ Z_ERRNO: -1,
1324
+ Z_STREAM_ERROR: -2,
1325
+ Z_DATA_ERROR: -3,
1326
+ Z_BUF_ERROR: -5,
1327
+ Z_NO_COMPRESSION: 0,
1328
+ Z_BEST_SPEED: 1,
1329
+ Z_BEST_COMPRESSION: 9,
1330
+ Z_DEFAULT_COMPRESSION: -1,
1331
+ Z_FILTERED: 1,
1332
+ Z_HUFFMAN_ONLY: 2,
1333
+ Z_RLE: 3,
1334
+ Z_FIXED: 4,
1335
+ Z_DEFAULT_STRATEGY: 0,
1336
+ Z_BINARY: 0,
1337
+ Z_TEXT: 1,
1338
+ Z_UNKNOWN: 2,
1339
+ Z_DEFLATED: 8
1340
+ }
1341
+ }, {}],
1342
+ 31: [function (a, b) {
1343
+ "use strict";
1344
+
1345
+ function c() {
1346
+ for (var a, b = [], c = 0; 256 > c; c++) {
1347
+ a = c;
1348
+ for (var d = 0; 8 > d; d++)
1349
+ a = 1 & a ? 3988292384 ^ a >>> 1 : a >>> 1;
1350
+ b[c] = a
1351
+ }
1352
+ return b
1353
+ }
1354
+
1355
+ function d(a, b, c, d) {
1356
+ var f = e,
1357
+ g = d + c;
1358
+ a = -1 ^ a;
1359
+ for (var h = d; g > h; h++)
1360
+ a = a >>> 8 ^ f[255 & (a ^ b[h])];
1361
+ return -1 ^ a
1362
+ }
1363
+ var e = c();
1364
+ b.exports = d
1365
+ }, {}],
1366
+ 32: [function (a, b, c) {
1367
+ "use strict";
1368
+
1369
+ function d(a, b) {
1370
+ return a.msg = G[b], b
1371
+ }
1372
+
1373
+ function e(a) {
1374
+ return (a << 1) - (a > 4 ? 9 : 0)
1375
+ }
1376
+
1377
+ function f(a) {
1378
+ for (var b = a.length; --b >= 0; )
1379
+ a[b] = 0
1380
+ }
1381
+
1382
+ function g(a) {
1383
+ var b = a.state,
1384
+ c = b.pending;
1385
+ c > a.avail_out && (c = a.avail_out), 0 !== c && (C.arraySet(a.output, b.pending_buf, b.pending_out, c, a.next_out), a.next_out += c, b.pending_out += c, a.total_out += c, a.avail_out -= c, b.pending -= c, 0 === b.pending && (b.pending_out = 0))
1386
+ }
1387
+
1388
+ function h(a, b) {
1389
+ D._tr_flush_block(a, a.block_start >= 0 ? a.block_start : -1, a.strstart - a.block_start, b), a.block_start = a.strstart, g(a.strm)
1390
+ }
1391
+
1392
+ function i(a, b) {
1393
+ a.pending_buf[a.pending++] = b
1394
+ }
1395
+
1396
+ function j(a, b) {
1397
+ a.pending_buf[a.pending++] = b >>> 8 & 255, a.pending_buf[a.pending++] = 255 & b
1398
+ }
1399
+
1400
+ function k(a, b, c, d) {
1401
+ var e = a.avail_in;
1402
+ return e > d && (e = d), 0 === e ? 0 : (a.avail_in -= e, C.arraySet(b, a.input, a.next_in, e, c), 1 === a.state.wrap ? a.adler = E(a.adler, b, e, c) : 2 === a.state.wrap && (a.adler = F(a.adler, b, e, c)), a.next_in += e, a.total_in += e, e)
1403
+ }
1404
+
1405
+ function l(a, b) {
1406
+ var c, d, e = a.max_chain_length,
1407
+ f = a.strstart,
1408
+ g = a.prev_length,
1409
+ h = a.nice_match,
1410
+ i = a.strstart > a.w_size - jb ? a.strstart - (a.w_size - jb) : 0,
1411
+ j = a.window,
1412
+ k = a.w_mask,
1413
+ l = a.prev,
1414
+ m = a.strstart + ib,
1415
+ n = j[f + g - 1],
1416
+ o = j[f + g];
1417
+ a.prev_length >= a.good_match && (e >>= 2), h > a.lookahead && (h = a.lookahead);
1418
+ do
1419
+ if (c = b, j[c + g] === o && j[c + g - 1] === n && j[c] === j[f] && j[++c] === j[f + 1]) {
1420
+ f += 2, c++;
1421
+ do
1422
+ ;
1423
+ while (j[++f] === j[++c] && j[++f] === j[++c] && j[++f] === j[++c] && j[++f] === j[++c] && j[++f] === j[++c] && j[++f] === j[++c] && j[++f] === j[++c] && j[++f] === j[++c] && m > f);
1424
+ if (d = ib - (m - f), f = m - ib, d > g) {
1425
+ if (a.match_start = b, g = d, d >= h)
1426
+ break;
1427
+ n = j[f + g - 1], o = j[f + g]
1428
+ }
1429
+ }
1430
+ while ((b = l[b & k]) > i && 0 !== --e);
1431
+ return g <= a.lookahead ? g : a.lookahead
1432
+ }
1433
+
1434
+ function m(a) {
1435
+ var b, c, d, e, f, g = a.w_size;
1436
+ do {
1437
+ if (e = a.window_size - a.lookahead - a.strstart, a.strstart >= g + (g - jb)) {
1438
+ C.arraySet(a.window, a.window, g, g, 0), a.match_start -= g, a.strstart -= g, a.block_start -= g, c = a.hash_size, b = c;
1439
+ do
1440
+ d = a.head[--b], a.head[b] = d >= g ? d - g : 0;
1441
+ while (--c);
1442
+ c = g, b = c;
1443
+ do
1444
+ d = a.prev[--b], a.prev[b] = d >= g ? d - g : 0;
1445
+ while (--c);
1446
+ e += g
1447
+ }
1448
+ if (0 === a.strm.avail_in)
1449
+ break;
1450
+ if (c = k(a.strm, a.window, a.strstart + a.lookahead, e), a.lookahead += c, a.lookahead + a.insert >= hb)
1451
+ for (f = a.strstart - a.insert, a.ins_h = a.window[f], a.ins_h = (a.ins_h << a.hash_shift ^ a.window[f + 1]) & a.hash_mask; a.insert && (a.ins_h = (a.ins_h << a.hash_shift ^ a.window[f + hb - 1]) & a.hash_mask, a.prev[f & a.w_mask] = a.head[a.ins_h], a.head[a.ins_h] = f, f++, a.insert--, !(a.lookahead + a.insert < hb)); )
1452
+ ;
1453
+ } while (a.lookahead < jb && 0 !== a.strm.avail_in)
1454
+ }
1455
+
1456
+ function n(a, b) {
1457
+ var c = 65535;
1458
+ for (c > a.pending_buf_size - 5 && (c = a.pending_buf_size - 5); ; ) {
1459
+ if (a.lookahead <= 1) {
1460
+ if (m(a), 0 === a.lookahead && b === H)
1461
+ return sb;
1462
+ if (0 === a.lookahead)
1463
+ break
1464
+ }
1465
+ a.strstart += a.lookahead, a.lookahead = 0;
1466
+ var d = a.block_start + c;
1467
+ if ((0 === a.strstart || a.strstart >= d) && (a.lookahead = a.strstart - d, a.strstart = d, h(a, !1), 0 === a.strm.avail_out))
1468
+ return sb;
1469
+ if (a.strstart - a.block_start >= a.w_size - jb && (h(a, !1), 0 === a.strm.avail_out))
1470
+ return sb
1471
+ }
1472
+ return a.insert = 0, b === K ? (h(a, !0), 0 === a.strm.avail_out ? ub : vb) : a.strstart > a.block_start && (h(a, !1), 0 === a.strm.avail_out) ? sb : sb
1473
+ }
1474
+
1475
+ function o(a, b) {
1476
+ for (var c, d; ; ) {
1477
+ if (a.lookahead < jb) {
1478
+ if (m(a), a.lookahead < jb && b === H)
1479
+ return sb;
1480
+ if (0 === a.lookahead)
1481
+ break
1482
+ }
1483
+ if (c = 0, a.lookahead >= hb && (a.ins_h = (a.ins_h << a.hash_shift ^ a.window[a.strstart + hb - 1]) & a.hash_mask, c = a.prev[a.strstart & a.w_mask] = a.head[a.ins_h], a.head[a.ins_h] = a.strstart), 0 !== c && a.strstart - c <= a.w_size - jb && (a.match_length = l(a, c)), a.match_length >= hb)
1484
+ if (d = D._tr_tally(a, a.strstart - a.match_start, a.match_length - hb), a.lookahead -= a.match_length, a.match_length <= a.max_lazy_match && a.lookahead >= hb) {
1485
+ a.match_length--;
1486
+ do
1487
+ a.strstart++, a.ins_h = (a.ins_h << a.hash_shift ^ a.window[a.strstart + hb - 1]) & a.hash_mask, c = a.prev[a.strstart & a.w_mask] = a.head[a.ins_h], a.head[a.ins_h] = a.strstart;
1488
+ while (0 !== --a.match_length);
1489
+ a.strstart++
1490
+ } else
1491
+ a.strstart += a.match_length, a.match_length = 0, a.ins_h = a.window[a.strstart], a.ins_h = (a.ins_h << a.hash_shift ^ a.window[a.strstart + 1]) & a.hash_mask;
1492
+ else
1493
+ d = D._tr_tally(a, 0, a.window[a.strstart]), a.lookahead--, a.strstart++;
1494
+ if (d && (h(a, !1), 0 === a.strm.avail_out))
1495
+ return sb
1496
+ }
1497
+ return a.insert = a.strstart < hb - 1 ? a.strstart : hb - 1, b === K ? (h(a, !0), 0 === a.strm.avail_out ? ub : vb) : a.last_lit && (h(a, !1), 0 === a.strm.avail_out) ? sb : tb
1498
+ }
1499
+
1500
+ function p(a, b) {
1501
+ for (var c, d, e; ; ) {
1502
+ if (a.lookahead < jb) {
1503
+ if (m(a), a.lookahead < jb && b === H)
1504
+ return sb;
1505
+ if (0 === a.lookahead)
1506
+ break
1507
+ }
1508
+ if (c = 0, a.lookahead >= hb && (a.ins_h = (a.ins_h << a.hash_shift ^ a.window[a.strstart + hb - 1]) & a.hash_mask, c = a.prev[a.strstart & a.w_mask] = a.head[a.ins_h], a.head[a.ins_h] = a.strstart), a.prev_length = a.match_length, a.prev_match = a.match_start, a.match_length = hb - 1, 0 !== c && a.prev_length < a.max_lazy_match && a.strstart - c <= a.w_size - jb && (a.match_length = l(a, c), a.match_length <= 5 && (a.strategy === S || a.match_length === hb && a.strstart - a.match_start > 4096) && (a.match_length = hb - 1)), a.prev_length >= hb && a.match_length <= a.prev_length) {
1509
+ e = a.strstart + a.lookahead - hb, d = D._tr_tally(a, a.strstart - 1 - a.prev_match, a.prev_length - hb), a.lookahead -= a.prev_length - 1, a.prev_length -= 2;
1510
+ do
1511
+ ++a.strstart <= e && (a.ins_h = (a.ins_h << a.hash_shift ^ a.window[a.strstart + hb - 1]) & a.hash_mask, c = a.prev[a.strstart & a.w_mask] = a.head[a.ins_h], a.head[a.ins_h] = a.strstart);
1512
+ while (0 !== --a.prev_length);
1513
+ if (a.match_available = 0, a.match_length = hb - 1, a.strstart++, d && (h(a, !1), 0 === a.strm.avail_out))
1514
+ return sb
1515
+ } else if (a.match_available) {
1516
+ if (d = D._tr_tally(a, 0, a.window[a.strstart - 1]), d && h(a, !1), a.strstart++, a.lookahead--, 0 === a.strm.avail_out)
1517
+ return sb
1518
+ } else
1519
+ a.match_available = 1, a.strstart++, a.lookahead--
1520
+ }
1521
+ return a.match_available && (d = D._tr_tally(a, 0, a.window[a.strstart - 1]), a.match_available = 0), a.insert = a.strstart < hb - 1 ? a.strstart : hb - 1, b === K ? (h(a, !0), 0 === a.strm.avail_out ? ub : vb) : a.last_lit && (h(a, !1), 0 === a.strm.avail_out) ? sb : tb
1522
+ }
1523
+
1524
+ function q(a, b) {
1525
+ for (var c, d, e, f, g = a.window; ; ) {
1526
+ if (a.lookahead <= ib) {
1527
+ if (m(a), a.lookahead <= ib && b === H)
1528
+ return sb;
1529
+ if (0 === a.lookahead)
1530
+ break
1531
+ }
1532
+ if (a.match_length = 0, a.lookahead >= hb && a.strstart > 0 && (e = a.strstart - 1, d = g[e], d === g[++e] && d === g[++e] && d === g[++e])) {
1533
+ f = a.strstart + ib;
1534
+ do
1535
+ ;
1536
+ while (d === g[++e] && d === g[++e] && d === g[++e] && d === g[++e] && d === g[++e] && d === g[++e] && d === g[++e] && d === g[++e] && f > e);
1537
+ a.match_length = ib - (f - e), a.match_length > a.lookahead && (a.match_length = a.lookahead)
1538
+ }
1539
+ if (a.match_length >= hb ? (c = D._tr_tally(a, 1, a.match_length - hb), a.lookahead -= a.match_length, a.strstart += a.match_length, a.match_length = 0) : (c = D._tr_tally(a, 0, a.window[a.strstart]), a.lookahead--, a.strstart++), c && (h(a, !1), 0 === a.strm.avail_out))
1540
+ return sb
1541
+ }
1542
+ return a.insert = 0, b === K ? (h(a, !0), 0 === a.strm.avail_out ? ub : vb) : a.last_lit && (h(a, !1), 0 === a.strm.avail_out) ? sb : tb
1543
+ }
1544
+
1545
+ function r(a, b) {
1546
+ for (var c; ; ) {
1547
+ if (0 === a.lookahead && (m(a), 0 === a.lookahead)) {
1548
+ if (b === H)
1549
+ return sb;
1550
+ break
1551
+ }
1552
+ if (a.match_length = 0, c = D._tr_tally(a, 0, a.window[a.strstart]), a.lookahead--, a.strstart++, c && (h(a, !1), 0 === a.strm.avail_out))
1553
+ return sb
1554
+ }
1555
+ return a.insert = 0, b === K ? (h(a, !0), 0 === a.strm.avail_out ? ub : vb) : a.last_lit && (h(a, !1), 0 === a.strm.avail_out) ? sb : tb
1556
+ }
1557
+
1558
+ function s(a) {
1559
+ a.window_size = 2 * a.w_size, f(a.head), a.max_lazy_match = B[a.level].max_lazy, a.good_match = B[a.level].good_length, a.nice_match = B[a.level].nice_length, a.max_chain_length = B[a.level].max_chain, a.strstart = 0, a.block_start = 0, a.lookahead = 0, a.insert = 0, a.match_length = a.prev_length = hb - 1, a.match_available = 0, a.ins_h = 0
1560
+ }
1561
+
1562
+ function t() {
1563
+ this.strm = null, this.status = 0, this.pending_buf = null, this.pending_buf_size = 0, this.pending_out = 0, this.pending = 0, this.wrap = 0, this.gzhead = null, this.gzindex = 0, this.method = Y, this.last_flush = -1, this.w_size = 0, this.w_bits = 0, this.w_mask = 0, this.window = null, this.window_size = 0, this.prev = null, this.head = null, this.ins_h = 0, this.hash_size = 0, this.hash_bits = 0, this.hash_mask = 0, this.hash_shift = 0, this.block_start = 0, this.match_length = 0, this.prev_match = 0, this.match_available = 0, this.strstart = 0, this.match_start = 0, this.lookahead = 0, this.prev_length = 0, this.max_chain_length = 0, this.max_lazy_match = 0, this.level = 0, this.strategy = 0, this.good_match = 0, this.nice_match = 0, this.dyn_ltree = new C.Buf16(2 * fb), this.dyn_dtree = new C.Buf16(2 * (2 * db + 1)), this.bl_tree = new C.Buf16(2 * (2 * eb + 1)), f(this.dyn_ltree), f(this.dyn_dtree), f(this.bl_tree), this.l_desc = null, this.d_desc = null, this.bl_desc = null, this.bl_count = new C.Buf16(gb + 1), this.heap = new C.Buf16(2 * cb + 1), f(this.heap), this.heap_len = 0, this.heap_max = 0, this.depth = new C.Buf16(2 * cb + 1), f(this.depth), this.l_buf = 0, this.lit_bufsize = 0, this.last_lit = 0, this.d_buf = 0, this.opt_len = 0, this.static_len = 0, this.matches = 0, this.insert = 0, this.bi_buf = 0, this.bi_valid = 0
1564
+ }
1565
+
1566
+ function u(a) {
1567
+ var b;
1568
+ return a && a.state ? (a.total_in = a.total_out = 0, a.data_type = X, b = a.state, b.pending = 0, b.pending_out = 0, b.wrap < 0 && (b.wrap = -b.wrap), b.status = b.wrap ? lb : qb, a.adler = 2 === b.wrap ? 0 : 1, b.last_flush = H, D._tr_init(b), M) : d(a, O)
1569
+ }
1570
+
1571
+ function v(a) {
1572
+ var b = u(a);
1573
+ return b === M && s(a.state), b
1574
+ }
1575
+
1576
+ function w(a, b) {
1577
+ return a && a.state ? 2 !== a.state.wrap ? O : (a.state.gzhead = b, M) : O
1578
+ }
1579
+
1580
+ function x(a, b, c, e, f, g) {
1581
+ if (!a)
1582
+ return O;
1583
+ var h = 1;
1584
+ if (b === R && (b = 6), 0 > e ? (h = 0, e = -e) : e > 15 && (h = 2, e -= 16), 1 > f || f > Z || c !== Y || 8 > e || e > 15 || 0 > b || b > 9 || 0 > g || g > V)
1585
+ return d(a, O);
1586
+ 8 === e && (e = 9);
1587
+ var i = new t;
1588
+ return a.state = i, i.strm = a, i.wrap = h, i.gzhead = null, i.w_bits = e, i.w_size = 1 << i.w_bits, i.w_mask = i.w_size - 1, i.hash_bits = f + 7, i.hash_size = 1 << i.hash_bits, i.hash_mask = i.hash_size - 1, i.hash_shift = ~~((i.hash_bits + hb - 1) / hb), i.window = new C.Buf8(2 * i.w_size), i.head = new C.Buf16(i.hash_size), i.prev = new C.Buf16(i.w_size), i.lit_bufsize = 1 << f + 6, i.pending_buf_size = 4 * i.lit_bufsize, i.pending_buf = new C.Buf8(i.pending_buf_size), i.d_buf = i.lit_bufsize >> 1, i.l_buf = 3 * i.lit_bufsize, i.level = b, i.strategy = g, i.method = c, v(a)
1589
+ }
1590
+
1591
+ function y(a, b) {
1592
+ return x(a, b, Y, $, _, W)
1593
+ }
1594
+
1595
+ function z(a, b) {
1596
+ var c, h, k, l;
1597
+ if (!a || !a.state || b > L || 0 > b)
1598
+ return a ? d(a, O) : O;
1599
+ if (h = a.state, !a.output || !a.input && 0 !== a.avail_in || h.status === rb && b !== K)
1600
+ return d(a, 0 === a.avail_out ? Q : O);
1601
+ if (h.strm = a, c = h.last_flush, h.last_flush = b, h.status === lb)
1602
+ if (2 === h.wrap)
1603
+ a.adler = 0, i(h, 31), i(h, 139), i(h, 8), h.gzhead ? (i(h, (h.gzhead.text ? 1 : 0) + (h.gzhead.hcrc ? 2 : 0) + (h.gzhead.extra ? 4 : 0) + (h.gzhead.name ? 8 : 0) + (h.gzhead.comment ? 16 : 0)), i(h, 255 & h.gzhead.time), i(h, h.gzhead.time >> 8 & 255), i(h, h.gzhead.time >> 16 & 255), i(h, h.gzhead.time >> 24 & 255), i(h, 9 === h.level ? 2 : h.strategy >= T || h.level < 2 ? 4 : 0), i(h, 255 & h.gzhead.os), h.gzhead.extra && h.gzhead.extra.length && (i(h, 255 & h.gzhead.extra.length), i(h, h.gzhead.extra.length >> 8 & 255)), h.gzhead.hcrc && (a.adler = F(a.adler, h.pending_buf, h.pending, 0)), h.gzindex = 0, h.status = mb) : (i(h, 0), i(h, 0), i(h, 0), i(h, 0), i(h, 0), i(h, 9 === h.level ? 2 : h.strategy >= T || h.level < 2 ? 4 : 0), i(h, wb), h.status = qb);
1604
+ else {
1605
+ var m = Y + (h.w_bits - 8 << 4) << 8,
1606
+ n = -1;
1607
+ n = h.strategy >= T || h.level < 2 ? 0 : h.level < 6 ? 1 : 6 === h.level ? 2 : 3, m |= n << 6, 0 !== h.strstart && (m |= kb), m += 31 - m % 31, h.status = qb, j(h, m), 0 !== h.strstart && (j(h, a.adler >>> 16), j(h, 65535 & a.adler)), a.adler = 1
1608
+ }
1609
+ if (h.status === mb)
1610
+ if (h.gzhead.extra) {
1611
+ for (k = h.pending; h.gzindex < (65535 & h.gzhead.extra.length) && (h.pending !== h.pending_buf_size || (h.gzhead.hcrc && h.pending > k && (a.adler = F(a.adler, h.pending_buf, h.pending - k, k)), g(a), k = h.pending, h.pending !== h.pending_buf_size)); )
1612
+ i(h, 255 & h.gzhead.extra[h.gzindex]), h.gzindex++;
1613
+ h.gzhead.hcrc && h.pending > k && (a.adler = F(a.adler, h.pending_buf, h.pending - k, k)), h.gzindex === h.gzhead.extra.length && (h.gzindex = 0, h.status = nb)
1614
+ } else
1615
+ h.status = nb;
1616
+ if (h.status === nb)
1617
+ if (h.gzhead.name) {
1618
+ k = h.pending;
1619
+ do {
1620
+ if (h.pending === h.pending_buf_size && (h.gzhead.hcrc && h.pending > k && (a.adler = F(a.adler, h.pending_buf, h.pending - k, k)), g(a), k = h.pending, h.pending === h.pending_buf_size)) {
1621
+ l = 1;
1622
+ break
1623
+ }
1624
+ l = h.gzindex < h.gzhead.name.length ? 255 & h.gzhead.name.charCodeAt(h.gzindex++) : 0, i(h, l)
1625
+ } while (0 !== l);
1626
+ h.gzhead.hcrc && h.pending > k && (a.adler = F(a.adler, h.pending_buf, h.pending - k, k)), 0 === l && (h.gzindex = 0, h.status = ob)
1627
+ } else
1628
+ h.status = ob;
1629
+ if (h.status === ob)
1630
+ if (h.gzhead.comment) {
1631
+ k = h.pending;
1632
+ do {
1633
+ if (h.pending === h.pending_buf_size && (h.gzhead.hcrc && h.pending > k && (a.adler = F(a.adler, h.pending_buf, h.pending - k, k)), g(a), k = h.pending, h.pending === h.pending_buf_size)) {
1634
+ l = 1;
1635
+ break
1636
+ }
1637
+ l = h.gzindex < h.gzhead.comment.length ? 255 & h.gzhead.comment.charCodeAt(h.gzindex++) : 0, i(h, l)
1638
+ } while (0 !== l);
1639
+ h.gzhead.hcrc && h.pending > k && (a.adler = F(a.adler, h.pending_buf, h.pending - k, k)), 0 === l && (h.status = pb)
1640
+ } else
1641
+ h.status = pb;
1642
+ if (h.status === pb && (h.gzhead.hcrc ? (h.pending + 2 > h.pending_buf_size && g(a), h.pending + 2 <= h.pending_buf_size && (i(h, 255 & a.adler), i(h, a.adler >> 8 & 255), a.adler = 0, h.status = qb)) : h.status = qb), 0 !== h.pending) {
1643
+ if (g(a), 0 === a.avail_out)
1644
+ return h.last_flush = -1, M
1645
+ } else if (0 === a.avail_in && e(b) <= e(c) && b !== K)
1646
+ return d(a, Q);
1647
+ if (h.status === rb && 0 !== a.avail_in)
1648
+ return d(a, Q);
1649
+ if (0 !== a.avail_in || 0 !== h.lookahead || b !== H && h.status !== rb) {
1650
+ var o = h.strategy === T ? r(h, b) : h.strategy === U ? q(h, b) : B[h.level].func(h, b);
1651
+ if ((o === ub || o === vb) && (h.status = rb), o === sb || o === ub)
1652
+ return 0 === a.avail_out && (h.last_flush = -1), M;
1653
+ if (o === tb && (b === I ? D._tr_align(h) : b !== L && (D._tr_stored_block(h, 0, 0, !1), b === J && (f(h.head), 0 === h.lookahead && (h.strstart = 0, h.block_start = 0, h.insert = 0))), g(a), 0 === a.avail_out))
1654
+ return h.last_flush = -1, M
1655
+ }
1656
+ return b !== K ? M : h.wrap <= 0 ? N : (2 === h.wrap ? (i(h, 255 & a.adler), i(h, a.adler >> 8 & 255), i(h, a.adler >> 16 & 255), i(h, a.adler >> 24 & 255), i(h, 255 & a.total_in), i(h, a.total_in >> 8 & 255), i(h, a.total_in >> 16 & 255), i(h, a.total_in >> 24 & 255)) : (j(h, a.adler >>> 16), j(h, 65535 & a.adler)), g(a), h.wrap > 0 && (h.wrap = -h.wrap), 0 !== h.pending ? M : N)
1657
+ }
1658
+
1659
+ function A(a) {
1660
+ var b;
1661
+ return a && a.state ? (b = a.state.status, b !== lb && b !== mb && b !== nb && b !== ob && b !== pb && b !== qb && b !== rb ? d(a, O) : (a.state = null, b === qb ? d(a, P) : M)) : O
1662
+ }
1663
+ var B, C = a("../utils/common"),
1664
+ D = a("./trees"),
1665
+ E = a("./adler32"),
1666
+ F = a("./crc32"),
1667
+ G = a("./messages"),
1668
+ H = 0,
1669
+ I = 1,
1670
+ J = 3,
1671
+ K = 4,
1672
+ L = 5,
1673
+ M = 0,
1674
+ N = 1,
1675
+ O = -2,
1676
+ P = -3,
1677
+ Q = -5,
1678
+ R = -1,
1679
+ S = 1,
1680
+ T = 2,
1681
+ U = 3,
1682
+ V = 4,
1683
+ W = 0,
1684
+ X = 2,
1685
+ Y = 8,
1686
+ Z = 9,
1687
+ $ = 15,
1688
+ _ = 8,
1689
+ ab = 29,
1690
+ bb = 256,
1691
+ cb = bb + 1 + ab,
1692
+ db = 30,
1693
+ eb = 19,
1694
+ fb = 2 * cb + 1,
1695
+ gb = 15,
1696
+ hb = 3,
1697
+ ib = 258,
1698
+ jb = ib + hb + 1,
1699
+ kb = 32,
1700
+ lb = 42,
1701
+ mb = 69,
1702
+ nb = 73,
1703
+ ob = 91,
1704
+ pb = 103,
1705
+ qb = 113,
1706
+ rb = 666,
1707
+ sb = 1,
1708
+ tb = 2,
1709
+ ub = 3,
1710
+ vb = 4,
1711
+ wb = 3,
1712
+ xb = function (a, b, c, d, e) {
1713
+ this.good_length = a, this.max_lazy = b, this.nice_length = c, this.max_chain = d, this.func = e
1714
+ };
1715
+ B = [new xb(0, 0, 0, 0, n), new xb(4, 4, 8, 4, o), new xb(4, 5, 16, 8, o), new xb(4, 6, 32, 32, o), new xb(4, 4, 16, 16, p), new xb(8, 16, 32, 32, p), new xb(8, 16, 128, 128, p), new xb(8, 32, 128, 256, p), new xb(32, 128, 258, 1024, p), new xb(32, 258, 258, 4096, p)], c.deflateInit = y, c.deflateInit2 = x, c.deflateReset = v, c.deflateResetKeep = u, c.deflateSetHeader = w, c.deflate = z, c.deflateEnd = A, c.deflateInfo = "pako deflate (from Nodeca project)"
1716
+ }, {
1717
+ "../utils/common": 27,
1718
+ "./adler32": 29,
1719
+ "./crc32": 31,
1720
+ "./messages": 37,
1721
+ "./trees": 38
1722
+ }],
1723
+ 33: [function (a, b) {
1724
+ "use strict";
1725
+
1726
+ function c() {
1727
+ this.text = 0, this.time = 0, this.xflags = 0, this.os = 0, this.extra = null, this.extra_len = 0, this.name = "", this.comment = "", this.hcrc = 0, this.done = !1
1728
+ }
1729
+ b.exports = c
1730
+ }, {}],
1731
+ 34: [function (a, b) {
1732
+ "use strict";
1733
+ var c = 30,
1734
+ d = 12;
1735
+ b.exports = function (a, b) {
1736
+ var e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C;
1737
+ e = a.state, f = a.next_in, B = a.input, g = f + (a.avail_in - 5), h = a.next_out, C = a.output, i = h - (b - a.avail_out), j = h + (a.avail_out - 257), k = e.dmax, l = e.wsize, m = e.whave, n = e.wnext, o = e.window, p = e.hold, q = e.bits, r = e.lencode, s = e.distcode, t = (1 << e.lenbits) - 1, u = (1 << e.distbits) - 1;
1738
+ a: do {
1739
+ 15 > q && (p += B[f++] << q, q += 8, p += B[f++] << q, q += 8), v = r[p & t];
1740
+ b: for (; ; ) {
1741
+ if (w = v >>> 24, p >>>= w, q -= w, w = v >>> 16 & 255, 0 === w)
1742
+ C[h++] = 65535 & v;
1743
+ else {
1744
+ if (!(16 & w)) {
1745
+ if (0 === (64 & w)) {
1746
+ v = r[(65535 & v) + (p & (1 << w) - 1)];
1747
+ continue b
1748
+ }
1749
+ if (32 & w) {
1750
+ e.mode = d;
1751
+ break a
1752
+ }
1753
+ a.msg = "invalid literal/length code", e.mode = c;
1754
+ break a
1755
+ }
1756
+ x = 65535 & v, w &= 15, w && (w > q && (p += B[f++] << q, q += 8), x += p & (1 << w) - 1, p >>>= w, q -= w), 15 > q && (p += B[f++] << q, q += 8, p += B[f++] << q, q += 8), v = s[p & u];
1757
+ c: for (; ; ) {
1758
+ if (w = v >>> 24, p >>>= w, q -= w, w = v >>> 16 & 255, !(16 & w)) {
1759
+ if (0 === (64 & w)) {
1760
+ v = s[(65535 & v) + (p & (1 << w) - 1)];
1761
+ continue c
1762
+ }
1763
+ a.msg = "invalid distance code", e.mode = c;
1764
+ break a
1765
+ }
1766
+ if (y = 65535 & v, w &= 15, w > q && (p += B[f++] << q, q += 8, w > q && (p += B[f++] << q, q += 8)), y += p & (1 << w) - 1, y > k) {
1767
+ a.msg = "invalid distance too far back", e.mode = c;
1768
+ break a
1769
+ }
1770
+ if (p >>>= w, q -= w, w = h - i, y > w) {
1771
+ if (w = y - w, w > m && e.sane) {
1772
+ a.msg = "invalid distance too far back", e.mode = c;
1773
+ break a
1774
+ }
1775
+ if (z = 0, A = o, 0 === n) {
1776
+ if (z += l - w, x > w) {
1777
+ x -= w;
1778
+ do
1779
+ C[h++] = o[z++];
1780
+ while (--w);
1781
+ z = h - y, A = C
1782
+ }
1783
+ } else if (w > n) {
1784
+ if (z += l + n - w, w -= n, x > w) {
1785
+ x -= w;
1786
+ do
1787
+ C[h++] = o[z++];
1788
+ while (--w);
1789
+ if (z = 0, x > n) {
1790
+ w = n, x -= w;
1791
+ do
1792
+ C[h++] = o[z++];
1793
+ while (--w);
1794
+ z = h - y, A = C
1795
+ }
1796
+ }
1797
+ } else if (z += n - w, x > w) {
1798
+ x -= w;
1799
+ do
1800
+ C[h++] = o[z++];
1801
+ while (--w);
1802
+ z = h - y, A = C
1803
+ }
1804
+ for (; x > 2; )
1805
+ C[h++] = A[z++], C[h++] = A[z++], C[h++] = A[z++], x -= 3;
1806
+ x && (C[h++] = A[z++], x > 1 && (C[h++] = A[z++]))
1807
+ } else {
1808
+ z = h - y;
1809
+ do
1810
+ C[h++] = C[z++], C[h++] = C[z++], C[h++] = C[z++], x -= 3;
1811
+ while (x > 2);
1812
+ x && (C[h++] = C[z++], x > 1 && (C[h++] = C[z++]))
1813
+ }
1814
+ break
1815
+ }
1816
+ }
1817
+ break
1818
+ }
1819
+ } while (g > f && j > h);
1820
+ x = q >> 3, f -= x, q -= x << 3, p &= (1 << q) - 1, a.next_in = f, a.next_out = h, a.avail_in = g > f ? 5 + (g - f) : 5 - (f - g), a.avail_out = j > h ? 257 + (j - h) : 257 - (h - j), e.hold = p, e.bits = q
1821
+ }
1822
+ }, {}],
1823
+ 35: [function (a, b, c) {
1824
+ "use strict";
1825
+
1826
+ function d(a) {
1827
+ return (a >>> 24 & 255) + (a >>> 8 & 65280) + ((65280 & a) << 8) + ((255 & a) << 24)
1828
+ }
1829
+
1830
+ function e() {
1831
+ this.mode = 0, this.last = !1, this.wrap = 0, this.havedict = !1, this.flags = 0, this.dmax = 0, this.check = 0, this.total = 0, this.head = null, this.wbits = 0, this.wsize = 0, this.whave = 0, this.wnext = 0, this.window = null, this.hold = 0, this.bits = 0, this.length = 0, this.offset = 0, this.extra = 0, this.lencode = null, this.distcode = null, this.lenbits = 0, this.distbits = 0, this.ncode = 0, this.nlen = 0, this.ndist = 0, this.have = 0, this.next = null, this.lens = new r.Buf16(320), this.work = new r.Buf16(288), this.lendyn = null, this.distdyn = null, this.sane = 0, this.back = 0, this.was = 0
1832
+ }
1833
+
1834
+ function f(a) {
1835
+ var b;
1836
+ return a && a.state ? (b = a.state, a.total_in = a.total_out = b.total = 0, a.msg = "", b.wrap && (a.adler = 1 & b.wrap), b.mode = K, b.last = 0, b.havedict = 0, b.dmax = 32768, b.head = null, b.hold = 0, b.bits = 0, b.lencode = b.lendyn = new r.Buf32(ob), b.distcode = b.distdyn = new r.Buf32(pb), b.sane = 1, b.back = -1, C) : F
1837
+ }
1838
+
1839
+ function g(a) {
1840
+ var b;
1841
+ return a && a.state ? (b = a.state, b.wsize = 0, b.whave = 0, b.wnext = 0, f(a)) : F
1842
+ }
1843
+
1844
+ function h(a, b) {
1845
+ var c, d;
1846
+ return a && a.state ? (d = a.state, 0 > b ? (c = 0, b = -b) : (c = (b >> 4) + 1, 48 > b && (b &= 15)), b && (8 > b || b > 15) ? F : (null !== d.window && d.wbits !== b && (d.window = null), d.wrap = c, d.wbits = b, g(a))) : F
1847
+ }
1848
+
1849
+ function i(a, b) {
1850
+ var c, d;
1851
+ return a ? (d = new e, a.state = d, d.window = null, c = h(a, b), c !== C && (a.state = null), c) : F
1852
+ }
1853
+
1854
+ function j(a) {
1855
+ return i(a, rb)
1856
+ }
1857
+
1858
+ function k(a) {
1859
+ if (sb) {
1860
+ var b;
1861
+ for (p = new r.Buf32(512), q = new r.Buf32(32), b = 0; 144 > b; )
1862
+ a.lens[b++] = 8;
1863
+ for (; 256 > b; )
1864
+ a.lens[b++] = 9;
1865
+ for (; 280 > b; )
1866
+ a.lens[b++] = 7;
1867
+ for (; 288 > b; )
1868
+ a.lens[b++] = 8;
1869
+ for (v(x, a.lens, 0, 288, p, 0, a.work, {
1870
+ bits: 9
1871
+ }), b = 0; 32 > b; )
1872
+ a.lens[b++] = 5;
1873
+ v(y, a.lens, 0, 32, q, 0, a.work, {
1874
+ bits: 5
1875
+ }), sb = !1
1876
+ }
1877
+ a.lencode = p, a.lenbits = 9, a.distcode = q, a.distbits = 5
1878
+ }
1879
+
1880
+ function l(a, b, c, d) {
1881
+ var e, f = a.state;
1882
+ return null === f.window && (f.wsize = 1 << f.wbits, f.wnext = 0, f.whave = 0, f.window = new r.Buf8(f.wsize)), d >= f.wsize ? (r.arraySet(f.window, b, c - f.wsize, f.wsize, 0), f.wnext = 0, f.whave = f.wsize) : (e = f.wsize - f.wnext, e > d && (e = d), r.arraySet(f.window, b, c - d, e, f.wnext), d -= e, d ? (r.arraySet(f.window, b, c - d, d, 0), f.wnext = d, f.whave = f.wsize) : (f.wnext += e, f.wnext === f.wsize && (f.wnext = 0), f.whave < f.wsize && (f.whave += e))), 0
1883
+ }
1884
+
1885
+ function m(a, b) {
1886
+ var c, e, f, g, h, i, j, m, n, o, p, q, ob, pb, qb, rb, sb, tb, ub, vb, wb, xb, yb, zb, Ab = 0,
1887
+ Bb = new r.Buf8(4),
1888
+ Cb = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
1889
+ if (!a || !a.state || !a.output || !a.input && 0 !== a.avail_in)
1890
+ return F;
1891
+ c = a.state, c.mode === V && (c.mode = W), h = a.next_out, f = a.output, j = a.avail_out, g = a.next_in, e = a.input, i = a.avail_in, m = c.hold, n = c.bits, o = i, p = j, xb = C;
1892
+ a: for (; ; )
1893
+ switch (c.mode) {
1894
+ case K:
1895
+ if (0 === c.wrap) {
1896
+ c.mode = W;
1897
+ break
1898
+ }
1899
+ for (; 16 > n; ) {
1900
+ if (0 === i)
1901
+ break a;
1902
+ i--, m += e[g++] << n, n += 8
1903
+ }
1904
+ if (2 & c.wrap && 35615 === m) {
1905
+ c.check = 0, Bb[0] = 255 & m, Bb[1] = m >>> 8 & 255, c.check = t(c.check, Bb, 2, 0), m = 0, n = 0, c.mode = L;
1906
+ break
1907
+ }
1908
+ if (c.flags = 0, c.head && (c.head.done = !1), !(1 & c.wrap) || (((255 & m) << 8) + (m >> 8)) % 31) {
1909
+ a.msg = "incorrect header check", c.mode = lb;
1910
+ break
1911
+ }
1912
+ if ((15 & m) !== J) {
1913
+ a.msg = "unknown compression method", c.mode = lb;
1914
+ break
1915
+ }
1916
+ if (m >>>= 4, n -= 4, wb = (15 & m) + 8, 0 === c.wbits)
1917
+ c.wbits = wb;
1918
+ else if (wb > c.wbits) {
1919
+ a.msg = "invalid window size", c.mode = lb;
1920
+ break
1921
+ }
1922
+ c.dmax = 1 << wb, a.adler = c.check = 1, c.mode = 512 & m ? T : V, m = 0, n = 0;
1923
+ break;
1924
+ case L:
1925
+ for (; 16 > n; ) {
1926
+ if (0 === i)
1927
+ break a;
1928
+ i--, m += e[g++] << n, n += 8
1929
+ }
1930
+ if (c.flags = m, (255 & c.flags) !== J) {
1931
+ a.msg = "unknown compression method", c.mode = lb;
1932
+ break
1933
+ }
1934
+ if (57344 & c.flags) {
1935
+ a.msg = "unknown header flags set", c.mode = lb;
1936
+ break
1937
+ }
1938
+ c.head && (c.head.text = m >> 8 & 1), 512 & c.flags && (Bb[0] = 255 & m, Bb[1] = m >>> 8 & 255, c.check = t(c.check, Bb, 2, 0)), m = 0, n = 0, c.mode = M;
1939
+ case M:
1940
+ for (; 32 > n; ) {
1941
+ if (0 === i)
1942
+ break a;
1943
+ i--, m += e[g++] << n, n += 8
1944
+ }
1945
+ c.head && (c.head.time = m), 512 & c.flags && (Bb[0] = 255 & m, Bb[1] = m >>> 8 & 255, Bb[2] = m >>> 16 & 255, Bb[3] = m >>> 24 & 255, c.check = t(c.check, Bb, 4, 0)), m = 0, n = 0, c.mode = N;
1946
+ case N:
1947
+ for (; 16 > n; ) {
1948
+ if (0 === i)
1949
+ break a;
1950
+ i--, m += e[g++] << n, n += 8
1951
+ }
1952
+ c.head && (c.head.xflags = 255 & m, c.head.os = m >> 8), 512 & c.flags && (Bb[0] = 255 & m, Bb[1] = m >>> 8 & 255, c.check = t(c.check, Bb, 2, 0)), m = 0, n = 0, c.mode = O;
1953
+ case O:
1954
+ if (1024 & c.flags) {
1955
+ for (; 16 > n; ) {
1956
+ if (0 === i)
1957
+ break a;
1958
+ i--, m += e[g++] << n, n += 8
1959
+ }
1960
+ c.length = m, c.head && (c.head.extra_len = m), 512 & c.flags && (Bb[0] = 255 & m, Bb[1] = m >>> 8 & 255, c.check = t(c.check, Bb, 2, 0)), m = 0, n = 0
1961
+ } else
1962
+ c.head && (c.head.extra = null);
1963
+ c.mode = P;
1964
+ case P:
1965
+ if (1024 & c.flags && (q = c.length, q > i && (q = i), q && (c.head && (wb = c.head.extra_len - c.length, c.head.extra || (c.head.extra = new Array(c.head.extra_len)), r.arraySet(c.head.extra, e, g, q, wb)), 512 & c.flags && (c.check = t(c.check, e, q, g)), i -= q, g += q, c.length -= q), c.length))
1966
+ break a;
1967
+ c.length = 0, c.mode = Q;
1968
+ case Q:
1969
+ if (2048 & c.flags) {
1970
+ if (0 === i)
1971
+ break a;
1972
+ q = 0;
1973
+ do
1974
+ wb = e[g + q++], c.head && wb && c.length < 65536 && (c.head.name += String.fromCharCode(wb));
1975
+ while (wb && i > q);
1976
+ if (512 & c.flags && (c.check = t(c.check, e, q, g)), i -= q, g += q, wb)
1977
+ break a
1978
+ } else
1979
+ c.head && (c.head.name = null);
1980
+ c.length = 0, c.mode = R;
1981
+ case R:
1982
+ if (4096 & c.flags) {
1983
+ if (0 === i)
1984
+ break a;
1985
+ q = 0;
1986
+ do
1987
+ wb = e[g + q++], c.head && wb && c.length < 65536 && (c.head.comment += String.fromCharCode(wb));
1988
+ while (wb && i > q);
1989
+ if (512 & c.flags && (c.check = t(c.check, e, q, g)), i -= q, g += q, wb)
1990
+ break a
1991
+ } else
1992
+ c.head && (c.head.comment = null);
1993
+ c.mode = S;
1994
+ case S:
1995
+ if (512 & c.flags) {
1996
+ for (; 16 > n; ) {
1997
+ if (0 === i)
1998
+ break a;
1999
+ i--, m += e[g++] << n, n += 8
2000
+ }
2001
+ if (m !== (65535 & c.check)) {
2002
+ a.msg = "header crc mismatch", c.mode = lb;
2003
+ break
2004
+ }
2005
+ m = 0, n = 0
2006
+ }
2007
+ c.head && (c.head.hcrc = c.flags >> 9 & 1, c.head.done = !0), a.adler = c.check = 0, c.mode = V;
2008
+ break;
2009
+ case T:
2010
+ for (; 32 > n; ) {
2011
+ if (0 === i)
2012
+ break a;
2013
+ i--, m += e[g++] << n, n += 8
2014
+ }
2015
+ a.adler = c.check = d(m), m = 0, n = 0, c.mode = U;
2016
+ case U:
2017
+ if (0 === c.havedict)
2018
+ return a.next_out = h, a.avail_out = j, a.next_in = g, a.avail_in = i, c.hold = m, c.bits = n, E;
2019
+ a.adler = c.check = 1, c.mode = V;
2020
+ case V:
2021
+ if (b === A || b === B)
2022
+ break a;
2023
+ case W:
2024
+ if (c.last) {
2025
+ m >>>= 7 & n, n -= 7 & n, c.mode = ib;
2026
+ break
2027
+ }
2028
+ for (; 3 > n; ) {
2029
+ if (0 === i)
2030
+ break a;
2031
+ i--, m += e[g++] << n, n += 8
2032
+ }
2033
+ switch (c.last = 1 & m, m >>>= 1, n -= 1, 3 & m) {
2034
+ case 0:
2035
+ c.mode = X;
2036
+ break;
2037
+ case 1:
2038
+ if (k(c), c.mode = bb, b === B) {
2039
+ m >>>= 2, n -= 2;
2040
+ break a
2041
+ }
2042
+ break;
2043
+ case 2:
2044
+ c.mode = $;
2045
+ break;
2046
+ case 3:
2047
+ a.msg = "invalid block type", c.mode = lb
2048
+ }
2049
+ m >>>= 2, n -= 2;
2050
+ break;
2051
+ case X:
2052
+ for (m >>>= 7 & n, n -= 7 & n; 32 > n; ) {
2053
+ if (0 === i)
2054
+ break a;
2055
+ i--, m += e[g++] << n, n += 8
2056
+ }
2057
+ if ((65535 & m) !== (m >>> 16 ^ 65535)) {
2058
+ a.msg = "invalid stored block lengths", c.mode = lb;
2059
+ break
2060
+ }
2061
+ if (c.length = 65535 & m, m = 0, n = 0, c.mode = Y, b === B)
2062
+ break a;
2063
+ case Y:
2064
+ c.mode = Z;
2065
+ case Z:
2066
+ if (q = c.length) {
2067
+ if (q > i && (q = i), q > j && (q = j), 0 === q)
2068
+ break a;
2069
+ r.arraySet(f, e, g, q, h), i -= q, g += q, j -= q, h += q, c.length -= q;
2070
+ break
2071
+ }
2072
+ c.mode = V;
2073
+ break;
2074
+ case $:
2075
+ for (; 14 > n; ) {
2076
+ if (0 === i)
2077
+ break a;
2078
+ i--, m += e[g++] << n, n += 8
2079
+ }
2080
+ if (c.nlen = (31 & m) + 257, m >>>= 5, n -= 5, c.ndist = (31 & m) + 1, m >>>= 5, n -= 5, c.ncode = (15 & m) + 4, m >>>= 4, n -= 4, c.nlen > 286 || c.ndist > 30) {
2081
+ a.msg = "too many length or distance symbols", c.mode = lb;
2082
+ break
2083
+ }
2084
+ c.have = 0, c.mode = _;
2085
+ case _:
2086
+ for (; c.have < c.ncode; ) {
2087
+ for (; 3 > n; ) {
2088
+ if (0 === i)
2089
+ break a;
2090
+ i--, m += e[g++] << n, n += 8
2091
+ }
2092
+ c.lens[Cb[c.have++]] = 7 & m, m >>>= 3, n -= 3
2093
+ }
2094
+ for (; c.have < 19; )
2095
+ c.lens[Cb[c.have++]] = 0;
2096
+ if (c.lencode = c.lendyn, c.lenbits = 7, yb = {
2097
+ bits: c.lenbits
2098
+ }, xb = v(w, c.lens, 0, 19, c.lencode, 0, c.work, yb), c.lenbits = yb.bits, xb) {
2099
+ a.msg = "invalid code lengths set", c.mode = lb;
2100
+ break
2101
+ }
2102
+ c.have = 0, c.mode = ab;
2103
+ case ab:
2104
+ for (; c.have < c.nlen + c.ndist; ) {
2105
+ for (; Ab = c.lencode[m & (1 << c.lenbits) - 1], qb = Ab >>> 24, rb = Ab >>> 16 & 255, sb = 65535 & Ab, !(n >= qb); ) {
2106
+ if (0 === i)
2107
+ break a;
2108
+ i--, m += e[g++] << n, n += 8
2109
+ }
2110
+ if (16 > sb)
2111
+ m >>>= qb, n -= qb, c.lens[c.have++] = sb;
2112
+ else {
2113
+ if (16 === sb) {
2114
+ for (zb = qb + 2; zb > n; ) {
2115
+ if (0 === i)
2116
+ break a;
2117
+ i--, m += e[g++] << n, n += 8
2118
+ }
2119
+ if (m >>>= qb, n -= qb, 0 === c.have) {
2120
+ a.msg = "invalid bit length repeat", c.mode = lb;
2121
+ break
2122
+ }
2123
+ wb = c.lens[c.have - 1], q = 3 + (3 & m), m >>>= 2, n -= 2
2124
+ } else if (17 === sb) {
2125
+ for (zb = qb + 3; zb > n; ) {
2126
+ if (0 === i)
2127
+ break a;
2128
+ i--, m += e[g++] << n, n += 8
2129
+ }
2130
+ m >>>= qb, n -= qb, wb = 0, q = 3 + (7 & m), m >>>= 3, n -= 3
2131
+ } else {
2132
+ for (zb = qb + 7; zb > n; ) {
2133
+ if (0 === i)
2134
+ break a;
2135
+ i--, m += e[g++] << n, n += 8
2136
+ }
2137
+ m >>>= qb, n -= qb, wb = 0, q = 11 + (127 & m), m >>>= 7, n -= 7
2138
+ }
2139
+ if (c.have + q > c.nlen + c.ndist) {
2140
+ a.msg = "invalid bit length repeat", c.mode = lb;
2141
+ break
2142
+ }
2143
+ for (; q--; )
2144
+ c.lens[c.have++] = wb
2145
+ }
2146
+ }
2147
+ if (c.mode === lb)
2148
+ break;
2149
+ if (0 === c.lens[256]) {
2150
+ a.msg = "invalid code -- missing end-of-block", c.mode = lb;
2151
+ break
2152
+ }
2153
+ if (c.lenbits = 9, yb = {
2154
+ bits: c.lenbits
2155
+ }, xb = v(x, c.lens, 0, c.nlen, c.lencode, 0, c.work, yb), c.lenbits = yb.bits, xb) {
2156
+ a.msg = "invalid literal/lengths set", c.mode = lb;
2157
+ break
2158
+ }
2159
+ if (c.distbits = 6, c.distcode = c.distdyn, yb = {
2160
+ bits: c.distbits
2161
+ }, xb = v(y, c.lens, c.nlen, c.ndist, c.distcode, 0, c.work, yb), c.distbits = yb.bits, xb) {
2162
+ a.msg = "invalid distances set", c.mode = lb;
2163
+ break
2164
+ }
2165
+ if (c.mode = bb, b === B)
2166
+ break a;
2167
+ case bb:
2168
+ c.mode = cb;
2169
+ case cb:
2170
+ if (i >= 6 && j >= 258) {
2171
+ a.next_out = h, a.avail_out = j, a.next_in = g, a.avail_in = i, c.hold = m, c.bits = n, u(a, p), h = a.next_out, f = a.output, j = a.avail_out, g = a.next_in, e = a.input, i = a.avail_in, m = c.hold, n = c.bits, c.mode === V && (c.back = -1);
2172
+ break
2173
+ }
2174
+ for (c.back = 0; Ab = c.lencode[m & (1 << c.lenbits) - 1], qb = Ab >>> 24, rb = Ab >>> 16 & 255, sb = 65535 & Ab, !(n >= qb); ) {
2175
+ if (0 === i)
2176
+ break a;
2177
+ i--, m += e[g++] << n, n += 8
2178
+ }
2179
+ if (rb && 0 === (240 & rb)) {
2180
+ for (tb = qb, ub = rb, vb = sb; Ab = c.lencode[vb + ((m & (1 << tb + ub) - 1) >> tb)], qb = Ab >>> 24, rb = Ab >>> 16 & 255, sb = 65535 & Ab, !(n >= tb + qb); ) {
2181
+ if (0 === i)
2182
+ break a;
2183
+ i--, m += e[g++] << n, n += 8
2184
+ }
2185
+ m >>>= tb, n -= tb, c.back += tb
2186
+ }
2187
+ if (m >>>= qb, n -= qb, c.back += qb, c.length = sb, 0 === rb) {
2188
+ c.mode = hb;
2189
+ break
2190
+ }
2191
+ if (32 & rb) {
2192
+ c.back = -1, c.mode = V;
2193
+ break
2194
+ }
2195
+ if (64 & rb) {
2196
+ a.msg = "invalid literal/length code", c.mode = lb;
2197
+ break
2198
+ }
2199
+ c.extra = 15 & rb, c.mode = db;
2200
+ case db:
2201
+ if (c.extra) {
2202
+ for (zb = c.extra; zb > n; ) {
2203
+ if (0 === i)
2204
+ break a;
2205
+ i--, m += e[g++] << n, n += 8
2206
+ }
2207
+ c.length += m & (1 << c.extra) - 1, m >>>= c.extra, n -= c.extra, c.back += c.extra
2208
+ }
2209
+ c.was = c.length, c.mode = eb;
2210
+ case eb:
2211
+ for (; Ab = c.distcode[m & (1 << c.distbits) - 1], qb = Ab >>> 24, rb = Ab >>> 16 & 255, sb = 65535 & Ab, !(n >= qb); ) {
2212
+ if (0 === i)
2213
+ break a;
2214
+ i--, m += e[g++] << n, n += 8
2215
+ }
2216
+ if (0 === (240 & rb)) {
2217
+ for (tb = qb, ub = rb, vb = sb; Ab = c.distcode[vb + ((m & (1 << tb + ub) - 1) >> tb)], qb = Ab >>> 24, rb = Ab >>> 16 & 255, sb = 65535 & Ab, !(n >= tb + qb); ) {
2218
+ if (0 === i)
2219
+ break a;
2220
+ i--, m += e[g++] << n, n += 8
2221
+ }
2222
+ m >>>= tb, n -= tb, c.back += tb
2223
+ }
2224
+ if (m >>>= qb, n -= qb, c.back += qb, 64 & rb) {
2225
+ a.msg = "invalid distance code", c.mode = lb;
2226
+ break
2227
+ }
2228
+ c.offset = sb, c.extra = 15 & rb, c.mode = fb;
2229
+ case fb:
2230
+ if (c.extra) {
2231
+ for (zb = c.extra; zb > n; ) {
2232
+ if (0 === i)
2233
+ break a;
2234
+ i--, m += e[g++] << n, n += 8
2235
+ }
2236
+ c.offset += m & (1 << c.extra) - 1, m >>>= c.extra, n -= c.extra, c.back += c.extra
2237
+ }
2238
+ if (c.offset > c.dmax) {
2239
+ a.msg = "invalid distance too far back", c.mode = lb;
2240
+ break
2241
+ }
2242
+ c.mode = gb;
2243
+ case gb:
2244
+ if (0 === j)
2245
+ break a;
2246
+ if (q = p - j, c.offset > q) {
2247
+ if (q = c.offset - q, q > c.whave && c.sane) {
2248
+ a.msg = "invalid distance too far back", c.mode = lb;
2249
+ break
2250
+ }
2251
+ q > c.wnext ? (q -= c.wnext, ob = c.wsize - q) : ob = c.wnext - q, q > c.length && (q = c.length), pb = c.window
2252
+ } else
2253
+ pb = f, ob = h - c.offset, q = c.length;
2254
+ q > j && (q = j), j -= q, c.length -= q;
2255
+ do
2256
+ f[h++] = pb[ob++];
2257
+ while (--q);
2258
+ 0 === c.length && (c.mode = cb);
2259
+ break;
2260
+ case hb:
2261
+ if (0 === j)
2262
+ break a;
2263
+ f[h++] = c.length, j--, c.mode = cb;
2264
+ break;
2265
+ case ib:
2266
+ if (c.wrap) {
2267
+ for (; 32 > n; ) {
2268
+ if (0 === i)
2269
+ break a;
2270
+ i--, m |= e[g++] << n, n += 8
2271
+ }
2272
+ if (p -= j, a.total_out += p, c.total += p, p && (a.adler = c.check = c.flags ? t(c.check, f, p, h - p) : s(c.check, f, p, h - p)), p = j, (c.flags ? m : d(m)) !== c.check) {
2273
+ a.msg = "incorrect data check", c.mode = lb;
2274
+ break
2275
+ }
2276
+ m = 0, n = 0
2277
+ }
2278
+ c.mode = jb;
2279
+ case jb:
2280
+ if (c.wrap && c.flags) {
2281
+ for (; 32 > n; ) {
2282
+ if (0 === i)
2283
+ break a;
2284
+ i--, m += e[g++] << n, n += 8
2285
+ }
2286
+ if (m !== (4294967295 & c.total)) {
2287
+ a.msg = "incorrect length check", c.mode = lb;
2288
+ break
2289
+ }
2290
+ m = 0, n = 0
2291
+ }
2292
+ c.mode = kb;
2293
+ case kb:
2294
+ xb = D;
2295
+ break a;
2296
+ case lb:
2297
+ xb = G;
2298
+ break a;
2299
+ case mb:
2300
+ return H;
2301
+ case nb:
2302
+ default:
2303
+ return F
2304
+ }
2305
+ return a.next_out = h, a.avail_out = j, a.next_in = g, a.avail_in = i, c.hold = m, c.bits = n, (c.wsize || p !== a.avail_out && c.mode < lb && (c.mode < ib || b !== z)) && l(a, a.output, a.next_out, p - a.avail_out) ? (c.mode = mb, H) : (o -= a.avail_in, p -= a.avail_out, a.total_in += o, a.total_out += p, c.total += p, c.wrap && p && (a.adler = c.check = c.flags ? t(c.check, f, p, a.next_out - p) : s(c.check, f, p, a.next_out - p)), a.data_type = c.bits + (c.last ? 64 : 0) + (c.mode === V ? 128 : 0) + (c.mode === bb || c.mode === Y ? 256 : 0), (0 === o && 0 === p || b === z) && xb === C && (xb = I), xb)
2306
+ }
2307
+
2308
+ function n(a) {
2309
+ if (!a || !a.state)
2310
+ return F;
2311
+ var b = a.state;
2312
+ return b.window && (b.window = null), a.state = null, C
2313
+ }
2314
+
2315
+ function o(a, b) {
2316
+ var c;
2317
+ return a && a.state ? (c = a.state, 0 === (2 & c.wrap) ? F : (c.head = b, b.done = !1, C)) : F
2318
+ }
2319
+ var p, q, r = a("../utils/common"),
2320
+ s = a("./adler32"),
2321
+ t = a("./crc32"),
2322
+ u = a("./inffast"),
2323
+ v = a("./inftrees"),
2324
+ w = 0,
2325
+ x = 1,
2326
+ y = 2,
2327
+ z = 4,
2328
+ A = 5,
2329
+ B = 6,
2330
+ C = 0,
2331
+ D = 1,
2332
+ E = 2,
2333
+ F = -2,
2334
+ G = -3,
2335
+ H = -4,
2336
+ I = -5,
2337
+ J = 8,
2338
+ K = 1,
2339
+ L = 2,
2340
+ M = 3,
2341
+ N = 4,
2342
+ O = 5,
2343
+ P = 6,
2344
+ Q = 7,
2345
+ R = 8,
2346
+ S = 9,
2347
+ T = 10,
2348
+ U = 11,
2349
+ V = 12,
2350
+ W = 13,
2351
+ X = 14,
2352
+ Y = 15,
2353
+ Z = 16,
2354
+ $ = 17,
2355
+ _ = 18,
2356
+ ab = 19,
2357
+ bb = 20,
2358
+ cb = 21,
2359
+ db = 22,
2360
+ eb = 23,
2361
+ fb = 24,
2362
+ gb = 25,
2363
+ hb = 26,
2364
+ ib = 27,
2365
+ jb = 28,
2366
+ kb = 29,
2367
+ lb = 30,
2368
+ mb = 31,
2369
+ nb = 32,
2370
+ ob = 852,
2371
+ pb = 592,
2372
+ qb = 15,
2373
+ rb = qb,
2374
+ sb = !0;
2375
+ c.inflateReset = g, c.inflateReset2 = h, c.inflateResetKeep = f, c.inflateInit = j, c.inflateInit2 = i, c.inflate = m, c.inflateEnd = n, c.inflateGetHeader = o, c.inflateInfo = "pako inflate (from Nodeca project)"
2376
+ }, {
2377
+ "../utils/common": 27,
2378
+ "./adler32": 29,
2379
+ "./crc32": 31,
2380
+ "./inffast": 34,
2381
+ "./inftrees": 36
2382
+ }],
2383
+ 36: [function (a, b) {
2384
+ "use strict";
2385
+ var c = a("../utils/common"),
2386
+ d = 15,
2387
+ e = 852,
2388
+ f = 592,
2389
+ g = 0,
2390
+ h = 1,
2391
+ i = 2,
2392
+ j = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0],
2393
+ k = [16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78],
2394
+ l = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0],
2395
+ m = [16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64];
2396
+ b.exports = function (a, b, n, o, p, q, r, s) {
2397
+ var t, u, v, w, x, y, z, A, B, C = s.bits,
2398
+ D = 0,
2399
+ E = 0,
2400
+ F = 0,
2401
+ G = 0,
2402
+ H = 0,
2403
+ I = 0,
2404
+ J = 0,
2405
+ K = 0,
2406
+ L = 0,
2407
+ M = 0,
2408
+ N = null,
2409
+ O = 0,
2410
+ P = new c.Buf16(d + 1),
2411
+ Q = new c.Buf16(d + 1),
2412
+ R = null,
2413
+ S = 0;
2414
+ for (D = 0; d >= D; D++)
2415
+ P[D] = 0;
2416
+ for (E = 0; o > E; E++)
2417
+ P[b[n + E]]++;
2418
+ for (H = C, G = d; G >= 1 && 0 === P[G]; G--)
2419
+ ;
2420
+ if (H > G && (H = G), 0 === G)
2421
+ return p[q++] = 20971520, p[q++] = 20971520, s.bits = 1, 0;
2422
+ for (F = 1; G > F && 0 === P[F]; F++)
2423
+ ;
2424
+ for (F > H && (H = F), K = 1, D = 1; d >= D; D++)
2425
+ if (K <<= 1, K -= P[D], 0 > K)
2426
+ return -1;
2427
+ if (K > 0 && (a === g || 1 !== G))
2428
+ return -1;
2429
+ for (Q[1] = 0, D = 1; d > D; D++)
2430
+ Q[D + 1] = Q[D] + P[D];
2431
+ for (E = 0; o > E; E++)
2432
+ 0 !== b[n + E] && (r[Q[b[n + E]]++] = E);
2433
+ if (a === g ? (N = R = r, y = 19) : a === h ? (N = j, O -= 257, R = k, S -= 257, y = 256) : (N = l, R = m, y = -1), M = 0, E = 0, D = F, x = q, I = H, J = 0, v = -1, L = 1 << H, w = L - 1, a === h && L > e || a === i && L > f)
2434
+ return 1;
2435
+ for (var T = 0; ; ) {
2436
+ T++, z = D - J, r[E] < y ? (A = 0, B = r[E]) : r[E] > y ? (A = R[S + r[E]], B = N[O + r[E]]) : (A = 96, B = 0), t = 1 << D - J, u = 1 << I, F = u;
2437
+ do
2438
+ u -= t, p[x + (M >> J) + u] = z << 24 | A << 16 | B | 0;
2439
+ while (0 !== u);
2440
+ for (t = 1 << D - 1; M & t; )
2441
+ t >>= 1;
2442
+ if (0 !== t ? (M &= t - 1, M += t) : M = 0, E++, 0 === --P[D]) {
2443
+ if (D === G)
2444
+ break;
2445
+ D = b[n + r[E]]
2446
+ }
2447
+ if (D > H && (M & w) !== v) {
2448
+ for (0 === J && (J = H), x += F, I = D - J, K = 1 << I; G > I + J && (K -= P[I + J], !(0 >= K)); )
2449
+ I++, K <<= 1;
2450
+ if (L += 1 << I, a === h && L > e || a === i && L > f)
2451
+ return 1;
2452
+ v = M & w, p[v] = H << 24 | I << 16 | x - q | 0
2453
+ }
2454
+ }
2455
+ return 0 !== M && (p[x + M] = D - J << 24 | 64 << 16 | 0), s.bits = H, 0
2456
+ }
2457
+ }, {
2458
+ "../utils/common": 27
2459
+ }],
2460
+ 37: [function (a, b) {
2461
+ "use strict";
2462
+ b.exports = {
2463
+ 2: "need dictionary",
2464
+ 1: "stream end",
2465
+ 0: "",
2466
+ "-1": "file error",
2467
+ "-2": "stream error",
2468
+ "-3": "data error",
2469
+ "-4": "insufficient memory",
2470
+ "-5": "buffer error",
2471
+ "-6": "incompatible version"
2472
+ }
2473
+ }, {}],
2474
+ 38: [function (a, b, c) {
2475
+ "use strict";
2476
+
2477
+ function d(a) {
2478
+ for (var b = a.length; --b >= 0; )
2479
+ a[b] = 0
2480
+ }
2481
+
2482
+ function e(a) {
2483
+ return 256 > a ? gb[a] : gb[256 + (a >>> 7)]
2484
+ }
2485
+
2486
+ function f(a, b) {
2487
+ a.pending_buf[a.pending++] = 255 & b, a.pending_buf[a.pending++] = b >>> 8 & 255
2488
+ }
2489
+
2490
+ function g(a, b, c) {
2491
+ a.bi_valid > V - c ? (a.bi_buf |= b << a.bi_valid & 65535, f(a, a.bi_buf), a.bi_buf = b >> V - a.bi_valid, a.bi_valid += c - V) : (a.bi_buf |= b << a.bi_valid & 65535, a.bi_valid += c)
2492
+ }
2493
+
2494
+ function h(a, b, c) {
2495
+ g(a, c[2 * b], c[2 * b + 1])
2496
+ }
2497
+
2498
+ function i(a, b) {
2499
+ var c = 0;
2500
+ do
2501
+ c |= 1 & a, a >>>= 1, c <<= 1;
2502
+ while (--b > 0);
2503
+ return c >>> 1
2504
+ }
2505
+
2506
+ function j(a) {
2507
+ 16 === a.bi_valid ? (f(a, a.bi_buf), a.bi_buf = 0, a.bi_valid = 0) : a.bi_valid >= 8 && (a.pending_buf[a.pending++] = 255 & a.bi_buf, a.bi_buf >>= 8, a.bi_valid -= 8)
2508
+ }
2509
+
2510
+ function k(a, b) {
2511
+ var c, d, e, f, g, h, i = b.dyn_tree,
2512
+ j = b.max_code,
2513
+ k = b.stat_desc.static_tree,
2514
+ l = b.stat_desc.has_stree,
2515
+ m = b.stat_desc.extra_bits,
2516
+ n = b.stat_desc.extra_base,
2517
+ o = b.stat_desc.max_length,
2518
+ p = 0;
2519
+ for (f = 0; U >= f; f++)
2520
+ a.bl_count[f] = 0;
2521
+ for (i[2 * a.heap[a.heap_max] + 1] = 0, c = a.heap_max + 1; T > c; c++)
2522
+ d = a.heap[c], f = i[2 * i[2 * d + 1] + 1] + 1, f > o && (f = o, p++), i[2 * d + 1] = f, d > j || (a.bl_count[f]++, g = 0, d >= n && (g = m[d - n]), h = i[2 * d], a.opt_len += h * (f + g), l && (a.static_len += h * (k[2 * d + 1] + g)));
2523
+ if (0 !== p) {
2524
+ do {
2525
+ for (f = o - 1; 0 === a.bl_count[f]; )
2526
+ f--;
2527
+ a.bl_count[f]--, a.bl_count[f + 1] += 2, a.bl_count[o]--, p -= 2
2528
+ } while (p > 0);
2529
+ for (f = o; 0 !== f; f--)
2530
+ for (d = a.bl_count[f]; 0 !== d; )
2531
+ e = a.heap[--c], e > j || (i[2 * e + 1] !== f && (a.opt_len += (f - i[2 * e + 1]) * i[2 * e], i[2 * e + 1] = f), d--)
2532
+ }
2533
+ }
2534
+
2535
+ function l(a, b, c) {
2536
+ var d, e, f = new Array(U + 1),
2537
+ g = 0;
2538
+ for (d = 1; U >= d; d++)
2539
+ f[d] = g = g + c[d - 1] << 1;
2540
+ for (e = 0; b >= e; e++) {
2541
+ var h = a[2 * e + 1];
2542
+ 0 !== h && (a[2 * e] = i(f[h]++, h))
2543
+ }
2544
+ }
2545
+
2546
+ function m() {
2547
+ var a, b, c, d, e, f = new Array(U + 1);
2548
+ for (c = 0, d = 0; O - 1 > d; d++)
2549
+ for (ib[d] = c, a = 0; a < 1 << _[d]; a++)
2550
+ hb[c++] = d;
2551
+ for (hb[c - 1] = d, e = 0, d = 0; 16 > d; d++)
2552
+ for (jb[d] = e, a = 0; a < 1 << ab[d]; a++)
2553
+ gb[e++] = d;
2554
+ for (e >>= 7; R > d; d++)
2555
+ for (jb[d] = e << 7, a = 0; a < 1 << ab[d] - 7; a++)
2556
+ gb[256 + e++] = d;
2557
+ for (b = 0; U >= b; b++)
2558
+ f[b] = 0;
2559
+ for (a = 0; 143 >= a; )
2560
+ eb[2 * a + 1] = 8, a++, f[8]++;
2561
+ for (; 255 >= a; )
2562
+ eb[2 * a + 1] = 9, a++, f[9]++;
2563
+ for (; 279 >= a; )
2564
+ eb[2 * a + 1] = 7, a++, f[7]++;
2565
+ for (; 287 >= a; )
2566
+ eb[2 * a + 1] = 8, a++, f[8]++;
2567
+ for (l(eb, Q + 1, f), a = 0; R > a; a++)
2568
+ fb[2 * a + 1] = 5, fb[2 * a] = i(a, 5);
2569
+ kb = new nb(eb, _, P + 1, Q, U), lb = new nb(fb, ab, 0, R, U), mb = new nb(new Array(0), bb, 0, S, W)
2570
+ }
2571
+
2572
+ function n(a) {
2573
+ var b;
2574
+ for (b = 0; Q > b; b++)
2575
+ a.dyn_ltree[2 * b] = 0;
2576
+ for (b = 0; R > b; b++)
2577
+ a.dyn_dtree[2 * b] = 0;
2578
+ for (b = 0; S > b; b++)
2579
+ a.bl_tree[2 * b] = 0;
2580
+ a.dyn_ltree[2 * X] = 1, a.opt_len = a.static_len = 0, a.last_lit = a.matches = 0
2581
+ }
2582
+
2583
+ function o(a) {
2584
+ a.bi_valid > 8 ? f(a, a.bi_buf) : a.bi_valid > 0 && (a.pending_buf[a.pending++] = a.bi_buf), a.bi_buf = 0, a.bi_valid = 0
2585
+ }
2586
+
2587
+ function p(a, b, c, d) {
2588
+ o(a), d && (f(a, c), f(a, ~c)), E.arraySet(a.pending_buf, a.window, b, c, a.pending), a.pending += c
2589
+ }
2590
+
2591
+ function q(a, b, c, d) {
2592
+ var e = 2 * b,
2593
+ f = 2 * c;
2594
+ return a[e] < a[f] || a[e] === a[f] && d[b] <= d[c]
2595
+ }
2596
+
2597
+ function r(a, b, c) {
2598
+ for (var d = a.heap[c], e = c << 1; e <= a.heap_len && (e < a.heap_len && q(b, a.heap[e + 1], a.heap[e], a.depth) && e++, !q(b, d, a.heap[e], a.depth)); )
2599
+ a.heap[c] = a.heap[e], c = e, e <<= 1;
2600
+ a.heap[c] = d
2601
+ }
2602
+
2603
+ function s(a, b, c) {
2604
+ var d, f, i, j, k = 0;
2605
+ if (0 !== a.last_lit)
2606
+ do
2607
+ d = a.pending_buf[a.d_buf + 2 * k] << 8 | a.pending_buf[a.d_buf + 2 * k + 1], f = a.pending_buf[a.l_buf + k], k++, 0 === d ? h(a, f, b) : (i = hb[f], h(a, i + P + 1, b), j = _[i], 0 !== j && (f -= ib[i], g(a, f, j)), d--, i = e(d), h(a, i, c), j = ab[i], 0 !== j && (d -= jb[i], g(a, d, j)));
2608
+ while (k < a.last_lit);
2609
+ h(a, X, b)
2610
+ }
2611
+
2612
+ function t(a, b) {
2613
+ var c, d, e, f = b.dyn_tree,
2614
+ g = b.stat_desc.static_tree,
2615
+ h = b.stat_desc.has_stree,
2616
+ i = b.stat_desc.elems,
2617
+ j = -1;
2618
+ for (a.heap_len = 0, a.heap_max = T, c = 0; i > c; c++)
2619
+ 0 !== f[2 * c] ? (a.heap[++a.heap_len] = j = c, a.depth[c] = 0) : f[2 * c + 1] = 0;
2620
+ for (; a.heap_len < 2; )
2621
+ e = a.heap[++a.heap_len] = 2 > j ? ++j : 0, f[2 * e] = 1, a.depth[e] = 0, a.opt_len--, h && (a.static_len -= g[2 * e + 1]);
2622
+ for (b.max_code = j, c = a.heap_len >> 1; c >= 1; c--)
2623
+ r(a, f, c);
2624
+ e = i;
2625
+ do
2626
+ c = a.heap[1], a.heap[1] = a.heap[a.heap_len--], r(a, f, 1), d = a.heap[1], a.heap[--a.heap_max] = c, a.heap[--a.heap_max] = d, f[2 * e] = f[2 * c] + f[2 * d], a.depth[e] = (a.depth[c] >= a.depth[d] ? a.depth[c] : a.depth[d]) + 1, f[2 * c + 1] = f[2 * d + 1] = e, a.heap[1] = e++, r(a, f, 1);
2627
+ while (a.heap_len >= 2);
2628
+ a.heap[--a.heap_max] = a.heap[1], k(a, b), l(f, j, a.bl_count)
2629
+ }
2630
+
2631
+ function u(a, b, c) {
2632
+ var d, e, f = -1,
2633
+ g = b[1],
2634
+ h = 0,
2635
+ i = 7,
2636
+ j = 4;
2637
+ for (0 === g && (i = 138, j = 3), b[2 * (c + 1) + 1] = 65535, d = 0; c >= d; d++)
2638
+ e = g, g = b[2 * (d + 1) + 1], ++h < i && e === g || (j > h ? a.bl_tree[2 * e] += h : 0 !== e ? (e !== f && a.bl_tree[2 * e]++, a.bl_tree[2 * Y]++) : 10 >= h ? a.bl_tree[2 * Z]++ : a.bl_tree[2 * $]++, h = 0, f = e, 0 === g ? (i = 138, j = 3) : e === g ? (i = 6, j = 3) : (i = 7, j = 4))
2639
+ }
2640
+
2641
+ function v(a, b, c) {
2642
+ var d, e, f = -1,
2643
+ i = b[1],
2644
+ j = 0,
2645
+ k = 7,
2646
+ l = 4;
2647
+ for (0 === i && (k = 138, l = 3), d = 0; c >= d; d++)
2648
+ if (e = i, i = b[2 * (d + 1) + 1], !(++j < k && e === i)) {
2649
+ if (l > j) {
2650
+ do
2651
+ h(a, e, a.bl_tree);
2652
+ while (0 !== --j)
2653
+ } else
2654
+ 0 !== e ? (e !== f && (h(a, e, a.bl_tree), j--), h(a, Y, a.bl_tree), g(a, j - 3, 2)) : 10 >= j ? (h(a, Z, a.bl_tree), g(a, j - 3, 3)) : (h(a, $, a.bl_tree), g(a, j - 11, 7));
2655
+ j = 0, f = e, 0 === i ? (k = 138, l = 3) : e === i ? (k = 6, l = 3) : (k = 7, l = 4)
2656
+ }
2657
+ }
2658
+
2659
+ function w(a) {
2660
+ var b;
2661
+ for (u(a, a.dyn_ltree, a.l_desc.max_code), u(a, a.dyn_dtree, a.d_desc.max_code), t(a, a.bl_desc), b = S - 1; b >= 3 && 0 === a.bl_tree[2 * cb[b] + 1]; b--)
2662
+ ;
2663
+ return a.opt_len += 3 * (b + 1) + 5 + 5 + 4, b
2664
+ }
2665
+
2666
+ function x(a, b, c, d) {
2667
+ var e;
2668
+ for (g(a, b - 257, 5), g(a, c - 1, 5), g(a, d - 4, 4), e = 0; d > e; e++)
2669
+ g(a, a.bl_tree[2 * cb[e] + 1], 3);
2670
+ v(a, a.dyn_ltree, b - 1), v(a, a.dyn_dtree, c - 1)
2671
+ }
2672
+
2673
+ function y(a) {
2674
+ var b, c = 4093624447;
2675
+ for (b = 0; 31 >= b; b++, c >>>= 1)
2676
+ if (1 & c && 0 !== a.dyn_ltree[2 * b])
2677
+ return G;
2678
+ if (0 !== a.dyn_ltree[18] || 0 !== a.dyn_ltree[20] || 0 !== a.dyn_ltree[26])
2679
+ return H;
2680
+ for (b = 32; P > b; b++)
2681
+ if (0 !== a.dyn_ltree[2 * b])
2682
+ return H;
2683
+ return G
2684
+ }
2685
+
2686
+ function z(a) {
2687
+ pb || (m(), pb = !0), a.l_desc = new ob(a.dyn_ltree, kb), a.d_desc = new ob(a.dyn_dtree, lb), a.bl_desc = new ob(a.bl_tree, mb), a.bi_buf = 0, a.bi_valid = 0, n(a)
2688
+ }
2689
+
2690
+ function A(a, b, c, d) {
2691
+ g(a, (J << 1) + (d ? 1 : 0), 3), p(a, b, c, !0)
2692
+ }
2693
+
2694
+ function B(a) {
2695
+ g(a, K << 1, 3), h(a, X, eb), j(a)
2696
+ }
2697
+
2698
+ function C(a, b, c, d) {
2699
+ var e, f, h = 0;
2700
+ a.level > 0 ? (a.strm.data_type === I && (a.strm.data_type = y(a)), t(a, a.l_desc), t(a, a.d_desc), h = w(a), e = a.opt_len + 3 + 7 >>> 3, f = a.static_len + 3 + 7 >>> 3, e >= f && (e = f)) : e = f = c + 5, e >= c + 4 && -1 !== b ? A(a, b, c, d) : a.strategy === F || f === e ? (g(a, (K << 1) + (d ? 1 : 0), 3), s(a, eb, fb)) : (g(a, (L << 1) + (d ? 1 : 0), 3), x(a, a.l_desc.max_code + 1, a.d_desc.max_code + 1, h + 1), s(a, a.dyn_ltree, a.dyn_dtree)), n(a), d && o(a)
2701
+ }
2702
+
2703
+ function D(a, b, c) {
2704
+ return a.pending_buf[a.d_buf + 2 * a.last_lit] = b >>> 8 & 255, a.pending_buf[a.d_buf + 2 * a.last_lit + 1] = 255 & b, a.pending_buf[a.l_buf + a.last_lit] = 255 & c, a.last_lit++, 0 === b ? a.dyn_ltree[2 * c]++ : (a.matches++, b--, a.dyn_ltree[2 * (hb[c] + P + 1)]++, a.dyn_dtree[2 * e(b)]++), a.last_lit === a.lit_bufsize - 1
2705
+ }
2706
+ var E = a("../utils/common"),
2707
+ F = 4,
2708
+ G = 0,
2709
+ H = 1,
2710
+ I = 2,
2711
+ J = 0,
2712
+ K = 1,
2713
+ L = 2,
2714
+ M = 3,
2715
+ N = 258,
2716
+ O = 29,
2717
+ P = 256,
2718
+ Q = P + 1 + O,
2719
+ R = 30,
2720
+ S = 19,
2721
+ T = 2 * Q + 1,
2722
+ U = 15,
2723
+ V = 16,
2724
+ W = 7,
2725
+ X = 256,
2726
+ Y = 16,
2727
+ Z = 17,
2728
+ $ = 18,
2729
+ _ = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0],
2730
+ ab = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13],
2731
+ bb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7],
2732
+ cb = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],
2733
+ db = 512,
2734
+ eb = new Array(2 * (Q + 2));
2735
+ d(eb);
2736
+ var fb = new Array(2 * R);
2737
+ d(fb);
2738
+ var gb = new Array(db);
2739
+ d(gb);
2740
+ var hb = new Array(N - M + 1);
2741
+ d(hb);
2742
+ var ib = new Array(O);
2743
+ d(ib);
2744
+ var jb = new Array(R);
2745
+ d(jb);
2746
+ var kb, lb, mb, nb = function (a, b, c, d, e) {
2747
+ this.static_tree = a, this.extra_bits = b, this.extra_base = c, this.elems = d, this.max_length = e, this.has_stree = a && a.length
2748
+ },
2749
+ ob = function (a, b) {
2750
+ this.dyn_tree = a, this.max_code = 0, this.stat_desc = b
2751
+ },
2752
+ pb = !1;
2753
+ c._tr_init = z, c._tr_stored_block = A, c._tr_flush_block = C, c._tr_tally = D, c._tr_align = B
2754
+ }, {
2755
+ "../utils/common": 27
2756
+ }],
2757
+ 39: [function (a, b) {
2758
+ "use strict";
2759
+
2760
+ function c() {
2761
+ this.input = null, this.next_in = 0, this.avail_in = 0, this.total_in = 0, this.output = null, this.next_out = 0, this.avail_out = 0, this.total_out = 0, this.msg = "", this.state = null, this.data_type = 2, this.adler = 0
2762
+ }
2763
+ b.exports = c
2764
+ }, {}]
2765
+ }, {}, [9])(9)
2766
+ });
assets/global/plugins/icons/icons-lte-ie7.js CHANGED
@@ -6,172 +6,17 @@ window.onload = function () {
6
  el.innerHTML = '<span style="font-family: \'Simple-Line-Icons\'">' + entity + '</span>' + html;
7
  }
8
  var icons = {
9
- 'icon-user-unfollow': '&#xe000;',
10
- 'icon-user-friends': '&#xe001;',
11
- 'icon-user-following': '&#xe002;',
12
- 'icon-user-follow': '&#xe003;',
13
- 'icon-trophy': '&#xe004;',
14
- 'icon-speedometer': '&#xe005;',
15
- 'icon-social-youtube': '&#xe006;',
16
- 'icon-social-twitter': '&#xe007;',
17
- 'icon-social-tumblr': '&#xe008;',
18
- 'icon-social-facebook': '&#xe009;',
19
- 'icon-social-dropbox': '&#xe00a;',
20
- 'icon-social-dribbble': '&#xe00b;',
21
- 'icon-shield': '&#xe00c;',
22
- 'icon-screen-tablet': '&#xe00d;',
23
- 'icon-screen-smartphone': '&#xe00e;',
24
- 'icon-screen-desktop': '&#xe00f;',
25
- 'icon-plane': '&#xe010;',
26
- 'icon-notebook': '&#xe011;',
27
- 'icon-moustache': '&#xe012;',
28
- 'icon-mouse': '&#xe013;',
29
- 'icon-magnet': '&#xe014;',
30
- 'icon-magic-wand': '&#xe015;',
31
- 'icon-hourglass': '&#xe016;',
32
- 'icon-graduation': '&#xe017;',
33
- 'icon-ghost': '&#xe018;',
34
- 'icon-game-controller': '&#xe019;',
35
- 'icon-fire': '&#xe01a;',
36
- 'icon-eyeglasses': '&#xe01b;',
37
- 'icon-envelope-open': '&#xe01c;',
38
- 'icon-envelope-letter': '&#xe01d;',
39
- 'icon-energy': '&#xe01e;',
40
- 'icon-emoticon-smile': '&#xe01f;',
41
- 'icon-disc': '&#xe020;',
42
- 'icon-cursor-move': '&#xe021;',
43
- 'icon-crop': '&#xe022;',
44
- 'icon-credit-card': '&#xe023;',
45
- 'icon-chemistry': '&#xe024;',
46
- 'icon-bell': '&#xe025;',
47
- 'icon-badge': '&#xe026;',
48
- 'icon-anchor': '&#xe027;',
49
- 'icon-action-redo': '&#xe028;',
50
- 'icon-action-undo': '&#xe029;',
51
- 'icon-bag': '&#xe02a;',
52
- 'icon-basket': '&#xe02b;',
53
- 'icon-basket-loaded': '&#xe02c;',
54
- 'icon-book-open': '&#xe02d;',
55
- 'icon-briefcase': '&#xe02e;',
56
- 'icon-bubbles': '&#xe02f;',
57
- 'icon-calculator': '&#xe030;',
58
- 'icon-call-end': '&#xe031;',
59
- 'icon-call-in': '&#xe032;',
60
- 'icon-call-out': '&#xe033;',
61
- 'icon-compass': '&#xe034;',
62
- 'icon-cup': '&#xe035;',
63
- 'icon-diamond': '&#xe036;',
64
- 'icon-direction': '&#xe037;',
65
- 'icon-directions': '&#xe038;',
66
- 'icon-docs': '&#xe039;',
67
- 'icon-drawer': '&#xe03a;',
68
- 'icon-drop': '&#xe03b;',
69
- 'icon-earphones': '&#xe03c;',
70
- 'icon-earphones-alt': '&#xe03d;',
71
- 'icon-feed': '&#xe03e;',
72
- 'icon-film': '&#xe03f;',
73
- 'icon-folder-alt': '&#xe040;',
74
- 'icon-frame': '&#xe041;',
75
- 'icon-globe': '&#xe042;',
76
- 'icon-globe-alt': '&#xe043;',
77
- 'icon-handbag': '&#xe044;',
78
- 'icon-layers': '&#xe045;',
79
- 'icon-map': '&#xe046;',
80
- 'icon-picture': '&#xe047;',
81
- 'icon-pin': '&#xe048;',
82
- 'icon-playlist': '&#xe049;',
83
- 'icon-present': '&#xe04a;',
84
- 'icon-printer': '&#xe04b;',
85
- 'icon-puzzle': '&#xe04c;',
86
- 'icon-speech': '&#xe04d;',
87
- 'icon-vector': '&#xe04e;',
88
- 'icon-wallet': '&#xe04f;',
89
- 'icon-arrow-down': '&#xe050;',
90
- 'icon-arrow-left': '&#xe051;',
91
- 'icon-arrow-right': '&#xe052;',
92
- 'icon-arrow-up': '&#xe053;',
93
- 'icon-bar-chart': '&#xe054;',
94
- 'icon-bulb': '&#xe055;',
95
- 'icon-calendar': '&#xe056;',
96
- 'icon-control-end': '&#xe057;',
97
- 'icon-control-forward': '&#xe058;',
98
- 'icon-control-pause': '&#xe059;',
99
- 'icon-control-play': '&#xe05a;',
100
- 'icon-control-rewind': '&#xe05b;',
101
- 'icon-control-start': '&#xe05c;',
102
- 'icon-cursor': '&#xe05d;',
103
- 'icon-dislike': '&#xe05e;',
104
- 'icon-equalizer': '&#xe05f;',
105
- 'icon-graph': '&#xe060;',
106
- 'icon-grid': '&#xe061;',
107
- 'icon-home': '&#xe062;',
108
- 'icon-like': '&#xe063;',
109
- 'icon-list': '&#xe064;',
110
- 'icon-login': '&#xe065;',
111
- 'icon-logout': '&#xe066;',
112
- 'icon-loop': '&#xe067;',
113
- 'icon-microphone': '&#xe068;',
114
- 'icon-music-tone': '&#xe069;',
115
- 'icon-music-tone-alt': '&#xe06a;',
116
- 'icon-note': '&#xe06b;',
117
- 'icon-pencil': '&#xe06c;',
118
- 'icon-pie-chart': '&#xe06d;',
119
- 'icon-question': '&#xe06e;',
120
- 'icon-rocket': '&#xe06f;',
121
- 'icon-share': '&#xe070;',
122
- 'icon-share-alt': '&#xe071;',
123
- 'icon-shuffle': '&#xe072;',
124
- 'icon-size-actual': '&#xe073;',
125
- 'icon-size-fullscreen': '&#xe074;',
126
- 'icon-support': '&#xe075;',
127
- 'icon-tag': '&#xe076;',
128
- 'icon-trash': '&#xe077;',
129
- 'icon-umbrella': '&#xe078;',
130
- 'icon-wrench': '&#xe079;',
131
- 'icon-ban': '&#xe07a;',
132
- 'icon-bubble': '&#xe07b;',
133
- 'icon-camcorder': '&#xe07c;',
134
- 'icon-camera': '&#xe07d;',
135
- 'icon-check': '&#xe07e;',
136
- 'icon-clock': '&#xe07f;',
137
- 'icon-close': '&#xe080;',
138
- 'icon-cloud-download': '&#xe081;',
139
- 'icon-cloud-upload': '&#xe082;',
140
- 'icon-doc': '&#xe083;',
141
- 'icon-envelope': '&#xe084;',
142
- 'icon-eye': '&#xe085;',
143
- 'icon-flag': '&#xe086;',
144
- 'icon-folder': '&#xe087;',
145
- 'icon-heart': '&#xe088;',
146
- 'icon-info': '&#xe089;',
147
- 'icon-key': '&#xe08a;',
148
- 'icon-link': '&#xe08b;',
149
- 'icon-lock': '&#xe08c;',
150
- 'icon-lock-open': '&#xe08d;',
151
- 'icon-magnifier': '&#xe08e;',
152
- 'icon-magnifier-add': '&#xe08f;',
153
- 'icon-magnifier-remove': '&#xe090;',
154
- 'icon-paper-clip': '&#xe091;',
155
- 'icon-paper-plane': '&#xe092;',
156
- 'icon-plus': '&#xe093;',
157
- 'icon-pointer': '&#xe094;',
158
- 'icon-power': '&#xe095;',
159
- 'icon-refresh': '&#xe096;',
160
- 'icon-reload': '&#xe097;',
161
- 'icon-settings': '&#xe098;',
162
- 'icon-star': '&#xe099;',
163
- 'icon-symbol-female': '&#xe09a;',
164
- 'icon-symbol-male': '&#xe09b;',
165
- 'icon-target': '&#xe09c;',
166
- 'icon-user-female': '&#xe09d;',
167
- 'icon-user-male': '&#xe09e;',
168
- 'icon-volume-1': '&#xe09f;',
169
- 'icon-volume-2': '&#xe0a0;',
170
- 'icon-volume-off': '&#xe0a1;'
171
- },
172
  els = document.getElementsByTagName('*'),
173
- i, attr, c, el;
174
- for (i = 0; ; i += 1) {
 
 
 
 
 
175
  el = els[i];
176
  if (!el) {
177
  break;
6
  el.innerHTML = '<span style="font-family: \'Simple-Line-Icons\'">' + entity + '</span>' + html;
7
  }
8
  var icons = {
9
+ 'icon-user-unfollow': '&#xe000;', 'icon-user-friends': '&#xe001;', 'icon-user-following': '&#xe002;', 'icon-user-follow': '&#xe003;', 'icon-trophy': '&#xe004;', 'icon-speedometer': '&#xe005;', 'icon-social-youtube': '&#xe006;', 'icon-social-twitter': '&#xe007;', 'icon-social-tumblr': '&#xe008;', 'icon-social-facebook': '&#xe009;', 'icon-social-dropbox': '&#xe00a;', 'icon-social-dribbble': '&#xe00b;', 'icon-shield': '&#xe00c;', 'icon-screen-tablet': '&#xe00d;', 'icon-screen-smartphone': '&#xe00e;', 'icon-screen-desktop': '&#xe00f;', 'icon-plane': '&#xe010;', 'icon-notebook': '&#xe011;', 'icon-moustache': '&#xe012;', 'icon-mouse': '&#xe013;', 'icon-magnet': '&#xe014;', 'icon-magic-wand': '&#xe015;', 'icon-hourglass': '&#xe016;', 'icon-graduation': '&#xe017;', 'icon-ghost': '&#xe018;', 'icon-game-controller': '&#xe019;', 'icon-fire': '&#xe01a;', 'icon-eyeglasses': '&#xe01b;', 'icon-envelope-open': '&#xe01c;', 'icon-envelope-letter': '&#xe01d;', 'icon-energy': '&#xe01e;', 'icon-emoticon-smile': '&#xe01f;', 'icon-disc': '&#xe020;', 'icon-cursor-move': '&#xe021;', 'icon-crop': '&#xe022;', 'icon-credit-card': '&#xe023;', 'icon-chemistry': '&#xe024;', 'icon-bell': '&#xe025;', 'icon-badge': '&#xe026;', 'icon-anchor': '&#xe027;', 'icon-action-redo': '&#xe028;', 'icon-action-undo': '&#xe029;', 'icon-bag': '&#xe02a;', 'icon-basket': '&#xe02b;', 'icon-basket-loaded': '&#xe02c;', 'icon-book-open': '&#xe02d;', 'icon-briefcase': '&#xe02e;', 'icon-bubbles': '&#xe02f;', 'icon-calculator': '&#xe030;', 'icon-call-end': '&#xe031;', 'icon-call-in': '&#xe032;', 'icon-call-out': '&#xe033;', 'icon-compass': '&#xe034;', 'icon-cup': '&#xe035;', 'icon-diamond': '&#xe036;', 'icon-direction': '&#xe037;', 'icon-directions': '&#xe038;', 'icon-docs': '&#xe039;', 'icon-drawer': '&#xe03a;', 'icon-drop': '&#xe03b;', 'icon-earphones': '&#xe03c;', 'icon-earphones-alt': '&#xe03d;', 'icon-feed': '&#xe03e;', 'icon-film': '&#xe03f;', 'icon-folder-alt': '&#xe040;', 'icon-frame': '&#xe041;', 'icon-globe': '&#xe042;', 'icon-globe-alt': '&#xe043;', 'icon-handbag': '&#xe044;', 'icon-layers': '&#xe045;', 'icon-map': '&#xe046;', 'icon-picture': '&#xe047;', 'icon-pin': '&#xe048;', 'icon-playlist': '&#xe049;', 'icon-present': '&#xe04a;', 'icon-printer': '&#xe04b;', 'icon-puzzle': '&#xe04c;', 'icon-speech': '&#xe04d;', 'icon-vector': '&#xe04e;', 'icon-wallet': '&#xe04f;', 'icon-arrow-down': '&#xe050;', 'icon-arrow-left': '&#xe051;', 'icon-arrow-right': '&#xe052;', 'icon-arrow-up': '&#xe053;', 'icon-bar-chart': '&#xe054;', 'icon-bulb': '&#xe055;', 'icon-calendar': '&#xe056;', 'icon-control-end': '&#xe057;', 'icon-control-forward': '&#xe058;', 'icon-control-pause': '&#xe059;', 'icon-control-play': '&#xe05a;', 'icon-control-rewind': '&#xe05b;', 'icon-control-start': '&#xe05c;', 'icon-cursor': '&#xe05d;', 'icon-dislike': '&#xe05e;', 'icon-equalizer': '&#xe05f;', 'icon-graph': '&#xe060;', 'icon-grid': '&#xe061;', 'icon-home': '&#xe062;', 'icon-like': '&#xe063;', 'icon-list': '&#xe064;', 'icon-login': '&#xe065;', 'icon-logout': '&#xe066;', 'icon-loop': '&#xe067;', 'icon-microphone': '&#xe068;', 'icon-music-tone': '&#xe069;', 'icon-music-tone-alt': '&#xe06a;', 'icon-note': '&#xe06b;', 'icon-pencil': '&#xe06c;', 'icon-pie-chart': '&#xe06d;', 'icon-question': '&#xe06e;', 'icon-rocket': '&#xe06f;', 'icon-share': '&#xe070;', 'icon-share-alt': '&#xe071;', 'icon-shuffle': '&#xe072;', 'icon-size-actual': '&#xe073;', 'icon-size-fullscreen': '&#xe074;', 'icon-support': '&#xe075;', 'icon-tag': '&#xe076;', 'icon-trash': '&#xe077;', 'icon-umbrella': '&#xe078;', 'icon-wrench': '&#xe079;', 'icon-ban': '&#xe07a;', 'icon-bubble': '&#xe07b;', 'icon-camcorder': '&#xe07c;', 'icon-camera': '&#xe07d;', 'icon-check': '&#xe07e;', 'icon-clock': '&#xe07f;', 'icon-close': '&#xe080;', 'icon-cloud-download': '&#xe081;', 'icon-cloud-upload': '&#xe082;', 'icon-doc': '&#xe083;', 'icon-envelope': '&#xe084;', 'icon-eye': '&#xe085;', 'icon-flag': '&#xe086;', 'icon-folder': '&#xe087;', 'icon-heart': '&#xe088;', 'icon-info': '&#xe089;', 'icon-key': '&#xe08a;', 'icon-link': '&#xe08b;', 'icon-lock': '&#xe08c;', 'icon-lock-open': '&#xe08d;', 'icon-magnifier': '&#xe08e;', 'icon-magnifier-add': '&#xe08f;', 'icon-magnifier-remove': '&#xe090;', 'icon-paper-clip': '&#xe091;', 'icon-paper-plane': '&#xe092;', 'icon-plus': '&#xe093;', 'icon-pointer': '&#xe094;', 'icon-power': '&#xe095;', 'icon-refresh': '&#xe096;', 'icon-reload': '&#xe097;', 'icon-settings': '&#xe098;', 'icon-star': '&#xe099;', 'icon-symbol-female': '&#xe09a;', 'icon-symbol-male': '&#xe09b;', 'icon-target': '&#xe09c;', 'icon-user-female': '&#xe09d;', 'icon-user-male': '&#xe09e;', 'icon-volume-1': '&#xe09f;', 'icon-volume-2': '&#xe0a0;', 'icon-volume-off': '&#xe0a1;'
10
+ }
11
+ ,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  els = document.getElementsByTagName('*'),
13
+ i,
14
+ attr,
15
+ c,
16
+ el;
17
+ for (i = 0;
18
+ ;
19
+ i += 1) {
20
  el = els[i];
21
  if (!el) {
22
  break;
assets/global/plugins/icons/icons.css CHANGED
@@ -1,16 +1,13 @@
1
- @font-face
2
- {
3
  font-family: 'Simple-Line-Icons';
4
- src:url('fonts/icons.eot');
5
- src:url('fonts/icons.eot?#iefix') format('embedded-opentype'),
6
- url('fonts/icons.woff') format('woff'),
7
- url('fonts/icons.ttf') format('truetype'),
8
- url('fonts/icons.svg#Simple-Line-Icons') format('svg');
9
  font-weight: normal;
10
  font-style: normal;
11
  }
12
- [class^="icon-custom"]::before, [class*=" icon-custom"]::before
13
- {
 
14
  font-style: normal;
15
  font-weight: normal;
16
  display: inline-block;
@@ -24,17 +21,18 @@
24
  margin-left: 0.2em;
25
  font-family: "Simple-Line-Icons" !important;
26
  }
27
- @media screen and (-webkit-min-device-pixel-ratio:0)
28
- {
29
- @font-face
30
- {
31
  font-family: 'Simple-Line-Icons';
32
  src: url('fonts/icons.svg#Simple-Line-Icons') format('svg');
33
  }
34
  }
 
 
35
  /* Use the following CSS code if you want to use data attributes for inserting your icons */
36
- [data-icon]:before
37
- {
38
  font-family: 'Simple-Line-Icons';
39
  content: attr(data-icon);
40
  speak: none;
@@ -45,14 +43,179 @@
45
  -webkit-font-smoothing: antialiased;
46
  -moz-osx-font-smoothing: grayscale;
47
  }
 
 
48
  /* Use the following CSS code if you want to have a class per icon */
 
 
49
  /*
50
  Instead of a list of all class selectors,
51
  you can use the generic selector below, but it's slower:
52
  [class*="icon-"] {
53
  */
54
- .icon-custom-user-female, .icon-custom-user-follow, .icon-custom-user-following, .icon-custom-user-unfollow, .icon-custom-trophy, .icon-custom-screen-smartphone, .icon-custom-screen-desktop, .icon-custom-plane, .icon-custom-notebook, .icon-custom-moustache, .icon-custom-mouse, .icon-custom-magnet, .icon-custom-energy, .icon-custom-emoticon-custom-smile, .icon-custom-disc, .icon-custom-cursor-move, .icon-custom-crop, .icon-custom-credit-card, .icon-custom-chemistry, .icon-custom-user, .icon-custom-speedometer, .icon-custom-social-youtube, .icon-custom-social-twitter, .icon-custom-social-tumblr, .icon-custom-social-facebook, .icon-custom-social-dropbox, .icon-custom-social-dribbble, .icon-custom-shield, .icon-custom-screen-tablet, .icon-custom-magic-wand, .icon-custom-hourglass, .icon-custom-graduation, .icon-custom-ghost, .icon-custom-game-controller, .icon-custom-fire, .icon-custom-eyeglasses, .icon-custom-envelope-open, .icon-custom-envelope-letter, .icon-custom-bell, .icon-custom-badge, .icon-custom-anchor, .icon-custom-wallet, .icon-custom-vector, .icon-custom-speech, .icon-custom-puzzle, .icon-custom-printer, .icon-custom-present, .icon-custom-playlist, .icon-custom-pin, .icon-custom-picture, .icon-custom-map, .icon-custom-layers, .icon-custom-handbag, .icon-custom-globe-alt, .icon-custom-globe, .icon-custom-frame, .icon-custom-folder-alt, .icon-custom-film, .icon-custom-feed, .icon-custom-earphones-alt, .icon-custom-earphones, .icon-custom-drop, .icon-custom-drawer, .icon-custom-docs, .icon-custom-directions, .icon-custom-direction, .icon-custom-diamond, .icon-custom-cup, .icon-custom-compass, .icon-custom-call-out, .icon-custom-call-in, .icon-custom-call-end, .icon-custom-calculator, .icon-custom-bubbles, .icon-custom-briefcase, .icon-custom-book-open, .icon-custom-basket-loaded, .icon-custom-basket, .icon-custom-bag, .icon-custom-action-undo, .icon-custom-action-redo, .icon-custom-wrench, .icon-custom-umbrella, .icon-custom-trash, .icon-custom-tag, .icon-custom-support, .icon-custom-size-fullscreen, .icon-custom-size-actual, .icon-custom-shuffle, .icon-custom-share-alt, .icon-custom-share, .icon-custom-rocket, .icon-custom-question, .icon-custom-pie-chart, .icon-custom-pencil, .icon-custom-note, .icon-custom-music-tone-alt, .icon-custom-music-tone, .icon-custom-microphone, .icon-custom-loop, .icon-custom-logout, .icon-custom-login, .icon-custom-list, .icon-custom-like, .icon-custom-home, .icon-custom-grid, .icon-custom-graph, .icon-custom-equalizer, .icon-custom-dislike, .icon-custom-cursor, .icon-custom-control-start, .icon-custom-control-rewind, .icon-custom-control-play, .icon-custom-control-pause, .icon-custom-control-forward, .icon-custom-control-end, .icon-custom-calendar, .icon-custom-bulb, .icon-custom-bar-chart, .icon-custom-arrow-up, .icon-custom-arrow-right, .icon-custom-arrow-left, .icon-custom-arrow-down, .icon-custom-ban, .icon-custom-bubble, .icon-custom-camcorder, .icon-custom-camera, .icon-custom-check, .icon-custom-clock, .icon-custom-close, .icon-custom-cloud-download, .icon-custom-cloud-upload, .icon-custom-doc, .icon-custom-envelope, .icon-custom-eye, .icon-custom-flag, .icon-custom-folder, .icon-custom-heart, .icon-custom-info, .icon-custom-key, .icon-custom-link, .icon-custom-lock, .icon-custom-lock-open, .icon-custom-magnifier, .icon-custom-magnifier-add, .icon-custom-magnifier-remove, .icon-custom-paper-clip, .icon-custom-paper-plane, .icon-custom-plus, .icon-custom-pointer, .icon-custom-power, .icon-custom-refresh, .icon-custom-reload, .icon-custom-settings, .icon-custom-star, .icon-custom-symbol-female, .icon-custom-symbol-male, .icon-custom-target, .icon-custom-volume-1, .icon-custom-volume-2, .icon-custom-volume-off, .icon-custom-users
55
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  font-family: 'Simple-Line-icon';
57
  speak: none;
58
  font-style: normal;
@@ -62,651 +225,651 @@ you can use the generic selector below, but it's slower:
62
  line-height: 1;
63
  -webkit-font-smoothing: antialiased;
64
  }
65
- .icon-custom-user-female:before
66
- {
67
  content: "\e000";
68
  }
69
- .icon-custom-user-follow:before
70
- {
71
  content: "\e002";
72
  }
73
- .icon-custom-user-following:before
74
- {
75
  content: "\e003";
76
  }
77
- .icon-custom-user-unfollow:before
78
- {
79
  content: "\e004";
80
  }
81
- .icon-custom-trophy:before
82
- {
83
  content: "\e006";
84
  }
85
- .icon-custom-screen-smartphone:before
86
- {
87
  content: "\e010";
88
  }
89
- .icon-custom-screen-desktop:before
90
- {
91
  content: "\e011";
92
  }
93
- .icon-custom-plane:before
94
- {
95
  content: "\e012";
96
  }
97
- .icon-custom-notebook:before
98
- {
99
  content: "\e013";
100
  }
101
- .icon-custom-moustache:before
102
- {
103
  content: "\e014";
104
  }
105
- .icon-custom-mouse:before
106
- {
107
  content: "\e015";
108
  }
109
- .icon-custom-magnet:before
110
- {
111
  content: "\e016";
112
  }
113
- .icon-custom-energy:before
114
- {
115
  content: "\e020";
116
  }
117
- .icon-custom-emoticon-custom-smile:before
118
- {
119
  content: "\e021";
120
  }
121
- .icon-custom-disc:before
122
- {
123
  content: "\e022";
124
  }
125
- .icon-custom-cursor-move:before
126
- {
127
  content: "\e023";
128
  }
129
- .icon-custom-crop:before
130
- {
131
  content: "\e024";
132
  }
133
- .icon-custom-credit-card:before
134
- {
135
  content: "\e025";
136
  }
137
- .icon-custom-chemistry:before
138
- {
139
  content: "\e026";
140
  }
141
- .icon-custom-user:before
142
- {
143
  content: "\e005";
144
  }
145
- .icon-custom-speedometer:before
146
- {
147
  content: "\e007";
148
  }
149
- .icon-custom-social-youtube:before
150
- {
151
  content: "\e008";
152
  }
153
- .icon-custom-social-twitter:before
154
- {
155
  content: "\e009";
156
  }
157
- .icon-custom-social-tumblr:before
158
- {
159
  content: "\e00a";
160
  }
161
- .icon-custom-social-facebook:before
162
- {
163
  content: "\e00b";
164
  }
165
- .icon-custom-social-dropbox:before
166
- {
167
  content: "\e00c";
168
  }
169
- .icon-custom-social-dribbble:before
170
- {
171
  content: "\e00d";
172
  }
173
- .icon-custom-shield:before
174
- {
175
  content: "\e00e";
176
  }
177
- .icon-custom-screen-tablet:before
178
- {
179
  content: "\e00f";
180
  }
181
- .icon-custom-magic-wand:before
182
- {
183
  content: "\e017";
184
  }
185
- .icon-custom-hourglass:before
186
- {
187
  content: "\e018";
188
  }
189
- .icon-custom-graduation:before
190
- {
191
  content: "\e019";
192
  }
193
- .icon-custom-ghost:before
194
- {
195
  content: "\e01a";
196
  }
197
- .icon-custom-game-controller:before
198
- {
199
  content: "\e01b";
200
  }
201
- .icon-custom-fire:before
202
- {
203
  content: "\e01c";
204
  }
205
- .icon-custom-eyeglasses:before
206
- {
207
  content: "\e01d";
208
  }
209
- .icon-custom-envelope-open:before
210
- {
211
  content: "\e01e";
212
  }
213
- .icon-custom-envelope-letter:before
214
- {
215
  content: "\e01f";
216
  }
217
- .icon-custom-bell:before
218
- {
219
  content: "\e027";
220
  }
221
- .icon-custom-badge:before
222
- {
223
  content: "\e028";
224
  }
225
- .icon-custom-anchor:before
226
- {
227
  content: "\e029";
228
  }
229
- .icon-custom-wallet:before
230
- {
231
  content: "\e02a";
232
  }
233
- .icon-custom-vector:before
234
- {
235
  content: "\e02b";
236
  }
237
- .icon-custom-speech:before
238
- {
239
  content: "\e02c";
240
  }
241
- .icon-custom-puzzle:before
242
- {
243
  content: "\e02d";
244
  }
245
- .icon-custom-printer:before
246
- {
247
  content: "\e02e";
248
  }
249
- .icon-custom-present:before
250
- {
251
  content: "\e02f";
252
  }
253
- .icon-custom-playlist:before
254
- {
255
  content: "\e030";
256
  }
257
- .icon-custom-pin:before
258
- {
259
  content: "\e031";
260
  }
261
- .icon-custom-picture:before
262
- {
263
  content: "\e032";
264
  }
265
- .icon-custom-map:before
266
- {
267
  content: "\e033";
268
  }
269
- .icon-custom-layers:before
270
- {
271
  content: "\e034";
272
  }
273
- .icon-custom-handbag:before
274
- {
275
  content: "\e035";
276
  }
277
- .icon-custom-globe-alt:before
278
- {
279
  content: "\e036";
280
  }
281
- .icon-custom-globe:before
282
- {
283
  content: "\e037";
284
  }
285
- .icon-custom-frame:before
286
- {
287
  content: "\e038";
288
  }
289
- .icon-custom-folder-alt:before
290
- {
291
  content: "\e039";
292
  }
293
- .icon-custom-film:before
294
- {
295
  content: "\e03a";
296
  }
297
- .icon-custom-feed:before
298
- {
299
  content: "\e03b";
300
  }
301
- .icon-custom-earphones-alt:before
302
- {
303
  content: "\e03c";
304
  }
305
- .icon-custom-earphones:before
306
- {
307
  content: "\e03d";
308
  }
309
- .icon-custom-drop:before
310
- {
311
  content: "\e03e";
312
  }
313
- .icon-custom-drawer:before
314
- {
315
  content: "\e03f";
316
  }
317
- .icon-custom-docs:before
318
- {
319
  content: "\e040";
320
  }
321
- .icon-custom-directions:before
322
- {
323
  content: "\e041";
324
  }
325
- .icon-custom-direction:before
326
- {
327
  content: "\e042";
328
  }
329
- .icon-custom-diamond:before
330
- {
331
  content: "\e043";
332
  }
333
- .icon-custom-cup:before
334
- {
335
  content: "\e044";
336
  }
337
- .icon-custom-compass:before
338
- {
339
  content: "\e045";
340
  }
341
- .icon-custom-call-out:before
342
- {
343
  content: "\e046";
344
  }
345
- .icon-custom-call-in:before
346
- {
347
  content: "\e047";
348
  }
349
- .icon-custom-call-end:before
350
- {
351
  content: "\e048";
352
  }
353
- .icon-custom-calculator:before
354
- {
355
  content: "\e049";
356
  }
357
- .icon-custom-bubbles:before
358
- {
359
  content: "\e04a";
360
  }
361
- .icon-custom-briefcase:before
362
- {
363
  content: "\e04b";
364
  }
365
- .icon-custom-book-open:before
366
- {
367
  content: "\e04c";
368
  }
369
- .icon-custom-basket-loaded:before
370
- {
371
  content: "\e04d";
372
  }
373
- .icon-custom-basket:before
374
- {
375
  content: "\e04e";
376
  }
377
- .icon-custom-bag:before
378
- {
379
  content: "\e04f";
380
  }
381
- .icon-custom-action-undo:before
382
- {
383
  content: "\e050";
384
  }
385
- .icon-custom-action-redo:before
386
- {
387
  content: "\e051";
388
  }
389
- .icon-custom-wrench:before
390
- {
391
  content: "\e052";
392
  }
393
- .icon-custom-umbrella:before
394
- {
395
  content: "\e053";
396
  }
397
- .icon-custom-trash:before
398
- {
399
  content: "\e054";
400
  }
401
- .icon-custom-tag:before
402
- {
403
  content: "\e055";
404
  }
405
- .icon-custom-support:before
406
- {
407
  content: "\e056";
408
  }
409
- .icon-custom-size-fullscreen:before
410
- {
411
  content: "\e057";
412
  }
413
- .icon-custom-size-actual:before
414
- {
415
  content: "\e058";
416
  }
417
- .icon-custom-shuffle:before
418
- {
419
  content: "\e059";
420
  }
421
- .icon-custom-share-alt:before
422
- {
423
  content: "\e05a";
424
  }
425
- .icon-custom-share:before
426
- {
427
  content: "\e05b";
428
  }
429
- .icon-custom-rocket:before
430
- {
431
  content: "\e05c";
432
  }
433
- .icon-custom-question:before
434
- {
435
  content: "\e05d";
436
  }
437
- .icon-custom-pie-chart:before
438
- {
439
  content: "\e05e";
440
  }
441
- .icon-custom-pencil:before
442
- {
443
  content: "\e05f";
444
  }
445
- .icon-custom-note:before
446
- {
447
  content: "\e060";
448
  }
449
- .icon-custom-music-tone-alt:before
450
- {
451
  content: "\e061";
452
  }
453
- .icon-custom-music-tone:before
454
- {
455
  content: "\e062";
456
  }
457
- .icon-custom-microphone:before
458
- {
459
  content: "\e063";
460
  }
461
- .icon-custom-loop:before
462
- {
463
  content: "\e064";
464
  }
465
- .icon-custom-logout:before
466
- {
467
  content: "\e065";
468
  }
469
- .icon-custom-login:before
470
- {
471
  content: "\e066";
472
  }
473
- .icon-custom-list:before
474
- {
475
  content: "\e067";
476
  }
477
- .icon-custom-like:before
478
- {
479
  content: "\e068";
480
  }
481
- .icon-custom-home:before
482
- {
483
  content: "\e069";
484
  }
485
- .icon-custom-grid:before
486
- {
487
  content: "\e06a";
488
  }
489
- .icon-custom-graph:before
490
- {
491
  content: "\e06b";
492
  }
493
- .icon-custom-equalizer:before
494
- {
495
  content: "\e06c";
496
  }
497
- .icon-custom-dislike:before
498
- {
499
  content: "\e06d";
500
  }
501
- .icon-custom-cursor:before
502
- {
503
  content: "\e06e";
504
  }
505
- .icon-custom-control-start:before
506
- {
507
  content: "\e06f";
508
  }
509
- .icon-custom-control-rewind:before
510
- {
511
  content: "\e070";
512
  }
513
- .icon-custom-control-play:before
514
- {
515
  content: "\e071";
516
  }
517
- .icon-custom-control-pause:before
518
- {
519
  content: "\e072";
520
  }
521
- .icon-custom-control-forward:before
522
- {
523
  content: "\e073";
524
  }
525
- .icon-custom-control-end:before
526
- {
527
  content: "\e074";
528
  }
529
- .icon-custom-calendar:before
530
- {
531
  content: "\e075";
532
  }
533
- .icon-custom-bulb:before
534
- {
535
  content: "\e076";
536
  }
537
- .icon-custom-bar-chart:before
538
- {
539
  content: "\e077";
540
  }
541
- .icon-custom-arrow-up:before
542
- {
543
  content: "\e078";
544
  }
545
- .icon-custom-arrow-right:before
546
- {
547
  content: "\e079";
548
  }
549
- .icon-custom-arrow-left:before
550
- {
551
  content: "\e07a";
552
  }
553
- .icon-custom-arrow-down:before
554
- {
555
  content: "\e07b";
556
  }
557
- .icon-custom-ban:before
558
- {
559
  content: "\e07c";
560
  }
561
- .icon-custom-bubble:before
562
- {
563
  content: "\e07d";
564
  }
565
- .icon-custom-camcorder:before
566
- {
567
  content: "\e07e";
568
  }
569
- .icon-custom-camera:before
570
- {
571
  content: "\e07f";
572
  }
573
- .icon-custom-check:before
574
- {
575
  content: "\e080";
576
  }
577
- .icon-custom-clock:before
578
- {
579
  content: "\e081";
580
  }
581
- .icon-custom-close:before
582
- {
583
  content: "\e082";
584
  }
585
- .icon-custom-cloud-download:before
586
- {
587
  content: "\e083";
588
  }
589
- .icon-custom-cloud-upload:before
590
- {
591
  content: "\e084";
592
  }
593
- .icon-custom-doc:before
594
- {
595
  content: "\e085";
596
  }
597
- .icon-custom-envelope:before
598
- {
599
  content: "\e086";
600
  }
601
- .icon-custom-eye:before
602
- {
603
  content: "\e087";
604
  }
605
- .icon-custom-flag:before
606
- {
607
  content: "\e088";
608
  }
609
- .icon-custom-folder:before
610
- {
611
  content: "\e089";
612
  }
613
- .icon-custom-heart:before
614
- {
615
  content: "\e08a";
616
  }
617
- .icon-custom-info:before
618
- {
619
  content: "\e08b";
620
  }
621
- .icon-custom-key:before
622
- {
623
  content: "\e08c";
624
  }
625
- .icon-custom-link:before
626
- {
627
  content: "\e08d";
628
  }
629
- .icon-custom-lock:before
630
- {
631
  content: "\e08e";
632
  }
633
- .icon-custom-lock-open:before
634
- {
635
  content: "\e08f";
636
  }
637
- .icon-custom-magnifier:before
638
- {
639
  content: "\e090";
640
  }
641
- .icon-custom-magnifier-add:before
642
- {
643
  content: "\e091";
644
  }
645
- .icon-custom-magnifier-remove:before
646
- {
647
  content: "\e092";
648
  }
649
- .icon-custom-paper-clip:before
650
- {
651
  content: "\e093";
652
  }
653
- .icon-custom-paper-plane:before
654
- {
655
  content: "\e094";
656
  }
657
- .icon-custom-plus:before
658
- {
659
  content: "\e095";
660
  }
661
- .icon-custom-pointer:before
662
- {
663
  content: "\e096";
664
  }
665
- .icon-custom-power:before
666
- {
667
  content: "\e097";
668
  }
669
- .icon-custom-refresh:before
670
- {
671
  content: "\e098";
672
  }
673
- .icon-custom-reload:before
674
- {
675
  content: "\e099";
676
  }
677
- .icon-custom-settings:before
678
- {
679
  content: "\e09a";
680
  }
681
- .icon-custom-star:before
682
- {
683
  content: "\e09b";
684
  }
685
- .icon-custom-symbol-female:before
686
- {
687
  content: "\e09c";
688
  }
689
- .icon-custom-symbol-male:before
690
- {
691
  content: "\e09d";
692
  }
693
- .icon-custom-target:before
694
- {
695
  content: "\e09e";
696
  }
697
- .icon-custom-volume-1:before
698
- {
699
  content: "\e09f";
700
  }
701
- .icon-custom-volume-2:before
702
- {
703
  content: "\e0a0";
704
  }
705
- .icon-custom-volume-off:before
706
- {
707
  content: "\e0a1";
708
  }
709
- .icon-custom-users:before
710
- {
711
  content: "\e001";
712
- }
1
+ @font-face {
 
2
  font-family: 'Simple-Line-Icons';
3
+ src: url('fonts/icons.eot');
4
+ src: url('fonts/icons.eot?#iefix') format('embedded-opentype'), url('fonts/icons.woff') format('woff'), url('fonts/icons.ttf') format('truetype'), url('fonts/icons.svg#Simple-Line-Icons') format('svg');
 
 
 
5
  font-weight: normal;
6
  font-style: normal;
7
  }
8
+
9
+ [class^="icon-custom"]::before,
10
+ [class*=" icon-custom"]::before {
11
  font-style: normal;
12
  font-weight: normal;
13
  display: inline-block;
21
  margin-left: 0.2em;
22
  font-family: "Simple-Line-Icons" !important;
23
  }
24
+
25
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
26
+ @font-face {
 
27
  font-family: 'Simple-Line-Icons';
28
  src: url('fonts/icons.svg#Simple-Line-Icons') format('svg');
29
  }
30
  }
31
+
32
+
33
  /* Use the following CSS code if you want to use data attributes for inserting your icons */
34
+
35
+ [data-icon]:before {
36
  font-family: 'Simple-Line-Icons';
37
  content: attr(data-icon);
38
  speak: none;
43
  -webkit-font-smoothing: antialiased;
44
  -moz-osx-font-smoothing: grayscale;
45
  }
46
+
47
+
48
  /* Use the following CSS code if you want to have a class per icon */
49
+
50
+
51
  /*
52
  Instead of a list of all class selectors,
53
  you can use the generic selector below, but it's slower:
54
  [class*="icon-"] {
55
  */
56
+
57
+ .icon-custom-user-female,
58
+ .icon-custom-user-follow,
59
+ .icon-custom-user-following,
60
+ .icon-custom-user-unfollow,
61
+ .icon-custom-trophy,
62
+ .icon-custom-screen-smartphone,
63
+ .icon-custom-screen-desktop,
64
+ .icon-custom-plane,
65
+ .icon-custom-notebook,
66
+ .icon-custom-moustache,
67
+ .icon-custom-mouse,
68
+ .icon-custom-magnet,
69
+ .icon-custom-energy,
70
+ .icon-custom-emoticon-custom-smile,
71
+ .icon-custom-disc,
72
+ .icon-custom-cursor-move,
73
+ .icon-custom-crop,
74
+ .icon-custom-credit-card,
75
+ .icon-custom-chemistry,
76
+ .icon-custom-user,
77
+ .icon-custom-speedometer,
78
+ .icon-custom-social-youtube,
79
+ .icon-custom-social-twitter,
80
+ .icon-custom-social-tumblr,
81
+ .icon-custom-social-facebook,
82
+ .icon-custom-social-dropbox,
83
+ .icon-custom-social-dribbble,
84
+ .icon-custom-shield,
85
+ .icon-custom-screen-tablet,
86
+ .icon-custom-magic-wand,
87
+ .icon-custom-hourglass,
88
+ .icon-custom-graduation,
89
+ .icon-custom-ghost,
90
+ .icon-custom-game-controller,
91
+ .icon-custom-fire,
92
+ .icon-custom-eyeglasses,
93
+ .icon-custom-envelope-open,
94
+ .icon-custom-envelope-letter,
95
+ .icon-custom-bell,
96
+ .icon-custom-badge,
97
+ .icon-custom-anchor,
98
+ .icon-custom-wallet,
99
+ .icon-custom-vector,
100
+ .icon-custom-speech,
101
+ .icon-custom-puzzle,
102
+ .icon-custom-printer,
103
+ .icon-custom-present,
104
+ .icon-custom-playlist,
105
+ .icon-custom-pin,
106
+ .icon-custom-picture,
107
+ .icon-custom-map,
108
+ .icon-custom-layers,
109
+ .icon-custom-handbag,
110
+ .icon-custom-globe-alt,
111
+ .icon-custom-globe,
112
+ .icon-custom-frame,
113
+ .icon-custom-folder-alt,
114
+ .icon-custom-film,
115
+ .icon-custom-feed,
116
+ .icon-custom-earphones-alt,
117
+ .icon-custom-earphones,
118
+ .icon-custom-drop,
119
+ .icon-custom-drawer,
120
+ .icon-custom-docs,
121
+ .icon-custom-directions,
122
+ .icon-custom-direction,
123
+ .icon-custom-diamond,
124
+ .icon-custom-cup,
125
+ .icon-custom-compass,
126
+ .icon-custom-call-out,
127
+ .icon-custom-call-in,
128
+ .icon-custom-call-end,
129
+ .icon-custom-calculator,
130
+ .icon-custom-bubbles,
131
+ .icon-custom-briefcase,
132
+ .icon-custom-book-open,
133
+ .icon-custom-basket-loaded,
134
+ .icon-custom-basket,
135
+ .icon-custom-bag,
136
+ .icon-custom-action-undo,
137
+ .icon-custom-action-redo,
138
+ .icon-custom-wrench,
139
+ .icon-custom-umbrella,
140
+ .icon-custom-trash,
141
+ .icon-custom-tag,
142
+ .icon-custom-support,
143
+ .icon-custom-size-fullscreen,
144
+ .icon-custom-size-actual,
145
+ .icon-custom-shuffle,
146
+ .icon-custom-share-alt,
147
+ .icon-custom-share,
148
+ .icon-custom-rocket,
149
+ .icon-custom-question,
150
+ .icon-custom-pie-chart,
151
+ .icon-custom-pencil,
152
+ .icon-custom-note,
153
+ .icon-custom-music-tone-alt,
154
+ .icon-custom-music-tone,
155
+ .icon-custom-microphone,
156
+ .icon-custom-loop,
157
+ .icon-custom-logout,
158
+ .icon-custom-login,
159
+ .icon-custom-list,
160
+ .icon-custom-like,
161
+ .icon-custom-home,
162
+ .icon-custom-grid,
163
+ .icon-custom-graph,
164
+ .icon-custom-equalizer,
165
+ .icon-custom-dislike,
166
+ .icon-custom-cursor,
167
+ .icon-custom-control-start,
168
+ .icon-custom-control-rewind,
169
+ .icon-custom-control-play,
170
+ .icon-custom-control-pause,
171
+ .icon-custom-control-forward,
172
+ .icon-custom-control-end,
173
+ .icon-custom-calendar,
174
+ .icon-custom-bulb,
175
+ .icon-custom-bar-chart,
176
+ .icon-custom-arrow-up,
177
+ .icon-custom-arrow-right,
178
+ .icon-custom-arrow-left,
179
+ .icon-custom-arrow-down,
180
+ .icon-custom-ban,
181
+ .icon-custom-bubble,
182
+ .icon-custom-camcorder,
183
+ .icon-custom-camera,
184
+ .icon-custom-check,
185
+ .icon-custom-clock,
186
+ .icon-custom-close,
187
+ .icon-custom-cloud-download,
188
+ .icon-custom-cloud-upload,
189
+ .icon-custom-doc,
190
+ .icon-custom-envelope,
191
+ .icon-custom-eye,
192
+ .icon-custom-flag,
193
+ .icon-custom-folder,
194
+ .icon-custom-heart,
195
+ .icon-custom-info,
196
+ .icon-custom-key,
197
+ .icon-custom-link,
198
+ .icon-custom-lock,
199
+ .icon-custom-lock-open,
200
+ .icon-custom-magnifier,
201
+ .icon-custom-magnifier-add,
202
+ .icon-custom-magnifier-remove,
203
+ .icon-custom-paper-clip,
204
+ .icon-custom-paper-plane,
205
+ .icon-custom-plus,
206
+ .icon-custom-pointer,
207
+ .icon-custom-power,
208
+ .icon-custom-refresh,
209
+ .icon-custom-reload,
210
+ .icon-custom-settings,
211
+ .icon-custom-star,
212
+ .icon-custom-symbol-female,
213
+ .icon-custom-symbol-male,
214
+ .icon-custom-target,
215
+ .icon-custom-volume-1,
216
+ .icon-custom-volume-2,
217
+ .icon-custom-volume-off,
218
+ .icon-custom-users {
219
  font-family: 'Simple-Line-icon';
220
  speak: none;
221
  font-style: normal;
225
  line-height: 1;
226
  -webkit-font-smoothing: antialiased;
227
  }
228
+
229
+ .icon-custom-user-female:before {
230
  content: "\e000";
231
  }
232
+
233
+ .icon-custom-user-follow:before {
234
  content: "\e002";
235
  }
236
+
237
+ .icon-custom-user-following:before {
238
  content: "\e003";
239
  }
240
+
241
+ .icon-custom-user-unfollow:before {
242
  content: "\e004";
243
  }
244
+
245
+ .icon-custom-trophy:before {
246
  content: "\e006";
247
  }
248
+
249
+ .icon-custom-screen-smartphone:before {
250
  content: "\e010";
251
  }
252
+
253
+ .icon-custom-screen-desktop:before {
254
  content: "\e011";
255
  }
256
+
257
+ .icon-custom-plane:before {
258
  content: "\e012";
259
  }
260
+
261
+ .icon-custom-notebook:before {
262
  content: "\e013";
263
  }
264
+
265
+ .icon-custom-moustache:before {
266
  content: "\e014";
267
  }
268
+
269
+ .icon-custom-mouse:before {
270
  content: "\e015";
271
  }
272
+
273
+ .icon-custom-magnet:before {
274
  content: "\e016";
275
  }
276
+
277
+ .icon-custom-energy:before {
278
  content: "\e020";
279
  }
280
+
281
+ .icon-custom-emoticon-custom-smile:before {
282
  content: "\e021";
283
  }
284
+
285
+ .icon-custom-disc:before {
286
  content: "\e022";
287
  }
288
+
289
+ .icon-custom-cursor-move:before {
290
  content: "\e023";
291
  }
292
+
293
+ .icon-custom-crop:before {
294
  content: "\e024";
295
  }
296
+
297
+ .icon-custom-credit-card:before {
298
  content: "\e025";
299
  }
300
+
301
+ .icon-custom-chemistry:before {
302
  content: "\e026";
303
  }
304
+
305
+ .icon-custom-user:before {
306
  content: "\e005";
307
  }
308
+
309
+ .icon-custom-speedometer:before {
310
  content: "\e007";
311
  }
312
+
313
+ .icon-custom-social-youtube:before {
314
  content: "\e008";
315
  }
316
+
317
+ .icon-custom-social-twitter:before {
318
  content: "\e009";
319
  }
320
+
321
+ .icon-custom-social-tumblr:before {
322
  content: "\e00a";
323
  }
324
+
325
+ .icon-custom-social-facebook:before {
326
  content: "\e00b";
327
  }
328
+
329
+ .icon-custom-social-dropbox:before {
330
  content: "\e00c";
331
  }
332
+
333
+ .icon-custom-social-dribbble:before {
334
  content: "\e00d";
335
  }
336
+
337
+ .icon-custom-shield:before {
338
  content: "\e00e";
339
  }
340
+
341
+ .icon-custom-screen-tablet:before {
342
  content: "\e00f";
343
  }
344
+
345
+ .icon-custom-magic-wand:before {
346
  content: "\e017";
347
  }
348
+
349
+ .icon-custom-hourglass:before {
350
  content: "\e018";
351
  }
352
+
353
+ .icon-custom-graduation:before {
354
  content: "\e019";
355
  }
356
+
357
+ .icon-custom-ghost:before {
358
  content: "\e01a";
359
  }
360
+
361
+ .icon-custom-game-controller:before {
362
  content: "\e01b";
363
  }
364
+
365
+ .icon-custom-fire:before {
366
  content: "\e01c";
367
  }
368
+
369
+ .icon-custom-eyeglasses:before {
370
  content: "\e01d";
371
  }
372
+
373
+ .icon-custom-envelope-open:before {
374
  content: "\e01e";
375
  }
376
+
377
+ .icon-custom-envelope-letter:before {
378
  content: "\e01f";
379
  }
380
+
381
+ .icon-custom-bell:before {
382
  content: "\e027";
383
  }
384
+
385
+ .icon-custom-badge:before {
386
  content: "\e028";
387
  }
388
+
389
+ .icon-custom-anchor:before {
390
  content: "\e029";
391
  }
392
+
393
+ .icon-custom-wallet:before {
394
  content: "\e02a";
395
  }
396
+
397
+ .icon-custom-vector:before {
398
  content: "\e02b";
399
  }
400
+
401
+ .icon-custom-speech:before {
402
  content: "\e02c";
403
  }
404
+
405
+ .icon-custom-puzzle:before {
406
  content: "\e02d";
407
  }
408
+
409
+ .icon-custom-printer:before {
410
  content: "\e02e";
411
  }
412
+
413
+ .icon-custom-present:before {
414
  content: "\e02f";
415
  }
416
+
417
+ .icon-custom-playlist:before {
418
  content: "\e030";
419
  }
420
+
421
+ .icon-custom-pin:before {
422
  content: "\e031";
423
  }
424
+
425
+ .icon-custom-picture:before {
426
  content: "\e032";
427
  }
428
+
429
+ .icon-custom-map:before {
430
  content: "\e033";
431
  }
432
+
433
+ .icon-custom-layers:before {
434
  content: "\e034";
435
  }
436
+
437
+ .icon-custom-handbag:before {
438
  content: "\e035";
439
  }
440
+
441
+ .icon-custom-globe-alt:before {
442
  content: "\e036";
443
  }
444
+
445
+ .icon-custom-globe:before {
446
  content: "\e037";
447
  }
448
+
449
+ .icon-custom-frame:before {
450
  content: "\e038";
451
  }
452
+
453
+ .icon-custom-folder-alt:before {
454
  content: "\e039";
455
  }
456
+
457
+ .icon-custom-film:before {
458
  content: "\e03a";
459
  }
460
+
461
+ .icon-custom-feed:before {
462
  content: "\e03b";
463
  }
464
+
465
+ .icon-custom-earphones-alt:before {
466
  content: "\e03c";
467
  }
468
+
469
+ .icon-custom-earphones:before {
470
  content: "\e03d";
471
  }
472
+
473
+ .icon-custom-drop:before {
474
  content: "\e03e";
475
  }
476
+
477
+ .icon-custom-drawer:before {
478
  content: "\e03f";
479
  }
480
+
481
+ .icon-custom-docs:before {
482
  content: "\e040";
483
  }
484
+
485
+ .icon-custom-directions:before {
486
  content: "\e041";
487
  }
488
+
489
+ .icon-custom-direction:before {
490
  content: "\e042";
491
  }
492
+
493
+ .icon-custom-diamond:before {
494
  content: "\e043";
495
  }
496
+
497
+ .icon-custom-cup:before {
498
  content: "\e044";
499
  }
500
+
501
+ .icon-custom-compass:before {
502
  content: "\e045";
503
  }
504
+
505
+ .icon-custom-call-out:before {
506
  content: "\e046";
507
  }
508
+
509
+ .icon-custom-call-in:before {
510
  content: "\e047";
511
  }
512
+
513
+ .icon-custom-call-end:before {
514
  content: "\e048";
515
  }
516
+
517
+ .icon-custom-calculator:before {
518
  content: "\e049";
519
  }
520
+
521
+ .icon-custom-bubbles:before {
522
  content: "\e04a";
523
  }
524
+
525
+ .icon-custom-briefcase:before {
526
  content: "\e04b";
527
  }
528
+
529
+ .icon-custom-book-open:before {
530
  content: "\e04c";
531
  }
532
+
533
+ .icon-custom-basket-loaded:before {
534
  content: "\e04d";
535
  }
536
+
537
+ .icon-custom-basket:before {
538
  content: "\e04e";
539
  }
540
+
541
+ .icon-custom-bag:before {
542
  content: "\e04f";
543
  }
544
+
545
+ .icon-custom-action-undo:before {
546
  content: "\e050";
547
  }
548
+
549
+ .icon-custom-action-redo:before {
550
  content: "\e051";
551
  }
552
+
553
+ .icon-custom-wrench:before {
554
  content: "\e052";
555
  }
556
+
557
+ .icon-custom-umbrella:before {
558
  content: "\e053";
559
  }
560
+
561
+ .icon-custom-trash:before {
562
  content: "\e054";
563
  }
564
+
565
+ .icon-custom-tag:before {
566
  content: "\e055";
567
  }
568
+
569
+ .icon-custom-support:before {
570
  content: "\e056";
571
  }
572
+
573
+ .icon-custom-size-fullscreen:before {
574
  content: "\e057";
575
  }
576
+
577
+ .icon-custom-size-actual:before {
578
  content: "\e058";
579
  }
580
+
581
+ .icon-custom-shuffle:before {
582
  content: "\e059";
583
  }
584
+
585
+ .icon-custom-share-alt:before {
586
  content: "\e05a";
587
  }
588
+
589
+ .icon-custom-share:before {
590
  content: "\e05b";
591
  }
592
+
593
+ .icon-custom-rocket:before {
594
  content: "\e05c";
595
  }
596
+
597
+ .icon-custom-question:before {
598
  content: "\e05d";
599
  }
600
+
601
+ .icon-custom-pie-chart:before {
602
  content: "\e05e";
603
  }
604
+
605
+ .icon-custom-pencil:before {
606
  content: "\e05f";
607
  }
608
+
609
+ .icon-custom-note:before {
610
  content: "\e060";
611
  }
612
+
613
+ .icon-custom-music-tone-alt:before {
614
  content: "\e061";
615
  }
616
+
617
+ .icon-custom-music-tone:before {
618
  content: "\e062";
619
  }
620
+
621
+ .icon-custom-microphone:before {
622
  content: "\e063";
623
  }
624
+
625
+ .icon-custom-loop:before {
626
  content: "\e064";
627
  }
628
+
629
+ .icon-custom-logout:before {
630
  content: "\e065";
631
  }
632
+
633
+ .icon-custom-login:before {
634
  content: "\e066";
635
  }
636
+
637
+ .icon-custom-list:before {
638
  content: "\e067";
639
  }
640
+
641
+ .icon-custom-like:before {
642
  content: "\e068";
643
  }
644
+
645
+ .icon-custom-home:before {
646
  content: "\e069";
647
  }
648
+
649
+ .icon-custom-grid:before {
650
  content: "\e06a";
651
  }
652
+
653
+ .icon-custom-graph:before {
654
  content: "\e06b";
655
  }
656
+
657
+ .icon-custom-equalizer:before {
658
  content: "\e06c";
659
  }
660
+
661
+ .icon-custom-dislike:before {
662
  content: "\e06d";
663
  }
664
+
665
+ .icon-custom-cursor:before {
666
  content: "\e06e";
667
  }
668
+
669
+ .icon-custom-control-start:before {
670
  content: "\e06f";
671
  }
672
+
673
+ .icon-custom-control-rewind:before {
674
  content: "\e070";
675
  }
676
+
677
+ .icon-custom-control-play:before {
678
  content: "\e071";
679
  }
680
+
681
+ .icon-custom-control-pause:before {
682
  content: "\e072";
683
  }
684
+
685
+ .icon-custom-control-forward:before {
686
  content: "\e073";
687
  }
688
+
689
+ .icon-custom-control-end:before {
690
  content: "\e074";
691
  }
692
+
693
+ .icon-custom-calendar:before {
694
  content: "\e075";
695
  }
696
+
697
+ .icon-custom-bulb:before {
698
  content: "\e076";
699
  }
700
+
701
+ .icon-custom-bar-chart:before {
702
  content: "\e077";
703
  }
704
+
705
+ .icon-custom-arrow-up:before {
706
  content: "\e078";
707
  }
708
+
709
+ .icon-custom-arrow-right:before {
710
  content: "\e079";
711
  }
712
+
713
+ .icon-custom-arrow-left:before {
714
  content: "\e07a";
715
  }
716
+
717
+ .icon-custom-arrow-down:before {
718
  content: "\e07b";
719
  }
720
+
721
+ .icon-custom-ban:before {
722
  content: "\e07c";
723
  }
724
+
725
+ .icon-custom-bubble:before {
726
  content: "\e07d";
727
  }
728
+
729
+ .icon-custom-camcorder:before {
730
  content: "\e07e";
731
  }
732
+
733
+ .icon-custom-camera:before {
734
  content: "\e07f";
735
  }
736
+
737
+ .icon-custom-check:before {
738
  content: "\e080";
739
  }
740
+
741
+ .icon-custom-clock:before {
742
  content: "\e081";
743
  }
744
+
745
+ .icon-custom-close:before {
746
  content: "\e082";
747
  }
748
+
749
+ .icon-custom-cloud-download:before {
750
  content: "\e083";
751
  }
752
+
753
+ .icon-custom-cloud-upload:before {
754
  content: "\e084";
755
  }
756
+
757
+ .icon-custom-doc:before {
758
  content: "\e085";
759
  }
760
+
761
+ .icon-custom-envelope:before {
762
  content: "\e086";
763
  }
764
+
765
+ .icon-custom-eye:before {
766
  content: "\e087";
767
  }
768
+
769
+ .icon-custom-flag:before {
770
  content: "\e088";
771
  }
772
+
773
+ .icon-custom-folder:before {
774
  content: "\e089";
775
  }
776
+
777
+ .icon-custom-heart:before {
778
  content: "\e08a";
779
  }
780
+
781
+ .icon-custom-info:before {
782
  content: "\e08b";
783
  }
784
+
785
+ .icon-custom-key:before {
786
  content: "\e08c";
787
  }
788
+
789
+ .icon-custom-link:before {
790
  content: "\e08d";
791
  }
792
+
793
+ .icon-custom-lock:before {
794
  content: "\e08e";
795
  }
796
+
797
+ .icon-custom-lock-open:before {
798
  content: "\e08f";
799
  }
800
+
801
+ .icon-custom-magnifier:before {
802
  content: "\e090";
803
  }
804
+
805
+ .icon-custom-magnifier-add:before {
806
  content: "\e091";
807
  }
808
+
809
+ .icon-custom-magnifier-remove:before {
810
  content: "\e092";
811
  }
812
+
813
+ .icon-custom-paper-clip:before {
814
  content: "\e093";
815
  }
816
+
817
+ .icon-custom-paper-plane:before {
818
  content: "\e094";
819
  }
820
+
821
+ .icon-custom-plus:before {
822
  content: "\e095";
823
  }
824
+
825
+ .icon-custom-pointer:before {
826
  content: "\e096";
827
  }
828
+
829
+ .icon-custom-power:before {
830
  content: "\e097";
831
  }
832
+
833
+ .icon-custom-refresh:before {
834
  content: "\e098";
835
  }
836
+
837
+ .icon-custom-reload:before {
838
  content: "\e099";
839
  }
840
+
841
+ .icon-custom-settings:before {
842
  content: "\e09a";
843
  }
844
+
845
+ .icon-custom-star:before {
846
  content: "\e09b";
847
  }
848
+
849
+ .icon-custom-symbol-female:before {
850
  content: "\e09c";
851
  }
852
+
853
+ .icon-custom-symbol-male:before {
854
  content: "\e09d";
855
  }
856
+
857
+ .icon-custom-target:before {
858
  content: "\e09e";
859
  }
860
+
861
+ .icon-custom-volume-1:before {
862
  content: "\e09f";
863
  }
864
+
865
+ .icon-custom-volume-2:before {
866
  content: "\e0a0";
867
  }
868
+
869
+ .icon-custom-volume-off:before {
870
  content: "\e0a1";
871
  }
872
+
873
+ .icon-custom-users:before {
874
  content: "\e001";
875
+ }
assets/global/plugins/toastr/toastr.css CHANGED
@@ -1,23 +1,23 @@
1
- .toast-title
2
- {
3
  font-weight: bold
4
  }
5
- .toast-message
6
- {
7
  -ms-word-wrap: break-word;
8
  word-wrap: break-word
9
  }
10
- .toast-message a, .toast-message label
11
- {
 
12
  color: #fff
13
  }
14
- .toast-message a:hover
15
- {
16
  color: #ccc;
17
  text-decoration: none
18
  }
19
- .toast-close-button
20
- {
21
  position: relative;
22
  right: -0.3em;
23
  top: -0.3em;
@@ -28,83 +28,84 @@
28
  -webkit-text-shadow: 0 1px 0 #fff;
29
  text-shadow: 0 1px 0 #fff;
30
  opacity: .8;
31
- -ms-filter: alpha(opacity = 80);
32
- filter: alpha(opacity = 80)
33
  }
34
- .toast-close-button:hover, .toast-close-button:focus
35
- {
 
36
  color: #000;
37
  text-decoration: none;
38
  cursor: pointer;
39
  opacity: .4;
40
- -ms-filter: alpha(opacity = 40);
41
- filter: alpha(opacity = 40)
42
  }
43
- button.toast-close-button
44
- {
45
  padding: 0;
46
  cursor: pointer;
47
  background: transparent;
48
  border: 0;
49
  -webkit-appearance: none
50
  }
51
- .toast-top-center
52
- {
53
  top: 0;
54
  right: 0;
55
  width: 100%
56
  }
57
- .toast-bottom-center
58
- {
59
  bottom: 0;
60
  right: 0;
61
  width: 100%
62
  }
63
- .toast-top-full-width
64
- {
65
  top: 0;
66
  right: 0;
67
  width: 100%
68
  }
69
- .toast-bottom-full-width
70
- {
71
  bottom: 0;
72
  right: 0;
73
  width: 100%
74
  }
75
- .toast-top-left
76
- {
77
  top: 12px;
78
  left: 12px
79
  }
80
- .toast-top-right
81
- {
82
  top: 12px;
83
  right: 12px
84
  }
85
- .toast-bottom-right
86
- {
87
  right: 12px;
88
  bottom: 12px
89
  }
90
- .toast-bottom-left
91
- {
92
  bottom: 12px;
93
  left: 12px
94
  }
95
- #toast-container
96
- {
97
  position: fixed;
98
  z-index: 999999
99
  }
100
- #toast-container *
101
- {
102
  -moz-box-sizing: border-box;
103
  -webkit-box-sizing: border-box;
104
  box-sizing: border-box
105
  }
106
- #toast-container>div
107
- {
108
  margin: 0 0 6px;
109
  padding: 15px 15px 15px 50px;
110
  width: 300px;
@@ -118,106 +119,99 @@ button.toast-close-button
118
  box-shadow: 0 0 12px #999;
119
  color: #fff;
120
  opacity: .8;
121
- -ms-filter: alpha(opacity = 80);
122
- filter: alpha(opacity = 80)
123
  }
124
- #toast-container>:hover
125
- {
126
  -moz-box-shadow: 0 0 12px #000;
127
  -webkit-box-shadow: 0 0 12px #000;
128
  box-shadow: 0 0 12px #000;
129
  opacity: 1;
130
- -ms-filter: alpha(opacity = 100);
131
- filter: alpha(opacity = 100);
132
  cursor: pointer
133
  }
134
- #toast-container>.toast-info
135
- {
136
- background-image:
137
- url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=")
138
- !important
139
  }
140
- #toast-container>.toast-custom-error
141
- {
142
  /*background-image:
143
- url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")
144
- !important*/
145
  background-image: url("../../img/error.png") !important;
146
  }
147
- #toast-container>.toast-custom-success
148
- {
149
  /*background-image:
150
- url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")
151
- !important*/
152
  background-image: url("../../img/success.png") !important
153
  }
154
- #toast-container>.toast-warning
155
- {
156
- background-image:
157
- url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=")
158
- !important
159
  }
160
- #toast-container.toast-top-center>div, #toast-container.toast-bottom-center>div
161
- {
 
162
  width: 300px;
163
  margin: auto
164
  }
165
- #toast-container.toast-top-full-width>div, #toast-container.toast-bottom-full-width>div
166
- {
 
167
  width: 96%;
168
  margin: auto
169
  }
170
- .toast
171
- {
172
  background-color: #030303
173
  }
174
- .toast-custom-success
175
- {
176
  background-color: #51a351
177
  }
178
- .toast-custom-error
179
- {
180
  background-color: #bd362f
181
  }
182
- .toast-info
183
- {
184
  background-color: #2f96b4
185
  }
186
- .toast-warning
187
- {
188
  background-color: #f89406
189
  }
190
- @media all and (max-width:240px)
191
- {
192
- #toast-container>div
193
- {
194
  padding: 8px 8px 8px 50px;
195
  width: 11em
196
  }
197
- #toast-container .toast-close-button
198
- {
199
  right: -0.2em;
200
  top: -0.2em
201
  }
202
  }
203
- @media all and (min-width:241px) and (max-width:480px)
204
- {
205
- #toast-container>div
206
- {
207
  padding: 8px 8px 8px 50px;
208
  width: 18em
209
  }
210
- #toast-container .toast-close-button
211
- {
212
  right: -0.2em;
213
  top: -0.2em
214
  }
215
  }
216
- @media all and (min-width:481px) and (max-width:768px)
217
- {
218
- #toast-container>div
219
- {
220
  padding: 15px 15px 15px 50px;
221
  width: 25em
222
  }
223
- }
1
+ .toast-title {
 
2
  font-weight: bold
3
  }
4
+
5
+ .toast-message {
6
  -ms-word-wrap: break-word;
7
  word-wrap: break-word
8
  }
9
+
10
+ .toast-message a,
11
+ .toast-message label {
12
  color: #fff
13
  }
14
+
15
+ .toast-message a:hover {
16
  color: #ccc;
17
  text-decoration: none
18
  }
19
+
20
+ .toast-close-button {
21
  position: relative;
22
  right: -0.3em;
23
  top: -0.3em;
28
  -webkit-text-shadow: 0 1px 0 #fff;
29
  text-shadow: 0 1px 0 #fff;
30
  opacity: .8;
31
+ -ms-filter: alpha(opacity=80);
32
+ filter: alpha(opacity=80)
33
  }
34
+
35
+ .toast-close-button:hover,
36
+ .toast-close-button:focus {
37
  color: #000;
38
  text-decoration: none;
39
  cursor: pointer;
40
  opacity: .4;
41
+ -ms-filter: alpha(opacity=40);
42
+ filter: alpha(opacity=40)
43
  }
44
+
45
+ button.toast-close-button {
46
  padding: 0;
47
  cursor: pointer;
48
  background: transparent;
49
  border: 0;
50
  -webkit-appearance: none
51
  }
52
+
53
+ .toast-top-center {
54
  top: 0;
55
  right: 0;
56
  width: 100%
57
  }
58
+
59
+ .toast-bottom-center {
60
  bottom: 0;
61
  right: 0;
62
  width: 100%
63
  }
64
+
65
+ .toast-top-full-width {
66
  top: 0;
67
  right: 0;
68
  width: 100%
69
  }
70
+
71
+ .toast-bottom-full-width {
72
  bottom: 0;
73
  right: 0;
74
  width: 100%
75
  }
76
+
77
+ .toast-top-left {
78
  top: 12px;
79
  left: 12px
80
  }
81
+
82
+ .toast-top-right {
83
  top: 12px;
84
  right: 12px
85
  }
86
+
87
+ .toast-bottom-right {
88
  right: 12px;
89
  bottom: 12px
90
  }
91
+
92
+ .toast-bottom-left {
93
  bottom: 12px;
94
  left: 12px
95
  }
96
+
97
+ #toast-container {
98
  position: fixed;
99
  z-index: 999999
100
  }
101
+
102
+ #toast-container * {
103
  -moz-box-sizing: border-box;
104
  -webkit-box-sizing: border-box;
105
  box-sizing: border-box
106
  }
107
+
108
+ #toast-container>div {
109
  margin: 0 0 6px;
110
  padding: 15px 15px 15px 50px;
111
  width: 300px;
119
  box-shadow: 0 0 12px #999;
120
  color: #fff;
121
  opacity: .8;
122
+ -ms-filter: alpha(opacity=80);
123
+ filter: alpha(opacity=80)
124
  }
125
+
126
+ #toast-container>:hover {
127
  -moz-box-shadow: 0 0 12px #000;
128
  -webkit-box-shadow: 0 0 12px #000;
129
  box-shadow: 0 0 12px #000;
130
  opacity: 1;
131
+ -ms-filter: alpha(opacity=100);
132
+ filter: alpha(opacity=100);
133
  cursor: pointer
134
  }
135
+
136
+ #toast-container>.toast-info {
137
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important
 
 
138
  }
139
+
140
+ #toast-container>.toast-custom-error {
141
  /*background-image:
142
+ url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")
143
+ !important*/
144
  background-image: url("../../img/error.png") !important;
145
  }
146
+
147
+ #toast-container>.toast-custom-success {
148
  /*background-image:
149
+ url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")
150
+ !important*/
151
  background-image: url("../../img/success.png") !important
152
  }
153
+
154
+ #toast-container>.toast-warning {
155
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important
 
 
156
  }
157
+
158
+ #toast-container.toast-top-center>div,
159
+ #toast-container.toast-bottom-center>div {
160
  width: 300px;
161
  margin: auto
162
  }
163
+
164
+ #toast-container.toast-top-full-width>div,
165
+ #toast-container.toast-bottom-full-width>div {
166
  width: 96%;
167
  margin: auto
168
  }
169
+
170
+ .toast {
171
  background-color: #030303
172
  }
173
+
174
+ .toast-custom-success {
175
  background-color: #51a351
176
  }
177
+
178
+ .toast-custom-error {
179
  background-color: #bd362f
180
  }
181
+
182
+ .toast-info {
183
  background-color: #2f96b4
184
  }
185
+
186
+ .toast-warning {
187
  background-color: #f89406
188
  }
189
+
190
+ @media all and (max-width:240px) {
191
+ #toast-container>div {
 
192
  padding: 8px 8px 8px 50px;
193
  width: 11em
194
  }
195
+ #toast-container .toast-close-button {
 
196
  right: -0.2em;
197
  top: -0.2em
198
  }
199
  }
200
+
201
+ @media all and (min-width:241px) and (max-width:480px) {
202
+ #toast-container>div {
 
203
  padding: 8px 8px 8px 50px;
204
  width: 18em
205
  }
206
+ #toast-container .toast-close-button {
 
207
  right: -0.2em;
208
  top: -0.2em
209
  }
210
  }
211
+
212
+ @media all and (min-width:481px) and (max-width:768px) {
213
+ #toast-container>div {
 
214
  padding: 15px 15px 15px 50px;
215
  width: 25em
216
  }
217
+ }
assets/global/plugins/toastr/toastr.js CHANGED
@@ -249,10 +249,11 @@
249
  $container.append($toastElement);
250
  }
251
 
252
-
253
- $toastElement[options.showMethod](
254
- {duration: options.showDuration, easing: options.showEasing, complete: options.onShown}
255
- );
 
256
 
257
  if (options.timeOut > 0) {
258
  intervalId = setTimeout(hideToast, options.timeOut);
@@ -316,9 +317,10 @@
316
 
317
  function stickAround() {
318
  clearTimeout(intervalId);
319
- $toastElement.stop(true, true)[options.showMethod](
320
- {duration: options.showDuration, easing: options.showEasing}
321
- );
 
322
  }
323
  }
324
 
@@ -352,4 +354,4 @@
352
  }));
353
  jQuery.fn.exists = function () {
354
  return this.length > 0;
355
- }
249
  $container.append($toastElement);
250
  }
251
 
252
+ $toastElement[options.showMethod]({
253
+ duration: options.showDuration,
254
+ easing: options.showEasing,
255
+ complete: options.onShown
256
+ });
257
 
258
  if (options.timeOut > 0) {
259
  intervalId = setTimeout(hideToast, options.timeOut);
317
 
318
  function stickAround() {
319
  clearTimeout(intervalId);
320
+ $toastElement.stop(true, true)[options.showMethod]({
321
+ duration: options.showDuration,
322
+ easing: options.showEasing
323
+ });
324
  }
325
  }
326
 
354
  }));
355
  jQuery.fn.exists = function () {
356
  return this.length > 0;
357
+ }
assets/global/plugins/validation/jquery.validate.js CHANGED
@@ -1,1334 +1,1600 @@
1
- /*!
2
- * jQuery Validation Plugin
3
- * Copyright (c) 2015 Jörn Zaefferer
4
- */
5
- (function (factory) {
6
- if (typeof define === "function" && define.amd) {
7
- define(["jquery"], factory);
8
- } else if (typeof module === "object" && module.exports) {
9
- module.exports = factory(require("jquery"));
10
- } else {
11
- factory(jQuery);
12
- }
13
- }(function ($) {
14
-
15
- $.extend($.fn, {
16
- validate: function (options) {
17
-
18
- // If nothing is selected, return nothing; can't chain anyway
19
- if (!this.length) {
20
- if (options && options.debug && window.console) {
21
- console.warn("Nothing selected, can't validate, returning nothing.");
22
- }
23
- return;
24
- }
25
-
26
- // Check if a validator for this form was already created
27
- var validator = $.data(this[ 0 ], "validator");
28
- if (validator) {
29
- return validator;
30
- }
31
-
32
- // Add novalidate tag if HTML5.
33
- this.attr("novalidate", "novalidate");
34
-
35
- validator = new $.validator(options, this[ 0 ]);
36
- $.data(this[ 0 ], "validator", validator);
37
-
38
- if (validator.settings.onsubmit) {
39
-
40
- this.on("click.validate", ":submit", function (event) {
41
- if (validator.settings.submitHandler) {
42
- validator.submitButton = event.target;
43
- }
44
-
45
- // Allow suppressing validation by adding a cancel class to the submit button
46
- if ($(this).hasClass("cancel")) {
47
- validator.cancelSubmit = true;
48
- }
49
-
50
- // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
51
- if ($(this).attr("formnovalidate") !== undefined) {
52
- validator.cancelSubmit = true;
53
- }
54
- });
55
-
56
- // Validate the form on submit
57
- this.on("submit.validate", function (event) {
58
- if (validator.settings.debug) {
59
-
60
- // Prevent form submit to be able to see console output
61
- event.preventDefault();
62
- }
63
- function handle() {
64
- var hidden, result;
65
- if (validator.settings.submitHandler) {
66
- if (validator.submitButton) {
67
-
68
- // Insert a hidden input as a replacement for the missing submit button
69
- hidden = $("<input type='hidden'/>")
70
- .attr("name", validator.submitButton.name)
71
- .val($(validator.submitButton).val())
72
- .appendTo(validator.currentForm);
73
- }
74
- result = validator.settings.submitHandler.call(validator, validator.currentForm, event);
75
- if (validator.submitButton) {
76
-
77
- // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
78
- hidden.remove();
79
- }
80
- if (result !== undefined) {
81
- return result;
82
- }
83
- return false;
84
- }
85
- return true;
86
- }
87
- if (validator.cancelSubmit) {
88
- validator.cancelSubmit = false;
89
- return handle();
90
- }
91
- if (validator.form()) {
92
- if (validator.pendingRequest) {
93
- validator.formSubmitted = true;
94
- return false;
95
- }
96
- return handle();
97
- } else {
98
- validator.focusInvalid();
99
- return false;
100
- }
101
- });
102
- }
103
-
104
- return validator;
105
- },
106
- valid: function () {
107
- var valid, validator, errorList;
108
-
109
- if ($(this[ 0 ]).is("form")) {
110
- valid = this.validate().form();
111
- } else {
112
- errorList = [];
113
- valid = true;
114
- validator = $(this[ 0 ].form).validate();
115
- this.each(function () {
116
- valid = validator.element(this) && valid;
117
- if (!valid) {
118
- errorList = errorList.concat(validator.errorList);
119
- }
120
- });
121
- validator.errorList = errorList;
122
- }
123
- return valid;
124
- },
125
- rules: function (command, argument) {
126
-
127
- // If nothing is selected, return nothing; can't chain anyway
128
- if (!this.length) {
129
- return;
130
- }
131
-
132
- var element = this[ 0 ],
133
- settings, staticRules, existingRules, data, param, filtered;
134
-
135
- if (command) {
136
- settings = $.data(element.form, "validator").settings;
137
- staticRules = settings.rules;
138
- existingRules = $.validator.staticRules(element);
139
- switch (command) {
140
- case "add":
141
- $.extend(existingRules, $.validator.normalizeRule(argument));
142
-
143
- // Remove messages from rules, but allow them to be set separately
144
- delete existingRules.messages;
145
- staticRules[ element.name ] = existingRules;
146
- if (argument.messages) {
147
- settings.messages[ element.name ] = $.extend(settings.messages[ element.name ], argument.messages);
148
- }
149
- break;
150
- case "remove":
151
- if (!argument) {
152
- delete staticRules[ element.name ];
153
- return existingRules;
154
- }
155
- filtered = {};
156
- $.each(argument.split(/\s/), function (index, method) {
157
- filtered[ method ] = existingRules[ method ];
158
- delete existingRules[ method ];
159
- if (method === "required") {
160
- $(element).removeAttr("aria-required");
161
- }
162
- });
163
- return filtered;
164
- }
165
- }
166
-
167
- data = $.validator.normalizeRules(
168
- $.extend(
169
- {},
170
- $.validator.classRules(element),
171
- $.validator.attributeRules(element),
172
- $.validator.dataRules(element),
173
- $.validator.staticRules(element)
174
- ), element);
175
-
176
- // Make sure required is at front
177
- if (data.required) {
178
- param = data.required;
179
- delete data.required;
180
- data = $.extend({required: param}, data);
181
- $(element).attr("aria-required", "true");
182
- }
183
-
184
- // Make sure remote is at back
185
- if (data.remote) {
186
- param = data.remote;
187
- delete data.remote;
188
- data = $.extend(data, {remote: param});
189
- }
190
-
191
- return data;
192
- }
193
- });
194
-
195
- // Custom selectors
196
- $.extend($.expr[ ":" ], {
197
- blank: function (a) {
198
- return !$.trim("" + $(a).val());
199
- },
200
- filled: function (a) {
201
- var val = $(a).val();
202
- return val !== null && !!$.trim("" + val);
203
- },
204
-
205
- unchecked: function (a) {
206
- return !$(a).prop("checked");
207
- }
208
- });
209
-
210
- // Constructor for validator
211
- $.validator = function (options, form) {
212
- this.settings = $.extend(true, {}, $.validator.defaults, options);
213
- this.currentForm = form;
214
- this.init();
215
- };
216
-
217
- $.validator.format = function (source, params) {
218
- if (arguments.length === 1) {
219
- return function () {
220
- var args = $.makeArray(arguments);
221
- args.unshift(source);
222
- return $.validator.format.apply(this, args);
223
- };
224
- }
225
- if (params === undefined) {
226
- return source;
227
- }
228
- if (arguments.length > 2 && params.constructor !== Array) {
229
- params = $.makeArray(arguments).slice(1);
230
- }
231
- if (params.constructor !== Array) {
232
- params = [params];
233
- }
234
- $.each(params, function (i, n) {
235
- source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () {
236
- return n;
237
- });
238
- });
239
- return source;
240
- };
241
-
242
- $.extend($.validator, {
243
-
244
- defaults: {
245
- messages: {},
246
- groups: {},
247
- rules: {},
248
- errorClass: "error",
249
- pendingClass: "pending",
250
- validClass: "valid",
251
- errorElement: "label",
252
- focusCleanup: false,
253
- focusInvalid: true,
254
- errorContainer: $([]),
255
- errorLabelContainer: $([]),
256
- onsubmit: true,
257
- ignore: ":hidden",
258
- ignoreTitle: false,
259
- onfocusin: function (element) {
260
- this.lastActive = element;
261
- if (this.settings.focusCleanup) {
262
- if (this.settings.unhighlight) {
263
- this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass);
264
- }
265
- this.hideThese(this.errorsFor(element));
266
- }
267
- },
268
- onfocusout: function (element) {
269
- if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
270
- this.element(element);
271
- }
272
- },
273
- onkeyup: function (element, event) {
274
- var excludedKeys = [
275
- 16, 17, 18, 20, 35, 36, 37,
276
- 38, 39, 40, 45, 144, 225
277
- ];
278
-
279
- if (event.which === 9 && this.elementValue(element) === "" || $.inArray(event.keyCode, excludedKeys) !== -1) {
280
- return;
281
- } else if (element.name in this.submitted || element.name in this.invalid) {
282
- this.element(element);
283
- }
284
- },
285
- onclick: function (element) {
286
-
287
- // Click on selects, radiobuttons and checkboxes
288
- if (element.name in this.submitted) {
289
- this.element(element);
290
-
291
- // Or option elements, check parent select in that case
292
- } else if (element.parentNode.name in this.submitted) {
293
- this.element(element.parentNode);
294
- }
295
- },
296
- highlight: function (element, errorClass, validClass) {
297
- if (element.type === "radio") {
298
- this.findByName(element.name).addClass(errorClass).removeClass(validClass);
299
- } else {
300
- $(element).addClass(errorClass).removeClass(validClass);
301
- }
302
- },
303
- unhighlight: function (element, errorClass, validClass) {
304
- if (element.type === "radio") {
305
- this.findByName(element.name).removeClass(errorClass).addClass(validClass);
306
- } else {
307
- $(element).removeClass(errorClass).addClass(validClass);
308
- }
309
- }
310
- },
311
- setDefaults: function (settings) {
312
- $.extend($.validator.defaults, settings);
313
- },
314
-
315
- messages: {
316
- required: "This field is required.",
317
- remote: "Please fix this field.",
318
- email: "Please enter a valid email address.",
319
- url: "Please enter a valid URL.",
320
- date: "Please enter a valid date.",
321
- dateISO: "Please enter a valid date ( ISO ).",
322
- number: "Please enter a valid number.",
323
- digits: "Please enter only digits.",
324
- equalTo: "Please enter the same value again.",
325
- maxlength: $.validator.format("Please enter no more than {0} characters."),
326
- minlength: $.validator.format("Please enter at least {0} characters."),
327
- rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
328
- range: $.validator.format("Please enter a value between {0} and {1}."),
329
- max: $.validator.format("Please enter a value less than or equal to {0}."),
330
- min: $.validator.format("Please enter a value greater than or equal to {0}."),
331
- step: $.validator.format("Please enter a multiple of {0}.")
332
- },
333
-
334
- autoCreateRanges: false,
335
-
336
- prototype: {
337
-
338
- init: function () {
339
- this.labelContainer = $(this.settings.errorLabelContainer);
340
- this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
341
- this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer);
342
- this.submitted = {};
343
- this.valueCache = {};
344
- this.pendingRequest = 0;
345
- this.pending = {};
346
- this.invalid = {};
347
- this.reset();
348
-
349
- var groups = (this.groups = {}),
350
- rules;
351
- $.each(this.settings.groups, function (key, value) {
352
- if (typeof value === "string") {
353
- value = value.split(/\s/);
354
- }
355
- $.each(value, function (index, name) {
356
- groups[ name ] = key;
357
- });
358
- });
359
- rules = this.settings.rules;
360
- $.each(rules, function (key, value) {
361
- rules[ key ] = $.validator.normalizeRule(value);
362
- });
363
-
364
- function delegate(event) {
365
- var validator = $.data(this.form, "validator"),
366
- eventType = "on" + event.type.replace(/^validate/, ""),
367
- settings = validator.settings;
368
- if (settings[ eventType ] && !$(this).is(settings.ignore)) {
369
- settings[ eventType ].call(validator, this, event);
370
- }
371
- }
372
-
373
- $(this.currentForm)
374
- .on("focusin.validate focusout.validate keyup.validate",
375
- ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
376
- "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
377
- "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
378
- "[type='radio'], [type='checkbox'], [contenteditable]", delegate)
379
- .on("click.validate", "select, option, [type='radio'], [type='checkbox']", delegate);
380
-
381
- if (this.settings.invalidHandler) {
382
- $(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler);
383
- }
384
-
385
- // Add aria-required to any Static/Data/Class required fields before first validation
386
- // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
387
- $(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true");
388
- },
389
-
390
- form: function () {
391
- this.checkForm();
392
- $.extend(this.submitted, this.errorMap);
393
- this.invalid = $.extend({}, this.errorMap);
394
- if (!this.valid()) {
395
- $(this.currentForm).triggerHandler("invalid-form", [this]);
396
- }
397
- this.showErrors();
398
- return this.valid();
399
- },
400
-
401
- checkForm: function () {
402
- this.prepareForm();
403
- for (var i = 0, elements = (this.currentElements = this.elements()); elements[ i ]; i++) {
404
- this.check(elements[ i ]);
405
- }
406
- return this.valid();
407
- },
408
- element: function (element) {
409
- var cleanElement = this.clean(element),
410
- checkElement = this.validationTargetFor(cleanElement),
411
- v = this,
412
- result = true,
413
- rs, group;
414
-
415
- if (checkElement === undefined) {
416
- delete this.invalid[ cleanElement.name ];
417
- } else {
418
- this.prepareElement(checkElement);
419
- this.currentElements = $(checkElement);
420
-
421
- // If this element is grouped, then validate all group elements already
422
- // containing a value
423
- group = this.groups[ checkElement.name ];
424
- if (group) {
425
- $.each(this.groups, function (name, testgroup) {
426
- if (testgroup === group && name !== checkElement.name) {
427
- cleanElement = v.validationTargetFor(v.clean(v.findByName(name)));
428
- if (cleanElement && cleanElement.name in v.invalid) {
429
- v.currentElements.push(cleanElement);
430
- result = result && v.check(cleanElement);
431
- }
432
- }
433
- });
434
- }
435
-
436
- rs = this.check(checkElement) !== false;
437
- result = result && rs;
438
- if (rs) {
439
- this.invalid[ checkElement.name ] = false;
440
- } else {
441
- this.invalid[ checkElement.name ] = true;
442
- }
443
-
444
- if (!this.numberOfInvalids()) {
445
-
446
- // Hide error containers on last error
447
- this.toHide = this.toHide.add(this.containers);
448
- }
449
- this.showErrors();
450
-
451
- // Add aria-invalid status for screen readers
452
- $(element).attr("aria-invalid", !rs);
453
- }
454
-
455
- return result;
456
- },
457
- showErrors: function (errors) {
458
- if (errors) {
459
- var validator = this;
460
-
461
- // Add items to error list and map
462
- $.extend(this.errorMap, errors);
463
- this.errorList = $.map(this.errorMap, function (message, name) {
464
- return {
465
- message: message,
466
- element: validator.findByName(name)[ 0 ]
467
- };
468
- });
469
-
470
- // Remove items from success list
471
- this.successList = $.grep(this.successList, function (element) {
472
- return !(element.name in errors);
473
- });
474
- }
475
- if (this.settings.showErrors) {
476
- this.settings.showErrors.call(this, this.errorMap, this.errorList);
477
- } else {
478
- this.defaultShowErrors();
479
- }
480
- },
481
- resetForm: function () {
482
- if ($.fn.resetForm) {
483
- $(this.currentForm).resetForm();
484
- }
485
- this.invalid = {};
486
- this.submitted = {};
487
- this.prepareForm();
488
- this.hideErrors();
489
- var elements = this.elements()
490
- .removeData("previousValue")
491
- .removeAttr("aria-invalid");
492
-
493
- this.resetElements(elements);
494
- },
495
-
496
- resetElements: function (elements) {
497
- var i;
498
-
499
- if (this.settings.unhighlight) {
500
- for (i = 0; elements[ i ]; i++) {
501
- this.settings.unhighlight.call(this, elements[ i ],
502
- this.settings.errorClass, "");
503
- this.findByName(elements[ i ].name).removeClass(this.settings.validClass);
504
- }
505
- } else {
506
- elements
507
- .removeClass(this.settings.errorClass)
508
- .removeClass(this.settings.validClass);
509
- }
510
- },
511
-
512
- numberOfInvalids: function () {
513
- return this.objectLength(this.invalid);
514
- },
515
-
516
- objectLength: function (obj) {
517
- /* jshint unused: false */
518
- var count = 0,
519
- i;
520
- for (i in obj) {
521
- if (obj[ i ]) {
522
- count++;
523
- }
524
- }
525
- return count;
526
- },
527
-
528
- hideErrors: function () {
529
- this.hideThese(this.toHide);
530
- },
531
-
532
- hideThese: function (errors) {
533
- errors.not(this.containers).text("");
534
- this.addWrapper(errors).hide();
535
- },
536
-
537
- valid: function () {
538
- return this.size() === 0;
539
- },
540
-
541
- size: function () {
542
- return this.errorList.length;
543
- },
544
-
545
- focusInvalid: function () {
546
- if (this.settings.focusInvalid) {
547
- try {
548
- $(this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
549
- .filter(":visible")
550
- .focus()
551
-
552
- // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
553
- .trigger("focusin");
554
- } catch (e) {
555
- }
556
- }
557
- },
558
-
559
- findLastActive: function () {
560
- var lastActive = this.lastActive;
561
- return lastActive && $.grep(this.errorList, function (n) {
562
- return n.element.name === lastActive.name;
563
- }).length === 1 && lastActive;
564
- },
565
-
566
- elements: function () {
567
- var validator = this,
568
- rulesCache = {};
569
-
570
- // Select all valid inputs inside the form (no submit or reset buttons)
571
- return $(this.currentForm)
572
- .find("input, select, textarea, [contenteditable]")
573
- .not(":submit, :reset, :image, :disabled")
574
- .not(this.settings.ignore)
575
- .filter(function () {
576
- var name = this.name || $(this).attr("name"); // For contenteditable
577
- if (!name && validator.settings.debug && window.console) {
578
- console.error("%o has no name assigned", this);
579
- }
580
-
581
- if (this.hasAttribute("contenteditable")) {
582
- this.form = $(this).closest("form")[ 0 ];
583
- }
584
-
585
- // Select only the first element for each name, and only those with rules specified
586
- if (name in rulesCache || !validator.objectLength($(this).rules())) {
587
- return false;
588
- }
589
-
590
- rulesCache[ name ] = true;
591
- return true;
592
- });
593
- },
594
-
595
- clean: function (selector) {
596
- return $(selector)[ 0 ];
597
- },
598
-
599
- errors: function () {
600
- var errorClass = this.settings.errorClass.split(" ").join(".");
601
- return $(this.settings.errorElement + "." + errorClass, this.errorContext);
602
- },
603
-
604
- resetInternals: function () {
605
- this.successList = [];
606
- this.errorList = [];
607
- this.errorMap = {};
608
- this.toShow = $([]);
609
- this.toHide = $([]);
610
- },
611
-
612
- reset: function () {
613
- this.resetInternals();
614
- this.currentElements = $([]);
615
- },
616
-
617
- prepareForm: function () {
618
- this.reset();
619
- this.toHide = this.errors().add(this.containers);
620
- },
621
-
622
- prepareElement: function (element) {
623
- this.reset();
624
- this.toHide = this.errorsFor(element);
625
- },
626
-
627
- elementValue: function (element) {
628
- var $element = $(element),
629
- type = element.type,
630
- val, idx;
631
-
632
- if (type === "radio" || type === "checkbox") {
633
- return this.findByName(element.name).filter(":checked").val();
634
- } else if (type === "number" && typeof element.validity !== "undefined") {
635
- return element.validity.badInput ? "NaN" : $element.val();
636
- }
637
-
638
- if (element.hasAttribute("contenteditable")) {
639
- val = $element.text();
640
- } else {
641
- val = $element.val();
642
- }
643
-
644
- if (type === "file") {
645
-
646
- // Modern browser (chrome & safari)
647
- if (val.substr(0, 12) === "C:\\fakepath\\") {
648
- return val.substr(12);
649
- }
650
-
651
- idx = val.lastIndexOf("/");
652
- if (idx >= 0) {
653
- return val.substr(idx + 1);
654
- }
655
-
656
- // Windows-based path
657
- idx = val.lastIndexOf("\\");
658
- if (idx >= 0) {
659
- return val.substr(idx + 1);
660
- }
661
-
662
- // Just the file name
663
- return val;
664
- }
665
-
666
- if (typeof val === "string") {
667
- return val.replace(/\r/g, "");
668
- }
669
- return val;
670
- },
671
-
672
- check: function (element) {
673
- element = this.validationTargetFor(this.clean(element));
674
-
675
- var rules = $(element).rules(),
676
- rulesCount = $.map(rules, function (n, i) {
677
- return i;
678
- }).length,
679
- dependencyMismatch = false,
680
- val = this.elementValue(element),
681
- result, method, rule;
682
- if (typeof rules.normalizer === "function") {
683
- val = rules.normalizer.call(element, val);
684
-
685
- if (typeof val !== "string") {
686
- throw new TypeError("The normalizer should return a string value.");
687
- }
688
- delete rules.normalizer;
689
- }
690
-
691
- for (method in rules) {
692
- rule = {method: method, parameters: rules[ method ]};
693
- try {
694
- result = $.validator.methods[ method ].call(this, val, element, rule.parameters);
695
- if (result === "dependency-mismatch" && rulesCount === 1) {
696
- dependencyMismatch = true;
697
- continue;
698
- }
699
- dependencyMismatch = false;
700
-
701
- if (result === "pending") {
702
- this.toHide = this.toHide.not(this.errorsFor(element));
703
- return;
704
- }
705
-
706
- if (!result) {
707
- this.formatAndAdd(element, rule);
708
- return false;
709
- }
710
- } catch (e) {
711
- if (this.settings.debug && window.console) {
712
- console.log("Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e);
713
- }
714
- if (e instanceof TypeError) {
715
- e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
716
- }
717
-
718
- throw e;
719
- }
720
- }
721
- if (dependencyMismatch) {
722
- return;
723
- }
724
- if (this.objectLength(rules)) {
725
- this.successList.push(element);
726
- }
727
- return true;
728
- },
729
-
730
- customDataMessage: function (element, method) {
731
- return $(element).data("msg" + method.charAt(0).toUpperCase() +
732
- method.substring(1).toLowerCase()) || $(element).data("msg");
733
- },
734
-
735
- // Return the custom message for the given element name and validation method
736
- customMessage: function (name, method) {
737
- var m = this.settings.messages[ name ];
738
- return m && (m.constructor === String ? m : m[ method ]);
739
- },
740
-
741
- // Return the first defined argument, allowing empty strings
742
- findDefined: function () {
743
- for (var i = 0; i < arguments.length; i++) {
744
- if (arguments[ i ] !== undefined) {
745
- return arguments[ i ];
746
- }
747
- }
748
- return undefined;
749
- },
750
-
751
- defaultMessage: function (element, rule) {
752
- var message = this.findDefined(
753
- this.customMessage(element.name, rule.method),
754
- this.customDataMessage(element, rule.method),
755
- // 'title' is never undefined, so handle empty string as undefined
756
- !this.settings.ignoreTitle && element.title || undefined,
757
- $.validator.messages[ rule.method ],
758
- "<strong>Warning: No message defined for " + element.name + "</strong>"
759
- ),
760
- theregex = /\$?\{(\d+)\}/g;
761
- if (typeof message === "function") {
762
- message = message.call(this, rule.parameters, element);
763
- } else if (theregex.test(message)) {
764
- message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
765
- }
766
-
767
- return message;
768
- },
769
-
770
- formatAndAdd: function (element, rule) {
771
- var message = this.defaultMessage(element, rule);
772
-
773
- this.errorList.push({
774
- message: message,
775
- element: element,
776
- method: rule.method
777
- });
778
-
779
- this.errorMap[ element.name ] = message;
780
- this.submitted[ element.name ] = message;
781
- },
782
-
783
- addWrapper: function (toToggle) {
784
- if (this.settings.wrapper) {
785
- toToggle = toToggle.add(toToggle.parent(this.settings.wrapper));
786
- }
787
- return toToggle;
788
- },
789
-
790
- defaultShowErrors: function () {
791
- var i, elements, error;
792
- for (i = 0; this.errorList[ i ]; i++) {
793
- error = this.errorList[ i ];
794
- if (this.settings.highlight) {
795
- this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass);
796
- }
797
- this.showLabel(error.element, error.message);
798
- }
799
- if (this.errorList.length) {
800
- this.toShow = this.toShow.add(this.containers);
801
- }
802
- if (this.settings.success) {
803
- for (i = 0; this.successList[ i ]; i++) {
804
- this.showLabel(this.successList[ i ]);
805
- }
806
- }
807
- if (this.settings.unhighlight) {
808
- for (i = 0, elements = this.validElements(); elements[ i ]; i++) {
809
- this.settings.unhighlight.call(this, elements[ i ], this.settings.errorClass, this.settings.validClass);
810
- }
811
- }
812
- this.toHide = this.toHide.not(this.toShow);
813
- this.hideErrors();
814
- this.addWrapper(this.toShow).show();
815
- },
816
-
817
- validElements: function () {
818
- return this.currentElements.not(this.invalidElements());
819
- },
820
-
821
- invalidElements: function () {
822
- return $(this.errorList).map(function () {
823
- return this.element;
824
- });
825
- },
826
-
827
- showLabel: function (element, message) {
828
- var place, group, errorID, v,
829
- error = this.errorsFor(element),
830
- elementID = this.idOrName(element),
831
- describedBy = $(element).attr("aria-describedby");
832
-
833
- if (error.length) {
834
-
835
- // Refresh error/success class
836
- error.removeClass(this.settings.validClass).addClass(this.settings.errorClass);
837
-
838
- // Replace message on existing label
839
- error.html(message);
840
- } else {
841
-
842
- // Create error element
843
- error = $("<" + this.settings.errorElement + ">")
844
- .attr("id", elementID + "-error")
845
- .addClass(this.settings.errorClass)
846
- .html(message || "");
847
-
848
- // Maintain reference to the element to be placed into the DOM
849
- place = error;
850
- if (this.settings.wrapper) {
851
- place = error.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
852
- }
853
- if (this.labelContainer.length) {
854
- this.labelContainer.append(place);
855
- } else if (this.settings.errorPlacement) {
856
- this.settings.errorPlacement(place, $(element));
857
- } else {
858
- place.insertAfter(element);
859
- }
860
-
861
- if (error.is("label")) {
862
- error.attr("for", elementID);
863
- } else if (error.parents("label[for='" + this.escapeCssMeta(elementID) + "']").length === 0) {
864
- errorID = error.attr("id");
865
- if (!describedBy) {
866
- describedBy = errorID;
867
- } else if (!describedBy.match(new RegExp("\\b" + this.escapeCssMeta(errorID) + "\\b"))) {
868
- describedBy += " " + errorID;
869
- }
870
- $(element).attr("aria-describedby", describedBy);
871
- group = this.groups[ element.name ];
872
- if (group) {
873
- v = this;
874
- $.each(v.groups, function (name, testgroup) {
875
- if (testgroup === group) {
876
- $("[name='" + v.escapeCssMeta(name) + "']", v.currentForm)
877
- .attr("aria-describedby", error.attr("id"));
878
- }
879
- });
880
- }
881
- }
882
- }
883
- if (!message && this.settings.success) {
884
- error.text("");
885
- if (typeof this.settings.success === "string") {
886
- error.addClass(this.settings.success);
887
- } else {
888
- this.settings.success(error, element);
889
- }
890
- }
891
- this.toShow = this.toShow.add(error);
892
- },
893
-
894
- errorsFor: function (element) {
895
- var name = this.escapeCssMeta(this.idOrName(element)),
896
- describer = $(element).attr("aria-describedby"),
897
- selector = "label[for='" + name + "'], label[for='" + name + "'] *";
898
- if (describer) {
899
- selector = selector + ", #" + this.escapeCssMeta(describer)
900
- .replace(/\s+/g, ", #");
901
- }
902
-
903
- return this
904
- .errors()
905
- .filter(selector);
906
- },
907
- escapeCssMeta: function (string) {
908
- return string.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1");
909
- },
910
-
911
- idOrName: function (element) {
912
- return this.groups[ element.name ] || (this.checkable(element) ? element.name : element.id || element.name);
913
- },
914
-
915
- validationTargetFor: function (element) {
916
-
917
- if (this.checkable(element)) {
918
- element = this.findByName(element.name);
919
- }
920
- return $(element).not(this.settings.ignore)[ 0 ];
921
- },
922
-
923
- checkable: function (element) {
924
- return (/radio|checkbox/i).test(element.type);
925
- },
926
-
927
- findByName: function (name) {
928
- return $(this.currentForm).find("[name='" + this.escapeCssMeta(name) + "']");
929
- },
930
-
931
- getLength: function (value, element) {
932
- switch (element.nodeName.toLowerCase()) {
933
- case "select":
934
- return $("option:selected", element).length;
935
- case "input":
936
- if (this.checkable(element)) {
937
- return this.findByName(element.name).filter(":checked").length;
938
- }
939
- }
940
- return value.length;
941
- },
942
-
943
- depend: function (param, element) {
944
- return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ](param, element) : true;
945
- },
946
-
947
- dependTypes: {
948
- "boolean": function (param) {
949
- return param;
950
- },
951
- "string": function (param, element) {
952
- return !!$(param, element.form).length;
953
- },
954
- "function": function (param, element) {
955
- return param(element);
956
- }
957
- },
958
-
959
- optional: function (element) {
960
- var val = this.elementValue(element);
961
- return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
962
- },
963
-
964
- startRequest: function (element) {
965
- if (!this.pending[ element.name ]) {
966
- this.pendingRequest++;
967
- $(element).addClass(this.settings.pendingClass);
968
- this.pending[ element.name ] = true;
969
- }
970
- },
971
- stopRequest: function (element, valid) {
972
- this.pendingRequest--;
973
- if (this.pendingRequest < 0) {
974
- this.pendingRequest = 0;
975
- }
976
- delete this.pending[ element.name ];
977
- $(element).removeClass(this.settings.pendingClass);
978
- if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) {
979
- $(this.currentForm).submit();
980
- this.formSubmitted = false;
981
- } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
982
- $(this.currentForm).triggerHandler("invalid-form", [this]);
983
- this.formSubmitted = false;
984
- }
985
- },
986
- previousValue: function (element, method) {
987
- return $.data(element, "previousValue") || $.data(element, "previousValue", {
988
- old: null,
989
- valid: true,
990
- message: this.defaultMessage(element, {method: method})
991
- });
992
- },
993
- destroy: function () {
994
- this.resetForm();
995
- $(this.currentForm)
996
- .off(".validate")
997
- .removeData("validator")
998
- .find(".validate-equalTo-blur")
999
- .off(".validate-equalTo")
1000
- .removeClass("validate-equalTo-blur");
1001
- }
1002
- },
1003
- classRuleSettings: {
1004
- required: {required: true},
1005
- email: {email: true},
1006
- url: {url: true},
1007
- date: {date: true},
1008
- dateISO: {dateISO: true},
1009
- number: {number: true},
1010
- digits: {digits: true},
1011
- creditcard: {creditcard: true}
1012
- },
1013
-
1014
- addClassRules: function (className, rules) {
1015
- if (className.constructor === String) {
1016
- this.classRuleSettings[ className ] = rules;
1017
- } else {
1018
- $.extend(this.classRuleSettings, className);
1019
- }
1020
- },
1021
-
1022
- classRules: function (element) {
1023
- var rules = {},
1024
- classes = $(element).attr("class");
1025
-
1026
- if (classes) {
1027
- $.each(classes.split(" "), function () {
1028
- if (this in $.validator.classRuleSettings) {
1029
- $.extend(rules, $.validator.classRuleSettings[ this ]);
1030
- }
1031
- });
1032
- }
1033
- return rules;
1034
- },
1035
-
1036
- normalizeAttributeRule: function (rules, type, method, value) {
1037
- if (/min|max|step/.test(method) && (type === null || /number|range|text/.test(type))) {
1038
- value = Number(value);
1039
- if (isNaN(value)) {
1040
- value = undefined;
1041
- }
1042
- }
1043
-
1044
- if (value || value === 0) {
1045
- rules[ method ] = value;
1046
- } else if (type === method && type !== "range") {
1047
- rules[ method ] = true;
1048
- }
1049
- },
1050
-
1051
- attributeRules: function (element) {
1052
- var rules = {},
1053
- $element = $(element),
1054
- type = element.getAttribute("type"),
1055
- method, value;
1056
-
1057
- for (method in $.validator.methods) {
1058
- if (method === "required") {
1059
- value = element.getAttribute(method);
1060
- if (value === "") {
1061
- value = true;
1062
- }
1063
- value = !!value;
1064
- } else {
1065
- value = $element.attr(method);
1066
- }
1067
- this.normalizeAttributeRule(rules, type, method, value);
1068
- }
1069
- if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
1070
- delete rules.maxlength;
1071
- }
1072
-
1073
- return rules;
1074
- },
1075
-
1076
- dataRules: function (element) {
1077
- var rules = {},
1078
- $element = $(element),
1079
- type = element.getAttribute("type"),
1080
- method, value;
1081
-
1082
- for (method in $.validator.methods) {
1083
- value = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase());
1084
- this.normalizeAttributeRule(rules, type, method, value);
1085
- }
1086
- return rules;
1087
- },
1088
-
1089
- staticRules: function (element) {
1090
- var rules = {},
1091
- validator = $.data(element.form, "validator");
1092
-
1093
- if (validator.settings.rules) {
1094
- rules = $.validator.normalizeRule(validator.settings.rules[ element.name ]) || {};
1095
- }
1096
- return rules;
1097
- },
1098
-
1099
- normalizeRules: function (rules, element) {
1100
- $.each(rules, function (prop, val) {
1101
- if (val === false) {
1102
- delete rules[ prop ];
1103
- return;
1104
- }
1105
- if (val.param || val.depends) {
1106
- var keepRule = true;
1107
- switch (typeof val.depends) {
1108
- case "string":
1109
- keepRule = !!$(val.depends, element.form).length;
1110
- break;
1111
- case "function":
1112
- keepRule = val.depends.call(element, element);
1113
- break;
1114
- }
1115
- if (keepRule) {
1116
- rules[ prop ] = val.param !== undefined ? val.param : true;
1117
- } else {
1118
- $.data(element.form, "validator").resetElements($(element));
1119
- delete rules[ prop ];
1120
- }
1121
- }
1122
- });
1123
- $.each(rules, function (rule, parameter) {
1124
- rules[ rule ] = $.isFunction(parameter) && rule !== "normalizer" ? parameter(element) : parameter;
1125
- });
1126
- $.each(["minlength", "maxlength"], function () {
1127
- if (rules[ this ]) {
1128
- rules[ this ] = Number(rules[ this ]);
1129
- }
1130
- });
1131
- $.each(["rangelength", "range"], function () {
1132
- var parts;
1133
- if (rules[ this ]) {
1134
- if ($.isArray(rules[ this ])) {
1135
- rules[ this ] = [Number(rules[ this ][ 0 ]), Number(rules[ this ][ 1 ])];
1136
- } else if (typeof rules[ this ] === "string") {
1137
- parts = rules[ this ].replace(/[\[\]]/g, "").split(/[\s,]+/);
1138
- rules[ this ] = [Number(parts[ 0 ]), Number(parts[ 1 ])];
1139
- }
1140
- }
1141
- });
1142
- if ($.validator.autoCreateRanges) {
1143
- if (rules.min != null && rules.max != null) {
1144
- rules.range = [rules.min, rules.max];
1145
- delete rules.min;
1146
- delete rules.max;
1147
- }
1148
- if (rules.minlength != null && rules.maxlength != null) {
1149
- rules.rangelength = [rules.minlength, rules.maxlength];
1150
- delete rules.minlength;
1151
- delete rules.maxlength;
1152
- }
1153
- }
1154
- return rules;
1155
- },
1156
- normalizeRule: function (data) {
1157
- if (typeof data === "string") {
1158
- var transformed = {};
1159
- $.each(data.split(/\s/), function () {
1160
- transformed[ this ] = true;
1161
- });
1162
- data = transformed;
1163
- }
1164
- return data;
1165
- },
1166
- addMethod: function (name, method, message) {
1167
- $.validator.methods[ name ] = method;
1168
- $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1169
- if (method.length < 3) {
1170
- $.validator.addClassRules(name, $.validator.normalizeRule(name));
1171
- }
1172
- },
1173
- methods: {
1174
- required: function (value, element, param) {
1175
- if (!this.depend(param, element)) {
1176
- return "dependency-mismatch";
1177
- }
1178
- if (element.nodeName.toLowerCase() === "select") {
1179
- var val = $(element).val();
1180
- return val && val.length > 0;
1181
- }
1182
- if (this.checkable(element)) {
1183
- return this.getLength(value, element) > 0;
1184
- }
1185
- return value.length > 0;
1186
- },
1187
- email: function (value, element) {
1188
- return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
1189
- },
1190
- url: function (value, element) {
1191
- return this.optional(element) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
1192
- },
1193
- date: function (value, element) {
1194
- return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1195
- },
1196
- dateISO: function (value, element) {
1197
- return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
1198
- },
1199
- number: function (value, element) {
1200
- return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1201
- },
1202
- digits: function (value, element) {
1203
- return this.optional(element) || /^\d+$/.test(value);
1204
- },
1205
- minlength: function (value, element, param) {
1206
- var length = $.isArray(value) ? value.length : this.getLength(value, element);
1207
- return this.optional(element) || length >= param;
1208
- },
1209
- maxlength: function (value, element, param) {
1210
- var length = $.isArray(value) ? value.length : this.getLength(value, element);
1211
- return this.optional(element) || length <= param;
1212
- },
1213
- rangelength: function (value, element, param) {
1214
- var length = $.isArray(value) ? value.length : this.getLength(value, element);
1215
- return this.optional(element) || (length >= param[ 0 ] && length <= param[ 1 ]);
1216
- },
1217
- min: function (value, element, param) {
1218
- return this.optional(element) || value >= param;
1219
- },
1220
- max: function (value, element, param) {
1221
- return this.optional(element) || value <= param;
1222
- },
1223
- range: function (value, element, param) {
1224
- return this.optional(element) || (value >= param[ 0 ] && value <= param[ 1 ]);
1225
- },
1226
- step: function (value, element, param) {
1227
- var type = $(element).attr("type"),
1228
- errorMessage = "Step attribute on input type " + type + " is not supported.",
1229
- supportedTypes = ["text", "number", "range"],
1230
- re = new RegExp("\\b" + type + "\\b"),
1231
- notSupported = type && !re.test(supportedTypes.join());
1232
- if (notSupported) {
1233
- throw new Error(errorMessage);
1234
- }
1235
- return this.optional(element) || (value % param === 0);
1236
- },
1237
- equalTo: function (value, element, param) {
1238
- var target = $(param);
1239
- if (this.settings.onfocusout && target.not(".validate-equalTo-blur").length) {
1240
- target.addClass("validate-equalTo-blur").on("blur.validate-equalTo", function () {
1241
- $(element).valid();
1242
- });
1243
- }
1244
- return value === target.val();
1245
- },
1246
- remote: function (value, element, param, method) {
1247
- if (this.optional(element)) {
1248
- return "dependency-mismatch";
1249
- }
1250
-
1251
- method = typeof method === "string" && method || "remote";
1252
-
1253
- var previous = this.previousValue(element, method),
1254
- validator, data, optionDataString;
1255
-
1256
- if (!this.settings.messages[ element.name ]) {
1257
- this.settings.messages[ element.name ] = {};
1258
- }
1259
- previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
1260
- this.settings.messages[ element.name ][ method ] = previous.message;
1261
-
1262
- param = typeof param === "string" && {url: param} || param;
1263
- optionDataString = $.param($.extend({data: value}, param.data));
1264
- if (previous.old === optionDataString) {
1265
- return previous.valid;
1266
- }
1267
-
1268
- previous.old = optionDataString;
1269
- validator = this;
1270
- this.startRequest(element);
1271
- data = {};
1272
- data[ element.name ] = value;
1273
- $.ajax($.extend(true, {
1274
- mode: "abort",
1275
- port: "validate" + element.name,
1276
- dataType: "json",
1277
- data: data,
1278
- context: validator.currentForm,
1279
- success: function (response) {
1280
- var valid = response === true || response === "true",
1281
- errors, message, submitted;
1282
-
1283
- validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
1284
- if (valid) {
1285
- submitted = validator.formSubmitted;
1286
- validator.resetInternals();
1287
- validator.toHide = validator.errorsFor(element);
1288
- validator.formSubmitted = submitted;
1289
- validator.successList.push(element);
1290
- validator.invalid[ element.name ] = false;
1291
- validator.showErrors();
1292
- } else {
1293
- errors = {};
1294
- message = response || validator.defaultMessage(element, {method: method, parameters: value});
1295
- errors[ element.name ] = previous.message = message;
1296
- validator.invalid[ element.name ] = true;
1297
- validator.showErrors(errors);
1298
- }
1299
- previous.valid = valid;
1300
- validator.stopRequest(element, valid);
1301
- }
1302
- }, param));
1303
- return "pending";
1304
- }
1305
- }
1306
- });
1307
- var pendingRequests = {},
1308
- ajax;
1309
- if ($.ajaxPrefilter) {
1310
- $.ajaxPrefilter(function (settings, _, xhr) {
1311
- var port = settings.port;
1312
- if (settings.mode === "abort") {
1313
- if (pendingRequests[ port ]) {
1314
- pendingRequests[ port ].abort();
1315
- }
1316
- pendingRequests[ port ] = xhr;
1317
- }
1318
- });
1319
- } else {
1320
- ajax = $.ajax;
1321
- $.ajax = function (settings) {
1322
- var mode = ("mode" in settings ? settings : $.ajaxSettings).mode,
1323
- port = ("port" in settings ? settings : $.ajaxSettings).port;
1324
- if (mode === "abort") {
1325
- if (pendingRequests[ port ]) {
1326
- pendingRequests[ port ].abort();
1327
- }
1328
- pendingRequests[ port ] = ajax.apply(this, arguments);
1329
- return pendingRequests[ port ];
1330
- }
1331
- return ajax.apply(this, arguments);
1332
- };
1333
- }
1334
- }));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery Validation Plugin v1.17.0
3
+ *
4
+ * https://jqueryvalidation.org/
5
+ *
6
+ * Copyright (c) 2017 Jörn Zaefferer
7
+ * Released under the MIT license
8
+ */
9
+ (function (factory) {
10
+ if (typeof define === "function" && define.amd) {
11
+ define(["jquery"], factory);
12
+ } else if (typeof module === "object" && module.exports) {
13
+ module.exports = factory(require("jquery"));
14
+ } else {
15
+ factory(jQuery);
16
+ }
17
+ }(function ($) {
18
+
19
+ $.extend($.fn, {
20
+
21
+ // https://jqueryvalidation.org/validate/
22
+ validate: function (options) {
23
+
24
+ // If nothing is selected, return nothing; can't chain anyway
25
+ if (!this.length) {
26
+ if (options && options.debug && window.console) {
27
+ console.warn("Nothing selected, can't validate, returning nothing.");
28
+ }
29
+ return;
30
+ }
31
+
32
+ // Check if a validator for this form was already created
33
+ var validator = $.data(this[ 0 ], "validator");
34
+ if (validator) {
35
+ return validator;
36
+ }
37
+
38
+ // Add novalidate tag if HTML5.
39
+ this.attr("novalidate", "novalidate");
40
+
41
+ validator = new $.validator(options, this[ 0 ]);
42
+ $.data(this[ 0 ], "validator", validator);
43
+
44
+ if (validator.settings.onsubmit) {
45
+
46
+ this.on("click.validate", ":submit", function (event) {
47
+
48
+ // Track the used submit button to properly handle scripted
49
+ // submits later.
50
+ validator.submitButton = event.currentTarget;
51
+
52
+ // Allow suppressing validation by adding a cancel class to the submit button
53
+ if ($(this).hasClass("cancel")) {
54
+ validator.cancelSubmit = true;
55
+ }
56
+
57
+ // Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
58
+ if ($(this).attr("formnovalidate") !== undefined) {
59
+ validator.cancelSubmit = true;
60
+ }
61
+ });
62
+
63
+ // Validate the form on submit
64
+ this.on("submit.validate", function (event) {
65
+ if (validator.settings.debug) {
66
+
67
+ // Prevent form submit to be able to see console output
68
+ event.preventDefault();
69
+ }
70
+ function handle() {
71
+ var hidden, result;
72
+
73
+ // Insert a hidden input as a replacement for the missing submit button
74
+ // The hidden input is inserted in two cases:
75
+ // - A user defined a `submitHandler`
76
+ // - There was a pending request due to `remote` method and `stopRequest()`
77
+ // was called to submit the form in case it's valid
78
+ if (validator.submitButton && (validator.settings.submitHandler || validator.formSubmitted)) {
79
+ hidden = $("<input type='hidden'/>")
80
+ .attr("name", validator.submitButton.name)
81
+ .val($(validator.submitButton).val())
82
+ .appendTo(validator.currentForm);
83
+ }
84
+
85
+ if (validator.settings.submitHandler) {
86
+ result = validator.settings.submitHandler.call(validator, validator.currentForm, event);
87
+ if (hidden) {
88
+
89
+ // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
90
+ hidden.remove();
91
+ }
92
+ if (result !== undefined) {
93
+ return result;
94
+ }
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+
100
+ // Prevent submit for invalid forms or custom submit handlers
101
+ if (validator.cancelSubmit) {
102
+ validator.cancelSubmit = false;
103
+ return handle();
104
+ }
105
+ if (validator.form()) {
106
+ if (validator.pendingRequest) {
107
+ validator.formSubmitted = true;
108
+ return false;
109
+ }
110
+ return handle();
111
+ } else {
112
+ validator.focusInvalid();
113
+ return false;
114
+ }
115
+ });
116
+ }
117
+
118
+ return validator;
119
+ },
120
+
121
+ // https://jqueryvalidation.org/valid/
122
+ valid: function () {
123
+ var valid, validator, errorList;
124
+
125
+ if ($(this[ 0 ]).is("form")) {
126
+ valid = this.validate().form();
127
+ } else {
128
+ errorList = [];
129
+ valid = true;
130
+ validator = $(this[ 0 ].form).validate();
131
+ this.each(function () {
132
+ valid = validator.element(this) && valid;
133
+ if (!valid) {
134
+ errorList = errorList.concat(validator.errorList);
135
+ }
136
+ });
137
+ validator.errorList = errorList;
138
+ }
139
+ return valid;
140
+ },
141
+
142
+ // https://jqueryvalidation.org/rules/
143
+ rules: function (command, argument) {
144
+ var element = this[ 0 ],
145
+ settings, staticRules, existingRules, data, param, filtered;
146
+
147
+ // If nothing is selected, return empty object; can't chain anyway
148
+ if (element == null) {
149
+ return;
150
+ }
151
+
152
+ if (!element.form && element.hasAttribute("contenteditable")) {
153
+ element.form = this.closest("form")[ 0 ];
154
+ element.name = this.attr("name");
155
+ }
156
+
157
+ if (element.form == null) {
158
+ return;
159
+ }
160
+
161
+ if (command) {
162
+ settings = $.data(element.form, "validator").settings;
163
+ staticRules = settings.rules;
164
+ existingRules = $.validator.staticRules(element);
165
+ switch (command) {
166
+ case "add":
167
+ $.extend(existingRules, $.validator.normalizeRule(argument));
168
+
169
+ // Remove messages from rules, but allow them to be set separately
170
+ delete existingRules.messages;
171
+ staticRules[ element.name ] = existingRules;
172
+ if (argument.messages) {
173
+ settings.messages[ element.name ] = $.extend(settings.messages[ element.name ], argument.messages);
174
+ }
175
+ break;
176
+ case "remove":
177
+ if (!argument) {
178
+ delete staticRules[ element.name ];
179
+ return existingRules;
180
+ }
181
+ filtered = {};
182
+ $.each(argument.split(/\s/), function (index, method) {
183
+ filtered[ method ] = existingRules[ method ];
184
+ delete existingRules[ method ];
185
+ });
186
+ return filtered;
187
+ }
188
+ }
189
+
190
+ data = $.validator.normalizeRules(
191
+ $.extend(
192
+ {},
193
+ $.validator.classRules(element),
194
+ $.validator.attributeRules(element),
195
+ $.validator.dataRules(element),
196
+ $.validator.staticRules(element)
197
+ ), element);
198
+
199
+ // Make sure required is at front
200
+ if (data.required) {
201
+ param = data.required;
202
+ delete data.required;
203
+ data = $.extend({required: param}, data);
204
+ }
205
+
206
+ // Make sure remote is at back
207
+ if (data.remote) {
208
+ param = data.remote;
209
+ delete data.remote;
210
+ data = $.extend(data, {remote: param});
211
+ }
212
+
213
+ return data;
214
+ }
215
+ });
216
+
217
+ // Custom selectors
218
+ $.extend($.expr.pseudos || $.expr[ ":" ], {// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
219
+
220
+ // https://jqueryvalidation.org/blank-selector/
221
+ blank: function (a) {
222
+ return !$.trim("" + $(a).val());
223
+ },
224
+
225
+ // https://jqueryvalidation.org/filled-selector/
226
+ filled: function (a) {
227
+ var val = $(a).val();
228
+ return val !== null && !!$.trim("" + val);
229
+ },
230
+
231
+ // https://jqueryvalidation.org/unchecked-selector/
232
+ unchecked: function (a) {
233
+ return !$(a).prop("checked");
234
+ }
235
+ });
236
+
237
+ // Constructor for validator
238
+ $.validator = function (options, form) {
239
+ this.settings = $.extend(true, {}, $.validator.defaults, options);
240
+ this.currentForm = form;
241
+ this.init();
242
+ };
243
+
244
+ // https://jqueryvalidation.org/jQuery.validator.format/
245
+ $.validator.format = function (source, params) {
246
+ if (arguments.length === 1) {
247
+ return function () {
248
+ var args = $.makeArray(arguments);
249
+ args.unshift(source);
250
+ return $.validator.format.apply(this, args);
251
+ };
252
+ }
253
+ if (params === undefined) {
254
+ return source;
255
+ }
256
+ if (arguments.length > 2 && params.constructor !== Array) {
257
+ params = $.makeArray(arguments).slice(1);
258
+ }
259
+ if (params.constructor !== Array) {
260
+ params = [params];
261
+ }
262
+ $.each(params, function (i, n) {
263
+ source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () {
264
+ return n;
265
+ });
266
+ });
267
+ return source;
268
+ };
269
+
270
+ $.extend($.validator, {
271
+
272
+ defaults: {
273
+ messages: {},
274
+ groups: {},
275
+ rules: {},
276
+ errorClass: "error",
277
+ pendingClass: "pending",
278
+ validClass: "valid",
279
+ errorElement: "label",
280
+ focusCleanup: false,
281
+ focusInvalid: true,
282
+ errorContainer: $([]),
283
+ errorLabelContainer: $([]),
284
+ onsubmit: true,
285
+ ignore: ":hidden",
286
+ ignoreTitle: false,
287
+ onfocusin: function (element) {
288
+ this.lastActive = element;
289
+
290
+ // Hide error label and remove error class on focus if enabled
291
+ if (this.settings.focusCleanup) {
292
+ if (this.settings.unhighlight) {
293
+ this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass);
294
+ }
295
+ this.hideThese(this.errorsFor(element));
296
+ }
297
+ },
298
+ onfocusout: function (element) {
299
+ if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
300
+ this.element(element);
301
+ }
302
+ },
303
+ onkeyup: function (element, event) {
304
+
305
+ // Avoid revalidate the field when pressing one of the following keys
306
+ // Shift => 16
307
+ // Ctrl => 17
308
+ // Alt => 18
309
+ // Caps lock => 20
310
+ // End => 35
311
+ // Home => 36
312
+ // Left arrow => 37
313
+ // Up arrow => 38
314
+ // Right arrow => 39
315
+ // Down arrow => 40
316
+ // Insert => 45
317
+ // Num lock => 144
318
+ // AltGr key => 225
319
+ var excludedKeys = [
320
+ 16, 17, 18, 20, 35, 36, 37,
321
+ 38, 39, 40, 45, 144, 225
322
+ ];
323
+
324
+ if (event.which === 9 && this.elementValue(element) === "" || $.inArray(event.keyCode, excludedKeys) !== -1) {
325
+ return;
326
+ } else if (element.name in this.submitted || element.name in this.invalid) {
327
+ this.element(element);
328
+ }
329
+ },
330
+ onclick: function (element) {
331
+
332
+ // Click on selects, radiobuttons and checkboxes
333
+ if (element.name in this.submitted) {
334
+ this.element(element);
335
+
336
+ // Or option elements, check parent select in that case
337
+ } else if (element.parentNode.name in this.submitted) {
338
+ this.element(element.parentNode);
339
+ }
340
+ },
341
+ highlight: function (element, errorClass, validClass) {
342
+ if (element.type === "radio") {
343
+ this.findByName(element.name).addClass(errorClass).removeClass(validClass);
344
+ } else {
345
+ $(element).addClass(errorClass).removeClass(validClass);
346
+ }
347
+ },
348
+ unhighlight: function (element, errorClass, validClass) {
349
+ if (element.type === "radio") {
350
+ this.findByName(element.name).removeClass(errorClass).addClass(validClass);
351
+ } else {
352
+ $(element).removeClass(errorClass).addClass(validClass);
353
+ }
354
+ }
355
+ },
356
+
357
+ // https://jqueryvalidation.org/jQuery.validator.setDefaults/
358
+ setDefaults: function (settings) {
359
+ $.extend($.validator.defaults, settings);
360
+ },
361
+
362
+ messages: {
363
+ required: "This field is required.",
364
+ remote: "Please fix this field.",
365
+ email: "Please enter a valid email address.",
366
+ url: "Please enter a valid URL.",
367
+ date: "Please enter a valid date.",
368
+ dateISO: "Please enter a valid date (ISO).",
369
+ number: "Please enter a valid number.",
370
+ digits: "Please enter only digits.",
371
+ equalTo: "Please enter the same value again.",
372
+ maxlength: $.validator.format("Please enter no more than {0} characters."),
373
+ minlength: $.validator.format("Please enter at least {0} characters."),
374
+ rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
375
+ range: $.validator.format("Please enter a value between {0} and {1}."),
376
+ max: $.validator.format("Please enter a value less than or equal to {0}."),
377
+ min: $.validator.format("Please enter a value greater than or equal to {0}."),
378
+ step: $.validator.format("Please enter a multiple of {0}.")
379
+ },
380
+
381
+ autoCreateRanges: false,
382
+
383
+ prototype: {
384
+
385
+ init: function () {
386
+ this.labelContainer = $(this.settings.errorLabelContainer);
387
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
388
+ this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer);
389
+ this.submitted = {};
390
+ this.valueCache = {};
391
+ this.pendingRequest = 0;
392
+ this.pending = {};
393
+ this.invalid = {};
394
+ this.reset();
395
+
396
+ var groups = (this.groups = {}),
397
+ rules;
398
+ $.each(this.settings.groups, function (key, value) {
399
+ if (typeof value === "string") {
400
+ value = value.split(/\s/);
401
+ }
402
+ $.each(value, function (index, name) {
403
+ groups[ name ] = key;
404
+ });
405
+ });
406
+ rules = this.settings.rules;
407
+ $.each(rules, function (key, value) {
408
+ rules[ key ] = $.validator.normalizeRule(value);
409
+ });
410
+
411
+ function delegate(event) {
412
+
413
+ // Set form expando on contenteditable
414
+ if (!this.form && this.hasAttribute("contenteditable")) {
415
+ this.form = $(this).closest("form")[ 0 ];
416
+ this.name = $(this).attr("name");
417
+ }
418
+
419
+ var validator = $.data(this.form, "validator"),
420
+ eventType = "on" + event.type.replace(/^validate/, ""),
421
+ settings = validator.settings;
422
+ if (settings[ eventType ] && !$(this).is(settings.ignore)) {
423
+ settings[ eventType ].call(validator, this, event);
424
+ }
425
+ }
426
+
427
+ $(this.currentForm)
428
+ .on("focusin.validate focusout.validate keyup.validate",
429
+ ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
430
+ "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
431
+ "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
432
+ "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate)
433
+
434
+ // Support: Chrome, oldIE
435
+ // "select" is provided as event.target when clicking a option
436
+ .on("click.validate", "select, option, [type='radio'], [type='checkbox']", delegate);
437
+
438
+ if (this.settings.invalidHandler) {
439
+ $(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler);
440
+ }
441
+ },
442
+
443
+ // https://jqueryvalidation.org/Validator.form/
444
+ form: function () {
445
+ this.checkForm();
446
+ $.extend(this.submitted, this.errorMap);
447
+ this.invalid = $.extend({}, this.errorMap);
448
+ if (!this.valid()) {
449
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
450
+ }
451
+ this.showErrors();
452
+ return this.valid();
453
+ },
454
+
455
+ checkForm: function () {
456
+ this.prepareForm();
457
+ for (var i = 0, elements = (this.currentElements = this.elements()); elements[ i ]; i++) {
458
+ this.check(elements[ i ]);
459
+ }
460
+ return this.valid();
461
+ },
462
+
463
+ // https://jqueryvalidation.org/Validator.element/
464
+ element: function (element) {
465
+ var cleanElement = this.clean(element),
466
+ checkElement = this.validationTargetFor(cleanElement),
467
+ v = this,
468
+ result = true,
469
+ rs, group;
470
+
471
+ if (checkElement === undefined) {
472
+ delete this.invalid[ cleanElement.name ];
473
+ } else {
474
+ this.prepareElement(checkElement);
475
+ this.currentElements = $(checkElement);
476
+
477
+ // If this element is grouped, then validate all group elements already
478
+ // containing a value
479
+ group = this.groups[ checkElement.name ];
480
+ if (group) {
481
+ $.each(this.groups, function (name, testgroup) {
482
+ if (testgroup === group && name !== checkElement.name) {
483
+ cleanElement = v.validationTargetFor(v.clean(v.findByName(name)));
484
+ if (cleanElement && cleanElement.name in v.invalid) {
485
+ v.currentElements.push(cleanElement);
486
+ result = v.check(cleanElement) && result;
487
+ }
488
+ }
489
+ });
490
+ }
491
+
492
+ rs = this.check(checkElement) !== false;
493
+ result = result && rs;
494
+ if (rs) {
495
+ this.invalid[ checkElement.name ] = false;
496
+ } else {
497
+ this.invalid[ checkElement.name ] = true;
498
+ }
499
+
500
+ if (!this.numberOfInvalids()) {
501
+
502
+ // Hide error containers on last error
503
+ this.toHide = this.toHide.add(this.containers);
504
+ }
505
+ this.showErrors();
506
+
507
+ // Add aria-invalid status for screen readers
508
+ $(element).attr("aria-invalid", !rs);
509
+ }
510
+
511
+ return result;
512
+ },
513
+
514
+ // https://jqueryvalidation.org/Validator.showErrors/
515
+ showErrors: function (errors) {
516
+ if (errors) {
517
+ var validator = this;
518
+
519
+ // Add items to error list and map
520
+ $.extend(this.errorMap, errors);
521
+ this.errorList = $.map(this.errorMap, function (message, name) {
522
+ return {
523
+ message: message,
524
+ element: validator.findByName(name)[ 0 ]
525
+ };
526
+ });
527
+
528
+ // Remove items from success list
529
+ this.successList = $.grep(this.successList, function (element) {
530
+ return !(element.name in errors);
531
+ });
532
+ }
533
+ if (this.settings.showErrors) {
534
+ this.settings.showErrors.call(this, this.errorMap, this.errorList);
535
+ } else {
536
+ this.defaultShowErrors();
537
+ }
538
+ },
539
+
540
+ // https://jqueryvalidation.org/Validator.resetForm/
541
+ resetForm: function () {
542
+ if ($.fn.resetForm) {
543
+ $(this.currentForm).resetForm();
544
+ }
545
+ this.invalid = {};
546
+ this.submitted = {};
547
+ this.prepareForm();
548
+ this.hideErrors();
549
+ var elements = this.elements()
550
+ .removeData("previousValue")
551
+ .removeAttr("aria-invalid");
552
+
553
+ this.resetElements(elements);
554
+ },
555
+
556
+ resetElements: function (elements) {
557
+ var i;
558
+
559
+ if (this.settings.unhighlight) {
560
+ for (i = 0; elements[ i ]; i++) {
561
+ this.settings.unhighlight.call(this, elements[ i ],
562
+ this.settings.errorClass, "");
563
+ this.findByName(elements[ i ].name).removeClass(this.settings.validClass);
564
+ }
565
+ } else {
566
+ elements
567
+ .removeClass(this.settings.errorClass)
568
+ .removeClass(this.settings.validClass);
569
+ }
570
+ },
571
+
572
+ numberOfInvalids: function () {
573
+ return this.objectLength(this.invalid);
574
+ },
575
+
576
+ objectLength: function (obj) {
577
+ /* jshint unused: false */
578
+ var count = 0,
579
+ i;
580
+ for (i in obj) {
581
+
582
+ // This check allows counting elements with empty error
583
+ // message as invalid elements
584
+ if (obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false) {
585
+ count++;
586
+ }
587
+ }
588
+ return count;
589
+ },
590
+
591
+ hideErrors: function () {
592
+ this.hideThese(this.toHide);
593
+ },
594
+
595
+ hideThese: function (errors) {
596
+ errors.not(this.containers).text("");
597
+ this.addWrapper(errors).hide();
598
+ },
599
+
600
+ valid: function () {
601
+ return this.size() === 0;
602
+ },
603
+
604
+ size: function () {
605
+ return this.errorList.length;
606
+ },
607
+
608
+ focusInvalid: function () {
609
+ if (this.settings.focusInvalid) {
610
+ try {
611
+ $(this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [])
612
+ .filter(":visible")
613
+ .focus()
614
+
615
+ // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
616
+ .trigger("focusin");
617
+ } catch (e) {
618
+
619
+ // Ignore IE throwing errors when focusing hidden elements
620
+ }
621
+ }
622
+ },
623
+
624
+ findLastActive: function () {
625
+ var lastActive = this.lastActive;
626
+ return lastActive && $.grep(this.errorList, function (n) {
627
+ return n.element.name === lastActive.name;
628
+ }).length === 1 && lastActive;
629
+ },
630
+
631
+ elements: function () {
632
+ var validator = this,
633
+ rulesCache = {};
634
+
635
+ // Select all valid inputs inside the form (no submit or reset buttons)
636
+ return $(this.currentForm)
637
+ .find("input, select, textarea, [contenteditable]")
638
+ .not(":submit, :reset, :image, :disabled")
639
+ .not(this.settings.ignore)
640
+ .filter(function () {
641
+ var name = this.name || $(this).attr("name"); // For contenteditable
642
+ if (!name && validator.settings.debug && window.console) {
643
+ console.error("%o has no name assigned", this);
644
+ }
645
+
646
+ // Set form expando on contenteditable
647
+ if (this.hasAttribute("contenteditable")) {
648
+ this.form = $(this).closest("form")[ 0 ];
649
+ this.name = name;
650
+ }
651
+
652
+ // Select only the first element for each name, and only those with rules specified
653
+ if (name in rulesCache || !validator.objectLength($(this).rules())) {
654
+ return false;
655
+ }
656
+
657
+ rulesCache[ name ] = true;
658
+ return true;
659
+ });
660
+ },
661
+
662
+ clean: function (selector) {
663
+ return $(selector)[ 0 ];
664
+ },
665
+
666
+ errors: function () {
667
+ var errorClass = this.settings.errorClass.split(" ").join(".");
668
+ return $(this.settings.errorElement + "." + errorClass, this.errorContext);
669
+ },
670
+
671
+ resetInternals: function () {
672
+ this.successList = [];
673
+ this.errorList = [];
674
+ this.errorMap = {};
675
+ this.toShow = $([]);
676
+ this.toHide = $([]);
677
+ },
678
+
679
+ reset: function () {
680
+ this.resetInternals();
681
+ this.currentElements = $([]);
682
+ },
683
+
684
+ prepareForm: function () {
685
+ this.reset();
686
+ this.toHide = this.errors().add(this.containers);
687
+ },
688
+
689
+ prepareElement: function (element) {
690
+ this.reset();
691
+ this.toHide = this.errorsFor(element);
692
+ },
693
+
694
+ elementValue: function (element) {
695
+ var $element = $(element),
696
+ type = element.type,
697
+ val, idx;
698
+
699
+ if (type === "radio" || type === "checkbox") {
700
+ return this.findByName(element.name).filter(":checked").val();
701
+ } else if (type === "number" && typeof element.validity !== "undefined") {
702
+ return element.validity.badInput ? "NaN" : $element.val();
703
+ }
704
+
705
+ if (element.hasAttribute("contenteditable")) {
706
+ val = $element.text();
707
+ } else {
708
+ val = $element.val();
709
+ }
710
+
711
+ if (type === "file") {
712
+
713
+ // Modern browser (chrome & safari)
714
+ if (val.substr(0, 12) === "C:\\fakepath\\") {
715
+ return val.substr(12);
716
+ }
717
+
718
+ // Legacy browsers
719
+ // Unix-based path
720
+ idx = val.lastIndexOf("/");
721
+ if (idx >= 0) {
722
+ return val.substr(idx + 1);
723
+ }
724
+
725
+ // Windows-based path
726
+ idx = val.lastIndexOf("\\");
727
+ if (idx >= 0) {
728
+ return val.substr(idx + 1);
729
+ }
730
+
731
+ // Just the file name
732
+ return val;
733
+ }
734
+
735
+ if (typeof val === "string") {
736
+ return val.replace(/\r/g, "");
737
+ }
738
+ return val;
739
+ },
740
+
741
+ check: function (element) {
742
+ element = this.validationTargetFor(this.clean(element));
743
+
744
+ var rules = $(element).rules(),
745
+ rulesCount = $.map(rules, function (n, i) {
746
+ return i;
747
+ }).length,
748
+ dependencyMismatch = false,
749
+ val = this.elementValue(element),
750
+ result, method, rule, normalizer;
751
+
752
+ // Prioritize the local normalizer defined for this element over the global one
753
+ // if the former exists, otherwise user the global one in case it exists.
754
+ if (typeof rules.normalizer === "function") {
755
+ normalizer = rules.normalizer;
756
+ } else if (typeof this.settings.normalizer === "function") {
757
+ normalizer = this.settings.normalizer;
758
+ }
759
+
760
+ // If normalizer is defined, then call it to retreive the changed value instead
761
+ // of using the real one.
762
+ // Note that `this` in the normalizer is `element`.
763
+ if (normalizer) {
764
+ val = normalizer.call(element, val);
765
+
766
+ if (typeof val !== "string") {
767
+ throw new TypeError("The normalizer should return a string value.");
768
+ }
769
+
770
+ // Delete the normalizer from rules to avoid treating it as a pre-defined method.
771
+ delete rules.normalizer;
772
+ }
773
+
774
+ for (method in rules) {
775
+ rule = {method: method, parameters: rules[ method ]};
776
+ try {
777
+ result = $.validator.methods[ method ].call(this, val, element, rule.parameters);
778
+
779
+ // If a method indicates that the field is optional and therefore valid,
780
+ // don't mark it as valid when there are no other rules
781
+ if (result === "dependency-mismatch" && rulesCount === 1) {
782
+ dependencyMismatch = true;
783
+ continue;
784
+ }
785
+ dependencyMismatch = false;
786
+
787
+ if (result === "pending") {
788
+ this.toHide = this.toHide.not(this.errorsFor(element));
789
+ return;
790
+ }
791
+
792
+ if (!result) {
793
+ this.formatAndAdd(element, rule);
794
+ return false;
795
+ }
796
+ } catch (e) {
797
+ if (this.settings.debug && window.console) {
798
+ console.log("Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e);
799
+ }
800
+ if (e instanceof TypeError) {
801
+ e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
802
+ }
803
+
804
+ throw e;
805
+ }
806
+ }
807
+ if (dependencyMismatch) {
808
+ return;
809
+ }
810
+ if (this.objectLength(rules)) {
811
+ this.successList.push(element);
812
+ }
813
+ return true;
814
+ },
815
+
816
+ // Return the custom message for the given element and validation method
817
+ // specified in the element's HTML5 data attribute
818
+ // return the generic message if present and no method specific message is present
819
+ customDataMessage: function (element, method) {
820
+ return $(element).data("msg" + method.charAt(0).toUpperCase() +
821
+ method.substring(1).toLowerCase()) || $(element).data("msg");
822
+ },
823
+
824
+ // Return the custom message for the given element name and validation method
825
+ customMessage: function (name, method) {
826
+ var m = this.settings.messages[ name ];
827
+ return m && (m.constructor === String ? m : m[ method ]);
828
+ },
829
+
830
+ // Return the first defined argument, allowing empty strings
831
+ findDefined: function () {
832
+ for (var i = 0; i < arguments.length; i++) {
833
+ if (arguments[ i ] !== undefined) {
834
+ return arguments[ i ];
835
+ }
836
+ }
837
+ return undefined;
838
+ },
839
+
840
+ // The second parameter 'rule' used to be a string, and extended to an object literal
841
+ // of the following form:
842
+ // rule = {
843
+ // method: "method name",
844
+ // parameters: "the given method parameters"
845
+ // }
846
+ //
847
+ // The old behavior still supported, kept to maintain backward compatibility with
848
+ // old code, and will be removed in the next major release.
849
+ defaultMessage: function (element, rule) {
850
+ if (typeof rule === "string") {
851
+ rule = {method: rule};
852
+ }
853
+
854
+ var message = this.findDefined(
855
+ this.customMessage(element.name, rule.method),
856
+ this.customDataMessage(element, rule.method),
857
+ // 'title' is never undefined, so handle empty string as undefined
858
+ !this.settings.ignoreTitle && element.title || undefined,
859
+ $.validator.messages[ rule.method ],
860
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
861
+ ),
862
+ theregex = /\$?\{(\d+)\}/g;
863
+ if (typeof message === "function") {
864
+ message = message.call(this, rule.parameters, element);
865
+ } else if (theregex.test(message)) {
866
+ message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
867
+ }
868
+
869
+ return message;
870
+ },
871
+
872
+ formatAndAdd: function (element, rule) {
873
+ var message = this.defaultMessage(element, rule);
874
+
875
+ this.errorList.push({
876
+ message: message,
877
+ element: element,
878
+ method: rule.method
879
+ });
880
+
881
+ this.errorMap[ element.name ] = message;
882
+ this.submitted[ element.name ] = message;
883
+ },
884
+
885
+ addWrapper: function (toToggle) {
886
+ if (this.settings.wrapper) {
887
+ toToggle = toToggle.add(toToggle.parent(this.settings.wrapper));
888
+ }
889
+ return toToggle;
890
+ },
891
+
892
+ defaultShowErrors: function () {
893
+ var i, elements, error;
894
+ for (i = 0; this.errorList[ i ]; i++) {
895
+ error = this.errorList[ i ];
896
+ if (this.settings.highlight) {
897
+ this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass);
898
+ }
899
+ this.showLabel(error.element, error.message);
900
+ }
901
+ if (this.errorList.length) {
902
+ this.toShow = this.toShow.add(this.containers);
903
+ }
904
+ if (this.settings.success) {
905
+ for (i = 0; this.successList[ i ]; i++) {
906
+ this.showLabel(this.successList[ i ]);
907
+ }
908
+ }
909
+ if (this.settings.unhighlight) {
910
+ for (i = 0, elements = this.validElements(); elements[ i ]; i++) {
911
+ this.settings.unhighlight.call(this, elements[ i ], this.settings.errorClass, this.settings.validClass);
912
+ }
913
+ }
914
+ this.toHide = this.toHide.not(this.toShow);
915
+ this.hideErrors();
916
+ this.addWrapper(this.toShow).show();
917
+ },
918
+
919
+ validElements: function () {
920
+ return this.currentElements.not(this.invalidElements());
921
+ },
922
+
923
+ invalidElements: function () {
924
+ return $(this.errorList).map(function () {
925
+ return this.element;
926
+ });
927
+ },
928
+
929
+ showLabel: function (element, message) {
930
+ var place, group, errorID, v,
931
+ error = this.errorsFor(element),
932
+ elementID = this.idOrName(element),
933
+ describedBy = $(element).attr("aria-describedby");
934
+
935
+ if (error.length) {
936
+
937
+ // Refresh error/success class
938
+ error.removeClass(this.settings.validClass).addClass(this.settings.errorClass);
939
+
940
+ // Replace message on existing label
941
+ error.html(message);
942
+ } else {
943
+
944
+ // Create error element
945
+ error = $("<" + this.settings.errorElement + ">")
946
+ .attr("id", elementID + "-error")
947
+ .addClass(this.settings.errorClass)
948
+ .html(message || "");
949
+
950
+ // Maintain reference to the element to be placed into the DOM
951
+ place = error;
952
+ if (this.settings.wrapper) {
953
+
954
+ // Make sure the element is visible, even in IE
955
+ // actually showing the wrapped element is handled elsewhere
956
+ place = error.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
957
+ }
958
+ if (this.labelContainer.length) {
959
+ this.labelContainer.append(place);
960
+ } else if (this.settings.errorPlacement) {
961
+ this.settings.errorPlacement.call(this, place, $(element));
962
+ } else {
963
+ place.insertAfter(element);
964
+ }
965
+
966
+ // Link error back to the element
967
+ if (error.is("label")) {
968
+
969
+ // If the error is a label, then associate using 'for'
970
+ error.attr("for", elementID);
971
+
972
+ // If the element is not a child of an associated label, then it's necessary
973
+ // to explicitly apply aria-describedby
974
+ } else if (error.parents("label[for='" + this.escapeCssMeta(elementID) + "']").length === 0) {
975
+ errorID = error.attr("id");
976
+
977
+ // Respect existing non-error aria-describedby
978
+ if (!describedBy) {
979
+ describedBy = errorID;
980
+ } else if (!describedBy.match(new RegExp("\\b" + this.escapeCssMeta(errorID) + "\\b"))) {
981
+
982
+ // Add to end of list if not already present
983
+ describedBy += " " + errorID;
984
+ }
985
+ $(element).attr("aria-describedby", describedBy);
986
+
987
+ // If this element is grouped, then assign to all elements in the same group
988
+ group = this.groups[ element.name ];
989
+ if (group) {
990
+ v = this;
991
+ $.each(v.groups, function (name, testgroup) {
992
+ if (testgroup === group) {
993
+ $("[name='" + v.escapeCssMeta(name) + "']", v.currentForm)
994
+ .attr("aria-describedby", error.attr("id"));
995
+ }
996
+ });
997
+ }
998
+ }
999
+ }
1000
+ if (!message && this.settings.success) {
1001
+ error.text("");
1002
+ if (typeof this.settings.success === "string") {
1003
+ error.addClass(this.settings.success);
1004
+ } else {
1005
+ this.settings.success(error, element);
1006
+ }
1007
+ }
1008
+ this.toShow = this.toShow.add(error);
1009
+ },
1010
+
1011
+ errorsFor: function (element) {
1012
+ var name = this.escapeCssMeta(this.idOrName(element)),
1013
+ describer = $(element).attr("aria-describedby"),
1014
+ selector = "label[for='" + name + "'], label[for='" + name + "'] *";
1015
+
1016
+ // 'aria-describedby' should directly reference the error element
1017
+ if (describer) {
1018
+ selector = selector + ", #" + this.escapeCssMeta(describer)
1019
+ .replace(/\s+/g, ", #");
1020
+ }
1021
+
1022
+ return this
1023
+ .errors()
1024
+ .filter(selector);
1025
+ },
1026
+
1027
+ // See https://api.jquery.com/category/selectors/, for CSS
1028
+ // meta-characters that should be escaped in order to be used with JQuery
1029
+ // as a literal part of a name/id or any selector.
1030
+ escapeCssMeta: function (string) {
1031
+ return string.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1");
1032
+ },
1033
+
1034
+ idOrName: function (element) {
1035
+ return this.groups[ element.name ] || (this.checkable(element) ? element.name : element.id || element.name);
1036
+ },
1037
+
1038
+ validationTargetFor: function (element) {
1039
+
1040
+ // If radio/checkbox, validate first element in group instead
1041
+ if (this.checkable(element)) {
1042
+ element = this.findByName(element.name);
1043
+ }
1044
+
1045
+ // Always apply ignore filter
1046
+ return $(element).not(this.settings.ignore)[ 0 ];
1047
+ },
1048
+
1049
+ checkable: function (element) {
1050
+ return (/radio|checkbox/i).test(element.type);
1051
+ },
1052
+
1053
+ findByName: function (name) {
1054
+ return $(this.currentForm).find("[name='" + this.escapeCssMeta(name) + "']");
1055
+ },
1056
+
1057
+ getLength: function (value, element) {
1058
+ switch (element.nodeName.toLowerCase()) {
1059
+ case "select":
1060
+ return $("option:selected", element).length;
1061
+ case "input":
1062
+ if (this.checkable(element)) {
1063
+ return this.findByName(element.name).filter(":checked").length;
1064
+ }
1065
+ }
1066
+ return value.length;
1067
+ },
1068
+
1069
+ depend: function (param, element) {
1070
+ return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ](param, element) : true;
1071
+ },
1072
+
1073
+ dependTypes: {
1074
+ "boolean": function (param) {
1075
+ return param;
1076
+ },
1077
+ "string": function (param, element) {
1078
+ return !!$(param, element.form).length;
1079
+ },
1080
+ "function": function (param, element) {
1081
+ return param(element);
1082
+ }
1083
+ },
1084
+
1085
+ optional: function (element) {
1086
+ var val = this.elementValue(element);
1087
+ return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
1088
+ },
1089
+
1090
+ startRequest: function (element) {
1091
+ if (!this.pending[ element.name ]) {
1092
+ this.pendingRequest++;
1093
+ $(element).addClass(this.settings.pendingClass);
1094
+ this.pending[ element.name ] = true;
1095
+ }
1096
+ },
1097
+
1098
+ stopRequest: function (element, valid) {
1099
+ this.pendingRequest--;
1100
+
1101
+ // Sometimes synchronization fails, make sure pendingRequest is never < 0
1102
+ if (this.pendingRequest < 0) {
1103
+ this.pendingRequest = 0;
1104
+ }
1105
+ delete this.pending[ element.name ];
1106
+ $(element).removeClass(this.settings.pendingClass);
1107
+ if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) {
1108
+ $(this.currentForm).submit();
1109
+
1110
+ // Remove the hidden input that was used as a replacement for the
1111
+ // missing submit button. The hidden input is added by `handle()`
1112
+ // to ensure that the value of the used submit button is passed on
1113
+ // for scripted submits triggered by this method
1114
+ if (this.submitButton) {
1115
+ $("input:hidden[name='" + this.submitButton.name + "']", this.currentForm).remove();
1116
+ }
1117
+
1118
+ this.formSubmitted = false;
1119
+ } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
1120
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
1121
+ this.formSubmitted = false;
1122
+ }
1123
+ },
1124
+
1125
+ previousValue: function (element, method) {
1126
+ method = typeof method === "string" && method || "remote";
1127
+
1128
+ return $.data(element, "previousValue") || $.data(element, "previousValue", {
1129
+ old: null,
1130
+ valid: true,
1131
+ message: this.defaultMessage(element, {method: method})
1132
+ });
1133
+ },
1134
+
1135
+ // Cleans up all forms and elements, removes validator-specific events
1136
+ destroy: function () {
1137
+ this.resetForm();
1138
+
1139
+ $(this.currentForm)
1140
+ .off(".validate")
1141
+ .removeData("validator")
1142
+ .find(".validate-equalTo-blur")
1143
+ .off(".validate-equalTo")
1144
+ .removeClass("validate-equalTo-blur");
1145
+ }
1146
+
1147
+ },
1148
+
1149
+ classRuleSettings: {
1150
+ required: {required: true},
1151
+ email: {email: true},
1152
+ url: {url: true},
1153
+ date: {date: true},
1154
+ dateISO: {dateISO: true},
1155
+ number: {number: true},
1156
+ digits: {digits: true},
1157
+ creditcard: {creditcard: true}
1158
+ },
1159
+
1160
+ addClassRules: function (className, rules) {
1161
+ if (className.constructor === String) {
1162
+ this.classRuleSettings[ className ] = rules;
1163
+ } else {
1164
+ $.extend(this.classRuleSettings, className);
1165
+ }
1166
+ },
1167
+
1168
+ classRules: function (element) {
1169
+ var rules = {},
1170
+ classes = $(element).attr("class");
1171
+
1172
+ if (classes) {
1173
+ $.each(classes.split(" "), function () {
1174
+ if (this in $.validator.classRuleSettings) {
1175
+ $.extend(rules, $.validator.classRuleSettings[ this ]);
1176
+ }
1177
+ });
1178
+ }
1179
+ return rules;
1180
+ },
1181
+
1182
+ normalizeAttributeRule: function (rules, type, method, value) {
1183
+
1184
+ // Convert the value to a number for number inputs, and for text for backwards compability
1185
+ // allows type="date" and others to be compared as strings
1186
+ if (/min|max|step/.test(method) && (type === null || /number|range|text/.test(type))) {
1187
+ value = Number(value);
1188
+
1189
+ // Support Opera Mini, which returns NaN for undefined minlength
1190
+ if (isNaN(value)) {
1191
+ value = undefined;
1192
+ }
1193
+ }
1194
+
1195
+ if (value || value === 0) {
1196
+ rules[ method ] = value;
1197
+ } else if (type === method && type !== "range") {
1198
+
1199
+ // Exception: the jquery validate 'range' method
1200
+ // does not test for the html5 'range' type
1201
+ rules[ method ] = true;
1202
+ }
1203
+ },
1204
+
1205
+ attributeRules: function (element) {
1206
+ var rules = {},
1207
+ $element = $(element),
1208
+ type = element.getAttribute("type"),
1209
+ method, value;
1210
+
1211
+ for (method in $.validator.methods) {
1212
+
1213
+ // Support for <input required> in both html5 and older browsers
1214
+ if (method === "required") {
1215
+ value = element.getAttribute(method);
1216
+
1217
+ // Some browsers return an empty string for the required attribute
1218
+ // and non-HTML5 browsers might have required="" markup
1219
+ if (value === "") {
1220
+ value = true;
1221
+ }
1222
+
1223
+ // Force non-HTML5 browsers to return bool
1224
+ value = !!value;
1225
+ } else {
1226
+ value = $element.attr(method);
1227
+ }
1228
+
1229
+ this.normalizeAttributeRule(rules, type, method, value);
1230
+ }
1231
+
1232
+ // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
1233
+ if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
1234
+ delete rules.maxlength;
1235
+ }
1236
+
1237
+ return rules;
1238
+ },
1239
+
1240
+ dataRules: function (element) {
1241
+ var rules = {},
1242
+ $element = $(element),
1243
+ type = element.getAttribute("type"),
1244
+ method, value;
1245
+
1246
+ for (method in $.validator.methods) {
1247
+ value = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase());
1248
+ this.normalizeAttributeRule(rules, type, method, value);
1249
+ }
1250
+ return rules;
1251
+ },
1252
+
1253
+ staticRules: function (element) {
1254
+ var rules = {},
1255
+ validator = $.data(element.form, "validator");
1256
+
1257
+ if (validator.settings.rules) {
1258
+ rules = $.validator.normalizeRule(validator.settings.rules[ element.name ]) || {};
1259
+ }
1260
+ return rules;
1261
+ },
1262
+
1263
+ normalizeRules: function (rules, element) {
1264
+
1265
+ // Handle dependency check
1266
+ $.each(rules, function (prop, val) {
1267
+
1268
+ // Ignore rule when param is explicitly false, eg. required:false
1269
+ if (val === false) {
1270
+ delete rules[ prop ];
1271
+ return;
1272
+ }
1273
+ if (val.param || val.depends) {
1274
+ var keepRule = true;
1275
+ switch (typeof val.depends) {
1276
+ case "string":
1277
+ keepRule = !!$(val.depends, element.form).length;
1278
+ break;
1279
+ case "function":
1280
+ keepRule = val.depends.call(element, element);
1281
+ break;
1282
+ }
1283
+ if (keepRule) {
1284
+ rules[ prop ] = val.param !== undefined ? val.param : true;
1285
+ } else {
1286
+ $.data(element.form, "validator").resetElements($(element));
1287
+ delete rules[ prop ];
1288
+ }
1289
+ }
1290
+ });
1291
+
1292
+ // Evaluate parameters
1293
+ $.each(rules, function (rule, parameter) {
1294
+ rules[ rule ] = $.isFunction(parameter) && rule !== "normalizer" ? parameter(element) : parameter;
1295
+ });
1296
+
1297
+ // Clean number parameters
1298
+ $.each(["minlength", "maxlength"], function () {
1299
+ if (rules[ this ]) {
1300
+ rules[ this ] = Number(rules[ this ]);
1301
+ }
1302
+ });
1303
+ $.each(["rangelength", "range"], function () {
1304
+ var parts;
1305
+ if (rules[ this ]) {
1306
+ if ($.isArray(rules[ this ])) {
1307
+ rules[ this ] = [Number(rules[ this ][ 0 ]), Number(rules[ this ][ 1 ])];
1308
+ } else if (typeof rules[ this ] === "string") {
1309
+ parts = rules[ this ].replace(/[\[\]]/g, "").split(/[\s,]+/);
1310
+ rules[ this ] = [Number(parts[ 0 ]), Number(parts[ 1 ])];
1311
+ }
1312
+ }
1313
+ });
1314
+
1315
+ if ($.validator.autoCreateRanges) {
1316
+
1317
+ // Auto-create ranges
1318
+ if (rules.min != null && rules.max != null) {
1319
+ rules.range = [rules.min, rules.max];
1320
+ delete rules.min;
1321
+ delete rules.max;
1322
+ }
1323
+ if (rules.minlength != null && rules.maxlength != null) {
1324
+ rules.rangelength = [rules.minlength, rules.maxlength];
1325
+ delete rules.minlength;
1326
+ delete rules.maxlength;
1327
+ }
1328
+ }
1329
+
1330
+ return rules;
1331
+ },
1332
+
1333
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1334
+ normalizeRule: function (data) {
1335
+ if (typeof data === "string") {
1336
+ var transformed = {};
1337
+ $.each(data.split(/\s/), function () {
1338
+ transformed[ this ] = true;
1339
+ });
1340
+ data = transformed;
1341
+ }
1342
+ return data;
1343
+ },
1344
+
1345
+ // https://jqueryvalidation.org/jQuery.validator.addMethod/
1346
+ addMethod: function (name, method, message) {
1347
+ $.validator.methods[ name ] = method;
1348
+ $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1349
+ if (method.length < 3) {
1350
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
1351
+ }
1352
+ },
1353
+
1354
+ // https://jqueryvalidation.org/jQuery.validator.methods/
1355
+ methods: {
1356
+
1357
+ // https://jqueryvalidation.org/required-method/
1358
+ required: function (value, element, param) {
1359
+
1360
+ // Check if dependency is met
1361
+ if (!this.depend(param, element)) {
1362
+ return "dependency-mismatch";
1363
+ }
1364
+ if (element.nodeName.toLowerCase() === "select") {
1365
+
1366
+ // Could be an array for select-multiple or a string, both are fine this way
1367
+ var val = $(element).val();
1368
+ return val && val.length > 0;
1369
+ }
1370
+ if (this.checkable(element)) {
1371
+ return this.getLength(value, element) > 0;
1372
+ }
1373
+ return value.length > 0;
1374
+ },
1375
+
1376
+ // https://jqueryvalidation.org/email-method/
1377
+ email: function (value, element) {
1378
+
1379
+ // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
1380
+ // Retrieved 2014-01-14
1381
+ // If you have a problem with this implementation, report a bug against the above spec
1382
+ // Or use custom methods to implement your own email validation
1383
+ return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
1384
+ },
1385
+
1386
+ // https://jqueryvalidation.org/url-method/
1387
+ url: function (value, element) {
1388
+
1389
+ // Copyright (c) 2010-2013 Diego Perini, MIT licensed
1390
+ // https://gist.github.com/dperini/729294
1391
+ // see also https://mathiasbynens.be/demo/url-regex
1392
+ // modified to allow protocol-relative URLs
1393
+ return this.optional(element) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
1394
+ },
1395
+
1396
+ // https://jqueryvalidation.org/date-method/
1397
+ date: function (value, element) {
1398
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1399
+ },
1400
+
1401
+ // https://jqueryvalidation.org/dateISO-method/
1402
+ dateISO: function (value, element) {
1403
+ return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
1404
+ },
1405
+
1406
+ // https://jqueryvalidation.org/number-method/
1407
+ number: function (value, element) {
1408
+ return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1409
+ },
1410
+
1411
+ // https://jqueryvalidation.org/digits-method/
1412
+ digits: function (value, element) {
1413
+ return this.optional(element) || /^\d+$/.test(value);
1414
+ },
1415
+
1416
+ // https://jqueryvalidation.org/minlength-method/
1417
+ minlength: function (value, element, param) {
1418
+ var length = $.isArray(value) ? value.length : this.getLength(value, element);
1419
+ return this.optional(element) || length >= param;
1420
+ },
1421
+
1422
+ // https://jqueryvalidation.org/maxlength-method/
1423
+ maxlength: function (value, element, param) {
1424
+ var length = $.isArray(value) ? value.length : this.getLength(value, element);
1425
+ return this.optional(element) || length <= param;
1426
+ },
1427
+
1428
+ // https://jqueryvalidation.org/rangelength-method/
1429
+ rangelength: function (value, element, param) {
1430
+ var length = $.isArray(value) ? value.length : this.getLength(value, element);
1431
+ return this.optional(element) || (length >= param[ 0 ] && length <= param[ 1 ]);
1432
+ },
1433
+
1434
+ // https://jqueryvalidation.org/min-method/
1435
+ min: function (value, element, param) {
1436
+ return this.optional(element) || value >= param;
1437
+ },
1438
+
1439
+ // https://jqueryvalidation.org/max-method/
1440
+ max: function (value, element, param) {
1441
+ return this.optional(element) || value <= param;
1442
+ },
1443
+
1444
+ // https://jqueryvalidation.org/range-method/
1445
+ range: function (value, element, param) {
1446
+ return this.optional(element) || (value >= param[ 0 ] && value <= param[ 1 ]);
1447
+ },
1448
+
1449
+ // https://jqueryvalidation.org/step-method/
1450
+ step: function (value, element, param) {
1451
+ var type = $(element).attr("type"),
1452
+ errorMessage = "Step attribute on input type " + type + " is not supported.",
1453
+ supportedTypes = ["text", "number", "range"],
1454
+ re = new RegExp("\\b" + type + "\\b"),
1455
+ notSupported = type && !re.test(supportedTypes.join()),
1456
+ decimalPlaces = function (num) {
1457
+ var match = ("" + num).match(/(?:\.(\d+))?$/);
1458
+ if (!match) {
1459
+ return 0;
1460
+ }
1461
+
1462
+ // Number of digits right of decimal point.
1463
+ return match[ 1 ] ? match[ 1 ].length : 0;
1464
+ },
1465
+ toInt = function (num) {
1466
+ return Math.round(num * Math.pow(10, decimals));
1467
+ },
1468
+ valid = true,
1469
+ decimals;
1470
+
1471
+ // Works only for text, number and range input types
1472
+ // TODO find a way to support input types date, datetime, datetime-local, month, time and week
1473
+ if (notSupported) {
1474
+ throw new Error(errorMessage);
1475
+ }
1476
+
1477
+ decimals = decimalPlaces(param);
1478
+
1479
+ // Value can't have too many decimals
1480
+ if (decimalPlaces(value) > decimals || toInt(value) % toInt(param) !== 0) {
1481
+ valid = false;
1482
+ }
1483
+
1484
+ return this.optional(element) || valid;
1485
+ },
1486
+
1487
+ // https://jqueryvalidation.org/equalTo-method/
1488
+ equalTo: function (value, element, param) {
1489
+
1490
+ // Bind to the blur event of the target in order to revalidate whenever the target field is updated
1491
+ var target = $(param);
1492
+ if (this.settings.onfocusout && target.not(".validate-equalTo-blur").length) {
1493
+ target.addClass("validate-equalTo-blur").on("blur.validate-equalTo", function () {
1494
+ $(element).valid();
1495
+ });
1496
+ }
1497
+ return value === target.val();
1498
+ },
1499
+
1500
+ // https://jqueryvalidation.org/remote-method/
1501
+ remote: function (value, element, param, method) {
1502
+ if (this.optional(element)) {
1503
+ return "dependency-mismatch";
1504
+ }
1505
+
1506
+ method = typeof method === "string" && method || "remote";
1507
+
1508
+ var previous = this.previousValue(element, method),
1509
+ validator, data, optionDataString;
1510
+
1511
+ if (!this.settings.messages[ element.name ]) {
1512
+ this.settings.messages[ element.name ] = {};
1513
+ }
1514
+ previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
1515
+ this.settings.messages[ element.name ][ method ] = previous.message;
1516
+
1517
+ param = typeof param === "string" && {url: param} || param;
1518
+ optionDataString = $.param($.extend({data: value}, param.data));
1519
+ if (previous.old === optionDataString) {
1520
+ return previous.valid;
1521
+ }
1522
+
1523
+ previous.old = optionDataString;
1524
+ validator = this;
1525
+ this.startRequest(element);
1526
+ data = {};
1527
+ data[ element.name ] = value;
1528
+ $.ajax($.extend(true, {
1529
+ mode: "abort",
1530
+ port: "validate" + element.name,
1531
+ dataType: "json",
1532
+ data: data,
1533
+ context: validator.currentForm,
1534
+ success: function (response) {
1535
+ var valid = response === true || response === "true",
1536
+ errors, message, submitted;
1537
+
1538
+ validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
1539
+ if (valid) {
1540
+ submitted = validator.formSubmitted;
1541
+ validator.resetInternals();
1542
+ validator.toHide = validator.errorsFor(element);
1543
+ validator.formSubmitted = submitted;
1544
+ validator.successList.push(element);
1545
+ validator.invalid[ element.name ] = false;
1546
+ validator.showErrors();
1547
+ } else {
1548
+ errors = {};
1549
+ message = response || validator.defaultMessage(element, {method: method, parameters: value});
1550
+ errors[ element.name ] = previous.message = message;
1551
+ validator.invalid[ element.name ] = true;
1552
+ validator.showErrors(errors);
1553
+ }
1554
+ previous.valid = valid;
1555
+ validator.stopRequest(element, valid);
1556
+ }
1557
+ }, param));
1558
+ return "pending";
1559
+ }
1560
+ }
1561
+
1562
+ });
1563
+
1564
+ // Ajax mode: abort
1565
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1566
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1567
+
1568
+ var pendingRequests = {},
1569
+ ajax;
1570
+
1571
+ // Use a prefilter if available (1.5+)
1572
+ if ($.ajaxPrefilter) {
1573
+ $.ajaxPrefilter(function (settings, _, xhr) {
1574
+ var port = settings.port;
1575
+ if (settings.mode === "abort") {
1576
+ if (pendingRequests[ port ]) {
1577
+ pendingRequests[ port ].abort();
1578
+ }
1579
+ pendingRequests[ port ] = xhr;
1580
+ }
1581
+ });
1582
+ } else {
1583
+
1584
+ // Proxy ajax
1585
+ ajax = $.ajax;
1586
+ $.ajax = function (settings) {
1587
+ var mode = ("mode" in settings ? settings : $.ajaxSettings).mode,
1588
+ port = ("port" in settings ? settings : $.ajaxSettings).port;
1589
+ if (mode === "abort") {
1590
+ if (pendingRequests[ port ]) {
1591
+ pendingRequests[ port ].abort();
1592
+ }
1593
+ pendingRequests[ port ] = ajax.apply(this, arguments);
1594
+ return pendingRequests[ port ];
1595
+ }
1596
+ return ajax.apply(this, arguments);
1597
+ };
1598
+ }
1599
+ return $;
1600
+ }));
includes/footer.php CHANGED
@@ -447,43 +447,79 @@ if (!is_user_logged_in()) {
447
  {
448
  show_pop_up_mail_bank();
449
  });
 
 
 
 
 
 
450
  <?php
451
- $check_wp_mail_bank_wizard = get_option("wp-mail-bank-wizard-set-up");
452
- $page_url = $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : esc_attr($_GET["page"]);
453
- if (isset($_GET["page"])) {
454
  switch ($page_url) {
455
- case "wp_mail_bank_wizard":
456
  ?>
457
- function show_hide_details_wp_mail_bank()
458
- {
459
- if (jQuery("#ux_div_wizard_set_up").hasClass("wizard-set-up"))
460
- {
461
- jQuery("#ux_div_wizard_set_up").css("display", "none");
462
- jQuery("#ux_div_wizard_set_up").removeClass("wizard-set-up");
463
- } else
464
- {
465
- jQuery("#ux_div_wizard_set_up").css("display", "block");
466
- jQuery("#ux_div_wizard_set_up").addClass("wizard-set-up");
467
- }
468
- }
469
-
470
- function plugin_stats_wp_mail_bank(type)
471
- {
472
- overlay_loading_mail_bank();
473
- jQuery.post(ajaxurl,
 
 
 
 
 
 
474
  {
475
- type: type,
476
- param: "wizard_wp_mail_bank",
477
- action: "mail_bank_action",
478
- _wp_nonce: "<?php echo $wp_mail_bank_check_status; ?>"
479
  },
480
- function ()
481
  {
482
- remove_overlay_mail_bank();
483
- window.location.href = "admin.php?page=mb_email_configuration";
484
- });
485
- }
486
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
  <?php
488
  break;
489
  case "mb_email_configuration":
447
  {
448
  show_pop_up_mail_bank();
449
  });
450
+ function show_hide_text_field_options(id) {
451
+ jQuery("#" + id).animate({
452
+ height: 'toggle'
453
+ });
454
+ var sidebar_load_interval = setInterval(load_sidebar_content_mail_bank, 1000);
455
+ }
456
  <?php
457
+ $check_wp_mail_bank_wizard = get_option("mail-bank-welcome-page");
458
+ $page_url = $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : esc_attr($_GET["page"]);
459
+ if (isset($page_url)) {
460
  switch ($page_url) {
461
+ case "mb_mail_bank_welcome_page":
462
  ?>
463
+ jQuery("#ux_welcome_page").addClass("active");
464
+ var feedback_array = [];
465
+ var url = "<?php echo tech_banker_url . "/feedbacks.php"; ?>";
466
+ var domain_url = "<?php echo site_url(); ?>";
467
+ jQuery("#ux_frm_feedbacks").validate
468
+ ({
469
+ rules:
470
+ {
471
+ ux_txt_your_name:
472
+ {
473
+ required: true
474
+ },
475
+ ux_txt_email_address:
476
+ {
477
+ required: true,
478
+ email: true
479
+ },
480
+ ux_txtarea_feedbacks:
481
+ {
482
+ required: true
483
+ }
484
+ },
485
+ errorPlacement: function ()
486
  {
 
 
 
 
487
  },
488
+ highlight: function (element)
489
  {
490
+ jQuery(element).closest(".form-group").removeClass("has-success").addClass("has-error");
491
+ },
492
+ success: function (label, element)
493
+ {
494
+ var icon = jQuery(element).parent(".input-icon").children("i");
495
+ jQuery(element).closest(".form-group").removeClass("has-error").addClass("has-success");
496
+ icon.removeClass("fa-warning").addClass("fa-check");
497
+ },
498
+ submitHandler: function ()
499
+ {
500
+ feedback_array.push(jQuery("#ux_txt_your_name").val(), jQuery("#ux_txt_email_address").val(), domain_url, jQuery("#ux_txtarea_feedbacks").val());
501
+ overlay_loading_mail_bank(<?php echo json_encode($mb_update_feedbacks); ?>);
502
+ jQuery.post(url,
503
+ {
504
+ data: JSON.stringify(feedback_array),
505
+ param: "mail_bank_send_feedback"
506
+ },
507
+ function ()
508
+ {
509
+ setTimeout(function ()
510
+ {
511
+ remove_overlay_mail_bank();
512
+ window.location.href = "admin.php?page=mb_mail_bank_welcome_page";
513
+ }, 3000);
514
+ });
515
+ }
516
+ });
517
+ var sidebar_load_interval = setInterval(load_sidebar_content_mail_bank, 1000);
518
+ setTimeout(function ()
519
+ {
520
+ clearInterval(sidebar_load_interval);
521
+ }, 5000);
522
+ load_sidebar_content_mail_bank();
523
  <?php
524
  break;
525
  case "mb_email_configuration":
includes/queries.php CHANGED
@@ -45,8 +45,13 @@ if (!is_user_logged_in()) {
45
  );
46
  return maybe_unserialize($meta_value);
47
  }
48
- if (isset($_GET["page"])) {
49
- switch (esc_attr($_GET["page"])) {
 
 
 
 
 
50
  case "mb_roles_and_capabilities":
51
  $details_roles_capabilities = get_mail_bank_meta_value("roles_and_capabilities");
52
  $other_roles_access_array = array(
45
  );
46
  return maybe_unserialize($meta_value);
47
  }
48
+ $check_mail_bank_wizard = get_option("mail-bank-welcome-page");
49
+ $page_url = $check_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : esc_attr($_GET["page"]);
50
+ if (isset($page_url)) {
51
+ switch ($page_url) {
52
+ case "mb_mail_bank_welcome_page":
53
+ update_option("mail-bank-welcome-page", "open");
54
+ break;
55
  case "mb_roles_and_capabilities":
56
  $details_roles_capabilities = get_mail_bank_meta_value("roles_and_capabilities");
57
  $other_roles_access_array = array(
includes/sidebar.php CHANGED
@@ -32,6 +32,14 @@ if (!is_user_logged_in()) {
32
  <img src="<?php echo plugins_url("assets/global/img/mail-bank-logo.png", dirname(__FILE__)); ?>" alt="Mail Bank">
33
  </a>
34
  </div>
 
 
 
 
 
 
 
 
35
  <li id="ux_mb_li_email_configuration">
36
  <a href="admin.php?page=mb_email_configuration">
37
  <i class="icon-custom-envelope-open"></i>
@@ -114,44 +122,11 @@ if (!is_user_logged_in()) {
114
  </div>
115
  <div class="page-content-wrapper">
116
  <div class="page-content">
117
- <div style="margin-bottom:10px">
118
- <a href="http://beta.tech-banker.com/products/mail-bank/" target="_blank">
119
- <img src="<?php echo plugins_url("assets/global/img/mail-bank-banner.png", dirname(__FILE__)); ?>" title="Mail Bank" style="width: 100%;">
120
- </a>
121
- </div>
122
- <div class="container-fluid page-header-container">
123
- <div class="row">
124
- <div class="col-md-3 page-header-column">
125
- <h4>Get Started</h4>
126
- <a class="btn" href="#" target="_blank">Watch Video!</a>
127
- <p>or <a href="http://beta.tech-banker.com/products/mail-bank/user-guide/" target="_blank">read documentation here</a></p>
128
- </div>
129
- <div class="col-md-3 page-header-column">
130
- <h4>Go Premium</h4>
131
- <ul>
132
- <li><a href="http://beta.tech-banker.com/products/mail-bank/" target="_blank">Features</a></li>
133
- <li><a href="http://beta.tech-banker.com/products/mail-bank/demos/" target="_blank">Online Demos</a></li>
134
- <li><a href="http://beta.tech-banker.com/products/mail-bank/pricing/" target="_blank">Pricing Plans</a></li>
135
- </ul>
136
- </div>
137
- <div class="col-md-3 page-header-column">
138
- <h4>User Guide</h4>
139
- <ul>
140
- <li><a href="http://beta.tech-banker.com/products/mail-bank/user-guide/" target="_blank">Documentation</a></li>
141
- <li><a href="https://wordpress.org/support/plugin/wp-mail-bank" target="_blank">Support Question!</a></li>
142
- <li><a href="http://beta.tech-banker.com/contact-us/" target="_blank">Contact Us</a></li>
143
- </ul>
144
- </div>
145
- <div class="col-md-3 page-header-column">
146
- <h4>More Actions</h4>
147
- <ul>
148
- <li><a href="https://wordpress.org/support/plugin/wp-mail-bank/reviews/?filter=5" target="_blank">Rate Us!</a></li>
149
- <li><a href="http://beta.tech-banker.com/products/" target="_blank">Our Other Products</a></li>
150
- <li><a href="http://beta.tech-banker.com/services/" target="_blank">Our Other Services</a></li>
151
- </ul>
152
- </div>
153
- </div>
154
- </div>
155
  <?php
156
  }
157
  }
32
  <img src="<?php echo plugins_url("assets/global/img/mail-bank-logo.png", dirname(__FILE__)); ?>" alt="Mail Bank">
33
  </a>
34
  </div>
35
+ <li id="ux_welcome_page">
36
+ <a href="admin.php?page=mb_mail_bank_welcome_page">
37
+ <i class="icon-custom-present"></i>
38
+ <span class="title">
39
+ <?php echo $mb_overview; ?>
40
+ </span>
41
+ </a>
42
+ </li>
43
  <li id="ux_mb_li_email_configuration">
44
  <a href="admin.php?page=mb_email_configuration">
45
  <i class="icon-custom-envelope-open"></i>
122
  </div>
123
  <div class="page-content-wrapper">
124
  <div class="page-content">
125
+ <!-- <div style="margin-bottom:10px">
126
+ <a href="http://beta.tech-banker.com/products/mail-bank/" target="_blank">
127
+ <img src="<//?php echo plugins_url("assets/global/img/mail-bank-banner.png", dirname(__FILE__)); ?>" title="Mail Bank" style="width: 100%;">
128
+ </a>
129
+ </div> -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  <?php
131
  }
132
  }
includes/translations.php CHANGED
@@ -174,12 +174,17 @@ if (!is_user_logged_in()) {
174
  $mb_premium_edition_label = __("Premium Edition", "wp-mail-bank");
175
  $mb_message_premium_edition = __("This feature is available only in Premium Editions! <br> Kindly Purchase to unlock it!", "wp-mail-bank");
176
 
177
-
178
  //wizard
179
  $mb_wizard_basic_info = __("Basic Info", "wp-mail-bank");
180
  $mb_wizard_account_setup = __("Account Setup", "wp-mail-bank");
181
  $mb_wizard_confirm = __("Confirm", "wp-mail-bank");
182
 
 
 
 
 
 
 
183
  // Menus
184
  $wp_mail_bank = __("Mail Bank", "wp-mail-bank");
185
  $mb_email_configuration = __("Email Setup", "wp-mail-bank");
@@ -229,6 +234,7 @@ if (!is_user_logged_in()) {
229
  $mb_next_step = __("Next Step", "wp-mail-bank");
230
  $mb_previous_step = __("Previous Step", "wp-mail-bank");
231
  $mb_upgrade_to = __("Upgrade to Premium Editions", "wp-mail-bank");
 
232
 
233
  // Email Setup
234
  $mb_email_configuration_cc_label = __("Cc", "wp-mail-bank");
174
  $mb_premium_edition_label = __("Premium Edition", "wp-mail-bank");
175
  $mb_message_premium_edition = __("This feature is available only in Premium Editions! <br> Kindly Purchase to unlock it!", "wp-mail-bank");
176
 
 
177
  //wizard
178
  $mb_wizard_basic_info = __("Basic Info", "wp-mail-bank");
179
  $mb_wizard_account_setup = __("Account Setup", "wp-mail-bank");
180
  $mb_wizard_confirm = __("Confirm", "wp-mail-bank");
181
 
182
+
183
+ //overview
184
+ $mb_video_tutorials = __("Video Tutorials", "wp-mail-bank");
185
+ $mb_premium_editions = __("Premium Editions", "wp-mail-bank");
186
+ $mb_have_suggestions = __("Have Suggestion?", "wp-mail-bank");
187
+
188
  // Menus
189
  $wp_mail_bank = __("Mail Bank", "wp-mail-bank");
190
  $mb_email_configuration = __("Email Setup", "wp-mail-bank");
234
  $mb_next_step = __("Next Step", "wp-mail-bank");
235
  $mb_previous_step = __("Previous Step", "wp-mail-bank");
236
  $mb_upgrade_to = __("Upgrade to Premium Editions", "wp-mail-bank");
237
+ $mb_overview = __("Overview", "wp-mail-bank");
238
 
239
  // Email Setup
240
  $mb_email_configuration_cc_label = __("Cc", "wp-mail-bank");
lib/action-library.php CHANGED
@@ -37,58 +37,6 @@ if (!is_user_logged_in()) {
37
  if (isset($_REQUEST["param"])) {
38
  $obj_dbHelper_mail_bank = new dbHelper_mail_bank();
39
  switch (esc_attr($_REQUEST["param"])) {
40
- case "wizard_wp_mail_bank":
41
- if (wp_verify_nonce(isset($_REQUEST["_wp_nonce"]) ? esc_attr($_REQUEST["_wp_nonce"]) : "", "wp_mail_bank_check_status")) {
42
- $type = isset($_REQUEST["type"]) ? esc_attr($_REQUEST["type"]) : "";
43
- update_option("wp-mail-bank-wizard-set-up", $type);
44
- if ($type == "opt_in") {
45
- $plugin_info_wp_mail_bank = new plugin_info_wp_mail_bank();
46
- global $wp_version;
47
- $url = tech_banker_stats_url . "/wp-admin/admin-ajax.php";
48
- $theme_details = array();
49
- if ($wp_version >= 3.4) {
50
- $active_theme = wp_get_theme();
51
- $theme_details["theme_name"] = strip_tags($active_theme->Name);
52
- $theme_details["theme_version"] = strip_tags($active_theme->Version);
53
- $theme_details["author_url"] = strip_tags($active_theme->{"Author URI"});
54
- }
55
-
56
- $plugin_stat_data = array();
57
- $plugin_stat_data["plugin_slug"] = "wp-mail-bank";
58
- $plugin_stat_data["type"] = "standard_edition";
59
- $plugin_stat_data["version_number"] = mail_bank_version_number;
60
- $plugin_stat_data["status"] = $type;
61
- $plugin_stat_data["event"] = "activate";
62
- $plugin_stat_data["domain_url"] = site_url();
63
- $plugin_stat_data["wp_language"] = defined("WPLANG") && WPLANG ? WPLANG : get_locale();
64
- $plugin_stat_data["email"] = get_option("admin_email");
65
- $plugin_stat_data["wp_version"] = $wp_version;
66
- $plugin_stat_data["php_version"] = esc_html(phpversion());
67
- $plugin_stat_data["mysql_version"] = $wpdb->db_version();
68
- $plugin_stat_data["max_input_vars"] = ini_get("max_input_vars");
69
- $plugin_stat_data["operating_system"] = PHP_OS . " (" . PHP_INT_SIZE * 8 . ") BIT";
70
- $plugin_stat_data["php_memory_limit"] = ini_get("memory_limit") ? ini_get("memory_limit") : "N/A";
71
- $plugin_stat_data["extensions"] = get_loaded_extensions();
72
- $plugin_stat_data["plugins"] = $plugin_info_wp_mail_bank->get_plugin_info_wp_mail_bank();
73
- $plugin_stat_data["themes"] = $theme_details;
74
-
75
- $response = wp_safe_remote_post($url, array
76
- (
77
- "method" => "POST",
78
- "timeout" => 45,
79
- "redirection" => 5,
80
- "httpversion" => "1.0",
81
- "blocking" => true,
82
- "headers" => array(),
83
- "body" => array("data" => serialize($plugin_stat_data), "site_id" => get_option("mb_tech_banker_site_id") != "" ? get_option("mb_tech_banker_site_id") : "", "action" => "plugin_analysis_data")
84
- ));
85
- if (!is_wp_error($response)) {
86
- $response["body"] != "" ? update_option("mb_tech_banker_site_id", $response["body"]) : "";
87
- }
88
- }
89
- }
90
- break;
91
-
92
  case "mail_bank_set_hostname_port_module":
93
  if (wp_verify_nonce(isset($_REQUEST["_wp_nonce"]) ? esc_attr($_REQUEST["_wp_nonce"]) : "", "mail_bank_set_hostname_port")) {
94
  $smtp_user = isset($_REQUEST["smtp_user"]) ? esc_attr($_REQUEST["smtp_user"]) : "";
37
  if (isset($_REQUEST["param"])) {
38
  $obj_dbHelper_mail_bank = new dbHelper_mail_bank();
39
  switch (esc_attr($_REQUEST["param"])) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  case "mail_bank_set_hostname_port_module":
41
  if (wp_verify_nonce(isset($_REQUEST["_wp_nonce"]) ? esc_attr($_REQUEST["_wp_nonce"]) : "", "mail_bank_set_hostname_port")) {
42
  $smtp_user = isset($_REQUEST["smtp_user"]) ? esc_attr($_REQUEST["smtp_user"]) : "";
lib/admin-bar-menu.php CHANGED
@@ -76,6 +76,13 @@ if (!is_user_logged_in()) {
76
  "title" => $icon . "<span class=\"ab-label\">" . $wp_mail_bank . "</span>",
77
  "href" => admin_url("admin.php?page=mb_email_configuration")
78
  ));
 
 
 
 
 
 
 
79
  $wp_admin_bar->add_menu(array
80
  (
81
  "parent" => "wp_mail_bank",
76
  "title" => $icon . "<span class=\"ab-label\">" . $wp_mail_bank . "</span>",
77
  "href" => admin_url("admin.php?page=mb_email_configuration")
78
  ));
79
+ $wp_admin_bar->add_menu(array
80
+ (
81
+ "parent" => "wp_mail_bank",
82
+ "id" => "mb_mail_bank_welcome_page",
83
+ "title" => $mb_overview,
84
+ "href" => admin_url("admin.php?page=mb_mail_bank_welcome_page")
85
+ ));
86
  $wp_admin_bar->add_menu(array
87
  (
88
  "parent" => "wp_mail_bank",
lib/install-script.php CHANGED
@@ -22,37 +22,42 @@ if (!is_user_logged_in()) {
22
  Created On: 05-02-2016 11:40
23
  Created By: Tech Banker Team
24
  */
25
- class dbHelper_install_script_mail_bank {
26
- /*
27
- Function Name: insertCommand
28
- Parameters: Yes($table_name,$data)
29
- Description: This Function is used to Insert data in database.
30
- Created On: 05-02-2016 11:40
31
- Created By: Tech Banker Team
32
- */
33
- function insertCommand($table_name, $data) {
34
- global $wpdb;
35
- $wpdb->insert($table_name, $data);
36
- return $wpdb->insert_id;
37
- }
38
- /*
39
- Function Name: updateCommand
40
- Parameters: Yes($table_name,$data,$where)
41
- Description: This function is used to Update data.
42
- Created On: 05-02-2016 11:40
43
- Created By: Tech Banker Team
44
- */
45
- function updateCommand($table_name, $data, $where) {
46
- global $wpdb;
47
- $wpdb->update($table_name, $data, $where);
 
 
48
  }
49
  }
 
50
  if (file_exists(ABSPATH . "wp-admin/includes/upgrade.php"))
51
  require_once ABSPATH . "wp-admin/includes/upgrade.php";
52
 
53
  $mail_bank_version_number = get_option("mail-bank-version-number");
54
- function mail_bank_table() {
55
- $sql = "CREATE TABLE IF NOT EXISTS " . mail_bank() . "
 
 
56
  (
57
  `id` int(11) NOT NULL AUTO_INCREMENT,
58
  `type` varchar(100) NOT NULL,
@@ -60,19 +65,22 @@ if (!is_user_logged_in()) {
60
  PRIMARY KEY (`id`)
61
  )
62
  ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";
63
- dbDelta($sql);
64
 
65
- $data = "INSERT INTO " . mail_bank() . " (`type`, `parent_id`) VALUES
66
  ('email_configuration', 0),
67
  ('email_logs', 0),
68
  ('settings', 0),
69
  ('roles_and_capabilities', 0)";
70
- dbDelta($data);
 
71
  }
72
- function mail_bank_meta_table() {
73
- $obj_dbHelper_install_script_mail_bank = new dbHelper_install_script_mail_bank();
74
- global $wpdb;
75
- $sql = "CREATE TABLE IF NOT EXISTS " . mail_bank_meta() . "
 
 
76
  (
77
  `id` int(11) NOT NULL AUTO_INCREMENT,
78
  `meta_id` int(11) NOT NULL,
@@ -81,97 +89,101 @@ if (!is_user_logged_in()) {
81
  PRIMARY KEY (`id`)
82
  )
83
  ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";
84
- dbDelta($sql);
85
-
86
- $admin_email = get_option("admin_email");
87
- $admin_name = get_option("blogname");
88
-
89
- $mail_bank_table_data = $wpdb->get_results
90
- (
91
- "SELECT * FROM " . mail_bank()
92
- );
93
-
94
- foreach ($mail_bank_table_data as $row) {
95
- switch ($row->type) {
96
- case "email_configuration":
97
- $email_configuration_array = array();
98
- $email_configuration_array["email_address"] = $admin_email;
99
- $email_configuration_array["reply_to"] = "";
100
- $email_configuration_array["cc"] = "";
101
- $email_configuration_array["bcc"] = "";
102
- $email_configuration_array["mailer_type"] = "smtp";
103
- $email_configuration_array["sender_name"] = $admin_name;
104
- $email_configuration_array["sender_name_configuration"] = "override";
105
- $email_configuration_array["hostname"] = "";
106
- $email_configuration_array["port"] = "587";
107
- $email_configuration_array["client_id"] = "";
108
- $email_configuration_array["client_secret"] = "";
109
- $email_configuration_array["redirect_uri"] = "";
110
- $email_configuration_array["sender_email"] = $admin_email;
111
- $email_configuration_array["from_email_configuration"] = "override";
112
- $email_configuration_array["auth_type"] = "none";
113
- $email_configuration_array["username"] = $admin_email;
114
- $email_configuration_array["password"] = "";
115
- $email_configuration_array["enc_type"] = "tls";
116
-
117
- $email_configuration_array_data = array();
118
- $email_configuration_array_data["meta_id"] = $row->id;
119
- $email_configuration_array_data["meta_key"] = "email_configuration";
120
- $email_configuration_array_data["meta_value"] = serialize($email_configuration_array);
121
- $obj_dbHelper_install_script_mail_bank->insertCommand(mail_bank_meta(), $email_configuration_array_data);
122
- break;
123
-
124
- case "settings":
125
- $settings_data_array = array();
126
- $settings_data_array["debug_mode"] = "enable";
127
- $settings_data_array["remove_tables_at_uninstall"] = "enable";
128
- $settings_data_array["monitor_email_logs"] = "enable";
129
 
130
- $settings_array = array();
131
- $settings_array["meta_id"] = $row->id;
132
- $settings_array["meta_key"] = "settings";
133
- $settings_array["meta_value"] = serialize($settings_data_array);
134
- $obj_dbHelper_install_script_mail_bank->insertCommand(mail_bank_meta(), $settings_array);
135
- break;
136
-
137
- case "roles_and_capabilities":
138
- $roles_capabilities_data_array = array();
139
- $roles_capabilities_data_array["roles_and_capabilities"] = "1,1,1,0,0,0";
140
- $roles_capabilities_data_array["show_mail_bank_top_bar_menu"] = "enable";
141
- $roles_capabilities_data_array["others_full_control_capability"] = "0";
142
- $roles_capabilities_data_array["administrator_privileges"] = "1,1,1,1,1,1,1,1,1,1";
143
- $roles_capabilities_data_array["author_privileges"] = "0,0,1,0,0,0,0,0,0,0";
144
- $roles_capabilities_data_array["editor_privileges"] = "0,0,1,0,0,0,1,0,0,0";
145
- $roles_capabilities_data_array["contributor_privileges"] = "0,0,0,0,0,0,1,0,0,0";
146
- $roles_capabilities_data_array["subscriber_privileges"] = "0,0,0,0,0,0,0,0,0,0";
147
- $roles_capabilities_data_array["other_roles_privileges"] = "0,0,0,0,0,0,0,0,0,0";
148
- $user_capabilities = get_others_capabilities_mail_bank();
149
- $other_roles_array = array();
150
- $other_roles_access_array = array(
151
- "manage_options",
152
- "edit_plugins",
153
- "edit_posts",
154
- "publish_posts",
155
- "publish_pages",
156
- "edit_pages",
157
- "read"
158
- );
159
- foreach ($other_roles_access_array as $role) {
160
- if (in_array($role, $user_capabilities)) {
161
- array_push($other_roles_array, $role);
 
 
 
 
 
 
 
162
  }
163
- }
164
- $roles_capabilities_data_array["capabilities"] = $other_roles_array;
165
-
166
- $roles_data_array = array();
167
- $roles_data_array["meta_id"] = $row->id;
168
- $roles_data_array["meta_key"] = "roles_and_capabilities";
169
- $roles_data_array["meta_value"] = serialize($roles_capabilities_data_array);
170
- $obj_dbHelper_install_script_mail_bank->insertCommand(mail_bank_meta(), $roles_data_array);
171
- break;
172
  }
173
  }
174
  }
 
 
 
175
  $obj_dbHelper_install_script_mail_bank = new dbHelper_install_script_mail_bank();
176
  switch ($mail_bank_version_number) {
177
  case "":
22
  Created On: 05-02-2016 11:40
23
  Created By: Tech Banker Team
24
  */
25
+ if (!class_exists("dbHelper_install_script_mail_bank")) {
26
+ class dbHelper_install_script_mail_bank {
27
+ /*
28
+ Function Name: insertCommand
29
+ Parameters: Yes($table_name,$data)
30
+ Description: This Function is used to Insert data in database.
31
+ Created On: 05-02-2016 11:40
32
+ Created By: Tech Banker Team
33
+ */
34
+ function insertCommand($table_name, $data) {
35
+ global $wpdb;
36
+ $wpdb->insert($table_name, $data);
37
+ return $wpdb->insert_id;
38
+ }
39
+ /*
40
+ Function Name: updateCommand
41
+ Parameters: Yes($table_name,$data,$where)
42
+ Description: This function is used to Update data.
43
+ Created On: 05-02-2016 11:40
44
+ Created By: Tech Banker Team
45
+ */
46
+ function updateCommand($table_name, $data, $where) {
47
+ global $wpdb;
48
+ $wpdb->update($table_name, $data, $where);
49
+ }
50
  }
51
  }
52
+
53
  if (file_exists(ABSPATH . "wp-admin/includes/upgrade.php"))
54
  require_once ABSPATH . "wp-admin/includes/upgrade.php";
55
 
56
  $mail_bank_version_number = get_option("mail-bank-version-number");
57
+ if (!function_exists("mail_bank_table")) {
58
+
59
+ function mail_bank_table() {
60
+ $sql = "CREATE TABLE IF NOT EXISTS " . mail_bank() . "
61
  (
62
  `id` int(11) NOT NULL AUTO_INCREMENT,
63
  `type` varchar(100) NOT NULL,
65
  PRIMARY KEY (`id`)
66
  )
67
  ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";
68
+ dbDelta($sql);
69
 
70
+ $data = "INSERT INTO " . mail_bank() . " (`type`, `parent_id`) VALUES
71
  ('email_configuration', 0),
72
  ('email_logs', 0),
73
  ('settings', 0),
74
  ('roles_and_capabilities', 0)";
75
+ dbDelta($data);
76
+ }
77
  }
78
+ if (!function_exists("mail_bank_meta_table")) {
79
+
80
+ function mail_bank_meta_table() {
81
+ $obj_dbHelper_install_script_mail_bank = new dbHelper_install_script_mail_bank();
82
+ global $wpdb;
83
+ $sql = "CREATE TABLE IF NOT EXISTS " . mail_bank_meta() . "
84
  (
85
  `id` int(11) NOT NULL AUTO_INCREMENT,
86
  `meta_id` int(11) NOT NULL,
89
  PRIMARY KEY (`id`)
90
  )
91
  ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1";
92
+ dbDelta($sql);
93
+
94
+ $admin_email = get_option("admin_email");
95
+ $admin_name = get_option("blogname");
96
+
97
+ $mail_bank_table_data = $wpdb->get_results
98
+ (
99
+ "SELECT * FROM " . mail_bank()
100
+ );
101
+
102
+ foreach ($mail_bank_table_data as $row) {
103
+ switch ($row->type) {
104
+ case "email_configuration":
105
+ $email_configuration_array = array();
106
+ $email_configuration_array["email_address"] = $admin_email;
107
+ $email_configuration_array["reply_to"] = "";
108
+ $email_configuration_array["cc"] = "";
109
+ $email_configuration_array["bcc"] = "";
110
+ $email_configuration_array["mailer_type"] = "smtp";
111
+ $email_configuration_array["sender_name"] = $admin_name;
112
+ $email_configuration_array["sender_name_configuration"] = "override";
113
+ $email_configuration_array["hostname"] = "";
114
+ $email_configuration_array["port"] = "587";
115
+ $email_configuration_array["client_id"] = "";
116
+ $email_configuration_array["client_secret"] = "";
117
+ $email_configuration_array["redirect_uri"] = "";
118
+ $email_configuration_array["sender_email"] = $admin_email;
119
+ $email_configuration_array["from_email_configuration"] = "override";
120
+ $email_configuration_array["auth_type"] = "none";
121
+ $email_configuration_array["username"] = $admin_email;
122
+ $email_configuration_array["password"] = "";
123
+ $email_configuration_array["enc_type"] = "tls";
124
+
125
+ $email_configuration_array_data = array();
126
+ $email_configuration_array_data["meta_id"] = $row->id;
127
+ $email_configuration_array_data["meta_key"] = "email_configuration";
128
+ $email_configuration_array_data["meta_value"] = serialize($email_configuration_array);
129
+ $obj_dbHelper_install_script_mail_bank->insertCommand(mail_bank_meta(), $email_configuration_array_data);
130
+ break;
 
 
 
 
 
 
131
 
132
+ case "settings":
133
+ $settings_data_array = array();
134
+ $settings_data_array["debug_mode"] = "enable";
135
+ $settings_data_array["remove_tables_at_uninstall"] = "enable";
136
+ $settings_data_array["monitor_email_logs"] = "enable";
137
+
138
+ $settings_array = array();
139
+ $settings_array["meta_id"] = $row->id;
140
+ $settings_array["meta_key"] = "settings";
141
+ $settings_array["meta_value"] = serialize($settings_data_array);
142
+ $obj_dbHelper_install_script_mail_bank->insertCommand(mail_bank_meta(), $settings_array);
143
+ break;
144
+
145
+ case "roles_and_capabilities":
146
+ $roles_capabilities_data_array = array();
147
+ $roles_capabilities_data_array["roles_and_capabilities"] = "1,1,1,0,0,0";
148
+ $roles_capabilities_data_array["show_mail_bank_top_bar_menu"] = "enable";
149
+ $roles_capabilities_data_array["others_full_control_capability"] = "0";
150
+ $roles_capabilities_data_array["administrator_privileges"] = "1,1,1,1,1,1,1,1,1,1";
151
+ $roles_capabilities_data_array["author_privileges"] = "0,0,1,0,0,0,0,0,0,0";
152
+ $roles_capabilities_data_array["editor_privileges"] = "0,0,1,0,0,0,1,0,0,0";
153
+ $roles_capabilities_data_array["contributor_privileges"] = "0,0,0,0,0,0,1,0,0,0";
154
+ $roles_capabilities_data_array["subscriber_privileges"] = "0,0,0,0,0,0,0,0,0,0";
155
+ $roles_capabilities_data_array["other_roles_privileges"] = "0,0,0,0,0,0,0,0,0,0";
156
+ $user_capabilities = get_others_capabilities_mail_bank();
157
+ $other_roles_array = array();
158
+ $other_roles_access_array = array(
159
+ "manage_options",
160
+ "edit_plugins",
161
+ "edit_posts",
162
+ "publish_posts",
163
+ "publish_pages",
164
+ "edit_pages",
165
+ "read"
166
+ );
167
+ foreach ($other_roles_access_array as $role) {
168
+ if (in_array($role, $user_capabilities)) {
169
+ array_push($other_roles_array, $role);
170
+ }
171
  }
172
+ $roles_capabilities_data_array["capabilities"] = $other_roles_array;
173
+
174
+ $roles_data_array = array();
175
+ $roles_data_array["meta_id"] = $row->id;
176
+ $roles_data_array["meta_key"] = "roles_and_capabilities";
177
+ $roles_data_array["meta_value"] = serialize($roles_capabilities_data_array);
178
+ $obj_dbHelper_install_script_mail_bank->insertCommand(mail_bank_meta(), $roles_data_array);
179
+ break;
180
+ }
181
  }
182
  }
183
  }
184
+
185
+
186
+
187
  $obj_dbHelper_install_script_mail_bank = new dbHelper_install_script_mail_bank();
188
  switch ($mail_bank_version_number) {
189
  case "":
lib/sidebar-menu.php CHANGED
@@ -97,43 +97,50 @@ if (!is_user_logged_in()) {
97
  define("roles_and_capabilities_mail_bank", "$full_control[6]");
98
  if (!defined("system_information_mail_bank"))
99
  define("system_information_mail_bank", "$full_control[7]");
100
- $check_wp_mail_bank_wizard = get_option("wp-mail-bank-wizard-set-up");
101
  if ($flag == "1") {
102
- global $wp_version;
103
-
104
- $icon = plugins_url("assets/global/img/icon.png", dirname(__FILE__));
105
  if ($check_wp_mail_bank_wizard) {
106
  add_menu_page($wp_mail_bank, $wp_mail_bank, "read", "mb_email_configuration", "", $icon);
107
  } else {
108
- add_menu_page($wp_mail_bank, $wp_mail_bank, "read", "wp_mail_bank_wizard", "", plugins_url("assets/global/img/icon.png", dirname(__FILE__)));
109
- add_submenu_page($wp_mail_bank, $wp_mail_bank, "", "read", "wp_mail_bank_wizard", "wp_mail_bank_wizard");
110
  }
111
 
112
- add_submenu_page("mb_email_configuration", $mb_email_configuration, $mb_email_configuration, "read", "mb_email_configuration", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_email_configuration");
113
- add_submenu_page("mb_email_configuration", $mb_test_email, $mb_test_email, "read", "mb_test_email", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_test_email");
114
- add_submenu_page("mb_email_configuration", $mb_connectivity_test, $mb_connectivity_test, "read", "mb_connectivity_test", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_connectivity_test");
115
- add_submenu_page("mb_email_configuration", $mb_email_logs, $mb_email_logs, "read", "mb_email_logs", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_email_logs");
116
- add_submenu_page("mb_email_configuration", $mb_settings, $mb_settings, "read", "mb_settings", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_settings");
117
- add_submenu_page("mb_email_configuration", $mb_roles_and_capabilities, $mb_roles_and_capabilities, "read", "mb_roles_and_capabilities", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_roles_and_capabilities");
118
- add_submenu_page("mb_email_configuration", $mb_feedbacks, $mb_feedbacks, "read", "mb_feedbacks", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_feedbacks");
119
- add_submenu_page("mb_email_configuration", $mb_system_information, $mb_system_information, "read", "mb_system_information", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_system_information");
120
- add_submenu_page("mb_email_configuration", $mb_upgrade, $mb_upgrade, "read", "mb_upgrade", $check_wp_mail_bank_wizard == "" ? "wp_mail_bank_wizard" : "mb_upgrade");
 
121
  }
122
 
123
 
124
  /*
125
- Function Name: wp_mail_bank_wizard
126
  Parameters: No
127
- Descriptio
97
  define("roles_and_capabilities_mail_bank", "$full_control[6]");
98
  if (!defined("system_information_mail_bank"))
99
  define("system_information_mail_bank", "$full_control[7]");
100
+ $check_wp_mail_bank_wizard = get_option("mail-bank-welcome-page");
101
  if ($flag == "1") {
102
+ $icon = MAIL_BANK_PLUGIN_DIR_URL . "assets/global/img/icon.png";
 
 
103
  if ($check_wp_mail_bank_wizard) {
104
  add_menu_page($wp_mail_bank, $wp_mail_bank, "read", "mb_email_configuration", "", $icon);
105
  } else {
106
+ add_menu_page($wp_mail_bank, $wp_mail_bank, "read", "mb_mail_bank_welcome_page", "", plugins_url("assets/global/img/icon.png", dirname(__FILE__)));
 
107
  }
108
 
109
+ add_submenu_page("mb_email_configuration", $mb_email_configuration, $mb_email_configuration, "read", "mb_email_configuration", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_email_configuration");
110
+ add_submenu_page("mb_email_configuration", $mb_test_email, $mb_test_email, "read", "mb_test_email", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_test_email");
111
+ add_submenu_page("mb_email_configuration", $mb_connectivity_test, $mb_connectivity_test, "read", "mb_connectivity_test", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_connectivity_test");
112
+ add_submenu_page("mb_email_configuration", $mb_email_logs, $mb_email_logs, "read", "mb_email_logs", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_email_logs");
113
+ add_submenu_page("mb_email_configuration", $mb_settings, $mb_settings, "read", "mb_settings", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_settings");
114
+ add_submenu_page("mb_email_configuration", $mb_roles_and_capabilities, $mb_roles_and_capabilities, "read", "mb_roles_and_capabilities", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_roles_and_capabilities");
115
+ add_submenu_page("mb_email_configuration", $mb_feedbacks, $mb_feedbacks, "read", "mb_feedbacks", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_feedbacks");
116
+ add_submenu_page("mb_email_configuration", $mb_system_information, $mb_system_information, "read", "mb_system_information", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_system_information");
117
+ add_submenu_page("mb_email_configuration", $mb_upgrade, $mb_upgrade, "read", "mb_upgrade", $check_wp_mail_bank_wizard == "" ? "mb_mail_bank_welcome_page" : "mb_upgrade");
118
+ add_submenu_page($mb_email_configuration, $mb_overview, "", "read", "mb_mail_bank_welcome_page", "mb_mail_bank_welcome_page");
119
  }
120
 
121
 
122
  /*
123
+ Function Name: mb_mail_bank_welcome_page
124
  Parameters: No