Mercurial > zeropaste
comparison lib/assets/javascripts/marked.js @ 100:90b59418828a
Three times more fun with tabs (added plain and markdown tab).
author | Edho Arief <edho@myconan.net> |
---|---|
date | Mon, 12 Nov 2012 10:42:00 +0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
99:e0e99705e79d | 100:90b59418828a |
---|---|
1 /** | |
2 * marked - A markdown parser (https://github.com/chjj/marked) | |
3 * Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed) | |
4 */ | |
5 | |
6 ;(function() { | |
7 | |
8 /** | |
9 * Block-Level Grammar | |
10 */ | |
11 | |
12 var block = { | |
13 newline: /^\n+/, | |
14 code: /^( {4}[^\n]+\n*)+/, | |
15 fences: noop, | |
16 hr: /^( *[-*_]){3,} *(?:\n+|$)/, | |
17 heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, | |
18 lheading: /^([^\n]+)\n *(=|-){3,} *\n*/, | |
19 blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/, | |
20 list: /^( *)(bull) [^\0]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, | |
21 html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, | |
22 def: /^ *\[([^\]]+)\]: *([^\s]+)(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, | |
23 paragraph: /^([^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+\n*/, | |
24 text: /^[^\n]+/ | |
25 }; | |
26 | |
27 block.bullet = /(?:[*+-]|\d+\.)/; | |
28 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; | |
29 block.item = replace(block.item, 'gm') | |
30 (/bull/g, block.bullet) | |
31 (); | |
32 | |
33 block.list = replace(block.list) | |
34 (/bull/g, block.bullet) | |
35 ('hr', /\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/) | |
36 (); | |
37 | |
38 block.html = replace(block.html) | |
39 ('comment', /<!--[^\0]*?-->/) | |
40 ('closed', /<(tag)[^\0]+?<\/\1>/) | |
41 ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/) | |
42 (/tag/g, tag()) | |
43 (); | |
44 | |
45 block.paragraph = replace(block.paragraph) | |
46 ('hr', block.hr) | |
47 ('heading', block.heading) | |
48 ('lheading', block.lheading) | |
49 ('blockquote', block.blockquote) | |
50 ('tag', '<' + tag()) | |
51 ('def', block.def) | |
52 (); | |
53 | |
54 block.normal = { | |
55 fences: block.fences, | |
56 paragraph: block.paragraph | |
57 }; | |
58 | |
59 block.gfm = { | |
60 fences: /^ *(```|~~~) *(\w+)? *\n([^\0]+?)\s*\1 *(?:\n+|$)/, | |
61 paragraph: /^/ | |
62 }; | |
63 | |
64 block.gfm.paragraph = replace(block.paragraph) | |
65 ('(?!', '(?!' + block.gfm.fences.source.replace('\\1', '\\2') + '|') | |
66 (); | |
67 | |
68 /** | |
69 * Block Lexer | |
70 */ | |
71 | |
72 block.lexer = function(src) { | |
73 var tokens = []; | |
74 | |
75 tokens.links = {}; | |
76 | |
77 src = src | |
78 .replace(/\r\n|\r/g, '\n') | |
79 .replace(/\t/g, ' '); | |
80 | |
81 return block.token(src, tokens, true); | |
82 }; | |
83 | |
84 block.token = function(src, tokens, top) { | |
85 var src = src.replace(/^ +$/gm, '') | |
86 , next | |
87 , loose | |
88 , cap | |
89 , item | |
90 , space | |
91 , i | |
92 , l; | |
93 | |
94 while (src) { | |
95 // newline | |
96 if (cap = block.newline.exec(src)) { | |
97 src = src.substring(cap[0].length); | |
98 if (cap[0].length > 1) { | |
99 tokens.push({ | |
100 type: 'space' | |
101 }); | |
102 } | |
103 } | |
104 | |
105 // code | |
106 if (cap = block.code.exec(src)) { | |
107 src = src.substring(cap[0].length); | |
108 cap = cap[0].replace(/^ {4}/gm, ''); | |
109 tokens.push({ | |
110 type: 'code', | |
111 text: !options.pedantic | |
112 ? cap.replace(/\n+$/, '') | |
113 : cap | |
114 }); | |
115 continue; | |
116 } | |
117 | |
118 // fences (gfm) | |
119 if (cap = block.fences.exec(src)) { | |
120 src = src.substring(cap[0].length); | |
121 tokens.push({ | |
122 type: 'code', | |
123 lang: cap[2], | |
124 text: cap[3] | |
125 }); | |
126 continue; | |
127 } | |
128 | |
129 // heading | |
130 if (cap = block.heading.exec(src)) { | |
131 src = src.substring(cap[0].length); | |
132 tokens.push({ | |
133 type: 'heading', | |
134 depth: cap[1].length, | |
135 text: cap[2] | |
136 }); | |
137 continue; | |
138 } | |
139 | |
140 // lheading | |
141 if (cap = block.lheading.exec(src)) { | |
142 src = src.substring(cap[0].length); | |
143 tokens.push({ | |
144 type: 'heading', | |
145 depth: cap[2] === '=' ? 1 : 2, | |
146 text: cap[1] | |
147 }); | |
148 continue; | |
149 } | |
150 | |
151 // hr | |
152 if (cap = block.hr.exec(src)) { | |
153 src = src.substring(cap[0].length); | |
154 tokens.push({ | |
155 type: 'hr' | |
156 }); | |
157 continue; | |
158 } | |
159 | |
160 // blockquote | |
161 if (cap = block.blockquote.exec(src)) { | |
162 src = src.substring(cap[0].length); | |
163 | |
164 tokens.push({ | |
165 type: 'blockquote_start' | |
166 }); | |
167 | |
168 cap = cap[0].replace(/^ *> ?/gm, ''); | |
169 | |
170 // Pass `top` to keep the current | |
171 // "toplevel" state. This is exactly | |
172 // how markdown.pl works. | |
173 block.token(cap, tokens, top); | |
174 | |
175 tokens.push({ | |
176 type: 'blockquote_end' | |
177 }); | |
178 | |
179 continue; | |
180 } | |
181 | |
182 // list | |
183 if (cap = block.list.exec(src)) { | |
184 src = src.substring(cap[0].length); | |
185 | |
186 tokens.push({ | |
187 type: 'list_start', | |
188 ordered: isFinite(cap[2]) | |
189 }); | |
190 | |
191 // Get each top-level item. | |
192 cap = cap[0].match(block.item); | |
193 | |
194 next = false; | |
195 l = cap.length; | |
196 i = 0; | |
197 | |
198 for (; i < l; i++) { | |
199 item = cap[i]; | |
200 | |
201 // Remove the list item's bullet | |
202 // so it is seen as the next token. | |
203 space = item.length; | |
204 item = item.replace(/^ *([*+-]|\d+\.) +/, ''); | |
205 | |
206 // Outdent whatever the | |
207 // list item contains. Hacky. | |
208 if (~item.indexOf('\n ')) { | |
209 space -= item.length; | |
210 item = !options.pedantic | |
211 ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') | |
212 : item.replace(/^ {1,4}/gm, ''); | |
213 } | |
214 | |
215 // Determine whether item is loose or not. | |
216 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ | |
217 // for discount behavior. | |
218 loose = next || /\n\n(?!\s*$)/.test(item); | |
219 if (i !== l - 1) { | |
220 next = item[item.length-1] === '\n'; | |
221 if (!loose) loose = next; | |
222 } | |
223 | |
224 tokens.push({ | |
225 type: loose | |
226 ? 'loose_item_start' | |
227 : 'list_item_start' | |
228 }); | |
229 | |
230 // Recurse. | |
231 block.token(item, tokens); | |
232 | |
233 tokens.push({ | |
234 type: 'list_item_end' | |
235 }); | |
236 } | |
237 | |
238 tokens.push({ | |
239 type: 'list_end' | |
240 }); | |
241 | |
242 continue; | |
243 } | |
244 | |
245 // html | |
246 if (cap = block.html.exec(src)) { | |
247 src = src.substring(cap[0].length); | |
248 tokens.push({ | |
249 type: options.sanitize | |
250 ? 'paragraph' | |
251 : 'html', | |
252 pre: cap[1] === 'pre', | |
253 text: cap[0] | |
254 }); | |
255 continue; | |
256 } | |
257 | |
258 // def | |
259 if (top && (cap = block.def.exec(src))) { | |
260 src = src.substring(cap[0].length); | |
261 tokens.links[cap[1].toLowerCase()] = { | |
262 href: cap[2], | |
263 title: cap[3] | |
264 }; | |
265 continue; | |
266 } | |
267 | |
268 // top-level paragraph | |
269 if (top && (cap = block.paragraph.exec(src))) { | |
270 src = src.substring(cap[0].length); | |
271 tokens.push({ | |
272 type: 'paragraph', | |
273 text: cap[0] | |
274 }); | |
275 continue; | |
276 } | |
277 | |
278 // text | |
279 if (cap = block.text.exec(src)) { | |
280 // Top-level should never reach here. | |
281 src = src.substring(cap[0].length); | |
282 tokens.push({ | |
283 type: 'text', | |
284 text: cap[0] | |
285 }); | |
286 continue; | |
287 } | |
288 } | |
289 | |
290 return tokens; | |
291 }; | |
292 | |
293 /** | |
294 * Inline Processing | |
295 */ | |
296 | |
297 var inline = { | |
298 escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, | |
299 autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, | |
300 url: noop, | |
301 tag: /^<!--[^\0]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, | |
302 link: /^!?\[(inside)\]\(href\)/, | |
303 reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, | |
304 nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, | |
305 strong: /^__([^\0]+?)__(?!_)|^\*\*([^\0]+?)\*\*(?!\*)/, | |
306 em: /^\b_((?:__|[^\0])+?)_\b|^\*((?:\*\*|[^\0])+?)\*(?!\*)/, | |
307 code: /^(`+)([^\0]*?[^`])\1(?!`)/, | |
308 br: /^ {2,}\n(?!\s*$)/, | |
309 text: /^[^\0]+?(?=[\\<!\[_*`]| {2,}\n|$)/ | |
310 }; | |
311 | |
312 inline._linkInside = /(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/; | |
313 inline._linkHref = /\s*<?([^\s]*?)>?(?:\s+['"]([^\0]*?)['"])?\s*/; | |
314 | |
315 inline.link = replace(inline.link) | |
316 ('inside', inline._linkInside) | |
317 ('href', inline._linkHref) | |
318 (); | |
319 | |
320 inline.reflink = replace(inline.reflink) | |
321 ('inside', inline._linkInside) | |
322 (); | |
323 | |
324 inline.normal = { | |
325 url: inline.url, | |
326 strong: inline.strong, | |
327 em: inline.em, | |
328 text: inline.text | |
329 }; | |
330 | |
331 inline.pedantic = { | |
332 strong: /^__(?=\S)([^\0]*?\S)__(?!_)|^\*\*(?=\S)([^\0]*?\S)\*\*(?!\*)/, | |
333 em: /^_(?=\S)([^\0]*?\S)_(?!_)|^\*(?=\S)([^\0]*?\S)\*(?!\*)/ | |
334 }; | |
335 | |
336 inline.gfm = { | |
337 url: /^(https?:\/\/[^\s]+[^.,:;"')\]\s])/, | |
338 text: /^[^\0]+?(?=[\\<!\[_*`]|https?:\/\/| {2,}\n|$)/ | |
339 }; | |
340 | |
341 /** | |
342 * Inline Lexer | |
343 */ | |
344 | |
345 inline.lexer = function(src) { | |
346 var out = '' | |
347 , links = tokens.links | |
348 , link | |
349 , text | |
350 , href | |
351 , cap; | |
352 | |
353 while (src) { | |
354 // escape | |
355 if (cap = inline.escape.exec(src)) { | |
356 src = src.substring(cap[0].length); | |
357 out += cap[1]; | |
358 continue; | |
359 } | |
360 | |
361 // autolink | |
362 if (cap = inline.autolink.exec(src)) { | |
363 src = src.substring(cap[0].length); | |
364 if (cap[2] === '@') { | |
365 text = cap[1][6] === ':' | |
366 ? mangle(cap[1].substring(7)) | |
367 : mangle(cap[1]); | |
368 href = mangle('mailto:') + text; | |
369 } else { | |
370 text = escape(cap[1]); | |
371 href = text; | |
372 } | |
373 out += '<a href="' | |
374 + href | |
375 + '">' | |
376 + text | |
377 + '</a>'; | |
378 continue; | |
379 } | |
380 | |
381 // url (gfm) | |
382 if (cap = inline.url.exec(src)) { | |
383 src = src.substring(cap[0].length); | |
384 text = escape(cap[1]); | |
385 href = text; | |
386 out += '<a href="' | |
387 + href | |
388 + '">' | |
389 + text | |
390 + '</a>'; | |
391 continue; | |
392 } | |
393 | |
394 // tag | |
395 if (cap = inline.tag.exec(src)) { | |
396 src = src.substring(cap[0].length); | |
397 out += options.sanitize | |
398 ? escape(cap[0]) | |
399 : cap[0]; | |
400 continue; | |
401 } | |
402 | |
403 // link | |
404 if (cap = inline.link.exec(src)) { | |
405 src = src.substring(cap[0].length); | |
406 out += outputLink(cap, { | |
407 href: cap[2], | |
408 title: cap[3] | |
409 }); | |
410 continue; | |
411 } | |
412 | |
413 // reflink, nolink | |
414 if ((cap = inline.reflink.exec(src)) | |
415 || (cap = inline.nolink.exec(src))) { | |
416 src = src.substring(cap[0].length); | |
417 link = (cap[2] || cap[1]).replace(/\s+/g, ' '); | |
418 link = links[link.toLowerCase()]; | |
419 if (!link || !link.href) { | |
420 out += cap[0][0]; | |
421 src = cap[0].substring(1) + src; | |
422 continue; | |
423 } | |
424 out += outputLink(cap, link); | |
425 continue; | |
426 } | |
427 | |
428 // strong | |
429 if (cap = inline.strong.exec(src)) { | |
430 src = src.substring(cap[0].length); | |
431 out += '<strong>' | |
432 + inline.lexer(cap[2] || cap[1]) | |
433 + '</strong>'; | |
434 continue; | |
435 } | |
436 | |
437 // em | |
438 if (cap = inline.em.exec(src)) { | |
439 src = src.substring(cap[0].length); | |
440 out += '<em>' | |
441 + inline.lexer(cap[2] || cap[1]) | |
442 + '</em>'; | |
443 continue; | |
444 } | |
445 | |
446 // code | |
447 if (cap = inline.code.exec(src)) { | |
448 src = src.substring(cap[0].length); | |
449 out += '<code>' | |
450 + escape(cap[2], true) | |
451 + '</code>'; | |
452 continue; | |
453 } | |
454 | |
455 // br | |
456 if (cap = inline.br.exec(src)) { | |
457 src = src.substring(cap[0].length); | |
458 out += '<br>'; | |
459 continue; | |
460 } | |
461 | |
462 // text | |
463 if (cap = inline.text.exec(src)) { | |
464 src = src.substring(cap[0].length); | |
465 out += escape(cap[0]); | |
466 continue; | |
467 } | |
468 } | |
469 | |
470 return out; | |
471 }; | |
472 | |
473 function outputLink(cap, link) { | |
474 if (cap[0][0] !== '!') { | |
475 return '<a href="' | |
476 + escape(link.href) | |
477 + '"' | |
478 + (link.title | |
479 ? ' title="' | |
480 + escape(link.title) | |
481 + '"' | |
482 : '') | |
483 + '>' | |
484 + inline.lexer(cap[1]) | |
485 + '</a>'; | |
486 } else { | |
487 return '<img src="' | |
488 + escape(link.href) | |
489 + '" alt="' | |
490 + escape(cap[1]) | |
491 + '"' | |
492 + (link.title | |
493 ? ' title="' | |
494 + escape(link.title) | |
495 + '"' | |
496 : '') | |
497 + '>'; | |
498 } | |
499 } | |
500 | |
501 /** | |
502 * Parsing | |
503 */ | |
504 | |
505 var tokens | |
506 , token; | |
507 | |
508 function next() { | |
509 return token = tokens.pop(); | |
510 } | |
511 | |
512 function tok() { | |
513 switch (token.type) { | |
514 case 'space': { | |
515 return ''; | |
516 } | |
517 case 'hr': { | |
518 return '<hr>\n'; | |
519 } | |
520 case 'heading': { | |
521 return '<h' | |
522 + token.depth | |
523 + '>' | |
524 + inline.lexer(token.text) | |
525 + '</h' | |
526 + token.depth | |
527 + '>\n'; | |
528 } | |
529 case 'code': { | |
530 if (options.highlight) { | |
531 token.code = options.highlight(token.text, token.lang); | |
532 if (token.code != null && token.code !== token.text) { | |
533 token.escaped = true; | |
534 token.text = token.code; | |
535 } | |
536 } | |
537 | |
538 if (!token.escaped) { | |
539 token.text = escape(token.text, true); | |
540 } | |
541 | |
542 return '<pre><code' | |
543 + (token.lang | |
544 ? ' class="lang-' | |
545 + token.lang | |
546 + '"' | |
547 : '') | |
548 + '>' | |
549 + token.text | |
550 + '</code></pre>\n'; | |
551 } | |
552 case 'blockquote_start': { | |
553 var body = ''; | |
554 | |
555 while (next().type !== 'blockquote_end') { | |
556 body += tok(); | |
557 } | |
558 | |
559 return '<blockquote>\n' | |
560 + body | |
561 + '</blockquote>\n'; | |
562 } | |
563 case 'list_start': { | |
564 var type = token.ordered ? 'ol' : 'ul' | |
565 , body = ''; | |
566 | |
567 while (next().type !== 'list_end') { | |
568 body += tok(); | |
569 } | |
570 | |
571 return '<' | |
572 + type | |
573 + '>\n' | |
574 + body | |
575 + '</' | |
576 + type | |
577 + '>\n'; | |
578 } | |
579 case 'list_item_start': { | |
580 var body = ''; | |
581 | |
582 while (next().type !== 'list_item_end') { | |
583 body += token.type === 'text' | |
584 ? parseText() | |
585 : tok(); | |
586 } | |
587 | |
588 return '<li>' | |
589 + body | |
590 + '</li>\n'; | |
591 } | |
592 case 'loose_item_start': { | |
593 var body = ''; | |
594 | |
595 while (next().type !== 'list_item_end') { | |
596 body += tok(); | |
597 } | |
598 | |
599 return '<li>' | |
600 + body | |
601 + '</li>\n'; | |
602 } | |
603 case 'html': { | |
604 return !token.pre && !options.pedantic | |
605 ? inline.lexer(token.text) | |
606 : token.text; | |
607 } | |
608 case 'paragraph': { | |
609 return '<p>' | |
610 + inline.lexer(token.text) | |
611 + '</p>\n'; | |
612 } | |
613 case 'text': { | |
614 return '<p>' | |
615 + parseText() | |
616 + '</p>\n'; | |
617 } | |
618 } | |
619 } | |
620 | |
621 function parseText() { | |
622 var body = token.text | |
623 , top; | |
624 | |
625 while ((top = tokens[tokens.length-1]) | |
626 && top.type === 'text') { | |
627 body += '\n' + next().text; | |
628 } | |
629 | |
630 return inline.lexer(body); | |
631 } | |
632 | |
633 function parse(src) { | |
634 tokens = src.reverse(); | |
635 | |
636 var out = ''; | |
637 while (next()) { | |
638 out += tok(); | |
639 } | |
640 | |
641 tokens = null; | |
642 token = null; | |
643 | |
644 return out; | |
645 } | |
646 | |
647 /** | |
648 * Helpers | |
649 */ | |
650 | |
651 function escape(html, encode) { | |
652 return html | |
653 .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') | |
654 .replace(/</g, '<') | |
655 .replace(/>/g, '>') | |
656 .replace(/"/g, '"') | |
657 .replace(/'/g, '''); | |
658 } | |
659 | |
660 function mangle(text) { | |
661 var out = '' | |
662 , l = text.length | |
663 , i = 0 | |
664 , ch; | |
665 | |
666 for (; i < l; i++) { | |
667 ch = text.charCodeAt(i); | |
668 if (Math.random() > 0.5) { | |
669 ch = 'x' + ch.toString(16); | |
670 } | |
671 out += '&#' + ch + ';'; | |
672 } | |
673 | |
674 return out; | |
675 } | |
676 | |
677 function tag() { | |
678 var tag = '(?!(?:' | |
679 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' | |
680 + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' | |
681 + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b'; | |
682 | |
683 return tag; | |
684 } | |
685 | |
686 function replace(regex, opt) { | |
687 regex = regex.source; | |
688 opt = opt || ''; | |
689 return function self(name, val) { | |
690 if (!name) return new RegExp(regex, opt); | |
691 val = val.source || val; | |
692 val = val.replace(/(^|[^\[])\^/g, '$1'); | |
693 regex = regex.replace(name, val); | |
694 return self; | |
695 }; | |
696 } | |
697 | |
698 function noop() {} | |
699 noop.exec = noop; | |
700 | |
701 /** | |
702 * Marked | |
703 */ | |
704 | |
705 function marked(src, opt) { | |
706 setOptions(opt); | |
707 return parse(block.lexer(src)); | |
708 } | |
709 | |
710 /** | |
711 * Options | |
712 */ | |
713 | |
714 var options | |
715 , defaults; | |
716 | |
717 function setOptions(opt) { | |
718 if (!opt) opt = defaults; | |
719 if (options === opt) return; | |
720 options = opt; | |
721 | |
722 if (options.gfm) { | |
723 block.fences = block.gfm.fences; | |
724 block.paragraph = block.gfm.paragraph; | |
725 inline.text = inline.gfm.text; | |
726 inline.url = inline.gfm.url; | |
727 } else { | |
728 block.fences = block.normal.fences; | |
729 block.paragraph = block.normal.paragraph; | |
730 inline.text = inline.normal.text; | |
731 inline.url = inline.normal.url; | |
732 } | |
733 | |
734 if (options.pedantic) { | |
735 inline.em = inline.pedantic.em; | |
736 inline.strong = inline.pedantic.strong; | |
737 } else { | |
738 inline.em = inline.normal.em; | |
739 inline.strong = inline.normal.strong; | |
740 } | |
741 } | |
742 | |
743 marked.options = | |
744 marked.setOptions = function(opt) { | |
745 defaults = opt; | |
746 setOptions(opt); | |
747 return marked; | |
748 }; | |
749 | |
750 marked.setOptions({ | |
751 gfm: true, | |
752 pedantic: false, | |
753 sanitize: false, | |
754 highlight: null | |
755 }); | |
756 | |
757 /** | |
758 * Expose | |
759 */ | |
760 | |
761 marked.parser = function(src, opt) { | |
762 setOptions(opt); | |
763 return parse(src); | |
764 }; | |
765 | |
766 marked.lexer = function(src, opt) { | |
767 setOptions(opt); | |
768 return block.lexer(src); | |
769 }; | |
770 | |
771 marked.parse = marked; | |
772 | |
773 if (typeof module !== 'undefined') { | |
774 module.exports = marked; | |
775 } else { | |
776 this.marked = marked; | |
777 } | |
778 | |
779 }).call(function() { | |
780 return this || (typeof window !== 'undefined' ? window : global); | |
781 }()); |