app.js 25 KB

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