WordPress Download Manager - Version 2.5.96

Version Description

  • Fixed issues with category short-code
  • Fixed issue with tinymce button for category short-code
Download this release

Release Info

Developer codename065
Plugin Icon 128x128 WordPress Download Manager
Version 2.5.96
Comparing to
See all releases

Code changes from version 2.3.0 to 2.5.96

Files changed (136) hide show
  1. css/chosen-sprite.png +0 -0
  2. css/chosen.css +339 -0
  3. css/demo_table.css +576 -0
  4. css/demo_table_jui.css +380 -0
  5. css/front.css +3 -0
  6. css/jquery.dataTables.css +335 -0
  7. download-manager.php +308 -118
  8. download.php +8 -6
  9. editor_plugin.js +1 -1
  10. functions.php +6 -0
  11. icon/35.png +0 -0
  12. icon/Box Download.png +0 -0
  13. icon/Cloud Download Off.png +0 -0
  14. icon/Cloud Download On.png +0 -0
  15. icon/Download file.png +0 -0
  16. icon/Download-01.png +0 -0
  17. icon/Download_Blue.png +0 -0
  18. icon/Download_Crate.png +0 -0
  19. icon/Download_Green.png +0 -0
  20. icon/Globe-Download.png +0 -0
  21. icon/Gnome-Document-Save-32.png +0 -0
  22. icon/Gnome-Emblem-Downloads-32.png +0 -0
  23. icon/Package-Download.png +0 -0
  24. icon/Torrents.png +0 -0
  25. icon/agt_add-to-desktop.png +0 -0
  26. icon/agt_update_drivers.png +0 -0
  27. icon/agt_update_misc.png +0 -0
  28. icon/agt_update_recommended.png +0 -0
  29. icon/agt_update_recommended1.png +0 -0
  30. icon/application-x-kgetlist.png +0 -0
  31. icon/archive.png +0 -0
  32. icon/ark.png +0 -0
  33. icon/ark2.png +0 -0
  34. icon/arrow down.png +0 -0
  35. icon/arrow_down.png +0 -0
  36. icon/arrow_down_alt1.png +0 -0
  37. icon/basket_download.png +0 -0
  38. icon/bottom.png +0 -0
  39. icon/cloud-download.png +0 -0
  40. icon/down2.png +0 -0
  41. icon/down_arrow.png +0 -0
  42. icon/download off.png +0 -0
  43. icon/download on.png +0 -0
  44. icon/download-box-open.png +0 -0
  45. icon/download-database.png +0 -0
  46. icon/download_32.png +0 -0
  47. icon/download_accept_32.png +0 -0
  48. icon/download_cancel_32.png +0 -0
  49. icon/download_cloud.png +0 -0
  50. icon/download_down_arrow.png +0 -0
  51. icon/download_for_linux.png +0 -0
  52. icon/download_for_mac.png +0 -0
  53. icon/download_for_windows.png +0 -0
  54. icon/download_information_32.png +0 -0
  55. icon/download_manager.png +0 -0
  56. icon/download_pause_32.png +0 -0
  57. icon/download_run_32.png +0 -0
  58. icon/download_security_32.png +0 -0
  59. icon/download_settings_32.png +0 -0
  60. icon/download_stop_32.png +0 -0
  61. icon/downloads.png +0 -0
  62. icon/downloads_folder.png +0 -0
  63. icon/email_download.png +0 -0
  64. icon/emblem-downloads.png +0 -0
  65. icon/file_download.png +0 -0
  66. icon/file_extension_.png +0 -0
  67. icon/file_extension_bmp.png +0 -0
  68. icon/file_extension_doc.png +0 -0
  69. icon/file_extension_flv.png +0 -0
  70. icon/file_extension_gif.png +0 -0
  71. icon/file_extension_html.png +0 -0
  72. icon/file_extension_jpeg.png +0 -0
  73. icon/file_extension_jpg.png +0 -0
  74. icon/file_extension_log.png +0 -0
  75. icon/file_extension_pdf.png +0 -0
  76. icon/file_extension_png.png +0 -0
  77. icon/file_extension_psd.png +0 -0
  78. icon/file_extension_rar.png +0 -0
  79. icon/file_extension_txt.png +0 -0
  80. icon/file_extension_xls.png +0 -0
  81. icon/file_extension_zip.png +0 -0
  82. icon/find-next.png +0 -0
  83. icon/folder-download.png +0 -0
  84. icon/folder-downloads.png +0 -0
  85. icon/folder_apollon.png +0 -0
  86. icon/folder_download.png +0 -0
  87. icon/folder_downloads_32.png +0 -0
  88. icon/go-bottom.png +0 -0
  89. icon/human-folder-downloads.png +0 -0
  90. icon/icontexto-aurora-folders-downloads.png +0 -0
  91. icon/inbox_download.png +0 -0
  92. icon/kde-folder-downloads.png +0 -0
  93. icon/kget_list.png +0 -0
  94. icon/kthememgr.png +0 -0
  95. icon/load_download.png +0 -0
  96. icon/manilla-folder-downloads.png +0 -0
  97. icon/misc_23.png +0 -0
  98. icon/note_download.png +0 -0
  99. icon/old-go-bottom.png +0 -0
  100. icon/orange-folder-downloads.png +0 -0
  101. icon/photo_download.png +0 -0
  102. icon/save_download.png +0 -0
  103. icon/share.png +0 -0
  104. icon/system-config-kickstart.png +0 -0
  105. icon/system-log-out.png +0 -0
  106. icon/weather_03.png +0 -0
  107. images/back_disabled.png +0 -0
  108. images/back_enabled.png +0 -0
  109. images/back_enabled_hover.png +0 -0
  110. images/forward_disabled.png +0 -0
  111. images/forward_enabled.png +0 -0
  112. images/forward_enabled_hover.png +0 -0
  113. images/theme.png +0 -0
  114. images/wpdm.png +0 -0
  115. images/wpeden.png +0 -0
  116. images/wpmp.png +0 -0
  117. js/chosen.jquery.min.js +10 -0
  118. js/jquery.dataTables.js +12099 -0
  119. js/jquery.dataTables.min.js +154 -0
  120. process.php +39 -12
  121. readme.txt +156 -30
  122. screenshot-1.png +0 -0
  123. screenshot-6.png +0 -0
  124. screenshot-7.png +0 -0
  125. screenshot-8.png +0 -0
  126. wpdc.ppj +0 -67
  127. wpdc.ppx +0 -1
  128. wpdm-add-new-file.php +213 -32
  129. wpdm-all-downloads.php +146 -0
  130. wpdm-categories.php +12 -4
  131. wpdm-file-icon.php +50 -0
  132. wpdm-free-mce-button.php +387 -34
  133. wpdm-list-files.php +46 -46
  134. wpdm-server-file-browser.php +2 -2
  135. wpdm-settings.php +20 -10
  136. wpdm-widgets.php +62 -3
css/chosen-sprite.png ADDED
Binary file
css/chosen.css ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* @group Base */
2
+ select.chzn-select {
3
+ visibility: hidden;
4
+ height: 28px !important;
5
+ min-height: 28px !important;
6
+ }
7
+ .chzn-container {
8
+ font-size: 12px;
9
+ position: relative;
10
+ display: inline-block;
11
+ zoom: 1;
12
+ *display: inline;
13
+ }
14
+ .chzn-container .chzn-drop {
15
+ background: #fff;
16
+ border: 1px solid #aaa;
17
+ border-top: 0;
18
+ position: absolute;
19
+ top: 29px;
20
+ left: 0;
21
+ -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
22
+ -moz-box-shadow : 0 4px 5px rgba(0,0,0,.15);
23
+ -o-box-shadow : 0 4px 5px rgba(0,0,0,.15);
24
+ box-shadow : 0 4px 5px rgba(0,0,0,.15);
25
+ z-index: 999;
26
+ }
27
+ /* @end */
28
+
29
+ /* @group Single Chosen */
30
+ .chzn-container-single .chzn-single {
31
+ background-color: #fff;
32
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
33
+ background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
34
+ background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
35
+ background-image: -o-linear-gradient(top, #eeeeee 0%,#ffffff 50%);
36
+ background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 50%);
37
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
38
+ background-image: linear-gradient(top, #eeeeee 0%,#ffffff 50%);
39
+ -webkit-border-radius: 4px;
40
+ -moz-border-radius : 4px;
41
+ border-radius : 4px;
42
+ -moz-background-clip : padding;
43
+ -webkit-background-clip: padding-box;
44
+ background-clip : padding-box;
45
+ border: 1px solid #aaa;
46
+ display: block;
47
+ overflow: hidden;
48
+ white-space: nowrap;
49
+ position: relative;
50
+ height: 26px;
51
+ line-height: 26px;
52
+ padding: 0 0 0 8px;
53
+ color: #444;
54
+ text-decoration: none;
55
+ }
56
+ .chzn-container-single .chzn-single span {
57
+ margin-right: 26px;
58
+ display: block;
59
+ overflow: hidden;
60
+ white-space: nowrap;
61
+ -o-text-overflow: ellipsis;
62
+ -ms-text-overflow: ellipsis;
63
+ text-overflow: ellipsis;
64
+ }
65
+ .chzn-container-single .chzn-single div {
66
+ -webkit-border-radius: 0 4px 4px 0;
67
+ -moz-border-radius : 0 4px 4px 0;
68
+ border-radius : 0 4px 4px 0;
69
+ -moz-background-clip : padding;
70
+ -webkit-background-clip: padding-box;
71
+ background-clip : padding-box;
72
+ background: #ccc;
73
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
74
+ background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
75
+ background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
76
+ background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
77
+ background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%);
78
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 );
79
+ background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%);
80
+ border-left: 1px solid #aaa;
81
+ position: absolute;
82
+ right: 0;
83
+ top: 0;
84
+ display: block;
85
+ height: 100%;
86
+ width: 18px;
87
+ }
88
+ .chzn-container-single .chzn-single div b {
89
+ background: url('chosen-sprite.png') no-repeat 0 1px;
90
+ display: block;
91
+ width: 100%;
92
+ height: 100%;
93
+ }
94
+ .chzn-container-single .chzn-search {
95
+ padding: 3px 4px;
96
+ margin: 0;
97
+ white-space: nowrap;
98
+ }
99
+ .chzn-container-single .chzn-search input {
100
+ background: #fff url('chosen-sprite.png') no-repeat 100% -20px;
101
+ background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
102
+ background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
103
+ background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
104
+ background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
105
+ background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
106
+ background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
107
+ background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
108
+ margin: 1px 0;
109
+ padding: 4px 20px 4px 5px;
110
+ outline: 0;
111
+ border: 1px solid #aaa;
112
+ font-family: sans-serif;
113
+ font-size: 1em;
114
+ }
115
+ .chzn-container-single .chzn-drop {
116
+ -webkit-border-radius: 0 0 4px 4px;
117
+ -moz-border-radius : 0 0 4px 4px;
118
+ border-radius : 0 0 4px 4px;
119
+ -moz-background-clip : padding;
120
+ -webkit-background-clip: padding-box;
121
+ background-clip : padding-box;
122
+ }
123
+ /* @end */
124
+
125
+ /* @group Multi Chosen */
126
+ .chzn-container-multi .chzn-choices {
127
+ background-color: #fff;
128
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
129
+ background-image: -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
130
+ background-image: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
131
+ background-image: -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
132
+ background-image: -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
133
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
134
+ background-image: linear-gradient(top, #ffffff 85%,#eeeeee 99%);
135
+ border: 1px solid #aaa;
136
+ margin: 0;
137
+ padding: 0;
138
+ cursor: text;
139
+ overflow: hidden;
140
+ height: auto !important;
141
+ height: 1%;
142
+ position: relative;
143
+ }
144
+ .chzn-container-multi .chzn-choices li {
145
+ float: left;
146
+ list-style: none;
147
+ }
148
+ .chzn-container-multi .chzn-choices .search-field {
149
+ white-space: nowrap;
150
+ margin: 0;
151
+ padding: 0;
152
+ }
153
+ .chzn-container-multi .chzn-choices .search-field input {
154
+ color: #666;
155
+ background: transparent !important;
156
+ border: 0 !important;
157
+ padding: 5px;
158
+ margin: 1px 0;
159
+ outline: 0;
160
+ -webkit-box-shadow: none;
161
+ -moz-box-shadow : none;
162
+ -o-box-shadow : none;
163
+ box-shadow : none;
164
+ }
165
+ .chzn-container-multi .chzn-choices .search-field .default {
166
+ color: #999;
167
+ }
168
+ .chzn-container-multi .chzn-choices .search-choice {
169
+ -webkit-border-radius: 3px;
170
+ -moz-border-radius : 3px;
171
+ border-radius : 3px;
172
+ -moz-background-clip : padding;
173
+ -webkit-background-clip: padding-box;
174
+ background-clip : padding-box;
175
+ background-color: #e4e4e4;
176
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e4e4e4), color-stop(0.7, #eeeeee));
177
+ background-image: -webkit-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%);
178
+ background-image: -moz-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%);
179
+ background-image: -o-linear-gradient(bottom, #e4e4e4 0%, #eeeeee 70%);
180
+ background-image: -ms-linear-gradient(top, #e4e4e4 0%,#eeeeee 70%);
181
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4e4e4', endColorstr='#eeeeee',GradientType=0 );
182
+ background-image: linear-gradient(top, #e4e4e4 0%,#eeeeee 70%);
183
+ color: #333;
184
+ border: 1px solid #b4b4b4;
185
+ line-height: 13px;
186
+ padding: 3px 19px 3px 6px;
187
+ margin: 3px 0 3px 5px;
188
+ position: relative;
189
+ }
190
+ .chzn-container-multi .chzn-choices .search-choice span {
191
+ cursor: default;
192
+ }
193
+ .chzn-container-multi .chzn-choices .search-choice-focus {
194
+ background: #d4d4d4;
195
+ }
196
+ .chzn-container-multi .chzn-choices .search-choice .search-choice-close {
197
+ display: block;
198
+ position: absolute;
199
+ right: 5px;
200
+ top: 6px;
201
+ width: 8px;
202
+ height: 9px;
203
+ font-size: 1px;
204
+ background: url(chosen-sprite.png) right top no-repeat;
205
+ }
206
+ .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
207
+ background-position: right -9px;
208
+ }
209
+ .chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
210
+ background-position: right -9px;
211
+ }
212
+ /* @end */
213
+
214
+ /* @group Results */
215
+ .chzn-container .chzn-results {
216
+ margin: 0 4px 4px 0;
217
+ max-height: 190px;
218
+ padding: 0 0 0 4px;
219
+ position: relative;
220
+ overflow-x: hidden;
221
+ overflow-y: auto;
222
+ }
223
+ .chzn-container-multi .chzn-results {
224
+ margin: -1px 0 0;
225
+ padding: 0;
226
+ }
227
+ .chzn-container .chzn-results li {
228
+ line-height: 80%;
229
+ padding: 7px 7px 8px;
230
+ margin: 0;
231
+ list-style: none;
232
+ }
233
+ .chzn-container .chzn-results .active-result {
234
+ cursor: pointer;
235
+ }
236
+ .chzn-container .chzn-results .highlighted {
237
+ background: #3875d7;
238
+ color: #fff;
239
+ }
240
+ .chzn-container .chzn-results li em {
241
+ background: #feffde;
242
+ font-style: normal;
243
+ }
244
+ .chzn-container .chzn-results .highlighted em {
245
+ background: transparent;
246
+ }
247
+ .chzn-container .chzn-results .no-results {
248
+ background: #f4f4f4;
249
+ }
250
+ .chzn-container .chzn-results .group-result {
251
+ cursor: default;
252
+ color: #999;
253
+ font-weight: bold;
254
+ }
255
+ .chzn-container .chzn-results .group-option {
256
+ padding-left: 20px;
257
+ }
258
+ .chzn-container-multi .chzn-drop .result-selected {
259
+ display: none;
260
+ }
261
+ /* @end */
262
+
263
+ /* @group Active */
264
+ .chzn-container-active .chzn-single {
265
+ -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
266
+ -moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
267
+ -o-box-shadow : 0 0 5px rgba(0,0,0,.3);
268
+ box-shadow : 0 0 5px rgba(0,0,0,.3);
269
+ border: 1px solid #5897fb;
270
+ }
271
+ .chzn-container-active .chzn-single-with-drop {
272
+ border: 1px solid #aaa;
273
+ -webkit-box-shadow: 0 1px 0 #fff inset;
274
+ -moz-box-shadow : 0 1px 0 #fff inset;
275
+ -o-box-shadow : 0 1px 0 #fff inset;
276
+ box-shadow : 0 1px 0 #fff inset;
277
+ background-color: #eee;
278
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
279
+ background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
280
+ background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
281
+ background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
282
+ background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);
283
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
284
+ background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);
285
+ -webkit-border-bottom-left-radius : 0;
286
+ -webkit-border-bottom-right-radius: 0;
287
+ -moz-border-radius-bottomleft : 0;
288
+ -moz-border-radius-bottomright: 0;
289
+ border-bottom-left-radius : 0;
290
+ border-bottom-right-radius: 0;
291
+ }
292
+ .chzn-container-active .chzn-single-with-drop div {
293
+ background: transparent;
294
+ border-left: none;
295
+ }
296
+ .chzn-container-active .chzn-single-with-drop div b {
297
+ background-position: -18px 1px;
298
+ }
299
+ .chzn-container-active .chzn-choices {
300
+ -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
301
+ -moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
302
+ -o-box-shadow : 0 0 5px rgba(0,0,0,.3);
303
+ box-shadow : 0 0 5px rgba(0,0,0,.3);
304
+ border: 1px solid #5897fb;
305
+ }
306
+ .chzn-container-active .chzn-choices .search-field input {
307
+ color: #111 !important;
308
+ }
309
+ /* @end */
310
+
311
+ /* @group Right to Left */
312
+ .chzn-rtl { direction:rtl;text-align: right; }
313
+ .chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; }
314
+ .chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; }
315
+ .chzn-rtl .chzn-single div {
316
+ left: 0; right: auto;
317
+ border-left: none; border-right: 1px solid #aaaaaa;
318
+ -webkit-border-radius: 4px 0 0 4px;
319
+ -moz-border-radius : 4px 0 0 4px;
320
+ border-radius : 4px 0 0 4px;
321
+ }
322
+ .chzn-rtl .chzn-choices li { float: right; }
323
+ .chzn-rtl .chzn-choices .search-choice { padding: 3px 6px 3px 19px; margin: 3px 5px 3px 0; }
324
+ .chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 5px; right: auto; background-position: right top;}
325
+ .chzn-rtl.chzn-container-single .chzn-results { margin-left: 4px; margin-right: 0; padding-left: 0; padding-right: 4px; }
326
+ .chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; }
327
+ .chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; }
328
+ .chzn-rtl .chzn-search input {
329
+ background: url('chosen-sprite.png') no-repeat -38px -20px, #ffffff;
330
+ background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
331
+ background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
332
+ background: url('chosen-sprite.png') no-repeat -38px -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
333
+ background: url('chosen-sprite.png') no-repeat -38px -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
334
+ background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
335
+ background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
336
+ background: url('chosen-sprite.png') no-repeat -38px -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
337
+ padding: 4px 5px 4px 20px;
338
+ }
339
+ /* @end */
css/demo_table.css ADDED
@@ -0,0 +1,576 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * File: demo_table.css
3
+ * CVS: $Id$
4
+ * Description: CSS descriptions for DataTables demo pages
5
+ * Author: Allan Jardine
6
+ * Created: Tue May 12 06:47:22 BST 2009
7
+ * Modified: $Date$ by $Author$
8
+ * Language: CSS
9
+ * Project: DataTables
10
+ *
11
+ * Copyright 2009 Allan Jardine. All Rights Reserved.
12
+ *
13
+ * ***************************************************************************
14
+ * DESCRIPTION
15
+ *
16
+ * The styles given here are suitable for the demos that are used with the standard DataTables
17
+ * distribution (see www.datatables.net). You will most likely wish to modify these styles to
18
+ * meet the layout requirements of your site.
19
+ *
20
+ * Common issues:
21
+ * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
22
+ * no conflict between the two pagination types. If you want to use full_numbers pagination
23
+ * ensure that you either have "example_alt_pagination" as a body class name, or better yet,
24
+ * modify that selector.
25
+ * Note that the path used for Images is relative. All images are by default located in
26
+ * ../images/ - relative to this CSS file.
27
+ */
28
+
29
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
30
+ * DataTables features
31
+ */
32
+
33
+ .dataTables_wrapper {
34
+ position: relative;
35
+ clear: both;
36
+ zoom: 1; /* Feeling sorry for IE */
37
+ }
38
+
39
+ .dataTables_processing {
40
+ position: absolute;
41
+ top: 50%;
42
+ left: 50%;
43
+ width: 250px;
44
+ height: 30px;
45
+ margin-left: -125px;
46
+ margin-top: -15px;
47
+ padding: 14px 0 2px 0;
48
+ border: 1px solid #ddd;
49
+ text-align: center;
50
+ color: #999;
51
+ font-size: 14px;
52
+ background-color: white;
53
+ }
54
+
55
+ .dataTables_length {
56
+ width: 40%;
57
+ float: left;
58
+ }
59
+
60
+ .dataTables_filter {
61
+ width: 50%;
62
+ float: right;
63
+ text-align: right;
64
+ }
65
+
66
+ .dataTables_info {
67
+ width: 60%;
68
+ float: left;
69
+ }
70
+
71
+ .dataTables_paginate {
72
+ float: right;
73
+ text-align: right;
74
+ }
75
+
76
+ /* Pagination nested */
77
+ .paginate_disabled_previous, .paginate_enabled_previous,
78
+ .paginate_disabled_next, .paginate_enabled_next {
79
+ height: 19px;
80
+ float: left;
81
+ cursor: pointer;
82
+ *cursor: hand;
83
+ color: #111 !important;
84
+ }
85
+ .paginate_disabled_previous:hover, .paginate_enabled_previous:hover,
86
+ .paginate_disabled_next:hover, .paginate_enabled_next:hover {
87
+ text-decoration: none !important;
88
+ }
89
+ .paginate_disabled_previous:active, .paginate_enabled_previous:active,
90
+ .paginate_disabled_next:active, .paginate_enabled_next:active {
91
+ outline: none;
92
+ }
93
+
94
+ .paginate_disabled_previous,
95
+ .paginate_disabled_next {
96
+ color: #666 !important;
97
+ }
98
+ .paginate_disabled_previous, .paginate_enabled_previous {
99
+ padding-left: 23px;
100
+ }
101
+ .paginate_disabled_next, .paginate_enabled_next {
102
+ padding-right: 23px;
103
+ margin-left: 10px;
104
+ }
105
+
106
+ .paginate_disabled_previous {
107
+ background: url('../images/back_disabled.png') no-repeat top left;
108
+ }
109
+
110
+ .paginate_enabled_previous {
111
+ background: url('../images/back_enabled.png') no-repeat top left;
112
+ }
113
+ .paginate_enabled_previous:hover {
114
+ background: url('../images/back_enabled_hover.png') no-repeat top left;
115
+ }
116
+
117
+ .paginate_disabled_next {
118
+ background: url('../images/forward_disabled.png') no-repeat top right;
119
+ }
120
+
121
+ .paginate_enabled_next {
122
+ background: url('../images/forward_enabled.png') no-repeat top right;
123
+ }
124
+ .paginate_enabled_next:hover {
125
+ background: url('../images/forward_enabled_hover.png') no-repeat top right;
126
+ }
127
+
128
+
129
+
130
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
131
+ * DataTables display
132
+ */
133
+ table.display {
134
+ margin: 0 auto;
135
+ clear: both;
136
+ width: 100%;
137
+
138
+ /* Note Firefox 3.5 and before have a bug with border-collapse
139
+ * ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 )
140
+ * border-spacing: 0; is one possible option. Conditional-css.com is
141
+ * useful for this kind of thing
142
+ *
143
+ * Further note IE 6/7 has problems when calculating widths with border width.
144
+ * It subtracts one px relative to the other browsers from the first column, and
145
+ * adds one to the end...
146
+ *
147
+ * If you want that effect I'd suggest setting a border-top/left on th/td's and
148
+ * then filling in the gaps with other borders.
149
+ */
150
+ }
151
+
152
+ table.display thead th {
153
+ padding: 3px 18px 3px 10px;
154
+ border-bottom: 1px solid black;
155
+ font-weight: bold;
156
+ cursor: pointer;
157
+ * cursor: hand;
158
+ }
159
+
160
+ table.display tfoot th {
161
+ padding: 3px 18px 3px 10px;
162
+ border-top: 1px solid black;
163
+ font-weight: bold;
164
+ }
165
+
166
+ table.display tr.heading2 td {
167
+ border-bottom: 1px solid #aaa;
168
+ }
169
+
170
+ table.display td {
171
+ padding: 3px 10px;
172
+ }
173
+
174
+ table.display td.center {
175
+ text-align: center;
176
+ }
177
+
178
+
179
+
180
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
181
+ * DataTables sorting
182
+ */
183
+
184
+ .sorting_asc {
185
+ background: url('../images/sort_asc.png') no-repeat center right;
186
+ }
187
+
188
+ .sorting_desc {
189
+ background: url('../images/sort_desc.png') no-repeat center right;
190
+ }
191
+
192
+ .sorting {
193
+ background: url('../images/sort_both.png') no-repeat center right;
194
+ }
195
+
196
+ .sorting_asc_disabled {
197
+ background: url('../images/sort_asc_disabled.png') no-repeat center right;
198
+ }
199
+
200
+ .sorting_desc_disabled {
201
+ background: url('../images/sort_desc_disabled.png') no-repeat center right;
202
+ }
203
+
204
+ th:active {
205
+ outline: none;
206
+ }
207
+
208
+
209
+
210
+
211
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
212
+ * DataTables row classes
213
+ */
214
+ table.display tr.odd.gradeA {
215
+ background-color: #ddffdd;
216
+ }
217
+
218
+ table.display tr.even.gradeA {
219
+ background-color: #eeffee;
220
+ }
221
+
222
+ table.display tr.odd.gradeC {
223
+ background-color: #ddddff;
224
+ }
225
+
226
+ table.display tr.even.gradeC {
227
+ background-color: #eeeeff;
228
+ }
229
+
230
+ table.display tr.odd.gradeX {
231
+ background-color: #ffdddd;
232
+ }
233
+
234
+ table.display tr.even.gradeX {
235
+ background-color: #ffeeee;
236
+ }
237
+
238
+ table.display tr.odd.gradeU {
239
+ background-color: #ddd;
240
+ }
241
+
242
+ table.display tr.even.gradeU {
243
+ background-color: #eee;
244
+ }
245
+
246
+
247
+ tr.odd {
248
+ background-color: #E2E4FF;
249
+ }
250
+
251
+ tr.even {
252
+ background-color: white;
253
+ }
254
+
255
+
256
+
257
+
258
+
259
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
260
+ * Misc
261
+ */
262
+ .dataTables_scroll {
263
+ clear: both;
264
+ }
265
+
266
+ .dataTables_scrollBody {
267
+ *margin-top: -1px;
268
+ -webkit-overflow-scrolling: touch;
269
+ }
270
+
271
+ .top, .bottom {
272
+ padding: 15px;
273
+ background-color: #F5F5F5;
274
+ border: 1px solid #CCCCCC;
275
+ }
276
+
277
+ .top .dataTables_info {
278
+ float: none;
279
+ }
280
+
281
+ .clear {
282
+ clear: both;
283
+ }
284
+
285
+ .dataTables_empty {
286
+ text-align: center;
287
+ }
288
+
289
+ tfoot input {
290
+ margin: 0.5em 0;
291
+ width: 100%;
292
+ color: #444;
293
+ }
294
+
295
+ tfoot input.search_init {
296
+ color: #999;
297
+ }
298
+
299
+ td.group {
300
+ background-color: #d1cfd0;
301
+ border-bottom: 2px solid #A19B9E;
302
+ border-top: 2px solid #A19B9E;
303
+ }
304
+
305
+ td.details {
306
+ background-color: #d1cfd0;
307
+ border: 2px solid #A19B9E;
308
+ }
309
+
310
+
311
+ .example_alt_pagination div.dataTables_info {
312
+ width: 40%;
313
+ }
314
+
315
+ .paging_full_numbers {
316
+ width: 400px;
317
+ height: 22px;
318
+ line-height: 22px;
319
+ }
320
+
321
+ .paging_full_numbers a:active {
322
+ outline: none
323
+ }
324
+
325
+ .paging_full_numbers a:hover {
326
+ text-decoration: none;
327
+ }
328
+
329
+ .paging_full_numbers a.paginate_button,
330
+ .paging_full_numbers a.paginate_active {
331
+ border: 1px solid #aaa;
332
+ -webkit-border-radius: 5px;
333
+ -moz-border-radius: 5px;
334
+ padding: 2px 5px;
335
+ margin: 0 3px;
336
+ cursor: pointer;
337
+ *cursor: hand;
338
+ color: #333 !important;
339
+ }
340
+
341
+ .paging_full_numbers a.paginate_button {
342
+ background-color: #ddd;
343
+ }
344
+
345
+ .paging_full_numbers a.paginate_button:hover {
346
+ background-color: #ccc;
347
+ text-decoration: none !important;
348
+ }
349
+
350
+ .paging_full_numbers a.paginate_active {
351
+ background-color: #99B3FF;
352
+ }
353
+
354
+ table.display tr.even.row_selected td {
355
+ background-color: #B0BED9;
356
+ }
357
+
358
+ table.display tr.odd.row_selected td {
359
+ background-color: #9FAFD1;
360
+ }
361
+
362
+
363
+ /*
364
+ * Sorting classes for columns
365
+ */
366
+ /* For the standard odd/even */
367
+ tr.odd td.sorting_1 {
368
+ background-color: #D3D6FF;
369
+ }
370
+
371
+ tr.odd td.sorting_2 {
372
+ background-color: #DADCFF;
373
+ }
374
+
375
+ tr.odd td.sorting_3 {
376
+ background-color: #E0E2FF;
377
+ }
378
+
379
+ tr.even td.sorting_1 {
380
+ background-color: #EAEBFF;
381
+ }
382
+
383
+ tr.even td.sorting_2 {
384
+ background-color: #F2F3FF;
385
+ }
386
+
387
+ tr.even td.sorting_3 {
388
+ background-color: #F9F9FF;
389
+ }
390
+
391
+
392
+ /* For the Conditional-CSS grading rows */
393
+ /*
394
+ Colour calculations (based off the main row colours)
395
+ Level 1:
396
+ dd > c4
397
+ ee > d5
398
+ Level 2:
399
+ dd > d1
400
+ ee > e2
401
+ */
402
+ tr.odd.gradeA td.sorting_1 {
403
+ background-color: #c4ffc4;
404
+ }
405
+
406
+ tr.odd.gradeA td.sorting_2 {
407
+ background-color: #d1ffd1;
408
+ }
409
+
410
+ tr.odd.gradeA td.sorting_3 {
411
+ background-color: #d1ffd1;
412
+ }
413
+
414
+ tr.even.gradeA td.sorting_1 {
415
+ background-color: #d5ffd5;
416
+ }
417
+
418
+ tr.even.gradeA td.sorting_2 {
419
+ background-color: #e2ffe2;
420
+ }
421
+
422
+ tr.even.gradeA td.sorting_3 {
423
+ background-color: #e2ffe2;
424
+ }
425
+
426
+ tr.odd.gradeC td.sorting_1 {
427
+ background-color: #c4c4ff;
428
+ }
429
+
430
+ tr.odd.gradeC td.sorting_2 {
431
+ background-color: #d1d1ff;
432
+ }
433
+
434
+ tr.odd.gradeC td.sorting_3 {
435
+ background-color: #d1d1ff;
436
+ }
437
+
438
+ tr.even.gradeC td.sorting_1 {
439
+ background-color: #d5d5ff;
440
+ }
441
+
442
+ tr.even.gradeC td.sorting_2 {
443
+ background-color: #e2e2ff;
444
+ }
445
+
446
+ tr.even.gradeC td.sorting_3 {
447
+ background-color: #e2e2ff;
448
+ }
449
+
450
+ tr.odd.gradeX td.sorting_1 {
451
+ background-color: #ffc4c4;
452
+ }
453
+
454
+ tr.odd.gradeX td.sorting_2 {
455
+ background-color: #ffd1d1;
456
+ }
457
+
458
+ tr.odd.gradeX td.sorting_3 {
459
+ background-color: #ffd1d1;
460
+ }
461
+
462
+ tr.even.gradeX td.sorting_1 {
463
+ background-color: #ffd5d5;
464
+ }
465
+
466
+ tr.even.gradeX td.sorting_2 {
467
+ background-color: #ffe2e2;
468
+ }
469
+
470
+ tr.even.gradeX td.sorting_3 {
471
+ background-color: #ffe2e2;
472
+ }
473
+
474
+ tr.odd.gradeU td.sorting_1 {
475
+ background-color: #c4c4c4;
476
+ }
477
+
478
+ tr.odd.gradeU td.sorting_2 {
479
+ background-color: #d1d1d1;
480
+ }
481
+
482
+ tr.odd.gradeU td.sorting_3 {
483
+ background-color: #d1d1d1;
484
+ }
485
+
486
+ tr.even.gradeU td.sorting_1 {
487
+ background-color: #d5d5d5;
488
+ }
489
+
490
+ tr.even.gradeU td.sorting_2 {
491
+ background-color: #e2e2e2;
492
+ }
493
+
494
+ tr.even.gradeU td.sorting_3 {
495
+ background-color: #e2e2e2;
496
+ }
497
+
498
+
499
+ /*
500
+ * Row highlighting example
501
+ */
502
+ .ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
503
+ background-color: #ECFFB3;
504
+ }
505
+
506
+ .ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
507
+ background-color: #E6FF99;
508
+ }
509
+
510
+ .ex_highlight_row #example tr.even:hover {
511
+ background-color: #ECFFB3;
512
+ }
513
+
514
+ .ex_highlight_row #example tr.even:hover td.sorting_1 {
515
+ background-color: #DDFF75;
516
+ }
517
+
518
+ .ex_highlight_row #example tr.even:hover td.sorting_2 {
519
+ background-color: #E7FF9E;
520
+ }
521
+
522
+ .ex_highlight_row #example tr.even:hover td.sorting_3 {
523
+ background-color: #E2FF89;
524
+ }
525
+
526
+ .ex_highlight_row #example tr.odd:hover {
527
+ background-color: #E6FF99;
528
+ }
529
+
530
+ .ex_highlight_row #example tr.odd:hover td.sorting_1 {
531
+ background-color: #D6FF5C;
532
+ }
533
+
534
+ .ex_highlight_row #example tr.odd:hover td.sorting_2 {
535
+ background-color: #E0FF84;
536
+ }
537
+
538
+ .ex_highlight_row #example tr.odd:hover td.sorting_3 {
539
+ background-color: #DBFF70;
540
+ }
541
+
542
+
543
+ /*
544
+ * KeyTable
545
+ */
546
+ table.KeyTable td {
547
+ border: 3px solid transparent;
548
+ }
549
+
550
+ table.KeyTable td.focus {
551
+ border: 3px solid #3366FF;
552
+ }
553
+
554
+ table.display tr.gradeA {
555
+ background-color: #eeffee;
556
+ }
557
+
558
+ table.display tr.gradeC {
559
+ background-color: #ddddff;
560
+ }
561
+
562
+ table.display tr.gradeX {
563
+ background-color: #ffdddd;
564
+ }
565
+
566
+ table.display tr.gradeU {
567
+ background-color: #ddd;
568
+ }
569
+
570
+ div.box {
571
+ height: 100px;
572
+ padding: 10px;
573
+ overflow: auto;
574
+ border: 1px solid #8080FF;
575
+ background-color: #E5E5FF;
576
+ }
css/demo_table_jui.css ADDED
@@ -0,0 +1,380 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * File: demo_table_jui.css
3
+ * CVS: $Id$
4
+ * Description: CSS descriptions for DataTables demo pages
5
+ * Author: Allan Jardine
6
+ * Created: Tue May 12 06:47:22 BST 2009
7
+ * Modified: $Date$ by $Author$
8
+ * Language: CSS
9
+ * Project: DataTables
10
+ *
11
+ * Copyright 2009 Allan Jardine. All Rights Reserved.
12
+ *
13
+ * ***************************************************************************
14
+ * DESCRIPTION
15
+ *
16
+ * The styles given here are suitable for the demos that are used with the standard DataTables
17
+ * distribution (see www.datatables.net). You will most likely wish to modify these styles to
18
+ * meet the layout requirements of your site.
19
+ *
20
+ * Common issues:
21
+ * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
22
+ * no conflict between the two pagination types. If you want to use full_numbers pagination
23
+ * ensure that you either have "example_alt_pagination" as a body class name, or better yet,
24
+ * modify that selector.
25
+ * Note that the path used for Images is relative. All images are by default located in
26
+ * ../images/ - relative to this CSS file.
27
+ */
28
+
29
+
30
+ /*
31
+ * jQuery UI specific styling
32
+ */
33
+
34
+ .paging_two_button .ui-button {
35
+ float: left;
36
+ cursor: pointer;
37
+ * cursor: hand;
38
+ }
39
+
40
+ .paging_full_numbers .ui-button {
41
+ padding: 2px 6px;
42
+ margin: 0;
43
+ cursor: pointer;
44
+ * cursor: hand;
45
+ color: #333 !important;
46
+ }
47
+
48
+ .dataTables_paginate .ui-button {
49
+ margin-right: -0.1em !important;
50
+ }
51
+
52
+
53
+
54
+ .dataTables_wrapper .ui-toolbar {
55
+ padding: 5px;
56
+ }
57
+
58
+ .dataTables_paginate {
59
+ width: auto;
60
+ }
61
+
62
+ .dataTables_info {
63
+ padding-top: 3px;
64
+ }
65
+
66
+ table.display thead th {
67
+ padding: 3px 0px 3px 10px;
68
+ cursor: pointer;
69
+ * cursor: hand;
70
+ }
71
+
72
+ div.dataTables_wrapper .ui-widget-header {
73
+ font-weight: normal;
74
+ }
75
+
76
+
77
+ /*
78
+ * Sort arrow icon positioning
79
+ */
80
+ table.display thead th div.DataTables_sort_wrapper {
81
+ position: relative;
82
+ padding-right: 20px;
83
+ padding-right: 20px;
84
+ }
85
+
86
+ table.display thead th div.DataTables_sort_wrapper span {
87
+ position: absolute;
88
+ top: 50%;
89
+ margin-top: -8px;
90
+ right: 0;
91
+ }
92
+
93
+
94
+
95
+
96
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
97
+ *
98
+ * Everything below this line is the same as demo_table.css. This file is
99
+ * required for 'cleanliness' of the markup
100
+ *
101
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
102
+
103
+
104
+
105
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
106
+ * DataTables features
107
+ */
108
+
109
+ .dataTables_wrapper {
110
+ position: relative;
111
+ clear: both;
112
+ }
113
+
114
+ .dataTables_processing {
115
+ position: absolute;
116
+ top: 0px;
117
+ left: 50%;
118
+ width: 250px;
119
+ margin-left: -125px;
120
+ border: 1px solid #ddd;
121
+ text-align: center;
122
+ color: #999;
123
+ font-size: 11px;
124
+ padding: 2px 0;
125
+ }
126
+
127
+ .dataTables_length {
128
+ width: 40%;
129
+ float: left;
130
+ }
131
+
132
+ .dataTables_filter {
133
+ width: 50%;
134
+ float: right;
135
+ text-align: right;
136
+ }
137
+
138
+ .dataTables_info {
139
+ width: 50%;
140
+ float: left;
141
+ }
142
+
143
+ .dataTables_paginate {
144
+ float: right;
145
+ text-align: right;
146
+ }
147
+
148
+ /* Pagination nested */
149
+ .paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
150
+ height: 19px;
151
+ width: 19px;
152
+ margin-left: 3px;
153
+ float: left;
154
+ }
155
+
156
+ .paginate_disabled_previous {
157
+ background-image: url('../images/back_disabled.jpg');
158
+ }
159
+
160
+ .paginate_enabled_previous {
161
+ background-image: url('../images/back_enabled.jpg');
162
+ }
163
+
164
+ .paginate_disabled_next {
165
+ background-image: url('../images/forward_disabled.jpg');
166
+ }
167
+
168
+ .paginate_enabled_next {
169
+ background-image: url('../images/forward_enabled.jpg');
170
+ }
171
+
172
+
173
+
174
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
175
+ * DataTables display
176
+ */
177
+ table.display {
178
+ margin: 0 auto;
179
+ width: 100%;
180
+ clear: both;
181
+ border-collapse: collapse;
182
+ }
183
+
184
+ table.display tfoot th {
185
+ padding: 3px 0px 3px 10px;
186
+ font-weight: bold;
187
+ font-weight: normal;
188
+ }
189
+
190
+ table.display tr.heading2 td {
191
+ border-bottom: 1px solid #aaa;
192
+ }
193
+
194
+ table.display td {
195
+ padding: 3px 10px;
196
+ }
197
+
198
+ table.display td.center {
199
+ text-align: center;
200
+ }
201
+
202
+
203
+
204
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
205
+ * DataTables sorting
206
+ */
207
+
208
+ .sorting_asc {
209
+ background: url('../images/sort_asc.png') no-repeat center right;
210
+ }
211
+
212
+ .sorting_desc {
213
+ background: url('../images/sort_desc.png') no-repeat center right;
214
+ }
215
+
216
+ .sorting {
217
+ background: url('../images/sort_both.png') no-repeat center right;
218
+ }
219
+
220
+ .sorting_asc_disabled {
221
+ background: url('../images/sort_asc_disabled.png') no-repeat center right;
222
+ }
223
+
224
+ .sorting_desc_disabled {
225
+ background: url('../images/sort_desc_disabled.png') no-repeat center right;
226
+ }
227
+
228
+
229
+
230
+
231
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
232
+ * DataTables row classes
233
+ */
234
+ table.display tr.odd.gradeA {
235
+ background-color: #ddffdd;
236
+ }
237
+
238
+ table.display tr.even.gradeA {
239
+ background-color: #eeffee;
240
+ }
241
+
242
+
243
+
244
+
245
+ table.display tr.odd.gradeA {
246
+ background-color: #ddffdd;
247
+ }
248
+
249
+ table.display tr.even.gradeA {
250
+ background-color: #eeffee;
251
+ }
252
+
253
+ table.display tr.odd.gradeC {
254
+ background-color: #ddddff;
255
+ }
256
+
257
+ table.display tr.even.gradeC {
258
+ background-color: #eeeeff;
259
+ }
260
+
261
+ table.display tr.odd.gradeX {
262
+ background-color: #ffdddd;
263
+ }
264
+
265
+ table.display tr.even.gradeX {
266
+ background-color: #ffeeee;
267
+ }
268
+
269
+ table.display tr.odd.gradeU {
270
+ background-color: #ddd;
271
+ }
272
+
273
+ table.display tr.even.gradeU {
274
+ background-color: #eee;
275
+ }
276
+
277
+
278
+ tr.odd {
279
+ background-color: #E2E4FF;
280
+ }
281
+
282
+ tr.even {
283
+ background-color: white;
284
+ }
285
+
286
+
287
+
288
+
289
+
290
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
291
+ * Misc
292
+ */
293
+ .dataTables_scroll {
294
+ clear: both;
295
+ }
296
+
297
+ .dataTables_scrollBody {
298
+ -webkit-overflow-scrolling: touch;
299
+ }
300
+
301
+ .top, .bottom {
302
+ padding: 15px;
303
+ background-color: #F5F5F5;
304
+ border: 1px solid #CCCCCC;
305
+ }
306
+
307
+ .top .dataTables_info {
308
+ float: none;
309
+ }
310
+
311
+ .clear {
312
+ clear: both;
313
+ }
314
+
315
+ .dataTables_empty {
316
+ text-align: center;
317
+ }
318
+
319
+ tfoot input {
320
+ margin: 0.5em 0;
321
+ width: 100%;
322
+ color: #444;
323
+ }
324
+
325
+ tfoot input.search_init {
326
+ color: #999;
327
+ }
328
+
329
+ td.group {
330
+ background-color: #d1cfd0;
331
+ border-bottom: 2px solid #A19B9E;
332
+ border-top: 2px solid #A19B9E;
333
+ }
334
+
335
+ td.details {
336
+ background-color: #d1cfd0;
337
+ border: 2px solid #A19B9E;
338
+ }
339
+
340
+
341
+ .example_alt_pagination div.dataTables_info {
342
+ width: 40%;
343
+ }
344
+
345
+ .paging_full_numbers a.paginate_button,
346
+ .paging_full_numbers a.paginate_active {
347
+ border: 1px solid #aaa;
348
+ -webkit-border-radius: 5px;
349
+ -moz-border-radius: 5px;
350
+ padding: 2px 5px;
351
+ margin: 0 3px;
352
+ cursor: pointer;
353
+ *cursor: hand;
354
+ color: #333 !important;
355
+ }
356
+
357
+ .paging_full_numbers a.paginate_button {
358
+ background-color: #ddd;
359
+ }
360
+
361
+ .paging_full_numbers a.paginate_button:hover {
362
+ background-color: #ccc;
363
+ text-decoration: none !important;
364
+ }
365
+
366
+ .paging_full_numbers a.paginate_active {
367
+ background-color: #99B3FF;
368
+ }
369
+
370
+ table.display tr.even.row_selected td {
371
+ background-color: #B0BED9;
372
+ }
373
+
374
+ table.display tr.odd.row_selected td {
375
+ background-color: #9FAFD1;
376
+ }
377
+
378
+ .css_right{
379
+ float: right;
380
+ }
css/front.css CHANGED
@@ -40,8 +40,11 @@ line-height: normal !important;
40
  .wpdm-only-button .btn_outer_c{
41
  padding-left: 40px;
42
  background-image: url(../icon/download.png);
 
 
43
  background-position: 2px center;
44
  background-repeat: no-repeat;
 
45
  }
46
  .wpdm-only-button .has-counter,
47
  .wpdm-only-button .counter{
40
  .wpdm-only-button .btn_outer_c{
41
  padding-left: 40px;
42
  background-image: url(../icon/download.png);
43
+ min-height: 30px;
44
+ padding-top: 2px;
45
  background-position: 2px center;
46
  background-repeat: no-repeat;
47
+ vertical-align: middle;
48
  }
49
  .wpdm-only-button .has-counter,
50
  .wpdm-only-button .counter{
css/jquery.dataTables.css ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /*
3
+ * Table
4
+ */
5
+ table.dataTable {
6
+ margin: 0 auto;
7
+ clear: both;
8
+ width: 100%;
9
+ margin-bottom: 10px;
10
+ }
11
+
12
+ table.dataTable thead th {
13
+ padding: 3px 18px 3px 10px;
14
+ font-weight: bold;
15
+ cursor: pointer;
16
+ *cursor: hand;
17
+ }
18
+
19
+ table.dataTable tfoot th {
20
+ padding: 3px 18px 3px 10px;
21
+ border-top: 1px solid black;
22
+ font-weight: bold;
23
+ }
24
+
25
+ table.dataTable td {
26
+ padding: 3px 10px;
27
+ }
28
+
29
+ table.dataTable td.center,
30
+ table.dataTable td.dataTables_empty {
31
+ text-align: center;
32
+ }
33
+
34
+ table.dataTable tr.odd { background-color: #eeeeee; }
35
+ table.dataTable tr.even { background-color: white; }
36
+
37
+
38
+
39
+ /*
40
+ * Table wrapper
41
+ */
42
+ .dataTables_wrapper {
43
+ position: relative;
44
+ clear: both;
45
+ *zoom: 1;
46
+ }
47
+
48
+
49
+ /*
50
+ * Page length menu
51
+ */
52
+ .dataTables_length {
53
+ float: left;
54
+ }
55
+
56
+
57
+ /*
58
+ * Filter
59
+ */
60
+ .dataTables_filter {
61
+ float: right;
62
+ text-align: right;
63
+ }
64
+
65
+
66
+ /*
67
+ * Table information
68
+ */
69
+ .dataTables_info {
70
+ clear: both;
71
+ float: left;
72
+ }
73
+
74
+
75
+ /*
76
+ * Pagination
77
+ */
78
+ .dataTables_paginate {
79
+ float: right;
80
+ text-align: right;
81
+ vertical-align: middle;
82
+ line-height: normal;
83
+ }
84
+
85
+ /* Two button pagination - previous / next */
86
+ .paginate_disabled_previous,
87
+ .paginate_enabled_previous,
88
+ .paginate_disabled_next,
89
+ .paginate_enabled_next {
90
+ height: 19px;
91
+ float: left;
92
+ cursor: pointer;
93
+ *cursor: hand;
94
+ color: #111 !important;
95
+ }
96
+ .paginate_disabled_previous:hover,
97
+ .paginate_enabled_previous:hover,
98
+ .paginate_disabled_next:hover,
99
+ .paginate_enabled_next:hover {
100
+ text-decoration: none !important;
101
+ }
102
+ .paginate_disabled_previous:active,
103
+ .paginate_enabled_previous:active,
104
+ .paginate_disabled_next:active,
105
+ .paginate_enabled_next:active {
106
+ outline: none;
107
+ }
108
+
109
+ .paginate_disabled_previous,
110
+ .paginate_disabled_next {
111
+ color: #666 !important;
112
+ }
113
+ .paginate_disabled_previous,
114
+ .paginate_enabled_previous {
115
+ padding-left: 23px;
116
+ }
117
+ .paginate_disabled_next,
118
+ .paginate_enabled_next {
119
+ padding-right: 23px;
120
+ margin-left: 10px;
121
+ }
122
+
123
+ .paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat center left; }
124
+ .paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat center left; }
125
+ .paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat center left; }
126
+
127
+ .paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat center right; }
128
+ .paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat center right; }
129
+ .paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat center right; }
130
+
131
+ /* Full number pagination */
132
+ .paging_full_numbers {
133
+ height: 22px;
134
+ line-height: 22px;
135
+ }
136
+ .paging_full_numbers a:active {
137
+ outline: none
138
+ }
139
+ .paging_full_numbers a:hover {
140
+ text-decoration: none;
141
+ }
142
+
143
+ .paging_full_numbers a.paginate_button,
144
+ .paging_full_numbers a.paginate_active {
145
+ border: 1px solid #aaa;
146
+ -webkit-border-radius: 5px;
147
+ -moz-border-radius: 5px;
148
+ border-radius: 5px;
149
+ padding: 2px 5px;
150
+ margin: 0 3px;
151
+ cursor: pointer;
152
+ *cursor: hand;
153
+ color: #333 !important;
154
+ }
155
+
156
+ .paging_full_numbers a.paginate_button {
157
+ background-color: #ddd;
158
+ }
159
+
160
+ .paging_full_numbers a.paginate_button:hover {
161
+ background-color: #ccc;
162
+ text-decoration: none !important;
163
+ }
164
+
165
+ .paging_full_numbers a.paginate_active {
166
+ background-color: #99B3FF;
167
+ }
168
+
169
+
170
+ /*
171
+ * Processing indicator
172
+ */
173
+ .dataTables_processing {
174
+ position: absolute;
175
+ top: 50%;
176
+ left: 50%;
177
+ width: 250px;
178
+ height: 30px;
179
+ margin-left: -125px;
180
+ margin-top: -15px;
181
+ padding: 14px 0 2px 0;
182
+ border: 1px solid #ddd;
183
+ text-align: center;
184
+ color: #999;
185
+ font-size: 14px;
186
+ background-color: white;
187
+ }
188
+
189
+
190
+ /*
191
+ * Sorting
192
+ */
193
+ .sorting { background: url('../images/sort_both.png') no-repeat center right; }
194
+ .sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; }
195
+ .sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; }
196
+
197
+ .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; }
198
+ .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; }
199
+
200
+ table.dataTable th:active {
201
+ outline: none;
202
+ }
203
+
204
+
205
+ /*
206
+ * Scrolling
207
+ */
208
+ .dataTables_scroll {
209
+ clear: both;
210
+ }
211
+
212
+ .dataTables_scrollBody {
213
+ *margin-top: -1px;
214
+ -webkit-overflow-scrolling: touch;
215
+ }
216
+
217
+
218
+
219
+ div.dataTables_length label {
220
+ width: 460px;
221
+ float: left;
222
+ text-align: left;
223
+ }
224
+
225
+ div.dataTables_length select {
226
+ width: 75px;
227
+ }
228
+
229
+ div.dataTables_filter label {
230
+ float: right;
231
+ width: 460px;
232
+ }
233
+
234
+ div.dataTables_info {
235
+ padding-top: 8px;
236
+ }
237
+
238
+ div.dataTables_paginate {
239
+ float: right;
240
+ margin: 0;
241
+ }
242
+
243
+ table {
244
+ margin: 1em 0;
245
+ clear: both;
246
+ }
247
+
248
+ table.dataTable th:active {
249
+ outline: none;
250
+ }
251
+ .pagination ul{
252
+ box-shadow:none;
253
+ }
254
+
255
+ table .header:after {
256
+ border-color: #000000 transparent;
257
+ border-style: solid;
258
+ border-width: 0 4px 4px;
259
+ content: "";
260
+ float: right;
261
+ margin-top: 7px;
262
+ visibility: hidden;
263
+ }
264
+ table th{
265
+ background: #ddd;
266
+ }
267
+ table .headerSortUp, table .headerSortDown {
268
+ /*background-color: rgba(141, 192, 219, 0.25);*/
269
+ background-color: #ccc;
270
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
271
+ }
272
+ table .header:hover:after {
273
+ visibility: visible;
274
+ }
275
+ table .headerSortDown:after, table .headerSortDown:hover:after {
276
+ opacity: 0.6;
277
+ visibility: visible;
278
+ }
279
+ table .headerSortUp:after {
280
+ border-color: #000000 transparent -moz-use-text-color;
281
+ border-style: solid solid none;
282
+ border-width: 4px 4px medium;
283
+ box-shadow: none;
284
+ opacity: 0.6;
285
+ visibility: visible;
286
+ }
287
+ table .blue {
288
+ border-bottom-color: #049CDB;
289
+ color: #049CDB;
290
+ }
291
+ table .headerSortUp.blue, table .headerSortDown.blue {
292
+ background-color: #ADE6FE;
293
+ }
294
+ table .green {
295
+ border-bottom-color: #46A546;
296
+ color: #46A546;
297
+ }
298
+ table .headerSortUp.green, table .headerSortDown.green {
299
+ background-color: #CDEACD;
300
+ }
301
+ table .red {
302
+ border-bottom-color: #9D261D;
303
+ color: #9D261D;
304
+ }
305
+ table .headerSortUp.red, table .headerSortDown.red {
306
+ background-color: #F4C8C5;
307
+ }
308
+ table .yellow {
309
+ border-bottom-color: #FFC40D;
310
+ color: #FFC40D;
311
+ }
312
+ table .headerSortUp.yellow, table .headerSortDown.yellow {
313
+ background-color: #FFF6D9;
314
+ }
315
+ table .orange {
316
+ border-bottom-color: #F89406;
317
+ color: #F89406;
318
+ }
319
+ table .headerSortUp.orange, table .headerSortDown.orange {
320
+ background-color: #FEE9CC;
321
+ }
322
+ table .purple {
323
+ border-bottom-color: #7A43B6;
324
+ color: #7A43B6;
325
+ }
326
+ table .headerSortUp.purple, table .headerSortDown.purple {
327
+ background-color: #E2D5F0;
328
+ }
329
+ .pagination ul > li{
330
+ margin: 0px;
331
+ }
332
+ #wpdmmydls_filter input[type=text]{
333
+ padding:3px !important;
334
+ margin-bottom: 5px !important;
335
+ }
download-manager.php CHANGED
@@ -2,12 +2,13 @@
2
  /*
3
  Plugin Name: Download Manager
4
  Plugin URI: http://www.wpdownloadmanager.com/
5
- Description: Manage, track and controll file download from your wordpress site
6
  Author: Shaon
7
- Version: 2.3.0
8
  Author URI: http://www.wpdownloadmanager.com/
9
  */
10
 
 
11
 
12
  $d = str_replace('\\','/',dirname(__FILE__));
13
  $d = explode("/", $d);
@@ -31,7 +32,7 @@ include(dirname(__FILE__)."/wpdm-free-mce-button.php");
31
 
32
  if(!$_POST) $_SESSION['download'] = 0;
33
 
34
- function wpdm_download_info(){
35
  include("download.php");
36
  }
37
 
@@ -47,37 +48,52 @@ function wpdm_free_install(){
47
  `password` varchar(40) NOT NULL,
48
  `download_count` int(11) NOT NULL,
49
  `access` enum('guest','member') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
50
- `show_counter` tinyint(1) NOT NULL,
51
  `quota` INT NOT NULL,
52
  `link_label` varchar(255) NOT NULL,
 
53
  PRIMARY KEY (`id`)
54
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8";
55
 
56
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
57
 
58
  $wpdb->query($sql);
59
- //$wpdb->query("ALTER TABLE `ahm_files` ADD `` varchar(255) NOT NULL");
60
- $wpdb->query("ALTER TABLE `ahm_files` ADD `link_label` varchar(255) NOT NULL");
61
- $wpdb->query("ALTER TABLE `ahm_files` ADD `show_counter` tinyint(1) NOT NULL");
62
- $wpdb->query("ALTER TABLE `ahm_files` ADD `download_count` INT NOT NULL");
63
- $wpdb->query("ALTER TABLE `ahm_files` ADD `quota` INT NOT NULL");
64
- $wpdb->query("ALTER TABLE `ahm_files` ADD `category` TEXT NOT NULL");
65
 
66
- update_option('wpdm_access_level','administrator');
67
  wpdm_create_dir();
68
 
69
  }
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  function wpdm_new_packages($show=5, $show_count=true){
72
  global $wpdb;
73
 
74
  $data = $wpdb->get_results("select * from ahm_files order by id desc limit 0, $show",ARRAY_A);
75
  foreach($data as $d){
76
-
77
  $key = $d['id'];
 
 
78
  if($show_count) $sc = "<br/><i>$d[download_count] downloads</i>";
79
  $url = home_url("/?download={$d[id]}");
80
- echo "<li><div class='wpdm_link'><a class='wpdm-popup' title='$d[title]' href='$url'>{$d[title]}</a> $sc</div></li>\r\n";
81
  }
82
  }
83
 
@@ -122,21 +138,32 @@ function wpdm_import_download_monitor(){
122
 
123
  }
124
 
125
-
 
 
 
 
 
 
 
 
126
 
127
  function wpdm_downloadable_nsc($params){
128
  global $wpdb;
129
- extract($params);
130
-
131
-
132
  $home = home_url('/');
 
 
133
 
134
  $sap = count($_GET)>0?'&':'?';
135
 
136
  $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
 
 
137
  if($title=='true') $title = "<h3>".$data['title']."</h3>";
138
  else $title = '';
139
- if($desc=='true') $desc = $data['description']."</br>";
140
  else $desc = '';
141
  $desc = stripslashes($desc);
142
  if($data['show_counter']!=0) $hc= 'has-counter';
@@ -165,7 +192,9 @@ function wpdm_downloadable_nsc($params){
165
  $loginform = "<div id='wpdm-login-form' class='wpdm-login-form'>".wp_login_form( $args ).'</div>';*/
166
 
167
  //"<div class=passit>Login Required<br/><input placeholder='Username' type=text id='username_{$id}' size=15 class='inf' /> <input placeholder='Password' class='inf' type=password id='password_{$id}' size=15 /><span class='perror'></span></div>";
168
- $html = "<div id='wpdm_file_{$id}' class='wpdm_file $template'>{$title}<div class='cont'>{$desc}{$loginform}<div class='btn_outer'><div class='btn_outer_c'><a class='btn_left $classrel $hc login-please' rel='{$id}' title='{$data[title]}' href='$url' >$link_label</a>";
 
 
169
  //if($data['show_counter']!=0)
170
  //$html .= "<span class='btn_right counter'>$data[download_count] downloads</span>";
171
  //else
@@ -173,9 +202,10 @@ function wpdm_downloadable_nsc($params){
173
  $html .= "</div></div><div class='clear'></div></div></div>";
174
  }
175
  else {
 
176
  if($data['password']=='') { $url = home_url('/?wpdmact=process&did='.base64_encode($id.'.hotlink')); $classrel = ""; }
177
  else { $classrel='haspass'; /*$url = home_url('/?download='.$id);*/ $url = home_url('/'); $password_field = "<div class=passit>Enter password<br/><input type=password id='pass_{$id}' size=15 /><span class='perror'></span></div>"; }
178
- $html = "<div id='wpdm_file_{$id}' class='wpdm_file $template'>{$title}<div class='cont'>{$desc}{$password_field}<div class='btn_outer'><div class='btn_outer_c'><a class='btn_left $classrel $hc' rel='{$id}' title='{$data[title]}' href='$url' >$link_label</a>";
179
  if($data['show_counter']!=0)
180
  $html .= "<span class='btn_right counter'>$data[download_count] downloads</span>";
181
  else
@@ -195,7 +225,8 @@ function wpdm_downloadable($content){
195
  $sap = count($_GET)>0?'&':'?';
196
  for($i=0;$i<count($matches[1]);$i++){
197
  $id = $matches[1][$i];
198
- $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
 
199
  $wpdm_login_msg = get_option('wpdm_login_msg')?get_option('wpdm_login_msg'):'Login Required';
200
  $link_label = $data['link_label']?$data['link_label']:'Download';
201
  if($data['access']=='member'&&!is_user_logged_in())
@@ -221,23 +252,27 @@ function wpdm_downloadable($content){
221
  function wpdm_cblist_categories($parent="", $level = 0, $sel = array()){
222
  $cats = maybe_unserialize(get_option('_fm_categories'));
223
  if(is_array($cats)){
224
- if($parent!='') echo "<ul>";
225
  foreach($cats as $id=>$cat){
226
- $pres = str_repeat("&mdash;", $level);
227
  if($cat['parent']==$parent){
228
  if(in_array($id,$sel))
229
  $checked = 'checked=checked';
230
  else
231
  $checked = '';
232
- echo "<li><input type='checkbox' name='file[category][]' value='$id' $checked /> $cat[title]</li>\n";
233
- wpdm_cblist_categories($id,$level+1, $sel);}
 
 
 
 
234
  }
235
- if($parent!='') echo "</ul>";
236
  }
237
  }
238
 
239
  function wpdm_dropdown_categories($parent="", $level = 0, $sel='',$cid='',$class=array()){
240
- $cats = maybe_unserialize(get_option('_fm_categories'));
241
  if(!is_array($cats)) $cats = array();
242
  foreach($cats as $id=>$cat){
243
  $pres = str_repeat("&mdash;", $level);
@@ -256,15 +291,18 @@ function wpdm_dropdown_categories($parent="", $level = 0, $sel='',$cid='',$class
256
  }
257
 
258
  function wpdm_tree(){
259
- ?>
260
- <script language="JavaScript" src="<?php echo plugins_url().'/download-manager/js/jqueryFileTree.js';?>"></script>
261
- <link rel="stylesheet" href="<?php echo plugins_url().'/download-manager/css/jqueryFileTree.css';?>" />
 
 
 
262
  <div id="tree"></div>
263
  <script language="JavaScript">
264
  <!--
265
  jQuery(document).ready( function() {
266
  jQuery('#tree').fileTree({
267
- script: '<?php echo site_url(); ?>/?task=wpdm_tree',
268
  expandSpeed: 1000,
269
  collapseSpeed: 1000,
270
  multiFolder: false
@@ -272,7 +310,7 @@ function wpdm_tree(){
272
  //alert(file);
273
  //var sfilename = file.split('/');
274
  //var filename = sfilename[sfilename.length-1];
275
- tb_show(jQuery(this).html(),'<?php echo home_url('/?download=');?>'+file+'&modal=1&width=600&height=400');
276
 
277
  });
278
 
@@ -280,11 +318,13 @@ function wpdm_tree(){
280
  });
281
  //-->
282
  </script>
283
- <?php
 
 
284
  }
285
 
286
  function wpdm_embed_tree(){
287
- if($_GET['task']!='wpdm_tree') return;
288
  global $wpdb;
289
  $cats = maybe_unserialize(get_option('_fm_categories'));
290
  if(!is_array($cats)) $cats = array();
@@ -297,32 +337,36 @@ if($_GET['task']!='wpdm_tree') return;
297
  $_POST['dir'] = $_POST['dir']=='/'?'':$_POST['dir'];
298
  foreach( $cats as $id=>$file ) {
299
  if($file['parent']==$_POST['dir'])
300
- echo "<li class=\"directory collapsed\"><a href=\"#\" rel=\"" . $id . "\">" . htmlentities($file[title]) . "</a></li>";
301
  }
302
 
303
  // All files
304
- if($_POST[dir])
305
- $ct = "\"{$_POST[dir]}\"";
306
- else $ct = '';
307
- $ndata = $wpdb->get_results("select * from ahm_files where category like '%{$ct}%'",ARRAY_A);
 
 
 
308
  $sap = '?'; //count($_GET)>0?'&':'?';
309
 
310
  foreach($ndata as $data){
311
  $html = '';
 
312
  $link_label = $data['title']?$data['title']:'Download';
313
- $data['page_link'] = "<a class='wpdm-popup' href='' rel='{$data[id]}'>$link_label</a>";
314
- if($data[preview]!='')
315
- $data['thumb'] = "<img class='wpdm_icon' align='left' src='".plugins_url()."/{$data[preview]}' />";
316
  else
317
  $data['thumb'] = '';
318
- if($data[icon]!='')
319
- $data['icon'] = "<img class='wpdm_icon' align='left' src='".plugins_url()."/{$data[icon]}' />";
320
  else
321
  $data['icon'] = '';
322
 
323
 
324
  if($data['show_counter']==1){
325
- $counter = "{$data[download_count]} downloads<br/>";
326
  $data['counter'] = $counter;
327
  }
328
  $ext = end(explode(".", $data['file']));
@@ -330,7 +374,7 @@ if($_GET['task']!='wpdm_tree') return;
330
  //$repeater = stripslashes( strtr( $category['template_repeater'], $reps ));
331
  $template = "<li class=\"wpdm_clink file ext_$ext\">$data[page_link]</li>";
332
  if($data['access']=='member'&&!is_user_logged_in())
333
- $template = "<li class=\"file ext_$ext\"><a href='".get_option('siteurl')."/wp-login.php?redirect_to=".$_SERVER['REQUEST_URI']."' >$data[title]<small> (login to download)</small></a></li>";
334
  $html .= $template;
335
 
336
 
@@ -373,7 +417,7 @@ function wpdm_admin_options(){
373
  if(!file_exists(UPLOAD_DIR.'.htaccess'))
374
  wpdm_set_htaccess();
375
 
376
- if(isset($_GET['task'])&&$_GET['task']!='')
377
  return call_user_func($_GET['task']);
378
  else
379
  include('wpdm-list-files.php');
@@ -404,7 +448,7 @@ function wpdm_create_dir(){
404
  @chmod(UPLOAD_DIR,0777);
405
  @chmod(dir(__FILE__).'/cache/',0777);
406
  wpdm_set_htaccess();
407
- if($_GET[re]==1) {
408
  if(file_exists(UPLOAD_DIR)) $s=1;
409
  else $s = 0;
410
  echo "<script>
@@ -415,20 +459,41 @@ function wpdm_create_dir(){
415
  }
416
 
417
  function wpdm_settings(){
418
- if($_POST){
419
- update_option('wpdm_access_level',$_POST[access]);
420
- update_option('wpdm_login_msg',$_POST[wpdm_login_msg]);
 
 
421
  }
422
  if(is_uploaded_file($_FILES['icon']['tmp_name'])){
423
  ///print_r(dirname(__FILE__).'/icon/download.png');
424
  move_uploaded_file($_FILES['icon']['tmp_name'],dirname(__FILE__).'/icon/download.png');
425
  }
426
  $access = get_option('wpdm_access_level');
 
427
  include('wpdm-settings.php');
428
  }
429
 
430
  function wpdm_add_new_file(){
431
  global $wpdb;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  if(!file_exists(UPLOAD_DIR)){
433
 
434
  echo "
@@ -439,7 +504,7 @@ function wpdm_add_new_file(){
439
  </p></div>";
440
  }
441
 
442
- if($_GET[success]==1){
443
  echo "
444
  <div id=\"message\" class=\"updated fade\"><p>
445
  Congratulation! Plugin is ready to use now.
@@ -447,61 +512,25 @@ function wpdm_add_new_file(){
447
  ";
448
  }
449
 
450
- if($_POST){
451
- extract($_POST);
452
- if(is_uploaded_file($_FILES['media']['tmp_name'])){
453
- $info = pathinfo($_FILES['media']['name']);
454
- //echo dirname(__FILE__).'/files/'.$_FILES['media']['name'];
455
-
456
- $name = file_exists(dirname(__FILE__).'/files/'.$_FILES['media']['name'])?str_replace('.'.$info['extension'],'_'.uniqid().'.'.$info['extension'],$info['basename']):$_FILES['media']['name'];
457
- move_uploaded_file($_FILES['media']['tmp_name'], UPLOAD_DIR . $name);
458
- $file['file'] = $name;
459
-
460
- }
461
-
462
- $file['show_counter'] = 0;
463
- $file['quota'] = $file['quota']?$file['quota']:0;
464
- $file['category'] = serialize($file['category']);
465
- $wpdb->insert("ahm_files", $file);
466
- if(!$wpdb->insert_id){
467
- $wpdb->show_errors();
468
- $wpdb->print_error();
469
- die();
470
- }
471
- echo "<script>
472
- location.href='admin.php?page=file-manager';
473
- </script>";
474
-
475
- }
476
-
477
 
478
  include('wpdm-add-new-file.php');
479
  }
480
 
481
  function wpdm_edit_file(){
482
  global $wpdb;
483
- if($_POST){
484
  extract($_POST);
485
- if(is_uploaded_file($_FILES['media']['tmp_name'])){
486
- $info = pathinfo($_FILES['media']['name']);
487
- //echo dirname(__FILE__).'/files/'.$_FILES['media']['name'];
488
-
489
- $name = file_exists(UPLOAD_DIR . $_FILES['media']['name'])?str_replace('.'.$info['extension'],'_'.uniqid().'.'.$info['extension'],$info['basename']):$_FILES['media']['name'];
490
- move_uploaded_file($_FILES['media']['tmp_name'], UPLOAD_DIR . $name);
491
- $file['file'] = $name;
492
- }
493
 
494
  $file['category'] = serialize($file['category']);
495
-
496
- $wpdb->update("ahm_files", $file, array("id"=>$_POST[id]));
497
-
498
- echo "<script>
499
- location.href='admin.php?page=file-manager';
500
- </script>";
501
 
502
  }
503
-
504
- $file = $wpdb->get_row("select * from ahm_files where id='$_GET[id]'",ARRAY_A);
505
 
506
  include('wpdm-add-new-file.php');
507
  }
@@ -520,7 +549,11 @@ function wpdm_categories(){
520
  if($_POST['cat']){
521
  $tpldata = maybe_unserialize(get_option('_fm_categories'));
522
  if(!is_array($tpldata)) $tpldata =array();
523
- $tcid = $_POST['cid']?$_POST['cid']:strtolower(preg_replace("/([^a-zA-Z0-9\-]+)/","-", $_POST['cat']['title']));
 
 
 
 
524
  $cid = $tcid;
525
  while(array_key_exists($cid, $tpldata)&&$_POST['cid']==''){
526
  $cid = $tcid."-".(++$postfx);
@@ -576,17 +609,14 @@ $sap = strpos($plink,'?')>0?'&':'?';
576
  $html = '';
577
  foreach($ndata as $data){
578
 
579
- $link_label = $data['title']?$data['title']:'Download';
580
- $data['page_link'] = "<a class='wpdm-popup' href='{$postlink}{$sap}download={$data[id]}'>$link_label</a>";
581
- if($data[preview]!='')
582
- $data['thumb'] = "<img class='wpdm_icon' align='left' src='".plugins_url()."/{$data[preview]}' />";
583
- else
584
- $data['thumb'] = '';
585
- if($data[icon]!='')
586
- $data['icon'] = "<img class='wpdm_icon' align='left' src='".plugins_url()."/{$data[icon]}' />";
587
- else
588
- $data['icon'] = '';
589
-
590
 
591
  if($data['show_counter']==1){
592
  $counter = "{$data[download_count]} downloads<br/>";
@@ -595,9 +625,9 @@ foreach($ndata as $data){
595
 
596
  //foreach( $data as $ind=>$val ) $reps["[".$ind."]"] = $val;
597
  //$repeater = stripslashes( strtr( $category['template_repeater'], $reps ));
598
- $template = "<li><div class='wpdm_clink'><b>$data[page_link]</b><br/><small>$data[counter]</small></div></li>";
599
  if($data['access']=='member'&&!is_user_logged_in())
600
- $template = "<li><div class='wpdm_clink'><a href='".get_option('siteurl')."/wp-login.php?redirect_to=".$_SERVER['REQUEST_URI']."' >$data[title]</a></b><br/><small>login to download</small></div></li>";
601
  $html .= $template;
602
 
603
 
@@ -610,12 +640,83 @@ END;
610
 
611
 
612
  }
613
-
 
614
 
615
  return "<ul class='wpdm-category $id'>".$html."</ul><div style='clear:both'></div>".$pag->show()."<div style='clear:both'></div>";
616
  }
617
 
618
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
 
620
  function wpdm_tinymce()
621
  {
@@ -784,6 +885,7 @@ function wpdm_hotlink($params){
784
  if($id=='') return;
785
  $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
786
  if($data['id']=='') return;
 
787
  $link_label = $link_label?$link_label:$data['link_label'];
788
  $url = home_url('/?wpdmact=process&did='.base64_encode($id.'.hotlink'));
789
  return "<a href='$url'>$link_label</a>";
@@ -799,13 +901,91 @@ function delete_all_cats(){
799
  }
800
  }
801
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
802
  function wpdm_menu(){
803
- add_menu_page("File Manager","File Manager",get_option('wpdm_access_level'),'file-manager','wpdm_admin_options',plugins_url('download-manager/img/donwloadmanager-16.png'));
804
- $access = get_option('wpdm_access_level')?get_option('wpdm_access_level'):'administrator';
805
- add_submenu_page( 'file-manager', 'File Manager', 'Manage', $access, 'file-manager', 'wpdm_admin_options');
806
- add_submenu_page( 'file-manager', 'Add New File &lsaquo; File Manager', 'Add New File', $access, 'file-manager/add-new-file', 'wpdm_add_new_file');
807
- add_submenu_page( 'file-manager', 'Categories &lsaquo; File Manager', 'Categories', 'administrator', 'file-manager/categories', 'wpdm_categories');
808
- add_submenu_page( 'file-manager', 'Settings &lsaquo; File Manager', 'Settings', 'administrator', 'file-manager/settings', 'wpdm_settings');
 
809
 
810
  }
811
 
@@ -813,7 +993,11 @@ function wpdm_menu(){
813
  function wpdm_admin_enque_scripts(){
814
  wp_enqueue_style('icons',plugins_url().'/download-manager/css/icons.css');
815
  wp_enqueue_script('jquery');
 
 
816
  wp_enqueue_script('file-tree-js',plugins_url().'/download-manager/js/jqueryFileTree.js',array('jquery'));
 
 
817
 
818
  }
819
 
@@ -839,12 +1023,18 @@ add_action("wp","wpdm_download_info");
839
 
840
  add_filter( 'the_content', 'wpdm_downloadable');
841
 
 
842
  add_shortcode('wpdm_hotlink','wpdm_hotlink');
843
  add_shortcode('wpdm_file','wpdm_downloadable_nsc');
844
  add_shortcode('wpdm_tree','wpdm_tree');
 
845
 
846
  add_action('init','wpdm_embed_tree');
847
  add_action('init','wpdm_process');
 
 
 
 
848
 
849
  add_action("init","wpdm_file_browser");
850
  add_action("init","wpdm_dir_tree");
2
  /*
3
  Plugin Name: Download Manager
4
  Plugin URI: http://www.wpdownloadmanager.com/
5
+ Description: Manage, track and control file download from your wordpress site
6
  Author: Shaon
7
+ Version: 2.5.96
8
  Author URI: http://www.wpdownloadmanager.com/
9
  */
10
 
11
+ error_reporting(0);
12
 
13
  $d = str_replace('\\','/',dirname(__FILE__));
14
  $d = explode("/", $d);
32
 
33
  if(!$_POST) $_SESSION['download'] = 0;
34
 
35
+ function wpdm_download_info(){
36
  include("download.php");
37
  }
38
 
48
  `password` varchar(40) NOT NULL,
49
  `download_count` int(11) NOT NULL,
50
  `access` enum('guest','member') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
51
+ `show_counter` tinyint(1) NOT NULL,
52
  `quota` INT NOT NULL,
53
  `link_label` varchar(255) NOT NULL,
54
+ `icon` VARCHAR( 256 ) NOT NULL,
55
  PRIMARY KEY (`id`)
56
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8";
57
 
58
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
59
 
60
  $wpdb->query($sql);
61
+ $tmpdata = $wpdb->get_results("SHOW COLUMNS FROM ahm_files");
62
+ foreach($tmpdata as $d){
63
+ $fields[] = $d->Field;
64
+ }
65
+ if(!in_array('icon',$fields))
66
+ $wpdb->query("ALTER TABLE `ahm_files` ADD `icon` VARCHAR( 255 ) NOT NULL");
67
 
68
+ update_option('wpdm_access_level','publish_posts');
69
  wpdm_create_dir();
70
 
71
  }
72
 
73
+ function wpdm_top_packages($show=5, $show_count=true){
74
+ global $wpdb;
75
+
76
+ $data = $wpdb->get_results("select * from ahm_files order by download_count desc limit 0, $show",ARRAY_A);
77
+ foreach($data as $d){
78
+ $d['title'] = stripcslashes($d['title']);
79
+ $key = $d['id'];
80
+ if($show_count) $sc = "<br/><i>$d[download_count] downloads</i>";
81
+ $url = home_url("/?download={$d[id]}");
82
+ echo "<li><div class='wpdm_link'><a class='wpdm-popup' title='$d[title]' href='$url'>{$d[title]}</a> $sc</div></li>\r\n";
83
+ }
84
+ }
85
+
86
  function wpdm_new_packages($show=5, $show_count=true){
87
  global $wpdb;
88
 
89
  $data = $wpdb->get_results("select * from ahm_files order by id desc limit 0, $show",ARRAY_A);
90
  foreach($data as $d){
 
91
  $key = $d['id'];
92
+ $d['title'] = stripcslashes($d['title']);
93
+ $d['icon'] = $d['icon']?$d['icon']:'file_extension_'.end(explode('.',$d['file'])).'.png';
94
  if($show_count) $sc = "<br/><i>$d[download_count] downloads</i>";
95
  $url = home_url("/?download={$d[id]}");
96
+ echo "<li><div class='wpdm_link'><img src='".plugins_url('download-manager/icon/'.$d['icon'])."' style='border:0px;box-shadow:none;float:left;margin-right:5px;margin-top:5px;'><a style='line-height:normal;' class='wpdm-popup' title='$d[title]' href='$url'>{$d[title]}</a> $sc</div><div style='clear:both;margin-bottom:5px'></div></li>\r\n";
97
  }
98
  }
99
 
138
 
139
  }
140
 
141
+ function wpdm_all_packages($params = array()){
142
+ @extract($params);
143
+ global $wpdb, $current_user;
144
+ ob_start();
145
+ include("wpdm-all-downloads.php");
146
+ $data = ob_get_contents();
147
+ ob_clean();
148
+ return $data;
149
+ }
150
 
151
  function wpdm_downloadable_nsc($params){
152
  global $wpdb;
153
+ extract($params);
154
+
 
155
  $home = home_url('/');
156
+ $password_field = '';
157
+ $bg = '';
158
 
159
  $sap = count($_GET)>0?'&':'?';
160
 
161
  $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
162
+ $data['title'] = stripcslashes($data['title']);
163
+ $data['description'] = stripcslashes($data['description']);
164
  if($title=='true') $title = "<h3>".$data['title']."</h3>";
165
  else $title = '';
166
+ if($desc=='true') $desc = wpautop($data['description'])."</br>";
167
  else $desc = '';
168
  $desc = stripslashes($desc);
169
  if($data['show_counter']!=0) $hc= 'has-counter';
192
  $loginform = "<div id='wpdm-login-form' class='wpdm-login-form'>".wp_login_form( $args ).'</div>';*/
193
 
194
  //"<div class=passit>Login Required<br/><input placeholder='Username' type=text id='username_{$id}' size=15 class='inf' /> <input placeholder='Password' class='inf' type=password id='password_{$id}' size=15 /><span class='perror'></span></div>";
195
+ if($data['icon']!='') $bg = "background-image: url(".plugins_url()."/download-manager/icon/{$data[icon]});";
196
+
197
+ $html = "<div id='wpdm_file_{$id}' class='wpdm_file $template'>{$title}<div class='cont'>{$desc}{$loginform}<div class='btn_outer'><div class='btn_outer_c' style='{$bg}'><a class='btn_left $classrel $hc login-please' rel='{$id}' title='{$data[title]}' href='$url' >$link_label</a>";
198
  //if($data['show_counter']!=0)
199
  //$html .= "<span class='btn_right counter'>$data[download_count] downloads</span>";
200
  //else
202
  $html .= "</div></div><div class='clear'></div></div></div>";
203
  }
204
  else {
205
+ if($data['icon']!='') $bg = "background-image: url(\"".plugins_url()."/download-manager/icon/{$data[icon]}\");";
206
  if($data['password']=='') { $url = home_url('/?wpdmact=process&did='.base64_encode($id.'.hotlink')); $classrel = ""; }
207
  else { $classrel='haspass'; /*$url = home_url('/?download='.$id);*/ $url = home_url('/'); $password_field = "<div class=passit>Enter password<br/><input type=password id='pass_{$id}' size=15 /><span class='perror'></span></div>"; }
208
+ $html = "<div id='wpdm_file_{$id}' class='wpdm_file $template'>{$title}<div class='cont'>{$desc}{$password_field}<div class='btn_outer'><div class='btn_outer_c' style='{$bg}'><a class='btn_left $classrel $hc' rel='{$id}' title='{$data['title']}' href='$url' >$link_label</a>";
209
  if($data['show_counter']!=0)
210
  $html .= "<span class='btn_right counter'>$data[download_count] downloads</span>";
211
  else
225
  $sap = count($_GET)>0?'&':'?';
226
  for($i=0;$i<count($matches[1]);$i++){
227
  $id = $matches[1][$i];
228
+ $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
229
+ $data['title'] = stripcslashes($data['title']);
230
  $wpdm_login_msg = get_option('wpdm_login_msg')?get_option('wpdm_login_msg'):'Login Required';
231
  $link_label = $data['link_label']?$data['link_label']:'Download';
232
  if($data['access']=='member'&&!is_user_logged_in())
252
  function wpdm_cblist_categories($parent="", $level = 0, $sel = array()){
253
  $cats = maybe_unserialize(get_option('_fm_categories'));
254
  if(is_array($cats)){
255
+ //if($parent!='') echo "<ul>";
256
  foreach($cats as $id=>$cat){
257
+ $pres = str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $level);
258
  if($cat['parent']==$parent){
259
  if(in_array($id,$sel))
260
  $checked = 'checked=checked';
261
  else
262
  $checked = '';
263
+ echo "<li style='line-height:16px'><input type='checkbox' name='file[category][]' value='$id' $checked /> $cat[title]";
264
+ echo "<ul style='margin:0px;margin-left:20px;padding:0px;'>";
265
+ wpdm_cblist_categories($id,$level+1, $sel);
266
+ echo "</ul>";
267
+ echo "</li>\n";
268
+ }
269
  }
270
+ //if($parent!='') echo "</ul>";
271
  }
272
  }
273
 
274
  function wpdm_dropdown_categories($parent="", $level = 0, $sel='',$cid='',$class=array()){
275
+ $cats = maybe_unserialize(get_option('_fm_categories'));
276
  if(!is_array($cats)) $cats = array();
277
  foreach($cats as $id=>$cat){
278
  $pres = str_repeat("&mdash;", $level);
291
  }
292
 
293
  function wpdm_tree(){
294
+ $treejs = plugins_url().'/download-manager/js/jqueryFileTree.js';
295
+ $treecss = plugins_url().'/download-manager/css/jqueryFileTree.css';
296
+ $siteurl = site_url();
297
+ $data = <<<TREE
298
+ <script language="JavaScript" src="{$treejs}"></script>
299
+ <link rel="stylesheet" href="{$treecss}" />
300
  <div id="tree"></div>
301
  <script language="JavaScript">
302
  <!--
303
  jQuery(document).ready( function() {
304
  jQuery('#tree').fileTree({
305
+ script: '{$siteurl}/?task=wpdm_tree',
306
  expandSpeed: 1000,
307
  collapseSpeed: 1000,
308
  multiFolder: false
310
  //alert(file);
311
  //var sfilename = file.split('/');
312
  //var filename = sfilename[sfilename.length-1];
313
+ tb_show(jQuery(this).html(),'{$siteurl}/?download='+file+'&modal=1&width=600&height=400');
314
 
315
  });
316
 
318
  });
319
  //-->
320
  </script>
321
+ TREE;
322
+
323
+ return $data;
324
  }
325
 
326
  function wpdm_embed_tree(){
327
+ if(!isset($_GET['task'])||$_GET['task']!='wpdm_tree') return;
328
  global $wpdb;
329
  $cats = maybe_unserialize(get_option('_fm_categories'));
330
  if(!is_array($cats)) $cats = array();
337
  $_POST['dir'] = $_POST['dir']=='/'?'':$_POST['dir'];
338
  foreach( $cats as $id=>$file ) {
339
  if($file['parent']==$_POST['dir'])
340
+ echo "<li class=\"directory collapsed\"><a href=\"#\" rel=\"" . $id . "\">" . htmlentities(stripcslashes($file['title'])) . "</a></li>";
341
  }
342
 
343
  // All files
344
+
345
+
346
+ if($_POST['dir'])
347
+ $ndata = $wpdb->get_results("select * from ahm_files where category like '%\"{$_POST['dir']}\"%'",ARRAY_A);
348
+ else
349
+ $ndata = $wpdb->get_results("select * from ahm_files where category = 'N;'",ARRAY_A);
350
+
351
  $sap = '?'; //count($_GET)>0?'&':'?';
352
 
353
  foreach($ndata as $data){
354
  $html = '';
355
+ $data['title'] = stripcslashes($data['title']);
356
  $link_label = $data['title']?$data['title']:'Download';
357
+ $data['page_link'] = "<a class='wpdm-popup' href='' rel='{$data['id']}'>$link_label</a>";
358
+ if(isset($data['preview'])&&$data['preview']!='')
359
+ $data['thumb'] = "<img class='wpdm_icon' align='left' src='".plugins_url()."/{$data['preview']}' />";
360
  else
361
  $data['thumb'] = '';
362
+ if(isset($data['icon'])&&$data['icon']!='')
363
+ $data['icon'] = "<img class='wpdm_icon' align='left' src='".plugins_url()."/{$data['icon']}' />";
364
  else
365
  $data['icon'] = '';
366
 
367
 
368
  if($data['show_counter']==1){
369
+ $counter = "{$data['download_count']} downloads<br/>";
370
  $data['counter'] = $counter;
371
  }
372
  $ext = end(explode(".", $data['file']));
374
  //$repeater = stripslashes( strtr( $category['template_repeater'], $reps ));
375
  $template = "<li class=\"wpdm_clink file ext_$ext\">$data[page_link]</li>";
376
  if($data['access']=='member'&&!is_user_logged_in())
377
+ $template = "<li class=\"file ext_$ext\"><a href='".get_option('siteurl')."/wp-login.php?redirect_to=".$_SERVER['REQUEST_URI']."' >{$data['title']}<small> (login to download)</small></a></li>";
378
  $html .= $template;
379
 
380
 
417
  if(!file_exists(UPLOAD_DIR.'.htaccess'))
418
  wpdm_set_htaccess();
419
 
420
+ if(isset($_GET['task'])&&$_GET['task']!=''&&function_exists($_GET['task']))
421
  return call_user_func($_GET['task']);
422
  else
423
  include('wpdm-list-files.php');
448
  @chmod(UPLOAD_DIR,0777);
449
  @chmod(dir(__FILE__).'/cache/',0777);
450
  wpdm_set_htaccess();
451
+ if(isset($_GET['re'])&&$_GET['re']==1) {
452
  if(file_exists(UPLOAD_DIR)) $s=1;
453
  else $s = 0;
454
  echo "<script>
459
  }
460
 
461
  function wpdm_settings(){
462
+ if(isset($_POST['access'])){
463
+
464
+ update_option('wpdm_access_level',$_POST['access']);
465
+ update_option('wpdm_login_msg',$_POST['wpdm_login_msg']);
466
+ update_option('wpdm_show_cinfo',$_POST['wpdm_show_cinfo']);
467
  }
468
  if(is_uploaded_file($_FILES['icon']['tmp_name'])){
469
  ///print_r(dirname(__FILE__).'/icon/download.png');
470
  move_uploaded_file($_FILES['icon']['tmp_name'],dirname(__FILE__).'/icon/download.png');
471
  }
472
  $access = get_option('wpdm_access_level');
473
+ $wpdm_show_cinfo = get_option('wpdm_show_cinfo');
474
  include('wpdm-settings.php');
475
  }
476
 
477
  function wpdm_add_new_file(){
478
  global $wpdb;
479
+
480
+ if(isset($_POST['file'])){
481
+ extract($_POST);
482
+
483
+
484
+ $file['show_counter'] = 0;
485
+ $file['quota'] = $file['quota']?$file['quota']:0;
486
+ $file['category'] = serialize($file['category']);
487
+ $wpdb->insert("ahm_files", $file);
488
+ if(!$wpdb->insert_id){
489
+ $wpdb->show_errors();
490
+ $wpdb->print_error();
491
+ die();
492
+ }
493
+ die('Created!');
494
+
495
+ }
496
+
497
  if(!file_exists(UPLOAD_DIR)){
498
 
499
  echo "
504
  </p></div>";
505
  }
506
 
507
+ if($_GET['success']==1){
508
  echo "
509
  <div id=\"message\" class=\"updated fade\"><p>
510
  Congratulation! Plugin is ready to use now.
512
  ";
513
  }
514
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
515
 
516
  include('wpdm-add-new-file.php');
517
  }
518
 
519
  function wpdm_edit_file(){
520
  global $wpdb;
521
+ if($_POST['file']&&$_POST['id']){
522
  extract($_POST);
523
+
 
 
 
 
 
 
 
524
 
525
  $file['category'] = serialize($file['category']);
526
+
527
+ $wpdb->update("ahm_files", $file, array("id"=>$_POST['id']));
528
+
529
+ die('Updated!');
 
 
530
 
531
  }
532
+ $id = intval($_GET[id]);
533
+ $file = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
534
 
535
  include('wpdm-add-new-file.php');
536
  }
549
  if($_POST['cat']){
550
  $tpldata = maybe_unserialize(get_option('_fm_categories'));
551
  if(!is_array($tpldata)) $tpldata =array();
552
+ $_POST['cat']['title'] = esc_attr($_POST['cat']['title']);
553
+ $_POST['cat']['content'] = esc_attr($_POST['cat']['content']);
554
+ $tcid = $_POST['cid']?$_POST['cid']:trim(strtolower(preg_replace("/([^a-zA-Z0-9\-]+)/","-", $_POST['cat']['title'])),"-");
555
+ if($tcid=='') $tcid = uniqid();
556
+ $tcid = $tcid=='-'?uniqid():$tcid;
557
  $cid = $tcid;
558
  while(array_key_exists($cid, $tpldata)&&$_POST['cid']==''){
559
  $cid = $tcid."-".(++$postfx);
609
  $html = '';
610
  foreach($ndata as $data){
611
 
612
+ $link_label = $data['title']?stripcslashes($data['title']):'Download';
613
+ $data['page_link'] = "<a class='wpdm-popup' href='{$postlink}{$sap}download={$data['id']}'>$link_label</a>";
614
+ //if($data['password']=='') { $data['page_link'] = "<a href='".home_url('/?wpdmact=process&did='.base64_encode($id.'.hotlink'))."'>{$link_label}</a>"; }
615
+ if($data['password']=='') {
616
+ $url = home_url('/?wpdmact=process&did='.base64_encode($data['id'].'.hotlink'));
617
+ $data['page_link'] = "<a href='{$url}'>$link_label</a>";
618
+ }
619
+ if($data['icon']!='') $bg = "background-image: url(\"".plugins_url()."/download-manager/icon/{$data[icon]}\");";
 
 
 
620
 
621
  if($data['show_counter']==1){
622
  $counter = "{$data[download_count]} downloads<br/>";
625
 
626
  //foreach( $data as $ind=>$val ) $reps["[".$ind."]"] = $val;
627
  //$repeater = stripslashes( strtr( $category['template_repeater'], $reps ));
628
+ $template = "<li><div class='wpdm_clink' style='{$bg}'><b>$data[page_link]</b><br/><small>$data[counter]</small></div></li>";
629
  if($data['access']=='member'&&!is_user_logged_in())
630
+ $template = "<li><div class='wpdm_clink' style='{$bg}'><a href='".get_option('siteurl')."/wp-login.php?redirect_to=".$_SERVER['REQUEST_URI']."' >$data[title]</a></b><br/><small>login to download</small></div></li>";
631
  $html .= $template;
632
 
633
 
640
 
641
 
642
  }
643
+
644
+ if(get_option('wpdm_show_cinfo','no')=='yes') $html = "<h3>{$category['title']}</h3>".wpautop($category['content']).$html;
645
 
646
  return "<ul class='wpdm-category $id'>".$html."</ul><div style='clear:both'></div>".$pag->show()."<div style='clear:both'></div>";
647
  }
648
 
649
+ function wpdm_embed_category_sc($params){
650
+ global $wpdb, $current_user, $post, $wp_query;
651
+ extract($params);
652
+ $postlink = get_permalink($post->ID);
653
+ get_currentuserinfo();
654
+
655
+ $user = new WP_User(null);
656
+ $categories = maybe_unserialize(get_option("_fm_categories",true));
657
+ $category = $categories[$id];
658
+ $order = isset($order) && $order!="" ? $order: "desc";
659
+
660
+ $order_query = isset($order_field) && $order_field != '' ? "order by $order_field $order" : "order by id DESC";
661
+ $total = $wpdb->get_var("select count(*) from ahm_files where category like '%\"$id\"% $order_query'");
662
+
663
+ $item_per_page = 10;
664
+ $pages = ceil($total/$item_per_page);
665
+ $page = $_GET['cp']?$_GET['cp']:1;
666
+ $start = ($page-1)*$item_per_page;
667
+ $pag = new wpdmpagination();
668
+ $pag->items($total);
669
+ $pag->limit($item_per_page);
670
+ $pag->currentPage($page);
671
+ $plink = $url = preg_replace("/[\?|\&]+cp=[0-9]+/","",$_SERVER['REQUEST_URI']);
672
+ $url = strpos($url,'?')?$url.'&':$url.'?';
673
+ $pag->urlTemplate($url."cp=[%PAGENO%]");
674
+
675
+ $ndata = $wpdb->get_results("select * from ahm_files where category like '%\"$id\"%' $order_query limit $start, $item_per_page",ARRAY_A);
676
+
677
+
678
+
679
+ $sap = strpos($plink,'?')>0?'&':'?';
680
+ $html = '';
681
+ foreach($ndata as $data){
682
+
683
+ $link_label = $data['title']?stripcslashes($data['title']):'Download';
684
+ $data['page_link'] = "<a class='wpdm-popup' href='{$postlink}{$sap}download={$data['id']}'>$link_label</a>";
685
+ //if($data['password']=='') { $data['page_link'] = "<a href='".home_url('/?wpdmact=process&did='.base64_encode($id.'.hotlink'))."'>{$link_label}</a>"; }
686
+ if($data['password']=='') {
687
+ $url = home_url('/?wpdmact=process&did='.base64_encode($data['id'].'.hotlink'));
688
+ $data['page_link'] = "<a href='{$url}'>$link_label</a>";
689
+ }
690
+ if($data['icon']!='') $bg = "background-image: url(\"".plugins_url()."/download-manager/icon/{$data[icon]}\");";
691
+
692
+ if($data['show_counter']==1){
693
+ $counter = "{$data[download_count]} downloads<br/>";
694
+ $data['counter'] = $counter;
695
+ }
696
+
697
+ //foreach( $data as $ind=>$val ) $reps["[".$ind."]"] = $val;
698
+ //$repeater = stripslashes( strtr( $category['template_repeater'], $reps ));
699
+ $template = "<li><div class='wpdm_clink' style='{$bg}'><b>$data[page_link]</b><br/><small>$data[counter]</small></div></li>";
700
+ if($data['access']=='member'&&!is_user_logged_in())
701
+ $template = "<li><div class='wpdm_clink' style='{$bg}'><a href='".get_option('siteurl')."/wp-login.php?redirect_to=".$_SERVER['REQUEST_URI']."' >$data[title]</a></b><br/><small>login to download</small></div></li>";
702
+ $html .= $template;
703
+
704
+
705
+ END;
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+ }
714
+
715
+ if(get_option('wpdm_show_cinfo','no')=='yes') $html = "<h3>{$category['title']}</h3>".wpautop($category['content']).$html;
716
+
717
+ return "<ul class='wpdm-category $id'>".$html."</ul><div style='clear:both'></div>".$pag->show()."<div style='clear:both'></div>";
718
+ }
719
+
720
 
721
  function wpdm_tinymce()
722
  {
885
  if($id=='') return;
886
  $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
887
  if($data['id']=='') return;
888
+ $data['link_label'] = stripcslashes($data['link_label']);
889
  $link_label = $link_label?$link_label:$data['link_label'];
890
  $url = home_url('/?wpdmact=process&did='.base64_encode($id.'.hotlink'));
891
  return "<a href='$url'>$link_label</a>";
901
  }
902
  }
903
 
904
+ function wpdm_save_file(){
905
+ global $wpdb;
906
+ if(isset($_POST['id'])&&isset($_POST['wpdmtask'])&&$_POST['wpdmtask']=='update'){
907
+ extract($_POST);
908
+
909
+
910
+ $file['category'] = serialize($file['category']);
911
+
912
+ $wpdb->update("ahm_files", $file, array("id"=>$_POST['id']));
913
+
914
+ die('updated');
915
+
916
+ }
917
+
918
+ if($_POST['wpdmtask']=='create'){
919
+ extract($_POST);
920
+
921
+ $file['show_counter'] = 0;
922
+ $file['quota'] = $file['quota']?$file['quota']:0;
923
+ $file['category'] = serialize($file['category']);
924
+ $file['title'] = esc_attr($file['title']);
925
+ $id = $wpdb->insert("ahm_files", $file);
926
+ if(!$wpdb->insert_id){
927
+ $wpdb->show_errors();
928
+ $wpdb->print_error();
929
+ die();
930
+ }
931
+ echo $wpdb->insert_id;
932
+ die();
933
+ }
934
+ }
935
+
936
+
937
+ // handle uploaded file here
938
+ function wpdm_check_upload(){
939
+ check_ajax_referer('photo-upload');
940
+ if(file_exists(UPLOAD_DIR.$_FILES['async-upload']['name']))
941
+ $filename = time().'wpdm_'.$_FILES['async-upload']['name'];
942
+ else
943
+ $filename = $_FILES['async-upload']['name'];
944
+ move_uploaded_file($_FILES['async-upload']['tmp_name'],UPLOAD_DIR.$filename);
945
+ $filesize = number_format(filesize(UPLOAD_DIR.'/'.$filename)/1025,2);
946
+ echo $filename."|||".$filesize;
947
+ exit;
948
+ }
949
+
950
+ function wpdm_delete__file(){
951
+ global $wpdb;
952
+ $id = intval($_REQUEST['file']);
953
+ $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
954
+ if(file_exists(UPLOAD_DIR.'/'.$data['file']))
955
+ @unlink(UPLOAD_DIR.'/'.$data['file']);
956
+ else if(file_exists($data['file']))
957
+ @unlink($data['file']);
958
+ unset($data['file']);
959
+ $wpdb->query("update ahm_files set `file`='' where id='$id'");
960
+ die('ok');
961
+ }
962
+
963
+
964
+ function wpdm_help(){
965
+ ?>
966
+ <div class="wrap">
967
+ <div class="icon32" id="icon-index"><br></div>
968
+ <h2>Help</h2> <br>
969
+
970
+ If you have anything to ask or if anything not clear please search or ask here:
971
+ <br/>
972
+ <strong><a href="http://www.wpdownloadmanager.com/support/forum/download-manager-free/" target="_blank">http://www.wpdownloadmanager.com/support/forum/download-manager-free/</a></strong>
973
+
974
+
975
+
976
+ <?php
977
+ }
978
+
979
+
980
+
981
  function wpdm_menu(){
982
+ //echo get_option('wpdm_access_level','manage_options');die();
983
+ add_menu_page("File Manager","File Manager",get_option('wpdm_access_level','manage_options'),'file-manager','wpdm_admin_options',plugins_url('download-manager/img/donwloadmanager-16.png'));
984
+ add_submenu_page( 'file-manager', 'File Manager', 'Manage', get_option('wpdm_access_level','manage_options'), 'file-manager', 'wpdm_admin_options');
985
+ add_submenu_page( 'file-manager', 'Add New File &lsaquo; File Manager', 'Add New File', get_option('wpdm_access_level','manage_options'), 'file-manager/add-new-file', 'wpdm_add_new_file');
986
+ add_submenu_page( 'file-manager', 'Categories &lsaquo; File Manager', 'Categories', get_option('wpdm_access_level','manage_options'), 'file-manager/categories', 'wpdm_categories');
987
+ add_submenu_page( 'file-manager', 'Settings &lsaquo; File Manager', 'Settings', get_option('wpdm_access_level','manage_options'), 'file-manager/settings', 'wpdm_settings');
988
+ add_submenu_page( 'file-manager', 'Help &lsaquo; File Manager', 'Help', get_option('wpdm_access_level','manage_options'), 'file-manager/help', 'wpdm_help');
989
 
990
  }
991
 
993
  function wpdm_admin_enque_scripts(){
994
  wp_enqueue_style('icons',plugins_url().'/download-manager/css/icons.css');
995
  wp_enqueue_script('jquery');
996
+ wp_enqueue_script('jquery-form');
997
+ wp_enqueue_script('plupload-all');
998
  wp_enqueue_script('file-tree-js',plugins_url().'/download-manager/js/jqueryFileTree.js',array('jquery'));
999
+ wp_enqueue_script('chosen-jquery',plugins_url().'/download-manager/js/chosen.jquery.min.js',array('jquery'));
1000
+ wp_enqueue_style('chosen-css',plugins_url().'/download-manager/css/chosen.css');
1001
 
1002
  }
1003
 
1023
 
1024
  add_filter( 'the_content', 'wpdm_downloadable');
1025
 
1026
+ add_shortcode('wpdm_all_packages','wpdm_all_packages');
1027
  add_shortcode('wpdm_hotlink','wpdm_hotlink');
1028
  add_shortcode('wpdm_file','wpdm_downloadable_nsc');
1029
  add_shortcode('wpdm_tree','wpdm_tree');
1030
+ add_shortcode('wpdm_category','wpdm_embed_category_sc');
1031
 
1032
  add_action('init','wpdm_embed_tree');
1033
  add_action('init','wpdm_process');
1034
+ add_action('wp_ajax_file_upload','wpdm_check_upload');
1035
+ add_action('wp_ajax_delete_file','wpdm_delete__file');
1036
+ add_action('wp_ajax_save_wpdm_file','wpdm_save_file');
1037
+
1038
 
1039
  add_action("init","wpdm_file_browser");
1040
  add_action("init","wpdm_dir_tree");
download.php CHANGED
@@ -1,17 +1,19 @@
1
  <?php
2
  global $wpdb;
 
3
  $dl = isset($_REQUEST['download'])?(int)$_REQUEST['download']:0;
4
  if($dl>0){
 
5
  $data = $wpdb->get_row("select * from ahm_files where id='$dl'",ARRAY_A);
6
  if($data['access']=='member'&&!is_user_logged_in()){
7
  $wpdm_login_msg = get_option('wpdm_login_msg')?get_option('wpdm_login_msg'):'Login Required';
8
- die("<div style='padding:20px 30px;background:#fff'><a href='".get_option('siteurl')."/wp-login.php' style=\"background:url('".get_option('siteurl')."/wp-content/plugins/download-manager/l24.png') no-repeat;padding:3px 12px 12px 28px;font:bold 10pt verdana;\">".$wpdm_login_msg."</a></div>") ;
9
  }
10
- if($_POST['password']==$data['password']&&isset($_POST['password'])){
11
  $did = uniqid();
12
  file_put_contents(dirname(__FILE__).'/cache/'.$did,serialize($data));
13
  die($did);
14
- }else if($_POST['password']!=$data['password']&&isset($_POST['password'])){
15
  die('error');
16
  }
17
  ?>
@@ -26,7 +28,7 @@ form{text-align:center;}
26
 
27
  if($data){
28
 
29
- echo "<div style='min-weight:300px;min-height:200px;padding:30px;background:#fff;color:#000'><h1><nobr>$data[title]</nobr></h1><br/><p>".stripcslashes($data[description])."</p>";
30
  /*
31
  if($_POST&&$data[password]==''){
32
  echo "<script>
@@ -36,12 +38,12 @@ if($data){
36
  <form method="post">
37
  <?php
38
 
39
- if($_POST['password']==$data['password']&&count($_POST)>0){
40
 
41
 
42
 
43
 
44
- mysql_query("update ahm_files set `download_count`=`download_count`+1 where id='{$data[id]}'");
45
  echo "Please Wait... Download starting in a while...
46
  </form>
47
 
1
  <?php
2
  global $wpdb;
3
+ $did = '';
4
  $dl = isset($_REQUEST['download'])?(int)$_REQUEST['download']:0;
5
  if($dl>0){
6
+ @header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
7
  $data = $wpdb->get_row("select * from ahm_files where id='$dl'",ARRAY_A);
8
  if($data['access']=='member'&&!is_user_logged_in()){
9
  $wpdm_login_msg = get_option('wpdm_login_msg')?get_option('wpdm_login_msg'):'Login Required';
10
+ die("<div style='padding:20px 30px;background:#fff'><a href='".get_option('siteurl')."/wp-login.php' style=\"background:url('".get_option('siteurl')."/wp-content/plugins/download-manager/l24.png') no-repeat;padding:3px 12px 12px 28px;font:bold 10pt verdana;\">".$wpdm_login_msg."</a></div>");
11
  }
12
+ if(isset($_POST['password'])&&isset($data['password'])&&$_POST['password']==$data['password']){
13
  $did = uniqid();
14
  file_put_contents(dirname(__FILE__).'/cache/'.$did,serialize($data));
15
  die($did);
16
+ }else if(isset($_POST['password'])&&isset($data['password'])&&$_POST['password']!=$data['password']){
17
  die('error');
18
  }
19
  ?>
28
 
29
  if($data){
30
 
31
+ echo "<div style='min-weight:300px;min-height:200px;padding:30px;background:#fff;color:#000'><h1><nobr>{$data['title']}</nobr></h1><br/><p>".wpautop(stripcslashes($data['description']))."</p>";
32
  /*
33
  if($_POST&&$data[password]==''){
34
  echo "<script>
38
  <form method="post">
39
  <?php
40
 
41
+ if(isset($_POST['password'])&&isset($data['password'])&&$_POST['password']==$data['password']){
42
 
43
 
44
 
45
 
46
+ mysql_query("update ahm_files set `download_count`=`download_count`+1 where id='{$data['id']}'");
47
  echo "Please Wait... Download starting in a while...
48
  </form>
49
 
editor_plugin.js CHANGED
@@ -8,7 +8,7 @@
8
  ed.windowManager.open({
9
  title: 'Download Controller',
10
  file : 'admin.php?wpdm_action=wpdm_tinymce_button',
11
- height: 350,
12
  width:400,
13
  inline : 1
14
  }, {
8
  ed.windowManager.open({
9
  title: 'Download Controller',
10
  file : 'admin.php?wpdm_action=wpdm_tinymce_button',
11
+ height: 550,
12
  width:400,
13
  inline : 1
14
  }, {
functions.php CHANGED
@@ -145,4 +145,10 @@
145
  return $msgs[$key]?$msgs[$key]:$key;
146
  }
147
 
 
 
 
 
 
 
148
  ?>
145
  return $msgs[$key]?$msgs[$key]:$key;
146
  }
147
 
148
+ function wpdm_skip_ngg_resource_manager($r){
149
+ return false;
150
+ }
151
+
152
+ add_filter('run_ngg_resource_manager', 'wpdm_skip_ngg_resource_manager');
153
+
154
  ?>
icon/35.png ADDED
Binary file
icon/Box Download.png ADDED
Binary file
icon/Cloud Download Off.png ADDED
Binary file
icon/Cloud Download On.png ADDED
Binary file
icon/Download file.png ADDED
Binary file
icon/Download-01.png ADDED
Binary file
icon/Download_Blue.png ADDED
Binary file
icon/Download_Crate.png ADDED
Binary file
icon/Download_Green.png ADDED
Binary file
icon/Globe-Download.png ADDED
Binary file
icon/Gnome-Document-Save-32.png ADDED
Binary file
icon/Gnome-Emblem-Downloads-32.png ADDED
Binary file
icon/Package-Download.png ADDED
Binary file
icon/Torrents.png ADDED
Binary file
icon/agt_add-to-desktop.png ADDED
Binary file
icon/agt_update_drivers.png ADDED
Binary file
icon/agt_update_misc.png ADDED
Binary file
icon/agt_update_recommended.png ADDED
Binary file
icon/agt_update_recommended1.png ADDED
Binary file
icon/application-x-kgetlist.png ADDED
Binary file
icon/archive.png ADDED
Binary file
icon/ark.png ADDED
Binary file
icon/ark2.png ADDED
Binary file
icon/arrow down.png ADDED
Binary file
icon/arrow_down.png ADDED
Binary file
icon/arrow_down_alt1.png ADDED
Binary file
icon/basket_download.png ADDED
Binary file
icon/bottom.png ADDED
Binary file
icon/cloud-download.png ADDED
Binary file
icon/down2.png ADDED
Binary file
icon/down_arrow.png ADDED
Binary file
icon/download off.png ADDED
Binary file
icon/download on.png ADDED
Binary file
icon/download-box-open.png ADDED
Binary file
icon/download-database.png ADDED
Binary file
icon/download_32.png ADDED
Binary file
icon/download_accept_32.png ADDED
Binary file
icon/download_cancel_32.png ADDED
Binary file
icon/download_cloud.png ADDED
Binary file
icon/download_down_arrow.png ADDED
Binary file
icon/download_for_linux.png ADDED
Binary file
icon/download_for_mac.png ADDED
Binary file
icon/download_for_windows.png ADDED
Binary file
icon/download_information_32.png ADDED
Binary file
icon/download_manager.png ADDED
Binary file
icon/download_pause_32.png ADDED
Binary file
icon/download_run_32.png ADDED
Binary file
icon/download_security_32.png ADDED
Binary file
icon/download_settings_32.png ADDED
Binary file
icon/download_stop_32.png ADDED
Binary file
icon/downloads.png ADDED
Binary file
icon/downloads_folder.png ADDED
Binary file
icon/email_download.png ADDED
Binary file
icon/emblem-downloads.png ADDED
Binary file
icon/file_download.png ADDED
Binary file
icon/file_extension_.png ADDED
Binary file
icon/file_extension_bmp.png ADDED
Binary file
icon/file_extension_doc.png ADDED
Binary file
icon/file_extension_flv.png ADDED
Binary file
icon/file_extension_gif.png ADDED
Binary file
icon/file_extension_html.png ADDED
Binary file
icon/file_extension_jpeg.png ADDED
Binary file
icon/file_extension_jpg.png ADDED
Binary file
icon/file_extension_log.png ADDED
Binary file
icon/file_extension_pdf.png ADDED
Binary file
icon/file_extension_png.png ADDED
Binary file
icon/file_extension_psd.png ADDED
Binary file
icon/file_extension_rar.png ADDED
Binary file
icon/file_extension_txt.png ADDED
Binary file
icon/file_extension_xls.png ADDED
Binary file
icon/file_extension_zip.png ADDED
Binary file
icon/find-next.png ADDED
Binary file
icon/folder-download.png ADDED
Binary file
icon/folder-downloads.png ADDED
Binary file
icon/folder_apollon.png ADDED
Binary file
icon/folder_download.png ADDED
Binary file
icon/folder_downloads_32.png ADDED
Binary file
icon/go-bottom.png ADDED
Binary file
icon/human-folder-downloads.png ADDED
Binary file
icon/icontexto-aurora-folders-downloads.png ADDED
Binary file
icon/inbox_download.png ADDED
Binary file
icon/kde-folder-downloads.png ADDED
Binary file
icon/kget_list.png ADDED
Binary file
icon/kthememgr.png ADDED
Binary file
icon/load_download.png ADDED
Binary file
icon/manilla-folder-downloads.png ADDED
Binary file
icon/misc_23.png ADDED
Binary file
icon/note_download.png ADDED
Binary file
icon/old-go-bottom.png ADDED
Binary file
icon/orange-folder-downloads.png ADDED
Binary file
icon/photo_download.png ADDED
Binary file
icon/save_download.png ADDED
Binary file
icon/share.png ADDED
Binary file
icon/system-config-kickstart.png ADDED
Binary file
icon/system-log-out.png ADDED
Binary file
icon/weather_03.png ADDED
Binary file
images/back_disabled.png ADDED
Binary file
images/back_enabled.png ADDED
Binary file
images/back_enabled_hover.png ADDED
Binary file
images/forward_disabled.png ADDED
Binary file
images/forward_enabled.png ADDED
Binary file
images/forward_enabled_hover.png ADDED
Binary file
images/theme.png ADDED
Binary file
images/wpdm.png ADDED
Binary file
images/wpeden.png ADDED
Binary file
images/wpmp.png ADDED
Binary file
js/chosen.jquery.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ // Chosen, a Select Box Enhancer for jQuery and Protoype
2
+ // by Patrick Filler for Harvest, http://getharvest.com
3
+ //
4
+ // Version 0.9.10
5
+ // Full source at https://github.com/harvesthq/chosen
6
+ // Copyright (c) 2011 Harvest http://getharvest.com
7
+
8
+ // MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
9
+ // This file is generated by `cake build`, do not edit it by hand.
10
+ (function(){var e;e=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(e){return e.nodeName.toUpperCase()==="OPTGROUP"?this.add_group(e):this.add_option(e)},e.prototype.add_group=function(e){var t,n,r,i,s,o;t=this.parsed.length,this.parsed.push({array_index:t,group:!0,label:e.label,children:0,disabled:e.disabled}),s=e.childNodes,o=[];for(r=0,i=s.length;r<i;r++)n=s[r],o.push(this.add_option(n,t,e.disabled));return o},e.prototype.add_option=function(e,t,n){if(e.nodeName.toUpperCase()==="OPTION")return e.text!==""?(t!=null&&(this.parsed[t].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:e.value,text:e.text,html:e.innerHTML,selected:e.selected,disabled:n===!0?n:e.disabled,group_array_index:t,classes:e.className,style:e.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1},e}(),e.select_to_array=function(t){var n,r,i,s,o;r=new e,o=t.childNodes;for(i=0,s=o.length;i<s;i++)n=o[i],r.add_node(n);return r.parsed},this.SelectParser=e}).call(this),function(){var e,t;t=this,e=function(){function e(e,t){this.form_field=e,this.options=t!=null?t:{},this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers(),this.finish_setup()}return e.prototype.set_default_values=function(){var e=this;return this.click_test_action=function(t){return e.test_active_click(t)},this.activate_action=function(t){return e.activate_field(t)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0]!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.search_split_words=!this.options.disable_search_split_words&&!0,this.search_contains=this.options.search_contains||!1,this.choices=0,this.single_backstroke_delete=this.options.single_backstroke_delete||!1,this.max_selected_options=this.options.max_selected_options||Infinity},e.prototype.set_default_text=function(){return this.form_field.getAttribute("data-placeholder")?this.default_text=this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.default_text=this.options.placeholder_text_multiple||this.options.placeholder_text||"Who should be able to download?":this.default_text=this.options.placeholder_text_single||this.options.placeholder_text||"Select an Option",this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||"No results match"},e.prototype.mouse_enter=function(){return this.mouse_on_container=!0},e.prototype.mouse_leave=function(){return this.mouse_on_container=!1},e.prototype.input_focus=function(e){var t=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return t.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},e.prototype.input_blur=function(e){var t=this;if(!this.mouse_on_container)return this.active_field=!1,setTimeout(function(){return t.blur_test()},100)},e.prototype.result_add_option=function(e){var t,n;return e.disabled?"":(e.dom_id=this.container_id+"_o_"+e.array_index,t=e.selected&&this.is_multiple?[]:["active-result"],e.selected&&t.push("result-selected"),e.group_array_index!=null&&t.push("group-option"),e.classes!==""&&t.push(e.classes),n=e.style.cssText!==""?' style="'+e.style+'"':"",'<li id="'+e.dom_id+'" class="'+t.join(" ")+'"'+n+">"+e.html+"</li>")},e.prototype.results_update_field=function(){return this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},e.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},e.prototype.results_search=function(e){return this.results_showing?this.winnow_results():this.results_show()},e.prototype.keyup_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale();switch(t){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:e.preventDefault();if(this.results_showing)return this.result_select(e);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.generate_field_id=function(){var e;return e=this.generate_random_id(),this.form_field.id=e,e},e.prototype.generate_random_char=function(){var e,t,n;return e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",n=Math.floor(Math.random()*e.length),t=e.substring(n,n+1)},e}(),t.AbstractChosen=e}.call(this),function(){var e,t,n,r,i={}.hasOwnProperty,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e};r=this,e=jQuery,e.fn.extend({chosen:function(n){return e.browser.msie&&(e.browser.version==="6.0"||e.browser.version==="7.0"&&document.documentMode===7)?this:this.each(function(r){var i;i=e(this);if(!i.hasClass("chzn-done"))return i.data("chosen",new t(this,n))})}}),t=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return s(i,t),i.prototype.setup=function(){return this.form_field_jq=e(this.form_field),this.current_value=this.form_field_jq.val(),this.is_rtl=this.form_field_jq.hasClass("chzn-rtl")},i.prototype.finish_setup=function(){return this.form_field_jq.addClass("chzn-done")},i.prototype.set_up_html=function(){var t,r,i,s,o;return this.container_id=this.form_field.id.length?this.form_field.id.replace(/[^\w]/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.outerWidth(),r={id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px;",title:this.form_field.title},t=e("<div />",r),this.is_multiple?t.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'):t.html('<a href="javascript:void(0)" class="chzn-single chzn-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'),this.form_field_jq.hide().after(t),this.container=e("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.find("div.chzn-drop").first(),i=this.container.height(),s=this.f_width-n(this.dropdown),this.dropdown.css({width:s+"px",top:i+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),o=s-n(this.search_container)-n(this.search_field),this.search_field.css({width:o+"px"})),this.results_build(),this.set_tab_index(),this.form_field_jq.trigger("liszt:ready",{chosen:this})},i.prototype.register_observers=function(){var e=this;return this.container.mousedown(function(t){return e.container_mousedown(t)}),this.container.mouseup(function(t){return e.container_mouseup(t)}),this.container.mouseenter(function(t){return e.mouse_enter(t)}),this.container.mouseleave(function(t){return e.mouse_leave(t)}),this.search_results.mouseup(function(t){return e.search_results_mouseup(t)}),this.search_results.mouseover(function(t){return e.search_results_mouseover(t)}),this.search_results.mouseout(function(t){return e.search_results_mouseout(t)}),this.form_field_jq.bind("liszt:updated",function(t){return e.results_update_field(t)}),this.form_field_jq.bind("liszt:activate",function(t){return e.activate_field(t)}),this.form_field_jq.bind("liszt:open",function(t){return e.container_mousedown(t)}),this.search_field.blur(function(t){return e.input_blur(t)}),this.search_field.keyup(function(t){return e.keyup_checker(t)}),this.search_field.keydown(function(t){return e.keydown_checker(t)}),this.search_field.focus(function(t){return e.input_focus(t)}),this.is_multiple?this.search_choices.click(function(t){return e.choices_click(t)}):this.container.click(function(e){return e.preventDefault()})},i.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq[0].disabled;if(this.is_disabled)return this.container.addClass("chzn-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus",this.activate_action),this.close_field();this.container.removeClass("chzn-disabled"),this.search_field[0].disabled=!1;if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},i.prototype.container_mousedown=function(t){var n;if(!this.is_disabled)return n=t!=null?e(t.target).hasClass("search-choice-close"):!1,t&&t.type==="mousedown"&&!this.results_showing&&t.preventDefault(),!this.pending_destroy_click&&!n?(this.active_field?!this.is_multiple&&t&&(e(t.target)[0]===this.selected_item[0]||e(t.target).parents("a.chzn-single").length)&&(t.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),e(document).click(this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},i.prototype.container_mouseup=function(e){if(e.target.nodeName==="ABBR"&&!this.is_disabled)return this.results_reset(e)},i.prototype.blur_test=function(e){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},i.prototype.close_field=function(){return e(document).unbind("click",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},i.prototype.activate_field=function(){return this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},i.prototype.test_active_click=function(t){return e(t.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},i.prototype.results_build=function(){var e,t,n,i,s;this.parsing=!0,this.results_data=r.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||(this.selected_item.addClass("chzn-default").find("span").text(this.default_text),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?this.container.addClass("chzn-container-single-nosearch"):this.container.removeClass("chzn-container-single-nosearch")),e="",s=this.results_data;for(n=0,i=s.length;n<i;n++)t=s[n],t.group?e+=this.result_add_group(t):t.empty||(e+=this.result_add_option(t),t.selected&&this.is_multiple?this.choice_build(t):t.selected&&!this.is_multiple&&(this.selected_item.removeClass("chzn-default").find("span").text(t.text),this.allow_single_deselect&&this.single_deselect_control_build()));return this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.html(e),this.parsing=!1},i.prototype.result_add_group=function(t){return t.disabled?"":(t.dom_id=this.container_id+"_g_"+t.array_index,'<li id="'+t.dom_id+'" class="group-result">'+e("<div />").text(t.label).html()+"</li>")},i.prototype.result_do_highlight=function(e){var t,n,r,i,s;if(e.length){this.result_clear_highlight(),this.result_highlight=e,this.result_highlight.addClass("highlighted"),r=parseInt(this.search_results.css("maxHeight"),10),s=this.search_results.scrollTop(),i=r+s,n=this.result_highlight.position().top+this.search_results.scrollTop(),t=n+this.result_highlight.outerHeight();if(t>=i)return this.search_results.scrollTop(t-r>0?t-r:0);if(n<s)return this.search_results.scrollTop(n)}},i.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},i.prototype.results_show=function(){var e;if(!this.is_multiple)this.selected_item.addClass("chzn-single-with-drop"),this.result_single_selected&&this.result_do_highlight(this.result_single_selected);else if(this.max_selected_options<=this.choices)return this.form_field_jq.trigger("liszt:maxselected",{chosen:this}),!1;return e=this.is_multiple?this.container.height():this.container.height()-1,this.form_field_jq.trigger("liszt:showing_dropdown",{chosen:this}),this.dropdown.css({top:e+"px",left:0}),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results()},i.prototype.results_hide=function(){return this.is_multiple||this.selected_item.removeClass("chzn-single-with-drop"),this.result_clear_highlight(),this.form_field_jq.trigger("liszt:hiding_dropdown",{chosen:this}),this.dropdown.css({left:"-9000px"}),this.results_showing=!1},i.prototype.set_tab_index=function(e){var t;if(this.form_field_jq.attr("tabindex"))return t=this.form_field_jq.attr("tabindex"),this.form_field_jq.attr("tabindex",-1),this.search_field.attr("tabindex",t)},i.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},i.prototype.search_results_mouseup=function(t){var n;n=e(t.target).hasClass("active-result")?e(t.target):e(t.target).parents(".active-result").first();if(n.length)return this.result_highlight=n,this.result_select(t),this.search_field.focus()},i.prototype.search_results_mouseover=function(t){var n;n=e(t.target).hasClass("active-result")?e(t.target):e(t.target).parents(".active-result").first();if(n)return this.result_do_highlight(n)},i.prototype.search_results_mouseout=function(t){if(e(t.target).hasClass("active-result"))return this.result_clear_highlight()},i.prototype.choices_click=function(t){t.preventDefault();if(this.active_field&&!e(t.target).hasClass("search-choice")&&!this.results_showing)return this.results_show()},i.prototype.choice_build=function(t){var n,r,i,s=this;return this.is_multiple&&this.max_selected_options<=this.choices?(this.form_field_jq.trigger("liszt:maxselected",{chosen:this}),!1):(n=this.container_id+"_c_"+t.array_index,this.choices+=1,t.disabled?r='<li class="search-choice search-choice-disabled" id="'+n+'"><span>'+t.html+"</span></li>":r='<li class="search-choice" id="'+n+'"><span>'+t.html+'</span><a href="javascript:void(0)" class="search-choice-close" rel="'+t.array_index+'"></a></li>',this.search_container.before(r),i=e("#"+n).find("a").first(),i.click(function(e){return s.choice_destroy_link_click(e)}))},i.prototype.choice_destroy_link_click=function(t){return t.preventDefault(),this.is_disabled?t.stopPropagation:(this.pending_destroy_click=!0,this.choice_destroy(e(t.target)))},i.prototype.choice_destroy=function(e){if(this.result_deselect(e.attr("rel")))return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),e.parents("li").first().remove(),this.search_field_scale()},i.prototype.results_reset=function(){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.is_multiple||this.selected_item.addClass("chzn-default"),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},i.prototype.results_reset_cleanup=function(){return this.current_value=this.form_field_jq.val(),this.selected_item.find("abbr").remove()},i.prototype.result_select=function(e){var t,n,r,i;if(this.result_highlight)return t=this.result_highlight,n=t.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(t):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=t,this.selected_item.removeClass("chzn-default")),t.addClass("result-selected"),i=n.substr(n.lastIndexOf("_")+1),r=this.results_data[i],r.selected=!0,this.form_field.options[r.options_index].selected=!0,this.is_multiple?this.choice_build(r):(this.selected_item.find("span").first().text(r.text),this.allow_single_deselect&&this.single_deselect_control_build()),(!e.metaKey&&!e.ctrlKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field_jq.val()!==this.current_value)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[r.options_index].value}),this.current_value=this.form_field_jq.val(),this.search_field_scale()},i.prototype.result_activate=function(e){return e.addClass("active-result")},i.prototype.result_deactivate=function(e){return e.removeClass("active-result")},i.prototype.result_deselect=function(t){var n,r;return r=this.results_data[t],this.form_field.options[r.options_index].disabled?!1:(r.selected=!1,this.form_field.options[r.options_index].selected=!1,n=e("#"+this.container_id+"_o_"+t),n.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[r.options_index].value}),this.search_field_scale(),!0)},i.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&this.selected_item.find("abbr").length<1)return this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>')},i.prototype.winnow_results=function(){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;this.no_results_clear(),f=0,l=this.search_field.val()===this.default_text?"":e("<div/>").text(e.trim(this.search_field.val())).html(),o=this.search_contains?"":"^",s=new RegExp(o+l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),p=new RegExp(l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),y=this.results_data;for(d=0,m=y.length;d<m;d++){n=y[d];if(!n.disabled&&!n.empty)if(n.group)e("#"+n.dom_id).css("display","none");else if(!this.is_multiple||!n.selected){t=!1,a=n.dom_id,u=e("#"+a);if(s.test(n.html))t=!0,f+=1;else if(this.search_split_words&&(n.html.indexOf(" ")>=0||n.html.indexOf("[")===0)){i=n.html.replace(/\[|\]/g,"").split(" ");if(i.length)for(v=0,g=i.length;v<g;v++)r=i[v],s.test(r)&&(t=!0,f+=1)}t?(l.length?(c=n.html.search(p),h=n.html.substr(0,c+l.length)+"</em>"+n.html.substr(c+l.length),h=h.substr(0,c)+"<em>"+h.substr(c)):h=n.html,u.html(h),this.result_activate(u),n.group_array_index!=null&&e("#"+this.results_data[n.group_array_index].dom_id).css("display","list-item")):(this.result_highlight&&a===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(u))}}return f<1&&l.length?this.no_results(l):this.winnow_results_set_highlight()},i.prototype.winnow_results_clear=function(){var t,n,r,i,s;this.search_field.val(""),n=this.search_results.find("li"),s=[];for(r=0,i=n.length;r<i;r++)t=n[r],t=e(t),t.hasClass("group-result")?s.push(t.css("display","auto")):!this.is_multiple||!t.hasClass("result-selected")?s.push(this.result_activate(t)):s.push(void 0);return s},i.prototype.winnow_results_set_highlight=function(){var e,t;if(!this.result_highlight){t=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),e=t.length?t.first():this.search_results.find(".active-result").first();if(e!=null)return this.result_do_highlight(e)}},i.prototype.no_results=function(t){var n;return n=e('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),n.find("span").first().html(t),this.search_results.append(n)},i.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},i.prototype.keydown_arrow=function(){var t,n;this.result_highlight?this.results_showing&&(n=this.result_highlight.nextAll("li.active-result").first(),n&&this.result_do_highlight(n)):(t=this.search_results.find("li.active-result").first(),t&&this.result_do_highlight(e(t)));if(!this.results_showing)return this.results_show()},i.prototype.keyup_arrow=function(){var e;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return e=this.result_highlight.prevAll("li.active-result"),e.length?this.result_do_highlight(e.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},i.prototype.keydown_backstroke=function(){var e;if(this.pending_backstroke)return this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke();e=this.search_container.siblings("li.search-choice").last();if(e.length&&!e.hasClass("search-choice-disabled"))return this.pending_backstroke=e,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")},i.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},i.prototype.keydown_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale(),t!==8&&this.pending_backstroke&&this.clear_backstroke();switch(t){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(e),this.mouse_on_container=!1;break;case 13:e.preventDefault();break;case 38:e.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},i.prototype.search_field_scale=function(){var t,n,r,i,s,o,u,a,f;if(this.is_multiple){r=0,u=0,s="position:absolute; left: -1000px; top: -1000px; display:none;",o=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(a=0,f=o.length;a<f;a++)i=o[a],s+=i+":"+this.search_field.css(i)+";";return n=e("<div />",{style:s}),n.text(this.search_field.val()),e("body").append(n),u=n.width()+25,n.remove(),u>this.f_width-10&&(u=this.f_width-10),this.search_field.css({width:u+"px"}),t=this.container.height(),this.dropdown.css({top:t+"px"})}},i.prototype.generate_random_id=function(){var t;t="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(e("#"+t).length>0)t+=this.generate_random_char();return t},i}(AbstractChosen),r.Chosen=t,n=function(e){var t;return t=e.outerWidth()-e.width()},r.get_side_border_padding=n}.call(this);
js/jquery.dataTables.js ADDED
@@ -0,0 +1,12099 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @summary DataTables
3
+ * @description Paginate, search and sort HTML tables
4
+ * @version 1.9.4
5
+ * @file jquery.dataTables.js
6
+ * @author Allan Jardine (www.sprymedia.co.uk)
7
+ * @contact www.sprymedia.co.uk/contact
8
+ *
9
+ * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved.
10
+ *
11
+ * This source file is free software, under either the GPL v2 license or a
12
+ * BSD style license, available at:
13
+ * http://datatables.net/license_gpl2
14
+ * http://datatables.net/license_bsd
15
+ *
16
+ * This source file is distributed in the hope that it will be useful, but
17
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
19
+ *
20
+ * For details please refer to: http://www.datatables.net
21
+ */
22
+
23
+ /*jslint evil: true, undef: true, browser: true */
24
+ /*globals $, jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/
25
+
26
+ (/** @lends <global> */function( window, document, undefined ) {
27
+
28
+ (function( factory ) {
29
+ "use strict";
30
+
31
+ // Define as an AMD module if possible
32
+ if ( typeof define === 'function' && define.amd )
33
+ {
34
+ define( ['jquery'], factory );
35
+ }
36
+ /* Define using browser globals otherwise
37
+ * Prevent multiple instantiations if the script is loaded twice
38
+ */
39
+ else if ( jQuery && !jQuery.fn.dataTable )
40
+ {
41
+ factory( jQuery );
42
+ }
43
+ }
44
+ (/** @lends <global> */function( $ ) {
45
+ "use strict";
46
+ /**
47
+ * DataTables is a plug-in for the jQuery Javascript library. It is a
48
+ * highly flexible tool, based upon the foundations of progressive
49
+ * enhancement, which will add advanced interaction controls to any
50
+ * HTML table. For a full list of features please refer to
51
+ * <a href="http://datatables.net">DataTables.net</a>.
52
+ *
53
+ * Note that the <i>DataTable</i> object is not a global variable but is
54
+ * aliased to <i>jQuery.fn.DataTable</i> and <i>jQuery.fn.dataTable</i> through which
55
+ * it may be accessed.
56
+ *
57
+ * @class
58
+ * @param {object} [oInit={}] Configuration object for DataTables. Options
59
+ * are defined by {@link DataTable.defaults}
60
+ * @requires jQuery 1.3+
61
+ *
62
+ * @example
63
+ * // Basic initialisation
64
+ * $(document).ready( function {
65
+ * $('#example').dataTable();
66
+ * } );
67
+ *
68
+ * @example
69
+ * // Initialisation with configuration options - in this case, disable
70
+ * // pagination and sorting.
71
+ * $(document).ready( function {
72
+ * $('#example').dataTable( {
73
+ * "bPaginate": false,
74
+ * "bSort": false
75
+ * } );
76
+ * } );
77
+ */
78
+ var DataTable = function( oInit )
79
+ {
80
+
81
+
82
+ /**
83
+ * Add a column to the list used for the table with default values
84
+ * @param {object} oSettings dataTables settings object
85
+ * @param {node} nTh The th element for this column
86
+ * @memberof DataTable#oApi
87
+ */
88
+ function _fnAddColumn( oSettings, nTh )
89
+ {
90
+ var oDefaults = DataTable.defaults.columns;
91
+ var iCol = oSettings.aoColumns.length;
92
+ var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
93
+ "sSortingClass": oSettings.oClasses.sSortable,
94
+ "sSortingClassJUI": oSettings.oClasses.sSortJUI,
95
+ "nTh": nTh ? nTh : document.createElement('th'),
96
+ "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
97
+ "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
98
+ "mData": oDefaults.mData ? oDefaults.oDefaults : iCol
99
+ } );
100
+ oSettings.aoColumns.push( oCol );
101
+
102
+ /* Add a column specific filter */
103
+ if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null )
104
+ {
105
+ oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch );
106
+ }
107
+ else
108
+ {
109
+ var oPre = oSettings.aoPreSearchCols[ iCol ];
110
+
111
+ /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */
112
+ if ( oPre.bRegex === undefined )
113
+ {
114
+ oPre.bRegex = true;
115
+ }
116
+
117
+ if ( oPre.bSmart === undefined )
118
+ {
119
+ oPre.bSmart = true;
120
+ }
121
+
122
+ if ( oPre.bCaseInsensitive === undefined )
123
+ {
124
+ oPre.bCaseInsensitive = true;
125
+ }
126
+ }
127
+
128
+ /* Use the column options function to initialise classes etc */
129
+ _fnColumnOptions( oSettings, iCol, null );
130
+ }
131
+
132
+
133
+ /**
134
+ * Apply options for a column
135
+ * @param {object} oSettings dataTables settings object
136
+ * @param {int} iCol column index to consider
137
+ * @param {object} oOptions object with sType, bVisible and bSearchable etc
138
+ * @memberof DataTable#oApi
139
+ */
140
+ function _fnColumnOptions( oSettings, iCol, oOptions )
141
+ {
142
+ var oCol = oSettings.aoColumns[ iCol ];
143
+
144
+ /* User specified column options */
145
+ if ( oOptions !== undefined && oOptions !== null )
146
+ {
147
+ /* Backwards compatibility for mDataProp */
148
+ if ( oOptions.mDataProp && !oOptions.mData )
149
+ {
150
+ oOptions.mData = oOptions.mDataProp;
151
+ }
152
+
153
+ if ( oOptions.sType !== undefined )
154
+ {
155
+ oCol.sType = oOptions.sType;
156
+ oCol._bAutoType = false;
157
+ }
158
+
159
+ $.extend( oCol, oOptions );
160
+ _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
161
+
162
+ /* iDataSort to be applied (backwards compatibility), but aDataSort will take
163
+ * priority if defined
164
+ */
165
+ if ( oOptions.iDataSort !== undefined )
166
+ {
167
+ oCol.aDataSort = [ oOptions.iDataSort ];
168
+ }
169
+ _fnMap( oCol, oOptions, "aDataSort" );
170
+ }
171
+
172
+ /* Cache the data get and set functions for speed */
173
+ var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
174
+ var mData = _fnGetObjectDataFn( oCol.mData );
175
+
176
+ oCol.fnGetData = function (oData, sSpecific) {
177
+ var innerData = mData( oData, sSpecific );
178
+
179
+ if ( oCol.mRender && (sSpecific && sSpecific !== '') )
180
+ {
181
+ return mRender( innerData, sSpecific, oData );
182
+ }
183
+ return innerData;
184
+ };
185
+ oCol.fnSetData = _fnSetObjectDataFn( oCol.mData );
186
+
187
+ /* Feature sorting overrides column specific when off */
188
+ if ( !oSettings.oFeatures.bSort )
189
+ {
190
+ oCol.bSortable = false;
191
+ }
192
+
193
+ /* Check that the class assignment is correct for sorting */
194
+ if ( !oCol.bSortable ||
195
+ ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) )
196
+ {
197
+ oCol.sSortingClass = oSettings.oClasses.sSortableNone;
198
+ oCol.sSortingClassJUI = "";
199
+ }
200
+ else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 )
201
+ {
202
+ oCol.sSortingClass = oSettings.oClasses.sSortable;
203
+ oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI;
204
+ }
205
+ else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 )
206
+ {
207
+ oCol.sSortingClass = oSettings.oClasses.sSortableAsc;
208
+ oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed;
209
+ }
210
+ else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 )
211
+ {
212
+ oCol.sSortingClass = oSettings.oClasses.sSortableDesc;
213
+ oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed;
214
+ }
215
+ }
216
+
217
+
218
+ /**
219
+ * Adjust the table column widths for new data. Note: you would probably want to
220
+ * do a redraw after calling this function!
221
+ * @param {object} oSettings dataTables settings object
222
+ * @memberof DataTable#oApi
223
+ */
224
+ function _fnAdjustColumnSizing ( oSettings )
225
+ {
226
+ /* Not interested in doing column width calculation if auto-width is disabled */
227
+ if ( oSettings.oFeatures.bAutoWidth === false )
228
+ {
229
+ return false;
230
+ }
231
+
232
+ _fnCalculateColumnWidths( oSettings );
233
+ for ( var i=0 , iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
234
+ {
235
+ oSettings.aoColumns[i].nTh.style.width = oSettings.aoColumns[i].sWidth;
236
+ }
237
+ }
238
+
239
+
240
+ /**
241
+ * Covert the index of a visible column to the index in the data array (take account
242
+ * of hidden columns)
243
+ * @param {object} oSettings dataTables settings object
244
+ * @param {int} iMatch Visible column index to lookup
245
+ * @returns {int} i the data index
246
+ * @memberof DataTable#oApi
247
+ */
248
+ function _fnVisibleToColumnIndex( oSettings, iMatch )
249
+ {
250
+ var aiVis = _fnGetColumns( oSettings, 'bVisible' );
251
+
252
+ return typeof aiVis[iMatch] === 'number' ?
253
+ aiVis[iMatch] :
254
+ null;
255
+ }
256
+
257
+
258
+ /**
259
+ * Covert the index of an index in the data array and convert it to the visible
260
+ * column index (take account of hidden columns)
261
+ * @param {int} iMatch Column index to lookup
262
+ * @param {object} oSettings dataTables settings object
263
+ * @returns {int} i the data index
264
+ * @memberof DataTable#oApi
265
+ */
266
+ function _fnColumnIndexToVisible( oSettings, iMatch )
267
+ {
268
+ var aiVis = _fnGetColumns( oSettings, 'bVisible' );
269
+ var iPos = $.inArray( iMatch, aiVis );
270
+
271
+ return iPos !== -1 ? iPos : null;
272
+ }
273
+
274
+
275
+ /**
276
+ * Get the number of visible columns
277
+ * @param {object} oSettings dataTables settings object
278
+ * @returns {int} i the number of visible columns
279
+ * @memberof DataTable#oApi
280
+ */
281
+ function _fnVisbleColumns( oSettings )
282
+ {
283
+ return _fnGetColumns( oSettings, 'bVisible' ).length;
284
+ }
285
+
286
+
287
+ /**
288
+ * Get an array of column indexes that match a given property
289
+ * @param {object} oSettings dataTables settings object
290
+ * @param {string} sParam Parameter in aoColumns to look for - typically
291
+ * bVisible or bSearchable
292
+ * @returns {array} Array of indexes with matched properties
293
+ * @memberof DataTable#oApi
294
+ */
295
+ function _fnGetColumns( oSettings, sParam )
296
+ {
297
+ var a = [];
298
+
299
+ $.map( oSettings.aoColumns, function(val, i) {
300
+ if ( val[sParam] ) {
301
+ a.push( i );
302
+ }
303
+ } );
304
+
305
+ return a;
306
+ }
307
+
308
+
309
+ /**
310
+ * Get the sort type based on an input string
311
+ * @param {string} sData data we wish to know the type of
312
+ * @returns {string} type (defaults to 'string' if no type can be detected)
313
+ * @memberof DataTable#oApi
314
+ */
315
+ function _fnDetectType( sData )
316
+ {
317
+ var aTypes = DataTable.ext.aTypes;
318
+ var iLen = aTypes.length;
319
+
320
+ for ( var i=0 ; i<iLen ; i++ )
321
+ {
322
+ var sType = aTypes[i]( sData );
323
+ if ( sType !== null )
324
+ {
325
+ return sType;
326
+ }
327
+ }
328
+
329
+ return 'string';
330
+ }
331
+
332
+
333
+ /**
334
+ * Figure out how to reorder a display list
335
+ * @param {object} oSettings dataTables settings object
336
+ * @returns array {int} aiReturn index list for reordering
337
+ * @memberof DataTable#oApi
338
+ */
339
+ function _fnReOrderIndex ( oSettings, sColumns )
340
+ {
341
+ var aColumns = sColumns.split(',');
342
+ var aiReturn = [];
343
+
344
+ for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
345
+ {
346
+ for ( var j=0 ; j<iLen ; j++ )
347
+ {
348
+ if ( oSettings.aoColumns[i].sName == aColumns[j] )
349
+ {
350
+ aiReturn.push( j );
351
+ break;
352
+ }
353
+ }
354
+ }
355
+
356
+ return aiReturn;
357
+ }
358
+
359
+
360
+ /**
361
+ * Get the column ordering that DataTables expects
362
+ * @param {object} oSettings dataTables settings object
363
+ * @returns {string} comma separated list of names
364
+ * @memberof DataTable#oApi
365
+ */
366
+ function _fnColumnOrdering ( oSettings )
367
+ {
368
+ var sNames = '';
369
+ for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
370
+ {
371
+ sNames += oSettings.aoColumns[i].sName+',';
372
+ }
373
+ if ( sNames.length == iLen )
374
+ {
375
+ return "";
376
+ }
377
+ return sNames.slice(0, -1);
378
+ }
379
+
380
+
381
+ /**
382
+ * Take the column definitions and static columns arrays and calculate how
383
+ * they relate to column indexes. The callback function will then apply the
384
+ * definition found for a column to a suitable configuration object.
385
+ * @param {object} oSettings dataTables settings object
386
+ * @param {array} aoColDefs The aoColumnDefs array that is to be applied
387
+ * @param {array} aoCols The aoColumns array that defines columns individually
388
+ * @param {function} fn Callback function - takes two parameters, the calculated
389
+ * column index and the definition for that column.
390
+ * @memberof DataTable#oApi
391
+ */
392
+ function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
393
+ {
394
+ var i, iLen, j, jLen, k, kLen;
395
+
396
+ // Column definitions with aTargets
397
+ if ( aoColDefs )
398
+ {
399
+ /* Loop over the definitions array - loop in reverse so first instance has priority */
400
+ for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
401
+ {
402
+ /* Each definition can target multiple columns, as it is an array */
403
+ var aTargets = aoColDefs[i].aTargets;
404
+ if ( !$.isArray( aTargets ) )
405
+ {
406
+ _fnLog( oSettings, 1, 'aTargets must be an array of targets, not a '+(typeof aTargets) );
407
+ }
408
+
409
+ for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
410
+ {
411
+ if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
412
+ {
413
+ /* Add columns that we don't yet know about */
414
+ while( oSettings.aoColumns.length <= aTargets[j] )
415
+ {
416
+ _fnAddColumn( oSettings );
417
+ }
418
+
419
+ /* Integer, basic index */
420
+ fn( aTargets[j], aoColDefs[i] );
421
+ }
422
+ else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
423
+ {
424
+ /* Negative integer, right to left column counting */
425
+ fn( oSettings.aoColumns.length+aTargets[j], aoColDefs[i] );
426
+ }
427
+ else if ( typeof aTargets[j] === 'string' )
428
+ {
429
+ /* Class name matching on TH element */
430
+ for ( k=0, kLen=oSettings.aoColumns.length ; k<kLen ; k++ )
431
+ {
432
+ if ( aTargets[j] == "_all" ||
433
+ $(oSettings.aoColumns[k].nTh).hasClass( aTargets[j] ) )
434
+ {
435
+ fn( k, aoColDefs[i] );
436
+ }
437
+ }
438
+ }
439
+ }
440
+ }
441
+ }
442
+
443
+ // Statically defined columns array
444
+ if ( aoCols )
445
+ {
446
+ for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
447
+ {
448
+ fn( i, aoCols[i] );
449
+ }
450
+ }
451
+ }
452
+
453
+ /**
454
+ * Add a data array to the table, creating DOM node etc. This is the parallel to
455
+ * _fnGatherData, but for adding rows from a Javascript source, rather than a
456
+ * DOM source.
457
+ * @param {object} oSettings dataTables settings object
458
+ * @param {array} aData data array to be added
459
+ * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
460
+ * @memberof DataTable#oApi
461
+ */
462
+ function _fnAddData ( oSettings, aDataSupplied )
463
+ {
464
+ var oCol;
465
+
466
+ /* Take an independent copy of the data source so we can bash it about as we wish */
467
+ var aDataIn = ($.isArray(aDataSupplied)) ?
468
+ aDataSupplied.slice() :
469
+ $.extend( true, {}, aDataSupplied );
470
+
471
+ /* Create the object for storing information about this new row */
472
+ var iRow = oSettings.aoData.length;
473
+ var oData = $.extend( true, {}, DataTable.models.oRow );
474
+ oData._aData = aDataIn;
475
+ oSettings.aoData.push( oData );
476
+
477
+ /* Create the cells */
478
+ var nTd, sThisType;
479
+ for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
480
+ {
481
+ oCol = oSettings.aoColumns[i];
482
+
483
+ /* Use rendered data for filtering / sorting */
484
+ if ( typeof oCol.fnRender === 'function' && oCol.bUseRendered && oCol.mData !== null )
485
+ {
486
+ _fnSetCellData( oSettings, iRow, i, _fnRender(oSettings, iRow, i) );
487
+ }
488
+ else
489
+ {
490
+ _fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
491
+ }
492
+
493
+ /* See if we should auto-detect the column type */
494
+ if ( oCol._bAutoType && oCol.sType != 'string' )
495
+ {
496
+ /* Attempt to auto detect the type - same as _fnGatherData() */
497
+ var sVarType = _fnGetCellData( oSettings, iRow, i, 'type' );
498
+ if ( sVarType !== null && sVarType !== '' )
499
+ {
500
+ sThisType = _fnDetectType( sVarType );
501
+ if ( oCol.sType === null )
502
+ {
503
+ oCol.sType = sThisType;
504
+ }
505
+ else if ( oCol.sType != sThisType && oCol.sType != "html" )
506
+ {
507
+ /* String is always the 'fallback' option */
508
+ oCol.sType = 'string';
509
+ }
510
+ }
511
+ }
512
+ }
513
+
514
+ /* Add to the display array */
515
+ oSettings.aiDisplayMaster.push( iRow );
516
+
517
+ /* Create the DOM information */
518
+ if ( !oSettings.oFeatures.bDeferRender )
519
+ {
520
+ _fnCreateTr( oSettings, iRow );
521
+ }
522
+
523
+ return iRow;
524
+ }
525
+
526
+
527
+ /**
528
+ * Read in the data from the target table from the DOM
529
+ * @param {object} oSettings dataTables settings object
530
+ * @memberof DataTable#oApi
531
+ */
532
+ function _fnGatherData( oSettings )
533
+ {
534
+ var iLoop, i, iLen, j, jLen, jInner,
535
+ nTds, nTrs, nTd, nTr, aLocalData, iThisIndex,
536
+ iRow, iRows, iColumn, iColumns, sNodeName,
537
+ oCol, oData;
538
+
539
+ /*
540
+ * Process by row first
541
+ * Add the data object for the whole table - storing the tr node. Note - no point in getting
542
+ * DOM based data if we are going to go and replace it with Ajax source data.
543
+ */
544
+ if ( oSettings.bDeferLoading || oSettings.sAjaxSource === null )
545
+ {
546
+ nTr = oSettings.nTBody.firstChild;
547
+ while ( nTr )
548
+ {
549
+ if ( nTr.nodeName.toUpperCase() == "TR" )
550
+ {
551
+ iThisIndex = oSettings.aoData.length;
552
+ nTr._DT_RowIndex = iThisIndex;
553
+ oSettings.aoData.push( $.extend( true, {}, DataTable.models.oRow, {
554
+ "nTr": nTr
555
+ } ) );
556
+
557
+ oSettings.aiDisplayMaster.push( iThisIndex );
558
+ nTd = nTr.firstChild;
559
+ jInner = 0;
560
+ while ( nTd )
561
+ {
562
+ sNodeName = nTd.nodeName.toUpperCase();
563
+ if ( sNodeName == "TD" || sNodeName == "TH" )
564
+ {
565
+ _fnSetCellData( oSettings, iThisIndex, jInner, $.trim(nTd.innerHTML) );
566
+ jInner++;
567
+ }
568
+ nTd = nTd.nextSibling;
569
+ }
570
+ }
571
+ nTr = nTr.nextSibling;
572
+ }
573
+ }
574
+
575
+ /* Gather in the TD elements of the Table - note that this is basically the same as
576
+ * fnGetTdNodes, but that function takes account of hidden columns, which we haven't yet
577
+ * setup!
578
+ */
579
+ nTrs = _fnGetTrNodes( oSettings );
580
+ nTds = [];
581
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
582
+ {
583
+ nTd = nTrs[i].firstChild;
584
+ while ( nTd )
585
+ {
586
+ sNodeName = nTd.nodeName.toUpperCase();
587
+ if ( sNodeName == "TD" || sNodeName == "TH" )
588
+ {
589
+ nTds.push( nTd );
590
+ }
591
+ nTd = nTd.nextSibling;
592
+ }
593
+ }
594
+
595
+ /* Now process by column */
596
+ for ( iColumn=0, iColumns=oSettings.aoColumns.length ; iColumn<iColumns ; iColumn++ )
597
+ {
598
+ oCol = oSettings.aoColumns[iColumn];
599
+
600
+ /* Get the title of the column - unless there is a user set one */
601
+ if ( oCol.sTitle === null )
602
+ {
603
+ oCol.sTitle = oCol.nTh.innerHTML;
604
+ }
605
+
606
+ var
607
+ bAutoType = oCol._bAutoType,
608
+ bRender = typeof oCol.fnRender === 'function',
609
+ bClass = oCol.sClass !== null,
610
+ bVisible = oCol.bVisible,
611
+ nCell, sThisType, sRendered, sValType;
612
+
613
+ /* A single loop to rule them all (and be more efficient) */
614
+ if ( bAutoType || bRender || bClass || !bVisible )
615
+ {
616
+ for ( iRow=0, iRows=oSettings.aoData.length ; iRow<iRows ; iRow++ )
617
+ {
618
+ oData = oSettings.aoData[iRow];
619
+ nCell = nTds[ (iRow*iColumns) + iColumn ];
620
+
621
+ /* Type detection */
622
+ if ( bAutoType && oCol.sType != 'string' )
623
+ {
624
+ sValType = _fnGetCellData( oSettings, iRow, iColumn, 'type' );
625
+ if ( sValType !== '' )
626
+ {
627
+ sThisType = _fnDetectType( sValType );
628
+ if ( oCol.sType === null )
629
+ {
630
+ oCol.sType = sThisType;
631
+ }
632
+ else if ( oCol.sType != sThisType &&
633
+ oCol.sType != "html" )
634
+ {
635
+ /* String is always the 'fallback' option */
636
+ oCol.sType = 'string';
637
+ }
638
+ }
639
+ }
640
+
641
+ if ( oCol.mRender )
642
+ {
643
+ // mRender has been defined, so we need to get the value and set it
644
+ nCell.innerHTML = _fnGetCellData( oSettings, iRow, iColumn, 'display' );
645
+ }
646
+ else if ( oCol.mData !== iColumn )
647
+ {
648
+ // If mData is not the same as the column number, then we need to
649
+ // get the dev set value. If it is the column, no point in wasting
650
+ // time setting the value that is already there!
651
+ nCell.innerHTML = _fnGetCellData( oSettings, iRow, iColumn, 'display' );
652
+ }
653
+
654
+ /* Rendering */
655
+ if ( bRender )
656
+ {
657
+ sRendered = _fnRender( oSettings, iRow, iColumn );
658
+ nCell.innerHTML = sRendered;
659
+ if ( oCol.bUseRendered )
660
+ {
661
+ /* Use the rendered data for filtering / sorting */
662
+ _fnSetCellData( oSettings, iRow, iColumn, sRendered );
663
+ }
664
+ }
665
+
666
+ /* Classes */
667
+ if ( bClass )
668
+ {
669
+ nCell.className += ' '+oCol.sClass;
670
+ }
671
+
672
+ /* Column visibility */
673
+ if ( !bVisible )
674
+ {
675
+ oData._anHidden[iColumn] = nCell;
676
+ nCell.parentNode.removeChild( nCell );
677
+ }
678
+ else
679
+ {
680
+ oData._anHidden[iColumn] = null;
681
+ }
682
+
683
+ if ( oCol.fnCreatedCell )
684
+ {
685
+ oCol.fnCreatedCell.call( oSettings.oInstance,
686
+ nCell, _fnGetCellData( oSettings, iRow, iColumn, 'display' ), oData._aData, iRow, iColumn
687
+ );
688
+ }
689
+ }
690
+ }
691
+ }
692
+
693
+ /* Row created callbacks */
694
+ if ( oSettings.aoRowCreatedCallback.length !== 0 )
695
+ {
696
+ for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
697
+ {
698
+ oData = oSettings.aoData[i];
699
+ _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [oData.nTr, oData._aData, i] );
700
+ }
701
+ }
702
+ }
703
+
704
+
705
+ /**
706
+ * Take a TR element and convert it to an index in aoData
707
+ * @param {object} oSettings dataTables settings object
708
+ * @param {node} n the TR element to find
709
+ * @returns {int} index if the node is found, null if not
710
+ * @memberof DataTable#oApi
711
+ */
712
+ function _fnNodeToDataIndex( oSettings, n )
713
+ {
714
+ return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
715
+ }
716
+
717
+
718
+ /**
719
+ * Take a TD element and convert it into a column data index (not the visible index)
720
+ * @param {object} oSettings dataTables settings object
721
+ * @param {int} iRow The row number the TD/TH can be found in
722
+ * @param {node} n The TD/TH element to find
723
+ * @returns {int} index if the node is found, -1 if not
724
+ * @memberof DataTable#oApi
725
+ */
726
+ function _fnNodeToColumnIndex( oSettings, iRow, n )
727
+ {
728
+ var anCells = _fnGetTdNodes( oSettings, iRow );
729
+
730
+ for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
731
+ {
732
+ if ( anCells[i] === n )
733
+ {
734
+ return i;
735
+ }
736
+ }
737
+ return -1;
738
+ }
739
+
740
+
741
+ /**
742
+ * Get an array of data for a given row from the internal data cache
743
+ * @param {object} oSettings dataTables settings object
744
+ * @param {int} iRow aoData row id
745
+ * @param {string} sSpecific data get type ('type' 'filter' 'sort')
746
+ * @param {array} aiColumns Array of column indexes to get data from
747
+ * @returns {array} Data array
748
+ * @memberof DataTable#oApi
749
+ */
750
+ function _fnGetRowData( oSettings, iRow, sSpecific, aiColumns )
751
+ {
752
+ var out = [];
753
+ for ( var i=0, iLen=aiColumns.length ; i<iLen ; i++ )
754
+ {
755
+ out.push( _fnGetCellData( oSettings, iRow, aiColumns[i], sSpecific ) );
756
+ }
757
+ return out;
758
+ }
759
+
760
+
761
+ /**
762
+ * Get the data for a given cell from the internal cache, taking into account data mapping
763
+ * @param {object} oSettings dataTables settings object
764
+ * @param {int} iRow aoData row id
765
+ * @param {int} iCol Column index
766
+ * @param {string} sSpecific data get type ('display', 'type' 'filter' 'sort')
767
+ * @returns {*} Cell data
768
+ * @memberof DataTable#oApi
769
+ */
770
+ function _fnGetCellData( oSettings, iRow, iCol, sSpecific )
771
+ {
772
+ var sData;
773
+ var oCol = oSettings.aoColumns[iCol];
774
+ var oData = oSettings.aoData[iRow]._aData;
775
+
776
+ if ( (sData=oCol.fnGetData( oData, sSpecific )) === undefined )
777
+ {
778
+ if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null )
779
+ {
780
+ _fnLog( oSettings, 0, "Requested unknown parameter "+
781
+ (typeof oCol.mData=='function' ? '{mData function}' : "'"+oCol.mData+"'")+
782
+ " from the data source for row "+iRow );
783
+ oSettings.iDrawError = oSettings.iDraw;
784
+ }
785
+ return oCol.sDefaultContent;
786
+ }
787
+
788
+ /* When the data source is null, we can use default column data */
789
+ if ( sData === null && oCol.sDefaultContent !== null )
790
+ {
791
+ sData = oCol.sDefaultContent;
792
+ }
793
+ else if ( typeof sData === 'function' )
794
+ {
795
+ /* If the data source is a function, then we run it and use the return */
796
+ return sData();
797
+ }
798
+
799
+ if ( sSpecific == 'display' && sData === null )
800
+ {
801
+ return '';
802
+ }
803
+ return sData;
804
+ }
805
+
806
+
807
+ /**
808
+ * Set the value for a specific cell, into the internal data cache
809
+ * @param {object} oSettings dataTables settings object
810
+ * @param {int} iRow aoData row id
811
+ * @param {int} iCol Column index
812
+ * @param {*} val Value to set
813
+ * @memberof DataTable#oApi
814
+ */
815
+ function _fnSetCellData( oSettings, iRow, iCol, val )
816
+ {
817
+ var oCol = oSettings.aoColumns[iCol];
818
+ var oData = oSettings.aoData[iRow]._aData;
819
+
820
+ oCol.fnSetData( oData, val );
821
+ }
822
+
823
+
824
+ // Private variable that is used to match array syntax in the data property object
825
+ var __reArray = /\[.*?\]$/;
826
+
827
+ /**
828
+ * Return a function that can be used to get data from a source object, taking
829
+ * into account the ability to use nested objects as a source
830
+ * @param {string|int|function} mSource The data source for the object
831
+ * @returns {function} Data get function
832
+ * @memberof DataTable#oApi
833
+ */
834
+ function _fnGetObjectDataFn( mSource )
835
+ {
836
+ if ( mSource === null )
837
+ {
838
+ /* Give an empty string for rendering / sorting etc */
839
+ return function (data, type) {
840
+ return null;
841
+ };
842
+ }
843
+ else if ( typeof mSource === 'function' )
844
+ {
845
+ return function (data, type, extra) {
846
+ return mSource( data, type, extra );
847
+ };
848
+ }
849
+ else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1) )
850
+ {
851
+ /* If there is a . in the source string then the data source is in a
852
+ * nested object so we loop over the data for each level to get the next
853
+ * level down. On each loop we test for undefined, and if found immediately
854
+ * return. This allows entire objects to be missing and sDefaultContent to
855
+ * be used if defined, rather than throwing an error
856
+ */
857
+ var fetchData = function (data, type, src) {
858
+ var a = src.split('.');
859
+ var arrayNotation, out, innerSrc;
860
+
861
+ if ( src !== "" )
862
+ {
863
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ )
864
+ {
865
+ // Check if we are dealing with an array notation request
866
+ arrayNotation = a[i].match(__reArray);
867
+
868
+ if ( arrayNotation ) {
869
+ a[i] = a[i].replace(__reArray, '');
870
+
871
+ // Condition allows simply [] to be passed in
872
+ if ( a[i] !== "" ) {
873
+ data = data[ a[i] ];
874
+ }
875
+ out = [];
876
+
877
+ // Get the remainder of the nested object to get
878
+ a.splice( 0, i+1 );
879
+ innerSrc = a.join('.');
880
+
881
+ // Traverse each entry in the array getting the properties requested
882
+ for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
883
+ out.push( fetchData( data[j], type, innerSrc ) );
884
+ }
885
+
886
+ // If a string is given in between the array notation indicators, that
887
+ // is used to join the strings together, otherwise an array is returned
888
+ var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
889
+ data = (join==="") ? out : out.join(join);
890
+
891
+ // The inner call to fetchData has already traversed through the remainder
892
+ // of the source requested, so we exit from the loop
893
+ break;
894
+ }
895
+
896
+ if ( data === null || data[ a[i] ] === undefined )
897
+ {
898
+ return undefined;
899
+ }
900
+ data = data[ a[i] ];
901
+ }
902
+ }
903
+
904
+ return data;
905
+ };
906
+
907
+ return function (data, type) {
908
+ return fetchData( data, type, mSource );
909
+ };
910
+ }
911
+ else
912
+ {
913
+ /* Array or flat object mapping */
914
+ return function (data, type) {
915
+ return data[mSource];
916
+ };
917
+ }
918
+ }
919
+
920
+
921
+ /**
922
+ * Return a function that can be used to set data from a source object, taking
923
+ * into account the ability to use nested objects as a source
924
+ * @param {string|int|function} mSource The data source for the object
925
+ * @returns {function} Data set function
926
+ * @memberof DataTable#oApi
927
+ */
928
+ function _fnSetObjectDataFn( mSource )
929
+ {
930
+ if ( mSource === null )
931
+ {
932
+ /* Nothing to do when the data source is null */
933
+ return function (data, val) {};
934
+ }
935
+ else if ( typeof mSource === 'function' )
936
+ {
937
+ return function (data, val) {
938
+ mSource( data, 'set', val );
939
+ };
940
+ }
941
+ else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1) )
942
+ {
943
+ /* Like the get, we need to get data from a nested object */
944
+ var setData = function (data, val, src) {
945
+ var a = src.split('.'), b;
946
+ var arrayNotation, o, innerSrc;
947
+
948
+ for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
949
+ {
950
+ // Check if we are dealing with an array notation request
951
+ arrayNotation = a[i].match(__reArray);
952
+
953
+ if ( arrayNotation )
954
+ {
955
+ a[i] = a[i].replace(__reArray, '');
956
+ data[ a[i] ] = [];
957
+
958
+ // Get the remainder of the nested object to set so we can recurse
959
+ b = a.slice();
960
+ b.splice( 0, i+1 );
961
+ innerSrc = b.join('.');
962
+
963
+ // Traverse each entry in the array setting the properties requested
964
+ for ( var j=0, jLen=val.length ; j<jLen ; j++ )
965
+ {
966
+ o = {};
967
+ setData( o, val[j], innerSrc );
968
+ data[ a[i] ].push( o );
969
+ }
970
+
971
+ // The inner call to setData has already traversed through the remainder
972
+ // of the source and has set the data, thus we can exit here
973
+ return;
974
+ }
975
+
976
+ // If the nested object doesn't currently exist - since we are
977
+ // trying to set the value - create it
978
+ if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
979
+ {
980
+ data[ a[i] ] = {};
981
+ }
982
+ data = data[ a[i] ];
983
+ }
984
+
985
+ // If array notation is used, we just want to strip it and use the property name
986
+ // and assign the value. If it isn't used, then we get the result we want anyway
987
+ data[ a[a.length-1].replace(__reArray, '') ] = val;
988
+ };
989
+
990
+ return function (data, val) {
991
+ return setData( data, val, mSource );
992
+ };
993
+ }
994
+ else
995
+ {
996
+ /* Array or flat object mapping */
997
+ return function (data, val) {
998
+ data[mSource] = val;
999
+ };
1000
+ }
1001
+ }
1002
+
1003
+
1004
+ /**
1005
+ * Return an array with the full table data
1006
+ * @param {object} oSettings dataTables settings object
1007
+ * @returns array {array} aData Master data array
1008
+ * @memberof DataTable#oApi
1009
+ */
1010
+ function _fnGetDataMaster ( oSettings )
1011
+ {
1012
+ var aData = [];
1013
+ var iLen = oSettings.aoData.length;
1014
+ for ( var i=0 ; i<iLen; i++ )
1015
+ {
1016
+ aData.push( oSettings.aoData[i]._aData );
1017
+ }
1018
+ return aData;
1019
+ }
1020
+
1021
+
1022
+ /**
1023
+ * Nuke the table
1024
+ * @param {object} oSettings dataTables settings object
1025
+ * @memberof DataTable#oApi
1026
+ */
1027
+ function _fnClearTable( oSettings )
1028
+ {
1029
+ oSettings.aoData.splice( 0, oSettings.aoData.length );
1030
+ oSettings.aiDisplayMaster.splice( 0, oSettings.aiDisplayMaster.length );
1031
+ oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length );
1032
+ _fnCalculateEnd( oSettings );
1033
+ }
1034
+
1035
+
1036
+ /**
1037
+ * Take an array of integers (index array) and remove a target integer (value - not
1038
+ * the key!)
1039
+ * @param {array} a Index array to target
1040
+ * @param {int} iTarget value to find
1041
+ * @memberof DataTable#oApi
1042
+ */
1043
+ function _fnDeleteIndex( a, iTarget )
1044
+ {
1045
+ var iTargetIndex = -1;
1046
+
1047
+ for ( var i=0, iLen=a.length ; i<iLen ; i++ )
1048
+ {
1049
+ if ( a[i] == iTarget )
1050
+ {
1051
+ iTargetIndex = i;
1052
+ }
1053
+ else if ( a[i] > iTarget )
1054
+ {
1055
+ a[i]--;
1056
+ }
1057
+ }
1058
+
1059
+ if ( iTargetIndex != -1 )
1060
+ {
1061
+ a.splice( iTargetIndex, 1 );
1062
+ }
1063
+ }
1064
+
1065
+
1066
+ /**
1067
+ * Call the developer defined fnRender function for a given cell (row/column) with
1068
+ * the required parameters and return the result.
1069
+ * @param {object} oSettings dataTables settings object
1070
+ * @param {int} iRow aoData index for the row
1071
+ * @param {int} iCol aoColumns index for the column
1072
+ * @returns {*} Return of the developer's fnRender function
1073
+ * @memberof DataTable#oApi
1074
+ */
1075
+ function _fnRender( oSettings, iRow, iCol )
1076
+ {
1077
+ var oCol = oSettings.aoColumns[iCol];
1078
+
1079
+ return oCol.fnRender( {
1080
+ "iDataRow": iRow,
1081
+ "iDataColumn": iCol,
1082
+ "oSettings": oSettings,
1083
+ "aData": oSettings.aoData[iRow]._aData,
1084
+ "mDataProp": oCol.mData
1085
+ }, _fnGetCellData(oSettings, iRow, iCol, 'display') );
1086
+ }
1087
+ /**
1088
+ * Create a new TR element (and it's TD children) for a row
1089
+ * @param {object} oSettings dataTables settings object
1090
+ * @param {int} iRow Row to consider
1091
+ * @memberof DataTable#oApi
1092
+ */
1093
+ function _fnCreateTr ( oSettings, iRow )
1094
+ {
1095
+ var oData = oSettings.aoData[iRow];
1096
+ var nTd;
1097
+
1098
+ if ( oData.nTr === null )
1099
+ {
1100
+ oData.nTr = document.createElement('tr');
1101
+
1102
+ /* Use a private property on the node to allow reserve mapping from the node
1103
+ * to the aoData array for fast look up
1104
+ */
1105
+ oData.nTr._DT_RowIndex = iRow;
1106
+
1107
+ /* Special parameters can be given by the data source to be used on the row */
1108
+ if ( oData._aData.DT_RowId )
1109
+ {
1110
+ oData.nTr.id = oData._aData.DT_RowId;
1111
+ }
1112
+
1113
+ if ( oData._aData.DT_RowClass )
1114
+ {
1115
+ oData.nTr.className = oData._aData.DT_RowClass;
1116
+ }
1117
+
1118
+ /* Process each column */
1119
+ for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1120
+ {
1121
+ var oCol = oSettings.aoColumns[i];
1122
+ nTd = document.createElement( oCol.sCellType );
1123
+
1124
+ /* Render if needed - if bUseRendered is true then we already have the rendered
1125
+ * value in the data source - so can just use that
1126
+ */
1127
+ nTd.innerHTML = (typeof oCol.fnRender === 'function' && (!oCol.bUseRendered || oCol.mData === null)) ?
1128
+ _fnRender( oSettings, iRow, i ) :
1129
+ _fnGetCellData( oSettings, iRow, i, 'display' );
1130
+
1131
+ /* Add user defined class */
1132
+ if ( oCol.sClass !== null )
1133
+ {
1134
+ nTd.className = oCol.sClass;
1135
+ }
1136
+
1137
+ if ( oCol.bVisible )
1138
+ {
1139
+ oData.nTr.appendChild( nTd );
1140
+ oData._anHidden[i] = null;
1141
+ }
1142
+ else
1143
+ {
1144
+ oData._anHidden[i] = nTd;
1145
+ }
1146
+
1147
+ if ( oCol.fnCreatedCell )
1148
+ {
1149
+ oCol.fnCreatedCell.call( oSettings.oInstance,
1150
+ nTd, _fnGetCellData( oSettings, iRow, i, 'display' ), oData._aData, iRow, i
1151
+ );
1152
+ }
1153
+ }
1154
+
1155
+ _fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [oData.nTr, oData._aData, iRow] );
1156
+ }
1157
+ }
1158
+
1159
+
1160
+ /**
1161
+ * Create the HTML header for the table
1162
+ * @param {object} oSettings dataTables settings object
1163
+ * @memberof DataTable#oApi
1164
+ */
1165
+ function _fnBuildHead( oSettings )
1166
+ {
1167
+ var i, nTh, iLen, j, jLen;
1168
+ var iThs = $('th, td', oSettings.nTHead).length;
1169
+ var iCorrector = 0;
1170
+ var jqChildren;
1171
+
1172
+ /* If there is a header in place - then use it - otherwise it's going to get nuked... */
1173
+ if ( iThs !== 0 )
1174
+ {
1175
+ /* We've got a thead from the DOM, so remove hidden columns and apply width to vis cols */
1176
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1177
+ {
1178
+ nTh = oSettings.aoColumns[i].nTh;
1179
+ nTh.setAttribute('role', 'columnheader');
1180
+ if ( oSettings.aoColumns[i].bSortable )
1181
+ {
1182
+ nTh.setAttribute('tabindex', oSettings.iTabIndex);
1183
+ nTh.setAttribute('aria-controls', oSettings.sTableId);
1184
+ }
1185
+
1186
+ if ( oSettings.aoColumns[i].sClass !== null )
1187
+ {
1188
+ $(nTh).addClass( oSettings.aoColumns[i].sClass );
1189
+ }
1190
+
1191
+ /* Set the title of the column if it is user defined (not what was auto detected) */
1192
+ if ( oSettings.aoColumns[i].sTitle != nTh.innerHTML )
1193
+ {
1194
+ nTh.innerHTML = oSettings.aoColumns[i].sTitle;
1195
+ }
1196
+ }
1197
+ }
1198
+ else
1199
+ {
1200
+ /* We don't have a header in the DOM - so we are going to have to create one */
1201
+ var nTr = document.createElement( "tr" );
1202
+
1203
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1204
+ {
1205
+ nTh = oSettings.aoColumns[i].nTh;
1206
+ nTh.innerHTML = oSettings.aoColumns[i].sTitle;
1207
+ nTh.setAttribute('tabindex', '0');
1208
+
1209
+ if ( oSettings.aoColumns[i].sClass !== null )
1210
+ {
1211
+ $(nTh).addClass( oSettings.aoColumns[i].sClass );
1212
+ }
1213
+
1214
+ nTr.appendChild( nTh );
1215
+ }
1216
+ $(oSettings.nTHead).html( '' )[0].appendChild( nTr );
1217
+ _fnDetectHeader( oSettings.aoHeader, oSettings.nTHead );
1218
+ }
1219
+
1220
+ /* ARIA role for the rows */
1221
+ $(oSettings.nTHead).children('tr').attr('role', 'row');
1222
+
1223
+ /* Add the extra markup needed by jQuery UI's themes */
1224
+ if ( oSettings.bJUI )
1225
+ {
1226
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1227
+ {
1228
+ nTh = oSettings.aoColumns[i].nTh;
1229
+
1230
+ var nDiv = document.createElement('div');
1231
+ nDiv.className = oSettings.oClasses.sSortJUIWrapper;
1232
+ $(nTh).contents().appendTo(nDiv);
1233
+
1234
+ var nSpan = document.createElement('span');
1235
+ nSpan.className = oSettings.oClasses.sSortIcon;
1236
+ nDiv.appendChild( nSpan );
1237
+ nTh.appendChild( nDiv );
1238
+ }
1239
+ }
1240
+
1241
+ if ( oSettings.oFeatures.bSort )
1242
+ {
1243
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
1244
+ {
1245
+ if ( oSettings.aoColumns[i].bSortable !== false )
1246
+ {
1247
+ _fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );
1248
+ }
1249
+ else
1250
+ {
1251
+ $(oSettings.aoColumns[i].nTh).addClass( oSettings.oClasses.sSortableNone );
1252
+ }
1253
+ }
1254
+ }
1255
+
1256
+ /* Deal with the footer - add classes if required */
1257
+ if ( oSettings.oClasses.sFooterTH !== "" )
1258
+ {
1259
+ $(oSettings.nTFoot).children('tr').children('th').addClass( oSettings.oClasses.sFooterTH );
1260
+ }
1261
+
1262
+ /* Cache the footer elements */
1263
+ if ( oSettings.nTFoot !== null )
1264
+ {
1265
+ var anCells = _fnGetUniqueThs( oSettings, null, oSettings.aoFooter );
1266
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
1267
+ {
1268
+ if ( anCells[i] )
1269
+ {
1270
+ oSettings.aoColumns[i].nTf = anCells[i];
1271
+ if ( oSettings.aoColumns[i].sClass )
1272
+ {
1273
+ $(anCells[i]).addClass( oSettings.aoColumns[i].sClass );
1274
+ }
1275
+ }
1276
+ }
1277
+ }
1278
+ }
1279
+
1280
+
1281
+ /**
1282
+ * Draw the header (or footer) element based on the column visibility states. The
1283
+ * methodology here is to use the layout array from _fnDetectHeader, modified for
1284
+ * the instantaneous column visibility, to construct the new layout. The grid is
1285
+ * traversed over cell at a time in a rows x columns grid fashion, although each
1286
+ * cell insert can cover multiple elements in the grid - which is tracks using the
1287
+ * aApplied array. Cell inserts in the grid will only occur where there isn't
1288
+ * already a cell in that position.
1289
+ * @param {object} oSettings dataTables settings object
1290
+ * @param array {objects} aoSource Layout array from _fnDetectHeader
1291
+ * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
1292
+ * @memberof DataTable#oApi
1293
+ */
1294
+ function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
1295
+ {
1296
+ var i, iLen, j, jLen, k, kLen, n, nLocalTr;
1297
+ var aoLocal = [];
1298
+ var aApplied = [];
1299
+ var iColumns = oSettings.aoColumns.length;
1300
+ var iRowspan, iColspan;
1301
+
1302
+ if ( bIncludeHidden === undefined )
1303
+ {
1304
+ bIncludeHidden = false;
1305
+ }
1306
+
1307
+ /* Make a copy of the master layout array, but without the visible columns in it */
1308
+ for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
1309
+ {
1310
+ aoLocal[i] = aoSource[i].slice();
1311
+ aoLocal[i].nTr = aoSource[i].nTr;
1312
+
1313
+ /* Remove any columns which are currently hidden */
1314
+ for ( j=iColumns-1 ; j>=0 ; j-- )
1315
+ {
1316
+ if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
1317
+ {
1318
+ aoLocal[i].splice( j, 1 );
1319
+ }
1320
+ }
1321
+
1322
+ /* Prep the applied array - it needs an element for each row */
1323
+ aApplied.push( [] );
1324
+ }
1325
+
1326
+ for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
1327
+ {
1328
+ nLocalTr = aoLocal[i].nTr;
1329
+
1330
+ /* All cells are going to be replaced, so empty out the row */
1331
+ if ( nLocalTr )
1332
+ {
1333
+ while( (n = nLocalTr.firstChild) )
1334
+ {
1335
+ nLocalTr.removeChild( n );
1336
+ }
1337
+ }
1338
+
1339
+ for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
1340
+ {
1341
+ iRowspan = 1;
1342
+ iColspan = 1;
1343
+
1344
+ /* Check to see if there is already a cell (row/colspan) covering our target
1345
+ * insert point. If there is, then there is nothing to do.
1346
+ */
1347
+ if ( aApplied[i][j] === undefined )
1348
+ {
1349
+ nLocalTr.appendChild( aoLocal[i][j].cell );
1350
+ aApplied[i][j] = 1;
1351
+
1352
+ /* Expand the cell to cover as many rows as needed */
1353
+ while ( aoLocal[i+iRowspan] !== undefined &&
1354
+ aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
1355
+ {
1356
+ aApplied[i+iRowspan][j] = 1;
1357
+ iRowspan++;
1358
+ }
1359
+
1360
+ /* Expand the cell to cover as many columns as needed */
1361
+ while ( aoLocal[i][j+iColspan] !== undefined &&
1362
+ aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
1363
+ {
1364
+ /* Must update the applied array over the rows for the columns */
1365
+ for ( k=0 ; k<iRowspan ; k++ )
1366
+ {
1367
+ aApplied[i+k][j+iColspan] = 1;
1368
+ }
1369
+ iColspan++;
1370
+ }
1371
+
1372
+ /* Do the actual expansion in the DOM */
1373
+ aoLocal[i][j].cell.rowSpan = iRowspan;
1374
+ aoLocal[i][j].cell.colSpan = iColspan;
1375
+ }
1376
+ }
1377
+ }
1378
+ }
1379
+
1380
+
1381
+ /**
1382
+ * Insert the required TR nodes into the table for display
1383
+ * @param {object} oSettings dataTables settings object
1384
+ * @memberof DataTable#oApi
1385
+ */
1386
+ function _fnDraw( oSettings )
1387
+ {
1388
+ /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
1389
+ var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
1390
+ if ( $.inArray( false, aPreDraw ) !== -1 )
1391
+ {
1392
+ _fnProcessingDisplay( oSettings, false );
1393
+ return;
1394
+ }
1395
+
1396
+ var i, iLen, n;
1397
+ var anRows = [];
1398
+ var iRowCount = 0;
1399
+ var iStripes = oSettings.asStripeClasses.length;
1400
+ var iOpenRows = oSettings.aoOpenRows.length;
1401
+
1402
+ oSettings.bDrawing = true;
1403
+
1404
+ /* Check and see if we have an initial draw position from state saving */
1405
+ if ( oSettings.iInitDisplayStart !== undefined && oSettings.iInitDisplayStart != -1 )
1406
+ {
1407
+ if ( oSettings.oFeatures.bServerSide )
1408
+ {
1409
+ oSettings._iDisplayStart = oSettings.iInitDisplayStart;
1410
+ }
1411
+ else
1412
+ {
1413
+ oSettings._iDisplayStart = (oSettings.iInitDisplayStart >= oSettings.fnRecordsDisplay()) ?
1414
+ 0 : oSettings.iInitDisplayStart;
1415
+ }
1416
+ oSettings.iInitDisplayStart = -1;
1417
+ _fnCalculateEnd( oSettings );
1418
+ }
1419
+
1420
+ /* Server-side processing draw intercept */
1421
+ if ( oSettings.bDeferLoading )
1422
+ {
1423
+ oSettings.bDeferLoading = false;
1424
+ oSettings.iDraw++;
1425
+ }
1426
+ else if ( !oSettings.oFeatures.bServerSide )
1427
+ {
1428
+ oSettings.iDraw++;
1429
+ }
1430
+ else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
1431
+ {
1432
+ return;
1433
+ }
1434
+
1435
+ if ( oSettings.aiDisplay.length !== 0 )
1436
+ {
1437
+ var iStart = oSettings._iDisplayStart;
1438
+ var iEnd = oSettings._iDisplayEnd;
1439
+
1440
+ if ( oSettings.oFeatures.bServerSide )
1441
+ {
1442
+ iStart = 0;
1443
+ iEnd = oSettings.aoData.length;
1444
+ }
1445
+
1446
+ for ( var j=iStart ; j<iEnd ; j++ )
1447
+ {
1448
+ var aoData = oSettings.aoData[ oSettings.aiDisplay[j] ];
1449
+ if ( aoData.nTr === null )
1450
+ {
1451
+ _fnCreateTr( oSettings, oSettings.aiDisplay[j] );
1452
+ }
1453
+
1454
+ var nRow = aoData.nTr;
1455
+
1456
+ /* Remove the old striping classes and then add the new one */
1457
+ if ( iStripes !== 0 )
1458
+ {
1459
+ var sStripe = oSettings.asStripeClasses[ iRowCount % iStripes ];
1460
+ if ( aoData._sRowStripe != sStripe )
1461
+ {
1462
+ $(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
1463
+ aoData._sRowStripe = sStripe;
1464
+ }
1465
+ }
1466
+
1467
+ /* Row callback functions - might want to manipulate the row */
1468
+ _fnCallbackFire( oSettings, 'aoRowCallback', null,
1469
+ [nRow, oSettings.aoData[ oSettings.aiDisplay[j] ]._aData, iRowCount, j] );
1470
+
1471
+ anRows.push( nRow );
1472
+ iRowCount++;
1473
+
1474
+ /* If there is an open row - and it is attached to this parent - attach it on redraw */
1475
+ if ( iOpenRows !== 0 )
1476
+ {
1477
+ for ( var k=0 ; k<iOpenRows ; k++ )
1478
+ {
1479
+ if ( nRow == oSettings.aoOpenRows[k].nParent )
1480
+ {
1481
+ anRows.push( oSettings.aoOpenRows[k].nTr );
1482
+ break;
1483
+ }
1484
+ }
1485
+ }
1486
+ }
1487
+ }
1488
+ else
1489
+ {
1490
+ /* Table is empty - create a row with an empty message in it */
1491
+ anRows[ 0 ] = document.createElement( 'tr' );
1492
+
1493
+ if ( oSettings.asStripeClasses[0] )
1494
+ {
1495
+ anRows[ 0 ].className = oSettings.asStripeClasses[0];
1496
+ }
1497
+
1498
+ var oLang = oSettings.oLanguage;
1499
+ var sZero = oLang.sZeroRecords;
1500
+ if ( oSettings.iDraw == 1 && oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
1501
+ {
1502
+ sZero = oLang.sLoadingRecords;
1503
+ }
1504
+ else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
1505
+ {
1506
+ sZero = oLang.sEmptyTable;
1507
+ }
1508
+
1509
+ var nTd = document.createElement( 'td' );
1510
+ nTd.setAttribute( 'valign', "top" );
1511
+ nTd.colSpan = _fnVisbleColumns( oSettings );
1512
+ nTd.className = oSettings.oClasses.sRowEmpty;
1513
+ nTd.innerHTML = _fnInfoMacros( oSettings, sZero );
1514
+
1515
+ anRows[ iRowCount ].appendChild( nTd );
1516
+ }
1517
+
1518
+ /* Header and footer callbacks */
1519
+ _fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
1520
+ _fnGetDataMaster( oSettings ), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ] );
1521
+
1522
+ _fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
1523
+ _fnGetDataMaster( oSettings ), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ] );
1524
+
1525
+ /*
1526
+ * Need to remove any old row from the display - note we can't just empty the tbody using
1527
+ * $().html('') since this will unbind the jQuery event handlers (even although the node
1528
+ * still exists!) - equally we can't use innerHTML, since IE throws an exception.
1529
+ */
1530
+ var
1531
+ nAddFrag = document.createDocumentFragment(),
1532
+ nRemoveFrag = document.createDocumentFragment(),
1533
+ nBodyPar, nTrs;
1534
+
1535
+ if ( oSettings.nTBody )
1536
+ {
1537
+ nBodyPar = oSettings.nTBody.parentNode;
1538
+ nRemoveFrag.appendChild( oSettings.nTBody );
1539
+
1540
+ /* When doing infinite scrolling, only remove child rows when sorting, filtering or start
1541
+ * up. When not infinite scroll, always do it.
1542
+ */
1543
+ if ( !oSettings.oScroll.bInfinite || !oSettings._bInitComplete ||
1544
+ oSettings.bSorted || oSettings.bFiltered )
1545
+ {
1546
+ while( (n = oSettings.nTBody.firstChild) )
1547
+ {
1548
+ oSettings.nTBody.removeChild( n );
1549
+ }
1550
+ }
1551
+
1552
+ /* Put the draw table into the dom */
1553
+ for ( i=0, iLen=anRows.length ; i<iLen ; i++ )
1554
+ {
1555
+ nAddFrag.appendChild( anRows[i] );
1556
+ }
1557
+
1558
+ oSettings.nTBody.appendChild( nAddFrag );
1559
+ if ( nBodyPar !== null )
1560
+ {
1561
+ nBodyPar.appendChild( oSettings.nTBody );
1562
+ }
1563
+ }
1564
+
1565
+ /* Call all required callback functions for the end of a draw */
1566
+ _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
1567
+
1568
+ /* Draw is complete, sorting and filtering must be as well */
1569
+ oSettings.bSorted = false;
1570
+ oSettings.bFiltered = false;
1571
+ oSettings.bDrawing = false;
1572
+
1573
+ if ( oSettings.oFeatures.bServerSide )
1574
+ {
1575
+ _fnProcessingDisplay( oSettings, false );
1576
+ if ( !oSettings._bInitComplete )
1577
+ {
1578
+ _fnInitComplete( oSettings );
1579
+ }
1580
+ }
1581
+ }
1582
+
1583
+
1584
+ /**
1585
+ * Redraw the table - taking account of the various features which are enabled
1586
+ * @param {object} oSettings dataTables settings object
1587
+ * @memberof DataTable#oApi
1588
+ */
1589
+ function _fnReDraw( oSettings )
1590
+ {
1591
+ if ( oSettings.oFeatures.bSort )
1592
+ {
1593
+ /* Sorting will refilter and draw for us */
1594
+ _fnSort( oSettings, oSettings.oPreviousSearch );
1595
+ }
1596
+ else if ( oSettings.oFeatures.bFilter )
1597
+ {
1598
+ /* Filtering will redraw for us */
1599
+ _fnFilterComplete( oSettings, oSettings.oPreviousSearch );
1600
+ }
1601
+ else
1602
+ {
1603
+ _fnCalculateEnd( oSettings );
1604
+ _fnDraw( oSettings );
1605
+ }
1606
+ }
1607
+
1608
+
1609
+ /**
1610
+ * Add the options to the page HTML for the table
1611
+ * @param {object} oSettings dataTables settings object
1612
+ * @memberof DataTable#oApi
1613
+ */
1614
+ function _fnAddOptionsHtml ( oSettings )
1615
+ {
1616
+ /*
1617
+ * Create a temporary, empty, div which we can later on replace with what we have generated
1618
+ * we do it this way to rendering the 'options' html offline - speed :-)
1619
+ */
1620
+ var nHolding = $('<div></div>')[0];
1621
+ oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable );
1622
+
1623
+ /*
1624
+ * All DataTables are wrapped in a div
1625
+ */
1626
+ oSettings.nTableWrapper = $('<div id="'+oSettings.sTableId+'_wrapper" class="'+oSettings.oClasses.sWrapper+'" role="grid"></div>')[0];
1627
+ oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
1628
+
1629
+ /* Track where we want to insert the option */
1630
+ var nInsertNode = oSettings.nTableWrapper;
1631
+
1632
+ /* Loop over the user set positioning and place the elements as needed */
1633
+ var aDom = oSettings.sDom.split('');
1634
+ var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j;
1635
+ for ( var i=0 ; i<aDom.length ; i++ )
1636
+ {
1637
+ iPushFeature = 0;
1638
+ cOption = aDom[i];
1639
+
1640
+ if ( cOption == '<' )
1641
+ {
1642
+ /* New container div */
1643
+ nNewNode = $('<div></div>')[0];
1644
+
1645
+ /* Check to see if we should append an id and/or a class name to the container */
1646
+ cNext = aDom[i+1];
1647
+ if ( cNext == "'" || cNext == '"' )
1648
+ {
1649
+ sAttr = "";
1650
+ j = 2;
1651
+ while ( aDom[i+j] != cNext )
1652
+ {
1653
+ sAttr += aDom[i+j];
1654
+ j++;
1655
+ }
1656
+
1657
+ /* Replace jQuery UI constants */
1658
+ if ( sAttr == "H" )
1659
+ {
1660
+ sAttr = oSettings.oClasses.sJUIHeader;
1661
+ }
1662
+ else if ( sAttr == "F" )
1663
+ {
1664
+ sAttr = oSettings.oClasses.sJUIFooter;
1665
+ }
1666
+
1667
+ /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
1668
+ * breaks the string into parts and applies them as needed
1669
+ */
1670
+ if ( sAttr.indexOf('.') != -1 )
1671
+ {
1672
+ var aSplit = sAttr.split('.');
1673
+ nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
1674
+ nNewNode.className = aSplit[1];
1675
+ }
1676
+ else if ( sAttr.charAt(0) == "#" )
1677
+ {
1678
+ nNewNode.id = sAttr.substr(1, sAttr.length-1);
1679
+ }
1680
+ else
1681
+ {
1682
+ nNewNode.className = sAttr;
1683
+ }
1684
+
1685
+ i += j; /* Move along the position array */
1686
+ }
1687
+
1688
+ nInsertNode.appendChild( nNewNode );
1689
+ nInsertNode = nNewNode;
1690
+ }
1691
+ else if ( cOption == '>' )
1692
+ {
1693
+ /* End container div */
1694
+ nInsertNode = nInsertNode.parentNode;
1695
+ }
1696
+ else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange )
1697
+ {
1698
+ /* Length */
1699
+ nTmp = _fnFeatureHtmlLength( oSettings );
1700
+ iPushFeature = 1;
1701
+ }
1702
+ else if ( cOption == 'f' && oSettings.oFeatures.bFilter )
1703
+ {
1704
+ /* Filter */
1705
+ nTmp = _fnFeatureHtmlFilter( oSettings );
1706
+ iPushFeature = 1;
1707
+ }
1708
+ else if ( cOption == 'r' && oSettings.oFeatures.bProcessing )
1709
+ {
1710
+ /* pRocessing */
1711
+ nTmp = _fnFeatureHtmlProcessing( oSettings );
1712
+ iPushFeature = 1;
1713
+ }
1714
+ else if ( cOption == 't' )
1715
+ {
1716
+ /* Table */
1717
+ nTmp = _fnFeatureHtmlTable( oSettings );
1718
+ iPushFeature = 1;
1719
+ }
1720
+ else if ( cOption == 'i' && oSettings.oFeatures.bInfo )
1721
+ {
1722
+ /* Info */
1723
+ nTmp = _fnFeatureHtmlInfo( oSettings );
1724
+ iPushFeature = 1;
1725
+ }
1726
+ else if ( cOption == 'p' && oSettings.oFeatures.bPaginate )
1727
+ {
1728
+ /* Pagination */
1729
+ nTmp = _fnFeatureHtmlPaginate( oSettings );
1730
+ iPushFeature = 1;
1731
+ }
1732
+ else if ( DataTable.ext.aoFeatures.length !== 0 )
1733
+ {
1734
+ /* Plug-in features */
1735
+ var aoFeatures = DataTable.ext.aoFeatures;
1736
+ for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
1737
+ {
1738
+ if ( cOption == aoFeatures[k].cFeature )
1739
+ {
1740
+ nTmp = aoFeatures[k].fnInit( oSettings );
1741
+ if ( nTmp )
1742
+ {
1743
+ iPushFeature = 1;
1744
+ }
1745
+ break;
1746
+ }
1747
+ }
1748
+ }
1749
+
1750
+ /* Add to the 2D features array */
1751
+ if ( iPushFeature == 1 && nTmp !== null )
1752
+ {
1753
+ if ( typeof oSettings.aanFeatures[cOption] !== 'object' )
1754
+ {
1755
+ oSettings.aanFeatures[cOption] = [];
1756
+ }
1757
+ oSettings.aanFeatures[cOption].push( nTmp );
1758
+ nInsertNode.appendChild( nTmp );
1759
+ }
1760
+ }
1761
+
1762
+ /* Built our DOM structure - replace the holding div with what we want */
1763
+ nHolding.parentNode.replaceChild( oSettings.nTableWrapper, nHolding );
1764
+ }
1765
+
1766
+
1767
+ /**
1768
+ * Use the DOM source to create up an array of header cells. The idea here is to
1769
+ * create a layout grid (array) of rows x columns, which contains a reference
1770
+ * to the cell that that point in the grid (regardless of col/rowspan), such that
1771
+ * any column / row could be removed and the new grid constructed
1772
+ * @param array {object} aLayout Array to store the calculated layout in
1773
+ * @param {node} nThead The header/footer element for the table
1774
+ * @memberof DataTable#oApi
1775
+ */
1776
+ function _fnDetectHeader ( aLayout, nThead )
1777
+ {
1778
+ var nTrs = $(nThead).children('tr');
1779
+ var nTr, nCell;
1780
+ var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
1781
+ var bUnique;
1782
+ var fnShiftCol = function ( a, i, j ) {
1783
+ var k = a[i];
1784
+ while ( k[j] ) {
1785
+ j++;
1786
+ }
1787
+ return j;
1788
+ };
1789
+
1790
+ aLayout.splice( 0, aLayout.length );
1791
+
1792
+ /* We know how many rows there are in the layout - so prep it */
1793
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
1794
+ {
1795
+ aLayout.push( [] );
1796
+ }
1797
+
1798
+ /* Calculate a layout array */
1799
+ for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
1800
+ {
1801
+ nTr = nTrs[i];
1802
+ iColumn = 0;
1803
+
1804
+ /* For every cell in the row... */
1805
+ nCell = nTr.firstChild;
1806
+ while ( nCell ) {
1807
+ if ( nCell.nodeName.toUpperCase() == "TD" ||
1808
+ nCell.nodeName.toUpperCase() == "TH" )
1809
+ {
1810
+ /* Get the col and rowspan attributes from the DOM and sanitise them */
1811
+ iColspan = nCell.getAttribute('colspan') * 1;
1812
+ iRowspan = nCell.getAttribute('rowspan') * 1;
1813
+ iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
1814
+ iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
1815
+
1816
+ /* There might be colspan cells already in this row, so shift our target
1817
+ * accordingly
1818
+ */
1819
+ iColShifted = fnShiftCol( aLayout, i, iColumn );
1820
+
1821
+ /* Cache calculation for unique columns */
1822
+ bUnique = iColspan === 1 ? true : false;
1823
+
1824
+ /* If there is col / rowspan, copy the information into the layout grid */
1825
+ for ( l=0 ; l<iColspan ; l++ )
1826
+ {
1827
+ for ( k=0 ; k<iRowspan ; k++ )
1828
+ {
1829
+ aLayout[i+k][iColShifted+l] = {
1830
+ "cell": nCell,
1831
+ "unique": bUnique
1832
+ };
1833
+ aLayout[i+k].nTr = nTr;
1834
+ }
1835
+ }
1836
+ }
1837
+ nCell = nCell.nextSibling;
1838
+ }
1839
+ }
1840
+ }
1841
+
1842
+
1843
+ /**
1844
+ * Get an array of unique th elements, one for each column
1845
+ * @param {object} oSettings dataTables settings object
1846
+ * @param {node} nHeader automatically detect the layout from this node - optional
1847
+ * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
1848
+ * @returns array {node} aReturn list of unique th's
1849
+ * @memberof DataTable#oApi
1850
+ */
1851
+ function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
1852
+ {
1853
+ var aReturn = [];
1854
+ if ( !aLayout )
1855
+ {
1856
+ aLayout = oSettings.aoHeader;
1857
+ if ( nHeader )
1858
+ {
1859
+ aLayout = [];
1860
+ _fnDetectHeader( aLayout, nHeader );
1861
+ }
1862
+ }
1863
+
1864
+ for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
1865
+ {
1866
+ for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
1867
+ {
1868
+ if ( aLayout[i][j].unique &&
1869
+ (!aReturn[j] || !oSettings.bSortCellsTop) )
1870
+ {
1871
+ aReturn[j] = aLayout[i][j].cell;
1872
+ }
1873
+ }
1874
+ }
1875
+
1876
+ return aReturn;
1877
+ }
1878
+
1879
+
1880
+
1881
+ /**
1882
+ * Update the table using an Ajax call
1883
+ * @param {object} oSettings dataTables settings object
1884
+ * @returns {boolean} Block the table drawing or not
1885
+ * @memberof DataTable#oApi
1886
+ */
1887
+ function _fnAjaxUpdate( oSettings )
1888
+ {
1889
+ if ( oSettings.bAjaxDataGet )
1890
+ {
1891
+ oSettings.iDraw++;
1892
+ _fnProcessingDisplay( oSettings, true );
1893
+ var iColumns = oSettings.aoColumns.length;
1894
+ var aoData = _fnAjaxParameters( oSettings );
1895
+ _fnServerParams( oSettings, aoData );
1896
+
1897
+ oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData,
1898
+ function(json) {
1899
+ _fnAjaxUpdateDraw( oSettings, json );
1900
+ }, oSettings );
1901
+ return false;
1902
+ }
1903
+ else
1904
+ {
1905
+ return true;
1906
+ }
1907
+ }
1908
+
1909
+
1910
+ /**
1911
+ * Build up the parameters in an object needed for a server-side processing request
1912
+ * @param {object} oSettings dataTables settings object
1913
+ * @returns {bool} block the table drawing or not
1914
+ * @memberof DataTable#oApi
1915
+ */
1916
+ function _fnAjaxParameters( oSettings )
1917
+ {
1918
+ var iColumns = oSettings.aoColumns.length;
1919
+ var aoData = [], mDataProp, aaSort, aDataSort;
1920
+ var i, j;
1921
+
1922
+ aoData.push( { "name": "sEcho", "value": oSettings.iDraw } );
1923
+ aoData.push( { "name": "iColumns", "value": iColumns } );
1924
+ aoData.push( { "name": "sColumns", "value": _fnColumnOrdering(oSettings) } );
1925
+ aoData.push( { "name": "iDisplayStart", "value": oSettings._iDisplayStart } );
1926
+ aoData.push( { "name": "iDisplayLength", "value": oSettings.oFeatures.bPaginate !== false ?
1927
+ oSettings._iDisplayLength : -1 } );
1928
+
1929
+ for ( i=0 ; i<iColumns ; i++ )
1930
+ {
1931
+ mDataProp = oSettings.aoColumns[i].mData;
1932
+ aoData.push( { "name": "mDataProp_"+i, "value": typeof(mDataProp)==="function" ? 'function' : mDataProp } );
1933
+ }
1934
+
1935
+ /* Filtering */
1936
+ if ( oSettings.oFeatures.bFilter !== false )
1937
+ {
1938
+ aoData.push( { "name": "sSearch", "value": oSettings.oPreviousSearch.sSearch } );
1939
+ aoData.push( { "name": "bRegex", "value": oSettings.oPreviousSearch.bRegex } );
1940
+ for ( i=0 ; i<iColumns ; i++ )
1941
+ {
1942
+ aoData.push( { "name": "sSearch_"+i, "value": oSettings.aoPreSearchCols[i].sSearch } );
1943
+ aoData.push( { "name": "bRegex_"+i, "value": oSettings.aoPreSearchCols[i].bRegex } );
1944
+ aoData.push( { "name": "bSearchable_"+i, "value": oSettings.aoColumns[i].bSearchable } );
1945
+ }
1946
+ }
1947
+
1948
+ /* Sorting */
1949
+ if ( oSettings.oFeatures.bSort !== false )
1950
+ {
1951
+ var iCounter = 0;
1952
+
1953
+ aaSort = ( oSettings.aaSortingFixed !== null ) ?
1954
+ oSettings.aaSortingFixed.concat( oSettings.aaSorting ) :
1955
+ oSettings.aaSorting.slice();
1956
+
1957
+ for ( i=0 ; i<aaSort.length ; i++ )
1958
+ {
1959
+ aDataSort = oSettings.aoColumns[ aaSort[i][0] ].aDataSort;
1960
+
1961
+ for ( j=0 ; j<aDataSort.length ; j++ )
1962
+ {
1963
+ aoData.push( { "name": "iSortCol_"+iCounter, "value": aDataSort[j] } );
1964
+ aoData.push( { "name": "sSortDir_"+iCounter, "value": aaSort[i][1] } );
1965
+ iCounter++;
1966
+ }
1967
+ }
1968
+ aoData.push( { "name": "iSortingCols", "value": iCounter } );
1969
+
1970
+ for ( i=0 ; i<iColumns ; i++ )
1971
+ {
1972
+ aoData.push( { "name": "bSortable_"+i, "value": oSettings.aoColumns[i].bSortable } );
1973
+ }
1974
+ }
1975
+
1976
+ return aoData;
1977
+ }
1978
+
1979
+
1980
+ /**
1981
+ * Add Ajax parameters from plug-ins
1982
+ * @param {object} oSettings dataTables settings object
1983
+ * @param array {objects} aoData name/value pairs to send to the server
1984
+ * @memberof DataTable#oApi
1985
+ */
1986
+ function _fnServerParams( oSettings, aoData )
1987
+ {
1988
+ _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [aoData] );
1989
+ }
1990
+
1991
+
1992
+ /**
1993
+ * Data the data from the server (nuking the old) and redraw the table
1994
+ * @param {object} oSettings dataTables settings object
1995
+ * @param {object} json json data return from the server.
1996
+ * @param {string} json.sEcho Tracking flag for DataTables to match requests
1997
+ * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
1998
+ * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
1999
+ * @param {array} json.aaData The data to display on this page
2000
+ * @param {string} [json.sColumns] Column ordering (sName, comma separated)
2001
+ * @memberof DataTable#oApi
2002
+ */
2003
+ function _fnAjaxUpdateDraw ( oSettings, json )
2004
+ {
2005
+ if ( json.sEcho !== undefined )
2006
+ {
2007
+ /* Protect against old returns over-writing a new one. Possible when you get
2008
+ * very fast interaction, and later queries are completed much faster
2009
+ */
2010
+ if ( json.sEcho*1 < oSettings.iDraw )
2011
+ {
2012
+ return;
2013
+ }
2014
+ else
2015
+ {
2016
+ oSettings.iDraw = json.sEcho * 1;
2017
+ }
2018
+ }
2019
+
2020
+ if ( !oSettings.oScroll.bInfinite ||
2021
+ (oSettings.oScroll.bInfinite && (oSettings.bSorted || oSettings.bFiltered)) )
2022
+ {
2023
+ _fnClearTable( oSettings );
2024
+ }
2025
+ oSettings._iRecordsTotal = parseInt(json.iTotalRecords, 10);
2026
+ oSettings._iRecordsDisplay = parseInt(json.iTotalDisplayRecords, 10);
2027
+
2028
+ /* Determine if reordering is required */
2029
+ var sOrdering = _fnColumnOrdering(oSettings);
2030
+ var bReOrder = (json.sColumns !== undefined && sOrdering !== "" && json.sColumns != sOrdering );
2031
+ var aiIndex;
2032
+ if ( bReOrder )
2033
+ {
2034
+ aiIndex = _fnReOrderIndex( oSettings, json.sColumns );
2035
+ }
2036
+
2037
+ var aData = _fnGetObjectDataFn( oSettings.sAjaxDataProp )( json );
2038
+ for ( var i=0, iLen=aData.length ; i<iLen ; i++ )
2039
+ {
2040
+ if ( bReOrder )
2041
+ {
2042
+ /* If we need to re-order, then create a new array with the correct order and add it */
2043
+ var aDataSorted = [];
2044
+ for ( var j=0, jLen=oSettings.aoColumns.length ; j<jLen ; j++ )
2045
+ {
2046
+ aDataSorted.push( aData[i][ aiIndex[j] ] );
2047
+ }
2048
+ _fnAddData( oSettings, aDataSorted );
2049
+ }
2050
+ else
2051
+ {
2052
+ /* No re-order required, sever got it "right" - just straight add */
2053
+ _fnAddData( oSettings, aData[i] );
2054
+ }
2055
+ }
2056
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
2057
+
2058
+ oSettings.bAjaxDataGet = false;
2059
+ _fnDraw( oSettings );
2060
+ oSettings.bAjaxDataGet = true;
2061
+ _fnProcessingDisplay( oSettings, false );
2062
+ }
2063
+
2064
+
2065
+
2066
+ /**
2067
+ * Generate the node required for filtering text
2068
+ * @returns {node} Filter control element
2069
+ * @param {object} oSettings dataTables settings object
2070
+ * @memberof DataTable#oApi
2071
+ */
2072
+ function _fnFeatureHtmlFilter ( oSettings )
2073
+ {
2074
+ var oPreviousSearch = oSettings.oPreviousSearch;
2075
+
2076
+ var sSearchStr = oSettings.oLanguage.sSearch;
2077
+ sSearchStr = (sSearchStr.indexOf('_INPUT_') !== -1) ?
2078
+ sSearchStr.replace('_INPUT_', '<input type="text" />') :
2079
+ sSearchStr==="" ? '<input type="text" />' : sSearchStr+' <input type="text" />';
2080
+
2081
+ var nFilter = document.createElement( 'div' );
2082
+ nFilter.className = oSettings.oClasses.sFilter;
2083
+ nFilter.innerHTML = '<label>'+sSearchStr+'</label>';
2084
+ if ( !oSettings.aanFeatures.f )
2085
+ {
2086
+ nFilter.id = oSettings.sTableId+'_filter';
2087
+ }
2088
+
2089
+ var jqFilter = $('input[type="text"]', nFilter);
2090
+
2091
+ // Store a reference to the input element, so other input elements could be
2092
+ // added to the filter wrapper if needed (submit button for example)
2093
+ nFilter._DT_Input = jqFilter[0];
2094
+
2095
+ jqFilter.val( oPreviousSearch.sSearch.replace('"','&quot;') );
2096
+ jqFilter.bind( 'keyup.DT', function(e) {
2097
+ /* Update all other filter input elements for the new display */
2098
+ var n = oSettings.aanFeatures.f;
2099
+ var val = this.value==="" ? "" : this.value; // mental IE8 fix :-(
2100
+
2101
+ for ( var i=0, iLen=n.length ; i<iLen ; i++ )
2102
+ {
2103
+ if ( n[i] != $(this).parents('div.dataTables_filter')[0] )
2104
+ {
2105
+ $(n[i]._DT_Input).val( val );
2106
+ }
2107
+ }
2108
+
2109
+ /* Now do the filter */
2110
+ if ( val != oPreviousSearch.sSearch )
2111
+ {
2112
+ _fnFilterComplete( oSettings, {
2113
+ "sSearch": val,
2114
+ "bRegex": oPreviousSearch.bRegex,
2115
+ "bSmart": oPreviousSearch.bSmart ,
2116
+ "bCaseInsensitive": oPreviousSearch.bCaseInsensitive
2117
+ } );
2118
+ }
2119
+ } );
2120
+
2121
+ jqFilter
2122
+ .attr('aria-controls', oSettings.sTableId)
2123
+ .bind( 'keypress.DT', function(e) {
2124
+ /* Prevent form submission */
2125
+ if ( e.keyCode == 13 )
2126
+ {
2127
+ return false;
2128
+ }
2129
+ }
2130
+ );
2131
+
2132
+ return nFilter;
2133
+ }
2134
+
2135
+
2136
+ /**
2137
+ * Filter the table using both the global filter and column based filtering
2138
+ * @param {object} oSettings dataTables settings object
2139
+ * @param {object} oSearch search information
2140
+ * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
2141
+ * @memberof DataTable#oApi
2142
+ */
2143
+ function _fnFilterComplete ( oSettings, oInput, iForce )
2144
+ {
2145
+ var oPrevSearch = oSettings.oPreviousSearch;
2146
+ var aoPrevSearch = oSettings.aoPreSearchCols;
2147
+ var fnSaveFilter = function ( oFilter ) {
2148
+ /* Save the filtering values */
2149
+ oPrevSearch.sSearch = oFilter.sSearch;
2150
+ oPrevSearch.bRegex = oFilter.bRegex;
2151
+ oPrevSearch.bSmart = oFilter.bSmart;
2152
+ oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
2153
+ };
2154
+
2155
+ /* In server-side processing all filtering is done by the server, so no point hanging around here */
2156
+ if ( !oSettings.oFeatures.bServerSide )
2157
+ {
2158
+ /* Global filter */
2159
+ _fnFilter( oSettings, oInput.sSearch, iForce, oInput.bRegex, oInput.bSmart, oInput.bCaseInsensitive );
2160
+ fnSaveFilter( oInput );
2161
+
2162
+ /* Now do the individual column filter */
2163
+ for ( var i=0 ; i<oSettings.aoPreSearchCols.length ; i++ )
2164
+ {
2165
+ _fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, aoPrevSearch[i].bRegex,
2166
+ aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
2167
+ }
2168
+
2169
+ /* Custom filtering */
2170
+ _fnFilterCustom( oSettings );
2171
+ }
2172
+ else
2173
+ {
2174
+ fnSaveFilter( oInput );
2175
+ }
2176
+
2177
+ /* Tell the draw function we have been filtering */
2178
+ oSettings.bFiltered = true;
2179
+ $(oSettings.oInstance).trigger('filter', oSettings);
2180
+
2181
+ /* Redraw the table */
2182
+ oSettings._iDisplayStart = 0;
2183
+ _fnCalculateEnd( oSettings );
2184
+ _fnDraw( oSettings );
2185
+
2186
+ /* Rebuild search array 'offline' */
2187
+ _fnBuildSearchArray( oSettings, 0 );
2188
+ }
2189
+
2190
+
2191
+ /**
2192
+ * Apply custom filtering functions
2193
+ * @param {object} oSettings dataTables settings object
2194
+ * @memberof DataTable#oApi
2195
+ */
2196
+ function _fnFilterCustom( oSettings )
2197
+ {
2198
+ var afnFilters = DataTable.ext.afnFiltering;
2199
+ var aiFilterColumns = _fnGetColumns( oSettings, 'bSearchable' );
2200
+
2201
+ for ( var i=0, iLen=afnFilters.length ; i<iLen ; i++ )
2202
+ {
2203
+ var iCorrector = 0;
2204
+ for ( var j=0, jLen=oSettings.aiDisplay.length ; j<jLen ; j++ )
2205
+ {
2206
+ var iDisIndex = oSettings.aiDisplay[j-iCorrector];
2207
+ var bTest = afnFilters[i](
2208
+ oSettings,
2209
+ _fnGetRowData( oSettings, iDisIndex, 'filter', aiFilterColumns ),
2210
+ iDisIndex
2211
+ );
2212
+
2213
+ /* Check if we should use this row based on the filtering function */
2214
+ if ( !bTest )
2215
+ {
2216
+ oSettings.aiDisplay.splice( j-iCorrector, 1 );
2217
+ iCorrector++;
2218
+ }
2219
+ }
2220
+ }
2221
+ }
2222
+
2223
+
2224
+ /**
2225
+ * Filter the table on a per-column basis
2226
+ * @param {object} oSettings dataTables settings object
2227
+ * @param {string} sInput string to filter on
2228
+ * @param {int} iColumn column to filter
2229
+ * @param {bool} bRegex treat search string as a regular expression or not
2230
+ * @param {bool} bSmart use smart filtering or not
2231
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
2232
+ * @memberof DataTable#oApi
2233
+ */
2234
+ function _fnFilterColumn ( oSettings, sInput, iColumn, bRegex, bSmart, bCaseInsensitive )
2235
+ {
2236
+ if ( sInput === "" )
2237
+ {
2238
+ return;
2239
+ }
2240
+
2241
+ var iIndexCorrector = 0;
2242
+ var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive );
2243
+
2244
+ for ( var i=oSettings.aiDisplay.length-1 ; i>=0 ; i-- )
2245
+ {
2246
+ var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ),
2247
+ oSettings.aoColumns[iColumn].sType );
2248
+ if ( ! rpSearch.test( sData ) )
2249
+ {
2250
+ oSettings.aiDisplay.splice( i, 1 );
2251
+ iIndexCorrector++;
2252
+ }
2253
+ }
2254
+ }
2255
+
2256
+
2257
+ /**
2258
+ * Filter the data table based on user input and draw the table
2259
+ * @param {object} oSettings dataTables settings object
2260
+ * @param {string} sInput string to filter on
2261
+ * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0)
2262
+ * @param {bool} bRegex treat as a regular expression or not
2263
+ * @param {bool} bSmart perform smart filtering or not
2264
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
2265
+ * @memberof DataTable#oApi
2266
+ */
2267
+ function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive )
2268
+ {
2269
+ var i;
2270
+ var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive );
2271
+ var oPrevSearch = oSettings.oPreviousSearch;
2272
+
2273
+ /* Check if we are forcing or not - optional parameter */
2274
+ if ( !iForce )
2275
+ {
2276
+ iForce = 0;
2277
+ }
2278
+
2279
+ /* Need to take account of custom filtering functions - always filter */
2280
+ if ( DataTable.ext.afnFiltering.length !== 0 )
2281
+ {
2282
+ iForce = 1;
2283
+ }
2284
+
2285
+ /*
2286
+ * If the input is blank - we want the full data set
2287
+ */
2288
+ if ( sInput.length <= 0 )
2289
+ {
2290
+ oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
2291
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
2292
+ }
2293
+ else
2294
+ {
2295
+ /*
2296
+ * We are starting a new search or the new search string is smaller
2297
+ * then the old one (i.e. delete). Search from the master array
2298
+ */
2299
+ if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length ||
2300
+ oPrevSearch.sSearch.length > sInput.length || iForce == 1 ||
2301
+ sInput.indexOf(oPrevSearch.sSearch) !== 0 )
2302
+ {
2303
+ /* Nuke the old display array - we are going to rebuild it */
2304
+ oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
2305
+
2306
+ /* Force a rebuild of the search array */
2307
+ _fnBuildSearchArray( oSettings, 1 );
2308
+
2309
+ /* Search through all records to populate the search array
2310
+ * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1
2311
+ * mapping
2312
+ */
2313
+ for ( i=0 ; i<oSettings.aiDisplayMaster.length ; i++ )
2314
+ {
2315
+ if ( rpSearch.test(oSettings.asDataSearch[i]) )
2316
+ {
2317
+ oSettings.aiDisplay.push( oSettings.aiDisplayMaster[i] );
2318
+ }
2319
+ }
2320
+ }
2321
+ else
2322
+ {
2323
+ /* Using old search array - refine it - do it this way for speed
2324
+ * Don't have to search the whole master array again
2325
+ */
2326
+ var iIndexCorrector = 0;
2327
+
2328
+ /* Search the current results */
2329
+ for ( i=0 ; i<oSettings.asDataSearch.length ; i++ )
2330
+ {
2331
+ if ( ! rpSearch.test(oSettings.asDataSearch[i]) )
2332
+ {
2333
+ oSettings.aiDisplay.splice( i-iIndexCorrector, 1 );
2334
+ iIndexCorrector++;
2335
+ }
2336
+ }
2337
+ }
2338
+ }
2339
+ }
2340
+
2341
+
2342
+ /**
2343
+ * Create an array which can be quickly search through
2344
+ * @param {object} oSettings dataTables settings object
2345
+ * @param {int} iMaster use the master data array - optional
2346
+ * @memberof DataTable#oApi
2347
+ */
2348
+ function _fnBuildSearchArray ( oSettings, iMaster )
2349
+ {
2350
+ if ( !oSettings.oFeatures.bServerSide )
2351
+ {
2352
+ /* Clear out the old data */
2353
+ oSettings.asDataSearch = [];
2354
+
2355
+ var aiFilterColumns = _fnGetColumns( oSettings, 'bSearchable' );
2356
+ var aiIndex = (iMaster===1) ?
2357
+ oSettings.aiDisplayMaster :
2358
+ oSettings.aiDisplay;
2359
+
2360
+ for ( var i=0, iLen=aiIndex.length ; i<iLen ; i++ )
2361
+ {
2362
+ oSettings.asDataSearch[i] = _fnBuildSearchRow(
2363
+ oSettings,
2364
+ _fnGetRowData( oSettings, aiIndex[i], 'filter', aiFilterColumns )
2365
+ );
2366
+ }
2367
+ }
2368
+ }
2369
+
2370
+
2371
+ /**
2372
+ * Create a searchable string from a single data row
2373
+ * @param {object} oSettings dataTables settings object
2374
+ * @param {array} aData Row data array to use for the data to search
2375
+ * @memberof DataTable#oApi
2376
+ */
2377
+ function _fnBuildSearchRow( oSettings, aData )
2378
+ {
2379
+ var sSearch = aData.join(' ');
2380
+
2381
+ /* If it looks like there is an HTML entity in the string, attempt to decode it */
2382
+ if ( sSearch.indexOf('&') !== -1 )
2383
+ {
2384
+ sSearch = $('<div>').html(sSearch).text();
2385
+ }
2386
+
2387
+ // Strip newline characters
2388
+ return sSearch.replace( /[\n\r]/g, " " );
2389
+ }
2390
+
2391
+ /**
2392
+ * Build a regular expression object suitable for searching a table
2393
+ * @param {string} sSearch string to search for
2394
+ * @param {bool} bRegex treat as a regular expression or not
2395
+ * @param {bool} bSmart perform smart filtering or not
2396
+ * @param {bool} bCaseInsensitive Do case insensitive matching or not
2397
+ * @returns {RegExp} constructed object
2398
+ * @memberof DataTable#oApi
2399
+ */
2400
+ function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive )
2401
+ {
2402
+ var asSearch, sRegExpString;
2403
+
2404
+ if ( bSmart )
2405
+ {
2406
+ /* Generate the regular expression to use. Something along the lines of:
2407
+ * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$
2408
+ */
2409
+ asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' );
2410
+ sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$';
2411
+ return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" );
2412
+ }
2413
+ else
2414
+ {
2415
+ sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch );
2416
+ return new RegExp( sSearch, bCaseInsensitive ? "i" : "" );
2417
+ }
2418
+ }
2419
+
2420
+
2421
+ /**
2422
+ * Convert raw data into something that the user can search on
2423
+ * @param {string} sData data to be modified
2424
+ * @param {string} sType data type
2425
+ * @returns {string} search string
2426
+ * @memberof DataTable#oApi
2427
+ */
2428
+ function _fnDataToSearch ( sData, sType )
2429
+ {
2430
+ if ( typeof DataTable.ext.ofnSearch[sType] === "function" )
2431
+ {
2432
+ return DataTable.ext.ofnSearch[sType]( sData );
2433
+ }
2434
+ else if ( sData === null )
2435
+ {
2436
+ return '';
2437
+ }
2438
+ else if ( sType == "html" )
2439
+ {
2440
+ return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" );
2441
+ }
2442
+ else if ( typeof sData === "string" )
2443
+ {
2444
+ return sData.replace(/[\r\n]/g," ");
2445
+ }
2446
+ return sData;
2447
+ }
2448
+
2449
+
2450
+ /**
2451
+ * scape a string such that it can be used in a regular expression
2452
+ * @param {string} sVal string to escape
2453
+ * @returns {string} escaped string
2454
+ * @memberof DataTable#oApi
2455
+ */
2456
+ function _fnEscapeRegex ( sVal )
2457
+ {
2458
+ var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ];
2459
+ var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' );
2460
+ return sVal.replace(reReplace, '\\$1');
2461
+ }
2462
+
2463
+
2464
+ /**
2465
+ * Generate the node required for the info display
2466
+ * @param {object} oSettings dataTables settings object
2467
+ * @returns {node} Information element
2468
+ * @memberof DataTable#oApi
2469
+ */
2470
+ function _fnFeatureHtmlInfo ( oSettings )
2471
+ {
2472
+ var nInfo = document.createElement( 'div' );
2473
+ nInfo.className = oSettings.oClasses.sInfo;
2474
+
2475
+ /* Actions that are to be taken once only for this feature */
2476
+ if ( !oSettings.aanFeatures.i )
2477
+ {
2478
+ /* Add draw callback */
2479
+ oSettings.aoDrawCallback.push( {
2480
+ "fn": _fnUpdateInfo,
2481
+ "sName": "information"
2482
+ } );
2483
+
2484
+ /* Add id */
2485
+ nInfo.id = oSettings.sTableId+'_info';
2486
+ }
2487
+ oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' );
2488
+
2489
+ return nInfo;
2490
+ }
2491
+
2492
+
2493
+ /**
2494
+ * Update the information elements in the display
2495
+ * @param {object} oSettings dataTables settings object
2496
+ * @memberof DataTable#oApi
2497
+ */
2498
+ function _fnUpdateInfo ( oSettings )
2499
+ {
2500
+ /* Show information about the table */
2501
+ if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 )
2502
+ {
2503
+ return;
2504
+ }
2505
+
2506
+ var
2507
+ oLang = oSettings.oLanguage,
2508
+ iStart = oSettings._iDisplayStart+1,
2509
+ iEnd = oSettings.fnDisplayEnd(),
2510
+ iMax = oSettings.fnRecordsTotal(),
2511
+ iTotal = oSettings.fnRecordsDisplay(),
2512
+ sOut;
2513
+
2514
+ if ( iTotal === 0 )
2515
+ {
2516
+ /* Empty record set */
2517
+ sOut = oLang.sInfoEmpty;
2518
+ }
2519
+ else {
2520
+ /* Normal record set */
2521
+ sOut = oLang.sInfo;
2522
+ }
2523
+
2524
+ if ( iTotal != iMax )
2525
+ {
2526
+ /* Record set after filtering */
2527
+ sOut += ' ' + oLang.sInfoFiltered;
2528
+ }
2529
+
2530
+ // Convert the macros
2531
+ sOut += oLang.sInfoPostFix;
2532
+ sOut = _fnInfoMacros( oSettings, sOut );
2533
+
2534
+ if ( oLang.fnInfoCallback !== null )
2535
+ {
2536
+ sOut = oLang.fnInfoCallback.call( oSettings.oInstance,
2537
+ oSettings, iStart, iEnd, iMax, iTotal, sOut );
2538
+ }
2539
+
2540
+ var n = oSettings.aanFeatures.i;
2541
+ for ( var i=0, iLen=n.length ; i<iLen ; i++ )
2542
+ {
2543
+ $(n[i]).html( sOut );
2544
+ }
2545
+ }
2546
+
2547
+
2548
+ function _fnInfoMacros ( oSettings, str )
2549
+ {
2550
+ var
2551
+ iStart = oSettings._iDisplayStart+1,
2552
+ sStart = oSettings.fnFormatNumber( iStart ),
2553
+ iEnd = oSettings.fnDisplayEnd(),
2554
+ sEnd = oSettings.fnFormatNumber( iEnd ),
2555
+ iTotal = oSettings.fnRecordsDisplay(),
2556
+ sTotal = oSettings.fnFormatNumber( iTotal ),
2557
+ iMax = oSettings.fnRecordsTotal(),
2558
+ sMax = oSettings.fnFormatNumber( iMax );
2559
+
2560
+ // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
2561
+ // internally
2562
+ if ( oSettings.oScroll.bInfinite )
2563
+ {
2564
+ sStart = oSettings.fnFormatNumber( 1 );
2565
+ }
2566
+
2567
+ return str.
2568
+ replace(/_START_/g, sStart).
2569
+ replace(/_END_/g, sEnd).
2570
+ replace(/_TOTAL_/g, sTotal).
2571
+ replace(/_MAX_/g, sMax);
2572
+ }
2573
+
2574
+
2575
+
2576
+ /**
2577
+ * Draw the table for the first time, adding all required features
2578
+ * @param {object} oSettings dataTables settings object
2579
+ * @memberof DataTable#oApi
2580
+ */
2581
+ function _fnInitialise ( oSettings )
2582
+ {
2583
+ var i, iLen, iAjaxStart=oSettings.iInitDisplayStart;
2584
+
2585
+ /* Ensure that the table data is fully initialised */
2586
+ if ( oSettings.bInitialised === false )
2587
+ {
2588
+ setTimeout( function(){ _fnInitialise( oSettings ); }, 200 );
2589
+ return;
2590
+ }
2591
+
2592
+ /* Show the display HTML options */
2593
+ _fnAddOptionsHtml( oSettings );
2594
+
2595
+ /* Build and draw the header / footer for the table */
2596
+ _fnBuildHead( oSettings );
2597
+ _fnDrawHead( oSettings, oSettings.aoHeader );
2598
+ if ( oSettings.nTFoot )
2599
+ {
2600
+ _fnDrawHead( oSettings, oSettings.aoFooter );
2601
+ }
2602
+
2603
+ /* Okay to show that something is going on now */
2604
+ _fnProcessingDisplay( oSettings, true );
2605
+
2606
+ /* Calculate sizes for columns */
2607
+ if ( oSettings.oFeatures.bAutoWidth )
2608
+ {
2609
+ _fnCalculateColumnWidths( oSettings );
2610
+ }
2611
+
2612
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
2613
+ {
2614
+ if ( oSettings.aoColumns[i].sWidth !== null )
2615
+ {
2616
+ oSettings.aoColumns[i].nTh.style.width = _fnStringToCss( oSettings.aoColumns[i].sWidth );
2617
+ }
2618
+ }
2619
+
2620
+ /* If there is default sorting required - let's do it. The sort function will do the
2621
+ * drawing for us. Otherwise we draw the table regardless of the Ajax source - this allows
2622
+ * the table to look initialised for Ajax sourcing data (show 'loading' message possibly)
2623
+ */
2624
+ if ( oSettings.oFeatures.bSort )
2625
+ {
2626
+ _fnSort( oSettings );
2627
+ }
2628
+ else if ( oSettings.oFeatures.bFilter )
2629
+ {
2630
+ _fnFilterComplete( oSettings, oSettings.oPreviousSearch );
2631
+ }
2632
+ else
2633
+ {
2634
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
2635
+ _fnCalculateEnd( oSettings );
2636
+ _fnDraw( oSettings );
2637
+ }
2638
+
2639
+ /* if there is an ajax source load the data */
2640
+ if ( oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
2641
+ {
2642
+ var aoData = [];
2643
+ _fnServerParams( oSettings, aoData );
2644
+ oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData, function(json) {
2645
+ var aData = (oSettings.sAjaxDataProp !== "") ?
2646
+ _fnGetObjectDataFn( oSettings.sAjaxDataProp )(json) : json;
2647
+
2648
+ /* Got the data - add it to the table */
2649
+ for ( i=0 ; i<aData.length ; i++ )
2650
+ {
2651
+ _fnAddData( oSettings, aData[i] );
2652
+ }
2653
+
2654
+ /* Reset the init display for cookie saving. We've already done a filter, and
2655
+ * therefore cleared it before. So we need to make it appear 'fresh'
2656
+ */
2657
+ oSettings.iInitDisplayStart = iAjaxStart;
2658
+
2659
+ if ( oSettings.oFeatures.bSort )
2660
+ {
2661
+ _fnSort( oSettings );
2662
+ }
2663
+ else
2664
+ {
2665
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
2666
+ _fnCalculateEnd( oSettings );
2667
+ _fnDraw( oSettings );
2668
+ }
2669
+
2670
+ _fnProcessingDisplay( oSettings, false );
2671
+ _fnInitComplete( oSettings, json );
2672
+ }, oSettings );
2673
+ return;
2674
+ }
2675
+
2676
+ /* Server-side processing initialisation complete is done at the end of _fnDraw */
2677
+ if ( !oSettings.oFeatures.bServerSide )
2678
+ {
2679
+ _fnProcessingDisplay( oSettings, false );
2680
+ _fnInitComplete( oSettings );
2681
+ }
2682
+ }
2683
+
2684
+
2685
+ /**
2686
+ * Draw the table for the first time, adding all required features
2687
+ * @param {object} oSettings dataTables settings object
2688
+ * @param {object} [json] JSON from the server that completed the table, if using Ajax source
2689
+ * with client-side processing (optional)
2690
+ * @memberof DataTable#oApi
2691
+ */
2692
+ function _fnInitComplete ( oSettings, json )
2693
+ {
2694
+ oSettings._bInitComplete = true;
2695
+ _fnCallbackFire( oSettings, 'aoInitComplete', 'init', [oSettings, json] );
2696
+ }
2697
+
2698
+
2699
+ /**
2700
+ * Language compatibility - when certain options are given, and others aren't, we
2701
+ * need to duplicate the values over, in order to provide backwards compatibility
2702
+ * with older language files.
2703
+ * @param {object} oSettings dataTables settings object
2704
+ * @memberof DataTable#oApi
2705
+ */
2706
+ function _fnLanguageCompat( oLanguage )
2707
+ {
2708
+ var oDefaults = DataTable.defaults.oLanguage;
2709
+
2710
+ /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
2711
+ * sZeroRecords - assuming that is given.
2712
+ */
2713
+ if ( !oLanguage.sEmptyTable && oLanguage.sZeroRecords &&
2714
+ oDefaults.sEmptyTable === "No data available in table" )
2715
+ {
2716
+ _fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sEmptyTable' );
2717
+ }
2718
+
2719
+ /* Likewise with loading records */
2720
+ if ( !oLanguage.sLoadingRecords && oLanguage.sZeroRecords &&
2721
+ oDefaults.sLoadingRecords === "Loading..." )
2722
+ {
2723
+ _fnMap( oLanguage, oLanguage, 'sZeroRecords', 'sLoadingRecords' );
2724
+ }
2725
+ }
2726
+
2727
+
2728
+
2729
+ /**
2730
+ * Generate the node required for user display length changing
2731
+ * @param {object} oSettings dataTables settings object
2732
+ * @returns {node} Display length feature node
2733
+ * @memberof DataTable#oApi
2734
+ */
2735
+ function _fnFeatureHtmlLength ( oSettings )
2736
+ {
2737
+ if ( oSettings.oScroll.bInfinite )
2738
+ {
2739
+ return null;
2740
+ }
2741
+
2742
+ /* This can be overruled by not using the _MENU_ var/macro in the language variable */
2743
+ var sName = 'name="'+oSettings.sTableId+'_length"';
2744
+ var sStdMenu = '<select size="1" '+sName+'>';
2745
+ var i, iLen;
2746
+ var aLengthMenu = oSettings.aLengthMenu;
2747
+
2748
+ if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' &&
2749
+ typeof aLengthMenu[1] === 'object' )
2750
+ {
2751
+ for ( i=0, iLen=aLengthMenu[0].length ; i<iLen ; i++ )
2752
+ {
2753
+ sStdMenu += '<option value="'+aLengthMenu[0][i]+'">'+aLengthMenu[1][i]+'</option>';
2754
+ }
2755
+ }
2756
+ else
2757
+ {
2758
+ for ( i=0, iLen=aLengthMenu.length ; i<iLen ; i++ )
2759
+ {
2760
+ sStdMenu += '<option value="'+aLengthMenu[i]+'">'+aLengthMenu[i]+'</option>';
2761
+ }
2762
+ }
2763
+ sStdMenu += '</select>';
2764
+
2765
+ var nLength = document.createElement( 'div' );
2766
+ if ( !oSettings.aanFeatures.l )
2767
+ {
2768
+ nLength.id = oSettings.sTableId+'_length';
2769
+ }
2770
+ nLength.className = oSettings.oClasses.sLength;
2771
+ nLength.innerHTML = '<label>'+oSettings.oLanguage.sLengthMenu.replace( '_MENU_', sStdMenu )+'</label>';
2772
+
2773
+ /*
2774
+ * Set the length to the current display length - thanks to Andrea Pavlovic for this fix,
2775
+ * and Stefan Skopnik for fixing the fix!
2776
+ */
2777
+ $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true);
2778
+
2779
+ $('select', nLength).bind( 'change.DT', function(e) {
2780
+ var iVal = $(this).val();
2781
+
2782
+ /* Update all other length options for the new display */
2783
+ var n = oSettings.aanFeatures.l;
2784
+ for ( i=0, iLen=n.length ; i<iLen ; i++ )
2785
+ {
2786
+ if ( n[i] != this.parentNode )
2787
+ {
2788
+ $('select', n[i]).val( iVal );
2789
+ }
2790
+ }
2791
+
2792
+ /* Redraw the table */
2793
+ oSettings._iDisplayLength = parseInt(iVal, 10);
2794
+ _fnCalculateEnd( oSettings );
2795
+
2796
+ /* If we have space to show extra rows (backing up from the end point - then do so */
2797
+ if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() )
2798
+ {
2799
+ oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength;
2800
+ if ( oSettings._iDisplayStart < 0 )
2801
+ {
2802
+ oSettings._iDisplayStart = 0;
2803
+ }
2804
+ }
2805
+
2806
+ if ( oSettings._iDisplayLength == -1 )
2807
+ {
2808
+ oSettings._iDisplayStart = 0;
2809
+ }
2810
+
2811
+ _fnDraw( oSettings );
2812
+ } );
2813
+
2814
+
2815
+ $('select', nLength).attr('aria-controls', oSettings.sTableId);
2816
+
2817
+ return nLength;
2818
+ }
2819
+
2820
+
2821
+ /**
2822
+ * Recalculate the end point based on the start point
2823
+ * @param {object} oSettings dataTables settings object
2824
+ * @memberof DataTable#oApi
2825
+ */
2826
+ function _fnCalculateEnd( oSettings )
2827
+ {
2828
+ if ( oSettings.oFeatures.bPaginate === false )
2829
+ {
2830
+ oSettings._iDisplayEnd = oSettings.aiDisplay.length;
2831
+ }
2832
+ else
2833
+ {
2834
+ /* Set the end point of the display - based on how many elements there are
2835
+ * still to display
2836
+ */
2837
+ if ( oSettings._iDisplayStart + oSettings._iDisplayLength > oSettings.aiDisplay.length ||
2838
+ oSettings._iDisplayLength == -1 )
2839
+ {
2840
+ oSettings._iDisplayEnd = oSettings.aiDisplay.length;
2841
+ }
2842
+ else
2843
+ {
2844
+ oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength;
2845
+ }
2846
+ }
2847
+ }
2848
+
2849
+
2850
+
2851
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2852
+ * Note that most of the paging logic is done in
2853
+ * DataTable.ext.oPagination
2854
+ */
2855
+
2856
+ /**
2857
+ * Generate the node required for default pagination
2858
+ * @param {object} oSettings dataTables settings object
2859
+ * @returns {node} Pagination feature node
2860
+ * @memberof DataTable#oApi
2861
+ */
2862
+ function _fnFeatureHtmlPaginate ( oSettings )
2863
+ {
2864
+ if ( oSettings.oScroll.bInfinite )
2865
+ {
2866
+ return null;
2867
+ }
2868
+
2869
+ var nPaginate = document.createElement( 'div' );
2870
+ nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType;
2871
+
2872
+ DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate,
2873
+ function( oSettings ) {
2874
+ _fnCalculateEnd( oSettings );
2875
+ _fnDraw( oSettings );
2876
+ }
2877
+ );
2878
+
2879
+ /* Add a draw callback for the pagination on first instance, to update the paging display */
2880
+ if ( !oSettings.aanFeatures.p )
2881
+ {
2882
+ oSettings.aoDrawCallback.push( {
2883
+ "fn": function( oSettings ) {
2884
+ DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) {
2885
+ _fnCalculateEnd( oSettings );
2886
+ _fnDraw( oSettings );
2887
+ } );
2888
+ },
2889
+ "sName": "pagination"
2890
+ } );
2891
+ }
2892
+ return nPaginate;
2893
+ }
2894
+
2895
+
2896
+ /**
2897
+ * Alter the display settings to change the page
2898
+ * @param {object} oSettings dataTables settings object
2899
+ * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
2900
+ * or page number to jump to (integer)
2901
+ * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1
2902
+ * @memberof DataTable#oApi
2903
+ */
2904
+ function _fnPageChange ( oSettings, mAction )
2905
+ {
2906
+ var iOldStart = oSettings._iDisplayStart;
2907
+
2908
+ if ( typeof mAction === "number" )
2909
+ {
2910
+ oSettings._iDisplayStart = mAction * oSettings._iDisplayLength;
2911
+ if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() )
2912
+ {
2913
+ oSettings._iDisplayStart = 0;
2914
+ }
2915
+ }
2916
+ else if ( mAction == "first" )
2917
+ {
2918
+ oSettings._iDisplayStart = 0;
2919
+ }
2920
+ else if ( mAction == "previous" )
2921
+ {
2922
+ oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ?
2923
+ oSettings._iDisplayStart - oSettings._iDisplayLength :
2924
+ 0;
2925
+
2926
+ /* Correct for under-run */
2927
+ if ( oSettings._iDisplayStart < 0 )
2928
+ {
2929
+ oSettings._iDisplayStart = 0;
2930
+ }
2931
+ }
2932
+ else if ( mAction == "next" )
2933
+ {
2934
+ if ( oSettings._iDisplayLength >= 0 )
2935
+ {
2936
+ /* Make sure we are not over running the display array */
2937
+ if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() )
2938
+ {
2939
+ oSettings._iDisplayStart += oSettings._iDisplayLength;
2940
+ }
2941
+ }
2942
+ else
2943
+ {
2944
+ oSettings._iDisplayStart = 0;
2945
+ }
2946
+ }
2947
+ else if ( mAction == "last" )
2948
+ {
2949
+ if ( oSettings._iDisplayLength >= 0 )
2950
+ {
2951
+ var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1;
2952
+ oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength;
2953
+ }
2954
+ else
2955
+ {
2956
+ oSettings._iDisplayStart = 0;
2957
+ }
2958
+ }
2959
+ else
2960
+ {
2961
+ _fnLog( oSettings, 0, "Unknown paging action: "+mAction );
2962
+ }
2963
+ $(oSettings.oInstance).trigger('page', oSettings);
2964
+
2965
+ return iOldStart != oSettings._iDisplayStart;
2966
+ }
2967
+
2968
+
2969
+
2970
+ /**
2971
+ * Generate the node required for the processing node
2972
+ * @param {object} oSettings dataTables settings object
2973
+ * @returns {node} Processing element
2974
+ * @memberof DataTable#oApi
2975
+ */
2976
+ function _fnFeatureHtmlProcessing ( oSettings )
2977
+ {
2978
+ var nProcessing = document.createElement( 'div' );
2979
+
2980
+ if ( !oSettings.aanFeatures.r )
2981
+ {
2982
+ nProcessing.id = oSettings.sTableId+'_processing';
2983
+ }
2984
+ nProcessing.innerHTML = oSettings.oLanguage.sProcessing;
2985
+ nProcessing.className = oSettings.oClasses.sProcessing;
2986
+ oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable );
2987
+
2988
+ return nProcessing;
2989
+ }
2990
+
2991
+
2992
+ /**
2993
+ * Display or hide the processing indicator
2994
+ * @param {object} oSettings dataTables settings object
2995
+ * @param {bool} bShow Show the processing indicator (true) or not (false)
2996
+ * @memberof DataTable#oApi
2997
+ */
2998
+ function _fnProcessingDisplay ( oSettings, bShow )
2999
+ {
3000
+ if ( oSettings.oFeatures.bProcessing )
3001
+ {
3002
+ var an = oSettings.aanFeatures.r;
3003
+ for ( var i=0, iLen=an.length ; i<iLen ; i++ )
3004
+ {
3005
+ an[i].style.visibility = bShow ? "visible" : "hidden";
3006
+ }
3007
+ }
3008
+
3009
+ $(oSettings.oInstance).trigger('processing', [oSettings, bShow]);
3010
+ }
3011
+
3012
+ /**
3013
+ * Add any control elements for the table - specifically scrolling
3014
+ * @param {object} oSettings dataTables settings object
3015
+ * @returns {node} Node to add to the DOM
3016
+ * @memberof DataTable#oApi
3017
+ */
3018
+ function _fnFeatureHtmlTable ( oSettings )
3019
+ {
3020
+ /* Check if scrolling is enabled or not - if not then leave the DOM unaltered */
3021
+ if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY === "" )
3022
+ {
3023
+ return oSettings.nTable;
3024
+ }
3025
+
3026
+ /*
3027
+ * The HTML structure that we want to generate in this function is:
3028
+ * div - nScroller
3029
+ * div - nScrollHead
3030
+ * div - nScrollHeadInner
3031
+ * table - nScrollHeadTable
3032
+ * thead - nThead
3033
+ * div - nScrollBody
3034
+ * table - oSettings.nTable
3035
+ * thead - nTheadSize
3036
+ * tbody - nTbody
3037
+ * div - nScrollFoot
3038
+ * div - nScrollFootInner
3039
+ * table - nScrollFootTable
3040
+ * tfoot - nTfoot
3041
+ */
3042
+ var
3043
+ nScroller = document.createElement('div'),
3044
+ nScrollHead = document.createElement('div'),
3045
+ nScrollHeadInner = document.createElement('div'),
3046
+ nScrollBody = document.createElement('div'),
3047
+ nScrollFoot = document.createElement('div'),
3048
+ nScrollFootInner = document.createElement('div'),
3049
+ nScrollHeadTable = oSettings.nTable.cloneNode(false),
3050
+ nScrollFootTable = oSettings.nTable.cloneNode(false),
3051
+ nThead = oSettings.nTable.getElementsByTagName('thead')[0],
3052
+ nTfoot = oSettings.nTable.getElementsByTagName('tfoot').length === 0 ? null :
3053
+ oSettings.nTable.getElementsByTagName('tfoot')[0],
3054
+ oClasses = oSettings.oClasses;
3055
+
3056
+ nScrollHead.appendChild( nScrollHeadInner );
3057
+ nScrollFoot.appendChild( nScrollFootInner );
3058
+ nScrollBody.appendChild( oSettings.nTable );
3059
+ nScroller.appendChild( nScrollHead );
3060
+ nScroller.appendChild( nScrollBody );
3061
+ nScrollHeadInner.appendChild( nScrollHeadTable );
3062
+ nScrollHeadTable.appendChild( nThead );
3063
+ if ( nTfoot !== null )
3064
+ {
3065
+ nScroller.appendChild( nScrollFoot );
3066
+ nScrollFootInner.appendChild( nScrollFootTable );
3067
+ nScrollFootTable.appendChild( nTfoot );
3068
+ }
3069
+
3070
+ nScroller.className = oClasses.sScrollWrapper;
3071
+ nScrollHead.className = oClasses.sScrollHead;
3072
+ nScrollHeadInner.className = oClasses.sScrollHeadInner;
3073
+ nScrollBody.className = oClasses.sScrollBody;
3074
+ nScrollFoot.className = oClasses.sScrollFoot;
3075
+ nScrollFootInner.className = oClasses.sScrollFootInner;
3076
+
3077
+ if ( oSettings.oScroll.bAutoCss )
3078
+ {
3079
+ nScrollHead.style.overflow = "hidden";
3080
+ nScrollHead.style.position = "relative";
3081
+ nScrollFoot.style.overflow = "hidden";
3082
+ nScrollBody.style.overflow = "auto";
3083
+ }
3084
+
3085
+ nScrollHead.style.border = "0";
3086
+ nScrollHead.style.width = "100%";
3087
+ nScrollFoot.style.border = "0";
3088
+ nScrollHeadInner.style.width = oSettings.oScroll.sXInner !== "" ?
3089
+ oSettings.oScroll.sXInner : "100%"; /* will be overwritten */
3090
+
3091
+ /* Modify attributes to respect the clones */
3092
+ nScrollHeadTable.removeAttribute('id');
3093
+ nScrollHeadTable.style.marginLeft = "0";
3094
+ oSettings.nTable.style.marginLeft = "0";
3095
+ if ( nTfoot !== null )
3096
+ {
3097
+ nScrollFootTable.removeAttribute('id');
3098
+ nScrollFootTable.style.marginLeft = "0";
3099
+ }
3100
+
3101
+ /* Move caption elements from the body to the header, footer or leave where it is
3102
+ * depending on the configuration. Note that the DTD says there can be only one caption */
3103
+ var nCaption = $(oSettings.nTable).children('caption');
3104
+ if ( nCaption.length > 0 )
3105
+ {
3106
+ nCaption = nCaption[0];
3107
+ if ( nCaption._captionSide === "top" )
3108
+ {
3109
+ nScrollHeadTable.appendChild( nCaption );
3110
+ }
3111
+ else if ( nCaption._captionSide === "bottom" && nTfoot )
3112
+ {
3113
+ nScrollFootTable.appendChild( nCaption );
3114
+ }
3115
+ }
3116
+
3117
+ /*
3118
+ * Sizing
3119
+ */
3120
+ /* When x-scrolling add the width and a scroller to move the header with the body */
3121
+ if ( oSettings.oScroll.sX !== "" )
3122
+ {
3123
+ nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX );
3124
+ nScrollBody.style.width = _fnStringToCss( oSettings.oScroll.sX );
3125
+
3126
+ if ( nTfoot !== null )
3127
+ {
3128
+ nScrollFoot.style.width = _fnStringToCss( oSettings.oScroll.sX );
3129
+ }
3130
+
3131
+ /* When the body is scrolled, then we also want to scroll the headers */
3132
+ $(nScrollBody).scroll( function (e) {
3133
+ nScrollHead.scrollLeft = this.scrollLeft;
3134
+
3135
+ if ( nTfoot !== null )
3136
+ {
3137
+ nScrollFoot.scrollLeft = this.scrollLeft;
3138
+ }
3139
+ } );
3140
+ }
3141
+
3142
+ /* When yscrolling, add the height */
3143
+ if ( oSettings.oScroll.sY !== "" )
3144
+ {
3145
+ nScrollBody.style.height = _fnStringToCss( oSettings.oScroll.sY );
3146
+ }
3147
+
3148
+ /* Redraw - align columns across the tables */
3149
+ oSettings.aoDrawCallback.push( {
3150
+ "fn": _fnScrollDraw,
3151
+ "sName": "scrolling"
3152
+ } );
3153
+
3154
+ /* Infinite scrolling event handlers */
3155
+ if ( oSettings.oScroll.bInfinite )
3156
+ {
3157
+ $(nScrollBody).scroll( function() {
3158
+ /* Use a blocker to stop scrolling from loading more data while other data is still loading */
3159
+ if ( !oSettings.bDrawing && $(this).scrollTop() !== 0 )
3160
+ {
3161
+ /* Check if we should load the next data set */
3162
+ if ( $(this).scrollTop() + $(this).height() >
3163
+ $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap )
3164
+ {
3165
+ /* Only do the redraw if we have to - we might be at the end of the data */
3166
+ if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() )
3167
+ {
3168
+ _fnPageChange( oSettings, 'next' );
3169
+ _fnCalculateEnd( oSettings );
3170
+ _fnDraw( oSettings );
3171
+ }
3172
+ }
3173
+ }
3174
+ } );
3175
+ }
3176
+
3177
+ oSettings.nScrollHead = nScrollHead;
3178
+ oSettings.nScrollFoot = nScrollFoot;
3179
+
3180
+ return nScroller;
3181
+ }
3182
+
3183
+
3184
+ /**
3185
+ * Update the various tables for resizing. It's a bit of a pig this function, but
3186
+ * basically the idea to:
3187
+ * 1. Re-create the table inside the scrolling div
3188
+ * 2. Take live measurements from the DOM
3189
+ * 3. Apply the measurements
3190
+ * 4. Clean up
3191
+ * @param {object} o dataTables settings object
3192
+ * @returns {node} Node to add to the DOM
3193
+ * @memberof DataTable#oApi
3194
+ */
3195
+ function _fnScrollDraw ( o )
3196
+ {
3197
+ var
3198
+ nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0],
3199
+ nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0],
3200
+ nScrollBody = o.nTable.parentNode,
3201
+ i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis,
3202
+ nTheadSize, nTfootSize,
3203
+ iWidth, aApplied=[], aAppliedFooter=[], iSanityWidth,
3204
+ nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null,
3205
+ nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null,
3206
+ ie67 = o.oBrowser.bScrollOversize,
3207
+ zeroOut = function(nSizer) {
3208
+ oStyle = nSizer.style;
3209
+ oStyle.paddingTop = "0";
3210
+ oStyle.paddingBottom = "0";
3211
+ oStyle.borderTopWidth = "0";
3212
+ oStyle.borderBottomWidth = "0";
3213
+ oStyle.height = 0;
3214
+ };
3215
+
3216
+ /*
3217
+ * 1. Re-create the table inside the scrolling div
3218
+ */
3219
+
3220
+ /* Remove the old minimised thead and tfoot elements in the inner table */
3221
+ $(o.nTable).children('thead, tfoot').remove();
3222
+
3223
+ /* Clone the current header and footer elements and then place it into the inner table */
3224
+ nTheadSize = $(o.nTHead).clone()[0];
3225
+ o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] );
3226
+ anHeadToSize = o.nTHead.getElementsByTagName('tr');
3227
+ anHeadSizers = nTheadSize.getElementsByTagName('tr');
3228
+
3229
+ if ( o.nTFoot !== null )
3230
+ {
3231
+ nTfootSize = $(o.nTFoot).clone()[0];
3232
+ o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] );
3233
+ anFootToSize = o.nTFoot.getElementsByTagName('tr');
3234
+ anFootSizers = nTfootSize.getElementsByTagName('tr');
3235
+ }
3236
+
3237
+ /*
3238
+ * 2. Take live measurements from the DOM - do not alter the DOM itself!
3239
+ */
3240
+
3241
+ /* Remove old sizing and apply the calculated column widths
3242
+ * Get the unique column headers in the newly created (cloned) header. We want to apply the
3243
+ * calculated sizes to this header
3244
+ */
3245
+ if ( o.oScroll.sX === "" )
3246
+ {
3247
+ nScrollBody.style.width = '100%';
3248
+ nScrollHeadInner.parentNode.style.width = '100%';
3249
+ }
3250
+
3251
+ var nThs = _fnGetUniqueThs( o, nTheadSize );
3252
+ for ( i=0, iLen=nThs.length ; i<iLen ; i++ )
3253
+ {
3254
+ iVis = _fnVisibleToColumnIndex( o, i );
3255
+ nThs[i].style.width = o.aoColumns[iVis].sWidth;
3256
+ }
3257
+
3258
+ if ( o.nTFoot !== null )
3259
+ {
3260
+ _fnApplyToChildren( function(n) {
3261
+ n.style.width = "";
3262
+ }, anFootSizers );
3263
+ }
3264
+
3265
+ // If scroll collapse is enabled, when we put the headers back into the body for sizing, we
3266
+ // will end up forcing the scrollbar to appear, making our measurements wrong for when we
3267
+ // then hide it (end of this function), so add the header height to the body scroller.
3268
+ if ( o.oScroll.bCollapse && o.oScroll.sY !== "" )
3269
+ {
3270
+ nScrollBody.style.height = (nScrollBody.offsetHeight + o.nTHead.offsetHeight)+"px";
3271
+ }
3272
+
3273
+ /* Size the table as a whole */
3274
+ iSanityWidth = $(o.nTable).outerWidth();
3275
+ if ( o.oScroll.sX === "" )
3276
+ {
3277
+ /* No x scrolling */
3278
+ o.nTable.style.width = "100%";
3279
+
3280
+ /* I know this is rubbish - but IE7 will make the width of the table when 100% include
3281
+ * the scrollbar - which is shouldn't. When there is a scrollbar we need to take this
3282
+ * into account.
3283
+ */
3284
+ if ( ie67 && ($('tbody', nScrollBody).height() > nScrollBody.offsetHeight ||
3285
+ $(nScrollBody).css('overflow-y') == "scroll") )
3286
+ {
3287
+ o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth() - o.oScroll.iBarWidth);
3288
+ }
3289
+ }
3290
+ else
3291
+ {
3292
+ if ( o.oScroll.sXInner !== "" )
3293
+ {
3294
+ /* x scroll inner has been given - use it */
3295
+ o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner);
3296
+ }
3297
+ else if ( iSanityWidth == $(nScrollBody).width() &&
3298
+ $(nScrollBody).height() < $(o.nTable).height() )
3299
+ {
3300
+ /* There is y-scrolling - try to take account of the y scroll bar */
3301
+ o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth );
3302
+ if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth )
3303
+ {
3304
+ /* Not possible to take account of it */
3305
+ o.nTable.style.width = _fnStringToCss( iSanityWidth );
3306
+ }
3307
+ }
3308
+ else
3309
+ {
3310
+ /* All else fails */
3311
+ o.nTable.style.width = _fnStringToCss( iSanityWidth );
3312
+ }
3313
+ }
3314
+
3315
+ /* Recalculate the sanity width - now that we've applied the required width, before it was
3316
+ * a temporary variable. This is required because the column width calculation is done
3317
+ * before this table DOM is created.
3318
+ */
3319
+ iSanityWidth = $(o.nTable).outerWidth();
3320
+
3321
+ /* We want the hidden header to have zero height, so remove padding and borders. Then
3322
+ * set the width based on the real headers
3323
+ */
3324
+
3325
+ // Apply all styles in one pass. Invalidates layout only once because we don't read any
3326
+ // DOM properties.
3327
+ _fnApplyToChildren( zeroOut, anHeadSizers );
3328
+
3329
+ // Read all widths in next pass. Forces layout only once because we do not change
3330
+ // any DOM properties.
3331
+ _fnApplyToChildren( function(nSizer) {
3332
+ aApplied.push( _fnStringToCss( $(nSizer).width() ) );
3333
+ }, anHeadSizers );
3334
+
3335
+ // Apply all widths in final pass. Invalidates layout only once because we do not
3336
+ // read any DOM properties.
3337
+ _fnApplyToChildren( function(nToSize, i) {
3338
+ nToSize.style.width = aApplied[i];
3339
+ }, anHeadToSize );
3340
+
3341
+ $(anHeadSizers).height(0);
3342
+
3343
+ /* Same again with the footer if we have one */
3344
+ if ( o.nTFoot !== null )
3345
+ {
3346
+ _fnApplyToChildren( zeroOut, anFootSizers );
3347
+
3348
+ _fnApplyToChildren( function(nSizer) {
3349
+ aAppliedFooter.push( _fnStringToCss( $(nSizer).width() ) );
3350
+ }, anFootSizers );
3351
+
3352
+ _fnApplyToChildren( function(nToSize, i) {
3353
+ nToSize.style.width = aAppliedFooter[i];
3354
+ }, anFootToSize );
3355
+
3356
+ $(anFootSizers).height(0);
3357
+ }
3358
+
3359
+ /*
3360
+ * 3. Apply the measurements
3361
+ */
3362
+
3363
+ /* "Hide" the header and footer that we used for the sizing. We want to also fix their width
3364
+ * to what they currently are
3365
+ */
3366
+ _fnApplyToChildren( function(nSizer, i) {
3367
+ nSizer.innerHTML = "";
3368
+ nSizer.style.width = aApplied[i];
3369
+ }, anHeadSizers );
3370
+
3371
+ if ( o.nTFoot !== null )
3372
+ {
3373
+ _fnApplyToChildren( function(nSizer, i) {
3374
+ nSizer.innerHTML = "";
3375
+ nSizer.style.width = aAppliedFooter[i];
3376
+ }, anFootSizers );
3377
+ }
3378
+
3379
+ /* Sanity check that the table is of a sensible width. If not then we are going to get
3380
+ * misalignment - try to prevent this by not allowing the table to shrink below its min width
3381
+ */
3382
+ if ( $(o.nTable).outerWidth() < iSanityWidth )
3383
+ {
3384
+ /* The min width depends upon if we have a vertical scrollbar visible or not */
3385
+ var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight ||
3386
+ $(nScrollBody).css('overflow-y') == "scroll")) ?
3387
+ iSanityWidth+o.oScroll.iBarWidth : iSanityWidth;
3388
+
3389
+ /* IE6/7 are a law unto themselves... */
3390
+ if ( ie67 && (nScrollBody.scrollHeight >
3391
+ nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") )
3392
+ {
3393
+ o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth );
3394
+ }
3395
+
3396
+ /* Apply the calculated minimum width to the table wrappers */
3397
+ nScrollBody.style.width = _fnStringToCss( iCorrection );
3398
+ o.nScrollHead.style.width = _fnStringToCss( iCorrection );
3399
+
3400
+ if ( o.nTFoot !== null )
3401
+ {
3402
+ o.nScrollFoot.style.width = _fnStringToCss( iCorrection );
3403
+ }
3404
+
3405
+ /* And give the user a warning that we've stopped the table getting too small */
3406
+ if ( o.oScroll.sX === "" )
3407
+ {
3408
+ _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+
3409
+ " misalignment. The table has been drawn at its minimum possible width." );
3410
+ }
3411
+ else if ( o.oScroll.sXInner !== "" )
3412
+ {
3413
+ _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+
3414
+ " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+
3415
+ " calculation" );
3416
+ }
3417
+ }
3418
+ else
3419
+ {
3420
+ nScrollBody.style.width = _fnStringToCss( '100%' );
3421
+ o.nScrollHead.style.width = _fnStringToCss( '100%' );
3422
+
3423
+ if ( o.nTFoot !== null )
3424
+ {
3425
+ o.nScrollFoot.style.width = _fnStringToCss( '100%' );
3426
+ }
3427
+ }
3428
+
3429
+
3430
+ /*
3431
+ * 4. Clean up
3432
+ */
3433
+ if ( o.oScroll.sY === "" )
3434
+ {
3435
+ /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
3436
+ * the scrollbar height from the visible display, rather than adding it on. We need to
3437
+ * set the height in order to sort this. Don't want to do it in any other browsers.
3438
+ */
3439
+ if ( ie67 )
3440
+ {
3441
+ nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth );
3442
+ }
3443
+ }
3444
+
3445
+ if ( o.oScroll.sY !== "" && o.oScroll.bCollapse )
3446
+ {
3447
+ nScrollBody.style.height = _fnStringToCss( o.oScroll.sY );
3448
+
3449
+ var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ?
3450
+ o.oScroll.iBarWidth : 0;
3451
+ if ( o.nTable.offsetHeight < nScrollBody.offsetHeight )
3452
+ {
3453
+ nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra );
3454
+ }
3455
+ }
3456
+
3457
+ /* Finally set the width's of the header and footer tables */
3458
+ var iOuterWidth = $(o.nTable).outerWidth();
3459
+ nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth );
3460
+ nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth );
3461
+
3462
+ // Figure out if there are scrollbar present - if so then we need a the header and footer to
3463
+ // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
3464
+ var bScrolling = $(o.nTable).height() > nScrollBody.clientHeight || $(nScrollBody).css('overflow-y') == "scroll";
3465
+ nScrollHeadInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px";
3466
+
3467
+ if ( o.nTFoot !== null )
3468
+ {
3469
+ nScrollFootTable.style.width = _fnStringToCss( iOuterWidth );
3470
+ nScrollFootInner.style.width = _fnStringToCss( iOuterWidth );
3471
+ nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px";
3472
+ }
3473
+
3474
+ /* Adjust the position of the header in case we loose the y-scrollbar */
3475
+ $(nScrollBody).scroll();
3476
+
3477
+ /* If sorting or filtering has occurred, jump the scrolling back to the top */
3478
+ if ( o.bSorted || o.bFiltered )
3479
+ {
3480
+ nScrollBody.scrollTop = 0;
3481
+ }
3482
+ }
3483
+
3484
+
3485
+ /**
3486
+ * Apply a given function to the display child nodes of an element array (typically
3487
+ * TD children of TR rows
3488
+ * @param {function} fn Method to apply to the objects
3489
+ * @param array {nodes} an1 List of elements to look through for display children
3490
+ * @param array {nodes} an2 Another list (identical structure to the first) - optional
3491
+ * @memberof DataTable#oApi
3492
+ */
3493
+ function _fnApplyToChildren( fn, an1, an2 )
3494
+ {
3495
+ var index=0, i=0, iLen=an1.length;
3496
+ var nNode1, nNode2;
3497
+
3498
+ while ( i < iLen )
3499
+ {
3500
+ nNode1 = an1[i].firstChild;
3501
+ nNode2 = an2 ? an2[i].firstChild : null;
3502
+ while ( nNode1 )
3503
+ {
3504
+ if ( nNode1.nodeType === 1 )
3505
+ {
3506
+ if ( an2 )
3507
+ {
3508
+ fn( nNode1, nNode2, index );
3509
+ }
3510
+ else
3511
+ {
3512
+ fn( nNode1, index );
3513
+ }
3514
+ index++;
3515
+ }
3516
+ nNode1 = nNode1.nextSibling;
3517
+ nNode2 = an2 ? nNode2.nextSibling : null;
3518
+ }
3519
+ i++;
3520
+ }
3521
+ }
3522
+
3523
+ /**
3524
+ * Convert a CSS unit width to pixels (e.g. 2em)
3525
+ * @param {string} sWidth width to be converted
3526
+ * @param {node} nParent parent to get the with for (required for relative widths) - optional
3527
+ * @returns {int} iWidth width in pixels
3528
+ * @memberof DataTable#oApi
3529
+ */
3530
+ function _fnConvertToWidth ( sWidth, nParent )
3531
+ {
3532
+ if ( !sWidth || sWidth === null || sWidth === '' )
3533
+ {
3534
+ return 0;
3535
+ }
3536
+
3537
+ if ( !nParent )
3538
+ {
3539
+ nParent = document.body;
3540
+ }
3541
+
3542
+ var iWidth;
3543
+ var nTmp = document.createElement( "div" );
3544
+ nTmp.style.width = _fnStringToCss( sWidth );
3545
+
3546
+ nParent.appendChild( nTmp );
3547
+ iWidth = nTmp.offsetWidth;
3548
+ nParent.removeChild( nTmp );
3549
+
3550
+ return ( iWidth );
3551
+ }
3552
+
3553
+
3554
+ /**
3555
+ * Calculate the width of columns for the table
3556
+ * @param {object} oSettings dataTables settings object
3557
+ * @memberof DataTable#oApi
3558
+ */
3559
+ function _fnCalculateColumnWidths ( oSettings )
3560
+ {
3561
+ var iTableWidth = oSettings.nTable.offsetWidth;
3562
+ var iUserInputs = 0;
3563
+ var iTmpWidth;
3564
+ var iVisibleColumns = 0;
3565
+ var iColums = oSettings.aoColumns.length;
3566
+ var i, iIndex, iCorrector, iWidth;
3567
+ var oHeaders = $('th', oSettings.nTHead);
3568
+ var widthAttr = oSettings.nTable.getAttribute('width');
3569
+ var nWrapper = oSettings.nTable.parentNode;
3570
+
3571
+ /* Convert any user input sizes into pixel sizes */
3572
+ for ( i=0 ; i<iColums ; i++ )
3573
+ {
3574
+ if ( oSettings.aoColumns[i].bVisible )
3575
+ {
3576
+ iVisibleColumns++;
3577
+
3578
+ if ( oSettings.aoColumns[i].sWidth !== null )
3579
+ {
3580
+ iTmpWidth = _fnConvertToWidth( oSettings.aoColumns[i].sWidthOrig,
3581
+ nWrapper );
3582
+ if ( iTmpWidth !== null )
3583
+ {
3584
+ oSettings.aoColumns[i].sWidth = _fnStringToCss( iTmpWidth );
3585
+ }
3586
+
3587
+ iUserInputs++;
3588
+ }
3589
+ }
3590
+ }
3591
+
3592
+ /* If the number of columns in the DOM equals the number that we have to process in
3593
+ * DataTables, then we can use the offsets that are created by the web-browser. No custom
3594
+ * sizes can be set in order for this to happen, nor scrolling used
3595
+ */
3596
+ if ( iColums == oHeaders.length && iUserInputs === 0 && iVisibleColumns == iColums &&
3597
+ oSettings.oScroll.sX === "" && oSettings.oScroll.sY === "" )
3598
+ {
3599
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
3600
+ {
3601
+ iTmpWidth = $(oHeaders[i]).width();
3602
+ if ( iTmpWidth !== null )
3603
+ {
3604
+ oSettings.aoColumns[i].sWidth = _fnStringToCss( iTmpWidth );
3605
+ }
3606
+ }
3607
+ }
3608
+ else
3609
+ {
3610
+ /* Otherwise we are going to have to do some calculations to get the width of each column.
3611
+ * Construct a 1 row table with the widest node in the data, and any user defined widths,
3612
+ * then insert it into the DOM and allow the browser to do all the hard work of
3613
+ * calculating table widths.
3614
+ */
3615
+ var
3616
+ nCalcTmp = oSettings.nTable.cloneNode( false ),
3617
+ nTheadClone = oSettings.nTHead.cloneNode(true),
3618
+ nBody = document.createElement( 'tbody' ),
3619
+ nTr = document.createElement( 'tr' ),
3620
+ nDivSizing;
3621
+
3622
+ nCalcTmp.removeAttribute( "id" );
3623
+ nCalcTmp.appendChild( nTheadClone );
3624
+ if ( oSettings.nTFoot !== null )
3625
+ {
3626
+ nCalcTmp.appendChild( oSettings.nTFoot.cloneNode(true) );
3627
+ _fnApplyToChildren( function(n) {
3628
+ n.style.width = "";
3629
+ }, nCalcTmp.getElementsByTagName('tr') );
3630
+ }
3631
+
3632
+ nCalcTmp.appendChild( nBody );
3633
+ nBody.appendChild( nTr );
3634
+
3635
+ /* Remove any sizing that was previously applied by the styles */
3636
+ var jqColSizing = $('thead th', nCalcTmp);
3637
+ if ( jqColSizing.length === 0 )
3638
+ {
3639
+ jqColSizing = $('tbody tr:eq(0)>td', nCalcTmp);
3640
+ }
3641
+
3642
+ /* Apply custom sizing to the cloned header */
3643
+ var nThs = _fnGetUniqueThs( oSettings, nTheadClone );
3644
+ iCorrector = 0;
3645
+ for ( i=0 ; i<iColums ; i++ )
3646
+ {
3647
+ var oColumn = oSettings.aoColumns[i];
3648
+ if ( oColumn.bVisible && oColumn.sWidthOrig !== null && oColumn.sWidthOrig !== "" )
3649
+ {
3650
+ nThs[i-iCorrector].style.width = _fnStringToCss( oColumn.sWidthOrig );
3651
+ }
3652
+ else if ( oColumn.bVisible )
3653
+ {
3654
+ nThs[i-iCorrector].style.width = "";
3655
+ }
3656
+ else
3657
+ {
3658
+ iCorrector++;
3659
+ }
3660
+ }
3661
+
3662
+ /* Find the biggest td for each column and put it into the table */
3663
+ for ( i=0 ; i<iColums ; i++ )
3664
+ {
3665
+ if ( oSettings.aoColumns[i].bVisible )
3666
+ {
3667
+ var nTd = _fnGetWidestNode( oSettings, i );
3668
+ if ( nTd !== null )
3669
+ {
3670
+ nTd = nTd.cloneNode(true);
3671
+ if ( oSettings.aoColumns[i].sContentPadding !== "" )
3672
+ {
3673
+ nTd.innerHTML += oSettings.aoColumns[i].sContentPadding;
3674
+ }
3675
+ nTr.appendChild( nTd );
3676
+ }
3677
+ }
3678
+ }
3679
+
3680
+ /* Build the table and 'display' it */
3681
+ nWrapper.appendChild( nCalcTmp );
3682
+
3683
+ /* When scrolling (X or Y) we want to set the width of the table as appropriate. However,
3684
+ * when not scrolling leave the table width as it is. This results in slightly different,
3685
+ * but I think correct behaviour
3686
+ */
3687
+ if ( oSettings.oScroll.sX !== "" && oSettings.oScroll.sXInner !== "" )
3688
+ {
3689
+ nCalcTmp.style.width = _fnStringToCss(oSettings.oScroll.sXInner);
3690
+ }
3691
+ else if ( oSettings.oScroll.sX !== "" )
3692
+ {
3693
+ nCalcTmp.style.width = "";
3694
+ if ( $(nCalcTmp).width() < nWrapper.offsetWidth )
3695
+ {
3696
+ nCalcTmp.style.width = _fnStringToCss( nWrapper.offsetWidth );
3697
+ }
3698
+ }
3699
+ else if ( oSettings.oScroll.sY !== "" )
3700
+ {
3701
+ nCalcTmp.style.width = _fnStringToCss( nWrapper.offsetWidth );
3702
+ }
3703
+ else if ( widthAttr )
3704
+ {
3705
+ nCalcTmp.style.width = _fnStringToCss( widthAttr );
3706
+ }
3707
+ nCalcTmp.style.visibility = "hidden";
3708
+
3709
+ /* Scrolling considerations */
3710
+ _fnScrollingWidthAdjust( oSettings, nCalcTmp );
3711
+
3712
+ /* Read the width's calculated by the browser and store them for use by the caller. We
3713
+ * first of all try to use the elements in the body, but it is possible that there are
3714
+ * no elements there, under which circumstances we use the header elements
3715
+ */
3716
+ var oNodes = $("tbody tr:eq(0)", nCalcTmp).children();
3717
+ if ( oNodes.length === 0 )
3718
+ {
3719
+ oNodes = _fnGetUniqueThs( oSettings, $('thead', nCalcTmp)[0] );
3720
+ }
3721
+
3722
+ /* Browsers need a bit of a hand when a width is assigned to any columns when
3723
+ * x-scrolling as they tend to collapse the table to the min-width, even if
3724
+ * we sent the column widths. So we need to keep track of what the table width
3725
+ * should be by summing the user given values, and the automatic values
3726
+ */
3727
+ if ( oSettings.oScroll.sX !== "" )
3728
+ {
3729
+ var iTotal = 0;
3730
+ iCorrector = 0;
3731
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
3732
+ {
3733
+ if ( oSettings.aoColumns[i].bVisible )
3734
+ {
3735
+ if ( oSettings.aoColumns[i].sWidthOrig === null )
3736
+ {
3737
+ iTotal += $(oNodes[iCorrector]).outerWidth();
3738
+ }
3739
+ else
3740
+ {
3741
+ iTotal += parseInt(oSettings.aoColumns[i].sWidth.replace('px',''), 10) +
3742
+ ($(oNodes[iCorrector]).outerWidth() - $(oNodes[iCorrector]).width());
3743
+ }
3744
+ iCorrector++;
3745
+ }
3746
+ }
3747
+
3748
+ nCalcTmp.style.width = _fnStringToCss( iTotal );
3749
+ oSettings.nTable.style.width = _fnStringToCss( iTotal );
3750
+ }
3751
+
3752
+ iCorrector = 0;
3753
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
3754
+ {
3755
+ if ( oSettings.aoColumns[i].bVisible )
3756
+ {
3757
+ iWidth = $(oNodes[iCorrector]).width();
3758
+ if ( iWidth !== null && iWidth > 0 )
3759
+ {
3760
+ oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth );
3761
+ }
3762
+ iCorrector++;
3763
+ }
3764
+ }
3765
+
3766
+ var cssWidth = $(nCalcTmp).css('width');
3767
+ oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ?
3768
+ cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() );
3769
+ nCalcTmp.parentNode.removeChild( nCalcTmp );
3770
+ }
3771
+
3772
+ if ( widthAttr )
3773
+ {
3774
+ oSettings.nTable.style.width = _fnStringToCss( widthAttr );
3775
+ }
3776
+ }
3777
+
3778
+
3779
+ /**
3780
+ * Adjust a table's width to take account of scrolling
3781
+ * @param {object} oSettings dataTables settings object
3782
+ * @param {node} n table node
3783
+ * @memberof DataTable#oApi
3784
+ */
3785
+ function _fnScrollingWidthAdjust ( oSettings, n )
3786
+ {
3787
+ if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" )
3788
+ {
3789
+ /* When y-scrolling only, we want to remove the width of the scroll bar so the table
3790
+ * + scroll bar will fit into the area avaialble.
3791
+ */
3792
+ var iOrigWidth = $(n).width();
3793
+ n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth );
3794
+ }
3795
+ else if ( oSettings.oScroll.sX !== "" )
3796
+ {
3797
+ /* When x-scrolling both ways, fix the table at it's current size, without adjusting */
3798
+ n.style.width = _fnStringToCss( $(n).outerWidth() );
3799
+ }
3800
+ }
3801
+
3802
+
3803
+ /**
3804
+ * Get the widest node
3805
+ * @param {object} oSettings dataTables settings object
3806
+ * @param {int} iCol column of interest
3807
+ * @returns {node} widest table node
3808
+ * @memberof DataTable#oApi
3809
+ */
3810
+ function _fnGetWidestNode( oSettings, iCol )
3811
+ {
3812
+ var iMaxIndex = _fnGetMaxLenString( oSettings, iCol );
3813
+ if ( iMaxIndex < 0 )
3814
+ {
3815
+ return null;
3816
+ }
3817
+
3818
+ if ( oSettings.aoData[iMaxIndex].nTr === null )
3819
+ {
3820
+ var n = document.createElement('td');
3821
+ n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' );
3822
+ return n;
3823
+ }
3824
+ return _fnGetTdNodes(oSettings, iMaxIndex)[iCol];
3825
+ }
3826
+
3827
+
3828
+ /**
3829
+ * Get the maximum strlen for each data column
3830
+ * @param {object} oSettings dataTables settings object
3831
+ * @param {int} iCol column of interest
3832
+ * @returns {string} max string length for each column
3833
+ * @memberof DataTable#oApi
3834
+ */
3835
+ function _fnGetMaxLenString( oSettings, iCol )
3836
+ {
3837
+ var iMax = -1;
3838
+ var iMaxIndex = -1;
3839
+
3840
+ for ( var i=0 ; i<oSettings.aoData.length ; i++ )
3841
+ {
3842
+ var s = _fnGetCellData( oSettings, i, iCol, 'display' )+"";
3843
+ s = s.replace( /<.*?>/g, "" );
3844
+ if ( s.length > iMax )
3845
+ {
3846
+ iMax = s.length;
3847
+ iMaxIndex = i;
3848
+ }
3849
+ }
3850
+
3851
+ return iMaxIndex;
3852
+ }
3853
+
3854
+
3855
+ /**
3856
+ * Append a CSS unit (only if required) to a string
3857
+ * @param {array} aArray1 first array
3858
+ * @param {array} aArray2 second array
3859
+ * @returns {int} 0 if match, 1 if length is different, 2 if no match
3860
+ * @memberof DataTable#oApi
3861
+ */
3862
+ function _fnStringToCss( s )
3863
+ {
3864
+ if ( s === null )
3865
+ {
3866
+ return "0px";
3867
+ }
3868
+
3869
+ if ( typeof s == 'number' )
3870
+ {
3871
+ if ( s < 0 )
3872
+ {
3873
+ return "0px";
3874
+ }
3875
+ return s+"px";
3876
+ }
3877
+
3878
+ /* Check if the last character is not 0-9 */
3879
+ var c = s.charCodeAt( s.length-1 );
3880
+ if (c < 0x30 || c > 0x39)
3881
+ {
3882
+ return s;
3883
+ }
3884
+ return s+"px";
3885
+ }
3886
+
3887
+
3888
+ /**
3889
+ * Get the width of a scroll bar in this browser being used
3890
+ * @returns {int} width in pixels
3891
+ * @memberof DataTable#oApi
3892
+ */
3893
+ function _fnScrollBarWidth ()
3894
+ {
3895
+ var inner = document.createElement('p');
3896
+ var style = inner.style;
3897
+ style.width = "100%";
3898
+ style.height = "200px";
3899
+ style.padding = "0px";
3900
+
3901
+ var outer = document.createElement('div');
3902
+ style = outer.style;
3903
+ style.position = "absolute";
3904
+ style.top = "0px";
3905
+ style.left = "0px";
3906
+ style.visibility = "hidden";
3907
+ style.width = "200px";
3908
+ style.height = "150px";
3909
+ style.padding = "0px";
3910
+ style.overflow = "hidden";
3911
+ outer.appendChild(inner);
3912
+
3913
+ document.body.appendChild(outer);
3914
+ var w1 = inner.offsetWidth;
3915
+ outer.style.overflow = 'scroll';
3916
+ var w2 = inner.offsetWidth;
3917
+ if ( w1 == w2 )
3918
+ {
3919
+ w2 = outer.clientWidth;
3920
+ }
3921
+
3922
+ document.body.removeChild(outer);
3923
+ return (w1 - w2);
3924
+ }
3925
+
3926
+ /**
3927
+ * Change the order of the table
3928
+ * @param {object} oSettings dataTables settings object
3929
+ * @param {bool} bApplyClasses optional - should we apply classes or not
3930
+ * @memberof DataTable#oApi
3931
+ */
3932
+ function _fnSort ( oSettings, bApplyClasses )
3933
+ {
3934
+ var
3935
+ i, iLen, j, jLen, k, kLen,
3936
+ sDataType, nTh,
3937
+ aaSort = [],
3938
+ aiOrig = [],
3939
+ oSort = DataTable.ext.oSort,
3940
+ aoData = oSettings.aoData,
3941
+ aoColumns = oSettings.aoColumns,
3942
+ oAria = oSettings.oLanguage.oAria;
3943
+
3944
+ /* No sorting required if server-side or no sorting array */
3945
+ if ( !oSettings.oFeatures.bServerSide &&
3946
+ (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) )
3947
+ {
3948
+ aaSort = ( oSettings.aaSortingFixed !== null ) ?
3949
+ oSettings.aaSortingFixed.concat( oSettings.aaSorting ) :
3950
+ oSettings.aaSorting.slice();
3951
+
3952
+ /* If there is a sorting data type, and a function belonging to it, then we need to
3953
+ * get the data from the developer's function and apply it for this column
3954
+ */
3955
+ for ( i=0 ; i<aaSort.length ; i++ )
3956
+ {
3957
+ var iColumn = aaSort[i][0];
3958
+ var iVisColumn = _fnColumnIndexToVisible( oSettings, iColumn );
3959
+ sDataType = oSettings.aoColumns[ iColumn ].sSortDataType;
3960
+ if ( DataTable.ext.afnSortData[sDataType] )
3961
+ {
3962
+ var aData = DataTable.ext.afnSortData[sDataType].call(
3963
+ oSettings.oInstance, oSettings, iColumn, iVisColumn
3964
+ );
3965
+ if ( aData.length === aoData.length )
3966
+ {
3967
+ for ( j=0, jLen=aoData.length ; j<jLen ; j++ )
3968
+ {
3969
+ _fnSetCellData( oSettings, j, iColumn, aData[j] );
3970
+ }
3971
+ }
3972
+ else
3973
+ {
3974
+ _fnLog( oSettings, 0, "Returned data sort array (col "+iColumn+") is the wrong length" );
3975
+ }
3976
+ }
3977
+ }
3978
+
3979
+ /* Create a value - key array of the current row positions such that we can use their
3980
+ * current position during the sort, if values match, in order to perform stable sorting
3981
+ */
3982
+ for ( i=0, iLen=oSettings.aiDisplayMaster.length ; i<iLen ; i++ )
3983
+ {
3984
+ aiOrig[ oSettings.aiDisplayMaster[i] ] = i;
3985
+ }
3986
+
3987
+ /* Build an internal data array which is specific to the sort, so we can get and prep
3988
+ * the data to be sorted only once, rather than needing to do it every time the sorting
3989
+ * function runs. This make the sorting function a very simple comparison
3990
+ */
3991
+ var iSortLen = aaSort.length;
3992
+ var fnSortFormat, aDataSort;
3993
+ for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
3994
+ {
3995
+ for ( j=0 ; j<iSortLen ; j++ )
3996
+ {
3997
+ aDataSort = aoColumns[ aaSort[j][0] ].aDataSort;
3998
+
3999
+ for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
4000
+ {
4001
+ sDataType = aoColumns[ aDataSort[k] ].sType;
4002
+ fnSortFormat = oSort[ (sDataType ? sDataType : 'string')+"-pre" ];
4003
+
4004
+ aoData[i]._aSortData[ aDataSort[k] ] = fnSortFormat ?
4005
+ fnSortFormat( _fnGetCellData( oSettings, i, aDataSort[k], 'sort' ) ) :
4006
+ _fnGetCellData( oSettings, i, aDataSort[k], 'sort' );
4007
+ }
4008
+ }
4009
+ }
4010
+
4011
+ /* Do the sort - here we want multi-column sorting based on a given data source (column)
4012
+ * and sorting function (from oSort) in a certain direction. It's reasonably complex to
4013
+ * follow on it's own, but this is what we want (example two column sorting):
4014
+ * fnLocalSorting = function(a,b){
4015
+ * var iTest;
4016
+ * iTest = oSort['string-asc']('data11', 'data12');
4017
+ * if (iTest !== 0)
4018
+ * return iTest;
4019
+ * iTest = oSort['numeric-desc']('data21', 'data22');
4020
+ * if (iTest !== 0)
4021
+ * return iTest;
4022
+ * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
4023
+ * }
4024
+ * Basically we have a test for each sorting column, if the data in that column is equal,
4025
+ * test the next column. If all columns match, then we use a numeric sort on the row
4026
+ * positions in the original data array to provide a stable sort.
4027
+ */
4028
+ oSettings.aiDisplayMaster.sort( function ( a, b ) {
4029
+ var k, l, lLen, iTest, aDataSort, sDataType;
4030
+ for ( k=0 ; k<iSortLen ; k++ )
4031
+ {
4032
+ aDataSort = aoColumns[ aaSort[k][0] ].aDataSort;
4033
+
4034
+ for ( l=0, lLen=aDataSort.length ; l<lLen ; l++ )
4035
+ {
4036
+ sDataType = aoColumns[ aDataSort[l] ].sType;
4037
+
4038
+ iTest = oSort[ (sDataType ? sDataType : 'string')+"-"+aaSort[k][1] ](
4039
+ aoData[a]._aSortData[ aDataSort[l] ],
4040
+ aoData[b]._aSortData[ aDataSort[l] ]
4041
+ );
4042
+
4043
+ if ( iTest !== 0 )
4044
+ {
4045
+ return iTest;
4046
+ }
4047
+ }
4048
+ }
4049
+
4050
+ return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
4051
+ } );
4052
+ }
4053
+
4054
+ /* Alter the sorting classes to take account of the changes */
4055
+ if ( (bApplyClasses === undefined || bApplyClasses) && !oSettings.oFeatures.bDeferRender )
4056
+ {
4057
+ _fnSortingClasses( oSettings );
4058
+ }
4059
+
4060
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
4061
+ {
4062
+ var sTitle = aoColumns[i].sTitle.replace( /<.*?>/g, "" );
4063
+ nTh = aoColumns[i].nTh;
4064
+ nTh.removeAttribute('aria-sort');
4065
+ nTh.removeAttribute('aria-label');
4066
+
4067
+ /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
4068
+ if ( aoColumns[i].bSortable )
4069
+ {
4070
+ if ( aaSort.length > 0 && aaSort[0][0] == i )
4071
+ {
4072
+ nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" );
4073
+
4074
+ var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ?
4075
+ aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0];
4076
+ nTh.setAttribute('aria-label', sTitle+
4077
+ (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
4078
+ }
4079
+ else
4080
+ {
4081
+ nTh.setAttribute('aria-label', sTitle+
4082
+ (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
4083
+ }
4084
+ }
4085
+ else
4086
+ {
4087
+ nTh.setAttribute('aria-label', sTitle);
4088
+ }
4089
+ }
4090
+
4091
+ /* Tell the draw function that we have sorted the data */
4092
+ oSettings.bSorted = true;
4093
+ $(oSettings.oInstance).trigger('sort', oSettings);
4094
+
4095
+ /* Copy the master data into the draw array and re-draw */
4096
+ if ( oSettings.oFeatures.bFilter )
4097
+ {
4098
+ /* _fnFilter() will redraw the table for us */
4099
+ _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 );
4100
+ }
4101
+ else
4102
+ {
4103
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
4104
+ oSettings._iDisplayStart = 0; /* reset display back to page 0 */
4105
+ _fnCalculateEnd( oSettings );
4106
+ _fnDraw( oSettings );
4107
+ }
4108
+ }
4109
+
4110
+
4111
+ /**
4112
+ * Attach a sort handler (click) to a node
4113
+ * @param {object} oSettings dataTables settings object
4114
+ * @param {node} nNode node to attach the handler to
4115
+ * @param {int} iDataIndex column sorting index
4116
+ * @param {function} [fnCallback] callback function
4117
+ * @memberof DataTable#oApi
4118
+ */
4119
+ function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback )
4120
+ {
4121
+ _fnBindAction( nNode, {}, function (e) {
4122
+ /* If the column is not sortable - don't to anything */
4123
+ if ( oSettings.aoColumns[iDataIndex].bSortable === false )
4124
+ {
4125
+ return;
4126
+ }
4127
+
4128
+ /*
4129
+ * This is a little bit odd I admit... I declare a temporary function inside the scope of
4130
+ * _fnBuildHead and the click handler in order that the code presented here can be used
4131
+ * twice - once for when bProcessing is enabled, and another time for when it is
4132
+ * disabled, as we need to perform slightly different actions.
4133
+ * Basically the issue here is that the Javascript engine in modern browsers don't
4134
+ * appear to allow the rendering engine to update the display while it is still executing
4135
+ * it's thread (well - it does but only after long intervals). This means that the
4136
+ * 'processing' display doesn't appear for a table sort. To break the js thread up a bit
4137
+ * I force an execution break by using setTimeout - but this breaks the expected
4138
+ * thread continuation for the end-developer's point of view (their code would execute
4139
+ * too early), so we only do it when we absolutely have to.
4140
+ */
4141
+ var fnInnerSorting = function () {
4142
+ var iColumn, iNextSort;
4143
+
4144
+ /* If the shift key is pressed then we are multiple column sorting */
4145
+ if ( e.shiftKey )
4146
+ {
4147
+ /* Are we already doing some kind of sort on this column? */
4148
+ var bFound = false;
4149
+ for ( var i=0 ; i<oSettings.aaSorting.length ; i++ )
4150
+ {
4151
+ if ( oSettings.aaSorting[i][0] == iDataIndex )
4152
+ {
4153
+ bFound = true;
4154
+ iColumn = oSettings.aaSorting[i][0];
4155
+ iNextSort = oSettings.aaSorting[i][2]+1;
4156
+
4157
+ if ( !oSettings.aoColumns[iColumn].asSorting[iNextSort] )
4158
+ {
4159
+ /* Reached the end of the sorting options, remove from multi-col sort */
4160
+ oSettings.aaSorting.splice( i, 1 );
4161
+ }
4162
+ else
4163
+ {
4164
+ /* Move onto next sorting direction */
4165
+ oSettings.aaSorting[i][1] = oSettings.aoColumns[iColumn].asSorting[iNextSort];
4166
+ oSettings.aaSorting[i][2] = iNextSort;
4167
+ }
4168
+ break;
4169
+ }
4170
+ }
4171
+
4172
+ /* No sort yet - add it in */
4173
+ if ( bFound === false )
4174
+ {
4175
+ oSettings.aaSorting.push( [ iDataIndex,
4176
+ oSettings.aoColumns[iDataIndex].asSorting[0], 0 ] );
4177
+ }
4178
+ }
4179
+ else
4180
+ {
4181
+ /* If no shift key then single column sort */
4182
+ if ( oSettings.aaSorting.length == 1 && oSettings.aaSorting[0][0] == iDataIndex )
4183
+ {
4184
+ iColumn = oSettings.aaSorting[0][0];
4185
+ iNextSort = oSettings.aaSorting[0][2]+1;
4186
+ if ( !oSettings.aoColumns[iColumn].asSorting[iNextSort] )
4187
+ {
4188
+ iNextSort = 0;
4189
+ }
4190
+ oSettings.aaSorting[0][1] = oSettings.aoColumns[iColumn].asSorting[iNextSort];
4191
+ oSettings.aaSorting[0][2] = iNextSort;
4192
+ }
4193
+ else
4194
+ {
4195
+ oSettings.aaSorting.splice( 0, oSettings.aaSorting.length );
4196
+ oSettings.aaSorting.push( [ iDataIndex,
4197
+ oSettings.aoColumns[iDataIndex].asSorting[0], 0 ] );
4198
+ }
4199
+ }
4200
+
4201
+ /* Run the sort */
4202
+ _fnSort( oSettings );
4203
+ }; /* /fnInnerSorting */
4204
+
4205
+ if ( !oSettings.oFeatures.bProcessing )
4206
+ {
4207
+ fnInnerSorting();
4208
+ }
4209
+ else
4210
+ {
4211
+ _fnProcessingDisplay( oSettings, true );
4212
+ setTimeout( function() {
4213
+ fnInnerSorting();
4214
+ if ( !oSettings.oFeatures.bServerSide )
4215
+ {
4216
+ _fnProcessingDisplay( oSettings, false );
4217
+ }
4218
+ }, 0 );
4219
+ }
4220
+
4221
+ /* Call the user specified callback function - used for async user interaction */
4222
+ if ( typeof fnCallback == 'function' )
4223
+ {
4224
+ fnCallback( oSettings );
4225
+ }
4226
+ } );
4227
+ }
4228
+
4229
+
4230
+ /**
4231
+ * Set the sorting classes on the header, Note: it is safe to call this function
4232
+ * when bSort and bSortClasses are false
4233
+ * @param {object} oSettings dataTables settings object
4234
+ * @memberof DataTable#oApi
4235
+ */
4236
+ function _fnSortingClasses( oSettings )
4237
+ {
4238
+ var i, iLen, j, jLen, iFound;
4239
+ var aaSort, sClass;
4240
+ var iColumns = oSettings.aoColumns.length;
4241
+ var oClasses = oSettings.oClasses;
4242
+
4243
+ for ( i=0 ; i<iColumns ; i++ )
4244
+ {
4245
+ if ( oSettings.aoColumns[i].bSortable )
4246
+ {
4247
+ $(oSettings.aoColumns[i].nTh).removeClass( oClasses.sSortAsc +" "+ oClasses.sSortDesc +
4248
+ " "+ oSettings.aoColumns[i].sSortingClass );
4249
+ }
4250
+ }
4251
+
4252
+ if ( oSettings.aaSortingFixed !== null )
4253
+ {
4254
+ aaSort = oSettings.aaSortingFixed.concat( oSettings.aaSorting );
4255
+ }
4256
+ else
4257
+ {
4258
+ aaSort = oSettings.aaSorting.slice();
4259
+ }
4260
+
4261
+ /* Apply the required classes to the header */
4262
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
4263
+ {
4264
+ if ( oSettings.aoColumns[i].bSortable )
4265
+ {
4266
+ sClass = oSettings.aoColumns[i].sSortingClass;
4267
+ iFound = -1;
4268
+ for ( j=0 ; j<aaSort.length ; j++ )
4269
+ {
4270
+ if ( aaSort[j][0] == i )
4271
+ {
4272
+ sClass = ( aaSort[j][1] == "asc" ) ?
4273
+ oClasses.sSortAsc : oClasses.sSortDesc;
4274
+ iFound = j;
4275
+ break;
4276
+ }
4277
+ }
4278
+ $(oSettings.aoColumns[i].nTh).addClass( sClass );
4279
+
4280
+ if ( oSettings.bJUI )
4281
+ {
4282
+ /* jQuery UI uses extra markup */
4283
+ var jqSpan = $("span."+oClasses.sSortIcon, oSettings.aoColumns[i].nTh);
4284
+ jqSpan.removeClass(oClasses.sSortJUIAsc +" "+ oClasses.sSortJUIDesc +" "+
4285
+ oClasses.sSortJUI +" "+ oClasses.sSortJUIAscAllowed +" "+ oClasses.sSortJUIDescAllowed );
4286
+
4287
+ var sSpanClass;
4288
+ if ( iFound == -1 )
4289
+ {
4290
+ sSpanClass = oSettings.aoColumns[i].sSortingClassJUI;
4291
+ }
4292
+ else if ( aaSort[iFound][1] == "asc" )
4293
+ {
4294
+ sSpanClass = oClasses.sSortJUIAsc;
4295
+ }
4296
+ else
4297
+ {
4298
+ sSpanClass = oClasses.sSortJUIDesc;
4299
+ }
4300
+
4301
+ jqSpan.addClass( sSpanClass );
4302
+ }
4303
+ }
4304
+ else
4305
+ {
4306
+ /* No sorting on this column, so add the base class. This will have been assigned by
4307
+ * _fnAddColumn
4308
+ */
4309
+ $(oSettings.aoColumns[i].nTh).addClass( oSettings.aoColumns[i].sSortingClass );
4310
+ }
4311
+ }
4312
+
4313
+ /*
4314
+ * Apply the required classes to the table body
4315
+ * Note that this is given as a feature switch since it can significantly slow down a sort
4316
+ * on large data sets (adding and removing of classes is always slow at the best of times..)
4317
+ * Further to this, note that this code is admittedly fairly ugly. It could be made a lot
4318
+ * simpler using jQuery selectors and add/removeClass, but that is significantly slower
4319
+ * (on the order of 5 times slower) - hence the direct DOM manipulation here.
4320
+ * Note that for deferred drawing we do use jQuery - the reason being that taking the first
4321
+ * row found to see if the whole column needs processed can miss classes since the first
4322
+ * column might be new.
4323
+ */
4324
+ sClass = oClasses.sSortColumn;
4325
+
4326
+ if ( oSettings.oFeatures.bSort && oSettings.oFeatures.bSortClasses )
4327
+ {
4328
+ var nTds = _fnGetTdNodes( oSettings );
4329
+
4330
+ /* Determine what the sorting class for each column should be */
4331
+ var iClass, iTargetCol;
4332
+ var asClasses = [];
4333
+ for (i = 0; i < iColumns; i++)
4334
+ {
4335
+ asClasses.push("");
4336
+ }
4337
+ for (i = 0, iClass = 1; i < aaSort.length; i++)
4338
+ {
4339
+ iTargetCol = parseInt( aaSort[i][0], 10 );
4340
+ asClasses[iTargetCol] = sClass + iClass;
4341
+
4342
+ if ( iClass < 3 )
4343
+ {
4344
+ iClass++;
4345
+ }
4346
+ }
4347
+
4348
+ /* Make changes to the classes for each cell as needed */
4349
+ var reClass = new RegExp(sClass + "[123]");
4350
+ var sTmpClass, sCurrentClass, sNewClass;
4351
+ for ( i=0, iLen=nTds.length; i<iLen; i++ )
4352
+ {
4353
+ /* Determine which column we're looking at */
4354
+ iTargetCol = i % iColumns;
4355
+
4356
+ /* What is the full list of classes now */
4357
+ sCurrentClass = nTds[i].className;
4358
+ /* What sorting class should be applied? */
4359
+ sNewClass = asClasses[iTargetCol];
4360
+ /* What would the new full list be if we did a replacement? */
4361
+ sTmpClass = sCurrentClass.replace(reClass, sNewClass);
4362
+
4363
+ if ( sTmpClass != sCurrentClass )
4364
+ {
4365
+ /* We changed something */
4366
+ nTds[i].className = $.trim( sTmpClass );
4367
+ }
4368
+ else if ( sNewClass.length > 0 && sCurrentClass.indexOf(sNewClass) == -1 )
4369
+ {
4370
+ /* We need to add a class */
4371
+ nTds[i].className = sCurrentClass + " " + sNewClass;
4372
+ }
4373
+ }
4374
+ }
4375
+ }
4376
+
4377
+
4378
+
4379
+ /**
4380
+ * Save the state of a table in a cookie such that the page can be reloaded
4381
+ * @param {object} oSettings dataTables settings object
4382
+ * @memberof DataTable#oApi
4383
+ */
4384
+ function _fnSaveState ( oSettings )
4385
+ {
4386
+ if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying )
4387
+ {
4388
+ return;
4389
+ }
4390
+
4391
+ /* Store the interesting variables */
4392
+ var i, iLen, bInfinite=oSettings.oScroll.bInfinite;
4393
+ var oState = {
4394
+ "iCreate": new Date().getTime(),
4395
+ "iStart": (bInfinite ? 0 : oSettings._iDisplayStart),
4396
+ "iEnd": (bInfinite ? oSettings._iDisplayLength : oSettings._iDisplayEnd),
4397
+ "iLength": oSettings._iDisplayLength,
4398
+ "aaSorting": $.extend( true, [], oSettings.aaSorting ),
4399
+ "oSearch": $.extend( true, {}, oSettings.oPreviousSearch ),
4400
+ "aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ),
4401
+ "abVisCols": []
4402
+ };
4403
+
4404
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
4405
+ {
4406
+ oState.abVisCols.push( oSettings.aoColumns[i].bVisible );
4407
+ }
4408
+
4409
+ _fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
4410
+
4411
+ oSettings.fnStateSave.call( oSettings.oInstance, oSettings, oState );
4412
+ }
4413
+
4414
+
4415
+ /**
4416
+ * Attempt to load a saved table state from a cookie
4417
+ * @param {object} oSettings dataTables settings object
4418
+ * @param {object} oInit DataTables init object so we can override settings
4419
+ * @memberof DataTable#oApi
4420
+ */
4421
+ function _fnLoadState ( oSettings, oInit )
4422
+ {
4423
+ if ( !oSettings.oFeatures.bStateSave )
4424
+ {
4425
+ return;
4426
+ }
4427
+
4428
+ var oData = oSettings.fnStateLoad.call( oSettings.oInstance, oSettings );
4429
+ if ( !oData )
4430
+ {
4431
+ return;
4432
+ }
4433
+
4434
+ /* Allow custom and plug-in manipulation functions to alter the saved data set and
4435
+ * cancelling of loading by returning false
4436
+ */
4437
+ var abStateLoad = _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
4438
+ if ( $.inArray( false, abStateLoad ) !== -1 )
4439
+ {
4440
+ return;
4441
+ }
4442
+
4443
+ /* Store the saved state so it might be accessed at any time */
4444
+ oSettings.oLoadedState = $.extend( true, {}, oData );
4445
+
4446
+ /* Restore key features */
4447
+ oSettings._iDisplayStart = oData.iStart;
4448
+ oSettings.iInitDisplayStart = oData.iStart;
4449
+ oSettings._iDisplayEnd = oData.iEnd;
4450
+ oSettings._iDisplayLength = oData.iLength;
4451
+ oSettings.aaSorting = oData.aaSorting.slice();
4452
+ oSettings.saved_aaSorting = oData.aaSorting.slice();
4453
+
4454
+ /* Search filtering */
4455
+ $.extend( oSettings.oPreviousSearch, oData.oSearch );
4456
+ $.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
4457
+
4458
+ /* Column visibility state
4459
+ * Pass back visibility settings to the init handler, but to do not here override
4460
+ * the init object that the user might have passed in
4461
+ */
4462
+ oInit.saved_aoColumns = [];
4463
+ for ( var i=0 ; i<oData.abVisCols.length ; i++ )
4464
+ {
4465
+ oInit.saved_aoColumns[i] = {};
4466
+ oInit.saved_aoColumns[i].bVisible = oData.abVisCols[i];
4467
+ }
4468
+
4469
+ _fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
4470
+ }
4471
+
4472
+
4473
+ /**
4474
+ * Create a new cookie with a value to store the state of a table
4475
+ * @param {string} sName name of the cookie to create
4476
+ * @param {string} sValue the value the cookie should take
4477
+ * @param {int} iSecs duration of the cookie
4478
+ * @param {string} sBaseName sName is made up of the base + file name - this is the base
4479
+ * @param {function} fnCallback User definable function to modify the cookie
4480
+ * @memberof DataTable#oApi
4481
+ */
4482
+ function _fnCreateCookie ( sName, sValue, iSecs, sBaseName, fnCallback )
4483
+ {
4484
+ var date = new Date();
4485
+ date.setTime( date.getTime()+(iSecs*1000) );
4486
+
4487
+ /*
4488
+ * Shocking but true - it would appear IE has major issues with having the path not having
4489
+ * a trailing slash on it. We need the cookie to be available based on the path, so we
4490
+ * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the
4491
+ * patch to use at least some of the path
4492
+ */
4493
+ var aParts = window.location.pathname.split('/');
4494
+ var sNameFile = sName + '_' + aParts.pop().replace(/[\/:]/g,"").toLowerCase();
4495
+ var sFullCookie, oData;
4496
+
4497
+ if ( fnCallback !== null )
4498
+ {
4499
+ oData = (typeof $.parseJSON === 'function') ?
4500
+ $.parseJSON( sValue ) : eval( '('+sValue+')' );
4501
+ sFullCookie = fnCallback( sNameFile, oData, date.toGMTString(),
4502
+ aParts.join('/')+"/" );
4503
+ }
4504
+ else
4505
+ {
4506
+ sFullCookie = sNameFile + "=" + encodeURIComponent(sValue) +
4507
+ "; expires=" + date.toGMTString() +"; path=" + aParts.join('/')+"/";
4508
+ }
4509
+
4510
+ /* Are we going to go over the cookie limit of 4KiB? If so, try to delete a cookies
4511
+ * belonging to DataTables.
4512
+ */
4513
+ var
4514
+ aCookies =document.cookie.split(';'),
4515
+ iNewCookieLen = sFullCookie.split(';')[0].length,
4516
+ aOldCookies = [];
4517
+
4518
+ if ( iNewCookieLen+document.cookie.length+10 > 4096 ) /* Magic 10 for padding */
4519
+ {
4520
+ for ( var i=0, iLen=aCookies.length ; i<iLen ; i++ )
4521
+ {
4522
+ if ( aCookies[i].indexOf( sBaseName ) != -1 )
4523
+ {
4524
+ /* It's a DataTables cookie, so eval it and check the time stamp */
4525
+ var aSplitCookie = aCookies[i].split('=');
4526
+ try {
4527
+ oData = eval( '('+decodeURIComponent(aSplitCookie[1])+')' );
4528
+
4529
+ if ( oData && oData.iCreate )
4530
+ {
4531
+ aOldCookies.push( {
4532
+ "name": aSplitCookie[0],
4533
+ "time": oData.iCreate
4534
+ } );
4535
+ }
4536
+ }
4537
+ catch( e ) {}
4538
+ }
4539
+ }
4540
+
4541
+ // Make sure we delete the oldest ones first
4542
+ aOldCookies.sort( function (a, b) {
4543
+ return b.time - a.time;
4544
+ } );
4545
+
4546
+ // Eliminate as many old DataTables cookies as we need to
4547
+ while ( iNewCookieLen + document.cookie.length + 10 > 4096 ) {
4548
+ if ( aOldCookies.length === 0 ) {
4549
+ // Deleted all DT cookies and still not enough space. Can't state save
4550
+ return;
4551
+ }
4552
+
4553
+ var old = aOldCookies.pop();
4554
+ document.cookie = old.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+
4555
+ aParts.join('/') + "/";
4556
+ }
4557
+ }
4558
+
4559
+ document.cookie = sFullCookie;
4560
+ }
4561
+
4562
+
4563
+ /**
4564
+ * Read an old cookie to get a cookie with an old table state
4565
+ * @param {string} sName name of the cookie to read
4566
+ * @returns {string} contents of the cookie - or null if no cookie with that name found
4567
+ * @memberof DataTable#oApi
4568
+ */
4569
+ function _fnReadCookie ( sName )
4570
+ {
4571
+ var
4572
+ aParts = window.location.pathname.split('/'),
4573
+ sNameEQ = sName + '_' + aParts[aParts.length-1].replace(/[\/:]/g,"").toLowerCase() + '=',
4574
+ sCookieContents = document.cookie.split(';');
4575
+
4576
+ for( var i=0 ; i<sCookieContents.length ; i++ )
4577
+ {
4578
+ var c = sCookieContents[i];
4579
+
4580
+ while (c.charAt(0)==' ')
4581
+ {
4582
+ c = c.substring(1,c.length);
4583
+ }
4584
+
4585
+ if (c.indexOf(sNameEQ) === 0)
4586
+ {
4587
+ return decodeURIComponent( c.substring(sNameEQ.length,c.length) );
4588
+ }
4589
+ }
4590
+ return null;
4591
+ }
4592
+
4593
+
4594
+ /**
4595
+ * Return the settings object for a particular table
4596
+ * @param {node} nTable table we are using as a dataTable
4597
+ * @returns {object} Settings object - or null if not found
4598
+ * @memberof DataTable#oApi
4599
+ */
4600
+ function _fnSettingsFromNode ( nTable )
4601
+ {
4602
+ for ( var i=0 ; i<DataTable.settings.length ; i++ )
4603
+ {
4604
+ if ( DataTable.settings[i].nTable === nTable )
4605
+ {
4606
+ return DataTable.settings[i];
4607
+ }
4608
+ }
4609
+
4610
+ return null;
4611
+ }
4612
+
4613
+
4614
+ /**
4615
+ * Return an array with the TR nodes for the table
4616
+ * @param {object} oSettings dataTables settings object
4617
+ * @returns {array} TR array
4618
+ * @memberof DataTable#oApi
4619
+ */
4620
+ function _fnGetTrNodes ( oSettings )
4621
+ {
4622
+ var aNodes = [];
4623
+ var aoData = oSettings.aoData;
4624
+ for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
4625
+ {
4626
+ if ( aoData[i].nTr !== null )
4627
+ {
4628
+ aNodes.push( aoData[i].nTr );
4629
+ }
4630
+ }
4631
+ return aNodes;
4632
+ }
4633
+
4634
+
4635
+ /**
4636
+ * Return an flat array with all TD nodes for the table, or row
4637
+ * @param {object} oSettings dataTables settings object
4638
+ * @param {int} [iIndividualRow] aoData index to get the nodes for - optional
4639
+ * if not given then the return array will contain all nodes for the table
4640
+ * @returns {array} TD array
4641
+ * @memberof DataTable#oApi
4642
+ */
4643
+ function _fnGetTdNodes ( oSettings, iIndividualRow )
4644
+ {
4645
+ var anReturn = [];
4646
+ var iCorrector;
4647
+ var anTds, nTd;
4648
+ var iRow, iRows=oSettings.aoData.length,
4649
+ iColumn, iColumns, oData, sNodeName, iStart=0, iEnd=iRows;
4650
+
4651
+ /* Allow the collection to be limited to just one row */
4652
+ if ( iIndividualRow !== undefined )
4653
+ {
4654
+ iStart = iIndividualRow;
4655
+ iEnd = iIndividualRow+1;
4656
+ }
4657
+
4658
+ for ( iRow=iStart ; iRow<iEnd ; iRow++ )
4659
+ {
4660
+ oData = oSettings.aoData[iRow];
4661
+ if ( oData.nTr !== null )
4662
+ {
4663
+ /* get the TD child nodes - taking into account text etc nodes */
4664
+ anTds = [];
4665
+ nTd = oData.nTr.firstChild;
4666
+ while ( nTd )
4667
+ {
4668
+ sNodeName = nTd.nodeName.toLowerCase();
4669
+ if ( sNodeName == 'td' || sNodeName == 'th' )
4670
+ {
4671
+ anTds.push( nTd );
4672
+ }
4673
+ nTd = nTd.nextSibling;
4674
+ }
4675
+
4676
+ iCorrector = 0;
4677
+ for ( iColumn=0, iColumns=oSettings.aoColumns.length ; iColumn<iColumns ; iColumn++ )
4678
+ {
4679
+ if ( oSettings.aoColumns[iColumn].bVisible )
4680
+ {
4681
+ anReturn.push( anTds[iColumn-iCorrector] );
4682
+ }
4683
+ else
4684
+ {
4685
+ anReturn.push( oData._anHidden[iColumn] );
4686
+ iCorrector++;
4687
+ }
4688
+ }
4689
+ }
4690
+ }
4691
+
4692
+ return anReturn;
4693
+ }
4694
+
4695
+
4696
+ /**
4697
+ * Log an error message
4698
+ * @param {object} oSettings dataTables settings object
4699
+ * @param {int} iLevel log error messages, or display them to the user
4700
+ * @param {string} sMesg error message
4701
+ * @memberof DataTable#oApi
4702
+ */
4703
+ function _fnLog( oSettings, iLevel, sMesg )
4704
+ {
4705
+ var sAlert = (oSettings===null) ?
4706
+ "DataTables warning: "+sMesg :
4707
+ "DataTables warning (table id = '"+oSettings.sTableId+"'): "+sMesg;
4708
+
4709
+ if ( iLevel === 0 )
4710
+ {
4711
+ if ( DataTable.ext.sErrMode == 'alert' )
4712
+ {
4713
+ alert( sAlert );
4714
+ }
4715
+ else
4716
+ {
4717
+ throw new Error(sAlert);
4718
+ }
4719
+ return;
4720
+ }
4721
+ else if ( window.console && console.log )
4722
+ {
4723
+ console.log( sAlert );
4724
+ }
4725
+ }
4726
+
4727
+
4728
+ /**
4729
+ * See if a property is defined on one object, if so assign it to the other object
4730
+ * @param {object} oRet target object
4731
+ * @param {object} oSrc source object
4732
+ * @param {string} sName property
4733
+ * @param {string} [sMappedName] name to map too - optional, sName used if not given
4734
+ * @memberof DataTable#oApi
4735
+ */
4736
+ function _fnMap( oRet, oSrc, sName, sMappedName )
4737
+ {
4738
+ if ( sMappedName === undefined )
4739
+ {
4740
+ sMappedName = sName;
4741
+ }
4742
+ if ( oSrc[sName] !== undefined )
4743
+ {
4744
+ oRet[sMappedName] = oSrc[sName];
4745
+ }
4746
+ }
4747
+
4748
+
4749
+ /**
4750
+ * Extend objects - very similar to jQuery.extend, but deep copy objects, and shallow
4751
+ * copy arrays. The reason we need to do this, is that we don't want to deep copy array
4752
+ * init values (such as aaSorting) since the dev wouldn't be able to override them, but
4753
+ * we do want to deep copy arrays.
4754
+ * @param {object} oOut Object to extend
4755
+ * @param {object} oExtender Object from which the properties will be applied to oOut
4756
+ * @returns {object} oOut Reference, just for convenience - oOut === the return.
4757
+ * @memberof DataTable#oApi
4758
+ * @todo This doesn't take account of arrays inside the deep copied objects.
4759
+ */
4760
+ function _fnExtend( oOut, oExtender )
4761
+ {
4762
+ var val;
4763
+
4764
+ for ( var prop in oExtender )
4765
+ {
4766
+ if ( oExtender.hasOwnProperty(prop) )
4767
+ {
4768
+ val = oExtender[prop];
4769
+
4770
+ if ( typeof oInit[prop] === 'object' && val !== null && $.isArray(val) === false )
4771
+ {
4772
+ $.extend( true, oOut[prop], val );
4773
+ }
4774
+ else
4775
+ {
4776
+ oOut[prop] = val;
4777
+ }
4778
+ }
4779
+ }
4780
+
4781
+ return oOut;
4782
+ }
4783
+
4784
+
4785
+ /**
4786
+ * Bind an event handers to allow a click or return key to activate the callback.
4787
+ * This is good for accessibility since a return on the keyboard will have the
4788
+ * same effect as a click, if the element has focus.
4789
+ * @param {element} n Element to bind the action to
4790
+ * @param {object} oData Data object to pass to the triggered function
4791
+ * @param {function} fn Callback function for when the event is triggered
4792
+ * @memberof DataTable#oApi
4793
+ */
4794
+ function _fnBindAction( n, oData, fn )
4795
+ {
4796
+ $(n)
4797
+ .bind( 'click.DT', oData, function (e) {
4798
+ n.blur(); // Remove focus outline for mouse users
4799
+ fn(e);
4800
+ } )
4801
+ .bind( 'keypress.DT', oData, function (e){
4802
+ if ( e.which === 13 ) {
4803
+ fn(e);
4804
+ } } )
4805
+ .bind( 'selectstart.DT', function () {
4806
+ /* Take the brutal approach to cancelling text selection */
4807
+ return false;
4808
+ } );
4809
+ }
4810
+
4811
+
4812
+ /**
4813
+ * Register a callback function. Easily allows a callback function to be added to
4814
+ * an array store of callback functions that can then all be called together.
4815
+ * @param {object} oSettings dataTables settings object
4816
+ * @param {string} sStore Name of the array storage for the callbacks in oSettings
4817
+ * @param {function} fn Function to be called back
4818
+ * @param {string} sName Identifying name for the callback (i.e. a label)
4819
+ * @memberof DataTable#oApi
4820
+ */
4821
+ function _fnCallbackReg( oSettings, sStore, fn, sName )
4822
+ {
4823
+ if ( fn )
4824
+ {
4825
+ oSettings[sStore].push( {
4826
+ "fn": fn,
4827
+ "sName": sName
4828
+ } );
4829
+ }
4830
+ }
4831
+
4832
+
4833
+ /**
4834
+ * Fire callback functions and trigger events. Note that the loop over the callback
4835
+ * array store is done backwards! Further note that you do not want to fire off triggers
4836
+ * in time sensitive applications (for example cell creation) as its slow.
4837
+ * @param {object} oSettings dataTables settings object
4838
+ * @param {string} sStore Name of the array storage for the callbacks in oSettings
4839
+ * @param {string} sTrigger Name of the jQuery custom event to trigger. If null no trigger
4840
+ * is fired
4841
+ * @param {array} aArgs Array of arguments to pass to the callback function / trigger
4842
+ * @memberof DataTable#oApi
4843
+ */
4844
+ function _fnCallbackFire( oSettings, sStore, sTrigger, aArgs )
4845
+ {
4846
+ var aoStore = oSettings[sStore];
4847
+ var aRet =[];
4848
+
4849
+ for ( var i=aoStore.length-1 ; i>=0 ; i-- )
4850
+ {
4851
+ aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) );
4852
+ }
4853
+
4854
+ if ( sTrigger !== null )
4855
+ {
4856
+ $(oSettings.oInstance).trigger(sTrigger, aArgs);
4857
+ }
4858
+
4859
+ return aRet;
4860
+ }
4861
+
4862
+
4863
+ /**
4864
+ * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other
4865
+ * library, then we use that as it is fast, safe and accurate. If the function isn't
4866
+ * available then we need to built it ourselves - the inspiration for this function comes
4867
+ * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is
4868
+ * not perfect and absolutely should not be used as a replacement to json2.js - but it does
4869
+ * do what we need, without requiring a dependency for DataTables.
4870
+ * @param {object} o JSON object to be converted
4871
+ * @returns {string} JSON string
4872
+ * @memberof DataTable#oApi
4873
+ */
4874
+ var _fnJsonString = (window.JSON) ? JSON.stringify : function( o )
4875
+ {
4876
+ /* Not an object or array */
4877
+ var sType = typeof o;
4878
+ if (sType !== "object" || o === null)
4879
+ {
4880
+ // simple data type
4881
+ if (sType === "string")
4882
+ {
4883
+ o = '"'+o+'"';
4884
+ }
4885
+ return o+"";
4886
+ }
4887
+
4888
+ /* If object or array, need to recurse over it */
4889
+ var
4890
+ sProp, mValue,
4891
+ json = [],
4892
+ bArr = $.isArray(o);
4893
+
4894
+ for (sProp in o)
4895
+ {
4896
+ mValue = o[sProp];
4897
+ sType = typeof mValue;
4898
+
4899
+ if (sType === "string")
4900
+ {
4901
+ mValue = '"'+mValue+'"';
4902
+ }
4903
+ else if (sType === "object" && mValue !== null)
4904
+ {
4905
+ mValue = _fnJsonString(mValue);
4906
+ }
4907
+
4908
+ json.push((bArr ? "" : '"'+sProp+'":') + mValue);
4909
+ }
4910
+
4911
+ return (bArr ? "[" : "{") + json + (bArr ? "]" : "}");
4912
+ };
4913
+
4914
+
4915
+ /**
4916
+ * From some browsers (specifically IE6/7) we need special handling to work around browser
4917
+ * bugs - this function is used to detect when these workarounds are needed.
4918
+ * @param {object} oSettings dataTables settings object
4919
+ * @memberof DataTable#oApi
4920
+ */
4921
+ function _fnBrowserDetect( oSettings )
4922
+ {
4923
+ /* IE6/7 will oversize a width 100% element inside a scrolling element, to include the
4924
+ * width of the scrollbar, while other browsers ensure the inner element is contained
4925
+ * without forcing scrolling
4926
+ */
4927
+ var n = $(
4928
+ '<div style="position:absolute; top:0; left:0; height:1px; width:1px; overflow:hidden">'+
4929
+ '<div style="position:absolute; top:1px; left:1px; width:100px; overflow:scroll;">'+
4930
+ '<div id="DT_BrowserTest" style="width:100%; height:10px;"></div>'+
4931
+ '</div>'+
4932
+ '</div>')[0];
4933
+
4934
+ document.body.appendChild( n );
4935
+ oSettings.oBrowser.bScrollOversize = $('#DT_BrowserTest', n)[0].offsetWidth === 100 ? true : false;
4936
+ document.body.removeChild( n );
4937
+ }
4938
+
4939
+
4940
+ /**
4941
+ * Perform a jQuery selector action on the table's TR elements (from the tbody) and
4942
+ * return the resulting jQuery object.
4943
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
4944
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
4945
+ * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
4946
+ * criterion ("applied") or all TR elements (i.e. no filter).
4947
+ * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
4948
+ * Can be either 'current', whereby the current sorting of the table is used, or
4949
+ * 'original' whereby the original order the data was read into the table is used.
4950
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
4951
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
4952
+ * 'current' and filter is 'applied', regardless of what they might be given as.
4953
+ * @returns {object} jQuery object, filtered by the given selector.
4954
+ * @dtopt API
4955
+ *
4956
+ * @example
4957
+ * $(document).ready(function() {
4958
+ * var oTable = $('#example').dataTable();
4959
+ *
4960
+ * // Highlight every second row
4961
+ * oTable.$('tr:odd').css('backgroundColor', 'blue');
4962
+ * } );
4963
+ *
4964
+ * @example
4965
+ * $(document).ready(function() {
4966
+ * var oTable = $('#example').dataTable();
4967
+ *
4968
+ * // Filter to rows with 'Webkit' in them, add a background colour and then
4969
+ * // remove the filter, thus highlighting the 'Webkit' rows only.
4970
+ * oTable.fnFilter('Webkit');
4971
+ * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue');
4972
+ * oTable.fnFilter('');
4973
+ * } );
4974
+ */
4975
+ this.$ = function ( sSelector, oOpts )
4976
+ {
4977
+ var i, iLen, a = [], tr;
4978
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
4979
+ var aoData = oSettings.aoData;
4980
+ var aiDisplay = oSettings.aiDisplay;
4981
+ var aiDisplayMaster = oSettings.aiDisplayMaster;
4982
+
4983
+ if ( !oOpts )
4984
+ {
4985
+ oOpts = {};
4986
+ }
4987
+
4988
+ oOpts = $.extend( {}, {
4989
+ "filter": "none", // applied
4990
+ "order": "current", // "original"
4991
+ "page": "all" // current
4992
+ }, oOpts );
4993
+
4994
+ // Current page implies that order=current and fitler=applied, since it is fairly
4995
+ // senseless otherwise
4996
+ if ( oOpts.page == 'current' )
4997
+ {
4998
+ for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i<iLen ; i++ )
4999
+ {
5000
+ tr = aoData[ aiDisplay[i] ].nTr;
5001
+ if ( tr )
5002
+ {
5003
+ a.push( tr );
5004
+ }
5005
+ }
5006
+ }
5007
+ else if ( oOpts.order == "current" && oOpts.filter == "none" )
5008
+ {
5009
+ for ( i=0, iLen=aiDisplayMaster.length ; i<iLen ; i++ )
5010
+ {
5011
+ tr = aoData[ aiDisplayMaster[i] ].nTr;
5012
+ if ( tr )
5013
+ {
5014
+ a.push( tr );
5015
+ }
5016
+ }
5017
+ }
5018
+ else if ( oOpts.order == "current" && oOpts.filter == "applied" )
5019
+ {
5020
+ for ( i=0, iLen=aiDisplay.length ; i<iLen ; i++ )
5021
+ {
5022
+ tr = aoData[ aiDisplay[i] ].nTr;
5023
+ if ( tr )
5024
+ {
5025
+ a.push( tr );
5026
+ }
5027
+ }
5028
+ }
5029
+ else if ( oOpts.order == "original" && oOpts.filter == "none" )
5030
+ {
5031
+ for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
5032
+ {
5033
+ tr = aoData[ i ].nTr ;
5034
+ if ( tr )
5035
+ {
5036
+ a.push( tr );
5037
+ }
5038
+ }
5039
+ }
5040
+ else if ( oOpts.order == "original" && oOpts.filter == "applied" )
5041
+ {
5042
+ for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
5043
+ {
5044
+ tr = aoData[ i ].nTr;
5045
+ if ( $.inArray( i, aiDisplay ) !== -1 && tr )
5046
+ {
5047
+ a.push( tr );
5048
+ }
5049
+ }
5050
+ }
5051
+ else
5052
+ {
5053
+ _fnLog( oSettings, 1, "Unknown selection options" );
5054
+ }
5055
+
5056
+ /* We need to filter on the TR elements and also 'find' in their descendants
5057
+ * to make the selector act like it would in a full table - so we need
5058
+ * to build both results and then combine them together
5059
+ */
5060
+ var jqA = $(a);
5061
+ var jqTRs = jqA.filter( sSelector );
5062
+ var jqDescendants = jqA.find( sSelector );
5063
+
5064
+ return $( [].concat($.makeArray(jqTRs), $.makeArray(jqDescendants)) );
5065
+ };
5066
+
5067
+
5068
+ /**
5069
+ * Almost identical to $ in operation, but in this case returns the data for the matched
5070
+ * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
5071
+ * rather than any descendants, so the data can be obtained for the row/cell. If matching
5072
+ * rows are found, the data returned is the original data array/object that was used to
5073
+ * create the row (or a generated array if from a DOM source).
5074
+ *
5075
+ * This method is often useful in-combination with $ where both functions are given the
5076
+ * same parameters and the array indexes will match identically.
5077
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
5078
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
5079
+ * @param {string} [oOpts.filter=none] Select elements that meet the current filter
5080
+ * criterion ("applied") or all elements (i.e. no filter).
5081
+ * @param {string} [oOpts.order=current] Order of the data in the processed array.
5082
+ * Can be either 'current', whereby the current sorting of the table is used, or
5083
+ * 'original' whereby the original order the data was read into the table is used.
5084
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
5085
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
5086
+ * 'current' and filter is 'applied', regardless of what they might be given as.
5087
+ * @returns {array} Data for the matched elements. If any elements, as a result of the
5088
+ * selector, were not TR, TD or TH elements in the DataTable, they will have a null
5089
+ * entry in the array.
5090
+ * @dtopt API
5091
+ *
5092
+ * @example
5093
+ * $(document).ready(function() {
5094
+ * var oTable = $('#example').dataTable();
5095
+ *
5096
+ * // Get the data from the first row in the table
5097
+ * var data = oTable._('tr:first');
5098
+ *
5099
+ * // Do something useful with the data
5100
+ * alert( "First cell is: "+data[0] );
5101
+ * } );
5102
+ *
5103
+ * @example
5104
+ * $(document).ready(function() {
5105
+ * var oTable = $('#example').dataTable();
5106
+ *
5107
+ * // Filter to 'Webkit' and get all data for
5108
+ * oTable.fnFilter('Webkit');
5109
+ * var data = oTable._('tr', {"filter": "applied"});
5110
+ *
5111
+ * // Do something with the data
5112
+ * alert( data.length+" rows matched the filter" );
5113
+ * } );
5114
+ */
5115
+ this._ = function ( sSelector, oOpts )
5116
+ {
5117
+ var aOut = [];
5118
+ var i, iLen, iIndex;
5119
+ var aTrs = this.$( sSelector, oOpts );
5120
+
5121
+ for ( i=0, iLen=aTrs.length ; i<iLen ; i++ )
5122
+ {
5123
+ aOut.push( this.fnGetData(aTrs[i]) );
5124
+ }
5125
+
5126
+ return aOut;
5127
+ };
5128
+
5129
+
5130
+ /**
5131
+ * Add a single new row or multiple rows of data to the table. Please note
5132
+ * that this is suitable for client-side processing only - if you are using
5133
+ * server-side processing (i.e. "bServerSide": true), then to add data, you
5134
+ * must add it to the data source, i.e. the server-side, through an Ajax call.
5135
+ * @param {array|object} mData The data to be added to the table. This can be:
5136
+ * <ul>
5137
+ * <li>1D array of data - add a single row with the data provided</li>
5138
+ * <li>2D array of arrays - add multiple rows in a single call</li>
5139
+ * <li>object - data object when using <i>mData</i></li>
5140
+ * <li>array of objects - multiple data objects when using <i>mData</i></li>
5141
+ * </ul>
5142
+ * @param {bool} [bRedraw=true] redraw the table or not
5143
+ * @returns {array} An array of integers, representing the list of indexes in
5144
+ * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
5145
+ * the table.
5146
+ * @dtopt API
5147
+ *
5148
+ * @example
5149
+ * // Global var for counter
5150
+ * var giCount = 2;
5151
+ *
5152
+ * $(document).ready(function() {
5153
+ * $('#example').dataTable();
5154
+ * } );
5155
+ *
5156
+ * function fnClickAddRow() {
5157
+ * $('#example').dataTable().fnAddData( [
5158
+ * giCount+".1",
5159
+ * giCount+".2",
5160
+ * giCount+".3",
5161
+ * giCount+".4" ]
5162
+ * );
5163
+ *
5164
+ * giCount++;
5165
+ * }
5166
+ */
5167
+ this.fnAddData = function( mData, bRedraw )
5168
+ {
5169
+ if ( mData.length === 0 )
5170
+ {
5171
+ return [];
5172
+ }
5173
+
5174
+ var aiReturn = [];
5175
+ var iTest;
5176
+
5177
+ /* Find settings from table node */
5178
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5179
+
5180
+ /* Check if we want to add multiple rows or not */
5181
+ if ( typeof mData[0] === "object" && mData[0] !== null )
5182
+ {
5183
+ for ( var i=0 ; i<mData.length ; i++ )
5184
+ {
5185
+ iTest = _fnAddData( oSettings, mData[i] );
5186
+ if ( iTest == -1 )
5187
+ {
5188
+ return aiReturn;
5189
+ }
5190
+ aiReturn.push( iTest );
5191
+ }
5192
+ }
5193
+ else
5194
+ {
5195
+ iTest = _fnAddData( oSettings, mData );
5196
+ if ( iTest == -1 )
5197
+ {
5198
+ return aiReturn;
5199
+ }
5200
+ aiReturn.push( iTest );
5201
+ }
5202
+
5203
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
5204
+
5205
+ if ( bRedraw === undefined || bRedraw )
5206
+ {
5207
+ _fnReDraw( oSettings );
5208
+ }
5209
+ return aiReturn;
5210
+ };
5211
+
5212
+
5213
+ /**
5214
+ * This function will make DataTables recalculate the column sizes, based on the data
5215
+ * contained in the table and the sizes applied to the columns (in the DOM, CSS or
5216
+ * through the sWidth parameter). This can be useful when the width of the table's
5217
+ * parent element changes (for example a window resize).
5218
+ * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
5219
+ * @dtopt API
5220
+ *
5221
+ * @example
5222
+ * $(document).ready(function() {
5223
+ * var oTable = $('#example').dataTable( {
5224
+ * "sScrollY": "200px",
5225
+ * "bPaginate": false
5226
+ * } );
5227
+ *
5228
+ * $(window).bind('resize', function () {
5229
+ * oTable.fnAdjustColumnSizing();
5230
+ * } );
5231
+ * } );
5232
+ */
5233
+ this.fnAdjustColumnSizing = function ( bRedraw )
5234
+ {
5235
+ var oSettings = _fnSettingsFromNode(this[DataTable.ext.iApiIndex]);
5236
+ _fnAdjustColumnSizing( oSettings );
5237
+
5238
+ if ( bRedraw === undefined || bRedraw )
5239
+ {
5240
+ this.fnDraw( false );
5241
+ }
5242
+ else if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
5243
+ {
5244
+ /* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
5245
+ this.oApi._fnScrollDraw(oSettings);
5246
+ }
5247
+ };
5248
+
5249
+
5250
+ /**
5251
+ * Quickly and simply clear a table
5252
+ * @param {bool} [bRedraw=true] redraw the table or not
5253
+ * @dtopt API
5254
+ *
5255
+ * @example
5256
+ * $(document).ready(function() {
5257
+ * var oTable = $('#example').dataTable();
5258
+ *
5259
+ * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
5260
+ * oTable.fnClearTable();
5261
+ * } );
5262
+ */
5263
+ this.fnClearTable = function( bRedraw )
5264
+ {
5265
+ /* Find settings from table node */
5266
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5267
+ _fnClearTable( oSettings );
5268
+
5269
+ if ( bRedraw === undefined || bRedraw )
5270
+ {
5271
+ _fnDraw( oSettings );
5272
+ }
5273
+ };
5274
+
5275
+
5276
+ /**
5277
+ * The exact opposite of 'opening' a row, this function will close any rows which
5278
+ * are currently 'open'.
5279
+ * @param {node} nTr the table row to 'close'
5280
+ * @returns {int} 0 on success, or 1 if failed (can't find the row)
5281
+ * @dtopt API
5282
+ *
5283
+ * @example
5284
+ * $(document).ready(function() {
5285
+ * var oTable;
5286
+ *
5287
+ * // 'open' an information row when a row is clicked on
5288
+ * $('#example tbody tr').click( function () {
5289
+ * if ( oTable.fnIsOpen(this) ) {
5290
+ * oTable.fnClose( this );
5291
+ * } else {
5292
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5293
+ * }
5294
+ * } );
5295
+ *
5296
+ * oTable = $('#example').dataTable();
5297
+ * } );
5298
+ */
5299
+ this.fnClose = function( nTr )
5300
+ {
5301
+ /* Find settings from table node */
5302
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5303
+
5304
+ for ( var i=0 ; i<oSettings.aoOpenRows.length ; i++ )
5305
+ {
5306
+ if ( oSettings.aoOpenRows[i].nParent == nTr )
5307
+ {
5308
+ var nTrParent = oSettings.aoOpenRows[i].nTr.parentNode;
5309
+ if ( nTrParent )
5310
+ {
5311
+ /* Remove it if it is currently on display */
5312
+ nTrParent.removeChild( oSettings.aoOpenRows[i].nTr );
5313
+ }
5314
+ oSettings.aoOpenRows.splice( i, 1 );
5315
+ return 0;
5316
+ }
5317
+ }
5318
+ return 1;
5319
+ };
5320
+
5321
+
5322
+ /**
5323
+ * Remove a row for the table
5324
+ * @param {mixed} mTarget The index of the row from aoData to be deleted, or
5325
+ * the TR element you want to delete
5326
+ * @param {function|null} [fnCallBack] Callback function
5327
+ * @param {bool} [bRedraw=true] Redraw the table or not
5328
+ * @returns {array} The row that was deleted
5329
+ * @dtopt API
5330
+ *
5331
+ * @example
5332
+ * $(document).ready(function() {
5333
+ * var oTable = $('#example').dataTable();
5334
+ *
5335
+ * // Immediately remove the first row
5336
+ * oTable.fnDeleteRow( 0 );
5337
+ * } );
5338
+ */
5339
+ this.fnDeleteRow = function( mTarget, fnCallBack, bRedraw )
5340
+ {
5341
+ /* Find settings from table node */
5342
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5343
+ var i, iLen, iAODataIndex;
5344
+
5345
+ iAODataIndex = (typeof mTarget === 'object') ?
5346
+ _fnNodeToDataIndex(oSettings, mTarget) : mTarget;
5347
+
5348
+ /* Return the data array from this row */
5349
+ var oData = oSettings.aoData.splice( iAODataIndex, 1 );
5350
+
5351
+ /* Update the _DT_RowIndex parameter */
5352
+ for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
5353
+ {
5354
+ if ( oSettings.aoData[i].nTr !== null )
5355
+ {
5356
+ oSettings.aoData[i].nTr._DT_RowIndex = i;
5357
+ }
5358
+ }
5359
+
5360
+ /* Remove the target row from the search array */
5361
+ var iDisplayIndex = $.inArray( iAODataIndex, oSettings.aiDisplay );
5362
+ oSettings.asDataSearch.splice( iDisplayIndex, 1 );
5363
+
5364
+ /* Delete from the display arrays */
5365
+ _fnDeleteIndex( oSettings.aiDisplayMaster, iAODataIndex );
5366
+ _fnDeleteIndex( oSettings.aiDisplay, iAODataIndex );
5367
+
5368
+ /* If there is a user callback function - call it */
5369
+ if ( typeof fnCallBack === "function" )
5370
+ {
5371
+ fnCallBack.call( this, oSettings, oData );
5372
+ }
5373
+
5374
+ /* Check for an 'overflow' they case for displaying the table */
5375
+ if ( oSettings._iDisplayStart >= oSettings.fnRecordsDisplay() )
5376
+ {
5377
+ oSettings._iDisplayStart -= oSettings._iDisplayLength;
5378
+ if ( oSettings._iDisplayStart < 0 )
5379
+ {
5380
+ oSettings._iDisplayStart = 0;
5381
+ }
5382
+ }
5383
+
5384
+ if ( bRedraw === undefined || bRedraw )
5385
+ {
5386
+ _fnCalculateEnd( oSettings );
5387
+ _fnDraw( oSettings );
5388
+ }
5389
+
5390
+ return oData;
5391
+ };
5392
+
5393
+
5394
+ /**
5395
+ * Restore the table to it's original state in the DOM by removing all of DataTables
5396
+ * enhancements, alterations to the DOM structure of the table and event listeners.
5397
+ * @param {boolean} [bRemove=false] Completely remove the table from the DOM
5398
+ * @dtopt API
5399
+ *
5400
+ * @example
5401
+ * $(document).ready(function() {
5402
+ * // This example is fairly pointless in reality, but shows how fnDestroy can be used
5403
+ * var oTable = $('#example').dataTable();
5404
+ * oTable.fnDestroy();
5405
+ * } );
5406
+ */
5407
+ this.fnDestroy = function ( bRemove )
5408
+ {
5409
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5410
+ var nOrig = oSettings.nTableWrapper.parentNode;
5411
+ var nBody = oSettings.nTBody;
5412
+ var i, iLen;
5413
+
5414
+ bRemove = (bRemove===undefined) ? false : bRemove;
5415
+
5416
+ /* Flag to note that the table is currently being destroyed - no action should be taken */
5417
+ oSettings.bDestroying = true;
5418
+
5419
+ /* Fire off the destroy callbacks for plug-ins etc */
5420
+ _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] );
5421
+
5422
+ /* If the table is not being removed, restore the hidden columns */
5423
+ if ( !bRemove )
5424
+ {
5425
+ for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
5426
+ {
5427
+ if ( oSettings.aoColumns[i].bVisible === false )
5428
+ {
5429
+ this.fnSetColumnVis( i, true );
5430
+ }
5431
+ }
5432
+ }
5433
+
5434
+ /* Blitz all DT events */
5435
+ $(oSettings.nTableWrapper).find('*').andSelf().unbind('.DT');
5436
+
5437
+ /* If there is an 'empty' indicator row, remove it */
5438
+ $('tbody>tr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove();
5439
+
5440
+ /* When scrolling we had to break the table up - restore it */
5441
+ if ( oSettings.nTable != oSettings.nTHead.parentNode )
5442
+ {
5443
+ $(oSettings.nTable).children('thead').remove();
5444
+ oSettings.nTable.appendChild( oSettings.nTHead );
5445
+ }
5446
+
5447
+ if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode )
5448
+ {
5449
+ $(oSettings.nTable).children('tfoot').remove();
5450
+ oSettings.nTable.appendChild( oSettings.nTFoot );
5451
+ }
5452
+
5453
+ /* Remove the DataTables generated nodes, events and classes */
5454
+ oSettings.nTable.parentNode.removeChild( oSettings.nTable );
5455
+ $(oSettings.nTableWrapper).remove();
5456
+
5457
+ oSettings.aaSorting = [];
5458
+ oSettings.aaSortingFixed = [];
5459
+ _fnSortingClasses( oSettings );
5460
+
5461
+ $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') );
5462
+
5463
+ $('th, td', oSettings.nTHead).removeClass( [
5464
+ oSettings.oClasses.sSortable,
5465
+ oSettings.oClasses.sSortableAsc,
5466
+ oSettings.oClasses.sSortableDesc,
5467
+ oSettings.oClasses.sSortableNone ].join(' ')
5468
+ );
5469
+ if ( oSettings.bJUI )
5470
+ {
5471
+ $('th span.'+oSettings.oClasses.sSortIcon
5472
+ + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove();
5473
+
5474
+ $('th, td', oSettings.nTHead).each( function () {
5475
+ var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this);
5476
+ var kids = jqWrapper.contents();
5477
+ $(this).append( kids );
5478
+ jqWrapper.remove();
5479
+ } );
5480
+ }
5481
+
5482
+ /* Add the TR elements back into the table in their original order */
5483
+ if ( !bRemove && oSettings.nTableReinsertBefore )
5484
+ {
5485
+ nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore );
5486
+ }
5487
+ else if ( !bRemove )
5488
+ {
5489
+ nOrig.appendChild( oSettings.nTable );
5490
+ }
5491
+
5492
+ for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
5493
+ {
5494
+ if ( oSettings.aoData[i].nTr !== null )
5495
+ {
5496
+ nBody.appendChild( oSettings.aoData[i].nTr );
5497
+ }
5498
+ }
5499
+
5500
+ /* Restore the width of the original table */
5501
+ if ( oSettings.oFeatures.bAutoWidth === true )
5502
+ {
5503
+ oSettings.nTable.style.width = _fnStringToCss(oSettings.sDestroyWidth);
5504
+ }
5505
+
5506
+ /* If the were originally stripe classes - then we add them back here. Note
5507
+ * this is not fool proof (for example if not all rows had stripe classes - but
5508
+ * it's a good effort without getting carried away
5509
+ */
5510
+ iLen = oSettings.asDestroyStripes.length;
5511
+ if (iLen)
5512
+ {
5513
+ var anRows = $(nBody).children('tr');
5514
+ for ( i=0 ; i<iLen ; i++ )
5515
+ {
5516
+ anRows.filter(':nth-child(' + iLen + 'n + ' + i + ')').addClass( oSettings.asDestroyStripes[i] );
5517
+ }
5518
+ }
5519
+
5520
+ /* Remove the settings object from the settings array */
5521
+ for ( i=0, iLen=DataTable.settings.length ; i<iLen ; i++ )
5522
+ {
5523
+ if ( DataTable.settings[i] == oSettings )
5524
+ {
5525
+ DataTable.settings.splice( i, 1 );
5526
+ }
5527
+ }
5528
+
5529
+ /* End it all */
5530
+ oSettings = null;
5531
+ oInit = null;
5532
+ };
5533
+
5534
+
5535
+ /**
5536
+ * Redraw the table
5537
+ * @param {bool} [bComplete=true] Re-filter and resort (if enabled) the table before the draw.
5538
+ * @dtopt API
5539
+ *
5540
+ * @example
5541
+ * $(document).ready(function() {
5542
+ * var oTable = $('#example').dataTable();
5543
+ *
5544
+ * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
5545
+ * oTable.fnDraw();
5546
+ * } );
5547
+ */
5548
+ this.fnDraw = function( bComplete )
5549
+ {
5550
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5551
+ if ( bComplete === false )
5552
+ {
5553
+ _fnCalculateEnd( oSettings );
5554
+ _fnDraw( oSettings );
5555
+ }
5556
+ else
5557
+ {
5558
+ _fnReDraw( oSettings );
5559
+ }
5560
+ };
5561
+
5562
+
5563
+ /**
5564
+ * Filter the input based on data
5565
+ * @param {string} sInput String to filter the table on
5566
+ * @param {int|null} [iColumn] Column to limit filtering to
5567
+ * @param {bool} [bRegex=false] Treat as regular expression or not
5568
+ * @param {bool} [bSmart=true] Perform smart filtering or not
5569
+ * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
5570
+ * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
5571
+ * @dtopt API
5572
+ *
5573
+ * @example
5574
+ * $(document).ready(function() {
5575
+ * var oTable = $('#example').dataTable();
5576
+ *
5577
+ * // Sometime later - filter...
5578
+ * oTable.fnFilter( 'test string' );
5579
+ * } );
5580
+ */
5581
+ this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
5582
+ {
5583
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5584
+
5585
+ if ( !oSettings.oFeatures.bFilter )
5586
+ {
5587
+ return;
5588
+ }
5589
+
5590
+ if ( bRegex === undefined || bRegex === null )
5591
+ {
5592
+ bRegex = false;
5593
+ }
5594
+
5595
+ if ( bSmart === undefined || bSmart === null )
5596
+ {
5597
+ bSmart = true;
5598
+ }
5599
+
5600
+ if ( bShowGlobal === undefined || bShowGlobal === null )
5601
+ {
5602
+ bShowGlobal = true;
5603
+ }
5604
+
5605
+ if ( bCaseInsensitive === undefined || bCaseInsensitive === null )
5606
+ {
5607
+ bCaseInsensitive = true;
5608
+ }
5609
+
5610
+ if ( iColumn === undefined || iColumn === null )
5611
+ {
5612
+ /* Global filter */
5613
+ _fnFilterComplete( oSettings, {
5614
+ "sSearch":sInput+"",
5615
+ "bRegex": bRegex,
5616
+ "bSmart": bSmart,
5617
+ "bCaseInsensitive": bCaseInsensitive
5618
+ }, 1 );
5619
+
5620
+ if ( bShowGlobal && oSettings.aanFeatures.f )
5621
+ {
5622
+ var n = oSettings.aanFeatures.f;
5623
+ for ( var i=0, iLen=n.length ; i<iLen ; i++ )
5624
+ {
5625
+ // IE9 throws an 'unknown error' if document.activeElement is used
5626
+ // inside an iframe or frame...
5627
+ try {
5628
+ if ( n[i]._DT_Input != document.activeElement )
5629
+ {
5630
+ $(n[i]._DT_Input).val( sInput );
5631
+ }
5632
+ }
5633
+ catch ( e ) {
5634
+ $(n[i]._DT_Input).val( sInput );
5635
+ }
5636
+ }
5637
+ }
5638
+ }
5639
+ else
5640
+ {
5641
+ /* Single column filter */
5642
+ $.extend( oSettings.aoPreSearchCols[ iColumn ], {
5643
+ "sSearch": sInput+"",
5644
+ "bRegex": bRegex,
5645
+ "bSmart": bSmart,
5646
+ "bCaseInsensitive": bCaseInsensitive
5647
+ } );
5648
+ _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 );
5649
+ }
5650
+ };
5651
+
5652
+
5653
+ /**
5654
+ * Get the data for the whole table, an individual row or an individual cell based on the
5655
+ * provided parameters.
5656
+ * @param {int|node} [mRow] A TR row node, TD/TH cell node or an integer. If given as
5657
+ * a TR node then the data source for the whole row will be returned. If given as a
5658
+ * TD/TH cell node then iCol will be automatically calculated and the data for the
5659
+ * cell returned. If given as an integer, then this is treated as the aoData internal
5660
+ * data index for the row (see fnGetPosition) and the data for that row used.
5661
+ * @param {int} [iCol] Optional column index that you want the data of.
5662
+ * @returns {array|object|string} If mRow is undefined, then the data for all rows is
5663
+ * returned. If mRow is defined, just data for that row, and is iCol is
5664
+ * defined, only data for the designated cell is returned.
5665
+ * @dtopt API
5666
+ *
5667
+ * @example
5668
+ * // Row data
5669
+ * $(document).ready(function() {
5670
+ * oTable = $('#example').dataTable();
5671
+ *
5672
+ * oTable.$('tr').click( function () {
5673
+ * var data = oTable.fnGetData( this );
5674
+ * // ... do something with the array / object of data for the row
5675
+ * } );
5676
+ * } );
5677
+ *
5678
+ * @example
5679
+ * // Individual cell data
5680
+ * $(document).ready(function() {
5681
+ * oTable = $('#example').dataTable();
5682
+ *
5683
+ * oTable.$('td').click( function () {
5684
+ * var sData = oTable.fnGetData( this );
5685
+ * alert( 'The cell clicked on had the value of '+sData );
5686
+ * } );
5687
+ * } );
5688
+ */
5689
+ this.fnGetData = function( mRow, iCol )
5690
+ {
5691
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5692
+
5693
+ if ( mRow !== undefined )
5694
+ {
5695
+ var iRow = mRow;
5696
+ if ( typeof mRow === 'object' )
5697
+ {
5698
+ var sNode = mRow.nodeName.toLowerCase();
5699
+ if (sNode === "tr" )
5700
+ {
5701
+ iRow = _fnNodeToDataIndex(oSettings, mRow);
5702
+ }
5703
+ else if ( sNode === "td" )
5704
+ {
5705
+ iRow = _fnNodeToDataIndex(oSettings, mRow.parentNode);
5706
+ iCol = _fnNodeToColumnIndex( oSettings, iRow, mRow );
5707
+ }
5708
+ }
5709
+
5710
+ if ( iCol !== undefined )
5711
+ {
5712
+ return _fnGetCellData( oSettings, iRow, iCol, '' );
5713
+ }
5714
+ return (oSettings.aoData[iRow]!==undefined) ?
5715
+ oSettings.aoData[iRow]._aData : null;
5716
+ }
5717
+ return _fnGetDataMaster( oSettings );
5718
+ };
5719
+
5720
+
5721
+ /**
5722
+ * Get an array of the TR nodes that are used in the table's body. Note that you will
5723
+ * typically want to use the '$' API method in preference to this as it is more
5724
+ * flexible.
5725
+ * @param {int} [iRow] Optional row index for the TR element you want
5726
+ * @returns {array|node} If iRow is undefined, returns an array of all TR elements
5727
+ * in the table's body, or iRow is defined, just the TR element requested.
5728
+ * @dtopt API
5729
+ *
5730
+ * @example
5731
+ * $(document).ready(function() {
5732
+ * var oTable = $('#example').dataTable();
5733
+ *
5734
+ * // Get the nodes from the table
5735
+ * var nNodes = oTable.fnGetNodes( );
5736
+ * } );
5737
+ */
5738
+ this.fnGetNodes = function( iRow )
5739
+ {
5740
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5741
+
5742
+ if ( iRow !== undefined ) {
5743
+ return (oSettings.aoData[iRow]!==undefined) ?
5744
+ oSettings.aoData[iRow].nTr : null;
5745
+ }
5746
+ return _fnGetTrNodes( oSettings );
5747
+ };
5748
+
5749
+
5750
+ /**
5751
+ * Get the array indexes of a particular cell from it's DOM element
5752
+ * and column index including hidden columns
5753
+ * @param {node} nNode this can either be a TR, TD or TH in the table's body
5754
+ * @returns {int} If nNode is given as a TR, then a single index is returned, or
5755
+ * if given as a cell, an array of [row index, column index (visible),
5756
+ * column index (all)] is given.
5757
+ * @dtopt API
5758
+ *
5759
+ * @example
5760
+ * $(document).ready(function() {
5761
+ * $('#example tbody td').click( function () {
5762
+ * // Get the position of the current data from the node
5763
+ * var aPos = oTable.fnGetPosition( this );
5764
+ *
5765
+ * // Get the data array for this row
5766
+ * var aData = oTable.fnGetData( aPos[0] );
5767
+ *
5768
+ * // Update the data array and return the value
5769
+ * aData[ aPos[1] ] = 'clicked';
5770
+ * this.innerHTML = 'clicked';
5771
+ * } );
5772
+ *
5773
+ * // Init DataTables
5774
+ * oTable = $('#example').dataTable();
5775
+ * } );
5776
+ */
5777
+ this.fnGetPosition = function( nNode )
5778
+ {
5779
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5780
+ var sNodeName = nNode.nodeName.toUpperCase();
5781
+
5782
+ if ( sNodeName == "TR" )
5783
+ {
5784
+ return _fnNodeToDataIndex(oSettings, nNode);
5785
+ }
5786
+ else if ( sNodeName == "TD" || sNodeName == "TH" )
5787
+ {
5788
+ var iDataIndex = _fnNodeToDataIndex( oSettings, nNode.parentNode );
5789
+ var iColumnIndex = _fnNodeToColumnIndex( oSettings, iDataIndex, nNode );
5790
+ return [ iDataIndex, _fnColumnIndexToVisible(oSettings, iColumnIndex ), iColumnIndex ];
5791
+ }
5792
+ return null;
5793
+ };
5794
+
5795
+
5796
+ /**
5797
+ * Check to see if a row is 'open' or not.
5798
+ * @param {node} nTr the table row to check
5799
+ * @returns {boolean} true if the row is currently open, false otherwise
5800
+ * @dtopt API
5801
+ *
5802
+ * @example
5803
+ * $(document).ready(function() {
5804
+ * var oTable;
5805
+ *
5806
+ * // 'open' an information row when a row is clicked on
5807
+ * $('#example tbody tr').click( function () {
5808
+ * if ( oTable.fnIsOpen(this) ) {
5809
+ * oTable.fnClose( this );
5810
+ * } else {
5811
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5812
+ * }
5813
+ * } );
5814
+ *
5815
+ * oTable = $('#example').dataTable();
5816
+ * } );
5817
+ */
5818
+ this.fnIsOpen = function( nTr )
5819
+ {
5820
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5821
+ var aoOpenRows = oSettings.aoOpenRows;
5822
+
5823
+ for ( var i=0 ; i<oSettings.aoOpenRows.length ; i++ )
5824
+ {
5825
+ if ( oSettings.aoOpenRows[i].nParent == nTr )
5826
+ {
5827
+ return true;
5828
+ }
5829
+ }
5830
+ return false;
5831
+ };
5832
+
5833
+
5834
+ /**
5835
+ * This function will place a new row directly after a row which is currently
5836
+ * on display on the page, with the HTML contents that is passed into the
5837
+ * function. This can be used, for example, to ask for confirmation that a
5838
+ * particular record should be deleted.
5839
+ * @param {node} nTr The table row to 'open'
5840
+ * @param {string|node|jQuery} mHtml The HTML to put into the row
5841
+ * @param {string} sClass Class to give the new TD cell
5842
+ * @returns {node} The row opened. Note that if the table row passed in as the
5843
+ * first parameter, is not found in the table, this method will silently
5844
+ * return.
5845
+ * @dtopt API
5846
+ *
5847
+ * @example
5848
+ * $(document).ready(function() {
5849
+ * var oTable;
5850
+ *
5851
+ * // 'open' an information row when a row is clicked on
5852
+ * $('#example tbody tr').click( function () {
5853
+ * if ( oTable.fnIsOpen(this) ) {
5854
+ * oTable.fnClose( this );
5855
+ * } else {
5856
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
5857
+ * }
5858
+ * } );
5859
+ *
5860
+ * oTable = $('#example').dataTable();
5861
+ * } );
5862
+ */
5863
+ this.fnOpen = function( nTr, mHtml, sClass )
5864
+ {
5865
+ /* Find settings from table node */
5866
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5867
+
5868
+ /* Check that the row given is in the table */
5869
+ var nTableRows = _fnGetTrNodes( oSettings );
5870
+ if ( $.inArray(nTr, nTableRows) === -1 )
5871
+ {
5872
+ return;
5873
+ }
5874
+
5875
+ /* the old open one if there is one */
5876
+ this.fnClose( nTr );
5877
+
5878
+ var nNewRow = document.createElement("tr");
5879
+ var nNewCell = document.createElement("td");
5880
+ nNewRow.appendChild( nNewCell );
5881
+ nNewCell.className = sClass;
5882
+ nNewCell.colSpan = _fnVisbleColumns( oSettings );
5883
+
5884
+ if (typeof mHtml === "string")
5885
+ {
5886
+ nNewCell.innerHTML = mHtml;
5887
+ }
5888
+ else
5889
+ {
5890
+ $(nNewCell).html( mHtml );
5891
+ }
5892
+
5893
+ /* If the nTr isn't on the page at the moment - then we don't insert at the moment */
5894
+ var nTrs = $('tr', oSettings.nTBody);
5895
+ if ( $.inArray(nTr, nTrs) != -1 )
5896
+ {
5897
+ $(nNewRow).insertAfter(nTr);
5898
+ }
5899
+
5900
+ oSettings.aoOpenRows.push( {
5901
+ "nTr": nNewRow,
5902
+ "nParent": nTr
5903
+ } );
5904
+
5905
+ return nNewRow;
5906
+ };
5907
+
5908
+
5909
+ /**
5910
+ * Change the pagination - provides the internal logic for pagination in a simple API
5911
+ * function. With this function you can have a DataTables table go to the next,
5912
+ * previous, first or last pages.
5913
+ * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
5914
+ * or page number to jump to (integer), note that page 0 is the first page.
5915
+ * @param {bool} [bRedraw=true] Redraw the table or not
5916
+ * @dtopt API
5917
+ *
5918
+ * @example
5919
+ * $(document).ready(function() {
5920
+ * var oTable = $('#example').dataTable();
5921
+ * oTable.fnPageChange( 'next' );
5922
+ * } );
5923
+ */
5924
+ this.fnPageChange = function ( mAction, bRedraw )
5925
+ {
5926
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5927
+ _fnPageChange( oSettings, mAction );
5928
+ _fnCalculateEnd( oSettings );
5929
+
5930
+ if ( bRedraw === undefined || bRedraw )
5931
+ {
5932
+ _fnDraw( oSettings );
5933
+ }
5934
+ };
5935
+
5936
+
5937
+ /**
5938
+ * Show a particular column
5939
+ * @param {int} iCol The column whose display should be changed
5940
+ * @param {bool} bShow Show (true) or hide (false) the column
5941
+ * @param {bool} [bRedraw=true] Redraw the table or not
5942
+ * @dtopt API
5943
+ *
5944
+ * @example
5945
+ * $(document).ready(function() {
5946
+ * var oTable = $('#example').dataTable();
5947
+ *
5948
+ * // Hide the second column after initialisation
5949
+ * oTable.fnSetColumnVis( 1, false );
5950
+ * } );
5951
+ */
5952
+ this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
5953
+ {
5954
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
5955
+ var i, iLen;
5956
+ var aoColumns = oSettings.aoColumns;
5957
+ var aoData = oSettings.aoData;
5958
+ var nTd, bAppend, iBefore;
5959
+
5960
+ /* No point in doing anything if we are requesting what is already true */
5961
+ if ( aoColumns[iCol].bVisible == bShow )
5962
+ {
5963
+ return;
5964
+ }
5965
+
5966
+ /* Show the column */
5967
+ if ( bShow )
5968
+ {
5969
+ var iInsert = 0;
5970
+ for ( i=0 ; i<iCol ; i++ )
5971
+ {
5972
+ if ( aoColumns[i].bVisible )
5973
+ {
5974
+ iInsert++;
5975
+ }
5976
+ }
5977
+
5978
+ /* Need to decide if we should use appendChild or insertBefore */
5979
+ bAppend = (iInsert >= _fnVisbleColumns( oSettings ));
5980
+
5981
+ /* Which coloumn should we be inserting before? */
5982
+ if ( !bAppend )
5983
+ {
5984
+ for ( i=iCol ; i<aoColumns.length ; i++ )
5985
+ {
5986
+ if ( aoColumns[i].bVisible )
5987
+ {
5988
+ iBefore = i;
5989
+ break;
5990
+ }
5991
+ }
5992
+ }
5993
+
5994
+ for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
5995
+ {
5996
+ if ( aoData[i].nTr !== null )
5997
+ {
5998
+ if ( bAppend )
5999
+ {
6000
+ aoData[i].nTr.appendChild(
6001
+ aoData[i]._anHidden[iCol]
6002
+ );
6003
+ }
6004
+ else
6005
+ {
6006
+ aoData[i].nTr.insertBefore(
6007
+ aoData[i]._anHidden[iCol],
6008
+ _fnGetTdNodes( oSettings, i )[iBefore] );
6009
+ }
6010
+ }
6011
+ }
6012
+ }
6013
+ else
6014
+ {
6015
+ /* Remove a column from display */
6016
+ for ( i=0, iLen=aoData.length ; i<iLen ; i++ )
6017
+ {
6018
+ if ( aoData[i].nTr !== null )
6019
+ {
6020
+ nTd = _fnGetTdNodes( oSettings, i )[iCol];
6021
+ aoData[i]._anHidden[iCol] = nTd;
6022
+ nTd.parentNode.removeChild( nTd );
6023
+ }
6024
+ }
6025
+ }
6026
+
6027
+ /* Clear to set the visible flag */
6028
+ aoColumns[iCol].bVisible = bShow;
6029
+
6030
+ /* Redraw the header and footer based on the new column visibility */
6031
+ _fnDrawHead( oSettings, oSettings.aoHeader );
6032
+ if ( oSettings.nTFoot )
6033
+ {
6034
+ _fnDrawHead( oSettings, oSettings.aoFooter );
6035
+ }
6036
+
6037
+ /* If there are any 'open' rows, then we need to alter the colspan for this col change */
6038
+ for ( i=0, iLen=oSettings.aoOpenRows.length ; i<iLen ; i++ )
6039
+ {
6040
+ oSettings.aoOpenRows[i].nTr.colSpan = _fnVisbleColumns( oSettings );
6041
+ }
6042
+
6043
+ /* Do a redraw incase anything depending on the table columns needs it
6044
+ * (built-in: scrolling)
6045
+ */
6046
+ if ( bRedraw === undefined || bRedraw )
6047
+ {
6048
+ _fnAdjustColumnSizing( oSettings );
6049
+ _fnDraw( oSettings );
6050
+ }
6051
+
6052
+ _fnSaveState( oSettings );
6053
+ };
6054
+
6055
+
6056
+ /**
6057
+ * Get the settings for a particular table for external manipulation
6058
+ * @returns {object} DataTables settings object. See
6059
+ * {@link DataTable.models.oSettings}
6060
+ * @dtopt API
6061
+ *
6062
+ * @example
6063
+ * $(document).ready(function() {
6064
+ * var oTable = $('#example').dataTable();
6065
+ * var oSettings = oTable.fnSettings();
6066
+ *
6067
+ * // Show an example parameter from the settings
6068
+ * alert( oSettings._iDisplayStart );
6069
+ * } );
6070
+ */
6071
+ this.fnSettings = function()
6072
+ {
6073
+ return _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
6074
+ };
6075
+
6076
+
6077
+ /**
6078
+ * Sort the table by a particular column
6079
+ * @param {int} iCol the data index to sort on. Note that this will not match the
6080
+ * 'display index' if you have hidden data entries
6081
+ * @dtopt API
6082
+ *
6083
+ * @example
6084
+ * $(document).ready(function() {
6085
+ * var oTable = $('#example').dataTable();
6086
+ *
6087
+ * // Sort immediately with columns 0 and 1
6088
+ * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
6089
+ * } );
6090
+ */
6091
+ this.fnSort = function( aaSort )
6092
+ {
6093
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
6094
+ oSettings.aaSorting = aaSort;
6095
+ _fnSort( oSettings );
6096
+ };
6097
+
6098
+
6099
+ /**
6100
+ * Attach a sort listener to an element for a given column
6101
+ * @param {node} nNode the element to attach the sort listener to
6102
+ * @param {int} iColumn the column that a click on this node will sort on
6103
+ * @param {function} [fnCallback] callback function when sort is run
6104
+ * @dtopt API
6105
+ *
6106
+ * @example
6107
+ * $(document).ready(function() {
6108
+ * var oTable = $('#example').dataTable();
6109
+ *
6110
+ * // Sort on column 1, when 'sorter' is clicked on
6111
+ * oTable.fnSortListener( document.getElementById('sorter'), 1 );
6112
+ * } );
6113
+ */
6114
+ this.fnSortListener = function( nNode, iColumn, fnCallback )
6115
+ {
6116
+ _fnSortAttachListener( _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ), nNode, iColumn,
6117
+ fnCallback );
6118
+ };
6119
+
6120
+
6121
+ /**
6122
+ * Update a table cell or row - this method will accept either a single value to
6123
+ * update the cell with, an array of values with one element for each column or
6124
+ * an object in the same format as the original data source. The function is
6125
+ * self-referencing in order to make the multi column updates easier.
6126
+ * @param {object|array|string} mData Data to update the cell/row with
6127
+ * @param {node|int} mRow TR element you want to update or the aoData index
6128
+ * @param {int} [iColumn] The column to update (not used of mData is an array or object)
6129
+ * @param {bool} [bRedraw=true] Redraw the table or not
6130
+ * @param {bool} [bAction=true] Perform pre-draw actions or not
6131
+ * @returns {int} 0 on success, 1 on error
6132
+ * @dtopt API
6133
+ *
6134
+ * @example
6135
+ * $(document).ready(function() {
6136
+ * var oTable = $('#example').dataTable();
6137
+ * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
6138
+ * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], 1, 0 ); // Row
6139
+ * } );
6140
+ */
6141
+ this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
6142
+ {
6143
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
6144
+ var i, iLen, sDisplay;
6145
+ var iRow = (typeof mRow === 'object') ?
6146
+ _fnNodeToDataIndex(oSettings, mRow) : mRow;
6147
+
6148
+ if ( $.isArray(mData) && iColumn === undefined )
6149
+ {
6150
+ /* Array update - update the whole row */
6151
+ oSettings.aoData[iRow]._aData = mData.slice();
6152
+
6153
+ /* Flag to the function that we are recursing */
6154
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
6155
+ {
6156
+ this.fnUpdate( _fnGetCellData( oSettings, iRow, i ), iRow, i, false, false );
6157
+ }
6158
+ }
6159
+ else if ( $.isPlainObject(mData) && iColumn === undefined )
6160
+ {
6161
+ /* Object update - update the whole row - assume the developer gets the object right */
6162
+ oSettings.aoData[iRow]._aData = $.extend( true, {}, mData );
6163
+
6164
+ for ( i=0 ; i<oSettings.aoColumns.length ; i++ )
6165
+ {
6166
+ this.fnUpdate( _fnGetCellData( oSettings, iRow, i ), iRow, i, false, false );
6167
+ }
6168
+ }
6169
+ else
6170
+ {
6171
+ /* Individual cell update */
6172
+ _fnSetCellData( oSettings, iRow, iColumn, mData );
6173
+ sDisplay = _fnGetCellData( oSettings, iRow, iColumn, 'display' );
6174
+
6175
+ var oCol = oSettings.aoColumns[iColumn];
6176
+ if ( oCol.fnRender !== null )
6177
+ {
6178
+ sDisplay = _fnRender( oSettings, iRow, iColumn );
6179
+ if ( oCol.bUseRendered )
6180
+ {
6181
+ _fnSetCellData( oSettings, iRow, iColumn, sDisplay );
6182
+ }
6183
+ }
6184
+
6185
+ if ( oSettings.aoData[iRow].nTr !== null )
6186
+ {
6187
+ /* Do the actual HTML update */
6188
+ _fnGetTdNodes( oSettings, iRow )[iColumn].innerHTML = sDisplay;
6189
+ }
6190
+ }
6191
+
6192
+ /* Modify the search index for this row (strictly this is likely not needed, since fnReDraw
6193
+ * will rebuild the search array - however, the redraw might be disabled by the user)
6194
+ */
6195
+ var iDisplayIndex = $.inArray( iRow, oSettings.aiDisplay );
6196
+ oSettings.asDataSearch[iDisplayIndex] = _fnBuildSearchRow(
6197
+ oSettings,
6198
+ _fnGetRowData( oSettings, iRow, 'filter', _fnGetColumns( oSettings, 'bSearchable' ) )
6199
+ );
6200
+
6201
+ /* Perform pre-draw actions */
6202
+ if ( bAction === undefined || bAction )
6203
+ {
6204
+ _fnAdjustColumnSizing( oSettings );
6205
+ }
6206
+
6207
+ /* Redraw the table */
6208
+ if ( bRedraw === undefined || bRedraw )
6209
+ {
6210
+ _fnReDraw( oSettings );
6211
+ }
6212
+ return 0;
6213
+ };
6214
+
6215
+
6216
+ /**
6217
+ * Provide a common method for plug-ins to check the version of DataTables being used, in order
6218
+ * to ensure compatibility.
6219
+ * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
6220
+ * formats "X" and "X.Y" are also acceptable.
6221
+ * @returns {boolean} true if this version of DataTables is greater or equal to the required
6222
+ * version, or false if this version of DataTales is not suitable
6223
+ * @method
6224
+ * @dtopt API
6225
+ *
6226
+ * @example
6227
+ * $(document).ready(function() {
6228
+ * var oTable = $('#example').dataTable();
6229
+ * alert( oTable.fnVersionCheck( '1.9.0' ) );
6230
+ * } );
6231
+ */
6232
+ this.fnVersionCheck = DataTable.ext.fnVersionCheck;
6233
+
6234
+
6235
+ /*
6236
+ * This is really a good bit rubbish this method of exposing the internal methods
6237
+ * publicly... - To be fixed in 2.0 using methods on the prototype
6238
+ */
6239
+
6240
+
6241
+ /**
6242
+ * Create a wrapper function for exporting an internal functions to an external API.
6243
+ * @param {string} sFunc API function name
6244
+ * @returns {function} wrapped function
6245
+ * @memberof DataTable#oApi
6246
+ */
6247
+ function _fnExternApiFunc (sFunc)
6248
+ {
6249
+ return function() {
6250
+ var aArgs = [_fnSettingsFromNode(this[DataTable.ext.iApiIndex])].concat(
6251
+ Array.prototype.slice.call(arguments) );
6252
+ return DataTable.ext.oApi[sFunc].apply( this, aArgs );
6253
+ };
6254
+ }
6255
+
6256
+
6257
+ /**
6258
+ * Reference to internal functions for use by plug-in developers. Note that these
6259
+ * methods are references to internal functions and are considered to be private.
6260
+ * If you use these methods, be aware that they are liable to change between versions
6261
+ * (check the upgrade notes).
6262
+ * @namespace
6263
+ */
6264
+ this.oApi = {
6265
+ "_fnExternApiFunc": _fnExternApiFunc,
6266
+ "_fnInitialise": _fnInitialise,
6267
+ "_fnInitComplete": _fnInitComplete,
6268
+ "_fnLanguageCompat": _fnLanguageCompat,
6269
+ "_fnAddColumn": _fnAddColumn,
6270
+ "_fnColumnOptions": _fnColumnOptions,
6271
+ "_fnAddData": _fnAddData,
6272
+ "_fnCreateTr": _fnCreateTr,
6273
+ "_fnGatherData": _fnGatherData,
6274
+ "_fnBuildHead": _fnBuildHead,
6275
+ "_fnDrawHead": _fnDrawHead,
6276
+ "_fnDraw": _fnDraw,
6277
+ "_fnReDraw": _fnReDraw,
6278
+ "_fnAjaxUpdate": _fnAjaxUpdate,
6279
+ "_fnAjaxParameters": _fnAjaxParameters,
6280
+ "_fnAjaxUpdateDraw": _fnAjaxUpdateDraw,
6281
+ "_fnServerParams": _fnServerParams,
6282
+ "_fnAddOptionsHtml": _fnAddOptionsHtml,
6283
+ "_fnFeatureHtmlTable": _fnFeatureHtmlTable,
6284
+ "_fnScrollDraw": _fnScrollDraw,
6285
+ "_fnAdjustColumnSizing": _fnAdjustColumnSizing,
6286
+ "_fnFeatureHtmlFilter": _fnFeatureHtmlFilter,
6287
+ "_fnFilterComplete": _fnFilterComplete,
6288
+ "_fnFilterCustom": _fnFilterCustom,
6289
+ "_fnFilterColumn": _fnFilterColumn,
6290
+ "_fnFilter": _fnFilter,
6291
+ "_fnBuildSearchArray": _fnBuildSearchArray,
6292
+ "_fnBuildSearchRow": _fnBuildSearchRow,
6293
+ "_fnFilterCreateSearch": _fnFilterCreateSearch,
6294
+ "_fnDataToSearch": _fnDataToSearch,
6295
+ "_fnSort": _fnSort,
6296
+ "_fnSortAttachListener": _fnSortAttachListener,
6297
+ "_fnSortingClasses": _fnSortingClasses,
6298
+ "_fnFeatureHtmlPaginate": _fnFeatureHtmlPaginate,
6299
+ "_fnPageChange": _fnPageChange,
6300
+ "_fnFeatureHtmlInfo": _fnFeatureHtmlInfo,
6301
+ "_fnUpdateInfo": _fnUpdateInfo,
6302
+ "_fnFeatureHtmlLength": _fnFeatureHtmlLength,
6303
+ "_fnFeatureHtmlProcessing": _fnFeatureHtmlProcessing,
6304
+ "_fnProcessingDisplay": _fnProcessingDisplay,
6305
+ "_fnVisibleToColumnIndex": _fnVisibleToColumnIndex,
6306
+ "_fnColumnIndexToVisible": _fnColumnIndexToVisible,
6307
+ "_fnNodeToDataIndex": _fnNodeToDataIndex,
6308
+ "_fnVisbleColumns": _fnVisbleColumns,
6309
+ "_fnCalculateEnd": _fnCalculateEnd,
6310
+ "_fnConvertToWidth": _fnConvertToWidth,
6311
+ "_fnCalculateColumnWidths": _fnCalculateColumnWidths,
6312
+ "_fnScrollingWidthAdjust": _fnScrollingWidthAdjust,
6313
+ "_fnGetWidestNode": _fnGetWidestNode,
6314
+ "_fnGetMaxLenString": _fnGetMaxLenString,
6315
+ "_fnStringToCss": _fnStringToCss,
6316
+ "_fnDetectType": _fnDetectType,
6317
+ "_fnSettingsFromNode": _fnSettingsFromNode,
6318
+ "_fnGetDataMaster": _fnGetDataMaster,
6319
+ "_fnGetTrNodes": _fnGetTrNodes,
6320
+ "_fnGetTdNodes": _fnGetTdNodes,
6321
+ "_fnEscapeRegex": _fnEscapeRegex,
6322
+ "_fnDeleteIndex": _fnDeleteIndex,
6323
+ "_fnReOrderIndex": _fnReOrderIndex,
6324
+ "_fnColumnOrdering": _fnColumnOrdering,
6325
+ "_fnLog": _fnLog,
6326
+ "_fnClearTable": _fnClearTable,
6327
+ "_fnSaveState": _fnSaveState,
6328
+ "_fnLoadState": _fnLoadState,
6329
+ "_fnCreateCookie": _fnCreateCookie,
6330
+ "_fnReadCookie": _fnReadCookie,
6331
+ "_fnDetectHeader": _fnDetectHeader,
6332
+ "_fnGetUniqueThs": _fnGetUniqueThs,
6333
+ "_fnScrollBarWidth": _fnScrollBarWidth,
6334
+ "_fnApplyToChildren": _fnApplyToChildren,
6335
+ "_fnMap": _fnMap,
6336
+ "_fnGetRowData": _fnGetRowData,
6337
+ "_fnGetCellData": _fnGetCellData,
6338
+ "_fnSetCellData": _fnSetCellData,
6339
+ "_fnGetObjectDataFn": _fnGetObjectDataFn,
6340
+ "_fnSetObjectDataFn": _fnSetObjectDataFn,
6341
+ "_fnApplyColumnDefs": _fnApplyColumnDefs,
6342
+ "_fnBindAction": _fnBindAction,
6343
+ "_fnExtend": _fnExtend,
6344
+ "_fnCallbackReg": _fnCallbackReg,
6345
+ "_fnCallbackFire": _fnCallbackFire,
6346
+ "_fnJsonString": _fnJsonString,
6347
+ "_fnRender": _fnRender,
6348
+ "_fnNodeToColumnIndex": _fnNodeToColumnIndex,
6349
+ "_fnInfoMacros": _fnInfoMacros,
6350
+ "_fnBrowserDetect": _fnBrowserDetect,
6351
+ "_fnGetColumns": _fnGetColumns
6352
+ };
6353
+
6354
+ $.extend( DataTable.ext.oApi, this.oApi );
6355
+
6356
+ for ( var sFunc in DataTable.ext.oApi )
6357
+ {
6358
+ if ( sFunc )
6359
+ {
6360
+ this[sFunc] = _fnExternApiFunc(sFunc);
6361
+ }
6362
+ }
6363
+
6364
+
6365
+ var _that = this;
6366
+ this.each(function() {
6367
+ var i=0, iLen, j, jLen, k, kLen;
6368
+ var sId = this.getAttribute( 'id' );
6369
+ var bInitHandedOff = false;
6370
+ var bUsePassedData = false;
6371
+
6372
+
6373
+ /* Sanity check */
6374
+ if ( this.nodeName.toLowerCase() != 'table' )
6375
+ {
6376
+ _fnLog( null, 0, "Attempted to initialise DataTables on a node which is not a "+
6377
+ "table: "+this.nodeName );
6378
+ return;
6379
+ }
6380
+
6381
+ /* Check to see if we are re-initialising a table */
6382
+ for ( i=0, iLen=DataTable.settings.length ; i<iLen ; i++ )
6383
+ {
6384
+ /* Base check on table node */
6385
+ if ( DataTable.settings[i].nTable == this )
6386
+ {
6387
+ if ( oInit === undefined || oInit.bRetrieve )
6388
+ {
6389
+ return DataTable.settings[i].oInstance;
6390
+ }
6391
+ else if ( oInit.bDestroy )
6392
+ {
6393
+ DataTable.settings[i].oInstance.fnDestroy();
6394
+ break;
6395
+ }
6396
+ else
6397
+ {
6398
+ _fnLog( DataTable.settings[i], 0, "Cannot reinitialise DataTable.\n\n"+
6399
+ "To retrieve the DataTables object for this table, pass no arguments or see "+
6400
+ "the docs for bRetrieve and bDestroy" );
6401
+ return;
6402
+ }
6403
+ }
6404
+
6405
+ /* If the element we are initialising has the same ID as a table which was previously
6406
+ * initialised, but the table nodes don't match (from before) then we destroy the old
6407
+ * instance by simply deleting it. This is under the assumption that the table has been
6408
+ * destroyed by other methods. Anyone using non-id selectors will need to do this manually
6409
+ */
6410
+ if ( DataTable.settings[i].sTableId == this.id )
6411
+ {
6412
+ DataTable.settings.splice( i, 1 );
6413
+ break;
6414
+ }
6415
+ }
6416
+
6417
+ /* Ensure the table has an ID - required for accessibility */
6418
+ if ( sId === null || sId === "" )
6419
+ {
6420
+ sId = "DataTables_Table_"+(DataTable.ext._oExternConfig.iNextUnique++);
6421
+ this.id = sId;
6422
+ }
6423
+
6424
+ /* Create the settings object for this table and set some of the default parameters */
6425
+ var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
6426
+ "nTable": this,
6427
+ "oApi": _that.oApi,
6428
+ "oInit": oInit,
6429
+ "sDestroyWidth": $(this).width(),
6430
+ "sInstance": sId,
6431
+ "sTableId": sId
6432
+ } );
6433
+ DataTable.settings.push( oSettings );
6434
+
6435
+ // Need to add the instance after the instance after the settings object has been added
6436
+ // to the settings array, so we can self reference the table instance if more than one
6437
+ oSettings.oInstance = (_that.length===1) ? _that : $(this).dataTable();
6438
+
6439
+ /* Setting up the initialisation object */
6440
+ if ( !oInit )
6441
+ {
6442
+ oInit = {};
6443
+ }
6444
+
6445
+ // Backwards compatibility, before we apply all the defaults
6446
+ if ( oInit.oLanguage )
6447
+ {
6448
+ _fnLanguageCompat( oInit.oLanguage );
6449
+ }
6450
+
6451
+ oInit = _fnExtend( $.extend(true, {}, DataTable.defaults), oInit );
6452
+
6453
+ // Map the initialisation options onto the settings object
6454
+ _fnMap( oSettings.oFeatures, oInit, "bPaginate" );
6455
+ _fnMap( oSettings.oFeatures, oInit, "bLengthChange" );
6456
+ _fnMap( oSettings.oFeatures, oInit, "bFilter" );
6457
+ _fnMap( oSettings.oFeatures, oInit, "bSort" );
6458
+ _fnMap( oSettings.oFeatures, oInit, "bInfo" );
6459
+ _fnMap( oSettings.oFeatures, oInit, "bProcessing" );
6460
+ _fnMap( oSettings.oFeatures, oInit, "bAutoWidth" );
6461
+ _fnMap( oSettings.oFeatures, oInit, "bSortClasses" );
6462
+ _fnMap( oSettings.oFeatures, oInit, "bServerSide" );
6463
+ _fnMap( oSettings.oFeatures, oInit, "bDeferRender" );
6464
+ _fnMap( oSettings.oScroll, oInit, "sScrollX", "sX" );
6465
+ _fnMap( oSettings.oScroll, oInit, "sScrollXInner", "sXInner" );
6466
+ _fnMap( oSettings.oScroll, oInit, "sScrollY", "sY" );
6467
+ _fnMap( oSettings.oScroll, oInit, "bScrollCollapse", "bCollapse" );
6468
+ _fnMap( oSettings.oScroll, oInit, "bScrollInfinite", "bInfinite" );
6469
+ _fnMap( oSettings.oScroll, oInit, "iScrollLoadGap", "iLoadGap" );
6470
+ _fnMap( oSettings.oScroll, oInit, "bScrollAutoCss", "bAutoCss" );
6471
+ _fnMap( oSettings, oInit, "asStripeClasses" );
6472
+ _fnMap( oSettings, oInit, "asStripClasses", "asStripeClasses" ); // legacy
6473
+ _fnMap( oSettings, oInit, "fnServerData" );
6474
+ _fnMap( oSettings, oInit, "fnFormatNumber" );
6475
+ _fnMap( oSettings, oInit, "sServerMethod" );
6476
+ _fnMap( oSettings, oInit, "aaSorting" );
6477
+ _fnMap( oSettings, oInit, "aaSortingFixed" );
6478
+ _fnMap( oSettings, oInit, "aLengthMenu" );
6479
+ _fnMap( oSettings, oInit, "sPaginationType" );
6480
+ _fnMap( oSettings, oInit, "sAjaxSource" );
6481
+ _fnMap( oSettings, oInit, "sAjaxDataProp" );
6482
+ _fnMap( oSettings, oInit, "iCookieDuration" );
6483
+ _fnMap( oSettings, oInit, "sCookiePrefix" );
6484
+ _fnMap( oSettings, oInit, "sDom" );
6485
+ _fnMap( oSettings, oInit, "bSortCellsTop" );
6486
+ _fnMap( oSettings, oInit, "iTabIndex" );
6487
+ _fnMap( oSettings, oInit, "oSearch", "oPreviousSearch" );
6488
+ _fnMap( oSettings, oInit, "aoSearchCols", "aoPreSearchCols" );
6489
+ _fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" );
6490
+ _fnMap( oSettings, oInit, "bJQueryUI", "bJUI" );
6491
+ _fnMap( oSettings, oInit, "fnCookieCallback" );
6492
+ _fnMap( oSettings, oInit, "fnStateLoad" );
6493
+ _fnMap( oSettings, oInit, "fnStateSave" );
6494
+ _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
6495
+
6496
+ /* Callback functions which are array driven */
6497
+ _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
6498
+ _fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
6499
+ _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
6500
+ _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
6501
+ _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
6502
+ _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
6503
+ _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
6504
+ _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
6505
+ _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
6506
+ _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
6507
+ _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
6508
+
6509
+ if ( oSettings.oFeatures.bServerSide && oSettings.oFeatures.bSort &&
6510
+ oSettings.oFeatures.bSortClasses )
6511
+ {
6512
+ /* Enable sort classes for server-side processing. Safe to do it here, since server-side
6513
+ * processing must be enabled by the developer
6514
+ */
6515
+ _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSortingClasses, 'server_side_sort_classes' );
6516
+ }
6517
+ else if ( oSettings.oFeatures.bDeferRender )
6518
+ {
6519
+ _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSortingClasses, 'defer_sort_classes' );
6520
+ }
6521
+
6522
+ if ( oInit.bJQueryUI )
6523
+ {
6524
+ /* Use the JUI classes object for display. You could clone the oStdClasses object if
6525
+ * you want to have multiple tables with multiple independent classes
6526
+ */
6527
+ $.extend( oSettings.oClasses, DataTable.ext.oJUIClasses );
6528
+
6529
+ if ( oInit.sDom === DataTable.defaults.sDom && DataTable.defaults.sDom === "lfrtip" )
6530
+ {
6531
+ /* Set the DOM to use a layout suitable for jQuery UI's theming */
6532
+ oSettings.sDom = '<"H"lfr>t<"F"ip>';
6533
+ }
6534
+ }
6535
+ else
6536
+ {
6537
+ $.extend( oSettings.oClasses, DataTable.ext.oStdClasses );
6538
+ }
6539
+ $(this).addClass( oSettings.oClasses.sTable );
6540
+
6541
+ /* Calculate the scroll bar width and cache it for use later on */
6542
+ if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
6543
+ {
6544
+ oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
6545
+ }
6546
+
6547
+ if ( oSettings.iInitDisplayStart === undefined )
6548
+ {
6549
+ /* Display start point, taking into account the save saving */
6550
+ oSettings.iInitDisplayStart = oInit.iDisplayStart;
6551
+ oSettings._iDisplayStart = oInit.iDisplayStart;
6552
+ }
6553
+
6554
+ /* Must be done after everything which can be overridden by a cookie! */
6555
+ if ( oInit.bStateSave )
6556
+ {
6557
+ oSettings.oFeatures.bStateSave = true;
6558
+ _fnLoadState( oSettings, oInit );
6559
+ _fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
6560
+ }
6561
+
6562
+ if ( oInit.iDeferLoading !== null )
6563
+ {
6564
+ oSettings.bDeferLoading = true;
6565
+ var tmp = $.isArray( oInit.iDeferLoading );
6566
+ oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
6567
+ oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
6568
+ }
6569
+
6570
+ if ( oInit.aaData !== null )
6571
+ {
6572
+ bUsePassedData = true;
6573
+ }
6574
+
6575
+ /* Language definitions */
6576
+ if ( oInit.oLanguage.sUrl !== "" )
6577
+ {
6578
+ /* Get the language definitions from a file - because this Ajax call makes the language
6579
+ * get async to the remainder of this function we use bInitHandedOff to indicate that
6580
+ * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
6581
+ */
6582
+ oSettings.oLanguage.sUrl = oInit.oLanguage.sUrl;
6583
+ $.getJSON( oSettings.oLanguage.sUrl, null, function( json ) {
6584
+ _fnLanguageCompat( json );
6585
+ $.extend( true, oSettings.oLanguage, oInit.oLanguage, json );
6586
+ _fnInitialise( oSettings );
6587
+ } );
6588
+ bInitHandedOff = true;
6589
+ }
6590
+ else
6591
+ {
6592
+ $.extend( true, oSettings.oLanguage, oInit.oLanguage );
6593
+ }
6594
+
6595
+
6596
+ /*
6597
+ * Stripes
6598
+ */
6599
+ if ( oInit.asStripeClasses === null )
6600
+ {
6601
+ oSettings.asStripeClasses =[
6602
+ oSettings.oClasses.sStripeOdd,
6603
+ oSettings.oClasses.sStripeEven
6604
+ ];
6605
+ }
6606
+
6607
+ /* Remove row stripe classes if they are already on the table row */
6608
+ iLen=oSettings.asStripeClasses.length;
6609
+ oSettings.asDestroyStripes = [];
6610
+ if (iLen)
6611
+ {
6612
+ var bStripeRemove = false;
6613
+ var anRows = $(this).children('tbody').children('tr:lt(' + iLen + ')');
6614
+ for ( i=0 ; i<iLen ; i++ )
6615
+ {
6616
+ if ( anRows.hasClass( oSettings.asStripeClasses[i] ) )
6617
+ {
6618
+ bStripeRemove = true;
6619
+
6620
+ /* Store the classes which we are about to remove so they can be re-added on destroy */
6621
+ oSettings.asDestroyStripes.push( oSettings.asStripeClasses[i] );
6622
+ }
6623
+ }
6624
+
6625
+ if ( bStripeRemove )
6626
+ {
6627
+ anRows.removeClass( oSettings.asStripeClasses.join(' ') );
6628
+ }
6629
+ }
6630
+
6631
+ /*
6632
+ * Columns
6633
+ * See if we should load columns automatically or use defined ones
6634
+ */
6635
+ var anThs = [];
6636
+ var aoColumnsInit;
6637
+ var nThead = this.getElementsByTagName('thead');
6638
+ if ( nThead.length !== 0 )
6639
+ {
6640
+ _fnDetectHeader( oSettings.aoHeader, nThead[0] );
6641
+ anThs = _fnGetUniqueThs( oSettings );
6642
+ }
6643
+
6644
+ /* If not given a column array, generate one with nulls */
6645
+ if ( oInit.aoColumns === null )
6646
+ {
6647
+ aoColumnsInit = [];
6648
+ for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
6649
+ {
6650
+ aoColumnsInit.push( null );
6651
+ }
6652
+ }
6653
+ else
6654
+ {
6655
+ aoColumnsInit = oInit.aoColumns;
6656
+ }
6657
+
6658
+ /* Add the columns */
6659
+ for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
6660
+ {
6661
+ /* Short cut - use the loop to check if we have column visibility state to restore */
6662
+ if ( oInit.saved_aoColumns !== undefined && oInit.saved_aoColumns.length == iLen )
6663
+ {
6664
+ if ( aoColumnsInit[i] === null )
6665
+ {
6666
+ aoColumnsInit[i] = {};
6667
+ }
6668
+ aoColumnsInit[i].bVisible = oInit.saved_aoColumns[i].bVisible;
6669
+ }
6670
+
6671
+ _fnAddColumn( oSettings, anThs ? anThs[i] : null );
6672
+ }
6673
+
6674
+ /* Apply the column definitions */
6675
+ _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
6676
+ _fnColumnOptions( oSettings, iCol, oDef );
6677
+ } );
6678
+
6679
+
6680
+ /*
6681
+ * Sorting
6682
+ * Check the aaSorting array
6683
+ */
6684
+ for ( i=0, iLen=oSettings.aaSorting.length ; i<iLen ; i++ )
6685
+ {
6686
+ if ( oSettings.aaSorting[i][0] >= oSettings.aoColumns.length )
6687
+ {
6688
+ oSettings.aaSorting[i][0] = 0;
6689
+ }
6690
+ var oColumn = oSettings.aoColumns[ oSettings.aaSorting[i][0] ];
6691
+
6692
+ /* Add a default sorting index */
6693
+ if ( oSettings.aaSorting[i][2] === undefined )
6694
+ {
6695
+ oSettings.aaSorting[i][2] = 0;
6696
+ }
6697
+
6698
+ /* If aaSorting is not defined, then we use the first indicator in asSorting */
6699
+ if ( oInit.aaSorting === undefined && oSettings.saved_aaSorting === undefined )
6700
+ {
6701
+ oSettings.aaSorting[i][1] = oColumn.asSorting[0];
6702
+ }
6703
+
6704
+ /* Set the current sorting index based on aoColumns.asSorting */
6705
+ for ( j=0, jLen=oColumn.asSorting.length ; j<jLen ; j++ )
6706
+ {
6707
+ if ( oSettings.aaSorting[i][1] == oColumn.asSorting[j] )
6708
+ {
6709
+ oSettings.aaSorting[i][2] = j;
6710
+ break;
6711
+ }
6712
+ }
6713
+ }
6714
+
6715
+ /* Do a first pass on the sorting classes (allows any size changes to be taken into
6716
+ * account, and also will apply sorting disabled classes if disabled
6717
+ */
6718
+ _fnSortingClasses( oSettings );
6719
+
6720
+
6721
+ /*
6722
+ * Final init
6723
+ * Cache the header, body and footer as required, creating them if needed
6724
+ */
6725
+
6726
+ /* Browser support detection */
6727
+ _fnBrowserDetect( oSettings );
6728
+
6729
+ // Work around for Webkit bug 83867 - store the caption-side before removing from doc
6730
+ var captions = $(this).children('caption').each( function () {
6731
+ this._captionSide = $(this).css('caption-side');
6732
+ } );
6733
+
6734
+ var thead = $(this).children('thead');
6735
+ if ( thead.length === 0 )
6736
+ {
6737
+ thead = [ document.createElement( 'thead' ) ];
6738
+ this.appendChild( thead[0] );
6739
+ }
6740
+ oSettings.nTHead = thead[0];
6741
+
6742
+ var tbody = $(this).children('tbody');
6743
+ if ( tbody.length === 0 )
6744
+ {
6745
+ tbody = [ document.createElement( 'tbody' ) ];
6746
+ this.appendChild( tbody[0] );
6747
+ }
6748
+ oSettings.nTBody = tbody[0];
6749
+ oSettings.nTBody.setAttribute( "role", "alert" );
6750
+ oSettings.nTBody.setAttribute( "aria-live", "polite" );
6751
+ oSettings.nTBody.setAttribute( "aria-relevant", "all" );
6752
+
6753
+ var tfoot = $(this).children('tfoot');
6754
+ if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
6755
+ {
6756
+ // If we are a scrolling table, and no footer has been given, then we need to create
6757
+ // a tfoot element for the caption element to be appended to
6758
+ tfoot = [ document.createElement( 'tfoot' ) ];
6759
+ this.appendChild( tfoot[0] );
6760
+ }
6761
+
6762
+ if ( tfoot.length > 0 )
6763
+ {
6764
+ oSettings.nTFoot = tfoot[0];
6765
+ _fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
6766
+ }
6767
+
6768
+ /* Check if there is data passing into the constructor */
6769
+ if ( bUsePassedData )
6770
+ {
6771
+ for ( i=0 ; i<oInit.aaData.length ; i++ )
6772
+ {
6773
+ _fnAddData( oSettings, oInit.aaData[ i ] );
6774
+ }
6775
+ }
6776
+ else
6777
+ {
6778
+ /* Grab the data from the page */
6779
+ _fnGatherData( oSettings );
6780
+ }
6781
+
6782
+ /* Copy the data index array */
6783
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
6784
+
6785
+ /* Initialisation complete - table can be drawn */
6786
+ oSettings.bInitialised = true;
6787
+
6788
+ /* Check if we need to initialise the table (it might not have been handed off to the
6789
+ * language processor)
6790
+ */
6791
+ if ( bInitHandedOff === false )
6792
+ {
6793
+ _fnInitialise( oSettings );
6794
+ }
6795
+ } );
6796
+ _that = null;
6797
+ return this;
6798
+ };
6799
+
6800
+
6801
+
6802
+ /**
6803
+ * Provide a common method for plug-ins to check the version of DataTables being used, in order
6804
+ * to ensure compatibility.
6805
+ * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
6806
+ * formats "X" and "X.Y" are also acceptable.
6807
+ * @returns {boolean} true if this version of DataTables is greater or equal to the required
6808
+ * version, or false if this version of DataTales is not suitable
6809
+ * @static
6810
+ * @dtopt API-Static
6811
+ *
6812
+ * @example
6813
+ * alert( $.fn.dataTable.fnVersionCheck( '1.9.0' ) );
6814
+ */
6815
+ DataTable.fnVersionCheck = function( sVersion )
6816
+ {
6817
+ /* This is cheap, but effective */
6818
+ var fnZPad = function (Zpad, count)
6819
+ {
6820
+ while(Zpad.length < count) {
6821
+ Zpad += '0';
6822
+ }
6823
+ return Zpad;
6824
+ };
6825
+ var aThis = DataTable.ext.sVersion.split('.');
6826
+ var aThat = sVersion.split('.');
6827
+ var sThis = '', sThat = '';
6828
+
6829
+ for ( var i=0, iLen=aThat.length ; i<iLen ; i++ )
6830
+ {
6831
+ sThis += fnZPad( aThis[i], 3 );
6832
+ sThat += fnZPad( aThat[i], 3 );
6833
+ }
6834
+
6835
+ return parseInt(sThis, 10) >= parseInt(sThat, 10);
6836
+ };
6837
+
6838
+
6839
+ /**
6840
+ * Check if a TABLE node is a DataTable table already or not.
6841
+ * @param {node} nTable The TABLE node to check if it is a DataTable or not (note that other
6842
+ * node types can be passed in, but will always return false).
6843
+ * @returns {boolean} true the table given is a DataTable, or false otherwise
6844
+ * @static
6845
+ * @dtopt API-Static
6846
+ *
6847
+ * @example
6848
+ * var ex = document.getElementById('example');
6849
+ * if ( ! $.fn.DataTable.fnIsDataTable( ex ) ) {
6850
+ * $(ex).dataTable();
6851
+ * }
6852
+ */
6853
+ DataTable.fnIsDataTable = function ( nTable )
6854
+ {
6855
+ var o = DataTable.settings;
6856
+
6857
+ for ( var i=0 ; i<o.length ; i++ )
6858
+ {
6859
+ if ( o[i].nTable === nTable || o[i].nScrollHead === nTable || o[i].nScrollFoot === nTable )
6860
+ {
6861
+ return true;
6862
+ }
6863
+ }
6864
+
6865
+ return false;
6866
+ };
6867
+
6868
+
6869
+ /**
6870
+ * Get all DataTable tables that have been initialised - optionally you can select to
6871
+ * get only currently visible tables.
6872
+ * @param {boolean} [bVisible=false] Flag to indicate if you want all (default) or
6873
+ * visible tables only.
6874
+ * @returns {array} Array of TABLE nodes (not DataTable instances) which are DataTables
6875
+ * @static
6876
+ * @dtopt API-Static
6877
+ *
6878
+ * @example
6879
+ * var table = $.fn.dataTable.fnTables(true);
6880
+ * if ( table.length > 0 ) {
6881
+ * $(table).dataTable().fnAdjustColumnSizing();
6882
+ * }
6883
+ */
6884
+ DataTable.fnTables = function ( bVisible )
6885
+ {
6886
+ var out = [];
6887
+
6888
+ jQuery.each( DataTable.settings, function (i, o) {
6889
+ if ( !bVisible || (bVisible === true && $(o.nTable).is(':visible')) )
6890
+ {
6891
+ out.push( o.nTable );
6892
+ }
6893
+ } );
6894
+
6895
+ return out;
6896
+ };
6897
+
6898
+
6899
+ /**
6900
+ * Version string for plug-ins to check compatibility. Allowed format is
6901
+ * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
6902
+ * e are optional
6903
+ * @member
6904
+ * @type string
6905
+ * @default Version number
6906
+ */
6907
+ DataTable.version = "1.9.4";
6908
+
6909
+ /**
6910
+ * Private data store, containing all of the settings objects that are created for the
6911
+ * tables on a given page.
6912
+ *
6913
+ * Note that the <i>DataTable.settings</i> object is aliased to <i>jQuery.fn.dataTableExt</i>
6914
+ * through which it may be accessed and manipulated, or <i>jQuery.fn.dataTable.settings</i>.
6915
+ * @member
6916
+ * @type array
6917
+ * @default []
6918
+ * @private
6919
+ */
6920
+ DataTable.settings = [];
6921
+
6922
+ /**
6923
+ * Object models container, for the various models that DataTables has available
6924
+ * to it. These models define the objects that are used to hold the active state
6925
+ * and configuration of the table.
6926
+ * @namespace
6927
+ */
6928
+ DataTable.models = {};
6929
+
6930
+
6931
+ /**
6932
+ * DataTables extension options and plug-ins. This namespace acts as a collection "area"
6933
+ * for plug-ins that can be used to extend the default DataTables behaviour - indeed many
6934
+ * of the build in methods use this method to provide their own capabilities (sorting methods
6935
+ * for example).
6936
+ *
6937
+ * Note that this namespace is aliased to jQuery.fn.dataTableExt so it can be readily accessed
6938
+ * and modified by plug-ins.
6939
+ * @namespace
6940
+ */
6941
+ DataTable.models.ext = {
6942
+ /**
6943
+ * Plug-in filtering functions - this method of filtering is complimentary to the default
6944
+ * type based filtering, and a lot more comprehensive as it allows you complete control
6945
+ * over the filtering logic. Each element in this array is a function (parameters
6946
+ * described below) that is called for every row in the table, and your logic decides if
6947
+ * it should be included in the filtered data set or not.
6948
+ * <ul>
6949
+ * <li>
6950
+ * Function input parameters:
6951
+ * <ul>
6952
+ * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
6953
+ * <li>{array|object} Data for the row to be processed (same as the original format
6954
+ * that was passed in as the data source, or an array from a DOM data source</li>
6955
+ * <li>{int} Row index in aoData ({@link DataTable.models.oSettings.aoData}), which can
6956
+ * be useful to retrieve the TR element if you need DOM interaction.</li>
6957
+ * </ul>
6958
+ * </li>
6959
+ * <li>
6960
+ * Function return:
6961
+ * <ul>
6962
+ * <li>{boolean} Include the row in the filtered result set (true) or not (false)</li>
6963
+ * </ul>
6964
+ * </il>
6965
+ * </ul>
6966
+ * @type array
6967
+ * @default []
6968
+ *
6969
+ * @example
6970
+ * // The following example shows custom filtering being applied to the fourth column (i.e.
6971
+ * // the aData[3] index) based on two input values from the end-user, matching the data in
6972
+ * // a certain range.
6973
+ * $.fn.dataTableExt.afnFiltering.push(
6974
+ * function( oSettings, aData, iDataIndex ) {
6975
+ * var iMin = document.getElementById('min').value * 1;
6976
+ * var iMax = document.getElementById('max').value * 1;
6977
+ * var iVersion = aData[3] == "-" ? 0 : aData[3]*1;
6978
+ * if ( iMin == "" && iMax == "" ) {
6979
+ * return true;
6980
+ * }
6981
+ * else if ( iMin == "" && iVersion < iMax ) {
6982
+ * return true;
6983
+ * }
6984
+ * else if ( iMin < iVersion && "" == iMax ) {
6985
+ * return true;
6986
+ * }
6987
+ * else if ( iMin < iVersion && iVersion < iMax ) {
6988
+ * return true;
6989
+ * }
6990
+ * return false;
6991
+ * }
6992
+ * );
6993
+ */
6994
+ "afnFiltering": [],
6995
+
6996
+
6997
+ /**
6998
+ * Plug-in sorting functions - this method of sorting is complimentary to the default type
6999
+ * based sorting that DataTables does automatically, allowing much greater control over the
7000
+ * the data that is being used to sort a column. This is useful if you want to do sorting
7001
+ * based on live data (for example the contents of an 'input' element) rather than just the
7002
+ * static string that DataTables knows of. The way these plug-ins work is that you create
7003
+ * an array of the values you wish to be sorted for the column in question and then return
7004
+ * that array. Which pre-sorting function is run here depends on the sSortDataType parameter
7005
+ * that is used for the column (if any). This is the corollary of <i>ofnSearch</i> for sort
7006
+ * data.
7007
+ * <ul>
7008
+ * <li>
7009
+ * Function input parameters:
7010
+ * <ul>
7011
+ * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
7012
+ * <li>{int} Target column index</li>
7013
+ * </ul>
7014
+ * </li>
7015
+ * <li>
7016
+ * Function return:
7017
+ * <ul>
7018
+ * <li>{array} Data for the column to be sorted upon</li>
7019
+ * </ul>
7020
+ * </il>
7021
+ * </ul>
7022
+ *
7023
+ * Note that as of v1.9, it is typically preferable to use <i>mData</i> to prepare data for
7024
+ * the different uses that DataTables can put the data to. Specifically <i>mData</i> when
7025
+ * used as a function will give you a 'type' (sorting, filtering etc) that you can use to
7026
+ * prepare the data as required for the different types. As such, this method is deprecated.
7027
+ * @type array
7028
+ * @default []
7029
+ * @deprecated
7030
+ *
7031
+ * @example
7032
+ * // Updating the cached sorting information with user entered values in HTML input elements
7033
+ * jQuery.fn.dataTableExt.afnSortData['dom-text'] = function ( oSettings, iColumn )
7034
+ * {
7035
+ * var aData = [];
7036
+ * $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () {
7037
+ * aData.push( this.value );
7038
+ * } );
7039
+ * return aData;
7040
+ * }
7041
+ */
7042
+ "afnSortData": [],
7043
+
7044
+
7045
+ /**
7046
+ * Feature plug-ins - This is an array of objects which describe the feature plug-ins that are
7047
+ * available to DataTables. These feature plug-ins are accessible through the sDom initialisation
7048
+ * option. As such, each feature plug-in must describe a function that is used to initialise
7049
+ * itself (fnInit), a character so the feature can be enabled by sDom (cFeature) and the name
7050
+ * of the feature (sFeature). Thus the objects attached to this method must provide:
7051
+ * <ul>
7052
+ * <li>{function} fnInit Initialisation of the plug-in
7053
+ * <ul>
7054
+ * <li>
7055
+ * Function input parameters:
7056
+ * <ul>
7057
+ * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
7058
+ * </ul>
7059
+ * </li>
7060
+ * <li>
7061
+ * Function return:
7062
+ * <ul>
7063
+ * <li>{node|null} The element which contains your feature. Note that the return
7064
+ * may also be void if your plug-in does not require to inject any DOM elements
7065
+ * into DataTables control (sDom) - for example this might be useful when
7066
+ * developing a plug-in which allows table control via keyboard entry.</li>
7067
+ * </ul>
7068
+ * </il>
7069
+ * </ul>
7070
+ * </li>
7071
+ * <li>{character} cFeature Character that will be matched in sDom - case sensitive</li>
7072
+ * <li>{string} sFeature Feature name</li>
7073
+ * </ul>
7074
+ * @type array
7075
+ * @default []
7076
+ *
7077
+ * @example
7078
+ * // How TableTools initialises itself.
7079
+ * $.fn.dataTableExt.aoFeatures.push( {
7080
+ * "fnInit": function( oSettings ) {
7081
+ * return new TableTools( { "oDTSettings": oSettings } );
7082
+ * },
7083
+ * "cFeature": "T",
7084
+ * "sFeature": "TableTools"
7085
+ * } );
7086
+ */
7087
+ "aoFeatures": [],
7088
+
7089
+
7090
+ /**
7091
+ * Type detection plug-in functions - DataTables utilises types to define how sorting and
7092
+ * filtering behave, and types can be either be defined by the developer (sType for the
7093
+ * column) or they can be automatically detected by the methods in this array. The functions
7094
+ * defined in the array are quite simple, taking a single parameter (the data to analyse)
7095
+ * and returning the type if it is a known type, or null otherwise.
7096
+ * <ul>
7097
+ * <li>
7098
+ * Function input parameters:
7099
+ * <ul>
7100
+ * <li>{*} Data from the column cell to be analysed</li>
7101
+ * </ul>
7102
+ * </li>
7103
+ * <li>
7104
+ * Function return:
7105
+ * <ul>
7106
+ * <li>{string|null} Data type detected, or null if unknown (and thus pass it
7107
+ * on to the other type detection functions.</li>
7108
+ * </ul>
7109
+ * </il>
7110
+ * </ul>
7111
+ * @type array
7112
+ * @default []
7113
+ *
7114
+ * @example
7115
+ * // Currency type detection plug-in:
7116
+ * jQuery.fn.dataTableExt.aTypes.push(
7117
+ * function ( sData ) {
7118
+ * var sValidChars = "0123456789.-";
7119
+ * var Char;
7120
+ *
7121
+ * // Check the numeric part
7122
+ * for ( i=1 ; i<sData.length ; i++ ) {
7123
+ * Char = sData.charAt(i);
7124
+ * if (sValidChars.indexOf(Char) == -1) {
7125
+ * return null;
7126
+ * }
7127
+ * }
7128
+ *
7129
+ * // Check prefixed by currency
7130
+ * if ( sData.charAt(0) == '$' || sData.charAt(0) == '&pound;' ) {
7131
+ * return 'currency';
7132
+ * }
7133
+ * return null;
7134
+ * }
7135
+ * );
7136
+ */
7137
+ "aTypes": [],
7138
+
7139
+
7140
+ /**
7141
+ * Provide a common method for plug-ins to check the version of DataTables being used,
7142
+ * in order to ensure compatibility.
7143
+ * @type function
7144
+ * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note
7145
+ * that the formats "X" and "X.Y" are also acceptable.
7146
+ * @returns {boolean} true if this version of DataTables is greater or equal to the
7147
+ * required version, or false if this version of DataTales is not suitable
7148
+ *
7149
+ * @example
7150
+ * $(document).ready(function() {
7151
+ * var oTable = $('#example').dataTable();
7152
+ * alert( oTable.fnVersionCheck( '1.9.0' ) );
7153
+ * } );
7154
+ */
7155
+ "fnVersionCheck": DataTable.fnVersionCheck,
7156
+
7157
+
7158
+ /**
7159
+ * Index for what 'this' index API functions should use
7160
+ * @type int
7161
+ * @default 0
7162
+ */
7163
+ "iApiIndex": 0,
7164
+
7165
+
7166
+ /**
7167
+ * Pre-processing of filtering data plug-ins - When you assign the sType for a column
7168
+ * (or have it automatically detected for you by DataTables or a type detection plug-in),
7169
+ * you will typically be using this for custom sorting, but it can also be used to provide
7170
+ * custom filtering by allowing you to pre-processing the data and returning the data in
7171
+ * the format that should be filtered upon. This is done by adding functions this object
7172
+ * with a parameter name which matches the sType for that target column. This is the
7173
+ * corollary of <i>afnSortData</i> for filtering data.
7174
+ * <ul>
7175
+ * <li>
7176
+ * Function input parameters:
7177
+ * <ul>
7178
+ * <li>{*} Data from the column cell to be prepared for filtering</li>
7179
+ * </ul>
7180
+ * </li>
7181
+ * <li>
7182
+ * Function return:
7183
+ * <ul>
7184
+ * <li>{string|null} Formatted string that will be used for the filtering.</li>
7185
+ * </ul>
7186
+ * </il>
7187
+ * </ul>
7188
+ *
7189
+ * Note that as of v1.9, it is typically preferable to use <i>mData</i> to prepare data for
7190
+ * the different uses that DataTables can put the data to. Specifically <i>mData</i> when
7191
+ * used as a function will give you a 'type' (sorting, filtering etc) that you can use to
7192
+ * prepare the data as required for the different types. As such, this method is deprecated.
7193
+ * @type object
7194
+ * @default {}
7195
+ * @deprecated
7196
+ *
7197
+ * @example
7198
+ * $.fn.dataTableExt.ofnSearch['title-numeric'] = function ( sData ) {
7199
+ * return sData.replace(/\n/g," ").replace( /<.*?>/g, "" );
7200
+ * }
7201
+ */
7202
+ "ofnSearch": {},
7203
+
7204
+
7205
+ /**
7206
+ * Container for all private functions in DataTables so they can be exposed externally
7207
+ * @type object
7208
+ * @default {}
7209
+ */
7210
+ "oApi": {},
7211
+
7212
+
7213
+ /**
7214
+ * Storage for the various classes that DataTables uses
7215
+ * @type object
7216
+ * @default {}
7217
+ */
7218
+ "oStdClasses": {},
7219
+
7220
+
7221
+ /**
7222
+ * Storage for the various classes that DataTables uses - jQuery UI suitable
7223
+ * @type object
7224
+ * @default {}
7225
+ */
7226
+ "oJUIClasses": {},
7227
+
7228
+
7229
+ /**
7230
+ * Pagination plug-in methods - The style and controls of the pagination can significantly
7231
+ * impact on how the end user interacts with the data in your table, and DataTables allows
7232
+ * the addition of pagination controls by extending this object, which can then be enabled
7233
+ * through the <i>sPaginationType</i> initialisation parameter. Each pagination type that
7234
+ * is added is an object (the property name of which is what <i>sPaginationType</i> refers
7235
+ * to) that has two properties, both methods that are used by DataTables to update the
7236
+ * control's state.
7237
+ * <ul>
7238
+ * <li>
7239
+ * fnInit - Initialisation of the paging controls. Called only during initialisation
7240
+ * of the table. It is expected that this function will add the required DOM elements
7241
+ * to the page for the paging controls to work. The element pointer
7242
+ * 'oSettings.aanFeatures.p' array is provided by DataTables to contain the paging
7243
+ * controls (note that this is a 2D array to allow for multiple instances of each
7244
+ * DataTables DOM element). It is suggested that you add the controls to this element
7245
+ * as children
7246
+ * <ul>
7247
+ * <li>
7248
+ * Function input parameters:
7249
+ * <ul>
7250
+ * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
7251
+ * <li>{node} Container into which the pagination controls must be inserted</li>
7252
+ * <li>{function} Draw callback function - whenever the controls cause a page
7253
+ * change, this method must be called to redraw the table.</li>
7254
+ * </ul>
7255
+ * </li>
7256
+ * <li>
7257
+ * Function return:
7258
+ * <ul>
7259
+ * <li>No return required</li>
7260
+ * </ul>
7261
+ * </il>
7262
+ * </ul>
7263
+ * </il>
7264
+ * <li>
7265
+ * fnInit - This function is called whenever the paging status of the table changes and is
7266
+ * typically used to update classes and/or text of the paging controls to reflex the new
7267
+ * status.
7268
+ * <ul>
7269
+ * <li>
7270
+ * Function input parameters:
7271
+ * <ul>
7272
+ * <li>{object} DataTables settings object: see {@link DataTable.models.oSettings}.</li>
7273
+ * <li>{function} Draw callback function - in case you need to redraw the table again
7274
+ * or attach new event listeners</li>
7275
+ * </ul>
7276
+ * </li>
7277
+ * <li>
7278
+ * Function return:
7279
+ * <ul>
7280
+ * <li>No return required</li>
7281
+ * </ul>
7282
+ * </il>
7283
+ * </ul>
7284
+ * </il>
7285
+ * </ul>
7286
+ * @type object
7287
+ * @default {}
7288
+ *
7289
+ * @example
7290
+ * $.fn.dataTableExt.oPagination.four_button = {
7291
+ * "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) {
7292
+ * nFirst = document.createElement( 'span' );
7293
+ * nPrevious = document.createElement( 'span' );
7294
+ * nNext = document.createElement( 'span' );
7295
+ * nLast = document.createElement( 'span' );
7296
+ *
7297
+ * nFirst.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sFirst ) );
7298
+ * nPrevious.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sPrevious ) );
7299
+ * nNext.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sNext ) );
7300
+ * nLast.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sLast ) );
7301
+ *
7302
+ * nFirst.className = "paginate_button first";
7303
+ * nPrevious.className = "paginate_button previous";
7304
+ * nNext.className="paginate_button next";
7305
+ * nLast.className = "paginate_button last";
7306
+ *
7307
+ * nPaging.appendChild( nFirst );
7308
+ * nPaging.appendChild( nPrevious );
7309
+ * nPaging.appendChild( nNext );
7310
+ * nPaging.appendChild( nLast );
7311
+ *
7312
+ * $(nFirst).click( function () {
7313
+ * oSettings.oApi._fnPageChange( oSettings, "first" );
7314
+ * fnCallbackDraw( oSettings );
7315
+ * } );
7316
+ *
7317
+ * $(nPrevious).click( function() {
7318
+ * oSettings.oApi._fnPageChange( oSettings, "previous" );
7319
+ * fnCallbackDraw( oSettings );
7320
+ * } );
7321
+ *
7322
+ * $(nNext).click( function() {
7323
+ * oSettings.oApi._fnPageChange( oSettings, "next" );
7324
+ * fnCallbackDraw( oSettings );
7325
+ * } );
7326
+ *
7327
+ * $(nLast).click( function() {
7328
+ * oSettings.oApi._fnPageChange( oSettings, "last" );
7329
+ * fnCallbackDraw( oSettings );
7330
+ * } );
7331
+ *
7332
+ * $(nFirst).bind( 'selectstart', function () { return false; } );
7333
+ * $(nPrevious).bind( 'selectstart', function () { return false; } );
7334
+ * $(nNext).bind( 'selectstart', function () { return false; } );
7335
+ * $(nLast).bind( 'selectstart', function () { return false; } );
7336
+ * },
7337
+ *
7338
+ * "fnUpdate": function ( oSettings, fnCallbackDraw ) {
7339
+ * if ( !oSettings.aanFeatures.p ) {
7340
+ * return;
7341
+ * }
7342
+ *
7343
+ * // Loop over each instance of the pager
7344
+ * var an = oSettings.aanFeatures.p;
7345
+ * for ( var i=0, iLen=an.length ; i<iLen ; i++ ) {
7346
+ * var buttons = an[i].getElementsByTagName('span');
7347
+ * if ( oSettings._iDisplayStart === 0 ) {
7348
+ * buttons[0].className = "paginate_disabled_previous";
7349
+ * buttons[1].className = "paginate_disabled_previous";
7350
+ * }
7351
+ * else {
7352
+ * buttons[0].className = "paginate_enabled_previous";
7353
+ * buttons[1].className = "paginate_enabled_previous";
7354
+ * }
7355
+ *
7356
+ * if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() ) {
7357
+ * buttons[2].className = "paginate_disabled_next";
7358
+ * buttons[3].className = "paginate_disabled_next";
7359
+ * }
7360
+ * else {
7361
+ * buttons[2].className = "paginate_enabled_next";
7362
+ * buttons[3].className = "paginate_enabled_next";
7363
+ * }
7364
+ * }
7365
+ * }
7366
+ * };
7367
+ */
7368
+ "oPagination": {},
7369
+
7370
+
7371
+ /**
7372
+ * Sorting plug-in methods - Sorting in DataTables is based on the detected type of the
7373
+ * data column (you can add your own type detection functions, or override automatic
7374
+ * detection using sType). With this specific type given to the column, DataTables will
7375
+ * apply the required sort from the functions in the object. Each sort type must provide
7376
+ * two mandatory methods, one each for ascending and descending sorting, and can optionally
7377
+ * provide a pre-formatting method that will help speed up sorting by allowing DataTables
7378
+ * to pre-format the sort data only once (rather than every time the actual sort functions
7379
+ * are run). The two sorting functions are typical Javascript sort methods:
7380
+ * <ul>
7381
+ * <li>
7382
+ * Function input parameters:
7383
+ * <ul>
7384
+ * <li>{*} Data to compare to the second parameter</li>
7385
+ * <li>{*} Data to compare to the first parameter</li>
7386
+ * </ul>
7387
+ * </li>
7388
+ * <li>
7389
+ * Function return:
7390
+ * <ul>
7391
+ * <li>{int} Sorting match: <0 if first parameter should be sorted lower than
7392
+ * the second parameter, ===0 if the two parameters are equal and >0 if
7393
+ * the first parameter should be sorted height than the second parameter.</li>
7394
+ * </ul>
7395
+ * </il>
7396
+ * </ul>
7397
+ * @type object
7398
+ * @default {}
7399
+ *
7400
+ * @example
7401
+ * // Case-sensitive string sorting, with no pre-formatting method
7402
+ * $.extend( $.fn.dataTableExt.oSort, {
7403
+ * "string-case-asc": function(x,y) {
7404
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
7405
+ * },
7406
+ * "string-case-desc": function(x,y) {
7407
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
7408
+ * }
7409
+ * } );
7410
+ *
7411
+ * @example
7412
+ * // Case-insensitive string sorting, with pre-formatting
7413
+ * $.extend( $.fn.dataTableExt.oSort, {
7414
+ * "string-pre": function(x) {
7415
+ * return x.toLowerCase();
7416
+ * },
7417
+ * "string-asc": function(x,y) {
7418
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
7419
+ * },
7420
+ * "string-desc": function(x,y) {
7421
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
7422
+ * }
7423
+ * } );
7424
+ */
7425
+ "oSort": {},
7426
+
7427
+
7428
+ /**
7429
+ * Version string for plug-ins to check compatibility. Allowed format is
7430
+ * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
7431
+ * e are optional
7432
+ * @type string
7433
+ * @default Version number
7434
+ */
7435
+ "sVersion": DataTable.version,
7436
+
7437
+
7438
+ /**
7439
+ * How should DataTables report an error. Can take the value 'alert' or 'throw'
7440
+ * @type string
7441
+ * @default alert
7442
+ */
7443
+ "sErrMode": "alert",
7444
+
7445
+
7446
+ /**
7447
+ * Store information for DataTables to access globally about other instances
7448
+ * @namespace
7449
+ * @private
7450
+ */
7451
+ "_oExternConfig": {
7452
+ /* int:iNextUnique - next unique number for an instance */
7453
+ "iNextUnique": 0
7454
+ }
7455
+ };
7456
+
7457
+
7458
+
7459
+
7460
+ /**
7461
+ * Template object for the way in which DataTables holds information about
7462
+ * search information for the global filter and individual column filters.
7463
+ * @namespace
7464
+ */
7465
+ DataTable.models.oSearch = {
7466
+ /**
7467
+ * Flag to indicate if the filtering should be case insensitive or not
7468
+ * @type boolean
7469
+ * @default true
7470
+ */
7471
+ "bCaseInsensitive": true,
7472
+
7473
+ /**
7474
+ * Applied search term
7475
+ * @type string
7476
+ * @default <i>Empty string</i>
7477
+ */
7478
+ "sSearch": "",
7479
+
7480
+ /**
7481
+ * Flag to indicate if the search term should be interpreted as a
7482
+ * regular expression (true) or not (false) and therefore and special
7483
+ * regex characters escaped.
7484
+ * @type boolean
7485
+ * @default false
7486
+ */
7487
+ "bRegex": false,
7488
+
7489
+ /**
7490
+ * Flag to indicate if DataTables is to use its smart filtering or not.
7491
+ * @type boolean
7492
+ * @default true
7493
+ */
7494
+ "bSmart": true
7495
+ };
7496
+
7497
+
7498
+
7499
+
7500
+ /**
7501
+ * Template object for the way in which DataTables holds information about
7502
+ * each individual row. This is the object format used for the settings
7503
+ * aoData array.
7504
+ * @namespace
7505
+ */
7506
+ DataTable.models.oRow = {
7507
+ /**
7508
+ * TR element for the row
7509
+ * @type node
7510
+ * @default null
7511
+ */
7512
+ "nTr": null,
7513
+
7514
+ /**
7515
+ * Data object from the original data source for the row. This is either
7516
+ * an array if using the traditional form of DataTables, or an object if
7517
+ * using mData options. The exact type will depend on the passed in
7518
+ * data from the data source, or will be an array if using DOM a data
7519
+ * source.
7520
+ * @type array|object
7521
+ * @default []
7522
+ */
7523
+ "_aData": [],
7524
+
7525
+ /**
7526
+ * Sorting data cache - this array is ostensibly the same length as the
7527
+ * number of columns (although each index is generated only as it is
7528
+ * needed), and holds the data that is used for sorting each column in the
7529
+ * row. We do this cache generation at the start of the sort in order that
7530
+ * the formatting of the sort data need be done only once for each cell
7531
+ * per sort. This array should not be read from or written to by anything
7532
+ * other than the master sorting methods.
7533
+ * @type array
7534
+ * @default []
7535
+ * @private
7536
+ */
7537
+ "_aSortData": [],
7538
+
7539
+ /**
7540
+ * Array of TD elements that are cached for hidden rows, so they can be
7541
+ * reinserted into the table if a column is made visible again (or to act
7542
+ * as a store if a column is made hidden). Only hidden columns have a
7543
+ * reference in the array. For non-hidden columns the value is either
7544
+ * undefined or null.
7545
+ * @type array nodes
7546
+ * @default []
7547
+ * @private
7548
+ */
7549
+ "_anHidden": [],
7550
+
7551
+ /**
7552
+ * Cache of the class name that DataTables has applied to the row, so we
7553
+ * can quickly look at this variable rather than needing to do a DOM check
7554
+ * on className for the nTr property.
7555
+ * @type string
7556
+ * @default <i>Empty string</i>
7557
+ * @private
7558
+ */
7559
+ "_sRowStripe": ""
7560
+ };
7561
+
7562
+
7563
+
7564
+ /**
7565
+ * Template object for the column information object in DataTables. This object
7566
+ * is held in the settings aoColumns array and contains all the information that
7567
+ * DataTables needs about each individual column.
7568
+ *
7569
+ * Note that this object is related to {@link DataTable.defaults.columns}
7570
+ * but this one is the internal data store for DataTables's cache of columns.
7571
+ * It should NOT be manipulated outside of DataTables. Any configuration should
7572
+ * be done through the initialisation options.
7573
+ * @namespace
7574
+ */
7575
+ DataTable.models.oColumn = {
7576
+ /**
7577
+ * A list of the columns that sorting should occur on when this column
7578
+ * is sorted. That this property is an array allows multi-column sorting
7579
+ * to be defined for a column (for example first name / last name columns
7580
+ * would benefit from this). The values are integers pointing to the
7581
+ * columns to be sorted on (typically it will be a single integer pointing
7582
+ * at itself, but that doesn't need to be the case).
7583
+ * @type array
7584
+ */
7585
+ "aDataSort": null,
7586
+
7587
+ /**
7588
+ * Define the sorting directions that are applied to the column, in sequence
7589
+ * as the column is repeatedly sorted upon - i.e. the first value is used
7590
+ * as the sorting direction when the column if first sorted (clicked on).
7591
+ * Sort it again (click again) and it will move on to the next index.
7592
+ * Repeat until loop.
7593
+ * @type array
7594
+ */
7595
+ "asSorting": null,
7596
+
7597
+ /**
7598
+ * Flag to indicate if the column is searchable, and thus should be included
7599
+ * in the filtering or not.
7600
+ * @type boolean
7601
+ */
7602
+ "bSearchable": null,
7603
+
7604
+ /**
7605
+ * Flag to indicate if the column is sortable or not.
7606
+ * @type boolean
7607
+ */
7608
+ "bSortable": null,
7609
+
7610
+ /**
7611
+ * <code>Deprecated</code> When using fnRender, you have two options for what
7612
+ * to do with the data, and this property serves as the switch. Firstly, you
7613
+ * can have the sorting and filtering use the rendered value (true - default),
7614
+ * or you can have the sorting and filtering us the original value (false).
7615
+ *
7616
+ * Please note that this option has now been deprecated and will be removed
7617
+ * in the next version of DataTables. Please use mRender / mData rather than
7618
+ * fnRender.
7619
+ * @type boolean
7620
+ * @deprecated
7621
+ */
7622
+ "bUseRendered": null,
7623
+
7624
+ /**
7625
+ * Flag to indicate if the column is currently visible in the table or not
7626
+ * @type boolean
7627
+ */
7628
+ "bVisible": null,
7629
+
7630
+ /**
7631
+ * Flag to indicate to the type detection method if the automatic type
7632
+ * detection should be used, or if a column type (sType) has been specified
7633
+ * @type boolean
7634
+ * @default true
7635
+ * @private
7636
+ */
7637
+ "_bAutoType": true,
7638
+
7639
+ /**
7640
+ * Developer definable function that is called whenever a cell is created (Ajax source,
7641
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
7642
+ * allowing you to modify the DOM element (add background colour for example) when the
7643
+ * element is available.
7644
+ * @type function
7645
+ * @param {element} nTd The TD node that has been created
7646
+ * @param {*} sData The Data for the cell
7647
+ * @param {array|object} oData The data for the whole row
7648
+ * @param {int} iRow The row index for the aoData data store
7649
+ * @default null
7650
+ */
7651
+ "fnCreatedCell": null,
7652
+
7653
+ /**
7654
+ * Function to get data from a cell in a column. You should <b>never</b>
7655
+ * access data directly through _aData internally in DataTables - always use
7656
+ * the method attached to this property. It allows mData to function as
7657
+ * required. This function is automatically assigned by the column
7658
+ * initialisation method
7659
+ * @type function
7660
+ * @param {array|object} oData The data array/object for the array
7661
+ * (i.e. aoData[]._aData)
7662
+ * @param {string} sSpecific The specific data type you want to get -
7663
+ * 'display', 'type' 'filter' 'sort'
7664
+ * @returns {*} The data for the cell from the given row's data
7665
+ * @default null
7666
+ */
7667
+ "fnGetData": null,
7668
+
7669
+ /**
7670
+ * <code>Deprecated</code> Custom display function that will be called for the
7671
+ * display of each cell in this column.
7672
+ *
7673
+ * Please note that this option has now been deprecated and will be removed
7674
+ * in the next version of DataTables. Please use mRender / mData rather than
7675
+ * fnRender.
7676
+ * @type function
7677
+ * @param {object} o Object with the following parameters:
7678
+ * @param {int} o.iDataRow The row in aoData
7679
+ * @param {int} o.iDataColumn The column in question
7680
+ * @param {array} o.aData The data for the row in question
7681
+ * @param {object} o.oSettings The settings object for this DataTables instance
7682
+ * @returns {string} The string you which to use in the display
7683
+ * @default null
7684
+ * @deprecated
7685
+ */
7686
+ "fnRender": null,
7687
+
7688
+ /**
7689
+ * Function to set data for a cell in the column. You should <b>never</b>
7690
+ * set the data directly to _aData internally in DataTables - always use
7691
+ * this method. It allows mData to function as required. This function
7692
+ * is automatically assigned by the column initialisation method
7693
+ * @type function
7694
+ * @param {array|object} oData The data array/object for the array
7695
+ * (i.e. aoData[]._aData)
7696
+ * @param {*} sValue Value to set
7697
+ * @default null
7698
+ */
7699
+ "fnSetData": null,
7700
+
7701
+ /**
7702
+ * Property to read the value for the cells in the column from the data
7703
+ * source array / object. If null, then the default content is used, if a
7704
+ * function is given then the return from the function is used.
7705
+ * @type function|int|string|null
7706
+ * @default null
7707
+ */
7708
+ "mData": null,
7709
+
7710
+ /**
7711
+ * Partner property to mData which is used (only when defined) to get
7712
+ * the data - i.e. it is basically the same as mData, but without the
7713
+ * 'set' option, and also the data fed to it is the result from mData.
7714
+ * This is the rendering method to match the data method of mData.
7715
+ * @type function|int|string|null
7716
+ * @default null
7717
+ */
7718
+ "mRender": null,
7719
+
7720
+ /**
7721
+ * Unique header TH/TD element for this column - this is what the sorting
7722
+ * listener is attached to (if sorting is enabled.)
7723
+ * @type node
7724
+ * @default null
7725
+ */
7726
+ "nTh": null,
7727
+
7728
+ /**
7729
+ * Unique footer TH/TD element for this column (if there is one). Not used
7730
+ * in DataTables as such, but can be used for plug-ins to reference the
7731
+ * footer for each column.
7732
+ * @type node
7733
+ * @default null
7734
+ */
7735
+ "nTf": null,
7736
+
7737
+ /**
7738
+ * The class to apply to all TD elements in the table's TBODY for the column
7739
+ * @type string
7740
+ * @default null
7741
+ */
7742
+ "sClass": null,
7743
+
7744
+ /**
7745
+ * When DataTables calculates the column widths to assign to each column,
7746
+ * it finds the longest string in each column and then constructs a
7747
+ * temporary table and reads the widths from that. The problem with this
7748
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
7749
+ * string - thus the calculation can go wrong (doing it properly and putting
7750
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
7751
+ * a "work around" we provide this option. It will append its value to the
7752
+ * text that is found to be the longest string for the column - i.e. padding.
7753
+ * @type string
7754
+ */
7755
+ "sContentPadding": null,
7756
+
7757
+ /**
7758
+ * Allows a default value to be given for a column's data, and will be used
7759
+ * whenever a null data source is encountered (this can be because mData
7760
+ * is set to null, or because the data source itself is null).
7761
+ * @type string
7762
+ * @default null
7763
+ */
7764
+ "sDefaultContent": null,
7765
+
7766
+ /**
7767
+ * Name for the column, allowing reference to the column by name as well as
7768
+ * by index (needs a lookup to work by name).
7769
+ * @type string
7770
+ */
7771
+ "sName": null,
7772
+
7773
+ /**
7774
+ * Custom sorting data type - defines which of the available plug-ins in
7775
+ * afnSortData the custom sorting will use - if any is defined.
7776
+ * @type string
7777
+ * @default std
7778
+ */
7779
+ "sSortDataType": 'std',
7780
+
7781
+ /**
7782
+ * Class to be applied to the header element when sorting on this column
7783
+ * @type string
7784
+ * @default null
7785
+ */
7786
+ "sSortingClass": null,
7787
+
7788
+ /**
7789
+ * Class to be applied to the header element when sorting on this column -
7790
+ * when jQuery UI theming is used.
7791
+ * @type string
7792
+ * @default null
7793
+ */
7794
+ "sSortingClassJUI": null,
7795
+
7796
+ /**
7797
+ * Title of the column - what is seen in the TH element (nTh).
7798
+ * @type string
7799
+ */
7800
+ "sTitle": null,
7801
+
7802
+ /**
7803
+ * Column sorting and filtering type
7804
+ * @type string
7805
+ * @default null
7806
+ */
7807
+ "sType": null,
7808
+
7809
+ /**
7810
+ * Width of the column
7811
+ * @type string
7812
+ * @default null
7813
+ */
7814
+ "sWidth": null,
7815
+
7816
+ /**
7817
+ * Width of the column when it was first "encountered"
7818
+ * @type string
7819
+ * @default null
7820
+ */
7821
+ "sWidthOrig": null
7822
+ };
7823
+
7824
+
7825
+
7826
+ /**
7827
+ * Initialisation options that can be given to DataTables at initialisation
7828
+ * time.
7829
+ * @namespace
7830
+ */
7831
+ DataTable.defaults = {
7832
+ /**
7833
+ * An array of data to use for the table, passed in at initialisation which
7834
+ * will be used in preference to any data which is already in the DOM. This is
7835
+ * particularly useful for constructing tables purely in Javascript, for
7836
+ * example with a custom Ajax call.
7837
+ * @type array
7838
+ * @default null
7839
+ * @dtopt Option
7840
+ *
7841
+ * @example
7842
+ * // Using a 2D array data source
7843
+ * $(document).ready( function () {
7844
+ * $('#example').dataTable( {
7845
+ * "aaData": [
7846
+ * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
7847
+ * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
7848
+ * ],
7849
+ * "aoColumns": [
7850
+ * { "sTitle": "Engine" },
7851
+ * { "sTitle": "Browser" },
7852
+ * { "sTitle": "Platform" },
7853
+ * { "sTitle": "Version" },
7854
+ * { "sTitle": "Grade" }
7855
+ * ]
7856
+ * } );
7857
+ * } );
7858
+ *
7859
+ * @example
7860
+ * // Using an array of objects as a data source (mData)
7861
+ * $(document).ready( function () {
7862
+ * $('#example').dataTable( {
7863
+ * "aaData": [
7864
+ * {
7865
+ * "engine": "Trident",
7866
+ * "browser": "Internet Explorer 4.0",
7867
+ * "platform": "Win 95+",
7868
+ * "version": 4,
7869
+ * "grade": "X"
7870
+ * },
7871
+ * {
7872
+ * "engine": "Trident",
7873
+ * "browser": "Internet Explorer 5.0",
7874
+ * "platform": "Win 95+",
7875
+ * "version": 5,
7876
+ * "grade": "C"
7877
+ * }
7878
+ * ],
7879
+ * "aoColumns": [
7880
+ * { "sTitle": "Engine", "mData": "engine" },
7881
+ * { "sTitle": "Browser", "mData": "browser" },
7882
+ * { "sTitle": "Platform", "mData": "platform" },
7883
+ * { "sTitle": "Version", "mData": "version" },
7884
+ * { "sTitle": "Grade", "mData": "grade" }
7885
+ * ]
7886
+ * } );
7887
+ * } );
7888
+ */
7889
+ "aaData": null,
7890
+
7891
+
7892
+ /**
7893
+ * If sorting is enabled, then DataTables will perform a first pass sort on
7894
+ * initialisation. You can define which column(s) the sort is performed upon,
7895
+ * and the sorting direction, with this variable. The aaSorting array should
7896
+ * contain an array for each column to be sorted initially containing the
7897
+ * column's index and a direction string ('asc' or 'desc').
7898
+ * @type array
7899
+ * @default [[0,'asc']]
7900
+ * @dtopt Option
7901
+ *
7902
+ * @example
7903
+ * // Sort by 3rd column first, and then 4th column
7904
+ * $(document).ready( function() {
7905
+ * $('#example').dataTable( {
7906
+ * "aaSorting": [[2,'asc'], [3,'desc']]
7907
+ * } );
7908
+ * } );
7909
+ *
7910
+ * // No initial sorting
7911
+ * $(document).ready( function() {
7912
+ * $('#example').dataTable( {
7913
+ * "aaSorting": []
7914
+ * } );
7915
+ * } );
7916
+ */
7917
+ "aaSorting": [[0,'asc']],
7918
+
7919
+
7920
+ /**
7921
+ * This parameter is basically identical to the aaSorting parameter, but
7922
+ * cannot be overridden by user interaction with the table. What this means
7923
+ * is that you could have a column (visible or hidden) which the sorting will
7924
+ * always be forced on first - any sorting after that (from the user) will
7925
+ * then be performed as required. This can be useful for grouping rows
7926
+ * together.
7927
+ * @type array
7928
+ * @default null
7929
+ * @dtopt Option
7930
+ *
7931
+ * @example
7932
+ * $(document).ready( function() {
7933
+ * $('#example').dataTable( {
7934
+ * "aaSortingFixed": [[0,'asc']]
7935
+ * } );
7936
+ * } )
7937
+ */
7938
+ "aaSortingFixed": null,
7939
+
7940
+
7941
+ /**
7942
+ * This parameter allows you to readily specify the entries in the length drop
7943
+ * down menu that DataTables shows when pagination is enabled. It can be
7944
+ * either a 1D array of options which will be used for both the displayed
7945
+ * option and the value, or a 2D array which will use the array in the first
7946
+ * position as the value, and the array in the second position as the
7947
+ * displayed options (useful for language strings such as 'All').
7948
+ * @type array
7949
+ * @default [ 10, 25, 50, 100 ]
7950
+ * @dtopt Option
7951
+ *
7952
+ * @example
7953
+ * $(document).ready( function() {
7954
+ * $('#example').dataTable( {
7955
+ * "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
7956
+ * } );
7957
+ * } );
7958
+ *
7959
+ * @example
7960
+ * // Setting the default display length as well as length menu
7961
+ * // This is likely to be wanted if you remove the '10' option which
7962
+ * // is the iDisplayLength default.
7963
+ * $(document).ready( function() {
7964
+ * $('#example').dataTable( {
7965
+ * "iDisplayLength": 25,
7966
+ * "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]]
7967
+ * } );
7968
+ * } );
7969
+ */
7970
+ "aLengthMenu": [ 10, 25, 50, 100 ],
7971
+
7972
+
7973
+ /**
7974
+ * The aoColumns option in the initialisation parameter allows you to define
7975
+ * details about the way individual columns behave. For a full list of
7976
+ * column options that can be set, please see
7977
+ * {@link DataTable.defaults.columns}. Note that if you use aoColumns to
7978
+ * define your columns, you must have an entry in the array for every single
7979
+ * column that you have in your table (these can be null if you don't which
7980
+ * to specify any options).
7981
+ * @member
7982
+ */
7983
+ "aoColumns": null,
7984
+
7985
+ /**
7986
+ * Very similar to aoColumns, aoColumnDefs allows you to target a specific
7987
+ * column, multiple columns, or all columns, using the aTargets property of
7988
+ * each object in the array. This allows great flexibility when creating
7989
+ * tables, as the aoColumnDefs arrays can be of any length, targeting the
7990
+ * columns you specifically want. aoColumnDefs may use any of the column
7991
+ * options available: {@link DataTable.defaults.columns}, but it _must_
7992
+ * have aTargets defined in each object in the array. Values in the aTargets
7993
+ * array may be:
7994
+ * <ul>
7995
+ * <li>a string - class name will be matched on the TH for the column</li>
7996
+ * <li>0 or a positive integer - column index counting from the left</li>
7997
+ * <li>a negative integer - column index counting from the right</li>
7998
+ * <li>the string "_all" - all columns (i.e. assign a default)</li>
7999
+ * </ul>
8000
+ * @member
8001
+ */
8002
+ "aoColumnDefs": null,
8003
+
8004
+
8005
+ /**
8006
+ * Basically the same as oSearch, this parameter defines the individual column
8007
+ * filtering state at initialisation time. The array must be of the same size
8008
+ * as the number of columns, and each element be an object with the parameters
8009
+ * "sSearch" and "bEscapeRegex" (the latter is optional). 'null' is also
8010
+ * accepted and the default will be used.
8011
+ * @type array
8012
+ * @default []
8013
+ * @dtopt Option
8014
+ *
8015
+ * @example
8016
+ * $(document).ready( function() {
8017
+ * $('#example').dataTable( {
8018
+ * "aoSearchCols": [
8019
+ * null,
8020
+ * { "sSearch": "My filter" },
8021
+ * null,
8022
+ * { "sSearch": "^[0-9]", "bEscapeRegex": false }
8023
+ * ]
8024
+ * } );
8025
+ * } )
8026
+ */
8027
+ "aoSearchCols": [],
8028
+
8029
+
8030
+ /**
8031
+ * An array of CSS classes that should be applied to displayed rows. This
8032
+ * array may be of any length, and DataTables will apply each class
8033
+ * sequentially, looping when required.
8034
+ * @type array
8035
+ * @default null <i>Will take the values determined by the oClasses.sStripe*
8036
+ * options</i>
8037
+ * @dtopt Option
8038
+ *
8039
+ * @example
8040
+ * $(document).ready( function() {
8041
+ * $('#example').dataTable( {
8042
+ * "asStripeClasses": [ 'strip1', 'strip2', 'strip3' ]
8043
+ * } );
8044
+ * } )
8045
+ */
8046
+ "asStripeClasses": null,
8047
+
8048
+
8049
+ /**
8050
+ * Enable or disable automatic column width calculation. This can be disabled
8051
+ * as an optimisation (it takes some time to calculate the widths) if the
8052
+ * tables widths are passed in using aoColumns.
8053
+ * @type boolean
8054
+ * @default true
8055
+ * @dtopt Features
8056
+ *
8057
+ * @example
8058
+ * $(document).ready( function () {
8059
+ * $('#example').dataTable( {
8060
+ * "bAutoWidth": false
8061
+ * } );
8062
+ * } );
8063
+ */
8064
+ "bAutoWidth": true,
8065
+
8066
+
8067
+ /**
8068
+ * Deferred rendering can provide DataTables with a huge speed boost when you
8069
+ * are using an Ajax or JS data source for the table. This option, when set to
8070
+ * true, will cause DataTables to defer the creation of the table elements for
8071
+ * each row until they are needed for a draw - saving a significant amount of
8072
+ * time.
8073
+ * @type boolean
8074
+ * @default false
8075
+ * @dtopt Features
8076
+ *
8077
+ * @example
8078
+ * $(document).ready( function() {
8079
+ * var oTable = $('#example').dataTable( {
8080
+ * "sAjaxSource": "sources/arrays.txt",
8081
+ * "bDeferRender": true
8082
+ * } );
8083
+ * } );
8084
+ */
8085
+ "bDeferRender": false,
8086
+
8087
+
8088
+ /**
8089
+ * Replace a DataTable which matches the given selector and replace it with
8090
+ * one which has the properties of the new initialisation object passed. If no
8091
+ * table matches the selector, then the new DataTable will be constructed as
8092
+ * per normal.
8093
+ * @type boolean
8094
+ * @default false
8095
+ * @dtopt Options
8096
+ *
8097
+ * @example
8098
+ * $(document).ready( function() {
8099
+ * $('#example').dataTable( {
8100
+ * "sScrollY": "200px",
8101
+ * "bPaginate": false
8102
+ * } );
8103
+ *
8104
+ * // Some time later....
8105
+ * $('#example').dataTable( {
8106
+ * "bFilter": false,
8107
+ * "bDestroy": true
8108
+ * } );
8109
+ * } );
8110
+ */
8111
+ "bDestroy": false,
8112
+
8113
+
8114
+ /**
8115
+ * Enable or disable filtering of data. Filtering in DataTables is "smart" in
8116
+ * that it allows the end user to input multiple words (space separated) and
8117
+ * will match a row containing those words, even if not in the order that was
8118
+ * specified (this allow matching across multiple columns). Note that if you
8119
+ * wish to use filtering in DataTables this must remain 'true' - to remove the
8120
+ * default filtering input box and retain filtering abilities, please use
8121
+ * {@link DataTable.defaults.sDom}.
8122
+ * @type boolean
8123
+ * @default true
8124
+ * @dtopt Features
8125
+ *
8126
+ * @example
8127
+ * $(document).ready( function () {
8128
+ * $('#example').dataTable( {
8129
+ * "bFilter": false
8130
+ * } );
8131
+ * } );
8132
+ */
8133
+ "bFilter": true,
8134
+
8135
+
8136
+ /**
8137
+ * Enable or disable the table information display. This shows information
8138
+ * about the data that is currently visible on the page, including information
8139
+ * about filtered data if that action is being performed.
8140
+ * @type boolean
8141
+ * @default true
8142
+ * @dtopt Features
8143
+ *
8144
+ * @example
8145
+ * $(document).ready( function () {
8146
+ * $('#example').dataTable( {
8147
+ * "bInfo": false
8148
+ * } );
8149
+ * } );
8150
+ */
8151
+ "bInfo": true,
8152
+
8153
+
8154
+ /**
8155
+ * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
8156
+ * slightly different and additional mark-up from what DataTables has
8157
+ * traditionally used).
8158
+ * @type boolean
8159
+ * @default false
8160
+ * @dtopt Features
8161
+ *
8162
+ * @example
8163
+ * $(document).ready( function() {
8164
+ * $('#example').dataTable( {
8165
+ * "bJQueryUI": true
8166
+ * } );
8167
+ * } );
8168
+ */
8169
+ "bJQueryUI": false,
8170
+
8171
+
8172
+ /**
8173
+ * Allows the end user to select the size of a formatted page from a select
8174
+ * menu (sizes are 10, 25, 50 and 100). Requires pagination (bPaginate).
8175
+ * @type boolean
8176
+ * @default true
8177
+ * @dtopt Features
8178
+ *
8179
+ * @example
8180
+ * $(document).ready( function () {
8181
+ * $('#example').dataTable( {
8182
+ * "bLengthChange": false
8183
+ * } );
8184
+ * } );
8185
+ */
8186
+ "bLengthChange": true,
8187
+
8188
+
8189
+ /**
8190
+ * Enable or disable pagination.
8191
+ * @type boolean
8192
+ * @default true
8193
+ * @dtopt Features
8194
+ *
8195
+ * @example
8196
+ * $(document).ready( function () {
8197
+ * $('#example').dataTable( {
8198
+ * "bPaginate": false
8199
+ * } );
8200
+ * } );
8201
+ */
8202
+ "bPaginate": true,
8203
+
8204
+
8205
+ /**
8206
+ * Enable or disable the display of a 'processing' indicator when the table is
8207
+ * being processed (e.g. a sort). This is particularly useful for tables with
8208
+ * large amounts of data where it can take a noticeable amount of time to sort
8209
+ * the entries.
8210
+ * @type boolean
8211
+ * @default false
8212
+ * @dtopt Features
8213
+ *
8214
+ * @example
8215
+ * $(document).ready( function () {
8216
+ * $('#example').dataTable( {
8217
+ * "bProcessing": true
8218
+ * } );
8219
+ * } );
8220
+ */
8221
+ "bProcessing": false,
8222
+
8223
+
8224
+ /**
8225
+ * Retrieve the DataTables object for the given selector. Note that if the
8226
+ * table has already been initialised, this parameter will cause DataTables
8227
+ * to simply return the object that has already been set up - it will not take
8228
+ * account of any changes you might have made to the initialisation object
8229
+ * passed to DataTables (setting this parameter to true is an acknowledgement
8230
+ * that you understand this). bDestroy can be used to reinitialise a table if
8231
+ * you need.
8232
+ * @type boolean
8233
+ * @default false
8234
+ * @dtopt Options
8235
+ *
8236
+ * @example
8237
+ * $(document).ready( function() {
8238
+ * initTable();
8239
+ * tableActions();
8240
+ * } );
8241
+ *
8242
+ * function initTable ()
8243
+ * {
8244
+ * return $('#example').dataTable( {
8245
+ * "sScrollY": "200px",
8246
+ * "bPaginate": false,
8247
+ * "bRetrieve": true
8248
+ * } );
8249
+ * }
8250
+ *
8251
+ * function tableActions ()
8252
+ * {
8253
+ * var oTable = initTable();
8254
+ * // perform API operations with oTable
8255
+ * }
8256
+ */
8257
+ "bRetrieve": false,
8258
+
8259
+
8260
+ /**
8261
+ * Indicate if DataTables should be allowed to set the padding / margin
8262
+ * etc for the scrolling header elements or not. Typically you will want
8263
+ * this.
8264
+ * @type boolean
8265
+ * @default true
8266
+ * @dtopt Options
8267
+ *
8268
+ * @example
8269
+ * $(document).ready( function() {
8270
+ * $('#example').dataTable( {
8271
+ * "bScrollAutoCss": false,
8272
+ * "sScrollY": "200px"
8273
+ * } );
8274
+ * } );
8275
+ */
8276
+ "bScrollAutoCss": true,
8277
+
8278
+
8279
+ /**
8280
+ * When vertical (y) scrolling is enabled, DataTables will force the height of
8281
+ * the table's viewport to the given height at all times (useful for layout).
8282
+ * However, this can look odd when filtering data down to a small data set,
8283
+ * and the footer is left "floating" further down. This parameter (when
8284
+ * enabled) will cause DataTables to collapse the table's viewport down when
8285
+ * the result set will fit within the given Y height.
8286
+ * @type boolean
8287
+ * @default false
8288
+ * @dtopt Options
8289
+ *
8290
+ * @example
8291
+ * $(document).ready( function() {
8292
+ * $('#example').dataTable( {
8293
+ * "sScrollY": "200",
8294
+ * "bScrollCollapse": true
8295
+ * } );
8296
+ * } );
8297
+ */
8298
+ "bScrollCollapse": false,
8299
+
8300
+
8301
+ /**
8302
+ * Enable infinite scrolling for DataTables (to be used in combination with
8303
+ * sScrollY). Infinite scrolling means that DataTables will continually load
8304
+ * data as a user scrolls through a table, which is very useful for large
8305
+ * dataset. This cannot be used with pagination, which is automatically
8306
+ * disabled. Note - the Scroller extra for DataTables is recommended in
8307
+ * in preference to this option.
8308
+ * @type boolean
8309
+ * @default false
8310
+ * @dtopt Features
8311
+ *
8312
+ * @example
8313
+ * $(document).ready( function() {
8314
+ * $('#example').dataTable( {
8315
+ * "bScrollInfinite": true,
8316
+ * "bScrollCollapse": true,
8317
+ * "sScrollY": "200px"
8318
+ * } );
8319
+ * } );
8320
+ */
8321
+ "bScrollInfinite": false,
8322
+
8323
+
8324
+ /**
8325
+ * Configure DataTables to use server-side processing. Note that the
8326
+ * sAjaxSource parameter must also be given in order to give DataTables a
8327
+ * source to obtain the required data for each draw.
8328
+ * @type boolean
8329
+ * @default false
8330
+ * @dtopt Features
8331
+ * @dtopt Server-side
8332
+ *
8333
+ * @example
8334
+ * $(document).ready( function () {
8335
+ * $('#example').dataTable( {
8336
+ * "bServerSide": true,
8337
+ * "sAjaxSource": "xhr.php"
8338
+ * } );
8339
+ * } );
8340
+ */
8341
+ "bServerSide": false,
8342
+
8343
+
8344
+ /**
8345
+ * Enable or disable sorting of columns. Sorting of individual columns can be
8346
+ * disabled by the "bSortable" option for each column.
8347
+ * @type boolean
8348
+ * @default true
8349
+ * @dtopt Features
8350
+ *
8351
+ * @example
8352
+ * $(document).ready( function () {
8353
+ * $('#example').dataTable( {
8354
+ * "bSort": false
8355
+ * } );
8356
+ * } );
8357
+ */
8358
+ "bSort": true,
8359
+
8360
+
8361
+ /**
8362
+ * Allows control over whether DataTables should use the top (true) unique
8363
+ * cell that is found for a single column, or the bottom (false - default).
8364
+ * This is useful when using complex headers.
8365
+ * @type boolean
8366
+ * @default false
8367
+ * @dtopt Options
8368
+ *
8369
+ * @example
8370
+ * $(document).ready( function() {
8371
+ * $('#example').dataTable( {
8372
+ * "bSortCellsTop": true
8373
+ * } );
8374
+ * } );
8375
+ */
8376
+ "bSortCellsTop": false,
8377
+
8378
+
8379
+ /**
8380
+ * Enable or disable the addition of the classes 'sorting_1', 'sorting_2' and
8381
+ * 'sorting_3' to the columns which are currently being sorted on. This is
8382
+ * presented as a feature switch as it can increase processing time (while
8383
+ * classes are removed and added) so for large data sets you might want to
8384
+ * turn this off.
8385
+ * @type boolean
8386
+ * @default true
8387
+ * @dtopt Features
8388
+ *
8389
+ * @example
8390
+ * $(document).ready( function () {
8391
+ * $('#example').dataTable( {
8392
+ * "bSortClasses": false
8393
+ * } );
8394
+ * } );
8395
+ */
8396
+ "bSortClasses": true,
8397
+
8398
+
8399
+ /**
8400
+ * Enable or disable state saving. When enabled a cookie will be used to save
8401
+ * table display information such as pagination information, display length,
8402
+ * filtering and sorting. As such when the end user reloads the page the
8403
+ * display display will match what thy had previously set up.
8404
+ * @type boolean
8405
+ * @default false
8406
+ * @dtopt Features
8407
+ *
8408
+ * @example
8409
+ * $(document).ready( function () {
8410
+ * $('#example').dataTable( {
8411
+ * "bStateSave": true
8412
+ * } );
8413
+ * } );
8414
+ */
8415
+ "bStateSave": false,
8416
+
8417
+
8418
+ /**
8419
+ * Customise the cookie and / or the parameters being stored when using
8420
+ * DataTables with state saving enabled. This function is called whenever
8421
+ * the cookie is modified, and it expects a fully formed cookie string to be
8422
+ * returned. Note that the data object passed in is a Javascript object which
8423
+ * must be converted to a string (JSON.stringify for example).
8424
+ * @type function
8425
+ * @param {string} sName Name of the cookie defined by DataTables
8426
+ * @param {object} oData Data to be stored in the cookie
8427
+ * @param {string} sExpires Cookie expires string
8428
+ * @param {string} sPath Path of the cookie to set
8429
+ * @returns {string} Cookie formatted string (which should be encoded by
8430
+ * using encodeURIComponent())
8431
+ * @dtopt Callbacks
8432
+ *
8433
+ * @example
8434
+ * $(document).ready( function () {
8435
+ * $('#example').dataTable( {
8436
+ * "fnCookieCallback": function (sName, oData, sExpires, sPath) {
8437
+ * // Customise oData or sName or whatever else here
8438
+ * return sName + "="+JSON.stringify(oData)+"; expires=" + sExpires +"; path=" + sPath;
8439
+ * }
8440
+ * } );
8441
+ * } );
8442
+ */
8443
+ "fnCookieCallback": null,
8444
+
8445
+
8446
+ /**
8447
+ * This function is called when a TR element is created (and all TD child
8448
+ * elements have been inserted), or registered if using a DOM source, allowing
8449
+ * manipulation of the TR element (adding classes etc).
8450
+ * @type function
8451
+ * @param {node} nRow "TR" element for the current row
8452
+ * @param {array} aData Raw data array for this row
8453
+ * @param {int} iDataIndex The index of this row in aoData
8454
+ * @dtopt Callbacks
8455
+ *
8456
+ * @example
8457
+ * $(document).ready( function() {
8458
+ * $('#example').dataTable( {
8459
+ * "fnCreatedRow": function( nRow, aData, iDataIndex ) {
8460
+ * // Bold the grade for all 'A' grade browsers
8461
+ * if ( aData[4] == "A" )
8462
+ * {
8463
+ * $('td:eq(4)', nRow).html( '<b>A</b>' );
8464
+ * }
8465
+ * }
8466
+ * } );
8467
+ * } );
8468
+ */
8469
+ "fnCreatedRow": null,
8470
+
8471
+
8472
+ /**
8473
+ * This function is called on every 'draw' event, and allows you to
8474
+ * dynamically modify any aspect you want about the created DOM.
8475
+ * @type function
8476
+ * @param {object} oSettings DataTables settings object
8477
+ * @dtopt Callbacks
8478
+ *
8479
+ * @example
8480
+ * $(document).ready( function() {
8481
+ * $('#example').dataTable( {
8482
+ * "fnDrawCallback": function( oSettings ) {
8483
+ * alert( 'DataTables has redrawn the table' );
8484
+ * }
8485
+ * } );
8486
+ * } );
8487
+ */
8488
+ "fnDrawCallback": null,
8489
+
8490
+
8491
+ /**
8492
+ * Identical to fnHeaderCallback() but for the table footer this function
8493
+ * allows you to modify the table footer on every 'draw' even.
8494
+ * @type function
8495
+ * @param {node} nFoot "TR" element for the footer
8496
+ * @param {array} aData Full table data (as derived from the original HTML)
8497
+ * @param {int} iStart Index for the current display starting point in the
8498
+ * display array
8499
+ * @param {int} iEnd Index for the current display ending point in the
8500
+ * display array
8501
+ * @param {array int} aiDisplay Index array to translate the visual position
8502
+ * to the full data array
8503
+ * @dtopt Callbacks
8504
+ *
8505
+ * @example
8506
+ * $(document).ready( function() {
8507
+ * $('#example').dataTable( {
8508
+ * "fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) {
8509
+ * nFoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+iStart;
8510
+ * }
8511
+ * } );
8512
+ * } )
8513
+ */
8514
+ "fnFooterCallback": null,
8515
+
8516
+
8517
+ /**
8518
+ * When rendering large numbers in the information element for the table
8519
+ * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
8520
+ * to have a comma separator for the 'thousands' units (e.g. 1 million is
8521
+ * rendered as "1,000,000") to help readability for the end user. This
8522
+ * function will override the default method DataTables uses.
8523
+ * @type function
8524
+ * @member
8525
+ * @param {int} iIn number to be formatted
8526
+ * @returns {string} formatted string for DataTables to show the number
8527
+ * @dtopt Callbacks
8528
+ *
8529
+ * @example
8530
+ * $(document).ready( function() {
8531
+ * $('#example').dataTable( {
8532
+ * "fnFormatNumber": function ( iIn ) {
8533
+ * if ( iIn &lt; 1000 ) {
8534
+ * return iIn;
8535
+ * } else {
8536
+ * var
8537
+ * s=(iIn+""),
8538
+ * a=s.split(""), out="",
8539
+ * iLen=s.length;
8540
+ *
8541
+ * for ( var i=0 ; i&lt;iLen ; i++ ) {
8542
+ * if ( i%3 === 0 &amp;&amp; i !== 0 ) {
8543
+ * out = "'"+out;
8544
+ * }
8545
+ * out = a[iLen-i-1]+out;
8546
+ * }
8547
+ * }
8548
+ * return out;
8549
+ * };
8550
+ * } );
8551
+ * } );
8552
+ */
8553
+ "fnFormatNumber": function ( iIn ) {
8554
+ if ( iIn < 1000 )
8555
+ {
8556
+ // A small optimisation for what is likely to be the majority of use cases
8557
+ return iIn;
8558
+ }
8559
+
8560
+ var s=(iIn+""), a=s.split(""), out="", iLen=s.length;
8561
+
8562
+ for ( var i=0 ; i<iLen ; i++ )
8563
+ {
8564
+ if ( i%3 === 0 && i !== 0 )
8565
+ {
8566
+ out = this.oLanguage.sInfoThousands+out;
8567
+ }
8568
+ out = a[iLen-i-1]+out;
8569
+ }
8570
+ return out;
8571
+ },
8572
+
8573
+
8574
+ /**
8575
+ * This function is called on every 'draw' event, and allows you to
8576
+ * dynamically modify the header row. This can be used to calculate and
8577
+ * display useful information about the table.
8578
+ * @type function
8579
+ * @param {node} nHead "TR" element for the header
8580
+ * @param {array} aData Full table data (as derived from the original HTML)
8581
+ * @param {int} iStart Index for the current display starting point in the
8582
+ * display array
8583
+ * @param {int} iEnd Index for the current display ending point in the
8584
+ * display array
8585
+ * @param {array int} aiDisplay Index array to translate the visual position
8586
+ * to the full data array
8587
+ * @dtopt Callbacks
8588
+ *
8589
+ * @example
8590
+ * $(document).ready( function() {
8591
+ * $('#example').dataTable( {
8592
+ * "fnHeaderCallback": function( nHead, aData, iStart, iEnd, aiDisplay ) {
8593
+ * nHead.getElementsByTagName('th')[0].innerHTML = "Displaying "+(iEnd-iStart)+" records";
8594
+ * }
8595
+ * } );
8596
+ * } )
8597
+ */
8598
+ "fnHeaderCallback": null,
8599
+
8600
+
8601
+ /**
8602
+ * The information element can be used to convey information about the current
8603
+ * state of the table. Although the internationalisation options presented by
8604
+ * DataTables are quite capable of dealing with most customisations, there may
8605
+ * be times where you wish to customise the string further. This callback
8606
+ * allows you to do exactly that.
8607
+ * @type function
8608
+ * @param {object} oSettings DataTables settings object
8609
+ * @param {int} iStart Starting position in data for the draw
8610
+ * @param {int} iEnd End position in data for the draw
8611
+ * @param {int} iMax Total number of rows in the table (regardless of
8612
+ * filtering)
8613
+ * @param {int} iTotal Total number of rows in the data set, after filtering
8614
+ * @param {string} sPre The string that DataTables has formatted using it's
8615
+ * own rules
8616
+ * @returns {string} The string to be displayed in the information element.
8617
+ * @dtopt Callbacks
8618
+ *
8619
+ * @example
8620
+ * $('#example').dataTable( {
8621
+ * "fnInfoCallback": function( oSettings, iStart, iEnd, iMax, iTotal, sPre ) {
8622
+ * return iStart +" to "+ iEnd;
8623
+ * }
8624
+ * } );
8625
+ */
8626
+ "fnInfoCallback": null,
8627
+
8628
+
8629
+ /**
8630
+ * Called when the table has been initialised. Normally DataTables will
8631
+ * initialise sequentially and there will be no need for this function,
8632
+ * however, this does not hold true when using external language information
8633
+ * since that is obtained using an async XHR call.
8634
+ * @type function
8635
+ * @param {object} oSettings DataTables settings object
8636
+ * @param {object} json The JSON object request from the server - only
8637
+ * present if client-side Ajax sourced data is used
8638
+ * @dtopt Callbacks
8639
+ *
8640
+ * @example
8641
+ * $(document).ready( function() {
8642
+ * $('#example').dataTable( {
8643
+ * "fnInitComplete": function(oSettings, json) {
8644
+ * alert( 'DataTables has finished its initialisation.' );
8645
+ * }
8646
+ * } );
8647
+ * } )
8648
+ */
8649
+ "fnInitComplete": null,
8650
+
8651
+
8652
+ /**
8653
+ * Called at the very start of each table draw and can be used to cancel the
8654
+ * draw by returning false, any other return (including undefined) results in
8655
+ * the full draw occurring).
8656
+ * @type function
8657
+ * @param {object} oSettings DataTables settings object
8658
+ * @returns {boolean} False will cancel the draw, anything else (including no
8659
+ * return) will allow it to complete.
8660
+ * @dtopt Callbacks
8661
+ *
8662
+ * @example
8663
+ * $(document).ready( function() {
8664
+ * $('#example').dataTable( {
8665
+ * "fnPreDrawCallback": function( oSettings ) {
8666
+ * if ( $('#test').val() == 1 ) {
8667
+ * return false;
8668
+ * }
8669
+ * }
8670
+ * } );
8671
+ * } );
8672
+ */
8673
+ "fnPreDrawCallback": null,
8674
+
8675
+
8676
+ /**
8677
+ * This function allows you to 'post process' each row after it have been
8678
+ * generated for each table draw, but before it is rendered on screen. This
8679
+ * function might be used for setting the row class name etc.
8680
+ * @type function
8681
+ * @param {node} nRow "TR" element for the current row
8682
+ * @param {array} aData Raw data array for this row
8683
+ * @param {int} iDisplayIndex The display index for the current table draw
8684
+ * @param {int} iDisplayIndexFull The index of the data in the full list of
8685
+ * rows (after filtering)
8686
+ * @dtopt Callbacks
8687
+ *
8688
+ * @example
8689
+ * $(document).ready( function() {
8690
+ * $('#example').dataTable( {
8691
+ * "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
8692
+ * // Bold the grade for all 'A' grade browsers
8693
+ * if ( aData[4] == "A" )
8694
+ * {
8695
+ * $('td:eq(4)', nRow).html( '<b>A</b>' );
8696
+ * }
8697
+ * }
8698
+ * } );
8699
+ * } );
8700
+ */
8701
+ "fnRowCallback": null,
8702
+
8703
+
8704
+ /**
8705
+ * This parameter allows you to override the default function which obtains
8706
+ * the data from the server ($.getJSON) so something more suitable for your
8707
+ * application. For example you could use POST data, or pull information from
8708
+ * a Gears or AIR database.
8709
+ * @type function
8710
+ * @member
8711
+ * @param {string} sSource HTTP source to obtain the data from (sAjaxSource)
8712
+ * @param {array} aoData A key/value pair object containing the data to send
8713
+ * to the server
8714
+ * @param {function} fnCallback to be called on completion of the data get
8715
+ * process that will draw the data on the page.
8716
+ * @param {object} oSettings DataTables settings object
8717
+ * @dtopt Callbacks
8718
+ * @dtopt Server-side
8719
+ *
8720
+ * @example
8721
+ * // POST data to server
8722
+ * $(document).ready( function() {
8723
+ * $('#example').dataTable( {
8724
+ * "bProcessing": true,
8725
+ * "bServerSide": true,
8726
+ * "sAjaxSource": "xhr.php",
8727
+ * "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) {
8728
+ * oSettings.jqXHR = $.ajax( {
8729
+ * "dataType": 'json',
8730
+ * "type": "POST",
8731
+ * "url": sSource,
8732
+ * "data": aoData,
8733
+ * "success": fnCallback
8734
+ * } );
8735
+ * }
8736
+ * } );
8737
+ * } );
8738
+ */
8739
+ "fnServerData": function ( sUrl, aoData, fnCallback, oSettings ) {
8740
+ oSettings.jqXHR = $.ajax( {
8741
+ "url": sUrl,
8742
+ "data": aoData,
8743
+ "success": function (json) {
8744
+ if ( json.sError ) {
8745
+ oSettings.oApi._fnLog( oSettings, 0, json.sError );
8746
+ }
8747
+
8748
+ $(oSettings.oInstance).trigger('xhr', [oSettings, json]);
8749
+ fnCallback( json );
8750
+ },
8751
+ "dataType": "json",
8752
+ "cache": false,
8753
+ "type": oSettings.sServerMethod,
8754
+ "error": function (xhr, error, thrown) {
8755
+ if ( error == "parsererror" ) {
8756
+ oSettings.oApi._fnLog( oSettings, 0, "DataTables warning: JSON data from "+
8757
+ "server could not be parsed. This is caused by a JSON formatting error." );
8758
+ }
8759
+ }
8760
+ } );
8761
+ },
8762
+
8763
+
8764
+ /**
8765
+ * It is often useful to send extra data to the server when making an Ajax
8766
+ * request - for example custom filtering information, and this callback
8767
+ * function makes it trivial to send extra information to the server. The
8768
+ * passed in parameter is the data set that has been constructed by
8769
+ * DataTables, and you can add to this or modify it as you require.
8770
+ * @type function
8771
+ * @param {array} aoData Data array (array of objects which are name/value
8772
+ * pairs) that has been constructed by DataTables and will be sent to the
8773
+ * server. In the case of Ajax sourced data with server-side processing
8774
+ * this will be an empty array, for server-side processing there will be a
8775
+ * significant number of parameters!
8776
+ * @returns {undefined} Ensure that you modify the aoData array passed in,
8777
+ * as this is passed by reference.
8778
+ * @dtopt Callbacks
8779
+ * @dtopt Server-side
8780
+ *
8781
+ * @example
8782
+ * $(document).ready( function() {
8783
+ * $('#example').dataTable( {
8784
+ * "bProcessing": true,
8785
+ * "bServerSide": true,
8786
+ * "sAjaxSource": "scripts/server_processing.php",
8787
+ * "fnServerParams": function ( aoData ) {
8788
+ * aoData.push( { "name": "more_data", "value": "my_value" } );
8789
+ * }
8790
+ * } );
8791
+ * } );
8792
+ */
8793
+ "fnServerParams": null,
8794
+
8795
+
8796
+ /**
8797
+ * Load the table state. With this function you can define from where, and how, the
8798
+ * state of a table is loaded. By default DataTables will load from its state saving
8799
+ * cookie, but you might wish to use local storage (HTML5) or a server-side database.
8800
+ * @type function
8801
+ * @member
8802
+ * @param {object} oSettings DataTables settings object
8803
+ * @return {object} The DataTables state object to be loaded
8804
+ * @dtopt Callbacks
8805
+ *
8806
+ * @example
8807
+ * $(document).ready( function() {
8808
+ * $('#example').dataTable( {
8809
+ * "bStateSave": true,
8810
+ * "fnStateLoad": function (oSettings) {
8811
+ * var o;
8812
+ *
8813
+ * // Send an Ajax request to the server to get the data. Note that
8814
+ * // this is a synchronous request.
8815
+ * $.ajax( {
8816
+ * "url": "/state_load",
8817
+ * "async": false,
8818
+ * "dataType": "json",
8819
+ * "success": function (json) {
8820
+ * o = json;
8821
+ * }
8822
+ * } );
8823
+ *
8824
+ * return o;
8825
+ * }
8826
+ * } );
8827
+ * } );
8828
+ */
8829
+ "fnStateLoad": function ( oSettings ) {
8830
+ var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance );
8831
+ var oData;
8832
+
8833
+ try {
8834
+ oData = (typeof $.parseJSON === 'function') ?
8835
+ $.parseJSON(sData) : eval( '('+sData+')' );
8836
+ } catch (e) {
8837
+ oData = null;
8838
+ }
8839
+
8840
+ return oData;
8841
+ },
8842
+
8843
+
8844
+ /**
8845
+ * Callback which allows modification of the saved state prior to loading that state.
8846
+ * This callback is called when the table is loading state from the stored data, but
8847
+ * prior to the settings object being modified by the saved state. Note that for
8848
+ * plug-in authors, you should use the 'stateLoadParams' event to load parameters for
8849
+ * a plug-in.
8850
+ * @type function
8851
+ * @param {object} oSettings DataTables settings object
8852
+ * @param {object} oData The state object that is to be loaded
8853
+ * @dtopt Callbacks
8854
+ *
8855
+ * @example
8856
+ * // Remove a saved filter, so filtering is never loaded
8857
+ * $(document).ready( function() {
8858
+ * $('#example').dataTable( {
8859
+ * "bStateSave": true,
8860
+ * "fnStateLoadParams": function (oSettings, oData) {
8861
+ * oData.oSearch.sSearch = "";
8862
+ * }
8863
+ * } );
8864
+ * } );
8865
+ *
8866
+ * @example
8867
+ * // Disallow state loading by returning false
8868
+ * $(document).ready( function() {
8869
+ * $('#example').dataTable( {
8870
+ * "bStateSave": true,
8871
+ * "fnStateLoadParams": function (oSettings, oData) {
8872
+ * return false;
8873
+ * }
8874
+ * } );
8875
+ * } );
8876
+ */
8877
+ "fnStateLoadParams": null,
8878
+
8879
+
8880
+ /**
8881
+ * Callback that is called when the state has been loaded from the state saving method
8882
+ * and the DataTables settings object has been modified as a result of the loaded state.
8883
+ * @type function
8884
+ * @param {object} oSettings DataTables settings object
8885
+ * @param {object} oData The state object that was loaded
8886
+ * @dtopt Callbacks
8887
+ *
8888
+ * @example
8889
+ * // Show an alert with the filtering value that was saved
8890
+ * $(document).ready( function() {
8891
+ * $('#example').dataTable( {
8892
+ * "bStateSave": true,
8893
+ * "fnStateLoaded": function (oSettings, oData) {
8894
+ * alert( 'Saved filter was: '+oData.oSearch.sSearch );
8895
+ * }
8896
+ * } );
8897
+ * } );
8898
+ */
8899
+ "fnStateLoaded": null,
8900
+
8901
+
8902
+ /**
8903
+ * Save the table state. This function allows you to define where and how the state
8904
+ * information for the table is stored - by default it will use a cookie, but you
8905
+ * might want to use local storage (HTML5) or a server-side database.
8906
+ * @type function
8907
+ * @member
8908
+ * @param {object} oSettings DataTables settings object
8909
+ * @param {object} oData The state object to be saved
8910
+ * @dtopt Callbacks
8911
+ *
8912
+ * @example
8913
+ * $(document).ready( function() {
8914
+ * $('#example').dataTable( {
8915
+ * "bStateSave": true,
8916
+ * "fnStateSave": function (oSettings, oData) {
8917
+ * // Send an Ajax request to the server with the state object
8918
+ * $.ajax( {
8919
+ * "url": "/state_save",
8920
+ * "data": oData,
8921
+ * "dataType": "json",
8922
+ * "method": "POST"
8923
+ * "success": function () {}
8924
+ * } );
8925
+ * }
8926
+ * } );
8927
+ * } );
8928
+ */
8929
+ "fnStateSave": function ( oSettings, oData ) {
8930
+ this.oApi._fnCreateCookie(
8931
+ oSettings.sCookiePrefix+oSettings.sInstance,
8932
+ this.oApi._fnJsonString(oData),
8933
+ oSettings.iCookieDuration,
8934
+ oSettings.sCookiePrefix,
8935
+ oSettings.fnCookieCallback
8936
+ );
8937
+ },
8938
+
8939
+
8940
+ /**
8941
+ * Callback which allows modification of the state to be saved. Called when the table
8942
+ * has changed state a new state save is required. This method allows modification of
8943
+ * the state saving object prior to actually doing the save, including addition or
8944
+ * other state properties or modification. Note that for plug-in authors, you should
8945
+ * use the 'stateSaveParams' event to save parameters for a plug-in.
8946
+ * @type function
8947
+ * @param {object} oSettings DataTables settings object
8948
+ * @param {object} oData The state object to be saved
8949
+ * @dtopt Callbacks
8950
+ *
8951
+ * @example
8952
+ * // Remove a saved filter, so filtering is never saved
8953
+ * $(document).ready( function() {
8954
+ * $('#example').dataTable( {
8955
+ * "bStateSave": true,
8956
+ * "fnStateSaveParams": function (oSettings, oData) {
8957
+ * oData.oSearch.sSearch = "";
8958
+ * }
8959
+ * } );
8960
+ * } );
8961
+ */
8962
+ "fnStateSaveParams": null,
8963
+
8964
+
8965
+ /**
8966
+ * Duration of the cookie which is used for storing session information. This
8967
+ * value is given in seconds.
8968
+ * @type int
8969
+ * @default 7200 <i>(2 hours)</i>
8970
+ * @dtopt Options
8971
+ *
8972
+ * @example
8973
+ * $(document).ready( function() {
8974
+ * $('#example').dataTable( {
8975
+ * "iCookieDuration": 60*60*24; // 1 day
8976
+ * } );
8977
+ * } )
8978
+ */
8979
+ "iCookieDuration": 7200,
8980
+
8981
+
8982
+ /**
8983
+ * When enabled DataTables will not make a request to the server for the first
8984
+ * page draw - rather it will use the data already on the page (no sorting etc
8985
+ * will be applied to it), thus saving on an XHR at load time. iDeferLoading
8986
+ * is used to indicate that deferred loading is required, but it is also used
8987
+ * to tell DataTables how many records there are in the full table (allowing
8988
+ * the information element and pagination to be displayed correctly). In the case
8989
+ * where a filtering is applied to the table on initial load, this can be
8990
+ * indicated by giving the parameter as an array, where the first element is
8991
+ * the number of records available after filtering and the second element is the
8992
+ * number of records without filtering (allowing the table information element
8993
+ * to be shown correctly).
8994
+ * @type int | array
8995
+ * @default null
8996
+ * @dtopt Options
8997
+ *
8998
+ * @example
8999
+ * // 57 records available in the table, no filtering applied
9000
+ * $(document).ready( function() {
9001
+ * $('#example').dataTable( {
9002
+ * "bServerSide": true,
9003
+ * "sAjaxSource": "scripts/server_processing.php",
9004
+ * "iDeferLoading": 57
9005
+ * } );
9006
+ * } );
9007
+ *
9008
+ * @example
9009
+ * // 57 records after filtering, 100 without filtering (an initial filter applied)
9010
+ * $(document).ready( function() {
9011
+ * $('#example').dataTable( {
9012
+ * "bServerSide": true,
9013
+ * "sAjaxSource": "scripts/server_processing.php",
9014
+ * "iDeferLoading": [ 57, 100 ],
9015
+ * "oSearch": {
9016
+ * "sSearch": "my_filter"
9017
+ * }
9018
+ * } );
9019
+ * } );
9020
+ */
9021
+ "iDeferLoading": null,
9022
+
9023
+
9024
+ /**
9025
+ * Number of rows to display on a single page when using pagination. If
9026
+ * feature enabled (bLengthChange) then the end user will be able to override
9027
+ * this to a custom setting using a pop-up menu.
9028
+ * @type int
9029
+ * @default 10
9030
+ * @dtopt Options
9031
+ *
9032
+ * @example
9033
+ * $(document).ready( function() {
9034
+ * $('#example').dataTable( {
9035
+ * "iDisplayLength": 50
9036
+ * } );
9037
+ * } )
9038
+ */
9039
+ "iDisplayLength": 10,
9040
+
9041
+
9042
+ /**
9043
+ * Define the starting point for data display when using DataTables with
9044
+ * pagination. Note that this parameter is the number of records, rather than
9045
+ * the page number, so if you have 10 records per page and want to start on
9046
+ * the third page, it should be "20".
9047
+ * @type int
9048
+ * @default 0
9049
+ * @dtopt Options
9050
+ *
9051
+ * @example
9052
+ * $(document).ready( function() {
9053
+ * $('#example').dataTable( {
9054
+ * "iDisplayStart": 20
9055
+ * } );
9056
+ * } )
9057
+ */
9058
+ "iDisplayStart": 0,
9059
+
9060
+
9061
+ /**
9062
+ * The scroll gap is the amount of scrolling that is left to go before
9063
+ * DataTables will load the next 'page' of data automatically. You typically
9064
+ * want a gap which is big enough that the scrolling will be smooth for the
9065
+ * user, while not so large that it will load more data than need.
9066
+ * @type int
9067
+ * @default 100
9068
+ * @dtopt Options
9069
+ *
9070
+ * @example
9071
+ * $(document).ready( function() {
9072
+ * $('#example').dataTable( {
9073
+ * "bScrollInfinite": true,
9074
+ * "bScrollCollapse": true,
9075
+ * "sScrollY": "200px",
9076
+ * "iScrollLoadGap": 50
9077
+ * } );
9078
+ * } );
9079
+ */
9080
+ "iScrollLoadGap": 100,
9081
+
9082
+
9083
+ /**
9084
+ * By default DataTables allows keyboard navigation of the table (sorting, paging,
9085
+ * and filtering) by adding a tabindex attribute to the required elements. This
9086
+ * allows you to tab through the controls and press the enter key to activate them.
9087
+ * The tabindex is default 0, meaning that the tab follows the flow of the document.
9088
+ * You can overrule this using this parameter if you wish. Use a value of -1 to
9089
+ * disable built-in keyboard navigation.
9090
+ * @type int
9091
+ * @default 0
9092
+ * @dtopt Options
9093
+ *
9094
+ * @example
9095
+ * $(document).ready( function() {
9096
+ * $('#example').dataTable( {
9097
+ * "iTabIndex": 1
9098
+ * } );
9099
+ * } );
9100
+ */
9101
+ "iTabIndex": 0,
9102
+
9103
+
9104
+ /**
9105
+ * All strings that DataTables uses in the user interface that it creates
9106
+ * are defined in this object, allowing you to modified them individually or
9107
+ * completely replace them all as required.
9108
+ * @namespace
9109
+ */
9110
+ "oLanguage": {
9111
+ /**
9112
+ * Strings that are used for WAI-ARIA labels and controls only (these are not
9113
+ * actually visible on the page, but will be read by screenreaders, and thus
9114
+ * must be internationalised as well).
9115
+ * @namespace
9116
+ */
9117
+ "oAria": {
9118
+ /**
9119
+ * ARIA label that is added to the table headers when the column may be
9120
+ * sorted ascending by activing the column (click or return when focused).
9121
+ * Note that the column header is prefixed to this string.
9122
+ * @type string
9123
+ * @default : activate to sort column ascending
9124
+ * @dtopt Language
9125
+ *
9126
+ * @example
9127
+ * $(document).ready( function() {
9128
+ * $('#example').dataTable( {
9129
+ * "oLanguage": {
9130
+ * "oAria": {
9131
+ * "sSortAscending": " - click/return to sort ascending"
9132
+ * }
9133
+ * }
9134
+ * } );
9135
+ * } );
9136
+ */
9137
+ "sSortAscending": ": activate to sort column ascending",
9138
+
9139
+ /**
9140
+ * ARIA label that is added to the table headers when the column may be
9141
+ * sorted descending by activing the column (click or return when focused).
9142
+ * Note that the column header is prefixed to this string.
9143
+ * @type string
9144
+ * @default : activate to sort column ascending
9145
+ * @dtopt Language
9146
+ *
9147
+ * @example
9148
+ * $(document).ready( function() {
9149
+ * $('#example').dataTable( {
9150
+ * "oLanguage": {
9151
+ * "oAria": {
9152
+ * "sSortDescending": " - click/return to sort descending"
9153
+ * }
9154
+ * }
9155
+ * } );
9156
+ * } );
9157
+ */
9158
+ "sSortDescending": ": activate to sort column descending"
9159
+ },
9160
+
9161
+ /**
9162
+ * Pagination string used by DataTables for the two built-in pagination
9163
+ * control types ("two_button" and "full_numbers")
9164
+ * @namespace
9165
+ */
9166
+ "oPaginate": {
9167
+ /**
9168
+ * Text to use when using the 'full_numbers' type of pagination for the
9169
+ * button to take the user to the first page.
9170
+ * @type string
9171
+ * @default First
9172
+ * @dtopt Language
9173
+ *
9174
+ * @example
9175
+ * $(document).ready( function() {
9176
+ * $('#example').dataTable( {
9177
+ * "oLanguage": {
9178
+ * "oPaginate": {
9179
+ * "sFirst": "First page"
9180
+ * }
9181
+ * }
9182
+ * } );
9183
+ * } );
9184
+ */
9185
+ "sFirst": "First",
9186
+
9187
+
9188
+ /**
9189
+ * Text to use when using the 'full_numbers' type of pagination for the
9190
+ * button to take the user to the last page.
9191
+ * @type string
9192
+ * @default Last
9193
+ * @dtopt Language
9194
+ *
9195
+ * @example
9196
+ * $(document).ready( function() {
9197
+ * $('#example').dataTable( {
9198
+ * "oLanguage": {
9199
+ * "oPaginate": {
9200
+ * "sLast": "Last page"
9201
+ * }
9202
+ * }
9203
+ * } );
9204
+ * } );
9205
+ */
9206
+ "sLast": "Last",
9207
+
9208
+
9209
+ /**
9210
+ * Text to use for the 'next' pagination button (to take the user to the
9211
+ * next page).
9212
+ * @type string
9213
+ * @default Next
9214
+ * @dtopt Language
9215
+ *
9216
+ * @example
9217
+ * $(document).ready( function() {
9218
+ * $('#example').dataTable( {
9219
+ * "oLanguage": {
9220
+ * "oPaginate": {
9221
+ * "sNext": "Next page"
9222
+ * }
9223
+ * }
9224
+ * } );
9225
+ * } );
9226
+ */
9227
+ "sNext": "Next",
9228
+
9229
+
9230
+ /**
9231
+ * Text to use for the 'previous' pagination button (to take the user to
9232
+ * the previous page).
9233
+ * @type string
9234
+ * @default Previous
9235
+ * @dtopt Language
9236
+ *
9237
+ * @example
9238
+ * $(document).ready( function() {
9239
+ * $('#example').dataTable( {
9240
+ * "oLanguage": {
9241
+ * "oPaginate": {
9242
+ * "sPrevious": "Previous page"
9243
+ * }
9244
+ * }
9245
+ * } );
9246
+ * } );
9247
+ */
9248
+ "sPrevious": "Previous"
9249
+ },
9250
+
9251
+ /**
9252
+ * This string is shown in preference to sZeroRecords when the table is
9253
+ * empty of data (regardless of filtering). Note that this is an optional
9254
+ * parameter - if it is not given, the value of sZeroRecords will be used
9255
+ * instead (either the default or given value).
9256
+ * @type string
9257
+ * @default No data available in table
9258
+ * @dtopt Language
9259
+ *
9260
+ * @example
9261
+ * $(document).ready( function() {
9262
+ * $('#example').dataTable( {
9263
+ * "oLanguage": {
9264
+ * "sEmptyTable": "No data available in table"
9265
+ * }
9266
+ * } );
9267
+ * } );
9268
+ */
9269
+ "sEmptyTable": "No data available in table",
9270
+
9271
+
9272
+ /**
9273
+ * This string gives information to the end user about the information that
9274
+ * is current on display on the page. The _START_, _END_ and _TOTAL_
9275
+ * variables are all dynamically replaced as the table display updates, and
9276
+ * can be freely moved or removed as the language requirements change.
9277
+ * @type string
9278
+ * @default Showing _START_ to _END_ of _TOTAL_ entries
9279
+ * @dtopt Language
9280
+ *
9281
+ * @example
9282
+ * $(document).ready( function() {
9283
+ * $('#example').dataTable( {
9284
+ * "oLanguage": {
9285
+ * "sInfo": "Got a total of _TOTAL_ entries to show (_START_ to _END_)"
9286
+ * }
9287
+ * } );
9288
+ * } );
9289
+ */
9290
+ "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
9291
+
9292
+
9293
+ /**
9294
+ * Display information string for when the table is empty. Typically the
9295
+ * format of this string should match sInfo.
9296
+ * @type string
9297
+ * @default Showing 0 to 0 of 0 entries
9298
+ * @dtopt Language
9299
+ *
9300
+ * @example
9301
+ * $(document).ready( function() {
9302
+ * $('#example').dataTable( {
9303
+ * "oLanguage": {
9304
+ * "sInfoEmpty": "No entries to show"
9305
+ * }
9306
+ * } );
9307
+ * } );
9308
+ */
9309
+ "sInfoEmpty": "Showing 0 to 0 of 0 entries",
9310
+
9311
+
9312
+ /**
9313
+ * When a user filters the information in a table, this string is appended
9314
+ * to the information (sInfo) to give an idea of how strong the filtering
9315
+ * is. The variable _MAX_ is dynamically updated.
9316
+ * @type string
9317
+ * @default (filtered from _MAX_ total entries)
9318
+ * @dtopt Language
9319
+ *
9320
+ * @example
9321
+ * $(document).ready( function() {
9322
+ * $('#example').dataTable( {
9323
+ * "oLanguage": {
9324
+ * "sInfoFiltered": " - filtering from _MAX_ records"
9325
+ * }
9326
+ * } );
9327
+ * } );
9328
+ */
9329
+ "sInfoFiltered": "(filtered from _MAX_ total entries)",
9330
+
9331
+
9332
+ /**
9333
+ * If can be useful to append extra information to the info string at times,
9334
+ * and this variable does exactly that. This information will be appended to
9335
+ * the sInfo (sInfoEmpty and sInfoFiltered in whatever combination they are
9336
+ * being used) at all times.
9337
+ * @type string
9338
+ * @default <i>Empty string</i>
9339
+ * @dtopt Language
9340
+ *
9341
+ * @example
9342
+ * $(document).ready( function() {
9343
+ * $('#example').dataTable( {
9344
+ * "oLanguage": {
9345
+ * "sInfoPostFix": "All records shown are derived from real information."
9346
+ * }
9347
+ * } );
9348
+ * } );
9349
+ */
9350
+ "sInfoPostFix": "",
9351
+
9352
+
9353
+ /**
9354
+ * DataTables has a build in number formatter (fnFormatNumber) which is used
9355
+ * to format large numbers that are used in the table information. By
9356
+ * default a comma is used, but this can be trivially changed to any
9357
+ * character you wish with this parameter.
9358
+ * @type string
9359
+ * @default ,
9360
+ * @dtopt Language
9361
+ *
9362
+ * @example
9363
+ * $(document).ready( function() {
9364
+ * $('#example').dataTable( {
9365
+ * "oLanguage": {
9366
+ * "sInfoThousands": "'"
9367
+ * }
9368
+ * } );
9369
+ * } );
9370
+ */
9371
+ "sInfoThousands": ",",
9372
+
9373
+
9374
+ /**
9375
+ * Detail the action that will be taken when the drop down menu for the
9376
+ * pagination length option is changed. The '_MENU_' variable is replaced
9377
+ * with a default select list of 10, 25, 50 and 100, and can be replaced
9378
+ * with a custom select box if required.
9379
+ * @type string
9380
+ * @default Show _MENU_ entries
9381
+ * @dtopt Language
9382
+ *
9383
+ * @example
9384
+ * // Language change only
9385
+ * $(document).ready( function() {
9386
+ * $('#example').dataTable( {
9387
+ * "oLanguage": {
9388
+ * "sLengthMenu": "Display _MENU_ records"
9389
+ * }
9390
+ * } );
9391
+ * } );
9392
+ *
9393
+ * @example
9394
+ * // Language and options change
9395
+ * $(document).ready( function() {
9396
+ * $('#example').dataTable( {
9397
+ * "oLanguage": {
9398
+ * "sLengthMenu": 'Display <select>'+
9399
+ * '<option value="10">10</option>'+
9400
+ * '<option value="20">20</option>'+
9401
+ * '<option value="30">30</option>'+
9402
+ * '<option value="40">40</option>'+
9403
+ * '<option value="50">50</option>'+
9404
+ * '<option value="-1">All</option>'+
9405
+ * '</select> records'
9406
+ * }
9407
+ * } );
9408
+ * } );
9409
+ */
9410
+ "sLengthMenu": "Show _MENU_ entries",
9411
+
9412
+
9413
+ /**
9414
+ * When using Ajax sourced data and during the first draw when DataTables is
9415
+ * gathering the data, this message is shown in an empty row in the table to
9416
+ * indicate to the end user the the data is being loaded. Note that this
9417
+ * parameter is not used when loading data by server-side processing, just
9418
+ * Ajax sourced data with client-side processing.
9419
+ * @type string
9420
+ * @default Loading...
9421
+ * @dtopt Language
9422
+ *
9423
+ * @example
9424
+ * $(document).ready( function() {
9425
+ * $('#example').dataTable( {
9426
+ * "oLanguage": {
9427
+ * "sLoadingRecords": "Please wait - loading..."
9428
+ * }
9429
+ * } );
9430
+ * } );
9431
+ */
9432
+ "sLoadingRecords": "Loading...",
9433
+
9434
+
9435
+ /**
9436
+ * Text which is displayed when the table is processing a user action
9437
+ * (usually a sort command or similar).
9438
+ * @type string
9439
+ * @default Processing...
9440
+ * @dtopt Language
9441
+ *
9442
+ * @example
9443
+ * $(document).ready( function() {
9444
+ * $('#example').dataTable( {
9445
+ * "oLanguage": {
9446
+ * "sProcessing": "DataTables is currently busy"
9447
+ * }
9448
+ * } );
9449
+ * } );
9450
+ */
9451
+ "sProcessing": "Processing...",
9452
+
9453
+
9454
+ /**
9455
+ * Details the actions that will be taken when the user types into the
9456
+ * filtering input text box. The variable "_INPUT_", if used in the string,
9457
+ * is replaced with the HTML text box for the filtering input allowing
9458
+ * control over where it appears in the string. If "_INPUT_" is not given
9459
+ * then the input box is appended to the string automatically.
9460
+ * @type string
9461
+ * @default Search:
9462
+ * @dtopt Language
9463
+ *
9464
+ * @example
9465
+ * // Input text box will be appended at the end automatically
9466
+ * $(document).ready( function() {
9467
+ * $('#example').dataTable( {
9468
+ * "oLanguage": {
9469
+ * "sSearch": "Filter records:"
9470
+ * }
9471
+ * } );
9472
+ * } );
9473
+ *
9474
+ * @example
9475
+ * // Specify where the filter should appear
9476
+ * $(document).ready( function() {
9477
+ * $('#example').dataTable( {
9478
+ * "oLanguage": {
9479
+ * "sSearch": "Apply filter _INPUT_ to table"
9480
+ * }
9481
+ * } );
9482
+ * } );
9483
+ */
9484
+ "sSearch": "Search:",
9485
+
9486
+
9487
+ /**
9488
+ * All of the language information can be stored in a file on the
9489
+ * server-side, which DataTables will look up if this parameter is passed.
9490
+ * It must store the URL of the language file, which is in a JSON format,
9491
+ * and the object has the same properties as the oLanguage object in the
9492
+ * initialiser object (i.e. the above parameters). Please refer to one of
9493
+ * the example language files to see how this works in action.
9494
+ * @type string
9495
+ * @default <i>Empty string - i.e. disabled</i>
9496
+ * @dtopt Language
9497
+ *
9498
+ * @example
9499
+ * $(document).ready( function() {
9500
+ * $('#example').dataTable( {
9501
+ * "oLanguage": {
9502
+ * "sUrl": "http://www.sprymedia.co.uk/dataTables/lang.txt"
9503
+ * }
9504
+ * } );
9505
+ * } );
9506
+ */
9507
+ "sUrl": "",
9508
+
9509
+
9510
+ /**
9511
+ * Text shown inside the table records when the is no information to be
9512
+ * displayed after filtering. sEmptyTable is shown when there is simply no
9513
+ * information in the table at all (regardless of filtering).
9514
+ * @type string
9515
+ * @default No matching records found
9516
+ * @dtopt Language
9517
+ *
9518
+ * @example
9519
+ * $(document).ready( function() {
9520
+ * $('#example').dataTable( {
9521
+ * "oLanguage": {
9522
+ * "sZeroRecords": "No records to display"
9523
+ * }
9524
+ * } );
9525
+ * } );
9526
+ */
9527
+ "sZeroRecords": "No matching records found"
9528
+ },
9529
+
9530
+
9531
+ /**
9532
+ * This parameter allows you to have define the global filtering state at
9533
+ * initialisation time. As an object the "sSearch" parameter must be
9534
+ * defined, but all other parameters are optional. When "bRegex" is true,
9535
+ * the search string will be treated as a regular expression, when false
9536
+ * (default) it will be treated as a straight string. When "bSmart"
9537
+ * DataTables will use it's smart filtering methods (to word match at
9538
+ * any point in the data), when false this will not be done.
9539
+ * @namespace
9540
+ * @extends DataTable.models.oSearch
9541
+ * @dtopt Options
9542
+ *
9543
+ * @example
9544
+ * $(document).ready( function() {
9545
+ * $('#example').dataTable( {
9546
+ * "oSearch": {"sSearch": "Initial search"}
9547
+ * } );
9548
+ * } )
9549
+ */
9550
+ "oSearch": $.extend( {}, DataTable.models.oSearch ),
9551
+
9552
+
9553
+ /**
9554
+ * By default DataTables will look for the property 'aaData' when obtaining
9555
+ * data from an Ajax source or for server-side processing - this parameter
9556
+ * allows that property to be changed. You can use Javascript dotted object
9557
+ * notation to get a data source for multiple levels of nesting.
9558
+ * @type string
9559
+ * @default aaData
9560
+ * @dtopt Options
9561
+ * @dtopt Server-side
9562
+ *
9563
+ * @example
9564
+ * // Get data from { "data": [...] }
9565
+ * $(document).ready( function() {
9566
+ * var oTable = $('#example').dataTable( {
9567
+ * "sAjaxSource": "sources/data.txt",
9568
+ * "sAjaxDataProp": "data"
9569
+ * } );
9570
+ * } );
9571
+ *
9572
+ * @example
9573
+ * // Get data from { "data": { "inner": [...] } }
9574
+ * $(document).ready( function() {
9575
+ * var oTable = $('#example').dataTable( {
9576
+ * "sAjaxSource": "sources/data.txt",
9577
+ * "sAjaxDataProp": "data.inner"
9578
+ * } );
9579
+ * } );
9580
+ */
9581
+ "sAjaxDataProp": "aaData",
9582
+
9583
+
9584
+ /**
9585
+ * You can instruct DataTables to load data from an external source using this
9586
+ * parameter (use aData if you want to pass data in you already have). Simply
9587
+ * provide a url a JSON object can be obtained from. This object must include
9588
+ * the parameter 'aaData' which is the data source for the table.
9589
+ * @type string
9590
+ * @default null
9591
+ * @dtopt Options
9592
+ * @dtopt Server-side
9593
+ *
9594
+ * @example
9595
+ * $(document).ready( function() {
9596
+ * $('#example').dataTable( {
9597
+ * "sAjaxSource": "http://www.sprymedia.co.uk/dataTables/json.php"
9598
+ * } );
9599
+ * } )
9600
+ */
9601
+ "sAjaxSource": null,
9602
+
9603
+
9604
+ /**
9605
+ * This parameter can be used to override the default prefix that DataTables
9606
+ * assigns to a cookie when state saving is enabled.
9607
+ * @type string
9608
+ * @default SpryMedia_DataTables_
9609
+ * @dtopt Options
9610
+ *
9611
+ * @example
9612
+ * $(document).ready( function() {
9613
+ * $('#example').dataTable( {
9614
+ * "sCookiePrefix": "my_datatable_",
9615
+ * } );
9616
+ * } );
9617
+ */
9618
+ "sCookiePrefix": "SpryMedia_DataTables_",
9619
+
9620
+
9621
+ /**
9622
+ * This initialisation variable allows you to specify exactly where in the
9623
+ * DOM you want DataTables to inject the various controls it adds to the page
9624
+ * (for example you might want the pagination controls at the top of the
9625
+ * table). DIV elements (with or without a custom class) can also be added to
9626
+ * aid styling. The follow syntax is used:
9627
+ * <ul>
9628
+ * <li>The following options are allowed:
9629
+ * <ul>
9630
+ * <li>'l' - Length changing</li
9631
+ * <li>'f' - Filtering input</li>
9632
+ * <li>'t' - The table!</li>
9633
+ * <li>'i' - Information</li>
9634
+ * <li>'p' - Pagination</li>
9635
+ * <li>'r' - pRocessing</li>
9636
+ * </ul>
9637
+ * </li>
9638
+ * <li>The following constants are allowed:
9639
+ * <ul>
9640
+ * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
9641
+ * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
9642
+ * </ul>
9643
+ * </li>
9644
+ * <li>The following syntax is expected:
9645
+ * <ul>
9646
+ * <li>'&lt;' and '&gt;' - div elements</li>
9647
+ * <li>'&lt;"class" and '&gt;' - div with a class</li>
9648
+ * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
9649
+ * </ul>
9650
+ * </li>
9651
+ * <li>Examples:
9652
+ * <ul>
9653
+ * <li>'&lt;"wrapper"flipt&gt;'</li>
9654
+ * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
9655
+ * </ul>
9656
+ * </li>
9657
+ * </ul>
9658
+ * @type string
9659
+ * @default lfrtip <i>(when bJQueryUI is false)</i> <b>or</b>
9660
+ * <"H"lfr>t<"F"ip> <i>(when bJQueryUI is true)</i>
9661
+ * @dtopt Options
9662
+ *
9663
+ * @example
9664
+ * $(document).ready( function() {
9665
+ * $('#example').dataTable( {
9666
+ * "sDom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
9667
+ * } );
9668
+ * } );
9669
+ */
9670
+ "sDom": "lfrtip",
9671
+
9672
+
9673
+ /**
9674
+ * DataTables features two different built-in pagination interaction methods
9675
+ * ('two_button' or 'full_numbers') which present different page controls to
9676
+ * the end user. Further methods can be added using the API (see below).
9677
+ * @type string
9678
+ * @default two_button
9679
+ * @dtopt Options
9680
+ *
9681
+ * @example
9682
+ * $(document).ready( function() {
9683
+ * $('#example').dataTable( {
9684
+ * "sPaginationType": "full_numbers"
9685
+ * } );
9686
+ * } )
9687
+ */
9688
+ "sPaginationType": "two_button",
9689
+
9690
+
9691
+ /**
9692
+ * Enable horizontal scrolling. When a table is too wide to fit into a certain
9693
+ * layout, or you have a large number of columns in the table, you can enable
9694
+ * x-scrolling to show the table in a viewport, which can be scrolled. This
9695
+ * property can be any CSS unit, or a number (in which case it will be treated
9696
+ * as a pixel measurement).
9697
+ * @type string
9698
+ * @default <i>blank string - i.e. disabled</i>
9699
+ * @dtopt Features
9700
+ *
9701
+ * @example
9702
+ * $(document).ready( function() {
9703
+ * $('#example').dataTable( {
9704
+ * "sScrollX": "100%",
9705
+ * "bScrollCollapse": true
9706
+ * } );
9707
+ * } );
9708
+ */
9709
+ "sScrollX": "",
9710
+
9711
+
9712
+ /**
9713
+ * This property can be used to force a DataTable to use more width than it
9714
+ * might otherwise do when x-scrolling is enabled. For example if you have a
9715
+ * table which requires to be well spaced, this parameter is useful for
9716
+ * "over-sizing" the table, and thus forcing scrolling. This property can by
9717
+ * any CSS unit, or a number (in which case it will be treated as a pixel
9718
+ * measurement).
9719
+ * @type string
9720
+ * @default <i>blank string - i.e. disabled</i>
9721
+ * @dtopt Options
9722
+ *
9723
+ * @example
9724
+ * $(document).ready( function() {
9725
+ * $('#example').dataTable( {
9726
+ * "sScrollX": "100%",
9727
+ * "sScrollXInner": "110%"
9728
+ * } );
9729
+ * } );
9730
+ */
9731
+ "sScrollXInner": "",
9732
+
9733
+
9734
+ /**
9735
+ * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
9736
+ * to the given height, and enable scrolling for any data which overflows the
9737
+ * current viewport. This can be used as an alternative to paging to display
9738
+ * a lot of data in a small area (although paging and scrolling can both be
9739
+ * enabled at the same time). This property can be any CSS unit, or a number
9740
+ * (in which case it will be treated as a pixel measurement).
9741
+ * @type string
9742
+ * @default <i>blank string - i.e. disabled</i>
9743
+ * @dtopt Features
9744
+ *
9745
+ * @example
9746
+ * $(document).ready( function() {
9747
+ * $('#example').dataTable( {
9748
+ * "sScrollY": "200px",
9749
+ * "bPaginate": false
9750
+ * } );
9751
+ * } );
9752
+ */
9753
+ "sScrollY": "",
9754
+
9755
+
9756
+ /**
9757
+ * Set the HTTP method that is used to make the Ajax call for server-side
9758
+ * processing or Ajax sourced data.
9759
+ * @type string
9760
+ * @default GET
9761
+ * @dtopt Options
9762
+ * @dtopt Server-side
9763
+ *
9764
+ * @example
9765
+ * $(document).ready( function() {
9766
+ * $('#example').dataTable( {
9767
+ * "bServerSide": true,
9768
+ * "sAjaxSource": "scripts/post.php",
9769
+ * "sServerMethod": "POST"
9770
+ * } );
9771
+ * } );
9772
+ */
9773
+ "sServerMethod": "GET"
9774
+ };
9775
+
9776
+
9777
+
9778
+ /**
9779
+ * Column options that can be given to DataTables at initialisation time.
9780
+ * @namespace
9781
+ */
9782
+ DataTable.defaults.columns = {
9783
+ /**
9784
+ * Allows a column's sorting to take multiple columns into account when
9785
+ * doing a sort. For example first name / last name columns make sense to
9786
+ * do a multi-column sort over the two columns.
9787
+ * @type array
9788
+ * @default null <i>Takes the value of the column index automatically</i>
9789
+ * @dtopt Columns
9790
+ *
9791
+ * @example
9792
+ * // Using aoColumnDefs
9793
+ * $(document).ready( function() {
9794
+ * $('#example').dataTable( {
9795
+ * "aoColumnDefs": [
9796
+ * { "aDataSort": [ 0, 1 ], "aTargets": [ 0 ] },
9797
+ * { "aDataSort": [ 1, 0 ], "aTargets": [ 1 ] },
9798
+ * { "aDataSort": [ 2, 3, 4 ], "aTargets": [ 2 ] }
9799
+ * ]
9800
+ * } );
9801
+ * } );
9802
+ *
9803
+ * @example
9804
+ * // Using aoColumns
9805
+ * $(document).ready( function() {
9806
+ * $('#example').dataTable( {
9807
+ * "aoColumns": [
9808
+ * { "aDataSort": [ 0, 1 ] },
9809
+ * { "aDataSort": [ 1, 0 ] },
9810
+ * { "aDataSort": [ 2, 3, 4 ] },
9811
+ * null,
9812
+ * null
9813
+ * ]
9814
+ * } );
9815
+ * } );
9816
+ */
9817
+ "aDataSort": null,
9818
+
9819
+
9820
+ /**
9821
+ * You can control the default sorting direction, and even alter the behaviour
9822
+ * of the sort handler (i.e. only allow ascending sorting etc) using this
9823
+ * parameter.
9824
+ * @type array
9825
+ * @default [ 'asc', 'desc' ]
9826
+ * @dtopt Columns
9827
+ *
9828
+ * @example
9829
+ * // Using aoColumnDefs
9830
+ * $(document).ready( function() {
9831
+ * $('#example').dataTable( {
9832
+ * "aoColumnDefs": [
9833
+ * { "asSorting": [ "asc" ], "aTargets": [ 1 ] },
9834
+ * { "asSorting": [ "desc", "asc", "asc" ], "aTargets": [ 2 ] },
9835
+ * { "asSorting": [ "desc" ], "aTargets": [ 3 ] }
9836
+ * ]
9837
+ * } );
9838
+ * } );
9839
+ *
9840
+ * @example
9841
+ * // Using aoColumns
9842
+ * $(document).ready( function() {
9843
+ * $('#example').dataTable( {
9844
+ * "aoColumns": [
9845
+ * null,
9846
+ * { "asSorting": [ "asc" ] },
9847
+ * { "asSorting": [ "desc", "asc", "asc" ] },
9848
+ * { "asSorting": [ "desc" ] },
9849
+ * null
9850
+ * ]
9851
+ * } );
9852
+ * } );
9853
+ */
9854
+ "asSorting": [ 'asc', 'desc' ],
9855
+
9856
+
9857
+ /**
9858
+ * Enable or disable filtering on the data in this column.
9859
+ * @type boolean
9860
+ * @default true
9861
+ * @dtopt Columns
9862
+ *
9863
+ * @example
9864
+ * // Using aoColumnDefs
9865
+ * $(document).ready( function() {
9866
+ * $('#example').dataTable( {
9867
+ * "aoColumnDefs": [
9868
+ * { "bSearchable": false, "aTargets": [ 0 ] }
9869
+ * ] } );
9870
+ * } );
9871
+ *
9872
+ * @example
9873
+ * // Using aoColumns
9874
+ * $(document).ready( function() {
9875
+ * $('#example').dataTable( {
9876
+ * "aoColumns": [
9877
+ * { "bSearchable": false },
9878
+ * null,
9879
+ * null,
9880
+ * null,
9881
+ * null
9882
+ * ] } );
9883
+ * } );
9884
+ */
9885
+ "bSearchable": true,
9886
+
9887
+
9888
+ /**
9889
+ * Enable or disable sorting on this column.
9890
+ * @type boolean
9891
+ * @default true
9892
+ * @dtopt Columns
9893
+ *
9894
+ * @example
9895
+ * // Using aoColumnDefs
9896
+ * $(document).ready( function() {
9897
+ * $('#example').dataTable( {
9898
+ * "aoColumnDefs": [
9899
+ * { "bSortable": false, "aTargets": [ 0 ] }
9900
+ * ] } );
9901
+ * } );
9902
+ *
9903
+ * @example
9904
+ * // Using aoColumns
9905
+ * $(document).ready( function() {
9906
+ * $('#example').dataTable( {
9907
+ * "aoColumns": [
9908
+ * { "bSortable": false },
9909
+ * null,
9910
+ * null,
9911
+ * null,
9912
+ * null
9913
+ * ] } );
9914
+ * } );
9915
+ */
9916
+ "bSortable": true,
9917
+
9918
+
9919
+ /**
9920
+ * <code>Deprecated</code> When using fnRender() for a column, you may wish
9921
+ * to use the original data (before rendering) for sorting and filtering
9922
+ * (the default is to used the rendered data that the user can see). This
9923
+ * may be useful for dates etc.
9924
+ *
9925
+ * Please note that this option has now been deprecated and will be removed
9926
+ * in the next version of DataTables. Please use mRender / mData rather than
9927
+ * fnRender.
9928
+ * @type boolean
9929
+ * @default true
9930
+ * @dtopt Columns
9931
+ * @deprecated
9932
+ */
9933
+ "bUseRendered": true,
9934
+
9935
+
9936
+ /**
9937
+ * Enable or disable the display of this column.
9938
+ * @type boolean
9939
+ * @default true
9940
+ * @dtopt Columns
9941
+ *
9942
+ * @example
9943
+ * // Using aoColumnDefs
9944
+ * $(document).ready( function() {
9945
+ * $('#example').dataTable( {
9946
+ * "aoColumnDefs": [
9947
+ * { "bVisible": false, "aTargets": [ 0 ] }
9948
+ * ] } );
9949
+ * } );
9950
+ *
9951
+ * @example
9952
+ * // Using aoColumns
9953
+ * $(document).ready( function() {
9954
+ * $('#example').dataTable( {
9955
+ * "aoColumns": [
9956
+ * { "bVisible": false },
9957
+ * null,
9958
+ * null,
9959
+ * null,
9960
+ * null
9961
+ * ] } );
9962
+ * } );
9963
+ */
9964
+ "bVisible": true,
9965
+
9966
+
9967
+ /**
9968
+ * Developer definable function that is called whenever a cell is created (Ajax source,
9969
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9970
+ * allowing you to modify the DOM element (add background colour for example) when the
9971
+ * element is available.
9972
+ * @type function
9973
+ * @param {element} nTd The TD node that has been created
9974
+ * @param {*} sData The Data for the cell
9975
+ * @param {array|object} oData The data for the whole row
9976
+ * @param {int} iRow The row index for the aoData data store
9977
+ * @param {int} iCol The column index for aoColumns
9978
+ * @dtopt Columns
9979
+ *
9980
+ * @example
9981
+ * $(document).ready( function() {
9982
+ * $('#example').dataTable( {
9983
+ * "aoColumnDefs": [ {
9984
+ * "aTargets": [3],
9985
+ * "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
9986
+ * if ( sData == "1.7" ) {
9987
+ * $(nTd).css('color', 'blue')
9988
+ * }
9989
+ * }
9990
+ * } ]
9991
+ * });
9992
+ * } );
9993
+ */
9994
+ "fnCreatedCell": null,
9995
+
9996
+
9997
+ /**
9998
+ * <code>Deprecated</code> Custom display function that will be called for the
9999
+ * display of each cell in this column.
10000
+ *
10001
+ * Please note that this option has now been deprecated and will be removed
10002
+ * in the next version of DataTables. Please use mRender / mData rather than
10003
+ * fnRender.
10004
+ * @type function
10005
+ * @param {object} o Object with the following parameters:
10006
+ * @param {int} o.iDataRow The row in aoData
10007
+ * @param {int} o.iDataColumn The column in question
10008
+ * @param {array} o.aData The data for the row in question
10009
+ * @param {object} o.oSettings The settings object for this DataTables instance
10010
+ * @param {object} o.mDataProp The data property used for this column
10011
+ * @param {*} val The current cell value
10012
+ * @returns {string} The string you which to use in the display
10013
+ * @dtopt Columns
10014
+ * @deprecated
10015
+ */
10016
+ "fnRender": null,
10017
+
10018
+
10019
+ /**
10020
+ * The column index (starting from 0!) that you wish a sort to be performed
10021
+ * upon when this column is selected for sorting. This can be used for sorting
10022
+ * on hidden columns for example.
10023
+ * @type int
10024
+ * @default -1 <i>Use automatically calculated column index</i>
10025
+ * @dtopt Columns
10026
+ *
10027
+ * @example
10028
+ * // Using aoColumnDefs
10029
+ * $(document).ready( function() {
10030
+ * $('#example').dataTable( {
10031
+ * "aoColumnDefs": [
10032
+ * { "iDataSort": 1, "aTargets": [ 0 ] }
10033
+ * ]
10034
+ * } );
10035
+ * } );
10036
+ *
10037
+ * @example
10038
+ * // Using aoColumns
10039
+ * $(document).ready( function() {
10040
+ * $('#example').dataTable( {
10041
+ * "aoColumns": [
10042
+ * { "iDataSort": 1 },
10043
+ * null,
10044
+ * null,
10045
+ * null,
10046
+ * null
10047
+ * ]
10048
+ * } );
10049
+ * } );
10050
+ */
10051
+ "iDataSort": -1,
10052
+
10053
+
10054
+ /**
10055
+ * This parameter has been replaced by mData in DataTables to ensure naming
10056
+ * consistency. mDataProp can still be used, as there is backwards compatibility
10057
+ * in DataTables for this option, but it is strongly recommended that you use
10058
+ * mData in preference to mDataProp.
10059
+ * @name DataTable.defaults.columns.mDataProp
10060
+ */
10061
+
10062
+
10063
+ /**
10064
+ * This property can be used to read data from any JSON data source property,
10065
+ * including deeply nested objects / properties. mData can be given in a
10066
+ * number of different ways which effect its behaviour:
10067
+ * <ul>
10068
+ * <li>integer - treated as an array index for the data source. This is the
10069
+ * default that DataTables uses (incrementally increased for each column).</li>
10070
+ * <li>string - read an object property from the data source. Note that you can
10071
+ * use Javascript dotted notation to read deep properties / arrays from the
10072
+ * data source.</li>
10073
+ * <li>null - the sDefaultContent option will be used for the cell (null
10074
+ * by default, so you will need to specify the default content you want -
10075
+ * typically an empty string). This can be useful on generated columns such
10076
+ * as edit / delete action columns.</li>
10077
+ * <li>function - the function given will be executed whenever DataTables
10078
+ * needs to set or get the data for a cell in the column. The function
10079
+ * takes three parameters:
10080
+ * <ul>
10081
+ * <li>{array|object} The data source for the row</li>
10082
+ * <li>{string} The type call data requested - this will be 'set' when
10083
+ * setting data or 'filter', 'display', 'type', 'sort' or undefined when
10084
+ * gathering data. Note that when <i>undefined</i> is given for the type
10085
+ * DataTables expects to get the raw data for the object back</li>
10086
+ * <li>{*} Data to set when the second parameter is 'set'.</li>
10087
+ * </ul>
10088
+ * The return value from the function is not required when 'set' is the type
10089
+ * of call, but otherwise the return is what will be used for the data
10090
+ * requested.</li>
10091
+ * </ul>
10092
+ *
10093
+ * Note that prior to DataTables 1.9.2 mData was called mDataProp. The name change
10094
+ * reflects the flexibility of this property and is consistent with the naming of
10095
+ * mRender. If 'mDataProp' is given, then it will still be used by DataTables, as
10096
+ * it automatically maps the old name to the new if required.
10097
+ * @type string|int|function|null
10098
+ * @default null <i>Use automatically calculated column index</i>
10099
+ * @dtopt Columns
10100
+ *
10101
+ * @example
10102
+ * // Read table data from objects
10103
+ * $(document).ready( function() {
10104
+ * var oTable = $('#example').dataTable( {
10105
+ * "sAjaxSource": "sources/deep.txt",
10106
+ * "aoColumns": [
10107
+ * { "mData": "engine" },
10108
+ * { "mData": "browser" },
10109
+ * { "mData": "platform.inner" },
10110
+ * { "mData": "platform.details.0" },
10111
+ * { "mData": "platform.details.1" }
10112
+ * ]
10113
+ * } );
10114
+ * } );
10115
+ *
10116
+ * @example
10117
+ * // Using mData as a function to provide different information for
10118
+ * // sorting, filtering and display. In this case, currency (price)
10119
+ * $(document).ready( function() {
10120
+ * var oTable = $('#example').dataTable( {
10121
+ * "aoColumnDefs": [ {
10122
+ * "aTargets": [ 0 ],
10123
+ * "mData": function ( source, type, val ) {
10124
+ * if (type === 'set') {
10125
+ * source.price = val;
10126
+ * // Store the computed dislay and filter values for efficiency
10127
+ * source.price_display = val=="" ? "" : "$"+numberFormat(val);
10128
+ * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
10129
+ * return;
10130
+ * }
10131
+ * else if (type === 'display') {
10132
+ * return source.price_display;
10133
+ * }
10134
+ * else if (type === 'filter') {
10135
+ * return source.price_filter;
10136
+ * }
10137
+ * // 'sort', 'type' and undefined all just use the integer
10138
+ * return source.price;
10139
+ * }
10140
+ * } ]
10141
+ * } );
10142
+ * } );
10143
+ */
10144
+ "mData": null,
10145
+
10146
+
10147
+ /**
10148
+ * This property is the rendering partner to mData and it is suggested that
10149
+ * when you want to manipulate data for display (including filtering, sorting etc)
10150
+ * but not altering the underlying data for the table, use this property. mData
10151
+ * can actually do everything this property can and more, but this parameter is
10152
+ * easier to use since there is no 'set' option. Like mData is can be given
10153
+ * in a number of different ways to effect its behaviour, with the addition of
10154
+ * supporting array syntax for easy outputting of arrays (including arrays of
10155
+ * objects):
10156
+ * <ul>
10157
+ * <li>integer - treated as an array index for the data source. This is the
10158
+ * default that DataTables uses (incrementally increased for each column).</li>
10159
+ * <li>string - read an object property from the data source. Note that you can
10160
+ * use Javascript dotted notation to read deep properties / arrays from the
10161
+ * data source and also array brackets to indicate that the data reader should
10162
+ * loop over the data source array. When characters are given between the array
10163
+ * brackets, these characters are used to join the data source array together.
10164
+ * For example: "accounts[, ].name" would result in a comma separated list with
10165
+ * the 'name' value from the 'accounts' array of objects.</li>
10166
+ * <li>function - the function given will be executed whenever DataTables
10167
+ * needs to set or get the data for a cell in the column. The function
10168
+ * takes three parameters:
10169
+ * <ul>
10170
+ * <li>{array|object} The data source for the row (based on mData)</li>
10171
+ * <li>{string} The type call data requested - this will be 'filter', 'display',
10172
+ * 'type' or 'sort'.</li>
10173
+ * <li>{array|object} The full data source for the row (not based on mData)</li>
10174
+ * </ul>
10175
+ * The return value from the function is what will be used for the data
10176
+ * requested.</li>
10177
+ * </ul>
10178
+ * @type string|int|function|null
10179
+ * @default null <i>Use mData</i>
10180
+ * @dtopt Columns
10181
+ *
10182
+ * @example
10183
+ * // Create a comma separated list from an array of objects
10184
+ * $(document).ready( function() {
10185
+ * var oTable = $('#example').dataTable( {
10186
+ * "sAjaxSource": "sources/deep.txt",
10187
+ * "aoColumns": [
10188
+ * { "mData": "engine" },
10189
+ * { "mData": "browser" },
10190
+ * {
10191
+ * "mData": "platform",
10192
+ * "mRender": "[, ].name"
10193
+ * }
10194
+ * ]
10195
+ * } );
10196
+ * } );
10197
+ *
10198
+ * @example
10199
+ * // Use as a function to create a link from the data source
10200
+ * $(document).ready( function() {
10201
+ * var oTable = $('#example').dataTable( {
10202
+ * "aoColumnDefs": [
10203
+ * {
10204
+ * "aTargets": [ 0 ],
10205
+ * "mData": "download_link",
10206
+ * "mRender": function ( data, type, full ) {
10207
+ * return '<a href="'+data+'">Download</a>';
10208
+ * }
10209
+ * ]
10210
+ * } );
10211
+ * } );
10212
+ */
10213
+ "mRender": null,
10214
+
10215
+
10216
+ /**
10217
+ * Change the cell type created for the column - either TD cells or TH cells. This
10218
+ * can be useful as TH cells have semantic meaning in the table body, allowing them
10219
+ * to act as a header for a row (you may wish to add scope='row' to the TH elements).
10220
+ * @type string
10221
+ * @default td
10222
+ * @dtopt Columns
10223
+ *
10224
+ * @example
10225
+ * // Make the first column use TH cells
10226
+ * $(document).ready( function() {
10227
+ * var oTable = $('#example').dataTable( {
10228
+ * "aoColumnDefs": [ {
10229
+ * "aTargets": [ 0 ],
10230
+ * "sCellType": "th"
10231
+ * } ]
10232
+ * } );
10233
+ * } );
10234
+ */
10235
+ "sCellType": "td",
10236
+
10237
+
10238
+ /**
10239
+ * Class to give to each cell in this column.
10240
+ * @type string
10241
+ * @default <i>Empty string</i>
10242
+ * @dtopt Columns
10243
+ *
10244
+ * @example
10245
+ * // Using aoColumnDefs
10246
+ * $(document).ready( function() {
10247
+ * $('#example').dataTable( {
10248
+ * "aoColumnDefs": [
10249
+ * { "sClass": "my_class", "aTargets": [ 0 ] }
10250
+ * ]
10251
+ * } );
10252
+ * } );
10253
+ *
10254
+ * @example
10255
+ * // Using aoColumns
10256
+ * $(document).ready( function() {
10257
+ * $('#example').dataTable( {
10258
+ * "aoColumns": [
10259
+ * { "sClass": "my_class" },
10260
+ * null,
10261
+ * null,
10262
+ * null,
10263
+ * null
10264
+ * ]
10265
+ * } );
10266
+ * } );
10267
+ */
10268
+ "sClass": "",
10269
+
10270
+ /**
10271
+ * When DataTables calculates the column widths to assign to each column,
10272
+ * it finds the longest string in each column and then constructs a
10273
+ * temporary table and reads the widths from that. The problem with this
10274
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
10275
+ * string - thus the calculation can go wrong (doing it properly and putting
10276
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
10277
+ * a "work around" we provide this option. It will append its value to the
10278
+ * text that is found to be the longest string for the column - i.e. padding.
10279
+ * Generally you shouldn't need this, and it is not documented on the
10280
+ * general DataTables.net documentation
10281
+ * @type string
10282
+ * @default <i>Empty string<i>
10283
+ * @dtopt Columns
10284
+ *
10285
+ * @example
10286
+ * // Using aoColumns
10287
+ * $(document).ready( function() {
10288
+ * $('#example').dataTable( {
10289
+ * "aoColumns": [
10290
+ * null,
10291
+ * null,
10292
+ * null,
10293
+ * {
10294
+ * "sContentPadding": "mmm"
10295
+ * }
10296
+ * ]
10297
+ * } );
10298
+ * } );
10299
+ */
10300
+ "sContentPadding": "",
10301
+
10302
+
10303
+ /**
10304
+ * Allows a default value to be given for a column's data, and will be used
10305
+ * whenever a null data source is encountered (this can be because mData
10306
+ * is set to null, or because the data source itself is null).
10307
+ * @type string
10308
+ * @default null
10309
+ * @dtopt Columns
10310
+ *
10311
+ * @example
10312
+ * // Using aoColumnDefs
10313
+ * $(document).ready( function() {
10314
+ * $('#example').dataTable( {
10315
+ * "aoColumnDefs": [
10316
+ * {
10317
+ * "mData": null,
10318
+ * "sDefaultContent": "Edit",
10319
+ * "aTargets": [ -1 ]
10320
+ * }
10321
+ * ]
10322
+ * } );
10323
+ * } );
10324
+ *
10325
+ * @example
10326
+ * // Using aoColumns
10327
+ * $(document).ready( function() {
10328
+ * $('#example').dataTable( {
10329
+ * "aoColumns": [
10330
+ * null,
10331
+ * null,
10332
+ * null,
10333
+ * {
10334
+ * "mData": null,
10335
+ * "sDefaultContent": "Edit"
10336
+ * }
10337
+ * ]
10338
+ * } );
10339
+ * } );
10340
+ */
10341
+ "sDefaultContent": null,
10342
+
10343
+
10344
+ /**
10345
+ * This parameter is only used in DataTables' server-side processing. It can
10346
+ * be exceptionally useful to know what columns are being displayed on the
10347
+ * client side, and to map these to database fields. When defined, the names
10348
+ * also allow DataTables to reorder information from the server if it comes
10349
+ * back in an unexpected order (i.e. if you switch your columns around on the
10350
+ * client-side, your server-side code does not also need updating).
10351
+ * @type string
10352
+ * @default <i>Empty string</i>
10353
+ * @dtopt Columns
10354
+ *
10355
+ * @example
10356
+ * // Using aoColumnDefs
10357
+ * $(document).ready( function() {
10358
+ * $('#example').dataTable( {
10359
+ * "aoColumnDefs": [
10360
+ * { "sName": "engine", "aTargets": [ 0 ] },
10361
+ * { "sName": "browser", "aTargets": [ 1 ] },
10362
+ * { "sName": "platform", "aTargets": [ 2 ] },
10363
+ * { "sName": "version", "aTargets": [ 3 ] },
10364
+ * { "sName": "grade", "aTargets": [ 4 ] }
10365
+ * ]
10366
+ * } );
10367
+ * } );
10368
+ *
10369
+ * @example
10370
+ * // Using aoColumns
10371
+ * $(document).ready( function() {
10372
+ * $('#example').dataTable( {
10373
+ * "aoColumns": [
10374
+ * { "sName": "engine" },
10375
+ * { "sName": "browser" },
10376
+ * { "sName": "platform" },
10377
+ * { "sName": "version" },
10378
+ * { "sName": "grade" }
10379
+ * ]
10380
+ * } );
10381
+ * } );
10382
+ */
10383
+ "sName": "",
10384
+
10385
+
10386
+ /**
10387
+ * Defines a data source type for the sorting which can be used to read
10388
+ * real-time information from the table (updating the internally cached
10389
+ * version) prior to sorting. This allows sorting to occur on user editable
10390
+ * elements such as form inputs.
10391
+ * @type string
10392
+ * @default std
10393
+ * @dtopt Columns
10394
+ *
10395
+ * @example
10396
+ * // Using aoColumnDefs
10397
+ * $(document).ready( function() {
10398
+ * $('#example').dataTable( {
10399
+ * "aoColumnDefs": [
10400
+ * { "sSortDataType": "dom-text", "aTargets": [ 2, 3 ] },
10401
+ * { "sType": "numeric", "aTargets": [ 3 ] },
10402
+ * { "sSortDataType": "dom-select", "aTargets": [ 4 ] },
10403
+ * { "sSortDataType": "dom-checkbox", "aTargets": [ 5 ] }
10404
+ * ]
10405
+ * } );
10406
+ * } );
10407
+ *
10408
+ * @example
10409
+ * // Using aoColumns
10410
+ * $(document).ready( function() {
10411
+ * $('#example').dataTable( {
10412
+ * "aoColumns": [
10413
+ * null,
10414
+ * null,
10415
+ * { "sSortDataType": "dom-text" },
10416
+ * { "sSortDataType": "dom-text", "sType": "numeric" },
10417
+ * { "sSortDataType": "dom-select" },
10418
+ * { "sSortDataType": "dom-checkbox" }
10419
+ * ]
10420
+ * } );
10421
+ * } );
10422
+ */
10423
+ "sSortDataType": "std",
10424
+
10425
+
10426
+ /**
10427
+ * The title of this column.
10428
+ * @type string
10429
+ * @default null <i>Derived from the 'TH' value for this column in the
10430
+ * original HTML table.</i>
10431
+ * @dtopt Columns
10432
+ *
10433
+ * @example
10434
+ * // Using aoColumnDefs
10435
+ * $(document).ready( function() {
10436
+ * $('#example').dataTable( {
10437
+ * "aoColumnDefs": [
10438
+ * { "sTitle": "My column title", "aTargets": [ 0 ] }
10439
+ * ]
10440
+ * } );
10441
+ * } );
10442
+ *
10443
+ * @example
10444
+ * // Using aoColumns
10445
+ * $(document).ready( function() {
10446
+ * $('#example').dataTable( {
10447
+ * "aoColumns": [
10448
+ * { "sTitle": "My column title" },
10449
+ * null,
10450
+ * null,
10451
+ * null,
10452
+ * null
10453
+ * ]
10454
+ * } );
10455
+ * } );
10456
+ */
10457
+ "sTitle": null,
10458
+
10459
+
10460
+ /**
10461
+ * The type allows you to specify how the data for this column will be sorted.
10462
+ * Four types (string, numeric, date and html (which will strip HTML tags
10463
+ * before sorting)) are currently available. Note that only date formats
10464
+ * understood by Javascript's Date() object will be accepted as type date. For
10465
+ * example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 'numeric',
10466
+ * 'date' or 'html' (by default). Further types can be adding through
10467
+ * plug-ins.
10468
+ * @type string
10469
+ * @default null <i>Auto-detected from raw data</i>
10470
+ * @dtopt Columns
10471
+ *
10472
+ * @example
10473
+ * // Using aoColumnDefs
10474
+ * $(document).ready( function() {
10475
+ * $('#example').dataTable( {
10476
+ * "aoColumnDefs": [
10477
+ * { "sType": "html", "aTargets": [ 0 ] }
10478
+ * ]
10479
+ * } );
10480
+ * } );
10481
+ *
10482
+ * @example
10483
+ * // Using aoColumns
10484
+ * $(document).ready( function() {
10485
+ * $('#example').dataTable( {
10486
+ * "aoColumns": [
10487
+ * { "sType": "html" },
10488
+ * null,
10489
+ * null,
10490
+ * null,
10491
+ * null
10492
+ * ]
10493
+ * } );
10494
+ * } );
10495
+ */
10496
+ "sType": null,
10497
+
10498
+
10499
+ /**
10500
+ * Defining the width of the column, this parameter may take any CSS value
10501
+ * (3em, 20px etc). DataTables apples 'smart' widths to columns which have not
10502
+ * been given a specific width through this interface ensuring that the table
10503
+ * remains readable.
10504
+ * @type string
10505
+ * @default null <i>Automatic</i>
10506
+ * @dtopt Columns
10507
+ *
10508
+ * @example
10509
+ * // Using aoColumnDefs
10510
+ * $(document).ready( function() {
10511
+ * $('#example').dataTable( {
10512
+ * "aoColumnDefs": [
10513
+ * { "sWidth": "20%", "aTargets": [ 0 ] }
10514
+ * ]
10515
+ * } );
10516
+ * } );
10517
+ *
10518
+ * @example
10519
+ * // Using aoColumns
10520
+ * $(document).ready( function() {
10521
+ * $('#example').dataTable( {
10522
+ * "aoColumns": [
10523
+ * { "sWidth": "20%" },
10524
+ * null,
10525
+ * null,
10526
+ * null,
10527
+ * null
10528
+ * ]
10529
+ * } );
10530
+ * } );
10531
+ */
10532
+ "sWidth": null
10533
+ };
10534
+
10535
+
10536
+
10537
+ /**
10538
+ * DataTables settings object - this holds all the information needed for a
10539
+ * given table, including configuration, data and current application of the
10540
+ * table options. DataTables does not have a single instance for each DataTable
10541
+ * with the settings attached to that instance, but rather instances of the
10542
+ * DataTable "class" are created on-the-fly as needed (typically by a
10543
+ * $().dataTable() call) and the settings object is then applied to that
10544
+ * instance.
10545
+ *
10546
+ * Note that this object is related to {@link DataTable.defaults} but this
10547
+ * one is the internal data store for DataTables's cache of columns. It should
10548
+ * NOT be manipulated outside of DataTables. Any configuration should be done
10549
+ * through the initialisation options.
10550
+ * @namespace
10551
+ * @todo Really should attach the settings object to individual instances so we
10552
+ * don't need to create new instances on each $().dataTable() call (if the
10553
+ * table already exists). It would also save passing oSettings around and
10554
+ * into every single function. However, this is a very significant
10555
+ * architecture change for DataTables and will almost certainly break
10556
+ * backwards compatibility with older installations. This is something that
10557
+ * will be done in 2.0.
10558
+ */
10559
+ DataTable.models.oSettings = {
10560
+ /**
10561
+ * Primary features of DataTables and their enablement state.
10562
+ * @namespace
10563
+ */
10564
+ "oFeatures": {
10565
+
10566
+ /**
10567
+ * Flag to say if DataTables should automatically try to calculate the
10568
+ * optimum table and columns widths (true) or not (false).
10569
+ * Note that this parameter will be set by the initialisation routine. To
10570
+ * set a default use {@link DataTable.defaults}.
10571
+ * @type boolean
10572
+ */
10573
+ "bAutoWidth": null,
10574
+
10575
+ /**
10576
+ * Delay the creation of TR and TD elements until they are actually
10577
+ * needed by a driven page draw. This can give a significant speed
10578
+ * increase for Ajax source and Javascript source data, but makes no
10579
+ * difference at all fro DOM and server-side processing tables.
10580
+ * Note that this parameter will be set by the initialisation routine. To
10581
+ * set a default use {@link DataTable.defaults}.
10582
+ * @type boolean
10583
+ */
10584
+ "bDeferRender": null,
10585
+
10586
+ /**
10587
+ * Enable filtering on the table or not. Note that if this is disabled
10588
+ * then there is no filtering at all on the table, including fnFilter.
10589
+ * To just remove the filtering input use sDom and remove the 'f' option.
10590
+ * Note that this parameter will be set by the initialisation routine. To
10591
+ * set a default use {@link DataTable.defaults}.
10592
+ * @type boolean
10593
+ */
10594
+ "bFilter": null,
10595
+
10596
+ /**
10597
+ * Table information element (the 'Showing x of y records' div) enable
10598
+ * flag.
10599
+ * Note that this parameter will be set by the initialisation routine. To
10600
+ * set a default use {@link DataTable.defaults}.
10601
+ * @type boolean
10602
+ */
10603
+ "bInfo": null,
10604
+
10605
+ /**
10606
+ * Present a user control allowing the end user to change the page size
10607
+ * when pagination is enabled.
10608
+ * Note that this parameter will be set by the initialisation routine. To
10609
+ * set a default use {@link DataTable.defaults}.
10610
+ * @type boolean
10611
+ */
10612
+ "bLengthChange": null,
10613
+
10614
+ /**
10615
+ * Pagination enabled or not. Note that if this is disabled then length
10616
+ * changing must also be disabled.
10617
+ * Note that this parameter will be set by the initialisation routine. To
10618
+ * set a default use {@link DataTable.defaults}.
10619
+ * @type boolean
10620
+ */
10621
+ "bPaginate": null,
10622
+
10623
+ /**
10624
+ * Processing indicator enable flag whenever DataTables is enacting a
10625
+ * user request - typically an Ajax request for server-side processing.
10626
+ * Note that this parameter will be set by the initialisation routine. To
10627
+ * set a default use {@link DataTable.defaults}.
10628
+ * @type boolean
10629
+ */
10630
+ "bProcessing": null,
10631
+
10632
+ /**
10633
+ * Server-side processing enabled flag - when enabled DataTables will
10634
+ * get all data from the server for every draw - there is no filtering,
10635
+ * sorting or paging done on the client-side.
10636
+ * Note that this parameter will be set by the initialisation routine. To
10637
+ * set a default use {@link DataTable.defaults}.
10638
+ * @type boolean
10639
+ */
10640
+ "bServerSide": null,
10641
+
10642
+ /**
10643
+ * Sorting enablement flag.
10644
+ * Note that this parameter will be set by the initialisation routine. To
10645
+ * set a default use {@link DataTable.defaults}.
10646
+ * @type boolean
10647
+ */
10648
+ "bSort": null,
10649
+
10650
+ /**
10651
+ * Apply a class to the columns which are being sorted to provide a
10652
+ * visual highlight or not. This can slow things down when enabled since
10653
+ * there is a lot of DOM interaction.
10654
+ * Note that this parameter will be set by the initialisation routine. To
10655
+ * set a default use {@link DataTable.defaults}.
10656
+ * @type boolean
10657
+ */
10658
+ "bSortClasses": null,
10659
+
10660
+ /**
10661
+ * State saving enablement flag.
10662
+ * Note that this parameter will be set by the initialisation routine. To
10663
+ * set a default use {@link DataTable.defaults}.
10664
+ * @type boolean
10665
+ */
10666
+ "bStateSave": null
10667
+ },
10668
+
10669
+
10670
+ /**
10671
+ * Scrolling settings for a table.
10672
+ * @namespace
10673
+ */
10674
+ "oScroll": {
10675
+ /**
10676
+ * Indicate if DataTables should be allowed to set the padding / margin
10677
+ * etc for the scrolling header elements or not. Typically you will want
10678
+ * this.
10679
+ * Note that this parameter will be set by the initialisation routine. To
10680
+ * set a default use {@link DataTable.defaults}.
10681
+ * @type boolean
10682
+ */
10683
+ "bAutoCss": null,
10684
+
10685
+ /**
10686
+ * When the table is shorter in height than sScrollY, collapse the
10687
+ * table container down to the height of the table (when true).
10688
+ * Note that this parameter will be set by the initialisation routine. To
10689
+ * set a default use {@link DataTable.defaults}.
10690
+ * @type boolean
10691
+ */
10692
+ "bCollapse": null,
10693
+
10694
+ /**
10695
+ * Infinite scrolling enablement flag. Now deprecated in favour of
10696
+ * using the Scroller plug-in.
10697
+ * Note that this parameter will be set by the initialisation routine. To
10698
+ * set a default use {@link DataTable.defaults}.
10699
+ * @type boolean
10700
+ */
10701
+ "bInfinite": null,
10702
+
10703
+ /**
10704
+ * Width of the scrollbar for the web-browser's platform. Calculated
10705
+ * during table initialisation.
10706
+ * @type int
10707
+ * @default 0
10708
+ */
10709
+ "iBarWidth": 0,
10710
+
10711
+ /**
10712
+ * Space (in pixels) between the bottom of the scrolling container and
10713
+ * the bottom of the scrolling viewport before the next page is loaded
10714
+ * when using infinite scrolling.
10715
+ * Note that this parameter will be set by the initialisation routine. To
10716
+ * set a default use {@link DataTable.defaults}.
10717
+ * @type int
10718
+ */
10719
+ "iLoadGap": null,
10720
+
10721
+ /**
10722
+ * Viewport width for horizontal scrolling. Horizontal scrolling is
10723
+ * disabled if an empty string.
10724
+ * Note that this parameter will be set by the initialisation routine. To
10725
+ * set a default use {@link DataTable.defaults}.
10726
+ * @type string
10727
+ */
10728
+ "sX": null,
10729
+
10730
+ /**
10731
+ * Width to expand the table to when using x-scrolling. Typically you
10732
+ * should not need to use this.
10733
+ * Note that this parameter will be set by the initialisation routine. To
10734
+ * set a default use {@link DataTable.defaults}.
10735
+ * @type string
10736
+ * @deprecated
10737
+ */
10738
+ "sXInner": null,
10739
+
10740
+ /**
10741
+ * Viewport height for vertical scrolling. Vertical scrolling is disabled
10742
+ * if an empty string.
10743
+ * Note that this parameter will be set by the initialisation routine. To
10744
+ * set a default use {@link DataTable.defaults}.
10745
+ * @type string
10746
+ */
10747
+ "sY": null
10748
+ },
10749
+
10750
+ /**
10751
+ * Language information for the table.
10752
+ * @namespace
10753
+ * @extends DataTable.defaults.oLanguage
10754
+ */
10755
+ "oLanguage": {
10756
+ /**
10757
+ * Information callback function. See
10758
+ * {@link DataTable.defaults.fnInfoCallback}
10759
+ * @type function
10760
+ * @default null
10761
+ */
10762
+ "fnInfoCallback": null
10763
+ },
10764
+
10765
+ /**
10766
+ * Browser support parameters
10767
+ * @namespace
10768
+ */
10769
+ "oBrowser": {
10770
+ /**
10771
+ * Indicate if the browser incorrectly calculates width:100% inside a
10772
+ * scrolling element (IE6/7)
10773
+ * @type boolean
10774
+ * @default false
10775
+ */
10776
+ "bScrollOversize": false
10777
+ },
10778
+
10779
+ /**
10780
+ * Array referencing the nodes which are used for the features. The
10781
+ * parameters of this object match what is allowed by sDom - i.e.
10782
+ * <ul>
10783
+ * <li>'l' - Length changing</li>
10784
+ * <li>'f' - Filtering input</li>
10785
+ * <li>'t' - The table!</li>
10786
+ * <li>'i' - Information</li>
10787
+ * <li>'p' - Pagination</li>
10788
+ * <li>'r' - pRocessing</li>
10789
+ * </ul>
10790
+ * @type array
10791
+ * @default []
10792
+ */
10793
+ "aanFeatures": [],
10794
+
10795
+ /**
10796
+ * Store data information - see {@link DataTable.models.oRow} for detailed
10797
+ * information.
10798
+ * @type array
10799
+ * @default []
10800
+ */
10801
+ "aoData": [],
10802
+
10803
+ /**
10804
+ * Array of indexes which are in the current display (after filtering etc)
10805
+ * @type array
10806
+ * @default []
10807
+ */
10808
+ "aiDisplay": [],
10809
+
10810
+ /**
10811
+ * Array of indexes for display - no filtering
10812
+ * @type array
10813
+ * @default []
10814
+ */
10815
+ "aiDisplayMaster": [],
10816
+
10817
+ /**
10818
+ * Store information about each column that is in use
10819
+ * @type array
10820
+ * @default []
10821
+ */
10822
+ "aoColumns": [],
10823
+
10824
+ /**
10825
+ * Store information about the table's header
10826
+ * @type array
10827
+ * @default []
10828
+ */
10829
+ "aoHeader": [],
10830
+
10831
+ /**
10832
+ * Store information about the table's footer
10833
+ * @type array
10834
+ * @default []
10835
+ */
10836
+ "aoFooter": [],
10837
+
10838
+ /**
10839
+ * Search data array for regular expression searching
10840
+ * @type array
10841
+ * @default []
10842
+ */
10843
+ "asDataSearch": [],
10844
+
10845
+ /**
10846
+ * Store the applied global search information in case we want to force a
10847
+ * research or compare the old search to a new one.
10848
+ * Note that this parameter will be set by the initialisation routine. To
10849
+ * set a default use {@link DataTable.defaults}.
10850
+ * @namespace
10851
+ * @extends DataTable.models.oSearch
10852
+ */
10853
+ "oPreviousSearch": {},
10854
+
10855
+ /**
10856
+ * Store the applied search for each column - see
10857
+ * {@link DataTable.models.oSearch} for the format that is used for the
10858
+ * filtering information for each column.
10859
+ * @type array
10860
+ * @default []
10861
+ */
10862
+ "aoPreSearchCols": [],
10863
+
10864
+ /**
10865
+ * Sorting that is applied to the table. Note that the inner arrays are
10866
+ * used in the following manner:
10867
+ * <ul>
10868
+ * <li>Index 0 - column number</li>
10869
+ * <li>Index 1 - current sorting direction</li>
10870
+ * <li>Index 2 - index of asSorting for this column</li>
10871
+ * </ul>
10872
+ * Note that this parameter will be set by the initialisation routine. To
10873
+ * set a default use {@link DataTable.defaults}.
10874
+ * @type array
10875
+ * @todo These inner arrays should really be objects
10876
+ */
10877
+ "aaSorting": null,
10878
+
10879
+ /**
10880
+ * Sorting that is always applied to the table (i.e. prefixed in front of
10881
+ * aaSorting).
10882
+ * Note that this parameter will be set by the initialisation routine. To
10883
+ * set a default use {@link DataTable.defaults}.
10884
+ * @type array|null
10885
+ * @default null
10886
+ */
10887
+ "aaSortingFixed": null,
10888
+
10889
+ /**
10890
+ * Classes to use for the striping of a table.
10891
+ * Note that this parameter will be set by the initialisation routine. To
10892
+ * set a default use {@link DataTable.defaults}.
10893
+ * @type array
10894
+ * @default []
10895
+ */
10896
+ "asStripeClasses": null,
10897
+
10898
+ /**
10899
+ * If restoring a table - we should restore its striping classes as well
10900
+ * @type array
10901
+ * @default []
10902
+ */
10903
+ "asDestroyStripes": [],
10904
+
10905
+ /**
10906
+ * If restoring a table - we should restore its width
10907
+ * @type int
10908
+ * @default 0
10909
+ */
10910
+ "sDestroyWidth": 0,
10911
+
10912
+ /**
10913
+ * Callback functions array for every time a row is inserted (i.e. on a draw).
10914
+ * @type array
10915
+ * @default []
10916
+ */
10917
+ "aoRowCallback": [],
10918
+
10919
+ /**
10920
+ * Callback functions for the header on each draw.
10921
+ * @type array
10922
+ * @default []
10923
+ */
10924
+ "aoHeaderCallback": [],
10925
+
10926
+ /**
10927
+ * Callback function for the footer on each draw.
10928
+ * @type array
10929
+ * @default []
10930
+ */
10931
+ "aoFooterCallback": [],
10932
+
10933
+ /**
10934
+ * Array of callback functions for draw callback functions
10935
+ * @type array
10936
+ * @default []
10937
+ */
10938
+ "aoDrawCallback": [],
10939
+
10940
+ /**
10941
+ * Array of callback functions for row created function
10942
+ * @type array
10943
+ * @default []
10944
+ */
10945
+ "aoRowCreatedCallback": [],
10946
+
10947
+ /**
10948
+ * Callback functions for just before the table is redrawn. A return of
10949
+ * false will be used to cancel the draw.
10950
+ * @type array
10951
+ * @default []
10952
+ */
10953
+ "aoPreDrawCallback": [],
10954
+
10955
+ /**
10956
+ * Callback functions for when the table has been initialised.
10957
+ * @type array
10958
+ * @default []
10959
+ */
10960
+ "aoInitComplete": [],
10961
+
10962
+
10963
+ /**
10964
+ * Callbacks for modifying the settings to be stored for state saving, prior to
10965
+ * saving state.
10966
+ * @type array
10967
+ * @default []
10968
+ */
10969
+ "aoStateSaveParams": [],
10970
+
10971
+ /**
10972
+ * Callbacks for modifying the settings that have been stored for state saving
10973
+ * prior to using the stored values to restore the state.
10974
+ * @type array
10975
+ * @default []
10976
+ */
10977
+ "aoStateLoadParams": [],
10978
+
10979
+ /**
10980
+ * Callbacks for operating on the settings object once the saved state has been
10981
+ * loaded
10982
+ * @type array
10983
+ * @default []
10984
+ */
10985
+ "aoStateLoaded": [],
10986
+
10987
+ /**
10988
+ * Cache the table ID for quick access
10989
+ * @type string
10990
+ * @default <i>Empty string</i>
10991
+ */
10992
+ "sTableId": "",
10993
+
10994
+ /**
10995
+ * The TABLE node for the main table
10996
+ * @type node
10997
+ * @default null
10998
+ */
10999
+ "nTable": null,
11000
+
11001
+ /**
11002
+ * Permanent ref to the thead element
11003
+ * @type node
11004
+ * @default null
11005
+ */
11006
+ "nTHead": null,
11007
+
11008
+ /**
11009
+ * Permanent ref to the tfoot element - if it exists
11010
+ * @type node
11011
+ * @default null
11012
+ */
11013
+ "nTFoot": null,
11014
+
11015
+ /**
11016
+ * Permanent ref to the tbody element
11017
+ * @type node
11018
+ * @default null
11019
+ */
11020
+ "nTBody": null,
11021
+
11022
+ /**
11023
+ * Cache the wrapper node (contains all DataTables controlled elements)
11024
+ * @type node
11025
+ * @default null
11026
+ */
11027
+ "nTableWrapper": null,
11028
+
11029
+ /**
11030
+ * Indicate if when using server-side processing the loading of data
11031
+ * should be deferred until the second draw.
11032
+ * Note that this parameter will be set by the initialisation routine. To
11033
+ * set a default use {@link DataTable.defaults}.
11034
+ * @type boolean
11035
+ * @default false
11036
+ */
11037
+ "bDeferLoading": false,
11038
+
11039
+ /**
11040
+ * Indicate if all required information has been read in
11041
+ * @type boolean
11042
+ * @default false
11043
+ */
11044
+ "bInitialised": false,
11045
+
11046
+ /**
11047
+ * Information about open rows. Each object in the array has the parameters
11048
+ * 'nTr' and 'nParent'
11049
+ * @type array
11050
+ * @default []
11051
+ */
11052
+ "aoOpenRows": [],
11053
+
11054
+ /**
11055
+ * Dictate the positioning of DataTables' control elements - see
11056
+ * {@link DataTable.model.oInit.sDom}.
11057
+ * Note that this parameter will be set by the initialisation routine. To
11058
+ * set a default use {@link DataTable.defaults}.
11059
+ * @type string
11060
+ * @default null
11061
+ */
11062
+ "sDom": null,
11063
+
11064
+ /**
11065
+ * Which type of pagination should be used.
11066
+ * Note that this parameter will be set by the initialisation routine. To
11067
+ * set a default use {@link DataTable.defaults}.
11068
+ * @type string
11069
+ * @default two_button
11070
+ */
11071
+ "sPaginationType": "two_button",
11072
+
11073
+ /**
11074
+ * The cookie duration (for bStateSave) in seconds.
11075
+ * Note that this parameter will be set by the initialisation routine. To
11076
+ * set a default use {@link DataTable.defaults}.
11077
+ * @type int
11078
+ * @default 0
11079
+ */
11080
+ "iCookieDuration": 0,
11081
+
11082
+ /**
11083
+ * The cookie name prefix.
11084
+ * Note that this parameter will be set by the initialisation routine. To
11085
+ * set a default use {@link DataTable.defaults}.
11086
+ * @type string
11087
+ * @default <i>Empty string</i>
11088
+ */
11089
+ "sCookiePrefix": "",
11090
+
11091
+ /**
11092
+ * Callback function for cookie creation.
11093
+ * Note that this parameter will be set by the initialisation routine. To
11094
+ * set a default use {@link DataTable.defaults}.
11095
+ * @type function
11096
+ * @default null
11097
+ */
11098
+ "fnCookieCallback": null,
11099
+
11100
+ /**
11101
+ * Array of callback functions for state saving. Each array element is an
11102
+ * object with the following parameters:
11103
+ * <ul>
11104
+ * <li>function:fn - function to call. Takes two parameters, oSettings
11105
+ * and the JSON string to save that has been thus far created. Returns
11106
+ * a JSON string to be inserted into a json object
11107
+ * (i.e. '"param": [ 0, 1, 2]')</li>
11108
+ * <li>string:sName - name of callback</li>
11109
+ * </ul>
11110
+ * @type array
11111
+ * @default []
11112
+ */
11113
+ "aoStateSave": [],
11114
+
11115
+ /**
11116
+ * Array of callback functions for state loading. Each array element is an
11117
+ * object with the following parameters:
11118
+ * <ul>
11119
+ * <li>function:fn - function to call. Takes two parameters, oSettings
11120
+ * and the object stored. May return false to cancel state loading</li>
11121
+ * <li>string:sName - name of callback</li>
11122
+ * </ul>
11123
+ * @type array
11124
+ * @default []
11125
+ */
11126
+ "aoStateLoad": [],
11127
+
11128
+ /**
11129
+ * State that was loaded from the cookie. Useful for back reference
11130
+ * @type object
11131
+ * @default null
11132
+ */
11133
+ "oLoadedState": null,
11134
+
11135
+ /**
11136
+ * Source url for AJAX data for the table.
11137
+ * Note that this parameter will be set by the initialisation routine. To
11138
+ * set a default use {@link DataTable.defaults}.
11139
+ * @type string
11140
+ * @default null
11141
+ */
11142
+ "sAjaxSource": null,
11143
+
11144
+ /**
11145
+ * Property from a given object from which to read the table data from. This
11146
+ * can be an empty string (when not server-side processing), in which case
11147
+ * it is assumed an an array is given directly.
11148
+ * Note that this parameter will be set by the initialisation routine. To
11149
+ * set a default use {@link DataTable.defaults}.
11150
+ * @type string
11151
+ */
11152
+ "sAjaxDataProp": null,
11153
+
11154
+ /**
11155
+ * Note if draw should be blocked while getting data
11156
+ * @type boolean
11157
+ * @default true
11158
+ */
11159
+ "bAjaxDataGet": true,
11160
+
11161
+ /**
11162
+ * The last jQuery XHR object that was used for server-side data gathering.
11163
+ * This can be used for working with the XHR information in one of the
11164
+ * callbacks
11165
+ * @type object
11166
+ * @default null
11167
+ */
11168
+ "jqXHR": null,
11169
+
11170
+ /**
11171
+ * Function to get the server-side data.
11172
+ * Note that this parameter will be set by the initialisation routine. To
11173
+ * set a default use {@link DataTable.defaults}.
11174
+ * @type function
11175
+ */
11176
+ "fnServerData": null,
11177
+
11178
+ /**
11179
+ * Functions which are called prior to sending an Ajax request so extra
11180
+ * parameters can easily be sent to the server
11181
+ * @type array
11182
+ * @default []
11183
+ */
11184
+ "aoServerParams": [],
11185
+
11186
+ /**
11187
+ * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
11188
+ * required).
11189
+ * Note that this parameter will be set by the initialisation routine. To
11190
+ * set a default use {@link DataTable.defaults}.
11191
+ * @type string
11192
+ */
11193
+ "sServerMethod": null,
11194
+
11195
+ /**
11196
+ * Format numbers for display.
11197
+ * Note that this parameter will be set by the initialisation routine. To
11198
+ * set a default use {@link DataTable.defaults}.
11199
+ * @type function
11200
+ */
11201
+ "fnFormatNumber": null,
11202
+
11203
+ /**
11204
+ * List of options that can be used for the user selectable length menu.
11205
+ * Note that this parameter will be set by the initialisation routine. To
11206
+ * set a default use {@link DataTable.defaults}.
11207
+ * @type array
11208
+ * @default []
11209
+ */
11210
+ "aLengthMenu": null,
11211
+
11212
+ /**
11213
+ * Counter for the draws that the table does. Also used as a tracker for
11214
+ * server-side processing
11215
+ * @type int
11216
+ * @default 0
11217
+ */
11218
+ "iDraw": 0,
11219
+
11220
+ /**
11221
+ * Indicate if a redraw is being done - useful for Ajax
11222
+ * @type boolean
11223
+ * @default false
11224
+ */
11225
+ "bDrawing": false,
11226
+
11227
+ /**
11228
+ * Draw index (iDraw) of the last error when parsing the returned data
11229
+ * @type int
11230
+ * @default -1
11231
+ */
11232
+ "iDrawError": -1,
11233
+
11234
+ /**
11235
+ * Paging display length
11236
+ * @type int
11237
+ * @default 10
11238
+ */
11239
+ "_iDisplayLength": 10,
11240
+
11241
+ /**
11242
+ * Paging start point - aiDisplay index
11243
+ * @type int
11244
+ * @default 0
11245
+ */
11246
+ "_iDisplayStart": 0,
11247
+
11248
+ /**
11249
+ * Paging end point - aiDisplay index. Use fnDisplayEnd rather than
11250
+ * this property to get the end point
11251
+ * @type int
11252
+ * @default 10
11253
+ * @private
11254
+ */
11255
+ "_iDisplayEnd": 10,
11256
+
11257
+ /**
11258
+ * Server-side processing - number of records in the result set
11259
+ * (i.e. before filtering), Use fnRecordsTotal rather than
11260
+ * this property to get the value of the number of records, regardless of
11261
+ * the server-side processing setting.
11262
+ * @type int
11263
+ * @default 0
11264
+ * @private
11265
+ */
11266
+ "_iRecordsTotal": 0,
11267
+
11268
+ /**
11269
+ * Server-side processing - number of records in the current display set
11270
+ * (i.e. after filtering). Use fnRecordsDisplay rather than
11271
+ * this property to get the value of the number of records, regardless of
11272
+ * the server-side processing setting.
11273
+ * @type boolean
11274
+ * @default 0
11275
+ * @private
11276
+ */
11277
+ "_iRecordsDisplay": 0,
11278
+
11279
+ /**
11280
+ * Flag to indicate if jQuery UI marking and classes should be used.
11281
+ * Note that this parameter will be set by the initialisation routine. To
11282
+ * set a default use {@link DataTable.defaults}.
11283
+ * @type boolean
11284
+ */
11285
+ "bJUI": null,
11286
+
11287
+ /**
11288
+ * The classes to use for the table
11289
+ * @type object
11290
+ * @default {}
11291
+ */
11292
+ "oClasses": {},
11293
+
11294
+ /**
11295
+ * Flag attached to the settings object so you can check in the draw
11296
+ * callback if filtering has been done in the draw. Deprecated in favour of
11297
+ * events.
11298
+ * @type boolean
11299
+ * @default false
11300
+ * @deprecated
11301
+ */
11302
+ "bFiltered": false,
11303
+
11304
+ /**
11305
+ * Flag attached to the settings object so you can check in the draw
11306
+ * callback if sorting has been done in the draw. Deprecated in favour of
11307
+ * events.
11308
+ * @type boolean
11309
+ * @default false
11310
+ * @deprecated
11311
+ */
11312
+ "bSorted": false,
11313
+
11314
+ /**
11315
+ * Indicate that if multiple rows are in the header and there is more than
11316
+ * one unique cell per column, if the top one (true) or bottom one (false)
11317
+ * should be used for sorting / title by DataTables.
11318
+ * Note that this parameter will be set by the initialisation routine. To
11319
+ * set a default use {@link DataTable.defaults}.
11320
+ * @type boolean
11321
+ */
11322
+ "bSortCellsTop": null,
11323
+
11324
+ /**
11325
+ * Initialisation object that is used for the table
11326
+ * @type object
11327
+ * @default null
11328
+ */
11329
+ "oInit": null,
11330
+
11331
+ /**
11332
+ * Destroy callback functions - for plug-ins to attach themselves to the
11333
+ * destroy so they can clean up markup and events.
11334
+ * @type array
11335
+ * @default []
11336
+ */
11337
+ "aoDestroyCallback": [],
11338
+
11339
+
11340
+ /**
11341
+ * Get the number of records in the current record set, before filtering
11342
+ * @type function
11343
+ */
11344
+ "fnRecordsTotal": function ()
11345
+ {
11346
+ if ( this.oFeatures.bServerSide ) {
11347
+ return parseInt(this._iRecordsTotal, 10);
11348
+ } else {
11349
+ return this.aiDisplayMaster.length;
11350
+ }
11351
+ },
11352
+
11353
+ /**
11354
+ * Get the number of records in the current record set, after filtering
11355
+ * @type function
11356
+ */
11357
+ "fnRecordsDisplay": function ()
11358
+ {
11359
+ if ( this.oFeatures.bServerSide ) {
11360
+ return parseInt(this._iRecordsDisplay, 10);
11361
+ } else {
11362
+ return this.aiDisplay.length;
11363
+ }
11364
+ },
11365
+
11366
+ /**
11367
+ * Set the display end point - aiDisplay index
11368
+ * @type function
11369
+ * @todo Should do away with _iDisplayEnd and calculate it on-the-fly here
11370
+ */
11371
+ "fnDisplayEnd": function ()
11372
+ {
11373
+ if ( this.oFeatures.bServerSide ) {
11374
+ if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) {
11375
+ return this._iDisplayStart+this.aiDisplay.length;
11376
+ } else {
11377
+ return Math.min( this._iDisplayStart+this._iDisplayLength,
11378
+ this._iRecordsDisplay );
11379
+ }
11380
+ } else {
11381
+ return this._iDisplayEnd;
11382
+ }
11383
+ },
11384
+
11385
+ /**
11386
+ * The DataTables object for this table
11387
+ * @type object
11388
+ * @default null
11389
+ */
11390
+ "oInstance": null,
11391
+
11392
+ /**
11393
+ * Unique identifier for each instance of the DataTables object. If there
11394
+ * is an ID on the table node, then it takes that value, otherwise an
11395
+ * incrementing internal counter is used.
11396
+ * @type string
11397
+ * @default null
11398
+ */
11399
+ "sInstance": null,
11400
+
11401
+ /**
11402
+ * tabindex attribute value that is added to DataTables control elements, allowing
11403
+ * keyboard navigation of the table and its controls.
11404
+ */
11405
+ "iTabIndex": 0,
11406
+
11407
+ /**
11408
+ * DIV container for the footer scrolling table if scrolling
11409
+ */
11410
+ "nScrollHead": null,
11411
+
11412
+ /**
11413
+ * DIV container for the footer scrolling table if scrolling
11414
+ */
11415
+ "nScrollFoot": null
11416
+ };
11417
+
11418
+ /**
11419
+ * Extension object for DataTables that is used to provide all extension options.
11420
+ *
11421
+ * Note that the <i>DataTable.ext</i> object is available through
11422
+ * <i>jQuery.fn.dataTable.ext</i> where it may be accessed and manipulated. It is
11423
+ * also aliased to <i>jQuery.fn.dataTableExt</i> for historic reasons.
11424
+ * @namespace
11425
+ * @extends DataTable.models.ext
11426
+ */
11427
+ DataTable.ext = $.extend( true, {}, DataTable.models.ext );
11428
+
11429
+ $.extend( DataTable.ext.oStdClasses, {
11430
+ "sTable": "dataTable",
11431
+
11432
+ /* Two buttons buttons */
11433
+ "sPagePrevEnabled": "paginate_enabled_previous",
11434
+ "sPagePrevDisabled": "paginate_disabled_previous",
11435
+ "sPageNextEnabled": "paginate_enabled_next",
11436
+ "sPageNextDisabled": "paginate_disabled_next",
11437
+ "sPageJUINext": "",
11438
+ "sPageJUIPrev": "",
11439
+
11440
+ /* Full numbers paging buttons */
11441
+ "sPageButton": "paginate_button",
11442
+ "sPageButtonActive": "paginate_active",
11443
+ "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled",
11444
+ "sPageFirst": "first",
11445
+ "sPagePrevious": "previous",
11446
+ "sPageNext": "next",
11447
+ "sPageLast": "last",
11448
+
11449
+ /* Striping classes */
11450
+ "sStripeOdd": "odd",
11451
+ "sStripeEven": "even",
11452
+
11453
+ /* Empty row */
11454
+ "sRowEmpty": "dataTables_empty",
11455
+
11456
+ /* Features */
11457
+ "sWrapper": "dataTables_wrapper",
11458
+ "sFilter": "dataTables_filter",
11459
+ "sInfo": "dataTables_info",
11460
+ "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
11461
+ "sLength": "dataTables_length",
11462
+ "sProcessing": "dataTables_processing",
11463
+
11464
+ /* Sorting */
11465
+ "sSortAsc": "sorting_asc",
11466
+ "sSortDesc": "sorting_desc",
11467
+ "sSortable": "sorting", /* Sortable in both directions */
11468
+ "sSortableAsc": "sorting_asc_disabled",
11469
+ "sSortableDesc": "sorting_desc_disabled",
11470
+ "sSortableNone": "sorting_disabled",
11471
+ "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
11472
+ "sSortJUIAsc": "",
11473
+ "sSortJUIDesc": "",
11474
+ "sSortJUI": "",
11475
+ "sSortJUIAscAllowed": "",
11476
+ "sSortJUIDescAllowed": "",
11477
+ "sSortJUIWrapper": "",
11478
+ "sSortIcon": "",
11479
+
11480
+ /* Scrolling */
11481
+ "sScrollWrapper": "dataTables_scroll",
11482
+ "sScrollHead": "dataTables_scrollHead",
11483
+ "sScrollHeadInner": "dataTables_scrollHeadInner",
11484
+ "sScrollBody": "dataTables_scrollBody",
11485
+ "sScrollFoot": "dataTables_scrollFoot",
11486
+ "sScrollFootInner": "dataTables_scrollFootInner",
11487
+
11488
+ /* Misc */
11489
+ "sFooterTH": "",
11490
+ "sJUIHeader": "",
11491
+ "sJUIFooter": ""
11492
+ } );
11493
+
11494
+
11495
+ $.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, {
11496
+ /* Two buttons buttons */
11497
+ "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left",
11498
+ "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
11499
+ "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right",
11500
+ "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",
11501
+ "sPageJUINext": "ui-icon ui-icon-circle-arrow-e",
11502
+ "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w",
11503
+
11504
+ /* Full numbers paging buttons */
11505
+ "sPageButton": "fg-button ui-button ui-state-default",
11506
+ "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled",
11507
+ "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled",
11508
+ "sPageFirst": "first ui-corner-tl ui-corner-bl",
11509
+ "sPageLast": "last ui-corner-tr ui-corner-br",
11510
+
11511
+ /* Features */
11512
+ "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
11513
+ "ui-buttonset-multi paging_", /* Note that the type is postfixed */
11514
+
11515
+ /* Sorting */
11516
+ "sSortAsc": "ui-state-default",
11517
+ "sSortDesc": "ui-state-default",
11518
+ "sSortable": "ui-state-default",
11519
+ "sSortableAsc": "ui-state-default",
11520
+ "sSortableDesc": "ui-state-default",
11521
+ "sSortableNone": "ui-state-default",
11522
+ "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n",
11523
+ "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s",
11524
+ "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s",
11525
+ "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n",
11526
+ "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s",
11527
+ "sSortJUIWrapper": "DataTables_sort_wrapper",
11528
+ "sSortIcon": "DataTables_sort_icon",
11529
+
11530
+ /* Scrolling */
11531
+ "sScrollHead": "dataTables_scrollHead ui-state-default",
11532
+ "sScrollFoot": "dataTables_scrollFoot ui-state-default",
11533
+
11534
+ /* Misc */
11535
+ "sFooterTH": "ui-state-default",
11536
+ "sJUIHeader": "fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix",
11537
+ "sJUIFooter": "fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix"
11538
+ } );
11539
+
11540
+ /*
11541
+ * Variable: oPagination
11542
+ * Purpose:
11543
+ * Scope: jQuery.fn.dataTableExt
11544
+ */
11545
+ $.extend( DataTable.ext.oPagination, {
11546
+ /*
11547
+ * Variable: two_button
11548
+ * Purpose: Standard two button (forward/back) pagination
11549
+ * Scope: jQuery.fn.dataTableExt.oPagination
11550
+ */
11551
+ "two_button": {
11552
+ /*
11553
+ * Function: oPagination.two_button.fnInit
11554
+ * Purpose: Initialise dom elements required for pagination with forward/back buttons only
11555
+ * Returns: -
11556
+ * Inputs: object:oSettings - dataTables settings object
11557
+ * node:nPaging - the DIV which contains this pagination control
11558
+ * function:fnCallbackDraw - draw function which must be called on update
11559
+ */
11560
+ "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
11561
+ {
11562
+ var oLang = oSettings.oLanguage.oPaginate;
11563
+ var oClasses = oSettings.oClasses;
11564
+ var fnClickHandler = function ( e ) {
11565
+ if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
11566
+ {
11567
+ fnCallbackDraw( oSettings );
11568
+ }
11569
+ };
11570
+
11571
+ var sAppend = (!oSettings.bJUI) ?
11572
+ '<a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sPrevious+'</a>'+
11573
+ '<a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sNext+'</a>'
11574
+ :
11575
+ '<a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oClasses.sPageJUIPrev+'"></span></a>'+
11576
+ '<a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="'+oSettings.oClasses.sPageJUINext+'"></span></a>';
11577
+ $(nPaging).append( sAppend );
11578
+
11579
+ var els = $('a', nPaging);
11580
+ var nPrevious = els[0],
11581
+ nNext = els[1];
11582
+
11583
+ oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler );
11584
+ oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
11585
+
11586
+ /* ID the first elements only */
11587
+ if ( !oSettings.aanFeatures.p )
11588
+ {
11589
+ nPaging.id = oSettings.sTableId+'_paginate';
11590
+ nPrevious.id = oSettings.sTableId+'_previous';
11591
+ nNext.id = oSettings.sTableId+'_next';
11592
+
11593
+ nPrevious.setAttribute('aria-controls', oSettings.sTableId);
11594
+ nNext.setAttribute('aria-controls', oSettings.sTableId);
11595
+ }
11596
+ },
11597
+
11598
+ /*
11599
+ * Function: oPagination.two_button.fnUpdate
11600
+ * Purpose: Update the two button pagination at the end of the draw
11601
+ * Returns: -
11602
+ * Inputs: object:oSettings - dataTables settings object
11603
+ * function:fnCallbackDraw - draw function to call on page change
11604
+ */
11605
+ "fnUpdate": function ( oSettings, fnCallbackDraw )
11606
+ {
11607
+ if ( !oSettings.aanFeatures.p )
11608
+ {
11609
+ return;
11610
+ }
11611
+
11612
+ var oClasses = oSettings.oClasses;
11613
+ var an = oSettings.aanFeatures.p;
11614
+ var nNode;
11615
+
11616
+ /* Loop over each instance of the pager */
11617
+ for ( var i=0, iLen=an.length ; i<iLen ; i++ )
11618
+ {
11619
+ nNode = an[i].firstChild;
11620
+ if ( nNode )
11621
+ {
11622
+ /* Previous page */
11623
+ nNode.className = ( oSettings._iDisplayStart === 0 ) ?
11624
+ oClasses.sPagePrevDisabled : oClasses.sPagePrevEnabled;
11625
+
11626
+ /* Next page */
11627
+ nNode = nNode.nextSibling;
11628
+ nNode.className = ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() ) ?
11629
+ oClasses.sPageNextDisabled : oClasses.sPageNextEnabled;
11630
+ }
11631
+ }
11632
+ }
11633
+ },
11634
+
11635
+
11636
+ /*
11637
+ * Variable: iFullNumbersShowPages
11638
+ * Purpose: Change the number of pages which can be seen
11639
+ * Scope: jQuery.fn.dataTableExt.oPagination
11640
+ */
11641
+ "iFullNumbersShowPages": 5,
11642
+
11643
+ /*
11644
+ * Variable: full_numbers
11645
+ * Purpose: Full numbers pagination
11646
+ * Scope: jQuery.fn.dataTableExt.oPagination
11647
+ */
11648
+ "full_numbers": {
11649
+ /*
11650
+ * Function: oPagination.full_numbers.fnInit
11651
+ * Purpose: Initialise dom elements required for pagination with a list of the pages
11652
+ * Returns: -
11653
+ * Inputs: object:oSettings - dataTables settings object
11654
+ * node:nPaging - the DIV which contains this pagination control
11655
+ * function:fnCallbackDraw - draw function which must be called on update
11656
+ */
11657
+ "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
11658
+ {
11659
+ var oLang = oSettings.oLanguage.oPaginate;
11660
+ var oClasses = oSettings.oClasses;
11661
+ var fnClickHandler = function ( e ) {
11662
+ if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
11663
+ {
11664
+ fnCallbackDraw( oSettings );
11665
+ }
11666
+ };
11667
+
11668
+ $(nPaging).append(
11669
+ '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'">'+oLang.sFirst+'</a>'+
11670
+ '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'">'+oLang.sPrevious+'</a>'+
11671
+ '<span></span>'+
11672
+ '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+'</a>'+
11673
+ '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+'</a>'
11674
+ );
11675
+ var els = $('a', nPaging);
11676
+ var nFirst = els[0],
11677
+ nPrev = els[1],
11678
+ nNext = els[2],
11679
+ nLast = els[3];
11680
+
11681
+ oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
11682
+ oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
11683
+ oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
11684
+ oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
11685
+
11686
+ /* ID the first elements only */
11687
+ if ( !oSettings.aanFeatures.p )
11688
+ {
11689
+ nPaging.id = oSettings.sTableId+'_paginate';
11690
+ nFirst.id =oSettings.sTableId+'_first';
11691
+ nPrev.id =oSettings.sTableId+'_previous';
11692
+ nNext.id =oSettings.sTableId+'_next';
11693
+ nLast.id =oSettings.sTableId+'_last';
11694
+ }
11695
+ },
11696
+
11697
+ /*
11698
+ * Function: oPagination.full_numbers.fnUpdate
11699
+ * Purpose: Update the list of page buttons shows
11700
+ * Returns: -
11701
+ * Inputs: object:oSettings - dataTables settings object
11702
+ * function:fnCallbackDraw - draw function to call on page change
11703
+ */
11704
+ "fnUpdate": function ( oSettings, fnCallbackDraw )
11705
+ {
11706
+ if ( !oSettings.aanFeatures.p )
11707
+ {
11708
+ return;
11709
+ }
11710
+
11711
+ var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages;
11712
+ var iPageCountHalf = Math.floor(iPageCount / 2);
11713
+ var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
11714
+ var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
11715
+ var sList = "";
11716
+ var iStartButton, iEndButton, i, iLen;
11717
+ var oClasses = oSettings.oClasses;
11718
+ var anButtons, anStatic, nPaginateList, nNode;
11719
+ var an = oSettings.aanFeatures.p;
11720
+ var fnBind = function (j) {
11721
+ oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) {
11722
+ /* Use the information in the element to jump to the required page */
11723
+ oSettings.oApi._fnPageChange( oSettings, e.data.page );
11724
+ fnCallbackDraw( oSettings );
11725
+ e.preventDefault();
11726
+ } );
11727
+ };
11728
+
11729
+ /* Pages calculation */
11730
+ if ( oSettings._iDisplayLength === -1 )
11731
+ {
11732
+ iStartButton = 1;
11733
+ iEndButton = 1;
11734
+ iCurrentPage = 1;
11735
+ }
11736
+ else if (iPages < iPageCount)
11737
+ {
11738
+ iStartButton = 1;
11739
+ iEndButton = iPages;
11740
+ }
11741
+ else if (iCurrentPage <= iPageCountHalf)
11742
+ {
11743
+ iStartButton = 1;
11744
+ iEndButton = iPageCount;
11745
+ }
11746
+ else if (iCurrentPage >= (iPages - iPageCountHalf))
11747
+ {
11748
+ iStartButton = iPages - iPageCount + 1;
11749
+ iEndButton = iPages;
11750
+ }
11751
+ else
11752
+ {
11753
+ iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
11754
+ iEndButton = iStartButton + iPageCount - 1;
11755
+ }
11756
+
11757
+
11758
+ /* Build the dynamic list */
11759
+ for ( i=iStartButton ; i<=iEndButton ; i++ )
11760
+ {
11761
+ sList += (iCurrentPage !== i) ?
11762
+ '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+'">'+oSettings.fnFormatNumber(i)+'</a>' :
11763
+ '<a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButtonActive+'">'+oSettings.fnFormatNumber(i)+'</a>';
11764
+ }
11765
+
11766
+ /* Loop over each instance of the pager */
11767
+ for ( i=0, iLen=an.length ; i<iLen ; i++ )
11768
+ {
11769
+ nNode = an[i];
11770
+ if ( !nNode.hasChildNodes() )
11771
+ {
11772
+ continue;
11773
+ }
11774
+
11775
+ /* Build up the dynamic list first - html and listeners */
11776
+ $('span:eq(0)', nNode)
11777
+ .html( sList )
11778
+ .children('a').each( fnBind );
11779
+
11780
+ /* Update the permanent button's classes */
11781
+ anButtons = nNode.getElementsByTagName('a');
11782
+ anStatic = [
11783
+ anButtons[0], anButtons[1],
11784
+ anButtons[anButtons.length-2], anButtons[anButtons.length-1]
11785
+ ];
11786
+
11787
+ $(anStatic).removeClass( oClasses.sPageButton+" "+oClasses.sPageButtonActive+" "+oClasses.sPageButtonStaticDisabled );
11788
+ $([anStatic[0], anStatic[1]]).addClass(
11789
+ (iCurrentPage==1) ?
11790
+ oClasses.sPageButtonStaticDisabled :
11791
+ oClasses.sPageButton
11792
+ );
11793
+ $([anStatic[2], anStatic[3]]).addClass(
11794
+ (iPages===0 || iCurrentPage===iPages || oSettings._iDisplayLength===-1) ?
11795
+ oClasses.sPageButtonStaticDisabled :
11796
+ oClasses.sPageButton
11797
+ );
11798
+ }
11799
+ }
11800
+ }
11801
+ } );
11802
+
11803
+ $.extend( DataTable.ext.oSort, {
11804
+ /*
11805
+ * text sorting
11806
+ */
11807
+ "string-pre": function ( a )
11808
+ {
11809
+ if ( typeof a != 'string' ) {
11810
+ a = (a !== null && a.toString) ? a.toString() : '';
11811
+ }
11812
+ return a.toLowerCase();
11813
+ },
11814
+
11815
+ "string-asc": function ( x, y )
11816
+ {
11817
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
11818
+ },
11819
+
11820
+ "string-desc": function ( x, y )
11821
+ {
11822
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
11823
+ },
11824
+
11825
+
11826
+ /*
11827
+ * html sorting (ignore html tags)
11828
+ */
11829
+ "html-pre": function ( a )
11830
+ {
11831
+ return a.replace( /<.*?>/g, "" ).toLowerCase();
11832
+ },
11833
+
11834
+ "html-asc": function ( x, y )
11835
+ {
11836
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
11837
+ },
11838
+
11839
+ "html-desc": function ( x, y )
11840
+ {
11841
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
11842
+ },
11843
+
11844
+
11845
+ /*
11846
+ * date sorting
11847
+ */
11848
+ "date-pre": function ( a )
11849
+ {
11850
+ var x = Date.parse( a );
11851
+
11852
+ if ( isNaN(x) || x==="" )
11853
+ {
11854
+ x = Date.parse( "01/01/1970 00:00:00" );
11855
+ }
11856
+ return x;
11857
+ },
11858
+
11859
+ "date-asc": function ( x, y )
11860
+ {
11861
+ return x - y;
11862
+ },
11863
+
11864
+ "date-desc": function ( x, y )
11865
+ {
11866
+ return y - x;
11867
+ },
11868
+
11869
+
11870
+ /*
11871
+ * numerical sorting
11872
+ */
11873
+ "numeric-pre": function ( a )
11874
+ {
11875
+ return (a=="-" || a==="") ? 0 : a*1;
11876
+ },
11877
+
11878
+ "numeric-asc": function ( x, y )
11879
+ {
11880
+ return x - y;
11881
+ },
11882
+
11883
+ "numeric-desc": function ( x, y )
11884
+ {
11885
+ return y - x;
11886
+ }
11887
+ } );
11888
+
11889
+
11890
+ $.extend( DataTable.ext.aTypes, [
11891
+ /*
11892
+ * Function: -
11893
+ * Purpose: Check to see if a string is numeric
11894
+ * Returns: string:'numeric' or null
11895
+ * Inputs: mixed:sText - string to check
11896
+ */
11897
+ function ( sData )
11898
+ {
11899
+ /* Allow zero length strings as a number */
11900
+ if ( typeof sData === 'number' )
11901
+ {
11902
+ return 'numeric';
11903
+ }
11904
+ else if ( typeof sData !== 'string' )
11905
+ {
11906
+ return null;
11907
+ }
11908
+
11909
+ var sValidFirstChars = "0123456789-";
11910
+ var sValidChars = "0123456789.";
11911
+ var Char;
11912
+ var bDecimal = false;
11913
+
11914
+ /* Check for a valid first char (no period and allow negatives) */
11915
+ Char = sData.charAt(0);
11916
+ if (sValidFirstChars.indexOf(Char) == -1)
11917
+ {
11918
+ return null;
11919
+ }
11920
+
11921
+ /* Check all the other characters are valid */
11922
+ for ( var i=1 ; i<sData.length ; i++ )
11923
+ {
11924
+ Char = sData.charAt(i);
11925
+ if (sValidChars.indexOf(Char) == -1)
11926
+ {
11927
+ return null;
11928
+ }
11929
+
11930
+ /* Only allowed one decimal place... */
11931
+ if ( Char == "." )
11932
+ {
11933
+ if ( bDecimal )
11934
+ {
11935
+ return null;
11936
+ }
11937
+ bDecimal = true;
11938
+ }
11939
+ }
11940
+
11941
+ return 'numeric';
11942
+ },
11943
+
11944
+ /*
11945
+ * Function: -
11946
+ * Purpose: Check to see if a string is actually a formatted date
11947
+ * Returns: string:'date' or null
11948
+ * Inputs: string:sText - string to check
11949
+ */
11950
+ function ( sData )
11951
+ {
11952
+ var iParse = Date.parse(sData);
11953
+ if ( (iParse !== null && !isNaN(iParse)) || (typeof sData === 'string' && sData.length === 0) )
11954
+ {
11955
+ return 'date';
11956
+ }
11957
+ return null;
11958
+ },
11959
+
11960
+ /*
11961
+ * Function: -
11962
+ * Purpose: Check to see if a string should be treated as an HTML string
11963
+ * Returns: string:'html' or null
11964
+ * Inputs: string:sText - string to check
11965
+ */
11966
+ function ( sData )
11967
+ {
11968
+ if ( typeof sData === 'string' && sData.indexOf('<') != -1 && sData.indexOf('>') != -1 )
11969
+ {
11970
+ return 'html';
11971
+ }
11972
+ return null;
11973
+ }
11974
+ ] );
11975
+
11976
+
11977
+ // jQuery aliases
11978
+ $.fn.DataTable = DataTable;
11979
+ $.fn.dataTable = DataTable;
11980
+ $.fn.dataTableSettings = DataTable.settings;
11981
+ $.fn.dataTableExt = DataTable.ext;
11982
+
11983
+
11984
+ // Information about events fired by DataTables - for documentation.
11985
+ /**
11986
+ * Draw event, fired whenever the table is redrawn on the page, at the same point as
11987
+ * fnDrawCallback. This may be useful for binding events or performing calculations when
11988
+ * the table is altered at all.
11989
+ * @name DataTable#draw
11990
+ * @event
11991
+ * @param {event} e jQuery event object
11992
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
11993
+ */
11994
+
11995
+ /**
11996
+ * Filter event, fired when the filtering applied to the table (using the build in global
11997
+ * global filter, or column filters) is altered.
11998
+ * @name DataTable#filter
11999
+ * @event
12000
+ * @param {event} e jQuery event object
12001
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
12002
+ */
12003
+
12004
+ /**
12005
+ * Page change event, fired when the paging of the table is altered.
12006
+ * @name DataTable#page
12007
+ * @event
12008
+ * @param {event} e jQuery event object
12009
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
12010
+ */
12011
+
12012
+ /**
12013
+ * Sort event, fired when the sorting applied to the table is altered.
12014
+ * @name DataTable#sort
12015
+ * @event
12016
+ * @param {event} e jQuery event object
12017
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
12018
+ */
12019
+
12020
+ /**
12021
+ * DataTables initialisation complete event, fired when the table is fully drawn,
12022
+ * including Ajax data loaded, if Ajax data is required.
12023
+ * @name DataTable#init
12024
+ * @event
12025
+ * @param {event} e jQuery event object
12026
+ * @param {object} oSettings DataTables settings object
12027
+ * @param {object} json The JSON object request from the server - only
12028
+ * present if client-side Ajax sourced data is used</li></ol>
12029
+ */
12030
+
12031
+ /**
12032
+ * State save event, fired when the table has changed state a new state save is required.
12033
+ * This method allows modification of the state saving object prior to actually doing the
12034
+ * save, including addition or other state properties (for plug-ins) or modification
12035
+ * of a DataTables core property.
12036
+ * @name DataTable#stateSaveParams
12037
+ * @event
12038
+ * @param {event} e jQuery event object
12039
+ * @param {object} oSettings DataTables settings object
12040
+ * @param {object} json The state information to be saved
12041
+ */
12042
+
12043
+ /**
12044
+ * State load event, fired when the table is loading state from the stored data, but
12045
+ * prior to the settings object being modified by the saved state - allowing modification
12046
+ * of the saved state is required or loading of state for a plug-in.
12047
+ * @name DataTable#stateLoadParams
12048
+ * @event
12049
+ * @param {event} e jQuery event object
12050
+ * @param {object} oSettings DataTables settings object
12051
+ * @param {object} json The saved state information
12052
+ */
12053
+
12054
+ /**
12055
+ * State loaded event, fired when state has been loaded from stored data and the settings
12056
+ * object has been modified by the loaded data.
12057
+ * @name DataTable#stateLoaded
12058
+ * @event
12059
+ * @param {event} e jQuery event object
12060
+ * @param {object} oSettings DataTables settings object
12061
+ * @param {object} json The saved state information
12062
+ */
12063
+
12064
+ /**
12065
+ * Processing event, fired when DataTables is doing some kind of processing (be it,
12066
+ * sort, filter or anything else). Can be used to indicate to the end user that
12067
+ * there is something happening, or that something has finished.
12068
+ * @name DataTable#processing
12069
+ * @event
12070
+ * @param {event} e jQuery event object
12071
+ * @param {object} oSettings DataTables settings object
12072
+ * @param {boolean} bShow Flag for if DataTables is doing processing or not
12073
+ */
12074
+
12075
+ /**
12076
+ * Ajax (XHR) event, fired whenever an Ajax request is completed from a request to
12077
+ * made to the server for new data (note that this trigger is called in fnServerData,
12078
+ * if you override fnServerData and which to use this event, you need to trigger it in
12079
+ * you success function).
12080
+ * @name DataTable#xhr
12081
+ * @event
12082
+ * @param {event} e jQuery event object
12083
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
12084
+ * @param {object} json JSON returned from the server
12085
+ */
12086
+
12087
+ /**
12088
+ * Destroy event, fired when the DataTable is destroyed by calling fnDestroy or passing
12089
+ * the bDestroy:true parameter in the initialisation object. This can be used to remove
12090
+ * bound events, added DOM nodes, etc.
12091
+ * @name DataTable#destroy
12092
+ * @event
12093
+ * @param {event} e jQuery event object
12094
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
12095
+ */
12096
+ }));
12097
+
12098
+ }(window, document));
12099
+
js/jquery.dataTables.min.js ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * File: jquery.dataTables.min.js
3
+ * Version: 1.9.1
4
+ * Author: Allan Jardine (www.sprymedia.co.uk)
5
+ * Info: www.datatables.net
6
+ *
7
+ * Copyright 2008-2012 Allan Jardine, all rights reserved.
8
+ *
9
+ * This source file is free software, under either the GPL v2 license or a
10
+ * BSD style license, available at:
11
+ * http://datatables.net/license_gpl2
12
+ * http://datatables.net/license_bsd
13
+ *
14
+ * This source file is distributed in the hope that it will be useful, but
15
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
17
+ */
18
+ (function(h,V,l,m){var j=function(e){function o(a,b){var c=j.defaults.columns,d=a.aoColumns.length,c=h.extend({},j.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:l.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mDataProp:c.mDataProp?c.oDefaults:d});a.aoColumns.push(c);if(a.aoPreSearchCols[d]===m||null===a.aoPreSearchCols[d])a.aoPreSearchCols[d]=h.extend({},j.models.oSearch);else{c=a.aoPreSearchCols[d];
19
+ if(c.bRegex===m)c.bRegex=!0;if(c.bSmart===m)c.bSmart=!0;if(c.bCaseInsensitive===m)c.bCaseInsensitive=!0}s(a,d,null)}function s(a,b,c){b=a.aoColumns[b];if(c!==m&&null!==c){if(c.sType!==m)b.sType=c.sType,b._bAutoType=!1;h.extend(b,c);p(b,c,"sWidth","sWidthOrig");if(c.iDataSort!==m)b.aDataSort=[c.iDataSort];p(b,c,"aDataSort")}b.fnGetData=W(b.mDataProp);b.fnSetData=ta(b.mDataProp);if(!a.oFeatures.bSort)b.bSortable=!1;if(!b.bSortable||-1==h.inArray("asc",b.asSorting)&&-1==h.inArray("desc",b.asSorting))b.sSortingClass=
20
+ a.oClasses.sSortableNone,b.sSortingClassJUI="";else if(b.bSortable||-1==h.inArray("asc",b.asSorting)&&-1==h.inArray("desc",b.asSorting))b.sSortingClass=a.oClasses.sSortable,b.sSortingClassJUI=a.oClasses.sSortJUI;else if(-1!=h.inArray("asc",b.asSorting)&&-1==h.inArray("desc",b.asSorting))b.sSortingClass=a.oClasses.sSortableAsc,b.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed;else if(-1==h.inArray("asc",b.asSorting)&&-1!=h.inArray("desc",b.asSorting))b.sSortingClass=a.oClasses.sSortableDesc,b.sSortingClassJUI=
21
+ a.oClasses.sSortJUIDescAllowed}function k(a){if(!1===a.oFeatures.bAutoWidth)return!1;ba(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function x(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++)if(!0===a.aoColumns[d].bVisible&&c++,c==b)return d;return null}function r(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++)if(!0===a.aoColumns[d].bVisible&&c++,d==b)return!0===a.aoColumns[d].bVisible?c:null;return null}function v(a){for(var b=0,c=0;c<a.aoColumns.length;c++)!0===
22
+ a.aoColumns[c].bVisible&&b++;return b}function A(a){for(var b=j.ext.aTypes,c=b.length,d=0;d<c;d++){var f=b[d](a);if(null!==f)return f}return"string"}function E(a,b){for(var c=b.split(","),d=[],f=0,g=a.aoColumns.length;f<g;f++)for(var i=0;i<g;i++)if(a.aoColumns[f].sName==c[i]){d.push(i);break}return d}function y(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";return b.length==d?"":b.slice(0,-1)}function J(a,b,c,d){var f,g,i,e,u;if(b)for(f=b.length-1;0<=f;f--){var n=b[f].aTargets;
23
+ h.isArray(n)||F(a,1,"aTargets must be an array of targets, not a "+typeof n);for(g=0,i=n.length;g<i;g++)if("number"===typeof n[g]&&0<=n[g]){for(;a.aoColumns.length<=n[g];)o(a);d(n[g],b[f])}else if("number"===typeof n[g]&&0>n[g])d(a.aoColumns.length+n[g],b[f]);else if("string"===typeof n[g])for(e=0,u=a.aoColumns.length;e<u;e++)("_all"==n[g]||h(a.aoColumns[e].nTh).hasClass(n[g]))&&d(e,b[f])}if(c)for(f=0,a=c.length;f<a;f++)d(f,c[f])}function H(a,b){var c;c=h.isArray(b)?b.slice():h.extend(!0,{},b);var d=
24
+ a.aoData.length,f=h.extend(!0,{},j.models.oRow);f._aData=c;a.aoData.push(f);for(var g,f=0,i=a.aoColumns.length;f<i;f++)if(c=a.aoColumns[f],"function"===typeof c.fnRender&&c.bUseRendered&&null!==c.mDataProp?I(a,d,f,R(a,d,f)):I(a,d,f,w(a,d,f)),c._bAutoType&&"string"!=c.sType&&(g=w(a,d,f,"type"),null!==g&&""!==g))if(g=A(g),null===c.sType)c.sType=g;else if(c.sType!=g&&"html"!=c.sType)c.sType="string";a.aiDisplayMaster.push(d);a.oFeatures.bDeferRender||ca(a,d);return d}function ua(a){var b,c,d,f,g,i,e,
25
+ u,n;if(a.bDeferLoading||null===a.sAjaxSource){e=a.nTBody.childNodes;for(b=0,c=e.length;b<c;b++)if("TR"==e[b].nodeName.toUpperCase()){u=a.aoData.length;e[b]._DT_RowIndex=u;a.aoData.push(h.extend(!0,{},j.models.oRow,{nTr:e[b]}));a.aiDisplayMaster.push(u);i=e[b].childNodes;g=0;for(d=0,f=i.length;d<f;d++)if(n=i[d].nodeName.toUpperCase(),"TD"==n||"TH"==n)I(a,u,g,h.trim(i[d].innerHTML)),g++}}e=S(a);i=[];for(b=0,c=e.length;b<c;b++)for(d=0,f=e[b].childNodes.length;d<f;d++)g=e[b].childNodes[d],n=g.nodeName.toUpperCase(),
26
+ ("TD"==n||"TH"==n)&&i.push(g);for(f=0,e=a.aoColumns.length;f<e;f++){n=a.aoColumns[f];if(null===n.sTitle)n.sTitle=n.nTh.innerHTML;g=n._bAutoType;u="function"===typeof n.fnRender;var o=null!==n.sClass,k=n.bVisible,m,s;if(g||u||o||!k)for(b=0,c=a.aoData.length;b<c;b++){d=a.aoData[b];m=i[b*e+f];if(g&&"string"!=n.sType&&(s=w(a,b,f,"type"),""!==s))if(s=A(s),null===n.sType)n.sType=s;else if(n.sType!=s&&"html"!=n.sType)n.sType="string";if("function"===typeof n.mDataProp)m.innerHTML=w(a,b,f,"display");if(u)s=
27
+ R(a,b,f),m.innerHTML=s,n.bUseRendered&&I(a,b,f,s);o&&(m.className+=" "+n.sClass);k?d._anHidden[f]=null:(d._anHidden[f]=m,m.parentNode.removeChild(m));n.fnCreatedCell&&n.fnCreatedCell.call(a.oInstance,m,w(a,b,f,"display"),d._aData,b,f)}}if(0!==a.aoRowCreatedCallback.length)for(b=0,c=a.aoData.length;b<c;b++)d=a.aoData[b],D(a,"aoRowCreatedCallback",null,[d.nTr,d._aData,b])}function K(a,b){return b._DT_RowIndex!==m?b._DT_RowIndex:null}function da(a,b,c){for(var b=L(a,b),d=0,a=a.aoColumns.length;d<a;d++)if(b[d]===
28
+ c)return d;return-1}function X(a,b,c){for(var d=[],f=0,g=a.aoColumns.length;f<g;f++)d.push(w(a,b,f,c));return d}function w(a,b,c,d){var f=a.aoColumns[c];if((c=f.fnGetData(a.aoData[b]._aData,d))===m){if(a.iDrawError!=a.iDraw&&null===f.sDefaultContent)F(a,0,"Requested unknown parameter "+("function"==typeof f.mDataProp?"{mDataprop function}":"'"+f.mDataProp+"'")+" from the data source for row "+b),a.iDrawError=a.iDraw;return f.sDefaultContent}if(null===c&&null!==f.sDefaultContent)c=f.sDefaultContent;
29
+ else if("function"===typeof c)return c();return"display"==d&&null===c?"":c}function I(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d)}function W(a){if(null===a)return function(){return null};if("function"===typeof a)return function(b,d){return a(b,d)};if("string"===typeof a&&-1!=a.indexOf(".")){var b=a.split(".");return function(a){for(var d=0,f=b.length;d<f;d++)if(a=a[b[d]],a===m)return m;return a}}return function(b){return b[a]}}function ta(a){if(null===a)return function(){};if("function"===
30
+ typeof a)return function(b,d){a(b,"set",d)};if("string"===typeof a&&-1!=a.indexOf(".")){var b=a.split(".");return function(a,d){for(var f=0,g=b.length-1;f<g;f++)if(a=a[b[f]],a===m)return;a[b[b.length-1]]=d}}return function(b,d){b[a]=d}}function Y(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function ea(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);B(a)}function fa(a,b){for(var c=
31
+ -1,d=0,f=a.length;d<f;d++)a[d]==b?c=d:a[d]>b&&a[d]--; -1!=c&&a.splice(c,1)}function R(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mDataProp},w(a,b,c,"display"))}function ca(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=l.createElement("tr");c.nTr._DT_RowIndex=b;if(c._aData.DT_RowId)c.nTr.id=c._aData.DT_RowId;c._aData.DT_RowClass&&h(c.nTr).addClass(c._aData.DT_RowClass);for(var f=0,g=a.aoColumns.length;f<g;f++){var i=a.aoColumns[f];
32
+ d=l.createElement(i.sCellType);d.innerHTML="function"===typeof i.fnRender&&(!i.bUseRendered||null===i.mDataProp)?R(a,b,f):w(a,b,f,"display");if(null!==i.sClass)d.className=i.sClass;i.bVisible?(c.nTr.appendChild(d),c._anHidden[f]=null):c._anHidden[f]=d;i.fnCreatedCell&&i.fnCreatedCell.call(a.oInstance,d,w(a,b,f,"display"),c._aData,b,f)}D(a,"aoRowCreatedCallback",null,[c.nTr,c._aData,b])}}function va(a){var b,c,d;if(0!==a.nTHead.getElementsByTagName("th").length)for(b=0,d=a.aoColumns.length;b<d;b++){if(c=
33
+ a.aoColumns[b].nTh,c.setAttribute("role","columnheader"),a.aoColumns[b].bSortable&&(c.setAttribute("tabindex",a.iTabIndex),c.setAttribute("aria-controls",a.sTableId)),null!==a.aoColumns[b].sClass&&h(c).addClass(a.aoColumns[b].sClass),a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}else{var f=l.createElement("tr");for(b=0,d=a.aoColumns.length;b<d;b++)c=a.aoColumns[b].nTh,c.innerHTML=a.aoColumns[b].sTitle,c.setAttribute("tabindex","0"),null!==a.aoColumns[b].sClass&&h(c).addClass(a.aoColumns[b].sClass),
34
+ f.appendChild(c);h(a.nTHead).html("")[0].appendChild(f);T(a.aoHeader,a.nTHead)}h(a.nTHead).children("tr").attr("role","row");if(a.bJUI)for(b=0,d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;f=l.createElement("div");f.className=a.oClasses.sSortJUIWrapper;h(c).contents().appendTo(f);var g=l.createElement("span");g.className=a.oClasses.sSortIcon;f.appendChild(g);c.appendChild(f)}if(a.oFeatures.bSort)for(b=0;b<a.aoColumns.length;b++)!1!==a.aoColumns[b].bSortable?ga(a,a.aoColumns[b].nTh,b):h(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);
35
+ ""!==a.oClasses.sFooterTH&&h(a.nTFoot).children("tr").children("th").addClass(a.oClasses.sFooterTH);if(null!==a.nTFoot){c=O(a,null,a.aoFooter);for(b=0,d=a.aoColumns.length;b<d;b++)if(c[b])a.aoColumns[b].nTf=c[b],a.aoColumns[b].sClass&&h(c[b]).addClass(a.aoColumns[b].sClass)}}function U(a,b,c){var d,f,g,i=[],e=[],h=a.aoColumns.length,n;c===m&&(c=!1);for(d=0,f=b.length;d<f;d++){i[d]=b[d].slice();i[d].nTr=b[d].nTr;for(g=h-1;0<=g;g--)!a.aoColumns[g].bVisible&&!c&&i[d].splice(g,1);e.push([])}for(d=0,f=
36
+ i.length;d<f;d++){if(a=i[d].nTr)for(;g=a.firstChild;)a.removeChild(g);for(g=0,b=i[d].length;g<b;g++)if(n=h=1,e[d][g]===m){a.appendChild(i[d][g].cell);for(e[d][g]=1;i[d+h]!==m&&i[d][g].cell==i[d+h][g].cell;)e[d+h][g]=1,h++;for(;i[d][g+n]!==m&&i[d][g].cell==i[d][g+n].cell;){for(c=0;c<h;c++)e[d+c][g+n]=1;n++}i[d][g].cell.rowSpan=h;i[d][g].cell.colSpan=n}}}function z(a){var b,c,d=[],f=0,g=a.asStripeClasses.length;b=a.aoOpenRows.length;c=D(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,c))G(a,
37
+ !1);else{a.bDrawing=!0;if(a.iInitDisplayStart!==m&&-1!=a.iInitDisplayStart)a._iDisplayStart=a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,B(a);if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!wa(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var i=a._iDisplayStart;c=a._iDisplayEnd;if(a.oFeatures.bServerSide)i=0,c=a.aoData.length;for(;i<c;i++){var e=a.aoData[a.aiDisplay[i]];
38
+ null===e.nTr&&ca(a,a.aiDisplay[i]);var j=e.nTr;if(0!==g){var n=a.asStripeClasses[f%g];if(e._sRowStripe!=n)h(j).removeClass(e._sRowStripe).addClass(n),e._sRowStripe=n}D(a,"aoRowCallback",null,[j,a.aoData[a.aiDisplay[i]]._aData,f,i]);d.push(j);f++;if(0!==b)for(e=0;e<b;e++)if(j==a.aoOpenRows[e].nParent){d.push(a.aoOpenRows[e].nTr);break}}}else{d[0]=l.createElement("tr");if(a.asStripeClasses[0])d[0].className=a.asStripeClasses[0];b=a.oLanguage;g=b.sZeroRecords;if(1==a.iDraw&&null!==a.sAjaxSource&&!a.oFeatures.bServerSide)g=
39
+ b.sLoadingRecords;else if(b.sEmptyTable&&0===a.fnRecordsTotal())g=b.sEmptyTable;b=l.createElement("td");b.setAttribute("valign","top");b.colSpan=v(a);b.className=a.oClasses.sRowEmpty;b.innerHTML=ha(a,g);d[f].appendChild(b)}D(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Y(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);D(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Y(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);f=l.createDocumentFragment();b=l.createDocumentFragment();
40
+ if(a.nTBody){g=a.nTBody.parentNode;b.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered)for(;b=a.nTBody.firstChild;)a.nTBody.removeChild(b);for(b=0,c=d.length;b<c;b++)f.appendChild(d[b]);a.nTBody.appendChild(f);null!==g&&g.appendChild(a.nTBody)}D(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1;a.oFeatures.bServerSide&&(G(a,!1),a._bInitComplete||Z(a))}}function $(a){a.oFeatures.bSort?P(a,a.oPreviousSearch):a.oFeatures.bFilter?M(a,a.oPreviousSearch):
41
+ (B(a),z(a))}function xa(a){var b=h("<div></div>")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=h('<div id="'+a.sTableId+'_wrapper" class="'+a.oClasses.sWrapper+'" role="grid"></div>')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),f,g,i,e,u,n,o,k=0;k<d.length;k++){g=0;i=d[k];if("<"==i){e=h("<div></div>")[0];u=d[k+1];if("'"==u||'"'==u){n="";for(o=2;d[k+o]!=u;)n+=d[k+o],o++;"H"==n?n="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix":
42
+ "F"==n&&(n="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix");-1!=n.indexOf(".")?(u=n.split("."),e.id=u[0].substr(1,u[0].length-1),e.className=u[1]):"#"==n.charAt(0)?e.id=n.substr(1,n.length-1):e.className=n;k+=o}c.appendChild(e);c=e}else if(">"==i)c=c.parentNode;else if("l"==i&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)f=ya(a),g=1;else if("f"==i&&a.oFeatures.bFilter)f=za(a),g=1;else if("r"==i&&a.oFeatures.bProcessing)f=Aa(a),g=1;else if("t"==i)f=Ba(a),g=
43
+ 1;else if("i"==i&&a.oFeatures.bInfo)f=Ca(a),g=1;else if("p"==i&&a.oFeatures.bPaginate)f=Da(a),g=1;else if(0!==j.ext.aoFeatures.length){e=j.ext.aoFeatures;o=0;for(u=e.length;o<u;o++)if(i==e[o].cFeature){(f=e[o].fnInit(a))&&(g=1);break}}1==g&&null!==f&&("object"!==typeof a.aanFeatures[i]&&(a.aanFeatures[i]=[]),a.aanFeatures[i].push(f),c.appendChild(f))}b.parentNode.replaceChild(a.nTableWrapper,b)}function T(a,b){var c=h(b).children("tr"),d,f,g,i,e,j,n,o;a.splice(0,a.length);for(f=0,j=c.length;f<j;f++)a.push([]);
44
+ for(f=0,j=c.length;f<j;f++)for(g=0,n=c[f].childNodes.length;g<n;g++)if(d=c[f].childNodes[g],"TD"==d.nodeName.toUpperCase()||"TH"==d.nodeName.toUpperCase()){var k=1*d.getAttribute("colspan"),m=1*d.getAttribute("rowspan"),k=!k||0===k||1===k?1:k,m=!m||0===m||1===m?1:m;for(i=0;a[f][i];)i++;o=i;for(e=0;e<k;e++)for(i=0;i<m;i++)a[f+i][o+e]={cell:d,unique:1==k?!0:!1},a[f+i].nTr=c[f]}}function O(a,b,c){var d=[];if(!c)c=a.aoHeader,b&&(c=[],T(c,b));for(var b=0,f=c.length;b<f;b++)for(var g=0,i=c[b].length;g<
45
+ i;g++)if(c[b][g].unique&&(!d[g]||!a.bSortCellsTop))d[g]=c[b][g].cell;return d}function wa(a){if(a.bAjaxDataGet){a.iDraw++;G(a,!0);var b=Ea(a);ia(a,b);a.fnServerData.call(a.oInstance,a.sAjaxSource,b,function(b){Fa(a,b)},a);return!1}return!0}function Ea(a){var b=a.aoColumns.length,c=[],d,f,g,i;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:y(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:!1!==a.oFeatures.bPaginate?
46
+ a._iDisplayLength:-1});for(g=0;g<b;g++)d=a.aoColumns[g].mDataProp,c.push({name:"mDataProp_"+g,value:"function"===typeof d?"function":d});if(!1!==a.oFeatures.bFilter){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});for(g=0;g<b;g++)c.push({name:"sSearch_"+g,value:a.aoPreSearchCols[g].sSearch}),c.push({name:"bRegex_"+g,value:a.aoPreSearchCols[g].bRegex}),c.push({name:"bSearchable_"+g,value:a.aoColumns[g].bSearchable})}if(!1!==a.oFeatures.bSort){var e=
47
+ 0;d=null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(g=0;g<d.length;g++){f=a.aoColumns[d[g][0]].aDataSort;for(i=0;i<f.length;i++)c.push({name:"iSortCol_"+e,value:f[i]}),c.push({name:"sSortDir_"+e,value:d[g][1]}),e++}c.push({name:"iSortingCols",value:e});for(g=0;g<b;g++)c.push({name:"bSortable_"+g,value:a.aoColumns[g].bSortable})}return c}function ia(a,b){D(a,"aoServerParams","serverParams",[b])}function Fa(a,b){if(b.sEcho!==m){if(1*b.sEcho<a.iDraw)return;a.iDraw=
48
+ 1*b.sEcho}(!a.oScroll.bInfinite||a.oScroll.bInfinite&&(a.bSorted||a.bFiltered))&&ea(a);a._iRecordsTotal=parseInt(b.iTotalRecords,10);a._iRecordsDisplay=parseInt(b.iTotalDisplayRecords,10);var c=y(a),c=b.sColumns!==m&&""!==c&&b.sColumns!=c,d;c&&(d=E(a,b.sColumns));for(var f=W(a.sAjaxDataProp)(b),g=0,i=f.length;g<i;g++)if(c){for(var e=[],h=0,n=a.aoColumns.length;h<n;h++)e.push(f[g][d[h]]);H(a,e)}else H(a,f[g]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;z(a);a.bAjaxDataGet=!0;G(a,!1)}function za(a){var b=
49
+ a.oPreviousSearch,c=a.oLanguage.sSearch,c=-1!==c.indexOf("_INPUT_")?c.replace("_INPUT_",'<input type="text" />'):""===c?'<input type="text" />':c+' <input type="text" />',d=l.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="<label>"+c+"</label>";if(!a.aanFeatures.f)d.id=a.sTableId+"_filter";c=h('input[type="text"]',d);d._DT_Input=c[0];c.val(b.sSearch.replace('"',"&quot;"));c.bind("keyup.DT",function(){for(var c=a.aanFeatures.f,d=""===this.value?"":this.value,i=0,e=c.length;i<e;i++)c[i]!=
50
+ h(this).parents("div.dataTables_filter")[0]&&h(c[i]._DT_Input).val(d);d!=b.sSearch&&M(a,{sSearch:d,bRegex:b.bRegex,bSmart:b.bSmart,bCaseInsensitive:b.bCaseInsensitive})});c.attr("aria-controls",a.sTableId).bind("keypress.DT",function(a){if(13==a.keyCode)return!1});return d}function M(a,b,c){var d=a.oPreviousSearch,f=a.aoPreSearchCols,g=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};if(a.oFeatures.bServerSide)g(b);else{Ga(a,b.sSearch,c,b.bRegex,
51
+ b.bSmart,b.bCaseInsensitive);g(b);for(b=0;b<a.aoPreSearchCols.length;b++)Ha(a,f[b].sSearch,b,f[b].bRegex,f[b].bSmart,f[b].bCaseInsensitive);Ia(a)}a.bFiltered=!0;h(a.oInstance).trigger("filter",a);a._iDisplayStart=0;B(a);z(a);ja(a,0)}function Ia(a){for(var b=j.ext.afnFiltering,c=0,d=b.length;c<d;c++)for(var f=0,g=0,i=a.aiDisplay.length;g<i;g++){var e=a.aiDisplay[g-f];b[c](a,X(a,e,"filter"),e)||(a.aiDisplay.splice(g-f,1),f++)}}function Ha(a,b,c,d,f,g){if(""!==b)for(var i=0,b=ka(b,d,f,g),d=a.aiDisplay.length-
52
+ 1;0<=d;d--)f=la(w(a,a.aiDisplay[d],c,"filter"),a.aoColumns[c].sType),b.test(f)||(a.aiDisplay.splice(d,1),i++)}function Ga(a,b,c,d,f,g){d=ka(b,d,f,g);f=a.oPreviousSearch;c||(c=0);0!==j.ext.afnFiltering.length&&(c=1);if(0>=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length||f.sSearch.length>b.length||1==c||0!==b.indexOf(f.sSearch)){a.aiDisplay.splice(0,a.aiDisplay.length);ja(a,1);for(b=0;b<a.aiDisplayMaster.length;b++)d.test(a.asDataSearch[b])&&
53
+ a.aiDisplay.push(a.aiDisplayMaster[b])}else for(b=c=0;b<a.asDataSearch.length;b++)d.test(a.asDataSearch[b])||(a.aiDisplay.splice(b-c,1),c++)}function ja(a,b){if(!a.oFeatures.bServerSide){a.asDataSearch.splice(0,a.asDataSearch.length);for(var c=b&&1===b?a.aiDisplayMaster:a.aiDisplay,d=0,f=c.length;d<f;d++)a.asDataSearch[d]=ma(a,X(a,c[d],"filter"))}}function ma(a,b){var c="";if(a.__nTmpFilter===m)a.__nTmpFilter=l.createElement("div");for(var d=a.__nTmpFilter,f=0,g=a.aoColumns.length;f<g;f++)a.aoColumns[f].bSearchable&&
54
+ (c+=la(b[f],a.aoColumns[f].sType)+" ");if(-1!==c.indexOf("&"))d.innerHTML=c,c=d.textContent?d.textContent:d.innerText,c=c.replace(/\n/g," ").replace(/\r/g,"");return c}function ka(a,b,c,d){if(c)return a=b?a.split(" "):na(a).split(" "),a="^(?=.*?"+a.join(")(?=.*?")+").*$",RegExp(a,d?"i":"");a=b?a:na(a);return RegExp(a,d?"i":"")}function la(a,b){return"function"===typeof j.ext.ofnSearch[b]?j.ext.ofnSearch[b](a):null===a?"":"html"==b?a.replace(/[\r\n]/g," ").replace(/<.*?>/g,""):"string"===typeof a?
55
+ a.replace(/[\r\n]/g," "):a}function na(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^)","g"),"\\$1")}function Ca(a){var b=l.createElement("div");b.className=a.oClasses.sInfo;if(!a.aanFeatures.i)a.aoDrawCallback.push({fn:Ja,sName:"information"}),b.id=a.sTableId+"_info";a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function Ja(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var b=a.oLanguage,c=a._iDisplayStart+1,d=a.fnDisplayEnd(),
56
+ f=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),i;i=0===g&&g==f?b.sInfoEmpty:0===g?b.sInfoEmpty+" "+b.sInfoFiltered:g==f?b.sInfo:b.sInfo+" "+b.sInfoFiltered;i+=b.sInfoPostFix;i=ha(a,i);null!==b.fnInfoCallback&&(i=b.fnInfoCallback.call(a.oInstance,a,c,d,f,g,i));a=a.aanFeatures.i;b=0;for(c=a.length;b<c;b++)h(a[b]).html(i)}}function ha(a,b){var c=a.fnFormatNumber(a._iDisplayStart+1),d=a.fnDisplayEnd(),d=a.fnFormatNumber(d),f=a.fnRecordsDisplay(),f=a.fnFormatNumber(f),g=a.fnRecordsTotal(),g=a.fnFormatNumber(g);
57
+ a.oScroll.bInfinite&&(c=a.fnFormatNumber(1));return b.replace("_START_",c).replace("_END_",d).replace("_TOTAL_",f).replace("_MAX_",g)}function aa(a){var b,c,d=a.iInitDisplayStart;if(!1===a.bInitialised)setTimeout(function(){aa(a)},200);else{xa(a);va(a);U(a,a.aoHeader);a.nTFoot&&U(a,a.aoFooter);G(a,!0);a.oFeatures.bAutoWidth&&ba(a);for(b=0,c=a.aoColumns.length;b<c;b++)if(null!==a.aoColumns[b].sWidth)a.aoColumns[b].nTh.style.width=q(a.aoColumns[b].sWidth);a.oFeatures.bSort?P(a):a.oFeatures.bFilter?
58
+ M(a,a.oPreviousSearch):(a.aiDisplay=a.aiDisplayMaster.slice(),B(a),z(a));null!==a.sAjaxSource&&!a.oFeatures.bServerSide?(c=[],ia(a,c),a.fnServerData.call(a.oInstance,a.sAjaxSource,c,function(c){var g=""!==a.sAjaxDataProp?W(a.sAjaxDataProp)(c):c;for(b=0;b<g.length;b++)H(a,g[b]);a.iInitDisplayStart=d;a.oFeatures.bSort?P(a):(a.aiDisplay=a.aiDisplayMaster.slice(),B(a),z(a));G(a,!1);Z(a,c)},a)):a.oFeatures.bServerSide||(G(a,!1),Z(a))}}function Z(a,b){a._bInitComplete=!0;D(a,"aoInitComplete","init",[a,
59
+ b])}function oa(a){var b=j.defaults.oLanguage;!a.sEmptyTable&&a.sZeroRecords&&"No data available in table"===b.sEmptyTable&&p(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&a.sZeroRecords&&"Loading..."===b.sLoadingRecords&&p(a,a,"sZeroRecords","sLoadingRecords")}function ya(a){if(a.oScroll.bInfinite)return null;var b='<select size="1" '+('name="'+a.sTableId+'_length"')+">",c,d,f=a.aLengthMenu;if(2==f.length&&"object"===typeof f[0]&&"object"===typeof f[1])for(c=0,d=f[0].length;c<d;c++)b+='<option value="'+
60
+ f[0][c]+'">'+f[1][c]+"</option>";else for(c=0,d=f.length;c<d;c++)b+='<option value="'+f[c]+'">'+f[c]+"</option>";b+="</select>";f=l.createElement("div");if(!a.aanFeatures.l)f.id=a.sTableId+"_length";f.className=a.oClasses.sLength;f.innerHTML="<label>"+a.oLanguage.sLengthMenu.replace("_MENU_",b)+"</label>";h('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",!0);h("select",f).bind("change.DT",function(){var b=h(this).val(),f=a.aanFeatures.l;for(c=0,d=f.length;c<d;c++)f[c]!=this.parentNode&&
61
+ h("select",f[c]).val(b);a._iDisplayLength=parseInt(b,10);B(a);if(a.fnDisplayEnd()==a.fnRecordsDisplay()&&(a._iDisplayStart=a.fnDisplayEnd()-a._iDisplayLength,0>a._iDisplayStart))a._iDisplayStart=0;if(-1==a._iDisplayLength)a._iDisplayStart=0;z(a)});h("select",f).attr("aria-controls",a.sTableId);return f}function B(a){a._iDisplayEnd=!1===a.oFeatures.bPaginate?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}
62
+ function Da(a){if(a.oScroll.bInfinite)return null;var b=l.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;j.ext.oPagination[a.sPaginationType].fnInit(a,b,function(a){B(a);z(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){j.ext.oPagination[a.sPaginationType].fnUpdate(a,function(a){B(a);z(a)})},sName:"pagination"});return b}function pa(a,b){var c=a._iDisplayStart;if("number"===typeof b){if(a._iDisplayStart=b*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay())a._iDisplayStart=
63
+ 0}else if("first"==b)a._iDisplayStart=0;else if("previous"==b){if(a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart)a._iDisplayStart=0}else if("next"==b)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLength<a.fnRecordsDisplay()&&(a._iDisplayStart+=a._iDisplayLength):a._iDisplayStart=0;else if("last"==b)if(0<=a._iDisplayLength){var d=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(d-1)*a._iDisplayLength}else a._iDisplayStart=
64
+ 0;else F(a,0,"Unknown paging action: "+b);h(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}function Aa(a){var b=l.createElement("div");if(!a.aanFeatures.r)b.id=a.sTableId+"_processing";b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function G(a,b){if(a.oFeatures.bProcessing)for(var c=a.aanFeatures.r,d=0,f=c.length;d<f;d++)c[d].style.visibility=b?"visible":"hidden";h(a.oInstance).trigger("processing",[a,b])}function Ba(a){if(""===
65
+ a.oScroll.sX&&""===a.oScroll.sY)return a.nTable;var b=l.createElement("div"),c=l.createElement("div"),d=l.createElement("div"),f=l.createElement("div"),g=l.createElement("div"),i=l.createElement("div"),e=a.nTable.cloneNode(!1),j=a.nTable.cloneNode(!1),n=a.nTable.getElementsByTagName("thead")[0],o=0===a.nTable.getElementsByTagName("tfoot").length?null:a.nTable.getElementsByTagName("tfoot")[0],k=a.oClasses;c.appendChild(d);g.appendChild(i);f.appendChild(a.nTable);b.appendChild(c);b.appendChild(f);d.appendChild(e);
66
+ e.appendChild(n);null!==o&&(b.appendChild(g),i.appendChild(j),j.appendChild(o));b.className=k.sScrollWrapper;c.className=k.sScrollHead;d.className=k.sScrollHeadInner;f.className=k.sScrollBody;g.className=k.sScrollFoot;i.className=k.sScrollFootInner;if(a.oScroll.bAutoCss)c.style.overflow="hidden",c.style.position="relative",g.style.overflow="hidden",f.style.overflow="auto";c.style.border="0";c.style.width="100%";g.style.border="0";d.style.width=""!==a.oScroll.sXInner?a.oScroll.sXInner:"100%";e.removeAttribute("id");
67
+ e.style.marginLeft="0";a.nTable.style.marginLeft="0";if(null!==o)j.removeAttribute("id"),j.style.marginLeft="0";d=h(a.nTable).children("caption");0<d.length&&(d=d[0],"top"===d._captionSide?e.appendChild(d):"bottom"===d._captionSide&&o&&j.appendChild(d));if(""!==a.oScroll.sX){c.style.width=q(a.oScroll.sX);f.style.width=q(a.oScroll.sX);if(null!==o)g.style.width=q(a.oScroll.sX);h(f).scroll(function(){c.scrollLeft=this.scrollLeft;if(null!==o)g.scrollLeft=this.scrollLeft})}if(""!==a.oScroll.sY)f.style.height=
68
+ q(a.oScroll.sY);a.aoDrawCallback.push({fn:Ka,sName:"scrolling"});a.oScroll.bInfinite&&h(f).scroll(function(){!a.bDrawing&&0!==h(this).scrollTop()&&h(this).scrollTop()+h(this).height()>h(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()<a.fnRecordsDisplay()&&(pa(a,"next"),B(a),z(a))});a.nScrollHead=c;a.nScrollFoot=g;return b}function Ka(a){var b=a.nScrollHead.getElementsByTagName("div")[0],c=b.getElementsByTagName("table")[0],d=a.nTable.parentNode,f,g,i,e,j,n,o,k,m=[],s=null!==a.nTFoot?a.nScrollFoot.getElementsByTagName("div")[0]:
69
+ null,p=null!==a.nTFoot?s.getElementsByTagName("table")[0]:null,l=h.browser.msie&&7>=h.browser.version;h(a.nTable).children("thead, tfoot").remove();i=h(a.nTHead).clone()[0];a.nTable.insertBefore(i,a.nTable.childNodes[0]);null!==a.nTFoot&&(j=h(a.nTFoot).clone()[0],a.nTable.insertBefore(j,a.nTable.childNodes[1]));if(""===a.oScroll.sX)d.style.width="100%",b.parentNode.style.width="100%";var r=O(a,i);for(f=0,g=r.length;f<g;f++)o=x(a,f),r[f].style.width=a.aoColumns[o].sWidth;null!==a.nTFoot&&N(function(a){a.style.width=
70
+ ""},j.getElementsByTagName("tr"));if(a.oScroll.bCollapse&&""!==a.oScroll.sY)d.style.height=d.offsetHeight+a.nTHead.offsetHeight+"px";f=h(a.nTable).outerWidth();if(""===a.oScroll.sX){if(a.nTable.style.width="100%",l&&(h("tbody",d).height()>d.offsetHeight||"scroll"==h(d).css("overflow-y")))a.nTable.style.width=q(h(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(""!==a.oScroll.sXInner)a.nTable.style.width=q(a.oScroll.sXInner);else if(f==h(d).width()&&h(d).height()<h(a.nTable).height()){if(a.nTable.style.width=
71
+ q(f-a.oScroll.iBarWidth),h(a.nTable).outerWidth()>f-a.oScroll.iBarWidth)a.nTable.style.width=q(f)}else a.nTable.style.width=q(f);f=h(a.nTable).outerWidth();g=a.nTHead.getElementsByTagName("tr");i=i.getElementsByTagName("tr");N(function(a,b){n=a.style;n.paddingTop="0";n.paddingBottom="0";n.borderTopWidth="0";n.borderBottomWidth="0";n.height=0;k=h(a).width();b.style.width=q(k);m.push(k)},i,g);h(i).height(0);null!==a.nTFoot&&(e=j.getElementsByTagName("tr"),j=a.nTFoot.getElementsByTagName("tr"),N(function(a,
72
+ b){n=a.style;n.paddingTop="0";n.paddingBottom="0";n.borderTopWidth="0";n.borderBottomWidth="0";n.height=0;k=h(a).width();b.style.width=q(k);m.push(k)},e,j),h(e).height(0));N(function(a){a.innerHTML="";a.style.width=q(m.shift())},i);null!==a.nTFoot&&N(function(a){a.innerHTML="";a.style.width=q(m.shift())},e);if(h(a.nTable).outerWidth()<f){e=d.scrollHeight>d.offsetHeight||"scroll"==h(d).css("overflow-y")?f+a.oScroll.iBarWidth:f;if(l&&(d.scrollHeight>d.offsetHeight||"scroll"==h(d).css("overflow-y")))a.nTable.style.width=
73
+ q(e-a.oScroll.iBarWidth);d.style.width=q(e);b.parentNode.style.width=q(e);if(null!==a.nTFoot)s.parentNode.style.width=q(e);""===a.oScroll.sX?F(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."):""!==a.oScroll.sXInner&&F(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else if(d.style.width=
74
+ q("100%"),b.parentNode.style.width=q("100%"),null!==a.nTFoot)s.parentNode.style.width=q("100%");if(""===a.oScroll.sY&&l)d.style.height=q(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(""!==a.oScroll.sY&&a.oScroll.bCollapse&&(d.style.height=q(a.oScroll.sY),l=""!==a.oScroll.sX&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeight<d.offsetHeight))d.style.height=q(a.nTable.offsetHeight+l);l=h(a.nTable).outerWidth();c.style.width=q(l);b.style.width=q(l);c=h(a.nTable).height()>
75
+ d.clientHeight||"scroll"==h(d).css("overflow-y");b.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px";if(null!==a.nTFoot)p.style.width=q(l),s.style.width=q(l),s.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px";h(d).scroll();if(a.bSorted||a.bFiltered)d.scrollTop=0}function N(a,b,c){for(var d=0,f=b.length;d<f;d++)for(var g=0,i=b[d].childNodes.length;g<i;g++)1==b[d].childNodes[g].nodeType&&(c?a(b[d].childNodes[g],c[d].childNodes[g]):a(b[d].childNodes[g]))}function La(a,b){if(!a||null===a||""===a)return 0;
76
+ b||(b=l.getElementsByTagName("body")[0]);var c,d=l.createElement("div");d.style.width=q(a);b.appendChild(d);c=d.offsetWidth;b.removeChild(d);return c}function ba(a){var b=0,c,d=0,f=a.aoColumns.length,g,i=h("th",a.nTHead),e=a.nTable.getAttribute("width");for(g=0;g<f;g++)if(a.aoColumns[g].bVisible&&(d++,null!==a.aoColumns[g].sWidth)){c=La(a.aoColumns[g].sWidthOrig,a.nTable.parentNode);if(null!==c)a.aoColumns[g].sWidth=q(c);b++}if(f==i.length&&0===b&&d==f&&""===a.oScroll.sX&&""===a.oScroll.sY)for(g=
77
+ 0;g<a.aoColumns.length;g++){if(c=h(i[g]).width(),null!==c)a.aoColumns[g].sWidth=q(c)}else{b=a.nTable.cloneNode(!1);g=a.nTHead.cloneNode(!0);d=l.createElement("tbody");c=l.createElement("tr");b.removeAttribute("id");b.appendChild(g);null!==a.nTFoot&&(b.appendChild(a.nTFoot.cloneNode(!0)),N(function(a){a.style.width=""},b.getElementsByTagName("tr")));b.appendChild(d);d.appendChild(c);d=h("thead th",b);0===d.length&&(d=h("tbody tr:eq(0)>td",b));i=O(a,g);for(g=d=0;g<f;g++){var j=a.aoColumns[g];j.bVisible&&
78
+ null!==j.sWidthOrig&&""!==j.sWidthOrig?i[g-d].style.width=q(j.sWidthOrig):j.bVisible?i[g-d].style.width="":d++}for(g=0;g<f;g++)a.aoColumns[g].bVisible&&(d=Ma(a,g),null!==d&&(d=d.cloneNode(!0),""!==a.aoColumns[g].sContentPadding&&(d.innerHTML+=a.aoColumns[g].sContentPadding),c.appendChild(d)));f=a.nTable.parentNode;f.appendChild(b);if(""!==a.oScroll.sX&&""!==a.oScroll.sXInner)b.style.width=q(a.oScroll.sXInner);else if(""!==a.oScroll.sX){if(b.style.width="",h(b).width()<f.offsetWidth)b.style.width=
79
+ q(f.offsetWidth)}else if(""!==a.oScroll.sY)b.style.width=q(f.offsetWidth);else if(e)b.style.width=q(e);b.style.visibility="hidden";Na(a,b);f=h("tbody tr:eq(0)",b).children();0===f.length&&(f=O(a,h("thead",b)[0]));if(""!==a.oScroll.sX){for(g=d=c=0;g<a.aoColumns.length;g++)a.aoColumns[g].bVisible&&(c=null===a.aoColumns[g].sWidthOrig?c+h(f[d]).outerWidth():c+(parseInt(a.aoColumns[g].sWidth.replace("px",""),10)+(h(f[d]).outerWidth()-h(f[d]).width())),d++);b.style.width=q(c);a.nTable.style.width=q(c)}for(g=
80
+ d=0;g<a.aoColumns.length;g++)if(a.aoColumns[g].bVisible){c=h(f[d]).width();if(null!==c&&0<c)a.aoColumns[g].sWidth=q(c);d++}f=h(b).css("width");a.nTable.style.width=-1!==f.indexOf("%")?f:q(h(b).outerWidth());b.parentNode.removeChild(b)}if(e)a.nTable.style.width=q(e)}function Na(a,b){if(""===a.oScroll.sX&&""!==a.oScroll.sY)h(b).width(),b.style.width=q(h(b).outerWidth()-a.oScroll.iBarWidth);else if(""!==a.oScroll.sX)b.style.width=q(h(b).outerWidth())}function Ma(a,b){var c=Oa(a,b);if(0>c)return null;
81
+ if(null===a.aoData[c].nTr){var d=l.createElement("td");d.innerHTML=w(a,c,b,"");return d}return L(a,c)[b]}function Oa(a,b){for(var c=-1,d=-1,f=0;f<a.aoData.length;f++){var g=w(a,f,b,"display")+"",g=g.replace(/<.*?>/g,"");if(g.length>c)c=g.length,d=f}return d}function q(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1);return 48>b||57<b?a:a+"px"}function Pa(){var a=l.createElement("p"),b=a.style;b.width="100%";b.height="200px";b.padding="0px";var c=
82
+ l.createElement("div"),b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";b.height="150px";b.padding="0px";b.overflow="hidden";c.appendChild(a);l.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";a=a.offsetWidth;if(b==a)a=c.clientWidth;l.body.removeChild(c);return b-a}function P(a,b){var c,d,f,g,i,e,o=[],n=[],k=j.ext.oSort,s=a.aoData,l=a.aoColumns,p=a.oLanguage.oAria;if(!a.oFeatures.bServerSide&&(0!==a.aaSorting.length||null!==a.aaSortingFixed)){o=
83
+ null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c<o.length;c++)if(d=o[c][0],f=r(a,d),g=a.aoColumns[d].sSortDataType,j.ext.afnSortData[g])if(i=j.ext.afnSortData[g].call(a.oInstance,a,d,f),i.length===s.length)for(f=0,g=s.length;f<g;f++)I(a,f,d,i[f]);else F(a,0,"Returned data sort array (col "+d+") is the wrong length");for(c=0,d=a.aiDisplayMaster.length;c<d;c++)n[a.aiDisplayMaster[c]]=c;var q=o.length,x;for(c=0,d=s.length;c<d;c++)for(f=0;f<q;f++){x=l[o[f][0]].aDataSort;
84
+ for(i=0,e=x.length;i<e;i++)g=l[x[i]].sType,g=k[(g?g:"string")+"-pre"],s[c]._aSortData[x[i]]=g?g(w(a,c,x[i],"sort")):w(a,c,x[i],"sort")}a.aiDisplayMaster.sort(function(a,b){var c,d,f,g,i;for(c=0;c<q;c++){i=l[o[c][0]].aDataSort;for(d=0,f=i.length;d<f;d++)if(g=l[i[d]].sType,g=k[(g?g:"string")+"-"+o[c][1]](s[a]._aSortData[i[d]],s[b]._aSortData[i[d]]),0!==g)return g}return k["numeric-asc"](n[a],n[b])})}(b===m||b)&&!a.oFeatures.bDeferRender&&Q(a);for(c=0,d=a.aoColumns.length;c<d;c++)g=l[c].sTitle.replace(/<.*?>/g,
85
+ ""),f=l[c].nTh,f.removeAttribute("aria-sort"),f.removeAttribute("aria-label"),l[c].bSortable?0<o.length&&o[0][0]==c?(f.setAttribute("aria-sort","asc"==o[0][1]?"ascending":"descending"),f.setAttribute("aria-label",g+("asc"==(l[c].asSorting[o[0][2]+1]?l[c].asSorting[o[0][2]+1]:l[c].asSorting[0])?p.sSortAscending:p.sSortDescending))):f.setAttribute("aria-label",g+("asc"==l[c].asSorting[0]?p.sSortAscending:p.sSortDescending)):f.setAttribute("aria-label",g);a.bSorted=!0;h(a.oInstance).trigger("sort",a);
86
+ a.oFeatures.bFilter?M(a,a.oPreviousSearch,1):(a.aiDisplay=a.aiDisplayMaster.slice(),a._iDisplayStart=0,B(a),z(a))}function ga(a,b,c,d){Qa(b,{},function(b){if(!1!==a.aoColumns[c].bSortable){var g=function(){var d,g;if(b.shiftKey){for(var e=!1,h=0;h<a.aaSorting.length;h++)if(a.aaSorting[h][0]==c){e=!0;d=a.aaSorting[h][0];g=a.aaSorting[h][2]+1;a.aoColumns[d].asSorting[g]?(a.aaSorting[h][1]=a.aoColumns[d].asSorting[g],a.aaSorting[h][2]=g):a.aaSorting.splice(h,1);break}!1===e&&a.aaSorting.push([c,a.aoColumns[c].asSorting[0],
87
+ 0])}else 1==a.aaSorting.length&&a.aaSorting[0][0]==c?(d=a.aaSorting[0][0],g=a.aaSorting[0][2]+1,a.aoColumns[d].asSorting[g]||(g=0),a.aaSorting[0][1]=a.aoColumns[d].asSorting[g],a.aaSorting[0][2]=g):(a.aaSorting.splice(0,a.aaSorting.length),a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0]));P(a)};a.oFeatures.bProcessing?(G(a,!0),setTimeout(function(){g();a.oFeatures.bServerSide||G(a,!1)},0)):g();"function"==typeof d&&d(a)}})}function Q(a){var b,c,d,f,g,e=a.aoColumns.length,j=a.oClasses;for(b=0;b<
88
+ e;b++)a.aoColumns[b].bSortable&&h(a.aoColumns[b].nTh).removeClass(j.sSortAsc+" "+j.sSortDesc+" "+a.aoColumns[b].sSortingClass);f=null!==a.aaSortingFixed?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable){g=a.aoColumns[b].sSortingClass;d=-1;for(c=0;c<f.length;c++)if(f[c][0]==b){g="asc"==f[c][1]?j.sSortAsc:j.sSortDesc;d=c;break}h(a.aoColumns[b].nTh).addClass(g);a.bJUI&&(c=h("span."+j.sSortIcon,a.aoColumns[b].nTh),c.removeClass(j.sSortJUIAsc+
89
+ " "+j.sSortJUIDesc+" "+j.sSortJUI+" "+j.sSortJUIAscAllowed+" "+j.sSortJUIDescAllowed),c.addClass(-1==d?a.aoColumns[b].sSortingClassJUI:"asc"==f[d][1]?j.sSortJUIAsc:j.sSortJUIDesc))}else h(a.aoColumns[b].nTh).addClass(a.aoColumns[b].sSortingClass);g=j.sSortColumn;if(a.oFeatures.bSort&&a.oFeatures.bSortClasses){d=L(a);if(a.oFeatures.bDeferRender)h(d).removeClass(g+"1 "+g+"2 "+g+"3");else if(d.length>=e)for(b=0;b<e;b++)if(-1!=d[b].className.indexOf(g+"1"))for(c=0,a=d.length/e;c<a;c++)d[e*c+b].className=
90
+ h.trim(d[e*c+b].className.replace(g+"1",""));else if(-1!=d[b].className.indexOf(g+"2"))for(c=0,a=d.length/e;c<a;c++)d[e*c+b].className=h.trim(d[e*c+b].className.replace(g+"2",""));else if(-1!=d[b].className.indexOf(g+"3"))for(c=0,a=d.length/e;c<a;c++)d[e*c+b].className=h.trim(d[e*c+b].className.replace(" "+g+"3",""));var j=1,o;for(b=0;b<f.length;b++){o=parseInt(f[b][0],10);for(c=0,a=d.length/e;c<a;c++)d[e*c+o].className+=" "+g+j;3>j&&j++}}}function qa(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b,
91
+ c;b=a.oScroll.bInfinite;var d={iCreate:(new Date).getTime(),iStart:b?0:a._iDisplayStart,iEnd:b?a._iDisplayLength:a._iDisplayEnd,iLength:a._iDisplayLength,aaSorting:h.extend(!0,[],a.aaSorting),oSearch:h.extend(!0,{},a.oPreviousSearch),aoSearchCols:h.extend(!0,[],a.aoPreSearchCols),abVisCols:[]};for(b=0,c=a.aoColumns.length;b<c;b++)d.abVisCols.push(a.aoColumns[b].bVisible);D(a,"aoStateSaveParams","stateSaveParams",[a,d]);a.fnStateSave.call(a.oInstance,a,d)}}function Ra(a,b){if(a.oFeatures.bStateSave){var c=
92
+ a.fnStateLoad.call(a.oInstance,a);if(c){var d=D(a,"aoStateLoadParams","stateLoadParams",[a,c]);if(-1===h.inArray(!1,d)){a.oLoadedState=h.extend(!0,{},c);a._iDisplayStart=c.iStart;a.iInitDisplayStart=c.iStart;a._iDisplayEnd=c.iEnd;a._iDisplayLength=c.iLength;a.aaSorting=c.aaSorting.slice();a.saved_aaSorting=c.aaSorting.slice();h.extend(a.oPreviousSearch,c.oSearch);h.extend(!0,a.aoPreSearchCols,c.aoSearchCols);b.saved_aoColumns=[];for(d=0;d<c.abVisCols.length;d++)b.saved_aoColumns[d]={},b.saved_aoColumns[d].bVisible=
93
+ c.abVisCols[d];D(a,"aoStateLoaded","stateLoaded",[a,c])}}}}function Sa(a){for(var b=V.location.pathname.split("/"),a=a+"_"+b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=",b=l.cookie.split(";"),c=0;c<b.length;c++){for(var d=b[c];" "==d.charAt(0);)d=d.substring(1,d.length);if(0===d.indexOf(a))return decodeURIComponent(d.substring(a.length,d.length))}return null}function t(a){for(var b=0;b<j.settings.length;b++)if(j.settings[b].nTable===a)return j.settings[b];return null}function S(a){for(var b=
94
+ [],a=a.aoData,c=0,d=a.length;c<d;c++)null!==a[c].nTr&&b.push(a[c].nTr);return b}function L(a,b){var c=[],d,f,g,e,h,j;f=0;var o=a.aoData.length;b!==m&&(f=b,o=b+1);for(g=f;g<o;g++)if(j=a.aoData[g],null!==j.nTr){f=[];for(e=0,h=j.nTr.childNodes.length;e<h;e++)d=j.nTr.childNodes[e].nodeName.toLowerCase(),("td"==d||"th"==d)&&f.push(j.nTr.childNodes[e]);d=0;for(e=0,h=a.aoColumns.length;e<h;e++)a.aoColumns[e].bVisible?c.push(f[e-d]):(c.push(j._anHidden[e]),d++)}return c}function F(a,b,c){a=null===a?"DataTables warning: "+
95
+ c:"DataTables warning (table id = '"+a.sTableId+"'): "+c;if(0===b)if("alert"==j.ext.sErrMode)alert(a);else throw Error(a);else V.console&&console.log&&console.log(a)}function p(a,b,c,d){d===m&&(d=c);b[c]!==m&&(a[d]=b[c])}function Ta(a,b){for(var c in b)b.hasOwnProperty(c)&&("object"===typeof e[c]&&!1===h.isArray(b[c])?h.extend(!0,a[c],b[c]):a[c]=b[c]);return a}function Qa(a,b,c){h(a).bind("click.DT",b,function(b){a.blur();c(b)}).bind("keypress.DT",b,function(a){13===a.which&&c(a)}).bind("selectstart.DT",
96
+ function(){return!1})}function C(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function D(a,b,c,d){for(var b=a[b],f=[],g=b.length-1;0<=g;g--)f.push(b[g].fn.apply(a.oInstance,d));null!==c&&h(a.oInstance).trigger(c,d);return f}function Ua(a){return function(){var b=[t(this[j.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return j.ext.oApi[a].apply(this,b)}}var Va=V.JSON?JSON.stringify:function(a){var b=typeof a;if("object"!==b||null===a)return"string"===b&&(a='"'+a+'"'),a+"";var c,d,f=[],g=
97
+ h.isArray(a);for(c in a)d=a[c],b=typeof d,"string"===b?d='"'+d+'"':"object"===b&&null!==d&&(d=Va(d)),f.push((g?"":'"'+c+'":')+d);return(g?"[":"{")+f+(g?"]":"}")};this.$=function(a,b){var c,d,f=[],g=t(this[j.ext.iApiIndex]);b||(b={});b=h.extend({},{filter:"none",order:"current",page:"all"},b);if("current"==b.page)for(c=g._iDisplayStart,d=g.fnDisplayEnd();c<d;c++)f.push(g.aoData[g.aiDisplay[c]].nTr);else if("current"==b.order&&"none"==b.filter)for(c=0,d=g.aiDisplayMaster.length;c<d;c++)f.push(g.aoData[g.aiDisplayMaster[c]].nTr);
98
+ else if("current"==b.order&&"applied"==b.filter)for(c=0,d=g.aiDisplay.length;c<d;c++)f.push(g.aoData[g.aiDisplay[c]].nTr);else if("original"==b.order&&"none"==b.filter)for(c=0,d=g.aoData.length;c<d;c++)f.push(g.aoData[c].nTr);else if("original"==b.order&&"applied"==b.filter)for(c=0,d=g.aoData.length;c<d;c++)-1!==h.inArray(c,g.aiDisplay)&&f.push(g.aoData[c].nTr);else F(g,1,"Unknown selection options");d=h(f);c=d.filter(a);d=d.find(a);return h([].concat(h.makeArray(c),h.makeArray(d)))};this._=function(a,
99
+ b){var c=[],d,f,g=this.$(a,b);for(d=0,f=g.length;d<f;d++)c.push(this.fnGetData(g[d]));return c};this.fnAddData=function(a,b){if(0===a.length)return[];var c=[],d,f=t(this[j.ext.iApiIndex]);if("object"===typeof a[0]&&null!==a[0])for(var g=0;g<a.length;g++){d=H(f,a[g]);if(-1==d)return c;c.push(d)}else{d=H(f,a);if(-1==d)return c;c.push(d)}f.aiDisplay=f.aiDisplayMaster.slice();(b===m||b)&&$(f);return c};this.fnAdjustColumnSizing=function(a){var b=t(this[j.ext.iApiIndex]);k(b);a===m||a?this.fnDraw(!1):
100
+ (""!==b.oScroll.sX||""!==b.oScroll.sY)&&this.oApi._fnScrollDraw(b)};this.fnClearTable=function(a){var b=t(this[j.ext.iApiIndex]);ea(b);(a===m||a)&&z(b)};this.fnClose=function(a){for(var b=t(this[j.ext.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a)return(a=b.aoOpenRows[c].nTr.parentNode)&&a.removeChild(b.aoOpenRows[c].nTr),b.aoOpenRows.splice(c,1),0;return 1};this.fnDeleteRow=function(a,b,c){var d=t(this[j.ext.iApiIndex]),f,g,a="object"===typeof a?K(d,a):a,e=d.aoData.splice(a,
101
+ 1);for(f=0,g=d.aoData.length;f<g;f++)if(null!==d.aoData[f].nTr)d.aoData[f].nTr._DT_RowIndex=f;f=h.inArray(a,d.aiDisplay);d.asDataSearch.splice(f,1);fa(d.aiDisplayMaster,a);fa(d.aiDisplay,a);"function"===typeof b&&b.call(this,d,e);if(d._iDisplayStart>=d.aiDisplay.length&&(d._iDisplayStart-=d._iDisplayLength,0>d._iDisplayStart))d._iDisplayStart=0;if(c===m||c)B(d),z(d);return e};this.fnDestroy=function(a){var b=t(this[j.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,f,g,a=a===m?!1:!0;b.bDestroying=
102
+ !0;D(b,"aoDestroyCallback","destroy",[b]);for(f=0,g=b.aoColumns.length;f<g;f++)!1===b.aoColumns[f].bVisible&&this.fnSetColumnVis(f,!0);h(b.nTableWrapper).find("*").andSelf().unbind(".DT");h("tbody>tr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();b.nTable!=b.nTHead.parentNode&&(h(b.nTable).children("thead").remove(),b.nTable.appendChild(b.nTHead));b.nTFoot&&b.nTable!=b.nTFoot.parentNode&&(h(b.nTable).children("tfoot").remove(),b.nTable.appendChild(b.nTFoot));b.nTable.parentNode.removeChild(b.nTable);
103
+ h(b.nTableWrapper).remove();b.aaSorting=[];b.aaSortingFixed=[];Q(b);h(S(b)).removeClass(b.asStripeClasses.join(" "));h("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc,b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));b.bJUI&&(h("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove(),h("th, td",b.nTHead).each(function(){var a=h("div."+b.oClasses.sSortJUIWrapper,this),c=a.contents();h(this).append(c);a.remove()}));!a&&b.nTableReinsertBefore?
104
+ c.insertBefore(b.nTable,b.nTableReinsertBefore):a||c.appendChild(b.nTable);for(f=0,g=b.aoData.length;f<g;f++)null!==b.aoData[f].nTr&&d.appendChild(b.aoData[f].nTr);if(!0===b.oFeatures.bAutoWidth)b.nTable.style.width=q(b.sDestroyWidth);h(d).children("tr:even").addClass(b.asDestroyStripes[0]);h(d).children("tr:odd").addClass(b.asDestroyStripes[1]);for(f=0,g=j.settings.length;f<g;f++)j.settings[f]==b&&j.settings.splice(f,1);b=null};this.fnDraw=function(a){var b=t(this[j.ext.iApiIndex]);!1===a?(B(b),
105
+ z(b)):$(b)};this.fnFilter=function(a,b,c,d,f,g){var e=t(this[j.ext.iApiIndex]);if(e.oFeatures.bFilter){if(c===m||null===c)c=!1;if(d===m||null===d)d=!0;if(f===m||null===f)f=!0;if(g===m||null===g)g=!0;if(b===m||null===b){if(M(e,{sSearch:a+"",bRegex:c,bSmart:d,bCaseInsensitive:g},1),f&&e.aanFeatures.f){b=e.aanFeatures.f;c=0;for(d=b.length;c<d;c++)h(b[c]._DT_Input).val(a)}}else h.extend(e.aoPreSearchCols[b],{sSearch:a+"",bRegex:c,bSmart:d,bCaseInsensitive:g}),M(e,e.oPreviousSearch,1)}};this.fnGetData=
106
+ function(a,b){var c=t(this[j.ext.iApiIndex]);if(a!==m){var d=a;if("object"===typeof a){var f=a.nodeName.toLowerCase();"tr"===f?d=K(c,a):"td"===f&&(d=K(c,a.parentNode),b=da(c,d,a))}return b!==m?w(c,d,b,""):c.aoData[d]!==m?c.aoData[d]._aData:null}return Y(c)};this.fnGetNodes=function(a){var b=t(this[j.ext.iApiIndex]);return a!==m?b.aoData[a]!==m?b.aoData[a].nTr:null:S(b)};this.fnGetPosition=function(a){var b=t(this[j.ext.iApiIndex]),c=a.nodeName.toUpperCase();if("TR"==c)return K(b,a);return"TD"==c||
107
+ "TH"==c?(c=K(b,a.parentNode),a=da(b,c,a),[c,r(b,a),a]):null};this.fnIsOpen=function(a){for(var b=t(this[j.ext.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a)return!0;return!1};this.fnOpen=function(a,b,c){var d=t(this[j.ext.iApiIndex]),f=S(d);if(-1!==h.inArray(a,f)){this.fnClose(a);var f=l.createElement("tr"),g=l.createElement("td");f.appendChild(g);g.className=c;g.colSpan=v(d);"string"===typeof b?g.innerHTML=b:h(g).html(b);b=h("tr",d.nTBody);-1!=h.inArray(a,b)&&h(f).insertAfter(a);
108
+ d.aoOpenRows.push({nTr:f,nParent:a});return f}};this.fnPageChange=function(a,b){var c=t(this[j.ext.iApiIndex]);pa(c,a);B(c);(b===m||b)&&z(c)};this.fnSetColumnVis=function(a,b,c){var d=t(this[j.ext.iApiIndex]),f,g,e=d.aoColumns,h=d.aoData,o,n;if(e[a].bVisible!=b){if(b){for(f=g=0;f<a;f++)e[f].bVisible&&g++;n=g>=v(d);if(!n)for(f=a;f<e.length;f++)if(e[f].bVisible){o=f;break}for(f=0,g=h.length;f<g;f++)null!==h[f].nTr&&(n?h[f].nTr.appendChild(h[f]._anHidden[a]):h[f].nTr.insertBefore(h[f]._anHidden[a],L(d,
109
+ f)[o]))}else for(f=0,g=h.length;f<g;f++)null!==h[f].nTr&&(o=L(d,f)[a],h[f]._anHidden[a]=o,o.parentNode.removeChild(o));e[a].bVisible=b;U(d,d.aoHeader);d.nTFoot&&U(d,d.aoFooter);for(f=0,g=d.aoOpenRows.length;f<g;f++)d.aoOpenRows[f].nTr.colSpan=v(d);if(c===m||c)k(d),z(d);qa(d)}};this.fnSettings=function(){return t(this[j.ext.iApiIndex])};this.fnSort=function(a){var b=t(this[j.ext.iApiIndex]);b.aaSorting=a;P(b)};this.fnSortListener=function(a,b,c){ga(t(this[j.ext.iApiIndex]),a,b,c)};this.fnUpdate=function(a,
110
+ b,c,d,f){var e=t(this[j.ext.iApiIndex]),b="object"===typeof b?K(e,b):b;if(e.__fnUpdateDeep===m&&h.isArray(a)&&"object"===typeof a){e.aoData[b]._aData=a.slice();e.__fnUpdateDeep=!0;for(c=0;c<e.aoColumns.length;c++)this.fnUpdate(w(e,b,c),b,c,!1,!1);e.__fnUpdateDeep=m}else if(e.__fnUpdateDeep===m&&null!==a&&"object"===typeof a){e.aoData[b]._aData=h.extend(!0,{},a);e.__fnUpdateDeep=!0;for(c=0;c<e.aoColumns.length;c++)this.fnUpdate(w(e,b,c),b,c,!1,!1);e.__fnUpdateDeep=m}else{I(e,b,c,a);var a=w(e,b,c,"display"),
111
+ i=e.aoColumns[c];null!==i.fnRender&&(a=R(e,b,c),i.bUseRendered&&I(e,b,c,a));if(null!==e.aoData[b].nTr)L(e,b)[c].innerHTML=a}c=h.inArray(b,e.aiDisplay);e.asDataSearch[c]=ma(e,X(e,b,"filter"));(f===m||f)&&k(e);(d===m||d)&&$(e);return 0};this.fnVersionCheck=j.ext.fnVersionCheck;this.oApi={_fnExternApiFunc:Ua,_fnInitialise:aa,_fnInitComplete:Z,_fnLanguageCompat:oa,_fnAddColumn:o,_fnColumnOptions:s,_fnAddData:H,_fnCreateTr:ca,_fnGatherData:ua,_fnBuildHead:va,_fnDrawHead:U,_fnDraw:z,_fnReDraw:$,_fnAjaxUpdate:wa,
112
+ _fnAjaxParameters:Ea,_fnAjaxUpdateDraw:Fa,_fnServerParams:ia,_fnAddOptionsHtml:xa,_fnFeatureHtmlTable:Ba,_fnScrollDraw:Ka,_fnAdjustColumnSizing:k,_fnFeatureHtmlFilter:za,_fnFilterComplete:M,_fnFilterCustom:Ia,_fnFilterColumn:Ha,_fnFilter:Ga,_fnBuildSearchArray:ja,_fnBuildSearchRow:ma,_fnFilterCreateSearch:ka,_fnDataToSearch:la,_fnSort:P,_fnSortAttachListener:ga,_fnSortingClasses:Q,_fnFeatureHtmlPaginate:Da,_fnPageChange:pa,_fnFeatureHtmlInfo:Ca,_fnUpdateInfo:Ja,_fnFeatureHtmlLength:ya,_fnFeatureHtmlProcessing:Aa,
113
+ _fnProcessingDisplay:G,_fnVisibleToColumnIndex:x,_fnColumnIndexToVisible:r,_fnNodeToDataIndex:K,_fnVisbleColumns:v,_fnCalculateEnd:B,_fnConvertToWidth:La,_fnCalculateColumnWidths:ba,_fnScrollingWidthAdjust:Na,_fnGetWidestNode:Ma,_fnGetMaxLenString:Oa,_fnStringToCss:q,_fnDetectType:A,_fnSettingsFromNode:t,_fnGetDataMaster:Y,_fnGetTrNodes:S,_fnGetTdNodes:L,_fnEscapeRegex:na,_fnDeleteIndex:fa,_fnReOrderIndex:E,_fnColumnOrdering:y,_fnLog:F,_fnClearTable:ea,_fnSaveState:qa,_fnLoadState:Ra,_fnCreateCookie:function(a,
114
+ b,c,d,e){var g=new Date;g.setTime(g.getTime()+1E3*c);var c=V.location.pathname.split("/"),a=a+"_"+c.pop().replace(/[\/:]/g,"").toLowerCase(),i;null!==e?(i="function"===typeof h.parseJSON?h.parseJSON(b):eval("("+b+")"),b=e(a,i,g.toGMTString(),c.join("/")+"/")):b=a+"="+encodeURIComponent(b)+"; expires="+g.toGMTString()+"; path="+c.join("/")+"/";e="";g=9999999999999;if(4096<(null!==Sa(a)?l.cookie.length:b.length+l.cookie.length)+10){for(var a=l.cookie.split(";"),j=0,o=a.length;j<o;j++)if(-1!=a[j].indexOf(d)){var k=
115
+ a[j].split("=");try{i=eval("("+decodeURIComponent(k[1])+")")}catch(m){continue}if(i.iCreate&&i.iCreate<g)e=k[0],g=i.iCreate}if(""!==e)l.cookie=e+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+c.join("/")+"/"}l.cookie=b},_fnReadCookie:Sa,_fnDetectHeader:T,_fnGetUniqueThs:O,_fnScrollBarWidth:Pa,_fnApplyToChildren:N,_fnMap:p,_fnGetRowData:X,_fnGetCellData:w,_fnSetCellData:I,_fnGetObjectDataFn:W,_fnSetObjectDataFn:ta,_fnApplyColumnDefs:J,_fnBindAction:Qa,_fnExtend:Ta,_fnCallbackReg:C,_fnCallbackFire:D,
116
+ _fnJsonString:Va,_fnRender:R,_fnNodeToColumnIndex:da,_fnInfoMacros:ha};h.extend(j.ext.oApi,this.oApi);for(var ra in j.ext.oApi)ra&&(this[ra]=Ua(ra));var sa=this;return this.each(function(){var a=0,b,c,d;c=this.getAttribute("id");var f=!1,g=!1;if("table"!=this.nodeName.toLowerCase())F(null,0,"Attempted to initialise DataTables on a node which is not a table: "+this.nodeName);else{for(a=0,b=j.settings.length;a<b;a++){if(j.settings[a].nTable==this){if(e===m||e.bRetrieve)return j.settings[a].oInstance;
117
+ if(e.bDestroy){j.settings[a].oInstance.fnDestroy();break}else{F(j.settings[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, pass no arguments or see the docs for bRetrieve and bDestroy");return}}if(j.settings[a].sTableId==this.id){j.settings.splice(a,1);break}}if(null===c||""===c)this.id=c="DataTables_Table_"+j.ext._oExternConfig.iNextUnique++;var i=h.extend(!0,{},j.models.oSettings,{nTable:this,oApi:sa.oApi,oInit:e,sDestroyWidth:h(this).width(),sInstance:c,
118
+ sTableId:c});j.settings.push(i);i.oInstance=1===sa.length?sa:h(this).dataTable();e||(e={});e.oLanguage&&oa(e.oLanguage);e=Ta(h.extend(!0,{},j.defaults),e);p(i.oFeatures,e,"bPaginate");p(i.oFeatures,e,"bLengthChange");p(i.oFeatures,e,"bFilter");p(i.oFeatures,e,"bSort");p(i.oFeatures,e,"bInfo");p(i.oFeatures,e,"bProcessing");p(i.oFeatures,e,"bAutoWidth");p(i.oFeatures,e,"bSortClasses");p(i.oFeatures,e,"bServerSide");p(i.oFeatures,e,"bDeferRender");p(i.oScroll,e,"sScrollX","sX");p(i.oScroll,e,"sScrollXInner",
119
+ "sXInner");p(i.oScroll,e,"sScrollY","sY");p(i.oScroll,e,"bScrollCollapse","bCollapse");p(i.oScroll,e,"bScrollInfinite","bInfinite");p(i.oScroll,e,"iScrollLoadGap","iLoadGap");p(i.oScroll,e,"bScrollAutoCss","bAutoCss");p(i,e,"asStripeClasses");p(i,e,"asStripClasses","asStripeClasses");p(i,e,"fnServerData");p(i,e,"fnFormatNumber");p(i,e,"sServerMethod");p(i,e,"aaSorting");p(i,e,"aaSortingFixed");p(i,e,"aLengthMenu");p(i,e,"sPaginationType");p(i,e,"sAjaxSource");p(i,e,"sAjaxDataProp");p(i,e,"iCookieDuration");
120
+ p(i,e,"sCookiePrefix");p(i,e,"sDom");p(i,e,"bSortCellsTop");p(i,e,"iTabIndex");p(i,e,"oSearch","oPreviousSearch");p(i,e,"aoSearchCols","aoPreSearchCols");p(i,e,"iDisplayLength","_iDisplayLength");p(i,e,"bJQueryUI","bJUI");p(i,e,"fnCookieCallback");p(i,e,"fnStateLoad");p(i,e,"fnStateSave");p(i.oLanguage,e,"fnInfoCallback");C(i,"aoDrawCallback",e.fnDrawCallback,"user");C(i,"aoServerParams",e.fnServerParams,"user");C(i,"aoStateSaveParams",e.fnStateSaveParams,"user");C(i,"aoStateLoadParams",e.fnStateLoadParams,
121
+ "user");C(i,"aoStateLoaded",e.fnStateLoaded,"user");C(i,"aoRowCallback",e.fnRowCallback,"user");C(i,"aoRowCreatedCallback",e.fnCreatedRow,"user");C(i,"aoHeaderCallback",e.fnHeaderCallback,"user");C(i,"aoFooterCallback",e.fnFooterCallback,"user");C(i,"aoInitComplete",e.fnInitComplete,"user");C(i,"aoPreDrawCallback",e.fnPreDrawCallback,"user");i.oFeatures.bServerSide&&i.oFeatures.bSort&&i.oFeatures.bSortClasses?C(i,"aoDrawCallback",Q,"server_side_sort_classes"):i.oFeatures.bDeferRender&&C(i,"aoDrawCallback",
122
+ Q,"defer_sort_classes");if(e.bJQueryUI){if(h.extend(i.oClasses,j.ext.oJUIClasses),e.sDom===j.defaults.sDom&&"lfrtip"===j.defaults.sDom)i.sDom='<"H"lfr>t<"F"ip>'}else h.extend(i.oClasses,j.ext.oStdClasses);h(this).addClass(i.oClasses.sTable);if(""!==i.oScroll.sX||""!==i.oScroll.sY)i.oScroll.iBarWidth=Pa();if(i.iInitDisplayStart===m)i.iInitDisplayStart=e.iDisplayStart,i._iDisplayStart=e.iDisplayStart;if(e.bStateSave)i.oFeatures.bStateSave=!0,Ra(i,e),C(i,"aoDrawCallback",qa,"state_save");if(null!==e.iDeferLoading)i.bDeferLoading=
123
+ !0,a=h.isArray(e.iDeferLoading),i._iRecordsDisplay=a?e.iDeferLoading[0]:e.iDeferLoading,i._iRecordsTotal=a?e.iDeferLoading[1]:e.iDeferLoading;null!==e.aaData&&(g=!0);""!==e.oLanguage.sUrl?(i.oLanguage.sUrl=e.oLanguage.sUrl,h.getJSON(i.oLanguage.sUrl,null,function(a){oa(a);h.extend(!0,i.oLanguage,e.oLanguage,a);aa(i)}),f=!0):h.extend(!0,i.oLanguage,e.oLanguage);if(null===e.asStripeClasses)i.asStripeClasses=[i.oClasses.sStripeOdd,i.oClasses.sStripeEven];c=!1;d=h(this).children("tbody").children("tr");
124
+ for(a=0,b=i.asStripeClasses.length;a<b;a++)if(d.filter(":lt(2)").hasClass(i.asStripeClasses[a])){c=!0;break}if(c)i.asDestroyStripes=["",""],h(d[0]).hasClass(i.oClasses.sStripeOdd)&&(i.asDestroyStripes[0]+=i.oClasses.sStripeOdd+" "),h(d[0]).hasClass(i.oClasses.sStripeEven)&&(i.asDestroyStripes[0]+=i.oClasses.sStripeEven),h(d[1]).hasClass(i.oClasses.sStripeOdd)&&(i.asDestroyStripes[1]+=i.oClasses.sStripeOdd+" "),h(d[1]).hasClass(i.oClasses.sStripeEven)&&(i.asDestroyStripes[1]+=i.oClasses.sStripeEven),
125
+ d.removeClass(i.asStripeClasses.join(" "));c=[];a=this.getElementsByTagName("thead");0!==a.length&&(T(i.aoHeader,a[0]),c=O(i));if(null===e.aoColumns){d=[];for(a=0,b=c.length;a<b;a++)d.push(null)}else d=e.aoColumns;for(a=0,b=d.length;a<b;a++){if(e.saved_aoColumns!==m&&e.saved_aoColumns.length==b)null===d[a]&&(d[a]={}),d[a].bVisible=e.saved_aoColumns[a].bVisible;o(i,c?c[a]:null)}J(i,e.aoColumnDefs,d,function(a,b){s(i,a,b)});for(a=0,b=i.aaSorting.length;a<b;a++){i.aaSorting[a][0]>=i.aoColumns.length&&
126
+ (i.aaSorting[a][0]=0);var k=i.aoColumns[i.aaSorting[a][0]];i.aaSorting[a][2]===m&&(i.aaSorting[a][2]=0);e.aaSorting===m&&i.saved_aaSorting===m&&(i.aaSorting[a][1]=k.asSorting[0]);for(c=0,d=k.asSorting.length;c<d;c++)if(i.aaSorting[a][1]==k.asSorting[c]){i.aaSorting[a][2]=c;break}}Q(i);a=h(this).children("caption").each(function(){this._captionSide=h(this).css("caption-side")});b=h(this).children("thead");0===b.length&&(b=[l.createElement("thead")],this.appendChild(b[0]));i.nTHead=b[0];b=h(this).children("tbody");
127
+ 0===b.length&&(b=[l.createElement("tbody")],this.appendChild(b[0]));i.nTBody=b[0];i.nTBody.setAttribute("role","alert");i.nTBody.setAttribute("aria-live","polite");i.nTBody.setAttribute("aria-relevant","all");b=h(this).children("tfoot");if(0===b.length&&0<a.length&&(""!==i.oScroll.sX||""!==i.oScroll.sY))b=[l.createElement("tfoot")],this.appendChild(b[0]);if(0<b.length)i.nTFoot=b[0],T(i.aoFooter,i.nTFoot);if(g)for(a=0;a<e.aaData.length;a++)H(i,e.aaData[a]);else ua(i);i.aiDisplay=i.aiDisplayMaster.slice();
128
+ i.bInitialised=!0;!1===f&&aa(i)}})};j.fnVersionCheck=function(e){for(var h=function(e,h){for(;e.length<h;)e+="0";return e},m=j.ext.sVersion.split("."),e=e.split("."),k="",l="",r=0,v=e.length;r<v;r++)k+=h(m[r],3),l+=h(e[r],3);return parseInt(k,10)>=parseInt(l,10)};j.fnIsDataTable=function(e){for(var h=j.settings,m=0;m<h.length;m++)if(h[m].nTable===e||h[m].nScrollHead===e||h[m].nScrollFoot===e)return!0;return!1};j.fnTables=function(e){var o=[];jQuery.each(j.settings,function(j,k){(!e||!0===e&&h(k.nTable).is(":visible"))&&
129
+ o.push(k.nTable)});return o};j.version="1.9.1";j.settings=[];j.models={};j.models.ext={afnFiltering:[],afnSortData:[],aoFeatures:[],aTypes:[],fnVersionCheck:j.fnVersionCheck,iApiIndex:0,ofnSearch:{},oApi:{},oStdClasses:{},oJUIClasses:{},oPagination:{},oSort:{},sVersion:j.version,sErrMode:"alert",_oExternConfig:{iNextUnique:0}};j.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};j.models.oRow={nTr:null,_aData:[],_aSortData:[],_anHidden:[],_sRowStripe:""};j.models.oColumn={aDataSort:null,
130
+ asSorting:null,bSearchable:null,bSortable:null,bUseRendered:null,bVisible:null,_bAutoType:!0,fnCreatedCell:null,fnGetData:null,fnRender:null,fnSetData:null,mDataProp: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};j.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],
131
+ asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollAutoCss:!0,bScrollCollapse:!1,bScrollInfinite:!1,bServerSide:!1,bSort:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCookieCallback:null,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(e){if(1E3>e)return e;for(var h=e+"",e=h.split(""),j="",h=h.length,k=0;k<h;k++)0===k%3&&0!==k&&(j=this.oLanguage.sInfoThousands+
132
+ j),j=e[h-k-1]+j;return j},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:function(e,j,m,k){k.jqXHR=h.ajax({url:e,data:j,success:function(e){h(k.oInstance).trigger("xhr",k);m(e)},dataType:"json",cache:!1,type:k.sServerMethod,error:function(e,h){"parsererror"==h&&k.oApi._fnLog(k,0,"DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})},fnServerParams:null,fnStateLoad:function(e){var e=
133
+ this.oApi._fnReadCookie(e.sCookiePrefix+e.sInstance),j;try{j="function"===typeof h.parseJSON?h.parseJSON(e):eval("("+e+")")}catch(m){j=null}return j},fnStateLoadParams:null,fnStateLoaded:null,fnStateSave:function(e,h){this.oApi._fnCreateCookie(e.sCookiePrefix+e.sInstance,this.oApi._fnJsonString(h),e.iCookieDuration,e.sCookiePrefix,e.fnCookieCallback)},fnStateSaveParams:null,iCookieDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iScrollLoadGap:100,iTabIndex:0,oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",
134
+ 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:"",sInfoThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sUrl:"",sZeroRecords:"No matching records found"},
135
+ oSearch:h.extend({},j.models.oSearch),sAjaxDataProp:"aaData",sAjaxSource:null,sCookiePrefix:"SpryMedia_DataTables_",sDom:"lfrtip",sPaginationType:"two_button",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET"};j.defaults.columns={aDataSort:null,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bUseRendered:!0,bVisible:!0,fnCreatedCell:null,fnRender:null,iDataSort:-1,mDataProp:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,
136
+ sType:null,sWidth:null};j.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortClasses:null,bStateSave:null},oScroll:{bAutoCss:null,bCollapse:null,bInfinite:null,iBarWidth:0,iLoadGap:null,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aoColumns:[],aoHeader:[],aoFooter:[],asDataSearch:[],oPreviousSearch:{},aoPreSearchCols:[],
137
+ aaSorting:null,aaSortingFixed:null,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,sPaginationType:"two_button",iCookieDuration:0,sCookiePrefix:"",fnCookieCallback:null,
138
+ aoStateSave:[],aoStateLoad:[],oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iDisplayEnd:10,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,
139
+ 10):this.aiDisplayMaster.length},fnRecordsDisplay:function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length},fnDisplayEnd:function(){return this.oFeatures.bServerSide?!1===this.oFeatures.bPaginate||-1==this._iDisplayLength?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null};j.ext=h.extend(!0,{},j.models.ext);
140
+ h.extend(j.ext.oStdClasses,{sTable:"dataTable",sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",sPageButtonStaticDisabled:"paginate_button paginate_button_disabled",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripeOdd:"odd",sStripeEven:"even",
141
+ 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_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",
142
+ sSortIcon:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""});h.extend(j.ext.oJUIClasses,j.ext.oStdClasses,{sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",
143
+ sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl",sPageLast:"last ui-corner-tr ui-corner-br",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",
144
+ sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default",sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",
145
+ sScrollHead:"dataTables_scrollHead ui-state-default",sScrollFoot:"dataTables_scrollFoot ui-state-default",sFooterTH:"ui-state-default"});h.extend(j.ext.oPagination,{two_button:{fnInit:function(e,j,m){var k=e.oLanguage.oPaginate,l=function(h){e.oApi._fnPageChange(e,h.data.action)&&m(e)},k=!e.bJUI?'<a class="'+e.oClasses.sPagePrevDisabled+'" tabindex="'+e.iTabIndex+'" role="button">'+k.sPrevious+'</a><a class="'+e.oClasses.sPageNextDisabled+'" tabindex="'+e.iTabIndex+'" role="button">'+k.sNext+"</a>":
146
+ '<a class="'+e.oClasses.sPagePrevDisabled+'" tabindex="'+e.iTabIndex+'" role="button"><span class="'+e.oClasses.sPageJUIPrev+'"></span></a><a class="'+e.oClasses.sPageNextDisabled+'" tabindex="'+e.iTabIndex+'" role="button"><span class="'+e.oClasses.sPageJUINext+'"></span></a>';h(j).append(k);var r=h("a",j),k=r[0],r=r[1];e.oApi._fnBindAction(k,{action:"previous"},l);e.oApi._fnBindAction(r,{action:"next"},l);if(!e.aanFeatures.p)j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_previous",r.id=e.sTableId+
147
+ "_next",k.setAttribute("aria-controls",e.sTableId),r.setAttribute("aria-controls",e.sTableId)},fnUpdate:function(e){if(e.aanFeatures.p)for(var h=e.oClasses,j=e.aanFeatures.p,k=0,m=j.length;k<m;k++)if(0!==j[k].childNodes.length)j[k].childNodes[0].className=0===e._iDisplayStart?h.sPagePrevDisabled:h.sPagePrevEnabled,j[k].childNodes[1].className=e.fnDisplayEnd()==e.fnRecordsDisplay()?h.sPageNextDisabled:h.sPageNextEnabled}},iFullNumbersShowPages:5,full_numbers:{fnInit:function(e,j,m){var k=e.oLanguage.oPaginate,
148
+ l=e.oClasses,r=function(h){e.oApi._fnPageChange(e,h.data.action)&&m(e)};h(j).append('<a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPageFirst+'">'+k.sFirst+'</a><a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPagePrevious+'">'+k.sPrevious+'</a><span></span><a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPageNext+'">'+k.sNext+'</a><a tabindex="'+e.iTabIndex+'" class="'+l.sPageButton+" "+l.sPageLast+'">'+k.sLast+"</a>");var v=h("a",j),k=v[0],l=v[1],A=v[2],v=v[3];
149
+ e.oApi._fnBindAction(k,{action:"first"},r);e.oApi._fnBindAction(l,{action:"previous"},r);e.oApi._fnBindAction(A,{action:"next"},r);e.oApi._fnBindAction(v,{action:"last"},r);if(!e.aanFeatures.p)j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_first",l.id=e.sTableId+"_previous",A.id=e.sTableId+"_next",v.id=e.sTableId+"_last"},fnUpdate:function(e,m){if(e.aanFeatures.p){var l=j.ext.oPagination.iFullNumbersShowPages,k=Math.floor(l/2),x=Math.ceil(e.fnRecordsDisplay()/e._iDisplayLength),r=Math.ceil(e._iDisplayStart/
150
+ e._iDisplayLength)+1,v="",A,E=e.oClasses,y,J=e.aanFeatures.p,H=function(h){e.oApi._fnBindAction(this,{page:h+A-1},function(h){e.oApi._fnPageChange(e,h.data.page);m(e);h.preventDefault()})};-1===e._iDisplayLength?r=k=A=1:x<l?(A=1,k=x):r<=k?(A=1,k=l):r>=x-k?(A=x-l+1,k=x):(A=r-Math.ceil(l/2)+1,k=A+l-1);for(l=A;l<=k;l++)v+=r!==l?'<a tabindex="'+e.iTabIndex+'" class="'+E.sPageButton+'">'+e.fnFormatNumber(l)+"</a>":'<a tabindex="'+e.iTabIndex+'" class="'+E.sPageButtonActive+'">'+e.fnFormatNumber(l)+"</a>";
151
+ for(l=0,k=J.length;l<k;l++)0!==J[l].childNodes.length&&(h("span:eq(0)",J[l]).html(v).children("a").each(H),y=J[l].getElementsByTagName("a"),y=[y[0],y[1],y[y.length-2],y[y.length-1]],h(y).removeClass(E.sPageButton+" "+E.sPageButtonActive+" "+E.sPageButtonStaticDisabled),h([y[0],y[1]]).addClass(1==r?E.sPageButtonStaticDisabled:E.sPageButton),h([y[2],y[3]]).addClass(0===x||r===x||-1===e._iDisplayLength?E.sPageButtonStaticDisabled:E.sPageButton))}}}});h.extend(j.ext.oSort,{"string-pre":function(e){"string"!=
152
+ typeof e&&(e=null!==e&&e.toString?e.toString():"");return e.toLowerCase()},"string-asc":function(e,h){return e<h?-1:e>h?1:0},"string-desc":function(e,h){return e<h?1:e>h?-1:0},"html-pre":function(e){return e.replace(/<.*?>/g,"").toLowerCase()},"html-asc":function(e,h){return e<h?-1:e>h?1:0},"html-desc":function(e,h){return e<h?1:e>h?-1:0},"date-pre":function(e){e=Date.parse(e);if(isNaN(e)||""===e)e=Date.parse("01/01/1970 00:00:00");return e},"date-asc":function(e,h){return e-h},"date-desc":function(e,
153
+ h){return h-e},"numeric-pre":function(e){return"-"==e||""===e?0:1*e},"numeric-asc":function(e,h){return e-h},"numeric-desc":function(e,h){return h-e}});h.extend(j.ext.aTypes,[function(e){if("number"===typeof e)return"numeric";if("string"!==typeof e)return null;var h,j=!1;h=e.charAt(0);if(-1=="0123456789-".indexOf(h))return null;for(var k=1;k<e.length;k++){h=e.charAt(k);if(-1=="0123456789.".indexOf(h))return null;if("."==h){if(j)return null;j=!0}}return"numeric"},function(e){var h=Date.parse(e);return null!==
154
+ h&&!isNaN(h)||"string"===typeof e&&0===e.length?"date":null},function(e){return"string"===typeof e&&-1!=e.indexOf("<")&&-1!=e.indexOf(">")?"html":null}]);h.fn.DataTable=j;h.fn.dataTable=j;h.fn.dataTableSettings=j.settings;h.fn.dataTableExt=j.ext})(jQuery,window,document,void 0);
process.php CHANGED
@@ -1,4 +1,6 @@
1
  <?php
 
 
2
  global $wpdb;
3
  if(!file_exists(dirname(__FILE__).'/cache/'))
4
  die("<code>".dirname(__FILE__).'/cache/</code> is missing!' );
@@ -7,21 +9,37 @@ global $wpdb;
7
  die("<code>".dirname(__FILE__).'/cache/</code> must have to be writable!' );
8
  $did = explode('.',base64_decode($_GET['did']));
9
  $id = array_shift($did);
10
- if(!is_numeric($id)){
 
11
  $data = @unserialize(file_get_contents(dirname(__FILE__).'/cache/'.$_GET['did']));
 
12
 
13
  }
14
  else {
15
 
16
-
17
  $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
18
  }
19
 
20
- if(is_array($data)){
21
-
 
 
 
 
22
  @unlink(dirname(__FILE__).'/cache/'.$_GET['did']);
 
 
 
23
 
24
- //d$data = DMDB::getById('ahm_files',$_GET['download']);
 
 
 
 
 
 
 
25
  if(file_exists($data['file']))
26
  $fname = $data['file'];
27
  else if(file_exists(UPLOAD_DIR . $data['file']))
@@ -30,7 +48,7 @@ if(is_array($data)){
30
  die('File not found!');
31
 
32
  $wpdb->query("update ahm_files set download_count=download_count+1 where id='$data[id]'");
33
-
34
  $mime_types = array("323" => "text/h323",
35
  "acx" => "application/internet-property-stream",
36
  "ai" => "application/postscript",
@@ -217,9 +235,13 @@ if(is_array($data)){
217
  "xwd" => "image/x-xwindowdump",
218
  "z" => "application/x-compress",
219
  "zip" => "application/zip");
220
-
221
- $mtype = $mime_types[strtolower(end(explode('.',$fname)))];
222
 
 
 
 
 
223
  $asfname = basename($fname);
224
 
225
  $fsize = filesize($fname);
@@ -231,14 +253,19 @@ if(is_array($data)){
231
  header("Content-Length: " . $fsize);
232
 
233
 
234
-
 
235
  $file = @fopen($fname,"rb");
236
-
237
  if ($file) {
238
 
239
 
240
  while (!feof($file)) {
241
- echo fread($file, 8192);
 
 
 
 
242
  }
243
  fclose($file);
244
 
@@ -258,7 +285,7 @@ if(is_array($data)){
258
  }
259
 
260
  } else {
261
- die('File not found');
262
  }
263
 
264
  die();
1
  <?php
2
+ if(!defined('ABSPATH')) die('Error!');
3
+
4
  global $wpdb;
5
  if(!file_exists(dirname(__FILE__).'/cache/'))
6
  die("<code>".dirname(__FILE__).'/cache/</code> is missing!' );
9
  die("<code>".dirname(__FILE__).'/cache/</code> must have to be writable!' );
10
  $did = explode('.',base64_decode($_GET['did']));
11
  $id = array_shift($did);
12
+ if(!is_numeric($id)){
13
+ $_GET['did'] = esc_attr($_GET['did']);
14
  $data = @unserialize(file_get_contents(dirname(__FILE__).'/cache/'.$_GET['did']));
15
+
16
 
17
  }
18
  else {
19
 
20
+ $id = (int)$id;
21
  $data = $wpdb->get_row("select * from ahm_files where id='$id'",ARRAY_A);
22
  }
23
 
24
+ if(is_array($data)){
25
+ if($data['access']=='member'&&!is_user_logged_in()) {
26
+ header("location: wp-login.php?redirect_to=".urlencode($_SERVER['REQUEST_URI']));
27
+ die();
28
+ }
29
+ $_GET['did'] = sanitize_file_name($_GET['did']);
30
  @unlink(dirname(__FILE__).'/cache/'.$_GET['did']);
31
+
32
+
33
+ if($data['download_count']>=$data['quota']&&$data['quota']>0) die('Download Limit Excedded!');
34
 
35
+ //added for download monitor import feature
36
+ $data['file'] = str_replace(site_url('/'),ABSPATH, $data['file']);
37
+
38
+ if(strpos($data['file'],'ttp://')){
39
+ header("location: ".$data['file']);
40
+ die();
41
+ }
42
+ $data['file'] = trim($data['file']);
43
  if(file_exists($data['file']))
44
  $fname = $data['file'];
45
  else if(file_exists(UPLOAD_DIR . $data['file']))
48
  die('File not found!');
49
 
50
  $wpdb->query("update ahm_files set download_count=download_count+1 where id='$data[id]'");
51
+ /*
52
  $mime_types = array("323" => "text/h323",
53
  "acx" => "application/internet-property-stream",
54
  "ai" => "application/postscript",
235
  "xwd" => "image/x-xwindowdump",
236
  "z" => "application/x-compress",
237
  "zip" => "application/zip");
238
+ *
239
+ */
240
 
241
+ $filetype = wp_check_filetype($fname);
242
+
243
+ $mtype = $filetype['type'];
244
+
245
  $asfname = basename($fname);
246
 
247
  $fsize = filesize($fname);
253
  header("Content-Length: " . $fsize);
254
 
255
 
256
+ $wpdm_tsize = 0;
257
+ $wpdm_chunk = 8192;
258
  $file = @fopen($fname,"rb");
259
+ $wpdm_rest = $fsize;
260
  if ($file) {
261
 
262
 
263
  while (!feof($file)) {
264
+ if($wpdm_rest<$wpdm_chunk&&$wpdm_rest>0) $wpdm_chunk = $wpdm_rest;
265
+ echo fread($file, $wpdm_chunk);
266
+ if(function_exists('ob_flush')) @ob_flush();
267
+ $wpdm_tsize += $wpdm_chunk;
268
+ $wpdm_rest = $fsize - $wpdm_tsize;
269
  }
270
  fclose($file);
271
 
285
  }
286
 
287
  } else {
288
+ die('File not found or Downlaoad Link Expired!');
289
  }
290
 
291
  die();
readme.txt CHANGED
@@ -1,32 +1,35 @@
1
  === WordPress Download Manager ===
2
- Contributors: Shaon
3
  Donate link:
4
- Tags: files, downloads, downloadables, download manager, file manager, download monitor, download counter, password protection, downlad tracker, download protection
5
- Requires at least: 2.0.2
6
- Tested up to: 3.3.2
7
  License: GPLv2 or later
8
 
9
 
10
 
11
- WordPress Download Manager plugin will help you to manage, track and control file downloads from your wordpress site.
12
 
13
 
14
  == Description ==
15
-
16
- WordPress Download Manager plugin will help you to manage, track and control file downloads from your wordpress site. You can set password and set access level any of your downloadable files from your wordpress site.
17
  You can add/embed downloadable files anywhere in the post just pasting the embed code inside your post content using WordPress Download Manager.
18
 
19
- `v2.3.x ! Yes, its totally redesigned to give you better experience`
20
 
21
  = Features =
 
22
  * Control who can access to download
23
  * Password protection
24
  * Download Counter
25
  * Control who can user this plugin (author, editor, administrator)
26
  * Custom download link icon
 
 
 
27
  * Custom link label
28
- * Shortcode for download link
29
- * Shortcode for direct link to downloadable file [wpdm_hotlink id=file_id_required link_label=any_text_optional]
30
  * New templates for file links
31
  * WP Thickbox popup for download page
32
  * Tinymce button for short-code embed
@@ -39,11 +42,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
39
  * "Download Monitor" to "Download Manager" files Importer
40
 
41
 
42
-
43
- = My other plugins =
44
- `http://wordpress.org/extend/plugins/profile/codename065`
45
-
46
-
47
  == Installation ==
48
 
49
 
@@ -56,11 +55,138 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
56
  1. Create new download package
57
  2. Manage download packages
58
  3. Categories
59
- 4. Frton-end link template preview
60
  5. Full tree view of categories and files with a simple short-code [wpdm_tree]
 
 
 
61
 
62
  == Changelog ==
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  = 2.3.0 =
65
  * Fixed category pagination issue
66
  * Fixed category count issue
@@ -82,7 +208,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
82
  * Adjusted enqueue script issue
83
 
84
  = 2.2.5 =
85
- * Fixed compatibility issue with wordpress 3.4
86
 
87
  = 2.2.4 =
88
  * Fixed empty category name issue
@@ -93,7 +219,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
93
  * Fixed category page security issue
94
 
95
  = 2.2.2 =
96
- * setHtaccess funtion error fixed
97
  * optimized front-end css
98
  * additional button template added
99
 
@@ -105,18 +231,18 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
105
  = 2.2.0 =
106
  * New templates for file links
107
  * WP Thickbox popup for download page
108
- * Upgraded tiny-mce butotn
109
 
110
  = 2.1.3 =
111
- * update short-code from {filelink=fileid} to [file id=fileid]. also support for old styles shortcode exists.
112
 
113
  = 2.1.2 =
114
  * fixed download issues with 2.1.1
115
- * acitvated direct download without apearing popup for the files without password, so popup will apear only for files with password
116
  = 2.1.1 =
117
- * added new shortcode [wpdm_hotlink id=file_id_required link_label=any_text_optional], use the short-code to place direct download link to files without showing popup
118
  = 2.1.0 =
119
- * adjusted category hirarchy issue on parent selection
120
  * download monitor importer adjusted
121
 
122
  = 2.0.19 =
@@ -140,7 +266,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
140
  * adjusted a minor database bug
141
 
142
  = 2.0.14 =
143
- * Addded option for "Import Download Monitor files". You can use this option if you already using "Download Monitor" from earlier and want use "Download Manager" now. It'll import all files and categories from "Download Monitor" to "Download Manager"
144
 
145
  = 2.0.13 =
146
  * access option restored
@@ -156,7 +282,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
156
  * fixed bug with db table creation
157
 
158
  = 2.0.9 =
159
- * added categroy feature
160
  * new popup style added
161
  * advanced server file browser added
162
 
@@ -174,14 +300,14 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
174
  * "Install" function conflict resolved
175
 
176
  = 2.0.4 =
177
- * some plgins conflict adjusted
178
  * new option added for setting custom message
179
  * new option added for uploading upload link icon
180
 
181
  = 2.0.3 =
182
- * Add/Edit Downoad count option added
183
  = 2.0.2 =
184
- * database class conflick fixed
185
 
186
  = 2.0.1 =
187
  * New Option added for download link label
@@ -204,7 +330,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
204
 
205
 
206
  = 1.5.1 =
207
- * Adjsuted minor issues with download counter
208
 
209
  = 1.5 =
210
  * New feature: Download counter
@@ -236,7 +362,7 @@ You can add/embed downloadable files anywhere in the post just pasting the embed
236
  * Fixed bug with download link
237
 
238
  = 1.2 =
239
- * Fxied installation bug
240
 
241
 
242
 
1
  === WordPress Download Manager ===
2
+ Contributors: codename065, shahriar0822
3
  Donate link:
4
+ Tags: file management plugin, downloads, document management plugin, download manager, file manager, download monitor, download counter, password protection, download tracker, download protection
5
+ Requires at least: 3.4
6
+ Tested up to: 3.8
7
  License: GPLv2 or later
8
 
9
 
10
 
11
+ This is a Files and Document Management plugin which will help you to manage, track and control file downloads from your WordPress site.
12
 
13
 
14
  == Description ==
15
+ WordPress Download Manager is a Files and Document Management plugin for your WordPress Site. WordPress Download Manager plugin will help you to manage, track and control file downloads from your WordPress site. You can set password and set access level any of your downloadable files from your WordPress site.
 
16
  You can add/embed downloadable files anywhere in the post just pasting the embed code inside your post content using WordPress Download Manager.
17
 
18
+ `"Download Monitor" to "Download Manager" Files Importer Integrated. Import all download monitor files in a single click`
19
 
20
  = Features =
21
+ * Drag and Drop File Upload
22
  * Control who can access to download
23
  * Password protection
24
  * Download Counter
25
  * Control who can user this plugin (author, editor, administrator)
26
  * Custom download link icon
27
+ * File type icon support
28
+ * DataTable support ( use short-code [wpdm_all_packages] )
29
+ * Searching and Sorting Option
30
  * Custom link label
31
+ * Short-code for download link
32
+ * Short-code for direct link to downloadable file [wpdm_hotlink id=file_id_required link_label=any_text_optional]
33
  * New templates for file links
34
  * WP Thickbox popup for download page
35
  * Tinymce button for short-code embed
42
  * "Download Monitor" to "Download Manager" files Importer
43
 
44
 
45
+
 
 
 
 
46
  == Installation ==
47
 
48
 
55
  1. Create new download package
56
  2. Manage download packages
57
  3. Categories
58
+ 4. Front-end link template preview
59
  5. Full tree view of categories and files with a simple short-code [wpdm_tree]
60
+ 6. Sortable and Searchable Download List , use short-code [wpdm_all_packages] to embed the list
61
+ 7. Insert short-code
62
+ 8. Create a new download package quickly from popup
63
 
64
  == Changelog ==
65
 
66
+ = 2.5.96 =
67
+ * Fixed issues with category short-code
68
+ * Fixed issue with tinymce button for category short-code
69
+
70
+ = 2.5.95 =
71
+ * Adjusted sorting option for category short-code
72
+ * You can use now [wpdm_category id=cid order_field="field_name" order="desc/asc"]
73
+
74
+ = 2.5.94 =
75
+ * Fixed HTTP response code for download page
76
+
77
+
78
+ = 2.5.93 =
79
+ * Added validation for input data
80
+ * Updated settings page
81
+ * Fixed access level issue
82
+
83
+ = 2.5.92 =
84
+ * Applied sanitize file name for cached file
85
+
86
+ = 2.5.91 =
87
+ * regular maintenance and compatibility release for wp 3.8
88
+
89
+ = 2.5.9 =
90
+ * Fixed input validation issue
91
+
92
+ = 2.5.8 =
93
+ * Adjusted 3 minor issues with input validation and notice display.
94
+
95
+ = 2.5.7 =
96
+ * Adjusted some minor issues ( notices )
97
+
98
+ = 2.5.6 =
99
+ * Fixed category id issue for non-ascii chars
100
+
101
+ = 2.5.5 =
102
+ * Fixed data validation issue
103
+
104
+ = 2.5.4 =
105
+ * Fixed an issue with quick add option
106
+
107
+ = 2.5.3 =
108
+ * regular maintenance and compatibility release for wp 3.7
109
+
110
+ = 2.5.2 =
111
+ * Updated tinymce button, added selection option for additional short-codes
112
+
113
+ = 2.5.1 =
114
+ * Fixed conflict with nextgen gallery
115
+
116
+ = 2.5.0 =
117
+ * Fixed issue with category id for utf8 charset
118
+ * Fixed issue with file title
119
+
120
+ = 2.4.9 =
121
+ * Fixed an issue with tinymce button
122
+
123
+ = 2.4.8 =
124
+ * Compatibility update for wp 3.6
125
+ * Adjusted minor css issue
126
+
127
+ = 2.4.7 =
128
+ * added title and description support to category short-code
129
+
130
+ = 2.4.6 =
131
+ * Added stripslashed for title and description
132
+ * Upgraded some internal css
133
+
134
+ = 2.4.5 =
135
+ * Fixed the issue with tinymce button
136
+
137
+ = 2.4.4 =
138
+ * Upgrade tinymce button feature, added quick add option
139
+
140
+ = 2.4.3 =
141
+ * Fixed issue with categories
142
+ * Fixed Download Limit Issue
143
+
144
+ = 2.4.2 =
145
+
146
+ * Added icon support for category short-code
147
+
148
+ = 2.4.1 =
149
+
150
+ * Upgraded category sort-code
151
+
152
+ = 2.4.0 =
153
+
154
+ * Fixed members download issue
155
+
156
+ = 2.3.9 =
157
+ * Fixed the issue with "fread"
158
+
159
+ = 2.3.8 =
160
+ * Adjusted broken file issue
161
+
162
+ = 2.3.7 =
163
+ * Upgraded new download widget
164
+
165
+ = 2.3.6 =
166
+ * Upgraded tree view
167
+
168
+ = 2.3.5 =
169
+ * Optimized ui and some internal code for better experience
170
+ * Fixed tree view short-code issue
171
+
172
+ = 2.3.4 =
173
+ * Fixed file save issue with v2.3.3
174
+ * Fixed issue with download monitor import
175
+
176
+ = 2.3.3 =
177
+ * added search functionality in admin
178
+ * added individual icon support
179
+ * added new short-code for all download using datatable.js, with sorting and searching option
180
+
181
+ = 2.3.2 =
182
+ * Fixed a minor issue with uploader
183
+
184
+ = 2.3.1 =
185
+ * Optimized for wp 3.5
186
+ * Upgraded file upload option
187
+ * Adjusted file delete issue
188
+ * Upgraded content formatting
189
+
190
  = 2.3.0 =
191
  * Fixed category pagination issue
192
  * Fixed category count issue
208
  * Adjusted enqueue script issue
209
 
210
  = 2.2.5 =
211
+ * Fixed compatibility issue with WordPress 3.4
212
 
213
  = 2.2.4 =
214
  * Fixed empty category name issue
219
  * Fixed category page security issue
220
 
221
  = 2.2.2 =
222
+ * setHtaccess function error fixed
223
  * optimized front-end css
224
  * additional button template added
225
 
231
  = 2.2.0 =
232
  * New templates for file links
233
  * WP Thickbox popup for download page
234
+ * Upgraded tiny-mce button
235
 
236
  = 2.1.3 =
237
+ * update short-code from {filelink=fileid} to [file id=fileid]. also support for old styles short-code exists.
238
 
239
  = 2.1.2 =
240
  * fixed download issues with 2.1.1
241
+ * activated direct download without appearing popup for the files without password, so popup will appear only for files with password
242
  = 2.1.1 =
243
+ * added new short-code [wpdm_hotlink id=file_id_required link_label=any_text_optional], use the short-code to place direct download link to files without showing popup
244
  = 2.1.0 =
245
+ * adjusted category hierarchy issue on parent selection
246
  * download monitor importer adjusted
247
 
248
  = 2.0.19 =
266
  * adjusted a minor database bug
267
 
268
  = 2.0.14 =
269
+ * Added option for "Import Download Monitor files". You can use this option if you already using "Download Monitor" from earlier and want use "Download Manager" now. It'll import all files and categories from "Download Monitor" to "Download Manager"
270
 
271
  = 2.0.13 =
272
  * access option restored
282
  * fixed bug with db table creation
283
 
284
  = 2.0.9 =
285
+ * added category feature
286
  * new popup style added
287
  * advanced server file browser added
288
 
300
  * "Install" function conflict resolved
301
 
302
  = 2.0.4 =
303
+ * some plugins conflict adjusted
304
  * new option added for setting custom message
305
  * new option added for uploading upload link icon
306
 
307
  = 2.0.3 =
308
+ * Add/Edit Download count option added
309
  = 2.0.2 =
310
+ * database class conflict fixed
311
 
312
  = 2.0.1 =
313
  * New Option added for download link label
330
 
331
 
332
  = 1.5.1 =
333
+ * Adjusted minor issues with download counter
334
 
335
  = 1.5 =
336
  * New feature: Download counter
362
  * Fixed bug with download link
363
 
364
  = 1.2 =
365
+ * Fixed installation bug
366
 
367
 
368
 
screenshot-1.png CHANGED
Binary file
screenshot-6.png ADDED
Binary file
screenshot-7.png ADDED
Binary file
screenshot-8.png ADDED
Binary file
wpdc.ppj DELETED
@@ -1,67 +0,0 @@
1
- [PHPEdProject]
2
- RelativeRootDir=..\download-controler
3
- URL=http://localhost
4
- MappingPublishingRoot=
5
- DriverID=
6
- SourceControl=0
7
- DontPublishDirs=CVS;.svn
8
- DefaultFile=
9
- HideFiles=
10
- HideDirs=CVS;.svn
11
- EncoderEnabled=0
12
- MappingRemote0=E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler
13
- MappingLocal0=E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler
14
- MappingURL0=http://localhost
15
- MappingPublishing0=
16
- MappingCount=1
17
- MappingMainIdx=0
18
- RunMode=2
19
- CustomPropCount=0
20
- PublishingFilterCount=1
21
- PublishingAllowFilterCount=1
22
- DefaultEncodingCount=1
23
- IncPath_count=0
24
- ParserProp_Override=0
25
- ParserProp_PHP_SubLang=2
26
- ParserPropPHPShortTags=1
27
- ParserProp_PHP_AspTags=0
28
- ParserProp_JS_ParsePHP=0
29
- ParserProp_CSS_ParsePHP=0
30
- [Encoder]
31
- destinationtype=0
32
- compatibilitylevel=1
33
- extinfo=0
34
- lineinfo=0
35
- phpdoc=1
36
- copyall=1
37
- stoponerr=0
38
- suppresssucc=0
39
- shorttags=1
40
- asptags=0
41
- licensing=0
42
- excl=0
43
- obfusclevel=0
44
- headertype=0
45
- [PHPEdProject.Filters]
46
- \=
47
- [PHPEdProject.Filters.Allow]
48
- \=
49
- [PHPEdProject.Encodings]
50
- \=UTF-8
51
- [Wizard]
52
- srunmode=2
53
- slocalwebroot=E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler
54
- swebrooturl=http://localhost/
55
- sprojectroot=E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler
56
- [Debugger]
57
- custom=0
58
- host=clienthost
59
- errlevel=3 - All errors and warnings
60
- sesstimeout=15
61
- cp=System default encoding
62
- stopbeginning=1
63
- dbgsessions=1
64
- showmaperrors=1
65
- readonlyed=0
66
- profwithdbg=0
67
- Custom.Debug.Settings=0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wpdc.ppx DELETED
@@ -1 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?><_root _check="0"><ca52F9DEE0 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler" _n="download-controler"><eaF4D759AE _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\download-controller.php" _n="download-controller.php" _sz="20363" _p="1" _crc="893348202" _dt="1053323668"><favar><abA343B7BF _n="d" _y="17" _x="3" _r="9" _vr=".implode()"/><ab77CB9B76 _n="_GET" _y="25" _x="9" _r="4"/><ab2F392DF8 _n="_POST" _y="33" _x="11" _r="1"/><ab788D0DAA _n="_SESSION" _y="33" _x="25" _r="1"/><abAFDCE5D4 _n="wpdb" _y="36" _x="17" _r="31"/><ab6A57CFA6 _n="current_user" _y="333" _x="32" _r="1"/><ab09BFF6FD _n="post" _y="333" _x="39" _r="2"/><abEDCC920F _n="wp_query" _y="333" _x="50" _r="1"/></favar><_rslv><ab2B73B2A1 _n=".str_replace()"/><ab1877273D _n=".dirname()"/><ab5C1FE996 _n=".explode()"/><abEA150E14 _n=".array_pop()"/><abDE856E16 _n=".implode()"/><ab4768846F _n=".define()"/><ab938C36EF _n="$wpdb.prefix"/><ab0F14E148 _n=".dbDelta()"/><ab8154F6D6 _n=".update_option()"/><ab42000EA6 _n=".wpdc_create_dir()"/><abE50C03E1 _n="$wpdb.get_results"/><ab79D15B35 _n="$wpdb.get_results()"/><ab060EE961 _n=".home_url()"/><ab0DF23739 _n=".preg_match_all()"/><ab4FCBF1EA _n=".count()"/><ab4EE10C8F _n="$wpdb.query"/><ab1E5C9923 _n="$wpdb.query()"/><abB2448AFB _n=".get_option()"/><abFCABF3AA _n=".is_user_logged_in()"/><ab91BF80EE _n=".wpdc_embed_category()"/><ab224FF3FC _n=".maybe_unserialize()"/><ab469BAD9C _n=".is_array()"/><ab7CD09A74 _n=".str_repeat()"/><abB508A541 _n=".in_array()"/><ab8F6C4766 _n=".wpdc_cblist_categories()"/><ab42DE73AF _n=".wpdc_dropdown_categories()"/><abAC5BFBC9 _n=".file_exists()"/><ab14385A3E _n=".setHtaccess()"/><ab35DAF71B _n=".call_user_func()"/><ab62A59C36 _n=".mkdir()"/><abD9E16C65 _n=".chmod()"/><ab073FFB00 _n=".wpdc_set_htaccess()"/><ab08979426 _n=".is_uploaded_file()"/><abF4B3CF52 _n=".move_uploaded_file()"/><ab878540D3 _n=".pathinfo()"/><ab3146EAB6 _n=".extract()"/><ab747887EF _n=".uniqid()"/><ab39C49F6B _n=".serialize()"/><ab08EFF854 _n="$wpdb.insert"/><ab1059A9F6 _n="$wpdb.insert()"/><ab4FC6D7D4 _n="$wpdb.insert_id"/><ab82DDA12F _n="$wpdb.print_error"/><ab18700CFF _n="$wpdb.print_error()"/><abC6F8D0FF _n="$wpdb.update"/><ab1AA10B65 _n="$wpdb.update()"/><abF4BBD253 _n="$wpdb.get_row"/><abE82FA3A0 _n="$wpdb.get_row()"/><ab1A56F49A _n=".strtolower()"/><ab786734F4 _n=".preg_replace()"/><ab41A5BD4D _n=".array_key_exists()"/><ab9A074D55 _n=".wpdc_cat_dropdown_tree()"/><ab76D41B93 _n=".get_permalink()"/><ab6D9B281A _n="$post.ID"/><abABDCD7A7 _n=".get_currentuserinfo()"/><ab947AEB55 _n="$wpdb.get_var"/><ab130C0FEC _n="$wpdb.get_var()"/><ab27B6EBD1 _n=".ceil()"/><ab4995040D _n="Pagination.items"/><ab2FCCD926 _n="Pagination.items()"/><ab0AF9E320 _n="Pagination.limit"/><abE63055BA _n="Pagination.limit()"/><ab0BDE5E20 _n="Pagination.currentPage"/><ab13D7806E _n="Pagination.currentPage()"/><ab0FEE6742 _n=".strpos()"/><ab98F88787 _n="Pagination.urlTemplate"/><ab16EBFDE5 _n="Pagination.urlTemplate()"/><ab874A99D3 _n=".plugins_url()"/><ab2BBF6839 _n=".wp_enqueue_script()"/><ab5432E4C9 _n=".wp_admin_css()"/><ab57B367CF _n=".wp_print_scripts()"/><abC4984DBC _n=".add_thickbox()"/><ab2B0C89EE _n=".wp_tiny_mce()"/><abB168BC98 _n=".do_action()"/><abF8826EFD _n=".remove_all_filters()"/><ab68E07B53 _n=".file_put_contents()"/><ab5C7AB9AC _n=".array_unique()"/><ab334F1BB1 _n=".array_merge()"/><ab5EB460BC _n=".mysql_query()"/><ab7FA0640A _n=".mysql_fetch_assoc()"/><ab87AC2012 _n=".add_menu_page()"/><abE9F19198 _n=".add_submenu_page()"/><abA9201B64 _n=".is_admin()"/><ab1B360886 _n=".add_action()"/><abEAF4E364 _n=".wp_enqueue_style()"/><ab875B5694 _n=".add_filter()"/><abFA57AEC2 _n=".register_activation_hook()"/></_rslv><fadef><ga2728084E _n="UPLOAD_DIR" _y="23" _x="8"/><ga5803FEF0 _n="UPLOAD_BASE" _y="24" _x="8"/></fadef><falnk><ia7C2AE9B0 _n="include" _y="26" _x="24" _val="(&quot;process.php&quot;)"/><ia5893648C _n="include" _y="28" _x="25" _val="(&quot;download.php&quot;)"/><ia30BAE221 _n="include" _y="29" _x="26" _val="(&quot;functions.php&quot;)"/><ia19AF0AE7 _n="include" _y="30" _x="33" _val="(&quot;class.pagination.php&quot;)"/><ia5EE36071 _n="include" _y="31" _x="41" _val="(&quot;wpdc-server-file-browser.php&quot;)"/><ia39037DDE _n="require_once" _y="54" _x="63" _val="(ABSPATH . &quot;wp-admin/includes/upgrade.php&quot;)"/><ia888D471B _n="include" _y="166" _x="36" _val="(&quot;wpdc-list-files.php&quot;)"/><ia2CF627F2 _n="include" _y="213" _x="34" _val="(&quot;wpdc-settings.php&quot;)"/><iaA8D78851 _n="include" _y="262" _x="38" _val="(&quot;wpdc-add-new-file.php&quot;)"/><ia528B6F31 _n="include" _y="319" _x="35" _val="(&quot;wpdc-categories.php&quot;)"/><ia1E101498 _n="include" _y="548" _x="41" _val="(&quot;wpdc-free-mce-button.php&quot;)"/><ia255D2743 _n="include" _y="564" _x="29" _val="(&quot;wpdc-widgets.php&quot;)"/></falnk><fafnc><ma1A77BA18 _n="wpdc_free_Install" _y="35" _x="27" _ex="1" _ey="62" _s="1"><favar><abAFDCE5D4 _n="wpdb" _y="36" _x="17" _r="3" _to="13"/><ab61C240D9 _n="sql" _y="39" _x="11" _r="2"/></favar></ma1A77BA18><ma6E9CFB1F _n="wpdc_new_packages" _y="64" _x="27" _ex="1" _ey="75" _al="$show = 5, $show_count = true" _s="1"><favar><abB6339E5F _n="show" _y="64" _x="28" _r="3" _pri="1" _val="5"/><ab4D8F63EE _n="show_count" _y="64" _x="37" _r="3" _pri="2" _val="true"/><abAFDCE5D4 _n="wpdb" _y="65" _x="17" _r="3" _to="13"/><ab053F6F95 _n="data" _y="67" _x="10" _r="2" _vr="$wpdb.get_results()"/><abA343B7BF _n="d" _y="68" _x="24" _r="4"/><ab4B640BDE _n="key" _y="70" _x="13" _r="1"/><abF517E1E9 _n="sc" _y="71" _x="28" _r="2"/><ab928EAC1D _n="url" _y="72" _x="13" _r="2" _vr=".home_url()"/></favar><fapar><naB6339E5F _n="show" _y="64" _x="28" _pri="1" _val="5" _to="2"/><na4D8F63EE _n="show_count" _y="64" _x="37" _pri="2" _val="true" _to="9"/></fapar></ma6E9CFB1F><maBCC79AB9 _n="wpdc_downloadable" _y="79" _x="27" _ex="1" _ey="108" _al="$content" _vr=".str_replace()" _s="1"><favar><ab31D699AB _n="content" _y="79" _x="28" _r="7" _pri="1" _vr=".str_replace()"/><abAFDCE5D4 _n="wpdb" _y="80" _x="17" _r="3" _to="13"/><abA47B1FEB _n="matches" _y="82" _x="66" _r="8"/><abA3C82E6F _n="sap" _y="86" _x="9" _r="2"/><ab77CB9B76 _n="_GET" _y="86" _x="23" _r="1"/><abEE3D190A _n="i" _y="87" _x="11" _r="12"/><abC9360499 _n="id" _y="88" _x="8" _r="3"/><ab053F6F95 _n="data" _y="89" _x="10" _r="5" _vr="$wpdb.query()"/><abF12C460D _n="wpdc_login_msg" _y="90" _x="20" _r="2" _vr=".get_option()"/><abBCBA0FD0 _n="link_label" _y="91" _x="16" _r="2"/><abC3353E85 _n="_SERVER" _y="93" _x="94" _r="2"/><ab437096C6 _n="cmatches" _y="101" _x="72" _r="6" _vr=".wpdc_embed_category()"/></favar><fapar><na31D699AB _n="content" _y="79" _x="28" _pri="1" _to="0"/></fapar></maBCC79AB9><ma99A63510 _n="wpdc_cblist_categories" _y="110" _x="32" _ex="1" _ey="126" _al="$parent, $level = 0, $sel = array" _s="1"><favar><abECE3A3B8 _n="parent" _y="110" _x="33" _r="5" _pri="1"/><abEE106E57 _n="level" _y="110" _x="45" _r="4" _pri="2" _val="0"/><abA9023B06 _n="sel" _y="110" _x="57" _r="4" _pri="3" _val="array"/><abCF465EE7 _n="cats" _y="111" _x="9" _r="3" _vr=".maybe_unserialize()"/><abC9360499 _n="id" _y="114" _x="24" _r="4"/><ab3C0F9408 _n="cat" _y="114" _x="30" _r="2"/><abC8308D78 _n="pres" _y="115" _x="13" _r="1" _vr=".str_repeat()"/><ab5B0856F6 _n="checked" _y="118" _x="16" _r="3"/></favar><fapar><naECE3A3B8 _n="parent" _y="110" _x="33" _pri="1" _to="4"/><naEE106E57 _n="level" _y="110" _x="45" _pri="2" _val="0" _to="2"/><naA9023B06 _n="sel" _y="110" _x="57" _pri="3" _val="array" _to="10"/></fapar></ma99A63510><maD86F55BE _n="wpdc_dropdown_categories" _y="128" _x="34" _ex="1" _ey="138" _al="$parent, $level = 0" _s="1"><favar><abECE3A3B8 _n="parent" _y="128" _x="35" _r="3" _pri="1"/><abEE106E57 _n="level" _y="128" _x="47" _r="4" _pri="2" _val="0"/><abCF465EE7 _n="cats" _y="129" _x="9" _r="2" _vr=".maybe_unserialize()"/><abC9360499 _n="id" _y="131" _x="24" _r="3"/><ab3C0F9408 _n="cat" _y="131" _x="30" _r="2"/><abC8308D78 _n="pres" _y="132" _x="13" _r="2" _vr=".str_repeat()"/><abA9023B06 _n="sel" _y="135" _x="51" _r="1"/></favar><fapar><naECE3A3B8 _n="parent" _y="128" _x="35" _pri="1" _to="4"/><naEE106E57 _n="level" _y="128" _x="47" _pri="2" _val="0" _to="2"/></fapar></maD86F55BE><maB38D692C _n="wpdc_admin_options" _y="140" _x="28" _ex="1" _ey="167" _vr=".call_user_func()" _s="1"><favar><ab77CB9B76 _n="_GET" _y="142" _x="39" _r="4"/></favar></maB38D692C><ma119F0A22 _n="wpdc_delete_file" _y="169" _x="26" _ex="1" _ey="183" _s="1"><favar><abAFDCE5D4 _n="wpdb" _y="170" _x="17" _r="3" _to="13"/><ab77CB9B76 _n="_GET" _y="171" _x="22" _r="3"/><abC9360499 _n="id" _y="172" _x="33" _r="2"/><ab902A88B1 _n="qry" _y="173" _x="17" _r="2"/><abD21473E7 _n="cond" _y="175" _x="14" _r="3" _vr=".implode()"/></favar></ma119F0A22><maD6740297 _n="wpdc_create_dir" _y="185" _x="25" _ex="1" _ey="201" _s="1"><favar><ab77CB9B76 _n="_GET" _y="193" _x="12" _r="1"/><ab35C734BA _n="s" _y="194" _x="34" _r="3"/><abC3353E85 _n="_SERVER" _y="197" _x="33" _r="1"/></favar></maD6740297><maC393E74B _n="wpdc_settings" _y="203" _x="23" _ex="1" _ey="214" _s="1"><favar><ab2F392DF8 _n="_POST" _y="204" _x="14" _r="3"/><ab433E752A _n="_FILES" _y="208" _x="32" _r="2"/><ab72BAC876 _n="access" _y="212" _x="12" _r="1" _vr=".get_option()"/></favar></maC393E74B><ma5334F944 _n="wpdc_add_new_file" _y="216" _x="27" _ex="1" _ey="263" _s="1"><favar><abAFDCE5D4 _n="wpdb" _y="217" _x="17" _r="5" _to="13"/><ab77CB9B76 _n="_GET" _y="228" _x="13" _r="1"/><ab2F392DF8 _n="_POST" _y="236" _x="14" _r="2"/><ab433E752A _n="_FILES" _y="238" _x="32" _r="5"/><ab9B2AAF9B _n="info" _y="239" _x="14" _r="4" _vr=".pathinfo()"/><abDCFED24D _n="name" _y="242" _x="14" _r="3" _vr=".file_exists()"/><ab6100D8CA _n="file" _y="244" _x="14" _r="5" _vr=".serialize()"/></favar></ma5334F944><ma3E60DC4A _n="wpdc_edit_file" _y="265" _x="24" _ex="1" _ey="290" _s="1"><favar><abAFDCE5D4 _n="wpdb" _y="266" _x="18" _r="5" _to="13"/><ab2F392DF8 _n="_POST" _y="267" _x="14" _r="3"/><ab433E752A _n="_FILES" _y="269" _x="32" _r="5"/><ab9B2AAF9B _n="info" _y="270" _x="14" _r="4" _vr=".pathinfo()"/><abDCFED24D _n="name" _y="273" _x="14" _r="3" _vr=".file_exists()"/><ab6100D8CA _n="file" _y="275" _x="14" _r="5" _vr="$wpdb.get_row()"/></favar></ma3E60DC4A><maDD9040E3 _n="wpdc_categories" _y="292" _x="25" _ex="1" _ey="320" _s="1"><favar><ab77CB9B76 _n="_GET" _y="294" _x="12" _r="2"/><abFFC0A43D _n="tpldata" _y="295" _x="17" _r="9" _vr=".maybe_unserialize()"/><abC3353E85 _n="_SERVER" _y="299" _x="33" _r="2"/><ab2F392DF8 _n="_POST" _y="303" _x="15" _r="6"/><ab22D4187B _n="tcid" _y="306" _x="14" _r="3"/><ab8235E287 _n="cid" _y="307" _x="13" _r="4"/><ab1C654BCB _n="postfx" _y="309" _x="40" _r="1"/></favar></maDD9040E3><maDCC6218C _n="wpdc_cat_dropdown_tree" _y="322" _x="32" _ex="1" _ey="330" _al="$parent, $level = 0" _s="1"><favar><abECE3A3B8 _n="parent" _y="322" _x="33" _r="3" _pri="1"/><abEE106E57 _n="level" _y="322" _x="45" _r="4" _pri="2" _val="0"/><abCF465EE7 _n="cats" _y="323" _x="9" _r="2" _vr=".maybe_unserialize()"/><abC9360499 _n="id" _y="324" _x="24" _r="3"/><ab3C0F9408 _n="cat" _y="324" _x="30" _r="2"/><abC8308D78 _n="pres" _y="325" _x="13" _r="2" _vr=".str_repeat()"/></favar><fapar><naECE3A3B8 _n="parent" _y="322" _x="33" _pri="1" _to="4"/><naEE106E57 _n="level" _y="322" _x="45" _pri="2" _val="0" _to="2"/></fapar></maDCC6218C><maB1CCBBA1 _n="wpdc_embed_category" _y="332" _x="29" _ex="1" _ey="396" _al="$id" _s="1"><favar><abC9360499 _n="id" _y="332" _x="30" _r="6" _pri="1"/><abAFDCE5D4 _n="wpdb" _y="333" _x="17" _r="5" _to="13"/><ab6A57CFA6 _n="current_user" _y="333" _x="32" _r="1" _to="13"/><ab09BFF6FD _n="post" _y="333" _x="39" _r="2" _to="13"/><abEDCC920F _n="wp_query" _y="333" _x="50" _r="1" _to="13"/><abB093524F _n="postlink" _y="334" _x="14" _r="2" _vr=".get_permalink()"/><ab48DC2AE2 _n="user" _y="337" _x="10" _r="1" _vr="WP_User"/><abCF8675CE _n="categories" _y="338" _x="16" _r="2" _vr=".maybe_unserialize()"/><abBA28DA1E _n="category" _y="339" _x="14" _r="1"/><ab66FB7D30 _n="total" _y="340" _x="11" _r="3" _vr="$wpdb.get_var()"/><ab794DE613 _n="item_per_page" _y="342" _x="19" _r="5"/><abD2A066EB _n="pages" _y="343" _x="11" _r="1" _vr=".ceil()"/><abA13D5E4B _n="page" _y="344" _x="10" _r="3"/><ab77CB9B76 _n="_GET" _y="344" _x="18" _r="3"/><ab623EDC60 _n="start" _y="345" _x="11" _r="2"/><ab9B3E39EC _n="pag" _y="346" _x="9" _r="5" _vr="Pagination"/><ab928EAC1D _n="url" _y="350" _x="9" _r="2" _vr=".strpos()"/><abC3353E85 _n="_SERVER" _y="350" _x="27" _r="3"/><abD9BCE9DC _n="ndata" _y="353" _x="11" _r="2" _vr="$wpdb.get_results()"/><abA3C82E6F _n="sap" _y="356" _x="5" _r="2"/><ab3ADF6409 _n="html" _y="357" _x="6" _r="3"/><ab053F6F95 _n="data" _y="358" _x="24" _r="16"/><abBCBA0FD0 _n="link_label" _y="360" _x="16" _r="2"/><ab74707DD0 _n="counter" _y="373" _x="25" _r="2"/><ab2C83E2E8 _n="template" _y="379" _x="22" _r="2"/></favar><fapar><naC9360499 _n="id" _y="332" _x="30" _pri="1" _to="0"/></fapar></maB1CCBBA1><ma032C0CB4 _n="wpdc_tinymce" _y="400" _x="22" _ex="1" _ey="420"/><maD1EA4107 _n="wpdc_set_htaccess" _y="422" _x="27" _ex="1" _ey="429" _s="1"><favar><ab8306B1AD _n="cont" _y="423" _x="10" _r="2"/></favar></maD1EA4107><ma1B961243 _n="wpdc_front_js" _y="432" _x="23" _ex="1" _ey="442"/><ma082E996D _n="wpdc_copyold" _y="444" _x="22" _ex="1" _ey="534" _s="1"><favar><abAFDCE5D4 _n="wpdb" _y="445" _x="17" _r="4" _to="13"/><abAF4A90D1 _n="ids" _y="446" _x="9" _r="9" _vr=".array_unique()"/><ab2F392DF8 _n="_POST" _y="447" _x="14" _r="6"/><ab31A42FD7 _n="fid" _y="450" _x="35" _r="2"/><ab6100D8CA _n="file" _y="452" _x="18" _r="3" _vr="$wpdb.get_row()"/><ab92DF3D00 _n="res" _y="472" _x="9" _r="2" _vr=".mysql_query()"/><abB519CA09 _n="media" _y="504" _x="23" _r="7" _vr=".in_array()"/></favar></ma082E996D><ma88580077 _n="wpdc_menu" _y="536" _x="19" _ex="1" _ey="544"/></fafnc></eaF4D759AE><ca0B8F7417 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\css" _n="css"><eaCF846626 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\css\colorbox.css" _n="colorbox.css" _sz="2400" _p="1" _crc="3094599639" _dt="1052872339"><facss><fasel><nb67EFD31B _n="#colorbox"><falstruct><gc6CAB71F2 _n="#colorbox" _y="5" _x="1" _ex="9" _ey="5" _spt="2"/></falstruct></nb67EFD31B><nbE58DE529 _n="#cboxOverlay"><falstruct><gc3CB7621A _n="#cboxOverlay" _y="5" _x="12" _ex="23" _ey="5" _spt="2"/></falstruct></nbE58DE529><nb632ABF7F _n="#cboxWrapper"><falstruct><gc4134D7A0 _n="#cboxWrapper" _y="5" _x="26" _ex="37" _ey="5" _spt="2"/></falstruct></nb632ABF7F><nbE148894D _n="#cboxOverlay"><falstruct><gc38720E7E _n="#cboxOverlay" _y="6" _x="1" _ex="12" _ey="6" _spt="2"/></falstruct></nbE148894D><nb6F650AD3 _n="#cboxMiddleLeft"><falstruct><gc9727CD93 _n="#cboxMiddleLeft" _y="7" _x="1" _ex="15" _ey="7" _spt="2"/></falstruct></nb6F650AD3><nbCC48F37D _n="#cboxBottomLeft"><falstruct><gc9619F3DD _n="#cboxBottomLeft" _y="7" _x="18" _ex="32" _ey="7" _spt="2"/></falstruct></nbCC48F37D><nb4E2AC54F _n="#cboxContent"><falstruct><gcF6159F66 _n="#cboxContent" _y="8" _x="1" _ex="12" _ey="8" _spt="2"/></falstruct></nb4E2AC54F><nbC88D9F19 _n="#cboxLoadedContent"><falstruct><gc41881F06 _n="#cboxLoadedContent" _y="9" _x="1" _ex="18" _ey="9" _spt="2"/></falstruct></nbC88D9F19><nb4AEFA92B _n="#cboxTitle"><falstruct><gc269B47AA _n="#cboxTitle" _y="10" _x="1" _ex="10" _ey="10" _spt="2"/></falstruct></nb4AEFA92B><nbC4C22AB5 _n="#cboxLoadingOverlay"><falstruct><gc6C38046B _n="#cboxLoadingOverlay" _y="11" _x="1" _ex="19" _ey="11" _spt="2"/></falstruct></nbC4C22AB5><nb22E7466F _n="#cboxLoadingGraphic"><falstruct><gcB774DCFF _n="#cboxLoadingGraphic" _y="11" _x="22" _ex="40" _ey="11" _spt="2"/></falstruct></nb22E7466F><nbA085705D _n="#cboxPrevious"><falstruct><gc50D1CC2E _n="#cboxPrevious" _y="12" _x="1" _ex="13" _ey="12" _spt="2"/></falstruct></nbA085705D><nb26222A0B _n="#cboxNext"><falstruct><gcE2B49713 _n="#cboxNext" _y="12" _x="16" _ex="24" _ey="12" _spt="2"/></falstruct></nb26222A0B><nbA4401C39 _n="#cboxClose"><falstruct><gcEC8CFB59 _n="#cboxClose" _y="12" _x="27" _ex="36" _ey="12" _spt="2"/></falstruct></nbA4401C39><nb2A6D9FA7 _n="#cboxSlideshow"><falstruct><gc43D059C5 _n="#cboxSlideshow" _y="12" _x="39" _ex="52" _ey="12" _spt="2"/></falstruct></nb2A6D9FA7><nb4780FAD7 _n=".cboxPhoto"><falstruct><dc7E83B83F _n=".cboxPhoto" _y="13" _x="1" _ex="10" _ey="13" _spt="3"/></falstruct></nb4780FAD7><nbC5E2CCE5 _n=".cboxIframe"><falstruct><dc083B6AA0 _n=".cboxIframe" _y="14" _x="1" _ex="11" _ey="14" _spt="3"/></falstruct></nbC5E2CCE5><nb434596B3 _n="#cboxOverlay"><falstruct><gc0487C784 _n="#cboxOverlay" _y="21" _x="1" _ex="12" _ey="21" _spt="2"/></falstruct></nb434596B3><nbC127A081 _n="#colorbox"><falstruct><gc05C442B2 _n="#colorbox" _y="22" _x="1" _ex="9" _ey="22" _spt="2"/></falstruct></nbC127A081><nb4F0A231F _n="#cboxContent"><falstruct><gcF7357936 _n="#cboxContent" _y="23" _x="5" _ex="16" _ey="23" _spt="2"/></falstruct></nb4F0A231F><nbFEB82D4A _n="#cboxError"><falstruct><gcFD1DB6D0 _n="#cboxError" _y="24" _x="9" _ex="18" _ey="24" _spt="2"/></falstruct></nbFEB82D4A><nb7CDA1B78 _n="#cboxLoadedContent"><falstruct><gcF5DF9B67 _n="#cboxLoadedContent" _y="25" _x="9" _ex="26" _ey="25" _spt="2"/></falstruct></nb7CDA1B78><nbFA7D412E _n="#cboxLoadingGraphic"><falstruct><gc6FEEDBBE _n="#cboxLoadingGraphic" _y="26" _x="9" _ex="27" _ey="26" _spt="2"/></falstruct></nbFA7D412E><nb781F771C _n="#cboxLoadingOverlay"><falstruct><gcD0E559C2 _n="#cboxLoadingOverlay" _y="27" _x="9" _ex="27" _ey="27" _spt="2"/></falstruct></nb781F771C><nbF632F482 _n="#cboxTitle"><falstruct><gc9A461A03 _n="#cboxTitle" _y="28" _x="9" _ex="18" _ey="28" _spt="2"/></falstruct></nbF632F482><nb9BDF91F2 _n="#cboxCurrent"><falstruct><gc306C256A _n="#cboxCurrent" _y="29" _x="9" _ex="20" _ey="29" _spt="2"/></falstruct></nb9BDF91F2><nb19BDA7C0 _n="#cboxSlideshow"><falstruct><gc700061A2 _n="#cboxSlideshow" _y="30" _x="9" _ex="22" _ey="30" _spt="2"/></falstruct></nb19BDA7C0><nb9F1AFD96 _n="#cboxPrevious"><falstruct><gc6F4E41E5 _n="#cboxPrevious" _y="30" _x="25" _ex="37" _ey="30" _spt="2"/></falstruct></nb9F1AFD96><nb1D78CBA4 _n="#cboxNext"><falstruct><gcD9EE76BC _n="#cboxNext" _y="30" _x="40" _ex="48" _ey="30" _spt="2"/></falstruct></nb1D78CBA4><nb9355483A _n="#cboxClose"><falstruct><gcDB99AF5A _n="#cboxClose" _y="30" _x="51" _ex="60" _ey="30" _spt="2"/></falstruct></nb9355483A><nb757024E0 _n="#cboxPrevious"><falstruct><gc85249893 _n="#cboxPrevious" _y="31" _x="9" _ex="21" _ey="31" _spt="2"/></falstruct></nb757024E0><nbF71212D2 _n="#cboxPrevious.hover"><falstruct><gc0746AEA1 _n="#cboxPrevious" _y="32" _x="9" _ex="21" _ey="32" _spt="2"/><dc5AF8678A _n=".hover" _y="32" _x="22" _ex="27" _ey="32" _spt="3"/></falstruct></nbF71212D2><nb3084539D _n="#cboxNext"><falstruct><gc7670D8B7 _n="#cboxNext" _y="33" _x="9" _ex="17" _ey="33" _spt="2"/></falstruct></nb3084539D><nbB2E665AF _n="#cboxNext.hover"><falstruct><gcF85D5B29 _n="#cboxNext" _y="34" _x="9" _ex="17" _ey="34" _spt="2"/><dc1786C93F _n=".hover" _y="34" _x="18" _ex="23" _ey="34" _spt="3"/></falstruct></nbB2E665AF><nb10179858 _n="#cboxClose"><falstruct><gc58DB7F38 _n="#cboxClose" _y="35" _x="9" _ex="18" _ey="35" _spt="2"/></falstruct></nb10179858><nb9275AE6A _n="#cboxClose.hover"><falstruct><gcDAB9490A _n="#cboxClose" _y="36" _x="9" _ex="18" _ey="36" _spt="2"/><dc3F9FDB32 _n=".hover" _y="36" _x="19" _ex="24" _ey="36" _spt="3"/></falstruct></nb9275AE6A><nb55E3EF25 _n=".cboxSlideshow_on #cboxPrevious"><falstruct><dcE1A34F21 _n=".cboxSlideshow_on" _y="37" _x="9" _ex="25" _ey="37" _spt="3"/><hc463B6AB4 _n=" " _spt="5"/><gcA9F8E6FA _n="#cboxPrevious" _y="37" _x="27" _ex="39" _ey="37" _spt="2"/></falstruct></nb55E3EF25><nb59AC5A89 _n=".cboxSlideshow_off #cboxPrevious"><falstruct><dc97901423 _n=".cboxSlideshow_off" _y="37" _x="42" _ex="59" _ey="37" _spt="3"/><hc968C53BA _n=" " _spt="5"/><gc75006A58 _n="#cboxPrevious" _y="37" _x="61" _ex="73" _ey="37" _spt="2"/></falstruct></nb59AC5A89><nb8554D62B _n=".cboxSlideshow_on #cboxSlideshow"><falstruct><dc35D11A4B _n=".cboxSlideshow_on" _y="38" _x="9" _ex="25" _ey="38" _spt="3"/><hc92493FDE _n=" " _spt="5"/><gcE82C7C2D _n="#cboxSlideshow" _y="38" _x="27" _ex="40" _ey="38" _spt="2"/></falstruct></nb8554D62B><nb8191BA4F _n=".cboxSlideshow_on #cboxSlideshow.hover"><falstruct><dc399EAFE7 _n=".cboxSlideshow_on" _y="39" _x="9" _ex="25" _ey="39" _spt="3"/><hc9E068A72 _n=" " _spt="5"/><gc0BEC9AC3 _n="#cboxSlideshow" _y="39" _x="27" _ex="40" _ey="39" _spt="2"/><dc491C73AF _n=".hover" _y="39" _x="41" _ex="46" _ey="39" _spt="3"/></falstruct></nb8191BA4F><nbA102718A _n=".cboxSlideshow_off #cboxSlideshow"><falstruct><dc31A485B0 _n=".cboxSlideshow_off" _y="40" _x="9" _ex="26" _ey="40" _spt="3"/><hcB61F987F _n=" " _spt="5"/><gc4E18EDBE _n="#cboxSlideshow" _y="40" _x="28" _ex="41" _ey="40" _spt="2"/></falstruct></nbA102718A><nbA5C71DEE _n=".cboxSlideshow_off #cboxSlideshow.hover"><falstruct><dc3561E9D4 _n=".cboxSlideshow_off" _y="41" _x="9" _ex="26" _ey="41" _spt="3"/><hcBA502DD3 _n=" " _spt="5"/><gc42575812 _n="#cboxSlideshow" _y="41" _x="28" _ex="41" _ey="41" _spt="2"/><dc8BD413BE _n=".hover" _y="41" _x="42" _ex="47" _ey="41" _spt="3"/></falstruct></nbA5C71DEE></fasel></facss></eaCF846626><ea152E0A52 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\css\front.css" _n="front.css" _sz="3770" _p="1" _crc="2552289014" _dt="1052872339"><facss><fasel><nb67EFD31B _n=".download_link"><falstruct><dc81C33596 _n=".download_link" _y="1" _x="1" _ex="14" _ey="1" _spt="3"/></falstruct></nb67EFD31B><nbE58DE529 _n=".download_link a"><falstruct><dc03A103A4 _n=".download_link" _y="24" _x="1" _ex="14" _ey="24" _spt="3"/><hc2A7CA3C5 _n=" " _spt="5"/><fc337210FF _n="a" _y="24" _x="16" _ex="16" _ey="24" _spt="1"/></falstruct></nbE58DE529><nbE148894D _n=".download_link input"><falstruct><dc07646FC0 _n=".download_link" _y="28" _x="1" _ex="14" _ey="28" _spt="3"/><hc26331669 _n=" " _spt="5"/><fc59EC99E3 _n="input" _y="28" _x="16" _ex="20" _ey="28" _spt="1"/></falstruct></nbE148894D><nbCC48F37D _n=".wpdm_submit"><falstruct><dc2FD66793 _n=".wpdm_submit" _y="36" _x="1" _ex="12" _ey="36" _spt="3"/></falstruct></nbCC48F37D><nb4E2AC54F _n=".wpdm_submit_wait"><falstruct><dcA90C9398 _n=".wpdm_submit_wait" _y="41" _x="1" _ex="17" _ey="41" _spt="3"/></falstruct></nb4E2AC54F><nbC88D9F19 _n="#wpdm_submit_error"><falstruct><gc2F61F4F0 _n="#wpdm_submit_error" _y="46" _x="1" _ex="18" _ey="46" _spt="2"/></falstruct></nbC88D9F19><nb4AEFA92B _n=".wpdm_package"><falstruct><dcEFABF531 _n=".wpdm_package" _y="55" _x="1" _ex="13" _ey="55" _spt="3"/></falstruct></nb4AEFA92B><nbC4C22AB5 _n=".download_link input"><falstruct><dc8F21712E _n=".download_link" _y="62" _x="1" _ex="14" _ey="62" _spt="3"/><hcB35DF5CC _n=" " _spt="5"/><fc642B99D3 _n="input" _y="62" _x="16" _ex="20" _ey="62" _spt="1"/></falstruct></nbC4C22AB5><nbA085705D _n=".myorder th"><falstruct><dcD312CF5F _n=".myorder" _y="66" _x="1" _ex="8" _ey="66" _spt="3"/><hcB79899A8 _n=" " _spt="5"/><fc57C073AE _n="th" _y="66" _x="10" _ex="11" _ey="66" _spt="1"/></falstruct></nbA085705D><nbA4401C39 _n=".myorder tr.items td"><falstruct><dcD7D7A33B _n=".myorder" _y="67" _x="1" _ex="8" _ey="67" _spt="3"/><hcBBD72C04 _n=" " _spt="5"/><fcA6AE8BA0 _n="tr" _y="67" _x="10" _ex="11" _ey="67" _spt="1"/><dc139770ED _n=".items" _y="67" _x="12" _ex="17" _ey="67" _spt="3"/><hc970B526D _n=" " _spt="5"/><fc8EF14C2E _n="td" _y="67" _x="19" _ex="20" _ey="67" _spt="1"/></falstruct></nbA4401C39><nb84D3D7FC _n=".myorder tr.item td"><falstruct><dc71E332A8 _n=".myorder" _y="68" _x="1" _ex="8" _ey="68" _spt="3"/><hc93CE3E09 _n=" " _spt="5"/><fc0CD5AF9F _n="tr" _y="68" _x="10" _ex="11" _ey="68" _spt="1"/><dc3B9D1A3C _n=".item" _y="68" _x="12" _ex="16" _ey="68" _spt="3"/><hcDEB090BC _n=" " _spt="5"/><fc4528B8CD _n="td" _y="68" _x="18" _ex="19" _ey="68" _spt="1"/></falstruct></nb84D3D7FC><nbFEB82D4A _n=".wpdm_category .thumb"><falstruct><dc492CBFBA _n=".wpdm_category" _y="70" _x="1" _ex="14" _ey="70" _spt="3"/><hcED60A8DB _n=" " _spt="5"/><dcF540F46C _n=".thumb" _y="70" _x="16" _ex="21" _ey="70" _spt="3"/></falstruct></nbFEB82D4A><nbFA7D412E _n=".wpdm_category .thumb"><falstruct><dc4DE9D3DE _n=".wpdm_category" _y="77" _x="1" _ex="14" _ey="77" _spt="3"/><hcE9A5C4BF _n=" " _spt="5"/><dcF1859808 _n=".thumb" _y="77" _x="16" _ex="21" _ey="77" _spt="3"/></falstruct></nbFA7D412E><nbF632F482 _n=".wpdm_category .desc"><falstruct><dc41A66672 _n=".wpdm_category" _y="81" _x="1" _ex="14" _ey="81" _spt="3"/><hc0A652251 _n=" " _spt="5"/><dc85D73699 _n=".desc" _y="81" _x="16" _ex="20" _ey="81" _spt="3"/></falstruct></nbF632F482><nb19BDA7C0 _n=".middle"><falstruct><dc7F90B4D1 _n=".middle" _y="86" _x="1" _ex="7" _ey="86" _spt="3"/></falstruct></nb19BDA7C0><nb9F1AFD96 _n=".middle .det"><falstruct><dcF937EE87 _n=".middle" _y="92" _x="1" _ex="7" _ey="92" _spt="3"/><hc8CC27807 _n=" " _spt="5"/><dcD3DC6CF2 _n=".det" _y="92" _x="9" _ex="12" _ey="92" _spt="3"/></falstruct></nb9F1AFD96><nb9355483A _n="#mytable caption"><falstruct><gc8FA528D0 _n="#mytable" _y="101" _x="1" _ex="8" _ey="101" _spt="2"/><hcE4CA9743 _n=" " _spt="5"/><fc106379CA _n="caption" _y="101" _x="10" _ex="16" _ey="101" _spt="1"/></falstruct></nb9355483A><nbF71212D2 _n="#mytable th"><falstruct><gcEBE27238 _n="#mytable" _y="108" _x="1" _ex="8" _ey="108" _spt="2"/><hcE00FFB27 _n=" " _spt="5"/><fc00571121 _n="th" _y="108" _x="10" _ex="11" _ey="108" _spt="1"/></falstruct></nbF71212D2><nbF3D77EB6 _n="#mytable th.nobg"><falstruct><gcEF271E5C _n="#mytable" _y="121" _x="1" _ex="8" _ey="121" _spt="2"/><hcEC404E8B _n=" " _spt="5"/><fc0C18A48D _n="th" _y="121" _x="10" _ex="11" _ey="121" _spt="1"/><dc4425B1FC _n=".nobg" _y="121" _x="12" _ex="16" _ey="121" _spt="3"/></falstruct></nbF3D77EB6><nb51268341 _n="#mytable td"><falstruct><gcCFB4D599 _n="#mytable" _y="128" _x="1" _ex="8" _ey="128" _spt="2"/><hc42FE06D0 _n=" " _spt="5"/><fc5FC174F7 _n="td" _y="128" _x="10" _ex="11" _ey="128" _spt="1"/></falstruct></nb51268341><nb55E3EF25 _n="#mytable tr.order td"><falstruct><gcCB71B9FD _n="#mytable" _y="138" _x="1" _ex="8" _ey="138" _spt="2"/><hc463B6AB4 _n=" " _spt="5"/><fcD56F4E8E _n="tr" _y="138" _x="10" _ex="11" _ey="138" _spt="1"/><dc75F65453 _n=".order" _y="138" _x="12" _ex="17" _ey="138" _spt="3"/><hcD7BD48A3 _n=" " _spt="5"/><fc4C2560D2 _n="td" _y="138" _x="19" _ex="20" _ey="138" _spt="1"/></falstruct></nb55E3EF25><nbC465CD32 _n="#mytable th.spec"><falstruct><gcD895ADD8 _n="#mytable" _y="143" _x="1" _ex="8" _ey="143" _spt="2"/><hcD37824C7 _n=" " _spt="5"/><fc3320CEC1 _n="th" _y="143" _x="10" _ex="11" _ey="143" _spt="1"/><dcECEFCE27 _n=".spec" _y="143" _x="12" _ex="16" _ey="143" _spt="3"/></falstruct></nbC465CD32><nb8191BA4F _n="#mytable th.specalt"><falstruct><gc134C593B _n="#mytable" _y="150" _x="1" _ex="8" _ey="150" _spt="2"/><hc9E068A72 _n=" " _spt="5"/><fc13B30504 _n="th" _y="150" _x="10" _ex="11" _ey="150" _spt="1"/><dc65FFB83A _n=".specalt" _y="150" _x="12" _ex="19" _ey="150" _spt="3"/></falstruct></nb8191BA4F><nbA102718A _n=".wpdm-filelist"><falstruct><dc18BCC21A _n=".wpdm-filelist" _y="158" _x="1" _ex="14" _ey="158" _spt="3"/></falstruct></nbA102718A><nb27A52BDC _n=".ind-download"><falstruct><dc5FE26AAA _n=".ind-download" _y="162" _x="1" _ex="13" _ey="162" _spt="3"/></falstruct></nb27A52BDC></fasel></facss><_prl><gdAED29F8E _y="10" _x="16" _prt="3,2,1,102,0" _pmg="MSIE-specific CSS syntax"/><gd5BB15909 _y="92" _x="28" _prt="3,4,1,0,0" _pmg="unexpected {"/></_prl></ea152E0A52><ea0B3EE60E _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\css\icons.css" _n="icons.css" _sz="1048" _p="1" _crc="2678558676" _dt="1052872339"><facss><fasel><nb67EFD31B _n=".wrap *"><falstruct><dcAB4200E1 _n=".wrap" _y="1" _x="1" _ex="5" _ey="1" _spt="3"/><hcACDBF993 _n=" " _spt="5"/><fc890A5FE5 _n="*" _y="1" _x="7" _ex="7" _ey="1" _spt="1"/></falstruct></nb67EFD31B><nb632ABF7F _n="#icon-file-manager"><falstruct><gcE1302948 _n="#icon-file-manager" _y="5" _x="1" _ex="18" _ey="5" _spt="2"/></falstruct></nb632ABF7F><nbE148894D _n="#icon-add-new-file"><falstruct><gc15A9906E _n="#icon-add-new-file" _y="9" _x="1" _ex="18" _ey="9" _spt="2"/></falstruct></nbE148894D><nb6F650AD3 _n="#icon-error"><falstruct><gc7BB3207E _n="#icon-error" _y="12" _x="1" _ex="11" _ey="12" _spt="2"/></falstruct></nb6F650AD3><nbCC48F37D _n="#icon-import-file"><falstruct><gc5C61F820 _n="#icon-import-file" _y="15" _x="1" _ex="17" _ey="15" _spt="2"/></falstruct></nbCC48F37D><nb4E2AC54F _n="#icon-categories"><falstruct><gcD2B3EC5D _n="#icon-categories" _y="18" _x="1" _ex="16" _ey="18" _spt="2"/></falstruct></nb4E2AC54F><nbC88D9F19 _n="#icon-template"><falstruct><gcED304166 _n="#icon-template" _y="21" _x="1" _ex="14" _ey="21" _spt="2"/></falstruct></nbC88D9F19><nb4AEFA92B _n="#icon-settings"><falstruct><gc74B0D0D9 _n="#icon-settings" _y="24" _x="1" _ex="14" _ey="24" _spt="2"/></falstruct></nb4AEFA92B><nbC4C22AB5 _n="#icon-stats"><falstruct><gc778FCA02 _n="#icon-stats" _y="27" _x="1" _ex="11" _ey="27" _spt="2"/></falstruct></nbC4C22AB5><nb22E7466F _n=".infoicon"><falstruct><dc9FBA5DA5 _n=".infoicon" _y="31" _x="1" _ex="9" _ey="31" _spt="3"/></falstruct></nb22E7466F></fasel></facss></ea0B3EE60E><eaFA7F6E8A _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\css\jqueryFileTree.css" _n="jqueryFileTree.css" _sz="5973" _p="1" _crc="2435237824" _dt="1052872339"><facss><fasel><nb67EFD31B _n="UL.jqueryFileTree"><falstruct><fc2F27E105 _n="UL" _y="1" _x="1" _ex="2" _ey="1" _spt="1"/><dc513A44C1 _n=".jqueryFileTree" _y="1" _x="3" _ex="17" _ey="1" _spt="3"/></falstruct></nb67EFD31B><nbA4BCFE30 _n="UL.jqueryFileTree LI"><falstruct><fc6AD39678 _n="UL" _y="9" _x="1" _ex="2" _ey="9" _spt="1"/><dc96AC058E _n=".jqueryFileTree" _y="9" _x="3" _ex="17" _ey="9" _spt="3"/><hcA81E95F7 _n=" " _spt="5"/><fcC823BC40 _n="LI" _y="9" _x="19" _ex="20" _ey="9" _spt="1"/></falstruct></nbA4BCFE30><nb6F650AD3 _n="UL.jqueryFileTree A"><falstruct><fc27AD38CD _n="UL" _y="17" _x="1" _ex="2" _ey="17" _spt="1"/><dcFEED5FA8 _n=".jqueryFileTree" _y="17" _x="3" _ex="17" _ey="17" _spt="3"/><hc1CC35BC7 _n=" " _spt="5"/><fc204CDE2F _n="A" _y="17" _x="19" _ex="19" _ey="17" _spt="1"/></falstruct></nb6F650AD3><nb0F1BDE56 _n="UL.jqueryFileTree A:hover"><falstruct><fc107B3C0C _n="UL" _y="24" _x="1" _ex="2" _ey="24" _spt="1"/><dcBB1928D5 _n=".jqueryFileTree" _y="24" _x="3" _ex="17" _ey="24" _spt="3"/><hcDB551A88 _n=" " _spt="5"/><fc65B8A952 _n="A" _y="24" _x="19" _ex="19" _ey="24" _spt="1"/><ecF6FD1389 _n=":hover" _spt="4"/></falstruct></nb0F1BDE56><nb85F331AC _n=".jqueryFileTree LI.directory"><falstruct><dc1042EABA _n=".jqueryFileTree" _y="29" _x="1" _ex="15" _ey="29" _spt="3"/><hcF26CEED5 _n=" " _spt="5"/><fcCBC8EA7B _n="LI" _y="29" _x="17" _ex="18" _ey="29" _spt="1"/><dc86E5B91D _n=".directory" _y="29" _x="19" _ex="28" _ey="29" _spt="3"/></falstruct></nb85F331AC><nb26222A0B _n=".jqueryFileTree LI.expanded"><falstruct><dc55B69DC7 _n=".jqueryFileTree" _y="30" _x="1" _ex="15" _ey="30" _spt="3"/><hc35FAAF9A _n=" " _spt="5"/><fc8E3C9D06 _n="LI" _y="30" _x="17" _ex="18" _ey="30" _spt="1"/><dc0213445F _n=".expanded" _y="30" _x="19" _ex="27" _ey="30" _spt="3"/></falstruct></nb26222A0B><nb6B5C84BE _n=".jqueryFileTree LI.file"><falstruct><dc75255602 _n=".jqueryFileTree" _y="31" _x="1" _ex="15" _ey="31" _spt="3"/><hc970B526D _n=" " _spt="5"/><fcAEAF56C3 _n="LI" _y="31" _x="17" _ex="18" _ey="31" _spt="1"/><dc5054AE0B _n=".file" _y="31" _x="19" _ex="23" _ey="31" _spt="3"/></falstruct></nb6B5C84BE><nb434596B3 _n=".jqueryFileTree LI.wait"><falstruct><dc30D1217F _n=".jqueryFileTree" _y="32" _x="1" _ex="15" _ey="32" _spt="3"/><hc509D1322 _n=" " _spt="5"/><fcEB5B21BE _n="LI" _y="32" _x="17" _ex="18" _ey="32" _spt="1"/><dcA6B35AEC _n=".wait" _y="32" _x="19" _ex="23" _ey="32" _spt="3"/></falstruct></nb434596B3><nb0E3B3806 _n=".jqueryFileTree LI.ext_3gp"><falstruct><dcCC1D819F _n=".jqueryFileTree" _y="34" _x="1" _ex="15" _ey="34" _spt="3"/><hc2E3385F0 _n=" " _spt="5"/><fc1797815E _n="LI" _y="34" _x="17" _ex="18" _ey="34" _spt="1"/><dc4294AC38 _n=".ext_3gp" _y="34" _x="19" _ex="26" _ey="34" _spt="3"/></falstruct></nb0E3B3806><nbFA7D412E _n=".jqueryFileTree LI.ext_afp"><falstruct><dc89E9F6E2 _n=".jqueryFileTree" _y="35" _x="1" _ex="15" _ey="35" _spt="3"/><hcE9A5C4BF _n=" " _spt="5"/><fc5263F623 _n="LI" _y="35" _x="17" _ex="18" _ey="35" _spt="1"/><dc621B13AA _n=".ext_afp" _y="35" _x="19" _ex="26" _ey="35" _spt="3"/></falstruct></nbFA7D412E><nbB703EF9B _n=".jqueryFileTree LI.ext_afpa"><falstruct><dcA97A3D27 _n=".jqueryFileTree" _y="36" _x="1" _ex="15" _ey="36" _spt="3"/><hc4B543948 _n=" " _spt="5"/><fc72F03DE6 _n="LI" _y="36" _x="17" _ex="18" _ey="36" _spt="1"/><dc734EEC87 _n=".ext_afpa" _y="36" _x="19" _ex="27" _ey="36" _spt="3"/></falstruct></nbB703EF9B><nb9F1AFD96 _n=".jqueryFileTree LI.ext_asp"><falstruct><dcEC8E4A5A _n=".jqueryFileTree" _y="37" _x="1" _ex="15" _ey="37" _spt="3"/><hc8CC27807 _n=" " _spt="5"/><fc37044A9B _n="LI" _y="37" _x="17" _ex="18" _ey="37" _spt="1"/><dc4843F426 _n=".ext_asp" _y="37" _x="19" _ex="26" _ey="37" _spt="3"/></falstruct></nb9F1AFD96><nbD2645323 _n=".jqueryFileTree LI.ext_aspx"><falstruct><dc47D58835 _n=".jqueryFileTree" _y="38" _x="1" _ex="15" _ey="38" _spt="3"/><hcA5FB8C5A _n=" " _spt="5"/><fc9C5F88F4 _n="LI" _y="38" _x="17" _ex="18" _ey="38" _spt="1"/><dc62F80770 _n=".ext_aspx" _y="38" _x="19" _ex="27" _ey="38" _spt="3"/></falstruct></nbD2645323><nb71B54884 _n=".jqueryFileTree LI.ext_avi"><falstruct><dc0221FF48 _n=".jqueryFileTree" _y="39" _x="1" _ex="15" _ey="39" _spt="3"/><hc626DCD15 _n=" " _spt="5"/><fcD9ABFF89 _n="LI" _y="39" _x="17" _ex="18" _ey="39" _spt="1"/><dc91B17858 _n=".ext_avi" _y="39" _x="19" _ex="26" _ey="39" _spt="3"/></falstruct></nb71B54884><nb3CCBE631 _n=".jqueryFileTree LI.ext_bat"><falstruct><dc22B2348D _n=".jqueryFileTree" _y="40" _x="1" _ex="15" _ey="40" _spt="3"/><hcC09C30E2 _n=" " _spt="5"/><fcF938344C _n="LI" _y="40" _x="17" _ex="18" _ey="40" _spt="1"/><dc4B9D3121 _n=".ext_bat" _y="40" _x="19" _ex="26" _ey="40" _spt="3"/></falstruct></nb3CCBE631><nb14D2F43C _n=".jqueryFileTree LI.ext_bmp"><falstruct><dc674643F0 _n=".jqueryFileTree" _y="41" _x="1" _ex="15" _ey="41" _spt="3"/><hc070A71AD _n=" " _spt="5"/><fcBCCC4331 _n="LI" _y="41" _x="17" _ex="18" _ey="41" _spt="1"/><dcD913FB0E _n=".ext_bmp" _y="41" _x="19" _ex="26" _ey="41" _spt="3"/></falstruct></nb14D2F43C><nb59AC5A89 _n=".jqueryFileTree LI.ext_c"><falstruct><dc74A257D5 _n=".jqueryFileTree" _y="42" _x="1" _ex="15" _ey="42" _spt="3"/><hc968C53BA _n=" " _spt="5"/><fcAF285714 _n="LI" _y="42" _x="17" _ex="18" _ey="42" _spt="1"/><dc3023F132 _n=".ext_c" _y="42" _x="19" _ex="24" _ey="42" _spt="3"/></falstruct></nb59AC5A89><nb42C29764 _n=".jqueryFileTree LI.ext_cfm"><falstruct><dc315620A8 _n=".jqueryFileTree" _y="43" _x="1" _ex="15" _ey="43" _spt="3"/><hc511A12F5 _n=" " _spt="5"/><fcEADC2069 _n="LI" _y="43" _x="17" _ex="18" _ey="43" _spt="1"/><dcA265785B _n=".ext_cfm" _y="43" _x="19" _ex="26" _ey="43" _spt="3"/></falstruct></nb42C29764><nb0FBC39D1 _n=".jqueryFileTree LI.ext_cgi"><falstruct><dc11C5EB6D _n=".jqueryFileTree" _y="44" _x="1" _ex="15" _ey="44" _spt="3"/><hcF3EBEF02 _n=" " _spt="5"/><fcCA4FEBAC _n="LI" _y="44" _x="17" _ex="18" _ey="44" _spt="1"/><dc84990B57 _n=".ext_cgi" _y="44" _x="19" _ex="26" _ey="44" _spt="3"/></falstruct></nb0FBC39D1><nb27A52BDC _n=".jqueryFileTree LI.ext_com"><falstruct><dc54319C10 _n=".jqueryFileTree" _y="45" _x="1" _ex="15" _ey="45" _spt="3"/><hc347DAE4D _n=" " _spt="5"/><fc8FBB9CD1 _n="LI" _y="45" _x="17" _ex="18" _ey="45" _spt="1"/><dcEC198BFC _n=".ext_com" _y="45" _x="19" _ex="26" _ey="45" _spt="3"/></falstruct></nb27A52BDC><nb6ADB8569 _n=".jqueryFileTree LI.ext_cpp"><falstruct><dc5ACCC28B _n=".jqueryFileTree" _y="46" _x="1" _ex="15" _ey="46" _spt="3"/><hcDB69FB9A _n=" " _spt="5"/><fcB9D15C7C _n="LI" _y="46" _x="17" _ex="18" _ey="46" _spt="1"/><dc86D9377A _n=".ext_cpp" _y="46" _x="19" _ex="26" _ey="46" _spt="3"/></falstruct></nb6ADB8569><nbE4DF62A4 _n=".jqueryFileTree LI.ext_css"><falstruct><dc1F38B5F6 _n=".jqueryFileTree" _y="47" _x="1" _ex="15" _ey="47" _spt="3"/><hc1CFFBAD5 _n=" " _spt="5"/><fcFC252B01 _n="LI" _y="47" _x="17" _ex="18" _ey="47" _spt="1"/><dcADBC7BFC _n=".ext_css" _y="47" _x="19" _ex="26" _ey="47" _spt="3"/></falstruct></nbE4DF62A4><nbA9A1CC11 _n=".jqueryFileTree LI.ext_doc"><falstruct><dc3FAB7E33 _n=".jqueryFileTree" _y="48" _x="1" _ex="15" _ey="48" _spt="3"/><hcBE0E4722 _n=" " _spt="5"/><fcDCB6E0C4 _n="LI" _y="48" _x="17" _ex="18" _ey="48" _spt="1"/><dcC1BB8292 _n=".ext_doc" _y="48" _x="19" _ex="26" _ey="48" _spt="3"/></falstruct></nbA9A1CC11><nb81B8DE1C _n=".jqueryFileTree LI.ext_exe"><falstruct><dc7A5F094E _n=".jqueryFileTree" _y="49" _x="1" _ex="15" _ey="49" _spt="3"/><hc7998066D _n=" " _spt="5"/><fc994297B9 _n="LI" _y="49" _x="17" _ex="18" _ey="49" _spt="1"/><dc73BDCEE9 _n=".ext_exe" _y="49" _x="19" _ex="26" _ey="49" _spt="3"/></falstruct></nb81B8DE1C><nbCCC670A9 _n=".jqueryFileTree LI.ext_gif"><falstruct><dcD104CB21 _n=".jqueryFileTree" _y="50" _x="1" _ex="15" _ey="50" _spt="3"/><hc50A1F230 _n=" " _spt="5"/><fc321955D6 _n="LI" _y="50" _x="17" _ex="18" _ey="50" _spt="1"/><dcFCB857B2 _n=".ext_gif" _y="50" _x="19" _ex="26" _ey="50" _spt="3"/></falstruct></nbCCC670A9><nb6F176B0E _n=".jqueryFileTree LI.ext_fla"><falstruct><dc94F0BC5C _n=".jqueryFileTree" _y="51" _x="1" _ex="15" _ey="51" _spt="3"/><hc9737B37F _n=" " _spt="5"/><fc77ED22AB _n="LI" _y="51" _x="17" _ex="18" _ey="51" _spt="1"/><dc05EFEA26 _n=".ext_fla" _y="51" _x="19" _ex="26" _ey="51" _spt="3"/></falstruct></nb6F176B0E><nb2269C5BB _n=".jqueryFileTree LI.ext_h"><falstruct><dcB4637799 _n=".jqueryFileTree" _y="52" _x="1" _ex="15" _ey="52" _spt="3"/><hc35C64E88 _n=" " _spt="5"/><fc577EE96E _n="LI" _y="52" _x="17" _ex="18" _ey="52" _spt="1"/><dcDE5D2FF3 _n=".ext_h" _y="52" _x="19" _ex="24" _ey="52" _spt="3"/></falstruct></nb2269C5BB><nb0A70D7B6 _n=".jqueryFileTree LI.ext_htm"><falstruct><dcF19700E4 _n=".jqueryFileTree" _y="53" _x="1" _ex="15" _ey="53" _spt="3"/><hcF2500FC7 _n=" " _spt="5"/><fc128A9E13 _n="LI" _y="53" _x="17" _ex="18" _ey="53" _spt="1"/><dc2D8FB114 _n=".ext_htm" _y="53" _x="19" _ex="26" _ey="53" _spt="3"/></falstruct></nb0A70D7B6><nb470E7903 _n=".jqueryFileTree LI.ext_html"><falstruct><dc0D5BA004 _n=".jqueryFileTree" _y="54" _x="1" _ex="15" _ey="54" _spt="3"/><hc8CFE9915 _n=" " _spt="5"/><fcEE463EF3 _n="LI" _y="54" _x="17" _ex="18" _ey="54" _spt="1"/><dc7B4D7B60 _n=".ext_html" _y="54" _x="19" _ex="27" _ey="54" _spt="3"/></falstruct></nb470E7903><nbB348002B _n=".jqueryFileTree LI.ext_jar"><falstruct><dc48AFD779 _n=".jqueryFileTree" _y="55" _x="1" _ex="15" _ey="55" _spt="3"/><hc4B68D85A _n=" " _spt="5"/><fcABB2498E _n="LI" _y="55" _x="17" _ex="18" _ey="55" _spt="1"/><dc20404101 _n=".ext_jar" _y="55" _x="19" _ex="26" _ey="55" _spt="3"/></falstruct></nbB348002B><nbFE36AE9E _n=".jqueryFileTree LI.ext_jpg"><falstruct><dc683C1CBC _n=".jqueryFileTree" _y="56" _x="1" _ex="15" _ey="56" _spt="3"/><hcE99925AD _n=" " _spt="5"/><fc8B21824B _n="LI" _y="56" _x="17" _ex="18" _ey="56" _spt="1"/><dc172B3EA6 _n=".ext_jpg" _y="56" _x="19" _ex="26" _ey="56" _spt="3"/></falstruct></nbFE36AE9E><nbD62FBC93 _n=".jqueryFileTree LI.ext_jpeg"><falstruct><dc2DC86BC1 _n=".jqueryFileTree" _y="57" _x="1" _ex="15" _ey="57" _spt="3"/><hc2E0F64E2 _n=" " _spt="5"/><fcCED5F536 _n="LI" _y="57" _x="17" _ex="18" _ey="57" _spt="1"/><dcA550E697 _n=".ext_jpeg" _y="57" _x="19" _ex="27" _ey="57" _spt="3"/></falstruct></nbD62FBC93><nb9B511226 _n=".jqueryFileTree LI.ext_js"><falstruct><dc8693A9AE _n=".jqueryFileTree" _y="58" _x="1" _ex="15" _ey="58" _spt="3"/><hc073690BF _n=" " _spt="5"/><fc658E3759 _n="LI" _y="58" _x="17" _ex="18" _ey="58" _spt="1"/><dc531751EB _n=".ext_js" _y="58" _x="19" _ex="25" _ey="58" _spt="3"/></falstruct></nb9B511226><nb38800981 _n=".jqueryFileTree LI.ext_lasso"><falstruct><dcC367DED3 _n=".jqueryFileTree" _y="59" _x="1" _ex="15" _ey="59" _spt="3"/><hcC0A0D1F0 _n=" " _spt="5"/><fc207A4024 _n="LI" _y="59" _x="17" _ex="18" _ey="59" _spt="1"/><dcE43B2AF1 _n=".ext_lasso" _y="59" _x="19" _ex="28" _ey="59" _spt="3"/></falstruct></nb38800981><nb75FEA734 _n=".jqueryFileTree LI.ext_log"><falstruct><dcE3F41516 _n=".jqueryFileTree" _y="60" _x="1" _ex="15" _ey="60" _spt="3"/><hc62512C07 _n=" " _spt="5"/><fc00E98BE1 _n="LI" _y="60" _x="17" _ex="18" _ey="60" _spt="1"/><dc199CAF35 _n=".ext_log" _y="60" _x="19" _ex="26" _ey="60" _spt="3"/></falstruct></nb75FEA734><nb5DE7B539 _n=".jqueryFileTree LI.ext_m4p"><falstruct><dcA600626B _n=".jqueryFileTree" _y="61" _x="1" _ex="15" _ey="61" _spt="3"/><hcA5C76D48 _n=" " _spt="5"/><fc451DFC9C _n="LI" _y="61" _x="17" _ex="18" _ey="61" _spt="1"/><dc304C747A _n=".ext_m4p" _y="61" _x="19" _ex="26" _ey="61" _spt="3"/></falstruct></nb5DE7B539><nb10991B8C _n=".jqueryFileTree LI.ext_mov"><falstruct><dcB5E4764E _n=".jqueryFileTree" _y="62" _x="1" _ex="15" _ey="62" _spt="3"/><hc34414F5F _n=" " _spt="5"/><fc56F9E8B9 _n="LI" _y="62" _x="17" _ex="18" _ey="62" _spt="1"/><dc95F17846 _n=".ext_mov" _y="62" _x="19" _ex="26" _ey="62" _spt="3"/></falstruct></nb10991B8C><nb0BF7D661 _n=".jqueryFileTree LI.ext_mp3"><falstruct><dcF0100133 _n=".jqueryFileTree" _y="63" _x="1" _ex="15" _ey="63" _spt="3"/><hcF3D70E10 _n=" " _spt="5"/><fc130D9FC4 _n="LI" _y="63" _x="17" _ex="18" _ey="63" _spt="1"/><dcB23E5412 _n=".ext_mp3" _y="63" _x="19" _ex="26" _ey="63" _spt="3"/></falstruct></nb0BF7D661><nb468978D4 _n=".jqueryFileTree LI.ext_mp4"><falstruct><dcD083CAF6 _n=".jqueryFileTree" _y="64" _x="1" _ex="15" _ey="64" _spt="3"/><hc5126F3E7 _n=" " _spt="5"/><fc339E5401 _n="LI" _y="64" _x="17" _ex="18" _ey="64" _spt="1"/><dc0589D943 _n=".ext_mp4" _y="64" _x="19" _ex="26" _ey="64" _spt="3"/></falstruct></nb468978D4><nb6E906AD9 _n=".jqueryFileTree LI.ext_mpg"><falstruct><dc9577BD8B _n=".jqueryFileTree" _y="65" _x="1" _ex="15" _ey="65" _spt="3"/><hc96B0B2A8 _n=" " _spt="5"/><fc766A237C _n="LI" _y="65" _x="17" _ex="18" _ey="65" _spt="1"/><dcEBA4847B _n=".ext_mpg" _y="65" _x="19" _ex="26" _ey="65" _spt="3"/></falstruct></nb6E906AD9><nb23EEC46C _n=".jqueryFileTree LI.ext_mpeg"><falstruct><dcF4BE560D _n=".jqueryFileTree" _y="66" _x="1" _ex="15" _ey="66" _spt="3"/><hc751B6F1C _n=" " _spt="5"/><fc17A3C8FA _n="LI" _y="66" _x="17" _ex="18" _ey="66" _spt="1"/><dc32A195A0 _n=".ext_mpeg" _y="66" _x="19" _ex="27" _ey="66" _spt="3"/></falstruct></nb23EEC46C><nb4AADF622 _n=".jqueryFileTree LI.ext_ogg"><falstruct><dcB14A2170 _n=".jqueryFileTree" _y="67" _x="1" _ex="15" _ey="67" _spt="3"/><hcB28D2E53 _n=" " _spt="5"/><fc5257BF87 _n="LI" _y="67" _x="17" _ex="18" _ey="67" _spt="1"/><dcC19D51A9 _n=".ext_ogg" _y="67" _x="19" _ex="26" _ey="67" _spt="3"/></falstruct></nb4AADF622><nb07D35897 _n=".jqueryFileTree LI.ext_pcx"><falstruct><dc91D9EAB5 _n=".jqueryFileTree" _y="68" _x="1" _ex="15" _ey="68" _spt="3"/><hc107CD3A4 _n=" " _spt="5"/><fc72C47442 _n="LI" _y="68" _x="17" _ex="18" _ey="68" _spt="1"/><dc1FD2E520 _n=".ext_pcx" _y="68" _x="19" _ex="26" _ey="68" _spt="3"/></falstruct></nb07D35897><nb2FCA4A9A _n=".jqueryFileTree LI.ext_pdf"><falstruct><dcD42D9DC8 _n=".jqueryFileTree" _y="69" _x="1" _ex="15" _ey="69" _spt="3"/><hcD7EA92EB _n=" " _spt="5"/><fc3730033F _n="LI" _y="69" _x="17" _ex="18" _ey="69" _spt="1"/><dcB433FC48 _n=".ext_pdf" _y="69" _x="19" _ex="26" _ey="69" _spt="3"/></falstruct></nb2FCA4A9A><nb62B4E42F _n=".jqueryFileTree LI.ext_php"><falstruct><dc7F765FA7 _n=".jqueryFileTree" _y="70" _x="1" _ex="15" _ey="70" _spt="3"/><hcFED366B6 _n=" " _spt="5"/><fc9C6BC150 _n="LI" _y="70" _x="17" _ex="18" _ey="70" _spt="1"/><dcB39D5519 _n=".ext_php" _y="70" _x="19" _ex="26" _ey="70" _spt="3"/></falstruct></nb62B4E42F><nbC165FF88 _n=".jqueryFileTree LI.ext_png"><falstruct><dc3A8228DA _n=".jqueryFileTree" _y="71" _x="1" _ex="15" _ey="71" _spt="3"/><hc394527F9 _n=" " _spt="5"/><fcD99FB62D _n="LI" _y="71" _x="17" _ex="18" _ey="71" _spt="1"/><dc0D0CC181 _n=".ext_png" _y="71" _x="19" _ex="26" _ey="71" _spt="3"/></falstruct></nbC165FF88><nb8C1B513D _n=".jqueryFileTree LI.ext_ppt"><falstruct><dc1A11E31F _n=".jqueryFileTree" _y="72" _x="1" _ex="15" _ey="72" _spt="3"/><hc9BB4DA0E _n=" " _spt="5"/><fcF90C7DE8 _n="LI" _y="72" _x="17" _ex="18" _ey="72" _spt="1"/><dc3035DA11 _n=".ext_ppt" _y="72" _x="19" _ex="26" _ey="72" _spt="3"/></falstruct></nb8C1B513D><nbA4024330 _n=".jqueryFileTree LI.ext_psd"><falstruct><dc5FE59462 _n=".jqueryFileTree" _y="73" _x="1" _ex="15" _ey="73" _spt="3"/><hc5C229B41 _n=" " _spt="5"/><fcBCF80A95 _n="LI" _y="73" _x="17" _ex="18" _ey="73" _spt="1"/><dcD366A265 _n=".ext_psd" _y="73" _x="19" _ex="26" _ey="73" _spt="3"/></falstruct></nbA4024330><nbE97CED85 _n=".jqueryFileTree LI.ext_pl"><falstruct><dcA3293482 _n=".jqueryFileTree" _y="74" _x="1" _ex="15" _ey="74" _spt="3"/><hc228C0D93 _n=" " _spt="5"/><fc4034AA75 _n="LI" _y="74" _x="17" _ex="18" _ey="74" _spt="1"/><dcD09FDB52 _n=".ext_pl" _y="74" _x="19" _ex="25" _ey="74" _spt="3"/></falstruct></nbE97CED85><nb1D3A94AD _n=".jqueryFileTree LI.ext_py"><falstruct><dcE6DD43FF _n=".jqueryFileTree" _y="75" _x="1" _ex="15" _ey="75" _spt="3"/><hcE51A4CDC _n=" " _spt="5"/><fc05C0DD08 _n="LI" _y="75" _x="17" _ex="18" _ey="75" _spt="1"/><dc54797485 _n=".ext_py" _y="75" _x="19" _ex="25" _ey="75" _spt="3"/></falstruct></nb1D3A94AD><nb50443A18 _n=".jqueryFileTree LI.ext_rb"><falstruct><dcC64E883A _n=".jqueryFileTree" _y="76" _x="1" _ex="15" _ey="76" _spt="3"/><hc47EBB12B _n=" " _spt="5"/><fc255316CD _n="LI" _y="76" _x="17" _ex="18" _ey="76" _spt="1"/><dcBA3A18FB _n=".ext_rb" _y="76" _x="19" _ex="25" _ey="76" _spt="3"/></falstruct></nb50443A18><nb785D2815 _n=".jqueryFileTree LI.ext_rbx"><falstruct><dc83BAFF47 _n=".jqueryFileTree" _y="77" _x="1" _ex="15" _ey="77" _spt="3"/><hc807DF064 _n=" " _spt="5"/><fc60A761B0 _n="LI" _y="77" _x="17" _ex="18" _ey="77" _spt="1"/><dc22698A4F _n=".ext_rbx" _y="77" _x="19" _ex="26" _ey="77" _spt="3"/></falstruct></nb785D2815><nb352386A0 _n=".jqueryFileTree LI.ext_rhtml"><falstruct><dc28E13D28 _n=".jqueryFileTree" _y="78" _x="1" _ex="15" _ey="78" _spt="3"/><hcA9440439 _n=" " _spt="5"/><fcCBFCA3DF _n="LI" _y="78" _x="17" _ex="18" _ey="78" _spt="1"/><dcC3F8C93F _n=".ext_rhtml" _y="78" _x="19" _ex="28" _ey="78" _spt="3"/></falstruct></nb352386A0><nb96F29D07 _n=".jqueryFileTree LI.ext_rpm"><falstruct><dc6D154A55 _n=".jqueryFileTree" _y="79" _x="1" _ex="15" _ey="79" _spt="3"/><hc6ED24576 _n=" " _spt="5"/><fc8E08D4A2 _n="LI" _y="79" _x="17" _ex="18" _ey="79" _spt="1"/><dc56A83F4A _n=".ext_rpm" _y="79" _x="19" _ex="26" _ey="79" _spt="3"/></falstruct></nb96F29D07><nbDB8C33B2 _n=".jqueryFileTree LI.ext_ruby"><falstruct><dc4D868190 _n=".jqueryFileTree" _y="80" _x="1" _ex="15" _ey="80" _spt="3"/><hcCC23B881 _n=" " _spt="5"/><fcAE9B1F67 _n="LI" _y="80" _x="17" _ex="18" _ey="80" _spt="1"/><dc615E2A1E _n=".ext_ruby" _y="80" _x="19" _ex="27" _ey="80" _spt="3"/></falstruct></nbDB8C33B2><nbF39521BF _n=".jqueryFileTree LI.ext_sql"><falstruct><dc0872F6ED _n=".jqueryFileTree" _y="81" _x="1" _ex="15" _ey="81" _spt="3"/><hc0BB5F9CE _n=" " _spt="5"/><fcEB6F681A _n="LI" _y="81" _x="17" _ex="18" _ey="81" _spt="1"/><dcFCE84E4A _n=".ext_sql" _y="81" _x="19" _ex="26" _ey="81" _spt="3"/></falstruct></nbF39521BF><nbBEEB8F0A _n=".jqueryFileTree LI.ext_swf"><falstruct><dc1B96E2C8 _n=".jqueryFileTree" _y="82" _x="1" _ex="15" _ey="82" _spt="3"/><hc9A33DBD9 _n=" " _spt="5"/><fcF88B7C3F _n="LI" _y="82" _x="17" _ex="18" _ey="82" _spt="1"/><dcEE4D076D _n=".ext_swf" _y="82" _x="19" _ex="26" _ey="82" _spt="3"/></falstruct></nbBEEB8F0A><nbA58542E7 _n=".jqueryFileTree LI.ext_tif"><falstruct><dc5E6295B5 _n=".jqueryFileTree" _y="83" _x="1" _ex="15" _ey="83" _spt="3"/><hc5DA59A96 _n=" " _spt="5"/><fcBD7F0B42 _n="LI" _y="83" _x="17" _ex="18" _ey="83" _spt="1"/><dcF1CC0CC3 _n=".ext_tif" _y="83" _x="19" _ex="26" _ey="83" _spt="3"/></falstruct></nbA58542E7><nbE8FBEC52 _n=".jqueryFileTree LI.ext_tiff"><falstruct><dc7EF15E70 _n=".jqueryFileTree" _y="84" _x="1" _ex="15" _ey="84" _spt="3"/><hcFF546761 _n=" " _spt="5"/><fc9DECC087 _n="LI" _y="84" _x="17" _ex="18" _ey="84" _spt="1"/><dc644155A3 _n=".ext_tiff" _y="84" _x="19" _ex="27" _ey="84" _spt="3"/></falstruct></nbE8FBEC52><nbC0E2FE5F _n=".jqueryFileTree LI.ext_txt"><falstruct><dc3B05290D _n=".jqueryFileTree" _y="85" _x="1" _ex="15" _ey="85" _spt="3"/><hc38C2262E _n=" " _spt="5"/><fcD818B7FA _n="LI" _y="85" _x="17" _ex="18" _ey="85" _spt="1"/><dc1477428D _n=".ext_txt" _y="85" _x="19" _ex="26" _ey="85" _spt="3"/></falstruct></nbC0E2FE5F><nb8D9C50EA _n=".jqueryFileTree LI.ext_vb"><falstruct><dc516D0AC6 _n=".jqueryFileTree" _y="86" _x="1" _ex="15" _ey="86" _spt="3"/><hcD0C833D7 _n=" " _spt="5"/><fcB2709431 _n="LI" _y="86" _x="17" _ex="18" _ey="86" _spt="1"/><dc57B9710E _n=".ext_vb" _y="86" _x="19" _ex="25" _ey="86" _spt="3"/></falstruct></nb8D9C50EA><nbEF7EAAE9 _n=".jqueryFileTree LI.ext_wav"><falstruct><dc14997DBB _n=".jqueryFileTree" _y="87" _x="1" _ex="15" _ey="87" _spt="3"/><hc175E7298 _n=" " _spt="5"/><fcF784E34C _n="LI" _y="87" _x="17" _ex="18" _ey="87" _spt="1"/><dc949416D5 _n=".ext_wav" _y="87" _x="19" _ex="26" _ey="87" _spt="3"/></falstruct></nbEF7EAAE9><nbA200045C _n=".jqueryFileTree LI.ext_wmv"><falstruct><dc340AB67E _n=".jqueryFileTree" _y="88" _x="1" _ex="15" _ey="88" _spt="3"/><hcB5AF8F6F _n=" " _spt="5"/><fcD7172889 _n="LI" _y="88" _x="17" _ex="18" _ey="88" _spt="1"/><dcB4CA6294 _n=".ext_wmv" _y="88" _x="19" _ex="26" _ey="88" _spt="3"/></falstruct></nbA200045C><nb8A191651 _n=".jqueryFileTree LI.ext_xls"><falstruct><dc71FEC103 _n=".jqueryFileTree" _y="89" _x="1" _ex="15" _ey="89" _spt="3"/><hc7239CE20 _n=" " _spt="5"/><fc92E35FF4 _n="LI" _y="89" _x="17" _ex="18" _ey="89" _spt="1"/><dc54E920A2 _n=".ext_xls" _y="89" _x="19" _ex="26" _ey="89" _spt="3"/></falstruct></nb8A191651><nbC767B8E4 _n=".jqueryFileTree LI.ext_xml"><falstruct><dcDAA5036C _n=".jqueryFileTree" _y="90" _x="1" _ex="15" _ey="90" _spt="3"/><hc5B003A7D _n=" " _spt="5"/><fc39B89D9B _n="LI" _y="90" _x="17" _ex="18" _ey="90" _spt="1"/><dcC8D73819 _n=".ext_xml" _y="90" _x="19" _ex="26" _ey="90" _spt="3"/></falstruct></nbC767B8E4><nb64B6A343 _n=".jqueryFileTree LI.ext_zip"><falstruct><dc9F517411 _n=".jqueryFileTree" _y="91" _x="1" _ex="15" _ey="91" _spt="3"/><hc9C967B32 _n=" " _spt="5"/><fc7C4CEAE6 _n="LI" _y="91" _x="17" _ex="18" _ey="91" _spt="1"/><dc82140834 _n=".ext_zip" _y="91" _x="19" _ex="26" _ey="91" _spt="3"/></falstruct></nb64B6A343></fasel></facss></eaFA7F6E8A></ca0B8F7417><ca0470CE40 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\js" _n="js"><ea351F75DE _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\js\jquery.colorbox-min.js" _n="jquery.colorbox-min.js" _sz="9820" _p="1" _crc="2679776101" _dt="1052872340"><fajsl><fajsvcls/><fajsvar><pcCABEC7C9 _n="O" _y="4" _x="40" _ex="42" _ey="4"/><pc97E3B02F _n="S" _y="4" _x="5338" _ex="5340" _ey="4"/></fajsvar></fajsl></ea351F75DE><eaE4E7AE75 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\js\jqueryFileTree.js" _n="jqueryFileTree.js" _sz="3805" _p="1" _crc="569444043" _dt="1052872340"/></ca0470CE40><ea2C500211 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\class.db.php" _n="class.db.php" _sz="1032" _p="1" _crc="802935355" _dt="1052872340"><facls><ja22FB9999 _n="DMDB" _y="3" _x="12" _ex="1" _ey="39" _exp="1" _s="0"><fafnc><oa969508E5 _n="AddNew" _y="6" _x="20" _ex="5" _ey="8" _al="$table, $data" _mod="65792" _s="1"><favar><ab466BD0D3 _n="table" _y="6" _x="21" _r="3" _pri="1"/><ab053F6F95 _n="data" _y="6" _x="29" _r="3" _pri="2"/></favar><fapar><na466BD0D3 _n="table" _y="6" _x="21" _pri="1" _to="0"/><na053F6F95 _n="data" _y="6" _x="29" _pri="2" _to="0"/></fapar></oa969508E5><oa7B9054A5 _n="Update" _y="10" _x="20" _ex="5" _ey="12" _al="$table, $data, $cond" _mod="65792" _s="1"><favar><ab466BD0D3 _n="table" _y="10" _x="21" _r="3" _pri="1"/><ab053F6F95 _n="data" _y="10" _x="29" _r="3" _pri="2"/><abD21473E7 _n="cond" _y="10" _x="36" _r="3" _pri="3"/></favar><fapar><na466BD0D3 _n="table" _y="10" _x="21" _pri="1" _to="0"/><na053F6F95 _n="data" _y="10" _x="29" _pri="2" _to="0"/><naD21473E7 _n="cond" _y="10" _x="36" _pri="3" _to="0"/></fapar></oa7B9054A5><oaE7221ABB _n="Delete" _y="14" _x="20" _ex="5" _ey="18" _al="$table, $cond" _mod="65792" _s="1"><favar><ab466BD0D3 _n="table" _y="14" _x="21" _r="4" _pri="1"/><abD21473E7 _n="cond" _y="14" _x="29" _r="4" _pri="2"/><abA343B7BF _n="d" _y="15" _x="11" _r="2" _vr=".mysql_fetch_assoc()"/></favar><fapar><na466BD0D3 _n="table" _y="14" _x="21" _pri="1" _to="0"/><naD21473E7 _n="cond" _y="14" _x="29" _pri="2" _to="0"/></fapar></oaE7221ABB><oaCE705B71 _n="getById" _y="20" _x="21" _ex="5" _ey="22" _al="$table, $id" _mod="65792" _vr=".mysql_fetch_assoc()" _s="1"><favar><ab466BD0D3 _n="table" _y="20" _x="22" _r="3" _pri="1"/><abC9360499 _n="id" _y="20" _x="30" _r="3" _pri="2"/></favar><fapar><na466BD0D3 _n="table" _y="20" _x="22" _pri="1" _to="0"/><naC9360499 _n="id" _y="20" _x="30" _pri="2" _to="0"/></fapar></oaCE705B71><oaB882B587 _n="getData" _y="24" _x="21" _ex="5" _ey="30" _al="$table, $where, $limit" _mod="65792" _vr=".mysql_fetch_assoc()" _s="1"><favar><ab466BD0D3 _n="table" _y="24" _x="22" _r="3" _pri="1"/><ab7ADB6B8A _n="where" _y="24" _x="30" _r="3" _pri="2"/><ab18D01DA1 _n="limit" _y="24" _x="43" _r="3" _pri="3"/><ab10BD0B32 _n="req" _y="25" _x="11" _r="1" _vr=".mysql_query()"/><ab74F62FA3 _n="r" _y="26" _x="15" _r="2" _vr=".mysql_fetch_assoc()"/><ab92DF3D00 _n="res" _y="26" _x="40" _r="1"/><abE4B9F07F _n="rows" _y="27" _x="16" _r="2" _vr=".mysql_fetch_assoc()"/></favar><fapar><na466BD0D3 _n="table" _y="24" _x="22" _pri="1" _to="0"/><na7ADB6B8A _n="where" _y="24" _x="30" _pri="2" _to="4"/><na18D01DA1 _n="limit" _y="24" _x="43" _pri="3" _to="4"/></fapar></oaB882B587><oaD0C170F2 _n="MakeQuery" _y="32" _x="23" _ex="5" _ey="37" _al="$data" _mod="65792" _vr=".implode()" _s="1"><favar><ab053F6F95 _n="data" _y="32" _x="24" _r="3" _pri="1"/><ab6C5F2F38 _n="k" _y="33" _x="28" _r="2"/><abA343B7BF _n="d" _y="33" _x="32" _r="2"/><ab902A88B1 _n="qry" _y="34" _x="17" _r="2"/></favar><fapar><na053F6F95 _n="data" _y="32" _x="24" _pri="1" _to="0"/></fapar></oaD0C170F2></fafnc></ja22FB9999></facls><_rslv><ab5EB460BC _n=".mysql_query()"/><ab4690C8D0 _n="DMDB.MakeQuery()"/><ab7FA0640A _n=".mysql_fetch_assoc()"/><abB475CEB8 _n=".unlink()"/><abDE856E16 _n=".implode()"/></_rslv></ea2C500211><ea5A7059E4 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\class.pagination.php" _n="class.pagination.php" _sz="15948" _p="1" _crc="219507963" _dt="1052872340"><facls><jaBCF4DEB1 _n="pagination" _y="3" _x="18" _ex="9" _ey="407" _exp="1" _s="0"><favar><ab1C15F7F9 _n="total_pages" _y="23" _x="33" _mod="256" _r="1"/><ab18D01DA1 _n="limit" _y="25" _x="27" _mod="256" _r="1"/><ab99FE6C21 _n="target" _y="27" _x="28" _mod="256" _r="1"/><abA13D5E4B _n="page" _y="29" _x="26" _mod="256" _r="1"/><abAE987AE0 _n="adjacents" _y="31" _x="31" _mod="256" _r="1"/><ab75972137 _n="showCounter" _y="33" _x="33" _mod="256" _r="1"/><ab13C4CB7A _n="className" _y="35" _x="31" _mod="256" _r="1"/><ab84CCFBAF _n="parameterName" _y="37" _x="35" _mod="256" _r="1"/><ab90B354EF _n="urlF" _y="39" _x="26" _mod="256" _r="1"/><ab0B640505 _n="uriTPL" _y="41" _x="28" _mod="256" _r="1"/><abA22DAB96 _n="nextT" _y="47" _x="27" _mod="256" _r="1"/><abBE41C769 _n="nextI" _y="49" _x="27" _mod="256" _r="1"/><ab057DF3CC _n="prevT" _y="51" _x="27" _mod="256" _r="1"/><ab19119F33 _n="prevI" _y="53" _x="27" _mod="256" _r="1"/><ab94163F53 _n="calculate" _y="59" _x="31" _mod="256" _r="1"/><abBCF4DEB1 _n="pagination" _y="143" _x="32" _mod="256" _r="1"/></favar><fafnc><oa5BBCFA8C _n="items" _y="65" _x="31" _ex="74" _ey="65" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="65" _x="32" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="65" _x="45" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="65" _x="32" _pri="1" _to="0"/></fapar></oa5BBCFA8C><oa18D01DA1 _n="limit" _y="71" _x="31" _ex="68" _ey="71" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="71" _x="32" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="71" _x="45" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="71" _x="32" _pri="1" _to="0"/></fapar></oa18D01DA1><oa99FE6C21 _n="target" _y="77" _x="32" _ex="64" _ey="77" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="77" _x="33" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="77" _x="46" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="77" _x="33" _pri="1" _to="0"/></fapar></oa99FE6C21><oaF2E9E1F2 _n="urlTemplate" _y="81" _x="37" _ex="69" _ey="81" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="81" _x="38" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="81" _x="51" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="81" _x="38" _pri="1" _to="0"/></fapar></oaF2E9E1F2><oa4AD671BB _n="currentPage" _y="87" _x="37" _ex="73" _ey="87" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="87" _x="38" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="87" _x="51" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="87" _x="38" _pri="1" _to="0"/></fapar></oa4AD671BB><oaAE987AE0 _n="adjacents" _y="93" _x="35" _ex="76" _ey="93" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="93" _x="36" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="93" _x="49" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="93" _x="36" _pri="1" _to="0"/></fapar></oaAE987AE0><oaADEF45FA _n="showCounter" _y="99" _x="37" _ex="95" _ey="99" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="99" _x="38" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="99" _x="54" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="99" _x="38" _pri="1" _to="4"/></fapar></oaADEF45FA><oaA7BCBFD5 _n="changeClass" _y="105" _x="37" _ex="73" _ey="105" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="105" _x="38" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="105" _x="54" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="105" _x="38" _pri="1" _to="4"/></fapar></oaA7BCBFD5><oa1264768C _n="nextLabel" _y="109" _x="35" _ex="66" _ey="109" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="109" _x="36" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="109" _x="49" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="109" _x="36" _pri="1" _to="0"/></fapar></oa1264768C><oa329BE206 _n="nextIcon" _y="111" _x="34" _ex="65" _ey="111" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="111" _x="35" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="111" _x="48" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="111" _x="35" _pri="1" _to="0"/></fapar></oa329BE206><oaC03E559D _n="prevLabel" _y="113" _x="35" _ex="66" _ey="113" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="113" _x="36" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="113" _x="49" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="113" _x="36" _pri="1" _to="0"/></fapar></oaC03E559D><oa84F97A55 _n="prevIcon" _y="115" _x="34" _ex="65" _ey="115" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="115" _x="35" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="115" _x="48" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="115" _x="35" _pri="1" _to="0"/></fapar></oa84F97A55><oaD2AE8D56 _n="parameterName" _y="121" _x="39" _ex="79" _ey="121" _al="$value" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="121" _x="40" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="121" _x="56" _r="1"/></favar><fapar><na1EC23EC0 _n="value" _y="121" _x="40" _pri="1" _to="4"/></fapar></oaD2AE8D56><oa93A1AA33 _n="urlFriendly" _y="127" _x="37" _ex="25" _ey="139" _al="$value = &quot;%&quot;" _mod="256" _s="1"><favar><ab1EC23EC0 _n="value" _y="127" _x="38" _r="4" _pri="1" _val="%"/><ab77A05C14 _n="this" _y="131" _x="54" _r="2"/></favar><fapar><na1EC23EC0 _n="value" _y="127" _x="38" _pri="1" _val="%" _to="4"/></fapar></oa93A1AA33><oaBCF4DEB1 _n="pagination" _y="147" _x="36" _ex="39" _ey="147" _mod="73984"/><oaB6339E5F _n="show" _y="149" _x="30" _ex="25" _ey="157" _mod="256" _s="1"><favar><ab77A05C14 _n="this" _y="151" _x="42" _r="4"/></favar></oaB6339E5F><oa430A2CC3 _n="get_pagenum_link" _y="159" _x="42" _ex="25" _ey="181" _al="$id" _mod="256" _vr=".str_replace()" _s="1"><favar><abC9360499 _n="id" _y="159" _x="43" _r="3" _pri="1"/><ab77A05C14 _n="this" _y="179" _x="73" _r="1"/></favar><fapar><naC9360499 _n="id" _y="159" _x="43" _pri="1" _to="0"/></fapar></oa430A2CC3><oa94163F53 _n="calculate" _y="185" _x="35" _ex="25" _ey="405" _mod="256" _s="1"><favar><ab77A05C14 _n="this" _y="187" _x="38" _r="86"/><abBB9E68FD _n="error" _y="191" _x="39" _r="6"/><ab29AB5845 _n="n" _y="231" _x="35" _r="3" _vr=".trim()"/><abF6941991 _n="p" _y="233" _x="35" _r="3" _vr=".trim()"/><ab623EDC60 _n="start" _y="241" _x="47" _r="2"/><ab8DC4FA05 _n="prev" _y="251" _x="38" _r="2"/><ab77385DE2 _n="next" _y="253" _x="38" _r="2"/><ab6BEF00E1 _n="lastpage" _y="255" _x="42" _r="13" _vr=".ceil()"/><abCFB0AA19 _n="lpm1" _y="257" _x="38" _r="5"/><ab74707DD0 _n="counter" _y="291" _x="78" _r="29"/></favar></oa94163F53></fafnc></jaBCF4DEB1></facls><_rslv><ab8C60FEDE _n="pagination.total_pages"/><abD824511A _n="pagination.limit"/><ab9EA44650 _n="pagination.target"/><ab0C3E2F74 _n="pagination.uriTPL"/><ab4FF7524A _n="pagination.page"/><ab41326015 _n="pagination.adjacents"/><abE5E22810 _n="pagination.showCounter"/><abFC6ED18F _n="pagination.className"/><ab62D9E72D _n="pagination.nextT"/><ab7EB58BD2 _n="pagination.nextI"/><abC589BF77 _n="pagination.prevT"/><abD9E5D388 _n="pagination.prevI"/><abB9894934 _n="pagination.parameterName"/><ab6DE72D07 _n=".eregi()"/><ab7E7958EE _n="pagination.urlF"/><ab7BBC25A6 _n="pagination.calculate"/><abE9EEFC86 _n="pagination.calculate()"/><ab73A43B5E _n="pagination.pagination"/><ab2B73B2A1 _n=".str_replace()"/><ab0FEE6742 _n=".strpos()"/><ab60FB45A7 _n=".trim()"/><ab27B6EBD1 _n=".ceil()"/><ab0918E6AD _n="pagination.get_pagenum_link"/><ab472EBEEE _n="pagination.get_pagenum_link()"/></_rslv></ea5A7059E4><ea6C274981 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\download.php" _n="download.php" _sz="3063" _p="1" _crc="503887981" _dt="1052872340"><favar><abAFDCE5D4 _n="wpdb" _y="2" _x="13" _r="4"/><ab1C64B7A3 _n="dl" _y="3" _x="4" _r="4"/><ab3367B828 _n="_REQUEST" _y="3" _x="21" _r="1"/><ab053F6F95 _n="data" _y="5" _x="10" _r="9" _vr="$wpdb.get_row()"/><ab2F392DF8 _n="_POST" _y="6" _x="14" _r="8"/><ab3A05E79A _n="did" _y="7" _x="13" _r="4" _vr=".uniqid()"/></favar><_rslv><abF4BBD253 _n="$wpdb.get_row"/><abE82FA3A0 _n="$wpdb.get_row()"/><ab938C36EF _n="$wpdb.prefix"/><ab747887EF _n=".uniqid()"/><ab68E07B53 _n=".file_put_contents()"/><ab1877273D _n=".dirname()"/><ab39C49F6B _n=".serialize()"/><ab4FCBF1EA _n=".count()"/><ab5EB460BC _n=".mysql_query()"/><abB2448AFB _n=".get_option()"/><ab060EE961 _n=".home_url()"/></_rslv><facss><fasel><nb67EFD31B _n="*"><falstruct><fc0B6869D7 _n="*" _y="15" _x="1" _ex="1" _ey="15" _spt="1"/></falstruct></nb67EFD31B><nbE58DE529 _n="input"><falstruct><fcD3047619 _n="input" _y="20" _x="1" _ex="5" _ey="20" _spt="1"/></falstruct></nbE58DE529><nb632ABF7F _n="form"><falstruct><fc0B10D0E4 _n="form" _y="20" _x="7" _ex="10" _ey="20" _spt="1"/></falstruct></nb632ABF7F><nbE148894D _n="p"><falstruct><fc4B208325 _n="p" _y="20" _x="12" _ex="12" _ey="20" _spt="1"/></falstruct></nbE148894D><nb6F650AD3 _n="form"><falstruct><fc075F6548 _n="form" _y="23" _x="1" _ex="4" _ey="23" _spt="1"/></falstruct></nb6F650AD3></fasel></facss><fajsl><fajsfnc><bd864AC1FC _n="validate_pass" _y="70" _x="11" _ex="11" _ey="77"/></fajsfnc></fajsl></ea6C274981><eaCA2E09B4 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\editor_plugin.js" _n="editor_plugin.js" _sz="1606" _p="1" _crc="3351340529" _dt="1052872340"/><ea2B9606AE _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\functions.php" _n="functions.php" _sz="4189" _p="1" _crc="3403450648" _dt="1052872340"><fafnc><maDAFB3204 _n="add_wpdc_meta" _y="9" _x="27" _ex="5" _ey="17" _al="mixed $pid, mixed $name, mixed $value, $uniq = false" _s="1"><_doc>fd05E293ED</_doc><favar><abB745A002 _n="pid" _y="9" _x="28" _r="4" _pri="1" _vr="mixed"/><abDCFED24D _n="name" _y="9" _x="34" _r="4" _pri="2" _vr="mixed"/><ab1EC23EC0 _n="value" _y="9" _x="41" _r="7" _pri="3" _vr=".is_array()"/><ab7621993C _n="uniq" _y="9" _x="49" _r="6" _pri="4" _val="false"/><abAFDCE5D4 _n="wpdb" _y="10" _x="21" _r="5" _to="13"/><ab132F665A _n="duplicate" _y="13" _x="19" _r="2" _vr="$wpdb.get_var()"/></favar><fapar><naB745A002 _n="pid" _y="9" _x="28" _pri="1" _to="0" _vr="mixed"/><naDCFED24D _n="name" _y="9" _x="34" _pri="2" _to="0" _vr="mixed"/><na1EC23EC0 _n="value" _y="9" _x="41" _pri="3" _to="0" _vr="mixed"/><na7621993C _n="uniq" _y="9" _x="49" _pri="4" _val="false" _to="9"/></fapar></maDAFB3204><ma7CBEABDC _n="update_wpdc_meta" _y="27" _x="30" _ex="5" _ey="34" _al="mixed $pid, mixed $name, mixed $value, mixed $uniq = false" _s="1"><_doc>fd26D1BA93</_doc><favar><abB745A002 _n="pid" _y="27" _x="31" _r="4" _pri="1" _vr="mixed"/><abDCFED24D _n="name" _y="27" _x="37" _r="4" _pri="2" _vr="mixed"/><ab1EC23EC0 _n="value" _y="27" _x="44" _r="7" _pri="3" _vr=".is_array()"/><ab7621993C _n="uniq" _y="27" _x="52" _r="5" _pri="4" _val="false" _vr="mixed"/><abAFDCE5D4 _n="wpdb" _y="28" _x="21" _r="2" _to="13"/></favar><fapar><naB745A002 _n="pid" _y="27" _x="31" _pri="1" _to="0" _vr="mixed"/><naDCFED24D _n="name" _y="27" _x="37" _pri="2" _to="0" _vr="mixed"/><na1EC23EC0 _n="value" _y="27" _x="44" _pri="3" _to="0" _vr="mixed"/><na7621993C _n="uniq" _y="27" _x="52" _pri="4" _val="false" _to="9" _vr="mixed"/></fapar></ma7CBEABDC><ma23F81CAA _n="delete_wpdc_meta" _y="43" _x="30" _ex="5" _ey="46" _al="mixed $pid, mixed $name" _s="1"><_doc>fdB3019085</_doc><favar><abB745A002 _n="pid" _y="43" _x="31" _r="3" _pri="1" _vr="mixed"/><abDCFED24D _n="name" _y="43" _x="37" _r="3" _pri="2" _vr="mixed"/><abAFDCE5D4 _n="wpdb" _y="44" _x="21" _r="3" _to="13"/></favar><fapar><naB745A002 _n="pid" _y="43" _x="31" _pri="1" _to="0" _vr="mixed"/><naDCFED24D _n="name" _y="43" _x="37" _pri="2" _to="0" _vr="mixed"/></fapar></ma23F81CAA><ma0D093E13 _n="get_wpdc_meta" _y="55" _x="27" _ex="5" _ey="65" _al="mixed $pid, mixed $name, mixed $single = true" _vr="$d.value" _s="1"><_doc>fdBAF98E09</_doc><favar><abB745A002 _n="pid" _y="55" _x="28" _r="3" _pri="1" _vr="mixed"/><abDCFED24D _n="name" _y="55" _x="34" _r="3" _pri="2" _vr="mixed"/><ab1C1FE643 _n="single" _y="55" _x="41" _r="3" _pri="3" _val="true" _vr="mixed"/><abAFDCE5D4 _n="wpdb" _y="56" _x="21" _r="3" _to="13"/><ab053F6F95 _n="data" _y="57" _x="14" _r="5" _vr="$wpdb.get_results()"/><abA343B7BF _n="d" _y="60" _x="28" _r="7"/><ab12435CB7 _n="metas" _y="62" _x="19" _r="2" _vr="$d.value"/></favar><fapar><naB745A002 _n="pid" _y="55" _x="28" _pri="1" _to="0" _vr="mixed"/><naDCFED24D _n="name" _y="55" _x="34" _pri="2" _to="0" _vr="mixed"/><na1C1FE643 _n="single" _y="55" _x="41" _pri="3" _val="true" _to="9" _vr="mixed"/></fapar></ma0D093E13><maEC646B81 _n="wpdc_multi_user" _y="73" _x="29" _ex="5" _ey="78" _al="mixed $cond" _s="1"><_doc>fdC3E460D3</_doc><favar><abD21473E7 _n="cond" _y="73" _x="30" _r="4" _pri="1" _vr="mixed"/><abAFDCE5D4 _n="wpdb" _y="74" _x="21" _r="1" _to="13"/><ab6A57CFA6 _n="current_user" _y="74" _x="36" _r="2" _to="13"/><ab0446CB43 _n="ismu" _y="76" _x="14" _r="3"/></favar><fapar><naD21473E7 _n="cond" _y="73" _x="30" _pri="1" _to="4" _vr="mixed"/></fapar></maEC646B81><ma08B099C3 _n="wpdc_popup" _y="84" _x="24" _ex="5" _ey="113"><_doc>fd4B618AA0</_doc></ma08B099C3><maB045303F _n="__msg" _y="115" _x="19" _ex="5" _ey="118" _al="$key" _s="1"><favar><ab4B640BDE _n="key" _y="115" _x="20" _r="5" _pri="1"/><ab1C0F66FE _n="msgs" _y="117" _x="21" _r="2"/></favar><fapar><na4B640BDE _n="key" _y="115" _x="20" _pri="1" _to="0"/></fapar></maB045303F></fafnc><_hsh><fd05E293ED _y="2" _x="5">/**\n * add new package meta\n * \n * @param mixed $pid\n * @param mixed $name\n * @param mixed $value\n */</fd05E293ED><fd26D1BA93 _y="19" _x="5">/**\n * update package meta\n * \n * @param mixed $pid\n * @param mixed $name\n * @param mixed $value\n * @param mixed $uniq\n */</fd26D1BA93><fdB3019085 _y="37" _x="5">/**\n * delete package meta\n * \n * @param mixed $pid\n * @param mixed $name\n */</fdB3019085><fdBAF98E09 _y="48" _x="5">/**\n * get package meta\n * \n * @param mixed $pid\n * @param mixed $name\n * @param mixed $single\n */</fdBAF98E09><fdC3E460D3 _y="67" _x="5">/**\n * check if multi-user ebabled\n * \n * @param mixed $cond\n */</fdC3E460D3><fd4B618AA0 _y="80" _x="5">/**\n * popup\n * \n */</fd4B618AA0></_hsh><favar><abAFDCE5D4 _n="wpdb" _y="10" _x="21" _r="14"/><ab6A57CFA6 _n="current_user" _y="74" _x="36" _r="2"/></favar><_rslv><ab469BAD9C _n=".is_array()"/><ab39C49F6B _n=".serialize()"/><ab947AEB55 _n="$wpdb.get_var"/><ab130C0FEC _n="$wpdb.get_var()"/><ab938C36EF _n="$wpdb.prefix"/><ab08EFF854 _n="$wpdb.insert"/><ab1059A9F6 _n="$wpdb.insert()"/><ab9B5F3A29 _n="$wpdb.show_errors"/><ab07517A4B _n="$wpdb.show_errors()"/><ab8C1E0E96 _n=".delete_wpdc_meta()"/><ab3FD842B2 _n=".add_wpdc_meta()"/><ab4EE10C8F _n="$wpdb.query"/><ab1E5C9923 _n="$wpdb.query()"/><abE50C03E1 _n="$wpdb.get_results"/><ab79D15B35 _n="$wpdb.get_results()"/><abE07A8A7C _n=".unserialize()"/><ab4D292B7F _n="$wpdb.get_results().value"/><ab13DE7068 _n="$d.value">.is_array()</ab13DE7068><abA5CB4357 _n="$d.name"/><abABDCD7A7 _n=".get_currentuserinfo()"/><abB2448AFB _n=".get_option()"/><ab358D1AFE _n="$current_user.caps"/></_rslv><falnk><ia2A976884 _n="include" _y="116" _x="33" _val="(&quot;messages.php&quot;)"/></falnk><facss><fasel><nb67EFD31B _n=".jqifade"><falstruct><dcD7309E4A _n=".jqifade" _y="99" _x="13" _ex="20" _ey="99" _spt="3"/></falstruct></nb67EFD31B><nbE58DE529 _n="div.jqi"><falstruct><fc354AB85B _n="div" _y="100" _x="13" _ex="15" _ey="100" _spt="1"/><dc838DB031 _n=".jqi" _y="100" _x="16" _ex="19" _ey="100" _spt="3"/></falstruct></nbE58DE529><nb221BA466 _n="div.jqi .jqicontainer"><falstruct><fc70BECF26 _n="div" _y="101" _x="13" _ex="15" _ey="101" _spt="1"/><dc40DE9D1A _n=".jqi" _y="101" _x="16" _ex="19" _ey="101" _spt="3"/><hc26331669 _n=" " _spt="5"/><dcCDC14737 _n=".jqicontainer" _y="101" _x="21" _ex="33" _ey="101" _spt="3"/></falstruct></nb221BA466><nbCC48F37D _n="div.jqi .jqiclose"><falstruct><fcB9FE6C58 _n="div" _y="102" _x="13" _ex="15" _ey="102" _spt="1"/><dcE6A10959 _n=".jqi" _y="102" _x="16" _ex="19" _ey="102" _spt="3"/><hc9EA16DF5 _n=" " _spt="5"/><dcA0E1B9DA _n=".jqiclose" _y="102" _x="21" _ex="29" _ey="102" _spt="3"/></falstruct></nbCC48F37D><nb89BC8400 _n="div.jqi .jqimessage"><falstruct><fc7E682D17 _n="div" _y="103" _x="13" _ex="15" _ey="103" _spt="1"/><dcA3557E24 _n=".jqi" _y="103" _x="16" _ex="19" _ey="103" _spt="3"/><hc55789916 _n=" " _spt="5"/><dcA8AF3825 _n=".jqimessage" _y="103" _x="21" _ex="31" _ey="103" _spt="3"/></falstruct></nb89BC8400><nb22E7466F _n="div.jqi .jqibuttons"><falstruct><fc5751D94A _n="div" _y="104" _x="13" _ex="15" _ey="104" _spt="1"/><dc080EBC4B _n=".jqi" _y="104" _x="16" _ex="19" _ey="104" _spt="3"/><hc700ED8E7 _n=" " _spt="5"/><dcAC6D2757 _n=".jqibuttons" _y="104" _x="21" _ex="31" _ey="104" _spt="3"/></falstruct></nb22E7466F><nb67133112 _n="div.jqi button"><falstruct><fc90C79805 _n="div" _y="105" _x="13" _ex="15" _ey="105" _spt="1"/><dc4DFACB36 _n=".jqi" _y="105" _x="16" _ex="19" _ey="105" _spt="3"/><hcBBD72C04 _n=" " _spt="5"/><fcA23F1474 _n="button" _y="105" _x="21" _ex="26" _ey="105" _spt="1"/></falstruct></nb67133112><nb4780FAD7 _n="div.jqi button:hover"><falstruct><fc323665F2 _n="div" _y="106" _x="13" _ex="15" _ey="106" _spt="1"/><dc6D6900F3 _n=".jqi" _y="106" _x="16" _ex="19" _ey="106" _spt="3"/><hc1569645F _n=" " _spt="5"/><fc8A260679 _n="button" _y="106" _x="21" _ex="26" _ey="106" _spt="1"/><ec304BB496 _n=":hover" _spt="4"/></falstruct></nb4780FAD7><nbC127A081 _n="div.jqi button.jqidefaultbutton"><falstruct><fcB4913FA4 _n="div" _y="107" _x="13" _ex="15" _ey="107" _spt="1"/><dcE781EF09 _n=".jqi" _y="107" _x="16" _ex="19" _ey="107" _spt="3"/><hc9F818BA5 _n=" " _spt="5"/><fc37DBBD80 _n="button" _y="107" _x="21" _ex="26" _ey="107" _spt="1"/><dcD83567BC _n=".jqidefaultbutton" _y="107" _x="27" _ex="43" _ey="107" _spt="3"/></falstruct></nbC127A081><nb7CDA1B78 _n=".jqiwarning .jqi .jqibuttons"><falstruct><dcB095F64E _n=".jqiwarning" _y="108" _x="13" _ex="23" _ey="108" _spt="3"/><hc6BC7F28D _n=" " _spt="5"/><dc13C79621 _n=".jqi" _y="108" _x="25" _ex="28" _ey="108" _spt="3"/><hcE9A5C4BF _n=" " _spt="5"/><dcB3616159 _n=".jqibuttons" _y="108" _x="30" _ex="40" _ey="108" _spt="3"/></falstruct></nb7CDA1B78></fasel></facss></ea2B9606AE><ea0313FFDD _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\process.php" _n="process.php" _sz="11648" _p="1" _crc="3609249464" _dt="1052872340"><favar><ab053F6F95 _n="data" _y="3" _x="6" _r="6" _vr=".unserialize()"/><ab77CB9B76 _n="_GET" _y="3" _x="74" _r="2"/><abF43D8317 _n="fname" _y="11" _x="11" _r="6"/><ab0426584F _n="mime_types" _y="17" _x="16" _r="2"/><ab54E4EE4F _n="mtype" _y="204" _x="11" _r="2"/><ab1E11B467 _n="asfname" _y="206" _x="13" _r="2" _vr=".basename()"/><ab45F4A0D1 _n="fsize" _y="208" _x="11" _r="3" _vr=".filesize()"/><ab6100D8CA _n="file" _y="222" _x="10" _r="5" _vr=".fopen()"/></favar><_rslv><abE07A8A7C _n=".unserialize()"/><ab93997FE6 _n=".file_get_contents()"/><ab1877273D _n=".dirname()"/><ab469BAD9C _n=".is_array()"/><abB475CEB8 _n=".unlink()"/><abAC5BFBC9 _n=".file_exists()"/><ab1A56F49A _n=".strtolower()"/><abBD192035 _n=".end()"/><ab5C1FE996 _n=".explode()"/><ab325D29CA _n=".basename()"/><ab17D5460C _n=".filesize()"/><abC5F7790A _n=".header()"/><abCD535C77 _n=".fopen()"/><abEFD8BD01 _n=".fread()"/><abC891668A _n=".flush()"/><ab36B147B1 _n=".connection_status()"/><ab4EBA7110 _n=".fclose()"/></_rslv></ea0313FFDD><eaA3573768 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-add-new-file.php" _n="wpdc-add-new-file.php" _sz="6514" _p="1" _crc="3451728348" _dt="1052872340"><_rslv><ab874A99D3 _n=".plugins_url()"/><abF5FECA14 _n=".the_editor()"/><ab6D7D7B72 _n=".stripslashes()"/><ab2B0F8458 _n=".wp_nonce_field()"/><ab224FF3FC _n=".maybe_unserialize()"/><ab469BAD9C _n=".is_array()"/><ab8F6C4766 _n=".wpdc_cblist_categories()"/><ab325D29CA _n=".basename()"/></_rslv><favar><ab77CB9B76 _n="_GET" _y="27" _x="15" _r="2"/><ab6100D8CA _n="file" _y="36" _x="55" _r="12"/><abF4B4D991 _n="currentAccesss" _y="92" _x="17" _r="4" _vr=".maybe_unserialize()"/><ab0BBAF478 _n="files" _y="136" _x="16" _r="1"/></favar><facss><fasel><nb67EFD31B _n=".wrap *"><falstruct><dcAB4200E1 _n=".wrap" _y="2" _x="1" _ex="5" _ey="2" _spt="3"/><hcACDBF993 _n=" " _spt="5"/><fc890A5FE5 _n="*" _y="2" _x="7" _ex="7" _ey="2" _spt="1"/></falstruct></nb67EFD31B><nb632ABF7F _n="input[type=text]"><falstruct><fc55A32C4F _n="input" _y="7" _x="1" _ex="5" _ey="7" _spt="1"/><ic55A30EDE _n="type" _val="text" _spt="6" _sop="="/></falstruct></nb632ABF7F><nbA0799254 _n="textarea"><falstruct><fc427F2AFB _n="textarea" _y="7" _x="18" _ex="25" _ey="7" _spt="1"/></falstruct></nbA0799254><nb2E5411CA _n="input"><falstruct><fcCBB537D8 _n="input" _y="12" _x="1" _ex="5" _ey="12" _spt="1"/></falstruct></nb2E5411CA><nb8D79E864 _n=".cfile"><falstruct><dc74954244 _n=".cfile" _y="15" _x="1" _ex="6" _ey="15" _spt="3"/></falstruct></nb8D79E864><nb0F1BDE56 _n=".dfile"><falstruct><dc3298D577 _n=".dfile" _y="16" _x="1" _ex="6" _ey="16" _spt="3"/></falstruct></nb0F1BDE56><nb89BC8400 _n=".cfile img"><falstruct><dc70502E20 _n=".cfile" _y="17" _x="1" _ex="6" _ey="17" _spt="3"/><hc9A640191 _n=" " _spt="5"/><fc84119030 _n="img" _y="17" _x="8" _ex="10" _ey="17" _spt="1"/></falstruct></nb89BC8400><nb85F331AC _n=".dfile img"><falstruct><dcD8F20C01 _n=".dfile" _y="17" _x="13" _ex="18" _ey="17" _spt="3"/><hcF26CEED5 _n=" " _spt="5"/><fcE056CAD8 _n="img" _y="17" _x="20" _ex="22" _ey="17" _spt="1"/></falstruct></nb85F331AC><nbE1B46B44 _n=".inside"><falstruct><dc304C45EC _n=".inside" _y="18" _x="1" _ex="7" _ey="18" _spt="3"/></falstruct></nbE1B46B44><nb67133112 _n="#editorcontainer textarea"><falstruct><gcD05A9B05 _n="#editorcontainer" _y="19" _x="1" _ex="16" _ey="19" _spt="2"/><hc74CBB483 _n=" " _spt="5"/><fc9FE6D77A _n="textarea" _y="19" _x="18" _ex="25" _ey="19" _spt="1"/></falstruct></nb67133112><nb6B5C84BE _n="#file_uploadUploader"><falstruct><gcA340F17D _n="#file_uploadUploader" _y="20" _x="1" _ex="20" _ey="20" _spt="2"/></falstruct></nb6B5C84BE><nb06B1E1CE _n="#file_uploadUploader:hover"><falstruct><gc2122C74F _n="#file_uploadUploader" _y="21" _x="1" _ex="20" _ey="21" _spt="2"/><ecB6ECEEC0 _n=":hover" _spt="4"/></falstruct></nb06B1E1CE><nb434596B3 _n=".frm td"><falstruct><dcD15A63B3 _n=".frm" _y="22" _x="1" _ex="4" _ey="22" _spt="3"/><hc509D1322 _n=" " _spt="5"/><fcCB053B53 _n="td" _y="22" _x="6" _ex="7" _ey="22" _spt="1"/></falstruct></nb434596B3></fasel></facss><_prl><gdE1AE28D8 _y="42" _x="94" _prt="3,4,1,1,0" _pmg="unexpected end of file"/></_prl></eaA3573768><ea288443A9 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-categories.php" _n="wpdc-categories.php" _sz="4676" _p="1" _crc="2484005270" _dt="1052872340"><fafnc><ma081AFC96 _n="wpdm_render_cats" _y="43" _x="30" _ex="47" _ey="65" _al="$parent, $level = 0" _s="1"><favar><abECE3A3B8 _n="parent" _y="43" _x="31" _r="3" _pri="1"/><abEE106E57 _n="level" _y="43" _x="42" _r="4" _pri="2" _val="0"/><abCF8675CE _n="categories" _y="44" _x="19" _r="3" _vr=".maybe_unserialize()"/><abC9360499 _n="id" _y="46" _x="31" _r="6"/><abBA28DA1E _n="category" _y="46" _x="42" _r="3"/><abC8308D78 _n="pres" _y="48" _x="18" _r="2" _vr=".str_repeat()"/></favar><fapar><naECE3A3B8 _n="parent" _y="43" _x="31" _pri="1" _to="4"/><naEE106E57 _n="level" _y="43" _x="42" _pri="2" _val="0" _to="2"/></fapar></ma081AFC96></fafnc><_rslv><ab224FF3FC _n=".maybe_unserialize()"/><abB2448AFB _n=".get_option()"/><ab469BAD9C _n=".is_array()"/><ab7CD09A74 _n=".str_repeat()"/><ab16BD4A3A _n=".wpdm_render_cats()"/><ab3E9F79DC _n=".htmlspecialchars()"/><ab6D7D7B72 _n=".stripslashes()"/><ab9A074D55 _n=".wpdc_cat_dropdown_tree()"/></_rslv><favar><ab77CB9B76 _n="_GET" _y="74" _x="131" _r="5"/><ab3C0F9408 _n="cat" _y="79" _x="9" _r="11" _vr=".maybe_unserialize()"/></favar><facss><fasel><nb67EFD31B _n=".wrap *"><falstruct><dcAB4200E1 _n=".wrap" _y="2" _x="1" _ex="5" _ey="2" _spt="3"/><hcACDBF993 _n=" " _spt="5"/><fc890A5FE5 _n="*" _y="2" _x="7" _ex="7" _ey="2" _spt="1"/></falstruct></nb67EFD31B><nb632ABF7F _n="input[type=text]"><falstruct><fc55A32C4F _n="input" _y="7" _x="1" _ex="5" _ey="7" _spt="1"/><ic55A30EDE _n="type" _val="text" _spt="6" _sop="="/></falstruct></nb632ABF7F><nbA0799254 _n="textarea"><falstruct><fc427F2AFB _n="textarea" _y="7" _x="18" _ex="25" _ey="7" _spt="1"/></falstruct></nbA0799254><nb2E5411CA _n="input"><falstruct><fcCBB537D8 _n="input" _y="12" _x="1" _ex="5" _ey="12" _spt="1"/></falstruct></nb2E5411CA></fasel></facss></ea288443A9><eaA32D146D _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-free-mce-button.php" _n="wpdc-free-mce-button.php" _sz="4095" _p="1" _crc="2161431151" _dt="1052925448"><_rslv><ab875B5694 _n=".add_filter()"/><abA30FED84 _n=".array_push()"/><ab60FB45A7 _n=".trim()"/><ab301F6CF3 _n=".get_bloginfo()"/><ab10368BE0 _n=".bloginfo()"/><abB2448AFB _n=".get_option()"/><abE50C03E1 _n="$wpdb.get_results"/><ab79D15B35 _n="$wpdb.get_results()"/><ab938C36EF _n="$wpdb.prefix"/><ab42DE73AF _n=".wpdc_dropdown_categories()"/><ab060EE961 _n=".home_url()"/><ab1B360886 _n=".add_action()"/></_rslv><fafnc><maA42B4BF6 _n="wpdc_tinyplugin_add_button" _y="8" _x="36" _ex="1" _ey="12" _al="$buttons" _s="1"><favar><ab5A96EF0E _n="buttons" _y="8" _x="37" _r="4" _pri="1"/></favar><fapar><na5A96EF0E _n="buttons" _y="8" _x="37" _pri="1" _to="0"/></fapar></maA42B4BF6><ma35BA0FB6 _n="wpdc_tinyplugin_register" _y="14" _x="34" _ex="1" _ey="20" _al="$plugin_array" _s="1"><favar><ab07988FB8 _n="plugin_array" _y="14" _x="35" _r="4" _pri="1"/><ab928EAC1D _n="url" _y="16" _x="9" _r="2"/></favar><fapar><na07988FB8 _n="plugin_array" _y="14" _x="35" _pri="1" _to="0"/></fapar></ma35BA0FB6><ma4FA65C0A _n="wpdc_free_tinymce" _y="23" _x="27" _ex="1" _ey="119" _s="1"><favar><abAFDCE5D4 _n="wpdb" _y="24" _x="17" _r="3" _to="13"/><ab77CB9B76 _n="_GET" _y="25" _x="13" _r="1"/><ab92DF3D00 _n="res" _y="70" _x="9" _r="2" _vr="$wpdb.get_results()"/><abF2FAEC0B _n="row" _y="71" _x="25" _r="3"/></favar></ma4FA65C0A></fafnc><favar><abAFDCE5D4 _n="wpdb" _y="24" _x="17" _r="3"/></favar><facss><fasel><nb67EFD31B _n="*"><falstruct><fc0B6869D7 _n="*" _y="32" _x="1" _ex="1" _ey="32" _spt="1"/></falstruct></nb67EFD31B><nbE58DE529 _n="select"><falstruct><fc906E3DC5 _n="select" _y="33" _x="1" _ex="6" _ey="33" _spt="1"/></falstruct></nbE58DE529><nb632ABF7F _n="input"><falstruct><fc55A32C4F _n="input" _y="33" _x="8" _ex="12" _ey="33" _spt="1"/></falstruct></nb632ABF7F><nbE148894D _n=".button"><falstruct><dc1FA34790 _n=".button" _y="34" _x="1" _ex="7" _ey="34" _spt="3"/></falstruct></nbE148894D><nb6F650AD3 _n=".input"><falstruct><dcA97E084F _n=".input" _y="49" _x="1" _ex="6" _ey="49" _spt="3"/></falstruct></nb6F650AD3><nbCC48F37D _n=".button-primary"><falstruct><dcE712B706 _n=".button-primary" _y="61" _x="1" _ex="15" _ey="61" _spt="3"/></falstruct></nbCC48F37D><nb4E2AC54F _n="fieldset"><falstruct><fc82E59B23 _n="fieldset" _y="62" _x="1" _ex="8" _ey="62" _spt="1"/></falstruct></nb4E2AC54F></fasel></facss><_prl><gd66268258 _y="41" _x="16" _prt="3,2,1,102,0" _pmg="MSIE-specific CSS syntax"/><gdD988CB96 _y="57" _x="16" _prt="3,2,1,102,0" _pmg="MSIE-specific CSS syntax"/></_prl></eaA32D146D><ea52C8BAD8 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-list-files.php" _n="wpdc-list-files.php" _sz="8148" _p="1" _crc="1428155774" _dt="1053323648"><favar><abAFDCE5D4 _n="wpdb" _y="2" _x="13" _r="3"/><ab18D01DA1 _n="limit" _y="3" _x="7" _r="6"/><ab623EDC60 _n="start" _y="5" _x="7" _r="2"/><ab77CB9B76 _n="_GET" _y="5" _x="15" _r="5"/><ab92DF3D00 _n="res" _y="6" _x="5" _r="2" _vr=".mysql_query()"/><abF2FAEC0B _n="row" _y="8" _x="5" _r="4" _vr=".mysql_fetch_assoc()"/><abB519CA09 _n="media" _y="80" _x="23" _r="17" _vr=".mysql_fetch_assoc()"/><ab8E472243 _n="icon" _y="84" _x="26" _r="8"/><ab437BEC6B _n="page_links" _y="124" _x="12" _r="3" _vr=".paginate_links()"/><ab5D215187 _n="page_links_text" _y="141" _x="51" _r="2" _vr=".sprintf()"/></favar><_rslv><ab5EB460BC _n=".mysql_query()"/><ab938C36EF _n="$wpdb.prefix"/><ab7FA0640A _n=".mysql_fetch_assoc()"/><abBD192035 _n=".end()"/><ab5C1FE996 _n=".explode()"/><abAC5BFBC9 _n=".file_exists()"/><ab1877273D _n=".dirname()"/><ab8D49ED36 _n=".paginate_links()"/><ab5B9A4D98 _n=".add_query_arg()"/><ab98E7FF1D _n=".__()"/><ab27B6EBD1 _n=".ceil()"/><ab88FB05A9 _n=".sprintf()"/><abD9A26C60 _n=".number_format_i18n()"/><ab3673A98D _n=".min()"/></_rslv><facss><fasel><nb67EFD31B _n=".wrap *"><falstruct><dcAB4200E1 _n=".wrap" _y="12" _x="1" _ex="5" _ey="12" _spt="3"/><hcACDBF993 _n=" " _spt="5"/><fc890A5FE5 _n="*" _y="12" _x="7" _ex="7" _ey="12" _spt="1"/></falstruct></nb67EFD31B></fasel></facss></ea52C8BAD8><eaBA4691E0 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-server-file-browser.php" _n="wpdc-server-file-browser.php" _sz="2829" _p="1" _crc="316912937" _dt="1052925448"><fafnc><ma84027707 _n="wpdc_dir_tree" _y="3" _x="23" _ex="1" _ey="27" _s="1"><favar><ab77CB9B76 _n="_GET" _y="4" _x="13" _r="1"/><ab2F392DF8 _n="_POST" _y="5" _x="11" _r="10" _vr=".urldecode()"/><ab53501CA5 _n="root" _y="6" _x="26" _r="6"/><ab0BBAF478 _n="files" _y="7" _x="12" _r="5" _vr=".scandir()"/><ab6100D8CA _n="file" _y="12" _x="31" _r="15"/><ab34F4DCF3 _n="ext" _y="20" _x="13" _r="2" _vr=".preg_replace()"/></favar></ma84027707><ma3F75AADB _n="wpdc_file_browser" _y="29" _x="27" _ex="1" _ey="61" _s="1"><favar><ab77CB9B76 _n="_GET" _y="30" _x="13" _r="1"/><abC3353E85 _n="_SERVER" _y="42" _x="80" _r="1"/></favar></ma3F75AADB></fafnc><_rslv><abF3DC3F29 _n=".urldecode()"/><abAC5BFBC9 _n=".file_exists()"/><ab62757A60 _n=".scandir()"/><ab120BA9D4 _n=".natcasesort()"/><ab4FCBF1EA _n=".count()"/><abDBE1D690 _n=".is_dir()"/><abD915D19A _n=".htmlentities()"/><ab786734F4 _n=".preg_replace()"/><ab874A99D3 _n=".plugins_url()"/><abB2448AFB _n=".get_option()"/><abA9201B64 _n=".is_admin()"/><ab2BBF6839 _n=".wp_enqueue_script()"/><ab1B360886 _n=".add_action()"/></_rslv><facss><fasel><nb67EFD31B _n=".jqueryFileTree li"><falstruct><dc926969EA _n=".jqueryFileTree" _y="33" _x="28" _ex="42" _ey="33" _spt="3"/><hcACDBF993 _n=" " _spt="5"/><fcC44C4E83 _n="li" _y="33" _x="44" _ex="45" _ey="33" _spt="1"/></falstruct></nb67EFD31B></fasel></facss></eaBA4691E0><ea453EE848 _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-settings.php" _n="wpdc-settings.php" _sz="1595" _p="1" _crc="2153703175" _dt="1052872340"><favar><ab72BAC876 _n="access" _y="29" _x="47" _r="2"/></favar><_rslv><abB2448AFB _n=".get_option()"/><ab874A99D3 _n=".plugins_url()"/></_rslv><facss><fasel><nb67EFD31B _n=".wrap *"><falstruct><dcAB4200E1 _n=".wrap" _y="2" _x="1" _ex="5" _ey="2" _spt="3"/><hcACDBF993 _n=" " _spt="5"/><fc890A5FE5 _n="*" _y="2" _x="7" _ex="7" _ey="2" _spt="1"/></falstruct></nb67EFD31B><nb632ABF7F _n="input[type=text]"><falstruct><fc55A32C4F _n="input" _y="7" _x="1" _ex="5" _ey="7" _spt="1"/><ic55A30EDE _n="type" _val="text" _spt="6" _sop="="/></falstruct></nb632ABF7F><nbA0799254 _n="textarea"><falstruct><fc427F2AFB _n="textarea" _y="7" _x="18" _ex="25" _ey="7" _spt="1"/></falstruct></nbA0799254><nb2E5411CA _n="input"><falstruct><fcCBB537D8 _n="input" _y="12" _x="1" _ex="5" _ey="12" _spt="1"/></falstruct></nb2E5411CA></fasel></facss></ea453EE848><ea8A19846E _rn="E:\xampp\htdocs\wpdm\wp-content\plugins\download-controler\wpdc-widgets.php" _n="wpdc-widgets.php" _sz="2371" _p="1" _crc="3941145648" _dt="1052872340"><facls><jaE6D3EFD9 _n="wpdc_newpacks_widget" _y="5" _x="45" _ex="1" _ey="59" _exp="1" _s="0" _par="WP_Widget"><fafnc><oaE6D3EFD9 _n="wpdc_newpacks_widget" _y="7" _x="34" _ex="5" _ey="9" _mod="73984"><_doc>fdFE4B7F81</_doc></oaE6D3EFD9><oa3154F1FF _n="widget" _y="12" _x="20" _ex="5" _ey="26" _al="$args, $instance" _mod="65792" _s="1"><_doc>fd8A066FF5</_doc><favar><abF6C99562 _n="args" _y="12" _x="21" _r="3" _pri="1"/><abBC92E803 _n="instance" _y="12" _x="28" _r="5" _pri="2"/><ab7591BAD5 _n="title" _y="14" _x="15" _r="3" _vr=".apply_filters()"/><ab03791F39 _n="sdc" _y="15" _x="13" _r="2"/><abD5AEB930 _n="nop" _y="16" _x="13" _r="2"/><abAFF424D8 _n="before_widget" _y="18" _x="40" _r="1"/><ab940E5C39 _n="before_title" _y="20" _x="43" _r="1"/><abA551F1A4 _n="after_title" _y="20" _x="67" _r="1"/><abD522ADE5 _n="after_widget" _y="24" _x="34" _r="1"/></favar><fapar><naF6C99562 _n="args" _y="12" _x="21" _pri="1" _to="0"/><naBC92E803 _n="instance" _y="12" _x="28" _pri="2" _to="0"/></fapar></oa3154F1FF><oa7B9054A5 _n="update" _y="29" _x="20" _ex="5" _ey="35" _al="$new_instance, $old_instance" _mod="65792" _vr=".strip_tags()" _s="1"><_doc>fdCA23A75C</_doc><favar><ab974A27B3 _n="new_instance" _y="29" _x="21" _r="5" _pri="1"/><ab9F8B06D3 _n="old_instance" _y="29" _x="36" _r="3" _pri="2"/><abBC92E803 _n="instance" _y="30" _x="14" _r="5" _vr=".strip_tags()"/></favar><fapar><na974A27B3 _n="new_instance" _y="29" _x="21" _pri="1" _to="0"/><na9F8B06D3 _n="old_instance" _y="29" _x="36" _pri="2" _to="0"/></fapar></oa7B9054A5><oaD8499E64 _n="form" _y="38" _x="18" _ex="5" _ey="57" _al="$instance" _mod="256" _s="1"><_doc>fdC0854D67</_doc><favar><abBC92E803 _n="instance" _y="38" _x="19" _r="5" _pri="1"/><ab7591BAD5 _n="title" _y="39" _x="15" _r="2" _vr=".esc_attr()"/><ab03791F39 _n="sdc" _y="40" _x="13" _r="2" _vr=".esc_attr()"/><abD5AEB930 _n="nop" _y="41" _x="13" _r="2" _vr=".esc_attr()"/><ab77A05C14 _n="this" _y="44" _x="39" _r="9"/></favar><fapar><naBC92E803 _n="instance" _y="38" _x="19" _pri="1" _to="0"/></fapar></oaD8499E64></fafnc></jaE6D3EFD9></facls><_hsh><fdFE4B7F81 _y="6" _x="5">/** constructor */</fdFE4B7F81><fd8A066FF5 _y="11" _x="5">/** @see WP_Widget::widget */</fd8A066FF5><fdCA23A75C _y="28" _x="5">/** @see WP_Widget::update */</fdCA23A75C><fdC0854D67 _y="37" _x="5">/** @see WP_Widget::form */</fdC0854D67></_hsh><_rslv><abE5ECE0CD _n="WP_Widget.WP_Widget()"/><ab3146EAB6 _n=".extract()"/><ab42896E64 _n=".apply_filters()"/><ab4DABD018 _n=".wpdc_new_packages()"/><abA791C526 _n=".strip_tags()"/><ab75A1E851 _n=".esc_attr()"/><abC5630884 _n="wpdc_newpacks_widget.get_field_id"/><ab46BECE08 _n="wpdc_newpacks_widget.get_field_id()"/><ab53C31EB8 _n="._e()"/><abEA8EC0A2 _n="wpdc_newpacks_widget.get_field_name"/><ab669A8B80 _n="wpdc_newpacks_widget.get_field_name()"/><ab1B360886 _n=".add_action()"/><ab491E6EBA _n=".create_function()"/></_rslv></ea8A19846E></ca52F9DEE0><_ver ParserProp_Override="0" ParserProp_PHP_SubLang="2" ParserPropPHPShortTags="1" ParserProp_PHP_AspTags="0" ParserProp_JS_ParsePHP="0" ParserProp_CSS_ParsePHP="0">1125397</_ver><_grp><fadef _s="1"/><favar _s="1"/><facls _s="1"/><fafnc _s="1"/><faint/><fanms/><fajsfnc _s="1"/><fajsvar _s="1"/></_grp></_root>
 
wpdm-add-new-file.php CHANGED
@@ -8,12 +8,12 @@ input[type=text],textarea{
8
  input{
9
  padding: 4px 7px;
10
  }
11
- .cfile{margin: 2px;border:1px solid #008000;background: #F3FFF2;overflow:hidden;padding:5px;}
12
  .dfile{margin: 2px;border:1px solid #800;background: #ffdfdf;overflow:hidden;padding:5px;}
13
  .cfile img, .dfile img{cursor: pointer;}
14
  .inside{padding:10px !important;}
15
  #editorcontainer textarea{border:0px;width:99.9%;}
16
- #file_uploadUploader {background: transparent url('<?php echo plugins_url(); ?>/download-manager/images/browse.png') left top no-repeat; }
17
  #file_uploadUploader:hover {background-position: left bottom; }
18
  .frm td{line-height: 30px; border-bottom: 1px solid #EEEEEE; padding:5px; font-size:9pt;font-family: Tahoma;}
19
 
@@ -28,20 +28,22 @@ input{
28
  <h2>Add New Download Package</h2>
29
 
30
  <?php }?>
31
- <form action="" method="post" enctype="multipart/form-data">
 
 
32
  <input type="hidden" name="id" value="<?php echo $file['id']; ?>" />
33
  <div style="width: 75%;float:left;">
34
 
35
  <table cellpadding="5" cellspacing="5" width="100%">
36
  <tr>
37
 
38
- <td><input style="font-size:16pt;width:100%;color:<?php echo $file['title']?'#000':'#ccc'; ?>" onfocus="if(this.value=='Enter title here') {this.value=''; jQuery(this).css('color','#000'); }" onblur="if(this.value==''||this.value=='Enter title here') {this.value='Enter title here'; jQuery(this).css('color','#ccc');}" type="text" value="<?php echo $file['title']?$file['title']:'Enter title here'; ?>" name="file[title]" /></td>
39
  </tr>
40
 
41
  <tr>
42
  <td valign="top">
43
  <div id="poststuff" class="postarea">
44
- <?php the_editor(stripslashes($file['description']),'file[description]','file[description]', true); ?>
45
  <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
46
  <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
47
  </div>
@@ -60,33 +62,33 @@ input{
60
  <table cellpadding="5" id="file_settings_table" cellspacing="0" width="100%" class="frm">
61
  <tr id="link_label_row">
62
  <td width="110px">Link Label:</td>
63
- <td><input size="10" type="text" style="width: 200px" value="<?php echo $file[link_label]?$file[link_label]:'Download'; ?>" name="file[link_label]" />
64
  </td></tr>
65
  <tr id="password_row">
66
  <td>Password:</td>
67
- <td><input size="10" style="width: 200px" type="text" name="file[password]" value="<?php echo $file[password]; ?>" /></td>
68
  </tr>
69
  <tr id="download_limit_row">
70
  <td>Stock&nbsp;Limit:</td>
71
- <td><input size="10" style="width: 80px" type="text" name="file[quota]" value="<?php echo $file[quota]; ?>" /></td>
72
  </tr>
73
  <tr>
74
  <td>Download Count: </td>
75
- <td><input type="text" name="file[download_count]" value="<?php echo $file[download_count]?$file[download_count]:0; ?>" /></td>
76
  </tr>
77
 
78
  <tr>
79
  <td>Counter: </td>
80
- <td><select name="file[show_counter]">
81
  <option value="0">Hide</option>
82
  <option value="1" <?php if($file['show_counter']!=0) echo 'selected="selected"'; ?> >Show</option>
83
  </select></td>
84
  </tr>
85
  <tr>
86
  <td width="70">Access:</td>
87
- <td><select name="file[access]">
88
  <option value="guest">All Visitors</option>
89
- <option value="member" <?php if($file[access]=='memder') echo 'selected'; ?>>Members Only</option>
90
  </select>
91
  </td>
92
  </tr>
@@ -101,7 +103,7 @@ input{
101
  <div style="width: 48%;float: right;height: inherit;">
102
  <div class="postbox " id="categories_meta_box">
103
  <div title="Click to toggle" class="handlediv"><br></div><h3 class="hndle"><span>Categories</span></h3>
104
- <div class="inside">
105
  <ul>
106
  <?php
107
  $currentAccesss = maybe_unserialize( $file['category'] );
@@ -113,6 +115,11 @@ input{
113
  <div class="clear"></div>
114
  </div>
115
  </div>
 
 
 
 
 
116
 
117
 
118
  </div>
@@ -136,24 +143,34 @@ input{
136
  <div class="postbox " id="upload_meta_box">
137
  <div title="Click to toggle" class="handlediv"><br></div><h3 class="hndle"><span>Upload file from PC</span></h3>
138
  <div class="inside">
139
-
140
  <div id="currentfiles">
141
- <?php if($file['file']!=''){ ?>
142
  <div class="cfile" id="cfl">
143
- <nobr>
144
- <b style="float: left"><?php echo basename($file['file']); ?></b> <a href='#' id="dcf" title="Delete Current File" style="float: right;">delete</a>
145
- </nobr>
 
 
 
 
 
 
146
  <div style="clear: both;"></div>
147
  </div>
148
- <?php } ?>
149
 
150
 
151
  <?php if($file['file']!=''): ?>
152
  <script type="text/javascript">
153
 
154
 
155
- jQuery('#dcf').click(function(){
156
- jQuery('#cfl').slideUp();
 
 
 
 
 
157
  return false;
158
  });
159
 
@@ -167,7 +184,134 @@ jQuery('#dcf').click(function(){
167
 
168
 
169
  </div>
170
- <input type="file" id="file_upload" name="media"/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
  <div class="clear"></div>
173
  </div>
@@ -237,22 +381,23 @@ jQuery('#dcf').click(function(){
237
 
238
 
239
 
240
- <input type="button" value="&#171; Back" tabindex="9" class="button-secondary" onclick="location.href='admin.php?page=file-manager'" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
241
 
242
- <input type="reset" value="Reset" tabindex="9" class="button-secondary" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
243
 
244
- <input type="submit" value="<?php echo $_GET['task']=='wpdm_edit_file'?'Update Package':'Create Package'; ?>" accesskey="p" tabindex="5" id="publish" class="button-primary" name="publish">
245
  <div class="clear"></div>
 
246
  </div>
247
  </div>
248
 
249
  <div class="postbox " id="action">
250
- <h3><span>My Other Plugins</span></h3>
251
  <div class="inside">
252
- <a href="http://wpeden.com/wpeden-club/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Themes & Plugins Club</h3><span style="display: block;padding: 10px;font-size:14pt;font-family:'Segoe UI Light';line-height: 1.5;color:#008000">WP Eden Club! Download all of our club themes and plugins only for $35!</span></a>
253
- <a href="http://wpeden.com/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Themes & Plugins Collection</h3><img src="http://wpeden.com/wp-content/themes/wp-eden/img/logo.png" /></a>
254
- <a href="http://www.wpdownloadmanager.com/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Download Manager Pro</h3><img src="http://www.wpdownloadmanager.com/wp-content/themes/wpdm/images/icon.png" /></a>
255
- <a href="http://www.wpmarketplaceplugin.com/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Marketplace Plugin</h3><img vspace="12" src="http://wpmarketplaceplugin.com/wp-content/uploads/2011/06/logo2.png" /></a>
 
256
  <div style="clear: both;"></div>
257
  </div>
258
  </div>
@@ -262,7 +407,43 @@ jQuery('#dcf').click(function(){
262
  </form>
263
 
264
  </div>
265
-
 
 
 
 
266
 
267
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
 
8
  input{
9
  padding: 4px 7px;
10
  }
11
+ .cfile{margin: 2px;border:3px solid #eeeeee;background: #fafafa;overflow:hidden;padding:5px;margin-bottom: 10px;}
12
  .dfile{margin: 2px;border:1px solid #800;background: #ffdfdf;overflow:hidden;padding:5px;}
13
  .cfile img, .dfile img{cursor: pointer;}
14
  .inside{padding:10px !important;}
15
  #editorcontainer textarea{border:0px;width:99.9%;}
16
+ #file_uploadUploader {background: transparent url('<?php echo plugins_url('/download-manager/images/browse.png'); ?>') left top no-repeat; }
17
  #file_uploadUploader:hover {background-position: left bottom; }
18
  .frm td{line-height: 30px; border-bottom: 1px solid #EEEEEE; padding:5px; font-size:9pt;font-family: Tahoma;}
19
 
28
  <h2>Add New Download Package</h2>
29
 
30
  <?php }?>
31
+ <form id="wpdmpack" action="" method="post">
32
+ <input type="hidden" name="action" value="save_wpdm_file" />
33
+ <input type="hidden" name="wpdmtask" value="<?php echo isset($_GET['task'])&&$_GET['task']=='wpdm_edit_file'?'update':'create';?>" />
34
  <input type="hidden" name="id" value="<?php echo $file['id']; ?>" />
35
  <div style="width: 75%;float:left;">
36
 
37
  <table cellpadding="5" cellspacing="5" width="100%">
38
  <tr>
39
 
40
+ <td><input style="font-size:16pt;width:100%;color:<?php echo $file['title']?'#000':'#ccc'; ?>" onfocus="if(this.value=='Enter title here') {this.value=''; jQuery(this).css('color','#000'); }" onblur="if(this.value==''||this.value=='Enter title here') {this.value='Enter title here'; jQuery(this).css('color','#ccc');}" type="text" value="<?php echo $file['title']?esc_attr($file['title']):'Enter title here'; ?>" name="file[title]" /></td>
41
  </tr>
42
 
43
  <tr>
44
  <td valign="top">
45
  <div id="poststuff" class="postarea">
46
+ <?php $file['description'] = !isset($file['description'])?' ':$file['description']; wp_editor(stripslashes($file['description']),'file[description]','file[description]', true); ?>
47
  <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
48
  <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
49
  </div>
62
  <table cellpadding="5" id="file_settings_table" cellspacing="0" width="100%" class="frm">
63
  <tr id="link_label_row">
64
  <td width="110px">Link Label:</td>
65
+ <td><input size="10" type="text" style="width: 200px" value="<?php echo $file[link_label]?esc_attr($file['link_label']):'Download'; ?>" name="file[link_label]" />
66
  </td></tr>
67
  <tr id="password_row">
68
  <td>Password:</td>
69
+ <td><input size="10" style="width: 200px" type="text" name="file[password]" value="<?php echo esc_attr($file['password']); ?>" /></td>
70
  </tr>
71
  <tr id="download_limit_row">
72
  <td>Stock&nbsp;Limit:</td>
73
+ <td><input size="10" style="width: 80px" type="text" name="file[quota]" value="<?php echo $file['quota']; ?>" /></td>
74
  </tr>
75
  <tr>
76
  <td>Download Count: </td>
77
+ <td><input type="text" name="file[download_count]" value="<?php echo $file['download_count']?$file['download_count']:0; ?>" /></td>
78
  </tr>
79
 
80
  <tr>
81
  <td>Counter: </td>
82
+ <td><select id="counter" style="width: 100px;" name="file[show_counter]">
83
  <option value="0">Hide</option>
84
  <option value="1" <?php if($file['show_counter']!=0) echo 'selected="selected"'; ?> >Show</option>
85
  </select></td>
86
  </tr>
87
  <tr>
88
  <td width="70">Access:</td>
89
+ <td><select id="access" style="width: 120px;" name="file[access]">
90
  <option value="guest">All Visitors</option>
91
+ <option value="member" <?php if($file['access']=='member') echo 'selected'; ?>>Members Only</option>
92
  </select>
93
  </td>
94
  </tr>
103
  <div style="width: 48%;float: right;height: inherit;">
104
  <div class="postbox " id="categories_meta_box">
105
  <div title="Click to toggle" class="handlediv"><br></div><h3 class="hndle"><span>Categories</span></h3>
106
+ <div class="inside" style="max-height: 150px;overflow: auto;">
107
  <ul>
108
  <?php
109
  $currentAccesss = maybe_unserialize( $file['category'] );
115
  <div class="clear"></div>
116
  </div>
117
  </div>
118
+
119
+ <?php
120
+ include(dirname(__FILE__).'/wpdm-file-icon.php');
121
+ ?>
122
+
123
 
124
 
125
  </div>
143
  <div class="postbox " id="upload_meta_box">
144
  <div title="Click to toggle" class="handlediv"><br></div><h3 class="hndle"><span>Upload file from PC</span></h3>
145
  <div class="inside">
146
+ <input type="hidden" name="file[file]" value="<?php echo $file['file']; ?>" id="wpdmfile" />
147
  <div id="currentfiles">
 
148
  <div class="cfile" id="cfl">
149
+ <?php if($file['file']!=''){
150
+ if(file_exists(UPLOAD_DIR.'/'.$file['file']))
151
+ $filesize = number_format(filesize(UPLOAD_DIR.'/'.$file['file'])/1025,2);
152
+ else if(file_exists($file['file']))
153
+ $filesize = number_format(filesize($file['file'])/1025,2);
154
+ ?>
155
+
156
+ <div style="float: left"><strong><?php echo basename($file['file']); ?></strong><br/><?php echo $filesize; ?> KB</div> <a href='#' id="dcf" title="Delete Current File" style="float: right;height:32px;"><img src="<?php echo plugins_url('/download-manager/images/error.png'); ?>" /></a>
157
+ <?php } else echo "<span style='font-weight:bold;color:#ddd'>No file uploaded yet!</span>"; ?>
158
  <div style="clear: both;"></div>
159
  </div>
160
+
161
 
162
 
163
  <?php if($file['file']!=''): ?>
164
  <script type="text/javascript">
165
 
166
 
167
+ jQuery('#dcf').click(function(){
168
+ if(!confirm('Are your sure?')) return false;
169
+ jQuery('#cfl').fadeTo('slow',0.3);
170
+ jQuery.post('admin-ajax.php',{action:'delete_file',file:'<?php echo $file['id']; ?>'},function(res){
171
+ jQuery('#cfl').slideUp();
172
+ jQuery('#wpdmfile').val('');
173
+ });
174
  return false;
175
  });
176
 
184
 
185
 
186
  </div>
187
+
188
+ <div id="plupload-upload-ui" class="hide-if-no-js">
189
+ <div id="drag-drop-area">
190
+ <div class="drag-drop-inside">
191
+ <p class="drag-drop-info"><?php _e('Drop files here'); ?></p>
192
+ <p><?php _ex('or', 'Uploader: Drop files here - or - Select Files'); ?></p>
193
+ <p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
194
+ </div>
195
+ </div>
196
+ </div>
197
+
198
+ <?php
199
+
200
+ $plupload_init = array(
201
+ 'runtimes' => 'html5,silverlight,flash,html4',
202
+ 'browse_button' => 'plupload-browse-button',
203
+ 'container' => 'plupload-upload-ui',
204
+ 'drop_element' => 'drag-drop-area',
205
+ 'file_data_name' => 'async-upload',
206
+ 'multiple_queues' => false,
207
+ 'max_file_size' => wp_max_upload_size().'b',
208
+ 'url' => admin_url('admin-ajax.php'),
209
+ 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
210
+ 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
211
+ 'filters' => array(array('title' => __('Allowed Files'), 'extensions' => '*')),
212
+ 'multipart' => true,
213
+ 'urlstream_upload' => true,
214
+
215
+ // additional post data to send to our ajax hook
216
+ 'multipart_params' => array(
217
+ '_ajax_nonce' => wp_create_nonce('photo-upload'),
218
+ 'action' => 'file_upload', // the ajax action name
219
+ ),
220
+ );
221
+
222
+ // we should probably not apply this filter, plugins may expect wp's media uploader...
223
+ $plupload_init = apply_filters('plupload_init', $plupload_init); ?>
224
+
225
+ <script type="text/javascript">
226
+
227
+ jQuery(document).ready(function($){
228
+
229
+ // create the uploader and pass the config from above
230
+ var uploader = new plupload.Uploader(<?php echo json_encode($plupload_init); ?>);
231
+
232
+ // checks if browser supports drag and drop upload, makes some css adjustments if necessary
233
+ uploader.bind('Init', function(up){
234
+ var uploaddiv = jQuery('#plupload-upload-ui');
235
+
236
+ if(up.features.dragdrop){
237
+ uploaddiv.addClass('drag-drop');
238
+ jQuery('#drag-drop-area')
239
+ .bind('dragover.wp-uploader', function(){ uploaddiv.addClass('drag-over'); })
240
+ .bind('dragleave.wp-uploader, drop.wp-uploader', function(){ uploaddiv.removeClass('drag-over'); });
241
+
242
+ }else{
243
+ uploaddiv.removeClass('drag-drop');
244
+ jQuery('#drag-drop-area').unbind('.wp-uploader');
245
+ }
246
+ });
247
+
248
+ uploader.init();
249
+
250
+ // a file was added in the queue
251
+ uploader.bind('FilesAdded', function(up, files){
252
+ //var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10);
253
+
254
+
255
+
256
+ plupload.each(files, function(file){
257
+ jQuery('#filelist').append(
258
+ '<div class="file" id="' + file.id + '"><b>' +
259
+
260
+ file.name + '</b> (<span>' + plupload.formatSize(0) + '</span>/' + plupload.formatSize(file.size) + ') ' +
261
+ '<div class="progress progress-success progress-striped active"><div class="bar fileprogress"></div></div></div>');
262
+ });
263
+
264
+ up.refresh();
265
+ up.start();
266
+ });
267
+
268
+ uploader.bind('UploadProgress', function(up, file) {
269
+
270
+ jQuery('#' + file.id + " .fileprogress").width(file.percent + "%");
271
+ jQuery('#' + file.id + " span").html(plupload.formatSize(parseInt(file.size * file.percent / 100)));
272
+ });
273
+
274
+
275
+ // a file was uploaded
276
+ uploader.bind('FileUploaded', function(up, file, response) {
277
+
278
+ // this is your ajax response, update the DOM with it or something...
279
+ //console.log(response);
280
+ //response
281
+ jQuery('#' + file.id ).remove();
282
+ var d = new Date();
283
+ var ID = d.getTime();
284
+ response = response.response;
285
+ var data = response.split("|||");
286
+ jQuery('#wpdmfile').val(data[0]);
287
+ jQuery('#cfl').html('<div style="float: left"><strong>'+data[0]+'</strong><br/>'+data[1]+' KB</div>').slideDown();
288
+ /*if(response.length>20) nm = response.substring(0,7)+'...'+response.substring(response.length-10);
289
+ jQuery('#currentfiles table.widefat').append("<tr id='"+ID+"' class='cfile'><td><input type='hidden' id='in_"+ID+"' name='files[]' value='"+response+"' /><img id='del_"+ID+"' src='<?php echo plugins_url(); ?>/download-manager/images/minus.png' rel='del' align=left /></td><td>"+response+"</td><td width='40%'><input style='width:99%' type='text' name='wpdm_meta[fileinfo]["+response+"][title]' value='"+response+"' onclick='this.select()'></td><td><input size='10' type='text' id='indpass_"+ID+"' name='wpdm_meta[fileinfo]["+response+"][password]' value=''> <img style='cursor: pointer;float: right;margin-top: -3px' class='genpass' onclick=\"return generatepass('indpass_"+ID+"')\" title='Generate Password' src=\"<?php echo plugins_url('download-manager/images/generate-pass.png'); ?>\" /></td></tr>");
290
+ jQuery('#'+ID).fadeIn();
291
+ jQuery('#del_'+ID).click(function(){
292
+ if(jQuery(this).attr('rel')=='del'){
293
+ jQuery('#'+ID).removeClass('cfile').addClass('dfile');
294
+ jQuery('#in_'+ID).attr('name','del[]');
295
+ jQuery(this).attr('rel','undo').attr('src','<?php echo plugins_url(); ?>/download-manager/images/add.png').attr('title','Undo Delete');
296
+ } else if(jQuery(this).attr('rel')=='undo'){
297
+ jQuery('#'+ID).removeClass('dfile').addClass('cfile');
298
+ jQuery('#in_'+ID).attr('name','files[]');
299
+ jQuery(this).attr('rel','del').attr('src','<?php echo plugins_url(); ?>/download-manager/images/minus.png').attr('title','Delete File');
300
+ }
301
+
302
+
303
+ }); */
304
+
305
+
306
+ });
307
+
308
+ });
309
+
310
+ </script>
311
+ <div id="filelist"></div>
312
+
313
+ <div class="clear"></div>
314
+ <!--<input type="file" id="file_upload" name="media"/>-->
315
 
316
  <div class="clear"></div>
317
  </div>
381
 
382
 
383
 
 
384
 
385
+ <input style="float: right" type="reset" value="Reset" tabindex="9" class="button-secondary button button-large" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
386
 
387
+ <input type="submit" value="<?php echo $_GET['task']=='wpdm_edit_file'?'Update Package':'Create Package'; ?>" accesskey="p" tabindex="5" id="publish" class="button-primary button button-large" name="publish">
388
  <div class="clear"></div>
389
+
390
  </div>
391
  </div>
392
 
393
  <div class="postbox " id="action">
394
+ <h3><span>My Other Items</span></h3>
395
  <div class="inside">
396
+ <a href="http://wpeden.com/wordpress/themes/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">Pro Level Themes for Free</h3><span style="display: block;padding: 10px;font-size:14pt;font-family:'Segoe UI Light';line-height: 1.5;color:#008000"><img style="max-width: 100%;height:auto;" src="<?php echo plugins_url('download-manager/images/theme.png'); ?>" /></span></a>
397
+ <a href="http://www.wpdownloadmanager.com/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Download Manager Pro</h3><img style="max-width: 100%;height:auto;" src="<?php echo plugins_url('download-manager/images/wpdm.png'); ?>" /></a>
398
+ <a href="http://www.wpmarketplaceplugin.com/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Marketplace Plugin</h3><img style="max-width: 100%;height:auto;" vspace="12" src="<?php echo plugins_url('download-manager/images/wpmp.png'); ?>" /></a>
399
+ <a href="http://wpeden.com/" style="width:97%;overflow:hidden;margin:5px;background: #fafafa;border: 1px solid #ccc;display: block;float: left;text-align: center;-webkit-border-radius: 6px;-moz-border-radius: 6px;border-radius: 6px;" ><h3 style="margin: 0px;background: #ccc;-webkit-border-top-left-radius: 5px;-webkit-border-top-right-radius: 5px;-moz-border-radius-topleft: 5px;-moz-border-radius-topright: 5px;border-top-left-radius: 5px;border-top-right-radius: 5px;padding:5px;text-decoration: none;color:#333">WordPress Themes & Plugins Collection</h3><img style="max-width: 100%;height:auto;" src="<?php echo plugins_url('download-manager/images/wpeden.png'); ?>" /></a>
400
+
401
  <div style="clear: both;"></div>
402
  </div>
403
  </div>
407
  </form>
408
 
409
  </div>
410
+ <div id="w84sv" style="display: none;position: fixed;top:10px;right:10px;padding:15px 30px;border-radius:4px;background: #aa0000;color:#ffffff;font-weight: bold;font-family:'Courier New';z-index:999999;font-size: 12pt;">
411
+ Saving<span style="text-decoration:blink;">...</span>
412
+ </div>
413
+ <div id="svd" onclick="jQuery(this).fadeOut();" style="display: none;position: fixed;top:10px;right:10px;padding:15px 30px;border-radius:4px;background: #00aa00;color:#ffffff;font-weight: bold;font-family:'Courier New';z-index:999999;font-size: 12pt;">
414
+ </div>
415
 
416
+
417
+
418
+ <script language="JavaScript">
419
+ <!--
420
+ jQuery(function(){
421
+ jQuery('select').chosen();
422
+ });
423
+ jQuery('#wpdmpack').submit(function(){
424
+ jQuery('#svd').fadeOut();
425
+ jQuery('#w84sv').fadeIn();
426
+ jQuery('#publish').attr('disabled','disabled');
427
+ jQuery('#wpdmpack textarea').val(tinyMCE.activeEditor.getContent());
428
+ jQuery(this).ajaxSubmit({
429
+ url:'admin-ajax.php',
430
+ beforeSubmit:function(){
431
+
432
+ },
433
+ success:function(res){
434
+ var msg = '';
435
+ if(res=='updated') msg = '<?php _e('File Updated Successfully!'); ?>';
436
+ else if(parseInt(res)>0){
437
+ msg = '<?php _e('File Created Successfully! Please wait while redirecting...'); ?>';
438
+ //location.href='admin.php?page=file-manager&task=wpdm_edit_file&id='+res;
439
+ }
440
+ jQuery('#w84sv').fadeOut();
441
+ jQuery('#svd').html(msg).fadeIn();
442
+ jQuery('#publish').removeAttr('disabled');
443
+ }
444
+ });
445
+ return false;
446
+ });
447
+ //-->
448
+ </script>
449
 
wpdm-all-downloads.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script language="JavaScript" type="text/javascript" src="<?php echo plugins_url('download-manager/js/jquery.dataTables.js'); ?>"></script>
2
+ <link rel="stylesheet" href="<?php echo plugins_url('download-manager/css/jquery.dataTables.css'); ?>" type="text/css" media="all" />
3
+ <style type="text/css">
4
+ #TB_window{
5
+ -moz-box-shadow: 0 0 5px #000;
6
+ -webkit-box-shadow: 0 0 5px#000;
7
+ box-shadow: 0 0 5px #000;
8
+ }
9
+ #TB_overlay{
10
+ opacity:0.5;
11
+ }
12
+ </style>
13
+ <div class="wpdmpro">
14
+ <div class="container-fluid">
15
+ <table id="wpdmmydls" style="width: 100%;" class="dtable table-bordered zebra-striped">
16
+ <thead><tr>
17
+ <th class="">Title</th>
18
+ <th>File Type</th>
19
+ <th style="width: 100px;">Download</th></tr></thead>
20
+ <tbody>
21
+ <?php
22
+ global $wpdm_download_button_class, $wpdm_login_icon, $wpdm_download_icon, $wpdm_lock_icon;
23
+ $wpdm_download_button_class = '';
24
+ $wpdm_login_icon = $wpdm_download_icon = $wpdm_lock_icon = '';
25
+ $myfiles = $wpdb->get_results("select * from ahm_files",ARRAY_A);
26
+ if(!is_array($myfiles)) $myfiles = array();
27
+
28
+ foreach($myfiles as $mfile): $filetype = end(explode('.',$mfile['file'])) ?>
29
+ <tr>
30
+ <td style="line-height: normal;height: 40px;padding-left:40px;background: url('<?php echo plugins_url('download-manager/icon/'.($mfile['icon']?$mfile['icon']:'file_extension_'.$filetype.'.png')); ?>') 2px center no-repeat"><a href='?download=<?php echo $mfile['id']; ?>' class="wpdm-pck-dl"><b><?php echo htmlspecialchars(stripcslashes($mfile['title'])); ?></b></a>
31
+ <br/>Access: <?php echo $mfile['access']=='guest'?'For EveryOne':'Members Only'; ?><?php echo $mfile['password']==''?'':' / Password Protected'; ?>
32
+ </td>
33
+ <td><?php echo strtoupper($filetype); ?></td>
34
+ <td><?php echo $mfile['download_count']; ?></td></tr>
35
+ <?php endforeach; ?>
36
+ </tbody>
37
+ </table>
38
+ </div>
39
+ </div>
40
+ <script type="text/javascript" charset="utf-8">
41
+ /* Default class modification */
42
+ jQuery.extend( jQuery.fn.dataTableExt.oStdClasses, {
43
+ "sSortAsc": "header headerSortDown",
44
+ "sSortDesc": "header headerSortUp",
45
+ "sSortable": "header"
46
+ } );
47
+
48
+ jQuery('.wpdm-pck-dl').click(function(){
49
+ tb_show(jQuery(this).html(),this.href+'&modal=1&width=600&height=400');
50
+ return false;
51
+ });
52
+
53
+ /* API method to get paging information */
54
+ jQuery.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
55
+ {
56
+ return {
57
+ "iStart": oSettings._iDisplayStart,
58
+ "iEnd": oSettings.fnDisplayEnd(),
59
+ "iLength": oSettings._iDisplayLength,
60
+ "iTotal": oSettings.fnRecordsTotal(),
61
+ "iFilteredTotal": oSettings.fnRecordsDisplay(),
62
+ "iPage": Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
63
+ "iTotalPages": Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
64
+ };
65
+ }
66
+
67
+ /* Bootstrap style pagination control */
68
+ jQuery.extend( jQuery.fn.dataTableExt.oPagination, {
69
+ "bootstrap": {
70
+ "fnInit": function( oSettings, nPaging, fnDraw ) {
71
+ var oLang = oSettings.oLanguage.oPaginate;
72
+ var fnClickHandler = function ( e ) {
73
+ if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
74
+ fnDraw( oSettings );
75
+ }
76
+ };
77
+
78
+ jQuery(nPaging).addClass('pagination').append(
79
+ '<ul>'+
80
+ '<li class="prev disabled"><a href="#">&larr; '+oLang.sPrevious+'</a></li>'+
81
+ '<li class="next disabled"><a href="#">'+oLang.sNext+' &rarr; </a></li>'+
82
+ '</ul>'
83
+ );
84
+ var els =jQuery('a', nPaging);
85
+ jQuery(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
86
+ jQuery(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
87
+ },
88
+
89
+ "fnUpdate": function ( oSettings, fnDraw ) {
90
+ var oPaging = oSettings.oInstance.fnPagingInfo();
91
+ var an = oSettings.aanFeatures.p;
92
+ var i, sClass, iStart, iEnd, iHalf=Math.floor(oPaging.iTotalPages/2);
93
+
94
+ if ( oPaging.iTotalPages < 5) {
95
+ iStart = 1;
96
+ iEnd = oPaging.iTotalPages;
97
+ }
98
+ else if ( oPaging.iPage <= iHalf ) {
99
+ iStart = 1;
100
+ iEnd = 5;
101
+ } else if ( oPaging.iPage >= (5-iHalf) ) {
102
+ iStart = oPaging.iTotalPages - 5 + 1;
103
+ iEnd = oPaging.iTotalPages;
104
+ } else {
105
+ iStart = oPaging.iPage - Math.ceil(5/2) + 1;
106
+ iEnd = iStart + 5 - 1;
107
+ }
108
+
109
+ for ( i=0, iLen=an.length ; i<iLen ; i++ ) {
110
+ // Remove the middle elements
111
+ jQuery('li:gt(0)', an[i]).filter(':not(:last)').remove();
112
+
113
+ // Add the new list items and their event handlers
114
+ for ( i=iStart ; i<=iEnd ; i++ ) {
115
+ sClass = (i==oPaging.iPage+1) ? 'class="active"' : '';
116
+ jQuery('<li '+sClass+'><a href="#">'+i+'</a></li>')
117
+ .insertBefore('li:last', an[i])
118
+ .bind('click', function () {
119
+ oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
120
+ fnDraw( oSettings );
121
+ } );
122
+ }
123
+
124
+ // Add / remove disabled classes from the static elements
125
+ if ( oPaging.iPage === 0 ) {
126
+ jQuery('li:first', an[i]).addClass('disabled');
127
+ } else {
128
+ jQuery('li:first', an[i]).removeClass('disabled');
129
+ }
130
+
131
+ if ( oPaging.iPage === oPaging.iTotalPages-1 ) {
132
+ jQuery('li:last', an[i]).addClass('disabled');
133
+ } else {
134
+ jQuery('li:last', an[i]).removeClass('disabled');
135
+ }
136
+ }
137
+
138
+ }
139
+ }
140
+ } );
141
+
142
+ /* Table initialisation */
143
+ jQuery(document).ready(function() {
144
+ jQuery('#wpdmmydls').dataTable( );
145
+ } );
146
+ </script>
wpdm-categories.php CHANGED
@@ -22,7 +22,7 @@ input{
22
  <th style="" class="manage-column column-cb check-column" id="cb" scope="col"><input type="checkbox"></th>
23
 
24
  <th style="" class="manage-column column-media" id="media" scope="col">Category</th>
25
-
26
 
27
  </tr>
28
  </thead>
@@ -32,11 +32,12 @@ input{
32
  <th style="" class="manage-column column-cb check-column" id="cb" scope="col"><input type="checkbox"></th>
33
 
34
  <th style="" class="manage-column column-media" id="media" scope="col">Category</th>
 
35
  </tr>
36
  </tfoot>
37
 
38
  <tbody class="list:post" id="the-list">
39
- <?php
40
  function wpdm_render_cats($parent="",$level=0){
41
  if($categories = maybe_unserialize(get_option("_fm_categories",true))){
42
  if(is_array($categories)){
@@ -52,7 +53,10 @@ input{
52
  <a title="Edit" href="admin.php?page=file-manager/categories&task=EditCategory&cid=<?php echo $id; ?>">
53
  <b><?php echo $pres.' '.$category['title']?></b>
54
  </a>
55
- <div class="row-actions"><span class="edit"><a href="admin.php?page=file-manager/categories&task=EditCategory&cid=<?php echo $id; ?>">Edit</a> | </span><span class="delete"><a href="admin.php?page=file-manager/categories&task=DeleteCategory&cid=<?php echo $id?>" onclick="return showNotice.warn();" class="submitdelete">Delete Permanently</a> | <input type="text" title="copy the code and place it anywhere inside your post or page" value="{wpdm_category=<?php echo $id; ?>}" readonly=readonly onclick="this.select()" style="width:180px;font-size: 10px;" /></div>
 
 
 
56
  </td>
57
 
58
 
@@ -91,7 +95,7 @@ $cid = stripslashes($_GET['cid']);
91
  ?>
92
 
93
  <tbody class="list:post" id="the-list">
94
- <tr valign="top" class="alternate author-self status-inherit" id="post-8">
95
  <td class="author column-author">
96
  <input style="" type="hidden" name="cid" value="<?php echo $cat?$cid:''; ?>">
97
  Title:<br>
@@ -122,6 +126,10 @@ $cid = stripslashes($_GET['cid']);
122
  <!--
123
  jQuery('.<?php echo $cid;?>').attr('disabled','disabled');
124
 
 
 
 
 
125
  function wpdm_deleteallcats(){
126
  if(!confirm('Are you sure?')) return false;
127
  location.href='admin.php?page=file-manager/categories&task=delete-all';
22
  <th style="" class="manage-column column-cb check-column" id="cb" scope="col"><input type="checkbox"></th>
23
 
24
  <th style="" class="manage-column column-media" id="media" scope="col">Category</th>
25
+ <th style="" class="manage-column column-media" id="media" scope="col">Shortcode</th>
26
 
27
  </tr>
28
  </thead>
32
  <th style="" class="manage-column column-cb check-column" id="cb" scope="col"><input type="checkbox"></th>
33
 
34
  <th style="" class="manage-column column-media" id="media" scope="col">Category</th>
35
+ <th style="" class="manage-column column-media" id="media" scope="col">Shortcode</th>
36
  </tr>
37
  </tfoot>
38
 
39
  <tbody class="list:post" id="the-list">
40
+ <?php
41
  function wpdm_render_cats($parent="",$level=0){
42
  if($categories = maybe_unserialize(get_option("_fm_categories",true))){
43
  if(is_array($categories)){
53
  <a title="Edit" href="admin.php?page=file-manager/categories&task=EditCategory&cid=<?php echo $id; ?>">
54
  <b><?php echo $pres.' '.$category['title']?></b>
55
  </a>
56
+ <div class="row-actions"><div class="button-group"><a class="button" href="admin.php?page=file-manager/categories&task=EditCategory&cid=<?php echo $id; ?>">Edit</a><a href="admin.php?page=file-manager/categories&task=DeleteCategory&cid=<?php echo $id?>" onclick="return showNotice.warn();" class="button submitdelete" style="color: #aa0000">Delete Permanently</a></div></div>
57
+ </td>
58
+ <td>
59
+ <input type="text" title="copy the code and place it anywhere inside your post or page" value="[wpdm_category id=<?php echo $id; ?> order_field=id order=desc]" readonly=readonly onclick="this.select()" style="width:180px;font-size: 10px;" />
60
  </td>
61
 
62
 
95
  ?>
96
 
97
  <tbody class="list:post" id="the-list">
98
+ <tr valign="top">
99
  <td class="author column-author">
100
  <input style="" type="hidden" name="cid" value="<?php echo $cat?$cid:''; ?>">
101
  Title:<br>
126
  <!--
127
  jQuery('.<?php echo $cid;?>').attr('disabled','disabled');
128
 
129
+ jQuery(function(){
130
+ jQuery('select').chosen();
131
+ });
132
+
133
  function wpdm_deleteallcats(){
134
  if(!confirm('Are you sure?')) return false;
135
  location.href='admin.php?page=file-manager/categories&task=delete-all';
wpdm-file-icon.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //print_r( $fileinfo ); ?>
2
+ <style type="text/css">
3
+ .wdmiconfile{
4
+ -webkit-border-radius: 6px;
5
+ -moz-border-radius: 6px;
6
+ border-radius: 6px;
7
+ }
8
+ </style>
9
+
10
+
11
+ <div class="postbox " id="iconimage">
12
+ <div title="Click to toggle" class="handlediv"><br></div><h3 class="hndle"><span>Select Icon </span></h3>
13
+ <div class="inside" style="height: 200px;overflow: auto;">
14
+
15
+ <br clear="all" />
16
+ <div id="w-icons">
17
+
18
+ <?php
19
+ $img = array('jpg','gif','jpeg','png');
20
+ $icons = scandir(dirname(__FILE__).'/icon/');
21
+ array_shift($icons);
22
+ array_shift($icons);
23
+
24
+ foreach($icons as $icon): $ext = strtolower(end(explode(".",$icon))); if(in_array($ext,$img)): ?>
25
+ <label>
26
+ <img class="wdmiconfile" id="<?php echo md5($icon) ?>" src="<?php echo plugins_url().'/download-manager/icon/'.$icon; ?>" alt="<?php echo $icon ?>" style="padding:5px; margin:1px; float:left; border:#fff 2px solid;height: 32px;width:auto; " />
27
+ <input rel="wdmiconfile" style="display:none" <?php if($file['icon']==$icon) echo ' checked="checked" ' ?> type="radio" name="file[icon]" class="checkbox" value="<?php echo $icon; ?>"></label>
28
+ <?php endif; endforeach; ?>
29
+ </div>
30
+ <script type="text/javascript">
31
+ //border:#CCCCCC 2px solid
32
+
33
+
34
+ jQuery('#<?php echo md5($file['icon']) ?>').css('border','#008000 2px solid').css('background','#F2FFF2');
35
+
36
+ jQuery('img.wdmiconfile').live('click',function(){
37
+
38
+ jQuery('img.wdmiconfile').css('border','#fff 2px solid').css('background','transparent');
39
+ jQuery(this).css('border','#008000 2px solid').css('background','#F2FFF2');
40
+
41
+
42
+
43
+ });
44
+
45
+ </script>
46
+
47
+ <div class="clear"></div>
48
+ </div>
49
+ </div>
50
+
wpdm-free-mce-button.php CHANGED
@@ -39,11 +39,12 @@ background: -moz-linear-gradient(top, #7abcff 0%, #60abf8 44%, #4096ee 100%); /*
39
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7abcff), color-stop(44%,#60abf8), color-stop(100%,#4096ee)); /* webkit */
40
 
41
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7abcff', endColorstr='#4096ee',GradientType=0 ); /* ie */
42
- -webkit-border-radius: 4px;
43
- -moz-border-radius: 4px;
44
- border-radius: 4px;
45
- border:1px solid #FFF;
46
  color: #FFF;
 
47
  }
48
 
49
  .input{
@@ -61,11 +62,141 @@ color: #000;
61
  .button-primary{cursor: pointer;}
62
  fieldset{padding: 10px;}
63
  </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  </head>
65
- <body> <br>
 
 
 
 
66
  <fieldset><legend>Embed File</legend>
67
- <input type="checkbox" id="title" value="1"> <label for="title">Show Title</label>
68
- <input type="checkbox" id="desc" value="1"> <label for="desc">Show Description</label> <br/>
69
  Template: <select id="template">
70
  <option value="">None</option>
71
  <option value="facebook">Facebook</option>
@@ -87,7 +218,7 @@ Drop Shadow Effect: <select id="shadow">
87
  foreach($res as $row){
88
  ?>
89
 
90
- <option value="<?php echo $row['id']; ?>"><?php echo $row['title']; ?></option>
91
 
92
 
93
  <?php
@@ -104,36 +235,258 @@ Drop Shadow Effect: <select id="shadow">
104
  ?>
105
  </select>
106
  <input type="submit" id="addtopostc" class="button button-primary" name="addtopost" value="Insert into post" />
 
 
 
 
 
 
 
107
  </fieldset>
 
 
 
 
 
 
 
 
 
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
111
- <script type="text/javascript" src="<?php echo home_url('/wp-includes/js/tinymce/tiny_mce_popup.js'); ?>"></script>
112
- <script type="text/javascript">
113
- /* <![CDATA[ */
114
- var title ='', desc = '';
115
- jQuery('#addtopost').click(function(){
116
- var win = window.dialogArguments || opener || parent || top;
117
- if(jQuery('#title').attr("checked")==true) title = ' title="true" ';
118
- if(jQuery('#desc').attr("checked")==true) desc = ' desc="true" ';
119
- var shadow = jQuery('#shadow').val();
120
- var template = ' template="'+jQuery('#template').val()+' '+shadow+'" ';
121
- if(jQuery('#template').val()=='') template = "";
122
- win.send_to_editor('[wpdm_file id='+$('#fl').val()+title+desc+template+']');
123
- tinyMCEPopup.close();
124
- return false;
125
- });
126
- jQuery('#addtopostc').click(function(){
127
- var win = window.dialogArguments || opener || parent || top;
128
- if(jQuery('#title').attr("checked")==true) title = ' title="true" ';
129
- if(jQuery('#desc').attr("checked")==true) desc = ' desc="true" ';
130
- win.send_to_editor('{wpdm_category='+jQuery('#flc').val()+'}');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  tinyMCEPopup.close();
132
- return false;
133
- });
134
-
135
- /* ]]> */
136
- </script>
 
 
 
 
 
 
 
 
 
 
137
 
138
  </body>
139
  </html>
39
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7abcff), color-stop(44%,#60abf8), color-stop(100%,#4096ee)); /* webkit */
40
 
41
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7abcff', endColorstr='#4096ee',GradientType=0 ); /* ie */
42
+ -webkit-border-radius: 3px;
43
+ -moz-border-radius: 3px;
44
+ border-radius: 3px;
45
+ border:0px solid #FFF;
46
  color: #FFF;
47
+ cursor: pointer;
48
  }
49
 
50
  .input{
62
  .button-primary{cursor: pointer;}
63
  fieldset{padding: 10px;}
64
  </style>
65
+ <style type="text/css">
66
+ .wpdm-pro legend{
67
+ font-size:10pt;
68
+ }
69
+ .wpdm-pro .nav a:active,
70
+ .wpdm-pro .nav a:hover,
71
+ .wpdm-pro .nav a{
72
+ outline:none !important;
73
+ }
74
+ .wpdm-pro button,
75
+ .wpdm-pro input[type=submit],
76
+ .wpdm-pro input[type=button],
77
+ .wpdm-pro input[type=text]{
78
+ line-height:26px;
79
+ min-height:26px;
80
+ margin-bottom: 10px;
81
+
82
+ }
83
+ .wpdm-pro .btn small{
84
+ font-size: 65%;
85
+ }
86
+ #wpdmcats {
87
+ height:300px;
88
+ overflow: auto;
89
+ border:1px solid #eeeeee;
90
+ border-radius:4px;
91
+ margin: 0px;
92
+ padding: 10px;
93
+ }
94
+ #wpdmcats li label{
95
+ display: inline;
96
+ font-size:11px;
97
+ }
98
+ #wpdmcats li{
99
+ list-style: none;
100
+ }
101
+
102
+ .nav-tabs li a{
103
+ text-transform: uppercase;
104
+ font-weight: bold;
105
+ }
106
+
107
+ .drag-drop-inside{
108
+ text-align: center;
109
+ padding:5px;
110
+ border:2px dashed #ddd;
111
+ margin:5px 0px;
112
+ }
113
+
114
+ .tab{
115
+ padding:10px 20px;
116
+ text-decoration: none;
117
+ margin: 0px;
118
+
119
+ display: block;
120
+ float: left;
121
+ }
122
+
123
+ .tab:first-child{
124
+ border-right:0px
125
+ }
126
+ .tab.active{
127
+ background:#ffffff;
128
+
129
+ }
130
+
131
+ #qbtn b{
132
+ font-weight: normal;
133
+ }
134
+ #qbtn input,
135
+ #qbtn textarea{
136
+ margin:0px;
137
+ margin-bottom: 10px;
138
+ }
139
+
140
+ .tab-pane{
141
+ background: #ffffff;
142
+ padding:10px;
143
+ }
144
+
145
+ </style>
146
+ <script type="text/javascript" src="<?php echo includes_url('/js/jquery/jquery.js'); ?>"></script>
147
+ <script type="text/javascript" src="<?php echo includes_url('/js/jquery/jquery.form.js'); ?>"></script>
148
+ <script type="text/javascript" src="<?php echo includes_url('/js/tinymce/tiny_mce_popup.js'); ?>"></script>
149
+ <script type='text/javascript' src='<?php echo includes_url('/js/plupload/plupload.js');?>'></script>
150
+ <script type='text/javascript' src='<?php echo includes_url('/js/plupload/plupload.html5.js');?>'></script>
151
+ <script type='text/javascript' src='<?php echo includes_url('/js/plupload/plupload.flash.js');?>'></script>
152
+ <script type='text/javascript' src='<?php echo includes_url('/js/plupload/plupload.silverlight.js');?>'></script>
153
+ <script type='text/javascript' src='<?php echo includes_url('/js/plupload/plupload.html4.js');?>'></script>
154
+ <script type="text/javascript">
155
+
156
+ jQuery(function(){
157
+
158
+ var s_title ='', s_desc = '';
159
+ jQuery('#addtopost').click(function(){
160
+
161
+ var win = window.dialogArguments || opener || parent || top;
162
+
163
+ if(jQuery('#s_title').is(":checked")) s_title = ' title="true" ';
164
+ if(jQuery('#s_desc').is(":checked")) s_desc = ' desc="true" ';
165
+ var shadow = jQuery('#shadow').val();
166
+ var template = ' template="'+jQuery('#template').val()+' '+shadow+'" ';
167
+ if(jQuery('#template').val()=='') template = "";
168
+ win.send_to_editor('[wpdm_file id='+jQuery('#fl').val()+s_title+s_desc+template+']');
169
+ tinyMCEPopup.close();
170
+ return false;
171
+ });
172
+ jQuery('#addtopostc').click(function(){
173
+ var win = window.dialogArguments || opener || parent || top;
174
+
175
+ win.send_to_editor('[wpdm_category id='+jQuery('#flc').val()+']');
176
+ tinyMCEPopup.close();
177
+ return false;
178
+ });
179
+
180
+ jQuery('#addtoposte').click(function(){
181
+ var win = window.dialogArguments || opener || parent || top;
182
+
183
+ win.send_to_editor(jQuery('#esc').val());
184
+ tinyMCEPopup.close();
185
+ return false;
186
+ });
187
+
188
+ });
189
+ </script>
190
+
191
  </head>
192
+ <body>
193
+
194
+ <a href="#scode" class="tab active">Insert ShortCode</a><a href="#qbtn" class="tab">Quick Add</a>
195
+ <div style="clear: both;"></div>
196
+ <div id="scode" class="tab-pane">
197
  <fieldset><legend>Embed File</legend>
198
+ <input type="checkbox" id="s_title" value="1"> <label for="s_title">Show Title</label>
199
+ <input type="checkbox" id="s_desc" value="1"> <label for="s_desc">Show Description</label> <br/>
200
  Template: <select id="template">
201
  <option value="">None</option>
202
  <option value="facebook">Facebook</option>
218
  foreach($res as $row){
219
  ?>
220
 
221
+ <option value="<?php echo $row['id']; ?>"><?php echo stripcslashes($row['title']); ?></option>
222
 
223
 
224
  <?php
235
  ?>
236
  </select>
237
  <input type="submit" id="addtopostc" class="button button-primary" name="addtopost" value="Insert into post" />
238
+ </fieldset> <br>
239
+ <fieldset><legend>Additional Short-codes</legend>
240
+ <select class="button input" id="esc">
241
+ <option value="[wpdm_all_packages]">All Downloads (Data Table)</option>
242
+ <option value="[wpdm_tree]">All Downloads (Tree View)</option>
243
+ </select>
244
+ <input type="submit" id="addtoposte" class="button button-primary" name="addtopost" value="Insert into post" />
245
  </fieldset>
246
+ </div>
247
+ <div id="qbtn" class="tab-pane" style="display: none;">
248
+ <fieldset>
249
+ <legend>Add New Package</legend>
250
+ <form action="admin.php?page=file-manager/add-new-package" id="wpdmpack" method="post">
251
+
252
+ <input type="hidden" id="act" name="file[access]" value="guest" />
253
+ <input type="hidden" name="action" value="save_wpdm_file" />
254
+ <input type="hidden" name="wpdmtask" value="create" />
255
 
256
+ <div class="row-fluid">
257
+ <b>Title:</b><br>
258
+ <input type="text" size="40" name="file[title]" /><br>
259
+ <b>Description:</b><br>
260
+ <textarea cols="50" rows="3" class="span12" name="file[description]"></textarea><br>
261
+ <div>
262
+ <b>Download Link Label:</b><br>
263
+ <input type="text" id="act" style="max-width: 100%;" name="file[link_label]" value="Download" />
264
+ </div>
265
+
266
+ <div style="clear: both;"></div>
267
+ <div>
268
+
269
+
270
+ </div>
271
+ <div class="postbox " id="upload_meta_box">
272
+ <div title="Click to toggle" class="handlediv"><br></div><h3 class="hndle"><span>Upload file from PC</span></h3>
273
+ <div class="inside">
274
+ <input type="hidden" name="file[file]" value="<?php echo $file['file']; ?>" id="wpdmfile" />
275
+ <div id="currentfiles">
276
+ <div class="cfile" id="cfl">
277
+ <?php if($file['file']!=''){
278
+ if(file_exists(UPLOAD_DIR.'/'.$file['file']))
279
+ $filesize = number_format(filesize(UPLOAD_DIR.'/'.$file['file'])/1025,2);
280
+ else if(file_exists($file['file']))
281
+ $filesize = number_format(filesize($file['file'])/1025,2);
282
+ ?>
283
+
284
+ <div style="float: left"><strong><?php echo basename($file['file']); ?></strong><br/><?php echo $filesize; ?> KB</div> <a href='#' id="dcf" title="Delete Current File" style="float: right;height:32px;"><img src="<?php echo plugins_url('/download-manager/images/error.png'); ?>" /></a>
285
+ <?php } else echo "<span style='font-weight:bold;color:#ddd'>No file uploaded yet!</span>"; ?>
286
+ <div style="clear: both;"></div>
287
+ </div>
288
+ <div style="clear: both;"></div>
289
 
290
+
291
+ <?php if($file['file']!=''): ?>
292
+ <script type="text/javascript">
293
+
294
+
295
+ jQuery('#dcf').click(function(){
296
+ if(!confirm('Are your sure?')) return false;
297
+ jQuery('#cfl').fadeTo('slow',0.3);
298
+ jQuery.post('admin-ajax.php',{action:'delete_file',file:'<?php echo $file['id']; ?>'},function(res){
299
+ jQuery('#cfl').slideUp();
300
+ jQuery('#wpdmfile').val('');
301
+ });
302
+ return false;
303
+
304
+
305
+ });
306
+
307
+
308
+
309
+ </script>
310
+
311
+
312
+ <?php endif; ?>
313
+
314
+
315
+
316
+ </div>
317
+
318
+ <div id="plupload-upload-ui" class="hide-if-no-js">
319
+ <div id="drag-drop-area">
320
+ <div class="drag-drop-inside">
321
+ <p class="drag-drop-info"><?php _e('Drop files here'); ?></p>
322
+ <p><?php _ex('or', 'Uploader: Drop files here - or - Select Files'); ?></p>
323
+ <p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
324
+ </div>
325
+ </div>
326
+ </div>
327
+
328
+ <?php
329
+
330
+ $plupload_init = array(
331
+ 'runtimes' => 'html5,silverlight,flash,html4',
332
+ 'browse_button' => 'plupload-browse-button',
333
+ 'container' => 'plupload-upload-ui',
334
+ 'drop_element' => 'drag-drop-area',
335
+ 'file_data_name' => 'async-upload',
336
+ 'multiple_queues' => false,
337
+ 'max_file_size' => wp_max_upload_size().'b',
338
+ 'url' => admin_url('admin-ajax.php'),
339
+ 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
340
+ 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
341
+ 'filters' => array(array('title' => __('Allowed Files'), 'extensions' => '*')),
342
+ 'multipart' => true,
343
+ 'urlstream_upload' => true,
344
+
345
+ // additional post data to send to our ajax hook
346
+ 'multipart_params' => array(
347
+ '_ajax_nonce' => wp_create_nonce('photo-upload'),
348
+ 'action' => 'file_upload', // the ajax action name
349
+ ),
350
+ );
351
+
352
+ // we should probably not apply this filter, plugins may expect wp's media uploader...
353
+ $plupload_init = apply_filters('plupload_init', $plupload_init); ?>
354
+
355
+ <script type="text/javascript">
356
+
357
+ jQuery(document).ready(function($){
358
+
359
+ // create the uploader and pass the config from above
360
+ var uploader = new plupload.Uploader(<?php echo json_encode($plupload_init); ?>);
361
+
362
+ // checks if browser supports drag and drop upload, makes some css adjustments if necessary
363
+ uploader.bind('Init', function(up){
364
+ var uploaddiv = jQuery('#plupload-upload-ui');
365
+
366
+ if(up.features.dragdrop){
367
+ uploaddiv.addClass('drag-drop');
368
+ jQuery('#drag-drop-area')
369
+ .bind('dragover.wp-uploader', function(){ uploaddiv.addClass('drag-over'); })
370
+ .bind('dragleave.wp-uploader, drop.wp-uploader', function(){ uploaddiv.removeClass('drag-over'); });
371
+
372
+ }else{
373
+ uploaddiv.removeClass('drag-drop');
374
+ jQuery('#drag-drop-area').unbind('.wp-uploader');
375
+ }
376
+ });
377
+
378
+ uploader.init();
379
+
380
+ // a file was added in the queue
381
+ uploader.bind('FilesAdded', function(up, files){
382
+ //var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10);
383
+
384
+
385
+
386
+ plupload.each(files, function(file){
387
+ jQuery('#filelist').append(
388
+ '<div class="file" id="' + file.id + '"><b>' +
389
+
390
+ file.name + '</b> (<span>' + plupload.formatSize(0) + '</span>/' + plupload.formatSize(file.size) + ') ' +
391
+ '<div class="progress progress-success progress-striped active"><div class="bar fileprogress"></div></div></div>');
392
+ });
393
+
394
+ up.refresh();
395
+ up.start();
396
+ });
397
+
398
+ uploader.bind('UploadProgress', function(up, file) {
399
+
400
+ jQuery('#' + file.id + " .fileprogress").width(file.percent + "%");
401
+ jQuery('#' + file.id + " span").html(plupload.formatSize(parseInt(file.size * file.percent / 100)));
402
+ });
403
+
404
+
405
+ // a file was uploaded
406
+ uploader.bind('FileUploaded', function(up, file, response) {
407
+
408
+ // this is your ajax response, update the DOM with it or something...
409
+ //console.log(response);
410
+ //response
411
+ jQuery('#' + file.id ).remove();
412
+ var d = new Date();
413
+ var ID = d.getTime();
414
+ response = response.response;
415
+ var data = response.split("|||");
416
+ jQuery('#wpdmfile').val(data[0]);
417
+ jQuery('#cfl').html('<div style="float: left"><strong>'+data[0]+'</strong><br/>'+data[1]+' KB</div>').slideDown();
418
+ /*if(response.length>20) nm = response.substring(0,7)+'...'+response.substring(response.length-10);
419
+ jQuery('#currentfiles table.widefat').append("<tr id='"+ID+"' class='cfile'><td><input type='hidden' id='in_"+ID+"' name='files[]' value='"+response+"' /><img id='del_"+ID+"' src='<?php echo plugins_url(); ?>/download-manager/images/minus.png' rel='del' align=left /></td><td>"+response+"</td><td width='40%'><input style='width:99%' type='text' name='wpdm_meta[fileinfo]["+response+"][title]' value='"+response+"' onclick='this.select()'></td><td><input size='10' type='text' id='indpass_"+ID+"' name='wpdm_meta[fileinfo]["+response+"][password]' value=''> <img style='cursor: pointer;float: right;margin-top: -3px' class='genpass' onclick=\"return generatepass('indpass_"+ID+"')\" title='Generate Password' src=\"<?php echo plugins_url('download-manager/images/generate-pass.png'); ?>\" /></td></tr>");
420
+ jQuery('#'+ID).fadeIn();
421
+ jQuery('#del_'+ID).click(function(){
422
+ if(jQuery(this).attr('rel')=='del'){
423
+ jQuery('#'+ID).removeClass('cfile').addClass('dfile');
424
+ jQuery('#in_'+ID).attr('name','del[]');
425
+ jQuery(this).attr('rel','undo').attr('src','<?php echo plugins_url(); ?>/download-manager/images/add.png').attr('title','Undo Delete');
426
+ } else if(jQuery(this).attr('rel')=='undo'){
427
+ jQuery('#'+ID).removeClass('dfile').addClass('cfile');
428
+ jQuery('#in_'+ID).attr('name','files[]');
429
+ jQuery(this).attr('rel','del').attr('src','<?php echo plugins_url(); ?>/download-manager/images/minus.png').attr('title','Delete File');
430
+ }
431
+
432
+
433
+ }); */
434
+
435
+
436
+ });
437
+
438
+ });
439
+
440
+ </script>
441
+ <div id="filelist"></div>
442
+
443
+ <div class="clear"></div>
444
+ <!--<input type="file" id="file_upload" name="media"/>-->
445
+
446
+ <div class="clear"></div>
447
+ </div>
448
+ </div>
449
+
450
+ <input type="submit" class="button btn btn-success" value="Insert into post" />
451
+ <div id="sving" style="float: right;margin-right:10px;padding-left: 20px;background:url('<?php echo admin_url('images/loading.gif');?>') left center no-repeat;display: none;">Please Wait...</div>
452
+ </div>
453
+ </form>
454
+ </fieldset>
455
+ </div>
456
+
457
+ <script type="text/javascript">
458
+ jQuery('#wpdmpack').submit(function(){
459
+
460
+ jQuery('#sving').fadeIn();
461
+ jQuery('#publish').attr('disabled','disabled');
462
+ jQuery(this).ajaxSubmit({
463
+ url:'admin-ajax.php',
464
+ beforeSubmit:function(){
465
+
466
+ },
467
+ success:function(res){
468
+ var msg = '';
469
+
470
+ jQuery('#sving').fadeOut();
471
+ var win = window.dialogArguments || opener || parent || top;
472
+
473
+ win.send_to_editor('[wpdm_file id='+res+']');
474
  tinyMCEPopup.close();
475
+ return false;
476
+ }
477
+ });
478
+ return false;
479
+ });
480
+
481
+ jQuery('.tab').click(function(){
482
+ jQuery('.tab-pane').hide();
483
+ jQuery('.tab').removeClass('active');
484
+ jQuery(this).addClass('active');
485
+
486
+ jQuery(jQuery(this).attr('href')).show();
487
+ return false;
488
+ });
489
+ </script>
490
 
491
  </body>
492
  </html>
wpdm-list-files.php CHANGED
@@ -1,11 +1,20 @@
1
  <?php
 
2
  global $wpdb;
3
  $limit = 10;
 
 
 
 
 
 
 
 
4
 
5
  $start = isset($_GET['paged'])?(($_GET['paged']-1)*$limit):0;
6
- $res = $wpdb->get_results("select * from ahm_files limit $start, $limit",ARRAY_A);
7
 
8
- $row = $wpdb->get_row("select count(*) as total from ahm_files",ARRAY_A);
9
 
10
  ?>
11
 
@@ -14,35 +23,42 @@ $row = $wpdb->get_row("select count(*) as total from ahm_files",ARRAY_A);
14
  <div class="icon32" id="icon-upload"><br></div>
15
 
16
  <h2>Manage Files
17
- <a class="button add-new-h2" href="admin.php?page=file-manager/add-new-file">Add New</a>
18
- <a class="button add-new-h2" href="admin.php?page=file-manager&task=wpdm_import_download_monitor">Import Files from Download Monitor</a> <br />
19
- <div class="updated" style="padding:5px 10px;color:#008000;font-weight:bold;">
20
- <a style="color: #3399ff;" href="http://www.wpdownloadmanager.com/?ref=wpadmin&domain=<?php echo $_SERVER['HTTP_HOST']; ?>" target="_blank">Get download manager premium version now! only @ 45.00 $ </a> |
21
- <a style="color: #3399ff;" href="http://www.wpdownloadmanager.com/?ref=wpadmin&domain=<?php echo $_SERVER['HTTP_HOST']; ?>#features" target="_blank">Checkout the features here</a>
22
- </div>
23
- </h2>
 
 
 
24
  <i><b style="font-family:Georgia">Simply Copy and Paste the embed code at anywhere in post contents</b></i><br><br>
25
 
26
 
27
 
28
 
29
-
 
 
 
 
 
 
30
 
31
  <form method="get" action="" id="posts-filter">
32
  <div class="tablenav">
33
 
34
  <div class="alignleft actions">
35
  <select class="select-action" name="task">
36
- <option selected="selected" value="">Bulk Actions</option>
37
  <option value="DeleteFile">Delete Permanently</option>
38
  </select>
 
39
  <input type="submit" class="button-secondary action" id="doaction" name="doaction" value="Apply">
40
 
41
-
42
-
43
 
44
  </div>
45
-
46
  <br class="clear">
47
  </div>
48
 
@@ -76,7 +92,7 @@ $row = $wpdb->get_row("select count(*) as total from ahm_files",ARRAY_A);
76
  <tbody class="list:post" id="the-list">
77
  <?php foreach($res as $media) {
78
 
79
- switch(end(explode(".",$media[file]))){
80
  case 'jpg': case 'png': case 'bmp': case 'gif':
81
  $icon = 'img.png';
82
  break;
@@ -85,7 +101,7 @@ $row = $wpdb->get_row("select count(*) as total from ahm_files",ARRAY_A);
85
  case 'zip': $icon = 'zip.png'; break;
86
 
87
  default:
88
- $icon = end(explode(".",$media[file])).'.png';
89
  break;
90
 
91
 
@@ -102,10 +118,10 @@ $row = $wpdb->get_row("select count(*) as total from ahm_files",ARRAY_A);
102
  </a>
103
  </td>
104
  <td class="media column-media">
105
- <strong><a title="Edit" href="admin.php?page=file-manager&task=wpdm_edit_file&id=<?php echo $media['id']?>"><?php echo $media['title']?></a></strong> | Embed Code: <input style="text-align:center" type="text" onclick="this.select()" size="20" title="Simply Copy and Paste in post contents" value="[wpdm_file id=<?php echo $media['id'];?>]" /><br>
106
  <code>File: <?php echo $media['file']; ?></code><Br>
107
 
108
- <div class="row-actions"><span class="edit"><a href="admin.php?page=file-manager&task=wpdm_edit_file&id=<?php echo $media['id']?>">Edit</a> | </span><span class="delete"><a href="admin.php?page=file-manager&task=wpdm_delete_file&id=<?php echo $media['id']?>" onclick="return showNotice.warn();" class="submitdelete">Delete Permanently</a></div>
109
  </td>
110
  <td class="author column-author"><?php echo $media['password']; ?></td>
111
  <td class="parent column-parent"><?php echo $media['access']; ?></td>
@@ -118,13 +134,15 @@ $row = $wpdb->get_row("select count(*) as total from ahm_files",ARRAY_A);
118
  </table>
119
 
120
  <?php
 
 
121
  $page_links = paginate_links( array(
122
  'base' => add_query_arg( 'paged', '%#%' ),
123
  'format' => '',
124
  'prev_text' => __('&laquo;'),
125
  'next_text' => __('&raquo;'),
126
- 'total' => ceil($row[total]/$limit),
127
- 'current' => $_GET['paged']
128
  ));
129
 
130
 
@@ -134,11 +152,14 @@ $page_links = paginate_links( array(
134
 
135
  <div class="tablenav">
136
 
137
- <?php if ( $page_links ) { ?>
 
 
 
138
  <div class="tablenav-pages"><?php $page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s&#8211;%s of %s' ) . '</span>%s',
139
- number_format_i18n( ( $_GET['paged'] - 1 ) * $limit + 1 ),
140
- number_format_i18n( min( $_GET['paged'] * $limit, $row[total] ) ),
141
- number_format_i18n( $row[total] ),
142
  $page_links
143
  ); echo $page_links_text; ?></div>
144
  <?php } ?>
@@ -154,28 +175,7 @@ $page_links = paginate_links( array(
154
 
155
  <br class="clear">
156
  </div>
157
- <div style="display: none;" class="find-box" id="find-posts">
158
- <div class="find-box-head" id="find-posts-head">Find Posts or Pages</div>
159
- <div class="find-box-inside">
160
- <div class="find-box-search">
161
-
162
- <input type="hidden" value="" id="affected" name="affected">
163
- <input type="hidden" value="3a4edcbda3" name="_ajax_nonce" id="_ajax_nonce"> <label for="find-posts-input" class="screen-reader-text">Search</label>
164
- <input type="text" value="" name="ps" id="find-posts-input">
165
- <input type="button" class="button" value="Search" onclick="findPosts.send();"><br>
166
-
167
- <input type="radio" value="posts" checked="checked" id="find-posts-posts" name="find-posts-what">
168
- <label for="find-posts-posts">Posts</label>
169
- <input type="radio" value="pages" id="find-posts-pages" name="find-posts-what">
170
- <label for="find-posts-pages">Pages</label>
171
- </div>
172
- <div id="find-posts-response"></div>
173
- </div>
174
- <div class="find-box-buttons">
175
- <input type="button" value="Close" onclick="findPosts.close();" class="button alignleft">
176
- <input type="submit" value="Select" class="button-primary alignright" id="find-posts-submit">
177
- </div>
178
- </div>
179
  </form>
180
  <br class="clear">
181
 
1
  <?php
2
+ if(!defined('ABSPATH')) die('Direct Access is not Allowed!');
3
  global $wpdb;
4
  $limit = 10;
5
+
6
+ $cond = '';
7
+ $s = isset($_GET['s'])?explode(" ",$_GET['s']):array();
8
+ foreach($s as $p){
9
+ $cond[] = "title like '%".mysql_escape_string($p)."%'";
10
+
11
+ }
12
+ if(isset($_GET['s'])) $cond = "where ".implode(" or ", $cond);
13
 
14
  $start = isset($_GET['paged'])?(($_GET['paged']-1)*$limit):0;
15
+ $res = $wpdb->get_results("select * from ahm_files $cond order by id desc limit $start, $limit",ARRAY_A);
16
 
17
+ $row = $wpdb->get_row("select count(*) as total from ahm_files $cond",ARRAY_A);
18
 
19
  ?>
20
 
23
  <div class="icon32" id="icon-upload"><br></div>
24
 
25
  <h2>Manage Files
26
+ <a class="button button-secondary add-new-h2" href="admin.php?page=file-manager/add-new-file">Add New</a>
27
+ <a class="button button-secondary add-new-h2" href="admin.php?page=file-manager&task=wpdm_import_download_monitor">Import from Download Monitor</a>
28
+ <a class="button add-new-h2" style="font-weight: bold" href="http://wordpress.org/support/view/plugin-reviews/download-manager">A 5&#9733; rating will inspire me a lot :)</a>
29
+ <br />
30
+
31
+ </h2>
32
+ <div class="updated" style="padding:5px 10px;color:#fff;font-weight:bold;background: #6F9348; border: 0px;padding:8px 20px;font-size:10pt;font-style: italic;">
33
+ <a style="color: #fff;font-family: 'Verdana'" href="http://www.wpdownloadmanager.com/?affid=admin&domain=<?php echo $_SERVER['HTTP_HOST']; ?>" target="_blank">Get download manager premium version now! </a> /
34
+ <a style="color: #fff;font-family: 'Verdana'" href="http://www.wpdownloadmanager.com/?affid=admin&domain=<?php echo $_SERVER['HTTP_HOST']; ?>#features" target="_blank">Checkout the features here</a>
35
+ </div>
36
  <i><b style="font-family:Georgia">Simply Copy and Paste the embed code at anywhere in post contents</b></i><br><br>
37
 
38
 
39
 
40
 
41
+ <div style="position: absolute;right:10px;margin-top: 5px;">
42
+ <form action="" method="get">
43
+ <input type="hidden" name="page" value="file-manager" />
44
+ <input type="text" name="s" id="s" value="<?php echo isset($_GET['s'])?$_GET['s']:''; ?>" />
45
+ <input type="submit" class="button-primary action" id="doaction" name="doaction" value="Search">
46
+ </form>
47
+ </div>
48
 
49
  <form method="get" action="" id="posts-filter">
50
  <div class="tablenav">
51
 
52
  <div class="alignleft actions">
53
  <select class="select-action" name="task">
54
+ <option selected="selected" value="-1">Bulk Actions</option>
55
  <option value="DeleteFile">Delete Permanently</option>
56
  </select>
57
+
58
  <input type="submit" class="button-secondary action" id="doaction" name="doaction" value="Apply">
59
 
 
 
60
 
61
  </div>
 
62
  <br class="clear">
63
  </div>
64
 
92
  <tbody class="list:post" id="the-list">
93
  <?php foreach($res as $media) {
94
 
95
+ switch(end(explode(".",$media['file']))){
96
  case 'jpg': case 'png': case 'bmp': case 'gif':
97
  $icon = 'img.png';
98
  break;
101
  case 'zip': $icon = 'zip.png'; break;
102
 
103
  default:
104
+ $icon = end(explode(".",$media['file'])).'.png';
105
  break;
106
 
107
 
118
  </a>
119
  </td>
120
  <td class="media column-media">
121
+ <strong><a title="Edit" href="admin.php?page=file-manager&task=wpdm_edit_file&id=<?php echo $media['id']?>"><?php echo stripslashes($media['title'])?></a></strong> <input style="text-align:center" type="text" onclick="this.select()" size="20" title="Simply Copy and Paste in post contents" value="[wpdm_file id=<?php echo $media['id'];?>]" /><br>
122
  <code>File: <?php echo $media['file']; ?></code><Br>
123
 
124
+ <div class="row-actions"><div class="button-group"><a class="button" href="admin.php?page=file-manager&task=wpdm_edit_file&id=<?php echo $media['id']?>">Edit</a><a href="admin.php?page=file-manager&task=wpdm_delete_file&id=<?php echo $media['id']?>" onclick="return showNotice.warn();" class="button submitdelete" style="color: #aa0000;">Delete Permanently</a></div></div>
125
  </td>
126
  <td class="author column-author"><?php echo $media['password']; ?></td>
127
  <td class="parent column-parent"><?php echo $media['access']; ?></td>
134
  </table>
135
 
136
  <?php
137
+ $paged = isset($_GET['paged']) ?$_GET['paged'] :1;
138
+
139
  $page_links = paginate_links( array(
140
  'base' => add_query_arg( 'paged', '%#%' ),
141
  'format' => '',
142
  'prev_text' => __('&laquo;'),
143
  'next_text' => __('&raquo;'),
144
+ 'total' => ceil($row['total']/$limit),
145
+ 'current' => $paged
146
  ));
147
 
148
 
152
 
153
  <div class="tablenav">
154
 
155
+ <?php
156
+ if ( $page_links ) {
157
+
158
+ ?>
159
  <div class="tablenav-pages"><?php $page_links_text = sprintf( '<span class="displaying-num">' . __( 'Displaying %s&#8211;%s of %s' ) . '</span>%s',
160
+ number_format_i18n( ( $paged - 1 ) * $limit + 1 ),
161
+ number_format_i18n( min( $paged * $limit, $row['total'] ) ),
162
+ number_format_i18n( $row['total'] ),
163
  $page_links
164
  ); echo $page_links_text; ?></div>
165
  <?php } ?>
175
 
176
  <br class="clear">
177
  </div>
178
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  </form>
180
  <br class="clear">
181
 
wpdm-server-file-browser.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  function wpdm_dir_tree(){
4
- if($_GET['task']!='wpdm_dir_tree') return;
5
  $_POST['dir'] = urldecode($_POST['dir']);
6
  if( file_exists($root . $_POST['dir']) ) {
7
  $files = scandir($root . $_POST['dir']);
@@ -27,7 +27,7 @@ function wpdm_dir_tree(){
27
  }
28
 
29
  function wpdm_file_browser(){
30
- if($_GET['task']!='wpdm_file_browser') return;
31
  ?>
32
  <link rel="stylesheet" href="<?php echo plugins_url().'/download-manager/css/jqueryFileTree.css';?>" />
33
  <style type="text/css">.jqueryFileTree li{line-height: 20px;}</style>
1
  <?php
2
 
3
  function wpdm_dir_tree(){
4
+ if(!isset($_GET['task'])||$_GET['task']!='wpdm_dir_tree') return;
5
  $_POST['dir'] = urldecode($_POST['dir']);
6
  if( file_exists($root . $_POST['dir']) ) {
7
  $files = scandir($root . $_POST['dir']);
27
  }
28
 
29
  function wpdm_file_browser(){
30
+ if(!isset($_GET['task'])||$_GET['task']!='wpdm_file_browser') return;
31
  ?>
32
  <link rel="stylesheet" href="<?php echo plugins_url().'/download-manager/css/jqueryFileTree.css';?>" />
33
  <style type="text/css">.jqueryFileTree li{line-height: 20px;}</style>
wpdm-settings.php CHANGED
@@ -21,9 +21,18 @@ input{
21
  <tr>
22
  <td>Minimum User Access Level:</td>
23
  <td><select name="access">
24
- <option value="level_10">Administrator</option>
25
- <option value="level_5" <?php echo $access=='level_5'?'selected':''?>>Editor</option>
26
- <option value="level_2" <?php echo $access=='level_2'?'selected':''?>>Author</option>
 
 
 
 
 
 
 
 
 
27
  </select>
28
  </td>
29
  </tr>
@@ -31,7 +40,7 @@ input{
31
  <tr>
32
  <td>Login Required Message:</td>
33
  <td>
34
- <input type="text" name="wpdm_login_msg" value="<?php echo stripcslashes(htmlspecialchars(get_option('wpdm_login_msg',true))); ?>" size="40">
35
  </td>
36
  </tr>
37
 
@@ -39,8 +48,8 @@ input{
39
  <tr>
40
  <td>Download Link Icon:</td>
41
  <td>
42
- <input type="file" name="icon">
43
- | Current Icon: <img src="<?php echo plugins_url(); ?>/download-manager/icon/download.png" />
44
  </td>
45
  </tr>
46
 
@@ -48,13 +57,14 @@ input{
48
 
49
  <tr>
50
  <td valign="top"></td>
51
- <td align="right">
 
52
 
53
- <input type="button" value="&#171; back" tabindex="9" class="button-secondary" onclick="location.href='admin.php?page=file-manager'" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
54
 
55
- <input type="reset" value="reset" tabindex="9" class="button-secondary" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
 
56
 
57
- <input type="submit" value="save" accesskey="p" tabindex="5" id="publish" class="button-primary" name="publish">
58
  </td>
59
  </tr>
60
 
21
  <tr>
22
  <td>Minimum User Access Level:</td>
23
  <td><select name="access">
24
+ <option value="manage_options">Administrator</option>
25
+ <option value="manage_categories" <?php echo $access=='manage_categories'?'selected':''?>>Editor</option>
26
+ <option value="publish_posts" <?php echo $access=='publish_posts'?'selected':''?>>Author</option>
27
+ </select>
28
+ </td>
29
+ </tr>
30
+ <tr>
31
+ <td>Show category info with short-code:</td>
32
+ <td><select name="wpdm_show_cinfo">
33
+ <option value="no">No</option>
34
+ <option value="yes" <?php echo $wpdm_show_cinfo=='yes'?'selected':''?>>Yes</option>
35
+
36
  </select>
37
  </td>
38
  </tr>
40
  <tr>
41
  <td>Login Required Message:</td>
42
  <td>
43
+ <input type="text" name="wpdm_login_msg" value="<?php echo stripcslashes(htmlspecialchars(get_option('wpdm_login_msg','Login Required!'))); ?>" size="40">
44
  </td>
45
  </tr>
46
 
48
  <tr>
49
  <td>Download Link Icon:</td>
50
  <td>
51
+ <table><tr><td><img src="<?php echo plugins_url(); ?>/download-manager/icon/download.png" /></td><td><input type="file" name="icon"></td></tr></table>
52
+
53
  </td>
54
  </tr>
55
 
57
 
58
  <tr>
59
  <td valign="top"></td>
60
+ <td align="left">
61
+ <br>
62
 
 
63
 
64
+ <input type="submit" value="save" accesskey="p" tabindex="5" id="publish" class="button button-primary button-large" name="publish">
65
+ <input type="button" value="&#171; back" tabindex="9" class="button button-secondary button-large" onclick="location.href='admin.php?page=file-manager'" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
66
 
67
+ <input type="reset" value="reset" tabindex="9" class="button button-secondary button-large" class="add:the-list:newmeta" name="addmeta" id="addmetasub">
68
  </td>
69
  </tr>
70
 
wpdm-widgets.php CHANGED
@@ -1,5 +1,60 @@
1
  <?php
2
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
 
5
  class wpdm_newpacks_widget extends WP_Widget {
@@ -13,7 +68,7 @@ class wpdm_newpacks_widget extends WP_Widget {
13
  extract( $args );
14
  $title = apply_filters('widget_title', $instance['title']);
15
  $sdc = $instance['sdc'];
16
- $nop = $instance['nop1'];
17
  ?>
18
  <?php echo $before_widget; ?>
19
  <?php if ( $title )
@@ -58,6 +113,10 @@ class wpdm_newpacks_widget extends WP_Widget {
58
 
59
  }
60
 
61
- add_action('widgets_init', create_function('', 'return register_widget("wpdm_newpacks_widget");'));
 
 
 
 
62
 
63
  ?>
1
  <?php
2
+
3
+ class wpdm_topdownloads_widget extends WP_Widget {
4
+ /** constructor */
5
+ function wpdm_topdownloads_widget() {
6
+ parent::WP_Widget(true, 'WPDM Top Downlaods');
7
+ }
8
+
9
+ /** @see WP_Widget::widget */
10
+ function widget($args, $instance) {
11
+ extract( $args );
12
+ $title = apply_filters('widget_title', $instance['title']);
13
+ $sdc = $instance['sdc'];
14
+ $nop = $instance['nop2']>0?$instance['nop2']:5;
15
+ ?>
16
+ <?php echo $before_widget; ?>
17
+ <?php if ( $title )
18
+ echo $before_title . $title . $after_title;
19
+ echo "<ul>";
20
+ wpdm_top_packages($nop,$sdc);
21
+ echo "</ul>";
22
+ echo $after_widget; ?>
23
+ <?php
24
+ }
25
+
26
+ /** @see WP_Widget::update */
27
+ function update($new_instance, $old_instance) {
28
+ $instance = $old_instance;
29
+ $instance['title'] = strip_tags($new_instance['title']);
30
+ $instance['sdc'] = strip_tags($new_instance['sdc']);
31
+ $instance['nop2'] = strip_tags($new_instance['nop2']);
32
+ return $instance;
33
+ }
34
+
35
+ /** @see WP_Widget::form */
36
+ function form($instance) {
37
+ $title = esc_attr($instance['title']);
38
+ $sdc = esc_attr($instance['sdc']);
39
+ $nop = esc_attr($instance['nop2']);
40
+ ?>
41
+ <p>
42
+ <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label>
43
+ <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
44
+ </p>
45
+ <p>
46
+ <label for="<?php echo $this->get_field_id('nop1'); ?>"><?php _e('Number of packages to show:'); ?></label>
47
+ <input class="widefat" id="<?php echo $this->get_field_id('nop2'); ?>" name="<?php echo $this->get_field_name('nop2'); ?>" type="text" value="<?php echo $nop; ?>" />
48
+ </p>
49
+ <p>
50
+ <label for="<?php echo $this->get_field_id('sdc'); ?>"><?php _e('Show Download Count:'); ?>
51
+ <input id="<?php echo $this->get_field_id('sdc'); ?>" name="<?php echo $this->get_field_name('sdc'); ?>" type="checkbox" value="1" <?php echo $sdc?'checked=checked':''; ?> />
52
+ </label>
53
+ </p>
54
+ <?php
55
+ }
56
+
57
+ }
58
 
59
 
60
  class wpdm_newpacks_widget extends WP_Widget {
68
  extract( $args );
69
  $title = apply_filters('widget_title', $instance['title']);
70
  $sdc = $instance['sdc'];
71
+ $nop = $instance['nop1']>0?$instance['nop1']:5;
72
  ?>
73
  <?php echo $before_widget; ?>
74
  <?php if ( $title )
113
 
114
  }
115
 
116
+ function wpdm_register_widgets() {
117
+ register_widget( 'wpdm_newpacks_widget' );
118
+ }
119
+
120
+ add_action('widgets_init', 'wpdm_register_widgets');
121
 
122
  ?>