PageRenderTime 68ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/gc.xml

http://gocomics-stage.googlecode.com/
XML | 1538 lines | 1425 code | 110 blank | 3 comment | 0 complexity | d4c0f7c4304a17e8447d81fc78899817 MD5 | raw file
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Module>
  3. <ModulePrefs title="GoComics from Universal Uclick"
  4. title_url="http://www.gocomics.com"
  5. author="Universal Uclick"
  6. author_email="universaluclick@gmail.com"
  7. description="Get a Laugh each and everyday with the GoComics gadget for iGoogle - giving you access to the
  8. best and most extensive online comics collection ever compiled! It's the only place to get your
  9. favorites like 'Calvin and Hobbes', 'Garfield', 'Foxtrot', 'Doonesbury' and the newer hits like
  10. 'Lio', 'Pooch Cafe', 'The Argyle Sweater' and 'Cul de Sac'. Build your own personal daily comics
  11. page and choose from over 200+ Comic Strips. Share comics with your Friends, Favorite those you
  12. want to see again, and see Comments from other comic fans. Add GoComics to your iGoogle page now
  13. and start laughing!"
  14. screenshot="http://images.gocomics.com/images/google/comics_screenshot.jpg"
  15. thumbnail="http://images.gocomics.com/images/google/gocomics_logo.jpg">
  16. <Require feature="opensocial-0.8"/>
  17. <Require feature="setprefs"/>
  18. <Require feature="views"/>
  19. <Require feature="dynamic-height"/>
  20. <Require feature="minimessage"/>
  21. </ModulePrefs>
  22. <!-- H O M E -->
  23. <Content type="html" view="home,profile"><![CDATA[
  24. <style type='text/css'>
  25. /* http://meyerweb.com/eric/tools/css/reset/
  26. v2.0 | 20110126
  27. License: none (public domain)
  28. */
  29. html, body, div, span, applet, object, iframe,
  30. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  31. a, abbr, acronym, address, big, cite, code,
  32. del, dfn, em, img, ins, kbd, q, s, samp,
  33. small, strike, strong, sub, sup, tt, var,
  34. b, u, i, center,
  35. dl, dt, dd, ol, ul, li,
  36. fieldset, form, label, legend,
  37. table, caption, tbody, tfoot, thead, tr, th, td,
  38. article, aside, canvas, details, embed,
  39. figure, figcaption, footer, header, hgroup,
  40. menu, nav, output, ruby, section, summary,
  41. time, mark, audio, video {
  42. margin: 0;
  43. padding: 0;
  44. border: 0;
  45. font-size: 100%;
  46. font: inherit;
  47. vertical-align: baseline;
  48. }
  49. /* HTML5 display-role reset for older browsers */
  50. article, aside, details, figcaption, figure,
  51. footer, header, hgroup, menu, nav, section {
  52. display: block;
  53. }
  54. body {
  55. line-height: 1;
  56. }
  57. ol, ul {
  58. list-style: none;
  59. }
  60. blockquote, q {
  61. quotes: none;
  62. }
  63. blockquote:before, blockquote:after,
  64. q:before, q:after {
  65. content: '';
  66. content: none;
  67. }
  68. table {
  69. border-collapse: collapse;
  70. border-spacing: 0;
  71. }
  72. body {
  73. color: #474747;
  74. font-family: Helvetica, Arial, Verdana, sans-serif;
  75. font-size: 12px; }
  76. a {
  77. text-decoration: none;
  78. color: #4a91c1; }
  79. a:visited {
  80. color: #4a91c1; }
  81. .button, .big-button, .little-button {
  82. border-radius: 5px;
  83. -webkit-border-radius: 5px;
  84. -moz-border-radius: 5px;
  85. color: #FFF;
  86. font-weight: bold;
  87. text-align: center; }
  88. .button:visited, .big-button:visited, .little-button:visited {
  89. color: #FFF; }
  90. .big-button {
  91. background: #38a3cd;
  92. background: -webkit-gradient(linear, left top, left bottom, from(#8acae1), to(#38a3cd));
  93. background: -moz-linear-gradient(top, #8acae1, #38a3cd);
  94. width: 75px;
  95. display: block;
  96. padding: 6px 10px; }
  97. .big-button:hover {
  98. background: #8acae1;
  99. background: -webkit-gradient(linear, left top, left bottom, from(#38a3cd), to(#8acae1));
  100. background: -moz-linear-gradient(top, #38a3cd, #8acae1); }
  101. .little-button {
  102. background: #777777;
  103. background: -webkit-gradient(linear, left top, left bottom, from(#888888), to(#777777));
  104. background: -moz-linear-gradient(top, #888888, #777777);
  105. display: inline-block;
  106. width: 150px;
  107. padding: 4px 8px; }
  108. .little-button:hover {
  109. background: #888888;
  110. background: -webkit-gradient(linear, left top, left bottom, from(#777777), to(#888888));
  111. background: -moz-linear-gradient(top, #777777, #888888); }
  112. .clear {
  113. clear: both; }
  114. #home-container {
  115. display: block;
  116. width: 400px; }
  117. #home-container ul {
  118. list-style-type: none;
  119. text-align: center;
  120. width: inherit; }
  121. #home-container ul li {
  122. display: inline-block; }
  123. #home-container ul.feature-navigation {
  124. display: table;
  125. padding: 5px 0px;
  126. border-bottom: 1px solid #AAA; }
  127. #home-container ul.feature-navigation li {
  128. text-align: right;
  129. display: table-cell;
  130. padding-right: 10px;
  131. padding-left: 0px; }
  132. #home-container ul.feature-navigation li:first-child {
  133. padding-right: 0px;
  134. padding-left: 10px;
  135. text-align: left; }
  136. #home-container ul.feature-options {
  137. padding: 5px 0; }
  138. #feature {
  139. display: block;
  140. width: 400px; }
  141. #feature h1 {
  142. font-size: 16px;
  143. font-weight: bold;
  144. padding-bottom: 5px; }
  145. #feature h1 span {
  146. font-size: 12px; }
  147. #feature h1 span.date {
  148. float: right;
  149. text-align: right; }
  150. #feature div.feature-image {
  151. margin: 5px auto;
  152. width: 360px;
  153. border: 2px solid #FFF;
  154. padding: 10px;
  155. background: #f2f2f2;
  156. background: -webkit-gradient(linear, left top, left bottom, from(white), to(#f2f2f2));
  157. background: -moz-linear-gradient(top, white, #f2f2f2);
  158. -moz-box-shadow: 0 0 5px 1px #cccccc;
  159. -webkit-box-shadow: 0 0 5px 1px #cccccc;
  160. box-shadow: 0 0 5px 1px #cccccc;
  161. border-radius: 5px;
  162. -webkit-border-radius: 5px;
  163. -moz-border-radius: 5px; }
  164. #feature div.feature-image img {
  165. width: inherit;
  166. cursor: pointer; }
  167. </style>
  168. <div id="home">
  169. <div id="home-container">
  170. <div id="feature"></div>
  171. <ul class="feature-navigation">
  172. <li><a href="#" class="prev little-button">&larr;</a></li>
  173. <li><a href="#" class="next little-button">&rarr;</a></li>
  174. </ul>
  175. <ul class="feature-options">
  176. <li><a href="#" class="pick-comics big-button">Pick Comics</a></li>
  177. <li><a href="#" class="full-size big-button">Full Size</a></li>
  178. </ul>
  179. </div>
  180. </div>
  181. <script id="feature-template" type="text/mustache-tmpl">
  182. <h1>
  183. {{title}}
  184. <span class="byline">by {{author}}</span>
  185. <span class="date">{{display_date}}</span>
  186. </h1>
  187. <div class="feature-image">
  188. <img src="{{image_link}}" alt="{{title}}" />
  189. </div>
  190. </script>
  191. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
  192. <script type="text/javascript">/*
  193. mustache.js — Logic-less templates in JavaScript
  194. See http://mustache.github.com/ for more info.
  195. */
  196. var Mustache = function() {
  197. var Renderer = function() {};
  198. Renderer.prototype = {
  199. otag: "{{",
  200. ctag: "}}",
  201. pragmas: {},
  202. buffer: [],
  203. pragmas_implemented: {
  204. "IMPLICIT-ITERATOR": true
  205. },
  206. context: {},
  207. render: function(template, context, partials, in_recursion) {
  208. // reset buffer & set context
  209. if(!in_recursion) {
  210. this.context = context;
  211. this.buffer = []; // TODO: make this non-lazy
  212. }
  213. // fail fast
  214. if(!this.includes("", template)) {
  215. if(in_recursion) {
  216. return template;
  217. } else {
  218. this.send(template);
  219. return;
  220. }
  221. }
  222. template = this.render_pragmas(template);
  223. var html = this.render_section(template, context, partials);
  224. if(in_recursion) {
  225. return this.render_tags(html, context, partials, in_recursion);
  226. }
  227. this.render_tags(html, context, partials, in_recursion);
  228. },
  229. /*
  230. Sends parsed lines
  231. */
  232. send: function(line) {
  233. if(line != "") {
  234. this.buffer.push(line);
  235. }
  236. },
  237. /*
  238. Looks for %PRAGMAS
  239. */
  240. render_pragmas: function(template) {
  241. // no pragmas
  242. if(!this.includes("%", template)) {
  243. return template;
  244. }
  245. var that = this;
  246. var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
  247. this.ctag);
  248. return template.replace(regex, function(match, pragma, options) {
  249. if(!that.pragmas_implemented[pragma]) {
  250. throw({message:
  251. "This implementation of mustache doesn't understand the '" +
  252. pragma + "' pragma"});
  253. }
  254. that.pragmas[pragma] = {};
  255. if(options) {
  256. var opts = options.split("=");
  257. that.pragmas[pragma][opts[0]] = opts[1];
  258. }
  259. return "";
  260. // ignore unknown pragmas silently
  261. });
  262. },
  263. /*
  264. Tries to find a partial in the curent scope and render it
  265. */
  266. render_partial: function(name, context, partials) {
  267. name = this.trim(name);
  268. if(!partials || partials[name] === undefined) {
  269. throw({message: "unknown_partial '" + name + "'"});
  270. }
  271. if(typeof(context[name]) != "object") {
  272. return this.render(partials[name], context, partials, true);
  273. }
  274. return this.render(partials[name], context[name], partials, true);
  275. },
  276. /*
  277. Renders inverted (^) and normal (#) sections
  278. */
  279. render_section: function(template, context, partials) {
  280. if(!this.includes("#", template) && !this.includes("^", template)) {
  281. return template;
  282. }
  283. var that = this;
  284. // CSW - Added "+?" so it finds the tighest bound, not the widest
  285. var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
  286. "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
  287. "\\s*", "mg");
  288. // for each {{#foo}}{{/foo}} section do...
  289. return template.replace(regex, function(match, type, name, content) {
  290. var value = that.find(name, context);
  291. if(type == "^") { // inverted section
  292. if(!value || that.is_array(value) && value.length === 0) {
  293. // false or empty list, render it
  294. return that.render(content, context, partials, true);
  295. } else {
  296. return "";
  297. }
  298. } else if(type == "#") { // normal section
  299. if(that.is_array(value)) { // Enumerable, Let's loop!
  300. return that.map(value, function(row) {
  301. return that.render(content, that.create_context(row),
  302. partials, true);
  303. }).join("");
  304. } else if(that.is_object(value)) { // Object, Use it as subcontext!
  305. return that.render(content, that.create_context(value),
  306. partials, true);
  307. } else if(typeof value === "function") {
  308. // higher order section
  309. return value.call(context, content, function(text) {
  310. return that.render(text, context, partials, true);
  311. });
  312. } else if(value) { // boolean section
  313. return that.render(content, context, partials, true);
  314. } else {
  315. return "";
  316. }
  317. }
  318. });
  319. },
  320. /*
  321. Replace {{foo}} and friends with values from our view
  322. */
  323. render_tags: function(template, context, partials, in_recursion) {
  324. // tit for tat
  325. var that = this;
  326. var new_regex = function() {
  327. return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
  328. that.ctag + "+", "g");
  329. };
  330. var regex = new_regex();
  331. var tag_replace_callback = function(match, operator, name) {
  332. switch(operator) {
  333. case "!": // ignore comments
  334. return "";
  335. case "=": // set new delimiters, rebuild the replace regexp
  336. that.set_delimiters(name);
  337. regex = new_regex();
  338. return "";
  339. case ">": // render partial
  340. return that.render_partial(name, context, partials);
  341. case "{": // the triple mustache is unescaped
  342. return that.find(name, context);
  343. default: // escape the value
  344. return that.escape(that.find(name, context));
  345. }
  346. };
  347. var lines = template.split("\n");
  348. for(var i = 0; i < lines.length; i++) {
  349. lines[i] = lines[i].replace(regex, tag_replace_callback, this);
  350. if(!in_recursion) {
  351. this.send(lines[i]);
  352. }
  353. }
  354. if(in_recursion) {
  355. return lines.join("\n");
  356. }
  357. },
  358. set_delimiters: function(delimiters) {
  359. var dels = delimiters.split(" ");
  360. this.otag = this.escape_regex(dels[0]);
  361. this.ctag = this.escape_regex(dels[1]);
  362. },
  363. escape_regex: function(text) {
  364. // thank you Simon Willison
  365. if(!arguments.callee.sRE) {
  366. var specials = [
  367. '/', '.', '*', '+', '?', '|',
  368. '(', ')', '[', ']', '{', '}', '\\'
  369. ];
  370. arguments.callee.sRE = new RegExp(
  371. '(\\' + specials.join('|\\') + ')', 'g'
  372. );
  373. }
  374. return text.replace(arguments.callee.sRE, '\\$1');
  375. },
  376. /*
  377. find `name` in current `context`. That is find me a value
  378. from the view object
  379. */
  380. find: function(name, context) {
  381. name = this.trim(name);
  382. // Checks whether a value is thruthy or false or 0
  383. function is_kinda_truthy(bool) {
  384. return bool === false || bool === 0 || bool;
  385. }
  386. var value;
  387. if(is_kinda_truthy(context[name])) {
  388. value = context[name];
  389. } else if(is_kinda_truthy(this.context[name])) {
  390. value = this.context[name];
  391. }
  392. if(typeof value === "function") {
  393. return value.apply(context);
  394. }
  395. if(value !== undefined) {
  396. return value;
  397. }
  398. // silently ignore unkown variables
  399. return "";
  400. },
  401. // Utility methods
  402. /* includes tag */
  403. includes: function(needle, haystack) {
  404. return haystack.indexOf(this.otag + needle) != -1;
  405. },
  406. /*
  407. Does away with nasty characters
  408. */
  409. escape: function(s) {
  410. s = String(s === null ? "" : s);
  411. return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) {
  412. switch(s) {
  413. case "&": return "&amp;";
  414. case "\\": return "\\\\";
  415. case '"': return '&quot;';
  416. case "'": return '&#39;';
  417. case "<": return "&lt;";
  418. case ">": return "&gt;";
  419. default: return s;
  420. }
  421. });
  422. },
  423. // by @langalex, support for arrays of strings
  424. create_context: function(_context) {
  425. if(this.is_object(_context)) {
  426. return _context;
  427. } else {
  428. var iterator = ".";
  429. if(this.pragmas["IMPLICIT-ITERATOR"]) {
  430. iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
  431. }
  432. var ctx = {};
  433. ctx[iterator] = _context;
  434. return ctx;
  435. }
  436. },
  437. is_object: function(a) {
  438. return a && typeof a == "object";
  439. },
  440. is_array: function(a) {
  441. return Object.prototype.toString.call(a) === '[object Array]';
  442. },
  443. /*
  444. Gets rid of leading and trailing whitespace
  445. */
  446. trim: function(s) {
  447. return s.replace(/^\s*|\s*$/g, "");
  448. },
  449. /*
  450. Why, why, why? Because IE. Cry, cry cry.
  451. */
  452. map: function(array, fn) {
  453. if (typeof array.map == "function") {
  454. return array.map(fn);
  455. } else {
  456. var r = [];
  457. var l = array.length;
  458. for(var i = 0; i < l; i++) {
  459. r.push(fn(array[i]));
  460. }
  461. return r;
  462. }
  463. }
  464. };
  465. return({
  466. name: "mustache.js",
  467. version: "0.3.1-dev",
  468. /*
  469. Turns a template and view into HTML
  470. */
  471. to_html: function(template, view, partials, send_fun) {
  472. var renderer = new Renderer();
  473. if(send_fun) {
  474. renderer.send = send_fun;
  475. }
  476. renderer.render(template, view, partials);
  477. if(!send_fun) {
  478. return renderer.buffer.join("\n");
  479. }
  480. }
  481. });
  482. }();
  483. </script>
  484. <script type="text/javascript">// Underscore.js 1.1.6
  485. // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
  486. // Underscore is freely distributable under the MIT license.
  487. // Portions of Underscore are inspired or borrowed from Prototype,
  488. // Oliver Steele's Functional, and John Resig's Micro-Templating.
  489. // For all details and documentation:
  490. // http://documentcloud.github.com/underscore
  491. (function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.6";var h=b.each=b.forEach=function(a,c,d){if(a!=null)if(s&&a.forEach===s)a.forEach(c,d);else if(b.isNumber(a.length))for(var e=
  492. 0,k=a.length;e<k;e++){if(c.call(d,a[e],e,a)===m)break}else for(e in a)if(l.call(a,e)&&c.call(d,a[e],e,a)===m)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(c,b);h(a,function(a,g,G){e[e.length]=c.call(b,a,g,G)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var k=d!==void 0;a==null&&(a=[]);if(u&&a.reduce===u)return e&&(c=b.bind(c,e)),k?a.reduce(c,d):a.reduce(c);h(a,function(a,b,f){!k&&b===0?(d=a,k=!0):d=c.call(e,d,a,b,f)});if(!k)throw new TypeError("Reduce of empty array with no initial value");
  493. return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(v&&a.reduceRight===v)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;A(a,function(a,g,f){if(c.call(b,a,g,f))return e=a,!0});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.filter===w)return a.filter(c,b);h(a,function(a,g,f){c.call(b,a,g,f)&&(e[e.length]=a)});return e};
  494. b.reject=function(a,c,b){var e=[];if(a==null)return e;h(a,function(a,g,f){c.call(b,a,g,f)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=!0;if(a==null)return e;if(x&&a.every===x)return a.every(c,b);h(a,function(a,g,f){if(!(e=e&&c.call(b,a,g,f)))return m});return e};var A=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=!1;if(a==null)return e;if(y&&a.some===y)return a.some(c,d);h(a,function(a,b,f){if(e=c.call(d,a,b,f))return m});return e};b.include=b.contains=function(a,c){var b=
  495. !1;if(a==null)return b;if(o&&a.indexOf===o)return a.indexOf(c)!=-1;A(a,function(a){if(b=a===c)return!0});return b};b.invoke=function(a,c){var d=f.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,
  496. c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,f){return{value:a,criteria:c.call(d,a,b,f)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=
  497. function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return f.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?f.call(a,0,b):a[0]};b.rest=b.tail=function(a,b,d){return f.call(a,b==null||d?1:b)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a){return b.reduce(a,function(a,d){if(b.isArray(d))return a.concat(b.flatten(d));
  498. a[a.length]=d;return a},[])};b.without=function(a){var c=f.call(arguments,1);return b.filter(a,function(a){return!b.include(c,a)})};b.uniq=b.unique=function(a,c){return b.reduce(a,function(a,e,f){if(0==f||(c===!0?b.last(a)!=e:!b.include(a,e)))a[a.length]=e;return a},[])};b.intersect=function(a){var c=f.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.zip=function(){for(var a=f.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),
  499. e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(o&&a.indexOf===o)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(z&&a.lastIndexOf===z)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);d=arguments[2]||1;for(var e=Math.max(Math.ceil((b-a)/
  500. d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};b.bind=function(a,b){if(a.bind===q&&q)return q.apply(a,f.call(arguments,1));var d=f.call(arguments,2);return function(){return a.apply(b,d.concat(f.call(arguments)))}};b.bindAll=function(a){var c=f.call(arguments,1);c.length==0&&(c=b.functions(a));h(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return l.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
  501. function(a,b){var d=f.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(f.call(arguments,1)))};var B=function(a,b,d){var e;return function(){var f=this,g=arguments,h=function(){e=null;a.apply(f,g)};d&&clearTimeout(e);if(d||!e)e=setTimeout(h,b)}};b.throttle=function(a,b){return B(a,b,!1)};b.debounce=function(a,b){return B(a,b,!0)};b.once=function(a){var b=!1,d;return function(){if(b)return d;b=!0;return d=a.apply(this,arguments)}};
  502. b.wrap=function(a,b){return function(){var d=[a].concat(f.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=f.call(arguments);return function(){for(var b=f.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=F||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)l.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,
  503. b.identity)};b.functions=b.methods=function(a){return b.filter(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a){h(f.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){h(f.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,c){if(a===c)return!0;var d=typeof a;if(d!=
  504. typeof c)return!1;if(a==c)return!0;if(!a&&c||a&&!c)return!1;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return!1;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return!1;if(a.length&&a.length!==c.length)return!1;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return!1;
  505. for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return!1;return!0};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(l.call(a,c))return!1;return!0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=n||function(a){return E.call(a)==="[object Array]"};b.isArguments=function(a){return!(!a||!l.call(a,"callee"))};b.isFunction=function(a){return!(!a||!a.constructor||!a.call||!a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};
  506. b.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===!0||a===!1};b.isDate=function(a){return!(!a||!a.getTimezoneOffset||!a.setUTCFullYear)};b.isRegExp=function(a){return!(!a||!a.test||!a.exec||!(a.ignoreCase||a.ignoreCase===!1))};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){p._=C;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=
  507. 0;e<a;e++)b.call(d,e)};b.mixin=function(a){h(b.functions(a),function(c){H(c,b[c]=a[c])})};var I=0;b.uniqueId=function(a){var b=I++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||
  508. null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return c?d(c):d};var j=function(a){this._wrapped=a};b.prototype=j.prototype;var r=function(a,c){return c?b(a).chain():a},H=function(a,c){j.prototype[a]=function(){var a=f.call(arguments);D.call(a,this._wrapped);return r(c.apply(b,a),this._chain)}};b.mixin(b);h(["pop","push","reverse","shift","sort",
  509. "splice","unshift"],function(a){var b=i[a];j.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});h(["concat","join","slice"],function(a){var b=i[a];j.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});j.prototype.chain=function(){this._chain=!0;return this};j.prototype.value=function(){return this._wrapped}})();
  510. </script>
  511. <script type="text/javascript">// Backbone.js 0.3.3
  512. // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
  513. // Backbone may be freely distributed under the MIT license.
  514. // For all details and documentation:
  515. // http://documentcloud.github.com/backbone
  516. (function(){var e;e=typeof exports!=="undefined"?exports:this.Backbone={};e.VERSION="0.3.3";var f=this._;if(!f&&typeof require!=="undefined")f=require("underscore")._;var h=this.jQuery||this.Zepto;e.emulateHTTP=false;e.emulateJSON=false;e.Events={bind:function(a,b){this._callbacks||(this._callbacks={});(this._callbacks[a]||(this._callbacks[a]=[])).push(b);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=0,g=c.length;d<g;d++)if(b===c[d]){c.splice(d,
  517. 1);break}}else c[a]=[]}else this._callbacks={};return this},trigger:function(a){var b,c,d,g;if(!(c=this._callbacks))return this;if(b=c[a]){d=0;for(g=b.length;d<g;d++)b[d].apply(this,Array.prototype.slice.call(arguments,1))}if(b=c.all){d=0;for(g=b.length;d<g;d++)b[d].apply(this,arguments)}return this}};e.Model=function(a,b){a||(a={});if(this.defaults)a=f.extend({},this.defaults,a);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.set(a,{silent:true});this._previousAttributes=
  518. f.clone(this.attributes);if(b&&b.collection)this.collection=b.collection;this.initialize(a,b)};f.extend(e.Model.prototype,e.Events,{_previousAttributes:null,_changed:false,initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.attributes[a];return this._escapedAttributes[a]=(b==null?"":b).replace(/&(?!\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,
  519. "&quot;")},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes,d=this._escapedAttributes;if(!b.silent&&this.validate&&!this._performValidation(a,b))return false;if("id"in a)this.id=a.id;for(var g in a){var i=a[g];if(!f.isEqual(c[g],i)){c[g]=i;delete d[g];if(!b.silent){this._changed=true;this.trigger("change:"+g,this,i,b)}}}!b.silent&&this._changed&&this.change(b);return this},unset:function(a,b){b||(b={});var c={};c[a]=void 0;if(!b.silent&&this.validate&&
  520. !this._performValidation(c,b))return false;delete this.attributes[a];delete this._escapedAttributes[a];if(!b.silent){this._changed=true;this.trigger("change:"+a,this,void 0,b);this.change(b)}return this},clear:function(a){a||(a={});var b=this.attributes,c={};for(attr in b)c[attr]=void 0;if(!a.silent&&this.validate&&!this._performValidation(c,a))return false;this.attributes={};this._escapedAttributes={};if(!a.silent){this._changed=true;for(attr in b)this.trigger("change:"+attr,this,void 0,a);this.change(a)}return this},
  521. fetch:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("read",this,function(d){if(!b.set(b.parse(d),a))return false;a.success&&a.success(b,d)},c);return this},save:function(a,b){b||(b={});if(a&&!this.set(a,b))return false;var c=this,d=j(b.error,c,b),g=this.isNew()?"create":"update";(this.sync||e.sync)(g,this,function(i){if(!c.set(c.parse(i),b))return false;b.success&&b.success(c,i)},d);return this},destroy:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("delete",
  522. this,function(d){b.collection&&b.collection.remove(b);a.success&&a.success(b,d)},c);return this},url:function(){var a=k(this.collection);if(this.isNew())return a;return a+(a.charAt(a.length-1)=="/"?"":"/")+this.id},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return!this.id},change:function(a){this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);this._changed=false},hasChanged:function(a){if(a)return this._previousAttributes[a]!=
  523. this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=false,d;for(d in a)if(!f.isEqual(b[d],a[d])){c=c||{};c[d]=a[d]}return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},_performValidation:function(a,b){var c=this.validate(a);if(c){b.error?b.error(this,c):this.trigger("error",this,c,b);return false}return true}});
  524. e.Collection=function(a,b){b||(b={});if(b.comparator){this.comparator=b.comparator;delete b.comparator}this._boundOnModelEvent=f.bind(this._onModelEvent,this);this._reset();a&&this.refresh(a,{silent:true});this.initialize(a,b)};f.extend(e.Collection.prototype,e.Events,{model:e.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)this._add(a[c],b);else this._add(a,b);return this},remove:function(a,
  525. b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)this._remove(a[c],b);else this._remove(a,b);return this},get:function(a){if(a==null)return null;return this._byId[a.id!=null?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");this.models=this.sortBy(this.comparator);a.silent||this.trigger("refresh",this,a);return this},pluck:function(a){return f.map(this.models,
  526. function(b){return b.get(a)})},refresh:function(a,b){a||(a=[]);b||(b={});this._reset();this.add(a,{silent:true});b.silent||this.trigger("refresh",this,b);return this},fetch:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("read",this,function(d){b.refresh(b.parse(d));a.success&&a.success(b,d)},c);return this},create:function(a,b){var c=this;b||(b={});if(a instanceof e.Model)a.collection=c;else a=new this.model(a,{collection:c});return a.save(null,{success:function(d,g){c.add(d);
  527. b.success&&b.success(d,g)},error:b.error})},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_add:function(a,b){b||(b={});a instanceof e.Model||(a=new this.model(a,{collection:this}));var c=this.getByCid(a);if(c)throw Error(["Can't add the same model to a set twice",c.id]);this._byId[a.id]=a;this._byCid[a.cid]=a;a.collection=this;this.models.splice(this.comparator?this.sortedIndex(a,this.comparator):
  528. this.length,0,a);a.bind("all",this._boundOnModelEvent);this.length++;b.silent||a.trigger("add",a,this,b);return a},_remove:function(a,b){b||(b={});a=this.getByCid(a)||this.get(a);if(!a)return null;delete this._byId[a.id];delete this._byCid[a.cid];delete a.collection;this.models.splice(this.indexOf(a),1);this.length--;b.silent||a.trigger("remove",a,this,b);a.unbind("all",this._boundOnModelEvent);return a},_onModelEvent:function(a,b){if(a==="change:id"){delete this._byId[b.previous("id")];this._byId[b.id]=
  529. b}this.trigger.apply(this,arguments)}});f.each(["forEach","each","map","reduce","reduceRight","find","detect","filter","select","reject","every","all","some","any","include","invoke","max","min","sortBy","sortedIndex","toArray","size","first","rest","last","without","indexOf","lastIndexOf","isEmpty"],function(a){e.Collection.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});e.Controller=function(a){a||(a={});if(a.routes)this.routes=a.routes;this._bindRoutes();
  530. this.initialize(a)};var o=/:([\w\d]+)/g,p=/\*([\w\d]+)/g;f.extend(e.Controller.prototype,e.Events,{initialize:function(){},route:function(a,b,c){e.history||(e.history=new e.History);f.isRegExp(a)||(a=this._routeToRegExp(a));e.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d))},this))},saveLocation:function(a){e.history.saveLocation(a)},_bindRoutes:function(){if(this.routes)for(var a in this.routes){var b=this.routes[a];
  531. this.route(a,b,this[b])}},_routeToRegExp:function(a){a=a.replace(o,"([^/]*)").replace(p,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});e.History=function(){this.handlers=[];this.fragment=this.getFragment();f.bindAll(this,"checkUrl")};var l=/^#*/;f.extend(e.History.prototype,{interval:50,getFragment:function(a){return(a||window.location).hash.replace(l,"")},start:function(){var a=document.documentMode;if(a=h.browser.msie&&(!a||a<=7))this.iframe=h('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow;
  532. "onhashchange"in window&&!a?h(window).bind("hashchange",this.checkUrl):setInterval(this.checkUrl,this.interval);return this.loadUrl()},route:function(a,b){this.handlers.push({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();if(a==this.fragment&&this.iframe)a=this.getFragment(this.iframe.location);if(a==this.fragment||a==decodeURIComponent(this.fragment))return false;if(this.iframe)window.location.hash=this.iframe.location.hash=a;this.loadUrl()},loadUrl:function(){var a=this.fragment=
  533. this.getFragment();return f.any(this.handlers,function(b){if(b.route.test(a)){b.callback(a);return true}})},saveLocation:function(a){a=(a||"").replace(l,"");if(this.fragment!=a){window.location.hash=this.fragment=a;if(this.iframe&&a!=this.getFragment(this.iframe.location)){this.iframe.document.open().close();this.iframe.location.hash=a}}}});e.View=function(a){this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize(a)};var q=/^(\w+)\s*(.*)$/;f.extend(e.View.prototype,e.Events,
  534. {tagName:"div",$:function(a){return h(a,this.el)},initialize:function(){},render:function(){return this},remove:function(){h(this.el).remove();return this},make:function(a,b,c){a=document.createElement(a);b&&h(a).attr(b);c&&h(a).html(c);return a},delegateEvents:function(a){if(a||(a=this.events)){h(this.el).unbind();for(var b in a){var c=a[b],d=b.match(q),g=d[1];d=d[2];c=f.bind(this[c],this);d===""?h(this.el).bind(g,c):h(this.el).delegate(d,g,c)}}},_configure:function(a){if(this.options)a=f.extend({},
  535. this.options,a);if(a.model)this.model=a.model;if(a.collection)this.collection=a.collection;if(a.el)this.el=a.el;if(a.id)this.id=a.id;if(a.className)this.className=a.className;if(a.tagName)this.tagName=a.tagName;this.options=a},_ensureElement:function(){if(!this.el){var a={};if(this.id)a.id=this.id;if(this.className)a["class"]=this.className;this.el=this.make(this.tagName,a)}}});var m=function(a,b){var c=r(this,a,b);c.extend=m;return c};e.Model.extend=e.Collection.extend=e.Controller.extend=e.View.extend=
  536. m;var s={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};e.sync=function(a,b,c,d){var g=s[a];a=a==="create"||a==="update"?JSON.stringify(b.toJSON()):null;b={url:k(b),type:g,contentType:"application/json",data:a,dataType:"json",processData:false,success:c,error:d};if(e.emulateJSON){b.contentType="application/x-www-form-urlencoded";b.processData=true;b.data=a?{model:a}:{}}if(e.emulateHTTP)if(g==="PUT"||g==="DELETE"){if(e.emulateJSON)b.data._method=g;b.type="POST";b.beforeSend=function(i){i.setRequestHeader("X-HTTP-Method-Override",
  537. g)}}h.ajax(b)};var n=function(){},r=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};n.prototype=a.prototype;d.prototype=new n;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},k=function(a){if(!(a&&a.url))throw Error("A 'url' property or function must be specified");return f.isFunction(a.url)?a.url():a.url},j=function(a,b,c){return function(d){a?a(b,d):b.trigger("error",b,d,c)}}})();
  538. </script>
  539. <script type="text/javascript">var GLOBALS, adjustHeight, makeDataRequest, prefs, slugify;
  540. prefs = new gadgets.Prefs();
  541. GLOBALS = {
  542. rootUrl: "http://gocomics.com"
  543. };
  544. GLOBALS.feedUrl = "" + GLOBALS.rootUrl + "/feeds";
  545. GLOBALS.featureUrl = "" + GLOBALS.feedUrl + "/recent_item/";
  546. GLOBALS.featureListUrl = "" + GLOBALS.feedUrl + "/features?min=true&category=comic";
  547. GLOBALS.navigation = {
  548. myComics: {
  549. title: 'My Comics',
  550. slug: 'MyComics',
  551. featureGroups: [
  552. {
  553. title: 'My Comics',
  554. slug: 'mycomics',
  555. ids: [],
  556. data: []
  557. }
  558. ]
  559. },
  560. favorites: {
  561. title: 'Favorites',
  562. slug: 'Favorites',
  563. featureGroups: [
  564. {
  565. title: 'My Favorites',
  566. slug: 'myfavorites',
  567. ids: [],
  568. data: []
  569. }, {
  570. title: "Friends' Favorites",
  571. slug: 'friendsfavorites',
  572. ids: [],
  573. data: []
  574. }
  575. ]
  576. },
  577. allComics: {
  578. title: 'All Comics',
  579. slug: 'AllComics',
  580. featureGroups: [
  581. {
  582. title: 'Popular',
  583. slug: 'popular',
  584. ids: [],
  585. data: []
  586. }, {
  587. title: "A-Z",
  588. slug: 'atoz',
  589. ids: [],
  590. data: []
  591. }
  592. ]
  593. }
  594. };
  595. adjustHeight = function() {
  596. return gadgets.window.adjustHeight();
  597. };
  598. makeDataRequest = function(url, callback) {
  599. return gadgets.io.makeRequest(url, function(obj) {
  600. if (!obj || obj.rc !== 200) {
  601. console.log('Failed to get data.');
  602. }
  603. return callback(obj.data);
  604. });
  605. };
  606. slugify = function(str) {
  607. var from, i, to, _ref;
  608. str = str.replace(/^\s+|\s+$/g, '').toLowerCase();
  609. from = "ŕáäâčéëęěíďîňóöôůúüűńçˇ/_,:;";
  610. to = "aaaaeeeeiiiioooouuuunc------";
  611. for (i = 0, _ref = from.length; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
  612. str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
  613. }
  614. return str.replace(/[^a-z0-9 -]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-');
  615. };</script>
  616. <script type="text/javascript">var Feature, FeatureList, HomeView, init;
  617. Feature = Backbone.Model.extend({
  618. BASE_URL: GLOBALS.featureUrl,
  619. url: function() {
  620. return this.BASE_URL + this.attributes.id;
  621. }
  622. });
  623. FeatureList = Backbone.Collection.extend({
  624. BASE_URL: GLOBALS.featureListUrl,
  625. model: Feature,
  626. url: function() {
  627. return this.BASE_URL;
  628. }
  629. });
  630. HomeView = Backbone.View.extend({
  631. el: $('#home-container'),
  632. template: $('#feature-template').html(),
  633. _features: null,
  634. _currentFeature: null,
  635. _previousFeature: null,
  636. _nextFeature: null,
  637. _index: 0,
  638. _supportedViews: null,
  639. events: {
  640. 'click .pick-comics': 'pickComics',
  641. 'click .full-size': 'fullSize',
  642. 'click .feature-image img': 'fullSize',
  643. 'click .prev': 'previous',
  644. 'click .next': 'next'
  645. },
  646. initialize: function() {
  647. this.collection = new FeatureList(_.detect(GLOBALS.navigation.myComics.featureGroups, function(g) {
  648. return g.slug === 'mycomics';
  649. }).data);
  650. this.setFeature(this._index);
  651. this._supportedViews = gadgets.views.getSupportedViews();
  652. return this;
  653. },
  654. render: function() {
  655. $('#feature').html(Mustache.to_html(this.template, this._currentFeature.toJSON()));
  656. $('.prev').html("&larr; " + this._previousFeature.attributes.title);
  657. $('.next').html("" + this._nextFeature.attributes.title + " &rarr;");
  658. adjustHeight();
  659. return this;
  660. },
  661. up: function(i) {
  662. if (i + 1 > this.collection.length - 1) {
  663. return 0;
  664. } else {
  665. return i + 1;
  666. }
  667. },
  668. down: function(i) {
  669. if (i - 1 < 0) {
  670. return this.collection.length - 1;
  671. } else {
  672. return i - 1;
  673. }
  674. },
  675. cycle: function(increment) {
  676. this._index = increment ? this.up(this._index) : this.down(this._index);
  677. return this.setFeature(this._index);
  678. },
  679. setFeature: function(i) {
  680. this._currentFeature = this.collection.at(i);
  681. this._previousFeature = this.collection.at(this.down(i));
  682. this._nextFeature = this.collection.at(this.up(i));
  683. return this.render();
  684. },
  685. rockTheCanvasView: function(isEditMode) {
  686. var params;
  687. params = {
  688. 'featureId': this._currentFeature.attributes.feature_id,
  689. 'isEditMode': isEditMode
  690. };
  691. return gadgets.views.requestNavigateTo(this._supportedViews.canvas, params);
  692. },
  693. pickComics: function(e) {
  694. e.preventDefault();
  695. return this.rockTheCanvasView(true);
  696. },
  697. fullSize: function(e) {
  698. e.preventDefault();
  699. return this.rockTheCanvasView(false);
  700. },
  701. previous: function(e) {
  702. e.preventDefault();
  703. return this.cycle(false);
  704. },
  705. next: function(e) {
  706. e.preventDefault();
  707. return this.cycle(true);
  708. }
  709. });
  710. init = function() {
  711. var featureGroup, initialize;
  712. featureGroup = _.detect(GLOBALS.navigation.myComics.featureGroups, function(g) {
  713. return g.slug === 'mycomics';
  714. });
  715. if (prefs.getArray(featureGroup.slug).length <= 0) {
  716. featureGroup.ids = [609, 9, 32];
  717. } else {
  718. featureGroup.ids = prefs.getArray(featureGroup.slug);
  719. }
  720. initialize = _.after(featureGroup.ids.length, function() {
  721. return window.View = new HomeView;
  722. });
  723. _(featureGroup.ids).each(function(id) {
  724. return makeDataRequest("" + GLOBALS.featureUrl + id, function(obj) {
  725. featureGroup.data.push(JSON.parse(obj));
  726. return initialize();
  727. });
  728. });
  729. return this;
  730. };
  731. gadgets.util.registerOnLoadHandler(init);</script>
  732. ]]>
  733. </Content>
  734. <!-- C A N V A S -->
  735. <Content type="html" view="canvas"><![CDATA[
  736. <style type='text/css'>
  737. /* http://meyerweb.com/eric/tools/css/reset/
  738. v2.0 | 20110126
  739. License: none (public domain)
  740. */
  741. html, body, div, span, applet, object, iframe,
  742. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  743. a, abbr, acronym, address, big, cite, code,
  744. del, dfn, em, img, ins, kbd, q, s, samp,
  745. small, strike, strong, sub, sup, tt, var,
  746. b, u, i, center,
  747. dl, dt, dd, ol, ul, li,
  748. fieldset, form, label, legend,
  749. table, caption, tbody, tfoot, thead, tr, th, td,
  750. article, aside, canvas, details, embed,
  751. figure, figcaption, footer, header, hgroup,
  752. menu, nav, output, ruby, section, summary,
  753. time, mark, audio, video {
  754. margin: 0;
  755. padding: 0;
  756. border: 0;
  757. font-size: 100%;
  758. font: inherit;
  759. vertical-align: baseline;
  760. }
  761. /* HTML5 display-role reset for older browsers */
  762. article, aside, details, figcaption, figure,
  763. footer, header, hgroup, menu, nav, section {
  764. display: block;
  765. }
  766. body {
  767. line-height: 1;
  768. }
  769. ol, ul {
  770. list-style: none;
  771. }
  772. blockquote, q {
  773. quotes: none;
  774. }
  775. blockquote:before, blockquote:after,
  776. q:before, q:after {
  777. content: '';
  778. content: none;
  779. }
  780. table {
  781. border-collapse: collapse;
  782. border-spacing: 0;
  783. }
  784. body {
  785. color: #474747;
  786. font-family: Helvetica, Arial, Verdana, sans-serif;
  787. font-size: 12px; }
  788. a {
  789. text-decoration: none;
  790. color: #4a91c1; }
  791. a:visited {
  792. color: #4a91c1; }
  793. .button, .big-button, .little-button {
  794. border-radius: 5px;
  795. -webkit-border-radius: 5px;
  796. -moz-border-radius: 5px;
  797. color: #FFF;
  798. font-weight: bold;
  799. text-align: center; }
  800. .button:visited, .big-button:visited, .little-button:visited {
  801. color: #FFF; }
  802. .big-button {
  803. background: #38a3cd;
  804. background: -webkit-gradient(linear, left top, left bottom, from(#8acae1), to(#38a3cd));
  805. background: -moz-linear-gradient(top, #8acae1, #38a3cd);
  806. width: 75px;
  807. display: block;
  808. padding: 6px 10px; }
  809. .big-button:hover {
  810. background: #8acae1;
  811. background: -webkit-gradient(linear, left top, left bottom, from(#38a3cd), to(#8acae1));
  812. background: -moz-linear-gradient(top, #38a3cd, #8acae1); }
  813. .little-button {
  814. background: #777777;
  815. background: -webkit-gradient(linear, left top, left bottom, from(#888888), to(#777777));
  816. background: -moz-linear-gradient(top, #888888, #777777);
  817. display: inline-block;
  818. width: 150px;
  819. padding: 4px 8px; }
  820. .little-button:hover {
  821. background: #888888;
  822. background: -webkit-gradient(linear, left top, left bottom, from(#777777), to(#888888));
  823. background: -moz-linear-gradient(top, #777777, #888888); }
  824. .clear {
  825. clear: both; }
  826. #canvas {
  827. width: 950px;
  828. background: #FFF;
  829. margin-left: 5px;
  830. margin-top: 5px; }
  831. #canvas-container {
  832. background: #FFF; }
  833. #tab-navigation {
  834. color: #FFF;
  835. width: inherit; }
  836. #tab-navigation ul {
  837. background: #5e9100;
  838. background: -webkit-gradient(linear, left top, left bottom, from(#78ae07), to(#5e9100));
  839. background: -moz-linear-gradient(top, #78ae07, #5e9100);
  840. border-radius: 5px;
  841. -webkit-border-radius: 5px;
  842. -moz-border-radius: 5px;
  843. display: table;
  844. width: 300px; }
  845. #tab-navigation ul li {
  846. display: table-cell;
  847. border-right: 1px solid #629000;
  848. border-left: 1px solid #8CB94A; }
  849. #tab-navigation ul li a {
  850. font-weight: bold;
  851. color: inherit;
  852. text-align: center;
  853. display: block;
  854. padding: 12px 12px 20px 12px; }
  855. #tab-navigation ul li a:hover, #tab-navigation ul li a.selected {
  856. background: #85b334;
  857. background: -webkit-gradient(linear, left top, left bottom, from(#78ae07), to(#85b334));
  858. background: -moz-linear-gradient(top, #78ae07, #85b334); }
  859. #tab-navigation ul li a.selected {
  860. cursor: inherit; }
  861. #tab-navigation ul li #myComics:hover, #tab-navigation ul li #myComics.selected {
  862. border-top-left-radius: 5px;
  863. border-bottom-left-radius: 5px;
  864. -webkit-border-top-left-radius: 5px;
  865. -webkit-border-bottom-left-radius: 5px;
  866. -moz-border-radius-topleft: 5px;
  867. -moz-border-radius-bottomleft: 5px; }
  868. #tab-navigation ul li #allComics:hover, #tab-navigation ul li #allComics.selected {
  869. border-top-right-radius: 5px;
  870. border-bottom-right-radius: 5px;
  871. -webkit-border-top-right-radius: 5px;
  872. -webkit-border-bottom-right-radius: 5px;
  873. -moz-border-radius-topright: 5px;
  874. -moz-border-radius-bottomright: 5px; }
  875. #tab-navigation ul li:first-child {
  876. border-left: none; }
  877. #tab-navigation ul li.last-li {
  878. border-right: none; }
  879. #content {
  880. -moz-box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.3);
  881. -webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.3);
  882. box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.3);
  883. border-radius: 5px;
  884. -webkit-border-radius: 5px;
  885. -moz-border-radius: 5px;
  886. border-top: 4px solid #71A9CC;
  887. position: relative;
  888. background: #FFF;
  889. top: -10px;
  890. padding-left: 10px;
  891. padding-top: 10px;
  892. padding-bottom: 10px; }
  893. #feature {
  894. background: white;
  895. background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(white));
  896. background: -moz-linear-gradient(top, #f2f2f2, white);
  897. -moz-box-shadow: 0 0 5px 2px #bbbbbb;
  898. -webkit-box-shadow: 0 0 5px 2px #bbbbbb;
  899. box-shadow: 0 0 5px 2px #bbbbbb;
  900. border-radius: 5px;
  901. -webkit-border-radius: 5px;
  902. -moz-border-radius: 5px;
  903. border: 2px solid #FFF;
  904. width: 615px;
  905. display: inline-block;
  906. padding: 15px; }
  907. #feature div.feature-header {
  908. display: table;
  909. width: inherit;
  910. margin-bottom: 10px; }
  911. #feature div.feature-header h1 {
  912. display: table-cell;
  913. vertical-align: middle;
  914. font-size: 24px; }
  915. #feature div.feature-header h1 .byline {
  916. color: #8e8e8e;
  917. font-size: 18px; }
  918. #feature div.feature-header ul.feature-navigation {
  919. display: table-cell;
  920. vertical-align: middle;
  921. text-align: right; }
  922. #feature div.feature-header ul.feature-navigation li {
  923. display: inline-block;
  924. padding: 0 2px; }
  925. #feature div.feature-image {
  926. width: inherit;
  927. text-align: center; }
  928. #feature ul.share-wrapper {
  929. background: #e4e4e4;
  930. background: -webkit-gradient(linear, left top, left bottom, from(white), to(#e4e4e4));
  931. background: -moz-linear-gradient(top, white, #e4e4e4);
  932. border-radius: 5px;
  933. -webkit-border-radius: 5px;
  934. -moz-border-radius: 5px;
  935. -moz-box-shadow: 0 0 5px 1px #cccccc;
  936. -webkit-box-shadow: 0 0 5px 1px #cccccc;
  937. box-shadow: 0 0 5px 1px #cccccc;
  938. font-size: 11px;
  939. border: 1px solid #CCC;
  940. text-align: center;
  941. text-transform: uppercase;
  942. margin-top: 10px; }
  943. #feature ul.share-wrapper li {
  944. display: inline-block;
  945. border-left: 1px solid #DDD; }
  946. #feature ul.share-wrapper li a {
  947. width: 203.667px;
  948. padding: 11px 0;
  949. display: block;
  950. color: inherit; }
  951. #feature ul.share-wrapper li a:hover {
  952. background: white;
  953. background: -webkit-gradient(linear, left top, left bottom, from(#e4e4e4), to(white));
  954. background: -moz-linear-gradient(top, #e4e4e4, white); }
  955. #feature ul.share-wrapper li a#share:hover {
  956. border-top-right-radius: 5px;
  957. border-bottom-right-radius: 5px;
  958. -webkit-border-top-right-radius: 5px;
  959. -webkit-border-bottom-right-radius: 5px;
  960. -moz-border-radius-topright: 5px;
  961. -moz-border-radius-bottomright: 5px; }
  962. #feature ul.share-wrapper li a#favorite:hover {
  963. border-top-left-radius: 5px;
  964. border-bottom-left-radius: 5px;
  965. -webkit-border-top-left-radius: 5px;
  966. -webkit-border-bottom-left-radius: 5px;
  967. -moz-border-radius-topleft: 5px;
  968. -moz-border-radius-bottomleft: 5px; }
  969. #feature ul.share-wrapper li:first-child {
  970. border-left: none; }
  971. #feature form#feature-comment {
  972. display: none;
  973. width: inherit;
  974. text-align: right; }
  975. #feature form#feature-comment h3 {
  976. text-align: left;
  977. font-size: 14px;
  978. color: #8e8e8e;
  979. padding: 10px 0; }
  980. #feature form#feature-comment h3 #counter {
  981. text-align: right;
  982. float: right;
  983. color: #d5d5d5; }
  984. #feature form#feature-comment textarea {
  985. width: inherit;
  986. text-align: left; }
  987. #feature-list {
  988. vertical-align: top;
  989. width: 288px;
  990. display: inline-block; }
  991. #feature-list ul, #feature-list > div {
  992. padding-left: 15px;
  993. padding-right: 15px; }
  994. #feature-list ul.feature-list-tabs {
  995. border-bottom: 1px solid #B2B2B2; }
  996. #feature-list ul.feature-list-tabs li {
  997. display: inline-block; }
  998. #feature-list ul.feature-list-tabs li a {
  999. background: white;
  1000. background: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(white));
  1001. background: -moz-linear-gradient(top, #e8e8e8, white);
  1002. border-top-left-radius: 5px;
  1003. border-top-right-radius: 5px;
  1004. -webkit-border-top-left-radius: 5px;
  1005. -webkit-border-top-right-radius: 5px;
  1006. -moz-border-radius-topleft: 5px;
  1007. -moz-border-radius-topbottom: 5px;
  1008. display: block;
  1009. padding: 6px 12px;
  1010. border-top: 1px solid #B2B2B2;
  1011. border-left: 1px solid #B2B2B2;
  1012. border-right: 1px solid #B2B2B2;
  1013. border-bottom: 1px solid #FFF;
  1014. position: relative;
  1015. top: 1px; }
  1016. #feature-list div.feature-list-header {
  1017. padding-top: 6px;
  1018. padding-bottom: 8px;
  1019. margin-top: 4px;
  1020. font-size: 16px;
  1021. font-weight: bold;
  1022. overflow: hidden;
  1023. border-bottom: 1px solid #DDD; }
  1024. #feature-list div.feature-list-header h3 {
  1025. width: 50%;
  1026. float: left;
  1027. padding: 2px 0; }
  1028. #feature-list div.feature-list-header div.edit {
  1029. font-weight: normal;
  1030. float: right;
  1031. color: #8e8e8e;
  1032. font-size: 12px; }
  1033. #feature-list div.feature-list-header div.edit a {
  1034. width: auto; }
  1035. #feature-list ul.feature-list-navigation {
  1036. background: #e4e4e4;
  1037. background: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#e4e4e4));
  1038. background: -moz-linear-gradient(top, #f4f4f4, #e4e4e4);
  1039. border-bottom: 1px solid #CCC;
  1040. margin-bottom: 5px;
  1041. display: table;
  1042. width: inherit;
  1043. height: 24px;
  1044. text-align: right; }
  1045. #feature-list ul.feature-list-navigation li {
  1046. vertical-align: middle;
  1047. font-weight: bold;
  1048. display: table-cell;
  1049. width: 50%; }
  1050. #feature-list ul.feature-list-navigation li:first-child {
  1051. text-align: left; }
  1052. #feature-list ul.features {
  1053. padding: 0px; }
  1054. #feature-list ul.features li a {
  1055. display: block;
  1056. padding: 5px 15px; }
  1057. #feature-list ul.features li a:hover {
  1058. background: #e7f2ff; }
  1059. #feature-list ul.features li.alt a {
  1060. background: #f4f4f4; }
  1061. #feature-list ul.features li.alt a:hover {
  1062. background: #e7f2ff; }
  1063. </style>
  1064. <div id="canvas">
  1065. <!-- Banner ad goes here. -->
  1066. <div id="canvas-container">
  1067. <div id="tab-navigation">
  1068. <ul>
  1069. <li>
  1070. <a href="#" id="MyComics" class="top-tab">My Comics</a>
  1071. </li>
  1072. <li>
  1073. <a href="#" id="Favorites" class="top-tab">Favorites</a>
  1074. </li>
  1075. <li class="last-li">
  1076. <a href="#" id="AllComics" class="top-tab">All Comics</a>
  1077. </li>
  1078. </ul>
  1079. </div>
  1080. <div id="content">
  1081. <div id="feature"></div>
  1082. <div id="feature-list"></div>
  1083. <div class="clear"></div>
  1084. <div id="feature-comments"></div>
  1085. </div>
  1086. </div>
  1087. </div>
  1088. <script id="feature-template" type="text/mustache-tmpl">
  1089. <div class="feature-header">
  1090. <h1>{{title}} <span class="byline">by {{author}}</span></h1>
  1091. <ul class="feature-navigation">
  1092. <li>{{display_date}}</li>
  1093. <li><a href="#" id="prev">&larr;</a></li>
  1094. <li><a href="#" id="next">&rarr;</a></li>
  1095. </ul>
  1096. </div>
  1097. <div class="feature-image">
  1098. <img src="{{image_link}}" alt="{{title}}" />
  1099. </div>
  1100. <ul class="share-wrapper"><li><a href="{{id}}" id="favorite">Favorite</a></li><li><a href="{{feature_id}}" id="subscribe">Subscribe</a></li><li><a href="{{id}}" id="share">Share</a></li></ul>
  1101. <form id="feature-comment">
  1102. <h3>Share with comment: <span id="counter">140</span></h3>
  1103. <textarea cols="40" rows="2" id="comment-field"></textarea>
  1104. <input id="comment-button" type="button" value="Share" />
  1105. </form>
  1106. </script>
  1107. <script id="feature-list-template" type="text/mustache-tmpl">
  1108. <ul class="feature-list-tabs">
  1109. {{#feature_groups}}
  1110. <li class="little-tab"><a href="#" id="{{slug}}">{{title}}</a></li>
  1111. {{/feature_groups}}
  1112. </ul>
  1113. <div class="feature-list-header">
  1114. <h3>{{title}}</h3>
  1115. <div class="edit"><a href="#" class="little-button">Edit</a></div>
  1116. </div>
  1117. <ul class="feature-list-navigation">
  1118. <li><a href="#" id="prev">&larr; Previous</a></li>
  1119. <li><a href="#" id="next">Next &rarr;</a></li>
  1120. </ul>
  1121. <ul class="features">
  1122. {{#features}}
  1123. <li><a href="{{id}}">{{title}}</a></li>
  1124. {{/features}}
  1125. </ul>
  1126. </script>
  1127. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" type="text/javascript"></script>
  1128. <script type="text/javascript">/*
  1129. mustache.js — Logic-less templates in JavaScript
  1130. See http://mustache.github.com/ for more info.
  1131. */
  1132. var Mustache = function() {
  1133. var Renderer = function() {};
  1134. Renderer.prototype = {
  1135. otag: "{{",
  1136. ctag: "}}",
  1137. pragmas: {},
  1138. buffer: [],
  1139. pragmas_implemented: {
  1140. "IMPLICIT-ITERATOR": true
  1141. },
  1142. context: {},
  1143. render: function(template, context, partials, in_recursion) {
  1144. // reset buffer & set context
  1145. if(!in_recursion) {
  1146. this.context = context;
  1147. this.buffer = []; // TODO: make this non-lazy
  1148. }
  1149. // fail fast
  1150. if(!this.includes("", template)) {
  1151. if(in_recursion) {
  1152. return template;
  1153. } else {
  1154. this.send(template);
  1155. return;
  1156. }
  1157. }
  1158. template = this.render_pragmas(template);
  1159. var html = this.render_section(template, context, partials);
  1160. if(in_recursion) {
  1161. return this.render_tags(html, context, partials, in_recursion);
  1162. }
  1163. this.render_tags(html, context, partials, in_recursion);
  1164. },
  1165. /*
  1166. Sends parsed lines
  1167. */
  1168. send: function(line) {
  1169. if(line != "") {
  1170. this.buffer.push(line);
  1171. }
  1172. },
  1173. /*
  1174. Looks for %PRAGMAS
  1175. */
  1176. render_pragmas: function(template) {
  1177. // no pragmas
  1178. if(!this.includes("%", template)) {
  1179. return template;
  1180. }
  1181. var that = this;
  1182. var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
  1183. this.ctag);
  1184. return template.replace(regex, function(match, pragma, options) {
  1185. if(!that.pragmas_implemented[pragma]) {
  1186. throw({message:
  1187. "This implementation of mustache doesn't understand the '" +
  1188. pragma + "' pragma"});
  1189. }
  1190. that.pragmas[pragma] = {};
  1191. if(options) {
  1192. var opts = options.split("=");
  1193. that.pragmas[pragma][opts[0]] = opts[1];
  1194. }
  1195. return "";
  1196. // ignore unknown pragmas silently
  1197. });
  1198. },
  1199. /*
  1200. Tries to find a partial in the curent scope and render it
  1201. */
  1202. render_partial: function(name, context, partials) {
  1203. name = this.trim(name);
  1204. if(!partials || partials[name] === undefined) {
  1205. throw({message: "unknown_partial '" + name + "'"});
  1206. }
  1207. if(typeof(context[name]) != "object") {
  1208. return this.render(partials[name], context, partials, true);
  1209. }
  1210. return this.render(partials[name], context[name], partials, true);
  1211. },
  1212. /*
  1213. Renders inverted (^) and normal (#) sections
  1214. */
  1215. render_section: function(template, context, partials) {
  1216. if(!this.includes("#", template) && !this.includes("^", template)) {
  1217. return template;
  1218. }
  1219. var that = this;
  1220. // CSW - Added "+?" so it finds the tighest bound, not the widest
  1221. var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
  1222. "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
  1223. "\\s*", "mg");
  1224. // for each {{#foo}}{{/foo}} section do...
  1225. return template.replace(regex, function(match, type, name, content) {
  1226. var value = that.find(name, context);
  1227. if(type == "^") { // inverted section
  1228. if(!value || that.is_array(value) && value.length === 0) {
  1229. // false or empty list, render it
  1230. return that.render(content, context, partials, true);
  1231. } else {
  1232. return "";
  1233. }
  1234. } else if(type == "#") { // normal section
  1235. if(that.is_array(value)) { // Enumerable, Let's loop!
  1236. return that.map(value, function(row) {
  1237. return that.render(content, that.create_context(row),
  1238. partials, true);
  1239. }).join("");
  1240. } else if(that.is_object(value)) { // Object, Use it as subcontext!
  1241. return that.render(content, that.create_context(value),
  1242. partials, true);
  1243. } else if(typeof value === "function") {
  1244. // higher order section
  1245. return value.call(context, content, function(text) {
  1246. return that.render(text, context, partials, true);
  1247. });
  1248. } else if(value) { // boolean section
  1249. return that.render(content, context, partials, true);
  1250. } else {
  1251. return "";
  1252. }
  1253. }
  1254. });
  1255. },
  1256. /*
  1257. Replace {{foo}} and friends with values from our view
  1258. */
  1259. render_tags: function(template, context, partials, in_recursion) {
  1260. // tit for tat
  1261. var that = this;
  1262. var new_regex = function() {
  1263. return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
  1264. that.ctag + "+", "g");
  1265. };
  1266. var regex = new_regex();
  1267. var tag_replace_callback = function(match, operator, name) {
  1268. switch(operator) {
  1269. case "!": // ignore comments
  1270. return "";
  1271. case "=": // set new delimiters, rebuild the replace regexp
  1272. that.set_delimiters(name);
  1273. regex = new_regex();
  1274. return "";
  1275. case ">": // render partial
  1276. return that.render_partial(name, context, partials);
  1277. case "{": // the triple mustache is unescaped
  1278. return that.find(name, context);
  1279. default: // escape the value
  1280. return that.escape(that.find(name, context));
  1281. }
  1282. };
  1283. var lines = template.split("\n");
  1284. for(var i = 0; i < lines.length; i++) {
  1285. lines[i] = lines[i].replace(regex, tag_replace_callback, this);
  1286. if(!in_recursion) {
  1287. this.send(lines[i]);
  1288. }
  1289. }
  1290. if(in_recursion) {
  1291. return lines.join("\n");
  1292. }
  1293. },
  1294. set_delimiters: function(delimiters) {
  1295. var dels = delimiters.split(" ");
  1296. this.otag = this.escape_regex(dels[0]);
  1297. this.ctag = this.escape_regex(dels[1]);
  1298. },
  1299. escape_regex: function(text) {
  1300. // thank you Simon Willison
  1301. if(!arguments.callee.sRE) {
  1302. var specials = [
  1303. '/', '.', '*', '+', '?', '|',
  1304. '(', ')', '[', ']', '{', '}', '\\'
  1305. ];
  1306. arguments.callee.sRE = new RegExp(
  1307. '(\\' + specials.join('|\\') + ')', 'g'
  1308. );
  1309. }
  1310. return text.replace(arguments.callee.sRE, '\\$1');
  1311. },
  1312. /*
  1313. find `name` in current `context`. That is find me a value
  1314. from the view object
  1315. */
  1316. find: function(name, context) {
  1317. name = this.trim(name);
  1318. // Checks whether a value is thruthy or false or 0
  1319. function is_kinda_truthy(bool) {
  1320. return bool === false || bool === 0 || bool;
  1321. }
  1322. var value;
  1323. if(is_kinda_truthy(context[name])) {
  1324. value = context[name];
  1325. } else if(is_kinda_truthy(this.context[name])) {
  1326. value = this.context[name];
  1327. }
  1328. if(typeof value === "function") {
  1329. return value.apply(context);
  1330. }
  1331. if(value !== undefined) {
  1332. return value;
  1333. }
  1334. // silently ignore unkown variables
  1335. return "";
  1336. },
  1337. // Utility methods
  1338. /* includes tag */
  1339. includes: function(needle, haystack) {
  1340. return haystack.indexOf(this.otag + needle) != -1;
  1341. },
  1342. /*
  1343. Does away with nasty characters
  1344. */
  1345. escape: function(s) {
  1346. s = String(s === null ? "" : s);
  1347. return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) {
  1348. switch(s) {
  1349. case "&": return "&amp;";
  1350. case "\\": return "\\\\";
  1351. case '"': return '&quot;';
  1352. case "'": return '&#39;';
  1353. case "<": return "&lt;";
  1354. case ">": return "&gt;";
  1355. default: return s;
  1356. }
  1357. });
  1358. },
  1359. // by @langalex, support for arrays of strings
  1360. create_context: function(_context) {
  1361. if(this.is_object(_context)) {
  1362. return _context;
  1363. } else {
  1364. var iterator = ".";
  1365. if(this.pragmas["IMPLICIT-ITERATOR"]) {
  1366. iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
  1367. }
  1368. var ctx = {};
  1369. ctx[iterator] = _context;
  1370. return ctx;
  1371. }
  1372. },
  1373. is_object: function(a) {
  1374. return a && typeof a == "object";
  1375. },
  1376. is_array: function(a) {
  1377. return Object.prototype.toString.call(a) === '[object Array]';
  1378. },
  1379. /*
  1380. Gets rid of leading and trailing whitespace
  1381. */
  1382. trim: function(s) {
  1383. return s.replace(/^\s*|\s*$/g, "");
  1384. },
  1385. /*
  1386. Why, why, why? Because IE. Cry, cry cry.
  1387. */
  1388. map: function(array, fn) {
  1389. if (typeof array.map == "function") {
  1390. return array.map(fn);
  1391. } else {
  1392. var r = [];
  1393. var l = array.length;
  1394. for(var i = 0; i < l; i++) {
  1395. r.push(fn(array[i]));
  1396. }
  1397. return r;
  1398. }
  1399. }
  1400. };
  1401. return({
  1402. name: "mustache.js",
  1403. version: "0.3.1-dev",
  1404. /*
  1405. Turns a template and view into HTML
  1406. */
  1407. to_html: function(template, view, partials, send_fun) {
  1408. var renderer = new Renderer();
  1409. if(send_fun) {
  1410. renderer.send = send_fun;
  1411. }
  1412. renderer.render(template, view, partials);
  1413. if(!send_fun) {
  1414. return renderer.buffer.join("\n");
  1415. }
  1416. }
  1417. });
  1418. }();
  1419. </script>
  1420. <script type="text/javascript">// Underscore.js 1.1.6
  1421. // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
  1422. // Underscore is freely distributable under the MIT license.
  1423. // Portions of Underscore are inspired or borrowed from Prototype,
  1424. // Oliver Steele's Functional, and John Resig's Micro-Templating.
  1425. // For all details and documentation:
  1426. // http://documentcloud.github.com/underscore
  1427. (function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.6";var h=b.each=b.forEach=function(a,c,d){if(a!=null)if(s&&a.forEach===s)a.forEach(c,d);else if(b.isNumber(a.length))for(var e=
  1428. 0,k=a.length;e<k;e++){if(c.call(d,a[e],e,a)===m)break}else for(e in a)if(l.call(a,e)&&c.call(d,a[e],e,a)===m)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(c,b);h(a,function(a,g,G){e[e.length]=c.call(b,a,g,G)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var k=d!==void 0;a==null&&(a=[]);if(u&&a.reduce===u)return e&&(c=b.bi