-
-
-
diff --git a/css/deckjs-js/deckjs-custom.js b/css/deckjs-js/deckjs-custom.js
deleted file mode 100644
index 41a0e5ab42bf7618b58f0b65c72ee63f7db46297..0000000000000000000000000000000000000000
--- a/css/deckjs-js/deckjs-custom.js
+++ /dev/null
@@ -1,10500 +0,0 @@
-/*
- This is a packed deck.js with some extensions and styles.
- It has been generated from version d8c74bcc860ba175ab020fd69656abee3fc057f3 .
- It includes:
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck/extensions/includedeck/load.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//jquery.min.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//modernizr.custom.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//core/deck.core.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/smarkdown/markdown.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/smarkdown/deck.smarkdown.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/fit/deck.fit.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/display-latex2.user.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/simplemath/deck.simplemath.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/clone/deck.clone.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/goto/deck.goto.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/progress/deck.progress.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/navigation/deck.navigation.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/menu/deck.menu.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/step/deck.step.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/events/deck.events.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/anim/deck.anim.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/jquerysvg/jquery.svg.min.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/jquerysvg/jquery.svganim.min.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/svg/deck.svg.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/metadata/deck.metadata.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/attribution/deck.attribution.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/container-styling/deck.container-styling.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/timekeeper/deck.timekeeper.js
- browsercast/popcorn.js
- browsercast/deck.browsercast.js
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/core.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/fit/deck.fit-fs.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/clone/deck.clone.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/goto/deck.goto.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/progress/deck.progress.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/navigation/deck.navigation.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/menu/deck.menu.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/attribution/deck.attribution.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/timekeeper/deck.timekeeper.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/simple.css
- /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/comments.css
- browsercast/deck.browsercast.css
- browsercast/player.css
-*/
-
-
-/*!
- * Includedeck.
- *
- * Copyright (c) 2013-2014 Rémi Emonet.
- * Licensed under the MIT license.
- * https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
- *
- * The goal of this extension is to simplify include of deck.js,
- * its profiles/themes and the extensions.
- *
- * The first goal is not performance of loading (still it should
- * allow the display of a message while loading) but on ease of
- * use and extensibility (i.e., includedeck does not need to know
- * about all existing extensions, even if by default it does know
- * some of them).
- *
- */
-
-
-
-var head_conf = {
-
-};
-
-if (typeof ACTUALLY_EXPORT_A_LIST_OF_FILES == 'undefined')
-// this is head.load.min.js (v1.0.3) from http://headjs.com/site/download.html
-/*! head.load - v1.0.3 */
-(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)[^>]*|#([\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="",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="",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="","#"===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="",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="
a",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>"!==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="
").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);
-/* Modernizr 2.0.6 (Custom Build) | MIT & BSD
- * 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
- */
-;window.Modernizr=function(a,b,c){function H(){e.input=function(a){for(var b=0,c=a.length;b",a,""].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;++b7)},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";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="";return a.childNodes.length!==1}()&&function(a,b){function s(a){var b=-1;while(++b 0) {
- slides[currentIndex-1].addClass(options.classes.previous);
- }
- if (currentIndex + 1 < slides.length) {
- slides[currentIndex+1].addClass(options.classes.next);
- }
- if (currentIndex > 1) {
- $.each(slides.slice(0, currentIndex - 1), function(i, $slide) {
- $slide.addClass(options.classes.before);
- });
- }
- if (currentIndex + 2 < slides.length) {
- $.each(slides.slice(currentIndex+2), function(i, $slide) {
- $slide.addClass(options.classes.after);
- });
- }
- };
-
- var setAriaHiddens = function() {
- $(options.selectors.slides).each(function() {
- var $slide = $(this);
- var isSub = $slide.closest('.' + options.classes.childCurrent).length;
- var isBefore = $slide.hasClass(options.classes.before) && !isSub;
- var isPrevious = $slide.hasClass(options.classes.previous) && !isSub;
- var isNext = $slide.hasClass(options.classes.next);
- var isAfter = $slide.hasClass(options.classes.after);
- var ariaHiddenValue = isBefore || isPrevious || isNext || isAfter;
- $slide.attr('aria-hidden', ariaHiddenValue);
- });
- };
-
- var updateStates = function() {
- updateContainerState();
- updateChildCurrent();
- removeOldSlideStates();
- addNewSlideStates();
- if (options.setAriaHiddens) {
- setAriaHiddens();
- }
- };
-
- var initSlidesArray = function(elements) {
- if ($.isArray(elements)) {
- $.each(elements, function(i, element) {
- slides.push($(element));
- });
- }
- else {
- $(elements).each(function(i, element) {
- slides.push($(element));
- });
- }
- };
-
- var bindKeyEvents = function() {
- var editables = [
- 'input',
- 'textarea',
- 'select',
- 'button',
- 'meter',
- 'progress',
- '[contentEditable]'
- ].join(', ');
-
- $document.unbind('keydown.deck').bind('keydown.deck', function(event) {
- var isNext = event.which === options.keys.next;
- var isPrev = event.which === options.keys.previous;
- isNext = isNext || $.inArray(event.which, options.keys.next) > -1;
- isPrev = isPrev || $.inArray(event.which, options.keys.previous) > -1;
-
- if (isNext) {
- methods.next();
- event.preventDefault();
- }
- else if (isPrev) {
- methods.prev();
- event.preventDefault();
- }
- });
-
- $document.undelegate(editables, 'keydown.deck', stopPropagation);
- $document.delegate(editables, 'keydown.deck', stopPropagation);
- };
-
- var bindTouchEvents = function() {
- var startTouch;
- var direction = options.touch.swipeDirection;
- var tolerance = options.touch.swipeTolerance;
- var listenToHorizontal = ({ both: true, horizontal: true })[direction];
- var listenToVertical = ({ both: true, vertical: true })[direction];
-
- $container.unbind('touchstart.deck');
- $container.bind('touchstart.deck', function(event) {
- if (!startTouch) {
- startTouch = $.extend({}, event.originalEvent.targetTouches[0]);
- }
- });
-
- $container.unbind('touchmove.deck');
- $container.bind('touchmove.deck', function(event) {
- $.each(event.originalEvent.changedTouches, function(i, touch) {
- if (!startTouch || touch.identifier !== startTouch.identifier) {
- return true;
- }
- var xDistance = touch.screenX - startTouch.screenX;
- var yDistance = touch.screenY - startTouch.screenY;
- var leftToRight = xDistance > tolerance && listenToHorizontal;
- var rightToLeft = xDistance < -tolerance && listenToHorizontal;
- var topToBottom = yDistance > tolerance && listenToVertical;
- var bottomToTop = yDistance < -tolerance && listenToVertical;
-
- if (leftToRight || topToBottom) {
- $.deck('prev');
- startTouch = undefined;
- }
- else if (rightToLeft || bottomToTop) {
- $.deck('next');
- startTouch = undefined;
- }
- return false;
- });
-
- if (listenToVertical) {
- event.preventDefault();
- }
- });
-
- $container.unbind('touchend.deck');
- $container.bind('touchend.deck', function(event) {
- $.each(event.originalEvent.changedTouches, function(i, touch) {
- if (startTouch && touch.identifier === startTouch.identifier) {
- startTouch = undefined;
- }
- });
- });
- };
-
- var indexInBounds = function(index) {
- return typeof index === 'number' && index >=0 && index < slides.length;
- };
-
- var createBeforeInitEvent = function() {
- var event = $.Event(events.beforeInitialize);
- event.locks = 0;
- event.done = $.noop;
- event.lockInit = function() {
- ++event.locks;
- };
- event.releaseInit = function() {
- --event.locks;
- if (!event.locks) {
- event.done();
- }
- };
- return event;
- };
-
- var goByHash = function(str) {
- var id = str.substr(str.indexOf("#") + 1);
-
- $.each(slides, function(i, $slide) {
- if ($slide.attr('id') === id) {
- $.deck('go', i);
- return false;
- }
- });
-
- // If we don't set these to 0 the container scrolls due to hashchange
- if (options.preventFragmentScroll) {
- $.deck('getContainer').scrollLeft(0).scrollTop(0);
- }
- };
-
- var assignSlideId = function(i, $slide) {
- var currentId = $slide.attr('id');
- var previouslyAssigned = $slide.data('deckAssignedId') === currentId;
- if (!currentId || previouslyAssigned) {
- $slide.attr('id', options.hashPrefix + i);
- $slide.data('deckAssignedId', options.hashPrefix + i);
- }
- };
-
- var removeContainerHashClass = function(id) {
- $container.removeClass(options.classes.onPrefix + id);
- };
-
- var addContainerHashClass = function(id) {
- $container.addClass(options.classes.onPrefix + id);
- };
-
- var setupHashBehaviors = function() {
- $fragmentLinks = $();
- $.each(slides, function(i, $slide) {
- var hash;
-
- assignSlideId(i, $slide);
- hash = '#' + $slide.attr('id');
- if (hash === window.location.hash) {
- setTimeout(function() {
- $.deck('go', i);
- }, 1);
- }
- $fragmentLinks = $fragmentLinks.add('a[href="' + hash + '"]');
- });
-
- if (slides.length) {
- addContainerHashClass($.deck('getSlide').attr('id'));
- };
- };
-
- var changeHash = function(from, to) {
- var hash = '#' + $.deck('getSlide', to).attr('id');
- var hashPath = window.location.href.replace(/#.*/, '') + hash;
-
- removeContainerHashClass($.deck('getSlide', from).attr('id'));
- addContainerHashClass($.deck('getSlide', to).attr('id'));
- if (Modernizr.history) {
- window.history.replaceState({}, "", hashPath);
- }
- };
-
- /* Methods exposed in the jQuery.deck namespace */
- var methods = {
-
- /*
- jQuery.deck(selector, options)
-
- selector: string | jQuery | array
- options: object, optional
-
- Initializes the deck, using each element matched by selector as a slide.
- May also be passed an array of string selectors or jQuery objects, in
- which case each selector in the array is considered a slide. The second
- parameter is an optional options object which will extend the default
- values.
-
- Users may also pass only an options object to init. In this case the slide
- selector will be options.selectors.slides which defaults to .slide.
-
- $.deck('.slide');
-
- or
-
- $.deck([
- '#first-slide',
- '#second-slide',
- '#etc'
- ]);
- */
- init: function(opts) {
- var beforeInitEvent = createBeforeInitEvent();
- var overrides = opts;
-
- if (!$.isPlainObject(opts)) {
- overrides = arguments[1] || {};
- $.extend(true, overrides, {
- selectors: {
- slides: arguments[0]
- }
- });
- }
-
- options = $.extend(true, {}, $.deck.defaults, overrides);
- slides = [];
- currentIndex = 0;
- $container = $(options.selectors.container);
-
- // Hide the deck while states are being applied to kill transitions
- $container.addClass(options.classes.loading);
-
- // populate the array of slides for pre-init
- initSlidesArray(options.selectors.slides);
- // Pre init event for preprocessing hooks
- beforeInitEvent.done = function() {
- // reInitSlidesArray is meant only for beforeInit
- methods['reInitSlidesArray'] = function() {
- alert('Deck.js method "reInitSlidesArray" is meant to be called in the beforeInit phase only.');
- }
- // re-populate the array of slides
- slides = [];
- initSlidesArray(options.selectors.slides);
- setupHashBehaviors();
- bindKeyEvents();
- bindTouchEvents();
- $container.scrollLeft(0).scrollTop(0);
-
- if (slides.length) {
- updateStates();
- }
-
- // Show deck again now that slides are in place
- $container.removeClass(options.classes.loading);
- $document.trigger(events.initialize);
- };
-
- beforeInitEvent.lockInit();
- $document.trigger(beforeInitEvent);
- beforeInitEvent.releaseInit();
- window.setTimeout(function() {
- if (beforeInitEvent.locks) {
- if (window.console) {
- window.console.warn('Something locked deck initialization\
- without releasing it before the timeout. Proceeding with\
- initialization anyway.');
- }
- beforeInitEvent.done();
- }
- }, options.initLockTimeout);
- },
-
- /*
- jQuery.deck('reInitSlidesArray')
-
- Force a recomputation of the "slides" array. This method is meant
- to be used by extensions that generate new slides in the
- beforeInit phase.
- */
-
- reInitSlidesArray: function() {
- slides = [];
- initSlidesArray(options.selectors.slides);
- },
-
- /*
- jQuery.deck('go', index)
-
- index: integer | string
-
- Moves to the slide at the specified index if index is a number. Index is
- 0-based, so $.deck('go', 0); will move to the first slide. If index is a
- string this will move to the slide with the specified id. If index is out
- of bounds or doesn't match a slide id the call is ignored.
- */
- go: function(indexOrId) {
- var beforeChangeEvent = $.Event(events.beforeChange);
- var index;
-
- /* Number index, easy. */
- if (indexInBounds(indexOrId)) {
- index = indexOrId;
- }
- /* Id string index, search for it and set integer index */
- else if (typeof indexOrId === 'string') {
- $.each(slides, function(i, $slide) {
- if ($slide.attr('id') === indexOrId) {
- index = i;
- return false;
- }
- });
- }
- if (typeof index === 'undefined') {
- return;
- }
-
- /* Trigger beforeChange. If nothing prevents the change, trigger
- the slide change. */
- $document.trigger(beforeChangeEvent, [currentIndex, index]);
- if (!beforeChangeEvent.isDefaultPrevented()) {
- $document.trigger(events.change, [currentIndex, index]);
- changeHash(currentIndex, index);
- currentIndex = index;
- updateStates();
- }
- },
-
- /*
- jQuery.deck('next')
-
- Moves to the next slide. If the last slide is already active, the call
- is ignored.
- */
- next: function() {
- methods.go(currentIndex+1);
- },
-
- /*
- jQuery.deck('prev')
-
- Moves to the previous slide. If the first slide is already active, the
- call is ignored.
- */
- prev: function() {
- methods.go(currentIndex-1);
- },
-
- /*
- jQuery.deck('getSlide', index)
-
- index: integer, optional
-
- Returns a jQuery object containing the slide at index. If index is not
- specified, the current slide is returned.
- */
- getSlide: function(index) {
- index = typeof index !== 'undefined' ? index : currentIndex;
- if (!indexInBounds(index)) {
- return null;
- }
- return slides[index];
- },
-
- /*
- jQuery.deck('getSlides')
-
- Returns all slides as an array of jQuery objects.
- */
- getSlides: function() {
- return slides;
- },
-
- /*
- jQuery.deck('getTopLevelSlides')
-
- Returns all slides that are not subslides.
- */
- getTopLevelSlides: function() {
- var topLevelSlides = [];
- var slideSelector = options.selectors.slides;
- var subSelector = [slideSelector, slideSelector].join(' ');
- $.each(slides, function(i, $slide) {
- if (!$slide.is(subSelector)) {
- topLevelSlides.push($slide);
- }
- });
- return topLevelSlides;
- },
-
- /*
- jQuery.deck('getNestedSlides', index)
-
- index: integer, optional
-
- Returns all the nested slides of the current slide. If index is
- specified it returns the nested slides of the slide at that index.
- If there are no nested slides this will return an empty array.
- */
- getNestedSlides: function(index) {
- var targetIndex = index == null ? currentIndex : index;
- var $targetSlide = $.deck('getSlide', targetIndex);
- var $nesteds = $targetSlide.find(options.selectors.slides);
- var nesteds = $nesteds.get();
- return $.map(nesteds, function(slide, i) {
- return $(slide);
- });
- },
-
-
- /*
- jQuery.deck('getContainer')
-
- Returns a jQuery object containing the deck container as defined by the
- container option.
- */
- getContainer: function() {
- return $container;
- },
-
- /*
- jQuery.deck('getOptions')
-
- Returns the options object for the deck, including any overrides that
- were defined at initialization.
- */
- getOptions: function() {
- return options;
- },
-
- /*
- jQuery.deck('extend', name, method)
-
- name: string
- method: function
-
- Adds method to the deck namespace with the key of name. This doesn’t
- give access to any private member data — public methods must still be
- used within method — but lets extension authors piggyback on the deck
- namespace rather than pollute jQuery.
-
- $.deck('extend', 'alert', function(msg) {
- alert(msg);
- });
-
- // Alerts 'boom'
- $.deck('alert', 'boom');
- */
- extend: function(name, method) {
- methods[name] = method;
- }
- };
-
- /* jQuery extension */
- $.deck = function(method, arg) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (methods[method]) {
- return methods[method].apply(this, args);
- }
- else {
- return methods.init(method, arg);
- }
- };
-
- /*
- The default settings object for a deck. All deck extensions should extend
- this object to add defaults for any of their options.
-
- options.classes.after
- This class is added to all slides that appear after the 'next' slide.
-
- options.classes.before
- This class is added to all slides that appear before the 'previous'
- slide.
-
- options.classes.childCurrent
- This class is added to all elements in the DOM tree between the
- 'current' slide and the deck container. For standard slides, this is
- mostly seen and used for nested slides.
-
- options.classes.current
- This class is added to the current slide.
-
- options.classes.loading
- This class is applied to the deck container during loading phases and is
- primarily used as a way to short circuit transitions between states
- where such transitions are distracting or unwanted. For example, this
- class is applied during deck initialization and then removed to prevent
- all the slides from appearing stacked and transitioning into place
- on load.
-
- options.classes.next
- This class is added to the slide immediately following the 'current'
- slide.
-
- options.classes.onPrefix
- This prefix, concatenated with the current slide index, is added to the
- deck container as you change slides.
-
- options.classes.previous
- This class is added to the slide immediately preceding the 'current'
- slide.
-
- options.selectors.container
- Elements matched by this CSS selector will be considered the deck
- container. The deck container is used to scope certain states of the
- deck, as with the onPrefix option, or with extensions such as deck.goto
- and deck.menu.
-
- options.selectors.slides
- Elements matched by this selector make up the individual deck slides.
- If a user chooses to pass the slide selector as the first argument to
- $.deck() on initialization it does the same thing as passing in this
- option and this option value will be set to the value of that parameter.
-
- options.keys.next
- The numeric keycode used to go to the next slide.
-
- options.keys.previous
- The numeric keycode used to go to the previous slide.
-
- options.touch.swipeDirection
- The direction swipes occur to cause slide changes. Can be 'horizontal',
- 'vertical', or 'both'. Any other value or a falsy value will disable
- swipe gestures for navigation.
-
- options.touch.swipeTolerance
- The number of pixels the users finger must travel to produce a swipe
- gesture.
-
- options.initLockTimeout
- The number of milliseconds the init event will wait for BeforeInit event
- locks to be released before firing the init event regardless.
-
- options.hashPrefix
- Every slide that does not have an id is assigned one at initialization.
- Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0,
- slide-12, etc.
-
- options.preventFragmentScroll
- When deep linking to a hash of a nested slide, this scrolls the deck
- container to the top, undoing the natural browser behavior of scrolling
- to the document fragment on load.
-
- options.setAriaHiddens
- When set to true, deck.js will set aria hidden attributes for slides
- that do not appear onscreen according to a typical heirarchical
- deck structure. You may want to turn this off if you are using a theme
- where slides besides the current slide are visible on screen and should
- be accessible to screenreaders.
- */
- $.deck.defaults = {
- classes: {
- after: 'deck-after',
- before: 'deck-before',
- childCurrent: 'deck-child-current',
- current: 'deck-current',
- loading: 'deck-loading',
- next: 'deck-next',
- onPrefix: 'on-slide-',
- previous: 'deck-previous'
- },
-
- selectors: {
- container: '.deck-container',
- slides: '.slide'
- },
-
- keys: {
- // enter, space, page down, right arrow, down arrow,
- next: [13, 32, 34, 39, 40],
- // backspace, page up, left arrow, up arrow
- previous: [8, 33, 37, 38]
- },
-
- touch: {
- swipeDirection: 'horizontal',
- swipeTolerance: 60
- },
-
- initLockTimeout: 10000,
- hashPrefix: 'slide-',
- preventFragmentScroll: true,
- setAriaHiddens: true
- };
-
- $document.ready(function() {
- $('html').addClass('ready');
- });
-
- $window.bind('hashchange.deck', function(event) {
- if (event.originalEvent && event.originalEvent.newURL) {
- goByHash(event.originalEvent.newURL);
- }
- else {
- goByHash(window.location.hash);
- }
- });
-
- $window.bind('load.deck', function() {
- if (options.preventFragmentScroll) {
- $container.scrollLeft(0).scrollTop(0);
- }
- });
-})(jQuery);
-
-// Released under MIT license
-// Copyright (c) 2009-2010 Dominic Baggott
-// Copyright (c) 2009-2010 Ash Berlin
-// Copyright (c) 2011 Christoph Dorn (http://www.christophdorn.com)
-
-/*jshint browser:true, devel:true */
-
-(function( expose ) {
-
-/**
- * class Markdown
- *
- * Markdown processing in Javascript done right. We have very particular views
- * on what constitutes 'right' which include:
- *
- * - produces well-formed HTML (this means that em and strong nesting is
- * important)
- *
- * - has an intermediate representation to allow processing of parsed data (We
- * in fact have two, both as [JsonML]: a markdown tree and an HTML tree).
- *
- * - is easily extensible to add new dialects without having to rewrite the
- * entire parsing mechanics
- *
- * - has a good test suite
- *
- * This implementation fulfills all of these (except that the test suite could
- * do with expanding to automatically run all the fixtures from other Markdown
- * implementations.)
- *
- * ##### Intermediate Representation
- *
- * *TODO* Talk about this :) Its JsonML, but document the node names we use.
- *
- * [JsonML]: http://jsonml.org/ "JSON Markup Language"
- **/
-var Markdown = expose.Markdown = function(dialect) {
- switch (typeof dialect) {
- case "undefined":
- this.dialect = Markdown.dialects.Gruber;
- break;
- case "object":
- this.dialect = dialect;
- break;
- default:
- if ( dialect in Markdown.dialects ) {
- this.dialect = Markdown.dialects[dialect];
- }
- else {
- throw new Error("Unknown Markdown dialect '" + String(dialect) + "'");
- }
- break;
- }
- this.em_state = [];
- this.strong_state = [];
- this.debug_indent = "";
-};
-
-/**
- * parse( markdown, [dialect] ) -> JsonML
- * - markdown (String): markdown string to parse
- * - dialect (String | Dialect): the dialect to use, defaults to gruber
- *
- * Parse `markdown` and return a markdown document as a Markdown.JsonML tree.
- **/
-expose.parse = function( source, dialect ) {
- // dialect will default if undefined
- var md = new Markdown( dialect );
- return md.toTree( source );
-};
-
-/**
- * toHTML( markdown, [dialect] ) -> String
- * toHTML( md_tree ) -> String
- * - markdown (String): markdown string to parse
- * - md_tree (Markdown.JsonML): parsed markdown tree
- *
- * Take markdown (either as a string or as a JsonML tree) and run it through
- * [[toHTMLTree]] then turn it into a well-formated HTML fragment.
- **/
-expose.toHTML = function toHTML( source , dialect , options ) {
- var input = expose.toHTMLTree( source , dialect , options );
-
- return expose.renderJsonML( input );
-};
-
-/**
- * toHTMLTree( markdown, [dialect] ) -> JsonML
- * toHTMLTree( md_tree ) -> JsonML
- * - markdown (String): markdown string to parse
- * - dialect (String | Dialect): the dialect to use, defaults to gruber
- * - md_tree (Markdown.JsonML): parsed markdown tree
- *
- * Turn markdown into HTML, represented as a JsonML tree. If a string is given
- * to this function, it is first parsed into a markdown tree by calling
- * [[parse]].
- **/
-expose.toHTMLTree = function toHTMLTree( input, dialect , options ) {
- // convert string input to an MD tree
- if ( typeof input ==="string" ) input = this.parse( input, dialect );
-
- // Now convert the MD tree to an HTML tree
-
- // remove references from the tree
- var attrs = extract_attr( input ),
- refs = {};
-
- if ( attrs && attrs.references ) {
- refs = attrs.references;
- }
-
- var html = convert_tree_to_html( input, refs , options );
- merge_text_nodes( html );
- return html;
-};
-
-// For Spidermonkey based engines
-function mk_block_toSource() {
- return "Markdown.mk_block( " +
- uneval(this.toString()) +
- ", " +
- uneval(this.trailing) +
- ", " +
- uneval(this.lineNumber) +
- " )";
-}
-
-// node
-function mk_block_inspect() {
- var util = require("util");
- return "Markdown.mk_block( " +
- util.inspect(this.toString()) +
- ", " +
- util.inspect(this.trailing) +
- ", " +
- util.inspect(this.lineNumber) +
- " )";
-
-}
-
-var mk_block = Markdown.mk_block = function(block, trail, line) {
- // Be helpful for default case in tests.
- if ( arguments.length == 1 ) trail = "\n\n";
-
- var s = new String(block);
- s.trailing = trail;
- // To make it clear its not just a string
- s.inspect = mk_block_inspect;
- s.toSource = mk_block_toSource;
-
- if ( line != undefined )
- s.lineNumber = line;
-
- return s;
-};
-
-function count_lines( str ) {
- var n = 0, i = -1;
- while ( ( i = str.indexOf("\n", i + 1) ) !== -1 ) n++;
- return n;
-}
-
-// Internal - split source into rough blocks
-Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) {
- input = input.replace(/(\r\n|\n|\r)/g, "\n");
- // [\s\S] matches _anything_ (newline or space)
- // [^] is equivalent but doesn't work in IEs.
- var re = /([\s\S]+?)($|\n#|\n(?:\s*\n|$)+)/g,
- blocks = [],
- m;
-
- var line_no = 1;
-
- if ( ( m = /^(\s*\n)/.exec(input) ) != null ) {
- // skip (but count) leading blank lines
- line_no += count_lines( m[0] );
- re.lastIndex = m[0].length;
- }
-
- while ( ( m = re.exec(input) ) !== null ) {
- if (m[2] == "\n#") {
- m[2] = "\n";
- re.lastIndex--;
- }
- blocks.push( mk_block( m[1], m[2], line_no ) );
- line_no += count_lines( m[0] );
- }
-
- return blocks;
-};
-
-/**
- * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ]
- * - block (String): the block to process
- * - next (Array): the following blocks
- *
- * Process `block` and return an array of JsonML nodes representing `block`.
- *
- * It does this by asking each block level function in the dialect to process
- * the block until one can. Succesful handling is indicated by returning an
- * array (with zero or more JsonML nodes), failure by a false value.
- *
- * Blocks handlers are responsible for calling [[Markdown#processInline]]
- * themselves as appropriate.
- *
- * If the blocks were split incorrectly or adjacent blocks need collapsing you
- * can adjust `next` in place using shift/splice etc.
- *
- * If any of this default behaviour is not right for the dialect, you can
- * define a `__call__` method on the dialect that will get invoked to handle
- * the block processing.
- */
-Markdown.prototype.processBlock = function processBlock( block, next ) {
- var cbs = this.dialect.block,
- ord = cbs.__order__;
-
- if ( "__call__" in cbs ) {
- return cbs.__call__.call(this, block, next);
- }
-
- for ( var i = 0; i < ord.length; i++ ) {
- //D:this.debug( "Testing", ord[i] );
- var res = cbs[ ord[i] ].call( this, block, next );
- if ( res ) {
- //D:this.debug(" matched");
- if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) )
- this.debug(ord[i], "didn't return a proper array");
- //D:this.debug( "" );
- return res;
- }
- }
-
- // Uhoh! no match! Should we throw an error?
- return [];
-};
-
-Markdown.prototype.processInline = function processInline( block ) {
- return this.dialect.inline.__call__.call( this, String( block ) );
-};
-
-/**
- * Markdown#toTree( source ) -> JsonML
- * - source (String): markdown source to parse
- *
- * Parse `source` into a JsonML tree representing the markdown document.
- **/
-// custom_tree means set this.tree to `custom_tree` and restore old value on return
-Markdown.prototype.toTree = function toTree( source, custom_root ) {
- var blocks = source instanceof Array ? source : this.split_blocks( source );
-
- // Make tree a member variable so its easier to mess with in extensions
- var old_tree = this.tree;
- try {
- this.tree = custom_root || this.tree || [ "markdown" ];
-
- blocks:
- while ( blocks.length ) {
- var b = this.processBlock( blocks.shift(), blocks );
-
- // Reference blocks and the like won't return any content
- if ( !b.length ) continue blocks;
-
- this.tree.push.apply( this.tree, b );
- }
- return this.tree;
- }
- finally {
- if ( custom_root ) {
- this.tree = old_tree;
- }
- }
-};
-
-// Noop by default
-Markdown.prototype.debug = function () {
- var args = Array.prototype.slice.call( arguments);
- args.unshift(this.debug_indent);
- if ( typeof print !== "undefined" )
- print.apply( print, args );
- if ( typeof console !== "undefined" && typeof console.log !== "undefined" )
- console.log.apply( null, args );
-}
-
-Markdown.prototype.loop_re_over_block = function( re, block, cb ) {
- // Dont use /g regexps with this
- var m,
- b = block.valueOf();
-
- while ( b.length && (m = re.exec(b) ) != null ) {
- b = b.substr( m[0].length );
- cb.call(this, m);
- }
- return b;
-};
-
-/**
- * Markdown.dialects
- *
- * Namespace of built-in dialects.
- **/
-Markdown.dialects = {};
-
-/**
- * Markdown.dialects.Gruber
- *
- * The default dialect that follows the rules set out by John Gruber's
- * markdown.pl as closely as possible. Well actually we follow the behaviour of
- * that script which in some places is not exactly what the syntax web page
- * says.
- **/
-Markdown.dialects.Gruber = {
- block: {
- atxHeader: function atxHeader( block, next ) {
- var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ );
-
- if ( !m ) return undefined;
-
- var header = [ "header", { level: m[ 1 ].length } ];
- Array.prototype.push.apply(header, this.processInline(m[ 2 ]));
-
- if ( m[0].length < block.length )
- next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
-
- return [ header ];
- },
-
- setextHeader: function setextHeader( block, next ) {
- var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ );
-
- if ( !m ) return undefined;
-
- var level = ( m[ 2 ] === "=" ) ? 1 : 2;
- var header = [ "header", { level : level }, m[ 1 ] ];
-
- if ( m[0].length < block.length )
- next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
-
- return [ header ];
- },
-
- code: function code( block, next ) {
- // | Foo
- // |bar
- // should be a code block followed by a paragraph. Fun
- //
- // There might also be adjacent code block to merge.
-
- var ret = [],
- re = /^(?: {0,3}\t| {4})(.*)\n?/,
- lines;
-
- // 4 spaces + content
- if ( !block.match( re ) ) return undefined;
-
- block_search:
- do {
- // Now pull out the rest of the lines
- var b = this.loop_re_over_block(
- re, block.valueOf(), function( m ) { ret.push( m[1] ); } );
-
- if ( b.length ) {
- // Case alluded to in first comment. push it back on as a new block
- next.unshift( mk_block(b, block.trailing) );
- break block_search;
- }
- else if ( next.length ) {
- // Check the next block - it might be code too
- if ( !next[0].match( re ) ) break block_search;
-
- // Pull how how many blanks lines follow - minus two to account for .join
- ret.push ( block.trailing.replace(/[^\n]/g, "").substring(2) );
-
- block = next.shift();
- }
- else {
- break block_search;
- }
- } while ( true );
-
- return [ [ "code_block", ret.join("\n") ] ];
- },
-
- horizRule: function horizRule( block, next ) {
- // this needs to find any hr in the block to handle abutting blocks
- var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ );
-
- if ( !m ) {
- return undefined;
- }
-
- var jsonml = [ [ "hr" ] ];
-
- // if there's a leading abutting block, process it
- if ( m[ 1 ] ) {
- jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) );
- }
-
- // if there's a trailing abutting block, stick it into next
- if ( m[ 3 ] ) {
- next.unshift( mk_block( m[ 3 ] ) );
- }
-
- return jsonml;
- },
-
- // There are two types of lists. Tight and loose. Tight lists have no whitespace
- // between the items (and result in text just in the
) and loose lists,
- // which have an empty line between list items, resulting in (one or more)
- // paragraphs inside the
.
- //
- // There are all sorts weird edge cases about the original markdown.pl's
- // handling of lists:
- //
- // * Nested lists are supposed to be indented by four chars per level. But
- // if they aren't, you can get a nested list by indenting by less than
- // four so long as the indent doesn't match an indent of an existing list
- // item in the 'nest stack'.
- //
- // * The type of the list (bullet or number) is controlled just by the
- // first item at the indent. Subsequent changes are ignored unless they
- // are for nested lists
- //
- lists: (function( ) {
- // Use a closure to hide a few variables.
- var any_list = "[*+-]|\\d+\\.",
- bullet_list = /[*+-]/,
- number_list = /\d+\./,
- // Capture leading indent as it matters for determining nested lists.
- is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ),
- indent_re = "(?: {0,3}\\t| {4})";
-
- // TODO: Cache this regexp for certain depths.
- // Create a regexp suitable for matching an li for a given stack depth
- function regex_for_depth( depth ) {
-
- return new RegExp(
- // m[1] = indent, m[2] = list_type
- "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" +
- // m[3] = cont
- "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})"
- );
- }
- function expand_tab( input ) {
- return input.replace( / {0,3}\t/g, " " );
- }
-
- // Add inline content `inline` to `li`. inline comes from processInline
- // so is an array of content
- function add(li, loose, inline, nl) {
- if ( loose ) {
- li.push( [ "para" ].concat(inline) );
- return;
- }
- // Hmmm, should this be any block level element or just paras?
- var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para"
- ? li[li.length -1]
- : li;
-
- // If there is already some content in this list, add the new line in
- if ( nl && li.length > 1 ) inline.unshift(nl);
-
- for ( var i = 0; i < inline.length; i++ ) {
- var what = inline[i],
- is_str = typeof what == "string";
- if ( is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) {
- add_to[ add_to.length-1 ] += what;
- }
- else {
- add_to.push( what );
- }
- }
- }
-
- // contained means have an indent greater than the current one. On
- // *every* line in the block
- function get_contained_blocks( depth, blocks ) {
-
- var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ),
- replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"),
- ret = [];
-
- while ( blocks.length > 0 ) {
- if ( re.exec( blocks[0] ) ) {
- var b = blocks.shift(),
- // Now remove that indent
- x = b.replace( replace, "");
-
- ret.push( mk_block( x, b.trailing, b.lineNumber ) );
- }
- else {
- break;
- }
- }
- return ret;
- }
-
- // passed to stack.forEach to turn list items up the stack into paras
- function paragraphify(s, i, stack) {
- var list = s.list;
- var last_li = list[list.length-1];
-
- if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
- return;
- }
- if ( i + 1 == stack.length ) {
- // Last stack frame
- // Keep the same array, but replace the contents
- last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ) );
- }
- else {
- var sublist = last_li.pop();
- last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
- }
- }
-
- // The matcher function
- return function( block, next ) {
- var m = block.match( is_list_re );
- if ( !m ) return undefined;
-
- function make_list( m ) {
- var list = bullet_list.exec( m[2] )
- ? ["bulletlist"]
- : ["numberlist"];
-
- stack.push( { list: list, indent: m[1] } );
- return list;
- }
-
-
- var stack = [], // Stack of lists for nesting.
- list = make_list( m ),
- last_li,
- loose = false,
- ret = [ stack[0].list ],
- i;
-
- // Loop to search over block looking for inner block elements and loose lists
- loose_search:
- while ( true ) {
- // Split into lines preserving new lines at end of line
- var lines = block.split( /(?=\n)/ );
-
- // We have to grab all lines for a li and call processInline on them
- // once as there are some inline things that can span lines.
- var li_accumulate = "";
-
- // Loop over the lines in this block looking for tight lists.
- tight_search:
- for ( var line_no = 0; line_no < lines.length; line_no++ ) {
- var nl = "",
- l = lines[line_no].replace(/^\n/, function(n) { nl = n; return ""; });
-
- // TODO: really should cache this
- var line_re = regex_for_depth( stack.length );
-
- m = l.match( line_re );
- //print( "line:", uneval(l), "\nline match:", uneval(m) );
-
- // We have a list item
- if ( m[1] !== undefined ) {
- // Process the previous list item, if any
- if ( li_accumulate.length ) {
- add( last_li, loose, this.processInline( li_accumulate ), nl );
- // Loose mode will have been dealt with. Reset it
- loose = false;
- li_accumulate = "";
- }
-
- m[1] = expand_tab( m[1] );
- var wanted_depth = Math.floor(m[1].length/4)+1;
- //print( "want:", wanted_depth, "stack:", stack.length);
- if ( wanted_depth > stack.length ) {
- // Deep enough for a nested list outright
- //print ( "new nested list" );
- list = make_list( m );
- last_li.push( list );
- last_li = list[1] = [ "listitem" ];
- }
- else {
- // We aren't deep enough to be strictly a new level. This is
- // where Md.pl goes nuts. If the indent matches a level in the
- // stack, put it there, else put it one deeper then the
- // wanted_depth deserves.
- var found = false;
- for ( i = 0; i < stack.length; i++ ) {
- if ( stack[ i ].indent != m[1] ) continue;
- list = stack[ i ].list;
- stack.splice( i+1, stack.length - (i+1) );
- found = true;
- break;
- }
-
- if (!found) {
- //print("not found. l:", uneval(l));
- wanted_depth++;
- if ( wanted_depth <= stack.length ) {
- stack.splice(wanted_depth, stack.length - wanted_depth);
- //print("Desired depth now", wanted_depth, "stack:", stack.length);
- list = stack[wanted_depth-1].list;
- //print("list:", uneval(list) );
- }
- else {
- //print ("made new stack for messy indent");
- list = make_list(m);
- last_li.push(list);
- }
- }
-
- //print( uneval(list), "last", list === stack[stack.length-1].list );
- last_li = [ "listitem" ];
- list.push(last_li);
- } // end depth of shenegains
- nl = "";
- }
-
- // Add content
- if ( l.length > m[0].length ) {
- li_accumulate += nl + l.substr( m[0].length );
- }
- } // tight_search
-
- if ( li_accumulate.length ) {
- add( last_li, loose, this.processInline( li_accumulate ), nl );
- // Loose mode will have been dealt with. Reset it
- loose = false;
- li_accumulate = "";
- }
-
- // Look at the next block - we might have a loose list. Or an extra
- // paragraph for the current li
- var contained = get_contained_blocks( stack.length, next );
-
- // Deal with code blocks or properly nested lists
- if ( contained.length > 0 ) {
- // Make sure all listitems up the stack are paragraphs
- forEach( stack, paragraphify, this);
-
- last_li.push.apply( last_li, this.toTree( contained, [] ) );
- }
-
- var next_block = next[0] && next[0].valueOf() || "";
-
- if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) {
- block = next.shift();
-
- // Check for an HR following a list: features/lists/hr_abutting
- var hr = this.dialect.block.horizRule( block, next );
-
- if ( hr ) {
- ret.push.apply(ret, hr);
- break;
- }
-
- // Make sure all listitems up the stack are paragraphs
- forEach( stack, paragraphify, this);
-
- loose = true;
- continue loose_search;
- }
- break;
- } // loose_search
-
- return ret;
- };
- })(),
-
- blockquote: function blockquote( block, next ) {
- if ( !block.match( /^>/m ) )
- return undefined;
-
- var jsonml = [];
-
- // separate out the leading abutting block, if any. I.e. in this case:
- //
- // a
- // > b
- //
- if ( block[ 0 ] != ">" ) {
- var lines = block.split( /\n/ ),
- prev = [],
- line_no = block.lineNumber;
-
- // keep shifting lines until you find a crotchet
- while ( lines.length && lines[ 0 ][ 0 ] != ">" ) {
- prev.push( lines.shift() );
- line_no++;
- }
-
- var abutting = mk_block( prev.join( "\n" ), "\n", block.lineNumber );
- jsonml.push.apply( jsonml, this.processBlock( abutting, [] ) );
- // reassemble new block of just block quotes!
- block = mk_block( lines.join( "\n" ), block.trailing, line_no );
- }
-
-
- // if the next block is also a blockquote merge it in
- while ( next.length && next[ 0 ][ 0 ] == ">" ) {
- var b = next.shift();
- block = mk_block( block + block.trailing + b, b.trailing, block.lineNumber );
- }
-
- // Strip off the leading "> " and re-process as a block.
- var input = block.replace( /^> ?/gm, "" ),
- old_tree = this.tree,
- processedBlock = this.toTree( input, [ "blockquote" ] ),
- attr = extract_attr( processedBlock );
-
- // If any link references were found get rid of them
- if ( attr && attr.references ) {
- delete attr.references;
- // And then remove the attribute object if it's empty
- if ( isEmpty( attr ) ) {
- processedBlock.splice( 1, 1 );
- }
- }
-
- jsonml.push( processedBlock );
- return jsonml;
- },
-
- referenceDefn: function referenceDefn( block, next) {
- var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/;
- // interesting matches are [ , ref_id, url, , title, title ]
-
- if ( !block.match(re) )
- return undefined;
-
- // make an attribute node if it doesn't exist
- if ( !extract_attr( this.tree ) ) {
- this.tree.splice( 1, 0, {} );
- }
-
- var attrs = extract_attr( this.tree );
-
- // make a references hash if it doesn't exist
- if ( attrs.references === undefined ) {
- attrs.references = {};
- }
-
- var b = this.loop_re_over_block(re, block, function( m ) {
-
- if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
- m[2] = m[2].substring( 1, m[2].length - 1 );
-
- var ref = attrs.references[ m[1].toLowerCase() ] = {
- href: m[2]
- };
-
- if ( m[4] !== undefined )
- ref.title = m[4];
- else if ( m[5] !== undefined )
- ref.title = m[5];
-
- } );
-
- if ( b.length )
- next.unshift( mk_block( b, block.trailing ) );
-
- return [];
- },
-
- para: function para( block, next ) {
- // everything's a para!
- return [ ["para"].concat( this.processInline( block ) ) ];
- }
- }
-};
-
-Markdown.dialects.Gruber.inline = {
-
- __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) {
- var m,
- res,
- lastIndex = 0;
-
- patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__;
- var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" );
-
- m = re.exec( text );
- if (!m) {
- // Just boring text
- return [ text.length, text ];
- }
- else if ( m[1] ) {
- // Some un-interesting text matched. Return that first
- return [ m[1].length, m[1] ];
- }
-
- var res;
- if ( m[2] in this.dialect.inline ) {
- res = this.dialect.inline[ m[2] ].call(
- this,
- text.substr( m.index ), m, previous_nodes || [] );
- }
- // Default for now to make dev easier. just slurp special and output it.
- res = res || [ m[2].length, m[2] ];
- return res;
- },
-
- __call__: function inline( text, patterns ) {
-
- var out = [],
- res;
-
- function add(x) {
- //D:self.debug(" adding output", uneval(x));
- if ( typeof x == "string" && typeof out[out.length-1] == "string" )
- out[ out.length-1 ] += x;
- else
- out.push(x);
- }
-
- while ( text.length > 0 ) {
- res = this.dialect.inline.__oneElement__.call(this, text, patterns, out );
- text = text.substr( res.shift() );
- forEach(res, add )
- }
-
- return out;
- },
-
- // These characters are intersting elsewhere, so have rules for them so that
- // chunks of plain text blocks don't include them
- "]": function () {},
- "}": function () {},
-
- __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
-
- "\\": function escaped( text ) {
- // [ length of input processed, node/children to add... ]
- // Only esacape: \ ` * _ { } [ ] ( ) # * + - . !
- if ( this.dialect.inline.__escape__.exec( text ) )
- return [ 2, text.charAt( 1 ) ];
- else
- // Not an esacpe
- return [ 1, "\\" ];
- },
-
- "
- // 1 2 3 4 <--- captures
- var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ );
-
- if ( m ) {
- if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
- m[2] = m[2].substring( 1, m[2].length - 1 );
-
- m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0];
-
- var attrs = { alt: m[1], href: m[2] || "" };
- if ( m[4] !== undefined)
- attrs.title = m[4];
-
- return [ m[0].length, [ "img", attrs ] ];
- }
-
- // ![Alt text][id]
- m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ );
-
- if ( m ) {
- // We can't check if the reference is known here as it likely wont be
- // found till after. Check it in md tree->hmtl tree conversion
- return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), original: m[0] } ] ];
- }
-
- // Just consume the '!['
- return [ 2, "![" ];
- },
-
- "[": function link( text ) {
-
- var orig = String(text);
- // Inline content is possible inside `link text`
- var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" );
-
- // No closing ']' found. Just consume the [
- if ( !res ) return [ 1, "[" ];
-
- var consumed = 1 + res[ 0 ],
- children = res[ 1 ],
- link,
- attrs;
-
- // At this point the first [...] has been parsed. See what follows to find
- // out which kind of link we are (reference or direct url)
- text = text.substr( consumed );
-
- // [link text](/path/to/img.jpg "Optional title")
- // 1 2 3 <--- captures
- // This will capture up to the last paren in the block. We then pull
- // back based on if there a matching ones in the url
- // ([here](/url/(test))
- // The parens have to be balanced
- var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
- if ( m ) {
- var url = m[1];
- consumed += m[0].length;
-
- if ( url && url[0] == "<" && url[url.length-1] == ">" )
- url = url.substring( 1, url.length - 1 );
-
- // If there is a title we don't have to worry about parens in the url
- if ( !m[3] ) {
- var open_parens = 1; // One open that isn't in the capture
- for ( var len = 0; len < url.length; len++ ) {
- switch ( url[len] ) {
- case "(":
- open_parens++;
- break;
- case ")":
- if ( --open_parens == 0) {
- consumed -= url.length - len;
- url = url.substring(0, len);
- }
- break;
- }
- }
- }
-
- // Process escapes only
- url = this.dialect.inline.__call__.call( this, url, /\\/ )[0];
-
- attrs = { href: url || "" };
- if ( m[3] !== undefined)
- attrs.title = m[3];
-
- link = [ "link", attrs ].concat( children );
- return [ consumed, link ];
- }
-
- // [Alt text][id]
- // [Alt text] [id]
- m = text.match( /^\s*\[(.*?)\]/ );
-
- if ( m ) {
-
- consumed += m[ 0 ].length;
-
- // [links][] uses links as its reference
- attrs = { ref: ( m[ 1 ] || String(children) ).toLowerCase(), original: orig.substr( 0, consumed ) };
-
- link = [ "link_ref", attrs ].concat( children );
-
- // We can't check if the reference is known here as it likely wont be
- // found till after. Check it in md tree->hmtl tree conversion.
- // Store the original so that conversion can revert if the ref isn't found.
- return [ consumed, link ];
- }
-
- // [id]
- // Only if id is plain (no formatting.)
- if ( children.length == 1 && typeof children[0] == "string" ) {
-
- attrs = { ref: children[0].toLowerCase(), original: orig.substr( 0, consumed ) };
- link = [ "link_ref", attrs, children[0] ];
- return [ consumed, link ];
- }
-
- // Just consume the "["
- return [ 1, "[" ];
- },
-
-
- "<": function autoLink( text ) {
- var m;
-
- if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) {
- if ( m[3] ) {
- return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ];
-
- }
- else if ( m[2] == "mailto" ) {
- return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ];
- }
- else
- return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ];
- }
-
- return [ 1, "<" ];
- },
-
- "`": function inlineCode( text ) {
- // Inline code block. as many backticks as you like to start it
- // Always skip over the opening ticks.
- var m = text.match( /(`+)(([\s\S]*?)\1)/ );
-
- if ( m && m[2] )
- return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ];
- else {
- // TODO: No matching end code found - warn!
- return [ 1, "`" ];
- }
- },
-
- " \n": function lineBreak( text ) {
- return [ 3, [ "linebreak" ] ];
- }
-
-};
-
-// Meta Helper/generator method for em and strong handling
-function strong_em( tag, md ) {
-
- var state_slot = tag + "_state",
- other_slot = tag == "strong" ? "em_state" : "strong_state";
-
- function CloseTag(len) {
- this.len_after = len;
- this.name = "close_" + md;
- }
-
- return function ( text, orig_match ) {
-
- if ( this[state_slot][0] == md ) {
- // Most recent em is of this type
- //D:this.debug("closing", md);
- this[state_slot].shift();
-
- // "Consume" everything to go back to the recrusion in the else-block below
- return[ text.length, new CloseTag(text.length-md.length) ];
- }
- else {
- // Store a clone of the em/strong states
- var other = this[other_slot].slice(),
- state = this[state_slot].slice();
-
- this[state_slot].unshift(md);
-
- //D:this.debug_indent += " ";
-
- // Recurse
- var res = this.processInline( text.substr( md.length ) );
- //D:this.debug_indent = this.debug_indent.substr(2);
-
- var last = res[res.length - 1];
-
- //D:this.debug("processInline from", tag + ": ", uneval( res ) );
-
- var check = this[state_slot].shift();
- if ( last instanceof CloseTag ) {
- res.pop();
- // We matched! Huzzah.
- var consumed = text.length - last.len_after;
- return [ consumed, [ tag ].concat(res) ];
- }
- else {
- // Restore the state of the other kind. We might have mistakenly closed it.
- this[other_slot] = other;
- this[state_slot] = state;
-
- // We can't reuse the processed result as it could have wrong parsing contexts in it.
- return [ md.length, md ];
- }
- }
- }; // End returned function
-}
-
-Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**");
-Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__");
-Markdown.dialects.Gruber.inline["*"] = strong_em("em", "*");
-Markdown.dialects.Gruber.inline["_"] = strong_em("em", "_");
-
-
-// Build default order from insertion order.
-Markdown.buildBlockOrder = function(d) {
- var ord = [];
- for ( var i in d ) {
- if ( i == "__order__" || i == "__call__" ) continue;
- ord.push( i );
- }
- d.__order__ = ord;
-};
-
-// Build patterns for inline matcher
-Markdown.buildInlinePatterns = function(d) {
- var patterns = [];
-
- for ( var i in d ) {
- // __foo__ is reserved and not a pattern
- if ( i.match( /^__.*__$/) ) continue;
- var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" )
- .replace( /\n/, "\\n" );
- patterns.push( i.length == 1 ? l : "(?:" + l + ")" );
- }
-
- patterns = patterns.join("|");
- d.__patterns__ = patterns;
- //print("patterns:", uneval( patterns ) );
-
- var fn = d.__call__;
- d.__call__ = function(text, pattern) {
- if ( pattern != undefined ) {
- return fn.call(this, text, pattern);
- }
- else
- {
- return fn.call(this, text, patterns);
- }
- };
-};
-
-Markdown.DialectHelpers = {};
-Markdown.DialectHelpers.inline_until_char = function( text, want ) {
- var consumed = 0,
- nodes = [];
-
- while ( true ) {
- if ( text.charAt( consumed ) == want ) {
- // Found the character we were looking for
- consumed++;
- return [ consumed, nodes ];
- }
-
- if ( consumed >= text.length ) {
- // No closing char found. Abort.
- return null;
- }
-
- var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) );
- consumed += res[ 0 ];
- // Add any returned nodes.
- nodes.push.apply( nodes, res.slice( 1 ) );
- }
-}
-
-// Helper function to make sub-classing a dialect easier
-Markdown.subclassDialect = function( d ) {
- function Block() {}
- Block.prototype = d.block;
- function Inline() {}
- Inline.prototype = d.inline;
-
- return { block: new Block(), inline: new Inline() };
-};
-
-Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block );
-Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline );
-
-Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber );
-
-Markdown.dialects.Maruku.processMetaHash = function processMetaHash( meta_string ) {
- var meta = split_meta_hash( meta_string ),
- attr = {};
-
- for ( var i = 0; i < meta.length; ++i ) {
- // id: #foo
- if ( /^#/.test( meta[ i ] ) ) {
- attr.id = meta[ i ].substring( 1 );
- }
- // class: .foo
- else if ( /^\./.test( meta[ i ] ) ) {
- // if class already exists, append the new one
- if ( attr["class"] ) {
- attr["class"] = attr["class"] + meta[ i ].replace( /./, " " );
- }
- else {
- attr["class"] = meta[ i ].substring( 1 );
- }
- }
- // attribute: foo=bar
- else if ( /\=/.test( meta[ i ] ) ) {
- var s = meta[ i ].split( /\=/ );
- attr[ s[ 0 ] ] = s[ 1 ];
- }
- }
-
- return attr;
-}
-
-function split_meta_hash( meta_string ) {
- var meta = meta_string.split( "" ),
- parts = [ "" ],
- in_quotes = false;
-
- while ( meta.length ) {
- var letter = meta.shift();
- switch ( letter ) {
- case " " :
- // if we're in a quoted section, keep it
- if ( in_quotes ) {
- parts[ parts.length - 1 ] += letter;
- }
- // otherwise make a new part
- else {
- parts.push( "" );
- }
- break;
- case "'" :
- case '"' :
- // reverse the quotes and move straight on
- in_quotes = !in_quotes;
- break;
- case "\\" :
- // shift off the next letter to be used straight away.
- // it was escaped so we'll keep it whatever it is
- letter = meta.shift();
- default :
- parts[ parts.length - 1 ] += letter;
- break;
- }
- }
-
- return parts;
-}
-
-Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) {
- // we're only interested in the first block
- if ( block.lineNumber > 1 ) return undefined;
-
- // document_meta blocks consist of one or more lines of `Key: Value\n`
- if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined;
-
- // make an attribute node if it doesn't exist
- if ( !extract_attr( this.tree ) ) {
- this.tree.splice( 1, 0, {} );
- }
-
- var pairs = block.split( /\n/ );
- for ( p in pairs ) {
- var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ),
- key = m[ 1 ].toLowerCase(),
- value = m[ 2 ];
-
- this.tree[ 1 ][ key ] = value;
- }
-
- // document_meta produces no content!
- return [];
-};
-
-Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) {
- // check if the last line of the block is an meta hash
- var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ );
- if ( !m ) return undefined;
-
- // process the meta hash
- var attr = this.dialect.processMetaHash( m[ 2 ] );
-
- var hash;
-
- // if we matched ^ then we need to apply meta to the previous block
- if ( m[ 1 ] === "" ) {
- var node = this.tree[ this.tree.length - 1 ];
- hash = extract_attr( node );
-
- // if the node is a string (rather than JsonML), bail
- if ( typeof node === "string" ) return undefined;
-
- // create the attribute hash if it doesn't exist
- if ( !hash ) {
- hash = {};
- node.splice( 1, 0, hash );
- }
-
- // add the attributes in
- for ( a in attr ) {
- hash[ a ] = attr[ a ];
- }
-
- // return nothing so the meta hash is removed
- return [];
- }
-
- // pull the meta hash off the block and process what's left
- var b = block.replace( /\n.*$/, "" ),
- result = this.processBlock( b, [] );
-
- // get or make the attributes hash
- hash = extract_attr( result[ 0 ] );
- if ( !hash ) {
- hash = {};
- result[ 0 ].splice( 1, 0, hash );
- }
-
- // attach the attributes to the block
- for ( a in attr ) {
- hash[ a ] = attr[ a ];
- }
-
- return result;
-};
-
-Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) {
- // one or more terms followed by one or more definitions, in a single block
- var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/,
- list = [ "dl" ],
- i, m;
-
- // see if we're dealing with a tight or loose block
- if ( ( m = block.match( tight ) ) ) {
- // pull subsequent tight DL blocks out of `next`
- var blocks = [ block ];
- while ( next.length && tight.exec( next[ 0 ] ) ) {
- blocks.push( next.shift() );
- }
-
- for ( var b = 0; b < blocks.length; ++b ) {
- var m = blocks[ b ].match( tight ),
- terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ),
- defns = m[ 2 ].split( /\n:\s+/ );
-
- // print( uneval( m ) );
-
- for ( i = 0; i < terms.length; ++i ) {
- list.push( [ "dt", terms[ i ] ] );
- }
-
- for ( i = 0; i < defns.length; ++i ) {
- // run inline processing over the definition
- list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) );
- }
- }
- }
- else {
- return undefined;
- }
-
- return [ list ];
-};
-
-// splits on unescaped instances of @ch. If @ch is not a character the result
-// can be unpredictable
-
-Markdown.dialects.Maruku.block.table = function table (block, next) {
-
- var _split_on_unescaped = function(s, ch) {
- ch = ch || '\\s';
- if (ch.match(/^[\\|\[\]{}?*.+^$]$/)) { ch = '\\' + ch; }
- var res = [ ],
- r = new RegExp('^((?:\\\\.|[^\\\\' + ch + '])*)' + ch + '(.*)'),
- m;
- while(m = s.match(r)) {
- res.push(m[1]);
- s = m[2];
- }
- res.push(s);
- return res;
- }
-
- var leading_pipe = /^ {0,3}\|(.+)\n {0,3}\|\s*([\-:]+[\-| :]*)\n((?:\s*\|.*(?:\n|$))*)(?=\n|$)/,
- // find at least an unescaped pipe in each line
- no_leading_pipe = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)\n {0,3}([\-:]+\s*\|[\-| :]*)\n((?:(?:\\.|[^\\|])*\|.*(?:\n|$))*)(?=\n|$)/,
- i, m;
- if (m = block.match(leading_pipe)) {
- // remove leading pipes in contents
- // (header and horizontal rule already have the leading pipe left out)
- m[3] = m[3].replace(/^\s*\|/gm, '');
- } else if (! ( m = block.match(no_leading_pipe))) {
- return undefined;
- }
-
- var table = [ "table", [ "thead", [ "tr" ] ], [ "tbody" ] ];
-
- // remove trailing pipes, then split on pipes
- // (no escaped pipes are allowed in horizontal rule)
- m[2] = m[2].replace(/\|\s*$/, '').split('|');
-
- // process alignment
- var html_attrs = [ ];
- forEach (m[2], function (s) {
- if (s.match(/^\s*-+:\s*$/)) html_attrs.push({align: "right"});
- else if (s.match(/^\s*:-+\s*$/)) html_attrs.push({align: "left"});
- else if (s.match(/^\s*:-+:\s*$/)) html_attrs.push({align: "center"});
- else html_attrs.push({});
- });
-
- // now for the header, avoid escaped pipes
- m[1] = _split_on_unescaped(m[1].replace(/\|\s*$/, ''), '|');
- for (i = 0; i < m[1].length; i++) {
- table[1][1].push(['th', html_attrs[i] || {}].concat(
- this.processInline(m[1][i].trim())));
- }
-
- // now for body contents
- forEach (m[3].replace(/\|\s*$/mg, '').split('\n'), function (row) {
- var html_row = ['tr'];
- row = _split_on_unescaped(row, '|');
- for (i = 0; i < row.length; i++) {
- html_row.push(['td', html_attrs[i] || {}].concat(this.processInline(row[i].trim())));
- }
- table[2].push(html_row);
- }, this);
-
- return [table];
-}
-
-Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) {
- if ( !out.length ) {
- return [ 2, "{:" ];
- }
-
- // get the preceeding element
- var before = out[ out.length - 1 ];
-
- if ( typeof before === "string" ) {
- return [ 2, "{:" ];
- }
-
- // match a meta hash
- var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ );
-
- // no match, false alarm
- if ( !m ) {
- return [ 2, "{:" ];
- }
-
- // attach the attributes to the preceeding element
- var meta = this.dialect.processMetaHash( m[ 1 ] ),
- attr = extract_attr( before );
-
- if ( !attr ) {
- attr = {};
- before.splice( 1, 0, attr );
- }
-
- for ( var k in meta ) {
- attr[ k ] = meta[ k ];
- }
-
- // cut out the string and replace it with nothing
- return [ m[ 0 ].length, "" ];
-};
-
-Markdown.dialects.Maruku.inline.__escape__ = /^\\[\\`\*_{}\[\]()#\+.!\-|:]/;
-
-Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block );
-Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline );
-
-var isArray = Array.isArray || function(obj) {
- return Object.prototype.toString.call(obj) == "[object Array]";
-};
-
-var forEach;
-// Don't mess with Array.prototype. Its not friendly
-if ( Array.prototype.forEach ) {
- forEach = function( arr, cb, thisp ) {
- return arr.forEach( cb, thisp );
- };
-}
-else {
- forEach = function(arr, cb, thisp) {
- for (var i = 0; i < arr.length; i++) {
- cb.call(thisp || arr, arr[i], i, arr);
- }
- }
-}
-
-var isEmpty = function( obj ) {
- for ( var key in obj ) {
- if ( hasOwnProperty.call( obj, key ) ) {
- return false;
- }
- }
-
- return true;
-}
-
-function extract_attr( jsonml ) {
- return isArray(jsonml)
- && jsonml.length > 1
- && typeof jsonml[ 1 ] === "object"
- && !( isArray(jsonml[ 1 ]) )
- ? jsonml[ 1 ]
- : undefined;
-}
-
-
-
-/**
- * renderJsonML( jsonml[, options] ) -> String
- * - jsonml (Array): JsonML array to render to XML
- * - options (Object): options
- *
- * Converts the given JsonML into well-formed XML.
- *
- * The options currently understood are:
- *
- * - root (Boolean): wether or not the root node should be included in the
- * output, or just its children. The default `false` is to not include the
- * root itself.
- */
-expose.renderJsonML = function( jsonml, options ) {
- options = options || {};
- // include the root element in the rendered output?
- options.root = options.root || false;
-
- var content = [];
-
- if ( options.root ) {
- content.push( render_tree( jsonml ) );
- }
- else {
- jsonml.shift(); // get rid of the tag
- if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
- jsonml.shift(); // get rid of the attributes
- }
-
- while ( jsonml.length ) {
- content.push( render_tree( jsonml.shift() ) );
- }
- }
-
- return content.join( "\n\n" );
-};
-
-function escapeHTML( text ) {
- return text.replace( /&/g, "&" )
- .replace( /
/g, ">" )
- .replace( /"/g, """ )
- .replace( /'/g, "'" );
-}
-
-function render_tree( jsonml ) {
- // basic case
- if ( typeof jsonml === "string" ) {
- return jsonml; // modified for deck.smarkdown.js
- }
-
- var tag = jsonml.shift(),
- attributes = {},
- content = [];
-
- if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
- attributes = jsonml.shift();
- }
-
- while ( jsonml.length ) {
- content.push( render_tree( jsonml.shift() ) );
- }
-
- var tag_attrs = "";
- for ( var a in attributes ) {
- tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
- }
-
- // be careful about adding whitespace here for inline elements
- if ( tag == "img" || tag == "br" || tag == "hr" ) {
- return "<"+ tag + tag_attrs + "/>";
- }
- else {
- return "<"+ tag + tag_attrs + ">" + content.join( "" ) + "" + tag + ">";
- }
-}
-
-function convert_tree_to_html( tree, references, options ) {
- var i;
- options = options || {};
-
- // shallow clone
- var jsonml = tree.slice( 0 );
-
- if ( typeof options.preprocessTreeNode === "function" ) {
- jsonml = options.preprocessTreeNode(jsonml, references);
- }
-
- // Clone attributes if they exist
- var attrs = extract_attr( jsonml );
- if ( attrs ) {
- jsonml[ 1 ] = {};
- for ( i in attrs ) {
- jsonml[ 1 ][ i ] = attrs[ i ];
- }
- attrs = jsonml[ 1 ];
- }
-
- // basic case
- if ( typeof jsonml === "string" ) {
- return jsonml;
- }
-
- // convert this node
- switch ( jsonml[ 0 ] ) {
- case "header":
- jsonml[ 0 ] = "h" + jsonml[ 1 ].level;
- delete jsonml[ 1 ].level;
- break;
- case "bulletlist":
- jsonml[ 0 ] = "ul";
- break;
- case "numberlist":
- jsonml[ 0 ] = "ol";
- break;
- case "listitem":
- jsonml[ 0 ] = "li";
- break;
- case "para":
- jsonml[ 0 ] = "p";
- break;
- case "markdown":
- jsonml[ 0 ] = "html";
- if ( attrs ) delete attrs.references;
- break;
- case "code_block":
- jsonml[ 0 ] = "pre";
- i = attrs ? 2 : 1;
- var code = [ "code" ];
- code.push.apply( code, jsonml.splice( i, jsonml.length - i ) );
- jsonml[ i ] = code;
- break;
- case "inlinecode":
- jsonml[ 0 ] = "code";
- break;
- case "img":
- jsonml[ 1 ].src = jsonml[ 1 ].href;
- delete jsonml[ 1 ].href;
- break;
- case "linebreak":
- jsonml[ 0 ] = "br";
- break;
- case "link":
- jsonml[ 0 ] = "a";
- break;
- case "link_ref":
- jsonml[ 0 ] = "a";
-
- // grab this ref and clean up the attribute node
- var ref = references[ attrs.ref ];
-
- // if the reference exists, make the link
- if ( ref ) {
- delete attrs.ref;
-
- // add in the href and title, if present
- attrs.href = ref.href;
- if ( ref.title ) {
- attrs.title = ref.title;
- }
-
- // get rid of the unneeded original text
- delete attrs.original;
- }
- // the reference doesn't exist, so revert to plain text
- else {
- return attrs.original;
- }
- break;
- case "img_ref":
- jsonml[ 0 ] = "img";
-
- // grab this ref and clean up the attribute node
- var ref = references[ attrs.ref ];
-
- // if the reference exists, make the link
- if ( ref ) {
- delete attrs.ref;
-
- // add in the href and title, if present
- attrs.src = ref.href;
- if ( ref.title ) {
- attrs.title = ref.title;
- }
-
- // get rid of the unneeded original text
- delete attrs.original;
- }
- // the reference doesn't exist, so revert to plain text
- else {
- return attrs.original;
- }
- break;
- }
-
- // convert all the children
- i = 1;
-
- // deal with the attribute node, if it exists
- if ( attrs ) {
- // if there are keys, skip over it
- for ( var key in jsonml[ 1 ] ) {
- i = 2;
- break;
- }
- // if there aren't, remove it
- if ( i === 1 ) {
- jsonml.splice( i, 1 );
- }
- }
-
- for ( ; i < jsonml.length; ++i ) {
- jsonml[ i ] = convert_tree_to_html( jsonml[ i ], references, options );
- }
-
- return jsonml;
-}
-
-
-// merges adjacent text nodes into a single node
-function merge_text_nodes( jsonml ) {
- // skip the tag name and attribute hash
- var i = extract_attr( jsonml ) ? 2 : 1;
-
- while ( i < jsonml.length ) {
- // if it's a string check the next item too
- if ( typeof jsonml[ i ] === "string" ) {
- if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) {
- // merge the second string into the first and remove it
- jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ];
- }
- else {
- ++i;
- }
- }
- // if it's not a string recurse
- else {
- merge_text_nodes( jsonml[ i ] );
- ++i;
- }
- }
-}
-
-} )( (function() {
- if ( typeof exports === "undefined" ) {
- window.markdown = {};
- return window.markdown;
- }
- else {
- return exports;
- }
-} )() );
-
-/*!
-Deck JS - deck.smarkdown
-Copyright (c) 2014-2014 Rémi Emonet
-Licensed under the MIT license.
-https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
-*/
-
-/*
-This module provides a support for a shorter syntax for slides, with a syntax that is closer to plain markdown.
-TODO:
-- configurize the .smark and the default duration also
-- have a shortcut for {slide}?
-
-*/
-
-(function($, deck, undefined) {
- var $d = $(document);
- var may = function(f) {return f ? f : function() {}};
- var endsWith = function(longStr, part) {return longStr.indexOf(part, longStr.length - part.length) !== -1;}
- var REST = null;
- var startsWith = function(longStr, part) {
- if (part == "%+class:") alert(":::"+longStr+":::");
- var res = longStr.substr(0, part.length) == part;
- REST = res ? longStr.slice(part.length) : null;
- RESTRIM = res ? REST.replace(/^ */, "") : null;
- return res;
- }
- var startsWithIgnoreCase = function(longStr, part) {
- var res = longStr.substr(0, part.length).toUpperCase() == part.toUpperCase();
- REST = res ? longStr.slice(part.length) : null;
- RESTRIM = res ? REST.replace(/^ */, "") : null;
- return res;
- }
- var isArray = Array.isArray || $.isArray; // there is also an alternative in markdownjs
-
- // the animation duration is stateful across the smarkdown sections
- var animationDurationDefault = 400;
- var animationDuration = animationDurationDefault;
-
- function clone(a) { return JSON.parse(JSON.stringify(a)) }
- function findTag(tree, regexp, startAt) {
- var i = startAt || 0;
- while (i < tree.length) {
- if (isArray(tree[i]) && tree[i][0].match(regexp)) {
- return i;
- }
- i++;
- }
- return -1;
- }
- function addSpaceSeparatedAttr(o, a, c) {
- ensureHasAttributes(o);
- if (o[1][a])
- o[1][a] += " " + c;
- else
- o[1][a] = c;
- }
- function addClass(o, c) {
- addSpaceSeparatedAttr(o, 'class', c);
- }
- function hasClass(o, c) {
- if (!isObject(o[1]) || !o[1]['class']) {
- return false;
- } else {
- return o[1]['class'].match(new RegExp("\\b"+c+"\\b"));
- }
- }
- function isObject(o) {
- return !isArray(o) && typeof(o) === 'object';
- }
- function ensureHasAttributes(tree) {
- if (!isObject(tree[1])) {
- tree.splice(1, 0, {});
- return true;
- }
- return false;
- }
- function lazyGetAttributes(tree) {
- if (isObject(tree[1])) {
- return tree[1];
- } else {
- return {};
- }
- }
- function lazyUnsetAttributes(tree) {
- if (isObject(tree[1])) {
- tree.splice(1, 1);
- }
- }
- function hasIDOrClassDecoration(s) {
- return s.match(/^(.*)\{([^{}<>]*)\}$/);
- }
- function maybeProcessCopySlide(tree, index) {
- var slide = tree[index];
- ensureHasAttributes(slide);
- if (slide.length != 3) return false;
- if (slide[2][0] != "h1") return false;
- ensureHasAttributes(slide[2]);
- if (startsWithIgnoreCase(slide[2][2], "@COPY:#")) {
- var main = RESTRIM.split(/:/);
- var idOfBase = main[0];
- var animPart = main.slice(1).join(":");
- var hasAnim = ! animPart.match(/^\s*$/);
- var base = null;
- for (i in tree) {
- if (i == 0 || (i==1 && isObject(tree[1]))) continue;
- ensureHasAttributes(tree[i]);
- if (tree[i][1].id == idOfBase) {
- base = tree[i];
- break;
- }
- }
- if (base == null) { alert("pb"); return false; } // TODO should alert based on options
- var content = [["div", {}, "@anim:" + animPart]];
- content = content.concat(clone(base.slice(2)));
- slide[1] = clone(base[1]);
- delete slide[1].id;
- if (hasAnim) addClass(slide, "anim-continue");
- slide.splice.apply(slide, [2, 1].concat(content)); // replace the h1 with content
- return true;
- }
- return false;
- }
- function processIDOrClassDecoration(tree, index) {
- var matched = hasIDOrClassDecoration(tree[index]); // make sure the group is set
- if (!matched) { alert("should call processIDOrClassDecoration() only if hasIDOrClassDecoration is true"); return; }
- var returnValue = false; // whether we added the attributes
- var base = RegExp.$1;
- var decorations = RegExp.$2.split(/ +/);
- if (ensureHasAttributes(tree)) {
- if (index>0) index++;
- returnValue = true;
- }
- tree[index] = base;
- for (d in decorations) {
- // allow .class and class notations
- if (startsWith(decorations[d], ".")) decorations[d] = decorations[d].slice(1);
-
- if (startsWith(decorations[d], "#")) {
- tree[1].id = decorations[d].slice(1);
- } else {
- if (startsWith(decorations[d], "*") | startsWith(decorations[d], "/")) {
- addSpaceSeparatedAttr(tree, "data-container-class", decorations[d].slice(1));
- } else {
- addClass(tree, decorations[d]);
- }
- }
- }
- return returnValue;
- }
- function possiblyHideIfEmpty(tree) { // if it contains only anim stuf etc
- var hide = false;
- var i = isObject(tree[1]) ? 2 : 1;
- function onlyDivAnims(tt) {
- var only = true;
- var start = isObject(tt[1]) ? 2 : 1;
- tt.slice(start).forEach(function(e) {
- if (!isArray(e) || !isObject(e[1]) || (" "+e[1]["class"]).indexOf(" anim-") == -1) {
- only = false;
- }
- });
- return only;
- }
-
- if (onlyDivAnims(tree)) hide = true;
- else if (tree.length == i+1 && isArray(tree[i]) && tree[i][0] == "p"
- && onlyDivAnims(tree[i])) hide = true;
- if (hide) {
- ensureHasAttributes(tree);
- tree[1].style = "display: none";
- }
- }
- function maybeProcessComment(tree, index) {
- var line = tree[index];
- var clean = function(s) { return s;}; //return s.replace(/\/\\\//g, '//'); };
- if (line.match(/^(.*?)[\n\s]*\/\/ +(.*)/)) {
- var obj = ["div", {
- 'class': "comment"
- }, clean(RegExp.$2)];
- tree.splice(index, 1, RegExp.$1, obj);
- return true;
- }
- tree[index] = clean(tree[index]);
- return false;
- }
- function maybeProcessAtSomething(tree, index) {
- var line = tree[index];
- if (startsWithIgnoreCase(line, "@SVG:")) {
- var content = RESTRIM
- var parts = content.split(/ +/);
- if (hasIDOrClassDecoration(content) || parts.length == 3) {
- // new version
- var obj = ["div", {
- 'data-src': parts[0],
- 'data-width': parts[1],
- 'data-height': parts[2],
- 'class': "svg-object"
- }, parts.slice(3).join(" ")];
- // TODO: alert when wrong number of args
- if (hasIDOrClassDecoration(content)) processIDOrClassDecoration(obj, 2);
- tree[index] = obj;
- } else {
- // TODO allow this only when an option is set option
- // old, smartsyntax version
- var obj = ["div", {
- 'data-src': parts[1],
- 'data-width': parts[2],
- 'data-height': parts[3],
- 'class': "svg-object"
- }, ""];
- parts[0].split(/,/).forEach(function (p) { addClass(obj, p); });
- tree[index] = obj;
- }
- } else if (startsWithIgnoreCase(line, "@ANIM:")) {
- line = RESTRIM.replace(/%[+]/i, "%%"); // protect the "%+class" from being split
- var allToAdd = [];
- var parts = line.split(/ *\| */); // TODO: configurize + reconsider all separators?
- for (i in parts) {
- // process each group of simultaneous animations
- var subparts = parts[i].split(/ *\+ */);
- for (ii in subparts) {
- var what = subparts[ii];
- 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)
- var continuating = ii != subparts.length-1;
- var toAdd = ["div", {}, ""];
- addClass(toAdd, "slide");
- // process the individual element (reminder: animationDuration is global)
- function dw() { addSpaceSeparatedAttr(toAdd, "data-what", REST); }
- function dd() { addSpaceSeparatedAttr(toAdd, "data-dur", ""+animationDuration); }
- if (startsWithIgnoreCase(what, "%duration:")) {
- animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
- continue;
- } else if (startsWithIgnoreCase(what, "%dur:")) {
- animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
- continue;
- } else if (startsWithIgnoreCase(what, "%play:")) {
- addClass(toAdd, "anim-play");
- dw();
- } else if (startsWithIgnoreCase(what, "%pause:")) {
- addClass(toAdd, "anim-pause");
- dw();
- } else if (startsWith(what, "%viewbox:")) {
- addClass(toAdd, "anim-viewboxas");
- // TODO: if REST contains ':', two params (then the target is specified, else it is just all SVGs root elements)
- addSpaceSeparatedAttr(toAdd, "data-as", REST);
- addSpaceSeparatedAttr(toAdd, "data-what", "svg");
- dd();
- } else if (startsWith(what, "%attr:")) {
- var main = RESTRIM.split(/ *: */);
- addClass(toAdd, "anim-attribute");
- addSpaceSeparatedAttr(toAdd, "data-what", main[0]);
- addSpaceSeparatedAttr(toAdd, "data-attr", main.slice(1).join(":"));
- dd();
- } else if (startsWith(what, "%along:")) {
- var main = RESTRIM.split(/ *: */);
- addClass(toAdd, "anim-along");
- if (startsWith(main[0], "-")) {
- main[0] = RESTRIM;
- addSpaceSeparatedAttr(toAdd, "data-reverse", "true");
- }
- addSpaceSeparatedAttr(toAdd, "data-path", main[0]);
- addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
- dd();
- } else if (startsWith(what, "%%class:")) {
- var main = RESTRIM.split(/ *: */);
- addClass(toAdd, "anim-addclass");
- addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
- addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
- } else if (startsWith(what, "%-class:")) {
- var main = RESTRIM.split(/ *: */);
- addClass(toAdd, "anim-removeclass");
- addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
- addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
- } else if (startsWith(what, "+")) {
- addClass(toAdd, "anim-show");
- dw();
- } else if (startsWith(what, "-")) {
- addClass(toAdd, "anim-hide");
- dw(); dd();
- } else {
- addClass(toAdd, "anim-show");
- addSpaceSeparatedAttr(toAdd, "data-what", what);
- dd();
- }
- if (continuating) addClass(toAdd, "anim-continue");
- allToAdd.push(toAdd);
- }
- }
- tree.splice.apply(tree, [index, 1].concat(allToAdd)); // just replacing the text with allToAdd elements
- } else {
- return false;
- }
- // TODO? handle the decorations for comments
- return true;
- }
- function processMath(content) {
- return content.replace(/\$([^$][^$]*)\$/g, '\\displaystyle $1').replace(/\$\$/, '$');
- }
-
- var interpretationOfSmartLanguage = function(smark, doc) {
- var jstree = markdown.toHTMLTree(smark);
-
- // split at each h2 or h1
- (function makeTopLevelDivs(jsTree) {
- var firstIndex = findTag(jsTree, /^(h1|h2)$/);
- if (firstIndex == -1) return;
- var secondIndex = findTag(jsTree, /^(h1|h2)$/, firstIndex+1);
- if (secondIndex == -1) secondIndex = jsTree.length;
- var slide = ["section"].concat( // we will add the 'slide' class later below
- jsTree.splice(firstIndex, secondIndex - firstIndex));
- jsTree.splice(firstIndex, 0, slide);
- makeTopLevelDivs(jsTree);
- })(jstree);
-
- // process:
- // - the class and id decorations like {#first hightlight slide}
- // - the @... custom notations
- // - the // for comments
- for (s in jstree) {
- if (s == 0 || (s==1 && isObject(jstree[1]))) continue;
- var slide = jstree[s];
- ensureHasAttributes(slide);
- if (maybeProcessCopySlide(jstree, s)) {
- //continue;
- // actually we want to apply anims to it
- }
- // 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)
- (function patch(tree){ // tree is slide or a subelement
- var i = 1;
- while (i < tree.length) {
- if (isArray(tree[i])) {
- if (tree[i][0] === "li") {
- var li = tree[i];
- if (isArray(li[1]) && li[1][0] === "p") {
- li.splice.apply(li, [1, 1].concat(li[1].slice(1)));
- continue;
- }
- }
- patch(tree[i]);
- }
- i++;
- }
- })(slide);
- // process @anim... and {} decoration
- (function patch(tree){ // tree is slide or a subelement
- var i = 1;
- while (i < tree.length) {
- if (isArray(tree[i])) patch(tree[i]);
- else if (typeof(tree[i]) == 'string') {
- if (maybeProcessComment(tree, i)) continue;
- else if (maybeProcessAtSomething(tree, i)) continue;
- else if (hasIDOrClassDecoration(tree[i])) {
- if (processIDOrClassDecoration(tree, i)) {
- i++; // avoid processing the same element twice
- }
- }
- }
- i++;
- }
- })(slide);
- // cleanup: hide empty "li" after @anim processing
- (function patch(tree){ // tree is slide or a subelement
- var i = 1;
- while (i < tree.length) {
- if (isArray(tree[i])) {
- if (tree[i][0] === "li" && possiblyHideIfEmpty(tree[i])) continue;
- else patch(tree[i]);
- }
- i++;
- }
- })(slide);
- // process the $math$
- (function patch(tree){ // tree is slide or a subelement
- if (hasClass(tree, "smark-nomath")) return;
- var i = 1;
- while (i < tree.length) {
- if (isArray(tree[i])) patch(tree[i]);
- else if (typeof(tree[i]) == 'string') {
- tree[i] = processMath(tree[i]);
- }
- i++;
- }
- })(slide);
- // change things to textarea (to help with codemirror) https://github.com/iros/deck.js-codemirror/issues/19
- (function patch(tree){ // tree is slide or a subelement
- if (hasClass(tree, "smark-textarea")) {
- tree[3][0] = "textarea";
- }
- var i = 1;
- while (i < tree.length) {
- if (isArray(tree[i])) patch(tree[i]);
- i++;
- }
- })(slide);
- // now propagate to the slide
- var hAttributes = lazyGetAttributes(slide[2]);
- if (slide[1]['class']) {
- var cl = slide[1]['class'];
- slide[1] = clone(hAttributes);
- addClass(slide, cl);
- } else {
- slide[1] = clone(hAttributes);
- }
- lazyUnsetAttributes(slide[2]);
- addClass(slide, 'slide');
- }
-
- return markdown.renderJsonML(jstree);
- }
-
- // this have to be executed before the deck init
- $d.bind('deck.beforeInit', function() {
- $('.smark').each(function() { // TODO make it configurable
- var it = this;
- var slides = interpretationOfSmartLanguage(it.innerHTML, document);
- $(it).after(slides);
- // remove the smart node (to avoid having an empty non-slide sibling (e.g., in the presenter view))
- $(it).remove();
- });
- var opts = $[deck]('getOptions');
- var maybe = function(f) { return f || (function(){}); }
- maybe(opts.AFTERSMARKDOWN)();
- $[deck]('reInitSlidesArray')
- });
-
-})(jQuery, 'deck');
-
-/*!
- Deck JS - deck.fit
- Copyright (c) 2012 Rémi Emonet
- Licensed under the MIT license.
- https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
-*/
-
-/*
- This extension provides a way of scaling the slides to fit the slide container.
- A "design size" is used to do global scaling of all slides in the same way.
- The default design size is 800x600.
-*/
-(function($, deck, window, undefined) {
- var $d = $(document),
- $w = $(window),
- timer, // Timeout id for debouncing
- rootSlides,
-
- /*
- Internal function to do all the dirty work of scaling the slides.
- */
- scaleDeck = function() {
- var opts = $[deck]('getOptions');
- var addMarginX = opts.fitMarginX * 2;
- var addMarginY = opts.fitMarginY * 2;
- var fitMode = opts.fitMode;
- var sdw = opts.designWidth;
- var sdh = opts.designHeight;
- var $container = $[deck]('getContainer');
- var scaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw+addMarginX) : 1;
- var scaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh+addMarginY) : 1;
- //var truescaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw) : 1;
- //var truescaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh) : 1;
- var scale = scaleX < scaleY ? scaleX : scaleY;
- var rootSlides = [];
- var slideTest = $.map([opts.classes.before, opts.classes.previous, opts.classes.current, opts.classes.next, opts.classes.after],
- function(el, i) {return '.' + el;}).join(', ');
-
- $.each($[deck]('getSlides'), function(i, $el) {
- if (!$el.parentsUntil(opts.selectors.container).length) {
- rootSlides.push($el);
- }
- });
- $.each(rootSlides, function(i, $slide) {
- $slide.css('width', sdw);
- $slide.css('height', sdh);
- $.each('Webkit Moz O ms Khtml'.split(' '), function(i, prefix) {
- if (scale == 1) {
- $slide.css(prefix + 'Transform', '');
- } else {
- if (fitMode == "left top" || fitMode == "top left") {
- // ok align left/top (ok with the percents)
- $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%,50%) translate('+(addMarginX/2)+'px,'+(addMarginY/2)+'px)');
- } else if (fitMode == "center middle") {
- // ok align center/middle
- $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)');
- } else if (fitMode == "right bottom" || fitMode == "bottom right") {
- // ok align right/bottom
- $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)');
- } else if (fitMode == "stretched") {
- // ok stretched (with respect of the margin, i.e., it is center/middle)
- $slide.css(prefix + 'Transform', 'scale(' + scaleX + ' , ' + scaleY + ') translate('+(($container.innerWidth()-sdw)/2/scaleX)+'px,'+(($container.innerHeight()-sdh)/2/scaleY)+'px)');
- }
- }
- });
- });
-
- }
-
- /*
- Extends defaults/options.
-
- options.designWidth
- Defaults to 800. You may instead specify a width as a number
- of px and all slides will be scaled in the same way, considering their
- size is the provided one.
-
- options.designHeight
- Defaults to 600. You may instead specify a height as a number
- of px and all slides will be scaled in the same way, considering their
- size is the provided one.
-
- options.fitMode
- How to adapt the slide to the container.
- Only the following combinations are available for now:
- "center middle", "top left", "bottom right", "stretched"
-
- options.fitMarginX
- options.fitMarginY
- Defaults to 5. Adds some margin in design space units.
- E.g., if the designe width is 800 and the margin is 5, the slide will be
- 810 pixel wide before rescaling.
-
- options.scaleDebounce
- Scaling on the browser resize event is debounced. This number is the
- threshold in milliseconds. You can learn more about debouncing here:
- http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
-
- */
- $.extend(true, $[deck].defaults, {
- classes: {
- globalscale: 'deck-globalscale'
- },
- keys: {
- scale: 83 // s
- },
-
- designWidth: 800,
- designHeight: 600,
- fitMode: "center middle",
- fitMarginX: 0,
- fitMarginY: 0,
- scaleDebounce: 200
- });
-
- /*
- jQuery.deck('disableScale')
-
- Disables scaling and removes the scale class from the deck container.
- */
- $[deck]('extend', 'disableScale', function() {
- $[deck]('getContainer').removeClass($[deck]('getOptions').classes.globalscale);
- scaleDeck();
- });
-
- /*
- jQuery.deck('enableScale')
-
- Enables scaling and adds the scale class to the deck container.
- */
- $[deck]('extend', 'enableScale', function() {
- $[deck]('getContainer').addClass($[deck]('getOptions').classes.globalscale);
- scaleDeck();
- });
-
- /*
- jQuery.deck('toggleScale')
-
- Toggles between enabling and disabling scaling.
- */
- $[deck]('extend', 'toggleScale', function() {
- var $c = $[deck]('getContainer');
- $[deck]($c.hasClass($[deck]('getOptions').classes.globalscale) ?
- 'disableScale' : 'enableScale');
- });
-
- $d.bind('deck.init', function() {
- var opts = $[deck]('getOptions');
-
- // Debounce the resize scaling
- $w.unbind('resize.deckscale').bind('resize.deckscale', function() {
- window.clearTimeout(timer);
- timer = window.setTimeout(scaleDeck, opts.scaleDebounce);
- })
- // Scale once on load, in case images or something change layout
- .unbind('load.deckscale').bind('load.deckscale', scaleDeck);
-
- // Bind key events
- $d.unbind('keydown.deckscale').bind('keydown.deckscale', function(e) {
- if (e.which === opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
- $[deck]('toggleScale');
- e.preventDefault();
- }
- });
-
- // Enable scale on init
- $[deck]('enableScale');
- });
-})(jQuery, 'deck', this);
-
-
-// This script was automatically generated from a literate source.
-// Do not edit this file; look at the literate source instead!
-//
-// Greasemonkey user script to
-// Display LaTeX in Web pages by transforming to MathML
-// --------------------------------------------------------------------
-
-// Original script by
-// Copyright (C) 2006 Steve Cheng
-// Home page: http://gold-saucer.afraid.org/mathml/greasemonkey/
-//
-// Modified by
-// Copyright (C) 2010 Valery Alexeev
-// Version 1.15, May 7, 2010
-// as follows:
-//
-// Added arxiv.org, front.math.ucdavis.edu, *mathscinet*, mail.google.com
-// Changed char_map to fix the display for \mathcal, \mathbb, \mathfrak
-// Fixed the displayed formulas with $$...$$ and \[...\]
-// Added \scr, \germ, \roman, etc used by Mathscinet.
-// Added miscellaneous symbols and arrows
-
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-// IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALNGS IN THE SOFTWARE.
-
-
-function latex2mml() {
-
-
- function GM_log() {}
-
-
-// First, find out where we are
-var va_loc = window.location.href;
-var va_view = 'web';
-
-//alert( 'va_view=' + va_view );
-
-// The script itself begins
-
-var/*const*/ mmlns = 'http://www.w3.org/1998/Math/MathML';
-
-/*
-// VA: Fix displayed equations first.
-if( va_view == 'web' ){
- document.body.innerHTML=
- document.body.innerHTML.replace(/\n/g," "); // remove end-of-lines
- document.body.innerHTML=
- document.body.innerHTML.replace(/(\$\$|\\\[)([^$]+)(\$\$|\\\])/g,
- "