app.js 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. /**
  2. * jQuery.browser.mobile (http://detectmobilebrowser.com/)
  3. *
  4. * jQuery.browser.mobile will be true if the browser is a mobile device
  5. *
  6. **/
  7. // eslint-disable-next-line no-useless-escape
  8. (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);
  9. $.fn.scrollTo = function( target, options, callback ){
  10. if(typeof options == 'function' && arguments.length == 2){ callback = options; options = target; }
  11. var settings = $.extend({
  12. scrollTarget : target,
  13. offsetTop : 50,
  14. duration : 10,
  15. easing : 'swing'
  16. }, options);
  17. return this.each(function(){
  18. var scrollPane = $(this);
  19. var scrollTarget = (typeof settings.scrollTarget == "number") ? settings.scrollTarget : $(settings.scrollTarget);
  20. var scrollY = (typeof scrollTarget == "number") ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop);
  21. scrollPane.animate({scrollTop : scrollY }, parseInt(settings.duration), settings.easing, function(){
  22. if (typeof callback == 'function') { callback.call(this); }
  23. });
  24. });
  25. }
  26. /*
  27. * Date Format 1.2.3
  28. * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
  29. * MIT license
  30. *
  31. * Includes enhancements by Scott Trenda <scott.trenda.net>
  32. * and Kris Kowal <cixar.com/~kris.kowal/>
  33. *
  34. * Accepts a date, a mask, or a date and a mask.
  35. * Returns a formatted version of the given date.
  36. * The date defaults to the current date/time.
  37. * The mask defaults to dateFormat.masks.default.
  38. */
  39. var dateFormat = function () {
  40. var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
  41. timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
  42. timezoneClip = /[^-+\dA-Z]/g,
  43. pad = function (val, len) {
  44. val = String(val);
  45. len = len || 2;
  46. while (val.length < len) val = "0" + val;
  47. return val;
  48. };
  49. // Regexes and supporting functions are cached through closure
  50. return function (date, mask, utc) {
  51. var dF = dateFormat;
  52. // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
  53. if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
  54. mask = date;
  55. date = undefined;
  56. }
  57. // Passing date through Date applies Date.parse, if necessary
  58. date = date ? new Date(date) : new Date;
  59. if (isNaN(date)) throw SyntaxError("invalid date");
  60. mask = String(dF.masks[mask] || mask || dF.masks["default"]);
  61. // Allow setting the utc argument via the mask
  62. if (mask.slice(0, 4) == "UTC:") {
  63. mask = mask.slice(4);
  64. utc = true;
  65. }
  66. var _ = utc ? "getUTC" : "get",
  67. d = date[_ + "Date"](),
  68. D = date[_ + "Day"](),
  69. m = date[_ + "Month"](),
  70. y = date[_ + "FullYear"](),
  71. H = date[_ + "Hours"](),
  72. M = date[_ + "Minutes"](),
  73. s = date[_ + "Seconds"](),
  74. L = date[_ + "Milliseconds"](),
  75. o = utc ? 0 : date.getTimezoneOffset(),
  76. flags = {
  77. d: d,
  78. dd: pad(d),
  79. ddd: dF.i18n.dayNames[D],
  80. dddd: dF.i18n.dayNames[D + 7],
  81. m: m + 1,
  82. mm: pad(m + 1),
  83. mmm: dF.i18n.monthNames[m],
  84. mmmm: dF.i18n.monthNames[m + 12],
  85. yy: String(y).slice(2),
  86. yyyy: y,
  87. h: H % 12 || 12,
  88. hh: pad(H % 12 || 12),
  89. H: H,
  90. HH: pad(H),
  91. M: M,
  92. MM: pad(M),
  93. s: s,
  94. ss: pad(s),
  95. l: pad(L, 3),
  96. L: pad(L > 99 ? Math.round(L / 10) : L),
  97. t: H < 12 ? "a" : "p",
  98. tt: H < 12 ? "am" : "pm",
  99. T: H < 12 ? "A" : "P",
  100. TT: H < 12 ? "AM" : "PM",
  101. Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
  102. o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
  103. S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
  104. };
  105. return mask.replace(token, function ($0) {
  106. return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
  107. });
  108. };
  109. }();
  110. // Some common format strings
  111. dateFormat.masks = {
  112. "default": "ddd mmm dd yyyy HH:MM:ss",
  113. shortDate: "m/d/yy",
  114. mediumDate: "mmm d, yyyy",
  115. longDate: "mmmm d, yyyy",
  116. fullDate: "dddd, mmmm d, yyyy",
  117. shortTime: "h:MM TT",
  118. mediumTime: "h:MM:ss TT",
  119. longTime: "h:MM:ss TT Z",
  120. isoDate: "yyyy-mm-dd",
  121. isoTime: "HH:MM:ss",
  122. isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
  123. isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
  124. };
  125. // Internationalization strings
  126. dateFormat.i18n = {
  127. dayNames: [
  128. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
  129. "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
  130. ],
  131. monthNames: [
  132. "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  133. "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
  134. ]
  135. };
  136. // For convenience...
  137. Date.prototype.format = function (mask, utc) {
  138. return dateFormat(this, mask, utc);
  139. };
  140. /*
  141. * http://code.google.com/p/flexible-js-formatting/
  142. *
  143. * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
  144. *
  145. * Permission is hereby granted, free of charge, to any person obtaining a copy
  146. * of this software and associated documentation files (the "Software"), to deal
  147. * in the Software without restriction, including without limitation the rights
  148. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  149. * copies of the Software, and to permit persons to whom the Software is
  150. * furnished to do so, subject to the following conditions:
  151. *
  152. * The above copyright notice and this permission notice shall be included in
  153. * all copies or substantial portions of the Software.
  154. *
  155. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  156. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  157. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  158. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  159. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  160. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  161. * THE SOFTWARE.
  162. */
  163. Date.parseFunctions = {count:0};
  164. Date.parseRegexes = [];
  165. Date.formatFunctions = {count:0};
  166. Date.prototype.dateFormat = function(format, ignore_offset) {
  167. if (Date.formatFunctions[format] == null) {
  168. Date.createNewFormat(format);
  169. }
  170. var func = Date.formatFunctions[format];
  171. if (ignore_offset || ! this.offset) {
  172. return this[func]();
  173. } else {
  174. return (new Date(this.valueOf() - this.offset))[func]();
  175. }
  176. };
  177. Date.createNewFormat = function(format) {
  178. var funcName = "format" + Date.formatFunctions.count++;
  179. Date.formatFunctions[format] = funcName;
  180. var code = "Date.prototype." + funcName + " = function(){return ";
  181. var special = false;
  182. var ch = '';
  183. for (var i = 0; i < format.length; ++i) {
  184. ch = format.charAt(i);
  185. // escape character start
  186. if (!special && ch == "\\") {
  187. special = true;
  188. }
  189. // escaped string
  190. else if (!special && ch == '"') {
  191. var end = format.indexOf('"', i+1);
  192. if (end==-1)
  193. {
  194. end = format.length;
  195. }
  196. code += "'" + String.escape(format.substring(i+1, end)) + "' + ";
  197. i = end;
  198. }
  199. // escaped character
  200. else if (special) {
  201. special = false;
  202. code += "'" + String.escape(ch) + "' + ";
  203. }
  204. else {
  205. code += Date.getFormatCode(ch);
  206. }
  207. }
  208. eval(code.substring(0, code.length - 3) + ";}");
  209. };
  210. Date.getFormatCode = function(character) {
  211. switch (character) {
  212. case "d":
  213. return "String.leftPad(this.getDate(), 2, '0') + ";
  214. case "D":
  215. return "Date.dayNames[this.getDay()].substring(0, 3) + ";
  216. case "j":
  217. return "this.getDate() + ";
  218. case "l":
  219. return "Date.dayNames[this.getDay()] + ";
  220. case "S":
  221. return "this.getSuffix() + ";
  222. case "w":
  223. return "this.getDay() + ";
  224. case "z":
  225. return "this.getDayOfYear() + ";
  226. case "W":
  227. return "this.getWeekOfYear() + ";
  228. case "F":
  229. return "Date.monthNames[this.getMonth()] + ";
  230. case "m":
  231. return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
  232. case "M":
  233. return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
  234. case "n":
  235. return "(this.getMonth() + 1) + ";
  236. case "t":
  237. return "this.getDaysInMonth() + ";
  238. case "L":
  239. return "(this.isLeapYear() ? 1 : 0) + ";
  240. case "Y":
  241. return "this.getFullYear() + ";
  242. case "y":
  243. return "('' + this.getFullYear()).substring(2, 4) + ";
  244. case "a":
  245. return "(this.getHours() < 12 ? 'am' : 'pm') + ";
  246. case "A":
  247. return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
  248. case "g":
  249. return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
  250. case "G":
  251. return "this.getHours() + ";
  252. case "h":
  253. return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
  254. case "H":
  255. return "String.leftPad(this.getHours(), 2, '0') + ";
  256. case "i":
  257. return "String.leftPad(this.getMinutes(), 2, '0') + ";
  258. case "s":
  259. return "String.leftPad(this.getSeconds(), 2, '0') + ";
  260. case "X":
  261. return "String.leftPad(this.getMilliseconds(), 3, '0') + ";
  262. case "O":
  263. return "this.getGMTOffset() + ";
  264. case "T":
  265. return "this.getTimezone() + ";
  266. case "Z":
  267. return "(this.getTimezoneOffset() * -60) + ";
  268. case "q": // quarter num, Q for name?
  269. return "this.getQuarter() + ";
  270. default:
  271. return "'" + String.escape(character) + "' + ";
  272. }
  273. };
  274. Date.parseDate = function(input, format) {
  275. if (Date.parseFunctions[format] == null) {
  276. Date.createParser(format);
  277. }
  278. var func = Date.parseFunctions[format];
  279. return Date[func](input);
  280. };
  281. Date.createParser = function(format) {
  282. var funcName = "parse" + Date.parseFunctions.count++;
  283. var regexNum = Date.parseRegexes.length;
  284. var currentGroup = 1;
  285. Date.parseFunctions[format] = funcName;
  286. var code = "Date." + funcName + " = function(input){\n"
  287. + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, ms = -1, z = 0;\n"
  288. + "var d = new Date();\n"
  289. + "y = d.getFullYear();\n"
  290. + "m = d.getMonth();\n"
  291. + "d = d.getDate();\n"
  292. + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
  293. + "if (results && results.length > 0) {" ;
  294. var regex = "";
  295. var special = false;
  296. var ch = '';
  297. for (var i = 0; i < format.length; ++i) {
  298. ch = format.charAt(i);
  299. if (!special && ch == "\\") {
  300. special = true;
  301. }
  302. else if (special) {
  303. special = false;
  304. regex += String.escape(ch);
  305. }
  306. else {
  307. obj = Date.formatCodeToRegex(ch, currentGroup);
  308. currentGroup += obj.g;
  309. regex += obj.s;
  310. if (obj.g && obj.c) {
  311. code += obj.c;
  312. }
  313. }
  314. }
  315. code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0 && ms >= 0)\n"
  316. + "{return new Date(y, m, d, h, i, s, ms).applyOffset(z);}\n"
  317. + "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
  318. + "{return new Date(y, m, d, h, i, s).applyOffset(z);}\n"
  319. + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
  320. + "{return new Date(y, m, d, h, i).applyOffset(z);}\n"
  321. + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"
  322. + "{return new Date(y, m, d, h).applyOffset(z);}\n"
  323. + "else if (y > 0 && m >= 0 && d > 0)\n"
  324. + "{return new Date(y, m, d).applyOffset(z);}\n"
  325. + "else if (y > 0 && m >= 0)\n"
  326. + "{return new Date(y, m).applyOffset(z);}\n"
  327. + "else if (y > 0)\n"
  328. + "{return new Date(y).applyOffset(z);}\n"
  329. + "}return null;}";
  330. Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
  331. eval(code);
  332. };
  333. Date.formatCodeToRegex = function(character, currentGroup) {
  334. switch (character) {
  335. case "D":
  336. return {g:0,
  337. c:null,
  338. s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
  339. case "j":
  340. case "d":
  341. return {g:1,
  342. c:"d = parseInt(results[" + currentGroup + "], 10);\n",
  343. s:"(\\d{1,2})"};
  344. case "l":
  345. return {g:0,
  346. c:null,
  347. s:"(?:" + Date.dayNames.join("|") + ")"};
  348. case "S":
  349. return {g:0,
  350. c:null,
  351. s:"(?:st|nd|rd|th)"};
  352. case "w":
  353. return {g:0,
  354. c:null,
  355. s:"\\d"};
  356. case "z":
  357. return {g:0,
  358. c:null,
  359. s:"(?:\\d{1,3})"};
  360. case "W":
  361. return {g:0,
  362. c:null,
  363. s:"(?:\\d{2})"};
  364. case "F":
  365. return {g:1,
  366. c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
  367. s:"(" + Date.monthNames.join("|") + ")"};
  368. case "M":
  369. return {g:1,
  370. c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
  371. s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
  372. case "n":
  373. case "m":
  374. return {g:1,
  375. c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
  376. s:"(\\d{1,2})"};
  377. case "t":
  378. return {g:0,
  379. c:null,
  380. s:"\\d{1,2}"};
  381. case "L":
  382. return {g:0,
  383. c:null,
  384. s:"(?:1|0)"};
  385. case "Y":
  386. return {g:1,
  387. c:"y = parseInt(results[" + currentGroup + "], 10);\n",
  388. s:"(\\d{4})"};
  389. case "y":
  390. return {g:1,
  391. c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
  392. + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
  393. s:"(\\d{1,2})"};
  394. case "a":
  395. return {g:1,
  396. c:"if (results[" + currentGroup + "] == 'am') {\n"
  397. + "if (h == 12) { h = 0; }\n"
  398. + "} else { if (h < 12) { h += 12; }}",
  399. s:"(am|pm)"};
  400. case "A":
  401. return {g:1,
  402. c:"if (results[" + currentGroup + "] == 'AM') {\n"
  403. + "if (h == 12) { h = 0; }\n"
  404. + "} else { if (h < 12) { h += 12; }}",
  405. s:"(AM|PM)"};
  406. case "g":
  407. case "G":
  408. case "h":
  409. case "H":
  410. return {g:1,
  411. c:"h = parseInt(results[" + currentGroup + "], 10);\n",
  412. s:"(\\d{1,2})"};
  413. case "i":
  414. return {g:1,
  415. c:"i = parseInt(results[" + currentGroup + "], 10);\n",
  416. s:"(\\d{2})"};
  417. case "s":
  418. return {g:1,
  419. c:"s = parseInt(results[" + currentGroup + "], 10);\n",
  420. s:"(\\d{2})"};
  421. case "X":
  422. return {g:1,
  423. c:"ms = parseInt(results[" + currentGroup + "], 10);\n",
  424. s:"(\\d{3})"};
  425. case "O":
  426. case "P":
  427. return {g:1,
  428. c:"z = Date.parseOffset(results[" + currentGroup + "], 10);\n",
  429. s:"(Z|[+-]\\d{2}:?\\d{2})"}; // "Z", "+05:00", "+0500" all acceptable.
  430. case "T":
  431. return {g:0,
  432. c:null,
  433. s:"[A-Z]{3}"};
  434. case "Z":
  435. return {g:1,
  436. c:"s = parseInt(results[" + currentGroup + "], 10);\n",
  437. s:"([+-]\\d{1,5})"};
  438. default:
  439. return {g:0,
  440. c:null,
  441. s:String.escape(character)};
  442. }
  443. };
  444. Date.parseOffset = function(str) {
  445. if (str == "Z") { return 0 ; } // UTC, no offset.
  446. var seconds ;
  447. seconds = parseInt(str[0] + str[1] + str[2]) * 3600 ; // e.g., "+05" or "-08"
  448. if (str[3] == ":") { // "+HH:MM" is preferred iso8601 format ("O")
  449. seconds += parseInt(str[4] + str[5]) * 60;
  450. } else { // "+HHMM" is frequently used, though. ("P")
  451. seconds += parseInt(str[3] + str[4]) * 60;
  452. }
  453. return seconds ;
  454. };
  455. Date.today = function() {
  456. var now = new Date();
  457. now.setHours(0);
  458. now.setMinutes(0);
  459. now.setSeconds(0);
  460. return now;
  461. }
  462. // convert the parsed date into UTC, but store the offset so we can optionally use it in dateFormat()
  463. Date.prototype.applyOffset = function(offset_seconds) {
  464. this.offset = offset_seconds * 1000 ;
  465. this.setTime(this.valueOf() + this.offset);
  466. return this ;
  467. };
  468. Date.prototype.getTimezone = function() {
  469. return this.toString().replace(
  470. /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
  471. /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3").replace(
  472. /^.*?[0-9]{4} \(([A-Z]{3})\)/, "$1");
  473. };
  474. Date.prototype.getGMTOffset = function() {
  475. return (this.getTimezoneOffset() > 0 ? "-" : "+")
  476. + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
  477. + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
  478. };
  479. Date.prototype.getDayOfYear = function() {
  480. var num = 0;
  481. Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
  482. for (var i = 0; i < this.getMonth(); ++i) {
  483. num += Date.daysInMonth[i];
  484. }
  485. return num + this.getDate() - 1;
  486. };
  487. Date.prototype.getWeekOfYear = function() {
  488. // Skip to Thursday of this week
  489. var now = this.getDayOfYear() + (4 - this.getDay());
  490. // Find the first Thursday of the year
  491. var jan1 = new Date(this.getFullYear(), 0, 1);
  492. var then = (7 - jan1.getDay() + 4);
  493. document.write(then);
  494. return String.leftPad(((now - then) / 7) + 1, 2, "0");
  495. };
  496. Date.prototype.isLeapYear = function() {
  497. var year = this.getFullYear();
  498. return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
  499. };
  500. Date.prototype.getFirstDayOfMonth = function() {
  501. var day = (this.getDay() - (this.getDate() - 1)) % 7;
  502. return (day < 0) ? (day + 7) : day;
  503. };
  504. Date.prototype.getLastDayOfMonth = function() {
  505. var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
  506. return (day < 0) ? (day + 7) : day;
  507. };
  508. Date.prototype.getDaysInMonth = function() {
  509. Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
  510. return Date.daysInMonth[this.getMonth()];
  511. };
  512. Date.prototype.getQuarter = function() {
  513. return Date.quarterFromMonthNum[this.getMonth()];
  514. };
  515. Date.prototype.getSuffix = function() {
  516. switch (this.getDate()) {
  517. case 1:
  518. case 21:
  519. case 31:
  520. return "st";
  521. case 2:
  522. case 22:
  523. return "nd";
  524. case 3:
  525. case 23:
  526. return "rd";
  527. default:
  528. return "th";
  529. }
  530. };
  531. String.escape = function(string) {
  532. return string.replace(/('|\\)/g, "\\$1");
  533. };
  534. String.leftPad = function (val, size, ch) {
  535. var result = new String(val);
  536. if (ch == null) {
  537. ch = " ";
  538. }
  539. while (result.length < size) {
  540. result = ch + result;
  541. }
  542. return result;
  543. };
  544. Date.quarterFromMonthNum = [1,1,1,2,2,2,3,3,3,4,4,4];
  545. Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
  546. Date.monthNames =
  547. ["January",
  548. "February",
  549. "March",
  550. "April",
  551. "May",
  552. "June",
  553. "July",
  554. "August",
  555. "September",
  556. "October",
  557. "November",
  558. "December"];
  559. Date.dayNames =
  560. ["Sunday",
  561. "Monday",
  562. "Tuesday",
  563. "Wednesday",
  564. "Thursday",
  565. "Friday",
  566. "Saturday"];
  567. Date.y2kYear = 50;
  568. Date.monthNumbers = {
  569. Jan:0,
  570. Feb:1,
  571. Mar:2,
  572. Apr:3,
  573. May:4,
  574. Jun:5,
  575. Jul:6,
  576. Aug:7,
  577. Sep:8,
  578. Oct:9,
  579. Nov:10,
  580. Dec:11};
  581. Date.patterns = {
  582. ISO8601LongPattern: "Y\\-m\\-d\\TH\\:i\\:sO",
  583. ISO8601ShortPattern: "Y\\-m\\-d",
  584. ShortDatePattern: "n/j/Y",
  585. LongDatePattern: "l, F d, Y",
  586. FullDateTimePattern: "l, F d, Y g:i:s A",
  587. MonthDayPattern: "F d",
  588. ShortTimePattern: "g:i A",
  589. LongTimePattern: "g:i:s A",
  590. SortableDateTimePattern: "Y-m-d\\TH:i:s",
  591. UniversalSortableDateTimePattern: "Y-m-d H:i:sO",
  592. YearMonthPattern: "F, Y"};
  593. /**
  594. *
  595. * @author: Malishev Dmitry <dima.malishev@gmail.com>
  596. */
  597. var _DEBUG = true;
  598. var _DEBUG_LEVEL = 'ALL';
  599. // possible levels: ALL, IMPORTANT
  600. var Error = {FATAL: 1, WARNING: 0, NORMAL: -1};
  601. /**
  602. * Init debug, grabs console object if accessible, or makes dummy debugger
  603. */
  604. var fb = _DEBUG && 'undefined' != typeof(console) ? console : {
  605. log : function(){},
  606. debug : function(){},
  607. info : function(){},
  608. warn : function(){},
  609. error : function(){},
  610. assert : function(){},
  611. dir : function(){},
  612. dirxml : function(){},
  613. trace : function(){},
  614. group : function(){},
  615. groupEnd : function(){},
  616. time : function(){},
  617. timeEnd : function(){},
  618. profile : function(){},
  619. profileEnd : function(){},
  620. count : function(){},
  621. msg : function(){}
  622. };
  623. var checked = false;
  624. var frmname = '';
  625. //
  626. var App = {
  627. // Main namespases for page specific functions
  628. // Core namespaces
  629. Ajax: {
  630. Busy: {}
  631. },
  632. Core: {},
  633. // CONSTANT VALUES
  634. Constants: {
  635. UNLIM_VALUE: 'unlimited', // overritten in i18n.js.php
  636. UNLIM_TRANSLATED_VALUE: 'unlimited' // overritten in i18n.js.php
  637. },
  638. // Actions. More widly used funcs
  639. Actions: {
  640. DB: {},
  641. WEB: {},
  642. PACKAGE: {},
  643. MAIL_ACC:{},
  644. MAIL: {}
  645. },
  646. // Utilities
  647. Helpers: {},
  648. HTML: {
  649. Build: {}
  650. },
  651. Filters: {},
  652. Env: {
  653. lang: GLOBAL.lang,
  654. },
  655. i18n: {},
  656. Listeners: {
  657. DB: {},
  658. WEB: {},
  659. PACKAGE: {},
  660. MAIL_ACC:{}
  661. },
  662. View:{
  663. HTML: {
  664. Build: {}
  665. },
  666. // pages related views
  667. },
  668. Cache: {
  669. clear: function() {} // TODO: stub method, will be used later
  670. },
  671. Ref: {},
  672. Tmp: {},
  673. Thread: {
  674. run: function(delay, ref) {
  675. setTimeout(function() {
  676. ref();
  677. }, delay*10);
  678. }
  679. },
  680. Settings: {
  681. GLOBAL: {},
  682. General: {}
  683. },
  684. Templates: {
  685. Templator: null,
  686. Tpl: {},
  687. _indexes: {}
  688. }
  689. };
  690. // Internals
  691. Array.prototype.set = function(key, value){
  692. var index = this[0][key];
  693. this[1][index] = value;
  694. }
  695. Array.prototype.get = function(key){
  696. var index = this[0][key];
  697. return this[1][index];
  698. }
  699. Array.prototype.finalize = function(){
  700. this.shift();
  701. this[0] = this[0].join('');
  702. return this[0];
  703. }
  704. Array.prototype.done = function(){
  705. return this.join('');
  706. }
  707. String.prototype.wrapperize = function(key, ns){
  708. var tpl = App.Templates.get(key, ns);
  709. tpl.set(':content', this);
  710. return tpl.finalize();
  711. }
  712. App.Ajax.request = function(method, data, callback, onError){
  713. // this will prevent multiple ajaxes on user clicks
  714. /*if (App.Helpers.isAjaxBusy(method, data)) {
  715. fb.warn('ajax request ['+method+'] is busy');
  716. return;
  717. }*/
  718. //App.Helpers.setAjaxBusy(method, data);
  719. data = data || {};
  720. var prgs = $('.progress-container');
  721. switch (method) {
  722. case 'cd':
  723. prgs.find('title').text('Opening dir');
  724. prgs.show();
  725. break;
  726. case 'delete_files':
  727. prgs.find('title').text('Deleting');
  728. prgs.show();
  729. break;
  730. case 'unpack_item':
  731. prgs.find('title').text('Unpacking');
  732. prgs.show();
  733. break;
  734. case 'create_file':
  735. prgs.find('title').text('Creating file');
  736. prgs.show();
  737. break;
  738. case 'create_dir':
  739. prgs.find('title').text('Creating directory');
  740. prgs.show();
  741. break;
  742. case 'rename_file':
  743. prgs.find('title').text('Renaming file');
  744. prgs.show();
  745. break;
  746. case 'copy_file':
  747. case 'copy_directory':
  748. prgs.find('title').text('Copying files');
  749. prgs.show();
  750. break;
  751. default:
  752. break;
  753. }
  754. jQuery.ajax({
  755. url: GLOBAL.ajax_url,
  756. global: false,
  757. type: data.request_method || "GET",
  758. data: jQuery.extend(data, {'action': method}),
  759. dataType: "text boost",
  760. converters: {
  761. "text boost": function(value) {
  762. value = value.trim();
  763. return $.parseJSON(value);
  764. }},
  765. async: true,
  766. cache: false,
  767. error: function(jqXHR, textStatus, errorThrown)
  768. {
  769. prgs.hide();
  770. onError && onError();
  771. if ('undefined' != typeof onError) {
  772. fb.error(textStatus);
  773. }
  774. },
  775. complete: function()
  776. {
  777. //App.Helpers.setAjaxFree(method, data);
  778. prgs.hide();
  779. },
  780. success: function(reply)
  781. {
  782. prgs.hide();
  783. //App.Helpers.setAjaxFree(method, data);
  784. try {
  785. callback && callback(reply);
  786. }
  787. catch(e) {
  788. fb.error('GENERAL ERROR with ajax method: ' + data.request_method + ' ' + e);
  789. //App.Helpers.generalError();
  790. }
  791. }
  792. });
  793. }
  794. jQuery.extend({
  795. keys: function(obj){
  796. if (!obj) {
  797. return [];
  798. }
  799. var a = [];
  800. jQuery.each(obj, function(k){ a.push(k) });
  801. return a;
  802. }
  803. })
  804. App.Core.create_hidden_form = function(action){
  805. var form = jQuery('<form>', {
  806. id : 'hidden-form',
  807. method : 'post',
  808. action : action
  809. });
  810. jQuery('body').append(form);
  811. return form;
  812. };
  813. App.Core.extend_from_json = function(elm, data, prefix){
  814. elm = jQuery(elm);
  815. var data = App.Core.flatten_json(data, prefix);
  816. var keys = jQuery.keys(data);
  817. for(var i=0, cnt=keys.length; i<cnt; i++)
  818. {
  819. elm.append(jQuery('<input>', {
  820. name : keys[i],
  821. value: data[keys[i]],
  822. type : 'hidden'
  823. }));
  824. }
  825. return elm;
  826. }
  827. App.Core.flatten_json = function(data, prefix){
  828. var keys = jQuery.keys(data);
  829. var result = {};
  830. prefix || (prefix = '');
  831. if(keys.length)
  832. {
  833. for(var i=0, cnt=keys.length; i<cnt; i++)
  834. {
  835. var value = data[keys[i]];
  836. switch(typeof(value))
  837. {
  838. case 'function': break;
  839. case 'object' : result = jQuery.extend(result, App.Core.flatten_json(value, prefix + '[' + keys[i] + ']')); break;
  840. default : result[prefix + '[' + keys[i] + ']'] = value;
  841. }
  842. }
  843. return result;
  844. }
  845. else
  846. {
  847. return false;
  848. }
  849. }
  850. //
  851. // Cookies adapter
  852. // Allow to work old pages realisations of cookie requests
  853. //
  854. function createCookie(name, value, expire_days) {
  855. jQuery.cookie(name, value, { expires: expire_days});
  856. }
  857. function readCookie(name) {
  858. jQuery.cookie(name);
  859. }
  860. function eraseCookie(name) {
  861. jQuery.removeCookie(name);
  862. }
  863. /**
  864. * Timer for profiling
  865. */
  866. var timer = {};
  867. timer.start = function()
  868. {
  869. timer.start_time = new Date();
  870. }
  871. timer.stop = function( msg )
  872. {
  873. timer.stop_time = new Date();
  874. timer.print( msg );
  875. }
  876. timer.print = function( msg )
  877. {
  878. var passed = timer.stop_time - timer.start_time;
  879. fb.info( msg || '' + passed / 1000 );
  880. }
  881. String.prototype.trim = function()
  882. {
  883. var str = this;
  884. str = str.replace(/^\s+/, '');
  885. for (var i = str.length - 1; i >= 0; i--) {
  886. if (/\S/.test(str.charAt(i))) {
  887. str = str.substring(0, i + 1);
  888. break;
  889. }
  890. }
  891. return str;
  892. }
  893. set_sticky_class = function() {
  894. var sort = $('.l-sort');
  895. var tableHeader = $('.table-header');
  896. var sortOffset = sort.offset().top;
  897. var headerHeight = $('.l-header').outerHeight();
  898. if ($(window).scrollTop() > sortOffset - headerHeight) {
  899. sort.addClass('active');
  900. tableHeader.addClass('active');
  901. } else {
  902. sort.removeClass('active');
  903. tableHeader.removeClass('active');
  904. }
  905. }
  906. function checkedAll(frmname) {
  907. if($('input#toggle-all').prop('checked')){
  908. $('.l-unit:not(.header)').addClass("selected");
  909. $('.ch-toggle').prop("checked", true);
  910. $('.toggle-all').addClass('clicked-on');
  911. } else {
  912. $('.l-unit:not(.header)').removeClass("selected");
  913. $('.ch-toggle').prop("checked", false);
  914. $('.toggle-all').removeClass('clicked-on');
  915. }
  916. }
  917. function doSearch(url) {
  918. var url = url || '/search/';
  919. var loc = url + '?q=' + $('.js-search-input').val() + '&token=' + $('input[name="token"]').val();
  920. location.href = loc;
  921. return false;
  922. }
  923. function elementHideShow(elementToHideOrShow,trigger){
  924. var el = document.getElementById(elementToHideOrShow);
  925. el.style.display = el.style.display === 'none' ? 'block' : 'none';
  926. if (typeof trigger !== 'undefined') {
  927. trigger.querySelector('.js-section-toggle-icon').classList.toggle('fa-square-minus');
  928. trigger.querySelector('.js-section-toggle-icon').classList.toggle('fa-square-plus');
  929. }
  930. }