feather_cms 0.0.5 → 0.0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,3 +12,5 @@
12
12
  //
13
13
  //= require jquery
14
14
  //= require jquery_ujs
15
+ //= require 'feather_cms/epiceditor'
16
+ //= require 'feather_cms/editor'
@@ -1,716 +1,4 @@
1
1
  /**
2
- * Copyright (c) 2011 Oscar Godson http://oscargodson.com
3
- * 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:
4
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5
- * 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 AUTHORS OR COPYRIGHT HOLDERS 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 DEALINGS IN THE SOFTWARE.
6
- */
7
- (function(window, undefined){
8
-
9
- /**
10
- * showdown.js -- A javascript port of Markdown.
11
- * Copyright (c) 2007 John Fraser.
12
- * Original Markdown Copyright (c) 2004-2005 John Gruber
13
- * Redistributable under a BSD-style open source license.
14
- */
15
- var Showdown={};"object"===typeof exports&&(Showdown=exports,Showdown.parse=function(h,i){return(new Showdown.converter).makeHtml(h,i)});var GitHub;
16
- Showdown.converter=function(){var h,i,o,p=0;this.makeHtml=function(a,c){"undefined"!==typeof c&&("string"===typeof c&&(c={nameWithOwner:c}),GitHub=c);h=[];i=[];o=[];a=a.replace(/~/g,"~T");a=a.replace(/\$/g,"~D");a=a.replace(/\r\n/g,"\n");a=a.replace(/\r/g,"\n");a="\n\n"+a+"\n\n";a=v(a);a=a.replace(/^[ \t]+$/mg,"");a=w(a);a=C(a);a=q(a);a=x(a);a=a.replace(/~D/g,"$$");a=a.replace(/~T/g,"~");a=a.replace(/https?\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!]/g,function(b,c){var d=a.slice(0,c),f=a.slice(c);return d.match(/<[^>]+$/)&&
17
- f.match(/^[^>]*>/)?b:"<a target='blank' href='"+b+"'>"+b+"</a>"});a=a.replace(/[a-z0-9_\-+=.]+@[a-z0-9\-]+(\.[a-z0-9-]+)+/ig,function(a){return"<a href='mailto:"+a+"'>"+a+"</a>"});a=a.replace(/[a-f0-9]{40}/ig,function(b,c){if("undefined"==typeof GitHub||"undefined"==typeof GitHub.nameWithOwner)return b;var d=a.slice(0,c),f=a.slice(c);return d.match(/@$/)||d.match(/<[^>]+$/)&&f.match(/^[^>]*>/)?b:"<a target='blank' href='http://github.com/"+GitHub.nameWithOwner+"/commit/"+b+"'>"+b.substring(0,7)+"</a>"});
18
- a=a.replace(/([a-z0-9_\-+=.]+)@([a-f0-9]{40})/ig,function(b,c,d,f){if("undefined"==typeof GitHub||"undefined"==typeof GitHub.nameWithOwner)return b;GitHub.repoName=GitHub.repoName||GitHub.nameWithOwner.match(/^.+\/(.+)$/)[1];var j=a.slice(0,f),f=a.slice(f);return j.match(/\/$/)||j.match(/<[^>]+$/)&&f.match(/^[^>]*>/)?b:"<a target='blank' href='http://github.com/"+c+"/"+GitHub.repoName+"/commit/"+d+"'>"+c+"@"+d.substring(0,7)+"</a>"});a=a.replace(/([a-z0-9_\-+=.]+\/[a-z0-9_\-+=.]+)@([a-f0-9]{40})/ig,
19
- function(a,c,d){return"<a target='blank' href='http://github.com/"+c+"/commit/"+d+"'>"+c+"@"+d.substring(0,7)+"</a>"});a=a.replace(/#([0-9]+)/ig,function(b,c,d){if("undefined"==typeof GitHub||"undefined"==typeof GitHub.nameWithOwner)return b;var f=a.slice(0,d),d=a.slice(d);return""==f||f.match(/[a-z0-9_\-+=.]$/)||f.match(/<[^>]+$/)&&d.match(/^[^>]*>/)?b:"<a target='blank' href='http://github.com/"+GitHub.nameWithOwner+"/issues/#issue/"+c+"'>"+b+"</a>"});a=a.replace(/([a-z0-9_\-+=.]+)#([0-9]+)/ig,
20
- function(b,c,d,f){if("undefined"==typeof GitHub||"undefined"==typeof GitHub.nameWithOwner)return b;GitHub.repoName=GitHub.repoName||GitHub.nameWithOwner.match(/^.+\/(.+)$/)[1];var j=a.slice(0,f),f=a.slice(f);return j.match(/\/$/)||j.match(/<[^>]+$/)&&f.match(/^[^>]*>/)?b:"<a target='blank' href='http://github.com/"+c+"/"+GitHub.repoName+"/issues/#issue/"+d+"'>"+b+"</a>"});return a=a.replace(/([a-z0-9_\-+=.]+\/[a-z0-9_\-+=.]+)#([0-9]+)/ig,function(a,c,d){return"<a target='blank' href='http://github.com/"+
21
- c+"/issues/#issue/"+d+"'>"+a+"</a>"})};var C=function(a){return a=a.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,function(a,b,e,d,f){b=b.toLowerCase();h[b]=y(e);if(d)return d+f;f&&(i[b]=f.replace(/"/g,"&quot;"));return""})},w=function(a){a=a.replace(/\n/g,"\n\n");a=a.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,m);a=a.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,
22
- m);a=a.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,m);a=a.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,m);a=a.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,m);return a=a.replace(/\n\n/g,"\n")},m=function(a,c){var b;b=c.replace(/\n\n/g,"\n");b=b.replace(/^\n/,"");b=b.replace(/\n+$/g,"");return b="\n\n~K"+(o.push(b)-1)+"K\n\n"},q=function(a){for(var a=D(a),c=k("<hr />"),a=a.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,c),a=a.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,
23
- c),a=a.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,c),a=z(a),a=E(a),a=F(a),a=G(a),a=w(a),a=a.replace(/^\n+/g,""),a=a.replace(/\n+$/g,""),b=a.split(/\n{2,}/g),a=[],c=b.length,e=0;e<c;e++){var d=b[e];0<=d.search(/~K(\d+)K/g)?a.push(d):0<=d.search(/\S/)&&(d=n(d),d=d.replace(/\n/g,"<br />"),d=d.replace(/^([ \t]*)/g,"<p>"),d+="</p>",a.push(d))}c=a.length;for(e=0;e<c;e++)for(;0<=a[e].search(/~K(\d+)K/);)b=o[RegExp.$1],b=b.replace(/\$/g,"$$$$"),a[e]=a[e].replace(/~K\d+K/,b);return a=a.join("\n\n")},n=function(a){a=
24
- H(a);a=I(a);a=a.replace(/\\(\\)/g,r);a=a.replace(/\\([`*_{}\[\]()>#+-.!])/g,r);a=a.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,A);a=a.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,A);a=a.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,s);a=a.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,s);a=a.replace(/(\[([^\[\]]+)\])()()()()()/g,s);a=J(a);a=y(a);a=a.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
25
- "<strong>$2</strong>");a=a.replace(/(\w)_(\w)/g,"$1~E95E$2");a=a.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,"<em>$2</em>");return a=a.replace(/ +\n/g," <br />\n")},I=function(a){return a=a.replace(/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi,function(a){a=a.replace(/(.)<\/?code>(?=.)/g,"$1`");return a=l(a,"\\`*_")})},s=function(a,c,b,e,d,f,j,g){void 0==g&&(g="");a=e.toLowerCase();if(""==d)if(""==a&&(a=b.toLowerCase().replace(/ ?\n/g," ")),void 0!=h[a])d=h[a],void 0!=i[a]&&(g=i[a]);else if(-1<
26
- c.search(/\(\s*\)$/m))d="";else return c;d=l(d,"*_");c="<a target='blank' href=\""+d+'"';""!=g&&(g=g.replace(/"/g,"&quot;"),g=l(g,"*_"),c+=' title="'+g+'"');return c+(">"+b+"</a>")},A=function(a,c,b,e,d,f,j,g){a=b;e=e.toLowerCase();g||(g="");if(""==d)if(""==e&&(e=a.toLowerCase().replace(/ ?\n/g," ")),void 0!=h[e])d=h[e],void 0!=i[e]&&(g=i[e]);else return c;a=a.replace(/"/g,"&quot;");d=l(d,"*_");c='<img src="'+d+'" alt="'+a+'"';g=g.replace(/"/g,"&quot;");g=l(g,"*_");return c+(' title="'+g+'"')+" />"},
27
- D=function(a){a=a.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,function(a,b){return k("<h1>"+n(b)+"</h1>")});a=a.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,function(a,b){return k("<h2>"+n(b)+"</h2>")});return a=a.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,function(a,b,e){a=b.length;return k("<h"+a+">"+n(e)+"</h"+a+">")})},t,z=function(a){var a=a+"~0",c=/^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;p?a=a.replace(c,function(a,c,d){a=c;d=-1<d.search(/[*+-]/g)?"ul":
28
- "ol";a=a.replace(/\n{2,}/g,"\n\n\n");a=t(a);a=a.replace(/\s+$/,"");return"<"+d+">"+a+"</"+d+">\n"}):(c=/(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g,a=a.replace(c,function(a,c,d,f){a=d;f=-1<f.search(/[*+-]/g)?"ul":"ol";a=a.replace(/\n{2,}/g,"\n\n\n");a=t(a);return c+"<"+f+">\n"+a+"</"+f+">\n"}));return a=a.replace(/~0/,"")};t=function(a){p++;a=a.replace(/\n{2,}$/,"\n");a=(a+"~0").replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
29
- function(a,b,e,d,f){a=f;b||-1<a.search(/\n{2,}/)?a=q(u(a)):(a=z(u(a)),a=a.replace(/\n$/,""),a=n(a));return"<li>"+a+"</li>\n"});a=a.replace(/~0/g,"");p--;return a};var F=function(a){a=(a+"~0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,function(a,b,e){a=B(u(b));a=v(a);a=a.replace(/^\n+/g,"");a=a.replace(/\n+$/g,"");return k("<pre><code>"+a+"\n</code></pre>")+e});return a=a.replace(/~0/,"")},E=function(a){return a=a.replace(/`{3}(?:(.*$)\n)?([\s\S]*?)`{3}/gm,function(a,
30
- b,e){return'<div class="highlight"><pre lang="'+b+'">'+e+"</pre></div>"})},k=function(a){a=a.replace(/(^\n+|\n+$)/g,"");return"\n\n~K"+(o.push(a)-1)+"K\n\n"},H=function(a){return a=a.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(a,b,e,d){a=d.replace(/^([ \t]*)/g,"");a=a.replace(/[ \t]*$/g,"");a=B(a);return b+"<code>"+a+"</code>"})},B=function(a){a=a.replace(/&/g,"&amp;");a=a.replace(/</g,"&lt;");a=a.replace(/>/g,"&gt;");return a=l(a,"*_{}[]\\",!1)},G=function(a){return a=a.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
31
- function(a,b){var e;e=b.replace(/^[ \t]*>[ \t]?/gm,"~0");e=e.replace(/~0/g,"");e=e.replace(/^[ \t]+$/gm,"");e=q(e);e=e.replace(/(^|\n)/g,"$1 ");e=e.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm,function(a,b){var c;c=b.replace(/^ /mg,"~0");return c=c.replace(/~0/g,"")});return k("<blockquote>\n"+e+"\n</blockquote>")})},y=function(a){a=a.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");return a=a.replace(/<(?![a-z\/?\$!])/gi,"&lt;")},J=function(a){a=a.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a target='blank' href=\"$1\">$1</a>");
32
- return a=a.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,function(a,b){return K(x(b))})},K=function(a){var c=[function(a){return"&#"+a.charCodeAt(0)+";"},function(a){a=a.charCodeAt(0);return"&#x"+("0123456789ABCDEF".charAt(a>>4)+"0123456789ABCDEF".charAt(a&15))+";"},function(a){return a}],a=("mailto:"+a).replace(/./g,function(a){if("@"==a)a=c[Math.floor(2*Math.random())](a);else if(":"!=a)var e=Math.random(),a=0.9<e?c[2](a):0.45<e?c[1](a):c[0](a);return a});return a=("<a target='blank' href=\""+
33
- a+'">'+a+"</a>").replace(/">.+:/g,'">')},x=function(a){return a=a.replace(/~E(\d+)E/g,function(a,b){var e=parseInt(b);return String.fromCharCode(e)})},u=function(a){a=a.replace(/^(\t|[ ]{1,4})/gm,"~0");return a=a.replace(/~0/g,"")},v=function(a){a=a.replace(/\t(?=\t)/g," ");a=a.replace(/\t/g,"~A~B");a=a.replace(/~B(.+?)~A/g,function(a,b){for(var e=b,d=4-e.length%4,f=0;f<d;f++)e+=" ";return e});a=a.replace(/~A/g," ");return a=a.replace(/~B/g,"")},l=function(a,c,b){c="(["+c.replace(/([\[\]\\])/g,
34
- "\\$1")+"])";b&&(c="\\\\"+c);return a=a.replace(RegExp(c,"g"),r)},r=function(a,c){return"~E"+c.charCodeAt(0)+"E"}};
35
-
36
- //Fullscreen API wrapper ( http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/ )
37
- //TODO: Need a new wrapper with support for W3C spec
38
- (function(){var a={supportsFullScreen:!1,isFullScreen:function(){return!1},requestFullScreen:function(){},cancelFullScreen:function(){},fullScreenEventName:"",prefix:""},c="webkit moz o ms khtml".split(" ");if("undefined"!=typeof document.cancelFullScreen)a.supportsFullScreen=!0;else for(var b=0,d=c.length;b<d;b++)if(a.prefix=c[b],"undefined"!=typeof document[a.prefix+"CancelFullScreen"]){a.supportsFullScreen=!0;break}if(a.supportsFullScreen)a.fullScreenEventName=a.prefix+"fullscreenchange",a.isFullScreen=
39
- function(){switch(this.prefix){case "":return document.fullScreen;case "webkit":return document.webkitIsFullScreen;default:return document[this.prefix+"FullScreen"]}},a.requestFullScreen=function(a){return""===this.prefix?a.requestFullScreen():a[this.prefix+"RequestFullScreen"]()},a.cancelFullScreen=function(){return""===this.prefix?document.cancelFullScreen():document[this.prefix+"CancelFullScreen"]()};if("undefined"!=typeof jQuery)jQuery.fn.requestFullScreen=function(){return this.each(function(){a.supportsFullScreen&&
40
- a.requestFullScreen(this)})};window.fullScreenApi=a})();
41
-
42
- /**
43
- * Applies attributes to a DOM object
44
- * @param {object} context The DOM obj you want to apply the attributes to
45
- * @param {object} attrs A key/value pair of attributes you want to apply
46
- * @returns {undefined}
47
- */
48
- function _applyAttrs(context,attrs){
49
- for(var attr in attrs){
50
- if(attrs.hasOwnProperty(attr)) {
51
- context[attr] = attrs[attr];
52
- }
53
- }
54
- }
55
-
56
- /**
57
- * Returns a DOM objects computed style
58
- * @param {object} el The element you want to get the style from
59
- * @param {string} styleProp The property you want to get from the element
60
- * @returns {string} Returns a string of the value. If property is not set it will return a blank string
61
- */
62
- function _getStyle(el,styleProp){
63
- var x = el;
64
- if(x.currentStyle) {
65
- var y = x.currentStyle[styleProp];
66
- }
67
- else if(window.getComputedStyle){
68
- var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
69
- }
70
- return y;
71
- }
72
-
73
- /**
74
- * Gets an elements total width including it's borders and padding
75
- * @param {object} el The element to get the total width of
76
- * @returns {int}
77
- */
78
- function _outerWidth(el){
79
- var b = parseInt(_getStyle(el,'border-left-width'))+parseInt(_getStyle(el,'border-right-width'))
80
- , p = parseInt(_getStyle(el,'padding-left'))+parseInt(_getStyle(el,'padding-right'))
81
- , w = el.offsetWidth
82
- , t = b+p+w;
83
- return t;
84
- }
85
-
86
- /**
87
- * Gets an elements total height including it's borders and padding
88
- * @param {object} el The element to get the total width of
89
- * @returns {int}
90
- */
91
- function _outerHeight(el){
92
- var b = parseInt(_getStyle(el,'border-top-width'))+parseInt(_getStyle(el,'border-bottom-width'))
93
- , p = parseInt(_getStyle(el,'padding-top'))+parseInt(_getStyle(el,'padding-bottom'))
94
- , w = el.offsetHeight
95
- , t = b+p+w;
96
- return t;
97
- }
98
-
99
- /**
100
- * Inserts a <link> tag specifically for CSS
101
- * @param {string} path The path to the CSS file
102
- * @param {object} context In what context you want to apply this to (document, iframe, etc)
103
- * @param {string} id An id for you to reference later for changing properties of the <link>
104
- * @returns {undefined}
105
- */
106
- function _insertCSSLink(path,context,id){
107
- id = id || '';
108
- var headID = context.getElementsByTagName("head")[0];
109
- var cssNode = context.createElement('link');
110
-
111
- _applyAttrs(cssNode,{
112
- type:'text/css'
113
- , id:id
114
- , rel:'stylesheet'
115
- , href: path+'?'+new Date().getTime()
116
- , name: path
117
- , media: 'screen'
118
- });
119
-
120
- cssNode.media = 'screen';
121
- headID.appendChild(cssNode);
122
- }
123
-
124
- /**
125
- * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
126
- * @param {boolean} [deepMerge=false] If true, will deep merge meaning it will merge sub-objects like {obj:obj2{foo:'bar'}}
127
- * @param {object} first object
128
- * @param {object} second object
129
- * @returnss {object} a new object based on obj1 and obj2
130
- */
131
- function _mergeObjs(){
132
- // copy reference to target object
133
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
134
-
135
- function isFunction(functionToCheck) {
136
- var getType = {};
137
- return functionToCheck && getType.toString.call(functionToCheck) == '[object Function]';
138
- }
139
- // Handle a deep copy situation
140
- if (typeof target === "boolean"){
141
- deep = target;
142
- target = arguments[1] || {};
143
- // skip the boolean and the target
144
- i = 2;
145
- }
146
-
147
- // Handle case when target is a string or something (possible in deep copy)
148
- if (typeof target !== "object" && !isFunction(target)){
149
- target = {};
150
- }
151
- // extend jQuery itself if only one argument is passed
152
- if (length == i){
153
- target = this;
154
- --i;
155
- }
156
-
157
- for ( ; i < length; i++ ){
158
- // Only deal with non-null/undefined values
159
- if ( (options = arguments[ i ]) != null ){
160
- // Extend the base object
161
- for ( var name in options ) {
162
- var src = target[ name ], copy = options[ name ];
163
-
164
- // Prevent never-ending loop
165
- if ( target === copy ){
166
- continue;
167
- }
168
- // Recurse if we're merging object values
169
- if ( deep && copy && typeof copy === "object" && !copy.nodeType ){
170
- target[ name ] = _mergeObjs( deep,
171
- // Never move original objects, clone them
172
- src || ( copy.length != null ? [ ] : { } )
173
- , copy );
174
- }
175
- // Don't bring in undefined values
176
- else if ( copy !== undefined ){
177
- target[ name ] = copy;
178
- }
179
- }
180
- }
181
- }
182
-
183
- // Return the modified object
184
- return target;
185
- };
186
-
187
- /**
188
- * Initiates the EpicEditor object and sets up offline storage as well
189
- * @class Represents an EpicEditor instance
190
- * @param {object} e A DOM object for the editor to be placed in
191
- * @returns {object} EpicEditor will be returned
192
- */
193
- function EpicEditor(e){
194
- var uId = 'epiceditor-'+Math.round(Math.random()*100000)
195
- , fileName = e.id;
196
-
197
- //TODO: Check for data-filename as well
198
- if(!fileName){ //If there is no id on the element to use, just use "default"
199
- fileName = 'default';
200
- }
201
-
202
- //Default settings (will be overwritten if .options() is called with parameters)
203
- this.settings = {
204
- basePath:'epiceditor'
205
- , themes: {
206
- preview:'/themes/preview/preview-dark.css'
207
- , editor:'/themes/editor/epic-dark.css'
208
- }
209
- , file: {
210
- name:fileName //Use the DOM element's ID for an unique persistent file name
211
- , defaultContent:''
212
- }
213
- //Because there might be multiple editors, we create a random id
214
- , id:uId
215
- , focusOnLoad:false
216
- };
217
-
218
- //Setup local storage of files
219
- if(localStorage){
220
- if(!localStorage['epiceditor']){
221
- //TODO: Needs a dynamic file name!
222
- var defaultStorage = {files:{}};
223
- defaultStorage.files[this.settings.file.name] = this.settings.file.defaultContent;
224
- defaultStorage = JSON.stringify(defaultStorage);
225
- localStorage['epiceditor'] = defaultStorage;
226
- }
227
- else if(!JSON.parse(localStorage['epiceditor']).files[this.settings.file.name]){
228
- JSON.parse(localStorage['epiceditor']).files[this.settings.file.name] = this.settings.file.defaultContent;
229
- }
230
- else{
231
- this.content = this.settings.file.defaultContent;
232
- }
233
- }
234
- //Now that it exists, allow binding of events if it doesn't exist yet
235
- if(!this.events){
236
- this.events = {};
237
- }
238
- this.element = e;
239
- return this;
240
- }
241
-
242
- /**
243
- * Changes default options such as theme, id, etc for the EpicEditor instance
244
- * @param {object} options A key/value pair of options you want to change from the default
245
- * @returns {object} EpicEditor will be returned
246
- */
247
- EpicEditor.prototype.options = function(options){
248
- var self = this;
249
- self.settings = _mergeObjs(true, this.settings, options);
250
- return self;
251
- }
252
-
253
- /**
254
- * Inserts the EpicEditor into the DOM via an iframe and gets it ready for editing and previewing
255
- * @returns {object} EpicEditor will be returned
256
- */
257
- EpicEditor.prototype.load = function(callback){
258
- var self = this;
259
-
260
- callback = callback || function(){};
261
-
262
- //The editor HTML
263
- //TODO: edit-mode class should be dynamicly added!
264
- var _HtmlTemplate = '<div class="epiceditor-wrapper epiceditor-edit-mode">'+
265
- '<div class="epiceditor-utilbar">'+
266
- '<img width="16" src="'+this.settings.basePath+'/images/preview.png" class="epiceditor-toggle-btn"> '+
267
- '<img width="16" src="'+this.settings.basePath+'/images/fullscreen.png" class="epiceditor-fullscreen-btn">'+
268
- '</div>'+
269
- '<div class="epiceditor-editor">'+
270
- '<textarea class="epiceditor-textarea"></textarea>'+
271
- '</div>'+
272
- '<div class="epiceditor-preview"></div>'+
273
- '</div>';
274
-
275
- //Write an iframe and then select it for the editor
276
- this.element.innerHTML = '<iframe scrolling="no" frameborder="0" id= "'+self.settings.id+'"></iframe>';
277
- var iframeElement = document.getElementById(self.settings.id);
278
-
279
- //Grab the innards of the iframe (returns the document.body)
280
- self.iframe = iframeElement.contentDocument || iframeElement.contentWindow.document;
281
- self.iframe.open();
282
- self.iframe.write(_HtmlTemplate);
283
-
284
- //Set the default styles for the iframe
285
-
286
- var widthDiff = _outerWidth(this.element) - this.element.offsetWidth;
287
- var heightDiff = _outerHeight(this.element) - this.element.offsetHeight;
288
-
289
- iframeElement.style.width = this.element.offsetWidth - widthDiff +'px';
290
- iframeElement.style.height = this.element.offsetHeight - heightDiff +'px';
291
-
292
- //Remove the default browser CSS body styles, then add base CSS styles for the editor
293
- var iframeBody = self.iframe.body;
294
- iframeBody.style.padding = '0';
295
- iframeBody.style.margin = '0';
296
- _insertCSSLink(self.settings.basePath+self.settings.themes.editor,self.iframe);
297
-
298
-
299
- //Add a relative style to the overall wrapper to keep CSS relative to the editor
300
- self.iframe.getElementsByClassName('epiceditor-wrapper')[0].style.position = 'relative';
301
-
302
- //Now grab the editor and previewer for later use
303
- this.editor = self.iframe.getElementsByClassName('epiceditor-textarea')[0];
304
- this.previewer = self.iframe.getElementsByClassName('epiceditor-preview')[0];
305
-
306
- //Firefox's <body> gets all fucked up so, to be sure, we need to hardcode it
307
- self.iframe.body.style.height = this.element.offsetHeight+'px';
308
-
309
- //Generate the width
310
- this.editor.style.width = '100%';
311
- this.editor.style.height = this.element.offsetHeight+'px';
312
-
313
- //Should actually check what mode it's in!
314
- this.previewer.style.display = 'none';
315
- this.previewer.style.overflow = 'auto';
316
-
317
- //Fit the preview window into the container
318
- //FIXME Should be in theme!
319
- this.previewer.style['padding'] = '10px';
320
- this.previewer.style.width = this.element.offsetWidth - _outerWidth(this.previewer) - widthDiff +'px';
321
- this.previewer.style.height = this.element.offsetHeight - _outerHeight(this.previewer) - heightDiff +'px';
322
-
323
- //If there is a file to be opened with that filename and it has content...
324
- this.open(self.settings.file.name);
325
-
326
- if(this.settings.focusOnLoad){
327
- this.editor.focus();
328
- }
329
-
330
- //Sets up the onclick event on the previewer/editor toggle button
331
- self.iframe.getElementsByClassName('epiceditor-toggle-btn')[0].addEventListener('click',function(){
332
- var editorWrapper = self.iframe.getElementsByClassName('epiceditor-wrapper')[0];
333
- //Simply replaces a class (o), to a new class (n) on an element provided (e)
334
- function replaceClass(e, o, n){
335
- e.className = editorWrapper.className.replace(o, n);
336
- }
337
- //If it was in edit mode...
338
- if(editorWrapper.className.indexOf('epiceditor-edit-mode') > -1){
339
- replaceClass(editorWrapper,'epiceditor-edit-mode','epiceditor-preview-mode');
340
- self.preview();
341
- }
342
- //If it was in preview mode...
343
- else{
344
- replaceClass(editorWrapper,'epiceditor-preview-mode','epiceditor-edit-mode');
345
- self.edit();
346
- }
347
- });
348
-
349
- //Sets up the fullscreen editor/previewer
350
- //TODO: Deal with the fact Firefox doesn't really support fullscreen and don't browser sniff
351
- if (fullScreenApi.supportsFullScreen && document.body.webkitRequestFullScreen) {
352
- var fsElement = document.getElementById(self.settings.id)
353
- , fsBtns = self.iframe.getElementsByClassName('epiceditor-utilbar')[0];
354
-
355
-
356
- //A simple helper to save the state of the styles on an element to make reverting easier
357
- var currentStyleState = [];
358
- var styleState = function(e,t){
359
- t = t || 'load';
360
- if(t === 'save'){
361
- currentStyleState[e] = {
362
- width:_getStyle(e,'width')
363
- , height:_getStyle(e,'height')
364
- , float:_getStyle(e,'float')
365
- , display:_getStyle(e,'display')
366
- }
367
- }
368
- else{
369
- for(x in currentStyleState[e]){
370
- if(currentStyleState[e].hasOwnProperty(x)){
371
- e.style[x] = currentStyleState[e][x];
372
- }
373
- }
374
- }
375
- }
376
-
377
- styleState(self.editor,'save');
378
- styleState(self.previewer,'save');
379
-
380
- var revertBackTo = self.editor;
381
-
382
- self.iframe.getElementsByClassName('epiceditor-fullscreen-btn')[0].addEventListener('click',function(){
383
- if(_getStyle(self.previewer,'display') === 'block'){
384
- revertBackTo = self.previewer;
385
- }
386
- fullScreenApi.requestFullScreen(fsElement);
387
- });
388
- fsElement.addEventListener(fullScreenApi.fullScreenEventName,function(){
389
- if (fullScreenApi.isFullScreen()) {
390
- fsBtns.style.visibility = 'hidden';
391
-
392
- //Editor styles
393
- self.editor.style.height = window.outerHeight+'px';
394
- self.editor.style.width = window.outerWidth/2+'px'; //Half of the screen
395
- self.editor.style.float = 'left';
396
- self.editor.style.display = 'block';
397
-
398
- //Previewer styles
399
- self.previewer.style.height = window.outerHeight+'px'
400
- self.previewer.style.width = (window.outerWidth-_outerWidth(self.editor))+'px'; //Fill in the remaining space
401
- self.previewer.style.float = 'right';
402
- self.previewer.style.display = 'block';
403
-
404
- self.preview(true);
405
-
406
- var fullscreenLivePreview = self.editor.addEventListener('keyup',function(){
407
- self.preview(true);
408
- });
409
-
410
- }
411
- else{
412
- fsBtns.style.visibility = 'visible';
413
- styleState(self.editor);
414
- styleState(self.previewer);
415
- if(revertBackTo === self.editor){
416
- self.edit();
417
- }
418
- else{
419
- self.preview();
420
- }
421
- }
422
- }, true);
423
- }
424
- else{
425
- //TODO: homebrew support by position:fixed and width/height 100% of document size
426
- self.iframe.getElementsByClassName('epiceditor-fullscreen-btn')[0].style.display = 'none';
427
- }
428
-
429
- var utilBar = self.iframe.getElementsByClassName('epiceditor-utilbar')[0];
430
-
431
- //Hide it at first until they move their mouse
432
- utilBar.style.display = 'none';
433
-
434
- //Hide and show the util bar based on mouse movements
435
- var utilBarTimer
436
- , mousePos = { y:-1, x:-1 };
437
- this.iframe.addEventListener('mousemove',function(e){
438
- //Here we check if the mouse has moves more than 5px in any direction before triggering the mousemove code
439
- //we do this for 2 reasons:
440
- //1. On Mac OS X lion when you scroll and it does the iOS like "jump" when it hits the top/bottom of the page itll fire off
441
- // a mousemove of a few pixels depending on how hard you scroll
442
- //2. We give a slight buffer to the user in case he barely touches his touchpad or mouse and not trigger the UI
443
- if(Math.abs(mousePos.y-e.pageY) >= 5 || Math.abs(mousePos.x-e.pageX) >= 5){
444
- utilBar.style.display = 'block';
445
- // if we have a timer already running, kill it out
446
- if(utilBarTimer){
447
- clearTimeout(utilBarTimer);
448
- }
449
-
450
- // begin a new timer that hides our object after 1000 ms
451
- utilBarTimer = window.setTimeout(function() {
452
- utilBar.style.display = 'none';
453
- }, 1000);
454
- }
455
- mousePos = { y:e.pageY, x:e.pageX };
456
- });
457
-
458
- //Make sure, on window resize, if the containing element changes size keep it fitting inside
459
- window.addEventListener('resize',function(){
460
- var widthDiff = _outerWidth(self.element) - self.element.offsetWidth;
461
- iframeElement.style.width = self.element.offsetWidth - widthDiff +'px';
462
- });
463
-
464
- //TODO: This should have a timer to save on performance
465
- //TODO: The save file shoudl be dynamic, not just default
466
- //On keyup, save the content to the proper file for offline use
467
- this.editor.addEventListener('keyup',function(){
468
- self.content = this.value;
469
- self.save(self.settings.file.name,this.value);
470
- });
471
-
472
- self.iframe.close();
473
- //The callback and call are the same thing, but different ways to access them
474
- callback.call(this);
475
- this.emit('load');
476
- return this;
477
- }
478
-
479
- /**
480
- * Will remove the editor, but not offline files
481
- * @returns {object} EpicEditor will be returned
482
- */
483
- EpicEditor.prototype.unload = function(callback){
484
- var self = this;
485
- var editor = window.parent.document.getElementById(self.settings.id);
486
- editor.parentNode.removeChild(editor);
487
- callback.call(this);
488
- self.emit('unload');
489
- return self;
490
- }
491
-
492
- /**
493
- * Will take the markdown and generate a preview view based on the theme
494
- * @param {string} theme The path to the theme you want to preview in
495
- * @returns {object} EpicEditor will be returned
496
- */
497
- EpicEditor.prototype.preview = function(theme,live){
498
- var self = this
499
- , themePath = self.settings.basePath+self.settings.themes.preview;
500
- if(typeof theme === 'boolean'){
501
- live = theme;
502
- theme = themePath
503
- }
504
- else{
505
- theme = theme || themePath
506
- }
507
-
508
- //Check if no CSS theme link exists
509
- if(!self.iframe.getElementById('theme')){
510
- _insertCSSLink(theme, self.iframe, 'theme');
511
- }
512
- else if(self.iframe.getElementById('theme').name !== theme){
513
- self.iframe.getElementById('theme').href = theme;
514
- }
515
-
516
- //Add the generated HTML into the previewer
517
- this.previewer.innerHTML = this.exportHTML();
518
-
519
- //Hide the editor and display the previewer
520
- if(!live){
521
- this.editor.style.display = 'none';
522
- this.previewer.style.display = 'block';
523
- }
524
-
525
- self.emit('preview');
526
- return this;
527
- }
528
-
529
- /**
530
- * Hides the preview and shows the editor again
531
- * @returns {object} EpicEditor will be returned
532
- */
533
- EpicEditor.prototype.edit = function(){
534
- var self = this;
535
- this.editor.style.display = 'block';
536
- this.previewer.style.display = 'none';
537
- self.emit('edit');
538
- return this;
539
- }
540
-
541
- /**
542
- * Grabs a specificed HTML node. Use it as a shortcut to getting the iframe contents
543
- * @param {String} name The name of the node (can be document, body, editor, or previewer)
544
- * @returns {Object|Null}
545
- */
546
- EpicEditor.prototype.get = function(name){
547
- var available = {
548
- document: this.iframe
549
- , body: this.iframe.body
550
- , editor: this.editor
551
- , previewer: this.previewer
552
- }
553
- if(!available[name]){
554
- return null;
555
- }
556
- else{
557
- return available[name];
558
- }
559
- }
560
-
561
- /**
562
- * Opens a file
563
- * @param {string} name The name of the file you want to open
564
- * @returns {object} EpicEditor will be returned
565
- */
566
- EpicEditor.prototype.open = function(name){
567
- var self = this;
568
- name = name || self.settings.file.name;
569
- if(localStorage && localStorage['epiceditor']){
570
- var fileObj = JSON.parse(localStorage['epiceditor']).files;
571
- if(fileObj[name]){
572
- self.editor.value = fileObj[name];
573
- }
574
- else{
575
- self.editor.value = this.settings.file.defaultContent;
576
- }
577
- self.settings.file.name = name;
578
- this.previewer.innerHTML = this.exportHTML();
579
- this.emit('open');
580
- }
581
- return this;
582
- }
583
-
584
- /**
585
- * Saves content for offline use
586
- * @param {string} file A filename for the content to be saved to
587
- * @param {string} content The content you want saved
588
- * @returns {object} EpicEditor will be returned
589
- */
590
- EpicEditor.prototype.save = function(file,content){
591
- var self = this;
592
- file = file || self.settings.file.name;
593
- content = content || this.editor.value;
594
- var s = JSON.parse(localStorage['epiceditor']);
595
- s.files[file] = content;
596
- localStorage['epiceditor'] = JSON.stringify(s);
597
- this.emit('save');
598
- return this;
599
- }
600
-
601
- /**
602
- * Removes a page
603
- * @param {string} name The name of the file you want to remove from localStorage
604
- * @returns {object} EpicEditor will be returned
605
- */
606
- EpicEditor.prototype.remove = function(name){
607
- var self = this;
608
- name = name || self.settings.file.name;
609
- var s = JSON.parse(localStorage['epiceditor']);
610
- delete s.files[name];
611
- localStorage['epiceditor'] = JSON.stringify(s);
612
- this.emit('remove');
613
- return this;
614
- };
615
-
616
-
617
- /**
618
- * Imports a MD file instead of having to manual inject content via
619
- * .get(editor).value = 'the content'
620
- * @param {string} name The name of the file
621
- * @param {stirng} content The MD to import
622
- * @returns {object} EpicEditor will be returned
623
- */
624
- EpicEditor.prototype.import = function(name,content){
625
- var self = this;
626
- content = content || '';
627
- self.open(name).get('editor').value = content;
628
- //we reopen the file after saving so that it will preview correctly if in the previewer
629
- self.save().open(name);
630
- return this;
631
- };
632
-
633
- /**
634
- * Renames a file
635
- * @param {string} oldName The old file name
636
- * @param {string} newName The new file name
637
- * @returns {object} EpicEditor will be returned
638
- */
639
- EpicEditor.prototype.rename = function(oldName,newName){
640
- var self = this;
641
- var s = JSON.parse(localStorage['epiceditor']);
642
- s.files[newName] = s.files[oldName];
643
- delete s.files[oldName];
644
- localStorage['epiceditor'] = JSON.stringify(s);
645
- self.open(newName);
646
- return this;
647
- };
648
-
649
- /**
650
- * Converts content into HTML from markdown
651
- * @returns {string} Returns the HTML that was converted from the markdown
652
- */
653
- EpicEditor.prototype.exportHTML = function(){
654
- var c = new Showdown.converter();
655
- return c.makeHtml(this.editor.value);
656
- }
657
-
658
- //EVENTS
659
- //TODO: Support for namespacing events like "preview.foo"
660
- /**
661
- * Sets up an event handler for a specified event
662
- * @param {string} ev The event name
663
- * @param {function} handler The callback to run when the event fires
664
- * @returns {object} EpicEditor will be returned
665
- */
666
- EpicEditor.prototype.on = function(ev, handler){
667
- var self = this;
668
- if (!this.events[ev]){
669
- this.events[ev] = [];
670
- }
671
- this.events[ev].push(handler);
672
- return self;
673
- };
674
-
675
- /**
676
- * This will emit or "trigger" an event specified
677
- * @param {string} ev The event name
678
- * @param {any} data Any data you want to pass into the callback
679
- * @returns {object} EpicEditor will be returned
680
- */
681
- EpicEditor.prototype.emit = function(ev, data){
682
- var self = this;
683
- if (!this.events[ev]){
684
- return;
685
- }
686
- //TODO: Cross browser support!
687
- this.events[ev].forEach(invokeHandler);
688
- function invokeHandler(handler) {
689
- handler.call(self.iframe,data);
690
- }
691
- return self;
692
- };
693
-
694
- /**
695
- * Will remove any listeners added from EpicEditor.on()
696
- * @param {string} ev The event name
697
- * @param {function} handler Handler to remove
698
- * @returns {object} EpicEditor will be returned
699
- */
700
- EpicEditor.prototype.removeListener = function(ev, handler){
701
- var self = this;
702
- if(!handler){
703
- this.events[ev] = [];
704
- return self;
705
- }
706
- if(!this.events[ev]){
707
- return self;
708
- }
709
- //Otherwise a handler and event exist, so take care of it
710
- this._events[ev].splice(this._events[ev].indexOf(handler), 1);
711
- return self;
712
- }
713
-
714
-
715
- window.EpicEditor = EpicEditor;
716
- })(window);
2
+ * EpicEditor - An Embeddable JavaScript Markdown Editor (https://github.com/OscarGodson/EpicEditor)
3
+ * Copyright (c) 2011-2012, Oscar Godson. (MIT Licensed)
4
+ */(function(a,b){function c(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}function d(a,b){for(var c in b)b.hasOwnProperty(c)&&(a.style[c]=b[c])}function e(b,c){var d=b,e=null;return a.getComputedStyle?e=document.defaultView.getComputedStyle(d,null).getPropertyValue(c):d.currentStyle&&(e=d.currentStyle[c]),e}function f(a,b,c){var f={},g;if(b==="save"){for(g in c)c.hasOwnProperty(g)&&(f[g]=e(a,g));d(a,c)}else b==="apply"&&d(a,c);return f}function g(a){var b=parseInt(e(a,"border-left-width"),10)+parseInt(e(a,"border-right-width"),10),c=parseInt(e(a,"padding-left"),10)+parseInt(e(a,"padding-right"),10),d=a.offsetWidth,f;return isNaN(b)&&(b=0),f=b+c+d,f}function h(a){var b=parseInt(e(a,"border-top-width"),10)+parseInt(e(a,"border-bottom-width"),10),c=parseInt(e(a,"padding-top"),10)+parseInt(e(a,"padding-bottom"),10),d=a.offsetHeight,f;return isNaN(b)&&(b=0),f=b+c+d,f}function i(a,b,d){d=d||"";var e=b.getElementsByTagName("head")[0],f=b.createElement("link");c(f,{type:"text/css",id:d,rel:"stylesheet",href:a,name:a,media:"screen"}),e.appendChild(f)}function j(a,b,c){a.className=a.className.replace(b,c)}function k(a){return a.contentDocument||a.contentWindow.document}function l(a){var b;return document.body.innerText?b=a.innerText:(b=a.innerHTML.replace(/<br>/gi,"\n"),b=b.replace(/<(?:.|\n)*?>/gm,""),b=b.replace(/&lt;/gi,"<"),b=b.replace(/&gt;/gi,">")),b}function m(a,b){return document.body.innerText?a.innerText=b:a.innerHTML=b.replace(/\n/g,"<br>"),!0}function n(){var a=-1,b=navigator.userAgent,c;return navigator.appName=="Microsoft Internet Explorer"&&(c=/MSIE ([0-9]{1,}[\.0-9]{0,})/,c.exec(b)!=null&&(a=parseFloat(RegExp.$1,10))),a}function o(a){var b={};return a&&b.toString.call(a)==="[object Function]"}function p(){var a=arguments[0]||{},c=1,d=arguments.length,e=!1,f,g,h,i;typeof a=="boolean"&&(e=a,a=arguments[1]||{},c=2),typeof a!="object"&&!o(a)&&(a={}),d===c&&(a=this,--c);for(;c<d;c++)if((f=arguments[c])!=null)for(g in f)if(f.hasOwnProperty(g)){h=a[g],i=f[g];if(a===i)continue;e&&i&&typeof i=="object"&&!i.nodeType?a[g]=p(e,h||(i.length!=null?[]:{}),i):i!==b&&(a[g]=i)}return a}function q(a){var c=this,d=a||{},e,f,g={container:"epiceditor",basePath:"epiceditor",clientSideStorage:!0,localStorageName:"epiceditor",file:{name:null,defaultContent:"",autoSave:100},theme:{base:"/themes/base/epiceditor.css",preview:"/themes/preview/github.css",editor:"/themes/editor/epic-dark.css"},focusOnLoad:!1,shortcut:{modifier:18,fullscreen:70,preview:80,edit:79},parser:typeof marked=="function"?marked:null},h;c.settings=p(!0,g,d);if(typeof c.settings.parser!="function"||typeof c.settings.parser("TEST")!="string")c.settings.parser=function(a){return a};return typeof c.settings.container=="string"?c.element=document.getElementById(c.settings.container):typeof c.settings.container=="object"&&(c.element=c.settings.container),c.settings.file.name||(typeof c.settings.container=="string"?c.settings.file.name=c.settings.container:typeof c.settings.container=="object"&&(c.element.id?c.settings.file.name=c.element.id:(q._data.unnamedEditors||(q._data.unnamedEditors=[]),q._data.unnamedEditors.push(c),c.settings.file.name="__epiceditor-untitled-"+q._data.unnamedEditors.length))),c._instanceId="epiceditor-"+Math.round(Math.random()*1e5),c._storage={},c._canSave=!0,c._defaultFileSchema=function(){return{content:c.settings.file.defaultContent,created:new Date,modified:new Date}},localStorage&&c.settings.clientSideStorage&&(this._storage=localStorage,this._storage[c.settings.localStorageName]&&c.getFiles(c.settings.file.name)===b&&(f=c.getFiles(c.settings.file.name),f=c._defaultFileSchema(),f.content=c.settings.file.defaultContent)),this._storage[c.settings.localStorageName]||(h={},h[c.settings.file.name]=c._defaultFileSchema(),h=JSON.stringify(h),this._storage[c.settings.localStorageName]=h),c.events||(c.events={}),this}q.prototype.load=function(b){function G(a){for(var b=0;b<a.length;b++)a[b].style.width=c.element.offsetWidth-o+"px",a[b].style.height=c.element.offsetHeight-p+"px"}function H(a){o=g(c.element)-c.element.offsetWidth;for(var b=0;b<a.length;b++)a[b].style.width=c.element.offsetWidth-o+"px"}function I(b){if(Math.abs(u.y-b.pageY)>=5||Math.abs(u.x-b.pageX)>=5)r.style.display="block",s&&clearTimeout(s),s=a.setTimeout(function(){r.style.display="none"},1e3);u={y:b.pageY,x:b.pageX}}function J(a){a.keyCode==c.settings.shortcut.modifier&&(C=!0),a.keyCode==17&&(D=!0),C===!0&&a.keyCode==c.settings.shortcut.preview&&!c.eeState.fullscreen&&(a.preventDefault(),c.preview()),C===!0&&a.keyCode==c.settings.shortcut.edit&&(a.preventDefault(),c.eeState.fullscreen||c.edit()),C===!0&&a.keyCode==c.settings.shortcut.fullscreen&&(a.preventDefault(),y(B)),C===!0&&a.keyCode!==c.settings.shortcut.modifier&&(C=!1),a.keyCode==27&&c.eeState.fullscreen&&(document.body.webkitRequestFullScreen||z(B)),D===!0&&a.keyCode==83&&(c.save(),a.preventDefault(),D=!1),a.metaKey&&a.keyCode==83&&(c.save(),a.preventDefault())}function K(a){a.keyCode==c.settings.shortcut.modifier&&(C=!1),a.keyCode==17&&(D=!1)}var c=this,j,l,m,o,p,q,r,s,t,u={y:-1,x:-1},v,w,x=document.body.webkitRequestFullScreen?!0:!1,y,z,A,B,C=!1,D=!1,E,F;b=b||function(){},c.eeState={fullscreen:!1,preview:!1,edit:!0,loaded:!1,unloaded:!1},j={chrome:'<div id="epiceditor-wrapper" class="epiceditor-edit-mode"><iframe frameborder="0" id="epiceditor-editor-frame"></iframe><iframe frameborder="0" id="epiceditor-previewer-frame"></iframe><div id="epiceditor-utilbar"><img width="30" src="'+this.settings.basePath+'/images/preview.png" title="Toggle Preview Mode" class="epiceditor-toggle-btn epiceditor-toggle-preview-btn"> '+'<img width="30" src="'+this.settings.basePath+'/images/edit.png" title="Toggle Edit Mode" class="epiceditor-toggle-btn epiceditor-toggle-edit-btn"> '+'<img width="30" src="'+this.settings.basePath+'/images/fullscreen.png" title="Enter Fullscreen" class="epiceditor-fullscreen-btn">'+"</div>"+"</div>",previewer:'<div id="epiceditor-preview"></div>'},c.element.innerHTML='<iframe scrolling="no" frameborder="0" id= "'+c._instanceId+'"></iframe>',l=document.getElementById(c._instanceId),c.iframeElement=l,c.iframe=k(l),c.iframe.open(),c.iframe.write(j.chrome),c.editorIframe=c.iframe.getElementById("epiceditor-editor-frame"),c.previewerIframe=c.iframe.getElementById("epiceditor-previewer-frame"),c.editorIframeDocument=k(c.editorIframe),c.editorIframeDocument.open(),c.editorIframeDocument.write(""),c.editorIframeDocument.close(),c.previewerIframeDocument=k(c.previewerIframe),c.previewerIframeDocument.open(),c.previewerIframeDocument.write(j.previewer),m=c.previewerIframeDocument.createElement("base"),m.target="_blank",c.previewerIframeDocument.getElementsByTagName("head")[0].appendChild(m),c.previewerIframeDocument.close(),o=g(c.element)-c.element.offsetWidth,p=h(c.element)-c.element.offsetHeight,A=[c.iframeElement,c.editorIframe,c.previewerIframe],G(A),i(c.settings.basePath+c.settings.theme.base,c.iframe,"theme"),i(c.settings.basePath+c.settings.theme.editor,c.editorIframeDocument,"theme"),i(c.settings.basePath+c.settings.theme.preview,c.previewerIframeDocument,"theme"),c.iframe.getElementById("epiceditor-wrapper").style.position="relative",c.editor=c.editorIframeDocument.body,c.previewer=c.previewerIframeDocument.getElementById("epiceditor-preview"),c.editor.contentEditable=!0,c.iframe.body.style.height=this.element.offsetHeight+"px",this.previewerIframe.style.display="none",n()>-1&&(this.previewer.style.height=parseInt(e(this.previewer,"height"),10)+2),this.open(c.settings.file.name),c.settings.focusOnLoad&&c.iframe.addEventListener("readystatechange",function(){c.iframe.readyState=="complete"&&c.editorIframeDocument.body.focus()}),q=c.iframe.getElementById("epiceditor-utilbar"),v={},y=function(b){if(c.eeState.fullscreen){z(b);return}x&&b.webkitRequestFullScreen(),w=c.eeState.edit,c.eeState.fullscreen=!0,c.eeState.edit=!0,c.eeState.preview=!0;var d=a.innerWidth,g=a.innerHeight,h=a.outerWidth,i=a.outerHeight;x||(i=a.innerHeight),v.editorIframe=f(c.editorIframe,"save",{width:h/2+"px",height:i+"px","float":"left",cssFloat:"left",styleFloat:"left",display:"block"}),v.previewerIframe=f(c.previewerIframe,"save",{width:h/2+"px",height:i+"px","float":"right",cssFloat:"right",styleFloat:"right",display:"block"}),v.element=f(c.element,"save",{position:"fixed",top:"0",left:"0",width:"100%","z-index":"9999",zIndex:"9999",border:"none",margin:"0",background:e(c.editor,"background-color"),height:g+"px"}),v.iframeElement=f(c.iframeElement,"save",{width:h+"px",height:g+"px"}),q.style.visibility="hidden",x||(document.body.style.overflow="hidden"),c.preview(),c.editorIframeDocument.body.focus()},z=function(a){f(c.element,"apply",v.element),f(c.iframeElement,"apply",v.iframeElement),f(c.editorIframe,"apply",v.editorIframe),f(c.previewerIframe,"apply",v.previewerIframe),c.element.style.width="",c.element.style.height="",q.style.visibility="visible",x?document.webkitCancelFullScreen():document.body.style.overflow="auto",c.eeState.fullscreen=!1,w?c.edit():c.preview(),H(A)},c.editor.addEventListener("keyup",function(){t&&a.clearTimeout(t),t=a.setTimeout(function(){c.eeState.fullscreen&&c.preview()},250)}),B=c.iframeElement,q.addEventListener("click",function(a){var b=a.target.className;b.indexOf("epiceditor-toggle-preview-btn")>-1?c.preview():b.indexOf("epiceditor-toggle-edit-btn")>-1?c.edit():b.indexOf("epiceditor-fullscreen-btn")>-1&&y(B)}),document.body.webkitRequestFullScreen&&B.addEventListener("webkitfullscreenchange",function(){document.webkitIsFullScreen||z(B)},!1),r=c.iframe.getElementById("epiceditor-utilbar"),r.style.display="none",r.addEventListener("mouseover",function(){s&&clearTimeout(s)}),E=[c.previewerIframeDocument,c.editorIframeDocument];for(F=0;F<E.length;F++)E[F].addEventListener("mousemove",function(a){I(a)}),E[F].addEventListener("scroll",function(a){I(a)}),E[F].addEventListener("keyup",function(a){K(a)}),E[F].addEventListener("keydown",function(a){J(a)});return c.settings.file.autoSave&&(c.saveInterval=a.setInterval(function(){if(!c._canSave)return;c.save()},c.settings.file.autoSave)),a.addEventListener("resize",function(){!c.iframe.webkitRequestFullScreen&&c.eeState.fullscreen?(d(c.iframeElement,{width:a.outerWidth+"px",height:a.innerHeight+"px"}),d(c.element,{height:a.innerHeight+"px"}),d(c.previewerIframe,{width:a.outerWidth/2+"px",height:a.innerHeight+"px"}),d(c.editorIframe,{width:a.outerWidth/2+"px",height:a.innerHeight+"px"})):c.eeState.fullscreen||H(A)}),c.iframe.close(),c.eeState.loaded=!0,c.eeState.unloaded=!1,b.call(this),this.emit("load"),this},q.prototype.unload=function(b){if(this.eeState.unloaded)throw new Error("Editor isn't loaded");var c=this,d=a.parent.document.getElementById(c._instanceId);return d.parentNode.removeChild(d),c.eeState.loaded=!1,c.eeState.unloaded=!0,b=b||function(){},c.saveInterval&&a.clearInterval(c.saveInterval),b.call(this),c.emit("unload"),c},q.prototype.preview=function(a){var b=this;return a=a||b.settings.basePath+b.settings.theme.preview,j(b.getElement("wrapper"),"epiceditor-edit-mode","epiceditor-preview-mode"),b.previewerIframeDocument.getElementById("theme")?b.previewerIframeDocument.getElementById("theme").name!==a&&(b.previewerIframeDocument.getElementById("theme").href=a):i(a,b.previewerIframeDocument,"theme"),b.previewer.innerHTML=b.exportFile(null,"html"),b.eeState.fullscreen||(b.editorIframe.style.display="none",b.previewerIframe.style.display="block",b.eeState.preview=!0,b.eeState.edit=!1,b.previewerIframe.focus()),b.emit("preview"),b},q.prototype.edit=function(){var a=this;return j(a.getElement("wrapper"),"epiceditor-preview-mode","epiceditor-edit-mode"),a.eeState.preview=!1,a.eeState.edit=!0,a.editorIframe.style.display="block",a.previewerIframe.style.display="none",a.editorIframe.focus(),a.emit("edit"),this},q.prototype.getElement=function(a){var b={container:this.element,wrapper:this.iframe.getElementById("epiceditor-wrapper"),wrapperIframe:this.iframeElement,editor:this.editorIframeDocument,editorIframe:this.editorIframe,previewer:this.previewerIframeDocument,previewerIframe:this.previewerIframe};return!b[a]||this.eeState.unloaded?null:b[a]},q.prototype.open=function(a){var c=this,d=c.settings.file.defaultContent,e;return a=a||c.settings.file.name,c.settings.file.name=a,this._storage[c.settings.localStorageName]&&(e=c.getFiles(),e[a]!==b?(m(c.editor,e[a].content),c.emit("read")):(m(c.editor,d),c.save(),c.emit("create")),c.previewer.innerHTML=c.exportFile(null,"html"),c.emit("open")),this},q.prototype.save=function(){var a=this,c,d=!1,e=a.settings.file.name,f=l(this.editor);return this._canSave=!0,c=JSON.parse(this._storage[a.settings.localStorageName]),c[e]===b?c[e]=a._defaultFileSchema():f!==c[e].content&&(c[e].modified=new Date,d=!0),c[e].content=f,this._storage[a.settings.localStorageName]=JSON.stringify(c),d&&a.emit("update"),this.emit("save"),this},q.prototype.remove=function(a){var b=this,c;return a=a||b.settings.file.name,a==b.settings.file.name&&(b._canSave=!1),c=JSON.parse(this._storage[b.settings.localStorageName]),delete c[a],this._storage[b.settings.localStorageName]=JSON.stringify(c),this.emit("remove"),this},q.prototype.rename=function(a,b){var c=this,d=JSON.parse(this._storage[c.settings.localStorageName]);return d[b]=d[a],delete d[a],this._storage[c.settings.localStorageName]=JSON.stringify(d),c.open(b),this},q.prototype.importFile=function(a,c,d,e){var f=this,g=!1;return a=a||f.settings.file.name,c=c||"",d=d||"md",e=e||{},JSON.parse(this._storage[f.settings.localStorageName])[a]===b&&(g=!0),f.settings.file.name=a,m(f.editor,c),g&&f.emit("create"),f.save(),f.eeState.fullscreen&&f.preview(),this},q.prototype.exportFile=function(a,c){var d=this,e,f;a=a||d.settings.file.name,c=c||"text",e=d.getFiles(a);if(e===b)return;f=e.content;switch(c){case"html":return f=f.replace(/\u00a0/g," ").replace(/&nbsp;/g," "),d.settings.parser(f);case"text":return f=f.replace(/&nbsp;/g," "),f;default:return f}},q.prototype.getFiles=function(a){var b=JSON.parse(this._storage[this.settings.localStorageName]);return a?b[a]:b},q.prototype.on=function(a,b){var c=this;return this.events[a]||(this.events[a]=[]),this.events[a].push(b),c},q.prototype.emit=function(a,b){function e(a){a.call(c,b)}var c=this,d;b=b||c.getFiles(c.settings.file.name);if(!this.events[a])return;for(d=0;d<c.events[a].length;d++)e(c.events[a][d]);return c},q.prototype.removeListener=function(a,b){var c=this;return b?this.events[a]?(this.events[a].splice(this.events[a].indexOf(b),1),c):c:(this.events[a]=[],c)},q.version="0.1.1",q._data={},a.EpicEditor=q})(window),function(){function c(a,c){return a[0][0]!=="!"?'<a href="'+j(c.href)+'"'+(c.title?' title="'+j(c.title)+'"':"")+">"+b.lexer(a[1])+"</a>":'<img src="'+j(c.href)+'" alt="'+j(a[1])+'"'+(c.title?' title="'+j(c.title)+'"':"")+">"}function f(){return e=d.pop()}function g(){switch(e.type){case"space":return"";case"hr":return"<hr>\n";case"heading":return"<h"+e.depth+">"+b.lexer(e.text)+"</h"+e.depth+">\n";case"code":return p.highlight&&(e.code=p.highlight(e.text,e.lang),e.code!=null&&e.code!==e.text&&(e.escaped=!0,e.text=e.code)),e.escaped||(e.text=j(e.text,!0)),"<pre><code"+(e.lang?' class="lang-'+e.lang+'"':"")+">"+e.text+"</code></pre>\n";case"blockquote_start":var a="";while(f().type!=="blockquote_end")a+=g();return"<blockquote>\n"+a+"</blockquote>\n";case"list_start":var c=e.ordered?"ol":"ul",a="";while(f().type!=="list_end")a+=g();return"<"+c+">\n"+a+"</"+c+">\n";case"list_item_start":var a="";while(f().type!=="list_item_end")a+=e.type==="text"?h():g();return"<li>"+a+"</li>\n";case"loose_item_start":var a="";while(f().type!=="list_item_end")a+=g();return"<li>"+a+"</li>\n";case"html":return p.sanitize?b.lexer(e.text):!e.pre&&!p.pedantic?b.lexer(e.text):e.text;case"paragraph":return"<p>"+b.lexer(e.text)+"</p>\n";case"text":return"<p>"+h()+"</p>\n"}}function h(){var a=e.text,c;while((c=d[d.length-1])&&c.type==="text")a+="\n"+f().text;return b.lexer(a)}function i(a){d=a.reverse();var b="";while(f())b+=g();return d=null,e=null,b}function j(a,b){return a.replace(b?/&/g:/&(?!#?\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function k(a){var b="",c=a.length,d=0,e;for(;d<c;d++)e=a.charCodeAt(d),Math.random()>.5&&(e="x"+e.toString(16)),b+="&#"+e+";";return b}function l(){var a="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+";return a}function m(a,b){return a=a.source,b=b||"",function c(d,e){return d?(a=a.replace(d,e.source||e),c):new RegExp(a,b)}}function n(){}function o(b,c){return r(c),i(a.lexer(b))}function r(c){c||(c=q);if(p===c)return;p=c,p.gfm?(a.fences=a.gfm.fences,a.paragraph=a.gfm.paragraph,b.text=b.gfm.text,b.url=b.gfm.url):(a.fences=a.normal.fences,a.paragraph=a.normal.paragraph,b.text=b.normal.text,b.url=b.normal.url),p.pedantic?(b.em=b.pedantic.em,b.strong=b.pedantic.strong):(b.em=b.normal.em,b.strong=b.normal.strong)}var a={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:n,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [^\0]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *([^\s]+)(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,paragraph:/^([^\n]+\n?(?!body))+\n*/,text:/^[^\n]+/};a.bullet=/(?:[*+-]|\d+\.)/,a.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,a.item=m(a.item,"gm")(/bull/g,a.bullet)(),a.list=m(a.list)(/bull/g,a.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)(),a.html=m(a.html)("comment",/<!--[^\0]*?-->/)("closed",/<(tag)[^\0]+?<\/\1>/)("closing",/<tag(?!:\/|@)\b(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,l())(),a.paragraph=function(){var b=a.paragraph.source,c=[];return function d(b){return b=a[b]?a[b].source:b,c.push(b.replace(/(^|[^\[])\^/g,"$1")),d}("hr")("heading")("lheading")("blockquote")("<"+l())("def"),new RegExp(b.replace("body",c.join("|")))}(),a.normal={fences:a.fences,paragraph:a.paragraph},a.gfm={fences:/^ *``` *(\w+)? *\n([^\0]+?)\s*``` *(?:\n+|$)/,paragraph:/^/},a.gfm.paragraph=m(a.paragraph)("(?!","(?!"+a.gfm.fences.source.replace(/(^|[^\[])\^/g,"$1")+"|")(),a.lexer=function(b){var c=[];return c.links={},b=b.replace(/\r\n|\r/g,"\n").replace(/\t/g," "),a.token(b,c,!0)},a.token=function(b,c,d){var b=b.replace(/^ +$/gm,""),e,f,g,h,i,j,k;while(b){if(g=a.newline.exec(b))b=b.substring(g[0].length),g[0].length>1&&c.push({type:"space"});if(g=a.code.exec(b)){b=b.substring(g[0].length),g=g[0].replace(/^ {4}/gm,""),c.push({type:"code",text:p.pedantic?g:g.replace(/\n+$/,"")});continue}if(g=a.fences.exec(b)){b=b.substring(g[0].length),c.push({type:"code",lang:g[1],text:g[2]});continue}if(g=a.heading.exec(b)){b=b.substring(g[0].length),c.push({type:"heading",depth:g[1].length,text:g[2]});continue}if(g=a.lheading.exec(b)){b=b.substring(g[0].length),c.push({type:"heading",depth:g[2]==="="?1:2,text:g[1]});continue}if(g=a.hr.exec(b)){b=b.substring(g[0].length),c.push({type:"hr"});continue}if(g=a.blockquote.exec(b)){b=b.substring(g[0].length),c.push({type:"blockquote_start"}),g=g[0].replace(/^ *> ?/gm,""),a.token(g,c,d),c.push({type:"blockquote_end"});continue}if(g=a.list.exec(b)){b=b.substring(g[0].length),c.push({type:"list_start",ordered:isFinite(g[2])}),g=g[0].match(a.item),e=!1,k=g.length,j=0;for(;j<k;j++)h=g[j],i=h.length,h=h.replace(/^ *([*+-]|\d+\.) +/,""),~h.indexOf("\n ")&&(i-=h.length,h=p.pedantic?h.replace(/^ {1,4}/gm,""):h.replace(new RegExp("^ {1,"+i+"}","gm"),"")),f=e||/\n\n(?!\s*$)/.test(h),j!==k-1&&(e=h[h.length-1]==="\n",f||(f=e)),c.push({type:f?"loose_item_start":"list_item_start"}),a.token(h,c),c.push({type:"list_item_end"});c.push({type:"list_end"});continue}if(g=a.html.exec(b)){b=b.substring(g[0].length),c.push({type:"html",pre:g[1]==="pre",text:g[0]});continue}if(d&&(g=a.def.exec(b))){b=b.substring(g[0].length),c.links[g[1].toLowerCase()]={href:g[2],title:g[3]};continue}if(d&&(g=a.paragraph.exec(b))){b=b.substring(g[0].length),c.push({type:"paragraph",text:g[0]});continue}if(g=a.text.exec(b)){b=b.substring(g[0].length),c.push({type:"text",text:g[0]});continue}}return c};var b={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:n,tag:/^<!--[^\0]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([^\0]+?)__(?!_)|^\*\*([^\0]+?)\*\*(?!\*)/,em:/^\b_((?:__|[^\0])+?)_\b|^\*((?:\*\*|[^\0])+?)\*(?!\*)/,code:/^(`+)([^\0]*?[^`])\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,text:/^[^\0]+?(?=[\\<!\[_*`]| {2,}\n|$)/};b._linkInside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/,b._linkHref=/\s*<?([^\s]*?)>?(?:\s+['"]([^\0]*?)['"])?\s*/,b.link=m(b.link)("inside",b._linkInside)("href",b._linkHref)(),b.reflink=m(b.reflink)("inside",b._linkInside)(),b.normal={url:b.url,strong:b.strong,em:b.em,text:b.text},b.pedantic={strong:/^__(?=\S)([^\0]*?\S)__(?!_)|^\*\*(?=\S)([^\0]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([^\0]*?\S)_(?!_)|^\*(?=\S)([^\0]*?\S)\*(?!\*)/},b.gfm={url:/^(https?:\/\/[^\s]+[^.,:;"')\]\s])/,text:/^[^\0]+?(?=[\\<!\[_*`]|https?:\/\/| {2,}\n|$)/},b.lexer=function(a){var e="",f=d.links,g,h,i,l;while(a){if(l=b.escape.exec(a)){a=a.substring(l[0].length),e+=l[1];continue}if(l=b.autolink.exec(a)){a=a.substring(l[0].length),l[2]==="@"?(h=l[1][6]===":"?k(l[1].substring(7)):k(l[1]),i=k("mailto:")+h):(h=j(l[1]),i=h),e+='<a href="'+i+'">'+h+"</a>";continue}if(l=b.url.exec(a)){a=a.substring(l[0].length),h=j(l[1]),i=h,e+='<a href="'+i+'">'+h+"</a>";continue}if(l=b.tag.exec(a)){a=a.substring(l[0].length),e+=p.sanitize?j(l[0]):l[0];continue}if(l=b.link.exec(a)){a=a.substring(l[0].length),e+=c(l,{href:l[2],title:l[3]});continue}if((l=b.reflink.exec(a))||(l=b.nolink.exec(a))){a=a.substring(l[0].length),g=(l[2]||l[1]).replace(/\s+/g," "),g=f[g.toLowerCase()];if(!g||!g.href){e+=l[0][0],a=l[0].substring(1)+a;continue}e+=c(l,g);continue}if(l=b.strong.exec(a)){a=a.substring(l[0].length),e+="<strong>"+b.lexer(l[2]||l[1])+"</strong>";continue}if(l=b.em.exec(a)){a=a.substring(l[0].length),e+="<em>"+b.lexer(l[2]||l[1])+"</em>";continue}if(l=b.code.exec(a)){a=a.substring(l[0].length),e+="<code>"+j(l[2],!0)+"</code>";continue}if(l=b.br.exec(a)){a=a.substring(l[0].length),e+="<br>";continue}if(l=b.text.exec(a)){a=a.substring(l[0].length),e+=j(l[0]);continue}}return e};var d,e;n.exec=n;var p,q;o.options=o.setOptions=function(a){return q=a,r(a),o},o.setOptions({gfm:!0,pedantic:!1,sanitize:!1,highlight:null}),o.parser=function(a,b){return r(b),i(a)},o.lexer=function(b,c){return r(c),a.lexer(b)},o.parse=o,typeof module!="undefined"?module.exports=o:this.marked=o}.call(function(){return this||(typeof window!="undefined"?window:global)}());