Merge pull request #5 from swcarpentry/join-site-lesson
[rnaseq-cwl-training.git] / css / deckjs-js / deckjs-custom.js
1 /*
2   This is a packed deck.js with some extensions and styles.
3   It has been generated from version d8c74bcc860ba175ab020fd69656abee3fc057f3 .
4   It includes:
5      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck/extensions/includedeck/load.js
6      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//jquery.min.js
7      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//modernizr.custom.js
8      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//core/deck.core.js
9      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/smarkdown/markdown.js
10      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/smarkdown/deck.smarkdown.js
11      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/fit/deck.fit.js
12      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/display-latex2.user.js
13      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/simplemath/deck.simplemath.js
14      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/clone/deck.clone.js
15      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/goto/deck.goto.js
16      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/progress/deck.progress.js
17      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/navigation/deck.navigation.js
18      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/menu/deck.menu.js
19      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/step/deck.step.js
20      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/events/deck.events.js
21      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/anim/deck.anim.js
22      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/jquerysvg/jquery.svg.min.js
23      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/jquerysvg/jquery.svganim.min.js
24      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/svg/deck.svg.js
25      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/metadata/deck.metadata.js
26      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/attribution/deck.attribution.js
27      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/container-styling/deck.container-styling.js
28      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/timekeeper/deck.timekeeper.js
29      browsercast/popcorn.js
30      browsercast/deck.browsercast.js
31      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/core.css
32      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/fit/deck.fit-fs.css
33      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/clone/deck.clone.css
34      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/goto/deck.goto.css
35      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/progress/deck.progress.css
36      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/navigation/deck.navigation.css
37      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/menu/deck.menu.css
38      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/attribution/deck.attribution.css
39      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/timekeeper/deck.timekeeper.css
40      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/simple.css
41      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/comments.css
42      browsercast/deck.browsercast.css
43      browsercast/player.css
44 */
45
46
47 /*!
48  * Includedeck.
49  *
50  * Copyright (c) 2013-2014 RĂ©mi Emonet.
51  * Licensed under the MIT license.
52  * https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
53  *
54  * The goal of this extension is to simplify include of deck.js,
55  * its profiles/themes and the extensions.
56  *
57  * The first goal is not performance of loading (still it should
58  * allow the display of a message while loading) but on ease of
59  * use and extensibility (i.e., includedeck does not need to know
60  * about all existing extensions, even if by default it does know
61  * some of them).
62  *
63  */
64
65
66
67 var head_conf = {
68     
69 };
70
71 if (typeof ACTUALLY_EXPORT_A_LIST_OF_FILES == 'undefined')
72 // this is head.load.min.js (v1.0.3) from http://headjs.com/site/download.html
73 /*! head.load - v1.0.3 */
74 (function(n,t){"use strict";function w(){}function u(n,t){if(n){typeof n=="object"&&(n=[].slice.call(n));for(var i=0,r=n.length;i<r;i++)t.call(n,n[i],i)}}function it(n,i){var r=Object.prototype.toString.call(i).slice(8,-1);return i!==t&&i!==null&&r===n}function s(n){return it("Function",n)}function a(n){return it("Array",n)}function et(n){var i=n.split("/"),t=i[i.length-1],r=t.indexOf("?");return r!==-1?t.substring(0,r):t}function f(n){(n=n||w,n._done)||(n(),n._done=1)}function ot(n,t,r,u){var f=typeof n=="object"?n:{test:n,success:!t?!1:a(t)?t:[t],failure:!r?!1:a(r)?r:[r],callback:u||w},e=!!f.test;return e&&!!f.success?(f.success.push(f.callback),i.load.apply(null,f.success)):e||!f.failure?u():(f.failure.push(f.callback),i.load.apply(null,f.failure)),i}function v(n){var t={},i,r;if(typeof n=="object")for(i in n)!n[i]||(t={name:i,url:n[i]});else t={name:et(n),url:n};return(r=c[t.name],r&&r.url===t.url)?r:(c[t.name]=t,t)}function y(n){n=n||c;for(var t in n)if(n.hasOwnProperty(t)&&n[t].state!==l)return!1;return!0}function st(n){n.state=ft;u(n.onpreload,function(n){n.call()})}function ht(n){n.state===t&&(n.state=nt,n.onpreload=[],rt({url:n.url,type:"cache"},function(){st(n)}))}function ct(){var n=arguments,t=n[n.length-1],r=[].slice.call(n,1),f=r[0];return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(f?(u(r,function(n){s(n)||!n||ht(v(n))}),b(v(n[0]),s(f)?f:function(){i.load.apply(null,r)})):b(v(n[0])),i)}function lt(){var n=arguments,t=n[n.length-1],r={};return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(u(n,function(n){n!==t&&(n=v(n),r[n.name]=n)}),u(n,function(n){n!==t&&(n=v(n),b(n,function(){y(r)&&f(t)}))}),i)}function b(n,t){if(t=t||w,n.state===l){t();return}if(n.state===tt){i.ready(n.name,t);return}if(n.state===nt){n.onpreload.push(function(){b(n,t)});return}n.state=tt;rt(n,function(){n.state=l;t();u(h[n.name],function(n){f(n)});o&&y()&&u(h.ALL,function(n){f(n)})})}function at(n){n=n||"";var t=n.split("?")[0].split(".");return t[t.length-1].toLowerCase()}function rt(t,i){function e(t){t=t||n.event;u.onload=u.onreadystatechange=u.onerror=null;i()}function o(f){f=f||n.event;(f.type==="load"||/loaded|complete/.test(u.readyState)&&(!r.documentMode||r.documentMode<9))&&(n.clearTimeout(t.errorTimeout),n.clearTimeout(t.cssTimeout),u.onload=u.onreadystatechange=u.onerror=null,i())}function s(){if(t.state!==l&&t.cssRetries<=20){for(var i=0,f=r.styleSheets.length;i<f;i++)if(r.styleSheets[i].href===u.href){o({type:"load"});return}t.cssRetries++;t.cssTimeout=n.setTimeout(s,250)}}var u,h,f;i=i||w;h=at(t.url);h==="css"?(u=r.createElement("link"),u.type="text/"+(t.type||"css"),u.rel="stylesheet",u.href=t.url,t.cssRetries=0,t.cssTimeout=n.setTimeout(s,500)):(u=r.createElement("script"),u.type="text/"+(t.type||"javascript"),u.src=t.url);u.onload=u.onreadystatechange=o;u.onerror=e;u.async=!1;u.defer=!1;t.errorTimeout=n.setTimeout(function(){e({type:"timeout"})},7e3);f=r.head||r.getElementsByTagName("head")[0];f.insertBefore(u,f.lastChild)}function vt(){for(var t,u=r.getElementsByTagName("script"),n=0,f=u.length;n<f;n++)if(t=u[n].getAttribute("data-headjs-load"),!!t){i.load(t);return}}function yt(n,t){var v,p,e;return n===r?(o?f(t):d.push(t),i):(s(n)&&(t=n,n="ALL"),a(n))?(v={},u(n,function(n){v[n]=c[n];i.ready(n,function(){y(v)&&f(t)})}),i):typeof n!="string"||!s(t)?i:(p=c[n],p&&p.state===l||n==="ALL"&&y()&&o)?(f(t),i):(e=h[n],e?e.push(t):e=h[n]=[t],i)}function e(){if(!r.body){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(e,50);return}o||(o=!0,vt(),u(d,function(n){f(n)}))}function k(){r.addEventListener?(r.removeEventListener("DOMContentLoaded",k,!1),e()):r.readyState==="complete"&&(r.detachEvent("onreadystatechange",k),e())}var r=n.document,d=[],h={},c={},ut="async"in r.createElement("script")||"MozAppearance"in r.documentElement.style||n.opera,o,g=n.head_conf&&n.head_conf.head||"head",i=n[g]=n[g]||function(){i.ready.apply(null,arguments)},nt=1,ft=2,tt=3,l=4,p;if(r.readyState==="complete")e();else if(r.addEventListener)r.addEventListener("DOMContentLoaded",k,!1),n.addEventListener("load",e,!1);else{r.attachEvent("onreadystatechange",k);n.attachEvent("onload",e);p=!1;try{p=!n.frameElement&&r.documentElement}catch(wt){}p&&p.doScroll&&function pt(){if(!o){try{p.doScroll("left")}catch(t){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(pt,50);return}e()}}()}i.load=i.js=ut?lt:ct;i.test=ot;i.ready=yt;i.ready(r,function(){y()&&u(h.ALL,function(n){f(n)});i.feature&&i.feature("domloaded",!0)})})(window);
75 //# sourceMappingURL=head.load.min.js.map
76
77
78 // this is the actual includedeck
79 function includedeck(m, c) {
80     var maybe = function(f) { return f || (function(){}); }
81     var modules = m || [];
82     var conf = c || {};
83     var initDelay = conf.INITDELAY;
84     var cb = {
85         beforeLoad: maybe(conf.BEFORELOAD),
86         beforeDelay: maybe(conf.BEFOREDELAY), // useful only if INITDELAY is set, else, just like BEFOREINIT
87         beforeInit: maybe(conf.BEFOREINIT),
88         afterInit: maybe(conf.AFTERINIT),
89         atExit: maybe(conf.ATEXIT), // for backward compatibility (same as AFTERINIT)
90         hasGeneric: conf.GENERIC ? true : false,
91         generic: maybe(conf.GENERIC) // will receive calls like GENERIC("AFTER", "svg"), one of each BEFORE/AFTER for each file group (svg, simplemath, ...)
92     };
93     var prefix = conf.PREFIX || "deck.js";
94
95     if (typeof(modules) == "string") {
96         modules = modules.split(/ +/);
97     }
98     
99     // todo: make this externally extensible
100     // todo: maybe have a mechanism to load a list of dependency (e.g., mymodule-files.js)
101
102     var info = {
103         //
104         // core (differerent possible cores)
105         "deck-core-dependencies": [
106             prefix + "/jquery.min.js",
107             prefix + "/modernizr.custom.js"
108             //prefix + "/extensions/includedeck/___after___core___.js"
109         ],
110         "deck": [
111             "@_deck-core-dependencies",
112             prefix + "/core/deck.core.css",
113             prefix + "/core/deck.core.js"
114         ],
115         "newdeck": [
116             "@_deck-core-dependencies",
117             prefix + "/extensions/style-chunks/core.css",
118             prefix + "/core/deck.core.js"
119         ],
120         //
121         // extensions
122         "fit": [ prefix + "/extensions/fit/deck.fit.js" ],
123         "fit-fs": [
124             prefix + "/extensions/fit/deck.fit-fs.css",
125             "@_fit"
126         ],
127         "simplemath": [
128             prefix + "/libs/display-latex2.user.js",
129             prefix + "/extensions/simplemath/deck.simplemath.js"
130         ],
131         "smartsyntax": [ prefix + "/extensions/smartsyntax/deck.smartsyntax.js" ],
132         "smarkdown": [
133             prefix + "/extensions/smarkdown/markdown.js",
134             prefix + "/extensions/smarkdown/deck.smarkdown.js"
135         ],
136         "clone": [
137             prefix + "/extensions/clone/deck.clone.css",
138             prefix + "/extensions/clone/deck.clone.js"
139         ],
140         "timekeeper": [
141             prefix + "/extensions/timekeeper/deck.timekeeper.css",
142             prefix + "/extensions/timekeeper/deck.timekeeper.js"
143         ],
144         "goto": [
145             prefix + "/extensions/goto/deck.goto.css",
146             prefix + "/extensions/goto/deck.goto.js"
147         ],
148         "status": [
149             prefix + "/extensions/status/deck.status.css",
150             prefix + "/extensions/status/deck.status.js"
151         ],
152         "progress": [
153             prefix + "/extensions/progress/deck.progress.css",
154             prefix + "/extensions/progress/deck.progress.js"
155         ],
156         "navigation": [
157             prefix + "/extensions/navigation/deck.navigation.css",
158             prefix + "/extensions/navigation/deck.navigation.js"
159         ],
160         "menu": [
161             prefix + "/extensions/menu/deck.menu.css",
162             prefix + "/extensions/menu/deck.menu.js"
163         ],
164         "step": [ prefix + "/extensions/step/deck.step.js" ],
165         "events": [ prefix + "/extensions/events/deck.events.js" ],
166         "anim": [ prefix + "/extensions/anim/deck.anim.js" ],
167         "svg": [
168             prefix + "/libs/jquerysvg/jquery.svg.min.js" ,
169             prefix + "/libs/jquerysvg/jquery.svganim.min.js",
170             prefix + "/extensions/svg/deck.svg.js"
171         ],
172         "metadata": [ prefix + "/extensions/metadata/deck.metadata.js" ],
173         "attribution": [
174             prefix + "/extensions/attribution/deck.attribution.css",
175             prefix + "/extensions/attribution/deck.attribution.js"
176         ],
177         "container-styling": [ prefix + "/extensions/container-styling/deck.container-styling.js" ],
178         // Style extensions
179         "style-chunks": [
180             prefix + "/extensions/style-chunks/simple.css",
181             prefix + "/extensions/style-chunks/comments.css"
182         ],
183         //
184         // Themes
185         // // by convention, "theme:blabla" will load the default blabla theme
186         //
187         // Some default profiles
188         //
189         /// profile-1: default deck with most extensions and no theme
190         "profile-1": ["@_deck", "@_smartsyntax", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
191         "profile-1-fitnofs": ["@_deck", "@_smartsyntax", "@_fit", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
192         /// profile-2: new deck (cleaner css) with most extensions and no theme
193         "profile-2": ["@_newdeck", "@_smartsyntax", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
194         "profile-2-fitnofs": ["@_newdeck", "@_smartsyntax", "@_fit", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
195         /// profile-3: big profile = profile-2 / with new status (progress) + all good bundled extensions
196         "profile-3": ["@_newdeck", "@_smartsyntax", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_progress", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg",
197                       "@_metadata", "@_attribution", "@_container-styling", "@_timekeeper"],
198         /// profile-4: big profile (as profile 3) but with the smarkdown instead of the smartsyntax
199         "profile-4": ["@_newdeck", "@_smarkdown", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_progress", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg",
200                       "@_metadata", "@_attribution", "@_container-styling", "@_timekeeper"],
201         /// profile-5: use smarkdown and include more useful things (CSS: simple, comments)
202         "profile-5": ["@_newdeck", "@_smarkdown", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_progress", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg",
203                       "@_metadata", "@_attribution", "@_container-styling", "@_timekeeper", "@_style-chunks"],
204         dummy: {}
205     };
206
207     var endsInJsOrCss = /\.(css|js)$/;
208
209     // Defensive check that there are no *.js/*.css in the info (as they won't be useable anyways)
210     for (k in info) {
211         if (endsInJsOrCss.test(k)) {
212             alert("Internal problem detected in includedeck: '" + k + "' won't be useable.");
213         }
214     }
215
216     // TODO?: handle default extensions (deck.js/extensions/N/deck.N.{js,css}
217     // TODO?: some should come before others, e.g. anim before svg, (or before any (deck) or before most (loading...))
218
219     // if there are two '#' in the url, take everything after the second as a theme name
220     var forceTheme = null;
221     if ((typeof ACTUALLY_EXPORT_A_LIST_OF_FILES == 'undefined') && (window.location.hash.replace(/[^#]/gi, '').length == 2)) {
222         var theme = window.location.hash.replace(/^.*#/gi, '')
223         var base = window.location.hash.replace(/#[^#]*$/gi, '')
224         forceTheme = theme;
225         window.location.hash = base;
226     }
227
228     var toLoad = [];
229     var addInfo = function(k) {
230         if (k.substring(0, 6) == "theme:") {
231             k = k.substring(6)
232             if (forceTheme) { // replace by the url forced theme (works only with default themes...
233                 k = forceTheme
234             }
235             if (k.substring(0, 2) == "x:") {
236                 k = k.substring(2)
237                 toLoad = toLoad.concat(prefix + "/deck.js-theme-builder/" + k + ".css");
238             } else {
239                 toLoad = toLoad.concat(prefix + "/themes/style/" + k + ".css");
240             }
241             return;
242         }
243         if (k.substring(0, 10) == "extension:") {
244             toLoad = toLoad.concat(prefix + "/extensions/" + k.substring(10));
245             return;
246         }
247         if (endsInJsOrCss.test(k)) {
248             toLoad = toLoad.concat(k);
249             return;
250         }
251         var closure = function(wh, e) { return function () { cb.generic(wh, e); } };
252         for (i in info[k]) {
253             if (info[k][i].substring(0,2) == "@_") {
254                 var e = info[k][i].substring(2);
255                 if (cb.hasGeneric) toLoad = toLoad.concat(closure("BEFORE", e));
256                 addInfo(e);
257                 if (cb.hasGeneric) toLoad = toLoad.concat(closure("AFTER", e));
258             } else {
259                 toLoad = toLoad.concat(info[k][i]);
260             }
261         }
262     }
263
264     for (i in modules) {
265         addInfo(modules[i]);
266     }
267
268     if (typeof ACTUALLY_EXPORT_A_LIST_OF_FILES !== 'undefined') {
269         return toLoad;
270     }
271
272     { // First insert a CSS, just to fit modernizr
273         var c = document.createElement("style");
274         c.type = "text/css";
275         if (typeof ACTUALLY_FILL_CSS !== 'undefined') {
276             ACTUALLY_FILL_CSS(c);
277         }
278         document.getElementsByTagName("head")[0].appendChild(c);
279     }
280     
281     // custom adapter function to split the load list at each function and call by head.js by block (need to end with a function)
282     // in the end, for IE9 compat, we load everything one by one... maybe switching to lazyload.js would avoid needing this.
283     var loadsAndCalls = function(l, stack) {
284         stack = stack || [];
285         if (l.length == 0) return;
286         if ("string" !== typeof l[0]) {
287             l[0]();
288             loadsAndCalls(l.slice(1));
289         } else {
290             head.js(l[0], function() {
291                 loadsAndCalls(l.slice(1));
292             });
293         }
294     }
295     cb.beforeLoad();
296     loadsAndCalls(toLoad.concat(function() {
297         $(function() {
298             var doIt = function() {
299                 cb.beforeInit();
300                 $.deck(conf);
301                 cb.afterInit();
302                 cb.atExit();
303             };
304             // delay and callback logic
305             cb.beforeDelay();
306             if (initDelay) {
307                 setTimeout(doIt, initDelay);
308             } else {
309                 doIt();
310             }
311         });
312     }));
313 }
314
315
316 /*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
317 //@ sourceMappingURL=jquery-1.10.2.min.map
318 */
319 (function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
320 }({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
321 u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
322 /* Modernizr 2.0.6 (Custom Build) | MIT & BSD
323  * Contains: fontface | backgroundsize | borderimage | borderradius | boxshadow | flexbox | hsla | multiplebgs | opacity | rgba | textshadow | cssanimations | csscolumns | generatedcontent | cssgradients | cssreflections | csstransforms | csstransforms3d | csstransitions | applicationcache | canvas | canvastext | draganddrop | hashchange | history | audio | video | indexeddb | input | inputtypes | localstorage | postmessage | sessionstorage | websockets | websqldatabase | webworkers | geolocation | inlinesvg | smil | svg | svgclippaths | touch | webgl | iepp | cssclasses | addtest | teststyles | testprop | testallprops | hasevent | prefixes | domprefixes | load
324  */
325 ;window.Modernizr=function(a,b,c){function H(){e.input=function(a){for(var b=0,c=a.length;b<c;b++)t[a[b]]=a[b]in l;return t}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)l.setAttribute("type",f=a[d]),e=l.type!=="text",e&&(l.value=m,l.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&l.style.WebkitAppearance!==c?(g.appendChild(l),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(l,null).WebkitAppearance!=="textfield"&&l.offsetHeight!==0,g.removeChild(l)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=l.checkValidity&&l.checkValidity()===!1:/^color$/.test(f)?(g.appendChild(l),g.offsetWidth,e=l.value!=m,g.removeChild(l)):e=l.value!=m)),s[a[d]]=!!e;return s}("search tel url email datetime date month week time datetime-local number range color".split(" "))}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c)return b=="pfx"?a[d]:!0;return!1}function D(a,b){return!!~(""+a).indexOf(b)}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="2.0.6",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v=function(a,c,d,e){var f,h,j,k=b.createElement("div");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:i+(d+1),k.appendChild(j);f=["&shy;","<style>",a,"</style>"].join(""),k.id=i,k.innerHTML+=f,g.appendChild(k),h=c(k,a),k.parentNode.removeChild(k);return!!h},w=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=C(e[d],"function"),C(e[d],c)||(e[d]=c),e.removeAttribute(d))),e=null;return f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),x,y={}.hasOwnProperty,z;!C(y,c)&&!C(y.call,c)?z=function(a,b){return y.call(a,b)}:z=function(a,b){return b in a&&C(a.constructor.prototype[b],c)};var G=function(c,d){var f=c.join(""),g=d.length;v(f,function(c,d){var f=b.styleSheets[b.styleSheets.length-1],h=f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"",i=c.childNodes,j={};while(g--)j[i[g].id]=i[g];e.touch="ontouchstart"in a||j.touch.offsetTop===9,e.csstransforms3d=j.csstransforms3d.offsetLeft===9,e.generatedcontent=j.generatedcontent.offsetHeight>=1,e.fontface=/src/i.test(h)&&h.indexOf(d.split(" ")[0])===0},g,d)}(['@font-face {font-family:"font";src:url("https://")}',["@media (",o.join("touch-enabled),("),i,")","{#touch{top:9px;position:absolute}}"].join(""),["@media (",o.join("transform-3d),("),i,")","{#csstransforms3d{left:9px;position:absolute}}"].join(""),['#generatedcontent:after{content:"',m,'";visibility:hidden}'].join("")],["fontface","touch","csstransforms3d","generatedcontent"]);r.flexbox=function(){function c(a,b,c,d){a.style.cssText=o.join(b+":"+c+";")+(d||"")}function a(a,b,c,d){b+=":",a.style.cssText=(b+o.join(c+";"+b)).slice(0,-b.length)+(d||"")}var d=b.createElement("div"),e=b.createElement("div");a(d,"display","box","width:42px;padding:0;"),c(e,"box-flex","1","width:10px;"),d.appendChild(e),g.appendChild(d);var f=e.offsetWidth===42;d.removeChild(e),g.removeChild(d);return f},r.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},r.canvastext=function(){return!!e.canvas&&!!C(b.createElement("canvas").getContext("2d").fillText,"function")},r.webgl=function(){return!!a.WebGLRenderingContext},r.touch=function(){return e.touch},r.geolocation=function(){return!!navigator.geolocation},r.postmessage=function(){return!!a.postMessage},r.websqldatabase=function(){var b=!!a.openDatabase;return b},r.indexedDB=function(){for(var b=-1,c=p.length;++b<c;)if(a[p[b].toLowerCase()+"IndexedDB"])return!0;return!!a.indexedDB},r.hashchange=function(){return w("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},r.history=function(){return!!a.history&&!!history.pushState},r.draganddrop=function(){return w("dragstart")&&w("drop")},r.websockets=function(){for(var b=-1,c=p.length;++b<c;)if(a[p[b]+"WebSocket"])return!0;return"WebSocket"in a},r.rgba=function(){A("background-color:rgba(150,255,150,.5)");return D(k.backgroundColor,"rgba")},r.hsla=function(){A("background-color:hsla(120,40%,100%,.5)");return D(k.backgroundColor,"rgba")||D(k.backgroundColor,"hsla")},r.multiplebgs=function(){A("background:url(https://),url(https://),red url(https://)");return/(url\s*\(.*?){3}/.test(k.background)},r.backgroundsize=function(){return F("backgroundSize")},r.borderimage=function(){return F("borderImage")},r.borderradius=function(){return F("borderRadius")},r.boxshadow=function(){return F("boxShadow")},r.textshadow=function(){return b.createElement("div").style.textShadow===""},r.opacity=function(){B("opacity:.55");return/^0.55$/.test(k.opacity)},r.cssanimations=function(){return F("animationName")},r.csscolumns=function(){return F("columnCount")},r.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";A((a+o.join(b+a)+o.join(c+a)).slice(0,-a.length));return D(k.backgroundImage,"gradient")},r.cssreflections=function(){return F("boxReflect")},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])},r.csstransforms3d=function(){var a=!!E(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);a&&"webkitPerspective"in g.style&&(a=e.csstransforms3d);return a},r.csstransitions=function(){return F("transitionProperty")},r.fontface=function(){return e.fontface},r.generatedcontent=function(){return e.generatedcontent},r.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType){c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"');var d='video/mp4; codecs="avc1.42E01E';c.h264=a.canPlayType(d+'"')||a.canPlayType(d+', mp4a.40.2"'),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}}catch(e){}return c},r.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"'),c.mp3=a.canPlayType("audio/mpeg;"),c.wav=a.canPlayType('audio/wav; codecs="1"'),c.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}catch(d){}return c},r.localstorage=function(){try{return!!localStorage.getItem}catch(a){return!1}},r.sessionstorage=function(){try{return!!sessionStorage.getItem}catch(a){return!1}},r.webworkers=function(){return!!a.Worker},r.applicationcache=function(){return!!a.applicationCache},r.svg=function(){return!!b.createElementNS&&!!b.createElementNS(q.svg,"svg").createSVGRect},r.inlinesvg=function(){var a=b.createElement("div");a.innerHTML="<svg/>";return(a.firstChild&&a.firstChild.namespaceURI)==q.svg},r.smil=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"animate")))},r.svgclippaths=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"clipPath")))};for(var I in r)z(r,I)&&(x=I.toLowerCase(),e[x]=r[I](),u.push((e[x]?"":"no-")+x));e.input||H(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)z(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return;b=typeof b=="boolean"?b:!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b}return e},A(""),j=l=null,a.attachEvent&&function(){var a=b.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}()&&function(a,b){function s(a){var b=-1;while(++b<g)a.createElement(f[b])}a.iepp=a.iepp||{};var d=a.iepp,e=d.html5elements||"abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",f=e.split("|"),g=f.length,h=new RegExp("(^|\\s)("+e+")","gi"),i=new RegExp("<(/*)("+e+")","gi"),j=/^\s*[\{\}]\s*$/,k=new RegExp("(^|[^\\n]*?\\s)("+e+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),l=b.createDocumentFragment(),m=b.documentElement,n=m.firstChild,o=b.createElement("body"),p=b.createElement("style"),q=/print|all/,r;d.getCSS=function(a,b){if(a+""===c)return"";var e=-1,f=a.length,g,h=[];while(++e<f){g=a[e];if(g.disabled)continue;b=g.media||b,q.test(b)&&h.push(d.getCSS(g.imports,b),g.cssText),b="all"}return h.join("")},d.parseCSS=function(a){var b=[],c;while((c=k.exec(a))!=null)b.push(((j.exec(c[1])?"\n":c[1])+c[2]+c[3]).replace(h,"$1.iepp_$2")+c[4]);return b.join("\n")},d.writeHTML=function(){var a=-1;r=r||b.body;while(++a<g){var c=b.getElementsByTagName(f[a]),d=c.length,e=-1;while(++e<d)c[e].className.indexOf("iepp_")<0&&(c[e].className+=" iepp_"+f[a])}l.appendChild(r),m.appendChild(o),o.className=r.className,o.id=r.id,o.innerHTML=r.innerHTML.replace(i,"<$1font")},d._beforePrint=function(){p.styleSheet.cssText=d.parseCSS(d.getCSS(b.styleSheets,"all")),d.writeHTML()},d.restoreHTML=function(){o.innerHTML="",m.removeChild(o),m.appendChild(r)},d._afterPrint=function(){d.restoreHTML(),p.styleSheet.cssText=""},s(b),s(l);d.disablePP||(n.insertBefore(p,n.firstChild),p.media="print",p.className="iepp-printshim",a.attachEvent("onbeforeprint",d._beforePrint),a.attachEvent("onafterprint",d._afterPrint))}(a,b),e._version=d,e._prefixes=o,e._domPrefixes=p,e.hasEvent=w,e.testProp=function(a){return E([a])},e.testAllProps=F,e.testStyles=v,g.className=g.className.replace(/\bno-js\b/,"")+(f?" js "+u.join(" "):"");return e}(this,this.document),function(a,b,c){function k(a){return!a||a=="loaded"||a=="complete"}function j(){var a=1,b=-1;while(p.length- ++b)if(p[b].s&&!(a=p[b].r))break;a&&g()}function i(a){var c=b.createElement("script"),d;c.src=a.s,c.onreadystatechange=c.onload=function(){!d&&k(c.readyState)&&(d=1,j(),c.onload=c.onreadystatechange=null)},m(function(){d||(d=1,j())},H.errorTimeout),a.e?c.onload():n.parentNode.insertBefore(c,n)}function h(a){var c=b.createElement("link"),d;c.href=a.s,c.rel="stylesheet",c.type="text/css";if(!a.e&&(w||r)){var e=function(a){m(function(){if(!d)try{a.sheet.cssRules.length?(d=1,j()):e(a)}catch(b){b.code==1e3||b.message=="security"||b.message=="denied"?(d=1,m(function(){j()},0)):e(a)}},0)};e(c)}else c.onload=function(){d||(d=1,m(function(){j()},0))},a.e&&c.onload();m(function(){d||(d=1,j())},H.errorTimeout),!a.e&&n.parentNode.insertBefore(c,n)}function g(){var a=p.shift();q=1,a?a.t?m(function(){a.t=="c"?h(a):i(a)},0):(a(),j()):q=0}function f(a,c,d,e,f,h){function i(){!o&&k(l.readyState)&&(r.r=o=1,!q&&j(),l.onload=l.onreadystatechange=null,m(function(){u.removeChild(l)},0))}var l=b.createElement(a),o=0,r={t:d,s:c,e:h};l.src=l.data=c,!s&&(l.style.display="none"),l.width=l.height="0",a!="object"&&(l.type=d),l.onload=l.onreadystatechange=i,a=="img"?l.onerror=i:a=="script"&&(l.onerror=function(){r.e=r.r=1,g()}),p.splice(e,0,r),u.insertBefore(l,s?null:n),m(function(){o||(u.removeChild(l),r.r=r.e=o=1,j())},H.errorTimeout)}function e(a,b,c){var d=b=="c"?z:y;q=0,b=b||"j",C(a)?f(d,a,b,this.i++,l,c):(p.splice(this.i++,0,a),p.length==1&&g());return this}function d(){var a=H;a.loader={load:e,i:0};return a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=r&&!s,u=s?l:n.parentNode,v=a.opera&&o.call(a.opera)=="[object Opera]",w="webkitAppearance"in l.style,x=w&&"async"in b.createElement("script"),y=r?"object":v||x?"img":"script",z=w?"img":y,A=Array.isArray||function(a){return o.call(a)=="[object Array]"},B=function(a){return Object(a)===a},C=function(a){return typeof a=="string"},D=function(a){return o.call(a)=="[object Function]"},E=[],F={},G,H;H=function(a){function f(a){var b=a.split("!"),c=E.length,d=b.pop(),e=b.length,f={url:d,origUrl:d,prefixes:b},g,h;for(h=0;h<e;h++)g=F[b[h]],g&&(f=g(f));for(h=0;h<c;h++)f=E[h](f);return f}function e(a,b,e,g,h){var i=f(a),j=i.autoCallback;if(!i.bypass){b&&(b=D(b)?b:b[a]||b[g]||b[a.split("/").pop().split("?")[0]]);if(i.instead)return i.instead(a,b,e,g,h);e.load(i.url,i.forceCSS||!i.forceJS&&/css$/.test(i.url)?"c":c,i.noexec),(D(b)||D(j))&&e.load(function(){d(),b&&b(i.origUrl,h,g),j&&j(i.origUrl,h,g)})}}function b(a,b){function c(a){if(C(a))e(a,h,b,0,d);else if(B(a))for(i in a)a.hasOwnProperty(i)&&e(a[i],h,b,i,d)}var d=!!a.test,f=d?a.yep:a.nope,g=a.load||a.both,h=a.callback,i;c(f),c(g),a.complete&&b.load(a.complete)}var g,h,i=this.yepnope.loader;if(C(a))e(a,0,i,0);else if(A(a))for(g=0;g<a.length;g++)h=a[g],C(h)?e(h,0,i,0):A(h)?H(h):B(h)&&b(h,i);else B(a)&&b(a,i)},H.addPrefix=function(a,b){F[a]=b},H.addFilter=function(a){E.push(a)},H.errorTimeout=1e4,b.readyState==null&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",G=function(){b.removeEventListener("DOMContentLoaded",G,0),b.readyState="complete"},0)),a.yepnope=d()}(this,this.document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
326 /*!
327 Deck JS - deck.core
328 Copyright (c) 2011-2014 Caleb Troughton
329 Dual licensed under the MIT license.
330 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
331 */
332
333 /*
334 The deck.core module provides all the basic functionality for creating and
335 moving through a deck.  It does so by applying classes to indicate the state of
336 the deck and its slides, allowing CSS to take care of the visual representation
337 of each state.  It also provides methods for navigating the deck and inspecting
338 its state, as well as basic key bindings for going to the next and previous
339 slides.  More functionality is provided by wholly separate extension modules
340 that use the API provided by core.
341 */
342 (function($, undefined) {
343   var slides, currentIndex, $container, $fragmentLinks;
344
345   var events = {
346     /*
347     This event fires at the beginning of a slide change, before the actual
348     change occurs. Its purpose is to give extension authors a way to prevent
349     the slide change from occuring. This is done by calling preventDefault
350     on the event object within this event. If that is done, the deck.change
351     event will never be fired and the slide will not change.
352     */
353     beforeChange: 'deck.beforeChange',
354
355     /*
356     This event fires whenever the current slide changes, whether by way of
357     next, prev, or go. The callback function is passed two parameters, from
358     and to, equal to the indices of the old slide and the new slide
359     respectively. If preventDefault is called on the event within this handler
360     the slide change does not occur.
361
362     $(document).bind('deck.change', function(event, from, to) {
363        alert('Moving from slide ' + from + ' to ' + to);
364     });
365     */
366     change: 'deck.change',
367
368     /*
369     This event fires at the beginning of deck initialization. This event makes
370     a good hook for preprocessing extensions looking to modify the DOM before
371     the deck is fully initialized. It is also possible to halt the deck.init
372     event from firing while you do things in beforeInit. This can be done by
373     calling lockInit on the event object passed to this event. The init can be
374     released by calling releaseInit.
375
376     $(document).bind('deck.beforeInit', function(event) {
377       event.lockInit(); // halts deck.init event
378       window.setTimeout(function() {
379         event.releaseInit(); // deck.init will now fire 2 seconds later
380       }, 2000);
381     });
382
383     The init event will be fired regardless of locks after
384     options.initLockTimeout milliseconds.
385     */
386     beforeInitialize: 'deck.beforeInit',
387
388     /*
389     This event fires at the end of deck initialization. Extensions should
390     implement any code that relies on user extensible options (key bindings,
391     element selectors, classes) within a handler for this event. Native
392     events associated with Deck JS should be scoped under a .deck event
393     namespace, as with the example below:
394
395     var $d = $(document);
396     $.deck.defaults.keys.myExtensionKeycode = 70; // 'h'
397     $d.bind('deck.init', function() {
398        $d.bind('keydown.deck', function(event) {
399           if (event.which === $.deck.getOptions().keys.myExtensionKeycode) {
400              // Rock out
401           }
402        });
403     });
404     */
405     initialize: 'deck.init'
406   };
407
408   var options = {};
409   var $document = $(document);
410   var $window = $(window);
411   var stopPropagation = function(event) {
412     event.stopPropagation();
413   };
414
415   var updateContainerState = function() {
416     var oldIndex = $container.data('onSlide');
417     $container.removeClass(options.classes.onPrefix + oldIndex);
418     $container.addClass(options.classes.onPrefix + currentIndex);
419     $container.data('onSlide', currentIndex);
420   };
421
422   var updateChildCurrent = function() {
423     var $oldCurrent = $('.' + options.classes.current);
424     var $oldParents = $oldCurrent.parentsUntil(options.selectors.container);
425     var $newCurrent = slides[currentIndex];
426     var $newParents = $newCurrent.parentsUntil(options.selectors.container);
427     $oldParents.removeClass(options.classes.childCurrent);
428     $newParents.addClass(options.classes.childCurrent);
429   };
430
431   var removeOldSlideStates = function() {
432     var $all = $();
433     $.each(slides, function(i, el) {
434       $all = $all.add(el);
435     });
436     $all.removeClass([
437       options.classes.before,
438       options.classes.previous,
439       options.classes.current,
440       options.classes.next,
441       options.classes.after
442     ].join(' '));
443   };
444
445   var addNewSlideStates = function() {
446     slides[currentIndex].addClass(options.classes.current);
447     if (currentIndex > 0) {
448       slides[currentIndex-1].addClass(options.classes.previous);
449     }
450     if (currentIndex + 1 < slides.length) {
451       slides[currentIndex+1].addClass(options.classes.next);
452     }
453     if (currentIndex > 1) {
454       $.each(slides.slice(0, currentIndex - 1), function(i, $slide) {
455         $slide.addClass(options.classes.before);
456       });
457     }
458     if (currentIndex + 2 < slides.length) {
459       $.each(slides.slice(currentIndex+2), function(i, $slide) {
460         $slide.addClass(options.classes.after);
461       });
462     }
463   };
464
465   var setAriaHiddens = function() {
466     $(options.selectors.slides).each(function() {
467       var $slide = $(this);
468       var isSub = $slide.closest('.' + options.classes.childCurrent).length;
469       var isBefore = $slide.hasClass(options.classes.before) && !isSub;
470       var isPrevious = $slide.hasClass(options.classes.previous) && !isSub;
471       var isNext = $slide.hasClass(options.classes.next);
472       var isAfter = $slide.hasClass(options.classes.after);
473       var ariaHiddenValue = isBefore || isPrevious || isNext || isAfter;
474       $slide.attr('aria-hidden', ariaHiddenValue);
475     });
476   };
477
478   var updateStates = function() {
479     updateContainerState();
480     updateChildCurrent();
481     removeOldSlideStates();
482     addNewSlideStates();
483     if (options.setAriaHiddens) {
484       setAriaHiddens();
485     }
486   };
487
488   var initSlidesArray = function(elements) {
489     if ($.isArray(elements)) {
490       $.each(elements, function(i, element) {
491         slides.push($(element));
492       });
493     }
494     else {
495       $(elements).each(function(i, element) {
496         slides.push($(element));
497       });
498     }
499   };
500
501   var bindKeyEvents = function() {
502     var editables = [
503       'input',
504       'textarea',
505       'select',
506       'button',
507       'meter',
508       'progress',
509       '[contentEditable]'
510     ].join(', ');
511
512     $document.unbind('keydown.deck').bind('keydown.deck', function(event) {
513       var isNext = event.which === options.keys.next;
514       var isPrev = event.which === options.keys.previous;
515       isNext = isNext || $.inArray(event.which, options.keys.next) > -1;
516       isPrev = isPrev || $.inArray(event.which, options.keys.previous) > -1;
517
518       if (isNext) {
519         methods.next();
520         event.preventDefault();
521       }
522       else if (isPrev) {
523         methods.prev();
524         event.preventDefault();
525       }
526     });
527
528     $document.undelegate(editables, 'keydown.deck', stopPropagation);
529     $document.delegate(editables, 'keydown.deck', stopPropagation);
530   };
531
532   var bindTouchEvents = function() {
533     var startTouch;
534     var direction = options.touch.swipeDirection;
535     var tolerance = options.touch.swipeTolerance;
536     var listenToHorizontal = ({ both: true, horizontal: true })[direction];
537     var listenToVertical = ({ both: true, vertical: true })[direction];
538
539     $container.unbind('touchstart.deck');
540     $container.bind('touchstart.deck', function(event) {
541       if (!startTouch) {
542         startTouch = $.extend({}, event.originalEvent.targetTouches[0]);
543       }
544     });
545
546     $container.unbind('touchmove.deck');
547     $container.bind('touchmove.deck', function(event) {
548       $.each(event.originalEvent.changedTouches, function(i, touch) {
549         if (!startTouch || touch.identifier !== startTouch.identifier) {
550           return true;
551         }
552         var xDistance = touch.screenX - startTouch.screenX;
553         var yDistance = touch.screenY - startTouch.screenY;
554         var leftToRight = xDistance > tolerance && listenToHorizontal;
555         var rightToLeft = xDistance < -tolerance && listenToHorizontal;
556         var topToBottom = yDistance > tolerance && listenToVertical;
557         var bottomToTop = yDistance < -tolerance && listenToVertical;
558
559         if (leftToRight || topToBottom) {
560           $.deck('prev');
561           startTouch = undefined;
562         }
563         else if (rightToLeft || bottomToTop) {
564           $.deck('next');
565           startTouch = undefined;
566         }
567         return false;
568       });
569
570       if (listenToVertical) {
571         event.preventDefault();
572       }
573     });
574
575     $container.unbind('touchend.deck');
576     $container.bind('touchend.deck', function(event) {
577       $.each(event.originalEvent.changedTouches, function(i, touch) {
578         if (startTouch && touch.identifier === startTouch.identifier) {
579           startTouch = undefined;
580         }
581       });
582     });
583   };
584
585   var indexInBounds = function(index) {
586     return typeof index === 'number' && index >=0 && index < slides.length;
587   };
588
589   var createBeforeInitEvent = function() {
590     var event = $.Event(events.beforeInitialize);
591     event.locks = 0;
592     event.done = $.noop;
593     event.lockInit = function() {
594       ++event.locks;
595     };
596     event.releaseInit = function() {
597       --event.locks;
598       if (!event.locks) {
599         event.done();
600       }
601     };
602     return event;
603   };
604
605   var goByHash = function(str) {
606     var id = str.substr(str.indexOf("#") + 1);
607
608     $.each(slides, function(i, $slide) {
609       if ($slide.attr('id') === id) {
610         $.deck('go', i);
611         return false;
612       }
613     });
614
615     // If we don't set these to 0 the container scrolls due to hashchange
616     if (options.preventFragmentScroll) {
617       $.deck('getContainer').scrollLeft(0).scrollTop(0);
618     }
619   };
620
621   var assignSlideId = function(i, $slide) {
622     var currentId = $slide.attr('id');
623     var previouslyAssigned = $slide.data('deckAssignedId') === currentId;
624     if (!currentId || previouslyAssigned) {
625       $slide.attr('id', options.hashPrefix + i);
626       $slide.data('deckAssignedId', options.hashPrefix + i);
627     }
628   };
629
630   var removeContainerHashClass = function(id) {
631     $container.removeClass(options.classes.onPrefix + id);
632   };
633
634   var addContainerHashClass = function(id) {
635     $container.addClass(options.classes.onPrefix + id);
636   };
637
638   var setupHashBehaviors = function() {
639     $fragmentLinks = $();
640     $.each(slides, function(i, $slide) {
641       var hash;
642
643       assignSlideId(i, $slide);
644       hash = '#' + $slide.attr('id');
645       if (hash === window.location.hash) {
646         setTimeout(function() {
647           $.deck('go', i);
648         }, 1);
649       }
650       $fragmentLinks = $fragmentLinks.add('a[href="' + hash + '"]');
651     });
652
653     if (slides.length) {
654       addContainerHashClass($.deck('getSlide').attr('id'));
655     };
656   };
657
658   var changeHash = function(from, to) {
659     var hash = '#' + $.deck('getSlide', to).attr('id');
660     var hashPath = window.location.href.replace(/#.*/, '') + hash;
661
662     removeContainerHashClass($.deck('getSlide', from).attr('id'));
663     addContainerHashClass($.deck('getSlide', to).attr('id'));
664     if (Modernizr.history) {
665       window.history.replaceState({}, "", hashPath);
666     }
667   };
668
669   /* Methods exposed in the jQuery.deck namespace */
670   var methods = {
671
672     /*
673     jQuery.deck(selector, options)
674
675     selector: string | jQuery | array
676     options: object, optional
677
678     Initializes the deck, using each element matched by selector as a slide.
679     May also be passed an array of string selectors or jQuery objects, in
680     which case each selector in the array is considered a slide. The second
681     parameter is an optional options object which will extend the default
682     values.
683
684     Users may also pass only an options object to init. In this case the slide
685     selector will be options.selectors.slides which defaults to .slide.
686
687     $.deck('.slide');
688
689     or
690
691     $.deck([
692        '#first-slide',
693        '#second-slide',
694        '#etc'
695     ]);
696     */
697     init: function(opts) {
698       var beforeInitEvent = createBeforeInitEvent();
699       var overrides = opts;
700
701       if (!$.isPlainObject(opts)) {
702         overrides = arguments[1] || {};
703         $.extend(true, overrides, {
704           selectors: {
705             slides: arguments[0]
706           }
707         });
708       }
709
710       options = $.extend(true, {}, $.deck.defaults, overrides);
711       slides = [];
712       currentIndex = 0;
713       $container = $(options.selectors.container);
714
715       // Hide the deck while states are being applied to kill transitions
716       $container.addClass(options.classes.loading);
717
718       // populate the array of slides for pre-init
719       initSlidesArray(options.selectors.slides);
720       // Pre init event for preprocessing hooks
721       beforeInitEvent.done = function() {
722         // reInitSlidesArray is meant only for beforeInit
723         methods['reInitSlidesArray'] = function() {
724             alert('Deck.js method "reInitSlidesArray" is meant to be called in the beforeInit phase only.');
725         }
726         // re-populate the array of slides
727         slides = [];
728         initSlidesArray(options.selectors.slides);
729         setupHashBehaviors();
730         bindKeyEvents();
731         bindTouchEvents();
732         $container.scrollLeft(0).scrollTop(0);
733
734         if (slides.length) {
735           updateStates();
736         }
737
738         // Show deck again now that slides are in place
739         $container.removeClass(options.classes.loading);
740         $document.trigger(events.initialize);
741       };
742
743       beforeInitEvent.lockInit();
744       $document.trigger(beforeInitEvent);
745       beforeInitEvent.releaseInit();
746       window.setTimeout(function() {
747         if (beforeInitEvent.locks) {
748           if (window.console) {
749             window.console.warn('Something locked deck initialization\
750               without releasing it before the timeout. Proceeding with\
751               initialization anyway.');
752           }
753           beforeInitEvent.done();
754         }
755       }, options.initLockTimeout);
756     },
757
758     /*
759     jQuery.deck('reInitSlidesArray')
760     
761     Force a recomputation of the "slides" array. This method is meant
762     to be used by extensions that generate new slides in the
763     beforeInit phase.
764     */
765
766     reInitSlidesArray: function() {
767         slides = [];
768         initSlidesArray(options.selectors.slides);
769     },
770
771     /*
772     jQuery.deck('go', index)
773
774     index: integer | string
775
776     Moves to the slide at the specified index if index is a number. Index is
777     0-based, so $.deck('go', 0); will move to the first slide. If index is a
778     string this will move to the slide with the specified id. If index is out
779     of bounds or doesn't match a slide id the call is ignored.
780     */
781     go: function(indexOrId) {
782       var beforeChangeEvent = $.Event(events.beforeChange);
783       var index;
784
785       /* Number index, easy. */
786       if (indexInBounds(indexOrId)) {
787         index = indexOrId;
788       }
789       /* Id string index, search for it and set integer index */
790       else if (typeof indexOrId === 'string') {
791         $.each(slides, function(i, $slide) {
792           if ($slide.attr('id') === indexOrId) {
793             index = i;
794             return false;
795           }
796         });
797       }
798       if (typeof index === 'undefined') {
799         return;
800       }
801
802       /* Trigger beforeChange. If nothing prevents the change, trigger
803       the slide change. */
804       $document.trigger(beforeChangeEvent, [currentIndex, index]);
805       if (!beforeChangeEvent.isDefaultPrevented()) {
806         $document.trigger(events.change, [currentIndex, index]);
807         changeHash(currentIndex, index);
808         currentIndex = index;
809         updateStates();
810       }
811     },
812
813     /*
814     jQuery.deck('next')
815
816     Moves to the next slide. If the last slide is already active, the call
817     is ignored.
818     */
819     next: function() {
820       methods.go(currentIndex+1);
821     },
822
823     /*
824     jQuery.deck('prev')
825
826     Moves to the previous slide. If the first slide is already active, the
827     call is ignored.
828     */
829     prev: function() {
830       methods.go(currentIndex-1);
831     },
832
833     /*
834     jQuery.deck('getSlide', index)
835
836     index: integer, optional
837
838     Returns a jQuery object containing the slide at index. If index is not
839     specified, the current slide is returned.
840     */
841     getSlide: function(index) {
842       index = typeof index !== 'undefined' ? index : currentIndex;
843       if (!indexInBounds(index)) {
844         return null;
845       }
846       return slides[index];
847     },
848
849     /*
850     jQuery.deck('getSlides')
851
852     Returns all slides as an array of jQuery objects.
853     */
854     getSlides: function() {
855       return slides;
856     },
857
858     /*
859     jQuery.deck('getTopLevelSlides')
860
861     Returns all slides that are not subslides.
862     */
863     getTopLevelSlides: function() {
864       var topLevelSlides = [];
865       var slideSelector = options.selectors.slides;
866       var subSelector = [slideSelector, slideSelector].join(' ');
867       $.each(slides, function(i, $slide) {
868         if (!$slide.is(subSelector)) {
869           topLevelSlides.push($slide);
870         }
871       });
872       return topLevelSlides;
873     },
874
875     /*
876     jQuery.deck('getNestedSlides', index)
877
878     index: integer, optional
879
880     Returns all the nested slides of the current slide. If index is
881     specified it returns the nested slides of the slide at that index.
882     If there are no nested slides this will return an empty array.
883     */
884     getNestedSlides: function(index) {
885       var targetIndex = index == null ? currentIndex : index;
886       var $targetSlide = $.deck('getSlide', targetIndex);
887       var $nesteds = $targetSlide.find(options.selectors.slides);
888       var nesteds = $nesteds.get();
889       return $.map(nesteds, function(slide, i) {
890         return $(slide);
891       });
892     },
893
894
895     /*
896     jQuery.deck('getContainer')
897
898     Returns a jQuery object containing the deck container as defined by the
899     container option.
900     */
901     getContainer: function() {
902       return $container;
903     },
904
905     /*
906     jQuery.deck('getOptions')
907
908     Returns the options object for the deck, including any overrides that
909     were defined at initialization.
910     */
911     getOptions: function() {
912       return options;
913     },
914
915     /*
916     jQuery.deck('extend', name, method)
917
918     name: string
919     method: function
920
921     Adds method to the deck namespace with the key of name. This doesn’t
922     give access to any private member data â€” public methods must still be
923     used within method â€” but lets extension authors piggyback on the deck
924     namespace rather than pollute jQuery.
925
926     $.deck('extend', 'alert', function(msg) {
927        alert(msg);
928     });
929
930     // Alerts 'boom'
931     $.deck('alert', 'boom');
932     */
933     extend: function(name, method) {
934       methods[name] = method;
935     }
936   };
937
938   /* jQuery extension */
939   $.deck = function(method, arg) {
940     var args = Array.prototype.slice.call(arguments, 1);
941     if (methods[method]) {
942       return methods[method].apply(this, args);
943     }
944     else {
945       return methods.init(method, arg);
946     }
947   };
948
949   /*
950   The default settings object for a deck. All deck extensions should extend
951   this object to add defaults for any of their options.
952
953   options.classes.after
954     This class is added to all slides that appear after the 'next' slide.
955
956   options.classes.before
957     This class is added to all slides that appear before the 'previous'
958     slide.
959
960   options.classes.childCurrent
961     This class is added to all elements in the DOM tree between the
962     'current' slide and the deck container. For standard slides, this is
963     mostly seen and used for nested slides.
964
965   options.classes.current
966     This class is added to the current slide.
967
968   options.classes.loading
969     This class is applied to the deck container during loading phases and is
970     primarily used as a way to short circuit transitions between states
971     where such transitions are distracting or unwanted.  For example, this
972     class is applied during deck initialization and then removed to prevent
973     all the slides from appearing stacked and transitioning into place
974     on load.
975
976   options.classes.next
977     This class is added to the slide immediately following the 'current'
978     slide.
979
980   options.classes.onPrefix
981     This prefix, concatenated with the current slide index, is added to the
982     deck container as you change slides.
983
984   options.classes.previous
985     This class is added to the slide immediately preceding the 'current'
986     slide.
987
988   options.selectors.container
989     Elements matched by this CSS selector will be considered the deck
990     container. The deck container is used to scope certain states of the
991     deck, as with the onPrefix option, or with extensions such as deck.goto
992     and deck.menu.
993
994   options.selectors.slides
995     Elements matched by this selector make up the individual deck slides.
996     If a user chooses to pass the slide selector as the first argument to
997     $.deck() on initialization it does the same thing as passing in this
998     option and this option value will be set to the value of that parameter.
999
1000   options.keys.next
1001     The numeric keycode used to go to the next slide.
1002
1003   options.keys.previous
1004     The numeric keycode used to go to the previous slide.
1005
1006   options.touch.swipeDirection
1007     The direction swipes occur to cause slide changes. Can be 'horizontal',
1008     'vertical', or 'both'. Any other value or a falsy value will disable
1009     swipe gestures for navigation.
1010
1011   options.touch.swipeTolerance
1012     The number of pixels the users finger must travel to produce a swipe
1013     gesture.
1014
1015   options.initLockTimeout
1016     The number of milliseconds the init event will wait for BeforeInit event
1017     locks to be released before firing the init event regardless.
1018
1019   options.hashPrefix
1020     Every slide that does not have an id is assigned one at initialization.
1021     Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0,
1022     slide-12, etc.
1023
1024   options.preventFragmentScroll
1025     When deep linking to a hash of a nested slide, this scrolls the deck
1026     container to the top, undoing the natural browser behavior of scrolling
1027     to the document fragment on load.
1028
1029   options.setAriaHiddens
1030     When set to true, deck.js will set aria hidden attributes for slides
1031     that do not appear onscreen according to a typical heirarchical
1032     deck structure. You may want to turn this off if you are using a theme
1033     where slides besides the current slide are visible on screen and should
1034     be accessible to screenreaders.
1035   */
1036   $.deck.defaults = {
1037     classes: {
1038       after: 'deck-after',
1039       before: 'deck-before',
1040       childCurrent: 'deck-child-current',
1041       current: 'deck-current',
1042       loading: 'deck-loading',
1043       next: 'deck-next',
1044       onPrefix: 'on-slide-',
1045       previous: 'deck-previous'
1046     },
1047
1048     selectors: {
1049       container: '.deck-container',
1050       slides: '.slide'
1051     },
1052
1053     keys: {
1054       // enter, space, page down, right arrow, down arrow,
1055       next: [13, 32, 34, 39, 40],
1056       // backspace, page up, left arrow, up arrow
1057       previous: [8, 33, 37, 38]
1058     },
1059
1060     touch: {
1061       swipeDirection: 'horizontal',
1062       swipeTolerance: 60
1063     },
1064
1065     initLockTimeout: 10000,
1066     hashPrefix: 'slide-',
1067     preventFragmentScroll: true,
1068     setAriaHiddens: true
1069   };
1070
1071   $document.ready(function() {
1072     $('html').addClass('ready');
1073   });
1074
1075   $window.bind('hashchange.deck', function(event) {
1076     if (event.originalEvent && event.originalEvent.newURL) {
1077       goByHash(event.originalEvent.newURL);
1078     }
1079     else {
1080       goByHash(window.location.hash);
1081     }
1082   });
1083
1084   $window.bind('load.deck', function() {
1085     if (options.preventFragmentScroll) {
1086       $container.scrollLeft(0).scrollTop(0);
1087     }
1088   });
1089 })(jQuery);
1090
1091 // Released under MIT license
1092 // Copyright (c) 2009-2010 Dominic Baggott
1093 // Copyright (c) 2009-2010 Ash Berlin
1094 // Copyright (c) 2011 Christoph Dorn <christoph@christophdorn.com> (http://www.christophdorn.com)
1095
1096 /*jshint browser:true, devel:true */
1097
1098 (function( expose ) {
1099
1100 /**
1101  *  class Markdown
1102  *
1103  *  Markdown processing in Javascript done right. We have very particular views
1104  *  on what constitutes 'right' which include:
1105  *
1106  *  - produces well-formed HTML (this means that em and strong nesting is
1107  *    important)
1108  *
1109  *  - has an intermediate representation to allow processing of parsed data (We
1110  *    in fact have two, both as [JsonML]: a markdown tree and an HTML tree).
1111  *
1112  *  - is easily extensible to add new dialects without having to rewrite the
1113  *    entire parsing mechanics
1114  *
1115  *  - has a good test suite
1116  *
1117  *  This implementation fulfills all of these (except that the test suite could
1118  *  do with expanding to automatically run all the fixtures from other Markdown
1119  *  implementations.)
1120  *
1121  *  ##### Intermediate Representation
1122  *
1123  *  *TODO* Talk about this :) Its JsonML, but document the node names we use.
1124  *
1125  *  [JsonML]: http://jsonml.org/ "JSON Markup Language"
1126  **/
1127 var Markdown = expose.Markdown = function(dialect) {
1128   switch (typeof dialect) {
1129     case "undefined":
1130       this.dialect = Markdown.dialects.Gruber;
1131       break;
1132     case "object":
1133       this.dialect = dialect;
1134       break;
1135     default:
1136       if ( dialect in Markdown.dialects ) {
1137         this.dialect = Markdown.dialects[dialect];
1138       }
1139       else {
1140         throw new Error("Unknown Markdown dialect '" + String(dialect) + "'");
1141       }
1142       break;
1143   }
1144   this.em_state = [];
1145   this.strong_state = [];
1146   this.debug_indent = "";
1147 };
1148
1149 /**
1150  *  parse( markdown, [dialect] ) -> JsonML
1151  *  - markdown (String): markdown string to parse
1152  *  - dialect (String | Dialect): the dialect to use, defaults to gruber
1153  *
1154  *  Parse `markdown` and return a markdown document as a Markdown.JsonML tree.
1155  **/
1156 expose.parse = function( source, dialect ) {
1157   // dialect will default if undefined
1158   var md = new Markdown( dialect );
1159   return md.toTree( source );
1160 };
1161
1162 /**
1163  *  toHTML( markdown, [dialect]  ) -> String
1164  *  toHTML( md_tree ) -> String
1165  *  - markdown (String): markdown string to parse
1166  *  - md_tree (Markdown.JsonML): parsed markdown tree
1167  *
1168  *  Take markdown (either as a string or as a JsonML tree) and run it through
1169  *  [[toHTMLTree]] then turn it into a well-formated HTML fragment.
1170  **/
1171 expose.toHTML = function toHTML( source , dialect , options ) {
1172   var input = expose.toHTMLTree( source , dialect , options );
1173
1174   return expose.renderJsonML( input );
1175 };
1176
1177 /**
1178  *  toHTMLTree( markdown, [dialect] ) -> JsonML
1179  *  toHTMLTree( md_tree ) -> JsonML
1180  *  - markdown (String): markdown string to parse
1181  *  - dialect (String | Dialect): the dialect to use, defaults to gruber
1182  *  - md_tree (Markdown.JsonML): parsed markdown tree
1183  *
1184  *  Turn markdown into HTML, represented as a JsonML tree. If a string is given
1185  *  to this function, it is first parsed into a markdown tree by calling
1186  *  [[parse]].
1187  **/
1188 expose.toHTMLTree = function toHTMLTree( input, dialect , options ) {
1189   // convert string input to an MD tree
1190   if ( typeof input ==="string" ) input = this.parse( input, dialect );
1191
1192   // Now convert the MD tree to an HTML tree
1193
1194   // remove references from the tree
1195   var attrs = extract_attr( input ),
1196       refs = {};
1197
1198   if ( attrs && attrs.references ) {
1199     refs = attrs.references;
1200   }
1201
1202   var html = convert_tree_to_html( input, refs , options );
1203   merge_text_nodes( html );
1204   return html;
1205 };
1206
1207 // For Spidermonkey based engines
1208 function mk_block_toSource() {
1209   return "Markdown.mk_block( " +
1210           uneval(this.toString()) +
1211           ", " +
1212           uneval(this.trailing) +
1213           ", " +
1214           uneval(this.lineNumber) +
1215           " )";
1216 }
1217
1218 // node
1219 function mk_block_inspect() {
1220   var util = require("util");
1221   return "Markdown.mk_block( " +
1222           util.inspect(this.toString()) +
1223           ", " +
1224           util.inspect(this.trailing) +
1225           ", " +
1226           util.inspect(this.lineNumber) +
1227           " )";
1228
1229 }
1230
1231 var mk_block = Markdown.mk_block = function(block, trail, line) {
1232   // Be helpful for default case in tests.
1233   if ( arguments.length == 1 ) trail = "\n\n";
1234
1235   var s = new String(block);
1236   s.trailing = trail;
1237   // To make it clear its not just a string
1238   s.inspect = mk_block_inspect;
1239   s.toSource = mk_block_toSource;
1240
1241   if ( line != undefined )
1242     s.lineNumber = line;
1243
1244   return s;
1245 };
1246
1247 function count_lines( str ) {
1248   var n = 0, i = -1;
1249   while ( ( i = str.indexOf("\n", i + 1) ) !== -1 ) n++;
1250   return n;
1251 }
1252
1253 // Internal - split source into rough blocks
1254 Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) {
1255   input = input.replace(/(\r\n|\n|\r)/g, "\n");
1256   // [\s\S] matches _anything_ (newline or space)
1257   // [^] is equivalent but doesn't work in IEs.
1258   var re = /([\s\S]+?)($|\n#|\n(?:\s*\n|$)+)/g,
1259       blocks = [],
1260       m;
1261
1262   var line_no = 1;
1263
1264   if ( ( m = /^(\s*\n)/.exec(input) ) != null ) {
1265     // skip (but count) leading blank lines
1266     line_no += count_lines( m[0] );
1267     re.lastIndex = m[0].length;
1268   }
1269
1270   while ( ( m = re.exec(input) ) !== null ) {
1271     if (m[2] == "\n#") {
1272       m[2] = "\n";
1273       re.lastIndex--;
1274     }
1275     blocks.push( mk_block( m[1], m[2], line_no ) );
1276     line_no += count_lines( m[0] );
1277   }
1278
1279   return blocks;
1280 };
1281
1282 /**
1283  *  Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ]
1284  *  - block (String): the block to process
1285  *  - next (Array): the following blocks
1286  *
1287  * Process `block` and return an array of JsonML nodes representing `block`.
1288  *
1289  * It does this by asking each block level function in the dialect to process
1290  * the block until one can. Succesful handling is indicated by returning an
1291  * array (with zero or more JsonML nodes), failure by a false value.
1292  *
1293  * Blocks handlers are responsible for calling [[Markdown#processInline]]
1294  * themselves as appropriate.
1295  *
1296  * If the blocks were split incorrectly or adjacent blocks need collapsing you
1297  * can adjust `next` in place using shift/splice etc.
1298  *
1299  * If any of this default behaviour is not right for the dialect, you can
1300  * define a `__call__` method on the dialect that will get invoked to handle
1301  * the block processing.
1302  */
1303 Markdown.prototype.processBlock = function processBlock( block, next ) {
1304   var cbs = this.dialect.block,
1305       ord = cbs.__order__;
1306
1307   if ( "__call__" in cbs ) {
1308     return cbs.__call__.call(this, block, next);
1309   }
1310
1311   for ( var i = 0; i < ord.length; i++ ) {
1312     //D:this.debug( "Testing", ord[i] );
1313     var res = cbs[ ord[i] ].call( this, block, next );
1314     if ( res ) {
1315       //D:this.debug("  matched");
1316       if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) )
1317         this.debug(ord[i], "didn't return a proper array");
1318       //D:this.debug( "" );
1319       return res;
1320     }
1321   }
1322
1323   // Uhoh! no match! Should we throw an error?
1324   return [];
1325 };
1326
1327 Markdown.prototype.processInline = function processInline( block ) {
1328   return this.dialect.inline.__call__.call( this, String( block ) );
1329 };
1330
1331 /**
1332  *  Markdown#toTree( source ) -> JsonML
1333  *  - source (String): markdown source to parse
1334  *
1335  *  Parse `source` into a JsonML tree representing the markdown document.
1336  **/
1337 // custom_tree means set this.tree to `custom_tree` and restore old value on return
1338 Markdown.prototype.toTree = function toTree( source, custom_root ) {
1339   var blocks = source instanceof Array ? source : this.split_blocks( source );
1340
1341   // Make tree a member variable so its easier to mess with in extensions
1342   var old_tree = this.tree;
1343   try {
1344     this.tree = custom_root || this.tree || [ "markdown" ];
1345
1346     blocks:
1347     while ( blocks.length ) {
1348       var b = this.processBlock( blocks.shift(), blocks );
1349
1350       // Reference blocks and the like won't return any content
1351       if ( !b.length ) continue blocks;
1352
1353       this.tree.push.apply( this.tree, b );
1354     }
1355     return this.tree;
1356   }
1357   finally {
1358     if ( custom_root ) {
1359       this.tree = old_tree;
1360     }
1361   }
1362 };
1363
1364 // Noop by default
1365 Markdown.prototype.debug = function () {
1366   var args = Array.prototype.slice.call( arguments);
1367   args.unshift(this.debug_indent);
1368   if ( typeof print !== "undefined" )
1369       print.apply( print, args );
1370   if ( typeof console !== "undefined" && typeof console.log !== "undefined" )
1371       console.log.apply( null, args );
1372 }
1373
1374 Markdown.prototype.loop_re_over_block = function( re, block, cb ) {
1375   // Dont use /g regexps with this
1376   var m,
1377       b = block.valueOf();
1378
1379   while ( b.length && (m = re.exec(b) ) != null ) {
1380     b = b.substr( m[0].length );
1381     cb.call(this, m);
1382   }
1383   return b;
1384 };
1385
1386 /**
1387  * Markdown.dialects
1388  *
1389  * Namespace of built-in dialects.
1390  **/
1391 Markdown.dialects = {};
1392
1393 /**
1394  * Markdown.dialects.Gruber
1395  *
1396  * The default dialect that follows the rules set out by John Gruber's
1397  * markdown.pl as closely as possible. Well actually we follow the behaviour of
1398  * that script which in some places is not exactly what the syntax web page
1399  * says.
1400  **/
1401 Markdown.dialects.Gruber = {
1402   block: {
1403     atxHeader: function atxHeader( block, next ) {
1404       var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ );
1405
1406       if ( !m ) return undefined;
1407
1408       var header = [ "header", { level: m[ 1 ].length } ];
1409       Array.prototype.push.apply(header, this.processInline(m[ 2 ]));
1410
1411       if ( m[0].length < block.length )
1412         next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1413
1414       return [ header ];
1415     },
1416
1417     setextHeader: function setextHeader( block, next ) {
1418       var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ );
1419
1420       if ( !m ) return undefined;
1421
1422       var level = ( m[ 2 ] === "=" ) ? 1 : 2;
1423       var header = [ "header", { level : level }, m[ 1 ] ];
1424
1425       if ( m[0].length < block.length )
1426         next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1427
1428       return [ header ];
1429     },
1430
1431     code: function code( block, next ) {
1432       // |    Foo
1433       // |bar
1434       // should be a code block followed by a paragraph. Fun
1435       //
1436       // There might also be adjacent code block to merge.
1437
1438       var ret = [],
1439           re = /^(?: {0,3}\t| {4})(.*)\n?/,
1440           lines;
1441
1442       // 4 spaces + content
1443       if ( !block.match( re ) ) return undefined;
1444
1445       block_search:
1446       do {
1447         // Now pull out the rest of the lines
1448         var b = this.loop_re_over_block(
1449                   re, block.valueOf(), function( m ) { ret.push( m[1] ); } );
1450
1451         if ( b.length ) {
1452           // Case alluded to in first comment. push it back on as a new block
1453           next.unshift( mk_block(b, block.trailing) );
1454           break block_search;
1455         }
1456         else if ( next.length ) {
1457           // Check the next block - it might be code too
1458           if ( !next[0].match( re ) ) break block_search;
1459
1460           // Pull how how many blanks lines follow - minus two to account for .join
1461           ret.push ( block.trailing.replace(/[^\n]/g, "").substring(2) );
1462
1463           block = next.shift();
1464         }
1465         else {
1466           break block_search;
1467         }
1468       } while ( true );
1469
1470       return [ [ "code_block", ret.join("\n") ] ];
1471     },
1472
1473     horizRule: function horizRule( block, next ) {
1474       // this needs to find any hr in the block to handle abutting blocks
1475       var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ );
1476
1477       if ( !m ) {
1478         return undefined;
1479       }
1480
1481       var jsonml = [ [ "hr" ] ];
1482
1483       // if there's a leading abutting block, process it
1484       if ( m[ 1 ] ) {
1485         jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) );
1486       }
1487
1488       // if there's a trailing abutting block, stick it into next
1489       if ( m[ 3 ] ) {
1490         next.unshift( mk_block( m[ 3 ] ) );
1491       }
1492
1493       return jsonml;
1494     },
1495
1496     // There are two types of lists. Tight and loose. Tight lists have no whitespace
1497     // between the items (and result in text just in the <li>) and loose lists,
1498     // which have an empty line between list items, resulting in (one or more)
1499     // paragraphs inside the <li>.
1500     //
1501     // There are all sorts weird edge cases about the original markdown.pl's
1502     // handling of lists:
1503     //
1504     // * Nested lists are supposed to be indented by four chars per level. But
1505     //   if they aren't, you can get a nested list by indenting by less than
1506     //   four so long as the indent doesn't match an indent of an existing list
1507     //   item in the 'nest stack'.
1508     //
1509     // * The type of the list (bullet or number) is controlled just by the
1510     //    first item at the indent. Subsequent changes are ignored unless they
1511     //    are for nested lists
1512     //
1513     lists: (function( ) {
1514       // Use a closure to hide a few variables.
1515       var any_list = "[*+-]|\\d+\\.",
1516           bullet_list = /[*+-]/,
1517           number_list = /\d+\./,
1518           // Capture leading indent as it matters for determining nested lists.
1519           is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ),
1520           indent_re = "(?: {0,3}\\t| {4})";
1521
1522       // TODO: Cache this regexp for certain depths.
1523       // Create a regexp suitable for matching an li for a given stack depth
1524       function regex_for_depth( depth ) {
1525
1526         return new RegExp(
1527           // m[1] = indent, m[2] = list_type
1528           "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" +
1529           // m[3] = cont
1530           "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})"
1531         );
1532       }
1533       function expand_tab( input ) {
1534         return input.replace( / {0,3}\t/g, "    " );
1535       }
1536
1537       // Add inline content `inline` to `li`. inline comes from processInline
1538       // so is an array of content
1539       function add(li, loose, inline, nl) {
1540         if ( loose ) {
1541           li.push( [ "para" ].concat(inline) );
1542           return;
1543         }
1544         // Hmmm, should this be any block level element or just paras?
1545         var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para"
1546                    ? li[li.length -1]
1547                    : li;
1548
1549         // If there is already some content in this list, add the new line in
1550         if ( nl && li.length > 1 ) inline.unshift(nl);
1551
1552         for ( var i = 0; i < inline.length; i++ ) {
1553           var what = inline[i],
1554               is_str = typeof what == "string";
1555           if ( is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) {
1556             add_to[ add_to.length-1 ] += what;
1557           }
1558           else {
1559             add_to.push( what );
1560           }
1561         }
1562       }
1563
1564       // contained means have an indent greater than the current one. On
1565       // *every* line in the block
1566       function get_contained_blocks( depth, blocks ) {
1567
1568         var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ),
1569             replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"),
1570             ret = [];
1571
1572         while ( blocks.length > 0 ) {
1573           if ( re.exec( blocks[0] ) ) {
1574             var b = blocks.shift(),
1575                 // Now remove that indent
1576                 x = b.replace( replace, "");
1577
1578             ret.push( mk_block( x, b.trailing, b.lineNumber ) );
1579           }
1580           else {
1581             break;
1582           }
1583         }
1584         return ret;
1585       }
1586
1587       // passed to stack.forEach to turn list items up the stack into paras
1588       function paragraphify(s, i, stack) {
1589         var list = s.list;
1590         var last_li = list[list.length-1];
1591
1592         if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
1593           return;
1594         }
1595         if ( i + 1 == stack.length ) {
1596           // Last stack frame
1597           // Keep the same array, but replace the contents
1598           last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ) );
1599         }
1600         else {
1601           var sublist = last_li.pop();
1602           last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
1603         }
1604       }
1605
1606       // The matcher function
1607       return function( block, next ) {
1608         var m = block.match( is_list_re );
1609         if ( !m ) return undefined;
1610
1611         function make_list( m ) {
1612           var list = bullet_list.exec( m[2] )
1613                    ? ["bulletlist"]
1614                    : ["numberlist"];
1615
1616           stack.push( { list: list, indent: m[1] } );
1617           return list;
1618         }
1619
1620
1621         var stack = [], // Stack of lists for nesting.
1622             list = make_list( m ),
1623             last_li,
1624             loose = false,
1625             ret = [ stack[0].list ],
1626             i;
1627
1628         // Loop to search over block looking for inner block elements and loose lists
1629         loose_search:
1630         while ( true ) {
1631           // Split into lines preserving new lines at end of line
1632           var lines = block.split( /(?=\n)/ );
1633
1634           // We have to grab all lines for a li and call processInline on them
1635           // once as there are some inline things that can span lines.
1636           var li_accumulate = "";
1637
1638           // Loop over the lines in this block looking for tight lists.
1639           tight_search:
1640           for ( var line_no = 0; line_no < lines.length; line_no++ ) {
1641             var nl = "",
1642                 l = lines[line_no].replace(/^\n/, function(n) { nl = n; return ""; });
1643
1644             // TODO: really should cache this
1645             var line_re = regex_for_depth( stack.length );
1646
1647             m = l.match( line_re );
1648             //print( "line:", uneval(l), "\nline match:", uneval(m) );
1649
1650             // We have a list item
1651             if ( m[1] !== undefined ) {
1652               // Process the previous list item, if any
1653               if ( li_accumulate.length ) {
1654                 add( last_li, loose, this.processInline( li_accumulate ), nl );
1655                 // Loose mode will have been dealt with. Reset it
1656                 loose = false;
1657                 li_accumulate = "";
1658               }
1659
1660               m[1] = expand_tab( m[1] );
1661               var wanted_depth = Math.floor(m[1].length/4)+1;
1662               //print( "want:", wanted_depth, "stack:", stack.length);
1663               if ( wanted_depth > stack.length ) {
1664                 // Deep enough for a nested list outright
1665                 //print ( "new nested list" );
1666                 list = make_list( m );
1667                 last_li.push( list );
1668                 last_li = list[1] = [ "listitem" ];
1669               }
1670               else {
1671                 // We aren't deep enough to be strictly a new level. This is
1672                 // where Md.pl goes nuts. If the indent matches a level in the
1673                 // stack, put it there, else put it one deeper then the
1674                 // wanted_depth deserves.
1675                 var found = false;
1676                 for ( i = 0; i < stack.length; i++ ) {
1677                   if ( stack[ i ].indent != m[1] ) continue;
1678                   list = stack[ i ].list;
1679                   stack.splice( i+1, stack.length - (i+1) );
1680                   found = true;
1681                   break;
1682                 }
1683
1684                 if (!found) {
1685                   //print("not found. l:", uneval(l));
1686                   wanted_depth++;
1687                   if ( wanted_depth <= stack.length ) {
1688                     stack.splice(wanted_depth, stack.length - wanted_depth);
1689                     //print("Desired depth now", wanted_depth, "stack:", stack.length);
1690                     list = stack[wanted_depth-1].list;
1691                     //print("list:", uneval(list) );
1692                   }
1693                   else {
1694                     //print ("made new stack for messy indent");
1695                     list = make_list(m);
1696                     last_li.push(list);
1697                   }
1698                 }
1699
1700                 //print( uneval(list), "last", list === stack[stack.length-1].list );
1701                 last_li = [ "listitem" ];
1702                 list.push(last_li);
1703               } // end depth of shenegains
1704               nl = "";
1705             }
1706
1707             // Add content
1708             if ( l.length > m[0].length ) {
1709               li_accumulate += nl + l.substr( m[0].length );
1710             }
1711           } // tight_search
1712
1713           if ( li_accumulate.length ) {
1714             add( last_li, loose, this.processInline( li_accumulate ), nl );
1715             // Loose mode will have been dealt with. Reset it
1716             loose = false;
1717             li_accumulate = "";
1718           }
1719
1720           // Look at the next block - we might have a loose list. Or an extra
1721           // paragraph for the current li
1722           var contained = get_contained_blocks( stack.length, next );
1723
1724           // Deal with code blocks or properly nested lists
1725           if ( contained.length > 0 ) {
1726             // Make sure all listitems up the stack are paragraphs
1727             forEach( stack, paragraphify, this);
1728
1729             last_li.push.apply( last_li, this.toTree( contained, [] ) );
1730           }
1731
1732           var next_block = next[0] && next[0].valueOf() || "";
1733
1734           if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) {
1735             block = next.shift();
1736
1737             // Check for an HR following a list: features/lists/hr_abutting
1738             var hr = this.dialect.block.horizRule( block, next );
1739
1740             if ( hr ) {
1741               ret.push.apply(ret, hr);
1742               break;
1743             }
1744
1745             // Make sure all listitems up the stack are paragraphs
1746             forEach( stack, paragraphify, this);
1747
1748             loose = true;
1749             continue loose_search;
1750           }
1751           break;
1752         } // loose_search
1753
1754         return ret;
1755       };
1756     })(),
1757
1758     blockquote: function blockquote( block, next ) {
1759       if ( !block.match( /^>/m ) )
1760         return undefined;
1761
1762       var jsonml = [];
1763
1764       // separate out the leading abutting block, if any. I.e. in this case:
1765       //
1766       //  a
1767       //  > b
1768       //
1769       if ( block[ 0 ] != ">" ) {
1770         var lines = block.split( /\n/ ),
1771             prev = [],
1772             line_no = block.lineNumber;
1773
1774         // keep shifting lines until you find a crotchet
1775         while ( lines.length && lines[ 0 ][ 0 ] != ">" ) {
1776             prev.push( lines.shift() );
1777             line_no++;
1778         }
1779
1780         var abutting = mk_block( prev.join( "\n" ), "\n", block.lineNumber );
1781         jsonml.push.apply( jsonml, this.processBlock( abutting, [] ) );
1782         // reassemble new block of just block quotes!
1783         block = mk_block( lines.join( "\n" ), block.trailing, line_no );
1784       }
1785
1786
1787       // if the next block is also a blockquote merge it in
1788       while ( next.length && next[ 0 ][ 0 ] == ">" ) {
1789         var b = next.shift();
1790         block = mk_block( block + block.trailing + b, b.trailing, block.lineNumber );
1791       }
1792
1793       // Strip off the leading "> " and re-process as a block.
1794       var input = block.replace( /^> ?/gm, "" ),
1795           old_tree = this.tree,
1796           processedBlock = this.toTree( input, [ "blockquote" ] ),
1797           attr = extract_attr( processedBlock );
1798
1799       // If any link references were found get rid of them
1800       if ( attr && attr.references ) {
1801         delete attr.references;
1802         // And then remove the attribute object if it's empty
1803         if ( isEmpty( attr ) ) {
1804           processedBlock.splice( 1, 1 );
1805         }
1806       }
1807
1808       jsonml.push( processedBlock );
1809       return jsonml;
1810     },
1811
1812     referenceDefn: function referenceDefn( block, next) {
1813       var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/;
1814       // interesting matches are [ , ref_id, url, , title, title ]
1815
1816       if ( !block.match(re) )
1817         return undefined;
1818
1819       // make an attribute node if it doesn't exist
1820       if ( !extract_attr( this.tree ) ) {
1821         this.tree.splice( 1, 0, {} );
1822       }
1823
1824       var attrs = extract_attr( this.tree );
1825
1826       // make a references hash if it doesn't exist
1827       if ( attrs.references === undefined ) {
1828         attrs.references = {};
1829       }
1830
1831       var b = this.loop_re_over_block(re, block, function( m ) {
1832
1833         if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1834           m[2] = m[2].substring( 1, m[2].length - 1 );
1835
1836         var ref = attrs.references[ m[1].toLowerCase() ] = {
1837           href: m[2]
1838         };
1839
1840         if ( m[4] !== undefined )
1841           ref.title = m[4];
1842         else if ( m[5] !== undefined )
1843           ref.title = m[5];
1844
1845       } );
1846
1847       if ( b.length )
1848         next.unshift( mk_block( b, block.trailing ) );
1849
1850       return [];
1851     },
1852
1853     para: function para( block, next ) {
1854       // everything's a para!
1855       return [ ["para"].concat( this.processInline( block ) ) ];
1856     }
1857   }
1858 };
1859
1860 Markdown.dialects.Gruber.inline = {
1861
1862     __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) {
1863       var m,
1864           res,
1865           lastIndex = 0;
1866
1867       patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__;
1868       var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" );
1869
1870       m = re.exec( text );
1871       if (!m) {
1872         // Just boring text
1873         return [ text.length, text ];
1874       }
1875       else if ( m[1] ) {
1876         // Some un-interesting text matched. Return that first
1877         return [ m[1].length, m[1] ];
1878       }
1879
1880       var res;
1881       if ( m[2] in this.dialect.inline ) {
1882         res = this.dialect.inline[ m[2] ].call(
1883                   this,
1884                   text.substr( m.index ), m, previous_nodes || [] );
1885       }
1886       // Default for now to make dev easier. just slurp special and output it.
1887       res = res || [ m[2].length, m[2] ];
1888       return res;
1889     },
1890
1891     __call__: function inline( text, patterns ) {
1892
1893       var out = [],
1894           res;
1895
1896       function add(x) {
1897         //D:self.debug("  adding output", uneval(x));
1898         if ( typeof x == "string" && typeof out[out.length-1] == "string" )
1899           out[ out.length-1 ] += x;
1900         else
1901           out.push(x);
1902       }
1903
1904       while ( text.length > 0 ) {
1905         res = this.dialect.inline.__oneElement__.call(this, text, patterns, out );
1906         text = text.substr( res.shift() );
1907         forEach(res, add )
1908       }
1909
1910       return out;
1911     },
1912
1913     // These characters are intersting elsewhere, so have rules for them so that
1914     // chunks of plain text blocks don't include them
1915     "]": function () {},
1916     "}": function () {},
1917
1918     __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
1919
1920     "\\": function escaped( text ) {
1921       // [ length of input processed, node/children to add... ]
1922       // Only esacape: \ ` * _ { } [ ] ( ) # * + - . !
1923       if ( this.dialect.inline.__escape__.exec( text ) )
1924         return [ 2, text.charAt( 1 ) ];
1925       else
1926         // Not an esacpe
1927         return [ 1, "\\" ];
1928     },
1929
1930     "![": function image( text ) {
1931
1932       // Unlike images, alt text is plain text only. no other elements are
1933       // allowed in there
1934
1935       // ![Alt text](/path/to/img.jpg "Optional title")
1936       //      1          2            3       4         <--- captures
1937       var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ );
1938
1939       if ( m ) {
1940         if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1941           m[2] = m[2].substring( 1, m[2].length - 1 );
1942
1943         m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0];
1944
1945         var attrs = { alt: m[1], href: m[2] || "" };
1946         if ( m[4] !== undefined)
1947           attrs.title = m[4];
1948
1949         return [ m[0].length, [ "img", attrs ] ];
1950       }
1951
1952       // ![Alt text][id]
1953       m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ );
1954
1955       if ( m ) {
1956         // We can't check if the reference is known here as it likely wont be
1957         // found till after. Check it in md tree->hmtl tree conversion
1958         return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), original: m[0] } ] ];
1959       }
1960
1961       // Just consume the '!['
1962       return [ 2, "![" ];
1963     },
1964
1965     "[": function link( text ) {
1966
1967       var orig = String(text);
1968       // Inline content is possible inside `link text`
1969       var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" );
1970
1971       // No closing ']' found. Just consume the [
1972       if ( !res ) return [ 1, "[" ];
1973
1974       var consumed = 1 + res[ 0 ],
1975           children = res[ 1 ],
1976           link,
1977           attrs;
1978
1979       // At this point the first [...] has been parsed. See what follows to find
1980       // out which kind of link we are (reference or direct url)
1981       text = text.substr( consumed );
1982
1983       // [link text](/path/to/img.jpg "Optional title")
1984       //                 1            2       3         <--- captures
1985       // This will capture up to the last paren in the block. We then pull
1986       // back based on if there a matching ones in the url
1987       //    ([here](/url/(test))
1988       // The parens have to be balanced
1989       var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
1990       if ( m ) {
1991         var url = m[1];
1992         consumed += m[0].length;
1993
1994         if ( url && url[0] == "<" && url[url.length-1] == ">" )
1995           url = url.substring( 1, url.length - 1 );
1996
1997         // If there is a title we don't have to worry about parens in the url
1998         if ( !m[3] ) {
1999           var open_parens = 1; // One open that isn't in the capture
2000           for ( var len = 0; len < url.length; len++ ) {
2001             switch ( url[len] ) {
2002             case "(":
2003               open_parens++;
2004               break;
2005             case ")":
2006               if ( --open_parens == 0) {
2007                 consumed -= url.length - len;
2008                 url = url.substring(0, len);
2009               }
2010               break;
2011             }
2012           }
2013         }
2014
2015         // Process escapes only
2016         url = this.dialect.inline.__call__.call( this, url, /\\/ )[0];
2017
2018         attrs = { href: url || "" };
2019         if ( m[3] !== undefined)
2020           attrs.title = m[3];
2021
2022         link = [ "link", attrs ].concat( children );
2023         return [ consumed, link ];
2024       }
2025
2026       // [Alt text][id]
2027       // [Alt text] [id]
2028       m = text.match( /^\s*\[(.*?)\]/ );
2029
2030       if ( m ) {
2031
2032         consumed += m[ 0 ].length;
2033
2034         // [links][] uses links as its reference
2035         attrs = { ref: ( m[ 1 ] || String(children) ).toLowerCase(),  original: orig.substr( 0, consumed ) };
2036
2037         link = [ "link_ref", attrs ].concat( children );
2038
2039         // We can't check if the reference is known here as it likely wont be
2040         // found till after. Check it in md tree->hmtl tree conversion.
2041         // Store the original so that conversion can revert if the ref isn't found.
2042         return [ consumed, link ];
2043       }
2044
2045       // [id]
2046       // Only if id is plain (no formatting.)
2047       if ( children.length == 1 && typeof children[0] == "string" ) {
2048
2049         attrs = { ref: children[0].toLowerCase(),  original: orig.substr( 0, consumed ) };
2050         link = [ "link_ref", attrs, children[0] ];
2051         return [ consumed, link ];
2052       }
2053
2054       // Just consume the "["
2055       return [ 1, "[" ];
2056     },
2057
2058
2059     "<": function autoLink( text ) {
2060       var m;
2061
2062       if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) {
2063         if ( m[3] ) {
2064           return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ];
2065
2066         }
2067         else if ( m[2] == "mailto" ) {
2068           return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ];
2069         }
2070         else
2071           return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ];
2072       }
2073
2074       return [ 1, "<" ];
2075     },
2076
2077     "`": function inlineCode( text ) {
2078       // Inline code block. as many backticks as you like to start it
2079       // Always skip over the opening ticks.
2080       var m = text.match( /(`+)(([\s\S]*?)\1)/ );
2081
2082       if ( m && m[2] )
2083         return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ];
2084       else {
2085         // TODO: No matching end code found - warn!
2086         return [ 1, "`" ];
2087       }
2088     },
2089
2090     "  \n": function lineBreak( text ) {
2091       return [ 3, [ "linebreak" ] ];
2092     }
2093
2094 };
2095
2096 // Meta Helper/generator method for em and strong handling
2097 function strong_em( tag, md ) {
2098
2099   var state_slot = tag + "_state",
2100       other_slot = tag == "strong" ? "em_state" : "strong_state";
2101
2102   function CloseTag(len) {
2103     this.len_after = len;
2104     this.name = "close_" + md;
2105   }
2106
2107   return function ( text, orig_match ) {
2108
2109     if ( this[state_slot][0] == md ) {
2110       // Most recent em is of this type
2111       //D:this.debug("closing", md);
2112       this[state_slot].shift();
2113
2114       // "Consume" everything to go back to the recrusion in the else-block below
2115       return[ text.length, new CloseTag(text.length-md.length) ];
2116     }
2117     else {
2118       // Store a clone of the em/strong states
2119       var other = this[other_slot].slice(),
2120           state = this[state_slot].slice();
2121
2122       this[state_slot].unshift(md);
2123
2124       //D:this.debug_indent += "  ";
2125
2126       // Recurse
2127       var res = this.processInline( text.substr( md.length ) );
2128       //D:this.debug_indent = this.debug_indent.substr(2);
2129
2130       var last = res[res.length - 1];
2131
2132       //D:this.debug("processInline from", tag + ": ", uneval( res ) );
2133
2134       var check = this[state_slot].shift();
2135       if ( last instanceof CloseTag ) {
2136         res.pop();
2137         // We matched! Huzzah.
2138         var consumed = text.length - last.len_after;
2139         return [ consumed, [ tag ].concat(res) ];
2140       }
2141       else {
2142         // Restore the state of the other kind. We might have mistakenly closed it.
2143         this[other_slot] = other;
2144         this[state_slot] = state;
2145
2146         // We can't reuse the processed result as it could have wrong parsing contexts in it.
2147         return [ md.length, md ];
2148       }
2149     }
2150   }; // End returned function
2151 }
2152
2153 Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**");
2154 Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__");
2155 Markdown.dialects.Gruber.inline["*"]  = strong_em("em", "*");
2156 Markdown.dialects.Gruber.inline["_"]  = strong_em("em", "_");
2157
2158
2159 // Build default order from insertion order.
2160 Markdown.buildBlockOrder = function(d) {
2161   var ord = [];
2162   for ( var i in d ) {
2163     if ( i == "__order__" || i == "__call__" ) continue;
2164     ord.push( i );
2165   }
2166   d.__order__ = ord;
2167 };
2168
2169 // Build patterns for inline matcher
2170 Markdown.buildInlinePatterns = function(d) {
2171   var patterns = [];
2172
2173   for ( var i in d ) {
2174     // __foo__ is reserved and not a pattern
2175     if ( i.match( /^__.*__$/) ) continue;
2176     var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" )
2177              .replace( /\n/, "\\n" );
2178     patterns.push( i.length == 1 ? l : "(?:" + l + ")" );
2179   }
2180
2181   patterns = patterns.join("|");
2182   d.__patterns__ = patterns;
2183   //print("patterns:", uneval( patterns ) );
2184
2185   var fn = d.__call__;
2186   d.__call__ = function(text, pattern) {
2187     if ( pattern != undefined ) {
2188       return fn.call(this, text, pattern);
2189     }
2190     else
2191     {
2192       return fn.call(this, text, patterns);
2193     }
2194   };
2195 };
2196
2197 Markdown.DialectHelpers = {};
2198 Markdown.DialectHelpers.inline_until_char = function( text, want ) {
2199   var consumed = 0,
2200       nodes = [];
2201
2202   while ( true ) {
2203     if ( text.charAt( consumed ) == want ) {
2204       // Found the character we were looking for
2205       consumed++;
2206       return [ consumed, nodes ];
2207     }
2208
2209     if ( consumed >= text.length ) {
2210       // No closing char found. Abort.
2211       return null;
2212     }
2213
2214     var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) );
2215     consumed += res[ 0 ];
2216     // Add any returned nodes.
2217     nodes.push.apply( nodes, res.slice( 1 ) );
2218   }
2219 }
2220
2221 // Helper function to make sub-classing a dialect easier
2222 Markdown.subclassDialect = function( d ) {
2223   function Block() {}
2224   Block.prototype = d.block;
2225   function Inline() {}
2226   Inline.prototype = d.inline;
2227
2228   return { block: new Block(), inline: new Inline() };
2229 };
2230
2231 Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block );
2232 Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline );
2233
2234 Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber );
2235
2236 Markdown.dialects.Maruku.processMetaHash = function processMetaHash( meta_string ) {
2237   var meta = split_meta_hash( meta_string ),
2238       attr = {};
2239
2240   for ( var i = 0; i < meta.length; ++i ) {
2241     // id: #foo
2242     if ( /^#/.test( meta[ i ] ) ) {
2243       attr.id = meta[ i ].substring( 1 );
2244     }
2245     // class: .foo
2246     else if ( /^\./.test( meta[ i ] ) ) {
2247       // if class already exists, append the new one
2248       if ( attr["class"] ) {
2249         attr["class"] = attr["class"] + meta[ i ].replace( /./, " " );
2250       }
2251       else {
2252         attr["class"] = meta[ i ].substring( 1 );
2253       }
2254     }
2255     // attribute: foo=bar
2256     else if ( /\=/.test( meta[ i ] ) ) {
2257       var s = meta[ i ].split( /\=/ );
2258       attr[ s[ 0 ] ] = s[ 1 ];
2259     }
2260   }
2261
2262   return attr;
2263 }
2264
2265 function split_meta_hash( meta_string ) {
2266   var meta = meta_string.split( "" ),
2267       parts = [ "" ],
2268       in_quotes = false;
2269
2270   while ( meta.length ) {
2271     var letter = meta.shift();
2272     switch ( letter ) {
2273       case " " :
2274         // if we're in a quoted section, keep it
2275         if ( in_quotes ) {
2276           parts[ parts.length - 1 ] += letter;
2277         }
2278         // otherwise make a new part
2279         else {
2280           parts.push( "" );
2281         }
2282         break;
2283       case "'" :
2284       case '"' :
2285         // reverse the quotes and move straight on
2286         in_quotes = !in_quotes;
2287         break;
2288       case "\\" :
2289         // shift off the next letter to be used straight away.
2290         // it was escaped so we'll keep it whatever it is
2291         letter = meta.shift();
2292       default :
2293         parts[ parts.length - 1 ] += letter;
2294         break;
2295     }
2296   }
2297
2298   return parts;
2299 }
2300
2301 Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) {
2302   // we're only interested in the first block
2303   if ( block.lineNumber > 1 ) return undefined;
2304
2305   // document_meta blocks consist of one or more lines of `Key: Value\n`
2306   if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined;
2307
2308   // make an attribute node if it doesn't exist
2309   if ( !extract_attr( this.tree ) ) {
2310     this.tree.splice( 1, 0, {} );
2311   }
2312
2313   var pairs = block.split( /\n/ );
2314   for ( p in pairs ) {
2315     var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ),
2316         key = m[ 1 ].toLowerCase(),
2317         value = m[ 2 ];
2318
2319     this.tree[ 1 ][ key ] = value;
2320   }
2321
2322   // document_meta produces no content!
2323   return [];
2324 };
2325
2326 Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) {
2327   // check if the last line of the block is an meta hash
2328   var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ );
2329   if ( !m ) return undefined;
2330
2331   // process the meta hash
2332   var attr = this.dialect.processMetaHash( m[ 2 ] );
2333
2334   var hash;
2335
2336   // if we matched ^ then we need to apply meta to the previous block
2337   if ( m[ 1 ] === "" ) {
2338     var node = this.tree[ this.tree.length - 1 ];
2339     hash = extract_attr( node );
2340
2341     // if the node is a string (rather than JsonML), bail
2342     if ( typeof node === "string" ) return undefined;
2343
2344     // create the attribute hash if it doesn't exist
2345     if ( !hash ) {
2346       hash = {};
2347       node.splice( 1, 0, hash );
2348     }
2349
2350     // add the attributes in
2351     for ( a in attr ) {
2352       hash[ a ] = attr[ a ];
2353     }
2354
2355     // return nothing so the meta hash is removed
2356     return [];
2357   }
2358
2359   // pull the meta hash off the block and process what's left
2360   var b = block.replace( /\n.*$/, "" ),
2361       result = this.processBlock( b, [] );
2362
2363   // get or make the attributes hash
2364   hash = extract_attr( result[ 0 ] );
2365   if ( !hash ) {
2366     hash = {};
2367     result[ 0 ].splice( 1, 0, hash );
2368   }
2369
2370   // attach the attributes to the block
2371   for ( a in attr ) {
2372     hash[ a ] = attr[ a ];
2373   }
2374
2375   return result;
2376 };
2377
2378 Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) {
2379   // one or more terms followed by one or more definitions, in a single block
2380   var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/,
2381       list = [ "dl" ],
2382       i, m;
2383
2384   // see if we're dealing with a tight or loose block
2385   if ( ( m = block.match( tight ) ) ) {
2386     // pull subsequent tight DL blocks out of `next`
2387     var blocks = [ block ];
2388     while ( next.length && tight.exec( next[ 0 ] ) ) {
2389       blocks.push( next.shift() );
2390     }
2391
2392     for ( var b = 0; b < blocks.length; ++b ) {
2393       var m = blocks[ b ].match( tight ),
2394           terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ),
2395           defns = m[ 2 ].split( /\n:\s+/ );
2396
2397       // print( uneval( m ) );
2398
2399       for ( i = 0; i < terms.length; ++i ) {
2400         list.push( [ "dt", terms[ i ] ] );
2401       }
2402
2403       for ( i = 0; i < defns.length; ++i ) {
2404         // run inline processing over the definition
2405         list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) );
2406       }
2407     }
2408   }
2409   else {
2410     return undefined;
2411   }
2412
2413   return [ list ];
2414 };
2415
2416 // splits on unescaped instances of @ch. If @ch is not a character the result
2417 // can be unpredictable
2418
2419 Markdown.dialects.Maruku.block.table = function table (block, next) {
2420
2421     var _split_on_unescaped = function(s, ch) {
2422         ch = ch || '\\s';
2423         if (ch.match(/^[\\|\[\]{}?*.+^$]$/)) { ch = '\\' + ch; }
2424         var res = [ ],
2425             r = new RegExp('^((?:\\\\.|[^\\\\' + ch + '])*)' + ch + '(.*)'),
2426             m;
2427         while(m = s.match(r)) {
2428             res.push(m[1]);
2429             s = m[2];
2430         }
2431         res.push(s);
2432         return res;
2433     }
2434
2435     var leading_pipe = /^ {0,3}\|(.+)\n {0,3}\|\s*([\-:]+[\-| :]*)\n((?:\s*\|.*(?:\n|$))*)(?=\n|$)/,
2436         // find at least an unescaped pipe in each line
2437         no_leading_pipe = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)\n {0,3}([\-:]+\s*\|[\-| :]*)\n((?:(?:\\.|[^\\|])*\|.*(?:\n|$))*)(?=\n|$)/,
2438         i, m;
2439     if (m = block.match(leading_pipe)) {
2440         // remove leading pipes in contents
2441         // (header and horizontal rule already have the leading pipe left out)
2442         m[3] = m[3].replace(/^\s*\|/gm, '');
2443     } else if (! ( m = block.match(no_leading_pipe))) {
2444         return undefined;
2445     }
2446
2447     var table = [ "table", [ "thead", [ "tr" ] ], [ "tbody" ] ];
2448
2449     // remove trailing pipes, then split on pipes
2450     // (no escaped pipes are allowed in horizontal rule)
2451     m[2] = m[2].replace(/\|\s*$/, '').split('|');
2452
2453     // process alignment
2454     var html_attrs = [ ];
2455     forEach (m[2], function (s) {
2456         if (s.match(/^\s*-+:\s*$/))       html_attrs.push({align: "right"});
2457         else if (s.match(/^\s*:-+\s*$/))  html_attrs.push({align: "left"});
2458         else if (s.match(/^\s*:-+:\s*$/)) html_attrs.push({align: "center"});
2459         else                              html_attrs.push({});
2460     });
2461
2462     // now for the header, avoid escaped pipes
2463     m[1] = _split_on_unescaped(m[1].replace(/\|\s*$/, ''), '|');
2464     for (i = 0; i < m[1].length; i++) {
2465         table[1][1].push(['th', html_attrs[i] || {}].concat(
2466             this.processInline(m[1][i].trim())));
2467     }
2468
2469     // now for body contents
2470     forEach (m[3].replace(/\|\s*$/mg, '').split('\n'), function (row) {
2471         var html_row = ['tr'];
2472         row = _split_on_unescaped(row, '|');
2473         for (i = 0; i < row.length; i++) {
2474             html_row.push(['td', html_attrs[i] || {}].concat(this.processInline(row[i].trim())));
2475         }
2476         table[2].push(html_row);
2477     }, this);
2478
2479     return [table];
2480 }
2481
2482 Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) {
2483   if ( !out.length ) {
2484     return [ 2, "{:" ];
2485   }
2486
2487   // get the preceeding element
2488   var before = out[ out.length - 1 ];
2489
2490   if ( typeof before === "string" ) {
2491     return [ 2, "{:" ];
2492   }
2493
2494   // match a meta hash
2495   var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ );
2496
2497   // no match, false alarm
2498   if ( !m ) {
2499     return [ 2, "{:" ];
2500   }
2501
2502   // attach the attributes to the preceeding element
2503   var meta = this.dialect.processMetaHash( m[ 1 ] ),
2504       attr = extract_attr( before );
2505
2506   if ( !attr ) {
2507     attr = {};
2508     before.splice( 1, 0, attr );
2509   }
2510
2511   for ( var k in meta ) {
2512     attr[ k ] = meta[ k ];
2513   }
2514
2515   // cut out the string and replace it with nothing
2516   return [ m[ 0 ].length, "" ];
2517 };
2518
2519 Markdown.dialects.Maruku.inline.__escape__ = /^\\[\\`\*_{}\[\]()#\+.!\-|:]/;
2520
2521 Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block );
2522 Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline );
2523
2524 var isArray = Array.isArray || function(obj) {
2525   return Object.prototype.toString.call(obj) == "[object Array]";
2526 };
2527
2528 var forEach;
2529 // Don't mess with Array.prototype. Its not friendly
2530 if ( Array.prototype.forEach ) {
2531   forEach = function( arr, cb, thisp ) {
2532     return arr.forEach( cb, thisp );
2533   };
2534 }
2535 else {
2536   forEach = function(arr, cb, thisp) {
2537     for (var i = 0; i < arr.length; i++) {
2538       cb.call(thisp || arr, arr[i], i, arr);
2539     }
2540   }
2541 }
2542
2543 var isEmpty = function( obj ) {
2544   for ( var key in obj ) {
2545     if ( hasOwnProperty.call( obj, key ) ) {
2546       return false;
2547     }
2548   }
2549
2550   return true;
2551 }
2552
2553 function extract_attr( jsonml ) {
2554   return isArray(jsonml)
2555       && jsonml.length > 1
2556       && typeof jsonml[ 1 ] === "object"
2557       && !( isArray(jsonml[ 1 ]) )
2558       ? jsonml[ 1 ]
2559       : undefined;
2560 }
2561
2562
2563
2564 /**
2565  *  renderJsonML( jsonml[, options] ) -> String
2566  *  - jsonml (Array): JsonML array to render to XML
2567  *  - options (Object): options
2568  *
2569  *  Converts the given JsonML into well-formed XML.
2570  *
2571  *  The options currently understood are:
2572  *
2573  *  - root (Boolean): wether or not the root node should be included in the
2574  *    output, or just its children. The default `false` is to not include the
2575  *    root itself.
2576  */
2577 expose.renderJsonML = function( jsonml, options ) {
2578   options = options || {};
2579   // include the root element in the rendered output?
2580   options.root = options.root || false;
2581
2582   var content = [];
2583
2584   if ( options.root ) {
2585     content.push( render_tree( jsonml ) );
2586   }
2587   else {
2588     jsonml.shift(); // get rid of the tag
2589     if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2590       jsonml.shift(); // get rid of the attributes
2591     }
2592
2593     while ( jsonml.length ) {
2594       content.push( render_tree( jsonml.shift() ) );
2595     }
2596   }
2597
2598   return content.join( "\n\n" );
2599 };
2600
2601 function escapeHTML( text ) {
2602   return text.replace( /&/g, "&amp;" )
2603              .replace( /</g, "&lt;" )
2604              .replace( />/g, "&gt;" )
2605              .replace( /"/g, "&quot;" )
2606              .replace( /'/g, "&#39;" );
2607 }
2608
2609 function render_tree( jsonml ) {
2610   // basic case
2611   if ( typeof jsonml === "string" ) {
2612     return jsonml; // modified for deck.smarkdown.js
2613   }
2614
2615   var tag = jsonml.shift(),
2616       attributes = {},
2617       content = [];
2618
2619   if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2620     attributes = jsonml.shift();
2621   }
2622
2623   while ( jsonml.length ) {
2624     content.push( render_tree( jsonml.shift() ) );
2625   }
2626
2627   var tag_attrs = "";
2628   for ( var a in attributes ) {
2629     tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
2630   }
2631
2632   // be careful about adding whitespace here for inline elements
2633   if ( tag == "img" || tag == "br" || tag == "hr" ) {
2634     return "<"+ tag + tag_attrs + "/>";
2635   }
2636   else {
2637     return "<"+ tag + tag_attrs + ">" + content.join( "" ) + "</" + tag + ">";
2638   }
2639 }
2640
2641 function convert_tree_to_html( tree, references, options ) {
2642   var i;
2643   options = options || {};
2644
2645   // shallow clone
2646   var jsonml = tree.slice( 0 );
2647
2648   if ( typeof options.preprocessTreeNode === "function" ) {
2649       jsonml = options.preprocessTreeNode(jsonml, references);
2650   }
2651
2652   // Clone attributes if they exist
2653   var attrs = extract_attr( jsonml );
2654   if ( attrs ) {
2655     jsonml[ 1 ] = {};
2656     for ( i in attrs ) {
2657       jsonml[ 1 ][ i ] = attrs[ i ];
2658     }
2659     attrs = jsonml[ 1 ];
2660   }
2661
2662   // basic case
2663   if ( typeof jsonml === "string" ) {
2664     return jsonml;
2665   }
2666
2667   // convert this node
2668   switch ( jsonml[ 0 ] ) {
2669     case "header":
2670       jsonml[ 0 ] = "h" + jsonml[ 1 ].level;
2671       delete jsonml[ 1 ].level;
2672       break;
2673     case "bulletlist":
2674       jsonml[ 0 ] = "ul";
2675       break;
2676     case "numberlist":
2677       jsonml[ 0 ] = "ol";
2678       break;
2679     case "listitem":
2680       jsonml[ 0 ] = "li";
2681       break;
2682     case "para":
2683       jsonml[ 0 ] = "p";
2684       break;
2685     case "markdown":
2686       jsonml[ 0 ] = "html";
2687       if ( attrs ) delete attrs.references;
2688       break;
2689     case "code_block":
2690       jsonml[ 0 ] = "pre";
2691       i = attrs ? 2 : 1;
2692       var code = [ "code" ];
2693       code.push.apply( code, jsonml.splice( i, jsonml.length - i ) );
2694       jsonml[ i ] = code;
2695       break;
2696     case "inlinecode":
2697       jsonml[ 0 ] = "code";
2698       break;
2699     case "img":
2700       jsonml[ 1 ].src = jsonml[ 1 ].href;
2701       delete jsonml[ 1 ].href;
2702       break;
2703     case "linebreak":
2704       jsonml[ 0 ] = "br";
2705     break;
2706     case "link":
2707       jsonml[ 0 ] = "a";
2708       break;
2709     case "link_ref":
2710       jsonml[ 0 ] = "a";
2711
2712       // grab this ref and clean up the attribute node
2713       var ref = references[ attrs.ref ];
2714
2715       // if the reference exists, make the link
2716       if ( ref ) {
2717         delete attrs.ref;
2718
2719         // add in the href and title, if present
2720         attrs.href = ref.href;
2721         if ( ref.title ) {
2722           attrs.title = ref.title;
2723         }
2724
2725         // get rid of the unneeded original text
2726         delete attrs.original;
2727       }
2728       // the reference doesn't exist, so revert to plain text
2729       else {
2730         return attrs.original;
2731       }
2732       break;
2733     case "img_ref":
2734       jsonml[ 0 ] = "img";
2735
2736       // grab this ref and clean up the attribute node
2737       var ref = references[ attrs.ref ];
2738
2739       // if the reference exists, make the link
2740       if ( ref ) {
2741         delete attrs.ref;
2742
2743         // add in the href and title, if present
2744         attrs.src = ref.href;
2745         if ( ref.title ) {
2746           attrs.title = ref.title;
2747         }
2748
2749         // get rid of the unneeded original text
2750         delete attrs.original;
2751       }
2752       // the reference doesn't exist, so revert to plain text
2753       else {
2754         return attrs.original;
2755       }
2756       break;
2757   }
2758
2759   // convert all the children
2760   i = 1;
2761
2762   // deal with the attribute node, if it exists
2763   if ( attrs ) {
2764     // if there are keys, skip over it
2765     for ( var key in jsonml[ 1 ] ) {
2766         i = 2;
2767         break;
2768     }
2769     // if there aren't, remove it
2770     if ( i === 1 ) {
2771       jsonml.splice( i, 1 );
2772     }
2773   }
2774
2775   for ( ; i < jsonml.length; ++i ) {
2776     jsonml[ i ] = convert_tree_to_html( jsonml[ i ], references, options );
2777   }
2778
2779   return jsonml;
2780 }
2781
2782
2783 // merges adjacent text nodes into a single node
2784 function merge_text_nodes( jsonml ) {
2785   // skip the tag name and attribute hash
2786   var i = extract_attr( jsonml ) ? 2 : 1;
2787
2788   while ( i < jsonml.length ) {
2789     // if it's a string check the next item too
2790     if ( typeof jsonml[ i ] === "string" ) {
2791       if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) {
2792         // merge the second string into the first and remove it
2793         jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ];
2794       }
2795       else {
2796         ++i;
2797       }
2798     }
2799     // if it's not a string recurse
2800     else {
2801       merge_text_nodes( jsonml[ i ] );
2802       ++i;
2803     }
2804   }
2805 }
2806
2807 } )( (function() {
2808   if ( typeof exports === "undefined" ) {
2809     window.markdown = {};
2810     return window.markdown;
2811   }
2812   else {
2813     return exports;
2814   }
2815 } )() );
2816
2817 /*!
2818 Deck JS - deck.smarkdown
2819 Copyright (c) 2014-2014 RĂ©mi Emonet
2820 Licensed under the MIT license.
2821 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
2822 */
2823
2824 /*
2825 This module provides a support for a shorter syntax for slides, with a syntax that is closer to plain markdown.
2826 TODO:
2827 - configurize the .smark and the default duration also
2828 - have a shortcut for {slide}?
2829
2830 */
2831
2832 (function($, deck, undefined) {
2833     var $d = $(document);
2834     var may = function(f) {return f ? f : function() {}};
2835     var endsWith = function(longStr, part) {return longStr.indexOf(part, longStr.length - part.length) !== -1;}
2836     var REST = null;
2837     var startsWith = function(longStr, part) {
2838         if (part == "%+class:") alert(":::"+longStr+":::");
2839         var res = longStr.substr(0, part.length) == part;
2840         REST = res ? longStr.slice(part.length) : null;
2841         RESTRIM = res ? REST.replace(/^ */, "") : null;
2842         return res;
2843     }
2844     var startsWithIgnoreCase = function(longStr, part) {
2845         var res = longStr.substr(0, part.length).toUpperCase() == part.toUpperCase();
2846         REST = res ? longStr.slice(part.length) : null;
2847         RESTRIM = res ? REST.replace(/^ */, "") : null;
2848         return res;
2849     }
2850     var isArray = Array.isArray || $.isArray; // there is also an alternative in markdownjs
2851
2852     // the animation duration is stateful across the smarkdown sections
2853     var animationDurationDefault = 400;
2854     var animationDuration = animationDurationDefault;
2855
2856     function clone(a) { return JSON.parse(JSON.stringify(a)) }
2857     function findTag(tree, regexp, startAt) {
2858         var i = startAt || 0;
2859         while (i < tree.length) {
2860             if (isArray(tree[i]) && tree[i][0].match(regexp)) {
2861                 return i;
2862             }
2863             i++;
2864         }
2865         return -1;
2866     }
2867     function addSpaceSeparatedAttr(o, a, c) {
2868         ensureHasAttributes(o);
2869         if (o[1][a])
2870             o[1][a] += " " + c;
2871         else
2872             o[1][a] = c;
2873     }
2874     function addClass(o, c) {
2875         addSpaceSeparatedAttr(o, 'class', c);
2876     }
2877     function hasClass(o, c) {
2878         if (!isObject(o[1]) || !o[1]['class']) {
2879             return false;
2880         } else {
2881             return o[1]['class'].match(new RegExp("\\b"+c+"\\b"));
2882         }
2883     }
2884     function isObject(o) {
2885         return !isArray(o) && typeof(o) === 'object';
2886     }
2887     function ensureHasAttributes(tree) {
2888         if (!isObject(tree[1])) {
2889             tree.splice(1, 0, {});
2890             return true;
2891         }
2892         return false;
2893     }
2894     function lazyGetAttributes(tree) {
2895         if (isObject(tree[1])) {
2896             return tree[1];
2897         } else {
2898             return {};
2899         }
2900     }
2901     function lazyUnsetAttributes(tree) {
2902         if (isObject(tree[1])) {
2903             tree.splice(1, 1);
2904         }
2905     }
2906     function hasIDOrClassDecoration(s) {
2907         return s.match(/^(.*)\{([^{}<>]*)\}$/);
2908     }
2909     function maybeProcessCopySlide(tree, index) {
2910         var slide = tree[index];
2911         ensureHasAttributes(slide);
2912         if (slide.length != 3) return false;
2913         if (slide[2][0] != "h1") return false;
2914         ensureHasAttributes(slide[2]);
2915         if (startsWithIgnoreCase(slide[2][2], "@COPY:#")) {
2916             var main = RESTRIM.split(/:/);
2917             var idOfBase = main[0];
2918             var animPart = main.slice(1).join(":");
2919             var hasAnim = ! animPart.match(/^\s*$/);
2920             var base = null;
2921             for (i in tree) {
2922                 if (i == 0 || (i==1 && isObject(tree[1]))) continue;
2923                 ensureHasAttributes(tree[i]);
2924                 if (tree[i][1].id == idOfBase) {
2925                     base = tree[i];
2926                     break;
2927                 }
2928             }
2929             if (base == null) { alert("pb"); return false; } // TODO should alert based on options
2930             var content = [["div", {}, "@anim:" + animPart]];
2931             content = content.concat(clone(base.slice(2)));
2932             slide[1] = clone(base[1]);
2933             delete slide[1].id;
2934             if (hasAnim) addClass(slide, "anim-continue");
2935             slide.splice.apply(slide, [2, 1].concat(content)); // replace the h1 with content
2936             return true;
2937         }
2938         return false;
2939     }
2940     function processIDOrClassDecoration(tree, index) {
2941         var matched = hasIDOrClassDecoration(tree[index]); // make sure the group is set
2942         if (!matched) { alert("should call processIDOrClassDecoration() only if hasIDOrClassDecoration is true"); return; }
2943         var returnValue = false; // whether we added the attributes
2944         var base = RegExp.$1;
2945         var decorations = RegExp.$2.split(/ +/);
2946         if (ensureHasAttributes(tree)) {
2947             if (index>0) index++;
2948             returnValue = true;
2949         }
2950         tree[index] = base;
2951         for (d in decorations) {
2952             // allow .class and class notations
2953             if (startsWith(decorations[d], ".")) decorations[d] = decorations[d].slice(1);
2954
2955             if (startsWith(decorations[d], "#")) {
2956                 tree[1].id = decorations[d].slice(1);
2957             } else {
2958                 if (startsWith(decorations[d], "*") | startsWith(decorations[d], "/")) {
2959                     addSpaceSeparatedAttr(tree, "data-container-class", decorations[d].slice(1));
2960                 } else {
2961                     addClass(tree, decorations[d]);
2962                 }
2963             }                
2964         }
2965         return returnValue;
2966     }
2967     function possiblyHideIfEmpty(tree) { // if it contains only anim stuf etc
2968         var hide = false;
2969         var i = isObject(tree[1]) ? 2 : 1;
2970         function onlyDivAnims(tt) {
2971             var only = true;
2972             var start = isObject(tt[1]) ? 2 : 1;
2973             tt.slice(start).forEach(function(e) {
2974                 if (!isArray(e) || !isObject(e[1]) || (" "+e[1]["class"]).indexOf(" anim-") == -1) {
2975                     only = false;
2976                 }
2977             });
2978             return only;
2979         }
2980
2981         if (onlyDivAnims(tree)) hide = true;
2982         else if (tree.length == i+1 && isArray(tree[i]) && tree[i][0] == "p"
2983                  && onlyDivAnims(tree[i])) hide = true;
2984         if (hide) {
2985             ensureHasAttributes(tree);
2986             tree[1].style = "display: none";
2987         }
2988     }
2989     function maybeProcessComment(tree, index) {
2990         var line = tree[index];
2991         var clean = function(s) { return s;}; //return s.replace(/\/\\\//g, '//'); };
2992         if (line.match(/^(.*?)[\n\s]*\/\/ +(.*)/)) {
2993             var obj = ["div", {
2994                 'class': "comment"
2995             }, clean(RegExp.$2)];
2996             tree.splice(index, 1, RegExp.$1, obj);
2997             return true;
2998         }
2999         tree[index] = clean(tree[index]);
3000         return false;
3001     }
3002     function maybeProcessAtSomething(tree, index) {
3003         var line = tree[index];
3004         if (startsWithIgnoreCase(line, "@SVG:")) {
3005             var content = RESTRIM
3006             var parts = content.split(/ +/);
3007             if (hasIDOrClassDecoration(content) || parts.length == 3) {
3008                 // new version
3009                 var obj = ["div", {
3010                     'data-src': parts[0],
3011                     'data-width': parts[1],
3012                     'data-height': parts[2],
3013                     'class': "svg-object"
3014                 }, parts.slice(3).join(" ")];
3015                 // TODO: alert when wrong number of args
3016                 if (hasIDOrClassDecoration(content)) processIDOrClassDecoration(obj, 2);
3017                 tree[index] = obj;
3018             } else {
3019                 // TODO allow this only when an option is set option
3020                 // old, smartsyntax version
3021                 var obj = ["div", {
3022                     'data-src': parts[1],
3023                     'data-width': parts[2],
3024                     'data-height': parts[3],
3025                     'class': "svg-object"
3026                 }, ""];
3027                 parts[0].split(/,/).forEach(function (p) { addClass(obj, p); });
3028                 tree[index] = obj;
3029             }
3030         } else if (startsWithIgnoreCase(line, "@ANIM:")) {
3031             line = RESTRIM.replace(/%[+]/i, "%%"); // protect the "%+class" from being split
3032             var allToAdd = [];
3033             var parts = line.split(/ *\| */); // TODO: configurize + reconsider all separators?
3034             for (i in parts) {
3035                 // process each group of simultaneous animations
3036                 var subparts = parts[i].split(/ *\+ */);
3037                 for (ii in subparts) {
3038                     var what = subparts[ii];
3039                     if (what == "") continue; // as a good side effect, this allows to set a "anim-continue" on all elements (e.g., put a + at the end of the line) 
3040                     var continuating  = ii != subparts.length-1;
3041                     var toAdd = ["div", {}, ""];
3042                     addClass(toAdd, "slide");
3043                     // process the individual element (reminder: animationDuration is global)
3044                     function dw() { addSpaceSeparatedAttr(toAdd, "data-what", REST); }
3045                     function dd() { addSpaceSeparatedAttr(toAdd, "data-dur", ""+animationDuration); }
3046                     if (startsWithIgnoreCase(what, "%duration:")) {
3047                         animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3048                         continue;
3049                     } else if (startsWithIgnoreCase(what, "%dur:")) {
3050                         animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3051                         continue;
3052                     } else if (startsWithIgnoreCase(what, "%play:")) {
3053                         addClass(toAdd, "anim-play");
3054                         dw();
3055                     } else if (startsWithIgnoreCase(what, "%pause:")) {
3056                         addClass(toAdd, "anim-pause");
3057                         dw();
3058                     } else if (startsWith(what, "%viewbox:")) {
3059                         addClass(toAdd, "anim-viewboxas");
3060                         // TODO: if REST contains ':', two params (then the target is specified, else it is just all SVGs root elements)
3061                         addSpaceSeparatedAttr(toAdd, "data-as", REST);
3062                         addSpaceSeparatedAttr(toAdd, "data-what", "svg");
3063                         dd();
3064                     } else if (startsWith(what, "%attr:")) {
3065                         var main = RESTRIM.split(/ *: */);
3066                         addClass(toAdd, "anim-attribute");
3067                         addSpaceSeparatedAttr(toAdd, "data-what", main[0]);
3068                         addSpaceSeparatedAttr(toAdd, "data-attr", main.slice(1).join(":"));
3069                         dd();
3070                     } else if (startsWith(what, "%along:")) {
3071                         var main = RESTRIM.split(/ *: */);
3072                         addClass(toAdd, "anim-along");
3073                         if (startsWith(main[0], "-")) {
3074                             main[0] = RESTRIM;
3075                             addSpaceSeparatedAttr(toAdd, "data-reverse", "true");
3076                         }
3077                         addSpaceSeparatedAttr(toAdd, "data-path", main[0]);
3078                         addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3079                         dd();
3080                     } else if (startsWith(what, "%%class:")) {
3081                         var main = RESTRIM.split(/ *: */);
3082                         addClass(toAdd, "anim-addclass");
3083                         addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3084                         addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3085                     } else if (startsWith(what, "%-class:")) {
3086                         var main = RESTRIM.split(/ *: */);
3087                         addClass(toAdd, "anim-removeclass");
3088                         addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3089                         addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3090                     } else if (startsWith(what, "+")) {
3091                         addClass(toAdd, "anim-show");
3092                         dw();
3093                     } else if (startsWith(what, "-")) {
3094                         addClass(toAdd, "anim-hide");
3095                         dw(); dd();
3096                     } else {
3097                         addClass(toAdd, "anim-show");
3098                         addSpaceSeparatedAttr(toAdd, "data-what", what);
3099                         dd();
3100                     }
3101                     if (continuating) addClass(toAdd, "anim-continue");
3102                     allToAdd.push(toAdd);
3103                 }
3104             }
3105             tree.splice.apply(tree, [index, 1].concat(allToAdd)); // just replacing the text with allToAdd elements
3106         } else {
3107             return false;
3108         }
3109         // TODO? handle the decorations for comments
3110         return true;
3111     }
3112     function processMath(content) {
3113         return content.replace(/\$([^$][^$]*)\$/g, '<span class="latex">\\displaystyle $1</span>').replace(/\$\$/, '$');
3114     }
3115
3116     var interpretationOfSmartLanguage = function(smark, doc) {
3117         var jstree = markdown.toHTMLTree(smark);
3118         
3119         // split at each h2 or h1
3120         (function makeTopLevelDivs(jsTree) {
3121             var firstIndex = findTag(jsTree, /^(h1|h2)$/);
3122             if (firstIndex == -1) return;
3123             var secondIndex = findTag(jsTree, /^(h1|h2)$/, firstIndex+1);
3124             if (secondIndex == -1) secondIndex = jsTree.length;
3125             var slide = ["section"].concat( // we will add the 'slide' class later below
3126                 jsTree.splice(firstIndex, secondIndex - firstIndex));
3127             jsTree.splice(firstIndex, 0, slide);
3128             makeTopLevelDivs(jsTree);
3129         })(jstree);
3130
3131         // process:
3132         // - the class and id decorations like    {#first hightlight slide}
3133         // - the @... custom notations
3134         // - the // for comments
3135         for (s in jstree) {
3136             if (s == 0 || (s==1 && isObject(jstree[1]))) continue;
3137             var slide = jstree[s];
3138             ensureHasAttributes(slide);
3139             if (maybeProcessCopySlide(jstree, s)) {
3140                 //continue;
3141                 // actually we want to apply anims to it
3142             }
3143             // cleanup: first, remove first "p" in a "li" (happens when one put an empty line in a bullet list, but it would break the decorations)
3144             (function patch(tree){ // tree is slide or a subelement
3145                 var i = 1;
3146                 while (i < tree.length) {
3147                     if (isArray(tree[i])) {
3148                         if (tree[i][0] === "li") {
3149                             var li = tree[i];
3150                             if (isArray(li[1]) && li[1][0] === "p") {
3151                                 li.splice.apply(li, [1, 1].concat(li[1].slice(1)));
3152                                 continue;
3153                             }
3154                         }
3155                         patch(tree[i]);
3156                     }
3157                     i++;
3158                 }
3159             })(slide);
3160             // process @anim... and {} decoration
3161             (function patch(tree){ // tree is slide or a subelement
3162                 var i = 1;
3163                 while (i < tree.length) {
3164                     if (isArray(tree[i])) patch(tree[i]);
3165                     else if (typeof(tree[i]) == 'string') {
3166                         if (maybeProcessComment(tree, i)) continue;
3167                         else if (maybeProcessAtSomething(tree, i)) continue;
3168                         else if (hasIDOrClassDecoration(tree[i])) {
3169                             if (processIDOrClassDecoration(tree, i)) {
3170                                 i++; // avoid processing the same element twice
3171                             }
3172                         }
3173                     }
3174                     i++;
3175                 }
3176             })(slide);
3177             // cleanup: hide empty "li" after @anim processing
3178             (function patch(tree){ // tree is slide or a subelement
3179                 var i = 1;
3180                 while (i < tree.length) {
3181                     if (isArray(tree[i])) {
3182                         if (tree[i][0] === "li" && possiblyHideIfEmpty(tree[i])) continue;
3183                         else patch(tree[i]);
3184                     }
3185                     i++;
3186                 }
3187             })(slide);
3188             // process the $math$
3189             (function patch(tree){ // tree is slide or a subelement
3190                 if (hasClass(tree, "smark-nomath")) return;
3191                 var i = 1;
3192                 while (i < tree.length) {
3193                     if (isArray(tree[i])) patch(tree[i]);
3194                     else if (typeof(tree[i]) == 'string') {
3195                         tree[i] = processMath(tree[i]);
3196                     }
3197                     i++;
3198                 }
3199             })(slide);
3200             // change things to textarea (to help with codemirror) https://github.com/iros/deck.js-codemirror/issues/19
3201             (function patch(tree){ // tree is slide or a subelement
3202                 if (hasClass(tree, "smark-textarea")) {
3203                     tree[3][0] = "textarea";
3204                 }
3205                 var i = 1;
3206                 while (i < tree.length) {
3207                     if (isArray(tree[i])) patch(tree[i]);
3208                     i++;
3209                 }
3210             })(slide);
3211             // now propagate to the slide
3212             var hAttributes = lazyGetAttributes(slide[2]);
3213             if (slide[1]['class']) {
3214                 var cl = slide[1]['class'];
3215                 slide[1] = clone(hAttributes);
3216                 addClass(slide, cl);
3217             } else {
3218                 slide[1] = clone(hAttributes);
3219             }
3220             lazyUnsetAttributes(slide[2]);
3221             addClass(slide, 'slide');
3222         }
3223
3224         return markdown.renderJsonML(jstree);
3225     }
3226
3227     // this have to be executed before the deck init
3228     $d.bind('deck.beforeInit', function() {
3229         $('.smark').each(function() { // TODO make it configurable
3230             var it = this;
3231             var slides = interpretationOfSmartLanguage(it.innerHTML, document);
3232             $(it).after(slides);
3233             // remove the smart node (to avoid having an empty non-slide sibling (e.g., in the presenter view))
3234             $(it).remove();
3235         });
3236         var opts = $[deck]('getOptions');
3237         var maybe = function(f) { return f || (function(){}); }
3238         maybe(opts.AFTERSMARKDOWN)();
3239         $[deck]('reInitSlidesArray')
3240     });
3241
3242 })(jQuery, 'deck');
3243
3244 /*!
3245   Deck JS - deck.fit
3246   Copyright (c) 2012 RĂ©mi Emonet
3247   Licensed under the MIT license.
3248   https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
3249 */
3250
3251 /*
3252   This extension provides a way of scaling the slides to fit the slide container.
3253   A "design size" is used to do global scaling of all slides in the same way.
3254   The default design size is 800x600.
3255 */
3256 (function($, deck, window, undefined) {
3257     var $d = $(document),
3258     $w = $(window),
3259     timer, // Timeout id for debouncing
3260     rootSlides,
3261     
3262     /*
3263       Internal function to do all the dirty work of scaling the slides.
3264     */
3265     scaleDeck = function() {
3266         var opts = $[deck]('getOptions');
3267         var addMarginX = opts.fitMarginX * 2;
3268         var addMarginY = opts.fitMarginY * 2;
3269         var fitMode = opts.fitMode;
3270         var sdw = opts.designWidth;
3271         var sdh = opts.designHeight;
3272         var $container = $[deck]('getContainer');
3273         var scaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw+addMarginX) : 1;
3274         var scaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh+addMarginY) : 1;
3275         //var truescaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw) : 1;
3276         //var truescaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh) : 1;
3277         var scale = scaleX < scaleY ? scaleX : scaleY;
3278         var rootSlides = [];
3279         var slideTest = $.map([opts.classes.before, opts.classes.previous, opts.classes.current, opts.classes.next, opts.classes.after],
3280                               function(el, i) {return '.' + el;}).join(', ');
3281
3282         $.each($[deck]('getSlides'), function(i, $el) {
3283             if (!$el.parentsUntil(opts.selectors.container).length) {
3284                 rootSlides.push($el);
3285             }
3286         });
3287         $.each(rootSlides, function(i, $slide) {
3288             $slide.css('width', sdw);
3289             $slide.css('height', sdh);
3290             $.each('Webkit Moz O ms Khtml'.split(' '), function(i, prefix) {
3291                 if (scale == 1) {
3292                     $slide.css(prefix + 'Transform', '');
3293                 } else {
3294                     if (fitMode == "left top" || fitMode == "top left") {
3295                         // ok align left/top (ok with the percents)
3296                         $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%,50%) translate('+(addMarginX/2)+'px,'+(addMarginY/2)+'px)');
3297                     } else if (fitMode == "center middle") {
3298                         // ok align center/middle
3299                         $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%, 50%) translate('+($container.innerWidth()/2/scale - sdw/2)+'px,'+($container.innerHeight()/2/scale - sdh/2)+'px)');
3300                     } else if (fitMode == "right bottom" || fitMode == "bottom right") {
3301                         // ok align right/bottom
3302                         $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%, 50%) translate('+($container.innerWidth()/scale - sdw - addMarginX/2)+'px,'+($container.innerHeight()/scale - sdh - addMarginY/2)+'px)');
3303                     } else if (fitMode == "stretched") {
3304                         // ok stretched (with respect of the margin, i.e., it is center/middle)
3305                         $slide.css(prefix + 'Transform', 'scale(' + scaleX + ' , ' + scaleY + ') translate('+(($container.innerWidth()-sdw)/2/scaleX)+'px,'+(($container.innerHeight()-sdh)/2/scaleY)+'px)');
3306                     }
3307                 }
3308             });
3309         });
3310         
3311     }
3312     
3313     /*
3314       Extends defaults/options.
3315       
3316       options.designWidth
3317       Defaults to 800. You may instead specify a width as a number
3318       of px and all slides will be scaled in the same way, considering their
3319       size is the provided one.
3320       
3321       options.designHeight
3322       Defaults to 600. You may instead specify a height as a number
3323       of px and all slides will be scaled in the same way, considering their
3324       size is the provided one.
3325       
3326       options.fitMode
3327       How to adapt the slide to the container.
3328       Only the following combinations are available for now:
3329       "center middle", "top left", "bottom right", "stretched"
3330     
3331       options.fitMarginX
3332       options.fitMarginY
3333       Defaults to 5. Adds some margin in design space units.
3334       E.g., if the designe width is 800 and the margin is 5, the slide will be
3335       810 pixel wide before rescaling.
3336     
3337       options.scaleDebounce
3338       Scaling on the browser resize event is debounced. This number is the
3339       threshold in milliseconds. You can learn more about debouncing here:
3340       http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
3341       
3342     */
3343     $.extend(true, $[deck].defaults, {
3344         classes: {
3345             globalscale: 'deck-globalscale'
3346         },
3347         keys: {
3348             scale: 83 // s
3349         },
3350         
3351         designWidth: 800,
3352         designHeight: 600,
3353         fitMode: "center middle",
3354         fitMarginX: 0,
3355         fitMarginY: 0,
3356         scaleDebounce: 200
3357     });
3358     
3359     /*
3360       jQuery.deck('disableScale')
3361       
3362       Disables scaling and removes the scale class from the deck container.
3363     */
3364     $[deck]('extend', 'disableScale', function() {
3365         $[deck]('getContainer').removeClass($[deck]('getOptions').classes.globalscale);
3366         scaleDeck();
3367     });
3368     
3369     /*
3370       jQuery.deck('enableScale')
3371       
3372       Enables scaling and adds the scale class to the deck container.
3373     */
3374     $[deck]('extend', 'enableScale', function() {
3375         $[deck]('getContainer').addClass($[deck]('getOptions').classes.globalscale);
3376         scaleDeck();
3377     });
3378     
3379     /*
3380       jQuery.deck('toggleScale')
3381       
3382       Toggles between enabling and disabling scaling.
3383     */
3384     $[deck]('extend', 'toggleScale', function() {
3385         var $c = $[deck]('getContainer');
3386         $[deck]($c.hasClass($[deck]('getOptions').classes.globalscale) ?
3387                 'disableScale' : 'enableScale');
3388     });
3389     
3390     $d.bind('deck.init', function() {
3391         var opts = $[deck]('getOptions');
3392         
3393         // Debounce the resize scaling
3394         $w.unbind('resize.deckscale').bind('resize.deckscale', function() {
3395             window.clearTimeout(timer);
3396             timer = window.setTimeout(scaleDeck, opts.scaleDebounce);
3397         })
3398         // Scale once on load, in case images or something change layout
3399             .unbind('load.deckscale').bind('load.deckscale', scaleDeck);
3400         
3401         // Bind key events
3402         $d.unbind('keydown.deckscale').bind('keydown.deckscale', function(e) {
3403             if (e.which === opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
3404                 $[deck]('toggleScale');
3405                 e.preventDefault();
3406             }
3407         });
3408         
3409         // Enable scale on init
3410         $[deck]('enableScale');
3411     });
3412 })(jQuery, 'deck', this);
3413
3414
3415 // This script was automatically generated from a literate source.  
3416 // Do not edit this file; look at the literate source instead!
3417 //
3418 // Greasemonkey user script to 
3419 // Display LaTeX in Web pages by transforming to MathML
3420 // --------------------------------------------------------------------
3421
3422 // Original script by
3423 // Copyright (C) 2006 Steve Cheng <stevecheng@users.sourceforge.net>
3424 // Home page: http://gold-saucer.afraid.org/mathml/greasemonkey/
3425 //
3426 // Modified by
3427 // Copyright (C) 2010 Valery Alexeev <va.email.tex@gmail.com>
3428 // Version 1.15, May 7, 2010
3429 // as follows:
3430 //
3431 // Added arxiv.org, front.math.ucdavis.edu, *mathscinet*, mail.google.com
3432 // Changed char_map to fix the display for \mathcal, \mathbb, \mathfrak
3433 // Fixed the displayed formulas with $$...$$ and \[...\]
3434 // Added \scr, \germ, \roman, etc used by Mathscinet.
3435 // Added miscellaneous symbols and arrows 
3436
3437 // Permission is hereby granted, free of charge, to any person obtaining
3438 // a copy of this software and associated documentation files (the
3439 // "Software"), to deal in the Software without restriction, including
3440 // without limitation the rights to use, copy, modify, merge, publish,
3441 // distribute, sublicense, and/or sell copies of the Software, and to
3442 // permit persons to whom the Software is furnished to do so, subject to
3443 // the following conditions:
3444
3445 // The above copyright notice and this permission notice shall be included
3446 // in all copies or substantial portions of the Software.
3447
3448 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3449 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3450 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3451 // IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
3452 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
3453 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3454 // OTHER DEALNGS IN THE SOFTWARE.
3455
3456
3457 function latex2mml() {
3458
3459
3460     function GM_log() {}
3461
3462
3463 // First, find out where we are
3464 var va_loc = window.location.href;
3465 var va_view = 'web';
3466
3467 //alert( 'va_view=' + va_view );
3468
3469 // The script itself begins
3470
3471 var/*const*/ mmlns = 'http://www.w3.org/1998/Math/MathML';
3472
3473 /*
3474 // VA: Fix displayed equations first.
3475 if( va_view == 'web' ){
3476     document.body.innerHTML=
3477         document.body.innerHTML.replace(/\n/g," "); // remove end-of-lines
3478     document.body.innerHTML=
3479         document.body.innerHTML.replace(/(\$\$|\\\[)([^$]+)(\$\$|\\\])/g,
3480                                         "<p style=\"text-indent: 20px;\"> \$ $2 \$ </p>");
3481 // VA: Experimental: may lead to slow down. \spcheck is used on MathSciNet
3482 // document.body.innerHTML=
3483 // document.body.innerHTML.replace(/\\spcheck/g,"^{\\vee}");
3484 }
3485 */
3486
3487
3488 function result_element(tag, num_attrs)
3489 {
3490   var node = document.createElementNS(mmlns, tag);
3491
3492   var k = 2;
3493   while(--num_attrs >= 0) {
3494     if(arguments[k+1] != null) {
3495       node.setAttribute(arguments[k], arguments[k+1]);
3496     }
3497     k += 2;
3498   }
3499     
3500   for(; k < arguments.length; k++) {
3501     if(arguments[k] != null) {
3502       if(typeof(arguments[k]) == 'string')
3503         node.appendChild(document.createTextNode(arguments[k]));
3504       else
3505         node.appendChild(arguments[k]);
3506     }
3507   }
3508
3509   return node;
3510 }
3511
3512
3513 function result_element_append(parent, child)
3514 {
3515   if(parent != null && child != null) {
3516     if(typeof(child) == 'string')
3517       parent.appendChild(document.createTextNode(child));
3518     else
3519       parent.appendChild(child);
3520   }
3521 }
3522
3523
3524 function result_element_prepend(parent, child, next)
3525 {
3526   if(next == null)
3527     result_element_append(parent, child);
3528   else if (parent != null && child != null)
3529     parent.insertBefore(child, next);
3530 }
3531
3532
3533 function result_set_attr(elem, attr, value)
3534 {
3535   if(elem != null && attr != null) {
3536     if(value != null)
3537       elem.setAttribute(attr, value);
3538     else
3539       elem.removeAttribute(attr);
3540   }
3541 }
3542
3543
3544 function result_append_attr(elem, attr, value)
3545 {
3546   if(elem != null && attr != null) {
3547     var old_value = elem.getAttribute(elem, attr);
3548     if(old_value == null)
3549       elem.setAttribute(attr, value);
3550     else
3551       elem.setAttribute(attr, old_value + value);
3552   }
3553 }
3554
3555 /*
3556 if( va_view == 'web' ){
3557     if(!this.GM_getValue) {
3558         this.GM_getValue = function(key, value) { return value; }
3559         this.GM_log = function() {}
3560     }
3561     
3562     
3563     if(this.GM_registerMenuCommand) {
3564         GM_registerMenuCommand("Enable native display of math images", 
3565                                function() {
3566                                    GM_setValue("patch-images", true);
3567                                    do_patch_images = true;
3568                                    patch_element(document.documentElement);
3569                                });
3570         GM_registerMenuCommand("Disable native display of math images",
3571                                function() {
3572                                    GM_setValue("patch-images", false);
3573                                });
3574     }
3575 }
3576 */
3577
3578 // VA: changed char_map
3579 var/*const*/ char_map = {
3580   'script': [
3581              '\uD835\uDC9C', '\u212C', '\uD835\uDC9E', //abc
3582              '\uD835\uDC9F', '\u2130', '\u2131', //def
3583              '\uD835\uDCA2', '\u210B', '\u2110', //ghi
3584              '\uD835\uDCA5', '\uD835\uDCA6', '\u2112', //jkl
3585              '\u2133', '\uD835\uDCA9', '\uD835\uDCAA', //mno
3586              '\uD835\uDCAB', '\uD835\uDCAC', '\u211B', //pqr
3587              '\uD835\uDCAE', '\uD835\uDCAF', '\uD835\uDCB0', //stu
3588              '\uD835\uDCB1', '\uD835\uDCB2', '\uD835\uDCB3', //vwx
3589              '\uD835\uDCB4', '\uD835\uDCB5' ], //yz
3590
3591   'fraktur': [
3592               '\uD835\uDD04', '\uD835\uDD05', '\u212D', //abc
3593               '\uD835\uDD07', '\uD835\uDD08', '\uD835\uDD09', //def
3594               '\uD835\uDD0A', '\u210C', '\u2111', //ghi
3595               '\uD835\uDD0D', '\uD835\uDD0E', '\uD835\uDD0F', //jkl
3596               '\uD835\uDD10', '\uD835\uDD11', '\uD835\uDD12', //mno
3597               '\uD835\uDD13', '\uD835\uDD14', '\u211C', //pqr
3598               '\uD835\uDD16', '\uD835\uDD17', '\uD835\uDD18', //stu
3599               '\uD835\uDD19', '\uD835\uDD1A', '\uD835\uDD1B', //vwx
3600               '\uD835\uDD1C', '\u2128' ], //yz
3601
3602   'double-struck': [
3603                     '\uD835\uDD38', '\uD835\uDD39', '\u2102', //abc
3604                     '\uD835\uDD3B', '\uD835\uDD3C', '\uD835\uDD3D', //def
3605                     '\uD835\uDD3E', '\u210D', '\uD835\uDD40', //ghi
3606                     '\uD835\uDD41', '\uD835\uDD42', '\uD835\uDD43', //jkl
3607                     '\uD835\uDD44', '\u2115', '\uD835\uDD46', //mno
3608                     '\u2119', '\u211A', '\u211D', //pqr
3609                     '\uD835\uDD4A', '\uD835\uDD4B', '\uD835\uDD4C', //stu
3610                     '\uD835\uDD4D', '\uD835\uDD4E', '\uD835\uDD4F', //vwx
3611                     '\uD835\uDD50', '\u2124', ], //yz
3612 };
3613
3614 var/*const*/ uppercase_re = /[A-Z]/;
3615
3616 function fix_mathvariant(node, style)
3617 {
3618   if(node.nodeType == node.TEXT_NODE) {
3619     if(style != null && style != '' && style in char_map) {
3620       node.data = node.data.replace(uppercase_re,
3621         function(s) {return char_map[style][s.charCodeAt(0)-65]});
3622     }
3623   } else if(node.nodeType == node.ELEMENT_NODE) {
3624     var new_style = node.getAttribute('mathvariant');
3625     if(new_style != null && new_style != '')
3626       style = new_style;
3627
3628     for(var i=0; i < node.childNodes.length; i++)
3629       fix_mathvariant(node.childNodes.item(i), style);
3630   }
3631 }
3632
3633 var g_punct_and_space
3634 = {"\\quad" : "\u2003" ,
3635 "\\qquad" : "\u2003\u2003" ,
3636 "\\thickspace" : "\u2002" ,
3637 "\\;" : "\u2002" ,
3638 "\\medspace" : "\u2005" ,
3639 "\\:" : "\u2005" ,
3640 "\\thinspace" : "\u2004" ,
3641 "\\," : "\u2004" ,
3642 "\\!" : "\u200b" ,
3643 "." : "." ,
3644 ";" : ";" ,
3645 "?" : "?" ,
3646 "\\qedsymbol" : "\u25a0" ,
3647 }
3648 ;
3649 var g_left_delimiters
3650 = {"(" : "(" ,
3651 "[" : "[" ,
3652 "\\{" : "{" ,
3653 "\\lgroup" : "(" ,
3654 "\\lbrace" : "{" ,
3655 "\\lvert" : "|" ,
3656 "\\lVert" : "\u2016" ,
3657 "\\lceil" : "\u2308" ,
3658 "\\lfloor" : "\u230a" ,
3659 "\\lmoustache" : "\u23b0" ,
3660 "\\langle" : "\u2329" ,
3661 }
3662 ;
3663 var g_right_delimiters
3664 = {")" : ")" ,
3665 "]" : "]" ,
3666 "\\}" : "}" ,
3667 "\\rbrace" : "}" ,
3668 "\\rgroup" : ")" ,
3669 "\\rvert" : "|" ,
3670 "\\rVert" : "\u2016" ,
3671 "\\rceil" : "\u2309" ,
3672 "\\rfloor" : "\u230b" ,
3673 "\\rmoustache" : "\u23b1" ,
3674 "\\rangle" : "\u232a" ,
3675 }
3676 ;
3677 var g_operator_symbols
3678 = {"\\amalg" : "\u2a3f" ,
3679 "\\ast" : "*" ,
3680 "\\ast" : "\u2217" ,
3681 "\\barwedge" : "\u22bc" ,
3682 "\\barwedge" : "\u2305" ,
3683 "\\bigcirc" : "\u25cb" ,
3684 "\\bigtriangledown" : "\u25bd" ,
3685 "\\bigtriangleup" : "\u25b3" ,
3686 "\\boxdot" : "\u22a1" ,
3687 "\\boxminus" : "\u229f" ,
3688 "\\boxplus" : "\u229e" ,
3689 "\\boxtimes" : "\u22a0" ,
3690 "\\bullet" : "\u2022" ,
3691 "\\bullet" : "\u2219" ,
3692 "\\cap" : "\u2229" ,
3693 "\\Cap" : "\u22d2" ,
3694 "\\cdot" : "\u22c5" ,
3695 "\\centerdot" : "\u00b7" ,
3696 "\\circ" : "\u2218" ,
3697 "\\circledast" : "\u229b" ,
3698 "\\circledcirc" : "\u229a" ,
3699 "\\circleddash" : "\u229d" ,
3700 "\\cup" : "\u222a" ,
3701 "\\Cup" : "\u22d3" ,
3702 "\\curlyvee" : "\u22ce" ,
3703 "\\curlywedge" : "\u22cf" ,
3704 "\\dagger" : "\u2020" ,
3705 "\\ddagger" : "\u2021" ,
3706 "\\diamond" : "\u22c4" ,
3707 "\\div" : "\u00f7" ,
3708 "\\divideontimes" : "\u22c7" ,
3709 "\\dotplus" : "\u2214" ,
3710 "\\doublebarwedge" : "\u2306" ,
3711 "\\doublecap" : "\u22d2" ,
3712 "\\doublecup" : "\u22d3" ,
3713 "\\gtrdot" : "\u22d7" ,
3714 "\\intercal" : "\u22ba" ,
3715 "\\land" : "\u2227" ,
3716 "\\leftthreetimes" : "\u22cb" ,
3717 "\\lessdot" : "\u22d6" ,
3718 "\\lor" : "\u2228" ,
3719 "\\ltimes" : "\u22c9" ,
3720 "\\mp" : "\u2213" ,
3721 "\\odot" : "\u2299" ,
3722 "\\ominus" : "\u2296" ,
3723 "\\oplus" : "\u2295" ,
3724 "\\oslash" : "\u2298" ,
3725 "\\otimes" : "\u2297" ,
3726 "\\pm" : "\u00b1" ,
3727 "\\rightthreetimes" : "\u22cc" ,
3728 "\\rtimes" : "\u22ca" ,
3729 "\\setminus" : "\u2216" ,
3730 "\\smallsetminus" : "\u2216" ,
3731 "\\sqcap" : "\u2293" ,
3732 "\\sqcup" : "\u2294" ,
3733 "\\star" : "\u22c6" ,
3734 "\\times" : "\u00d7" ,
3735 "\\triangleleft" : "\u25c1" ,
3736 "\\triangleright" : "\u25b7" ,
3737 "\\uplus" : "\u228e" ,
3738 "\\vee" : "\u2228" ,
3739 "\\spcheck" : "\u207a" , // has to be ^{\vee} instead but that's hard
3740                          // to code
3741     //"\\spcheck" : "\u002a" , 
3742 "\\veebar" : "\u22bb" ,
3743 "\\veebar" : "\u2a61" ,
3744 "\\wedge" : "\u2227" ,
3745 "\\wr" : "\u2240" ,
3746 "+" : "+" ,
3747 "-" : "\u2212" ,
3748 "*" : "*" ,
3749 "," : "," ,
3750 "/" : "\u2215" ,
3751 ":" : ":" ,
3752 "\\colon" : ":" ,
3753 "|" : "|" ,
3754 "\\vert" : "|" ,
3755 "\\Vert" : "\u2016" ,
3756 "\\|" : "\u2016" ,
3757 "\\backslash" : "\\" ,
3758 "'" : "\u2032" ,
3759 "\\#" : "#" ,
3760 "\\bmod" : "mod" ,
3761 "\\mod" : "mod" ,
3762 "\\downarrow" : "\u2193" ,
3763 "\\Downarrow" : "\u21d3" ,
3764 "\\uparrow" : "\u2191" ,
3765 "\\Uparrow" : "\u21d1" ,
3766 "\\updownarrow" : "\u2195" ,
3767 "\\Updownarrow" : "\u21d5" ,
3768 "\\bigcap" : "\u22c2" ,
3769 "\\bigcup" : "\u22c3" ,
3770 "\\bigodot" : "\u2a00" ,
3771 "\\bigoplus" : "\u2a01" ,
3772 "\\bigotimes" : "\u2a02" ,
3773 "\\bigsqcup" : "\u2a06" ,
3774 "\\biguplus" : "\u2a04" ,
3775 "\\bigvee" : "\u22c1" ,
3776 "\\bigwedge" : "\u22c0" ,
3777 "\\coprod" : "\u2210" ,
3778 "\\prod" : "\u220f" ,
3779 "\\sum" : "\u2211" ,
3780 "\\int" : "\u222b" ,
3781 "\\smallint" : "\u222b" ,
3782 "\\oint" : "\u222e" ,
3783 "\\angle" : "\u2220" ,
3784 "\\backprime" : "\u2035" ,
3785 "\\bigstar" : "\u2605" ,
3786 "\\blacklozenge" : "\u29eb" ,
3787 "\\blacksquare" : "\u25a0" ,
3788 "\\blacktriangle" : "\u25b4" ,
3789 "\\blacktriangledown" : "\u25be" ,
3790 "\\bot" : "\u22a5" ,
3791 "\\clubsuit" : "\u2663" ,
3792 "\\diagdown" : "\u2572" ,
3793 "\\diagup" : "\u2571" ,
3794 "\\diamondsuit" : "\u2662" ,
3795 "\\emptyset" : "\u2205" ,
3796 "\\exists" : "\u2203" ,
3797 "\\flat" : "\u266d" ,
3798 "\\forall" : "\u2200" ,
3799 "\\heartsuit" : "\u2661" ,
3800 "\\infty" : "\u221e" ,
3801 "\\lnot" : "\u00ac" ,
3802 "\\lozenge" : "\u25ca" ,
3803 "\\measuredangle" : "\u2221" ,
3804 "\\nabla" : "\u2207" ,
3805 "\\natural" : "\u266e" ,
3806 "\\neg" : "\u00ac" ,
3807 "\\nexists" : "\u2204" ,
3808 "\\prime" : "\u2032" ,
3809 "\\sharp" : "\u266f" ,
3810 "\\spadesuit" : "\u2660" ,
3811 "\\sphericalangle" : "\u2222" ,
3812 "\\square" : "\u25a1" ,
3813 "\\surd" : "\u221a" ,
3814 "\\top" : "\u22a4" ,
3815 "\\triangle" : "\u25b5" ,
3816 "\\triangledown" : "\u25bf" ,
3817 "\\varnothing" : "\u2205" ,
3818 "\\aleph" : "\u2135" ,
3819 "\\Bbbk" : "\u1d55C" ,
3820 "\\beth" : "\u2136" ,
3821 "\\circledS" : "\u24c8" ,
3822 "\\complement" : "\u2201" ,
3823 "\\daleth" : "\u2138" ,
3824 "\\ell" : "\u2113" ,
3825 "\\eth" : "\u00f0" ,
3826 "\\Finv" : "\u2132" ,
3827 "\\Game" : "\u2141" ,
3828 "\\gimel" : "\u2137" ,
3829 "\\hbar" : "\u210f" ,
3830 "\\hslash" : "\u210f" ,
3831 "\\Im" : "\u2111" ,
3832 "\\mho" : "\u2127" ,
3833 "\\partial" : "\u2202" ,
3834 "\\Re" : "\u211c" ,
3835 "\\wp" : "\u2118" ,
3836 }
3837 ;
3838 var g_relation_symbols
3839 = {"=" : "=" ,
3840 "<" : "<" ,
3841 ">" : ">" ,
3842 "\\approx" : "\u2248" ,
3843 "\\approxeq" : "\u224a" ,
3844 "\\asymp" : "\u2248" ,
3845 "\\backsim" : "\u223d" ,
3846 "\\backsimeq" : "\u22cd" ,
3847 "\\bumpeq" : "\u224f" ,
3848 "\\Bumpeq" : "\u224e" ,
3849 "\\circeq" : "\u2257" ,
3850 "\\cong" : "\u2245" ,
3851 "\\curlyeqprec" : "\u22de" ,
3852 "\\curlyeqsucc" : "\u22df" ,
3853 "\\doteq" : "\u2250" ,
3854 "\\doteqdot" : "\u2251" ,
3855 "\\eqcirc" : "\u2256" ,
3856 "\\eqsim" : "\u2242" ,
3857 "\\eqslantgtr" : "\u2a96" ,
3858 "\\eqslantless" : "\u2a95" ,
3859 "\\equiv" : "\u2261" ,
3860 "\\fallingdotseq" : "\u2252" ,
3861 "\\ge" : "\u2265" ,
3862 "\\geq" : "\u2265" ,
3863 "\\geqq" : "\u2267" ,
3864 "\\geqslant" : "\u2a7e" ,
3865 "\\gg" : "\u226b" ,
3866 "\\gg" : "\u2aa2" ,
3867 "\\ggg" : "\u22d9" ,
3868 "\\gggtr" : "\u22d9" ,
3869 "\\gnapprox" : "\u2a8a" ,
3870 "\\gneq" : "\u2a88" ,
3871 "\\gneqq" : "\u2269" ,
3872 "\\gnsim" : "\u22e7" ,
3873 "\\gtrapprox" : "\u2a86" ,
3874 "\\gtreqless" : "\u22db" ,
3875 "\\gtreqqless" : "\u2a8c" ,
3876 "\\gtrless" : "\u2277" ,
3877 "\\gtrsim" : "\u2273" ,
3878 "\\gvertneqq" : "\u2269" ,
3879 "\\le" : "\u2264" ,
3880 "\\leq" : "\u2264" ,
3881 "\\leqq" : "\u2266" ,
3882 "\\leqslant" : "\u2a7d" ,
3883 "\\lessapprox" : "\u2a85" ,
3884 "\\lesseqgtr" : "\u22da" ,
3885 "\\lesseqqgtr" : "\u2a8b" ,
3886 "\\lessgtr" : "\u2276" ,
3887 "\\lesssim" : "\u2272" ,
3888 "\\ll" : "\u226a" ,
3889 "\\llless" : "\u22d8" ,
3890 "\\lnapprox" : "\u2a89" ,
3891 "\\lneq" : "\u2a87" ,
3892 "\\lneqq" : "\u2268" ,
3893 "\\lnsim" : "\u22e6" ,
3894 "\\lvertneqq" : "\u2268" ,
3895 "\\ncong" : "\u2247" ,
3896 "\\ne" : "\u2260" ,
3897 "\\neq" : "\u2260" ,
3898 "\\ngeq" : "\u2271" ,
3899 "\\ngeqq" : "\u2267" ,
3900 "\\ngeqslant" : "\u2a7e" ,
3901 "\\ngtr" : "\u226f" ,
3902 "\\nleq" : "\u2270" ,
3903 "\\nleqq" : "\u2266" ,
3904 "\\nleqslant" : "\u2a7d" ,
3905 "\\nless" : "\u226e" ,
3906 "\\nprec" : "\u2280" ,
3907 "\\npreceq" : "\u2aaf" ,
3908 "\\nsim" : "\u2241" ,
3909 "\\nsucc" : "\u2281" ,
3910 "\\nsucceq" : "\u2ab0" ,
3911 "\\prec" : "\u227a" ,
3912 "\\precapprox" : "\u2ab7" ,
3913 "\\preccurlyeq" : "\u227c" ,
3914 "\\preceq" : "\u2aaf" ,
3915 "\\precnapprox" : "\u2ab9" ,
3916 "\\precneqq" : "\u2ab5" ,
3917 "\\precnsim" : "\u22e8" ,
3918 "\\precsim" : "\u227e" ,
3919 "\\risingdotseq" : "\u2253" ,
3920 "\\sim" : "\u223c" ,
3921 "\\simeq" : "\u2243" ,
3922 "\\succ" : "\u227b" ,
3923 "\\succapprox" : "\u2ab8" ,
3924 "\\succcurlyeq" : "\u227d" ,
3925 "\\succeq" : "\u2ab0" ,
3926 "\\succnapprox" : "\u2aba" ,
3927 "\\succneqq" : "\u2ab6" ,
3928 "\\succnsim" : "\u22e9" ,
3929 "\\succsim" : "\u227f" ,
3930 "\\thickapprox" : "\u2248" ,
3931 "\\thicksim" : "\u223c" ,
3932 "\\triangleq" : "\u225c" ,
3933 "\\longrightarrow" : "\u27F6" ,
3934 "\\curvearrowleft" : "\u21b6" ,
3935 "\\curvearrowright" : "\u21b7" ,
3936 "\\downdownarrows" : "\u21ca" ,
3937 "\\downharpoonleft" : "\u21c3" ,
3938 "\\downharpoonright" : "\u21c2" ,
3939 "\\gets" : "\u2190" ,
3940 "\\hookleftarrow" : "\u21a9" ,
3941 "\\hookrightarrow" : "\u21aa" ,
3942 "\\leftarrow" : "\u2190" ,
3943 "\\Leftarrow" : "\u21d0" ,
3944 "\\leftarrowtail" : "\u21a2" ,
3945 "\\leftharpoondown" : "\u21bd" ,
3946 "\\leftharpoonup" : "\u21bc" ,
3947 "\\leftleftarrows" : "\u21c7" ,
3948 "\\leftrightarrow" : "\u2194" ,
3949 "\\leftrightarrows" : "\u21c6" ,
3950 "\\leftrightharpoons" : "\u21cb" ,
3951 "\\leftrightsquigarrow" : "\u21ad" ,
3952 "\\Lleftarrow" : "\u21da" ,
3953 "\\longleftarrow" : "\u27f5" ,
3954 "\\Longleftarrow" : "\u27f8" ,
3955 "\\longleftrightarrow" : "\u27f7" ,
3956 "\\Longleftrightarrow" : "\u27fa" ,
3957 "\\looparrowleft" : "\u21ab" ,
3958 "\\looparrowright" : "\u21ac" ,
3959 "\\Lsh" : "\u21b0" ,
3960 "\\mapsto" : "\u21a6" ,
3961 "\\multimap" : "\u22b8" ,
3962 "\\nearrow" : "\u2197" ,
3963 "\\nleftarrow" : "\u219a" ,
3964 "\\nLeftarrow" : "\u21cd" ,
3965 "\\nleftrightarrow" : "\u21ae" ,
3966 "\\nLeftrightarrow" : "\u21ce" ,
3967 "\\nrightarrow" : "\u219b" ,
3968 "\\nRightarrow" : "\u21cf" ,
3969 "\\nwarrow" : "\u2196" ,
3970 "\\restriction" : "\u21be" ,
3971 "\\rightarrow" : "\u2192" ,
3972 "\\Rightarrow" : "\u21d2" ,
3973 "\\rightarrowtail" : "\u21a3" ,
3974 "\\rightharpoondown" : "\u21c1" ,
3975 "\\rightharpoonup" : "\u21c0" ,
3976 "\\rightleftarrows" : "\u21c4" ,
3977 "\\rightleftharpoons" : "\u21cc" ,
3978 "\\rightrightarrows" : "\u21c9" ,
3979 "\\rightsquigarrow" : "\u219d" ,
3980 "\\Rrightarrow" : "\u21db" ,
3981 "\\Rsh" : "\u21b1" ,
3982 "\\searrow" : "\u2198" ,
3983 "\\swarrow" : "\u2199" ,
3984 "\\to" : "\u2192" ,
3985 "\\twoheadleftarrow" : "\u219e" ,
3986 "\\twoheadrightarrow" : "\u21a0" ,
3987 "\\upharpoonleft" : "\u21bf" ,
3988 "\\upharpoonright" : "\u21be" ,
3989 "\\upuparrows" : "\u21c8" ,
3990 "\\backepsilon" : "\u03f6" ,
3991 "\\because" : "\u2235" ,
3992 "\\between" : "\u226c" ,
3993 "\\blacktriangleleft" : "\u25c0" ,
3994 "\\blacktriangleright" : "\u25b6" ,
3995 "\\bowtie" : "\u22c8" ,
3996 "\\dashv" : "\u22a3" ,
3997 "\\frown" : "\u2323" ,
3998 "\\in" : "\u220a" ,
3999 "\\mid" : "\u2223" ,
4000 "\\models" : "\u22a7" ,
4001 "\\ni" : "\u220b" ,
4002 "\\ni" : "\u220d" ,
4003 "\\nmid" : "\u2224" ,
4004 "\\notin" : "\u2209" ,
4005 "\\nparallel" : "\u2226" ,
4006 "\\nshortmid" : "\u2224" ,
4007 "\\nshortparallel" : "\u2226" ,
4008 "\\nsubseteq" : "\u2286" ,
4009 "\\nsubseteq" : "\u2288" ,
4010 "\\nsubseteqq" : "\u2ac5" ,
4011 "\\nsupseteq" : "\u2287" ,
4012 "\\nsupseteq" : "\u2289" ,
4013 "\\nsupseteqq" : "\u2ac6" ,
4014 "\\ntriangleleft" : "\u22ea" ,
4015 "\\ntrianglelefteq" : "\u22ec" ,
4016 "\\ntriangleright" : "\u22eb" ,
4017 "\\ntrianglerighteq" : "\u22ed" ,
4018 "\\nvdash" : "\u22ac" ,
4019 "\\nvDash" : "\u22ad" ,
4020 "\\nVdash" : "\u22ae" ,
4021 "\\nVDash" : "\u22af" ,
4022 "\\owns" : "\u220d" ,
4023 "\\parallel" : "\u2225" ,
4024 "\\perp" : "\u22a5" ,
4025 "\\pitchfork" : "\u22d4" ,
4026 "\\propto" : "\u221d" ,
4027 "\\shortmid" : "\u2223" ,
4028 "\\shortparallel" : "\u2225" ,
4029 "\\smallfrown" : "\u2322" ,
4030 "\\smallsmile" : "\u2323" ,
4031 "\\smile" : "\u2323" ,
4032 "\\sqsubset" : "\u228f" ,
4033 "\\sqsubseteq" : "\u2291" ,
4034 "\\sqsupset" : "\u2290" ,
4035 "\\sqsupseteq" : "\u2292" ,
4036 "\\subset" : "\u2282" ,
4037 "\\Subset" : "\u22d0" ,
4038 "\\subseteq" : "\u2286" ,
4039 "\\subseteqq" : "\u2ac5" ,
4040 "\\subsetneq" : "\u228a" ,
4041 "\\subsetneqq" : "\u2acb" ,
4042 "\\supset" : "\u2283" ,
4043 "\\Supset" : "\u22d1" ,
4044 "\\supseteq" : "\u2287" ,
4045 "\\supseteqq" : "\u2ac6" ,
4046 "\\supsetneq" : "\u228b" ,
4047 "\\supsetneqq" : "\u2acc" ,
4048 "\\therefore" : "\u2234" ,
4049 "\\trianglelefteq" : "\u22b4" ,
4050 "\\trianglerighteq" : "\u22b5" ,
4051 "\\varpropto" : "\u221d" ,
4052 "\\varsubsetneq" : "\u228a" ,
4053 "\\varsubsetneqq" : "\u2acb" ,
4054 "\\varsupsetneq" : "\u228b" ,
4055 "\\varsupsetneqq" : "\u2acc" ,
4056 "\\vartriangle" : "\u25b5" ,
4057 "\\vartriangleleft" : "\u22b2" ,
4058 "\\vartriangleright" : "\u22b3" ,
4059 "\\vdash" : "\u22a2" ,
4060 "\\vDash" : "\u22a8" ,
4061 "\\Vdash" : "\u22a9" ,
4062 "\\Vvdash" : "\u22aa" ,
4063 // AMS Arrows
4064 "\\dashleftarrow" : "\u21e0" ,
4065 "\\dashrightarrow" : "\u21e2" ,
4066 }
4067 ;
4068 var g_named_identifiers
4069 = {"\\arccos" : "arccos" ,
4070 "\\arcsin" : "arcsin" ,
4071 "\\arctan" : "arctan" ,
4072 "\\arg" : "arg" ,
4073 "\\cos" : "cos" ,
4074 "\\cosh" : "cosh" ,
4075 "\\cot" : "cot" ,
4076 "\\coth" : "coth" ,
4077 "\\csc" : "csc" ,
4078 "\\deg" : "deg" ,
4079 "\\det" : "det" ,
4080 "\\dim" : "dim" ,
4081 "\\exp" : "exp" ,
4082 "\\gcd" : "gcd" ,
4083 "\\hom" : "hom" ,
4084 "\\ker" : "ker" ,
4085 "\\lg" : "lg" ,
4086 "\\ln" : "ln" ,
4087 "\\log" : "log" ,
4088 "\\Pr" : "Pr" ,
4089 "\\sec" : "sec" ,
4090 "\\sin" : "sin" ,
4091 "\\sinh" : "sinh" ,
4092 "\\tan" : "tan" ,
4093 "\\tanh" : "tanh" ,
4094 "\\inf" : "inf" ,
4095 "\\injlim" : "inj lim" ,
4096 "\\lim" : "lim" ,
4097 "\\liminf" : "lim inf" ,
4098 "\\limsup" : "lum sup" ,
4099 "\\max" : "max" ,
4100 "\\min" : "min" ,
4101 "\\projlim" : "proj lim" ,
4102 "\\sup" : "sup" ,
4103 "\\alpha" : "\u03b1" ,
4104 "\\beta" : "\u03b2" ,
4105 "\\chi" : "\u03c7" ,
4106 "\\delta" : "\u03b4" ,
4107 "\\Delta" : "\u0394" ,
4108 "\\digamma" : "\u03dd" ,
4109 "\\epsilon" : "\u03f5" ,
4110 "\\eta" : "\u03b7" ,
4111 "\\gamma" : "\u03b3" ,
4112 "\\Gamma" : "\u0393" ,
4113 "\\iota" : "\u03b9" ,
4114 "\\kappa" : "\u03ba" ,
4115 "\\lambda" : "\u03bb" ,
4116 "\\Lambda" : "\u039b" ,
4117 "\\mu" : "\u03bc" ,
4118 "\\nu" : "\u03bd" ,
4119 "\\omega" : "\u03c9" ,
4120 "\\Omega" : "\u03a9" ,
4121 "\\phi" : "\u03c6" ,
4122 "\\Phi" : "\u03a6" ,
4123 "\\pi" : "\u03c0" ,
4124 "\\Pi" : "\u03a0" ,
4125 "\\psi" : "\u03c8" ,
4126 "\\Psi" : "\u03a8" ,
4127 "\\rho" : "\u03c1" ,
4128 "\\sigma" : "\u03c3" ,
4129 "\\Sigma" : "\u03a3" ,
4130 "\\tau" : "\u03c4" ,
4131 "\\theta" : "\u03b8" ,
4132 "\\Theta" : "\u0398" ,
4133 "\\upsilon" : "\u03c5" ,
4134 "\\Upsilon" : "\u03d2" ,
4135 "\\varepsilon" : "\u03b5" ,
4136 "\\varkappa" : "\u03f0" ,
4137 "\\varphi" : "\u03d5" ,
4138 "\\varpi" : "\u03d6" ,
4139 "\\varrho" : "\u03f1" ,
4140 "\\varsigma" : "\u03c2" ,
4141 "\\vartheta" : "\u03d1" ,
4142 "\\xi" : "\u03be" ,
4143 "\\Xi" : "\u039e" ,
4144 "\\zeta" : "\u03b6" ,
4145 "a" : "a" ,
4146 "b" : "b" ,
4147 "c" : "c" ,
4148 "d" : "d" ,
4149 "e" : "e" ,
4150 "f" : "f" ,
4151 "g" : "g" ,
4152 "h" : "h" ,
4153 "i" : "i" ,
4154 "j" : "j" ,
4155 "k" : "k" ,
4156 "l" : "l" ,
4157 "m" : "m" ,
4158 "n" : "n" ,
4159 "o" : "o" ,
4160 "p" : "p" ,
4161 "q" : "q" ,
4162 "r" : "r" ,
4163 "s" : "s" ,
4164 "t" : "t" ,
4165 "u" : "u" ,
4166 "v" : "v" ,
4167 "w" : "w" ,
4168 "x" : "x" ,
4169 "y" : "y" ,
4170 "z" : "z" ,
4171 "A" : "A" ,
4172 "B" : "B" ,
4173 "C" : "C" ,
4174 "D" : "D" ,
4175 "E" : "E" ,
4176 "F" : "F" ,
4177 "G" : "G" ,
4178 "H" : "H" ,
4179 "I" : "I" ,
4180 "J" : "J" ,
4181 "K" : "K" ,
4182 "L" : "L" ,
4183 "M" : "M" ,
4184 "N" : "N" ,
4185 "O" : "O" ,
4186 "P" : "P" ,
4187 "Q" : "Q" ,
4188 "R" : "R" ,
4189 "S" : "S" ,
4190 "T" : "T" ,
4191 "U" : "U" ,
4192 "V" : "V" ,
4193 "W" : "W" ,
4194 "X" : "X" ,
4195 "Y" : "Y" ,
4196 "Z" : "Z" ,
4197 "\\vdots" : "\u22ee" ,
4198 "\\hdots" : "\u2026" ,
4199 "\\ldots" : "\u2026" ,
4200 "\\dots" : "\u2026" ,
4201 "\\cdots" : "\u00b7\u00b7\u00b7" ,
4202 "\\dotsb" : "\u00b7\u00b7\u00b7" ,
4203 "\\dotsc" : "\u2026" ,
4204 "\\dotsi" : "\u22c5\u22c5\u22c5" ,
4205 "\\dotsm" : "\u22c5\u22c5\u22c5" ,
4206 "\\dotso" : "\u2026" ,
4207 "\\ddots" : "\u22f1" ,
4208     // Common abbreviation for \mathbb letters
4209 "\\A" : "\uD835\uDD38" ,
4210 "\\bA" : "\uD835\uDD38" ,
4211 "\\B" : "\uD835\uDD39" ,
4212 "\\bB" : "\uD835\uDD39" ,
4213 "\\C" : "\u2102" ,
4214 "\\bC" : "\u2102" ,
4215 "\\D" : "\uD835\uDD3B" ,
4216 "\\bD" : "\uD835\uDD3B" ,
4217 "\\E" : "\uD835\uDD3C" ,
4218 "\\bE" : "\uD835\uDD3C" ,
4219 "\\F" : "\uD835\uDD3D" ,
4220 "\\bF" : "\uD835\uDD3D" ,
4221 "\\G" : "\uD835\uDD3E" ,
4222 "\\bG" : "\uD835\uDD3E" ,
4223 "\\H" : "\u210D" ,
4224 "\\bH" : "\u210D" ,
4225 "\\I" : "\uD835\uDD40" ,
4226 "\\bI" : "\uD835\uDD40" ,
4227 "\\J" : "\uD835\uDD41" ,
4228 "\\bJ" : "\uD835\uDD41" ,
4229 "\\K" : "\uD835\uDD42" ,
4230 "\\bK" : "\uD835\uDD42" ,
4231 "\\L" : "\uD835\uDD43" ,
4232 "\\bL" : "\uD835\uDD43" ,
4233 "\\M" : "\uD835\uDD44" ,
4234 "\\bM" : "\uD835\uDD44" ,
4235 "\\N" : "\u2115" ,
4236 "\\bN" : "\u2115" ,
4237 "\\O" : "\uD835\uDD46" ,
4238 "\\bO" : "\uD835\uDD46" ,
4239 "\\P" : "\u2119" ,
4240 "\\bP" : "\u2119" ,
4241 "\\Q" : "\u211A" ,
4242 "\\bQ" : "\u211A" ,
4243 "\\R" : "\u211D" ,
4244 "\\bR" : "\u211D" ,
4245 "\\S" : "\uD835\uDD4A" ,
4246 "\\bS" : "\uD835\uDD4A" ,
4247 "\\T" : "\uD835\uDD4B" ,
4248 "\\bT" : "\uD835\uDD4B" ,
4249 "\\U" : "\uD835\uDD4C" ,
4250 "\\bU" : "\uD835\uDD4C" ,
4251 "\\V" : "\uD835\uDD4D" ,
4252 "\\bV" : "\uD835\uDD4D" ,
4253 "\\W" : "\uD835\uDD4E" ,
4254 "\\bW" : "\uD835\uDD4E" ,
4255 "\\X" : "\uD835\uDD4F" ,
4256 "\\bX" : "\uD835\uDD4F" ,
4257 "\\Y" : "\uD835\uDD50" ,
4258 "\\bY" : "\uD835\uDD50" ,
4259 "\\Z" : "\u2124" ,
4260 "\\bZ" : "\u2124" ,
4261     // Common abbreviations for \mathcal letters
4262 "\\cA" : "\uD835\uDC9C" ,
4263 "\\cB" : "\u212C" ,
4264 "\\cC" : "\uD835\uDC9E" ,
4265 "\\cD" : "\uD835\uDC9F" ,
4266 "\\cE" : "\u2130" ,
4267 "\\cF" : "\u2131" ,
4268 "\\cG" : "\uD835\uDCA2" ,
4269 "\\cH" : "\u210B" ,
4270 "\\cI" : "\u2110" ,
4271 "\\cJ" : "\uD835\uDCA5" ,
4272 "\\cK" : "\uD835\uDCA6" ,
4273 "\\cL" : "\u2112" ,
4274 "\\cM" : "\u2133" ,
4275 "\\cN" : "\uD835\uDCA9" ,
4276 "\\cO" : "\uD835\uDCAA" ,
4277 "\\OO" : "\uD835\uDCAA" ,
4278 "\\cP" : "\uD835\uDCAB" ,
4279 "\\cQ" : "\uD835\uDCAC" ,
4280 "\\cR" : "\u211B" ,
4281 "\\cS" : "\uD835\uDCAE" ,
4282 "\\cT" : "\uD835\uDCAF" ,
4283 "\\cU" : "\uD835\uDCB0" ,
4284 "\\cV" : "\uD835\uDCB1" ,
4285 "\\cW" : "\uD835\uDCB2" ,
4286 "\\cX" : "\uD835\uDCB3" ,
4287 "\\cY" : "\uD835\uDCB4" ,
4288 "\\cZ" : "\uD835\uDCB5" ,
4289     // Common operators
4290     "\\Pic" : "Pic" ,
4291     "\\Spec" : "Spec" ,
4292     "\\Proj" : "Proj" ,
4293     // Misc
4294 "\\eps" : "\u03f5" ,
4295 }
4296 ;
4297 var g_word_operators
4298 = {"\\arccos" : "arccos" ,
4299 "\\arcsin" : "arcsin" ,
4300 "\\arctan" : "arctan" ,
4301 "\\arg" : "arg" ,
4302 "\\cos" : "cos" ,
4303 "\\cosh" : "cosh" ,
4304 "\\cot" : "cot" ,
4305 "\\coth" : "coth" ,
4306 "\\csc" : "csc" ,
4307 "\\deg" : "deg" ,
4308 "\\det" : "det" ,
4309 "\\dim" : "dim" ,
4310 "\\exp" : "exp" ,
4311 "\\gcd" : "gcd" ,
4312 "\\hom" : "hom" ,
4313 "\\ker" : "ker" ,
4314 "\\lg" : "lg" ,
4315 "\\ln" : "ln" ,
4316 "\\log" : "log" ,
4317 "\\Pr" : "Pr" ,
4318 "\\sec" : "sec" ,
4319 "\\sin" : "sin" ,
4320 "\\sinh" : "sinh" ,
4321 "\\tan" : "tan" ,
4322 "\\tanh" : "tanh" ,
4323 }
4324 ;
4325 var g_big_word_operators
4326 = {"\\inf" : "inf" ,
4327 "\\injlim" : "inj lim" ,
4328 "\\lim" : "lim" ,
4329 "\\liminf" : "lim inf" ,
4330 "\\limsup" : "lum sup" ,
4331 "\\max" : "max" ,
4332 "\\min" : "min" ,
4333 "\\projlim" : "proj lim" ,
4334 "\\sup" : "sup" ,
4335 }
4336 ;
4337 var g_greek_letters
4338 = {"\\alpha" : "\u03b1" ,
4339 "\\beta" : "\u03b2" ,
4340 "\\chi" : "\u03c7" ,
4341 "\\delta" : "\u03b4" ,
4342 "\\Delta" : "\u0394" ,
4343 "\\digamma" : "\u03dd" ,
4344 "\\epsilon" : "\u03f5" ,
4345 "\\eta" : "\u03b7" ,
4346 "\\gamma" : "\u03b3" ,
4347 "\\Gamma" : "\u0393" ,
4348 "\\iota" : "\u03b9" ,
4349 "\\kappa" : "\u03ba" ,
4350 "\\lambda" : "\u03bb" ,
4351 "\\Lambda" : "\u039b" ,
4352 "\\mu" : "\u03bc" ,
4353 "\\nu" : "\u03bd" ,
4354 "\\omega" : "\u03c9" ,
4355 "\\Omega" : "\u03a9" ,
4356 "\\phi" : "\u03c6" ,
4357 "\\Phi" : "\u03a6" ,
4358 "\\pi" : "\u03c0" ,
4359 "\\Pi" : "\u03a0" ,
4360 "\\psi" : "\u03c8" ,
4361 "\\Psi" : "\u03a8" ,
4362 "\\rho" : "\u03c1" ,
4363 "\\sigma" : "\u03c3" ,
4364 "\\Sigma" : "\u03a3" ,
4365 "\\tau" : "\u03c4" ,
4366 "\\theta" : "\u03b8" ,
4367 "\\Theta" : "\u0398" ,
4368 "\\upsilon" : "\u03c5" ,
4369 "\\Upsilon" : "\u03d2" ,
4370 "\\varepsilon" : "\u03b5" ,
4371 "\\varkappa" : "\u03f0" ,
4372 "\\varphi" : "\u03d5" ,
4373 "\\varpi" : "\u03d6" ,
4374 "\\varrho" : "\u03f1" ,
4375 "\\varsigma" : "\u03c2" ,
4376 "\\vartheta" : "\u03d1" ,
4377 "\\xi" : "\u03be" ,
4378 "\\Xi" : "\u039e" ,
4379 "\\zeta" : "\u03b6" ,
4380 }
4381 ;
4382 function v_fraction_to_mathml (tokens ) {
4383  var v_numerator = v_piece_to_mathml (tokens ) ;
4384  var v_denominator = v_piece_to_mathml (tokens ) ;
4385  return result_element( "mfrac" ,0 , v_numerator , v_denominator ) ;
4386 }
4387 function v_binom_to_mathml (tokens ) {
4388  var v_top = v_piece_to_mathml (tokens ) ;
4389  var v_bottom = v_piece_to_mathml (tokens ) ;
4390  return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mfrac" , 1
4391 , "linethickness" , "0" , v_top , v_bottom ) , result_element( "mo" ,0 , ")" ) ) ;
4392 }
4393 function v_sqrt_to_mathml (tokens ) {
4394  var v_index = v_optional_arg_to_mathml (tokens ) ;
4395  var v_object = v_piece_to_mathml (tokens ) ;
4396  if( ( v_index != null ) ) {
4397   return result_element( "mroot" ,0 , v_object , v_index ) ;
4398  }
4399  else {
4400   return result_element( "msqrt" ,0 , v_object ) ;
4401  }
4402 }
4403 function v_parenthesized_operator (tokens , v_word ) {
4404  var v_object = v_piece_to_mathml (tokens ) ;
4405  if( ( v_word != null ) ) {
4406   return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mo" ,0 , v_word ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4407  }
4408  else {
4409   return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4410  }
4411 }
4412 function v_operatorname_to_mathml (tokens ) {
4413  var v_result = result_element( "mo" ,0 , tokens.list[tokens.index] ) ;
4414  tokens.index++;
4415  return v_result ;
4416 }
4417 function v_displaystyle_to_mathml (tokens ) {
4418  var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4419 ) ;
4420  return result_element( "mstyle" , 2
4421 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4422 }
4423 function v_displaymath_to_mathml (tokens ) {
4424  var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4425 ) ;
4426   v_finish_latex_block (tokens );
4427  return result_element( "mstyle" , 2
4428 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4429 }
4430 function v_font_to_mathml (tokens , v_font_name ) {
4431  if( ( tokens.list[tokens.index] != "{" ) ) {
4432   var v_result = result_element( "mi" , 1
4433 , "mathvariant" , v_font_name , tokens.list[tokens.index] ) ;
4434   if( ( v_font_name == "normal" ) ) {
4435    result_set_attr(
4436 v_result , "fontstyle" , "normal" );
4437   }
4438   tokens.index++;
4439   return v_result ;
4440  }
4441  else {
4442   var v_result = v_piece_to_mathml (tokens ) ;
4443   result_set_attr(
4444 v_result , "mathvariant" , v_font_name );
4445   if( ( v_font_name == "normal" ) ) {
4446    result_set_attr(
4447 v_result , "fontstyle" , "normal" );
4448   }
4449   return v_result ;
4450  }
4451 }
4452 function v_old_font_to_mathml (tokens , v_font_name ) {
4453  return result_element( "mstyle" , 2
4454 , "mathvariant" , v_font_name , "fontstyle" , ( ( v_font_name == "normal" ) ? "normal" : null ) , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4455 ) ) ;
4456 }
4457 function v_size_to_mathml (tokens , v_min_size , v_max_size ) {
4458  var v_result = v_piece_to_mathml (tokens ) ;
4459  result_set_attr(
4460 v_result , "minsize" , v_min_size );
4461  result_set_attr(
4462 v_result , "maxsize" , v_max_size );
4463  return v_result ;
4464 }
4465 function v_accent_to_mathml (tokens , v_char ) {
4466  return result_element( "mover" , 1
4467 , "accent" , "true" , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4468 }
4469 function v_matrix_to_mathml (tokens , v_open_delim , v_close_delim ) {
4470  var v_mtable = v_matrix_to_mtable (tokens , result_element( "mtable" ,0) ) ;
4471  if( ( ( v_open_delim != null )  ||  ( v_close_delim != null ) ) ) {
4472   var v_mrow = result_element( "mrow" ,0) ;
4473   if( ( v_open_delim != null ) ) {
4474    result_element_append( v_mrow , result_element( "mo" ,0 , v_open_delim ) );
4475   }
4476   result_element_append( v_mrow , v_mtable );
4477   if( ( v_close_delim != null ) ) {
4478    result_element_append( v_mrow , result_element( "mo" ,0 , v_close_delim ) );
4479   }
4480   return v_mrow ;
4481  }
4482  else {
4483   return v_mtable ;
4484  }
4485 }
4486 function v_array_to_mathml (tokens ) {
4487  var v_mtable = result_element( "mtable" ,0) ;
4488  if( ( tokens.list[tokens.index] == "{" ) ) {
4489   tokens.index++;
4490   while( ( ( tokens.list[tokens.index] != null )  &&  ( tokens.list[tokens.index] != "}" ) ) ) {
4491    if( ( tokens.list[tokens.index] == "c" ) ) {
4492     result_append_attr(
4493 v_mtable , "columnalign" , "center " );
4494    }
4495    else if( ( tokens.list[tokens.index] == "l" ) ) {
4496     result_append_attr(
4497 v_mtable , "columnalign" , "left " );
4498    }
4499    else if( ( tokens.list[tokens.index] == "r" ) ) {
4500     result_append_attr(
4501 v_mtable , "columnalign" , "right " );
4502    }
4503    tokens.index++;
4504   }
4505   if( ( tokens.list[tokens.index] != null ) ) {
4506    tokens.index++;
4507   }
4508  }
4509  return v_matrix_to_mtable (tokens , v_mtable ) ;
4510 }
4511 function v_matrix_to_mtable (tokens , v_mtable ) {
4512  var v_mtr = result_element( "mtr" ,0) ;
4513  var v_mtd = result_element( "mtd" ,0) ;
4514  var v_token = tokens.list[tokens.index] ;
4515  result_element_append( v_mtable , v_mtr );
4516  result_element_append( v_mtr , v_mtd );
4517  while( ( ( v_token != null )  &&  ( v_token != "\\end" ) ) ) {
4518   if( ( v_token == "\\\\" ) ) {
4519     v_mtr = result_element( "mtr" ,0) ;
4520     v_mtd = result_element( "mtd" ,0) ;
4521    result_element_append( v_mtable , v_mtr );
4522    result_element_append( v_mtr , v_mtd );
4523    tokens.index++;
4524   }
4525   else if( ( v_token == "&" ) ) {
4526     v_mtd = result_element( "mtd" ,0) ;
4527    result_element_append( v_mtr , v_mtd );
4528    tokens.index++;
4529   }
4530   else {
4531    result_element_append( v_mtd , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4532 ) );
4533   }
4534    v_token = tokens.list[tokens.index] ;
4535  }
4536   v_finish_latex_block (tokens );
4537  return v_mtable ;
4538 }
4539 function v_over_to_mathml (tokens , v_char ) {
4540  return result_element( "mover" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4541 }
4542 function v_under_to_mathml (tokens , v_char ) {
4543  return result_element( "munder" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4544 }
4545 function v_delimiter_to_mathml (tokens , v_end_command , v_min_size , v_max_size ) {
4546  var v_mrow = result_element( "mrow" ,0) ;
4547  result_element_append( v_mrow , result_element( "mo" , 2
4548 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4549  result_element_append( v_mrow , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4550 ) );
4551  if( ( tokens.list[tokens.index] != v_end_command ) ) {
4552   return v_mrow ;
4553  }
4554  tokens.index++;
4555  result_element_append( v_mrow , result_element( "mo" , 2
4556 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4557  return v_mrow ;
4558 }
4559 function v_read_delimiter (tokens ) {
4560  var v_token = tokens.list[tokens.index] ;
4561  if( ( v_token == null ) ) {
4562   throw "unexpected eof" ;
4563  }
4564  else if( ( v_token == "." ) ) {
4565   tokens.index++;
4566   return "" ;
4567  }
4568  else if( ( v_token == "<" ) ) {
4569   tokens.index++;
4570   return "\u2329" ;
4571  }
4572  else if( ( v_token == ">" ) ) {
4573   tokens.index++;
4574   return "\u232a" ;
4575  }
4576  else if( ( v_token in g_punct_and_space
4577 ) ) {
4578   tokens.index++;
4579   return g_punct_and_space
4580 [ v_token ] ;
4581  }
4582  else if( ( v_token in g_left_delimiters
4583 ) ) {
4584   tokens.index++;
4585   return g_left_delimiters
4586 [ v_token ] ;
4587  }
4588  else if( ( v_token in g_right_delimiters
4589 ) ) {
4590   tokens.index++;
4591   return g_right_delimiters
4592 [ v_token ] ;
4593  }
4594  else if( ( v_token in g_operator_symbols
4595 ) ) {
4596   tokens.index++;
4597   return g_operator_symbols
4598 [ v_token ] ;
4599  }
4600  else {
4601   throw "invalid delimiter" ;
4602  }
4603 }
4604 function v_latex_block_to_mathml (tokens ) {
4605   v_cmd = tokens.list[tokens.index] ;
4606  if( ( v_cmd in g_tex_environments
4607 ) ) {
4608   tokens.index++;
4609   return g_tex_environments
4610 [ v_cmd ] (tokens ) ;
4611  }
4612  else {
4613   throw "unknown command" ;
4614  }
4615 }
4616 function v_finish_latex_block (tokens ) {
4617  if( ( tokens.list[tokens.index] == null ) ) {
4618   throw "unexpected eof" ;
4619  }
4620  tokens.index++;
4621  tokens.index++;
4622 }
4623 function v_combining_to_mathml (tokens , v_char ) {
4624  var v_base = tokens.list[tokens.index] ;
4625  tokens.index++;
4626  return result_element( "mo" ,0 , v_base , v_char ) ;
4627 }
4628 var g_char_escape_codes
4629 = {"93" : "#" ,
4630 }
4631 ;
4632 function v_char_escape_to_mathml (tokens ) {
4633  var v_result = null ;
4634  if( ( tokens.list[tokens.index] in g_char_escape_codes
4635 ) ) {
4636    v_result = result_element( "mtext" ,0 , g_char_escape_codes
4637 [ tokens.list[tokens.index] ] ) ;
4638  }
4639  else {
4640    v_result = result_element( "merror" ,0 , "\\char" , tokens.list[tokens.index] ) ;
4641  }
4642  tokens.index++;
4643  return v_result ;
4644 }
4645 function v_text_to_mathml (tokens ) {
4646  if( ( tokens.list[tokens.index] != "{" ) ) {
4647   var v_result = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4648   tokens.index++;
4649   return v_result ;
4650  }
4651  tokens.index++;
4652  var v_result = null ;
4653  var v_mrow = null ;
4654  var v_node = null ;
4655  while( ( tokens.list[tokens.index] != null ) ) {
4656   if( ( tokens.list[tokens.index] == "}" ) ) {
4657    tokens.index++;
4658    return v_result ;
4659   }
4660   else if( ( tokens.list[tokens.index] == "$" ) ) {
4661    tokens.index++;
4662     v_node = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4663 ) ;
4664    tokens.index++;
4665   }
4666   else {
4667     v_node = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4668    tokens.index++;
4669   }
4670   if( ( v_mrow != null ) ) {
4671    result_element_append( v_mrow , v_node );
4672   }
4673   else if( ( v_result != null ) ) {
4674     v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
4675     v_result = v_mrow ;
4676   }
4677   else {
4678     v_result = v_node ;
4679   }
4680  }
4681  return v_result ;
4682 }
4683 var g_tex_commands
4684 = {
4685 "\\frac" : v_fraction_to_mathml ,
4686 "\\dfrac" : v_fraction_to_mathml ,
4687 "\\tfrac" : v_fraction_to_mathml ,
4688 "\\binom" : v_binom_to_mathml ,
4689 "\\sqrt" : v_sqrt_to_mathml ,
4690 "\\operatorname" : v_operatorname_to_mathml ,
4691 "\\displaystyle" : v_displaystyle_to_mathml ,
4692 "\\pod" : function(tokens ) {return v_parenthesized_operator (tokens , null ) ;} ,
4693 "\\pmod" : function(tokens ) {return v_parenthesized_operator (tokens , "mod" ) ;} ,
4694 "\\boldsymbol" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4695 "\\bold" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4696 "\\Bbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4697 "\\mathbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4698 "\\mathbbmss" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4699 "\\mathbf" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4700 "\\mathop" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4701 "\\mathopen" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4702 "\\mathclose" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4703 "\\mathrm" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4704 "\\mathfrak" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4705 "\\germ" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4706 "\\mathit" : function(tokens ) {return v_font_to_mathml (tokens , "italic" ) ;} ,
4707 "\\mathscr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4708 "\\scr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4709 "\\mathcal" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4710 "\\mathsf" : function(tokens ) {return v_font_to_mathml (tokens , "sans-serif" ) ;} ,
4711 "\\mathtt" : function(tokens ) {return v_font_to_mathml (tokens , "monospace" ) ;} ,
4712 "\\EuScript" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4713 "\\bf" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4714 "\\rm" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4715 "\\roman" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4716 "\\tag" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4717 "\\big" : function(tokens ) {return v_size_to_mathml (tokens , "2" , "2" ) ;} ,
4718 "\\Big" : function(tokens ) {return v_size_to_mathml (tokens , "3" , "3" ) ;} ,
4719 "\\bigg" : function(tokens ) {return v_size_to_mathml (tokens , "4" , "4" ) ;} ,
4720 "\\Bigg" : function(tokens ) {return v_size_to_mathml (tokens , "5" , "5" ) ;} ,
4721 "\\acute" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0301" ) ;} ,
4722 "\\grave" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0300" ) ;} ,
4723 "\\tilde" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0303" ) ;} ,
4724 "\\bar" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0304" ) ;} ,
4725 "\\breve" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0306" ) ;} ,
4726 "\\check" : function(tokens ) {return v_accent_to_mathml (tokens , "\u030c" ) ;} ,
4727 "\\hat" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0302" ) ;} ,
4728 "\\vec" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20d7" ) ;} ,
4729 "\\dot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0307" ) ;} ,
4730 "\\ddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0308" ) ;} ,
4731 "\\dddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20db" ) ;} ,
4732 "\\underbrace" : function(tokens ) {return v_under_to_mathml (tokens , "\ufe38" ) ;} ,
4733 "\\overbrace" : function(tokens ) {return v_over_to_mathml (tokens , "\ufe37" ) ;} ,
4734 "\\underline" : function(tokens ) {return v_under_to_mathml (tokens , "\u0332" ) ;} ,
4735 "\\overline" : function(tokens ) {return v_over_to_mathml (tokens , "\u00af" ) ;} ,
4736 "\\widetilde" : function(tokens ) {return v_over_to_mathml (tokens , "\u0303" ) ;} ,
4737 "\\widehat" : function(tokens ) {return v_over_to_mathml (tokens , "\u0302" ) ;} ,
4738 "\\not" : function(tokens ) {return v_combining_to_mathml (tokens , "\u0338" ) ;} ,
4739 "\\left" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\right" , "1" , null ) ;} ,
4740 "\\bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\bigr" , "2" , "2" ) ;} ,
4741 "\\Bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Bigr" , "3" , "3" ) ;} ,
4742 "\\biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\biggr" , "4" , "4" ) ;} ,
4743 "\\Biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Biggr" , "5" , "5" ) ;} ,
4744 "\\char" : v_char_escape_to_mathml ,
4745 "\\!" : function(tokens ) {return null ;} ,
4746 "\\text" : v_text_to_mathml ,
4747 "\\textnormal" : v_text_to_mathml ,
4748 "\\textrm" : v_text_to_mathml ,
4749 "\\textsl" : v_text_to_mathml ,
4750 "\\textit" : v_text_to_mathml ,
4751 "\\texttt" : v_text_to_mathml ,
4752 "\\textbf" : v_text_to_mathml ,
4753 "\\hbox" : v_text_to_mathml ,
4754 "\\mbox" : v_text_to_mathml ,
4755 "\\begin" : v_latex_block_to_mathml ,
4756 }
4757 ;
4758 var g_tex_environments
4759 = {"smallmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4760 "pmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4761 "bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "[" , "]" ) ;} ,
4762 "Bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , "}" ) ;} ,
4763 "vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "|" , "|" ) ;} ,
4764 "Vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "\u2016" , "\u2016" ) ;} ,
4765 "cases" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , null ) ;} ,
4766 "array" : v_array_to_mathml ,
4767 "displaymath" : v_displaymath_to_mathml ,
4768 }
4769 ;
4770 var g_limit_commands
4771 = {"\\bigcap" : "\u22c2" ,
4772 "\\bigcup" : "\u22c3" ,
4773 "\\bigodot" : "\u2a00" ,
4774 "\\bigoplus" : "\u2a01" ,
4775 "\\bigotimes" : "\u2a02" ,
4776 "\\bigsqcup" : "\u2a06" ,
4777 "\\biguplus" : "\u2a04" ,
4778 "\\bigvee" : "\u22c1" ,
4779 "\\bigwedge" : "\u22c0" ,
4780 "\\coprod" : "\u2210" ,
4781 "\\prod" : "\u220f" ,
4782 "\\sum" : "\u2211" ,
4783 "\\inf" : "inf" ,
4784 "\\injlim" : "inj lim" ,
4785 "\\lim" : "lim" ,
4786 "\\liminf" : "lim inf" ,
4787 "\\limsup" : "lum sup" ,
4788 "\\max" : "max" ,
4789 "\\min" : "min" ,
4790 "\\projlim" : "proj lim" ,
4791 "\\sup" : "sup" ,
4792 "\\underbrace" : null ,
4793 "\\overbrace" : null ,
4794 "\\underline" : null ,
4795 "\\overline" : null ,
4796 }
4797 ;
4798 function v_piece_to_mathml (tokens ) {
4799  var v_token = tokens.list[tokens.index] ;
4800  var v_result = null ;
4801  if( ( v_token == "{" ) ) {
4802   tokens.index++;
4803    v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4804 ) ;
4805   if( ( tokens.list[tokens.index] == "}" ) ) {
4806    tokens.index++;
4807   }
4808  }
4809  else if( ( v_token in g_relation_symbols
4810 ) ) {
4811    v_result = result_element( "mo" ,0 , g_relation_symbols
4812 [ v_token ] ) ;
4813   tokens.index++;
4814  }
4815  else if( ( v_token in g_operator_symbols
4816 ) ) {
4817    v_result = result_element( "mo" ,0 , g_operator_symbols
4818 [ v_token ] ) ;
4819   tokens.index++;
4820  }
4821  else if( ( v_token in g_left_delimiters
4822 ) ) {
4823    v_result = result_element( "mo" ,0 , g_left_delimiters
4824 [ v_token ] ) ;
4825   tokens.index++;
4826  }
4827  else if( ( v_token in g_right_delimiters
4828 ) ) {
4829    v_result = result_element( "mo" ,0 , g_right_delimiters
4830 [ v_token ] ) ;
4831   tokens.index++;
4832  }
4833  else if( ( v_token in g_word_operators
4834 ) ) {
4835    v_result = result_element( "mi" , 1
4836 , "mathvariant" , "normal" , g_word_operators
4837 [ v_token ] ) ;
4838   tokens.index++;
4839  }
4840  else if( ( v_token in g_greek_letters
4841 ) ) {
4842    v_result = result_element( "mi" , 1
4843 , "fontstyle" , "normal" , g_greek_letters
4844 [ v_token ] ) ;
4845   tokens.index++;
4846  }
4847  else if( ( v_token in g_named_identifiers
4848 ) ) {
4849    v_result = result_element( "mi" ,0 , g_named_identifiers
4850 [ v_token ] ) ;
4851   tokens.index++;
4852  }
4853  else if( ( v_token in g_punct_and_space
4854 ) ) {
4855    v_result = result_element( "mtext" ,0 , g_punct_and_space
4856 [ v_token ] ) ;
4857   tokens.index++;
4858  }
4859  else if( ( v_token in g_tex_commands
4860 ) ) {
4861   tokens.index++;
4862    v_result = g_tex_commands
4863 [ v_token ] (tokens ) ;
4864  }
4865  else {
4866    v_result = result_element( "mn" ,0 , v_token ) ;
4867   tokens.index++;
4868  }
4869  return v_result ;
4870 }
4871 function v_subexpr_to_mathml (tokens ) {
4872  var v_result = null ;
4873  var v_mmultiscripts = null ;
4874  var v_mprescripts = null ;
4875  if( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4876 == "{" )  &&  ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4877 == "}" )  &&  ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4878 == "_" )  ||  ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4879 == "^" ) ) ) ) {
4880    v_mmultiscripts = result_element( "mmultiscripts" ,0) ;
4881    v_mprescripts = result_element( "mprescripts" ,0) ;
4882   result_element_append( v_mmultiscripts , v_mprescripts );
4883   while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4884 == "{" )  &&  ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4885 == "}" )  &&  ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4886 == "_" )  ||  ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4887 == "^" ) ) ) ) {
4888    var v_subscript = null ;
4889    var v_superscript = null ;
4890    tokens.index++;
4891    tokens.index++;
4892    if( ( tokens.list[tokens.index] == "_" ) ) {
4893     tokens.index++;
4894      v_subscript = v_piece_to_mathml (tokens ) ;
4895    }
4896    else if( ( tokens.list[tokens.index] == "^" ) ) {
4897     tokens.index++;
4898      v_superscript = v_piece_to_mathml (tokens ) ;
4899    }
4900    if( ( tokens.list[tokens.index] == "_" ) ) {
4901     tokens.index++;
4902      v_subscript = v_piece_to_mathml (tokens ) ;
4903    }
4904    else if( ( tokens.list[tokens.index] == "^" ) ) {
4905     tokens.index++;
4906      v_superscript = v_piece_to_mathml (tokens ) ;
4907    }
4908    result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4909    result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4910   }
4911  }
4912  var v_limit_style = ( tokens.list[tokens.index] in g_limit_commands
4913 ) ;
4914  if( ( tokens.list[tokens.index] == null ) ) {
4915   if( ( v_mmultiscripts != null ) ) {
4916    result_element_prepend( v_mmultiscripts , result_element( "mrow" ,0) , v_mprescripts );
4917    return v_mmultiscripts ;
4918   }
4919   else {
4920    return result_element( "mrow" ,0) ;
4921   }
4922  }
4923  else if( ( tokens.list[tokens.index] in g_left_delimiters
4924 ) ) {
4925    v_result = v_heuristic_subexpression (tokens ) ;
4926  }
4927  else {
4928    v_result = v_piece_to_mathml (tokens ) ;
4929  }
4930  var v_base = v_result ;
4931  var v_subscript = null ;
4932  var v_superscript = null ;
4933  if( ( tokens.list[tokens.index] == "_" ) ) {
4934   tokens.index++;
4935    v_subscript = v_piece_to_mathml (tokens ) ;
4936  }
4937  else if( ( tokens.list[tokens.index] == "^" ) ) {
4938   tokens.index++;
4939    v_superscript = v_piece_to_mathml (tokens ) ;
4940  }
4941  if( ( tokens.list[tokens.index] == "_" ) ) {
4942   tokens.index++;
4943    v_subscript = v_piece_to_mathml (tokens ) ;
4944  }
4945  else if( ( tokens.list[tokens.index] == "^" ) ) {
4946   tokens.index++;
4947    v_superscript = v_piece_to_mathml (tokens ) ;
4948  }
4949  if( ( v_mmultiscripts != null ) ) {
4950   result_element_prepend( v_mmultiscripts , v_base , v_mprescripts );
4951   result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4952   result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4953  }
4954  while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4955 == "{" )  &&  ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4956 == "}" )  &&  ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4957 == "_" )  ||  ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4958 == "^" ) ) ) ) {
4959   if( ( v_mmultiscripts == null ) ) {
4960     v_mmultiscripts = result_element( "mmultiscripts" ,0 , v_base ) ;
4961     v_mprescripts = null ;
4962    if( ( ( v_superscript != null )  ||  ( v_subscript != null ) ) ) {
4963     result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4964     result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4965    }
4966   }
4967   var v_subscript = null ;
4968   var v_superscript = null ;
4969   tokens.index++;
4970   tokens.index++;
4971   if( ( tokens.list[tokens.index] == "_" ) ) {
4972    tokens.index++;
4973     v_subscript = v_piece_to_mathml (tokens ) ;
4974   }
4975   else if( ( tokens.list[tokens.index] == "^" ) ) {
4976    tokens.index++;
4977     v_superscript = v_piece_to_mathml (tokens ) ;
4978   }
4979   if( ( tokens.list[tokens.index] == "_" ) ) {
4980    tokens.index++;
4981     v_subscript = v_piece_to_mathml (tokens ) ;
4982   }
4983   else if( ( tokens.list[tokens.index] == "^" ) ) {
4984    tokens.index++;
4985     v_superscript = v_piece_to_mathml (tokens ) ;
4986   }
4987   result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4988   result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4989  }
4990  if( ( v_mmultiscripts != null ) ) {
4991    v_result = v_mmultiscripts ;
4992  }
4993  else if( ( ( v_subscript != null )  &&  ( v_superscript != null ) ) ) {
4994    v_result = result_element( ( v_limit_style ? "munderover" : "msubsup" ) ,0 , v_base , v_subscript , v_superscript ) ;
4995  }
4996  else if( ( v_subscript != null ) ) {
4997    v_result = result_element( ( v_limit_style ? "munder" : "msub" ) ,0 , v_base , v_subscript ) ;
4998  }
4999  else if( ( v_superscript != null ) ) {
5000    v_result = result_element( ( v_limit_style ? "mover" : "msup" ) ,0 , v_base , v_superscript ) ;
5001  }
5002  return v_result ;
5003 }
5004 function v_subexpr_chain_to_mathml (tokens , v_stop_tokens ) {
5005  var v_result = null ;
5006  var v_mrow = null ;
5007  var v_mfrac = null ;
5008  var v_wrapped_result = null ;
5009  while( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in v_stop_tokens ) ) ) ) {
5010   if( ( tokens.list[tokens.index] == "\\over" ) ) {
5011    tokens.index++;
5012     v_mfrac = result_element( "mfrac" ,0 , v_result ) ;
5013     v_wrapped_result = v_mfrac ;
5014     v_mrow = null ;
5015     v_result = null ;
5016   }
5017   else if( ( tokens.list[tokens.index] == "\\choose" ) ) {
5018    tokens.index++;
5019     v_mfrac = result_element( "mfrac" , 1
5020 , "linethickness" , "0" , v_result ) ;
5021     v_wrapped_result = result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_mfrac , result_element( "mo" ,0 , ")" ) ) ;
5022     v_mrow = null ;
5023     v_result = null ;
5024   }
5025   else {
5026    var v_node = v_collect_precedence_group (tokens , g_relations_precedence_group
5027 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_addition_precedence_group
5028 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_multiplication_precedence_group
5029 , v_stop_tokens , v_collect_invisible_group ) ;} ) ;} ) ;
5030    if( ( v_mrow != null ) ) {
5031     result_element_append( v_mrow , v_node );
5032    }
5033    else if( ( v_result != null ) ) {
5034      v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
5035      v_result = v_mrow ;
5036    }
5037    else {
5038      v_result = v_node ;
5039    }
5040   }
5041  }
5042  if( ( v_mfrac != null ) ) {
5043   result_element_append( v_mfrac , v_result );
5044   return v_wrapped_result ;
5045  }
5046  else {
5047   return v_result ;
5048  }
5049 }
5050 var g_optional_arg_stop_tokens
5051 = {"&" : null ,
5052 "\\\\" : null ,
5053 "}" : null ,
5054 "$" : null ,
5055 "\\end" : null ,
5056 "\\right" : null ,
5057 "\\bigr" : null ,
5058 "\\Bigr" : null ,
5059 "\\biggr" : null ,
5060 "\\Biggr" : null ,
5061 "\\choose" : null ,
5062 "\\over" : null ,
5063 "]" : null ,
5064 }
5065 ;
5066 function v_optional_arg_to_mathml (tokens ) {
5067  if( ( tokens.list[tokens.index] != "[" ) ) {
5068   return null ;
5069  }
5070  tokens.index++;
5071  var v_result = v_subexpr_chain_to_mathml (tokens , g_optional_arg_stop_tokens
5072 ) ;
5073  if( ( tokens.list[tokens.index] == "]" ) ) {
5074   tokens.index++;
5075  }
5076  return v_result ;
5077 }
5078 var g_hard_stop_tokens
5079 = {"&" : null ,
5080 "\\\\" : null ,
5081 "}" : null ,
5082 "$" : null ,
5083 "\\end" : null ,
5084 "\\right" : null ,
5085 "\\bigr" : null ,
5086 "\\Bigr" : null ,
5087 "\\biggr" : null ,
5088 "\\Biggr" : null ,
5089 "\\choose" : null ,
5090 "\\over" : null ,
5091 }
5092 ;
5093 var g_right_delimiter_stop_tokens
5094 = {"&" : null ,
5095 "\\\\" : null ,
5096 "}" : null ,
5097 "$" : null ,
5098 "\\end" : null ,
5099 "\\right" : null ,
5100 "\\bigr" : null ,
5101 "\\Bigr" : null ,
5102 "\\biggr" : null ,
5103 "\\Biggr" : null ,
5104 "\\choose" : null ,
5105 "\\over" : null ,
5106 ")" : ")" ,
5107 "]" : "]" ,
5108 "\\}" : "}" ,
5109 "\\rbrace" : "}" ,
5110 "\\rgroup" : ")" ,
5111 "\\rvert" : "|" ,
5112 "\\rVert" : "\u2016" ,
5113 "\\rceil" : "\u2309" ,
5114 "\\rfloor" : "\u230b" ,
5115 "\\rmoustache" : "\u23b1" ,
5116 "\\rangle" : "\u232a" ,
5117 }
5118 ;
5119 function v_heuristic_subexpression (tokens ) {
5120  var v_result = result_element( "mrow" ,0) ;
5121  result_element_append( v_result , v_piece_to_mathml (tokens ) );
5122  result_element_append( v_result , v_subexpr_chain_to_mathml (tokens , g_right_delimiter_stop_tokens
5123 ) );
5124  if( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in g_hard_stop_tokens
5125 ) ) ) ) {
5126   result_element_append( v_result , v_piece_to_mathml (tokens ) );
5127  }
5128  return v_result ;
5129 }
5130 var g_relations_precedence_group
5131 = g_relation_symbols
5132 ;
5133 var g_addition_precedence_group
5134 = {"+" : null ,
5135 "-" : null ,
5136 "\\oplus" : null ,
5137 }
5138 ;
5139 var g_multiplication_precedence_group
5140 = {"*" : null ,
5141 "\\times" : null ,
5142 "\\cdot" : null ,
5143 "/" : null ,
5144 }
5145 ;
5146 function v_collect_precedence_group (tokens , v_operators , v_stop_tokens , v_reader ) {
5147  var v_result = v_reader (tokens , v_stop_tokens ) ;
5148  var v_mrow = null ;
5149  while( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in v_stop_tokens ) )  &&  ( tokens.list[tokens.index] in v_operators ) ) ) {
5150   if( ( v_mrow == null ) ) {
5151     v_mrow = result_element( "mrow" ,0 , v_result ) ;
5152     v_result = v_mrow ;
5153   }
5154   result_element_append( v_mrow , v_piece_to_mathml (tokens ) );
5155   if( ( ( tokens.list[tokens.index] != null )  &&  ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5156    return v_result ;
5157   }
5158   else {
5159    result_element_append( v_mrow , v_reader (tokens , v_stop_tokens ) );
5160   }
5161  }
5162  return v_result ;
5163 }
5164 function v_collect_invisible_group (tokens , v_stop_tokens ) {
5165  var v_result = v_subexpr_to_mathml (tokens ) ;
5166  var v_mrow = null ;
5167  while( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in v_stop_tokens ) )  &&  ( ( tokens.list[tokens.index] in g_named_identifiers
5168 )  ||  ( tokens.list[tokens.index] in g_left_delimiters
5169 ) ) ) ) {
5170   if( ( v_mrow == null ) ) {
5171     v_mrow = result_element( "mrow" ,0 , v_result ) ;
5172     v_result = v_mrow ;
5173   }
5174   result_element_append( v_mrow , result_element( "mo" ,0 , "\u2062" ) );
5175   if( ( ( tokens.list[tokens.index] != null )  &&  ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5176    return v_result ;
5177   }
5178   else {
5179    result_element_append( v_mrow , v_subexpr_to_mathml (tokens ) );
5180   }
5181  }
5182  return v_result ;
5183 }
5184
5185
5186 var/*const*/ tokenize_re = /(\\begin|\\operatorname|\\mathrm|\\mathop|\\end)\s*\{\s*([A-Z a-z]+)\s*\}|(\\[a-zA-Z]+|\\[\\#\{\},:;!])|(\s+)|([0-9\.]+)|([\$!"#%&'()*+,-.\/:;<=>?\[\]^_`\{\|\}~])|([a-zA-Z])/g;
5187
5188 var/*const*/ tokenize_text_re = /[\${}\\]|\\[a-zA-Z]+|[^{}\$]+/g;
5189
5190 var/*const*/ tokenize_text_commands = {
5191   '\\textrm': 1,
5192   '\\textsl': 1,
5193   '\\textit': 1,
5194   '\\texttt': 1,
5195   '\\textbf': 1,
5196   '\\textnormal': 1,
5197   '\\text': 1,
5198   '\\hbox': 1,
5199   '\\mbox': 1
5200 };
5201
5202 function tokenize_latex_math(input)
5203 {
5204   var result = new Array();
5205   var in_text_mode = 0;
5206   var brace_level = [];
5207   var pos = 0;
5208
5209   if(input.charAt(0) == '$' && 
5210      input.charAt(input.length-1) == '$')
5211     input = input.slice(1, input.length-1);
5212
5213   while(1) {
5214     if(!in_text_mode) {
5215       tokenize_re.lastIndex = pos;
5216       var m = tokenize_re.exec(input);
5217       pos = tokenize_re.lastIndex;
5218
5219       if(m == null) {
5220         return result;
5221       } else if(m[1] != null) {
5222         result.push(m[1], m[2]);
5223       } else if(m[3] == '\\sp') {
5224         result.push('^');
5225       } else if(m[3] == '\\sb') {
5226         result.push('_');
5227       } else {
5228         if(m[0] == '$') {
5229           in_text_mode = 1;
5230         } else if(m[4] != null) {
5231           continue;
5232         } else if(m[3] != null && m[3] in tokenize_text_commands) {
5233           in_text_mode = 2;
5234           brace_level.push(0);
5235         } 
5236
5237         result.push(m[0]);
5238       }
5239     } else {
5240       tokenize_text_re.lastIndex = pos;
5241       var m = tokenize_text_re.exec(input);
5242       pos = tokenize_text_re.lastIndex;
5243       
5244       if(m == null) {
5245         return result;
5246       } else if(m[0] == '$') {
5247         in_text_mode = 0;
5248       } else if(m[0] == '{') {
5249         brace_level[brace_level.length-1]++;
5250       } else if(m[0] == '}') {
5251         if(--brace_level[brace_level.length-1] <= 0) {
5252           in_text_mode = 0;
5253           brace_level.pop();
5254         }
5255       }
5256       result.push(m[0]);
5257     }
5258   }
5259 }
5260
5261 /*
5262 function post_process_mathml(event)
5263 {
5264   var url = GM_getValue('click-post-url', null);
5265   if(url == null)
5266     return;
5267
5268   var ser = new XMLSerializer();
5269   var xhr = GM_xmlhttpRequest({ 
5270     method: 'POST',
5271     url: url,
5272     headers: { 'Content-Type': 'text/xml; charset=utf-8',
5273                'Content-Location': document.location },
5274     data: ser.serializeToString(event.currentTarget),
5275     onerror: function(details) {
5276       alert("There was an error processing the request. " +
5277             "HTTP status code " + details.status + ' ' + details.statusText);
5278     },
5279     onload: function(details) {
5280       window.status = "Successfully posted MathML.  Status: " 
5281             + details.status + ' ' + details.statusText;
5282     }});
5283
5284   window.status = "Posting MathML to " + url + "...";
5285 }
5286 */
5287
5288 function patch_img(node)
5289 {
5290
5291     if(node.currentTarget)
5292     node = node.currentTarget;
5293
5294   var alt = node.getAttribute('alt');
5295
5296   if(alt == null || 
5297      /^\\includegraphics|^\$\\displaystyle \\xymatrix/.test(alt))
5298     return;
5299
5300   var latex_string = null;
5301   
5302   
5303
5304   
5305   if((node.parentNode.tagName == 'DIV' && 
5306       node.parentNode.getAttribute('CLASS') == 'mathdisplay')
5307      || (node.parentNode.tagName == 'SPAN' &&
5308          node.parentNode.getAttribute('CLASS') == 'MATH'))
5309   {
5310     var parent = node.parentNode;
5311     var previous = parent.previousSibling;
5312     var/*const*/ non_whitespace = /[^\s]/;
5313
5314         if(previous &&
5315        previous.nodeType == node.TEXT_NODE &&
5316        !non_whitespace.test(previous.data))
5317       previous = previous.previousSibling;
5318
5319         if(previous &&
5320        previous.nodeType == node.ELEMENT_NODE &&
5321        previous.tagName == 'P' &&
5322        previous.lastChild) 
5323     {
5324       previous = previous.lastChild;
5325       if(previous &&
5326          previous.nodeType == node.TEXT_NODE &&
5327          !non_whitespace.test(previous.data))
5328         previous = previous.previousSibling;
5329     }
5330
5331         if(previous &&
5332        previous.nodeType == node.COMMENT_NODE) {
5333       latex_string = previous.data.replace(/^\s*MATH\s*/, '')
5334                                   .replace(/\s+$/, '');
5335     }
5336   }
5337
5338
5339   if(!latex_string && /^\$.+\$$/.test(alt)
5340      && !(/\.{3} \.{3}/.test(alt)))
5341   {
5342     latex_string = alt;
5343   }
5344
5345   if(latex_string == null)
5346     return;
5347
5348   
5349   tokens = new Object();
5350   tokens.list = tokenize_latex_math(latex_string);
5351   tokens.list.push(null);
5352   tokens.index = 0;
5353
5354   var mathml = null;
5355   try {
5356     var mrow = v_subexpr_chain_to_mathml(tokens, {});
5357     fix_mathvariant(mrow, null);
5358
5359     mathml = document.createElementNS(mmlns, 'math');
5360     mathml.setAttribute("latex", latex_string);
5361     mathml.setAttribute("mathvariant", "normal");
5362     mathml.appendChild(mrow);
5363
5364     mathml.addEventListener("click", post_process_mathml, false);
5365
5366   } catch(e) {
5367     GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5368   }
5369
5370   
5371   if(mathml == null)
5372     return;
5373
5374   node.parentNode.replaceChild(mathml, node);
5375 }
5376
5377
5378 function patch_text(node0) 
5379 {
5380   var text = node0.nodeValue;
5381   var results = /\$[^$]+\$|\[tex\](.+?)\[\/tex\]/.exec(text);
5382
5383   if(results) {
5384     var latex_string = (results[1] == null ? results[0] : '$'+results[1]+'$');
5385
5386     
5387   tokens = new Object();
5388   tokens.list = tokenize_latex_math(latex_string);
5389   tokens.list.push(null);
5390   tokens.index = 0;
5391
5392   var mathml = null;
5393   try {
5394     var mrow = v_subexpr_chain_to_mathml(tokens, {});
5395     fix_mathvariant(mrow, null);
5396
5397     mathml = document.createElementNS(mmlns, 'math');
5398     mathml.setAttribute("latex", latex_string);
5399     mathml.setAttribute("mathvariant", "normal");
5400     mathml.appendChild(mrow);
5401
5402     mathml.addEventListener("click", post_process_mathml, false);
5403
5404   } catch(e) {
5405     GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5406   }
5407
5408
5409     if(mathml == null)
5410       return;
5411
5412     var node2 = node0.splitText(results.index);
5413     node2.deleteData(0, results[0].length);
5414     
5415     node2.parentNode.insertBefore(mathml, node2);
5416
5417
5418     patch_text(node2);
5419   }
5420 }
5421
5422
5423
5424 function patch_element(node)
5425 {
5426   if(node.nodeType == node.TEXT_NODE)
5427     patch_text(node);
5428   else if(node.nodeType == node.ELEMENT_NODE) {if(node.tagName == 'TEXTAREA' || node.tagName == 'textarea' || 
5429        node.tagName == 'INPUT' || node.tagName == 'input' || 
5430        node.tagName == 'SCRIPT' || node.tagName == 'script')
5431       return;
5432
5433
5434     if(do_patch_images && (node.tagName == 'IMG' || node.tagName == 'img')) {
5435       if(!delayed_patch)
5436         patch_img(node);
5437       else
5438         node.addEventListener("click", patch_img, false);
5439
5440       return;
5441     }
5442
5443     var child = node.firstChild;
5444     while(child) {
5445       var next = child.nextSibling;
5446       if (child.className == 'stopLatex2mml') {
5447           break;
5448       }
5449       patch_element(child);
5450       child = next;
5451     }
5452   }
5453 }
5454 this.patch_element = patch_element;
5455
5456 /*
5457 var do_patch_images = GM_getValue("patch-images", false);
5458 var delayed_patch = GM_getValue("delayed-patch", false);
5459 */
5460 var do_patch_images = true;
5461 var delayed_patch = false;
5462
5463 /*
5464 if( va_view == 'web' ){
5465     patch_element(document.documentElement);
5466 }
5467 */
5468 };
5469
5470
5471
5472 /*!
5473 Deck JS - deck.simplemath
5474 Copyright (c) 2012 RĂ©mi Emonet,
5475 using a modified version of the script from http://gold-saucer.afraid.org/mathml/greasemonkey/ by Steve Cheng
5476 */
5477
5478 /*
5479 This module provides a support for latex equation syntax.
5480 */
5481
5482 (function($, deck, undefined) {
5483     var $d = $(document);
5484     var may = function(f) {return f ? f : function() {}};
5485     
5486     $d.bind('deck.init', function() {
5487         var container = $[deck]('getContainer');
5488         $('.latex', container).each(function() {
5489             var it = this;
5490             var v = $(it).text();
5491             it.innerHTML = "$\\displaystyle "+v+"$";
5492             new latex2mml().patch_element(it);
5493         });
5494     });
5495
5496 })(jQuery, 'deck');
5497
5498 /*!
5499 Deck JS - deck.clone
5500 Copyright (c) 2011-2014 RĂ©mi Emonet, original version from RĂ©mi BARRAQUAND
5501 Licensed under the MIT license.
5502 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5503 */
5504
5505 /*
5506 This module provides a support for cloning the deck and enabling a presenter view.
5507 It also provides the behavior that copies the current "notes" to a "notes-target", to be used in the presenter view.
5508 */
5509
5510 (function($, deck, undefined) {
5511     var $d = $(document);
5512     var clones = new Array();
5513         
5514     $.extend(true, $[deck].defaults, {  
5515         selectors: {
5516             clonepointer: '.clonepointer',
5517             cloneNotes: '.notes',
5518             cloneNotesTarget: '.notes-target'
5519         },
5520         classes: {
5521             isClone: 'is-clone',
5522             hasClones: 'has-clones',
5523             pointerClick: 'pointer-click'
5524         },
5525         snippets: {
5526             clone: true
5527         },
5528         keys: {
5529             clone: 67 // c
5530         },
5531         fitFollowsClone: true
5532     });
5533
5534     var hadClones = false;
5535     var cleanClones = function() {
5536         var opts = $[deck]('getOptions');
5537         // remove closed windows
5538         $.each(clones, function(index, clone) {
5539             if (clone.closed()) {
5540                 clones.splice(index, 1); // remove element "index"
5541             }
5542         });
5543         // tag/untag the current container depending on the presence of clones
5544         if (clones.length > 0) {
5545             $("body").addClass(opts.classes.hasClones);
5546             if (opts.fitFollowsClone && !hadClones) $[deck]('disableScale');
5547             hadClones = true;
5548         } else {
5549             $("body").removeClass(opts.classes.hasClones);
5550             if (opts.fitFollowsClone && hadClones) $[deck]('enableScale');
5551             hadClones = false;
5552         }
5553     };
5554
5555     /*
5556       jQuery.deck('addClone')
5557       Create a clone of this window and add it to the clones list.
5558     */
5559     $[deck]('extend', 'addClone', function() {
5560         clone = new DeckClone();
5561         clones.push(clone);
5562         cleanClones();
5563         return clone;
5564     });
5565     $[deck]('extend', 'cleanClones', function() { // to be triggered by the closing of a clone window
5566         setTimeout(cleanClones, 1);
5567     });
5568     $[deck]('extend', 'pointerAt', function(rx, ry) {
5569         var pos = {left: (rx*100)+"%", top: (ry*100)+"%"};
5570         var opts = $[deck]('getOptions');
5571         var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension
5572         var pointers = $(opts.selectors.clonepointer);
5573         if (!current.is(pointers.parent())) { // move them within the new slide if it changed
5574             pointers.show().appendTo(current);
5575         }
5576         pointers.css(pos);
5577         // using % position instead of ".offset" as there are jitter/glitches with it
5578     });
5579     $[deck]('extend', 'pointerDown', function() {
5580         var opts = $[deck]('getOptions');
5581         var pointers = $(opts.selectors.clonepointer);
5582         pointers.addClass(opts.classes.pointerClick);
5583     });
5584     $[deck]('extend', 'pointerUp', function() {
5585         var opts = $[deck]('getOptions');
5586         var pointers = $(opts.selectors.clonepointer);
5587         pointers.removeClass(opts.classes.pointerClick);
5588     });
5589     
5590     var isClone = false;
5591     var parentDeck = null;
5592     /*
5593       jQuery.deck('Init')
5594     */
5595     $d.bind('deck.init', function() {
5596         var opts = $[deck]('getOptions');
5597         var container = $[deck]('getContainer');
5598         
5599         if (opts.snippets.clone) {
5600             var d = function() {return $('<div/>');}
5601             d().addClass("clonepointer scale-on-click").append(
5602                 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5603                          +"margin: -11px 0 0 -11px; width:20px; height:20px; opacity: .5;")
5604                 ).appendTo(container);
5605             d().addClass("clonepointer scale-on-click").append(
5606                 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5607                          +"margin: -16px 0 0 -16px; width:30px; height:30px;")
5608                 ).appendTo(container);
5609             d().addClass(opts.selectors.cloneNotesTarget.replace(/\./, ''))
5610                 .appendTo(container);
5611         }
5612
5613         $(opts.selectors.clonepointer).hide();
5614
5615         function safeIsClone(w) {
5616             try {
5617                 return w.opener && w.opener.___iscloner___;
5618             } catch(e) {
5619                 // when linked from another origin, there is an opener
5620                 // but accessing its properties throws a security exception
5621                 return false;
5622             }
5623         }
5624
5625         isClone = safeIsClone(window);
5626
5627         if (isClone) { // it's a clone!
5628             $("body").addClass(opts.classes.isClone);
5629             $(".anim-continue", container).removeClass("anim-continue"); // friend with anim extension
5630             window.___fromparent___ = false;
5631             parentDeck = function() {
5632                 if (! window.___fromparent___) {
5633                     window.opener.$.deck.apply(window.opener.$, arguments);
5634                 }
5635             }
5636             $(window).on('unload', function() {
5637                 parentDeck('cleanClones');
5638             });
5639         } else { // it is a normal window
5640             /* bind clone key events */
5641             $d.unbind('keydown.deckclone').bind('keydown.deckclone', function(e) {
5642                 if (e.which === opts.keys.clone || $.inArray(e.which, opts.keys.clone) > -1) {
5643                     if (e.ctrlKey) return; // do not trigger on Ctrl+C (by default)
5644                     $[deck]('addClone');
5645                     window.___iscloner___ = true;
5646                     e.preventDefault();
5647                 }
5648             });
5649         }
5650     })
5651     /* Update current slide number with each change event */
5652     .bind('deck.change', function(e, from, to) {
5653         if (isClone) {
5654             parentDeck('go', to);
5655         } else {
5656             cleanClones();
5657             $.each(clones, function(index, clone) {
5658                 clone.deck('go', to);
5659             });
5660             
5661             var opts = $[deck]('getOptions');
5662             var currentTopLevel = $[deck]('getToplevelSlideOf', $[deck]('getSlide', to)).node;
5663             var notes = $(opts.selectors.cloneNotes, currentTopLevel).html();
5664             if (notes === undefined) {
5665                 $(opts.selectors.cloneNotesTarget).html("");
5666             } else {
5667                 $(opts.selectors.cloneNotesTarget).html(notes);
5668             }
5669         }
5670     })
5671     /* Replicate mouse cursor */
5672     .bind('mousemove', function(e) {
5673         if (isClone) return;
5674         var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension (dependency can be removed if needed)
5675         var r = current.get(0).getBoundingClientRect();
5676         var x = (e.clientX - r.left) / r.width;
5677         var y = (e.clientY - r.top) / r.height;
5678         cleanClones();
5679         if (x < 0 || y < 0 || x > 1 || y > 1) return;
5680         $.each(clones, function(index, clone) {
5681             clone.deck('pointerAt', x, y);
5682         });
5683     })
5684     .bind('mousedown', function(e) {
5685         if (isClone) return;
5686         cleanClones();
5687         $.each(clones, function(index, clone) {
5688             clone.deck('pointerDown');
5689         });
5690     })
5691     .bind('mouseup', function(e) {
5692         if (isClone) return;
5693         cleanClones();
5694         $.each(clones, function(index, clone) {
5695             clone.deck('pointerUp');
5696         });
5697     });
5698     
5699     /*
5700         Simple Clone manager (must be improved, by for instance adding cloning
5701         option e.g. propagate change, etc.)
5702         */
5703     var DeckClone = function() {
5704         var clone = window.open(window.location);
5705         this.closed = function() {return clone.closed;}
5706         this.deck = function() {
5707             if (clone.closed) return;
5708             if (clone.$) {
5709                 clone.___fromparent___ = true;
5710                 clone.$.deck.apply(clone.$, arguments);
5711                 clone.___fromparent___ = false;
5712             }
5713         }
5714     }
5715 })(jQuery, 'deck');
5716
5717
5718 /*!
5719 Deck JS - deck.goto
5720 Copyright (c) 2011-2014 Caleb Troughton
5721 Dual licensed under the MIT license.
5722 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5723 */
5724
5725 /*
5726 This module adds the necessary methods and key bindings to show and hide a form
5727 for jumping to any slide number/id in the deck (and processes that form
5728 accordingly). The form-showing state is indicated by the presence of a class on
5729 the deck container.
5730 */
5731 (function($, undefined) {
5732   var $document = $(document);
5733   var rootCounter;
5734
5735   var maybeAddSnippet = function() {
5736     var options = $.deck('getOptions');
5737     if (options.snippets.goto) {
5738       if ($(options.selectors.gotoForm).size() > 0 && options.alert.goto) {
5739         alert("'options.snippets.goto' is true but a "+options.selectors.gotoForm+" has been found."
5740               +"\nThis might cause interaction glitches."
5741               +"\n"
5742               +"\nSuggestion: remove your html snippet or pass the {snippets: {goto: false}} option."
5743              );
5744       }
5745       $('<form/>').addClass('goto-form').attr('action', '.').attr('method', 'get')
5746         .append($('<label/>').attr('for', 'goto-slide').text('Go to slide:'))
5747         .append($('<input/>').attr('type', 'text').attr('id', 'goto-slide').attr('name', 'slidenum').attr('list', 'goto-datalist'))
5748         .append($('<datalist/>').attr('id', 'goto-datalist'))
5749         .append($('<input/>').attr('type', 'submit').attr('value', 'Go'))
5750       .appendTo($.deck('getContainer'));
5751     }
5752   };
5753
5754   var bindKeyEvents = function() {
5755     $document.unbind('keydown.deckgoto');
5756     $document.bind('keydown.deckgoto', function(event) {
5757       var key = $.deck('getOptions').keys.goto;
5758       if (event.which === key || $.inArray(event.which, key) > -1) {
5759         event.preventDefault();
5760         $.deck('toggleGoTo');
5761       }
5762     });
5763   };
5764
5765   var populateDatalist = function() {
5766     var options = $.deck('getOptions');
5767     var $datalist = $(options.selectors.gotoDatalist);
5768
5769     $.each($.deck('getSlides'), function(i, $slide) {
5770       var id = $slide.attr('id');
5771       if (id) {
5772         $datalist.append('<option value="' + id + '">');
5773       }
5774     });
5775   };
5776
5777   var markRootSlides = function() {
5778     var options = $.deck('getOptions');
5779     var slideTest = $.map([
5780       options.classes.before,
5781       options.classes.previous,
5782       options.classes.current,
5783       options.classes.next,
5784       options.classes.after
5785     ], function(el, i) {
5786       return '.' + el;
5787     }).join(', ');
5788
5789     rootCounter = 0;
5790     $.each($.deck('getSlides'), function(i, $slide) {
5791       var $parentSlides = $slide.parentsUntil(
5792         options.selectors.container,
5793         slideTest
5794       );
5795
5796       if ($parentSlides.length) {
5797         $slide.removeData('rootIndex');
5798       }
5799       else if (!options.countNested) {
5800         ++rootCounter;
5801         $slide.data('rootIndex', rootCounter);
5802       }
5803     });
5804   };
5805
5806   var handleFormSubmit = function() {
5807     var options = $.deck('getOptions');
5808     var $form = $(options.selectors.gotoForm);
5809
5810     $form.unbind('submit.deckgoto');
5811     $form.bind('submit.deckgoto', function(event) {
5812       var $field = $(options.selectors.gotoInput);
5813       var indexOrId = $field.val();
5814       var index = parseInt(indexOrId, 10);
5815
5816       if (!options.countNested) {
5817         if (!isNaN(index) && (index > rootCounter || index <= 0)) {
5818           return false;
5819         }
5820         $.each($.deck('getSlides'), function(i, $slide) {
5821           if ($slide.data('rootIndex') === index) {
5822             index = i + 1;
5823             return false;
5824           }
5825         });
5826       }
5827
5828       $.deck('go', isNaN(index) ? indexOrId : index - 1);
5829       $.deck('hideGoTo');
5830       $field.val('');
5831       event.preventDefault();
5832     });
5833   };
5834
5835   /*
5836   Extends defaults/options.
5837
5838   options.classes.goto
5839     This class is added to the deck container when showing the Go To Slide
5840     form.
5841
5842   options.selectors.gotoDatalist
5843     The element that matches this selector is the datalist element that will
5844     be populated with options for each of the slide ids.  In browsers that
5845     support the datalist element, this provides a drop list of slide ids to
5846     aid the user in selecting a slide.
5847
5848   options.selectors.gotoForm
5849     The element that matches this selector is the form that is submitted
5850     when a user hits enter after typing a slide number/id in the gotoInput
5851     element.
5852
5853   options.selectors.gotoInput
5854     The element that matches this selector is the text input field for
5855     entering a slide number/id in the Go To Slide form.
5856
5857   options.keys.goto
5858     The numeric keycode used to show the Go To Slide form.
5859
5860   options.countNested
5861     If false, only top level slides will be counted when entering a
5862     slide number.
5863   */
5864   $.extend(true, $.deck.defaults, {
5865     classes: {
5866       goto: 'deck-goto'
5867     },
5868
5869     selectors: {
5870       gotoDatalist: '#goto-datalist',
5871       gotoForm: '.goto-form',
5872       gotoInput: '#goto-slide'
5873     },
5874
5875     snippets: {
5876       goto: true
5877     },
5878
5879     alert: {
5880       goto: true
5881     },
5882
5883     keys: {
5884       goto: 71 // g
5885     },
5886
5887     countNested: true
5888   });
5889
5890   /*
5891   jQuery.deck('showGoTo')
5892
5893   Shows the Go To Slide form by adding the class specified by the goto class
5894   option to the deck container.
5895   */
5896   $.deck('extend', 'showGoTo', function() {
5897     var options = $.deck('getOptions');
5898     $.deck('getContainer').addClass(options.classes.goto);
5899     $(options.selectors.gotoForm).attr('aria-hidden', false);
5900     $(options.selectors.gotoInput).focus();
5901   });
5902
5903   /*
5904   jQuery.deck('hideGoTo')
5905
5906   Hides the Go To Slide form by removing the class specified by the goto class
5907   option from the deck container.
5908   */
5909   $.deck('extend', 'hideGoTo', function() {
5910     var options = $.deck('getOptions');
5911     $(options.selectors.gotoInput).blur();
5912     $.deck('getContainer').removeClass(options.classes.goto);
5913     $(options.selectors.gotoForm).attr('aria-hidden', true);
5914   });
5915
5916   /*
5917   jQuery.deck('toggleGoTo')
5918
5919   Toggles between showing and hiding the Go To Slide form.
5920   */
5921   $.deck('extend', 'toggleGoTo', function() {
5922     var options = $.deck('getOptions');
5923     var hasGotoClass = $.deck('getContainer').hasClass(options.classes.goto);
5924     $.deck(hasGotoClass ? 'hideGoTo' : 'showGoTo');
5925   });
5926
5927   $document.bind('deck.init', function() {
5928     maybeAddSnippet();
5929     bindKeyEvents();
5930     populateDatalist();
5931     markRootSlides();
5932     handleFormSubmit();
5933   });
5934 })(jQuery);
5935
5936
5937 /*!
5938 Deck JS - deck.progress
5939 Copyright (c) 2014 RĂ©mi Emonet
5940 Dual licensed under the MIT license.
5941 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5942 */
5943
5944 /*
5945 This module adds a (current)/(total) style status indicator to the deck.
5946
5947 It is designed to be a drop-in replacement of deck.status, but on steroĂ¯ds.
5948 Note however, that it does not handle the countNested=true case.
5949 */
5950 (function($, undefined) {
5951     var $document = $(document);
5952     var rootCounter;
5953     var INITEVENT = "dummyinit";
5954     var SIZEEVENT = "dummysize";
5955     
5956     var updateCurrent = function(event, from, to) {
5957         var opts = $.deck('getOptions');
5958         var currentSlideNumber = to + 1;
5959         var $container = $.deck('getContainer');
5960         currentSlideNumber = $.deck('getSlide', to).data('rootSlide');
5961         $(opts.selectors.statusCurrent).text(currentSlideNumber);
5962
5963         var icur = 0;
5964         for (; icur < $.deck('getSlides').length; icur++) {
5965             var top = $.deck('getSlide', icur).data('rootSlide');
5966             if (top == currentSlideNumber) {
5967                 break;
5968             }
5969         }
5970         var last = null;
5971         var currentDetail = to;
5972         var lastDetail = icur;
5973         for (; icur < $.deck('getSlides').length; icur++) {
5974             last = $.deck('getSlide', icur).data('rootSlide');
5975             lastDetail = icur+1;
5976             if ($.deck('getSlide', icur).filter(opts.selectors.statusFakeEnd).size() > 0) break;
5977         }
5978         $(opts.selectors.statusTotal).text(last);
5979
5980         // handle the data-progress
5981         var progresses = $('*['+opts.dataProgress+'], *['+opts.dataProgressOnce+'], *['+opts.dataProgressSize+']');
5982         if (progresses.size() > 0) {
5983             var visibleSlide = $.deck('getSlide').parentsUntil(opts.selectors.container).addBack().filter(opts.selectors.slides);
5984             // the eval context
5985             var slide = visibleSlide.get(0).getBoundingClientRect();
5986             var screen = {width: $container.innerWidth(), height: $container.innerHeight()};
5987             var n = currentSlideNumber;
5988             var N = last;
5989             var fullTotal = $.deck('getTopLevelSlides').length;
5990             var detail = {n: currentDetail+1, N: lastDetail, fullTotal: $.deck('getSlides').length};
5991             var designRatio = Math.max(slide.width / opts.designWidth, slide.height / opts.designHeight);
5992             var o = opts;
5993             var p = n/N;
5994             var pFull = n/fullTotal;
5995             detail.p = detail.n/detail.N;
5996             detail.pFull = detail.n/detail.fullTotal;
5997             // 
5998             progresses.each(function(i, el) {
5999                 var spe = {
6000                     bottom: function(fontSize, botByRatio, botFixed) {
6001                         botFixed = botFixed || 0;
6002                         $(el).css('font-size', (fontSize * designRatio)+"px");
6003                         $(el).css('top', (slide.bottom - botFixed - botByRatio*designRatio)+'px');
6004                     },
6005                     top: function(fontSize, topByRatio, topFixed) {
6006                         topFixed = topFixed || 0;
6007                         $(el).css('font-size', (fontSize * designRatio)+"px");
6008                         $(el).css('top', (slide.top + topFixed + topByRatio*designRatio)+'px');
6009                     }
6010                 };
6011                 var att = $(el).attr(event == INITEVENT ? opts.dataProgressOnce : event == SIZEEVENT ? opts.dataProgressSize : opts.dataProgress);
6012                 if (att == null || att.length == 0) return;
6013                 var tasks = att.split(/ *; */);
6014                 for (t in tasks) {
6015                     var parts = tasks[t].split(/ *: */);
6016                     if (parts.length != 2) {
6017                         if (opts.alert.wrongDataProgress) alert(
6018                             "There seem to be a problem with the following data-progress of\n   '" +tasks[t]+ "'\n");
6019                     } else {
6020                         var what = parts[0];
6021                         var expr = parts[1];
6022                         var val = eval(expr);
6023                         if (what == "") {
6024                             // skip: expected to be some "magic", e.g. custom code or call to helpers
6025                         } else if (what.substring(0,1) == "@") {
6026                             // special attribute setting, not css
6027                             what = what.substring(1);
6028                             $(el).attr(what, val);
6029                         } else if (what == "$text") {
6030                             $(el).text(val);
6031                         } else if (what == "$html") {
6032                             $(el).html(val);
6033                         } else {
6034                             $(el).css(what, val);
6035                         }
6036                     }
6037                 }
6038             });
6039         }
6040     };
6041     
6042     var markRootSlides = function() {
6043         var opts = $.deck('getOptions');
6044         var slideTest = $.map([
6045             opts.classes.before,
6046             opts.classes.previous,
6047             opts.classes.current,
6048             opts.classes.next,
6049             opts.classes.after
6050         ], function(el, i) {
6051             return '.' + el;
6052         }).join(', ');
6053         
6054         rootCounter = 0;
6055         $.each($.deck('getSlides'), function(i, $slide) {
6056             var $parentSlides = $slide.parentsUntil(
6057                 opts.selectors.container,
6058                 slideTest
6059             );
6060             
6061             if ($parentSlides.length) {
6062                 $slide.data('rootSlide', $parentSlides.last().data('rootSlide'));
6063             }
6064             else {
6065                 ++rootCounter;
6066                 $slide.data('rootSlide', rootCounter);
6067             }
6068         });
6069     };
6070     
6071     var fireEventOnCurrentSlide = function(ev) {
6072         var slides = $.deck('getSlides');
6073         var $currentSlide = $.deck('getSlide');
6074         var index;
6075         
6076         $.each(slides, function(i, $slide) {
6077             if ($slide === $currentSlide) {
6078                 index = i;
6079                 return false;
6080             }
6081         });
6082         updateCurrent(ev, index, index);
6083     };
6084     
6085     var setTotalSlideNumber = function() {
6086         var opts = $.deck('getOptions');
6087         var slides = $.deck('getSlides');
6088         
6089         var nSlides = $.deck('getTopLevelSlides').length;
6090         $(opts.selectors.statusFullTotal).text(nSlides);
6091
6092     };
6093     
6094     /*
6095       Extends defaults/options.
6096       
6097       opts.selectors.statusCurrent
6098       The element matching this selector displays the current slide number.
6099       
6100       opts.selectors.statusTotal
6101       The element matching this selector displays the total number of slides.
6102       
6103       opts.countNested
6104       If false, only top level slides will be counted in the current and
6105       total numbers.
6106     */
6107     $.extend(true, $.deck.defaults, {
6108         selectors: {
6109             statusCurrent: '.deck-status-current',
6110             statusTotal: '.deck-status-total',
6111             statusFakeEnd: '.deck-status-fake-end',
6112             statusFullTotal: '.deck-status-full-total',
6113             progress10: '.deck-progress-10'
6114         },
6115         alert: {
6116             wrongDataProgress: true,
6117             possibleDebounceProblem: true
6118         },
6119         dataProgress: "data-progress",
6120         dataProgressOnce: "data-progress-once",
6121         dataProgressSize: "data-progress-size",
6122         progressSizeDebounce: 201 /* somewhat, it should be bigger that the fit debounce */
6123     });
6124     
6125     $document.bind('deck.init', function() {
6126         var opts = $.deck('getOptions');
6127         $(opts.selectors.progress10).attr(opts.dataProgressSize, ':spe.bottom(10, 12)')
6128         markRootSlides();
6129         fireEventOnCurrentSlide(INITEVENT);
6130         fireEventOnCurrentSlide(SIZEEVENT);
6131         setTotalSlideNumber();
6132     });
6133     var timer = -1;
6134     $(window).unbind('resize.deckprogress').bind('resize.deckprogress', function() {
6135         var opts = $.deck('getOptions');
6136         if (opts.alert.possibleDebounceProblem && opts.progressSizeDebounce < opts.scaleDebounce + 1) {
6137             alert(
6138                 "There might be a problem with the respective debounce value:\n   progressSizeDebounce: "+opts.progressSizeDebounce+"\n   scaleDebounce: "+opts.scaleDebounce);
6139
6140         }
6141         window.clearTimeout(timer);
6142         timer = window.setTimeout( function() {
6143             fireEventOnCurrentSlide(SIZEEVENT);
6144             fireEventOnCurrentSlide("fire also the update event as some things might also need resizing");
6145         }, opts.progressSizeDebounce);
6146     });
6147     $document.bind('deck.change', updateCurrent);
6148 })(jQuery, 'deck');
6149
6150
6151 /*!
6152 Deck JS - deck.navigation
6153 Copyright (c) 2011-2014 Caleb Troughton
6154 Dual licensed under the MIT license.
6155 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6156 */
6157
6158 /*
6159 This module adds clickable previous and next links to the deck.
6160 */
6161 (function($, undefined) {
6162   var $document = $(document);
6163
6164   /* Updates link hrefs, and disabled states if last/first slide */
6165   var updateButtons = function(event, from, to) {
6166     var options = $.deck('getOptions');
6167     var lastIndex = $.deck('getSlides').length - 1;
6168     var $prevSlide = $.deck('getSlide', to - 1);
6169     var $nextSlide = $.deck('getSlide', to + 1);
6170     var hrefBase = window.location.href.replace(/#.*/, '');
6171     var prevId = $prevSlide ? $prevSlide.attr('id') : undefined;
6172     var nextId = $nextSlide ? $nextSlide.attr('id') : undefined;
6173     var $prevButton = $(options.selectors.previousLink);
6174     var $nextButton = $(options.selectors.nextLink);
6175
6176     $prevButton.toggleClass(options.classes.navDisabled, to === 0);
6177     $prevButton.attr('aria-disabled', to === 0);
6178     $prevButton.attr('href', hrefBase + '#' + (prevId ? prevId : ''));
6179     $nextButton.toggleClass(options.classes.navDisabled, to === lastIndex);
6180     $nextButton.attr('aria-disabled', to === lastIndex);
6181     $nextButton.attr('href', hrefBase + '#' + (nextId ? nextId : ''));
6182   };
6183
6184   /*
6185   Extends defaults/options.
6186
6187   options.classes.navDisabled
6188     This class is added to a navigation link when that action is disabled.
6189     It is added to the previous link when on the first slide, and to the
6190     next link when on the last slide.
6191
6192   options.selectors.nextLink
6193     The elements that match this selector will move the deck to the next
6194     slide when clicked.
6195
6196   options.selectors.previousLink
6197     The elements that match this selector will move to deck to the previous
6198     slide when clicked.
6199   */
6200   $.extend(true, $.deck.defaults, {
6201     classes: {
6202       navDisabled: 'deck-nav-disabled'
6203     },
6204
6205     selectors: {
6206       nextLink: '.deck-next-link',
6207       previousLink: '.deck-prev-link'
6208     }
6209   });
6210
6211   $document.bind('deck.init', function() {
6212     var options = $.deck('getOptions');
6213     var slides = $.deck('getSlides');
6214     var $current = $.deck('getSlide');
6215     var $prevButton = $(options.selectors.previousLink);
6216     var $nextButton = $(options.selectors.nextLink);
6217     var index;
6218
6219     // Setup prev/next link events
6220     $prevButton.unbind('click.decknavigation');
6221     $prevButton.bind('click.decknavigation', function(event) {
6222       $.deck('prev');
6223       event.preventDefault();
6224     });
6225
6226     $nextButton.unbind('click.decknavigation');
6227     $nextButton.bind('click.decknavigation', function(event) {
6228       $.deck('next');
6229       event.preventDefault();
6230     });
6231
6232     // Find where we started in the deck and set initial states
6233     $.each(slides, function(i, $slide) {
6234       if ($slide === $current) {
6235         index = i;
6236         return false;
6237       }
6238     });
6239     updateButtons(null, index, index);
6240   });
6241
6242   $document.bind('deck.change', updateButtons);
6243 })(jQuery);
6244
6245
6246 /*!
6247 Deck JS - deck.menu
6248 Copyright (c) 2011-2014 Caleb Troughton
6249 Dual licensed under the MIT license.
6250 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6251 */
6252
6253 /*
6254 This module adds the methods and key binding to show and hide a menu of all
6255 slides in the deck. The deck menu state is indicated by the presence of a class
6256 on the deck container.
6257 */
6258 (function($, undefined) {
6259   var $document = $(document);
6260   var $html = $('html');
6261   var rootSlides;
6262
6263   var populateRootSlidesArray = function() {
6264     var options = $.deck('getOptions');
6265     var slideTest = $.map([
6266       options.classes.before,
6267       options.classes.previous,
6268       options.classes.current,
6269       options.classes.next,
6270       options.classes.after
6271     ], function(el, i) {
6272       return '.' + el;
6273     }).join(', ');
6274
6275     rootSlides = [];
6276     $.each($.deck('getSlides'), function(i, $slide) {
6277       var $parentSlides = $slide.parentsUntil(
6278         options.selectors.container,
6279         slideTest
6280       );
6281       if (!$parentSlides.length) {
6282         rootSlides.push($slide);
6283       }
6284     });
6285   };
6286
6287   var bindKeyEvents = function() {
6288     var options = $.deck('getOptions');
6289     $document.unbind('keydown.deckmenu');
6290     $document.bind('keydown.deckmenu', function(event) {
6291       var isMenuKey = event.which === options.keys.menu;
6292       isMenuKey = isMenuKey || $.inArray(event.which, options.keys.menu) > -1;
6293       if (isMenuKey && !event.ctrlKey) {
6294         $.deck('toggleMenu');
6295         event.preventDefault();
6296       }
6297     });
6298   };
6299
6300   var bindTouchEvents = function() {
6301     var $container = $.deck('getContainer');
6302     var options = $.deck('getOptions');
6303     var touchEndTime = 0;
6304     var currentSlide;
6305
6306     $container.unbind('touchstart.deckmenu');
6307     $container.bind('touchstart.deckmenu', function() {
6308       currentSlide = $.deck('getSlide');
6309     });
6310     $container.unbind('touchend.deckmenu');
6311     $container.bind('touchend.deckmenu', function(event) {
6312       var now = Date.now();
6313       var isDoubletap = now - touchEndTime < options.touch.doubletapWindow;
6314
6315       // Ignore this touch event if it caused a nav change (swipe)
6316       if (currentSlide !== $.deck('getSlide')) {
6317         return;
6318       }
6319       if (isDoubletap) {
6320         $.deck('toggleMenu');
6321         event.preventDefault();
6322       }
6323       touchEndTime = now;
6324     });
6325   };
6326
6327   var setupMenuSlideSelection = function() {
6328     var options = $.deck('getOptions');
6329
6330     $.each($.deck('getSlides'), function(i, $slide) {
6331       $slide.unbind('click.deckmenu');
6332       $slide.bind('click.deckmenu', function(event) {
6333         if (!$.deck('getContainer').hasClass(options.classes.menu)) {
6334           return;
6335         }
6336         $.deck('go', i);
6337         $.deck('hideMenu');
6338         event.stopPropagation();
6339         event.preventDefault();
6340       });
6341     });
6342   };
6343
6344   /*
6345   Extends defaults/options.
6346
6347   options.classes.menu
6348     This class is added to the deck container when showing the slide menu.
6349
6350   options.keys.menu
6351     The numeric keycode used to toggle between showing and hiding the slide
6352     menu.
6353
6354   options.touch.doubletapWindow
6355     Two consecutive touch events within this number of milliseconds will
6356     be considered a double tap, and will toggle the menu on touch devices.
6357   */
6358   $.extend(true, $.deck.defaults, {
6359     classes: {
6360       menu: 'deck-menu'
6361     },
6362
6363     keys: {
6364       menu: 77 // m
6365     },
6366
6367     touch: {
6368       doubletapWindow: 400
6369     }
6370   });
6371
6372   /*
6373   jQuery.deck('showMenu')
6374
6375   Shows the slide menu by adding the class specified by the menu class option
6376   to the deck container.
6377   */
6378   $.deck('extend', 'showMenu', function() {
6379     var $container = $.deck('getContainer');
6380     var options = $.deck('getOptions');
6381
6382     if ($container.hasClass(options.classes.menu)) {
6383       return;
6384     }
6385
6386     // Hide through loading class to short-circuit transitions (perf)
6387     $container.addClass([
6388       options.classes.loading,
6389       options.classes.menu
6390     ].join(' '));
6391
6392     /* Forced to do this in JS until CSS learns second-grade math. Save old
6393     style value for restoration when menu is hidden. */
6394     if (Modernizr.csstransforms) {
6395       $.each(rootSlides, function(i, $slide) {
6396         $slide.data('oldStyle', $slide.attr('style'));
6397         $slide.css({
6398           'position': 'absolute',
6399           'left': ((i % 4) * 25) + '%',
6400           'top': (Math.floor(i / 4) * 25) + '%'
6401         });
6402       });
6403     }
6404
6405     // Need to ensure the loading class renders first, then remove
6406     window.setTimeout(function() {
6407       $container.removeClass(options.classes.loading);
6408       $container.scrollTop($.deck('getSlide').position().top);
6409     }, 0);
6410   });
6411
6412   /*
6413   jQuery.deck('hideMenu')
6414
6415   Hides the slide menu by removing the class specified by the menu class
6416   option from the deck container.
6417   */
6418   $.deck('extend', 'hideMenu', function() {
6419     var $container = $.deck('getContainer');
6420     var options = $.deck('getOptions');
6421
6422     if (!$container.hasClass(options.classes.menu)) {
6423       return;
6424     }
6425
6426     $container.removeClass(options.classes.menu);
6427     $container.addClass(options.classes.loading);
6428
6429     /* Restore old style value */
6430     if (Modernizr.csstransforms) {
6431       $.each(rootSlides, function(i, $slide) {
6432         var oldStyle = $slide.data('oldStyle');
6433         $slide.attr('style', oldStyle ? oldStyle : '');
6434       });
6435     }
6436
6437     window.setTimeout(function() {
6438       $container.removeClass(options.classes.loading);
6439       $container.scrollTop(0);
6440     }, 0);
6441   });
6442
6443   /*
6444   jQuery.deck('toggleMenu')
6445
6446   Toggles between showing and hiding the slide menu.
6447   */
6448   $.deck('extend', 'toggleMenu', function() {
6449     $.deck('getContainer').hasClass($.deck('getOptions').classes.menu) ?
6450     $.deck('hideMenu') : $.deck('showMenu');
6451   });
6452
6453   $document.bind('deck.init', function() {
6454     populateRootSlidesArray();
6455     bindKeyEvents();
6456     bindTouchEvents();
6457     setupMenuSlideSelection();
6458   });
6459
6460   $document.bind('deck.change', function(event, from, to) {
6461     var $container = $.deck('getContainer');
6462     var containerScroll, slideTop;
6463
6464     if ($container.hasClass($.deck('getOptions').classes.menu)) {
6465       containerScroll = $container.scrollTop();
6466       slideTop = $.deck('getSlide', to).position().top;
6467       $container.scrollTop(containerScroll + slideTop);
6468     }
6469   });
6470 })(jQuery);
6471
6472 /*!
6473 Deck JS - deck.step
6474 Copyright (c) 2011-2014 RĂ©mi Emonet
6475 Licensed under the MIT license.
6476 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6477 */
6478
6479 /*
6480 This module provides new methods for stepping without considering sub-slides, together with tools for finding toplevel slides etc.
6481 It also overrides the defaults keybinding and countNested value (so it is better to include it after "goto" and "status" extensions).
6482 */
6483
6484 (function($, deck, undefined) {
6485     var $d = $(document);
6486     // undo the defaults (to be sure jquery behaves properly when overriding it)
6487     $.extend(true, $[deck].defaults, { keys: {next:null, previous:null}});
6488     // and go on
6489     $.extend(true, $[deck].defaults, {
6490         selectors: {
6491             subslidesToNotify: ".slide,.onshowtoplevel"
6492         },
6493         // Here we redefined the defaults:
6494         //  - we avoid counting nested slides
6495         //  - we keep up/down for top-level slides
6496         //  - we still use pgup/pgdown for inner slides as they are sent by some pluggable remote controls
6497         keys: {
6498             // backspace, left arrow, page down
6499             previous: [8, 37, 33],
6500             // enter, space, right arrow, page up
6501             next: [13, 32, 39, 34],
6502             // up arrow
6503             previousTopLevel: [38],
6504             // down arrow,
6505             nextTopLevel: [40],
6506             // key 'z'
6507             nextEndOfTopLevel: [90]
6508         },
6509         countNested: false
6510     });
6511     var myInArray = function(el, arr) {
6512         for (i in arr) if (arr[i].is(el)) return i*1; // cast to int
6513         return -1;
6514     };
6515     $[deck]('extend', 'getSlideIndex', function(node) {
6516         var slides = $[deck]('getSlides');
6517         var ind = myInArray(node, slides);
6518         return ind;
6519     });
6520     $[deck]('extend', 'getToplevelSlideOf', function(node) {
6521         var opts = $[deck]('getOptions');
6522         var slides = $[deck]('getSlides');
6523         var last = {node: $(node), index: myInArray(node, slides)};
6524         $(node).parentsUntil(opts.selectors.container).each( function(ii, v) {
6525             var ind = myInArray(v, slides);
6526             if (ind != -1) {
6527                 last = {node: $(v), index: ind};
6528             }
6529         });
6530         return last;
6531     });
6532     $[deck]('extend', 'getToplevelSlideOfIndex', function(ind) {
6533         return $[deck]('getToplevelSlideOf', $[deck]('getSlide', ind));
6534     });
6535     $[deck]('extend', 'previousTopLevelSlide', function() {
6536         /* Find the real previous parent */
6537         var current = $[deck]('getSlide');
6538         var currentParent = $[deck]('getToplevelSlideOf', current);
6539         var toGo = currentParent.index;
6540         if (current.is(currentParent.node) && toGo > 0) {
6541             // This is already toplevel slide, just go to the previous toplevel one (parent of the previous one)
6542             toGo = $[deck]('getToplevelSlideOfIndex', toGo-1).index;
6543         }
6544         $[deck]('go', toGo);
6545         
6546     });
6547     $[deck]('extend', 'nextTopLevelSlide', function() {
6548         /* Find the real next parent */
6549         var current = $[deck]('getSlide');
6550         var currentParent = $[deck]('getToplevelSlideOf', current);
6551         var icur = currentParent.index;
6552         for (; icur < $[deck]('getSlides').length; icur++) {
6553             var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6554             if (!cursorParent.is(currentParent.node)) {
6555                 $[deck]('go', icur);
6556                 break;
6557             }
6558         }
6559     });
6560     $[deck]('extend', 'nextEndOfTopLevelSlide', function() {
6561         /* Find the real next parent */
6562         var current = $[deck]('getSlideIndex', $[deck]('getSlide'));
6563         var nextParent = $[deck]('getToplevelSlideOfIndex', current + 1);
6564         var icur = nextParent.index;
6565         for (; icur < $[deck]('getSlides').length; icur++) {
6566             var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6567             if (!cursorParent.is(nextParent.node)) {
6568                 $[deck]('go', icur-1);
6569                 break;
6570             }
6571         }
6572         if (icur == $[deck]('getSlides').length) {
6573             $[deck]('go', icur-1);            
6574         }
6575     });
6576     $d.bind('deck.init', function() {
6577         $d.unbind('keydown.decknexttoplevel').bind('keydown.decknexttoplevel', function(e) {
6578             var $opts = $[deck]('getOptions');
6579             var key = $opts.keys.nextTopLevel;
6580             if (e.which === key || $.inArray(e.which, key) > -1) {
6581                 e.preventDefault();
6582                 $[deck]('nextTopLevelSlide');
6583             }
6584         });
6585         $d.unbind('keydown.decknextendoftoplevel').bind('keydown.decknextendoftoplevel', function(e) {
6586             var $opts = $[deck]('getOptions');
6587             var key = $opts.keys.nextEndOfTopLevel;
6588             if (e.which === key || $.inArray(e.which, key) > -1) {
6589                 e.preventDefault();
6590                 $[deck]('nextEndOfTopLevelSlide');
6591             }
6592         });
6593         $d.unbind('keydown.deckprevioustoplevel').bind('keydown.deckprevioustoplevel', function(e) {
6594             var $opts = $[deck]('getOptions');
6595             var key = $opts.keys.previousTopLevel;
6596             if (e.which === key || $.inArray(e.which, key) > -1) {
6597                 e.preventDefault();
6598                 $[deck]('previousTopLevelSlide');
6599             }
6600         });
6601     });
6602     // When jumping (not steping), we will init the subslides (in case they are animations), in a backward order, and then fast forward necessary animations
6603     var bigJump = function(from, to) {
6604         var direction = "forward";
6605         if (from > to){
6606             direction = "reverse";
6607         }
6608         var opts = $[deck]('getOptions');
6609         $($[deck]('getToplevelSlideOfIndex', to).node.find(opts.selectors.subslidesToNotify).get().reverse()).each(function(ind, el) {$(el).triggerHandler('deck.toplevelBecameCurrent', direction)});
6610         for (icur = $[deck]('getToplevelSlideOfIndex', to).index + 1; icur < to+1; icur++) {
6611             $[deck]('getSlides')[icur].triggerHandler('deck.afterToplevelBecameCurrent', 'forward');
6612         }
6613     }
6614     $d.bind('deck.change', function(e, from, to) {
6615         if (  Math.abs(from - to) > 1 || ! $[deck]('getToplevelSlideOfIndex', to).node.is($[deck]('getToplevelSlideOfIndex', from).node)) {
6616             // consider natural jumps and the case where we actually changed (top level) slide (even with a step)
6617             bigJump(from, to);
6618         }
6619     });
6620 })(jQuery, 'deck');
6621
6622 (function($, deck, undefined) {
6623    $(document).bind('deck.change', function(e, from, to) {
6624       var $prev = $[deck]('getSlide', to-1),
6625       $next = $[deck]('getSlide', to+1),
6626       $oldprev = $[deck]('getSlide', from-1),
6627       $oldnext = $[deck]('getSlide', from+1);
6628       
6629       var direction = "forward";
6630       if(from > to){
6631         direction = "reverse";
6632       }
6633
6634       $[deck]('getSlide', from).triggerHandler('deck.lostCurrent', [direction, from, to]);
6635       $[deck]('getSlide', to).triggerHandler('deck.becameCurrent', [direction, from, to]);
6636
6637       $oldprev && $oldprev.triggerHandler('deck.lostPrevious', [direction, from, to]);
6638       $oldnext && $oldnext.triggerHandler('deck.lostNext', [direction, from, to]);
6639
6640       $prev && $prev.triggerHandler('deck.becamePrevious', [direction, from, to]);
6641       $next && $next.triggerHandler('deck.becameNext', [direction, from, to]);
6642    });
6643 })(jQuery, 'deck');
6644
6645
6646 /*!
6647 Deck JS - deck.anim
6648 Copyright (c) 2012-2014 RĂ©mi Emonet
6649 Licensed under the MIT license.
6650 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6651 */
6652
6653
6654 (function($, deck, undefined) {
6655     // The next two lines are the color plugin from jquery
6656     /*! jQuery Color v@2.1.2 http://github.com/jquery/jquery-color | jquery.org/license */
6657     (function(a,b){function m(a,b,c){var d=h[b.type]||{};return a==null?c||!b.def?null:b.def:(a=d.floor?~~a:parseFloat(a),isNaN(a)?b.def:d.mod?(a+d.mod)%d.mod:0>a?0:d.max<a?d.max:a)}function n(b){var c=f(),d=c._rgba=[];return b=b.toLowerCase(),l(e,function(a,e){var f,h=e.re.exec(b),i=h&&e.parse(h),j=e.space||"rgba";if(i)return f=c[j](i),c[g[j].cache]=f[g[j].cache],d=c._rgba=f._rgba,!1}),d.length?(d.join()==="0,0,0,0"&&a.extend(d,k.transparent),c):k[b]}function o(a,b,c){return c=(c+1)%1,c*6<1?a+(b-a)*c*6:c*2<1?b:c*3<2?a+(b-a)*(2/3-c)*6:a}var c="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",d=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1]*2.55,a[2]*2.55,a[3]*2.55,a[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a){return[a[1],a[2]/100,a[3]/100,a[4]]}}],f=a.Color=function(b,c,d,e){return new a.Color.fn.parse(b,c,d,e)},g={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},h={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},i=f.support={},j=a("<p>")[0],k,l=a.each;j.style.cssText="background-color:rgba(1,1,1,.5)",i.rgba=j.style.backgroundColor.indexOf("rgba")>-1,l(g,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),f.fn=a.extend(f.prototype,{parse:function(c,d,e,h){if(c===b)return this._rgba=[null,null,null,null],this;if(c.jquery||c.nodeType)c=a(c).css(d),d=b;var i=this,j=a.type(c),o=this._rgba=[];d!==b&&(c=[c,d,e,h],j="array");if(j==="string")return this.parse(n(c)||k._default);if(j==="array")return l(g.rgba.props,function(a,b){o[b.idx]=m(c[b.idx],b)}),this;if(j==="object")return c instanceof f?l(g,function(a,b){c[b.cache]&&(i[b.cache]=c[b.cache].slice())}):l(g,function(b,d){var e=d.cache;l(d.props,function(a,b){if(!i[e]&&d.to){if(a==="alpha"||c[a]==null)return;i[e]=d.to(i._rgba)}i[e][b.idx]=m(c[a],b,!0)}),i[e]&&a.inArray(null,i[e].slice(0,3))<0&&(i[e][3]=1,d.from&&(i._rgba=d.from(i[e])))}),this},is:function(a){var b=f(a),c=!0,d=this;return l(g,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],l(e.props,function(a,b){if(g[b.idx]!=null)return c=g[b.idx]===f[b.idx],c})),c}),c},_space:function(){var a=[],b=this;return l(g,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var c=f(a),d=c._space(),e=g[d],i=this.alpha()===0?f("transparent"):this,j=i[e.cache]||e.to(i._rgba),k=j.slice();return c=c[e.cache],l(e.props,function(a,d){var e=d.idx,f=j[e],g=c[e],i=h[d.type]||{};if(g===null)return;f===null?k[e]=g:(i.mod&&(g-f>i.mod/2?f+=i.mod:f-g>i.mod/2&&(f-=i.mod)),k[e]=m((g-f)*b+f,d))}),this[d](k)},blend:function(b){if(this._rgba[3]===1)return this;var c=this._rgba.slice(),d=c.pop(),e=f(b)._rgba;return f(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return a==null?b>2?1:0:a});return c[3]===1&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return a==null&&(a=b>2?1:0),b&&b<3&&(a=Math.round(a*100)+"%"),a});return c[3]===1&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(d*255)),"#"+a.map(c,function(a){return a=(a||0).toString(16),a.length===1?"0"+a:a}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),f.fn.parse.prototype=f.fn,g.hsla.to=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,e=a[3],f=Math.max(b,c,d),g=Math.min(b,c,d),h=f-g,i=f+g,j=i*.5,k,l;return g===f?k=0:b===f?k=60*(c-d)/h+360:c===f?k=60*(d-b)/h+120:k=60*(b-c)/h+240,h===0?l=0:j<=.5?l=h/i:l=h/(2-i),[Math.round(k)%360,l,j,e==null?1:e]},g.hsla.from=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],e=a[3],f=d<=.5?d*(1+c):d+c-d*c,g=2*d-f;return[Math.round(o(g,f,b+1/3)*255),Math.round(o(g,f,b)*255),Math.round(o(g,f,b-1/3)*255),e]},l(g,function(c,e){var g=e.props,h=e.cache,i=e.to,j=e.from;f.fn[c]=function(c){i&&!this[h]&&(this[h]=i(this._rgba));if(c===b)return this[h].slice();var d,e=a.type(c),k=e==="array"||e==="object"?c:arguments,n=this[h].slice();return l(g,function(a,b){var c=k[e==="object"?a:b.idx];c==null&&(c=n[b.idx]),n[b.idx]=m(c,b)}),j?(d=f(j(n)),d[h]=n,d):f(n)},l(g,function(b,e){if(f.fn[b])return;f.fn[b]=function(f){var g=a.type(f),h=b==="alpha"?this._hsla?"hsla":"rgba":c,i=this[h](),j=i[e.idx],k;return g==="undefined"?j:(g==="function"&&(f=f.call(this,j),g=a.type(f)),f==null&&e.empty?this:(g==="string"&&(k=d.exec(f),k&&(f=j+parseFloat(k[2])*(k[1]==="+"?1:-1))),i[e.idx]=f,this[h](i)))}})}),f.hook=function(b){var c=b.split(" ");l(c,function(b,c){a.cssHooks[c]={set:function(b,d){var e,g,h="";if(d!=="transparent"&&(a.type(d)!=="string"||(e=n(d)))){d=f(e||d);if(!i.rgba&&d._rgba[3]!==1){g=c==="backgroundColor"?b.parentNode:b;while((h===""||h==="transparent")&&g&&g.style)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(j){}d=d.blend(h&&h!=="transparent"?h:"_default")}d=d.toRgbaString()}try{b.style[c]=d}catch(j){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=f(b.elem,c),b.end=f(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},f.hook(c),a.cssHooks.borderColor={expand:function(a){var b={};return l(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},k=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery);
6658
6659     var $d = $(document);
6660     var may = function(o,f) {return f ? f.bind(o) : function() {}};
6661
6662     $.extend(true, $[deck].defaults, {
6663         selectors: {
6664             animShow: ".anim-show",
6665             animHide: ".anim-hide",
6666             animAddClass: ".anim-addclass",
6667             animRemoveClass: ".anim-removeclass",
6668             animAttribute: ".anim-attribute",
6669             animWait: ".anim-wait",
6670             // specific ones
6671             animPlay: ".anim-play",
6672             animPause: ".anim-pause",
6673             animViewboxAs: ".anim-viewboxas",
6674             animAlong: ".anim-along",
6675             //
6676             animContinue: ".anim-continue"
6677         },
6678         classes: {
6679             animReady: "deck-anim-ready"
6680         },
6681         anim: {
6682             duration: 400
6683         }
6684     });
6685
6686     var doInit = function() {
6687         // first we define some tools and grab some info from deck.js
6688         var o = $[deck]('getOptions');
6689         var context = function(el) {
6690             return {
6691                 what: function() {return $(el).attr("data-what")},
6692                 dur: function() {return $(el).attr("data-dur")*1 || o.anim.duration},
6693                 delay: function() {return $(el).attr("data-delay")*1 || 0},
6694                 classs: function() {return $(el).attr("data-class")},
6695                 attribute: function() {return $(el).attr("data-attr").split(':')[0]},
6696                 as: function() {return $(el).attr("data-as")},
6697                 path: function() {return $(el).attr("data-path")},
6698                 reverse: function() {var r = $(el).attr("data-reverse"); return r && r.toUpperCase() == "TRUE";},
6699                 value: function() {return $(el).attr("data-attr").split(':')[1]},
6700                 toplevel: function() {return $[deck]('getToplevelSlideOf', el).node},
6701                 all: function() {return $(this.what(),this.toplevel())}
6702             }
6703         };
6704         var globalHasAnimContinue = false;
6705         var classical = function(selector, methods) {
6706             $(selector).each(function(i, el) {
6707                 var c = context(el);
6708                 may(methods, methods.create)(c);
6709                 $(el).bind('deck.toplevelBecameCurrent', function(_, direction) {
6710                     may(methods, methods.init)(c);
6711                 }).bind('deck.afterToplevelBecameCurrent', function(_, direction) {
6712                     may(methods, methods.fast)(c);
6713                 }).bind('deck.lostCurrent', function(_, direction, from, to) {
6714                     if (direction == 'forward' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6715                     may(methods, methods.undo)(c);
6716                 }).bind('deck.becameCurrent', function(_, direction, from, to) {
6717                     if (direction == 'reverse' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6718                     if (c.delay()>0) {
6719                         setTimeout(function() {
6720                             may(methods, methods.doit)(c);
6721                         }, c.delay());
6722                     } else {
6723                         may(methods, methods.doit)(c);
6724                     }
6725                 });
6726             });
6727         };
6728         
6729         // here come the real animations
6730         classical(o.selectors.animShow, {
6731             init: function(c) {c.all().animate({'opacity': 0.}, 0)},
6732             undo: function(c) {c.all().animate({'opacity': 0.}, c.dur()/100)},
6733             doit: function(c) {c.all().animate({'opacity': 1.}, c.dur())},
6734             fast: function(c) {c.all().animate({'opacity': 1.}, 0)}
6735         });
6736         classical(o.selectors.animHide, {
6737             init: function(c) {c.all().animate({'opacity': 1.}, 0)},
6738             undo: function(c) {c.all().animate({'opacity': 1.}, c.dur()/100)},
6739             doit: function(c) {c.all().animate({'opacity': 0.}, c.dur())},
6740             fast: function(c) {c.all().animate({'opacity': 0.}, 0)}
6741         });
6742         classical(o.selectors.animAddClass, {
6743             init: function(c) {c.all().removeClass(c.classs())},
6744             undo: function(c) {c.all().removeClass(c.classs())},
6745             doit: function(c) {c.all().addClass(c.classs())},
6746             fast: function(c) {c.all().addClass(c.classs())}
6747         });
6748         classical(o.selectors.animRemoveClass, {
6749             init: function(c) {c.all().addClass(c.classs())},
6750             undo: function(c) {c.all().addClass(c.classs())},
6751             doit: function(c) {c.all().removeClass(c.classs())},
6752             fast: function(c) {c.all().removeClass(c.classs())}
6753         });
6754         function svgRealAttrName(a) {
6755             if (startsWith(a, "svg")) {
6756                 return REST.substr(0, 1).toLowerCase() + REST.slice(1);
6757             }
6758             return null;
6759         }
6760         function startsWith(longStr, part) {
6761             var res = longStr.substr(0, part.length) == part;
6762             REST = res ? longStr.slice(part.length) : null;
6763             return res;
6764         }
6765         classical(o.selectors.animAttribute, {
6766             init: function(c) {
6767                 this.undo(c);
6768             },
6769             undo: function(c) {
6770                 // TODO: [feature] could allow multiple attributes to be passed and animated simultaneously
6771                 var k = c.attribute()
6772                 for (i in c.previousElement) { // use the saved list of elements and values
6773                     var whatTo = {};
6774                     whatTo[k] = c.previousCss[i];
6775                     $(c.previousElement[i]).finish();
6776                     if (c.previousElement[i] instanceof SVGElement) {
6777                         if (whatTo[k] != null) {
6778                             var realAttrName = svgRealAttrName(k) || k;
6779                             c.previousElement[i].attributes.getNamedItem(realAttrName).value = whatTo[k];
6780                         } else {
6781                             var realAttrName = svgRealAttrName(k) || k;
6782                             c.previousElement[i].attributes.removeNamedItem(realAttrName);
6783                         }
6784                     } else {
6785                         $(c.previousElement[i]).animate(whatTo, 0);
6786                     }
6787                 }
6788             },
6789             doit: function(c, factor) {
6790                 if (factor === undefined) factor = 1
6791                 c.all().each( function() {
6792                     // finish all previous animations
6793                     if (!globalHasAnimContinue && $(this).queue().length) {
6794                         $(this).finish();
6795                     }
6796                 });
6797                 var k = c.attribute()
6798                 c.previousCss = []
6799                 c.previousElement = []
6800                 c.all().each( function(){
6801                     c.previousElement.push(this);
6802                     var v = $(this).css(k);
6803                     if (v == null && this instanceof SVGElement) {
6804                         var realAttrName = svgRealAttrName(k) || k;
6805                         var attr = this.attributes.getNamedItem(realAttrName);
6806                         c.previousCss.push(attr ? attr.value : null);
6807                     } else {
6808                         c.previousCss.push(v);
6809                     }
6810                 }); // save a list of elements and values
6811                 var whatTo = {}
6812                 whatTo[c.attribute()] = c.value()
6813                 c.all().animate(whatTo, c.dur()*factor)
6814             },
6815             fast: function(c) {this.doit(c,0)}
6816         });
6817         classical(o.selectors.animViewboxAs, {
6818             create: function(c) {
6819                 c.attribute = function() {return "svgViewBox"};
6820                 c.value = function() {
6821                     var asWhat = $(c.as());
6822                     var a = function (i) {return asWhat.attr(i)}
6823                     var toViewBox = a('x')+" "+a('y')+" "+a('width')+" "+a('height');
6824                     return toViewBox;
6825                 };
6826             },
6827             init: function(c) {this.undo(c)},
6828             undo: function(c) {
6829                 var k = c.attribute()
6830                 for (i in c.previousElement) { // use the saved list of elements and values
6831                     var whatTo = {}
6832                     whatTo[k] = c.previousValue[i]
6833                     $(c.previousElement[i]).finish();
6834                     $(c.previousElement[i]).animate(whatTo, 0)
6835                 }
6836             },
6837             doit: function(c, factor) {
6838                 if (factor === undefined) factor = 1
6839                 c.all().each( function() {
6840                     // finish all previous animations
6841                     if (!globalHasAnimContinue && $(this).queue().length) {
6842                         $(this).finish();
6843                     }
6844                 });
6845                 var k = c.attribute()
6846                 c.previousValue = []
6847                 c.previousElement = []
6848                 c.all().each( function() {
6849                     c.previousElement.push(this);
6850                     c.previousValue.push(this.attributes.getNamedItem('viewBox').value);
6851                 }); // save a list of elements and values
6852                 var whatTo = {}
6853                 whatTo[k] = c.value()
6854                 c.all().animate(whatTo, c.dur()*factor)
6855             },
6856             fast: function(c) {this.doit(c,0)}
6857         });
6858         classical(o.selectors.animAlong, {
6859             init: function(c) {this.undo(c)},
6860             undo: function(c) {
6861                 for (i in c.previousElement) { // use the saved list of elements and values
6862                     var prev = c.previousValue[i];
6863                     $(c.previousElement[i]).finish();
6864                     $(c.previousElement[i]).attr("transform", prev);
6865                 }
6866             },
6867             doit: function(c, factor) {
6868                 if (factor === undefined) factor = 1;
6869                 c.all().each( function() {
6870                     // finish all previous animations
6871                     if (!globalHasAnimContinue && $(this).queue().length) {
6872                         $(this).finish();
6873                     }
6874                 });
6875                 var path = $(c.path()).get(0);
6876                 var rev = c.reverse();
6877                 var len = path.getTotalLength()
6878                 var s = path.getPointAtLength(rev?len:0);
6879                 c.previousValue = [];
6880                 c.previousElement = [];
6881                 c.all().each( function() {
6882                     var base = "";
6883                     if ($(this).attr("transform") != null) {
6884                         base = $(this).attr("transform"); // TODO maybe can use attr also above (anim-attr)
6885                         c.previousValue.push(base);
6886                     } else {
6887                         c.previousValue.push(null);
6888                     }
6889                     c.previousElement.push(this);
6890                     $(this).css({svgDeckAnim: 0.});
6891                     $(this).animate({svgDeckAnim: 1.}, {
6892                         duration: c.dur()*factor,
6893                         step: function(v) {
6894                             if (rev) v = 1-v;
6895                             var p = path.getPointAtLength(v * len);
6896                             $(this).attr("transform", 'translate('+(p.x-s.x)+','+(p.y-s.y)+')' + base);
6897                         }
6898                     });
6899                 });
6900             },
6901             fast: function(c) {this.doit(c, 0);}
6902         });
6903         classical(o.selectors.animPlay, {
6904             init: function(c) {c.all().each(function(){this.pause(); try{this.currentTime=0}catch(e){} })},
6905             undo: function(c) {c.all().each(function(){this.pause()})},
6906             doit: function(c) {c.all().each(function(){this.play()})},
6907             fast: function(c) {c.all().each(function(){this.play()})}
6908         });
6909         classical(o.selectors.animPause, {
6910             undo: function(c) {c.all().each(function(){this.play()})},
6911             doit: function(c) {c.all().each(function(){this.pause()})},
6912             fast: function(c) {c.all().each(function(){this.pause()})}
6913         });
6914         classical(o.selectors.animContinue, {
6915             doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, 1)}
6916             // do not do it in fast mode
6917         });
6918         classical(o.selectors.animWait, {
6919             doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, c.dur())}
6920         });
6921         // handle the chained undo for "anim-continue"
6922         $(o.selectors.animContinue + "," + o.selectors.animWait).each(function(i, curSlide) {
6923             $(curSlide).bind('deck.becameCurrent', function(_, direction) {
6924                 if (direction == 'forward') return;
6925                 setTimeout(function(){$[deck]('prev')}, 1)
6926             });
6927
6928         });
6929
6930         // finally force "refresh" (notification of slide change)
6931         var current = $[deck]('getSlide')
6932         var icur = 0
6933         for (; icur < $[deck]('getSlides').length; icur++) {
6934             if ($[deck]('getSlides')[icur] == current) break;                
6935         }
6936         $d.trigger("deck.change", [icur, 0]);
6937         $d.trigger("deck.change", [0, icur]);
6938
6939         var container = $[deck]('getContainer');
6940         $(container).addClass(o.classes.animReady)
6941     }
6942     $(document).bind('deck.init', function() {
6943         doInit();
6944     });
6945         
6946 })(jQuery, 'deck');
6947
6948
6949 (function(e){function d(){this._settings=[];this._extensions=[];this.regional=[];this.regional[""]={errorLoadingText:"Error loading",notSupportedText:"This browser does not support SVG"};this.local=this.regional[""];this._uuid=new Date().getTime();this._renesis=c("RenesisX.RenesisCtrl")}function c(i){try{return !!(window.ActiveXObject&&new ActiveXObject(i))}catch(j){return false}}var g="svgwrapper";e.extend(d.prototype,{markerClassName:"hasSVG",svgNS:"http://www.w3.org/2000/svg",xlinkNS:"http://www.w3.org/1999/xlink",_wrapperClass:b,_attrNames:{class_:"class",in_:"in",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorRendering:"color-rendering",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",underlinePosition:"underline-position",underlineThickness:"underline-thickness",vertAdvY:"vert-adv-y",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode"},_attachSVG:function(i,k){var j=(i.namespaceURI==this.svgNS?i:null);var i=(j?null:i);if(e(i||j).hasClass(this.markerClassName)){return}if(typeof k=="string"){k={loadURL:k}}else{if(typeof k=="function"){k={onLoad:k}}}e(i||j).addClass(this.markerClassName);try{if(!j){j=document.createElementNS(this.svgNS,"svg");j.setAttribute("version","1.1");if(i.clientWidth>0){j.setAttribute("width",i.clientWidth)}if(i.clientHeight>0){j.setAttribute("height",i.clientHeight)}i.appendChild(j)}this._afterLoad(i,j,k||{})}catch(l){if(!e.support.noCloneChecked){if(!i.id){i.id="svg"+(this._uuid++)}this._settings[i.id]=k;i.innerHTML='<embed type="image/svg+xml" width="100%" height="100%" src="'+(k.initPath||"")+'blank.svg" pluginspage="http://www.adobe.com/svg/viewer/install/main.html"/>'}else{i.innerHTML='<p class="svg_error">'+this.local.notSupportedText+"</p>"}}},_registerSVG:function(){for(var l=0;l<document.embeds.length;l++){var j=document.embeds[l].parentNode;if(!e(j).hasClass(e.svg.markerClassName)||e.data(j,g)){continue}var k=null;try{k=document.embeds[l].getSVGDocument()}catch(m){setTimeout(e.svg._registerSVG,250);return}k=(k?k.documentElement:null);if(k){e.svg._afterLoad(j,k)}}},_afterLoad:function(i,j,k){var k=k||this._settings[i.id];this._settings[i?i.id:""]=null;var m=new this._wrapperClass(j,i);e.data(i||j,g,m);try{if(k.loadURL){m.load(k.loadURL,k)}if(k.settings){m.configure(k.settings)}if(k.onLoad&&!k.loadURL){k.onLoad.apply(i||j,[m])}}catch(l){alert(l)}},_getSVG:function(i){i=(typeof i=="string"?e(i)[0]:(i.jquery?i[0]:i));return e.data(i,g)},_destroySVG:function(i){var j=e(i);if(!j.hasClass(this.markerClassName)){return}j.removeClass(this.markerClassName);if(i.namespaceURI!=this.svgNS){j.empty()}e.removeData(i,g)},addExtension:function(j,i){this._extensions.push([j,i])},isSVGElem:function(i){return(i.nodeType==1&&i.namespaceURI==e.svg.svgNS)}});function b(k,j){this._svg=k;this._container=j;for(var l=0;l<e.svg._extensions.length;l++){var m=e.svg._extensions[l];this[m[0]]=new m[1](this)}}e.extend(b.prototype,{_width:function(){return(this._container?this._container.clientWidth:this._svg.width)},_height:function(){return(this._container?this._container.clientHeight:this._svg.height)},root:function(){return this._svg},configure:function(o,n,k){if(!o.nodeName){k=n;n=o;o=this._svg}if(k){for(var m=o.attributes.length-1;m>=0;m--){var j=o.attributes.item(m);if(!(j.nodeName=="onload"||j.nodeName=="version"||j.nodeName.substring(0,5)=="xmlns")){o.attributes.removeNamedItem(j.nodeName)}}}for(var l in n){o.setAttribute(e.svg._attrNames[l]||l,n[l])}return this},getElementById:function(i){return this._svg.ownerDocument.getElementById(i)},change:function(j,k){if(j){for(var i in k){if(k[i]==null){j.removeAttribute(e.svg._attrNames[i]||i)}else{j.setAttribute(e.svg._attrNames[i]||i,k[i])}}}return this},_args:function(k,n,j){n.splice(0,0,"parent");n.splice(n.length,0,"settings");var l={};var o=0;if(k[0]!=null&&k[0].jquery){k[0]=k[0][0]}if(k[0]!=null&&!(typeof k[0]=="object"&&k[0].nodeName)){l.parent=null;o=1}for(var m=0;m<k.length;m++){l[n[m+o]]=k[m]}if(j){e.each(j,function(p,q){if(typeof l[q]=="object"){l.settings=l[q];l[q]=null}})}return l},title:function(k,m,j){var i=this._args(arguments,["text"]);var l=this._makeNode(i.parent,"title",i.settings||{});l.appendChild(this._svg.ownerDocument.createTextNode(i.text));return l},describe:function(k,m,j){var i=this._args(arguments,["text"]);var l=this._makeNode(i.parent,"desc",i.settings||{});l.appendChild(this._svg.ownerDocument.createTextNode(i.text));return l},defs:function(k,l,j){var i=this._args(arguments,["id"],["id"]);return this._makeNode(i.parent,"defs",e.extend((i.id?{id:i.id}:{}),i.settings||{}))},symbol:function(o,p,k,n,m,i,l){var j=this._args(arguments,["id","x1","y1","width","height"]);return this._makeNode(j.parent,"symbol",e.extend({id:j.id,viewBox:j.x1+" "+j.y1+" "+j.width+" "+j.height},j.settings||{}))},marker:function(o,i,q,p,l,j,m,k){var n=this._args(arguments,["id","refX","refY","mWidth","mHeight","orient"],["orient"]);return this._makeNode(n.parent,"marker",e.extend({id:n.id,refX:n.refX,refY:n.refY,markerWidth:n.mWidth,markerHeight:n.mHeight,orient:n.orient||"auto"},n.settings||{}))},style:function(k,m,j){var i=this._args(arguments,["styles"]);var l=this._makeNode(i.parent,"style",e.extend({type:"text/css"},i.settings||{}));l.appendChild(this._svg.ownerDocument.createTextNode(i.styles));return l},script:function(m,i,l,k){var j=this._args(arguments,["script","type"],["type"]);var n=this._makeNode(j.parent,"script",e.extend({type:j.type||"text/javascript"},j.settings||{}));n.appendChild(this._svg.ownerDocument.createTextNode(j.script));return n},linearGradient:function(q,j,r,k,p,i,o,l){var n=this._args(arguments,["id","stops","x1","y1","x2","y2"],["x1"]);var m=e.extend({id:n.id},(n.x1!=null?{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}:{}));return this._gradient(n.parent,"linearGradient",e.extend(m,n.settings||{}),n.stops)},radialGradient:function(s,j,t,o,m,i,n,k,l){var q=this._args(arguments,["id","stops","cx","cy","r","fx","fy"],["cx"]);var p=e.extend({id:q.id},(q.cx!=null?{cx:q.cx,cy:q.cy,r:q.r,fx:q.fx,fy:q.fy}:{}));return this._gradient(q.parent,"radialGradient",e.extend(p,q.settings||{}),q.stops)},_gradient:function(n,j,m,p){var o=this._makeNode(n,j,m);for(var l=0;l<p.length;l++){var k=p[l];this._makeNode(o,"stop",e.extend({offset:k[0],stopColor:k[1]},(k[2]!=null?{stopOpacity:k[2]}:{})))}return o},pattern:function(s,i,r,p,j,t,q,o,l,u,k){var n=this._args(arguments,["id","x","y","width","height","vx","vy","vwidth","vheight"],["vx"]);var m=e.extend({id:n.id,x:n.x,y:n.y,width:n.width,height:n.height},(n.vx!=null?{viewBox:n.vx+" "+n.vy+" "+n.vwidth+" "+n.vheight}:{}));return this._makeNode(n.parent,"pattern",e.extend(m,n.settings||{}))},clipPath:function(l,m,i,k){var j=this._args(arguments,["id","units"]);j.units=j.units||"userSpaceOnUse";return this._makeNode(j.parent,"clipPath",e.extend({id:j.id,clipPathUnits:j.units},j.settings||{}))},mask:function(n,p,j,o,m,i,l){var k=this._args(arguments,["id","x","y","width","height"]);return this._makeNode(k.parent,"mask",e.extend({id:k.id,x:k.x,y:k.y,width:k.width,height:k.height},k.settings||{}))},createPath:function(){return new f()},createText:function(){return new h()},svg:function(r,q,o,i,s,p,n,k,t,j){var m=this._args(arguments,["x","y","width","height","vx","vy","vwidth","vheight"],["vx"]);var l=e.extend({x:m.x,y:m.y,width:m.width,height:m.height},(m.vx!=null?{viewBox:m.vx+" "+m.vy+" "+m.vwidth+" "+m.vheight}:{}));return this._makeNode(m.parent,"svg",e.extend(l,m.settings||{}))},group:function(k,l,j){var i=this._args(arguments,["id"],["id"]);return this._makeNode(i.parent,"g",e.extend({id:i.id},i.settings||{}))},use:function(p,o,n,i,q,j,l){var m=this._args(arguments,["x","y","width","height","ref"]);if(typeof m.x=="string"){m.ref=m.x;m.settings=m.y;m.x=m.y=m.width=m.height=null}var k=this._makeNode(m.parent,"use",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},m.settings||{}));k.setAttributeNS(e.svg.xlinkNS,"href",m.ref);return k},link:function(k,m,j){var i=this._args(arguments,["ref"]);var l=this._makeNode(i.parent,"a",i.settings);l.setAttributeNS(e.svg.xlinkNS,"href",i.ref);return l},image:function(p,o,n,i,q,j,l){var m=this._args(arguments,["x","y","width","height","ref"]);var k=this._makeNode(m.parent,"image",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},m.settings||{}));k.setAttributeNS(e.svg.xlinkNS,"href",m.ref);return k},path:function(k,l,j){var i=this._args(arguments,["path"]);return this._makeNode(i.parent,"path",e.extend({d:(i.path.path?i.path.path():i.path)},i.settings||{}))},rect:function(p,o,n,k,q,j,i,l){var m=this._args(arguments,["x","y","width","height","rx","ry"],["rx"]);return this._makeNode(m.parent,"rect",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},(m.rx?{rx:m.rx,ry:m.ry}:{}),m.settings||{}))},circle:function(l,i,n,m,k){var j=this._args(arguments,["cx","cy","r"]);return this._makeNode(j.parent,"circle",e.extend({cx:j.cx,cy:j.cy,r:j.r},j.settings||{}))},ellipse:function(l,i,o,n,m,k){var j=this._args(arguments,["cx","cy","rx","ry"]);return this._makeNode(j.parent,"ellipse",e.extend({cx:j.cx,cy:j.cy,rx:j.rx,ry:j.ry},j.settings||{}))},line:function(o,k,n,i,l,m){var j=this._args(arguments,["x1","y1","x2","y2"]);return this._makeNode(j.parent,"line",e.extend({x1:j.x1,y1:j.y1,x2:j.x2,y2:j.y2},j.settings||{}))},polyline:function(l,k,j){var i=this._args(arguments,["points"]);return this._poly(i.parent,"polyline",i.points,i.settings)},polygon:function(l,k,j){var i=this._args(arguments,["points"]);return this._poly(i.parent,"polygon",i.points,i.settings)},_poly:function(n,j,m,l){var o="";for(var k=0;k<m.length;k++){o+=m[k].join()+" "}return this._makeNode(n,j,e.extend({points:e.trim(o)},l||{}))},text:function(l,i,n,m,k){var j=this._args(arguments,["x","y","value"]);if(typeof j.x=="string"&&arguments.length<4){j.value=j.x;j.settings=j.y;j.x=j.y=null}return this._text(j.parent,"text",j.value,e.extend({x:(j.x&&a(j.x)?j.x.join(" "):j.x),y:(j.y&&a(j.y)?j.y.join(" "):j.y)},j.settings||{}))},textpath:function(k,n,m,j){var i=this._args(arguments,["path","value"]);var l=this._text(i.parent,"textPath",i.value,i.settings||{});l.setAttributeNS(e.svg.xlinkNS,"href",i.path);return l},_text:function(r,j,q,n){var m=this._makeNode(r,j,n);if(typeof q=="string"){m.appendChild(m.ownerDocument.createTextNode(q))}else{for(var o=0;o<q._parts.length;o++){var l=q._parts[o];if(l[0]=="tspan"){var k=this._makeNode(m,l[0],l[2]);k.appendChild(m.ownerDocument.createTextNode(l[1]));m.appendChild(k)}else{if(l[0]=="tref"){var k=this._makeNode(m,l[0],l[2]);k.setAttributeNS(e.svg.xlinkNS,"href",l[1]);m.appendChild(k)}else{if(l[0]=="textpath"){var p=e.extend({},l[2]);p.href=null;var k=this._makeNode(m,l[0],p);k.setAttributeNS(e.svg.xlinkNS,"href",l[2].href);k.appendChild(m.ownerDocument.createTextNode(l[1]));m.appendChild(k)}else{m.appendChild(m.ownerDocument.createTextNode(l[1]))}}}}}return m},other:function(l,j,k){var i=this._args(arguments,["name"]);return this._makeNode(i.parent,i.name,i.settings||{})},_makeNode:function(k,i,j){k=k||this._svg;var l=this._svg.ownerDocument.createElementNS(e.svg.svgNS,i);for(var i in j){var m=j[i];if(m!=null&&m!=null&&(typeof m!="string"||m!="")){l.setAttribute(e.svg._attrNames[i]||i,m)}}k.appendChild(l);return l},add:function(k,l){var j=this._args((arguments.length==1?[null,k]:arguments),["node"]);var i=this;j.parent=j.parent||this._svg;j.node=(j.node.jquery?j.node:e(j.node));try{if(e.svg._renesis){throw"Force traversal"}j.parent.appendChild(j.node.cloneNode(true))}catch(m){j.node.each(function(){var n=i._cloneAsSVG(this);if(n){j.parent.appendChild(n)}})}return this},clone:function(l,m){var i=this;var k=this._args((arguments.length==1?[null,l]:arguments),["node"]);k.parent=k.parent||this._svg;k.node=(k.node.jquery?k.node:e(k.node));var j=[];k.node.each(function(){var n=i._cloneAsSVG(this);if(n){n.id="";k.parent.appendChild(n);j.push(n)}});return j},_cloneAsSVG:function(m){var l=null;if(m.nodeType==1){l=this._svg.ownerDocument.createElementNS(e.svg.svgNS,this._checkName(m.nodeName));for(var k=0;k<m.attributes.length;k++){var j=m.attributes.item(k);if(j.nodeName!="xmlns"&&j.nodeValue){if(j.prefix=="xlink"){l.setAttributeNS(e.svg.xlinkNS,j.localName||j.baseName,j.nodeValue)}else{l.setAttribute(this._checkName(j.nodeName),j.nodeValue)}}}for(var k=0;k<m.childNodes.length;k++){var o=this._cloneAsSVG(m.childNodes[k]);if(o){l.appendChild(o)}}}else{if(m.nodeType==3){if(e.trim(m.nodeValue)){l=this._svg.ownerDocument.createTextNode(m.nodeValue)}}else{if(m.nodeType==4){if(e.trim(m.nodeValue)){try{l=this._svg.ownerDocument.createCDATASection(m.nodeValue)}catch(n){l=this._svg.ownerDocument.createTextNode(m.nodeValue.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"))}}}}}return l},_checkName:function(i){i=(i.substring(0,1)>="A"&&i.substring(0,1)<="Z"?i.toLowerCase():i);return(i.substring(0,4)=="svg:"?i.substring(4):i)},load:function(i,l){l=(typeof l=="boolean"?{addTo:l}:(typeof l=="function"?{onLoad:l}:(typeof l=="string"?{parent:l}:(typeof l=="object"&&l.nodeName?{parent:l}:(typeof l=="object"&&l.jquery?{parent:l}:l||{})))));if(!l.parent&&!l.addTo){this.clear(false)}var j=[this._svg.getAttribute("width"),this._svg.getAttribute("height")];var o=this;var n=function(p){p=e.svg.local.errorLoadingText+": "+p;if(l.onLoad){l.onLoad.apply(o._container||o._svg,[o,p])}else{o.text(null,10,20,p)}};var m=function(q){var p=new ActiveXObject("Microsoft.XMLDOM");p.validateOnParse=false;p.resolveExternals=false;p.async=false;p.loadXML(q);if(p.parseError.errorCode!=0){n(p.parseError.reason);return null}return p};var k=function(s){if(!s){return}if(s.documentElement.nodeName!="svg"){var z=s.getElementsByTagName("parsererror");var r=(z.length?z[0].getElementsByTagName("div"):[]);n(!z.length?"???":(r.length?r[0]:z[0]).firstChild.nodeValue);return}if(!l.forceKeepRelativePath&&i.search(/\//)!=-1){var q=i.replace(/\/[^\/]*$/,"/");e("*[xlink\\:href]",s.documentElement).each(function(C,D){var w=e(D).attr("xlink:href")+"";if(!w.match(/(^[a-z]([-a-z0-9+.])*:.*$)|(^\/.*$)/i)&&w[0]!="#"){e(D).attr("xlink:href",q+e(D).attr("xlink:href"))}})}var A=(l.parent?e(l.parent)[0]:o._svg);var B={};for(var t=0;t<s.documentElement.attributes.length;t++){var x=s.documentElement.attributes.item(t);if(!(x.nodeName=="version"||x.nodeName.substring(0,5)=="xmlns")){B[x.nodeName]=x.nodeValue}}o.configure(A,B,!l.parent);var p=s.documentElement.childNodes;for(var t=0;t<p.length;t++){try{if(e.svg._renesis){throw"Force traversal"}A.appendChild(o._svg.ownerDocument.importNode(p[t],true));if(p[t].nodeName=="script"){e.globalEval(p[t].textContent)}}catch(v){o.add(A,p[t])}}if(!l.changeSize){o.configure(A,{width:j[0],height:j[1]})}if(l.onLoad){var y=s.documentElement.getAttribute("width");var u=s.documentElement.getAttribute("height");l.onLoad.apply(o._container||o._svg,[o,y,u])}};if(i.match("<svg")){k(!e.support.noCloneChecked?m(i):new DOMParser().parseFromString(i,"text/xml"))}else{e.ajax({url:i,dataType:(!e.support.noCloneChecked?"text":"xml"),success:function(p){k(!e.support.noCloneChecked?m(p):p)},error:function(q,r,p){n(r+(p?" "+p.message:""))}})}return this},remove:function(i){i=(i.jquery?i[0]:i);i.parentNode.removeChild(i);return this},clear:function(i){if(i){this.configure({},true)}while(this._svg.firstChild){this._svg.removeChild(this._svg.firstChild)}return this},toSVG:function(i){i=i||this._svg;return(typeof XMLSerializer=="undefined"?this._toSVG(i):new XMLSerializer().serializeToString(i))},_toSVG:function(m){var l="";if(!m){return l}if(m.nodeType==3){l=m.nodeValue}else{if(m.nodeType==4){l="<![CDATA["+m.nodeValue+"]]>"}else{l="<"+m.nodeName;if(m.attributes){for(var k=0;k<m.attributes.length;k++){var j=m.attributes.item(k);if(!(e.trim(j.nodeValue)==""||j.nodeValue.match(/^\[object/)||j.nodeValue.match(/^function/))){l+=" "+(j.namespaceURI==e.svg.xlinkNS?"xlink:":"")+j.nodeName+'="'+j.nodeValue+'"'}}}if(m.firstChild){l+=">";var n=m.firstChild;while(n){l+=this._toSVG(n);n=n.nextSibling}l+="</"+m.nodeName+">"}else{l+="/>"}}}return l}});function f(){this._path=""}e.extend(f.prototype,{reset:function(){this._path="";return this},move:function(i,k,j){j=(a(i)?k:j);return this._coords((j?"m":"M"),i,k)},line:function(i,k,j){j=(a(i)?k:j);return this._coords((j?"l":"L"),i,k)},horiz:function(i,j){this._path+=(j?"h":"H")+(a(i)?i.join(" "):i);return this},vert:function(j,i){this._path+=(i?"v":"V")+(a(j)?j.join(" "):j);return this},curveC:function(k,m,j,l,i,o,n){n=(a(k)?m:n);return this._coords((n?"c":"C"),k,m,j,l,i,o)},smoothC:function(j,k,i,m,l){l=(a(j)?k:l);return this._coords((l?"s":"S"),j,k,i,m)},curveQ:function(j,k,i,m,l){l=(a(j)?k:l);return this._coords((l?"q":"Q"),j,k,i,m)},smoothQ:function(i,k,j){j=(a(i)?k:j);return this._coords((j?"t":"T"),i,k)},_coords:function(m,l,r,k,q,j,p){if(a(l)){for(var n=0;n<l.length;n++){var o=l[n];this._path+=(n==0?m:" ")+o[0]+","+o[1]+(o.length<4?"":" "+o[2]+","+o[3]+(o.length<6?"":" "+o[4]+","+o[5]))}}else{this._path+=m+l+","+r+(k==null?"":" "+k+","+q+(j==null?"":" "+j+","+p))}return this},arc:function(m,j,p,s,l,r,q,k){k=(a(m)?j:k);this._path+=(k?"a":"A");if(a(m)){for(var n=0;n<m.length;n++){var o=m[n];this._path+=(n==0?"":" ")+o[0]+","+o[1]+" "+o[2]+" "+(o[3]?"1":"0")+","+(o[4]?"1":"0")+" "+o[5]+","+o[6]}}else{this._path+=m+","+j+" "+p+" "+(s?"1":"0")+","+(l?"1":"0")+" "+r+","+q}return this},close:function(){this._path+="z";return this},path:function(){return this._path}});f.prototype.moveTo=f.prototype.move;f.prototype.lineTo=f.prototype.line;f.prototype.horizTo=f.prototype.horiz;f.prototype.vertTo=f.prototype.vert;f.prototype.curveCTo=f.prototype.curveC;f.prototype.smoothCTo=f.prototype.smoothC;f.prototype.curveQTo=f.prototype.curveQ;f.prototype.smoothQTo=f.prototype.smoothQ;f.prototype.arcTo=f.prototype.arc;function h(){this._parts=[]}e.extend(h.prototype,{reset:function(){this._parts=[];return this},string:function(i){this._parts[this._parts.length]=["text",i];return this},span:function(j,i){this._parts[this._parts.length]=["tspan",j,i];return this},ref:function(j,i){this._parts[this._parts.length]=["tref",j,i];return this},path:function(k,j,i){this._parts[this._parts.length]=["textpath",j,e.extend({href:k},i||{})];return this}});e.fn.svg=function(j){var i=Array.prototype.slice.call(arguments,1);if(typeof j=="string"&&j=="get"){return e.svg["_"+j+"SVG"].apply(e.svg,[this[0]].concat(i))}return this.each(function(){if(typeof j=="string"){e.svg["_"+j+"SVG"].apply(e.svg,[this].concat(i))}else{e.svg._attachSVG(this,j||{})}})};function a(i){return(i&&i.constructor==Array)}e.svg=new d()})(jQuery);
6950 (function(a){a.each(["x","y","width","height","rx","ry","cx","cy","r","x1","y1","x2","y2","stroke-width","strokeWidth","opacity","fill-opacity","fillOpacity","stroke-opacity","strokeOpacity","stroke-dashoffset","strokeDashOffset","font-size","fontSize","font-weight","fontWeight","letter-spacing","letterSpacing","word-spacing","wordSpacing"],function(h,g){var f=g.charAt(0).toUpperCase()+g.substr(1);if(a.cssProps){a.cssProps["svg"+f]=a.cssProps["svg-"+g]=g}a.fx.step["svg"+f]=a.fx.step["svg-"+g]=function(k){var j=a.svg._attrNames[g]||g;var i=k.elem.attributes.getNamedItem(j);if(!k.set){k.start=(i?parseFloat(i.value):0);var m="";if(/^[+-]=/.exec(m)){k.end=k.start+parseFloat(m.replace(/=/,""))}a(k.elem).css(j,"");k.set=true}var l=(k.pos*(k.end-k.start)+k.start)+(k.unit=="%"?"%":"");(i?i.value=l:k.elem.setAttribute(j,l))}});a.fx.step.svgStrokeDashArray=a.fx.step["svg-strokeDashArray"]=a.fx.step["svgStroke-dasharray"]=a.fx.step["svg-stroke-dasharray"]=function(j){var g=j.elem.attributes.getNamedItem("stroke-dasharray");if(!j.set){j.start=c(g?g.value:"");var l=j.end;j.end=c(l);if(/^[+-]=/.exec(l)){l=l.split(/[, ]+/);if(l.length%2==1){var f=l.length;for(var h=0;h<f;h++){l.push(l[h])}}for(var h=0;h<l.length;h++){if(/^[+-]=/.exec(l[h])){j.end[h]=j.start[h]+parseFloat(l[h].replace(/=/,""))}}}j.set=true}var k=a.map(j.start,function(o,m){return(j.pos*(j.end[m]-o)+o)}).join(",");(g?g.value=k:j.elem.setAttribute("stroke-dasharray",k))};function c(j){var g=j.split(/[, ]+/);for(var h=0;h<g.length;h++){g[h]=parseFloat(g[h]);if(isNaN(g[h])){g[h]=0}}if(g.length%2==1){var f=g.length;for(var h=0;h<f;h++){g.push(g[h])}}return g}a.fx.step.svgViewBox=a.fx.step["svg-viewBox"]=function(h){var f=h.elem.attributes.getNamedItem("viewBox");if(!h.set){h.start=b(f?f.value:"");var k=h.end;h.end=b(k);if(/^[+-]=/.exec(k)){k=k.split(/[, ]+/);while(k.length<4){k.push("0")}for(var g=0;g<4;g++){if(/^[+-]=/.exec(k[g])){h.end[g]=h.start[g]+parseFloat(k[g].replace(/=/,""))}}}h.set=true}var j=a.map(h.start,function(m,l){return(h.pos*(h.end[l]-m)+m)}).join(" ");(f?f.value=j:h.elem.setAttribute("viewBox",j))};function b(g){var h=g.split(/[, ]+/);for(var f=0;f<h.length;f++){h[f]=parseFloat(h[f]);if(isNaN(h[f])){h[f]=0}}while(h.length<4){h.push(0)}return h}a.fx.step.svgTransform=a.fx.step["svg-transform"]=function(m){var f=m.elem.attributes.getNamedItem("transform");if(!m.set){m.start=e(f?f.value:"");m.end=e(m.end,m.start);m.set=true}var k="";for(var l=0;l<m.end.order.length;l++){switch(m.end.order.charAt(l)){case"t":k+=" translate("+(m.pos*(m.end.translateX-m.start.translateX)+m.start.translateX)+","+(m.pos*(m.end.translateY-m.start.translateY)+m.start.translateY)+")";break;case"s":k+=" scale("+(m.pos*(m.end.scaleX-m.start.scaleX)+m.start.scaleX)+","+(m.pos*(m.end.scaleY-m.start.scaleY)+m.start.scaleY)+")";break;case"r":k+=" rotate("+(m.pos*(m.end.rotateA-m.start.rotateA)+m.start.rotateA)+","+(m.pos*(m.end.rotateX-m.start.rotateX)+m.start.rotateX)+","+(m.pos*(m.end.rotateY-m.start.rotateY)+m.start.rotateY)+")";break;case"x":k+=" skewX("+(m.pos*(m.end.skewX-m.start.skewX)+m.start.skewX)+")";case"y":k+=" skewY("+(m.pos*(m.end.skewY-m.start.skewY)+m.start.skewY)+")";break;case"m":var g="";for(var h=0;h<6;h++){g+=","+(m.pos*(m.end.matrix[h]-m.start.matrix[h])+m.start.matrix[h])}k+=" matrix("+g.substr(1)+")";break}}(f?f.value=k:m.elem.setAttribute("transform",k))};function e(j,h){j=j||"";if(typeof j=="object"){j=j.value}var g=a.extend({translateX:0,translateY:0,scaleX:0,scaleY:0,rotateA:0,rotateX:0,rotateY:0,skewX:0,skewY:0,matrix:[0,0,0,0,0,0]},h||{});g.order="";var i=/([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g;var f=i.exec(j);while(f){switch(f[1]){case"translate":g.order+="t";g.translateX=parseFloat(f[2]);g.translateY=(f[3]?parseFloat(f[3]):0);break;case"scale":g.order+="s";g.scaleX=parseFloat(f[2]);g.scaleY=(f[3]?parseFloat(f[3]):g.scaleX);break;case"rotate":g.order+="r";g.rotateA=parseFloat(f[2]);g.rotateX=(f[3]?parseFloat(f[3]):0);g.rotateY=(f[4]?parseFloat(f[4]):0);break;case"skewX":g.order+="x";g.skewX=parseFloat(f[2]);break;case"skewY":g.order+="y";g.skewY=parseFloat(f[2]);break;case"matrix":g.order+="m";g.matrix=[parseFloat(f[2]),parseFloat(f[3]),parseFloat(f[4]),parseFloat(f[5]),parseFloat(f[6]),parseFloat(f[7])];break}f=i.exec(j)}if(g.order=="m"&&Math.abs(g.matrix[0])==Math.abs(g.matrix[3])&&g.matrix[1]!=0&&Math.abs(g.matrix[1])==Math.abs(g.matrix[2])){var k=Math.acos(g.matrix[0])*180/Math.PI;k=(g.matrix[1]<0?360-k:k);g.order="rt";g.rotateA=k;g.rotateX=g.rotateY=0;g.translateX=g.matrix[4];g.translateY=g.matrix[5]}return g}a.each(["fill","stroke"],function(h,g){var f=g.charAt(0).toUpperCase()+g.substr(1);a.fx.step["svg"+f]=a.fx.step["svg-"+g]=function(k){if(!k.set){k.start=a.svg._getColour(k.elem,g);var j=(k.end=="none");k.end=(j?a.svg._getColour(k.elem.parentNode,g):a.svg._getRGB(k.end));k.end[3]=j;a(k.elem).css(g,"");k.set=true}var i=k.elem.attributes.getNamedItem(g);var l="rgb("+[Math.min(Math.max(parseInt((k.pos*(k.end[0]-k.start[0]))+k.start[0],10),0),255),Math.min(Math.max(parseInt((k.pos*(k.end[1]-k.start[1]))+k.start[1],10),0),255),Math.min(Math.max(parseInt((k.pos*(k.end[2]-k.start[2]))+k.start[2],10),0),255)].join(",")+")";l=(k.end[3]&&k.state==1?"none":l);(i?i.value=l:k.elem.setAttribute(g,l))}});a.svg._getColour=function(g,f){g=a(g);var h;do{h=g.attr(f)||g.css(f);if((h!=""&&h!="none")||g.hasClass(a.svg.markerClassName)){break}}while(g=g.parent());return a.svg._getRGB(h)};a.svg._getRGB=function(g){var f;if(g&&g.constructor==Array){return(g.length==3||g.length==4?g:d.none)}if(f=/^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/^rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)$/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}return d[a.trim(g).toLowerCase()]||d.none};var d={"":[255,255,255,1],none:[255,255,255,1],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}})(jQuery);
6951 /*!
6952 Deck JS - deck.svg
6953 Copyright (c) 2012-2014 RĂ©mi Emonet, as a major refactor from an early version from RĂ©mi Barraquand.
6954 Licensed under the MIT license.
6955 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6956 */
6957
6958 /*
6959 This module provides a support for managed svg inclusion (allowing proper DOM access subsequently for animations, etc.).
6960 */
6961
6962 (function($, deck, undefined) {
6963     var $d = $(document);
6964     var may = function(f) {return f ? f : function() {}};
6965
6966     $.extend(true, $[deck].defaults, {
6967         classes: {
6968             svgPlaceholder: 'deck-svg'
6969         },
6970         selectors: {
6971             svgObject: "object[type='deckjs/svg'], div.svg-object",
6972             svgObjectDisable: {
6973                 idrewrite: ".no-idrewrite",
6974                 stylerewrite: ".no-stylerewrite"
6975             }
6976         },
6977         alert: {
6978             missingSVG: true
6979         }
6980     });
6981
6982     function walk(node, fn) {
6983         if (node) do {
6984             if (node.nodeType === 1) {
6985                 fn.call(node);
6986                 walk(node.firstChild, fn);
6987             }
6988         } while (node = node.nextSibling);
6989     }
6990     var svgPatcher = {
6991         styleToAttributes: function(root, svgfile) {
6992             walk(root, function() {
6993                 var $n = $(this);
6994                 if ($n.attr("style")) {
6995                     $($n.attr("style").trim().split(/ *; */)).each(function(index, style) {
6996                         if (style && style.substring(0,1) != "-") {
6997                             var s = style.trim().split(/ *: */);
6998                             $n.attr(s[0], s[1]);
6999                         }
7000                     });
7001                 }
7002                 $n.attr("style", null);
7003             })
7004         },
7005         referencingAttributes: ["clip-path", "color-profile", "fill", "filter", "marker-start", "marker-mid", "marker-end", "mask", "stroke"],
7006         nextId: 1,
7007         generateId: function(oldId) {
7008             var id = "uniquesvg"+svgPatcher.nextId;
7009             svgPatcher.nextId++;
7010             return id;
7011         },
7012         makeReferencedIdsUnique: function(root, svgfile, continuation) {
7013             var andThen = continuation || function(){}
7014             var byId = {};
7015             var referencersIds = {};
7016             var pushAdd = function(k, o) {
7017                 if (referencersIds[k]) {
7018                     referencersIds[k].push(o);
7019                 } else {
7020                     referencersIds[k] = [ o ];
7021                 }
7022             };
7023             // gather all ids and references
7024             walk(root, function() {
7025                 var that = this;
7026                 var $n = $(this);
7027                 var id = that.id;
7028                 if (id) {
7029                     byId[id] = this;
7030                 }
7031                 $(svgPatcher.referencingAttributes).each(function(i,attr) {
7032                     var val = $n.attr(attr);
7033                     if (val) {
7034                         var groups = val.trim().match(/^url\(#(.+?)\)$/)
7035                         if (groups) pushAdd(groups[1], {o:that, a:attr})
7036                     }
7037                 });
7038                 var xlink = $n.attr("xlink:href");
7039                 if (xlink) {
7040                     var groups = xlink.trim().match(/^#(.+?)$/)
7041                     if (groups) pushAdd(groups[1], {o:that, a:"xlink:href"})
7042                 }
7043             })
7044             // patch used ids and references (keep unreferenced ids fixed (to allow for identification from the editor to the css, even if classes should be preferred))
7045             var newIds = {};
7046             for (id in referencersIds) {
7047                 var newId = svgPatcher.generateId(id);
7048                 byId[id].id = newId;
7049                 newIds[id] = newId;
7050             }
7051
7052             setTimeout( // to help firefox in having updated ids
7053                 (function() {
7054                 for (id in referencersIds) {
7055                     var newId = newIds[id];
7056                     var refs = referencersIds[id];
7057                     $(refs).each(function(i,pair){
7058                         var prev = $(pair.o).attr(pair.a);
7059                         if (pair.a == "xlink:href") {
7060                             pair.o.setAttributeNS($.svg.xlinkNS, "href", prev.replace("#" + id, "#" + newId));
7061                         } else {
7062                             $(pair.o).attr(pair.a, prev.replace("#" + id, "#" + newId));
7063                         }
7064                     })
7065                         }
7066                     andThen();
7067                 }), 0)
7068
7069         }
7070     }
7071
7072
7073     $d.bind('deck.beforeInit', function (event) {
7074         event.lockInit();
7075         var opts = $[deck]('getOptions');
7076         var container = $[deck]('getContainer');
7077
7078         /*
7079           Load parameters from an Object element
7080         */
7081         var loadObjectParams = function(objectElement) {
7082             var attributes = {};
7083             $(objectElement).children("param").each(function(index){
7084                 attributes[$(this).attr("name")] = $(this).attr("value");
7085             });
7086             $.each(objectElement.attributes, function (index, attr) {
7087                 if ("data-" == attr.name.substr(0, 5)) {
7088                     attributes[attr.name.substr(5)] = attr.value;
7089                 }
7090             });
7091             return attributes;
7092         }
7093         
7094         /*
7095           Return true if default params are set.
7096         */
7097         var validateParams = function(params) {
7098             return params['src'];// && params['width'] && params['height'];// && params['animator'];
7099         }
7100         
7101         /*
7102           Create SVG placeholder
7103         */
7104         var createSVG = function(object, attributes) {
7105             var $canvas, $control, $next, $reload, $placeholder;
7106             /* Create svg canvas */
7107             $canvas = $("<div />").attr({
7108                 'id':  $(object).attr('id'),
7109                 'data-src': attributes['src'],
7110                 'class': opts.classes.svgPlaceholder + " " + $(object).attr('class')
7111             }).css({
7112                 'height': attributes['height'],
7113                 'width': attributes['width']
7114             });
7115             return $canvas;
7116         }
7117
7118         
7119         /* Go through all toplevel slides */
7120         $($[deck]('getTopLevelSlides')).each( function(i, $slide) {
7121
7122             /* Find all the object of type deckjs/svg */
7123             $slide.find(opts.selectors.svgObject).each(function(index, obj) {
7124                 /* Load attributes and validate them */
7125                 var attributes = loadObjectParams(obj);
7126                 if (!validateParams(attributes) ) {
7127                     throw "Error while initializing "+$(obj).attr('id')+", please ensure you have setup the required parameters."
7128                     return false;
7129                 }
7130                 
7131                 /* Create SVG placeholder */
7132                 var SVG = createSVG(obj, attributes);
7133                 $(obj).replaceWith(SVG);
7134                 
7135                 // Finaly load the SVG data
7136                 event.lockInit();
7137
7138                 var notDisabled = function(k) {
7139                     var kk = 'no'+k;
7140                     var disabled = (attributes[kk] && attributes[kk] == "true") || $(obj).filter(opts.selectors.svgObjectDisable[k]).length > 0
7141                     return !disabled;
7142                 };
7143
7144                 SVG.svg({
7145                     loadURL: attributes['src'],
7146                     onLoad: function($svg, w, h) {
7147                         var px = function (str) {return str.replace("px", "")}
7148                         var aa = $($svg.root());
7149                         aa.attr('width', '100%');
7150                         aa.attr('height', '100%');
7151                         if (aa.attr('viewBox') == undefined) {
7152                             if (w==undefined || h==undefined) {
7153                                 if (opts.alert.missingSVG) alert(
7154                                     "There seem to be a problem with the loading of\n   '"+attributes['src'] + "'\n"
7155                                         +"\nMaybe the file does not exist?"
7156                                         +"\nOr maybe"
7157                                         +"\n - it has no w or h attribute?"
7158                                         +"\n - you're using a file that is within a symbolic-link folder?"
7159                                         +"\n - you're using chrome with local files?"
7160                                         +"\n   â‡’ try to restart chrome with '--disable-web-security'");
7161                                 event.releaseInit();
7162                             } else {
7163                                 var to = "0 0 " + px(w) + " " + px(h);
7164                                 $svg.root().setAttribute("viewBox", to);
7165                                 aa.attr("svgViewBox", to);
7166                                 if (attributes['stretch'] == 'true') $svg.root().setAttribute('preserveAspectRatio', "none");
7167                                 if (notDisabled('stylerewrite')) {
7168                                     svgPatcher.styleToAttributes($svg.root(), attributes['src']);
7169                                 }
7170                                 if (notDisabled('idrewrite')) {
7171                                     svgPatcher.makeReferencedIdsUnique($svg.root(), attributes['src'], function() {
7172                                         event.releaseInit();
7173                                     });
7174                                 } else {
7175                                     event.releaseInit();
7176                                 }
7177                             }
7178                         }
7179                     }
7180                 });
7181             });
7182         });
7183         event.releaseInit();
7184     })
7185     
7186     
7187 })(jQuery, 'deck');
7188
7189
7190 /*!
7191 Deck JS - deck.metadata
7192 Copyright (c) 2014 RĂ©mi Emonet
7193 Licensed under the MIT license.
7194 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7195 */
7196
7197 /*
7198 This module automatically takes each meta tag (e.g., author, date, ...) and the page title.
7199 It then replaces the content of all elements having a var-... class by the value of the metadata.
7200
7201 This is very useful for example to repeat the date, title, venue name, author name, etc… in a title page, in the footer and in a closing page (without copy pasting).
7202 */
7203
7204 (function($, deck, undefined) {
7205     $.extend(true, $.deck.defaults, {
7206         selectors: {
7207             metadataPrefix: '.var-',
7208             metadataBrSuffix: '-br',
7209             metadataFullSuffix: '-full'
7210         },
7211         metadataSeparator: /(&nbsp;| )/gi   /* we need to handle '&nbsp;' and ' ' because in the title, ' ' becomes '&nbsp;' */
7212     });
7213
7214     var $d = $(document);
7215     $d.bind('deck.init', function() {
7216         var o = $.deck('getOptions');
7217         var app = function(_sel, v) {
7218             var sel = o.selectors.metadataPrefix + _sel;
7219             var sep = o.metadataSeparator;
7220             $(sel).html(v.replace(sep, ""));
7221             $(sel+o.selectors.metadataFullSuffix).html(v);
7222             $(sel+o.selectors.metadataBrSuffix).html(v.replace(sep, "<br/>"));
7223         };
7224         app("title", $("html>head>title").html());
7225         $("html>head>meta[name]").each(function(i,e) {
7226             app($(e).attr('name'), $(e).attr('content'))
7227         });
7228     });
7229 })(jQuery, 'deck');
7230
7231 /*!
7232 Deck JS - deck.attribution
7233 Copyright (c) 2014 RĂ©mi Emonet
7234 Licensed under the MIT license.
7235 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7236 */
7237
7238 /*
7239 This module automatically adds some text and a link for elements having a "data-attribution" attributes.
7240 */
7241
7242 (function($, deck, undefined) {
7243     $.extend(true, $.deck.defaults, {
7244         classes: {
7245             attributionWrapper: 'attribution-wrap',
7246             attributionLink: 'attribution-link'
7247         },
7248         dataAttribution: "data-attribution",
7249         dataAttributionContent: "data-attribution-content",
7250         dataAttributionClass: "data-attribution-class"
7251     });
7252
7253     var $d = $(document);
7254     $d.bind('deck.init', function() {
7255         var o = $.deck('getOptions');
7256         $('*['+o.dataAttribution+']').each(function(i, el){
7257             var c = $(el).attr(o.dataAttributionContent);
7258             var cc = $(el).attr(o.dataAttributionClass);
7259             var a = $(el).attr(o.dataAttribution);
7260             var w = $("<div>");
7261             w.addClass(o.classes.attributionWrapper);
7262             var link = $("<a>");
7263             link.addClass(o.classes.attributionLink);
7264             if (!! cc) link.addClass(cc);
7265             link.attr("href", a);
7266             link.attr("target", "_blank");
7267             if (!! c) {
7268                 link.html(c);
7269             } else {
7270                 link.html(a);
7271             }
7272             $(el).after(w);
7273             $(w).append(link);
7274         });
7275     });
7276 })(jQuery, 'deck');
7277
7278 /*!
7279 Deck JS - deck.container-styling
7280 Copyright (c) 2014 RĂ©mi Emonet
7281 Licensed under the MIT license.
7282 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7283 */
7284
7285 /*
7286 This module automatically adds/removes to the container the class specified in data-container-class (for toplevel slides).
7287
7288 This extension relies on the events extension.
7289 */
7290
7291 (function($, deck, undefined) {
7292     var $d = $(document);
7293     $d.bind('deck.init', function() {
7294         $('*[data-container-class]').each(function(i, el) {
7295             var toRemove = ""; // one 'toRemove' per element (that's why we do .each
7296             $(el).bind('deck.becameCurrent', function(_, direction) {
7297                 var target = $(_.target);
7298                 var toAdd = target.attr('data-container-class');
7299                 $[deck]('getContainer').addClass(toAdd);
7300                 toRemove = toAdd;
7301             }).bind('deck.lostCurrent', function(_, direction) {
7302                 $[deck]('getContainer').removeClass(toRemove);
7303                 toRemove = "";
7304             });
7305         });
7306     });
7307     $(document).bind('deck.init', function() { // force trigger even if no #slide-... is provided
7308         var current = $[deck]('getSlide')
7309         var icur = 0
7310         for (; icur < $[deck]('getSlides').length; icur++) {
7311             if ($[deck]('getSlides')[icur] == current) break;                
7312         }
7313         $(document).trigger("deck.change", [icur, icur]);
7314     });
7315 })(jQuery, 'deck');
7316
7317 /*!
7318 Deck JS - deck.timekeeper
7319 Copyright (c) 2013-2014 RĂ©mi Emonet
7320 Licensed under the MIT license.
7321 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7322 */
7323
7324 /*
7325 This module provides a support for displaying current time, time from start and logging the time spent on each slide etc.
7326 It also injects some default html for it if none is found (and styles it for the presenter/clone view).
7327 */
7328
7329 (function($, deck, undefined) {
7330     var $d = $(document);
7331
7332     $.extend(true, $[deck].defaults, {  
7333         selectors: {
7334             timekeeper: ".timekeeper", /* inject if this is not present */ // TODO inject
7335             timekeeperTime: ".timekeeper-time",
7336             timekeeperRelativeTime: ".timekeeper-relative-time",
7337             timekeeperLocalRelativeTime: ".timekeeper-local-relative-time",
7338             timekeeperLogs: ".timekeeper-logs",
7339             timekeeperLogsPre: ".timekeeper-logs pre",
7340             timekeeperLogsToggle: ".timekeeper-logs-toggle",
7341             timekeeperBang: ".timekeeper-bang",
7342             timekeeperClear: ".timekeeper-clear"
7343         },
7344         classes: {
7345             timekeeperNotification: "timekeeper-notification",
7346             timekeeperLogsVisible: "timekeeper-logs-visible"
7347         },
7348         snippets: {
7349             timekeeper: true
7350         },
7351         alert: {
7352             localStorageUnsupported: true
7353         },
7354         localStorage: {
7355             timekeeperArchivesMaxSize: 500*1000,
7356             timekeeperArchives: 'deckjs-timekeeper-archives',
7357             timekeeperLogs: 'deckjs-timekeeper-logs',
7358             timekeeperBase: 'deckjs-timekeeper-base',
7359             timekeeperLocalBase: 'deckjs-timekeeper-local-base'
7360         },
7361         timekeeperPeriod: 1000,
7362         timekeeperNotificationPeriod: 100,
7363         keys: {
7364             timekeeper: [27, 75] // escape, k (combine with SHIFT to reset the counter (when starting presenting))
7365         }
7366     });
7367
7368     $d.bind('deck.init', function() {
7369         var opts = $[deck]('getOptions');
7370         var container = $[deck]('getContainer');
7371
7372         // sligthly edited from
7373         var selectText = function(text) {
7374             var doc = document
7375             , range, selection
7376             ;
7377             if (doc.body.createTextRange) { //ms
7378                 range = doc.body.createTextRange();
7379                 range.moveToElementText(text);
7380                 range.select();
7381             } else if (window.getSelection) { //all others
7382                 selection = window.getSelection();
7383                 range = doc.createRange();
7384                 range.selectNodeContents(text);
7385                 selection.removeAllRanges();
7386                 selection.addRange(range);
7387             }
7388         }
7389
7390         if (opts.snippets.timekeeper) {
7391             var d = function() {return $('<div/>');}
7392             var divTK = d().addClass("timekeeper timekeeper-logs-toggle");
7393             divTK.append(d().addClass("timekeeper-local-relative-time"));
7394             divTK.append(d().addClass("timekeeper-time"));
7395             divTK.append(d().addClass("timekeeper-relative-time"));
7396             divTK.append(d().addClass("timekeeper-clear"));
7397             divTK.append(d().addClass("timekeeper-bang"));
7398             divTK.appendTo(container);
7399             var divLog = d().addClass("timekeeper-logs");
7400             var pre = $('<pre/>').appendTo(divLog);
7401             divLog.append(d().addClass("button").click(function() { doBang() }).html("Bang!"));
7402             divLog.append(d().addClass("button").click(function() { selectText(pre.get(0)) }).html("select all"));
7403             divLog.append(d().addClass("button").click(function() { clearStorage() }).html("Clear").css({color:'#f44', marginLeft: '2em'}));
7404             divLog.append(d().addClass("button").addClass("timekeeper-logs-toggle").css({position:'float', float:'right', color:'#0f0'}).html("X"));
7405             divLog.appendTo(container);
7406         }
7407
7408         if (!window.localStorage && opts.alert.localStorageUnsupported) { alert(
7409             "LocalStorage is unsupported in your browser, timing features are disabled (timekeeper extension).");
7410             return;
7411         }
7412
7413         var pad = function(base, right) {
7414             var s = ""+right;
7415             if (s.length >= base.length) return s;
7416             else return base.substring(0, base.length - s.length) + s
7417         }
7418         var formatTime = function(t) {
7419             var min = parseInt(t / 1000 / 60);
7420             var sec = parseInt(t / 1000 - 60 * min);
7421             if (min > 60) {
7422                 var hours = parseInt(t / 1000 / 60 / 60);
7423                 min = parseInt(t / 1000 / 60 - 60 * hours);
7424                 return pad("00", hours) +":"+ pad("00", min) + ":" + pad("00", sec)
7425             } else {
7426                 return pad("00", min) + ":" + pad("00", sec)
7427             }
7428         }
7429         var clearStorage = function(what) {
7430             // TODO archive
7431             localStorage.setItem(opts.localStorage.timekeeperLogs, null);
7432             log("CLEARED BY USER");
7433             localStorage.setItem(opts.localStorage.timekeeperBase, JSON.stringify(new Date()));
7434             $(opts.selectors.timekeeperClear).addClass(opts.classes.timekeeperNotification);
7435             setTimeout(function() {
7436                 $(opts.selectors.timekeeperClear).removeClass(opts.classes.timekeeperNotification);
7437             }, opts.timekeeperNotificationPeriod);
7438         }
7439         var reset = function() {
7440             localStorage.setItem(opts.localStorage.timekeeperLocalBase, JSON.stringify(new Date()));
7441         }
7442         var getDateOrSet = function(k, or) {
7443             var res = localStorage.getItem(k);
7444             if (res == null) {
7445                 res = JSON.stringify(or);
7446                 localStorage.setItem(k, res);
7447             } else {
7448                 res = new Date(JSON.parse(res));
7449             }
7450             return res;
7451         }
7452         var log = function(what) {
7453             var now = new Date();
7454             var time = now.toString()
7455             var localBase = getDateOrSet(opts.localStorage.timekeeperLocalBase, now);
7456             var base = getDateOrSet(opts.localStorage.timekeeperBase, now);
7457             var db = (now - localBase)/1000;
7458             var dcb = (now - base)/1000;
7459             var dbtime = formatTime(now - localBase);
7460             var dcbtime = formatTime(now - base);
7461             var log = time.replace(/GMT.*/, "") + " " + what + " " + dcb + " " + db + " " + dcbtime + " " + dbtime;
7462             
7463             var data = localStorage.getItem(opts.localStorage.timekeeperLogs);
7464             data = log + "\n" + data;
7465             localStorage.setItem(opts.localStorage.timekeeperLogs, data);
7466             $(opts.selectors.timekeeperLogsPre).html(data);
7467         }
7468
7469
7470         var saveCurrent = -1;
7471         $(document).bind('deck.change', function(e, from, to) {
7472             log(from + " " + to);
7473             saveCurrent = to;
7474         });
7475         
7476         // Bind key event to add a marker in the logs
7477         var $d = $(document);
7478         var doBang = function() {
7479             log("BANG " + saveCurrent);
7480             $(opts.selectors.timekeeperBang).addClass(opts.classes.timekeeperNotification);
7481             setTimeout(function() {
7482                 $(opts.selectors.timekeeperBang).removeClass(opts.classes.timekeeperNotification);
7483             }, opts.timekeeperNotificationPeriod);
7484             reset();
7485         }
7486         $d.unbind('keydown.logbang').bind('keydown.logbang', function(e) {
7487             if (e.ctrlKey) return;
7488             var K = opts.keys.timekeeper;
7489             if (e.which === K || $.inArray(e.which, K) > -1) {
7490                 doBang();
7491                 if (e.shiftKey) {
7492                     clearStorage();
7493                 }
7494             }
7495         });
7496         $(opts.selectors.timekeeperLogsToggle).unbind('click.timekeeper').bind('click.timekeeper', function(e) {
7497             $(opts.selectors.timekeeperLogs).toggleClass(opts.classes.timekeeperLogsVisible);
7498         });
7499
7500
7501         // Refresh display
7502         var period = opts.timekeeperPeriod;
7503         setInterval(function() {
7504             var today = new Date();
7505             today.setMinutes(0);
7506             today.setHours(0);
7507             today.setSeconds(0);
7508             var now = new Date();
7509             $(opts.selectors.timekeeperTime).html(formatTime(now - today));
7510             var v = localStorage.getItem(opts.localStorage.timekeeperBase);
7511             if (v != null) {
7512                 var t = now - new Date(JSON.parse(v));
7513                 var time = formatTime(t);
7514                 $(opts.selectors.timekeeperRelativeTime).html(time);
7515             }
7516             var v2 = localStorage.getItem(opts.localStorage.timekeeperLocalBase);
7517             if (v2 != null) {
7518                 var t = now - new Date(JSON.parse(v2));
7519                 var time = formatTime(t);
7520                 $(opts.selectors.timekeeperLocalRelativeTime).html(time);
7521             }
7522         }, period);
7523     
7524     });
7525
7526 })(jQuery, 'deck');
7527
7528
7529 (function(global, document) {
7530
7531   // Popcorn.js does not support archaic browsers
7532   if ( !document.addEventListener ) {
7533     global.Popcorn = {
7534       isSupported: false
7535     };
7536
7537     var methods = ( "byId forEach extend effects error guid sizeOf isArray nop position disable enable destroy" +
7538           "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
7539           "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/);
7540
7541     while ( methods.length ) {
7542       global.Popcorn[ methods.shift() ] = function() {};
7543     }
7544     return;
7545   }
7546
7547   var
7548
7549   AP = Array.prototype,
7550   OP = Object.prototype,
7551
7552   forEach = AP.forEach,
7553   slice = AP.slice,
7554   hasOwn = OP.hasOwnProperty,
7555   toString = OP.toString,
7556
7557   // Copy global Popcorn (may not exist)
7558   _Popcorn = global.Popcorn,
7559
7560   //  Ready fn cache
7561   readyStack = [],
7562   readyBound = false,
7563   readyFired = false,
7564
7565   //  Non-public internal data object
7566   internal = {
7567     events: {
7568       hash: {},
7569       apis: {}
7570     }
7571   },
7572
7573   //  Non-public `requestAnimFrame`
7574   //  http://paulirish.com/2011/requestanimationframe-for-smart-animating/
7575   requestAnimFrame = (function(){
7576     return global.requestAnimationFrame ||
7577       global.webkitRequestAnimationFrame ||
7578       global.mozRequestAnimationFrame ||
7579       global.oRequestAnimationFrame ||
7580       global.msRequestAnimationFrame ||
7581       function( callback, element ) {
7582         global.setTimeout( callback, 16 );
7583       };
7584   }()),
7585
7586   //  Non-public `getKeys`, return an object's keys as an array
7587   getKeys = function( obj ) {
7588     return Object.keys ? Object.keys( obj ) : (function( obj ) {
7589       var item,
7590           list = [];
7591
7592       for ( item in obj ) {
7593         if ( hasOwn.call( obj, item ) ) {
7594           list.push( item );
7595         }
7596       }
7597       return list;
7598     })( obj );
7599   },
7600
7601   Abstract = {
7602     // [[Put]] props from dictionary onto |this|
7603     // MUST BE CALLED FROM WITHIN A CONSTRUCTOR:
7604     //  Abstract.put.call( this, dictionary );
7605     put: function( dictionary ) {
7606       // For each own property of src, let key be the property key
7607       // and desc be the property descriptor of the property.
7608       Object.getOwnPropertyNames( dictionary ).forEach(function( key ) {
7609         this[ key ] = dictionary[ key ];
7610       }, this);
7611     }
7612   },
7613
7614
7615   //  Declare constructor
7616   //  Returns an instance object.
7617   Popcorn = function( entity, options ) {
7618     //  Return new Popcorn object
7619     return new Popcorn.p.init( entity, options || null );
7620   };
7621
7622   //  Popcorn API version, automatically inserted via build system.
7623   Popcorn.version = "@VERSION";
7624
7625   //  Boolean flag allowing a client to determine if Popcorn can be supported
7626   Popcorn.isSupported = true;
7627
7628   //  Instance caching
7629   Popcorn.instances = [];
7630
7631   //  Declare a shortcut (Popcorn.p) to and a definition of
7632   //  the new prototype for our Popcorn constructor
7633   Popcorn.p = Popcorn.prototype = {
7634
7635     init: function( entity, options ) {
7636
7637       var matches, nodeName,
7638           self = this;
7639
7640       //  Supports Popcorn(function () { /../ })
7641       //  Originally proposed by Daniel Brooks
7642
7643       if ( typeof entity === "function" ) {
7644
7645         //  If document ready has already fired
7646         if ( document.readyState === "complete" ) {
7647
7648           entity( document, Popcorn );
7649
7650           return;
7651         }
7652         //  Add `entity` fn to ready stack
7653         readyStack.push( entity );
7654
7655         //  This process should happen once per page load
7656         if ( !readyBound ) {
7657
7658           //  set readyBound flag
7659           readyBound = true;
7660
7661           var DOMContentLoaded  = function() {
7662
7663             readyFired = true;
7664
7665             //  Remove global DOM ready listener
7666             document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7667
7668             //  Execute all ready function in the stack
7669             for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) {
7670
7671               readyStack[ i ].call( document, Popcorn );
7672
7673             }
7674             //  GC readyStack
7675             readyStack = null;
7676           };
7677
7678           //  Register global DOM ready listener
7679           document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7680         }
7681
7682         return;
7683       }
7684
7685       if ( typeof entity === "string" ) {
7686         try {
7687           matches = document.querySelector( entity );
7688         } catch( e ) {
7689           throw new Error( "Popcorn.js Error: Invalid media element selector: " + entity );
7690         }
7691       }
7692
7693       //  Get media element by id or object reference
7694       this.media = matches || entity;
7695
7696       //  inner reference to this media element's nodeName string value
7697       nodeName = ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video";
7698
7699       //  Create an audio or video element property reference
7700       this[ nodeName ] = this.media;
7701
7702       this.options = Popcorn.extend( {}, options ) || {};
7703
7704       //  Resolve custom ID or default prefixed ID
7705       this.id = this.options.id || Popcorn.guid( nodeName );
7706
7707       //  Throw if an attempt is made to use an ID that already exists
7708       if ( Popcorn.byId( this.id ) ) {
7709         throw new Error( "Popcorn.js Error: Cannot use duplicate ID (" + this.id + ")" );
7710       }
7711
7712       this.isDestroyed = false;
7713
7714       this.data = {
7715
7716         // data structure of all
7717         running: {
7718           cue: []
7719         },
7720
7721         // Executed by either timeupdate event or in rAF loop
7722         timeUpdate: Popcorn.nop,
7723
7724         // Allows disabling a plugin per instance
7725         disabled: {},
7726
7727         // Stores DOM event queues by type
7728         events: {},
7729
7730         // Stores Special event hooks data
7731         hooks: {},
7732
7733         // Store track event history data
7734         history: [],
7735
7736         // Stores ad-hoc state related data]
7737         state: {
7738           volume: this.media.volume
7739         },
7740
7741         // Store track event object references by trackId
7742         trackRefs: {},
7743
7744         // Playback track event queues
7745         trackEvents: new TrackEvents( this )
7746       };
7747
7748       //  Register new instance
7749       Popcorn.instances.push( this );
7750
7751       //  function to fire when video is ready
7752       var isReady = function() {
7753
7754         // chrome bug: http://code.google.com/p/chromium/issues/detail?id=119598
7755         // it is possible the video's time is less than 0
7756         // this has the potential to call track events more than once, when they should not
7757         // start: 0, end: 1 will start, end, start again, when it should just start
7758         // just setting it to 0 if it is below 0 fixes this issue
7759         if ( self.media.currentTime < 0 ) {
7760
7761           self.media.currentTime = 0;
7762         }
7763
7764         self.media.removeEventListener( "loadedmetadata", isReady, false );
7765
7766         var duration, videoDurationPlus,
7767             runningPlugins, runningPlugin, rpLength, rpNatives;
7768
7769         //  Adding padding to the front and end of the arrays
7770         //  this is so we do not fall off either end
7771         duration = self.media.duration;
7772
7773         //  Check for no duration info (NaN)
7774         videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
7775
7776         Popcorn.addTrackEvent( self, {
7777           start: videoDurationPlus,
7778           end: videoDurationPlus
7779         });
7780
7781         if ( !self.isDestroyed ) {
7782           self.data.durationChange = function() {
7783             var newDuration = self.media.duration,
7784                 newDurationPlus = newDuration + 1,
7785                 byStart = self.data.trackEvents.byStart,
7786                 byEnd = self.data.trackEvents.byEnd;
7787
7788             // Remove old padding events
7789             byStart.pop();
7790             byEnd.pop();
7791
7792             // Remove any internal tracking of events that have end times greater than duration
7793             // otherwise their end events will never be hit.
7794             for ( var k = byEnd.length - 1; k > 0; k-- ) {
7795               if ( byEnd[ k ].end > newDuration ) {
7796                 self.removeTrackEvent( byEnd[ k ]._id );
7797               }
7798             }
7799
7800             // Remove any internal tracking of events that have end times greater than duration
7801             // otherwise their end events will never be hit.
7802             for ( var i = 0; i < byStart.length; i++ ) {
7803               if ( byStart[ i ].end > newDuration ) {
7804                 self.removeTrackEvent( byStart[ i ]._id );
7805               }
7806             }
7807
7808             // References to byEnd/byStart are reset, so accessing it this way is
7809             // forced upon us.
7810             self.data.trackEvents.byEnd.push({
7811               start: newDurationPlus,
7812               end: newDurationPlus
7813             });
7814
7815             self.data.trackEvents.byStart.push({
7816               start: newDurationPlus,
7817               end: newDurationPlus
7818             });
7819           };
7820
7821           // Listen for duration changes and adjust internal tracking of event timings
7822           self.media.addEventListener( "durationchange", self.data.durationChange, false );
7823         }
7824
7825         if ( self.options.frameAnimation ) {
7826
7827           //  if Popcorn is created with frameAnimation option set to true,
7828           //  requestAnimFrame is used instead of "timeupdate" media event.
7829           //  This is for greater frame time accuracy, theoretically up to
7830           //  60 frames per second as opposed to ~4 ( ~every 15-250ms)
7831           self.data.timeUpdate = function () {
7832
7833             Popcorn.timeUpdate( self, {} );
7834
7835             // fire frame for each enabled active plugin of every type
7836             Popcorn.forEach( Popcorn.manifest, function( key, val ) {
7837
7838               runningPlugins = self.data.running[ val ];
7839
7840               // ensure there are running plugins on this type on this instance
7841               if ( runningPlugins ) {
7842
7843                 rpLength = runningPlugins.length;
7844                 for ( var i = 0; i < rpLength; i++ ) {
7845
7846                   runningPlugin = runningPlugins[ i ];
7847                   rpNatives = runningPlugin._natives;
7848                   rpNatives && rpNatives.frame &&
7849                     rpNatives.frame.call( self, {}, runningPlugin, self.currentTime() );
7850                 }
7851               }
7852             });
7853
7854             self.emit( "timeupdate" );
7855
7856             !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7857           };
7858
7859           !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7860
7861         } else {
7862
7863           self.data.timeUpdate = function( event ) {
7864             Popcorn.timeUpdate( self, event );
7865           };
7866
7867           if ( !self.isDestroyed ) {
7868             self.media.addEventListener( "timeupdate", self.data.timeUpdate, false );
7869           }
7870         }
7871       };
7872
7873       Object.defineProperty( this, "error", {
7874         get: function() {
7875
7876           return self.media.error;
7877         }
7878       });
7879
7880       // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-readystate
7881       //
7882       // If media is in readyState (rS) >= 1, we know the media's duration,
7883       // which is required before running the isReady function.
7884       // If rS is 0, attach a listener for "loadedmetadata",
7885       // ( Which indicates that the media has moved from rS 0 to 1 )
7886       //
7887       // This has been changed from a check for rS 2 because
7888       // in certain conditions, Firefox can enter this code after dropping
7889       // to rS 1 from a higher state such as 2 or 3. This caused a "loadeddata"
7890       // listener to be attached to the media object, an event that had
7891       // already triggered and would not trigger again. This left Popcorn with an
7892       // instance that could never start a timeUpdate loop.
7893       if ( self.media.readyState >= 1 ) {
7894
7895         isReady();
7896       } else {
7897
7898         self.media.addEventListener( "loadedmetadata", isReady, false );
7899       }
7900
7901       return this;
7902     }
7903   };
7904
7905   //  Extend constructor prototype to instance prototype
7906   //  Allows chaining methods to instances
7907   Popcorn.p.init.prototype = Popcorn.p;
7908
7909   Popcorn.byId = function( str ) {
7910     var instances = Popcorn.instances,
7911         length = instances.length,
7912         i = 0;
7913
7914     for ( ; i < length; i++ ) {
7915       if ( instances[ i ].id === str ) {
7916         return instances[ i ];
7917       }
7918     }
7919
7920     return null;
7921   };
7922
7923   Popcorn.forEach = function( obj, fn, context ) {
7924
7925     if ( !obj || !fn ) {
7926       return {};
7927     }
7928
7929     context = context || this;
7930
7931     var key, len;
7932
7933     // Use native whenever possible
7934     if ( forEach && obj.forEach === forEach ) {
7935       return obj.forEach( fn, context );
7936     }
7937
7938     if ( toString.call( obj ) === "[object NodeList]" ) {
7939       for ( key = 0, len = obj.length; key < len; key++ ) {
7940         fn.call( context, obj[ key ], key, obj );
7941       }
7942       return obj;
7943     }
7944
7945     for ( key in obj ) {
7946       if ( hasOwn.call( obj, key ) ) {
7947         fn.call( context, obj[ key ], key, obj );
7948       }
7949     }
7950     return obj;
7951   };
7952
7953   Popcorn.extend = function( obj ) {
7954     var dest = obj, src = slice.call( arguments, 1 );
7955
7956     Popcorn.forEach( src, function( copy ) {
7957       for ( var prop in copy ) {
7958         dest[ prop ] = copy[ prop ];
7959       }
7960     });
7961
7962     return dest;
7963   };
7964
7965
7966   // A Few reusable utils, memoized onto Popcorn
7967   Popcorn.extend( Popcorn, {
7968     noConflict: function( deep ) {
7969
7970       if ( deep ) {
7971         global.Popcorn = _Popcorn;
7972       }
7973
7974       return Popcorn;
7975     },
7976     error: function( msg ) {
7977       throw new Error( msg );
7978     },
7979     guid: function( prefix ) {
7980       Popcorn.guid.counter++;
7981       return  ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter );
7982     },
7983     sizeOf: function( obj ) {
7984       var size = 0;
7985
7986       for ( var prop in obj ) {
7987         size++;
7988       }
7989
7990       return size;
7991     },
7992     isArray: Array.isArray || function( array ) {
7993       return toString.call( array ) === "[object Array]";
7994     },
7995
7996     nop: function() {},
7997
7998     position: function( elem ) {
7999
8000       if ( !elem.parentNode ) {
8001         return null;
8002       }
8003
8004       var clientRect = elem.getBoundingClientRect(),
8005           bounds = {},
8006           doc = elem.ownerDocument,
8007           docElem = document.documentElement,
8008           body = document.body,
8009           clientTop, clientLeft, scrollTop, scrollLeft, top, left;
8010
8011       //  Determine correct clientTop/Left
8012       clientTop = docElem.clientTop || body.clientTop || 0;
8013       clientLeft = docElem.clientLeft || body.clientLeft || 0;
8014
8015       //  Determine correct scrollTop/Left
8016       scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop );
8017       scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft );
8018
8019       //  Temp top/left
8020       top = Math.ceil( clientRect.top + scrollTop - clientTop );
8021       left = Math.ceil( clientRect.left + scrollLeft - clientLeft );
8022
8023       for ( var p in clientRect ) {
8024         bounds[ p ] = Math.round( clientRect[ p ] );
8025       }
8026
8027       return Popcorn.extend({}, bounds, { top: top, left: left });
8028     },
8029
8030     disable: function( instance, plugin ) {
8031
8032       if ( instance.data.disabled[ plugin ] ) {
8033         return;
8034       }
8035
8036       instance.data.disabled[ plugin ] = true;
8037
8038       if ( plugin in Popcorn.registryByName &&
8039            instance.data.running[ plugin ] ) {
8040
8041         for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8042
8043           event = instance.data.running[ plugin ][ i ];
8044           event._natives.end.call( instance, null, event  );
8045
8046           instance.emit( "trackend",
8047             Popcorn.extend({}, event, {
8048               plugin: event.type,
8049               type: "trackend"
8050             })
8051           );
8052         }
8053       }
8054
8055       return instance;
8056     },
8057     enable: function( instance, plugin ) {
8058
8059       if ( !instance.data.disabled[ plugin ] ) {
8060         return;
8061       }
8062
8063       instance.data.disabled[ plugin ] = false;
8064
8065       if ( plugin in Popcorn.registryByName &&
8066            instance.data.running[ plugin ] ) {
8067
8068         for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8069
8070           event = instance.data.running[ plugin ][ i ];
8071           event._natives.start.call( instance, null, event  );
8072
8073           instance.emit( "trackstart",
8074             Popcorn.extend({}, event, {
8075               plugin: event.type,
8076               type: "trackstart",
8077               track: event
8078             })
8079           );
8080         }
8081       }
8082
8083       return instance;
8084     },
8085     destroy: function( instance ) {
8086       var events = instance.data.events,
8087           trackEvents = instance.data.trackEvents,
8088           singleEvent, item, fn, plugin;
8089
8090       //  Iterate through all events and remove them
8091       for ( item in events ) {
8092         singleEvent = events[ item ];
8093         for ( fn in singleEvent ) {
8094           delete singleEvent[ fn ];
8095         }
8096         events[ item ] = null;
8097       }
8098
8099       // remove all plugins off the given instance
8100       for ( plugin in Popcorn.registryByName ) {
8101         Popcorn.removePlugin( instance, plugin );
8102       }
8103
8104       // Remove all data.trackEvents #1178
8105       trackEvents.byStart.length = 0;
8106       trackEvents.byEnd.length = 0;
8107
8108       if ( !instance.isDestroyed ) {
8109         instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
8110         instance.isDestroyed = true;
8111       }
8112
8113       Popcorn.instances.splice( Popcorn.instances.indexOf( instance ), 1 );
8114     }
8115   });
8116
8117   //  Memoized GUID Counter
8118   Popcorn.guid.counter = 1;
8119
8120   //  Factory to implement getters, setters and controllers
8121   //  as Popcorn instance methods. The IIFE will create and return
8122   //  an object with defined methods
8123   Popcorn.extend(Popcorn.p, (function() {
8124
8125       var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " +
8126                     "autoplay loop controls muted buffered readyState seeking paused played seekable ended",
8127           ret = {};
8128
8129
8130       //  Build methods, store in object that is returned and passed to extend
8131       Popcorn.forEach( methods.split( /\s+/g ), function( name ) {
8132
8133         ret[ name ] = function( arg ) {
8134           var previous;
8135
8136           if ( typeof this.media[ name ] === "function" ) {
8137
8138             // Support for shorthanded play(n)/pause(n) jump to currentTime
8139             // If arg is not null or undefined and called by one of the
8140             // allowed shorthandable methods, then set the currentTime
8141             // Supports time as seconds or SMPTE
8142             if ( arg != null && /play|pause/.test( name ) ) {
8143               this.media.currentTime = Popcorn.util.toSeconds( arg );
8144             }
8145
8146             this.media[ name ]();
8147
8148             return this;
8149           }
8150
8151           if ( arg != null ) {
8152             // Capture the current value of the attribute property
8153             previous = this.media[ name ];
8154
8155             // Set the attribute property with the new value
8156             this.media[ name ] = arg;
8157
8158             // If the new value is not the same as the old value
8159             // emit an "attrchanged event"
8160             if ( previous !== arg ) {
8161               this.emit( "attrchange", {
8162                 attribute: name,
8163                 previousValue: previous,
8164                 currentValue: arg
8165               });
8166             }
8167             return this;
8168           }
8169
8170           return this.media[ name ];
8171         };
8172       });
8173
8174       return ret;
8175
8176     })()
8177   );
8178
8179   Popcorn.forEach( "enable disable".split(" "), function( method ) {
8180     Popcorn.p[ method ] = function( plugin ) {
8181       return Popcorn[ method ]( this, plugin );
8182     };
8183   });
8184
8185   Popcorn.extend(Popcorn.p, {
8186
8187     //  Rounded currentTime
8188     roundTime: function() {
8189       return Math.round( this.media.currentTime );
8190     },
8191
8192     //  Attach an event to a single point in time
8193     exec: function( id, time, fn ) {
8194       var length = arguments.length,
8195           eventType = "trackadded",
8196           trackEvent, sec, options;
8197
8198       // Check if first could possibly be a SMPTE string
8199       // p.cue( "smpte string", fn );
8200       // try/catch avoid awful throw in Popcorn.util.toSeconds
8201       // TODO: Get rid of that, replace with NaN return?
8202       try {
8203         sec = Popcorn.util.toSeconds( id );
8204       } catch ( e ) {}
8205
8206       // If it can be converted into a number then
8207       // it's safe to assume that the string was SMPTE
8208       if ( typeof sec === "number" ) {
8209         id = sec;
8210       }
8211
8212       // Shift arguments based on use case
8213       //
8214       // Back compat for:
8215       // p.cue( time, fn );
8216       if ( typeof id === "number" && length === 2 ) {
8217         fn = time;
8218         time = id;
8219         id = Popcorn.guid( "cue" );
8220       } else {
8221         // Support for new forms
8222
8223         // p.cue( "empty-cue" );
8224         if ( length === 1 ) {
8225           // Set a time for an empty cue. It's not important what
8226           // the time actually is, because the cue is a no-op
8227           time = -1;
8228
8229         } else {
8230
8231           // Get the TrackEvent that matches the given id.
8232           trackEvent = this.getTrackEvent( id );
8233
8234           if ( trackEvent ) {
8235
8236             // remove existing cue so a new one can be added via trackEvents.add
8237             this.data.trackEvents.remove( id );
8238             TrackEvent.end( this, trackEvent );
8239             // Update track event references
8240             Popcorn.removeTrackEvent.ref( this, id );
8241
8242             eventType = "cuechange";
8243
8244             // p.cue( "my-id", 12 );
8245             // p.cue( "my-id", function() { ... });
8246             if ( typeof id === "string" && length === 2 ) {
8247
8248               // p.cue( "my-id", 12 );
8249               // The path will update the cue time.
8250               if ( typeof time === "number" ) {
8251                 // Re-use existing TrackEvent start callback
8252                 fn = trackEvent._natives.start;
8253               }
8254
8255               // p.cue( "my-id", function() { ... });
8256               // The path will update the cue function
8257               if ( typeof time === "function" ) {
8258                 fn = time;
8259                 // Re-use existing TrackEvent start time
8260                 time = trackEvent.start;
8261               }
8262             }
8263           } else {
8264
8265             if ( length >= 2 ) {
8266
8267               // p.cue( "a", "00:00:00");
8268               if ( typeof time === "string" ) {
8269                 try {
8270                   sec = Popcorn.util.toSeconds( time );
8271                 } catch ( e ) {}
8272
8273                 time = sec;
8274               }
8275
8276               // p.cue( "b", 11 );
8277               // p.cue( "b", 11, function() {} );
8278               if ( typeof time === "number" ) {
8279                 fn = fn || Popcorn.nop();
8280               }
8281
8282               // p.cue( "c", function() {});
8283               if ( typeof time === "function" ) {
8284                 fn = time;
8285                 time = -1;
8286               }
8287             }
8288           }
8289         }
8290       }
8291
8292       options = {
8293         id: id,
8294         start: time,
8295         end: time + 1,
8296         _running: false,
8297         _natives: {
8298           start: fn || Popcorn.nop,
8299           end: Popcorn.nop,
8300           type: "cue"
8301         }
8302       };
8303
8304       if ( trackEvent ) {
8305         options = Popcorn.extend( trackEvent, options );
8306       }
8307
8308       if ( eventType === "cuechange" ) {
8309
8310         //  Supports user defined track event id
8311         options._id = options.id || options._id || Popcorn.guid( options._natives.type );
8312
8313         this.data.trackEvents.add( options );
8314         TrackEvent.start( this, options );
8315
8316         this.timeUpdate( this, null, true );
8317
8318         // Store references to user added trackevents in ref table
8319         Popcorn.addTrackEvent.ref( this, options );
8320
8321         this.emit( eventType, Popcorn.extend({}, options, {
8322           id: id,
8323           type: eventType,
8324           previousValue: {
8325             time: trackEvent.start,
8326             fn: trackEvent._natives.start
8327           },
8328           currentValue: {
8329             time: time,
8330             fn: fn || Popcorn.nop
8331           },
8332           track: trackEvent
8333         }));
8334       } else {
8335         //  Creating a one second track event with an empty end
8336         Popcorn.addTrackEvent( this, options );
8337       }
8338
8339       return this;
8340     },
8341
8342     // Mute the calling media, optionally toggle
8343     mute: function( toggle ) {
8344
8345       var event = toggle == null || toggle === true ? "muted" : "unmuted";
8346
8347       // If `toggle` is explicitly `false`,
8348       // unmute the media and restore the volume level
8349       if ( event === "unmuted" ) {
8350         this.media.muted = false;
8351         this.media.volume = this.data.state.volume;
8352       }
8353
8354       // If `toggle` is either null or undefined,
8355       // save the current volume and mute the media element
8356       if ( event === "muted" ) {
8357         this.data.state.volume = this.media.volume;
8358         this.media.muted = true;
8359       }
8360
8361       // Trigger either muted|unmuted event
8362       this.emit( event );
8363
8364       return this;
8365     },
8366
8367     // Convenience method, unmute the calling media
8368     unmute: function( toggle ) {
8369
8370       return this.mute( toggle == null ? false : !toggle );
8371     },
8372
8373     // Get the client bounding box of an instance element
8374     position: function() {
8375       return Popcorn.position( this.media );
8376     },
8377
8378     // Toggle a plugin's playback behaviour (on or off) per instance
8379     toggle: function( plugin ) {
8380       return Popcorn[ this.data.disabled[ plugin ] ? "enable" : "disable" ]( this, plugin );
8381     },
8382
8383     // Set default values for plugin options objects per instance
8384     defaults: function( plugin, defaults ) {
8385
8386       // If an array of default configurations is provided,
8387       // iterate and apply each to this instance
8388       if ( Popcorn.isArray( plugin ) ) {
8389
8390         Popcorn.forEach( plugin, function( obj ) {
8391           for ( var name in obj ) {
8392             this.defaults( name, obj[ name ] );
8393           }
8394         }, this );
8395
8396         return this;
8397       }
8398
8399       if ( !this.options.defaults ) {
8400         this.options.defaults = {};
8401       }
8402
8403       if ( !this.options.defaults[ plugin ] ) {
8404         this.options.defaults[ plugin ] = {};
8405       }
8406
8407       Popcorn.extend( this.options.defaults[ plugin ], defaults );
8408
8409       return this;
8410     }
8411   });
8412
8413   Popcorn.Events  = {
8414     UIEvents: "blur focus focusin focusout load resize scroll unload",
8415     MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",
8416     Events: "loadstart progress suspend emptied stalled play pause error " +
8417             "loadedmetadata loadeddata waiting playing canplay canplaythrough " +
8418             "seeking seeked timeupdate ended ratechange durationchange volumechange"
8419   };
8420
8421   Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " +
8422                            Popcorn.Events.MouseEvents + " " +
8423                            Popcorn.Events.Events;
8424
8425   internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ];
8426
8427   // Privately compile events table at load time
8428   (function( events, data ) {
8429
8430     var apis = internal.events.apiTypes,
8431     eventsList = events.Natives.split( /\s+/g ),
8432     idx = 0, len = eventsList.length, prop;
8433
8434     for( ; idx < len; idx++ ) {
8435       data.hash[ eventsList[idx] ] = true;
8436     }
8437
8438     apis.forEach(function( val, idx ) {
8439
8440       data.apis[ val ] = {};
8441
8442       var apiEvents = events[ val ].split( /\s+/g ),
8443       len = apiEvents.length,
8444       k = 0;
8445
8446       for ( ; k < len; k++ ) {
8447         data.apis[ val ][ apiEvents[ k ] ] = true;
8448       }
8449     });
8450   })( Popcorn.Events, internal.events );
8451
8452   Popcorn.events = {
8453
8454     isNative: function( type ) {
8455       return !!internal.events.hash[ type ];
8456     },
8457     getInterface: function( type ) {
8458
8459       if ( !Popcorn.events.isNative( type ) ) {
8460         return false;
8461       }
8462
8463       var eventApi = internal.events,
8464         apis = eventApi.apiTypes,
8465         apihash = eventApi.apis,
8466         idx = 0, len = apis.length, api, tmp;
8467
8468       for ( ; idx < len; idx++ ) {
8469         tmp = apis[ idx ];
8470
8471         if ( apihash[ tmp ][ type ] ) {
8472           api = tmp;
8473           break;
8474         }
8475       }
8476       return api;
8477     },
8478     //  Compile all native events to single array
8479     all: Popcorn.Events.Natives.split( /\s+/g ),
8480     //  Defines all Event handling static functions
8481     fn: {
8482       trigger: function( type, data ) {
8483         var eventInterface, evt, clonedEvents,
8484             events = this.data.events[ type ];
8485
8486         //  setup checks for custom event system
8487         if ( events ) {
8488           eventInterface  = Popcorn.events.getInterface( type );
8489
8490           if ( eventInterface ) {
8491             evt = document.createEvent( eventInterface );
8492             evt.initEvent( type, true, true, global, 1 );
8493
8494             this.media.dispatchEvent( evt );
8495
8496             return this;
8497           }
8498
8499           // clone events in case callbacks remove callbacks themselves
8500           clonedEvents = events.slice();
8501
8502           // iterate through all callbacks
8503           while ( clonedEvents.length ) {
8504             clonedEvents.shift().call( this, data );
8505           }
8506         }
8507
8508         return this;
8509       },
8510       listen: function( type, fn ) {
8511         var self = this,
8512             hasEvents = true,
8513             eventHook = Popcorn.events.hooks[ type ],
8514             origType = type,
8515             clonedEvents,
8516             tmp;
8517
8518         if ( typeof fn !== "function" ) {
8519           throw new Error( "Popcorn.js Error: Listener is not a function" );
8520         }
8521
8522         // Setup event registry entry
8523         if ( !this.data.events[ type ] ) {
8524           this.data.events[ type ] = [];
8525           // Toggle if the previous assumption was untrue
8526           hasEvents = false;
8527         }
8528
8529         // Check and setup event hooks
8530         if ( eventHook ) {
8531           // Execute hook add method if defined
8532           if ( eventHook.add ) {
8533             eventHook.add.call( this, {}, fn );
8534           }
8535
8536           // Reassign event type to our piggyback event type if defined
8537           if ( eventHook.bind ) {
8538             type = eventHook.bind;
8539           }
8540
8541           // Reassign handler if defined
8542           if ( eventHook.handler ) {
8543             tmp = fn;
8544
8545             fn = function wrapper( event ) {
8546               eventHook.handler.call( self, event, tmp );
8547             };
8548           }
8549
8550           // assume the piggy back event is registered
8551           hasEvents = true;
8552
8553           // Setup event registry entry
8554           if ( !this.data.events[ type ] ) {
8555             this.data.events[ type ] = [];
8556             // Toggle if the previous assumption was untrue
8557             hasEvents = false;
8558           }
8559         }
8560
8561         //  Register event and handler
8562         this.data.events[ type ].push( fn );
8563
8564         // only attach one event of any type
8565         if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
8566           this.media.addEventListener( type, function( event ) {
8567             if ( self.data.events[ type ] ) {
8568               // clone events in case callbacks remove callbacks themselves
8569               clonedEvents = self.data.events[ type ].slice();
8570
8571               // iterate through all callbacks
8572               while ( clonedEvents.length ) {
8573                 clonedEvents.shift().call( self, event );
8574               }
8575             }
8576           }, false );
8577         }
8578         return this;
8579       },
8580       unlisten: function( type, fn ) {
8581         var ind,
8582             events = this.data.events[ type ];
8583
8584         if ( !events ) {
8585           return; // no listeners = nothing to do
8586         }
8587
8588         if ( typeof fn === "string" ) {
8589           // legacy support for string-based removal -- not recommended
8590           for ( var i = 0; i < events.length; i++ ) {
8591             if ( events[ i ].name === fn ) {
8592               // decrement i because array length just got smaller
8593               events.splice( i--, 1 );
8594             }
8595           }
8596
8597           return this;
8598         } else if ( typeof fn === "function" ) {
8599           while( ind !== -1 ) {
8600             ind = events.indexOf( fn );
8601             if ( ind !== -1 ) {
8602               events.splice( ind, 1 );
8603             }
8604           }
8605
8606           return this;
8607         }
8608
8609         // if we got to this point, we are deleting all functions of this type
8610         this.data.events[ type ] = null;
8611
8612         return this;
8613       }
8614     },
8615     hooks: {
8616       canplayall: {
8617         bind: "canplaythrough",
8618         add: function( event, callback ) {
8619
8620           var state = false;
8621
8622           if ( this.media.readyState ) {
8623
8624             // always call canplayall asynchronously
8625             setTimeout(function() {
8626               callback.call( this, event );
8627             }.bind(this), 0 );
8628
8629             state = true;
8630           }
8631
8632           this.data.hooks.canplayall = {
8633             fired: state
8634           };
8635         },
8636         // declare special handling instructions
8637         handler: function canplayall( event, callback ) {
8638
8639           if ( !this.data.hooks.canplayall.fired ) {
8640             // trigger original user callback once
8641             callback.call( this, event );
8642
8643             this.data.hooks.canplayall.fired = true;
8644           }
8645         }
8646       }
8647     }
8648   };
8649
8650   //  Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
8651   //  Extend aliases (on, off, emit)
8652   Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) {
8653     Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
8654   });
8655
8656   // Internal Only - construct simple "TrackEvent"
8657   // data type objects
8658   function TrackEvent( track ) {
8659     Abstract.put.call( this, track );
8660   }
8661
8662   // Determine if a TrackEvent's "start" and "trackstart" must be called.
8663   TrackEvent.start = function( instance, track ) {
8664
8665     if ( track.end > instance.media.currentTime &&
8666         track.start <= instance.media.currentTime && !track._running ) {
8667
8668       track._running = true;
8669       instance.data.running[ track._natives.type ].push( track );
8670
8671       if ( !instance.data.disabled[ track._natives.type ] ) {
8672
8673         track._natives.start.call( instance, null, track );
8674
8675         instance.emit( "trackstart",
8676           Popcorn.extend( {}, track, {
8677             plugin: track._natives.type,
8678             type: "trackstart",
8679             track: track
8680           })
8681         );
8682       }
8683     }
8684   };
8685
8686   // Determine if a TrackEvent's "end" and "trackend" must be called.
8687   TrackEvent.end = function( instance, track ) {
8688
8689     var runningPlugins;
8690
8691     if ( ( track.end <= instance.media.currentTime ||
8692         track.start > instance.media.currentTime ) && track._running ) {
8693
8694       runningPlugins = instance.data.running[ track._natives.type ];
8695
8696       track._running = false;
8697       runningPlugins.splice( runningPlugins.indexOf( track ), 1 );
8698
8699       if ( !instance.data.disabled[ track._natives.type ] ) {
8700
8701         track._natives.end.call( instance, null, track );
8702
8703         instance.emit( "trackend",
8704           Popcorn.extend( {}, track, {
8705             plugin: track._natives.type,
8706             type: "trackend",
8707             track: track
8708           })
8709         );
8710       }
8711     }
8712   };
8713
8714   // Internal Only - construct "TrackEvents"
8715   // data type objects that are used by the Popcorn
8716   // instance, stored at p.data.trackEvents
8717   function TrackEvents( parent ) {
8718     this.parent = parent;
8719
8720     this.byStart = [{
8721       start: -1,
8722       end: -1
8723     }];
8724
8725     this.byEnd = [{
8726       start: -1,
8727       end: -1
8728     }];
8729     this.animating = [];
8730     this.startIndex = 0;
8731     this.endIndex = 0;
8732     this.previousUpdateTime = -1;
8733
8734     Object.defineProperty( this, "count", {
8735       get: function() {
8736         return this.byStart.length;
8737       }
8738     });
8739   }
8740
8741   function isMatch( obj, key, value ) {
8742     return obj[ key ] && obj[ key ] === value;
8743   }
8744
8745   TrackEvents.prototype.where = function( params ) {
8746     return ( this.parent.getTrackEvents() || [] ).filter(function( event ) {
8747       var key, value;
8748
8749       // If no explicit params, match all TrackEvents
8750       if ( !params ) {
8751         return true;
8752       }
8753
8754       // Filter keys in params against both the top level properties
8755       // and the _natives properties
8756       for ( key in params ) {
8757         value = params[ key ];
8758         if ( isMatch( event, key, value ) || isMatch( event._natives, key, value ) ) {
8759           return true;
8760         }
8761       }
8762       return false;
8763     });
8764   };
8765
8766   TrackEvents.prototype.add = function( track ) {
8767
8768     //  Store this definition in an array sorted by times
8769     var byStart = this.byStart,
8770         byEnd = this.byEnd,
8771         startIndex, endIndex;
8772
8773     //  Push track event ids into the history
8774     if ( track && track._id ) {
8775       this.parent.data.history.push( track._id );
8776     }
8777
8778     track.start = Popcorn.util.toSeconds( track.start, this.parent.options.framerate );
8779     track.end   = Popcorn.util.toSeconds( track.end, this.parent.options.framerate );
8780
8781     for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
8782
8783       if ( track.start >= byStart[ startIndex ].start ) {
8784         byStart.splice( startIndex + 1, 0, track );
8785         break;
8786       }
8787     }
8788
8789     for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) {
8790
8791       if ( track.end > byEnd[ endIndex ].end ) {
8792         byEnd.splice( endIndex + 1, 0, track );
8793         break;
8794       }
8795     }
8796
8797     // update startIndex and endIndex
8798     if ( startIndex <= this.parent.data.trackEvents.startIndex &&
8799       track.start <= this.parent.data.trackEvents.previousUpdateTime ) {
8800
8801       this.parent.data.trackEvents.startIndex++;
8802     }
8803
8804     if ( endIndex <= this.parent.data.trackEvents.endIndex &&
8805       track.end < this.parent.data.trackEvents.previousUpdateTime ) {
8806
8807       this.parent.data.trackEvents.endIndex++;
8808     }
8809
8810   };
8811
8812   TrackEvents.prototype.remove = function( removeId, state ) {
8813
8814     if ( removeId instanceof TrackEvent ) {
8815       removeId = removeId.id;
8816     }
8817
8818     if ( typeof removeId === "object" ) {
8819       // Filter by key=val and remove all matching TrackEvents
8820       this.where( removeId ).forEach(function( event ) {
8821         // |this| refers to the calling Popcorn "parent" instance
8822         this.removeTrackEvent( event._id );
8823       }, this.parent );
8824
8825       return this;
8826     }
8827
8828     var start, end, animate, historyLen, track,
8829         length = this.byStart.length,
8830         index = 0,
8831         indexWasAt = 0,
8832         byStart = [],
8833         byEnd = [],
8834         animating = [],
8835         history = [],
8836         comparable = {};
8837
8838     state = state || {};
8839
8840     while ( --length > -1 ) {
8841       start = this.byStart[ index ];
8842       end = this.byEnd[ index ];
8843
8844       // Padding events will not have _id properties.
8845       // These should be safely pushed onto the front and back of the
8846       // track event array
8847       if ( !start._id ) {
8848         byStart.push( start );
8849         byEnd.push( end );
8850       }
8851
8852       // Filter for user track events (vs system track events)
8853       if ( start._id ) {
8854
8855         // If not a matching start event for removal
8856         if ( start._id !== removeId ) {
8857           byStart.push( start );
8858         }
8859
8860         // If not a matching end event for removal
8861         if ( end._id !== removeId ) {
8862           byEnd.push( end );
8863         }
8864
8865         // If the _id is matched, capture the current index
8866         if ( start._id === removeId ) {
8867           indexWasAt = index;
8868
8869           // cache the track event being removed
8870           track = start;
8871         }
8872       }
8873       // Increment the track index
8874       index++;
8875     }
8876
8877     // Reset length to be used by the condition below to determine
8878     // if animating track events should also be filtered for removal.
8879     // Reset index below to be used by the reverse while as an
8880     // incrementing counter
8881     length = this.animating.length;
8882     index = 0;
8883
8884     if ( length ) {
8885       while ( --length > -1 ) {
8886         animate = this.animating[ index ];
8887
8888         // Padding events will not have _id properties.
8889         // These should be safely pushed onto the front and back of the
8890         // track event array
8891         if ( !animate._id ) {
8892           animating.push( animate );
8893         }
8894
8895         // If not a matching animate event for removal
8896         if ( animate._id && animate._id !== removeId ) {
8897           animating.push( animate );
8898         }
8899         // Increment the track index
8900         index++;
8901       }
8902     }
8903
8904     //  Update
8905     if ( indexWasAt <= this.startIndex ) {
8906       this.startIndex--;
8907     }
8908
8909     if ( indexWasAt <= this.endIndex ) {
8910       this.endIndex--;
8911     }
8912
8913     this.byStart = byStart;
8914     this.byEnd = byEnd;
8915     this.animating = animating;
8916
8917     historyLen = this.parent.data.history.length;
8918
8919     for ( var i = 0; i < historyLen; i++ ) {
8920       if ( this.parent.data.history[ i ] !== removeId ) {
8921         history.push( this.parent.data.history[ i ] );
8922       }
8923     }
8924
8925     // Update ordered history array
8926     this.parent.data.history = history;
8927
8928   };
8929
8930   // Helper function used to retrieve old values of properties that
8931   // are provided for update.
8932   function getPreviousProperties( oldOptions, newOptions ) {
8933     var matchProps = {};
8934
8935     for ( var prop in oldOptions ) {
8936       if ( hasOwn.call( newOptions, prop ) && hasOwn.call( oldOptions, prop ) ) {
8937         matchProps[ prop ] = oldOptions[ prop ];
8938       }
8939     }
8940
8941     return matchProps;
8942   }
8943
8944   // Internal Only - Adds track events to the instance object
8945   Popcorn.addTrackEvent = function( obj, track ) {
8946     var temp;
8947
8948     if ( track instanceof TrackEvent ) {
8949       return;
8950     }
8951
8952     track = new TrackEvent( track );
8953
8954     // Determine if this track has default options set for it
8955     // If so, apply them to the track object
8956     if ( track && track._natives && track._natives.type &&
8957         ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
8958
8959       // To ensure that the TrackEvent Invariant Policy is enforced,
8960       // First, copy the properties of the newly created track event event
8961       // to a temporary holder
8962       temp = Popcorn.extend( {}, track );
8963
8964       // Next, copy the default onto the newly created trackevent, followed by the
8965       // temporary holder.
8966       Popcorn.extend( track, obj.options.defaults[ track._natives.type ], temp );
8967     }
8968
8969     if ( track._natives ) {
8970       //  Supports user defined track event id
8971       track._id = track.id || track._id || Popcorn.guid( track._natives.type );
8972
8973       // Trigger _setup method if exists
8974       if ( track._natives._setup ) {
8975
8976         track._natives._setup.call( obj, track );
8977
8978         obj.emit( "tracksetup", Popcorn.extend( {}, track, {
8979           plugin: track._natives.type,
8980           type: "tracksetup",
8981           track: track
8982         }));
8983       }
8984     }
8985
8986     obj.data.trackEvents.add( track );
8987     TrackEvent.start( obj, track );
8988
8989     this.timeUpdate( obj, null, true );
8990
8991     // Store references to user added trackevents in ref table
8992     if ( track._id ) {
8993       Popcorn.addTrackEvent.ref( obj, track );
8994     }
8995
8996     obj.emit( "trackadded", Popcorn.extend({}, track,
8997       track._natives ? { plugin: track._natives.type } : {}, {
8998         type: "trackadded",
8999         track: track
9000     }));
9001   };
9002
9003   // Internal Only - Adds track event references to the instance object's trackRefs hash table
9004   Popcorn.addTrackEvent.ref = function( obj, track ) {
9005     obj.data.trackRefs[ track._id ] = track;
9006
9007     return obj;
9008   };
9009
9010   Popcorn.removeTrackEvent = function( obj, removeId ) {
9011     var track = obj.getTrackEvent( removeId );
9012
9013     if ( !track ) {
9014       return;
9015     }
9016
9017     // If a _teardown function was defined,
9018     // enforce for track event removals
9019     if ( track._natives._teardown ) {
9020       track._natives._teardown.call( obj, track );
9021     }
9022
9023     obj.data.trackEvents.remove( removeId );
9024
9025     // Update track event references
9026     Popcorn.removeTrackEvent.ref( obj, removeId );
9027
9028     if ( track._natives ) {
9029
9030       // Fire a trackremoved event
9031       obj.emit( "trackremoved", Popcorn.extend({}, track, {
9032         plugin: track._natives.type,
9033         type: "trackremoved",
9034         track: track
9035       }));
9036     }
9037   };
9038
9039   // Internal Only - Removes track event references from instance object's trackRefs hash table
9040   Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
9041     delete obj.data.trackRefs[ removeId ];
9042
9043     return obj;
9044   };
9045
9046   // Return an array of track events bound to this instance object
9047   Popcorn.getTrackEvents = function( obj ) {
9048
9049     var trackevents = [],
9050       refs = obj.data.trackEvents.byStart,
9051       length = refs.length,
9052       idx = 0,
9053       ref;
9054
9055     for ( ; idx < length; idx++ ) {
9056       ref = refs[ idx ];
9057       // Return only user attributed track event references
9058       if ( ref._id ) {
9059         trackevents.push( ref );
9060       }
9061     }
9062
9063     return trackevents;
9064   };
9065
9066   // Internal Only - Returns an instance object's trackRefs hash table
9067   Popcorn.getTrackEvents.ref = function( obj ) {
9068     return obj.data.trackRefs;
9069   };
9070
9071   // Return a single track event bound to this instance object
9072   Popcorn.getTrackEvent = function( obj, trackId ) {
9073     return obj.data.trackRefs[ trackId ];
9074   };
9075
9076   // Internal Only - Returns an instance object's track reference by track id
9077   Popcorn.getTrackEvent.ref = function( obj, trackId ) {
9078     return obj.data.trackRefs[ trackId ];
9079   };
9080
9081   Popcorn.getLastTrackEventId = function( obj ) {
9082     return obj.data.history[ obj.data.history.length - 1 ];
9083   };
9084
9085   Popcorn.timeUpdate = function( obj, event ) {
9086     var currentTime = obj.media.currentTime,
9087         previousTime = obj.data.trackEvents.previousUpdateTime,
9088         tracks = obj.data.trackEvents,
9089         end = tracks.endIndex,
9090         start = tracks.startIndex,
9091         byStartLen = tracks.byStart.length,
9092         byEndLen = tracks.byEnd.length,
9093         registryByName = Popcorn.registryByName,
9094         trackstart = "trackstart",
9095         trackend = "trackend",
9096
9097         byEnd, byStart, byAnimate, natives, type, runningPlugins;
9098
9099     //  Playbar advancing
9100     if ( previousTime <= currentTime ) {
9101
9102       while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) {
9103
9104         byEnd = tracks.byEnd[ end ];
9105         natives = byEnd._natives;
9106         type = natives && natives.type;
9107
9108         //  If plugin does not exist on this instance, remove it
9109         if ( !natives ||
9110             ( !!registryByName[ type ] ||
9111               !!obj[ type ] ) ) {
9112
9113           if ( byEnd._running === true ) {
9114
9115             byEnd._running = false;
9116             runningPlugins = obj.data.running[ type ];
9117             runningPlugins.splice( runningPlugins.indexOf( byEnd ), 1 );
9118
9119             if ( !obj.data.disabled[ type ] ) {
9120
9121               natives.end.call( obj, event, byEnd );
9122
9123               obj.emit( trackend,
9124                 Popcorn.extend({}, byEnd, {
9125                   plugin: type,
9126                   type: trackend,
9127                   track: byEnd
9128                 })
9129               );
9130             }
9131           }
9132
9133           end++;
9134         } else {
9135           // remove track event
9136           Popcorn.removeTrackEvent( obj, byEnd._id );
9137           return;
9138         }
9139       }
9140
9141       while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) {
9142
9143         byStart = tracks.byStart[ start ];
9144         natives = byStart._natives;
9145         type = natives && natives.type;
9146         //  If plugin does not exist on this instance, remove it
9147         if ( !natives ||
9148             ( !!registryByName[ type ] ||
9149               !!obj[ type ] ) ) {
9150           if ( byStart.end > currentTime &&
9151                 byStart._running === false ) {
9152
9153             byStart._running = true;
9154             obj.data.running[ type ].push( byStart );
9155
9156             if ( !obj.data.disabled[ type ] ) {
9157
9158               natives.start.call( obj, event, byStart );
9159
9160               obj.emit( trackstart,
9161                 Popcorn.extend({}, byStart, {
9162                   plugin: type,
9163                   type: trackstart,
9164                   track: byStart
9165                 })
9166               );
9167             }
9168           }
9169           start++;
9170         } else {
9171           // remove track event
9172           Popcorn.removeTrackEvent( obj, byStart._id );
9173           return;
9174         }
9175       }
9176
9177     // Playbar receding
9178     } else if ( previousTime > currentTime ) {
9179
9180       while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) {
9181
9182         byStart = tracks.byStart[ start ];
9183         natives = byStart._natives;
9184         type = natives && natives.type;
9185
9186         // if plugin does not exist on this instance, remove it
9187         if ( !natives ||
9188             ( !!registryByName[ type ] ||
9189               !!obj[ type ] ) ) {
9190
9191           if ( byStart._running === true ) {
9192
9193             byStart._running = false;
9194             runningPlugins = obj.data.running[ type ];
9195             runningPlugins.splice( runningPlugins.indexOf( byStart ), 1 );
9196
9197             if ( !obj.data.disabled[ type ] ) {
9198
9199               natives.end.call( obj, event, byStart );
9200
9201               obj.emit( trackend,
9202                 Popcorn.extend({}, byStart, {
9203                   plugin: type,
9204                   type: trackend,
9205                   track: byStart
9206                 })
9207               );
9208             }
9209           }
9210           start--;
9211         } else {
9212           // remove track event
9213           Popcorn.removeTrackEvent( obj, byStart._id );
9214           return;
9215         }
9216       }
9217
9218       while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) {
9219
9220         byEnd = tracks.byEnd[ end ];
9221         natives = byEnd._natives;
9222         type = natives && natives.type;
9223
9224         // if plugin does not exist on this instance, remove it
9225         if ( !natives ||
9226             ( !!registryByName[ type ] ||
9227               !!obj[ type ] ) ) {
9228
9229           if ( byEnd.start <= currentTime &&
9230                 byEnd._running === false ) {
9231
9232             byEnd._running = true;
9233             obj.data.running[ type ].push( byEnd );
9234
9235             if ( !obj.data.disabled[ type ] ) {
9236
9237               natives.start.call( obj, event, byEnd );
9238
9239               obj.emit( trackstart,
9240                 Popcorn.extend({}, byEnd, {
9241                   plugin: type,
9242                   type: trackstart,
9243                   track: byEnd
9244                 })
9245               );
9246             }
9247           }
9248           end--;
9249         } else {
9250           // remove track event
9251           Popcorn.removeTrackEvent( obj, byEnd._id );
9252           return;
9253         }
9254       }
9255     }
9256
9257     tracks.endIndex = end;
9258     tracks.startIndex = start;
9259     tracks.previousUpdateTime = currentTime;
9260
9261     //enforce index integrity if trackRemoved
9262     tracks.byStart.length < byStartLen && tracks.startIndex--;
9263     tracks.byEnd.length < byEndLen && tracks.endIndex--;
9264
9265   };
9266
9267   //  Map and Extend TrackEvent functions to all Popcorn instances
9268   Popcorn.extend( Popcorn.p, {
9269
9270     getTrackEvents: function() {
9271       return Popcorn.getTrackEvents.call( null, this );
9272     },
9273
9274     getTrackEvent: function( id ) {
9275       return Popcorn.getTrackEvent.call( null, this, id );
9276     },
9277
9278     getLastTrackEventId: function() {
9279       return Popcorn.getLastTrackEventId.call( null, this );
9280     },
9281
9282     removeTrackEvent: function( id ) {
9283
9284       Popcorn.removeTrackEvent.call( null, this, id );
9285       return this;
9286     },
9287
9288     removePlugin: function( name ) {
9289       Popcorn.removePlugin.call( null, this, name );
9290       return this;
9291     },
9292
9293     timeUpdate: function( event ) {
9294       Popcorn.timeUpdate.call( null, this, event );
9295       return this;
9296     },
9297
9298     destroy: function() {
9299       Popcorn.destroy.call( null, this );
9300       return this;
9301     }
9302   });
9303
9304   //  Plugin manifests
9305   Popcorn.manifest = {};
9306   //  Plugins are registered
9307   Popcorn.registry = [];
9308   Popcorn.registryByName = {};
9309   //  An interface for extending Popcorn
9310   //  with plugin functionality
9311   Popcorn.plugin = function( name, definition, manifest ) {
9312
9313     if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9314       Popcorn.error( "'" + name + "' is a protected function name" );
9315       return;
9316     }
9317
9318     //  Provides some sugar, but ultimately extends
9319     //  the definition into Popcorn.p
9320     var isfn = typeof definition === "function",
9321         blacklist = [ "start", "end", "type", "manifest" ],
9322         methods = [ "_setup", "_teardown", "start", "end", "frame" ],
9323         plugin = {},
9324         setup;
9325
9326     // combines calls of two function calls into one
9327     var combineFn = function( first, second ) {
9328
9329       first = first || Popcorn.nop;
9330       second = second || Popcorn.nop;
9331
9332       return function() {
9333         first.apply( this, arguments );
9334         second.apply( this, arguments );
9335       };
9336     };
9337
9338     //  If `manifest` arg is undefined, check for manifest within the `definition` object
9339     //  If no `definition.manifest`, an empty object is a sufficient fallback
9340     Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9341
9342     // apply safe, and empty default functions
9343     methods.forEach(function( method ) {
9344       definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name );
9345     });
9346
9347     var pluginFn = function( setup, options ) {
9348
9349       if ( !options ) {
9350         return this;
9351       }
9352
9353       // When the "ranges" property is set and its value is an array, short-circuit
9354       // the pluginFn definition to recall itself with an options object generated from
9355       // each range object in the ranges array. (eg. { start: 15, end: 16 } )
9356       if ( options.ranges && Popcorn.isArray(options.ranges) ) {
9357         Popcorn.forEach( options.ranges, function( range ) {
9358           // Create a fresh object, extend with current options
9359           // and start/end range object's properties
9360           // Works with in/out as well.
9361           var opts = Popcorn.extend( {}, options, range );
9362
9363           // Remove the ranges property to prevent infinitely
9364           // entering this condition
9365           delete opts.ranges;
9366
9367           // Call the plugin with the newly created opts object
9368           this[ name ]( opts );
9369         }, this);
9370
9371         // Return the Popcorn instance to avoid creating an empty track event
9372         return this;
9373       }
9374
9375       //  Storing the plugin natives
9376       var natives = options._natives = {},
9377           compose = "",
9378           originalOpts, manifestOpts;
9379
9380       Popcorn.extend( natives, setup );
9381
9382       options._natives.type = options._natives.plugin = name;
9383       options._running = false;
9384
9385       natives.start = natives.start || natives[ "in" ];
9386       natives.end = natives.end || natives[ "out" ];
9387
9388       if ( options.once ) {
9389         natives.end = combineFn( natives.end, function() {
9390           this.removeTrackEvent( options._id );
9391         });
9392       }
9393
9394       // extend teardown to always call end if running
9395       natives._teardown = combineFn(function() {
9396
9397         var args = slice.call( arguments ),
9398             runningPlugins = this.data.running[ natives.type ];
9399
9400         // end function signature is not the same as teardown,
9401         // put null on the front of arguments for the event parameter
9402         args.unshift( null );
9403
9404         // only call end if event is running
9405         args[ 1 ]._running &&
9406           runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) &&
9407           natives.end.apply( this, args );
9408
9409         args[ 1 ]._running = false;
9410         this.emit( "trackend",
9411           Popcorn.extend( {}, options, {
9412             plugin: natives.type,
9413             type: "trackend",
9414             track: Popcorn.getTrackEvent( this, options.id || options._id )
9415           })
9416         );
9417       }, natives._teardown );
9418
9419       // extend teardown to always trigger trackteardown after teardown
9420       natives._teardown = combineFn( natives._teardown, function() {
9421
9422         this.emit( "trackteardown", Popcorn.extend( {}, options, {
9423           plugin: name,
9424           type: "trackteardown",
9425           track: Popcorn.getTrackEvent( this, options.id || options._id )
9426         }));
9427       });
9428
9429       // default to an empty string if no effect exists
9430       // split string into an array of effects
9431       options.compose = options.compose || [];
9432       if ( typeof options.compose === "string" ) {
9433         options.compose = options.compose.split( " " );
9434       }
9435       options.effect = options.effect || [];
9436       if ( typeof options.effect === "string" ) {
9437         options.effect = options.effect.split( " " );
9438       }
9439
9440       // join the two arrays together
9441       options.compose = options.compose.concat( options.effect );
9442
9443       options.compose.forEach(function( composeOption ) {
9444
9445         // if the requested compose is garbage, throw it away
9446         compose = Popcorn.compositions[ composeOption ] || {};
9447
9448         // extends previous functions with compose function
9449         methods.forEach(function( method ) {
9450           natives[ method ] = combineFn( natives[ method ], compose[ method ] );
9451         });
9452       });
9453
9454       //  Ensure a manifest object, an empty object is a sufficient fallback
9455       options._natives.manifest = manifest;
9456
9457       //  Checks for expected properties
9458       if ( !( "start" in options ) ) {
9459         options.start = options[ "in" ] || 0;
9460       }
9461
9462       if ( !options.end && options.end !== 0 ) {
9463         options.end = options[ "out" ] || Number.MAX_VALUE;
9464       }
9465
9466       // Use hasOwn to detect non-inherited toString, since all
9467       // objects will receive a toString - its otherwise undetectable
9468       if ( !hasOwn.call( options, "toString" ) ) {
9469         options.toString = function() {
9470           var props = [
9471             "start: " + options.start,
9472             "end: " + options.end,
9473             "id: " + (options.id || options._id)
9474           ];
9475
9476           // Matches null and undefined, allows: false, 0, "" and truthy
9477           if ( options.target != null ) {
9478             props.push( "target: " + options.target );
9479           }
9480
9481           return name + " ( " + props.join(", ") + " )";
9482         };
9483       }
9484
9485       // Resolves 239, 241, 242
9486       if ( !options.target ) {
9487
9488         //  Sometimes the manifest may be missing entirely
9489         //  or it has an options object that doesn't have a `target` property
9490         manifestOpts = "options" in manifest && manifest.options;
9491
9492         options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
9493       }
9494
9495       if ( !options._id && options._natives ) {
9496         // ensure an initial id is there before setup is called
9497         options._id = Popcorn.guid( options._natives.type );
9498       }
9499
9500       if ( options instanceof TrackEvent ) {
9501
9502         if ( options._natives ) {
9503           //  Supports user defined track event id
9504           options._id = options.id || options._id || Popcorn.guid( options._natives.type );
9505
9506           // Trigger _setup method if exists
9507           if ( options._natives._setup ) {
9508
9509             options._natives._setup.call( this, options );
9510
9511             this.emit( "tracksetup", Popcorn.extend( {}, options, {
9512               plugin: options._natives.type,
9513               type: "tracksetup",
9514               track: options
9515             }));
9516           }
9517         }
9518
9519         this.data.trackEvents.add( options );
9520         TrackEvent.start( this, options );
9521
9522         this.timeUpdate( this, null, true );
9523
9524         // Store references to user added trackevents in ref table
9525         if ( options._id ) {
9526           Popcorn.addTrackEvent.ref( this, options );
9527         }
9528       } else {
9529         // Create new track event for this instance
9530         Popcorn.addTrackEvent( this, options );
9531       }
9532
9533       //  Future support for plugin event definitions
9534       //  for all of the native events
9535       Popcorn.forEach( setup, function( callback, type ) {
9536         // Don't attempt to create events for certain properties:
9537         // "start", "end", "type", "manifest". Fixes #1365
9538         if ( blacklist.indexOf( type ) === -1 ) {
9539           this.on( type, callback );
9540         }
9541       }, this );
9542
9543       return this;
9544     };
9545
9546     //  Extend Popcorn.p with new named definition
9547     //  Assign new named definition
9548     Popcorn.p[ name ] = plugin[ name ] = function( id, options ) {
9549       var length = arguments.length,
9550           trackEvent, defaults, mergedSetupOpts, previousOpts, newOpts;
9551
9552       // Shift arguments based on use case
9553       //
9554       // Back compat for:
9555       // p.plugin( options );
9556       if ( id && !options ) {
9557         options = id;
9558         id = null;
9559       } else {
9560
9561         // Get the trackEvent that matches the given id.
9562         trackEvent = this.getTrackEvent( id );
9563
9564         // If the track event does not exist, ensure that the options
9565         // object has a proper id
9566         if ( !trackEvent ) {
9567           options.id = id;
9568
9569         // If the track event does exist, merge the updated properties
9570         } else {
9571
9572           newOpts = options;
9573           previousOpts = getPreviousProperties( trackEvent, newOpts );
9574
9575           // Call the plugins defined update method if provided. Allows for
9576           // custom defined updating for a track event to be defined by the plugin author
9577           if ( trackEvent._natives._update ) {
9578
9579             this.data.trackEvents.remove( trackEvent );
9580
9581             // It's safe to say that the intent of Start/End will never change
9582             // Update them first before calling update
9583             if ( hasOwn.call( options, "start" ) ) {
9584               trackEvent.start = options.start;
9585             }
9586
9587             if ( hasOwn.call( options, "end" ) ) {
9588               trackEvent.end = options.end;
9589             }
9590
9591             TrackEvent.end( this, trackEvent );
9592
9593             if ( isfn ) {
9594               definition.call( this, trackEvent );
9595             }
9596
9597             trackEvent._natives._update.call( this, trackEvent, options );
9598
9599             this.data.trackEvents.add( trackEvent );
9600             TrackEvent.start( this, trackEvent );
9601           } else {
9602             // This branch is taken when there is no explicitly defined
9603             // _update method for a plugin. Which will occur either explicitly or
9604             // as a result of the plugin definition being a function that _returns_
9605             // a definition object.
9606             //
9607             // In either case, this path can ONLY be reached for TrackEvents that
9608             // already exist.
9609
9610             // Directly update the TrackEvent instance.
9611             // This supports TrackEvent invariant enforcement.
9612             Popcorn.extend( trackEvent, options );
9613
9614             this.data.trackEvents.remove( id );
9615
9616             // If a _teardown function was defined,
9617             // enforce for track event removals
9618             if ( trackEvent._natives._teardown ) {
9619               trackEvent._natives._teardown.call( this, trackEvent );
9620             }
9621
9622             // Update track event references
9623             Popcorn.removeTrackEvent.ref( this, id );
9624
9625             if ( isfn ) {
9626               pluginFn.call( this, definition.call( this, trackEvent ), trackEvent );
9627             } else {
9628
9629               //  Supports user defined track event id
9630               trackEvent._id = trackEvent.id || trackEvent._id || Popcorn.guid( trackEvent._natives.type );
9631
9632               if ( trackEvent._natives && trackEvent._natives._setup ) {
9633
9634                 trackEvent._natives._setup.call( this, trackEvent );
9635
9636                 this.emit( "tracksetup", Popcorn.extend( {}, trackEvent, {
9637                   plugin: trackEvent._natives.type,
9638                   type: "tracksetup",
9639                   track: trackEvent
9640                 }));
9641               }
9642
9643               this.data.trackEvents.add( trackEvent );
9644               TrackEvent.start( this, trackEvent );
9645
9646               this.timeUpdate( this, null, true );
9647
9648               // Store references to user added trackevents in ref table
9649               Popcorn.addTrackEvent.ref( this, trackEvent );
9650             }
9651
9652             // Fire an event with change information
9653             this.emit( "trackchange", {
9654               id: trackEvent.id,
9655               type: "trackchange",
9656               previousValue: previousOpts,
9657               currentValue: trackEvent,
9658               track: trackEvent
9659             });
9660
9661             return this;
9662           }
9663
9664           if ( trackEvent._natives.type !== "cue" ) {
9665             // Fire an event with change information
9666             this.emit( "trackchange", {
9667               id: trackEvent.id,
9668               type: "trackchange",
9669               previousValue: previousOpts,
9670               currentValue: newOpts,
9671               track: trackEvent
9672             });
9673           }
9674
9675           return this;
9676         }
9677       }
9678
9679       this.data.running[ name ] = this.data.running[ name ] || [];
9680
9681       // Merge with defaults if they exist, make sure per call is prioritized
9682       defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {};
9683       mergedSetupOpts = Popcorn.extend( {}, defaults, options );
9684
9685       pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
9686                                   mergedSetupOpts );
9687
9688       return this;
9689     };
9690
9691     // if the manifest parameter exists we should extend it onto the definition object
9692     // so that it shows up when calling Popcorn.registry and Popcorn.registryByName
9693     if ( manifest ) {
9694       Popcorn.extend( definition, {
9695         manifest: manifest
9696       });
9697     }
9698
9699     //  Push into the registry
9700     var entry = {
9701       fn: plugin[ name ],
9702       definition: definition,
9703       base: definition,
9704       parents: [],
9705       name: name
9706     };
9707     Popcorn.registry.push(
9708        Popcorn.extend( plugin, entry, {
9709         type: name
9710       })
9711     );
9712     Popcorn.registryByName[ name ] = entry;
9713
9714     return plugin;
9715   };
9716
9717   // Storage for plugin function errors
9718   Popcorn.plugin.errors = [];
9719
9720   // Returns wrapped plugin function
9721   function safeTry( fn, pluginName ) {
9722     return function() {
9723
9724       //  When Popcorn.plugin.debug is true, do not suppress errors
9725       if ( Popcorn.plugin.debug ) {
9726         return fn.apply( this, arguments );
9727       }
9728
9729       try {
9730         return fn.apply( this, arguments );
9731       } catch ( ex ) {
9732
9733         // Push plugin function errors into logging queue
9734         Popcorn.plugin.errors.push({
9735           plugin: pluginName,
9736           thrown: ex,
9737           source: fn.toString()
9738         });
9739
9740         // Trigger an error that the instance can listen for
9741         // and react to
9742         this.emit( "pluginerror", Popcorn.plugin.errors );
9743       }
9744     };
9745   }
9746
9747   // Debug-mode flag for plugin development
9748   // True for Popcorn development versions, false for stable/tagged versions
9749   Popcorn.plugin.debug = ( Popcorn.version === "@" + "VERSION" );
9750
9751   //  removePlugin( type ) removes all tracks of that from all instances of popcorn
9752   //  removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn
9753   Popcorn.removePlugin = function( obj, name ) {
9754
9755     //  Check if we are removing plugin from an instance or from all of Popcorn
9756     if ( !name ) {
9757
9758       //  Fix the order
9759       name = obj;
9760       obj = Popcorn.p;
9761
9762       if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9763         Popcorn.error( "'" + name + "' is a protected function name" );
9764         return;
9765       }
9766
9767       var registryLen = Popcorn.registry.length,
9768           registryIdx;
9769
9770       // remove plugin reference from registry
9771       for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) {
9772         if ( Popcorn.registry[ registryIdx ].name === name ) {
9773           Popcorn.registry.splice( registryIdx, 1 );
9774           delete Popcorn.registryByName[ name ];
9775           delete Popcorn.manifest[ name ];
9776
9777           // delete the plugin
9778           delete obj[ name ];
9779
9780           // plugin found and removed, stop checking, we are done
9781           return;
9782         }
9783       }
9784
9785     }
9786
9787     var byStart = obj.data.trackEvents.byStart,
9788         byEnd = obj.data.trackEvents.byEnd,
9789         animating = obj.data.trackEvents.animating,
9790         idx, sl;
9791
9792     // remove all trackEvents
9793     for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
9794
9795       if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) {
9796
9797         byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
9798
9799         byStart.splice( idx, 1 );
9800
9801         // update for loop if something removed, but keep checking
9802         idx--; sl--;
9803         if ( obj.data.trackEvents.startIndex <= idx ) {
9804           obj.data.trackEvents.startIndex--;
9805           obj.data.trackEvents.endIndex--;
9806         }
9807       }
9808
9809       // clean any remaining references in the end index
9810       // we do this seperate from the above check because they might not be in the same order
9811       if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) {
9812
9813         byEnd.splice( idx, 1 );
9814       }
9815     }
9816
9817     //remove all animating events
9818     for ( idx = 0, sl = animating.length; idx < sl; idx++ ) {
9819
9820       if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) {
9821
9822         animating.splice( idx, 1 );
9823
9824         // update for loop if something removed, but keep checking
9825         idx--; sl--;
9826       }
9827     }
9828
9829   };
9830
9831   Popcorn.compositions = {};
9832
9833   //  Plugin inheritance
9834   Popcorn.compose = function( name, definition, manifest ) {
9835
9836     //  If `manifest` arg is undefined, check for manifest within the `definition` object
9837     //  If no `definition.manifest`, an empty object is a sufficient fallback
9838     Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9839
9840     // register the effect by name
9841     Popcorn.compositions[ name ] = definition;
9842   };
9843
9844   Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
9845
9846   var rnaiveExpr = /^(?:\.|#|\[)/;
9847
9848   //  Basic DOM utilities and helpers API. See #1037
9849   Popcorn.dom = {
9850     debug: false,
9851     //  Popcorn.dom.find( selector, context )
9852     //
9853     //  Returns the first element that matches the specified selector
9854     //  Optionally provide a context element, defaults to `document`
9855     //
9856     //  eg.
9857     //  Popcorn.dom.find("video") returns the first video element
9858     //  Popcorn.dom.find("#foo") returns the first element with `id="foo"`
9859     //  Popcorn.dom.find("foo") returns the first element with `id="foo"`
9860     //     Note: Popcorn.dom.find("foo") is the only allowed deviation
9861     //           from valid querySelector selector syntax
9862     //
9863     //  Popcorn.dom.find(".baz") returns the first element with `class="baz"`
9864     //  Popcorn.dom.find("[preload]") returns the first element with `preload="..."`
9865     //  ...
9866     //  See https://developer.mozilla.org/En/DOM/Document.querySelector
9867     //
9868     //
9869     find: function( selector, context ) {
9870       var node = null;
9871
9872       //  Default context is the `document`
9873       context = context || document;
9874
9875       if ( selector ) {
9876
9877         //  If the selector does not begin with "#", "." or "[",
9878         //  it could be either a nodeName or ID w/o "#"
9879         if ( !rnaiveExpr.test( selector ) ) {
9880
9881           //  Try finding an element that matches by ID first
9882           node = document.getElementById( selector );
9883
9884           //  If a match was found by ID, return the element
9885           if ( node !== null ) {
9886             return node;
9887           }
9888         }
9889         //  Assume no elements have been found yet
9890         //  Catch any invalid selector syntax errors and bury them.
9891         try {
9892           node = context.querySelector( selector );
9893         } catch ( e ) {
9894           if ( Popcorn.dom.debug ) {
9895             throw new Error(e);
9896           }
9897         }
9898       }
9899       return node;
9900     }
9901   };
9902
9903   //  Cache references to reused RegExps
9904   var rparams = /\?/,
9905   //  XHR Setup object
9906   setup = {
9907     ajax: null,
9908     url: "",
9909     data: "",
9910     dataType: "",
9911     success: Popcorn.nop,
9912     type: "GET",
9913     async: true,
9914     contentType: "application/x-www-form-urlencoded; charset=UTF-8"
9915   };
9916
9917   Popcorn.xhr = function( options ) {
9918     var settings;
9919
9920     options.dataType = options.dataType && options.dataType.toLowerCase() || null;
9921
9922     if ( options.dataType &&
9923          ( options.dataType === "jsonp" || options.dataType === "script" ) ) {
9924
9925       Popcorn.xhr.getJSONP(
9926         options.url,
9927         options.success,
9928         options.dataType === "script"
9929       );
9930       return;
9931     }
9932
9933     //  Merge the "setup" defaults and custom "options"
9934     //  into a new plain object.
9935     settings = Popcorn.extend( {}, setup, options );
9936
9937     //  Create new XMLHttpRequest object
9938     settings.ajax = new XMLHttpRequest();
9939
9940     if ( settings.ajax ) {
9941
9942       if ( settings.type === "GET" && settings.data ) {
9943
9944         //  append query string
9945         settings.url += ( rparams.test( settings.url ) ? "&" : "?" ) + settings.data;
9946
9947         //  Garbage collect and reset settings.data
9948         settings.data = null;
9949       }
9950
9951       //  Open the request
9952       settings.ajax.open( settings.type, settings.url, settings.async );
9953
9954       //  For POST, set the content-type request header
9955       if ( settings.type === "POST" ) {
9956         settings.ajax.setRequestHeader(
9957           "Content-Type", settings.contentType
9958         );
9959       }
9960
9961       settings.ajax.send( settings.data || null );
9962
9963       return Popcorn.xhr.httpData( settings );
9964     }
9965   };
9966
9967
9968   Popcorn.xhr.httpData = function( settings ) {
9969
9970     var data, json = null,
9971         parser, xml = null;
9972
9973     settings.ajax.onreadystatechange = function() {
9974
9975       if ( settings.ajax.readyState === 4 ) {
9976
9977         try {
9978           json = JSON.parse( settings.ajax.responseText );
9979         } catch( e ) {
9980           //suppress
9981         }
9982
9983         data = {
9984           xml: settings.ajax.responseXML,
9985           text: settings.ajax.responseText,
9986           json: json
9987         };
9988
9989         // Normalize: data.xml is non-null in IE9 regardless of if response is valid xml
9990         if ( !data.xml || !data.xml.documentElement ) {
9991           data.xml = null;
9992
9993           try {
9994             parser = new DOMParser();
9995             xml = parser.parseFromString( settings.ajax.responseText, "text/xml" );
9996
9997             if ( !xml.getElementsByTagName( "parsererror" ).length ) {
9998               data.xml = xml;
9999             }
10000           } catch ( e ) {
10001             // data.xml remains null
10002           }
10003         }
10004
10005         //  If a dataType was specified, return that type of data
10006         if ( settings.dataType ) {
10007           data = data[ settings.dataType ];
10008         }
10009
10010
10011         settings.success.call( settings.ajax, data );
10012
10013       }
10014     };
10015     return data;
10016   };
10017
10018   Popcorn.xhr.getJSONP = function( url, success, isScript ) {
10019
10020     var head = document.head || document.getElementsByTagName( "head" )[ 0 ] || document.documentElement,
10021       script = document.createElement( "script" ),
10022       isFired = false,
10023       params = [],
10024       rjsonp = /(=)\?(?=&|$)|\?\?/,
10025       replaceInUrl, prefix, paramStr, callback, callparam;
10026
10027     if ( !isScript ) {
10028
10029       // is there a calback already in the url
10030       callparam = url.match( /(callback=[^&]*)/ );
10031
10032       if ( callparam !== null && callparam.length ) {
10033
10034         prefix = callparam[ 1 ].split( "=" )[ 1 ];
10035
10036         // Since we need to support developer specified callbacks
10037         // and placeholders in harmony, make sure matches to "callback="
10038         // aren't just placeholders.
10039         // We coded ourselves into a corner here.
10040         // JSONP callbacks should never have been
10041         // allowed to have developer specified callbacks
10042         if ( prefix === "?" ) {
10043           prefix = "jsonp";
10044         }
10045
10046         // get the callback name
10047         callback = Popcorn.guid( prefix );
10048
10049         // replace existing callback name with unique callback name
10050         url = url.replace( /(callback=[^&]*)/, "callback=" + callback );
10051       } else {
10052
10053         callback = Popcorn.guid( "jsonp" );
10054
10055         if ( rjsonp.test( url ) ) {
10056           url = url.replace( rjsonp, "$1" + callback );
10057         }
10058
10059         // split on first question mark,
10060         // this is to capture the query string
10061         params = url.split( /\?(.+)?/ );
10062
10063         // rebuild url with callback
10064         url = params[ 0 ] + "?";
10065         if ( params[ 1 ] ) {
10066           url += params[ 1 ] + "&";
10067         }
10068         url += "callback=" + callback;
10069       }
10070
10071       //  Define the JSONP success callback globally
10072       window[ callback ] = function( data ) {
10073         // Fire success callbacks
10074         success && success( data );
10075         isFired = true;
10076       };
10077     }
10078
10079     script.addEventListener( "load",  function() {
10080
10081       //  Handling remote script loading callbacks
10082       if ( isScript ) {
10083         //  getScript
10084         success && success();
10085       }
10086
10087       //  Executing for JSONP requests
10088       if ( isFired ) {
10089         //  Garbage collect the callback
10090         delete window[ callback ];
10091       }
10092       //  Garbage collect the script resource
10093       head.removeChild( script );
10094     }, false );
10095
10096     script.addEventListener( "error",  function( e ) {
10097       //  Handling remote script loading callbacks
10098       success && success( { error: e } );
10099
10100       //  Executing for JSONP requests
10101       if ( !isScript ) {
10102         //  Garbage collect the callback
10103         delete window[ callback ];
10104       }
10105       //  Garbage collect the script resource
10106       head.removeChild( script );
10107     }, false );
10108
10109     script.src = url;
10110     head.insertBefore( script, head.firstChild );
10111
10112     return;
10113   };
10114
10115   Popcorn.getJSONP = Popcorn.xhr.getJSONP;
10116
10117   Popcorn.getScript = Popcorn.xhr.getScript = function( url, success ) {
10118
10119     return Popcorn.xhr.getJSONP( url, success, true );
10120   };
10121
10122   Popcorn.util = {
10123     // Simple function to parse a timestamp into seconds
10124     // Acceptable formats are:
10125     // HH:MM:SS.MMM
10126     // HH:MM:SS;FF
10127     // Hours and minutes are optional. They default to 0
10128     toSeconds: function( timeStr, framerate ) {
10129       // Hours and minutes are optional
10130       // Seconds must be specified
10131       // Seconds can be followed by milliseconds OR by the frame information
10132       var validTimeFormat = /^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,
10133           errorMessage = "Invalid time format",
10134           digitPairs, lastIndex, lastPair, firstPair,
10135           frameInfo, frameTime;
10136
10137       if ( typeof timeStr === "number" ) {
10138         return timeStr;
10139       }
10140
10141       if ( typeof timeStr === "string" &&
10142             !validTimeFormat.test( timeStr ) ) {
10143         Popcorn.error( errorMessage );
10144       }
10145
10146       digitPairs = timeStr.split( ":" );
10147       lastIndex = digitPairs.length - 1;
10148       lastPair = digitPairs[ lastIndex ];
10149
10150       // Fix last element:
10151       if ( lastPair.indexOf( ";" ) > -1 ) {
10152
10153         frameInfo = lastPair.split( ";" );
10154         frameTime = 0;
10155
10156         if ( framerate && ( typeof framerate === "number" ) ) {
10157           frameTime = parseFloat( frameInfo[ 1 ], 10 ) / framerate;
10158         }
10159
10160         digitPairs[ lastIndex ] = parseInt( frameInfo[ 0 ], 10 ) + frameTime;
10161       }
10162
10163       firstPair = digitPairs[ 0 ];
10164
10165       return {
10166
10167         1: parseFloat( firstPair, 10 ),
10168
10169         2: ( parseInt( firstPair, 10 ) * 60 ) +
10170               parseFloat( digitPairs[ 1 ], 10 ),
10171
10172         3: ( parseInt( firstPair, 10 ) * 3600 ) +
10173             ( parseInt( digitPairs[ 1 ], 10 ) * 60 ) +
10174               parseFloat( digitPairs[ 2 ], 10 )
10175
10176       }[ digitPairs.length || 1 ];
10177     }
10178   };
10179
10180   // alias for exec function
10181   Popcorn.p.cue = Popcorn.p.exec;
10182
10183   //  Protected API methods
10184   Popcorn.protect = {
10185     natives: getKeys( Popcorn.p ).map(function( val ) {
10186       return val.toLowerCase();
10187     })
10188   };
10189
10190   // Setup logging for deprecated methods
10191   Popcorn.forEach({
10192     // Deprecated: Recommended
10193     "listen": "on",
10194     "unlisten": "off",
10195     "trigger": "emit",
10196     "exec": "cue"
10197
10198   }, function( recommend, api ) {
10199     var original = Popcorn.p[ api ];
10200     // Override the deprecated api method with a method of the same name
10201     // that logs a warning and defers to the new recommended method
10202     Popcorn.p[ api ] = function() {
10203       if ( typeof console !== "undefined" && console.warn ) {
10204         console.warn(
10205           "Deprecated method '" + api + "', " +
10206           (recommend == null ? "do not use." : "use '" + recommend + "' instead." )
10207         );
10208
10209         // Restore api after first warning
10210         Popcorn.p[ api ] = original;
10211       }
10212       return Popcorn.p[ recommend ].apply( this, [].slice.call( arguments ) );
10213     };
10214   });
10215
10216
10217   //  Exposes Popcorn to global context
10218   global.Popcorn = Popcorn;
10219
10220 })(window, window.document);
10221
10222 (function (global, document, $, deck, window, undefined) {
10223
10224
10225     function maybeAddSnippet(audioDataFile, options, andThen) {
10226         if (options.snippets.browsercast) {
10227             if ($(options.selectors.browsercast).size() > 0 && options.alert.goto) {
10228                 alert("'options.snippets.browsercast' is true but a "+options.selectors.browsercast+" has been found."
10229                       +"\nThis might cause interaction glitches."
10230                       +"\n"
10231                       +"\nSuggestion: remove your html snippet or pass the {snippets: {browsercast: false}} option."
10232                      );
10233             }
10234             var ext = audioDataFile.replace(/.*[.]([^.]*)/, '$1');
10235             $('<div/>').addClass('browsercast')
10236                 .append($('<audio/>').addClass("browsercast-audio")
10237                         .append($('<source/>').attr('src', audioDataFile).attr('type', 'audio/'+ext)))
10238                 .append($('<menu/>').append($('<button/>').addClass('playpause')))
10239                 .append($('<div/>').addClass('browsercast-markers')
10240                         .append($('<div/>').addClass('browsercast-time-label').text('1:00')))
10241                 .appendTo($.deck('getContainer'));
10242         }
10243     }
10244
10245     var $document = $(document);
10246
10247     function togglePlay(popcorn) {
10248         if (popcorn.paused() === true) {
10249             popcorn.play()
10250         } else {
10251             popcorn.pause()
10252         }
10253     }
10254
10255     function timeString(nSeconds) {
10256         return new Date(null, null, null, null, null, nSeconds)
10257             .toTimeString()
10258             .replace(/ .*$/, '')
10259             .replace(/^00:/, '');
10260     }
10261
10262     function updatePlayPauseClass(paused, that, ifPlay, ifPause) {
10263         if (paused == true) {
10264             $(that).removeClass(ifPlay);
10265             $(that).addClass(ifPause);
10266         } else {
10267             $(that).removeClass(ifPause);
10268             $(that).addClass(ifPlay);
10269         }
10270     }
10271
10272     // Use the audio timeupdates to drive existing slides.
10273     function playBrowserCast(timings, options) {
10274         var audio, popcorn, markers, bc;
10275         var divs = {};
10276         var nTimings = Object.keys(timings).length;
10277         var defaultWidth = (100./nTimings)+'%';
10278
10279         var forEachTiming = function(f) {
10280             Object.keys(timings)
10281                 .sort(function(a, b) {return a - b;})
10282                 .forEach(f);
10283         };
10284
10285         var inited = false; // to avoid the audio setting the current slide to 0 at the beginning (and allow bookmarking)
10286
10287         bc = $(options.selectors.browsercast).get(0);
10288         audio = $(options.selectors.browsercastAudio).get(0);
10289         markers = $(options.selectors.browsercastMarkers).get(0);
10290         popcorn = Popcorn(audio);
10291
10292         $('.playpause', bc).click(function() {
10293             togglePlay(popcorn);
10294         });
10295
10296         forEachTiming(function(k, i) {
10297             var div = document.createElement('div');
10298             div.className = 'browsercast-cue';
10299             div.onclick = function(event) {
10300                 popcorn.currentTime(timings[k]);
10301             };
10302             $(div)
10303                 .css('width', defaultWidth)
10304                 .css('box-sizing', 'border-box');
10305             markers.appendChild(div);
10306             divs[k] = div;
10307             popcorn.cue(k, timings[k], function () {
10308                 if (!inited) return;
10309                 transitionLock = true;
10310                 $.deck('go', parseInt(k));
10311                 $('.active', markers).removeClass('active');
10312                 $(div).addClass('active');
10313                 transitionLock = false;
10314             });
10315         });
10316         var trySetCueLengthAndPlay = function(retries, delay) {
10317             if (retries <= 0) { return; }
10318             var totalDuration = popcorn.duration();
10319             if (totalDuration > 0) { // it tests also for NaN
10320                 var kPrev;
10321                 forEachTiming(function(k, i) {
10322                     if (i != 0) {
10323                         var pc = 100 * (timings[k] - timings[kPrev]) / totalDuration;
10324                         $(divs[kPrev]).css('width', pc+'%');
10325                     }
10326                     kPrev = k;
10327                 });
10328                 var pc = 100 * (totalDuration - timings[kPrev]) / totalDuration;
10329                 $(divs[kPrev]).css('width', pc+'%');
10330                 // Start the 'cast!
10331                 inited = true;
10332                 var currentSlideIndex = $.deck('getSlides').indexOf($.deck('getSlide'));
10333                 setTimeout(function() { // delay initialization for popcorn to be properly inited
10334                     $.deck('go', currentSlideIndex);
10335                 }, 1);
10336             } else {
10337                 setTimeout(function() {
10338                     trySetCueLengthAndPlay(retries - 1, delay*1.5);
10339                 }, delay);
10340             }
10341         }
10342
10343         // lock for preventing slidechanged event handler during timeupdate handler.
10344         // TODO using a mutex seems clunky.
10345         var transitionLock = false;
10346
10347         // Decorator for creating an event handler that doesn't run
10348         // when the lock is active.
10349         var ifNotLocked = function (f) {
10350             return function (event) {
10351                 if (!transitionLock) {
10352                     f.apply(this, arguments);
10353                 }
10354             };
10355         };
10356
10357         $document.bind('deck.change', ifNotLocked(function (event, from, to) {
10358             popcorn.currentTime(timings[to.toString()]);
10359             popcorn.play();
10360         }));
10361
10362
10363         var updatePlayPause = function() {
10364             $('.playpause').each(function() {
10365                 updatePlayPauseClass(popcorn.paused(), this, 'pause', 'play');
10366             });
10367         };
10368         audio.addEventListener('pause', updatePlayPause);
10369         audio.addEventListener('playing', updatePlayPause);
10370         audio.addEventListener('timeupdate', function () {
10371             var estimatedTotal = popcorn.duration();
10372             var pc = 100 * audio.currentTime / estimatedTotal;
10373             var timeTxt = timeString(audio.currentTime);
10374             $(options.selectors.browsercastTimeLabel).css('left', pc+'%').text(timeTxt);
10375         });
10376         
10377         $document.unbind('keydown.deckbcast').bind('keydown.deckbcast', function(e) {
10378             //opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
10379             if (e.which === 32) {
10380                 togglePlay(popcorn);
10381                 e.preventDefault();
10382             }
10383         });
10384
10385         trySetCueLengthAndPlay(20, 10);
10386
10387     }
10388
10389     function leftPad(number, targetLength, padding) {
10390         padding = padding || ' ';
10391         var output = number + '';
10392         while (output.length < targetLength) {
10393             output = padding + output;
10394         }
10395         return output;
10396     }
10397
10398     // Start recording a 'cast
10399     // In the end you can get the slide HTML with the cue attributes set
10400     // by running:
10401     //        browsercastRecorder.getHTMLSlides()
10402     // in the Javascript console.
10403     //
10404     // Press 'Left' on the first slide to start recording.
10405     function recordBrowserCast(options) {
10406
10407         var bc = $(options.selectors.browsercast);
10408         $(options.selectors.browsercastAudio).attr('controls', 'true');
10409         $(options.selectors.browsercastMarkers).hide();
10410         setTimeout(function(){ $.deck('go', 0); logs = [{time:0, slide:0}];}, 200);
10411
10412         var $document = $(document);
10413         var audio = $(options.selectors.browsercastAudio).get(0);
10414         var logs = []; // as a list of pairs, so we can have multiple values and clean afterwards
10415         var exportLogs = function() {
10416             var res = '{\n';
10417             for (i in logs) {
10418                 if (i != 0) {
10419                     res += ',\n';
10420                 }
10421                 res += leftPad('"'+logs[i].slide+'"', 8) + ':' + leftPad(logs[i].time.toFixed(2), 6);
10422             }
10423             res += '\n}\n';
10424             alert(res);
10425         };
10426
10427         $document.bind('deck.change', function(event, from, to) {
10428             logs.push({time: audio.currentTime, slide: to});
10429         });
10430         $document.unbind('keydown.deckbcastrecord').bind('keydown.deckbcastrecord', function(e) {
10431             if (e.which === 84) { // 't'
10432                 exportLogs();
10433             }
10434         });
10435     }
10436
10437     function unsetKey(which, fromWhat) {
10438         if ($.isArray(fromWhat)) {
10439             var match = -1;
10440             while( (match = fromWhat.indexOf(which)) > -1 ) {
10441                 fromWhat.splice(match, 1);
10442             }
10443         } else if ($.isPlainObject(fromWhat)) {
10444             for (var p in fromWhat) {
10445                 if (fromWhat.hasOwnProperty(p)) {
10446                     unsetKey(which, fromWhat[p]);
10447                 }
10448             }
10449         }
10450     }
10451
10452
10453     $.extend(true, $.deck.defaults, {
10454         selectors: {
10455             browsercast: '.browsercast',
10456             browsercastAudio: '.browsercast-audio',
10457             browsercastMarkers: '.browsercast-markers',
10458             browsercastTimeLabel: '.browsercast-time-label'
10459         },
10460         
10461         snippets: {
10462             browsercast: true,
10463             browsercastAlways: false
10464         },
10465         
10466         alert: {
10467             browsercast: true
10468         }
10469     });
10470
10471
10472     unsetKey(32, $.deck.defaults.keys); // unbind space from 'next slide'
10473     $document.bind('deck.init', function() {
10474         var options = $.deck('getOptions');
10475         var audioDataFile = $('html>head>meta[name="audio"]').attr('content');
10476         if (audioDataFile === undefined) {
10477             return;
10478         }
10479         maybeAddSnippet(audioDataFile, options);
10480         var timingDataFile = $('html>head>meta[name="timings"]').attr('content');
10481         if (timingDataFile === undefined) {
10482             recordBrowserCast(options);
10483         } else {
10484             $.getJSON(timingDataFile, function(timings) {
10485                 playBrowserCast(timings, options);
10486             }).fail(function( jqxhr, textStatus, error ) {
10487                 var err = textStatus + ', ' + error;
10488                 console.log('[Browsercast] Request Failed: ' + err);
10489                 if (options.alert.browsercast) {
10490                     alert('Timing file "' + timingDataFile + '" referenced but it was not found or wrong.\n' +
10491                           'See console logs for more details.\n' +
10492                           "Browsercast replay won't work, falling back to timing recording.");
10493                 }
10494                 recordBrowserCast();
10495             });
10496         }
10497     });
10498
10499 })(window, window.document, jQuery, 'deck', this);
10500 function ACTUALLY_FILL_CSS(el) { $(el).text("\n.deck-container {\n  position: relative;\n  overflow: hidden;\n  margin: 0;\n}\n\n.deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide:not(.deck-current), .deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide:not(.deck-child-current) {\n  display: none;\n}\n.deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide.deck-current, .deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide.deck-child-current {\n  display: block;\n}\n\n.deck-container.deck-loading > *:not(.deck-loading-splash) {\n  visibility: hidden;\n}\n.touch .deck-container {\n  -webkit-text-size-adjust: none;\n  -moz-text-size-adjust: none;\n}\n.deck-container > .slide {\n  position: absolute;\n}\n.deck-container > .slide.deck-current, .deck-container > .slide.deck-child-current {\n  position: absolute;\n  /* relative to parent */\n}\n.deck-container > .slide.deck-current .slide, .deck-container > .slide.deck-child-current .slide {\n  visibility: hidden;\n}\n.deck-container > .slide.deck-current .deck-previous, .deck-container > .slide.deck-current .deck-before, .deck-container > .slide.deck-current .deck-current, .deck-container > .slide.deck-child-current .deck-previous, .deck-container > .slide.deck-child-current .deck-before, .deck-container > .slide.deck-child-current .deck-current {\n  visibility: visible;\n}\n.deck-container.deck-anim-ready .deck-loading-splash {\n  visibility: hidden;\n  opacity: 0;\n  /*\n      right: 100%;\n      left: -100%;\n  */\n  -webkit-transition: visibility 0s linear 0.5s, all 0.5s linear;\n  transition: visibility 0s linear .5s, all 0.5s linear;\n}\n.deck-container .deck-loading-splash {\n  visibility: visible;\n  opacity: 1;\n  position: absolute;\n  text-align: center;\n  padding-top: 200px;\n  display: flex;\n  margin: 0 auto;\n  left: 0;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  background: black;\n  color: white;\n  z-index: 100;\n}\n\n\n.deck-container {\n    width: 100%; height: 100%; /* to get a proper filling of the parent */\n    margin: 0; padding: 0; /* any margin is handled by the parent or the fit extension */\n    position: absolute;\n    left:0; top:0; width:100%; height:100%;\n    border: 0;\n}\n.deck-container>.slide {\n    width: 100%; height: 100%; /* to get a proper filling of the parent */\n    min-width:0; min-height:0; /* undoing some hurting style in the defaults of deck.js */\n    overflow: hidden; /* don't show slides outside of their box */\n    /* margin:0; padding:0; /* remove possible margins */\n}\n\nbody.is-clone .clonepointer {\n  /* default convenient positioning for clone pointers */\n  position: absolute;\n  z-index: 10; }\n  body.is-clone .clonepointer.scale-on-click {\n    transition: transform 80ms linear;\n    -webkit-transition: -webkit-transform 80ms linear; }\n    body.is-clone .clonepointer.scale-on-click.pointer-click {\n      transition: transform 150ms linear;\n      -webkit-transition: -webkit-transform 150ms linear;\n      transform: translate(-50%, -50%) scale(1.5, 1.5) translate(50%, 50%);\n      -webkit-transform: translate(-50%, -50%) scale(1.5, 1.5) translate(50%, 50%); }\n\n.notes, .notes-target {\n  display: none; }\n\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current {\n  outline: 5px solid grey;\n  /* use outline to avoid layout issues with old themes and allow for precise pointer position estimation */\n  overflow: hidden;\n  left: 0;\n  top: 0;\n  transform: translate(20px, 20px);\n  -webkit-transform: translate(20px, 20px); }\n  body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current + .slide, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current + .slide {\n    outline: 5px solid grey;\n    overflow: hidden;\n    display: block !important;\n    visibility: visible;\n    top: 0;\n    left: 0;\n    transform: translate(-50%, -50%) scale(0.5) translate(50%, 50%) translate(200%, 0) translate(80px, 40px);\n    -webkit-transform: translate(-50%, -50%) scale(0.5) translate(50%, 50%) translate(200%, 0) translate(80px, 40px); }\n    body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current + .slide.deck-next, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current + .slide.deck-next {\n      outline-color: red; }\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) .notes-target {\n  display: block;\n  background: black;\n  color: #FFB;\n  padding: 5px;\n  position: absolute;\n  left: 840px;\n  right: 0;\n  top: 340px;\n  bottom: 0; }\n\n.goto-form {\n  position: absolute;\n  z-index: 3;\n  bottom: 10px;\n  left: 50%;\n  height: 1.75em;\n  margin: 0 0 0 -9.125em;\n  line-height: 1.75em;\n  padding: 0.625em;\n  display: none;\n  background: #ccc;\n  overflow: hidden;\n  border-radius: 10px;\n}\n.goto-form label {\n  font-weight: bold;\n}\n.goto-form label, .goto-form input {\n  display: inline-block;\n  font-family: inherit;\n}\n.deck-goto .goto-form {\n  display: block;\n}\n\n#goto-slide {\n  width: 8.375em;\n  margin: 0 0.625em;\n  height: 1.4375em;\n}\n\n@media print {\n  .goto-form, #goto-slide {\n    display: none;\n  }\n}\n\n.deck-container.no-status .deck-status {\n  display: none;\n}\n\n.deck-status {\n  position: absolute;\n  z-index: 3;\n  left: 0;\n  bottom: 10px;\n  margin: 0;\n  padding: 0;\n  font-size: 10px;\n  /*outline: 1px solid red;*/\n  width: 100%;\n  text-align: center;\n  color: #888;\n}\n\n.deck-prev-link, .deck-next-link {\n  display: none;\n  position: absolute;\n  z-index: 3;\n  top: 50%;\n  width: 32px;\n  height: 32px;\n  margin-top: -16px;\n  font-size: 20px;\n  font-weight: bold;\n  line-height: 32px;\n  vertical-align: middle;\n  text-align: center;\n  text-decoration: none;\n  color: #fff;\n  background: #888;\n  border-radius: 16px;\n}\n.deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {\n  color: #fff;\n}\n\n.deck-prev-link {\n  left: 8px;\n}\n\n.deck-next-link {\n  right: 8px;\n}\n\n.deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link {\n  display: block;\n}\n.deck-container:hover .deck-prev-link.deck-nav-disabled, .touch .deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link.deck-nav-disabled, .touch .deck-container:hover .deck-next-link {\n  display: none;\n}\n\n@media print {\n  .deck-prev-link, .deck-next-link {\n    display: none !important;\n  }\n}\n\n.deck-menu {\n  overflow: auto;\n}\n.deck-menu .slide {\n  background: #eee;\n  position: relative;\n  left: 0;\n  top: 0;\n  visibility: visible;\n  cursor: pointer;\n}\n.no-csstransforms .deck-menu > .slide {\n  float: left;\n  width: 22%;\n  height: 22%;\n  min-height: 0;\n  margin: 1%;\n  font-size: 0.22em;\n  overflow: hidden;\n  padding: 0 0.5%;\n}\n.csstransforms .deck-menu > .slide {\n  -webkit-transform: scale(0.22) !important;\n  -ms-transform: scale(0.22) !important;\n  transform: scale(0.22) !important;\n  -webkit-transform-origin: 0 0;\n  -ms-transform-origin: 0 0;\n  transform-origin: 0 0;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  padding: 0 48px;\n  margin: 12px;\n}\n.deck-menu iframe, .deck-menu img, .deck-menu video {\n  max-width: 100%;\n}\n.deck-menu .deck-current, .no-touch .deck-menu .slide:hover {\n  background: #ddf;\n}\n.deck-menu.deck-container:hover .deck-prev-link, .deck-menu.deck-container:hover .deck-next-link {\n  display: none;\n}\n\n.deck-container .attribution-wrap {\n  /* cover the complete offset parent */\n  position: absolute;\n  left: 0;\n  width: 100%;\n  top: 0;\n  height: 100%;\n}\n.deck-container .attribution-link {\n  font-size: 10px;\n  color: white;\n  background: black;\n  border: 1px solid darkgrey;\n  opacity: 0.6;\n  right: 0;\n  bottom: 5px;\n  position: absolute;\n  padding: 0 5px;\n}\n\n/* the time etc */\n.timekeeper {\n  font-size: 28px;\n  border-radius: 3px;\n  background: black;\n  color: white;\n  display: inline-block;\n  position: absolute;\n  left: 840px;\n  top: 340px;\n  width: 400px;\n  padding: 4px;\n  margin: -4px; }\n  body:not(.has-clones) .timekeeper {\n    visibility: hidden; }\n  .timekeeper .timekeeper-time, .timekeeper .timekeeper-local-relative-time {\n    margin: 0;\n    padding: 0;\n    display: inline-block;\n    width: 50%;\n    text-align: center;\n    vertical-align: middle; }\n    .timekeeper .timekeeper-time.timekeeper-local-relative-time, .timekeeper .timekeeper-local-relative-time.timekeeper-local-relative-time {\n      color: grey; }\n    .timekeeper .timekeeper-time.timekeeper-time, .timekeeper .timekeeper-local-relative-time.timekeeper-time {\n      border-left: 2px solid grey;\n      /*margin-left: -10px; not needed with the injected template (no space in it)*/\n      margin-right: -15px; }\n  .timekeeper .timekeeper-relative-time {\n    margin-top: 5px;\n    border-top: 2px solid grey;\n    text-align: center;\n    font-size: 300%; }\n  .timekeeper .timekeeper-bang, .timekeeper .timekeeper-clear {\n    display: inline-block;\n    position: absolute;\n    width: 10px;\n    height: 10px;\n    left: 45%;\n    border: 2px solid grey;\n    border-radius: 15px;\n    background: black; }\n    .timekeeper .timekeeper-bang.timekeeper-bang, .timekeeper .timekeeper-clear.timekeeper-bang {\n      top: 10px; }\n    .timekeeper .timekeeper-bang.timekeeper-clear, .timekeeper .timekeeper-clear.timekeeper-clear {\n      top: 23px; }\n    .timekeeper .timekeeper-bang:not(.timekeeper-notification), .timekeeper .timekeeper-clear:not(.timekeeper-notification) {\n      transition: background 300ms linear;\n      -webkit-transition: background 300ms linear; }\n    .timekeeper .timekeeper-bang.timekeeper-notification, .timekeeper .timekeeper-clear.timekeeper-notification {\n      border-color: white;\n      background: green; }\n      .timekeeper .timekeeper-bang.timekeeper-notification.timekeeper-clear, .timekeeper .timekeeper-clear.timekeeper-notification.timekeeper-clear {\n        background: red; }\n\n/* the logs */\n.timekeeper-logs {\n  visibility: hidden;\n  border: 2px solid black;\n  border-radius: 2px;\n  background: #181818;\n  color: yellow;\n  padding: 5px;\n  position: absolute;\n  width: 500px;\n  right: 0;\n  top: 0;\n  bottom: 0;\n  opacity: .8; }\n  .timekeeper-logs.timekeeper-logs-visible {\n    visibility: visible; }\n  .timekeeper-logs pre {\n    font-size: 10px;\n    overflow-y: scroll;\n    position: absolute;\n    top: 50px;\n    bottom: 0;\n    left: 0;\n    right: 0; }\n  .timekeeper-logs .button {\n    color: white;\n    background: black;\n    display: inline-block;\n    padding: 0 5px;\n    margin-right: 10px;\n    border: 1px solid white;\n    border-radius: 3px; }\n\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) div.notes-target {\n  top: 490px; }\n\n.deck-container .slide.image-full > .attribution-wrap, .deck-container .slide.image-full > img, .deck-container .slide.image-full > div.img, .deck-container .slide.image-fit > .attribution-wrap, .deck-container .slide.image-fit > img, .deck-container .slide.image-fit > div.img {\n  z-index: -1;\n}\n.deck-container .slide.image-full > img, .deck-container .slide.image-full > div.img, .deck-container .slide.image-fit > img, .deck-container .slide.image-fit > div.img {\n  margin: 0;\n  padding: 0;\n  position: relative;\n  left: 0;\n  top: 0;\n  width: 100%;\n  min-height: 100%;\n}\n.deck-container .slide.image-full div.img, .deck-container .slide.image-fit div.img {\n  width: 100%;\n  height: 100%;\n  outline: 2px solid red;\n  background-position: center center;\n  background-repeat: no-repeat;\n}\n.deck-container .slide.image-full.image-full div.img, .deck-container .slide.image-fit.image-full div.img {\n  -webkit-background-size: cover;\n  -moz-background-size: cover;\n  -o-background-size: cover;\n  background-size: cover;\n}\n.deck-container .slide.image-full.image-fit div.img, .deck-container .slide.image-fit.image-fit div.img {\n  -webkit-background-size: contain;\n  -moz-background-size: contain;\n  -o-background-size: contain;\n  background-size: contain;\n}\n.deck-container .slide.top-left h2 {\n  position: absolute;\n  border: 0px;\n  top: 50px;\n  left: 50px;\n}\n.deck-container .slide.top-right h2 {\n  position: absolute;\n  border: 0px;\n  top: 50px;\n  right: 50px;\n}\n.deck-container .slide.bottom-left h2 {\n  position: absolute;\n  border: 0px;\n  bottom: 50px;\n  left: 50px;\n}\n.deck-container .slide.bottom-right h2 {\n  position: absolute;\n  border: 0px;\n  bottom: 50px;\n  right: 50px;\n}\n.deck-container .slide.no-title h1, .deck-container .slide.no-title h2 {\n  display: none;\n}\n.deck-container .slide.darkened h2 {\n  background: rgba(0, 0, 0, 0.75);\n  padding: 15px;\n  margin: -15px;\n}\n.deck-container .in3d-table {\n  transform: scale(0.7) perspective(600px) rotateX(40deg) rotateZ(-15deg) translate(-30px, -120px);\n}\n\n.deck-container:not(.deck-globalscale) div.comment, .deck-container:not(.deck-globalscale) .comment {\n  z-index: 1000 !important;\n  /* might need theme specific thing here */\n  background-color: yellow;\n  /* force opaque... */\n  color: darkred;\n}\n\n.deck-container:not(.deck-globalscale) .hasSVG .comment {\n  /*transform: none;*/\n  -webkit-transform: none;\n}\n\nbody:not(.has-clones):not(.show-comments) .deck-container > .slide .comment, body:not(.has-clones):not(.show-comments) .deck-container > .slide .showwhencomment {\n  display: none;\n}\n\n.deck-container > .slide div.comment {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  /*outline: 1px solid red;*/\n  border-radius: 3px;\n  color: darkred;\n  background: rgba(255, 255, 128, 0.7);\n  /*        opacity: .8;*/\n  font-size: 14px;\n  line-height: initial;\n  padding: 1px 15px;\n  width: auto;\n  height: 20px;\n  margin: 0;\n  margin-left: 100px;\n  margin-top: -6.6px;\n  margin-bottom: -13.2px;\n}\n\n.deck-container > .slide div.comment.small {\n  width: 120px;\n  margin-left: -100px;\n}\n\n.deck-container > .slide div.comment.twolines {\n  height: 40px;\n  margin-top: -13.333px;\n  margin-bottom: -26.667px;\n}\n\n.browsercast {\n    position: absolute;\n    top: 5px; left: 5px;\n    right: 5px;\n}\n\n.browsercast-audio {\n    width: 100%;\n    margin: auto auto;\n}\n\n.browsercast-cue {\n    position: relative;\n    float: left;\n    height: 10px;\n    border-right: solid 2px #000;\n    cursor: pointer;\n}\n\n.browsercast-cue:last-child {\n    border-right: 0;\n}\n\n.browsercast-cue.active {\n    background-color: #abc;\n}\n\n\nmenu {\n  /* @size sets the relative size of the buttons, define before calling the buttons mixin */\n  /* Play */\n  /* Stop */\n  /* Fast-Forward */\n  /* Rewind */\n  /* Pause */\n  margin: 2em auto;\n  text-align: center;\n  position: relative;\n}\nmenu button {\n  position: relative;\n  display: inline-block;\n  padding: .6em;\n  background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n  border-radius: 10em;\n  border: 0 solid #d0d0d0;\n  width: 3em;\n  height: 3em;\n  margin-right: 20px;\n  box-shadow: 0 0.18em 0.21em rgba(0, 0, 0, 0.4);\n}\nmenu button:hover {\n  background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu button:before,\nmenu button:after {\n  position: absolute;\n  content: \" \";\n}\nmenu button:active {\n  top: 0.15em;\n  box-shadow: 0 0.06em 0.09em rgba(0, 0, 0, 0.4);\n}\nmenu .play:before {\n  z-index: 2;\n  top: 0.66em;\n  left: 1.08em;\n  width: 0;\n  height: 0;\n  border: 0.9em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 1.35em;\n}\nmenu .play:hover:before {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu .stop:before {\n  top: 0.84em;\n  left: 0.84em;\n  width: 1.41em;\n  height: 1.41em;\n  background: rgba(100, 100, 100, 0.8);\n}\nmenu .stop:hover:before {\n  background: rgba(36, 36, 36, 0.8);\n}\nmenu .ff:before,\nmenu .ff:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 0.81em;\n}\nmenu .ff:before {\n  left: 0.9em;\n}\nmenu .ff:after {\n  left: 1.698em;\n  content: \" \";\n}\nmenu .ff:hover:before,\nmenu .ff:hover:after {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu .rw:before,\nmenu .rw:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-right-color: rgba(100, 100, 100, 0.8);\n  border-right-width: 0.81em;\n}\nmenu .rw:before {\n  left: 0.66em;\n}\nmenu .rw:after {\n  left: -0.15em;\n  content: \" \";\n}\nmenu .rw:hover:after,\nmenu .rw:hover:before {\n  border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu .pause:before,\nmenu .pause:after {\n  height: 1.41em;\n  width: 0.57em;\n  left: 0.87em;\n  top: 0.84em;\n  display: block;\n  background-color: rgba(100, 100, 100, 0.8);\n}\nmenu .pause:after {\n  left: 1.62em;\n}\nmenu .pause:hover:before,\nmenu .pause:hover:after {\n  background-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium {\n  /* Play */\n  /* Stop */\n  /* Fast-Forward */\n  /* Rewind */\n  /* Pause */\n}\nmenu.medium button {\n  position: relative;\n  display: inline-block;\n  padding: .6em;\n  background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n  border-radius: 10em;\n  border: 0 solid #d0d0d0;\n  width: 5em;\n  height: 5em;\n  margin-right: 20px;\n  box-shadow: 0 0.3em 0.35em rgba(0, 0, 0, 0.4);\n}\nmenu.medium button:hover {\n  background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu.medium button:before,\nmenu.medium button:after {\n  position: absolute;\n  content: \" \";\n}\nmenu.medium button:active {\n  top: 0.25em;\n  box-shadow: 0 0.1em 0.15em rgba(0, 0, 0, 0.4);\n}\nmenu.medium .play:before {\n  z-index: 2;\n  top: 1.1em;\n  left: 1.8em;\n  width: 0;\n  height: 0;\n  border: 1.5em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 2.25em;\n}\nmenu.medium .play:hover:before {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .stop:before {\n  top: 1.4em;\n  left: 1.4em;\n  width: 2.35em;\n  height: 2.35em;\n  background: rgba(100, 100, 100, 0.8);\n}\nmenu.medium .stop:hover:before {\n  background: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .ff:before,\nmenu.medium .ff:after {\n  width: 0;\n  height: 0;\n  top: 1.3em;\n  border: 1.25em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 1.35em;\n}\nmenu.medium .ff:before {\n  left: 1.5em;\n}\nmenu.medium .ff:after {\n  left: 2.83em;\n  content: \" \";\n}\nmenu.medium .ff:hover:before,\nmenu.medium .ff:hover:after {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .rw:before,\nmenu.medium .rw:after {\n  width: 0;\n  height: 0;\n  top: 1.3em;\n  border: 1.25em solid transparent;\n  border-right-color: rgba(100, 100, 100, 0.8);\n  border-right-width: 1.35em;\n}\nmenu.medium .rw:before {\n  left: 1.1em;\n}\nmenu.medium .rw:after {\n  left: -0.25em;\n  content: \" \";\n}\nmenu.medium .rw:hover:after,\nmenu.medium .rw:hover:before {\n  border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .pause:before,\nmenu.medium .pause:after {\n  height: 2.35em;\n  width: 0.95em;\n  left: 1.45em;\n  top: 1.4em;\n  display: block;\n  background-color: rgba(100, 100, 100, 0.8);\n}\nmenu.medium .pause:after {\n  left: 2.7em;\n}\nmenu.medium .pause:hover:before,\nmenu.medium .pause:hover:after {\n  background-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small {\n  /* Play */\n  /* Stop */\n  /* Fast-Forward */\n  /* Rewind */\n  /* Pause */\n}\nmenu.small button {\n  position: relative;\n  display: inline-block;\n  padding: .6em;\n  background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n  border-radius: 10em;\n  border: 0 solid #d0d0d0;\n  width: 3em;\n  height: 3em;\n  margin-right: 20px;\n  box-shadow: 0 0.18em 0.21em rgba(0, 0, 0, 0.4);\n}\nmenu.small button:hover {\n  background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu.small button:before,\nmenu.small button:after {\n  position: absolute;\n  content: \" \";\n}\nmenu.small button:active {\n  top: 0.15em;\n  box-shadow: 0 0.06em 0.09em rgba(0, 0, 0, 0.4);\n}\nmenu.small .play:before {\n  z-index: 2;\n  top: 0.66em;\n  left: 1.08em;\n  width: 0;\n  height: 0;\n  border: 0.9em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 1.35em;\n}\nmenu.small .play:hover:before {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .stop:before {\n  top: 0.84em;\n  left: 0.84em;\n  width: 1.41em;\n  height: 1.41em;\n  background: rgba(100, 100, 100, 0.8);\n}\nmenu.small .stop:hover:before {\n  background: rgba(36, 36, 36, 0.8);\n}\nmenu.small .ff:before,\nmenu.small .ff:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 0.81em;\n}\nmenu.small .ff:before {\n  left: 0.9em;\n}\nmenu.small .ff:after {\n  left: 1.698em;\n  content: \" \";\n}\nmenu.small .ff:hover:before,\nmenu.small .ff:hover:after {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .rw:before,\nmenu.small .rw:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-right-color: rgba(100, 100, 100, 0.8);\n  border-right-width: 0.81em;\n}\nmenu.small .rw:before {\n  left: 0.66em;\n}\nmenu.small .rw:after {\n  left: -0.15em;\n  content: \" \";\n}\nmenu.small .rw:hover:after,\nmenu.small .rw:hover:before {\n  border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .pause:before,\nmenu.small .pause:after {\n  height: 1.41em;\n  width: 0.57em;\n  left: 0.87em;\n  top: 0.84em;\n  display: block;\n  background-color: rgba(100, 100, 100, 0.8);\n}\nmenu.small .pause:after {\n  left: 1.62em;\n}\nmenu.small .pause:hover:before,\nmenu.small .pause:hover:after {\n  background-color: rgba(36, 36, 36, 0.8);\n}\n/*\nThe buttons mixin that defines the buttons styles, the @size must be defined to set the relative size\n*/\n/*\nOther Styles\n*/\nbody {\n  background: #c1c1c1;\n}\n\n\n\n\n/* ///////////////////////////////// */\n\n\n.browsercast-time-label {\n    z-index: 1;\n    background-color: grey;\n    font-family: lato;\n    color: #DDD;\n    text-shadow: #555 1px 1px 1px;\n    padding: 0 5px;\n    border-radius: 2px;\n    /*\n      height: 100px;\n      width: 100px;\n      */\n    font-size: 10px;\n    display: inline-block;\n    position: absolute;\n    left: 0%;\n    transition: left 200ms linear;\n    top: -17px;\n    transform: translate(-50%, 0) translate(-3px, 0);\n}\n.browsercast-time-label:after {\n    content: ' ';\n    height: 0;\n    position: absolute;\n    width: 0;\n    \n    border: 7px solid transparent;\n    border-top-color: grey;\n    \n    top: 100%;\n    left: 50%;\n    margin-left: -7px;\n}\n\n\n/* ///////////////////////// */\nmenu {\n    padding: 0;\n    margin: 0;\n}\n\nmenu .playpause {\n    position: absolute;\n    left: 0;\n    top: 0;\n    font-size: 12px;\n    margin: 0; padding: 0;\n}\n\n.browsercast-markers {\n    position: absolute;\n    top: 1em; height: 10px;\n    left: 3em; right: 1em;\n    background-color: #e3e3e3;\n}\n") }