PageRenderTime 1215ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/files/mootools/1.5.0/mootools-core-compat.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 2172 lines | 1485 code | 424 blank | 263 comment | 488 complexity | 1182347b32e4e019a55acb855549ec49 MD5 | raw file
  1. /*
  2. ---
  3. MooTools: the javascript framework
  4. */
  5. /*
  6. ---
  7. name: Core
  8. description: The heart of MooTools.
  9. license: MIT-style license.
  10. copyright: Copyright (c) 2006-2014 [Valerio Proietti](http://mad4milk.net/).
  11. authors: The MooTools production team (http://mootools.net/developers/)
  12. inspiration:
  13. - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
  14. - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
  15. provides: [Core, MooTools, Type, typeOf, instanceOf, Native]
  16. ...
  17. */
  18. (function(){
  19. this.MooTools = {
  20. version: '1.5.0',
  21. build: '0f7b690afee9349b15909f33016a25d2e4d9f4e3'
  22. };
  23. // typeOf, instanceOf
  24. var typeOf = this.typeOf = function(item){
  25. if (item == null) return 'null';
  26. if (item.$family != null) return item.$family();
  27. if (item.nodeName){
  28. if (item.nodeType == 1) return 'element';
  29. if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
  30. } else if (typeof item.length == 'number'){
  31. if ('callee' in item) return 'arguments';
  32. if ('item' in item) return 'collection';
  33. }
  34. return typeof item;
  35. };
  36. var instanceOf = this.instanceOf = function(item, object){
  37. if (item == null) return false;
  38. var constructor = item.$constructor || item.constructor;
  39. while (constructor){
  40. if (constructor === object) return true;
  41. constructor = constructor.parent;
  42. }
  43. /*<ltIE8>*/
  44. if (!item.hasOwnProperty) return false;
  45. /*</ltIE8>*/
  46. return item instanceof object;
  47. };
  48. // Function overloading
  49. var Function = this.Function;
  50. var enumerables = true;
  51. for (var i in {toString: 1}) enumerables = null;
  52. if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
  53. Function.prototype.overloadSetter = function(usePlural){
  54. var self = this;
  55. return function(a, b){
  56. if (a == null) return this;
  57. if (usePlural || typeof a != 'string'){
  58. for (var k in a) self.call(this, k, a[k]);
  59. if (enumerables) for (var i = enumerables.length; i--;){
  60. k = enumerables[i];
  61. if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
  62. }
  63. } else {
  64. self.call(this, a, b);
  65. }
  66. return this;
  67. };
  68. };
  69. Function.prototype.overloadGetter = function(usePlural){
  70. var self = this;
  71. return function(a){
  72. var args, result;
  73. if (typeof a != 'string') args = a;
  74. else if (arguments.length > 1) args = arguments;
  75. else if (usePlural) args = [a];
  76. if (args){
  77. result = {};
  78. for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
  79. } else {
  80. result = self.call(this, a);
  81. }
  82. return result;
  83. };
  84. };
  85. Function.prototype.extend = function(key, value){
  86. this[key] = value;
  87. }.overloadSetter();
  88. Function.prototype.implement = function(key, value){
  89. this.prototype[key] = value;
  90. }.overloadSetter();
  91. // From
  92. var slice = Array.prototype.slice;
  93. Function.from = function(item){
  94. return (typeOf(item) == 'function') ? item : function(){
  95. return item;
  96. };
  97. };
  98. Array.from = function(item){
  99. if (item == null) return [];
  100. return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
  101. };
  102. Number.from = function(item){
  103. var number = parseFloat(item);
  104. return isFinite(number) ? number : null;
  105. };
  106. String.from = function(item){
  107. return item + '';
  108. };
  109. // hide, protect
  110. Function.implement({
  111. hide: function(){
  112. this.$hidden = true;
  113. return this;
  114. },
  115. protect: function(){
  116. this.$protected = true;
  117. return this;
  118. }
  119. });
  120. // Type
  121. var Type = this.Type = function(name, object){
  122. if (name){
  123. var lower = name.toLowerCase();
  124. var typeCheck = function(item){
  125. return (typeOf(item) == lower);
  126. };
  127. Type['is' + name] = typeCheck;
  128. if (object != null){
  129. object.prototype.$family = (function(){
  130. return lower;
  131. }).hide();
  132. //<1.2compat>
  133. object.type = typeCheck;
  134. //</1.2compat>
  135. }
  136. }
  137. if (object == null) return null;
  138. object.extend(this);
  139. object.$constructor = Type;
  140. object.prototype.$constructor = object;
  141. return object;
  142. };
  143. var toString = Object.prototype.toString;
  144. Type.isEnumerable = function(item){
  145. return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
  146. };
  147. var hooks = {};
  148. var hooksOf = function(object){
  149. var type = typeOf(object.prototype);
  150. return hooks[type] || (hooks[type] = []);
  151. };
  152. var implement = function(name, method){
  153. if (method && method.$hidden) return;
  154. var hooks = hooksOf(this);
  155. for (var i = 0; i < hooks.length; i++){
  156. var hook = hooks[i];
  157. if (typeOf(hook) == 'type') implement.call(hook, name, method);
  158. else hook.call(this, name, method);
  159. }
  160. var previous = this.prototype[name];
  161. if (previous == null || !previous.$protected) this.prototype[name] = method;
  162. if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
  163. return method.apply(item, slice.call(arguments, 1));
  164. });
  165. };
  166. var extend = function(name, method){
  167. if (method && method.$hidden) return;
  168. var previous = this[name];
  169. if (previous == null || !previous.$protected) this[name] = method;
  170. };
  171. Type.implement({
  172. implement: implement.overloadSetter(),
  173. extend: extend.overloadSetter(),
  174. alias: function(name, existing){
  175. implement.call(this, name, this.prototype[existing]);
  176. }.overloadSetter(),
  177. mirror: function(hook){
  178. hooksOf(this).push(hook);
  179. return this;
  180. }
  181. });
  182. new Type('Type', Type);
  183. // Default Types
  184. var force = function(name, object, methods){
  185. var isType = (object != Object),
  186. prototype = object.prototype;
  187. if (isType) object = new Type(name, object);
  188. for (var i = 0, l = methods.length; i < l; i++){
  189. var key = methods[i],
  190. generic = object[key],
  191. proto = prototype[key];
  192. if (generic) generic.protect();
  193. if (isType && proto) object.implement(key, proto.protect());
  194. }
  195. if (isType){
  196. var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
  197. object.forEachMethod = function(fn){
  198. if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){
  199. fn.call(prototype, prototype[methods[i]], methods[i]);
  200. }
  201. for (var key in prototype) fn.call(prototype, prototype[key], key);
  202. };
  203. }
  204. return force;
  205. };
  206. force('String', String, [
  207. 'charAt', 'charCodeAt', 'concat', 'contains', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
  208. 'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'
  209. ])('Array', Array, [
  210. 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
  211. 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'
  212. ])('Number', Number, [
  213. 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
  214. ])('Function', Function, [
  215. 'apply', 'call', 'bind'
  216. ])('RegExp', RegExp, [
  217. 'exec', 'test'
  218. ])('Object', Object, [
  219. 'create', 'defineProperty', 'defineProperties', 'keys',
  220. 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
  221. 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
  222. ])('Date', Date, ['now']);
  223. Object.extend = extend.overloadSetter();
  224. Date.extend('now', function(){
  225. return +(new Date);
  226. });
  227. new Type('Boolean', Boolean);
  228. // fixes NaN returning as Number
  229. Number.prototype.$family = function(){
  230. return isFinite(this) ? 'number' : 'null';
  231. }.hide();
  232. // Number.random
  233. Number.extend('random', function(min, max){
  234. return Math.floor(Math.random() * (max - min + 1) + min);
  235. });
  236. // forEach, each
  237. var hasOwnProperty = Object.prototype.hasOwnProperty;
  238. Object.extend('forEach', function(object, fn, bind){
  239. for (var key in object){
  240. if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);
  241. }
  242. });
  243. Object.each = Object.forEach;
  244. Array.implement({
  245. /*<!ES5>*/
  246. forEach: function(fn, bind){
  247. for (var i = 0, l = this.length; i < l; i++){
  248. if (i in this) fn.call(bind, this[i], i, this);
  249. }
  250. },
  251. /*</!ES5>*/
  252. each: function(fn, bind){
  253. Array.forEach(this, fn, bind);
  254. return this;
  255. }
  256. });
  257. // Array & Object cloning, Object merging and appending
  258. var cloneOf = function(item){
  259. switch (typeOf(item)){
  260. case 'array': return item.clone();
  261. case 'object': return Object.clone(item);
  262. default: return item;
  263. }
  264. };
  265. Array.implement('clone', function(){
  266. var i = this.length, clone = new Array(i);
  267. while (i--) clone[i] = cloneOf(this[i]);
  268. return clone;
  269. });
  270. var mergeOne = function(source, key, current){
  271. switch (typeOf(current)){
  272. case 'object':
  273. if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
  274. else source[key] = Object.clone(current);
  275. break;
  276. case 'array': source[key] = current.clone(); break;
  277. default: source[key] = current;
  278. }
  279. return source;
  280. };
  281. Object.extend({
  282. merge: function(source, k, v){
  283. if (typeOf(k) == 'string') return mergeOne(source, k, v);
  284. for (var i = 1, l = arguments.length; i < l; i++){
  285. var object = arguments[i];
  286. for (var key in object) mergeOne(source, key, object[key]);
  287. }
  288. return source;
  289. },
  290. clone: function(object){
  291. var clone = {};
  292. for (var key in object) clone[key] = cloneOf(object[key]);
  293. return clone;
  294. },
  295. append: function(original){
  296. for (var i = 1, l = arguments.length; i < l; i++){
  297. var extended = arguments[i] || {};
  298. for (var key in extended) original[key] = extended[key];
  299. }
  300. return original;
  301. }
  302. });
  303. // Object-less types
  304. ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){
  305. new Type(name);
  306. });
  307. // Unique ID
  308. var UID = Date.now();
  309. String.extend('uniqueID', function(){
  310. return (UID++).toString(36);
  311. });
  312. //<1.2compat>
  313. var Hash = this.Hash = new Type('Hash', function(object){
  314. if (typeOf(object) == 'hash') object = Object.clone(object.getClean());
  315. for (var key in object) this[key] = object[key];
  316. return this;
  317. });
  318. Hash.implement({
  319. forEach: function(fn, bind){
  320. Object.forEach(this, fn, bind);
  321. },
  322. getClean: function(){
  323. var clean = {};
  324. for (var key in this){
  325. if (this.hasOwnProperty(key)) clean[key] = this[key];
  326. }
  327. return clean;
  328. },
  329. getLength: function(){
  330. var length = 0;
  331. for (var key in this){
  332. if (this.hasOwnProperty(key)) length++;
  333. }
  334. return length;
  335. }
  336. });
  337. Hash.alias('each', 'forEach');
  338. Object.type = Type.isObject;
  339. var Native = this.Native = function(properties){
  340. return new Type(properties.name, properties.initialize);
  341. };
  342. Native.type = Type.type;
  343. Native.implement = function(objects, methods){
  344. for (var i = 0; i < objects.length; i++) objects[i].implement(methods);
  345. return Native;
  346. };
  347. var arrayType = Array.type;
  348. Array.type = function(item){
  349. return instanceOf(item, Array) || arrayType(item);
  350. };
  351. this.$A = function(item){
  352. return Array.from(item).slice();
  353. };
  354. this.$arguments = function(i){
  355. return function(){
  356. return arguments[i];
  357. };
  358. };
  359. this.$chk = function(obj){
  360. return !!(obj || obj === 0);
  361. };
  362. this.$clear = function(timer){
  363. clearTimeout(timer);
  364. clearInterval(timer);
  365. return null;
  366. };
  367. this.$defined = function(obj){
  368. return (obj != null);
  369. };
  370. this.$each = function(iterable, fn, bind){
  371. var type = typeOf(iterable);
  372. ((type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements') ? Array : Object).each(iterable, fn, bind);
  373. };
  374. this.$empty = function(){};
  375. this.$extend = function(original, extended){
  376. return Object.append(original, extended);
  377. };
  378. this.$H = function(object){
  379. return new Hash(object);
  380. };
  381. this.$merge = function(){
  382. var args = Array.slice(arguments);
  383. args.unshift({});
  384. return Object.merge.apply(null, args);
  385. };
  386. this.$lambda = Function.from;
  387. this.$mixin = Object.merge;
  388. this.$random = Number.random;
  389. this.$splat = Array.from;
  390. this.$time = Date.now;
  391. this.$type = function(object){
  392. var type = typeOf(object);
  393. if (type == 'elements') return 'array';
  394. return (type == 'null') ? false : type;
  395. };
  396. this.$unlink = function(object){
  397. switch (typeOf(object)){
  398. case 'object': return Object.clone(object);
  399. case 'array': return Array.clone(object);
  400. case 'hash': return new Hash(object);
  401. default: return object;
  402. }
  403. };
  404. //</1.2compat>
  405. })();
  406. /*
  407. ---
  408. name: Array
  409. description: Contains Array Prototypes like each, contains, and erase.
  410. license: MIT-style license.
  411. requires: [Type]
  412. provides: Array
  413. ...
  414. */
  415. Array.implement({
  416. /*<!ES5>*/
  417. every: function(fn, bind){
  418. for (var i = 0, l = this.length >>> 0; i < l; i++){
  419. if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
  420. }
  421. return true;
  422. },
  423. filter: function(fn, bind){
  424. var results = [];
  425. for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){
  426. value = this[i];
  427. if (fn.call(bind, value, i, this)) results.push(value);
  428. }
  429. return results;
  430. },
  431. indexOf: function(item, from){
  432. var length = this.length >>> 0;
  433. for (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++){
  434. if (this[i] === item) return i;
  435. }
  436. return -1;
  437. },
  438. map: function(fn, bind){
  439. var length = this.length >>> 0, results = Array(length);
  440. for (var i = 0; i < length; i++){
  441. if (i in this) results[i] = fn.call(bind, this[i], i, this);
  442. }
  443. return results;
  444. },
  445. some: function(fn, bind){
  446. for (var i = 0, l = this.length >>> 0; i < l; i++){
  447. if ((i in this) && fn.call(bind, this[i], i, this)) return true;
  448. }
  449. return false;
  450. },
  451. /*</!ES5>*/
  452. clean: function(){
  453. return this.filter(function(item){
  454. return item != null;
  455. });
  456. },
  457. invoke: function(methodName){
  458. var args = Array.slice(arguments, 1);
  459. return this.map(function(item){
  460. return item[methodName].apply(item, args);
  461. });
  462. },
  463. associate: function(keys){
  464. var obj = {}, length = Math.min(this.length, keys.length);
  465. for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
  466. return obj;
  467. },
  468. link: function(object){
  469. var result = {};
  470. for (var i = 0, l = this.length; i < l; i++){
  471. for (var key in object){
  472. if (object[key](this[i])){
  473. result[key] = this[i];
  474. delete object[key];
  475. break;
  476. }
  477. }
  478. }
  479. return result;
  480. },
  481. contains: function(item, from){
  482. return this.indexOf(item, from) != -1;
  483. },
  484. append: function(array){
  485. this.push.apply(this, array);
  486. return this;
  487. },
  488. getLast: function(){
  489. return (this.length) ? this[this.length - 1] : null;
  490. },
  491. getRandom: function(){
  492. return (this.length) ? this[Number.random(0, this.length - 1)] : null;
  493. },
  494. include: function(item){
  495. if (!this.contains(item)) this.push(item);
  496. return this;
  497. },
  498. combine: function(array){
  499. for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
  500. return this;
  501. },
  502. erase: function(item){
  503. for (var i = this.length; i--;){
  504. if (this[i] === item) this.splice(i, 1);
  505. }
  506. return this;
  507. },
  508. empty: function(){
  509. this.length = 0;
  510. return this;
  511. },
  512. flatten: function(){
  513. var array = [];
  514. for (var i = 0, l = this.length; i < l; i++){
  515. var type = typeOf(this[i]);
  516. if (type == 'null') continue;
  517. array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
  518. }
  519. return array;
  520. },
  521. pick: function(){
  522. for (var i = 0, l = this.length; i < l; i++){
  523. if (this[i] != null) return this[i];
  524. }
  525. return null;
  526. },
  527. hexToRgb: function(array){
  528. if (this.length != 3) return null;
  529. var rgb = this.map(function(value){
  530. if (value.length == 1) value += value;
  531. return parseInt(value, 16);
  532. });
  533. return (array) ? rgb : 'rgb(' + rgb + ')';
  534. },
  535. rgbToHex: function(array){
  536. if (this.length < 3) return null;
  537. if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
  538. var hex = [];
  539. for (var i = 0; i < 3; i++){
  540. var bit = (this[i] - 0).toString(16);
  541. hex.push((bit.length == 1) ? '0' + bit : bit);
  542. }
  543. return (array) ? hex : '#' + hex.join('');
  544. }
  545. });
  546. //<1.2compat>
  547. Array.alias('extend', 'append');
  548. var $pick = function(){
  549. return Array.from(arguments).pick();
  550. };
  551. //</1.2compat>
  552. /*
  553. ---
  554. name: String
  555. description: Contains String Prototypes like camelCase, capitalize, test, and toInt.
  556. license: MIT-style license.
  557. requires: [Type, Array]
  558. provides: String
  559. ...
  560. */
  561. String.implement({
  562. //<!ES6>
  563. contains: function(string, index){
  564. return (index ? String(this).slice(index) : String(this)).indexOf(string) > -1;
  565. },
  566. //</!ES6>
  567. test: function(regex, params){
  568. return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
  569. },
  570. trim: function(){
  571. return String(this).replace(/^\s+|\s+$/g, '');
  572. },
  573. clean: function(){
  574. return String(this).replace(/\s+/g, ' ').trim();
  575. },
  576. camelCase: function(){
  577. return String(this).replace(/-\D/g, function(match){
  578. return match.charAt(1).toUpperCase();
  579. });
  580. },
  581. hyphenate: function(){
  582. return String(this).replace(/[A-Z]/g, function(match){
  583. return ('-' + match.charAt(0).toLowerCase());
  584. });
  585. },
  586. capitalize: function(){
  587. return String(this).replace(/\b[a-z]/g, function(match){
  588. return match.toUpperCase();
  589. });
  590. },
  591. escapeRegExp: function(){
  592. return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
  593. },
  594. toInt: function(base){
  595. return parseInt(this, base || 10);
  596. },
  597. toFloat: function(){
  598. return parseFloat(this);
  599. },
  600. hexToRgb: function(array){
  601. var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
  602. return (hex) ? hex.slice(1).hexToRgb(array) : null;
  603. },
  604. rgbToHex: function(array){
  605. var rgb = String(this).match(/\d{1,3}/g);
  606. return (rgb) ? rgb.rgbToHex(array) : null;
  607. },
  608. substitute: function(object, regexp){
  609. return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
  610. if (match.charAt(0) == '\\') return match.slice(1);
  611. return (object[name] != null) ? object[name] : '';
  612. });
  613. }
  614. });
  615. //<1.4compat>
  616. String.prototype.contains = function(string, separator){
  617. return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : String(this).indexOf(string) > -1;
  618. };
  619. //</1.4compat>
  620. /*
  621. ---
  622. name: Number
  623. description: Contains Number Prototypes like limit, round, times, and ceil.
  624. license: MIT-style license.
  625. requires: Type
  626. provides: Number
  627. ...
  628. */
  629. Number.implement({
  630. limit: function(min, max){
  631. return Math.min(max, Math.max(min, this));
  632. },
  633. round: function(precision){
  634. precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
  635. return Math.round(this * precision) / precision;
  636. },
  637. times: function(fn, bind){
  638. for (var i = 0; i < this; i++) fn.call(bind, i, this);
  639. },
  640. toFloat: function(){
  641. return parseFloat(this);
  642. },
  643. toInt: function(base){
  644. return parseInt(this, base || 10);
  645. }
  646. });
  647. Number.alias('each', 'times');
  648. (function(math){
  649. var methods = {};
  650. math.each(function(name){
  651. if (!Number[name]) methods[name] = function(){
  652. return Math[name].apply(null, [this].concat(Array.from(arguments)));
  653. };
  654. });
  655. Number.implement(methods);
  656. })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
  657. /*
  658. ---
  659. name: Function
  660. description: Contains Function Prototypes like create, bind, pass, and delay.
  661. license: MIT-style license.
  662. requires: Type
  663. provides: Function
  664. ...
  665. */
  666. Function.extend({
  667. attempt: function(){
  668. for (var i = 0, l = arguments.length; i < l; i++){
  669. try {
  670. return arguments[i]();
  671. } catch (e){}
  672. }
  673. return null;
  674. }
  675. });
  676. Function.implement({
  677. attempt: function(args, bind){
  678. try {
  679. return this.apply(bind, Array.from(args));
  680. } catch (e){}
  681. return null;
  682. },
  683. /*<!ES5-bind>*/
  684. bind: function(that){
  685. var self = this,
  686. args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
  687. F = function(){};
  688. var bound = function(){
  689. var context = that, length = arguments.length;
  690. if (this instanceof bound){
  691. F.prototype = self.prototype;
  692. context = new F;
  693. }
  694. var result = (!args && !length)
  695. ? self.call(context)
  696. : self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);
  697. return context == that ? result : context;
  698. };
  699. return bound;
  700. },
  701. /*</!ES5-bind>*/
  702. pass: function(args, bind){
  703. var self = this;
  704. if (args != null) args = Array.from(args);
  705. return function(){
  706. return self.apply(bind, args || arguments);
  707. };
  708. },
  709. delay: function(delay, bind, args){
  710. return setTimeout(this.pass((args == null ? [] : args), bind), delay);
  711. },
  712. periodical: function(periodical, bind, args){
  713. return setInterval(this.pass((args == null ? [] : args), bind), periodical);
  714. }
  715. });
  716. //<1.2compat>
  717. delete Function.prototype.bind;
  718. Function.implement({
  719. create: function(options){
  720. var self = this;
  721. options = options || {};
  722. return function(event){
  723. var args = options.arguments;
  724. args = (args != null) ? Array.from(args) : Array.slice(arguments, (options.event) ? 1 : 0);
  725. if (options.event) args = [event || window.event].extend(args);
  726. var returns = function(){
  727. return self.apply(options.bind || null, args);
  728. };
  729. if (options.delay) return setTimeout(returns, options.delay);
  730. if (options.periodical) return setInterval(returns, options.periodical);
  731. if (options.attempt) return Function.attempt(returns);
  732. return returns();
  733. };
  734. },
  735. bind: function(bind, args){
  736. var self = this;
  737. if (args != null) args = Array.from(args);
  738. return function(){
  739. return self.apply(bind, args || arguments);
  740. };
  741. },
  742. bindWithEvent: function(bind, args){
  743. var self = this;
  744. if (args != null) args = Array.from(args);
  745. return function(event){
  746. return self.apply(bind, (args == null) ? arguments : [event].concat(args));
  747. };
  748. },
  749. run: function(args, bind){
  750. return this.apply(bind, Array.from(args));
  751. }
  752. });
  753. if (Object.create == Function.prototype.create) Object.create = null;
  754. var $try = Function.attempt;
  755. //</1.2compat>
  756. /*
  757. ---
  758. name: Object
  759. description: Object generic methods
  760. license: MIT-style license.
  761. requires: Type
  762. provides: [Object, Hash]
  763. ...
  764. */
  765. (function(){
  766. var hasOwnProperty = Object.prototype.hasOwnProperty;
  767. Object.extend({
  768. subset: function(object, keys){
  769. var results = {};
  770. for (var i = 0, l = keys.length; i < l; i++){
  771. var k = keys[i];
  772. if (k in object) results[k] = object[k];
  773. }
  774. return results;
  775. },
  776. map: function(object, fn, bind){
  777. var results = {};
  778. for (var key in object){
  779. if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object);
  780. }
  781. return results;
  782. },
  783. filter: function(object, fn, bind){
  784. var results = {};
  785. for (var key in object){
  786. var value = object[key];
  787. if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;
  788. }
  789. return results;
  790. },
  791. every: function(object, fn, bind){
  792. for (var key in object){
  793. if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;
  794. }
  795. return true;
  796. },
  797. some: function(object, fn, bind){
  798. for (var key in object){
  799. if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true;
  800. }
  801. return false;
  802. },
  803. keys: function(object){
  804. var keys = [];
  805. for (var key in object){
  806. if (hasOwnProperty.call(object, key)) keys.push(key);
  807. }
  808. return keys;
  809. },
  810. values: function(object){
  811. var values = [];
  812. for (var key in object){
  813. if (hasOwnProperty.call(object, key)) values.push(object[key]);
  814. }
  815. return values;
  816. },
  817. getLength: function(object){
  818. return Object.keys(object).length;
  819. },
  820. keyOf: function(object, value){
  821. for (var key in object){
  822. if (hasOwnProperty.call(object, key) && object[key] === value) return key;
  823. }
  824. return null;
  825. },
  826. contains: function(object, value){
  827. return Object.keyOf(object, value) != null;
  828. },
  829. toQueryString: function(object, base){
  830. var queryString = [];
  831. Object.each(object, function(value, key){
  832. if (base) key = base + '[' + key + ']';
  833. var result;
  834. switch (typeOf(value)){
  835. case 'object': result = Object.toQueryString(value, key); break;
  836. case 'array':
  837. var qs = {};
  838. value.each(function(val, i){
  839. qs[i] = val;
  840. });
  841. result = Object.toQueryString(qs, key);
  842. break;
  843. default: result = key + '=' + encodeURIComponent(value);
  844. }
  845. if (value != null) queryString.push(result);
  846. });
  847. return queryString.join('&');
  848. }
  849. });
  850. })();
  851. //<1.2compat>
  852. Hash.implement({
  853. has: Object.prototype.hasOwnProperty,
  854. keyOf: function(value){
  855. return Object.keyOf(this, value);
  856. },
  857. hasValue: function(value){
  858. return Object.contains(this, value);
  859. },
  860. extend: function(properties){
  861. Hash.each(properties || {}, function(value, key){
  862. Hash.set(this, key, value);
  863. }, this);
  864. return this;
  865. },
  866. combine: function(properties){
  867. Hash.each(properties || {}, function(value, key){
  868. Hash.include(this, key, value);
  869. }, this);
  870. return this;
  871. },
  872. erase: function(key){
  873. if (this.hasOwnProperty(key)) delete this[key];
  874. return this;
  875. },
  876. get: function(key){
  877. return (this.hasOwnProperty(key)) ? this[key] : null;
  878. },
  879. set: function(key, value){
  880. if (!this[key] || this.hasOwnProperty(key)) this[key] = value;
  881. return this;
  882. },
  883. empty: function(){
  884. Hash.each(this, function(value, key){
  885. delete this[key];
  886. }, this);
  887. return this;
  888. },
  889. include: function(key, value){
  890. if (this[key] == null) this[key] = value;
  891. return this;
  892. },
  893. map: function(fn, bind){
  894. return new Hash(Object.map(this, fn, bind));
  895. },
  896. filter: function(fn, bind){
  897. return new Hash(Object.filter(this, fn, bind));
  898. },
  899. every: function(fn, bind){
  900. return Object.every(this, fn, bind);
  901. },
  902. some: function(fn, bind){
  903. return Object.some(this, fn, bind);
  904. },
  905. getKeys: function(){
  906. return Object.keys(this);
  907. },
  908. getValues: function(){
  909. return Object.values(this);
  910. },
  911. toQueryString: function(base){
  912. return Object.toQueryString(this, base);
  913. }
  914. });
  915. Hash.extend = Object.append;
  916. Hash.alias({indexOf: 'keyOf', contains: 'hasValue'});
  917. //</1.2compat>
  918. /*
  919. ---
  920. name: Browser
  921. description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.
  922. license: MIT-style license.
  923. requires: [Array, Function, Number, String]
  924. provides: [Browser, Window, Document]
  925. ...
  926. */
  927. (function(){
  928. var document = this.document;
  929. var window = document.window = this;
  930. var parse = function(ua, platform){
  931. ua = ua.toLowerCase();
  932. platform = (platform ? platform.toLowerCase() : '');
  933. var UA = ua.match(/(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/) || [null, 'unknown', 0];
  934. if (UA[1] == 'trident'){
  935. UA[1] = 'ie';
  936. if (UA[4]) UA[2] = UA[4];
  937. } else if (UA[1] == 'crios') {
  938. UA[1] = 'chrome';
  939. }
  940. var platform = ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0];
  941. if (platform == 'win') platform = 'windows';
  942. return {
  943. extend: Function.prototype.extend,
  944. name: (UA[1] == 'version') ? UA[3] : UA[1],
  945. version: parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
  946. platform: platform
  947. };
  948. };
  949. var Browser = this.Browser = parse(navigator.userAgent, navigator.platform);
  950. if (Browser.ie){
  951. Browser.version = document.documentMode;
  952. }
  953. Browser.extend({
  954. Features: {
  955. xpath: !!(document.evaluate),
  956. air: !!(window.runtime),
  957. query: !!(document.querySelector),
  958. json: !!(window.JSON)
  959. },
  960. parseUA: parse
  961. });
  962. //<1.4compat>
  963. Browser[Browser.name] = true;
  964. Browser[Browser.name + parseInt(Browser.version, 10)] = true;
  965. if (Browser.name == 'ie' && Browser.version >= '11') {
  966. delete Browser.ie;
  967. }
  968. var platform = Browser.platform;
  969. if (platform == 'windows'){
  970. platform = 'win';
  971. }
  972. Browser.Platform = {
  973. name: platform
  974. };
  975. Browser.Platform[platform] = true;
  976. //</1.4compat>
  977. // Request
  978. Browser.Request = (function(){
  979. var XMLHTTP = function(){
  980. return new XMLHttpRequest();
  981. };
  982. var MSXML2 = function(){
  983. return new ActiveXObject('MSXML2.XMLHTTP');
  984. };
  985. var MSXML = function(){
  986. return new ActiveXObject('Microsoft.XMLHTTP');
  987. };
  988. return Function.attempt(function(){
  989. XMLHTTP();
  990. return XMLHTTP;
  991. }, function(){
  992. MSXML2();
  993. return MSXML2;
  994. }, function(){
  995. MSXML();
  996. return MSXML;
  997. });
  998. })();
  999. Browser.Features.xhr = !!(Browser.Request);
  1000. //<1.4compat>
  1001. // Flash detection
  1002. var version = (Function.attempt(function(){
  1003. return navigator.plugins['Shockwave Flash'].description;
  1004. }, function(){
  1005. return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
  1006. }) || '0 r0').match(/\d+/g);
  1007. Browser.Plugins = {
  1008. Flash: {
  1009. version: Number(version[0] || '0.' + version[1]) || 0,
  1010. build: Number(version[2]) || 0
  1011. }
  1012. };
  1013. //</1.4compat>
  1014. // String scripts
  1015. Browser.exec = function(text){
  1016. if (!text) return text;
  1017. if (window.execScript){
  1018. window.execScript(text);
  1019. } else {
  1020. var script = document.createElement('script');
  1021. script.setAttribute('type', 'text/javascript');
  1022. script.text = text;
  1023. document.head.appendChild(script);
  1024. document.head.removeChild(script);
  1025. }
  1026. return text;
  1027. };
  1028. String.implement('stripScripts', function(exec){
  1029. var scripts = '';
  1030. var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
  1031. scripts += code + '\n';
  1032. return '';
  1033. });
  1034. if (exec === true) Browser.exec(scripts);
  1035. else if (typeOf(exec) == 'function') exec(scripts, text);
  1036. return text;
  1037. });
  1038. // Window, Document
  1039. Browser.extend({
  1040. Document: this.Document,
  1041. Window: this.Window,
  1042. Element: this.Element,
  1043. Event: this.Event
  1044. });
  1045. this.Window = this.$constructor = new Type('Window', function(){});
  1046. this.$family = Function.from('window').hide();
  1047. Window.mirror(function(name, method){
  1048. window[name] = method;
  1049. });
  1050. this.Document = document.$constructor = new Type('Document', function(){});
  1051. document.$family = Function.from('document').hide();
  1052. Document.mirror(function(name, method){
  1053. document[name] = method;
  1054. });
  1055. document.html = document.documentElement;
  1056. if (!document.head) document.head = document.getElementsByTagName('head')[0];
  1057. if (document.execCommand) try {
  1058. document.execCommand("BackgroundImageCache", false, true);
  1059. } catch (e){}
  1060. /*<ltIE9>*/
  1061. if (this.attachEvent && !this.addEventListener){
  1062. var unloadEvent = function(){
  1063. this.detachEvent('onunload', unloadEvent);
  1064. document.head = document.html = document.window = null;
  1065. };
  1066. this.attachEvent('onunload', unloadEvent);
  1067. }
  1068. // IE fails on collections and <select>.options (refers to <select>)
  1069. var arrayFrom = Array.from;
  1070. try {
  1071. arrayFrom(document.html.childNodes);
  1072. } catch(e){
  1073. Array.from = function(item){
  1074. if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
  1075. var i = item.length, array = new Array(i);
  1076. while (i--) array[i] = item[i];
  1077. return array;
  1078. }
  1079. return arrayFrom(item);
  1080. };
  1081. var prototype = Array.prototype,
  1082. slice = prototype.slice;
  1083. ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
  1084. var method = prototype[name];
  1085. Array[name] = function(item){
  1086. return method.apply(Array.from(item), slice.call(arguments, 1));
  1087. };
  1088. });
  1089. }
  1090. /*</ltIE9>*/
  1091. //<1.2compat>
  1092. if (Browser.Platform.ios) Browser.Platform.ipod = true;
  1093. Browser.Engine = {};
  1094. var setEngine = function(name, version){
  1095. Browser.Engine.name = name;
  1096. Browser.Engine[name + version] = true;
  1097. Browser.Engine.version = version;
  1098. };
  1099. if (Browser.ie){
  1100. Browser.Engine.trident = true;
  1101. switch (Browser.version){
  1102. case 6: setEngine('trident', 4); break;
  1103. case 7: setEngine('trident', 5); break;
  1104. case 8: setEngine('trident', 6);
  1105. }
  1106. }
  1107. if (Browser.firefox){
  1108. Browser.Engine.gecko = true;
  1109. if (Browser.version >= 3) setEngine('gecko', 19);
  1110. else setEngine('gecko', 18);
  1111. }
  1112. if (Browser.safari || Browser.chrome){
  1113. Browser.Engine.webkit = true;
  1114. switch (Browser.version){
  1115. case 2: setEngine('webkit', 419); break;
  1116. case 3: setEngine('webkit', 420); break;
  1117. case 4: setEngine('webkit', 525);
  1118. }
  1119. }
  1120. if (Browser.opera){
  1121. Browser.Engine.presto = true;
  1122. if (Browser.version >= 9.6) setEngine('presto', 960);
  1123. else if (Browser.version >= 9.5) setEngine('presto', 950);
  1124. else setEngine('presto', 925);
  1125. }
  1126. if (Browser.name == 'unknown'){
  1127. switch ((navigator.userAgent.toLowerCase().match(/(?:webkit|khtml|gecko)/) || [])[0]){
  1128. case 'webkit':
  1129. case 'khtml':
  1130. Browser.Engine.webkit = true;
  1131. break;
  1132. case 'gecko':
  1133. Browser.Engine.gecko = true;
  1134. }
  1135. }
  1136. this.$exec = Browser.exec;
  1137. //</1.2compat>
  1138. })();
  1139. /*
  1140. ---
  1141. name: Event
  1142. description: Contains the Event Type, to make the event object cross-browser.
  1143. license: MIT-style license.
  1144. requires: [Window, Document, Array, Function, String, Object]
  1145. provides: Event
  1146. ...
  1147. */
  1148. (function() {
  1149. var _keys = {};
  1150. var DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){
  1151. if (!win) win = window;
  1152. event = event || win.event;
  1153. if (event.$extended) return event;
  1154. this.event = event;
  1155. this.$extended = true;
  1156. this.shift = event.shiftKey;
  1157. this.control = event.ctrlKey;
  1158. this.alt = event.altKey;
  1159. this.meta = event.metaKey;
  1160. var type = this.type = event.type;
  1161. var target = event.target || event.srcElement;
  1162. while (target && target.nodeType == 3) target = target.parentNode;
  1163. this.target = document.id(target);
  1164. if (type.indexOf('key') == 0){
  1165. var code = this.code = (event.which || event.keyCode);
  1166. this.key = _keys[code]/*<1.3compat>*/ || Object.keyOf(Event.Keys, code)/*</1.3compat>*/;
  1167. if (type == 'keydown' || type == 'keyup'){
  1168. if (code > 111 && code < 124) this.key = 'f' + (code - 111);
  1169. else if (code > 95 && code < 106) this.key = code - 96;
  1170. }
  1171. if (this.key == null) this.key = String.fromCharCode(code).toLowerCase();
  1172. } else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){
  1173. var doc = win.document;
  1174. doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
  1175. this.page = {
  1176. x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
  1177. y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
  1178. };
  1179. this.client = {
  1180. x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
  1181. y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
  1182. };
  1183. if (type == 'DOMMouseScroll' || type == 'mousewheel')
  1184. this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
  1185. this.rightClick = (event.which == 3 || event.button == 2);
  1186. if (type == 'mouseover' || type == 'mouseout'){
  1187. var related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
  1188. while (related && related.nodeType == 3) related = related.parentNode;
  1189. this.relatedTarget = document.id(related);
  1190. }
  1191. } else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){
  1192. this.rotation = event.rotation;
  1193. this.scale = event.scale;
  1194. this.targetTouches = event.targetTouches;
  1195. this.changedTouches = event.changedTouches;
  1196. var touches = this.touches = event.touches;
  1197. if (touches && touches[0]){
  1198. var touch = touches[0];
  1199. this.page = {x: touch.pageX, y: touch.pageY};
  1200. this.client = {x: touch.clientX, y: touch.clientY};
  1201. }
  1202. }
  1203. if (!this.client) this.client = {};
  1204. if (!this.page) this.page = {};
  1205. });
  1206. DOMEvent.implement({
  1207. stop: function(){
  1208. return this.preventDefault().stopPropagation();
  1209. },
  1210. stopPropagation: function(){
  1211. if (this.event.stopPropagation) this.event.stopPropagation();
  1212. else this.event.cancelBubble = true;
  1213. return this;
  1214. },
  1215. preventDefault: function(){
  1216. if (this.event.preventDefault) this.event.preventDefault();
  1217. else this.event.returnValue = false;
  1218. return this;
  1219. }
  1220. });
  1221. DOMEvent.defineKey = function(code, key){
  1222. _keys[code] = key;
  1223. return this;
  1224. };
  1225. DOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true);
  1226. DOMEvent.defineKeys({
  1227. '38': 'up', '40': 'down', '37': 'left', '39': 'right',
  1228. '27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',
  1229. '46': 'delete', '13': 'enter'
  1230. });
  1231. })();
  1232. /*<1.3compat>*/
  1233. var Event = DOMEvent;
  1234. Event.Keys = {};
  1235. /*</1.3compat>*/
  1236. /*<1.2compat>*/
  1237. Event.Keys = new Hash(Event.Keys);
  1238. /*</1.2compat>*/
  1239. /*
  1240. ---
  1241. name: Class
  1242. description: Contains the Class Function for easily creating, extending, and implementing reusable Classes.
  1243. license: MIT-style license.
  1244. requires: [Array, String, Function, Number]
  1245. provides: Class
  1246. ...
  1247. */
  1248. (function(){
  1249. var Class = this.Class = new Type('Class', function(params){
  1250. if (instanceOf(params, Function)) params = {initialize: params};
  1251. var newClass = function(){
  1252. reset(this);
  1253. if (newClass.$prototyping) return this;
  1254. this.$caller = null;
  1255. var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
  1256. this.$caller = this.caller = null;
  1257. return value;
  1258. }.extend(this).implement(params);
  1259. newClass.$constructor = Class;
  1260. newClass.prototype.$constructor = newClass;
  1261. newClass.prototype.parent = parent;
  1262. return newClass;
  1263. });
  1264. var parent = function(){
  1265. if (!this.$caller) throw new Error('The method "parent" cannot be called.');
  1266. var name = this.$caller.$name,
  1267. parent = this.$caller.$owner.parent,
  1268. previous = (parent) ? parent.prototype[name] : null;
  1269. if (!previous) throw new Error('The method "' + name + '" has no parent.');
  1270. return previous.apply(this, arguments);
  1271. };
  1272. var reset = function(object){
  1273. for (var key in object){
  1274. var value = object[key];
  1275. switch (typeOf(value)){
  1276. case 'object':
  1277. var F = function(){};
  1278. F.prototype = value;
  1279. object[key] = reset(new F);
  1280. break;
  1281. case 'array': object[key] = value.clone(); break;
  1282. }
  1283. }
  1284. return object;
  1285. };
  1286. var wrap = function(self, key, method){
  1287. if (method.$origin) method = method.$origin;
  1288. var wrapper = function(){
  1289. if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
  1290. var caller = this.caller, current = this.$caller;
  1291. this.caller = current; this.$caller = wrapper;
  1292. var result = method.apply(this, arguments);
  1293. this.$caller = current; this.caller = caller;
  1294. return result;
  1295. }.extend({$owner: self, $origin: method, $name: key});
  1296. return wrapper;
  1297. };
  1298. var implement = function(key, value, retain){
  1299. if (Class.Mutators.hasOwnProperty(key)){
  1300. value = Class.Mutators[key].call(this, value);
  1301. if (value == null) return this;
  1302. }
  1303. if (typeOf(value) == 'function'){
  1304. if (value.$hidden) return this;
  1305. this.prototype[key] = (retain) ? value : wrap(this, key, value);
  1306. } else {
  1307. Object.merge(this.prototype, key, value);
  1308. }
  1309. return this;
  1310. };
  1311. var getInstance = function(klass){
  1312. klass.$prototyping = true;
  1313. var proto = new klass;
  1314. delete klass.$prototyping;
  1315. return proto;
  1316. };
  1317. Class.implement('implement', implement.overloadSetter());
  1318. Class.Mutators = {
  1319. Extends: function(parent){
  1320. this.parent = parent;
  1321. this.prototype = getInstance(parent);
  1322. },
  1323. Implements: function(items){
  1324. Array.from(items).each(function(item){
  1325. var instance = new item;
  1326. for (var key in instance) implement.call(this, key, instance[key], true);
  1327. }, this);
  1328. }
  1329. };
  1330. })();
  1331. /*
  1332. ---
  1333. name: Class.Extras
  1334. description: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks.
  1335. license: MIT-style license.
  1336. requires: Class
  1337. provides: [Class.Extras, Chain, Events, Options]
  1338. ...
  1339. */
  1340. (function(){
  1341. this.Chain = new Class({
  1342. $chain: [],
  1343. chain: function(){
  1344. this.$chain.append(Array.flatten(arguments));
  1345. return this;
  1346. },
  1347. callChain: function(){
  1348. return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
  1349. },
  1350. clearChain: function(){
  1351. this.$chain.empty();
  1352. return this;
  1353. }
  1354. });
  1355. var removeOn = function(string){
  1356. return string.replace(/^on([A-Z])/, function(full, first){
  1357. return first.toLowerCase();
  1358. });
  1359. };
  1360. this.Events = new Class({
  1361. $events: {},
  1362. addEvent: function(type, fn, internal){
  1363. type = removeOn(type);
  1364. /*<1.2compat>*/
  1365. if (fn == $empty) return this;
  1366. /*</1.2compat>*/
  1367. this.$events[type] = (this.$events[type] || []).include(fn);
  1368. if (internal) fn.internal = true;
  1369. return this;
  1370. },
  1371. addEvents: function(events){
  1372. for (var type in events) this.addEvent(type, events[type]);
  1373. return this;
  1374. },
  1375. fireEvent: function(type, args, delay){
  1376. type = removeOn(type);
  1377. var events = this.$events[type];
  1378. if (!events) return this;
  1379. args = Array.from(args);
  1380. events.each(function(fn){
  1381. if (delay) fn.delay(delay, this, args);
  1382. else fn.apply(this, args);
  1383. }, this);
  1384. return this;
  1385. },
  1386. removeEvent: function(type, fn){
  1387. type = removeOn(type);
  1388. var events = this.$events[type];
  1389. if (events && !fn.internal){
  1390. var index = events.indexOf(fn);
  1391. if (index != -1) delete events[index];
  1392. }
  1393. return this;
  1394. },
  1395. removeEvents: function(events){
  1396. var type;
  1397. if (typeOf(events) == 'object'){
  1398. for (type in events) this.removeEvent(type, events[type]);
  1399. return this;
  1400. }
  1401. if (events) events = removeOn(events);
  1402. for (type in this.$events){
  1403. if (events && events != type) continue;
  1404. var fns = this.$events[type];
  1405. for (var i = fns.length; i--;) if (i in fns){
  1406. this.removeEvent(type, fns[i]);
  1407. }
  1408. }
  1409. return this;
  1410. }
  1411. });
  1412. this.Options = new Class({
  1413. setOptions: function(){
  1414. var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
  1415. if (this.addEvent) for (var option in options){
  1416. if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
  1417. this.addEvent(option, options[option]);
  1418. delete options[option];
  1419. }
  1420. return this;
  1421. }
  1422. });
  1423. })();
  1424. /*
  1425. ---
  1426. name: Slick.Parser
  1427. description: Standalone CSS3 Selector parser
  1428. provides: Slick.Parser
  1429. ...
  1430. */
  1431. ;(function(){
  1432. var parsed,
  1433. separatorIndex,
  1434. combinatorIndex,
  1435. reversed,
  1436. cache = {},
  1437. reverseCache = {},
  1438. reUnescape = /\\/g;
  1439. var parse = function(expression, isReversed){
  1440. if (expression == null) return null;
  1441. if (expression.Slick === true) return expression;
  1442. expression = ('' + expression).replace(/^\s+|\s+$/g, '');
  1443. reversed = !!isReversed;
  1444. var currentCache = (reversed) ? reverseCache : cache;
  1445. if (currentCache[expression]) return currentCache[expression];
  1446. parsed = {
  1447. Slick: true,
  1448. expressions: [],
  1449. raw: expression,
  1450. reverse: function(){
  1451. return parse(this.raw, true);
  1452. }
  1453. };
  1454. separatorIndex = -1;
  1455. while (expression != (expression = expression.replace(regexp, parser)));
  1456. parsed.length = parsed.expressions.length;
  1457. return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
  1458. };
  1459. var reverseCombinator = function(combinator){
  1460. if (combinator === '!') return ' ';
  1461. else if (combinator === ' ') return '!';
  1462. else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
  1463. else return '!' + combinator;
  1464. };
  1465. var reverse = function(expression){
  1466. var expressions = expression.expressions;
  1467. for (var i = 0; i < expressions.length; i++){
  1468. var exp = expressions[i];
  1469. var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};
  1470. for (var j = 0; j < exp.length; j++){
  1471. var cexp = exp[j];
  1472. if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
  1473. cexp.combinator = cexp.reverseCombinator;
  1474. delete cexp.reverseCombinator;
  1475. }
  1476. exp.reverse().push(last);
  1477. }
  1478. return expression;
  1479. };
  1480. var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
  1481. return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
  1482. return '\\' + match;
  1483. });
  1484. };
  1485. var regexp = new RegExp(
  1486. /*
  1487. #!/usr/bin/env ruby
  1488. puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
  1489. __END__
  1490. "(?x)^(?:\
  1491. \\s* ( , ) \\s* # Separator \n\
  1492. | \\s* ( <combinator>+ ) \\s* # Combinator \n\
  1493. | ( \\s+ ) # CombinatorChildren \n\
  1494. | ( <unicode>+ | \\* ) # Tag \n\
  1495. | \\# ( <unicode>+ ) # ID \n\
  1496. | \\. ( <unicode>+ ) # ClassName \n\
  1497. | # Attribute \n\
  1498. \\[ \
  1499. \\s* (<unicode1>+) (?: \
  1500. \\s* ([*^$!~|]?=) (?: \
  1501. \\s* (?:\
  1502. ([\"']?)(.*?)\\9 \
  1503. )\
  1504. ) \
  1505. )? \\s* \
  1506. \\](?!\\]) \n\
  1507. | :+ ( <unicode>+ )(?:\
  1508. \\( (?:\
  1509. (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
  1510. ) \\)\
  1511. )?\
  1512. )"
  1513. */
  1514. "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
  1515. .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
  1516. .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
  1517. .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
  1518. );
  1519. function parser(
  1520. rawMatch,
  1521. separator,
  1522. combinator,
  1523. combinatorChildren,
  1524. tagName,
  1525. id,
  1526. className,
  1527. attributeKey,
  1528. attributeOperator,
  1529. attributeQuote,
  1530. attributeValue,
  1531. pseudoMarker,
  1532. pseudoClass,
  1533. pseudoQuote,
  1534. pseudoClassQuotedValue,
  1535. pseudoClassValue
  1536. ){
  1537. if (separator || separatorIndex === -1){
  1538. parsed.expressions[++separatorIndex] = [];
  1539. combinatorIndex = -1;
  1540. if (separator) return '';
  1541. }
  1542. if (combinator || combinatorChildren || combinatorIndex === -1){
  1543. combinator = combinator || ' ';
  1544. var currentSeparator = parsed.expressions[separatorIndex];
  1545. if (reversed && currentSeparator[combinatorIndex])
  1546. currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);
  1547. currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
  1548. }
  1549. var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
  1550. if (tagName){
  1551. currentParsed.tag = tagName.replace(reUnescape, '');
  1552. } else if (id){
  1553. currentParsed.id = id.replace(reUnescape, '');
  1554. } else if (className){
  1555. className = className.replace(reUnescape, '');
  1556. if (!currentParsed.classList) currentParsed.classList = [];
  1557. if (!currentParsed.classes) currentParsed.classes = [];
  1558. currentParsed.classList.push(className);
  1559. currentParsed.classes.push({
  1560. value: className,
  1561. regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
  1562. });
  1563. } else if (pseudoClass){
  1564. pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
  1565. pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;
  1566. if (!currentParsed.pseudos) currentParsed.pseudos = [];
  1567. currentParsed.pseudos.push({
  1568. key: pseudoClass.replace(reUnescape, ''),
  1569. value: pseudoClassValue,
  1570. type: pseudoMarker.length == 1 ? 'class' : 'element'
  1571. });
  1572. } else if (attributeKey){
  1573. attributeKey = attributeKey.replace(reUnescape, '');
  1574. attributeValue = (attributeValue || '').replace(reUnescape, '');
  1575. var test, regexp;
  1576. switch (attributeOperator){
  1577. case '^=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) ); break;
  1578. case '$=' : regexp = new RegExp( escapeRegExp(attributeValue) +'$' ); break;
  1579. case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break;
  1580. case '|=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) +'(-|$)' ); break;
  1581. case '=' : test = function(value){
  1582. return attributeValue == value;
  1583. }; break;
  1584. case '*=' : test = function(value){
  1585. return value && value.indexOf(attributeValue) > -1;
  1586. }; break;
  1587. case '!=' : test = function(value){
  1588. return attributeValue != value;
  1589. }; break;
  1590. default : test = function(value){
  1591. return !!value;
  1592. };
  1593. }
  1594. if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){
  1595. return false;
  1596. };
  1597. if (!test) test = function(value){
  1598. return value && regexp.test(value);
  1599. };
  1600. if (!currentParsed.attributes) currentParsed.attributes = [];
  1601. currentParsed.attributes.push({
  1602. key: attributeKey,
  1603. operator: attributeOperator,
  1604. value: attributeValue,
  1605. test: test
  1606. });
  1607. }
  1608. return '';
  1609. };
  1610. // Slick NS
  1611. var Slick = (this.Slick || {});
  1612. Slick.parse = function(expression){
  1613. return parse(expression);
  1614. };
  1615. Slick.escapeRegExp = escapeRegExp;
  1616. if (!this.Slick) this.Slick = Slick;
  1617. }).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this);
  1618. /*
  1619. ---
  1620. name: Slick.Finder
  1621. description: The new, superfast css selector engine.
  1622. provides: Slick.Finder
  1623. requires: Slick.Parser
  1624. ...
  1625. */
  1626. ;(function(){
  1627. var local = {},
  1628. featuresCache = {},
  1629. toString = Object.prototype.toString;
  1630. // Feature / Bug detection
  1631. local.isNativeCode = function(fn){
  1632. return (/\{\s*\[native code\]\s*\}/).test('' + fn);
  1633. };
  1634. local.isXML = function(document){
  1635. return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||
  1636. (document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
  1637. };
  1638. local.setDocument = function(document){
  1639. // convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
  1640. var nodeType = document.nodeType;
  1641. if (nodeType == 9); // document
  1642. else if (nodeType) document = document.ownerDocument; // node
  1643. else if (document.navigator) document = document.document; // window
  1644. else return;
  1645. // check if it's the old document
  1646. if (this.document === document) return;
  1647. this.document = document;
  1648. // check if we have done feature detection on this document before
  1649. var root = document.documentElement,
  1650. rootUid = this.getUIDXML(root),
  1651. features = featuresCache[rootUid],
  1652. feature;
  1653. if (features){
  1654. for (feature in features){
  1655. this[feature] = features[feature];
  1656. }
  1657. return;
  1658. }
  1659. features = featuresCache[rootUid] = {};
  1660. features.root = root;
  1661. features.isXMLDocument = this.isXML(document);
  1662. features.brokenStarGEBTN
  1663. = features.starSelectsClosedQSA
  1664. = features.idGetsName
  1665. = features.brokenMixedCaseQSA
  1666. = features.brokenGEBCN
  1667. = features.brokenCheckedQSA
  1668. = features.brokenEmptyAttributeQSA
  1669. = features.isHTMLDocument
  1670. = features.nativeMatchesSelector
  1671. = false;
  1672. var starSelectsClosed, starSelectsComments,
  1673. brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
  1674. brokenFormAttributeGetter;
  1675. var selected, id = 'slick_uniqueid';
  1676. var testNode = document.createElement('div');
  1677. var testRoot = document.body || document.getElementsByTagName('body')[0] || root;
  1678. testRoot.appendChild(testNode);
  1679. // on non-HTML documents innerHTML and getElementsById doesnt work properly
  1680. try {
  1681. testNode.innerHTML = '<a id="'+id+'"></a>';
  1682. features.isHTMLDocument = !!document.getElementById(id);
  1683. } catch(e){};
  1684. if (features.isHTMLDocument){
  1685. testNode.style.displa