UNPKG

127 kBJavaScriptView Raw
1(function () {
2/**
3 * Create a cached version of a pure function.
4 */
5function cached(fn) {
6 var cache = Object.create(null);
7 return function (str) {
8 var key = isPrimitive(str) ? str : JSON.stringify(str);
9 var hit = cache[key];
10 return hit || (cache[key] = fn(str))
11 }
12}
13
14/**
15 * Hyphenate a camelCase string.
16 */
17var hyphenate = cached(function (str) {
18 return str.replace(/([A-Z])/g, function (m) { return '-' + m.toLowerCase(); })
19});
20
21var hasOwn = Object.prototype.hasOwnProperty;
22
23/**
24 * Simple Object.assign polyfill
25 */
26var merge =
27 Object.assign ||
28 function (to) {
29 var arguments$1 = arguments;
30
31 for (var i = 1; i < arguments.length; i++) {
32 var from = Object(arguments$1[i]);
33
34 for (var key in from) {
35 if (hasOwn.call(from, key)) {
36 to[key] = from[key];
37 }
38 }
39 }
40
41 return to
42 };
43
44/**
45 * Check if value is primitive
46 */
47function isPrimitive(value) {
48 return typeof value === 'string' || typeof value === 'number'
49}
50
51/**
52 * Perform no operation.
53 */
54function noop() {}
55
56/**
57 * Check if value is function
58 */
59function isFn(obj) {
60 return typeof obj === 'function'
61}
62
63function config () {
64 var config = merge(
65 {
66 el: '#app',
67 repo: '',
68 maxLevel: 6,
69 subMaxLevel: 0,
70 loadSidebar: null,
71 loadNavbar: null,
72 homepage: 'README.md',
73 coverpage: '',
74 basePath: '',
75 auto2top: false,
76 name: '',
77 themeColor: '',
78 nameLink: window.location.pathname,
79 autoHeader: false,
80 executeScript: null,
81 noEmoji: false,
82 ga: '',
83 ext: '.md',
84 mergeNavbar: false,
85 formatUpdated: '',
86 externalLinkTarget: '_blank',
87 routerMode: 'hash',
88 noCompileLinks: [],
89 relativePath: false
90 },
91 window.$docsify
92 );
93
94 var script =
95 document.currentScript ||
96 [].slice
97 .call(document.getElementsByTagName('script'))
98 .filter(function (n) { return /docsify\./.test(n.src); })[0];
99
100 if (script) {
101 for (var prop in config) {
102 if (hasOwn.call(config, prop)) {
103 var val = script.getAttribute('data-' + hyphenate(prop));
104
105 if (isPrimitive(val)) {
106 config[prop] = val === '' ? true : val;
107 }
108 }
109 }
110
111 if (config.loadSidebar === true) {
112 config.loadSidebar = '_sidebar' + config.ext;
113 }
114 if (config.loadNavbar === true) {
115 config.loadNavbar = '_navbar' + config.ext;
116 }
117 if (config.coverpage === true) {
118 config.coverpage = '_coverpage' + config.ext;
119 }
120 if (config.repo === true) {
121 config.repo = '';
122 }
123 if (config.name === true) {
124 config.name = '';
125 }
126 }
127
128 window.$docsify = config;
129
130 return config
131}
132
133function initLifecycle(vm) {
134 var hooks = [
135 'init',
136 'mounted',
137 'beforeEach',
138 'afterEach',
139 'doneEach',
140 'ready'
141 ];
142
143 vm._hooks = {};
144 vm._lifecycle = {};
145 hooks.forEach(function (hook) {
146 var arr = (vm._hooks[hook] = []);
147 vm._lifecycle[hook] = function (fn) { return arr.push(fn); };
148 });
149}
150
151function callHook(vm, hook, data, next) {
152 if ( next === void 0 ) next = noop;
153
154 var queue = vm._hooks[hook];
155
156 var step = function (index) {
157 var hook = queue[index];
158 if (index >= queue.length) {
159 next(data);
160 } else if (typeof hook === 'function') {
161 if (hook.length === 2) {
162 hook(data, function (result) {
163 data = result;
164 step(index + 1);
165 });
166 } else {
167 var result = hook(data);
168 data = result === undefined ? data : result;
169 step(index + 1);
170 }
171 } else {
172 step(index + 1);
173 }
174 };
175
176 step(0);
177}
178
179var inBrowser = !false;
180
181var isMobile = inBrowser && document.body.clientWidth <= 600;
182
183/**
184 * @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
185 */
186var supportsPushState =
187 inBrowser &&
188 (function () {
189 // Borrowed wholesale from https://github.com/defunkt/jquery-pjax
190 return (
191 window.history &&
192 window.history.pushState &&
193 window.history.replaceState &&
194 // PushState isn’t reliable on iOS until 5.
195 !navigator.userAgent.match(
196 /((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/
197 )
198 )
199 })();
200
201var cacheNode = {};
202
203/**
204 * Get Node
205 * @param {String|Element} el
206 * @param {Boolean} noCache
207 * @return {Element}
208 */
209function getNode(el, noCache) {
210 if ( noCache === void 0 ) noCache = false;
211
212 if (typeof el === 'string') {
213 if (typeof window.Vue !== 'undefined') {
214 return find(el)
215 }
216 el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el));
217 }
218
219 return el
220}
221
222var $ = inBrowser && document;
223
224var body = inBrowser && $.body;
225
226var head = inBrowser && $.head;
227
228/**
229 * Find element
230 * @example
231 * find('nav') => document.querySelector('nav')
232 * find(nav, 'a') => nav.querySelector('a')
233 */
234function find(el, node) {
235 return node ? el.querySelector(node) : $.querySelector(el)
236}
237
238/**
239 * Find all elements
240 * @example
241 * findAll('a') => [].slice.call(document.querySelectorAll('a'))
242 * findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a'))
243 */
244function findAll(el, node) {
245 return [].slice.call(
246 node ? el.querySelectorAll(node) : $.querySelectorAll(el)
247 )
248}
249
250function create(node, tpl) {
251 node = $.createElement(node);
252 if (tpl) {
253 node.innerHTML = tpl;
254 }
255 return node
256}
257
258function appendTo(target, el) {
259 return target.appendChild(el)
260}
261
262function before(target, el) {
263 return target.insertBefore(el, target.children[0])
264}
265
266function on(el, type, handler) {
267 isFn(type) ?
268 window.addEventListener(el, type) :
269 el.addEventListener(type, handler);
270}
271
272function off(el, type, handler) {
273 isFn(type) ?
274 window.removeEventListener(el, type) :
275 el.removeEventListener(type, handler);
276}
277
278/**
279 * Toggle class
280 *
281 * @example
282 * toggleClass(el, 'active') => el.classList.toggle('active')
283 * toggleClass(el, 'add', 'active') => el.classList.add('active')
284 */
285function toggleClass(el, type, val) {
286 el && el.classList[val ? type : 'toggle'](val || type);
287}
288
289function style(content) {
290 appendTo(head, create('style', content));
291}
292
293
294var dom = Object.freeze({
295 getNode: getNode,
296 $: $,
297 body: body,
298 head: head,
299 find: find,
300 findAll: findAll,
301 create: create,
302 appendTo: appendTo,
303 before: before,
304 on: on,
305 off: off,
306 toggleClass: toggleClass,
307 style: style
308});
309
310/**
311 * Render github corner
312 * @param {Object} data
313 * @return {String}
314 */
315function corner(data) {
316 if (!data) {
317 return ''
318 }
319 if (!/\/\//.test(data)) {
320 data = 'https://github.com/' + data;
321 }
322 data = data.replace(/^git\+/, '');
323
324 return (
325 "<a href=\"" + data + "\" class=\"github-corner\" aria-label=\"View source on Github\">" +
326 '<svg viewBox="0 0 250 250" aria-hidden="true">' +
327 '<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>' +
328 '<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>' +
329 '<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>' +
330 '</svg>' +
331 '</a>'
332 )
333}
334
335/**
336 * Render main content
337 */
338function main(config) {
339 var aside =
340 '<button class="sidebar-toggle">' +
341 '<div class="sidebar-toggle-button">' +
342 '<span></span><span></span><span></span>' +
343 '</div>' +
344 '</button>' +
345 '<aside class="sidebar">' +
346 (config.name ?
347 ("<h1 class=\"app-name\"><a class=\"app-name-link\" data-nosearch>" + (config.logo ?
348 ("<img alt=" + (config.name) + " src=" + (config.logo) + ">") :
349 config.name) + "</a></h1>") :
350 '') +
351 '<div class="sidebar-nav"><!--sidebar--></div>' +
352 '</aside>';
353
354 return (
355 (isMobile ? (aside + "<main>") : ("<main>" + aside)) +
356 '<section class="content">' +
357 '<article class="markdown-section" id="main"><!--main--></article>' +
358 '</section>' +
359 '</main>'
360 )
361}
362
363/**
364 * Cover Page
365 */
366function cover() {
367 var SL = ', 100%, 85%';
368 var bgc =
369 'linear-gradient(to left bottom, ' +
370 "hsl(" + (Math.floor(Math.random() * 255) + SL) + ") 0%," +
371 "hsl(" + (Math.floor(Math.random() * 255) + SL) + ") 100%)";
372
373 return (
374 "<section class=\"cover show\" style=\"background: " + bgc + "\">" +
375 '<div class="cover-main"><!--cover--></div>' +
376 '<div class="mask"></div>' +
377 '</section>'
378 )
379}
380
381/**
382 * Render tree
383 * @param {Array} tree
384 * @param {String} tpl
385 * @return {String}
386 */
387function tree(toc, tpl) {
388 if ( tpl === void 0 ) tpl = '<ul class="app-sub-sidebar">{inner}</ul>';
389
390 if (!toc || !toc.length) {
391 return ''
392 }
393 var innerHTML = '';
394 toc.forEach(function (node) {
395 innerHTML += "<li><a class=\"section-link\" href=\"" + (node.slug) + "\">" + (node.title) + "</a></li>";
396 if (node.children) {
397 innerHTML += tree(node.children, tpl);
398 }
399 });
400 return tpl.replace('{inner}', innerHTML)
401}
402
403function helper(className, content) {
404 return ("<p class=\"" + className + "\">" + (content.slice(5).trim()) + "</p>")
405}
406
407function theme(color) {
408 return ("<style>:root{--theme-color: " + color + ";}</style>")
409}
410
411var barEl;
412var timeId;
413
414/**
415 * Init progress component
416 */
417function init() {
418 var div = create('div');
419
420 div.classList.add('progress');
421 appendTo(body, div);
422 barEl = div;
423}
424/**
425 * Render progress bar
426 */
427function progressbar (ref) {
428 var loaded = ref.loaded;
429 var total = ref.total;
430 var step = ref.step;
431
432 var num;
433
434 !barEl && init();
435
436 if (step) {
437 num = parseInt(barEl.style.width || 0, 10) + step;
438 num = num > 80 ? 80 : num;
439 } else {
440 num = Math.floor(loaded / total * 100);
441 }
442
443 barEl.style.opacity = 1;
444 barEl.style.width = num >= 95 ? '100%' : num + '%';
445
446 if (num >= 95) {
447 clearTimeout(timeId);
448 timeId = setTimeout(function (_) {
449 barEl.style.opacity = 0;
450 barEl.style.width = '0%';
451 }, 200);
452 }
453}
454
455var cache = {};
456
457/**
458 * Simple ajax get
459 * @param {string} url
460 * @param {boolean} [hasBar=false] has progress bar
461 * @return { then(resolve, reject), abort }
462 */
463function get(url, hasBar, headers) {
464 if ( hasBar === void 0 ) hasBar = false;
465 if ( headers === void 0 ) headers = {};
466
467 var xhr = new XMLHttpRequest();
468 var on = function () {
469 xhr.addEventListener.apply(xhr, arguments);
470 };
471 var cached$$1 = cache[url];
472
473 if (cached$$1) {
474 return {then: function (cb) { return cb(cached$$1.content, cached$$1.opt); }, abort: noop}
475 }
476
477 xhr.open('GET', url);
478 for (var i in headers) {
479 if (hasOwn.call(headers, i)) {
480 xhr.setRequestHeader(i, headers[i]);
481 }
482 }
483 xhr.send();
484
485 return {
486 then: function (success, error) {
487 if ( error === void 0 ) error = noop;
488
489 if (hasBar) {
490 var id = setInterval(
491 function (_) { return progressbar({
492 step: Math.floor(Math.random() * 5 + 1)
493 }); },
494 500
495 );
496
497 on('progress', progressbar);
498 on('loadend', function (evt) {
499 progressbar(evt);
500 clearInterval(id);
501 });
502 }
503
504 on('error', error);
505 on('load', function (ref) {
506 var target = ref.target;
507
508 if (target.status >= 400) {
509 error(target);
510 } else {
511 var result = (cache[url] = {
512 content: target.response,
513 opt: {
514 updatedAt: xhr.getResponseHeader('last-modified')
515 }
516 });
517
518 success(result.content, result.opt);
519 }
520 });
521 },
522 abort: function (_) { return xhr.readyState !== 4 && xhr.abort(); }
523 }
524}
525
526function replaceVar(block, color) {
527 block.innerHTML = block.innerHTML.replace(
528 /var\(\s*--theme-color.*?\)/g,
529 color
530 );
531}
532
533function cssVars (color) {
534 // Variable support
535 if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) {
536 return
537 }
538
539 var styleBlocks = findAll('style:not(.inserted),link');
540 [].forEach.call(styleBlocks, function (block) {
541 if (block.nodeName === 'STYLE') {
542 replaceVar(block, color);
543 } else if (block.nodeName === 'LINK') {
544 var href = block.getAttribute('href');
545
546 if (!/\.css$/.test(href)) {
547 return
548 }
549
550 get(href).then(function (res) {
551 var style$$1 = create('style', res);
552
553 head.appendChild(style$$1);
554 replaceVar(style$$1, color);
555 });
556 }
557 });
558}
559
560var RGX = /([^{]*?)\w(?=\})/g;
561
562var dict = {
563 YYYY: 'getFullYear',
564 YY: 'getYear',
565 MM: function (d) {
566 return d.getMonth() + 1;
567 },
568 DD: 'getDate',
569 HH: 'getHours',
570 mm: 'getMinutes',
571 ss: 'getSeconds'
572};
573
574function tinydate (str) {
575 var parts=[], offset=0;
576 str.replace(RGX, function (key, _, idx) {
577 // save preceding string
578 parts.push(str.substring(offset, idx - 1));
579 offset = idx += key.length + 1;
580 // save function
581 parts.push(function(d){
582 return ('00' + (typeof dict[key]==='string' ? d[dict[key]]() : dict[key](d))).slice(-key.length);
583 });
584 });
585
586 if (offset !== str.length) {
587 parts.push(str.substring(offset));
588 }
589
590 return function (arg) {
591 var out='', i=0, d=arg||new Date();
592 for (; i<parts.length; i++) {
593 out += (typeof parts[i]==='string') ? parts[i] : parts[i](d);
594 }
595 return out;
596 };
597}
598
599var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
600
601
602
603
604
605function createCommonjsModule(fn, module) {
606 return module = { exports: {} }, fn(module, module.exports), module.exports;
607}
608
609var marked = createCommonjsModule(function (module, exports) {
610/**
611 * marked - a markdown parser
612 * Copyright (c) 2011-2018, Christopher Jeffrey. (MIT Licensed)
613 * https://github.com/markedjs/marked
614 */
615
616(function(root) {
617var block = {
618 newline: /^\n+/,
619 code: /^( {4}[^\n]+\n*)+/,
620 fences: noop,
621 hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,
622 heading: /^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,
623 nptable: noop,
624 blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
625 list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
626 html: '^ {0,3}(?:' // optional indentation
627 + '<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
628 + '|comment[^\\n]*(\\n+|$)' // (2)
629 + '|<\\?[\\s\\S]*?\\?>\\n*' // (3)
630 + '|<![A-Z][\\s\\S]*?>\\n*' // (4)
631 + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>\\n*' // (5)
632 + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)' // (6)
633 + '|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) open tag
634 + '|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=\\h*\\n)[\\s\\S]*?(?:\\n{2,}|$)' // (7) closing tag
635 + ')',
636 def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
637 table: noop,
638 lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
639 paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,
640 text: /^[^\n]+/
641};
642
643block._label = /(?!\s*\])(?:\\[\[\]]|[^\[\]])+/;
644block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
645block.def = edit(block.def)
646 .replace('label', block._label)
647 .replace('title', block._title)
648 .getRegex();
649
650block.bullet = /(?:[*+-]|\d+\.)/;
651block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
652block.item = edit(block.item, 'gm')
653 .replace(/bull/g, block.bullet)
654 .getRegex();
655
656block.list = edit(block.list)
657 .replace(/bull/g, block.bullet)
658 .replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
659 .replace('def', '\\n+(?=' + block.def.source + ')')
660 .getRegex();
661
662block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
663 + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
664 + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
665 + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
666 + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
667 + '|track|ul';
668block._comment = /<!--(?!-?>)[\s\S]*?-->/;
669block.html = edit(block.html, 'i')
670 .replace('comment', block._comment)
671 .replace('tag', block._tag)
672 .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
673 .getRegex();
674
675block.paragraph = edit(block.paragraph)
676 .replace('hr', block.hr)
677 .replace('heading', block.heading)
678 .replace('lheading', block.lheading)
679 .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
680 .getRegex();
681
682block.blockquote = edit(block.blockquote)
683 .replace('paragraph', block.paragraph)
684 .getRegex();
685
686/**
687 * Normal Block Grammar
688 */
689
690block.normal = merge({}, block);
691
692/**
693 * GFM Block Grammar
694 */
695
696block.gfm = merge({}, block.normal, {
697 fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\n? *\1 *(?:\n+|$)/,
698 paragraph: /^/,
699 heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
700});
701
702block.gfm.paragraph = edit(block.paragraph)
703 .replace('(?!', '(?!'
704 + block.gfm.fences.source.replace('\\1', '\\2') + '|'
705 + block.list.source.replace('\\1', '\\3') + '|')
706 .getRegex();
707
708/**
709 * GFM + Tables Block Grammar
710 */
711
712block.tables = merge({}, block.gfm, {
713 nptable: /^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,
714 table: /^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/
715});
716
717/**
718 * Pedantic grammar
719 */
720
721block.pedantic = merge({}, block.normal, {
722 html: edit(
723 '^ *(?:comment *(?:\\n|\\s*$)'
724 + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
725 + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
726 .replace('comment', block._comment)
727 .replace(/tag/g, '(?!(?:'
728 + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
729 + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
730 + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
731 .getRegex(),
732 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/
733});
734
735/**
736 * Block Lexer
737 */
738
739function Lexer(options) {
740 this.tokens = [];
741 this.tokens.links = Object.create(null);
742 this.options = options || marked.defaults;
743 this.rules = block.normal;
744
745 if (this.options.pedantic) {
746 this.rules = block.pedantic;
747 } else if (this.options.gfm) {
748 if (this.options.tables) {
749 this.rules = block.tables;
750 } else {
751 this.rules = block.gfm;
752 }
753 }
754}
755
756/**
757 * Expose Block Rules
758 */
759
760Lexer.rules = block;
761
762/**
763 * Static Lex Method
764 */
765
766Lexer.lex = function(src, options) {
767 var lexer = new Lexer(options);
768 return lexer.lex(src);
769};
770
771/**
772 * Preprocessing
773 */
774
775Lexer.prototype.lex = function(src) {
776 src = src
777 .replace(/\r\n|\r/g, '\n')
778 .replace(/\t/g, ' ')
779 .replace(/\u00a0/g, ' ')
780 .replace(/\u2424/g, '\n');
781
782 return this.token(src, true);
783};
784
785/**
786 * Lexing
787 */
788
789Lexer.prototype.token = function(src, top) {
790 var this$1 = this;
791
792 src = src.replace(/^ +$/gm, '');
793 var next,
794 loose,
795 cap,
796 bull,
797 b,
798 item,
799 listStart,
800 listItems,
801 t,
802 space,
803 i,
804 tag,
805 l,
806 isordered,
807 istask,
808 ischecked;
809
810 while (src) {
811 // newline
812 if (cap = this$1.rules.newline.exec(src)) {
813 src = src.substring(cap[0].length);
814 if (cap[0].length > 1) {
815 this$1.tokens.push({
816 type: 'space'
817 });
818 }
819 }
820
821 // code
822 if (cap = this$1.rules.code.exec(src)) {
823 src = src.substring(cap[0].length);
824 cap = cap[0].replace(/^ {4}/gm, '');
825 this$1.tokens.push({
826 type: 'code',
827 text: !this$1.options.pedantic
828 ? rtrim(cap, '\n')
829 : cap
830 });
831 continue;
832 }
833
834 // fences (gfm)
835 if (cap = this$1.rules.fences.exec(src)) {
836 src = src.substring(cap[0].length);
837 this$1.tokens.push({
838 type: 'code',
839 lang: cap[2],
840 text: cap[3] || ''
841 });
842 continue;
843 }
844
845 // heading
846 if (cap = this$1.rules.heading.exec(src)) {
847 src = src.substring(cap[0].length);
848 this$1.tokens.push({
849 type: 'heading',
850 depth: cap[1].length,
851 text: cap[2]
852 });
853 continue;
854 }
855
856 // table no leading pipe (gfm)
857 if (top && (cap = this$1.rules.nptable.exec(src))) {
858 item = {
859 type: 'table',
860 header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
861 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
862 cells: cap[3] ? cap[3].replace(/\n$/, '').split('\n') : []
863 };
864
865 if (item.header.length === item.align.length) {
866 src = src.substring(cap[0].length);
867
868 for (i = 0; i < item.align.length; i++) {
869 if (/^ *-+: *$/.test(item.align[i])) {
870 item.align[i] = 'right';
871 } else if (/^ *:-+: *$/.test(item.align[i])) {
872 item.align[i] = 'center';
873 } else if (/^ *:-+ *$/.test(item.align[i])) {
874 item.align[i] = 'left';
875 } else {
876 item.align[i] = null;
877 }
878 }
879
880 for (i = 0; i < item.cells.length; i++) {
881 item.cells[i] = splitCells(item.cells[i], item.header.length);
882 }
883
884 this$1.tokens.push(item);
885
886 continue;
887 }
888 }
889
890 // hr
891 if (cap = this$1.rules.hr.exec(src)) {
892 src = src.substring(cap[0].length);
893 this$1.tokens.push({
894 type: 'hr'
895 });
896 continue;
897 }
898
899 // blockquote
900 if (cap = this$1.rules.blockquote.exec(src)) {
901 src = src.substring(cap[0].length);
902
903 this$1.tokens.push({
904 type: 'blockquote_start'
905 });
906
907 cap = cap[0].replace(/^ *> ?/gm, '');
908
909 // Pass `top` to keep the current
910 // "toplevel" state. This is exactly
911 // how markdown.pl works.
912 this$1.token(cap, top);
913
914 this$1.tokens.push({
915 type: 'blockquote_end'
916 });
917
918 continue;
919 }
920
921 // list
922 if (cap = this$1.rules.list.exec(src)) {
923 src = src.substring(cap[0].length);
924 bull = cap[2];
925 isordered = bull.length > 1;
926
927 listStart = {
928 type: 'list_start',
929 ordered: isordered,
930 start: isordered ? +bull : '',
931 loose: false
932 };
933
934 this$1.tokens.push(listStart);
935
936 // Get each top-level item.
937 cap = cap[0].match(this$1.rules.item);
938
939 listItems = [];
940 next = false;
941 l = cap.length;
942 i = 0;
943
944 for (; i < l; i++) {
945 item = cap[i];
946
947 // Remove the list item's bullet
948 // so it is seen as the next token.
949 space = item.length;
950 item = item.replace(/^ *([*+-]|\d+\.) +/, '');
951
952 // Outdent whatever the
953 // list item contains. Hacky.
954 if (~item.indexOf('\n ')) {
955 space -= item.length;
956 item = !this$1.options.pedantic
957 ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
958 : item.replace(/^ {1,4}/gm, '');
959 }
960
961 // Determine whether the next list item belongs here.
962 // Backpedal if it does not belong in this list.
963 if (this$1.options.smartLists && i !== l - 1) {
964 b = block.bullet.exec(cap[i + 1])[0];
965 if (bull !== b && !(bull.length > 1 && b.length > 1)) {
966 src = cap.slice(i + 1).join('\n') + src;
967 i = l - 1;
968 }
969 }
970
971 // Determine whether item is loose or not.
972 // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
973 // for discount behavior.
974 loose = next || /\n\n(?!\s*$)/.test(item);
975 if (i !== l - 1) {
976 next = item.charAt(item.length - 1) === '\n';
977 if (!loose) { loose = next; }
978 }
979
980 if (loose) {
981 listStart.loose = true;
982 }
983
984 // Check for task list items
985 istask = /^\[[ xX]\] /.test(item);
986 ischecked = undefined;
987 if (istask) {
988 ischecked = item[1] !== ' ';
989 item = item.replace(/^\[[ xX]\] +/, '');
990 }
991
992 t = {
993 type: 'list_item_start',
994 task: istask,
995 checked: ischecked,
996 loose: loose
997 };
998
999 listItems.push(t);
1000 this$1.tokens.push(t);
1001
1002 // Recurse.
1003 this$1.token(item, false);
1004
1005 this$1.tokens.push({
1006 type: 'list_item_end'
1007 });
1008 }
1009
1010 if (listStart.loose) {
1011 l = listItems.length;
1012 i = 0;
1013 for (; i < l; i++) {
1014 listItems[i].loose = true;
1015 }
1016 }
1017
1018 this$1.tokens.push({
1019 type: 'list_end'
1020 });
1021
1022 continue;
1023 }
1024
1025 // html
1026 if (cap = this$1.rules.html.exec(src)) {
1027 src = src.substring(cap[0].length);
1028 this$1.tokens.push({
1029 type: this$1.options.sanitize
1030 ? 'paragraph'
1031 : 'html',
1032 pre: !this$1.options.sanitizer
1033 && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
1034 text: cap[0]
1035 });
1036 continue;
1037 }
1038
1039 // def
1040 if (top && (cap = this$1.rules.def.exec(src))) {
1041 src = src.substring(cap[0].length);
1042 if (cap[3]) { cap[3] = cap[3].substring(1, cap[3].length - 1); }
1043 tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
1044 if (!this$1.tokens.links[tag]) {
1045 this$1.tokens.links[tag] = {
1046 href: cap[2],
1047 title: cap[3]
1048 };
1049 }
1050 continue;
1051 }
1052
1053 // table (gfm)
1054 if (top && (cap = this$1.rules.table.exec(src))) {
1055 item = {
1056 type: 'table',
1057 header: splitCells(cap[1].replace(/^ *| *\| *$/g, '')),
1058 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
1059 cells: cap[3] ? cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') : []
1060 };
1061
1062 if (item.header.length === item.align.length) {
1063 src = src.substring(cap[0].length);
1064
1065 for (i = 0; i < item.align.length; i++) {
1066 if (/^ *-+: *$/.test(item.align[i])) {
1067 item.align[i] = 'right';
1068 } else if (/^ *:-+: *$/.test(item.align[i])) {
1069 item.align[i] = 'center';
1070 } else if (/^ *:-+ *$/.test(item.align[i])) {
1071 item.align[i] = 'left';
1072 } else {
1073 item.align[i] = null;
1074 }
1075 }
1076
1077 for (i = 0; i < item.cells.length; i++) {
1078 item.cells[i] = splitCells(
1079 item.cells[i].replace(/^ *\| *| *\| *$/g, ''),
1080 item.header.length);
1081 }
1082
1083 this$1.tokens.push(item);
1084
1085 continue;
1086 }
1087 }
1088
1089 // lheading
1090 if (cap = this$1.rules.lheading.exec(src)) {
1091 src = src.substring(cap[0].length);
1092 this$1.tokens.push({
1093 type: 'heading',
1094 depth: cap[2] === '=' ? 1 : 2,
1095 text: cap[1]
1096 });
1097 continue;
1098 }
1099
1100 // top-level paragraph
1101 if (top && (cap = this$1.rules.paragraph.exec(src))) {
1102 src = src.substring(cap[0].length);
1103 this$1.tokens.push({
1104 type: 'paragraph',
1105 text: cap[1].charAt(cap[1].length - 1) === '\n'
1106 ? cap[1].slice(0, -1)
1107 : cap[1]
1108 });
1109 continue;
1110 }
1111
1112 // text
1113 if (cap = this$1.rules.text.exec(src)) {
1114 // Top-level should never reach here.
1115 src = src.substring(cap[0].length);
1116 this$1.tokens.push({
1117 type: 'text',
1118 text: cap[0]
1119 });
1120 continue;
1121 }
1122
1123 if (src) {
1124 throw new Error('Infinite loop on byte: ' + src.charCodeAt(0));
1125 }
1126 }
1127
1128 return this.tokens;
1129};
1130
1131/**
1132 * Inline-Level Grammar
1133 */
1134
1135var inline = {
1136 escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
1137 autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
1138 url: noop,
1139 tag: '^comment'
1140 + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
1141 + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
1142 + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
1143 + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
1144 + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
1145 link: /^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,
1146 reflink: /^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,
1147 nolink: /^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,
1148 strong: /^__([^\s])__(?!_)|^\*\*([^\s])\*\*(?!\*)|^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)/,
1149 em: /^_([^\s_])_(?!_)|^\*([^\s*"<\[])\*(?!\*)|^_([^\s][\s\S]*?[^\s_])_(?!_)|^_([^\s_][\s\S]*?[^\s])_(?!_)|^\*([^\s"<\[][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*"<\[][\s\S]*?[^\s])\*(?!\*)/,
1150 code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
1151 br: /^( {2,}|\\)\n(?!\s*$)/,
1152 del: noop,
1153 text: /^(`+|[^`])[\s\S]*?(?=[\\<!\[`*]|\b_| {2,}\n|$)/
1154};
1155
1156inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
1157
1158inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
1159inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
1160inline.autolink = edit(inline.autolink)
1161 .replace('scheme', inline._scheme)
1162 .replace('email', inline._email)
1163 .getRegex();
1164
1165inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
1166
1167inline.tag = edit(inline.tag)
1168 .replace('comment', block._comment)
1169 .replace('attribute', inline._attribute)
1170 .getRegex();
1171
1172inline._label = /(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|[^\[\]\\])*?/;
1173inline._href = /\s*(<(?:\\[<>]?|[^\s<>\\])*>|(?:\\[()]?|\([^\s\x00-\x1f\\]*\)|[^\s\x00-\x1f()\\])*?)/;
1174inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
1175
1176inline.link = edit(inline.link)
1177 .replace('label', inline._label)
1178 .replace('href', inline._href)
1179 .replace('title', inline._title)
1180 .getRegex();
1181
1182inline.reflink = edit(inline.reflink)
1183 .replace('label', inline._label)
1184 .getRegex();
1185
1186/**
1187 * Normal Inline Grammar
1188 */
1189
1190inline.normal = merge({}, inline);
1191
1192/**
1193 * Pedantic Inline Grammar
1194 */
1195
1196inline.pedantic = merge({}, inline.normal, {
1197 strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
1198 em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,
1199 link: edit(/^!?\[(label)\]\((.*?)\)/)
1200 .replace('label', inline._label)
1201 .getRegex(),
1202 reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
1203 .replace('label', inline._label)
1204 .getRegex()
1205});
1206
1207/**
1208 * GFM Inline Grammar
1209 */
1210
1211inline.gfm = merge({}, inline.normal, {
1212 escape: edit(inline.escape).replace('])', '~|])').getRegex(),
1213 _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
1214 url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
1215 _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
1216 del: /^~+(?=\S)([\s\S]*?\S)~+/,
1217 text: edit(inline.text)
1218 .replace(']|', '~]|')
1219 .replace('|$', '|https?://|ftp://|www\\.|[a-zA-Z0-9.!#$%&\'*+/=?^_`{\\|}~-]+@|$')
1220 .getRegex()
1221});
1222
1223inline.gfm.url = edit(inline.gfm.url)
1224 .replace('email', inline.gfm._extended_email)
1225 .getRegex();
1226/**
1227 * GFM + Line Breaks Inline Grammar
1228 */
1229
1230inline.breaks = merge({}, inline.gfm, {
1231 br: edit(inline.br).replace('{2,}', '*').getRegex(),
1232 text: edit(inline.gfm.text).replace('{2,}', '*').getRegex()
1233});
1234
1235/**
1236 * Inline Lexer & Compiler
1237 */
1238
1239function InlineLexer(links, options) {
1240 this.options = options || marked.defaults;
1241 this.links = links;
1242 this.rules = inline.normal;
1243 this.renderer = this.options.renderer || new Renderer();
1244 this.renderer.options = this.options;
1245
1246 if (!this.links) {
1247 throw new Error('Tokens array requires a `links` property.');
1248 }
1249
1250 if (this.options.pedantic) {
1251 this.rules = inline.pedantic;
1252 } else if (this.options.gfm) {
1253 if (this.options.breaks) {
1254 this.rules = inline.breaks;
1255 } else {
1256 this.rules = inline.gfm;
1257 }
1258 }
1259}
1260
1261/**
1262 * Expose Inline Rules
1263 */
1264
1265InlineLexer.rules = inline;
1266
1267/**
1268 * Static Lexing/Compiling Method
1269 */
1270
1271InlineLexer.output = function(src, links, options) {
1272 var inline = new InlineLexer(links, options);
1273 return inline.output(src);
1274};
1275
1276/**
1277 * Lexing/Compiling
1278 */
1279
1280InlineLexer.prototype.output = function(src) {
1281 var this$1 = this;
1282
1283 var out = '',
1284 link,
1285 text,
1286 href,
1287 title,
1288 cap,
1289 prevCapZero;
1290
1291 while (src) {
1292 // escape
1293 if (cap = this$1.rules.escape.exec(src)) {
1294 src = src.substring(cap[0].length);
1295 out += cap[1];
1296 continue;
1297 }
1298
1299 // autolink
1300 if (cap = this$1.rules.autolink.exec(src)) {
1301 src = src.substring(cap[0].length);
1302 if (cap[2] === '@') {
1303 text = escape(this$1.mangle(cap[1]));
1304 href = 'mailto:' + text;
1305 } else {
1306 text = escape(cap[1]);
1307 href = text;
1308 }
1309 out += this$1.renderer.link(href, null, text);
1310 continue;
1311 }
1312
1313 // url (gfm)
1314 if (!this$1.inLink && (cap = this$1.rules.url.exec(src))) {
1315 if (cap[2] === '@') {
1316 text = escape(cap[0]);
1317 href = 'mailto:' + text;
1318 } else {
1319 // do extended autolink path validation
1320 do {
1321 prevCapZero = cap[0];
1322 cap[0] = this$1.rules._backpedal.exec(cap[0])[0];
1323 } while (prevCapZero !== cap[0]);
1324 text = escape(cap[0]);
1325 if (cap[1] === 'www.') {
1326 href = 'http://' + text;
1327 } else {
1328 href = text;
1329 }
1330 }
1331 src = src.substring(cap[0].length);
1332 out += this$1.renderer.link(href, null, text);
1333 continue;
1334 }
1335
1336 // tag
1337 if (cap = this$1.rules.tag.exec(src)) {
1338 if (!this$1.inLink && /^<a /i.test(cap[0])) {
1339 this$1.inLink = true;
1340 } else if (this$1.inLink && /^<\/a>/i.test(cap[0])) {
1341 this$1.inLink = false;
1342 }
1343 if (!this$1.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
1344 this$1.inRawBlock = true;
1345 } else if (this$1.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
1346 this$1.inRawBlock = false;
1347 }
1348
1349 src = src.substring(cap[0].length);
1350 out += this$1.options.sanitize
1351 ? this$1.options.sanitizer
1352 ? this$1.options.sanitizer(cap[0])
1353 : escape(cap[0])
1354 : cap[0];
1355 continue;
1356 }
1357
1358 // link
1359 if (cap = this$1.rules.link.exec(src)) {
1360 src = src.substring(cap[0].length);
1361 this$1.inLink = true;
1362 href = cap[2];
1363 if (this$1.options.pedantic) {
1364 link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
1365
1366 if (link) {
1367 href = link[1];
1368 title = link[3];
1369 } else {
1370 title = '';
1371 }
1372 } else {
1373 title = cap[3] ? cap[3].slice(1, -1) : '';
1374 }
1375 href = href.trim().replace(/^<([\s\S]*)>$/, '$1');
1376 out += this$1.outputLink(cap, {
1377 href: InlineLexer.escapes(href),
1378 title: InlineLexer.escapes(title)
1379 });
1380 this$1.inLink = false;
1381 continue;
1382 }
1383
1384 // reflink, nolink
1385 if ((cap = this$1.rules.reflink.exec(src))
1386 || (cap = this$1.rules.nolink.exec(src))) {
1387 src = src.substring(cap[0].length);
1388 link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
1389 link = this$1.links[link.toLowerCase()];
1390 if (!link || !link.href) {
1391 out += cap[0].charAt(0);
1392 src = cap[0].substring(1) + src;
1393 continue;
1394 }
1395 this$1.inLink = true;
1396 out += this$1.outputLink(cap, link);
1397 this$1.inLink = false;
1398 continue;
1399 }
1400
1401 // strong
1402 if (cap = this$1.rules.strong.exec(src)) {
1403 src = src.substring(cap[0].length);
1404 out += this$1.renderer.strong(this$1.output(cap[4] || cap[3] || cap[2] || cap[1]));
1405 continue;
1406 }
1407
1408 // em
1409 if (cap = this$1.rules.em.exec(src)) {
1410 src = src.substring(cap[0].length);
1411 out += this$1.renderer.em(this$1.output(cap[6] || cap[5] || cap[4] || cap[3] || cap[2] || cap[1]));
1412 continue;
1413 }
1414
1415 // code
1416 if (cap = this$1.rules.code.exec(src)) {
1417 src = src.substring(cap[0].length);
1418 out += this$1.renderer.codespan(escape(cap[2].trim(), true));
1419 continue;
1420 }
1421
1422 // br
1423 if (cap = this$1.rules.br.exec(src)) {
1424 src = src.substring(cap[0].length);
1425 out += this$1.renderer.br();
1426 continue;
1427 }
1428
1429 // del (gfm)
1430 if (cap = this$1.rules.del.exec(src)) {
1431 src = src.substring(cap[0].length);
1432 out += this$1.renderer.del(this$1.output(cap[1]));
1433 continue;
1434 }
1435
1436 // text
1437 if (cap = this$1.rules.text.exec(src)) {
1438 src = src.substring(cap[0].length);
1439 if (this$1.inRawBlock) {
1440 out += this$1.renderer.text(cap[0]);
1441 } else {
1442 out += this$1.renderer.text(escape(this$1.smartypants(cap[0])));
1443 }
1444 continue;
1445 }
1446
1447 if (src) {
1448 throw new Error('Infinite loop on byte: ' + src.charCodeAt(0));
1449 }
1450 }
1451
1452 return out;
1453};
1454
1455InlineLexer.escapes = function(text) {
1456 return text ? text.replace(InlineLexer.rules._escapes, '$1') : text;
1457};
1458
1459/**
1460 * Compile Link
1461 */
1462
1463InlineLexer.prototype.outputLink = function(cap, link) {
1464 var href = link.href,
1465 title = link.title ? escape(link.title) : null;
1466
1467 return cap[0].charAt(0) !== '!'
1468 ? this.renderer.link(href, title, this.output(cap[1]))
1469 : this.renderer.image(href, title, escape(cap[1]));
1470};
1471
1472/**
1473 * Smartypants Transformations
1474 */
1475
1476InlineLexer.prototype.smartypants = function(text) {
1477 if (!this.options.smartypants) { return text; }
1478 return text
1479 // em-dashes
1480 .replace(/---/g, '\u2014')
1481 // en-dashes
1482 .replace(/--/g, '\u2013')
1483 // opening singles
1484 .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
1485 // closing singles & apostrophes
1486 .replace(/'/g, '\u2019')
1487 // opening doubles
1488 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
1489 // closing doubles
1490 .replace(/"/g, '\u201d')
1491 // ellipses
1492 .replace(/\.{3}/g, '\u2026');
1493};
1494
1495/**
1496 * Mangle Links
1497 */
1498
1499InlineLexer.prototype.mangle = function(text) {
1500 if (!this.options.mangle) { return text; }
1501 var out = '',
1502 l = text.length,
1503 i = 0,
1504 ch;
1505
1506 for (; i < l; i++) {
1507 ch = text.charCodeAt(i);
1508 if (Math.random() > 0.5) {
1509 ch = 'x' + ch.toString(16);
1510 }
1511 out += '&#' + ch + ';';
1512 }
1513
1514 return out;
1515};
1516
1517/**
1518 * Renderer
1519 */
1520
1521function Renderer(options) {
1522 this.options = options || marked.defaults;
1523}
1524
1525Renderer.prototype.code = function(code, lang, escaped) {
1526 if (this.options.highlight) {
1527 var out = this.options.highlight(code, lang);
1528 if (out != null && out !== code) {
1529 escaped = true;
1530 code = out;
1531 }
1532 }
1533
1534 if (!lang) {
1535 return '<pre><code>'
1536 + (escaped ? code : escape(code, true))
1537 + '</code></pre>';
1538 }
1539
1540 return '<pre><code class="'
1541 + this.options.langPrefix
1542 + escape(lang, true)
1543 + '">'
1544 + (escaped ? code : escape(code, true))
1545 + '</code></pre>\n';
1546};
1547
1548Renderer.prototype.blockquote = function(quote) {
1549 return '<blockquote>\n' + quote + '</blockquote>\n';
1550};
1551
1552Renderer.prototype.html = function(html) {
1553 return html;
1554};
1555
1556Renderer.prototype.heading = function(text, level, raw) {
1557 if (this.options.headerIds) {
1558 return '<h'
1559 + level
1560 + ' id="'
1561 + this.options.headerPrefix
1562 + raw.toLowerCase().replace(/[^\w]+/g, '-')
1563 + '">'
1564 + text
1565 + '</h'
1566 + level
1567 + '>\n';
1568 }
1569 // ignore IDs
1570 return '<h' + level + '>' + text + '</h' + level + '>\n';
1571};
1572
1573Renderer.prototype.hr = function() {
1574 return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
1575};
1576
1577Renderer.prototype.list = function(body, ordered, start) {
1578 var type = ordered ? 'ol' : 'ul',
1579 startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1580 return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
1581};
1582
1583Renderer.prototype.listitem = function(text) {
1584 return '<li>' + text + '</li>\n';
1585};
1586
1587Renderer.prototype.checkbox = function(checked) {
1588 return '<input '
1589 + (checked ? 'checked="" ' : '')
1590 + 'disabled="" type="checkbox"'
1591 + (this.options.xhtml ? ' /' : '')
1592 + '> ';
1593};
1594
1595Renderer.prototype.paragraph = function(text) {
1596 return '<p>' + text + '</p>\n';
1597};
1598
1599Renderer.prototype.table = function(header, body) {
1600 if (body) { body = '<tbody>' + body + '</tbody>'; }
1601
1602 return '<table>\n'
1603 + '<thead>\n'
1604 + header
1605 + '</thead>\n'
1606 + body
1607 + '</table>\n';
1608};
1609
1610Renderer.prototype.tablerow = function(content) {
1611 return '<tr>\n' + content + '</tr>\n';
1612};
1613
1614Renderer.prototype.tablecell = function(content, flags) {
1615 var type = flags.header ? 'th' : 'td';
1616 var tag = flags.align
1617 ? '<' + type + ' align="' + flags.align + '">'
1618 : '<' + type + '>';
1619 return tag + content + '</' + type + '>\n';
1620};
1621
1622// span level renderer
1623Renderer.prototype.strong = function(text) {
1624 return '<strong>' + text + '</strong>';
1625};
1626
1627Renderer.prototype.em = function(text) {
1628 return '<em>' + text + '</em>';
1629};
1630
1631Renderer.prototype.codespan = function(text) {
1632 return '<code>' + text + '</code>';
1633};
1634
1635Renderer.prototype.br = function() {
1636 return this.options.xhtml ? '<br/>' : '<br>';
1637};
1638
1639Renderer.prototype.del = function(text) {
1640 return '<del>' + text + '</del>';
1641};
1642
1643Renderer.prototype.link = function(href, title, text) {
1644 if (this.options.sanitize) {
1645 try {
1646 var prot = decodeURIComponent(unescape(href))
1647 .replace(/[^\w:]/g, '')
1648 .toLowerCase();
1649 } catch (e) {
1650 return text;
1651 }
1652 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
1653 return text;
1654 }
1655 }
1656 if (this.options.baseUrl && !originIndependentUrl.test(href)) {
1657 href = resolveUrl(this.options.baseUrl, href);
1658 }
1659 try {
1660 href = encodeURI(href).replace(/%25/g, '%');
1661 } catch (e) {
1662 return text;
1663 }
1664 var out = '<a href="' + escape(href) + '"';
1665 if (title) {
1666 out += ' title="' + title + '"';
1667 }
1668 out += '>' + text + '</a>';
1669 return out;
1670};
1671
1672Renderer.prototype.image = function(href, title, text) {
1673 if (this.options.baseUrl && !originIndependentUrl.test(href)) {
1674 href = resolveUrl(this.options.baseUrl, href);
1675 }
1676 var out = '<img src="' + href + '" alt="' + text + '"';
1677 if (title) {
1678 out += ' title="' + title + '"';
1679 }
1680 out += this.options.xhtml ? '/>' : '>';
1681 return out;
1682};
1683
1684Renderer.prototype.text = function(text) {
1685 return text;
1686};
1687
1688/**
1689 * TextRenderer
1690 * returns only the textual part of the token
1691 */
1692
1693function TextRenderer() {}
1694
1695// no need for block level renderers
1696
1697TextRenderer.prototype.strong =
1698TextRenderer.prototype.em =
1699TextRenderer.prototype.codespan =
1700TextRenderer.prototype.del =
1701TextRenderer.prototype.text = function (text) {
1702 return text;
1703};
1704
1705TextRenderer.prototype.link =
1706TextRenderer.prototype.image = function(href, title, text) {
1707 return '' + text;
1708};
1709
1710TextRenderer.prototype.br = function() {
1711 return '';
1712};
1713
1714/**
1715 * Parsing & Compiling
1716 */
1717
1718function Parser(options) {
1719 this.tokens = [];
1720 this.token = null;
1721 this.options = options || marked.defaults;
1722 this.options.renderer = this.options.renderer || new Renderer();
1723 this.renderer = this.options.renderer;
1724 this.renderer.options = this.options;
1725}
1726
1727/**
1728 * Static Parse Method
1729 */
1730
1731Parser.parse = function(src, options) {
1732 var parser = new Parser(options);
1733 return parser.parse(src);
1734};
1735
1736/**
1737 * Parse Loop
1738 */
1739
1740Parser.prototype.parse = function(src) {
1741 var this$1 = this;
1742
1743 this.inline = new InlineLexer(src.links, this.options);
1744 // use an InlineLexer with a TextRenderer to extract pure text
1745 this.inlineText = new InlineLexer(
1746 src.links,
1747 merge({}, this.options, {renderer: new TextRenderer()})
1748 );
1749 this.tokens = src.reverse();
1750
1751 var out = '';
1752 while (this.next()) {
1753 out += this$1.tok();
1754 }
1755
1756 return out;
1757};
1758
1759/**
1760 * Next Token
1761 */
1762
1763Parser.prototype.next = function() {
1764 return this.token = this.tokens.pop();
1765};
1766
1767/**
1768 * Preview Next Token
1769 */
1770
1771Parser.prototype.peek = function() {
1772 return this.tokens[this.tokens.length - 1] || 0;
1773};
1774
1775/**
1776 * Parse Text Tokens
1777 */
1778
1779Parser.prototype.parseText = function() {
1780 var this$1 = this;
1781
1782 var body = this.token.text;
1783
1784 while (this.peek().type === 'text') {
1785 body += '\n' + this$1.next().text;
1786 }
1787
1788 return this.inline.output(body);
1789};
1790
1791/**
1792 * Parse Current Token
1793 */
1794
1795Parser.prototype.tok = function() {
1796 var this$1 = this;
1797
1798 switch (this.token.type) {
1799 case 'space': {
1800 return '';
1801 }
1802 case 'hr': {
1803 return this.renderer.hr();
1804 }
1805 case 'heading': {
1806 return this.renderer.heading(
1807 this.inline.output(this.token.text),
1808 this.token.depth,
1809 unescape(this.inlineText.output(this.token.text)));
1810 }
1811 case 'code': {
1812 return this.renderer.code(this.token.text,
1813 this.token.lang,
1814 this.token.escaped);
1815 }
1816 case 'table': {
1817 var header = '',
1818 body = '',
1819 i,
1820 row,
1821 cell,
1822 j;
1823
1824 // header
1825 cell = '';
1826 for (i = 0; i < this.token.header.length; i++) {
1827 cell += this$1.renderer.tablecell(
1828 this$1.inline.output(this$1.token.header[i]),
1829 { header: true, align: this$1.token.align[i] }
1830 );
1831 }
1832 header += this.renderer.tablerow(cell);
1833
1834 for (i = 0; i < this.token.cells.length; i++) {
1835 row = this$1.token.cells[i];
1836
1837 cell = '';
1838 for (j = 0; j < row.length; j++) {
1839 cell += this$1.renderer.tablecell(
1840 this$1.inline.output(row[j]),
1841 { header: false, align: this$1.token.align[j] }
1842 );
1843 }
1844
1845 body += this$1.renderer.tablerow(cell);
1846 }
1847 return this.renderer.table(header, body);
1848 }
1849 case 'blockquote_start': {
1850 body = '';
1851
1852 while (this.next().type !== 'blockquote_end') {
1853 body += this$1.tok();
1854 }
1855
1856 return this.renderer.blockquote(body);
1857 }
1858 case 'list_start': {
1859 body = '';
1860 var ordered = this.token.ordered,
1861 start = this.token.start;
1862
1863 while (this.next().type !== 'list_end') {
1864 body += this$1.tok();
1865 }
1866
1867 return this.renderer.list(body, ordered, start);
1868 }
1869 case 'list_item_start': {
1870 body = '';
1871 var loose = this.token.loose;
1872
1873 if (this.token.task) {
1874 body += this.renderer.checkbox(this.token.checked);
1875 }
1876
1877 while (this.next().type !== 'list_item_end') {
1878 body += !loose && this$1.token.type === 'text'
1879 ? this$1.parseText()
1880 : this$1.tok();
1881 }
1882
1883 return this.renderer.listitem(body);
1884 }
1885 case 'html': {
1886 // TODO parse inline content if parameter markdown=1
1887 return this.renderer.html(this.token.text);
1888 }
1889 case 'paragraph': {
1890 return this.renderer.paragraph(this.inline.output(this.token.text));
1891 }
1892 case 'text': {
1893 return this.renderer.paragraph(this.parseText());
1894 }
1895 }
1896};
1897
1898/**
1899 * Helpers
1900 */
1901
1902function escape(html, encode) {
1903 if (encode) {
1904 if (escape.escapeTest.test(html)) {
1905 return html.replace(escape.escapeReplace, function (ch) { return escape.replacements[ch] });
1906 }
1907 } else {
1908 if (escape.escapeTestNoEncode.test(html)) {
1909 return html.replace(escape.escapeReplaceNoEncode, function (ch) { return escape.replacements[ch] });
1910 }
1911 }
1912
1913 return html;
1914}
1915
1916escape.escapeTest = /[&<>"']/;
1917escape.escapeReplace = /[&<>"']/g;
1918escape.replacements = {
1919 '&': '&amp;',
1920 '<': '&lt;',
1921 '>': '&gt;',
1922 '"': '&quot;',
1923 "'": '&#39;'
1924};
1925
1926escape.escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
1927escape.escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
1928
1929function unescape(html) {
1930 // explicitly match decimal, hex, and named HTML entities
1931 return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, function(_, n) {
1932 n = n.toLowerCase();
1933 if (n === 'colon') { return ':'; }
1934 if (n.charAt(0) === '#') {
1935 return n.charAt(1) === 'x'
1936 ? String.fromCharCode(parseInt(n.substring(2), 16))
1937 : String.fromCharCode(+n.substring(1));
1938 }
1939 return '';
1940 });
1941}
1942
1943function edit(regex, opt) {
1944 regex = regex.source || regex;
1945 opt = opt || '';
1946 return {
1947 replace: function(name, val) {
1948 val = val.source || val;
1949 val = val.replace(/(^|[^\[])\^/g, '$1');
1950 regex = regex.replace(name, val);
1951 return this;
1952 },
1953 getRegex: function() {
1954 return new RegExp(regex, opt);
1955 }
1956 };
1957}
1958
1959function resolveUrl(base, href) {
1960 if (!baseUrls[' ' + base]) {
1961 // we can ignore everything in base after the last slash of its path component,
1962 // but we might need to add _that_
1963 // https://tools.ietf.org/html/rfc3986#section-3
1964 if (/^[^:]+:\/*[^/]*$/.test(base)) {
1965 baseUrls[' ' + base] = base + '/';
1966 } else {
1967 baseUrls[' ' + base] = rtrim(base, '/', true);
1968 }
1969 }
1970 base = baseUrls[' ' + base];
1971
1972 if (href.slice(0, 2) === '//') {
1973 return base.replace(/:[\s\S]*/, ':') + href;
1974 } else if (href.charAt(0) === '/') {
1975 return base.replace(/(:\/*[^/]*)[\s\S]*/, '$1') + href;
1976 } else {
1977 return base + href;
1978 }
1979}
1980var baseUrls = {};
1981var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
1982
1983function noop() {}
1984noop.exec = noop;
1985
1986function merge(obj) {
1987 var arguments$1 = arguments;
1988
1989 var i = 1,
1990 target,
1991 key;
1992
1993 for (; i < arguments.length; i++) {
1994 target = arguments$1[i];
1995 for (key in target) {
1996 if (Object.prototype.hasOwnProperty.call(target, key)) {
1997 obj[key] = target[key];
1998 }
1999 }
2000 }
2001
2002 return obj;
2003}
2004
2005function splitCells(tableRow, count) {
2006 // ensure that every cell-delimiting pipe has a space
2007 // before it to distinguish it from an escaped pipe
2008 var row = tableRow.replace(/\|/g, function (match, offset, str) {
2009 var escaped = false,
2010 curr = offset;
2011 while (--curr >= 0 && str[curr] === '\\') { escaped = !escaped; }
2012 if (escaped) {
2013 // odd number of slashes means | is escaped
2014 // so we leave it alone
2015 return '|';
2016 } else {
2017 // add space before unescaped |
2018 return ' |';
2019 }
2020 }),
2021 cells = row.split(/ \|/),
2022 i = 0;
2023
2024 if (cells.length > count) {
2025 cells.splice(count);
2026 } else {
2027 while (cells.length < count) { cells.push(''); }
2028 }
2029
2030 for (; i < cells.length; i++) {
2031 // leading or trailing whitespace is ignored per the gfm spec
2032 cells[i] = cells[i].trim().replace(/\\\|/g, '|');
2033 }
2034 return cells;
2035}
2036
2037// Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
2038// /c*$/ is vulnerable to REDOS.
2039// invert: Remove suffix of non-c chars instead. Default falsey.
2040function rtrim(str, c, invert) {
2041 if (str.length === 0) {
2042 return '';
2043 }
2044
2045 // Length of suffix matching the invert condition.
2046 var suffLen = 0;
2047
2048 // Step left until we fail to match the invert condition.
2049 while (suffLen < str.length) {
2050 var currChar = str.charAt(str.length - suffLen - 1);
2051 if (currChar === c && !invert) {
2052 suffLen++;
2053 } else if (currChar !== c && invert) {
2054 suffLen++;
2055 } else {
2056 break;
2057 }
2058 }
2059
2060 return str.substr(0, str.length - suffLen);
2061}
2062
2063/**
2064 * Marked
2065 */
2066
2067function marked(src, opt, callback) {
2068 // throw error in case of non string input
2069 if (typeof src === 'undefined' || src === null) {
2070 throw new Error('marked(): input parameter is undefined or null');
2071 }
2072 if (typeof src !== 'string') {
2073 throw new Error('marked(): input parameter is of type '
2074 + Object.prototype.toString.call(src) + ', string expected');
2075 }
2076
2077 if (callback || typeof opt === 'function') {
2078 if (!callback) {
2079 callback = opt;
2080 opt = null;
2081 }
2082
2083 opt = merge({}, marked.defaults, opt || {});
2084
2085 var highlight = opt.highlight,
2086 tokens,
2087 pending,
2088 i = 0;
2089
2090 try {
2091 tokens = Lexer.lex(src, opt);
2092 } catch (e) {
2093 return callback(e);
2094 }
2095
2096 pending = tokens.length;
2097
2098 var done = function(err) {
2099 if (err) {
2100 opt.highlight = highlight;
2101 return callback(err);
2102 }
2103
2104 var out;
2105
2106 try {
2107 out = Parser.parse(tokens, opt);
2108 } catch (e) {
2109 err = e;
2110 }
2111
2112 opt.highlight = highlight;
2113
2114 return err
2115 ? callback(err)
2116 : callback(null, out);
2117 };
2118
2119 if (!highlight || highlight.length < 3) {
2120 return done();
2121 }
2122
2123 delete opt.highlight;
2124
2125 if (!pending) { return done(); }
2126
2127 for (; i < tokens.length; i++) {
2128 (function(token) {
2129 if (token.type !== 'code') {
2130 return --pending || done();
2131 }
2132 return highlight(token.text, token.lang, function(err, code) {
2133 if (err) { return done(err); }
2134 if (code == null || code === token.text) {
2135 return --pending || done();
2136 }
2137 token.text = code;
2138 token.escaped = true;
2139 --pending || done();
2140 });
2141 })(tokens[i]);
2142 }
2143
2144 return;
2145 }
2146 try {
2147 if (opt) { opt = merge({}, marked.defaults, opt); }
2148 return Parser.parse(Lexer.lex(src, opt), opt);
2149 } catch (e) {
2150 e.message += '\nPlease report this to https://github.com/markedjs/marked.';
2151 if ((opt || marked.defaults).silent) {
2152 return '<p>An error occurred:</p><pre>'
2153 + escape(e.message + '', true)
2154 + '</pre>';
2155 }
2156 throw e;
2157 }
2158}
2159
2160/**
2161 * Options
2162 */
2163
2164marked.options =
2165marked.setOptions = function(opt) {
2166 merge(marked.defaults, opt);
2167 return marked;
2168};
2169
2170marked.getDefaults = function () {
2171 return {
2172 baseUrl: null,
2173 breaks: false,
2174 gfm: true,
2175 headerIds: true,
2176 headerPrefix: '',
2177 highlight: null,
2178 langPrefix: 'language-',
2179 mangle: true,
2180 pedantic: false,
2181 renderer: new Renderer(),
2182 sanitize: false,
2183 sanitizer: null,
2184 silent: false,
2185 smartLists: false,
2186 smartypants: false,
2187 tables: true,
2188 xhtml: false
2189 };
2190};
2191
2192marked.defaults = marked.getDefaults();
2193
2194/**
2195 * Expose
2196 */
2197
2198marked.Parser = Parser;
2199marked.parser = Parser.parse;
2200
2201marked.Renderer = Renderer;
2202marked.TextRenderer = TextRenderer;
2203
2204marked.Lexer = Lexer;
2205marked.lexer = Lexer.lex;
2206
2207marked.InlineLexer = InlineLexer;
2208marked.inlineLexer = InlineLexer.output;
2209
2210marked.parse = marked;
2211
2212{
2213 module.exports = marked;
2214}
2215})(commonjsGlobal || (typeof window !== 'undefined' ? window : commonjsGlobal));
2216});
2217
2218var prism = createCommonjsModule(function (module) {
2219/* **********************************************
2220 Begin prism-core.js
2221********************************************** */
2222
2223var _self = (typeof window !== 'undefined')
2224 ? window // if in browser
2225 : (
2226 (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
2227 ? self // if in worker
2228 : {} // if in node js
2229 );
2230
2231/**
2232 * Prism: Lightweight, robust, elegant syntax highlighting
2233 * MIT license http://www.opensource.org/licenses/mit-license.php/
2234 * @author Lea Verou http://lea.verou.me
2235 */
2236
2237var Prism = (function(){
2238
2239// Private helper vars
2240var lang = /\blang(?:uage)?-([\w-]+)\b/i;
2241var uniqueId = 0;
2242
2243var _ = _self.Prism = {
2244 manual: _self.Prism && _self.Prism.manual,
2245 disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
2246 util: {
2247 encode: function (tokens) {
2248 if (tokens instanceof Token) {
2249 return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
2250 } else if (_.util.type(tokens) === 'Array') {
2251 return tokens.map(_.util.encode);
2252 } else {
2253 return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
2254 }
2255 },
2256
2257 type: function (o) {
2258 return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
2259 },
2260
2261 objId: function (obj) {
2262 if (!obj['__id']) {
2263 Object.defineProperty(obj, '__id', { value: ++uniqueId });
2264 }
2265 return obj['__id'];
2266 },
2267
2268 // Deep clone a language definition (e.g. to extend it)
2269 clone: function (o, visited) {
2270 var type = _.util.type(o);
2271 visited = visited || {};
2272
2273 switch (type) {
2274 case 'Object':
2275 if (visited[_.util.objId(o)]) {
2276 return visited[_.util.objId(o)];
2277 }
2278 var clone = {};
2279 visited[_.util.objId(o)] = clone;
2280
2281 for (var key in o) {
2282 if (o.hasOwnProperty(key)) {
2283 clone[key] = _.util.clone(o[key], visited);
2284 }
2285 }
2286
2287 return clone;
2288
2289 case 'Array':
2290 if (visited[_.util.objId(o)]) {
2291 return visited[_.util.objId(o)];
2292 }
2293 var clone = [];
2294 visited[_.util.objId(o)] = clone;
2295
2296 o.forEach(function (v, i) {
2297 clone[i] = _.util.clone(v, visited);
2298 });
2299
2300 return clone;
2301 }
2302
2303 return o;
2304 }
2305 },
2306
2307 languages: {
2308 extend: function (id, redef) {
2309 var lang = _.util.clone(_.languages[id]);
2310
2311 for (var key in redef) {
2312 lang[key] = redef[key];
2313 }
2314
2315 return lang;
2316 },
2317
2318 /**
2319 * Insert a token before another token in a language literal
2320 * As this needs to recreate the object (we cannot actually insert before keys in object literals),
2321 * we cannot just provide an object, we need anobject and a key.
2322 * @param inside The key (or language id) of the parent
2323 * @param before The key to insert before. If not provided, the function appends instead.
2324 * @param insert Object with the key/value pairs to insert
2325 * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
2326 */
2327 insertBefore: function (inside, before, insert, root) {
2328 root = root || _.languages;
2329 var grammar = root[inside];
2330
2331 if (arguments.length == 2) {
2332 insert = arguments[1];
2333
2334 for (var newToken in insert) {
2335 if (insert.hasOwnProperty(newToken)) {
2336 grammar[newToken] = insert[newToken];
2337 }
2338 }
2339
2340 return grammar;
2341 }
2342
2343 var ret = {};
2344
2345 for (var token in grammar) {
2346
2347 if (grammar.hasOwnProperty(token)) {
2348
2349 if (token == before) {
2350
2351 for (var newToken in insert) {
2352
2353 if (insert.hasOwnProperty(newToken)) {
2354 ret[newToken] = insert[newToken];
2355 }
2356 }
2357 }
2358
2359 ret[token] = grammar[token];
2360 }
2361 }
2362
2363 // Update references in other language definitions
2364 _.languages.DFS(_.languages, function(key, value) {
2365 if (value === root[inside] && key != inside) {
2366 this[key] = ret;
2367 }
2368 });
2369
2370 return root[inside] = ret;
2371 },
2372
2373 // Traverse a language definition with Depth First Search
2374 DFS: function(o, callback, type, visited) {
2375 visited = visited || {};
2376 for (var i in o) {
2377 if (o.hasOwnProperty(i)) {
2378 callback.call(o, i, o[i], type || i);
2379
2380 if (_.util.type(o[i]) === 'Object' && !visited[_.util.objId(o[i])]) {
2381 visited[_.util.objId(o[i])] = true;
2382 _.languages.DFS(o[i], callback, null, visited);
2383 }
2384 else if (_.util.type(o[i]) === 'Array' && !visited[_.util.objId(o[i])]) {
2385 visited[_.util.objId(o[i])] = true;
2386 _.languages.DFS(o[i], callback, i, visited);
2387 }
2388 }
2389 }
2390 }
2391 },
2392 plugins: {},
2393
2394 highlightAll: function(async, callback) {
2395 _.highlightAllUnder(document, async, callback);
2396 },
2397
2398 highlightAllUnder: function(container, async, callback) {
2399 var env = {
2400 callback: callback,
2401 selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
2402 };
2403
2404 _.hooks.run("before-highlightall", env);
2405
2406 var elements = env.elements || container.querySelectorAll(env.selector);
2407
2408 for (var i=0, element; element = elements[i++];) {
2409 _.highlightElement(element, async === true, env.callback);
2410 }
2411 },
2412
2413 highlightElement: function(element, async, callback) {
2414 // Find language
2415 var language, grammar, parent = element;
2416
2417 while (parent && !lang.test(parent.className)) {
2418 parent = parent.parentNode;
2419 }
2420
2421 if (parent) {
2422 language = (parent.className.match(lang) || [,''])[1].toLowerCase();
2423 grammar = _.languages[language];
2424 }
2425
2426 // Set language on the element, if not present
2427 element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
2428
2429 if (element.parentNode) {
2430 // Set language on the parent, for styling
2431 parent = element.parentNode;
2432
2433 if (/pre/i.test(parent.nodeName)) {
2434 parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
2435 }
2436 }
2437
2438 var code = element.textContent;
2439
2440 var env = {
2441 element: element,
2442 language: language,
2443 grammar: grammar,
2444 code: code
2445 };
2446
2447 _.hooks.run('before-sanity-check', env);
2448
2449 if (!env.code || !env.grammar) {
2450 if (env.code) {
2451 _.hooks.run('before-highlight', env);
2452 env.element.textContent = env.code;
2453 _.hooks.run('after-highlight', env);
2454 }
2455 _.hooks.run('complete', env);
2456 return;
2457 }
2458
2459 _.hooks.run('before-highlight', env);
2460
2461 if (async && _self.Worker) {
2462 var worker = new Worker(_.filename);
2463
2464 worker.onmessage = function(evt) {
2465 env.highlightedCode = evt.data;
2466
2467 _.hooks.run('before-insert', env);
2468
2469 env.element.innerHTML = env.highlightedCode;
2470
2471 callback && callback.call(env.element);
2472 _.hooks.run('after-highlight', env);
2473 _.hooks.run('complete', env);
2474 };
2475
2476 worker.postMessage(JSON.stringify({
2477 language: env.language,
2478 code: env.code,
2479 immediateClose: true
2480 }));
2481 }
2482 else {
2483 env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
2484
2485 _.hooks.run('before-insert', env);
2486
2487 env.element.innerHTML = env.highlightedCode;
2488
2489 callback && callback.call(element);
2490
2491 _.hooks.run('after-highlight', env);
2492 _.hooks.run('complete', env);
2493 }
2494 },
2495
2496 highlight: function (text, grammar, language) {
2497 var env = {
2498 code: text,
2499 grammar: grammar,
2500 language: language
2501 };
2502 _.hooks.run('before-tokenize', env);
2503 env.tokens = _.tokenize(env.code, env.grammar);
2504 _.hooks.run('after-tokenize', env);
2505 return Token.stringify(_.util.encode(env.tokens), env.language);
2506 },
2507
2508 matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
2509 var Token = _.Token;
2510
2511 for (var token in grammar) {
2512 if(!grammar.hasOwnProperty(token) || !grammar[token]) {
2513 continue;
2514 }
2515
2516 if (token == target) {
2517 return;
2518 }
2519
2520 var patterns = grammar[token];
2521 patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
2522
2523 for (var j = 0; j < patterns.length; ++j) {
2524 var pattern = patterns[j],
2525 inside = pattern.inside,
2526 lookbehind = !!pattern.lookbehind,
2527 greedy = !!pattern.greedy,
2528 lookbehindLength = 0,
2529 alias = pattern.alias;
2530
2531 if (greedy && !pattern.pattern.global) {
2532 // Without the global flag, lastIndex won't work
2533 var flags = pattern.pattern.toString().match(/[imuy]*$/)[0];
2534 pattern.pattern = RegExp(pattern.pattern.source, flags + "g");
2535 }
2536
2537 pattern = pattern.pattern || pattern;
2538
2539 // Don’t cache length as it changes during the loop
2540 for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {
2541
2542 var str = strarr[i];
2543
2544 if (strarr.length > text.length) {
2545 // Something went terribly wrong, ABORT, ABORT!
2546 return;
2547 }
2548
2549 if (str instanceof Token) {
2550 continue;
2551 }
2552
2553 if (greedy && i != strarr.length - 1) {
2554 pattern.lastIndex = pos;
2555 var match = pattern.exec(text);
2556 if (!match) {
2557 break;
2558 }
2559
2560 var from = match.index + (lookbehind ? match[1].length : 0),
2561 to = match.index + match[0].length,
2562 k = i,
2563 p = pos;
2564
2565 for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
2566 p += strarr[k].length;
2567 // Move the index i to the element in strarr that is closest to from
2568 if (from >= p) {
2569 ++i;
2570 pos = p;
2571 }
2572 }
2573
2574 // If strarr[i] is a Token, then the match starts inside another Token, which is invalid
2575 if (strarr[i] instanceof Token) {
2576 continue;
2577 }
2578
2579 // Number of tokens to delete and replace with the new match
2580 delNum = k - i;
2581 str = text.slice(pos, p);
2582 match.index -= pos;
2583 } else {
2584 pattern.lastIndex = 0;
2585
2586 var match = pattern.exec(str),
2587 delNum = 1;
2588 }
2589
2590 if (!match) {
2591 if (oneshot) {
2592 break;
2593 }
2594
2595 continue;
2596 }
2597
2598 if(lookbehind) {
2599 lookbehindLength = match[1] ? match[1].length : 0;
2600 }
2601
2602 var from = match.index + lookbehindLength,
2603 match = match[0].slice(lookbehindLength),
2604 to = from + match.length,
2605 before = str.slice(0, from),
2606 after = str.slice(to);
2607
2608 var args = [i, delNum];
2609
2610 if (before) {
2611 ++i;
2612 pos += before.length;
2613 args.push(before);
2614 }
2615
2616 var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy);
2617
2618 args.push(wrapped);
2619
2620 if (after) {
2621 args.push(after);
2622 }
2623
2624 Array.prototype.splice.apply(strarr, args);
2625
2626 if (delNum != 1)
2627 { _.matchGrammar(text, strarr, grammar, i, pos, true, token); }
2628
2629 if (oneshot)
2630 { break; }
2631 }
2632 }
2633 }
2634 },
2635
2636 tokenize: function(text, grammar, language) {
2637 var strarr = [text];
2638
2639 var rest = grammar.rest;
2640
2641 if (rest) {
2642 for (var token in rest) {
2643 grammar[token] = rest[token];
2644 }
2645
2646 delete grammar.rest;
2647 }
2648
2649 _.matchGrammar(text, strarr, grammar, 0, 0, false);
2650
2651 return strarr;
2652 },
2653
2654 hooks: {
2655 all: {},
2656
2657 add: function (name, callback) {
2658 var hooks = _.hooks.all;
2659
2660 hooks[name] = hooks[name] || [];
2661
2662 hooks[name].push(callback);
2663 },
2664
2665 run: function (name, env) {
2666 var callbacks = _.hooks.all[name];
2667
2668 if (!callbacks || !callbacks.length) {
2669 return;
2670 }
2671
2672 for (var i=0, callback; callback = callbacks[i++];) {
2673 callback(env);
2674 }
2675 }
2676 }
2677};
2678
2679var Token = _.Token = function(type, content, alias, matchedStr, greedy) {
2680 this.type = type;
2681 this.content = content;
2682 this.alias = alias;
2683 // Copy of the full string this token was created from
2684 this.length = (matchedStr || "").length|0;
2685 this.greedy = !!greedy;
2686};
2687
2688Token.stringify = function(o, language, parent) {
2689 if (typeof o == 'string') {
2690 return o;
2691 }
2692
2693 if (_.util.type(o) === 'Array') {
2694 return o.map(function(element) {
2695 return Token.stringify(element, language, o);
2696 }).join('');
2697 }
2698
2699 var env = {
2700 type: o.type,
2701 content: Token.stringify(o.content, language, parent),
2702 tag: 'span',
2703 classes: ['token', o.type],
2704 attributes: {},
2705 language: language,
2706 parent: parent
2707 };
2708
2709 if (o.alias) {
2710 var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
2711 Array.prototype.push.apply(env.classes, aliases);
2712 }
2713
2714 _.hooks.run('wrap', env);
2715
2716 var attributes = Object.keys(env.attributes).map(function(name) {
2717 return name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
2718 }).join(' ');
2719
2720 return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + '</' + env.tag + '>';
2721
2722};
2723
2724if (!_self.document) {
2725 if (!_self.addEventListener) {
2726 // in Node.js
2727 return _self.Prism;
2728 }
2729
2730 if (!_.disableWorkerMessageHandler) {
2731 // In worker
2732 _self.addEventListener('message', function (evt) {
2733 var message = JSON.parse(evt.data),
2734 lang = message.language,
2735 code = message.code,
2736 immediateClose = message.immediateClose;
2737
2738 _self.postMessage(_.highlight(code, _.languages[lang], lang));
2739 if (immediateClose) {
2740 _self.close();
2741 }
2742 }, false);
2743 }
2744
2745 return _self.Prism;
2746}
2747
2748//Get current script and highlight
2749var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
2750
2751if (script) {
2752 _.filename = script.src;
2753
2754 if (!_.manual && !script.hasAttribute('data-manual')) {
2755 if(document.readyState !== "loading") {
2756 if (window.requestAnimationFrame) {
2757 window.requestAnimationFrame(_.highlightAll);
2758 } else {
2759 window.setTimeout(_.highlightAll, 16);
2760 }
2761 }
2762 else {
2763 document.addEventListener('DOMContentLoaded', _.highlightAll);
2764 }
2765 }
2766}
2767
2768return _self.Prism;
2769
2770})();
2771
2772if ('object' !== 'undefined' && module.exports) {
2773 module.exports = Prism;
2774}
2775
2776// hack for components to work correctly in node.js
2777if (typeof commonjsGlobal !== 'undefined') {
2778 commonjsGlobal.Prism = Prism;
2779}
2780
2781
2782/* **********************************************
2783 Begin prism-markup.js
2784********************************************** */
2785
2786Prism.languages.markup = {
2787 'comment': /<!--[\s\S]*?-->/,
2788 'prolog': /<\?[\s\S]+?\?>/,
2789 'doctype': /<!DOCTYPE[\s\S]+?>/i,
2790 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i,
2791 'tag': {
2792 pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,
2793 greedy: true,
2794 inside: {
2795 'tag': {
2796 pattern: /^<\/?[^\s>\/]+/i,
2797 inside: {
2798 'punctuation': /^<\/?/,
2799 'namespace': /^[^\s>\/:]+:/
2800 }
2801 },
2802 'attr-value': {
2803 pattern: /=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,
2804 inside: {
2805 'punctuation': [
2806 /^=/,
2807 {
2808 pattern: /(^|[^\\])["']/,
2809 lookbehind: true
2810 }
2811 ]
2812 }
2813 },
2814 'punctuation': /\/?>/,
2815 'attr-name': {
2816 pattern: /[^\s>\/]+/,
2817 inside: {
2818 'namespace': /^[^\s>\/:]+:/
2819 }
2820 }
2821
2822 }
2823 },
2824 'entity': /&#?[\da-z]{1,8};/i
2825};
2826
2827Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
2828 Prism.languages.markup['entity'];
2829
2830// Plugin to make entity title show the real entity, idea by Roman Komarov
2831Prism.hooks.add('wrap', function(env) {
2832
2833 if (env.type === 'entity') {
2834 env.attributes['title'] = env.content.replace(/&amp;/, '&');
2835 }
2836});
2837
2838Prism.languages.xml = Prism.languages.markup;
2839Prism.languages.html = Prism.languages.markup;
2840Prism.languages.mathml = Prism.languages.markup;
2841Prism.languages.svg = Prism.languages.markup;
2842
2843
2844/* **********************************************
2845 Begin prism-css.js
2846********************************************** */
2847
2848Prism.languages.css = {
2849 'comment': /\/\*[\s\S]*?\*\//,
2850 'atrule': {
2851 pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i,
2852 inside: {
2853 'rule': /@[\w-]+/
2854 // See rest below
2855 }
2856 },
2857 'url': /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
2858 'selector': /[^{}\s][^{};]*?(?=\s*\{)/,
2859 'string': {
2860 pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
2861 greedy: true
2862 },
2863 'property': /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,
2864 'important': /\B!important\b/i,
2865 'function': /[-a-z0-9]+(?=\()/i,
2866 'punctuation': /[(){};:]/
2867};
2868
2869Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
2870
2871if (Prism.languages.markup) {
2872 Prism.languages.insertBefore('markup', 'tag', {
2873 'style': {
2874 pattern: /(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,
2875 lookbehind: true,
2876 inside: Prism.languages.css,
2877 alias: 'language-css',
2878 greedy: true
2879 }
2880 });
2881
2882 Prism.languages.insertBefore('inside', 'attr-value', {
2883 'style-attr': {
2884 pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
2885 inside: {
2886 'attr-name': {
2887 pattern: /^\s*style/i,
2888 inside: Prism.languages.markup.tag.inside
2889 },
2890 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
2891 'attr-value': {
2892 pattern: /.+/i,
2893 inside: Prism.languages.css
2894 }
2895 },
2896 alias: 'language-css'
2897 }
2898 }, Prism.languages.markup.tag);
2899}
2900
2901/* **********************************************
2902 Begin prism-clike.js
2903********************************************** */
2904
2905Prism.languages.clike = {
2906 'comment': [
2907 {
2908 pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
2909 lookbehind: true
2910 },
2911 {
2912 pattern: /(^|[^\\:])\/\/.*/,
2913 lookbehind: true,
2914 greedy: true
2915 }
2916 ],
2917 'string': {
2918 pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
2919 greedy: true
2920 },
2921 'class-name': {
2922 pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,
2923 lookbehind: true,
2924 inside: {
2925 punctuation: /[.\\]/
2926 }
2927 },
2928 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
2929 'boolean': /\b(?:true|false)\b/,
2930 'function': /[a-z0-9_]+(?=\()/i,
2931 'number': /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
2932 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
2933 'punctuation': /[{}[\];(),.:]/
2934};
2935
2936
2937/* **********************************************
2938 Begin prism-javascript.js
2939********************************************** */
2940
2941Prism.languages.javascript = Prism.languages.extend('clike', {
2942 'keyword': /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,
2943 'number': /\b(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/,
2944 // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
2945 'function': /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i,
2946 'operator': /-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/
2947});
2948
2949Prism.languages.insertBefore('javascript', 'keyword', {
2950 'regex': {
2951 pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/,
2952 lookbehind: true,
2953 greedy: true
2954 },
2955 // This must be declared before keyword because we use "function" inside the look-forward
2956 'function-variable': {
2957 pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i,
2958 alias: 'function'
2959 },
2960 'constant': /\b[A-Z][A-Z\d_]*\b/
2961});
2962
2963Prism.languages.insertBefore('javascript', 'string', {
2964 'template-string': {
2965 pattern: /`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/,
2966 greedy: true,
2967 inside: {
2968 'interpolation': {
2969 pattern: /\${[^}]+}/,
2970 inside: {
2971 'interpolation-punctuation': {
2972 pattern: /^\${|}$/,
2973 alias: 'punctuation'
2974 },
2975 rest: null // See below
2976 }
2977 },
2978 'string': /[\s\S]+/
2979 }
2980 }
2981});
2982Prism.languages.javascript['template-string'].inside['interpolation'].inside.rest = Prism.languages.javascript;
2983
2984if (Prism.languages.markup) {
2985 Prism.languages.insertBefore('markup', 'tag', {
2986 'script': {
2987 pattern: /(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,
2988 lookbehind: true,
2989 inside: Prism.languages.javascript,
2990 alias: 'language-javascript',
2991 greedy: true
2992 }
2993 });
2994}
2995
2996Prism.languages.js = Prism.languages.javascript;
2997
2998
2999/* **********************************************
3000 Begin prism-file-highlight.js
3001********************************************** */
3002
3003(function () {
3004 if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {
3005 return;
3006 }
3007
3008 self.Prism.fileHighlight = function() {
3009
3010 var Extensions = {
3011 'js': 'javascript',
3012 'py': 'python',
3013 'rb': 'ruby',
3014 'ps1': 'powershell',
3015 'psm1': 'powershell',
3016 'sh': 'bash',
3017 'bat': 'batch',
3018 'h': 'c',
3019 'tex': 'latex'
3020 };
3021
3022 Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
3023 var src = pre.getAttribute('data-src');
3024
3025 var language, parent = pre;
3026 var lang = /\blang(?:uage)?-([\w-]+)\b/i;
3027 while (parent && !lang.test(parent.className)) {
3028 parent = parent.parentNode;
3029 }
3030
3031 if (parent) {
3032 language = (pre.className.match(lang) || [, ''])[1];
3033 }
3034
3035 if (!language) {
3036 var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
3037 language = Extensions[extension] || extension;
3038 }
3039
3040 var code = document.createElement('code');
3041 code.className = 'language-' + language;
3042
3043 pre.textContent = '';
3044
3045 code.textContent = 'Loading…';
3046
3047 pre.appendChild(code);
3048
3049 var xhr = new XMLHttpRequest();
3050
3051 xhr.open('GET', src, true);
3052
3053 xhr.onreadystatechange = function () {
3054 if (xhr.readyState == 4) {
3055
3056 if (xhr.status < 400 && xhr.responseText) {
3057 code.textContent = xhr.responseText;
3058
3059 Prism.highlightElement(code);
3060 }
3061 else if (xhr.status >= 400) {
3062 code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
3063 }
3064 else {
3065 code.textContent = '✖ Error: File does not exist or is empty';
3066 }
3067 }
3068 };
3069
3070 xhr.send(null);
3071 });
3072
3073 if (Prism.plugins.toolbar) {
3074 Prism.plugins.toolbar.registerButton('download-file', function (env) {
3075 var pre = env.element.parentNode;
3076 if (!pre || !/pre/i.test(pre.nodeName) || !pre.hasAttribute('data-src') || !pre.hasAttribute('data-download-link')) {
3077 return;
3078 }
3079 var src = pre.getAttribute('data-src');
3080 var a = document.createElement('a');
3081 a.textContent = pre.getAttribute('data-download-link-label') || 'Download';
3082 a.setAttribute('download', '');
3083 a.href = src;
3084 return a;
3085 });
3086 }
3087
3088 };
3089
3090 document.addEventListener('DOMContentLoaded', self.Prism.fileHighlight);
3091
3092})();
3093});
3094
3095/**
3096 * Gen toc tree
3097 * @link https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81
3098 * @param {Array} toc
3099 * @param {Number} maxLevel
3100 * @return {Array}
3101 */
3102function genTree(toc, maxLevel) {
3103 var headlines = [];
3104 var last = {};
3105
3106 toc.forEach(function (headline) {
3107 var level = headline.level || 1;
3108 var len = level - 1;
3109
3110 if (level > maxLevel) {
3111 return
3112 }
3113 if (last[len]) {
3114 last[len].children = (last[len].children || []).concat(headline);
3115 } else {
3116 headlines.push(headline);
3117 }
3118 last[level] = headline;
3119 });
3120
3121 return headlines
3122}
3123
3124var cache$1 = {};
3125var re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g;
3126
3127function lower(string) {
3128 return string.toLowerCase()
3129}
3130
3131function slugify(str) {
3132 if (typeof str !== 'string') {
3133 return ''
3134 }
3135
3136 var slug = str
3137 .trim()
3138 .replace(/[A-Z]+/g, lower)
3139 .replace(/<[^>\d]+>/g, '')
3140 .replace(re, '')
3141 .replace(/\s/g, '-')
3142 .replace(/-+/g, '-')
3143 .replace(/^(\d)/, '_$1');
3144 var count = cache$1[slug];
3145
3146 count = hasOwn.call(cache$1, slug) ? count + 1 : 0;
3147 cache$1[slug] = count;
3148
3149 if (count) {
3150 slug = slug + '-' + count;
3151 }
3152
3153 return slug
3154}
3155
3156slugify.clear = function () {
3157 cache$1 = {};
3158};
3159
3160function replace(m, $1) {
3161 return '<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
3162}
3163
3164function emojify(text) {
3165 return text
3166 .replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, function (m) { return m.replace(/:/g, '__colon__'); })
3167 .replace(/:(\w+?):/ig, (inBrowser && window.emojify) || replace)
3168 .replace(/__colon__/g, ':')
3169}
3170
3171var decode = decodeURIComponent;
3172var encode = encodeURIComponent;
3173
3174function parseQuery(query) {
3175 var res = {};
3176
3177 query = query.trim().replace(/^(\?|#|&)/, '');
3178
3179 if (!query) {
3180 return res
3181 }
3182
3183 // Simple parse
3184 query.split('&').forEach(function (param) {
3185 var parts = param.replace(/\+/g, ' ').split('=');
3186
3187 res[parts[0]] = parts[1] && decode(parts[1]);
3188 });
3189
3190 return res
3191}
3192
3193function stringifyQuery(obj, ignores) {
3194 if ( ignores === void 0 ) ignores = [];
3195
3196 var qs = [];
3197
3198 for (var key in obj) {
3199 if (ignores.indexOf(key) > -1) {
3200 continue
3201 }
3202 qs.push(
3203 obj[key] ?
3204 ((encode(key)) + "=" + (encode(obj[key]))).toLowerCase() :
3205 encode(key)
3206 );
3207 }
3208
3209 return qs.length ? ("?" + (qs.join('&'))) : ''
3210}
3211
3212var isAbsolutePath = cached(function (path) {
3213 return /(:|(\/{2}))/g.test(path)
3214});
3215
3216var getParentPath = cached(function (path) {
3217 return /\/$/g.test(path) ?
3218 path :
3219 (path = path.match(/(\S*\/)[^/]+$/)) ? path[1] : ''
3220});
3221
3222var cleanPath = cached(function (path) {
3223 return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/')
3224});
3225
3226var resolvePath = cached(function (path) {
3227 var segments = path.replace(/^\//, '').split('/');
3228 var resolved = [];
3229 for (var i = 0, len = segments.length; i < len; i++) {
3230 var segment = segments[i];
3231 if (segment === '..') {
3232 resolved.pop();
3233 } else if (segment !== '.') {
3234 resolved.push(segment);
3235 }
3236 }
3237 return '/' + resolved.join('/')
3238});
3239
3240function getPath() {
3241 var args = [], len = arguments.length;
3242 while ( len-- ) args[ len ] = arguments[ len ];
3243
3244 return cleanPath(args.join('/'))
3245}
3246
3247var replaceSlug = cached(function (path) {
3248 return path.replace('#', '?id=')
3249});
3250
3251Prism.languages['markup-templating'] = {};
3252
3253Object.defineProperties(Prism.languages['markup-templating'], {
3254 buildPlaceholders: {
3255 // Tokenize all inline templating expressions matching placeholderPattern
3256 // If the replaceFilter function is provided, it will be called with every match.
3257 // If it returns false, the match will not be replaced.
3258 value: function (env, language, placeholderPattern, replaceFilter) {
3259 if (env.language !== language) {
3260 return;
3261 }
3262
3263 env.tokenStack = [];
3264
3265 env.code = env.code.replace(placeholderPattern, function(match) {
3266 if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
3267 return match;
3268 }
3269 var i = env.tokenStack.length;
3270 // Check for existing strings
3271 while (env.code.indexOf('___' + language.toUpperCase() + i + '___') !== -1)
3272 { ++i; }
3273
3274 // Create a sparse array
3275 env.tokenStack[i] = match;
3276
3277 return '___' + language.toUpperCase() + i + '___';
3278 });
3279
3280 // Switch the grammar to markup
3281 env.grammar = Prism.languages.markup;
3282 }
3283 },
3284 tokenizePlaceholders: {
3285 // Replace placeholders with proper tokens after tokenizing
3286 value: function (env, language) {
3287 if (env.language !== language || !env.tokenStack) {
3288 return;
3289 }
3290
3291 // Switch the grammar back
3292 env.grammar = Prism.languages[language];
3293
3294 var j = 0;
3295 var keys = Object.keys(env.tokenStack);
3296 var walkTokens = function (tokens) {
3297 if (j >= keys.length) {
3298 return;
3299 }
3300 for (var i = 0; i < tokens.length; i++) {
3301 var token = tokens[i];
3302 if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
3303 var k = keys[j];
3304 var t = env.tokenStack[k];
3305 var s = typeof token === 'string' ? token : token.content;
3306
3307 var index = s.indexOf('___' + language.toUpperCase() + k + '___');
3308 if (index > -1) {
3309 ++j;
3310 var before = s.substring(0, index);
3311 var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar, language), 'language-' + language, t);
3312 var after = s.substring(index + ('___' + language.toUpperCase() + k + '___').length);
3313 var replacement;
3314 if (before || after) {
3315 replacement = [before, middle, after].filter(function (v) { return !!v; });
3316 walkTokens(replacement);
3317 } else {
3318 replacement = middle;
3319 }
3320 if (typeof token === 'string') {
3321 Array.prototype.splice.apply(tokens, [i, 1].concat(replacement));
3322 } else {
3323 token.content = replacement;
3324 }
3325
3326 if (j >= keys.length) {
3327 break;
3328 }
3329 }
3330 } else if (token.content && typeof token.content !== 'string') {
3331 walkTokens(token.content);
3332 }
3333 }
3334 };
3335
3336 walkTokens(env.tokens);
3337 }
3338 }
3339});
3340
3341// See https://github.com/PrismJS/prism/pull/1367
3342var cachedLinks = {};
3343
3344function getAndRemoveConfig(str) {
3345 if ( str === void 0 ) str = '';
3346
3347 var config = {};
3348
3349 if (str) {
3350 str = str
3351 .replace(/^'/, '')
3352 .replace(/'$/, '')
3353 .replace(/(?:^|\s):([\w-]+)=?([\w-]+)?/g, function (m, key, value) {
3354 config[key] = (value && value.replace(/&quot;/g, '')) || true;
3355 return ''
3356 })
3357 .trim();
3358 }
3359
3360 return {str: str, config: config}
3361}
3362
3363var compileMedia = {
3364 markdown: function markdown(url) {
3365 return {
3366 url: url
3367 }
3368 },
3369 mermaid: function mermaid(url) {
3370 return {
3371 url: url
3372 }
3373 },
3374 iframe: function iframe(url, title) {
3375 return {
3376 html: ("<iframe src=\"" + url + "\" " + (title || 'width=100% height=400') + "></iframe>")
3377 }
3378 },
3379 video: function video(url, title) {
3380 return {
3381 html: ("<video src=\"" + url + "\" " + (title || 'controls') + ">Not Support</video>")
3382 }
3383 },
3384 audio: function audio(url, title) {
3385 return {
3386 html: ("<audio src=\"" + url + "\" " + (title || 'controls') + ">Not Support</audio>")
3387 }
3388 },
3389 code: function code(url, title) {
3390 var lang = url.match(/\.(\w+)$/);
3391
3392 lang = title || (lang && lang[1]);
3393 if (lang === 'md') {
3394 lang = 'markdown';
3395 }
3396
3397 return {
3398 url: url,
3399 lang: lang
3400 }
3401 }
3402};
3403
3404var Compiler = function Compiler(config, router) {
3405 var this$1 = this;
3406
3407 this.config = config;
3408 this.router = router;
3409 this.cacheTree = {};
3410 this.toc = [];
3411 this.cacheTOC = {};
3412 this.linkTarget = config.externalLinkTarget || '_blank';
3413 this.contentBase = router.getBasePath();
3414
3415 var renderer = this._initRenderer();
3416 var compile;
3417 var mdConf = config.markdown || {};
3418
3419 if (isFn(mdConf)) {
3420 compile = mdConf(marked, renderer);
3421 } else {
3422 marked.setOptions(
3423 merge(mdConf, {
3424 renderer: merge(renderer, mdConf.renderer)
3425 })
3426 );
3427 compile = marked;
3428 }
3429
3430 this._marked = compile;
3431 this.compile = function (text) {
3432 var isCached = true;
3433 var result = cached(function (_) {
3434 isCached = false;
3435 var html = '';
3436
3437 if (!text) {
3438 return text
3439 }
3440
3441 if (isPrimitive(text)) {
3442 html = compile(text);
3443 } else {
3444 html = compile.parser(text);
3445 }
3446
3447 html = config.noEmoji ? html : emojify(html);
3448 slugify.clear();
3449
3450 return html
3451 })(text);
3452
3453 var curFileName = this$1.router.parse().file;
3454
3455 if (isCached) {
3456 this$1.toc = this$1.cacheTOC[curFileName];
3457 } else {
3458 this$1.cacheTOC[curFileName] = [].concat( this$1.toc );
3459 }
3460
3461 return result
3462 };
3463};
3464
3465Compiler.prototype.compileEmbed = function compileEmbed (href, title) {
3466 var ref = getAndRemoveConfig(title);
3467 var str = ref.str;
3468 var config = ref.config;
3469 var embed;
3470 title = str;
3471
3472 if (config.include) {
3473 if (!isAbsolutePath(href)) {
3474 href = getPath(
3475 this.contentBase,
3476 getParentPath(this.router.getCurrentPath()),
3477 href
3478 );
3479 }
3480
3481 var media;
3482 if (config.type && (media = compileMedia[config.type])) {
3483 embed = media.call(this, href, title);
3484 embed.type = config.type;
3485 } else {
3486 var type = 'code';
3487 if (/\.(md|markdown)/.test(href)) {
3488 type = 'markdown';
3489 } else if (/\.mmd/.test(href)) {
3490 type = 'mermaid';
3491 } else if (/\.html?/.test(href)) {
3492 type = 'iframe';
3493 } else if (/\.(mp4|ogg)/.test(href)) {
3494 type = 'video';
3495 } else if (/\.mp3/.test(href)) {
3496 type = 'audio';
3497 }
3498 embed = compileMedia[type].call(this, href, title);
3499 embed.type = type;
3500 }
3501 embed.fragment = config.fragment;
3502
3503 return embed
3504 }
3505};
3506
3507Compiler.prototype._matchNotCompileLink = function _matchNotCompileLink (link) {
3508 var links = this.config.noCompileLinks || [];
3509
3510 for (var i = 0; i < links.length; i++) {
3511 var n = links[i];
3512 var re = cachedLinks[n] || (cachedLinks[n] = new RegExp(("^" + n + "$")));
3513
3514 if (re.test(link)) {
3515 return link
3516 }
3517 }
3518};
3519
3520Compiler.prototype._initRenderer = function _initRenderer () {
3521 var renderer = new marked.Renderer();
3522 var ref = this;
3523 var linkTarget = ref.linkTarget;
3524 var router = ref.router;
3525 var contentBase = ref.contentBase;
3526 var _self = this;
3527 var origin = {};
3528
3529 /**
3530 * Render anchor tag
3531 * @link https://github.com/markedjs/marked#overriding-renderer-methods
3532 */
3533 origin.heading = renderer.heading = function (text, level) {
3534 var ref = getAndRemoveConfig(text);
3535 var str = ref.str;
3536 var config = ref.config;
3537 var nextToc = {level: level, title: str};
3538
3539 if (/{docsify-ignore}/g.test(str)) {
3540 str = str.replace('{docsify-ignore}', '');
3541 nextToc.title = str;
3542 nextToc.ignoreSubHeading = true;
3543 }
3544
3545 if (/{docsify-ignore-all}/g.test(str)) {
3546 str = str.replace('{docsify-ignore-all}', '');
3547 nextToc.title = str;
3548 nextToc.ignoreAllSubs = true;
3549 }
3550
3551 var slug = slugify(config.id || str);
3552 var url = router.toURL(router.getCurrentPath(), {id: slug});
3553 nextToc.slug = url;
3554 _self.toc.push(nextToc);
3555
3556 return ("<h" + level + " id=\"" + slug + "\"><a href=\"" + url + "\" data-id=\"" + slug + "\" class=\"anchor\"><span>" + str + "</span></a></h" + level + ">")
3557 };
3558 // Highlight code
3559 origin.code = renderer.code = function (code, lang) {
3560 if ( lang === void 0 ) lang = '';
3561
3562 code = code.replace(/@DOCSIFY_QM@/g, '`');
3563 var hl = prism.highlight(
3564 code,
3565 prism.languages[lang] || prism.languages.markup
3566 );
3567
3568 return ("<pre v-pre data-lang=\"" + lang + "\"><code class=\"lang-" + lang + "\">" + hl + "</code></pre>")
3569 };
3570 origin.link = renderer.link = function (href, title, text) {
3571 if ( title === void 0 ) title = '';
3572
3573 var attrs = '';
3574
3575 var ref = getAndRemoveConfig(title);
3576 var str = ref.str;
3577 var config = ref.config;
3578 title = str;
3579
3580 if (
3581 !isAbsolutePath(href) &&
3582 !_self._matchNotCompileLink(href) &&
3583 !config.ignore
3584 ) {
3585 if (href === _self.config.homepage) {
3586 href = 'README';
3587 }
3588 href = router.toURL(href, null, router.getCurrentPath());
3589 } else {
3590 attrs += href.indexOf('mailto:') === 0 ? '' : (" target=\"" + linkTarget + "\"");
3591 }
3592
3593 if (config.target) {
3594 attrs += ' target=' + config.target;
3595 }
3596
3597 if (config.disabled) {
3598 attrs += ' disabled';
3599 href = 'javascript:void(0)';
3600 }
3601
3602 if (title) {
3603 attrs += " title=\"" + title + "\"";
3604 }
3605
3606 return ("<a href=\"" + href + "\"" + attrs + ">" + text + "</a>")
3607 };
3608 origin.paragraph = renderer.paragraph = function (text) {
3609 var result;
3610 if (/^!&gt;/.test(text)) {
3611 result = helper('tip', text);
3612 } else if (/^\?&gt;/.test(text)) {
3613 result = helper('warn', text);
3614 } else {
3615 result = "<p>" + text + "</p>";
3616 }
3617 return result
3618 };
3619 origin.image = renderer.image = function (href, title, text) {
3620 var url = href;
3621 var attrs = '';
3622
3623 var ref = getAndRemoveConfig(title);
3624 var str = ref.str;
3625 var config = ref.config;
3626 title = str;
3627
3628 if (config['no-zoom']) {
3629 attrs += ' data-no-zoom';
3630 }
3631
3632 if (title) {
3633 attrs += " title=\"" + title + "\"";
3634 }
3635
3636 var size = config.size;
3637 if (size) {
3638 var sizes = size.split('x');
3639 if (sizes[1]) {
3640 attrs += 'width=' + sizes[0] + ' height=' + sizes[1];
3641 } else {
3642 attrs += 'width=' + sizes[0];
3643 }
3644 }
3645
3646 if (!isAbsolutePath(href)) {
3647 url = getPath(contentBase, getParentPath(router.getCurrentPath()), href);
3648 }
3649
3650 return ("<img src=\"" + url + "\"data-origin=\"" + href + "\" alt=\"" + text + "\"" + attrs + ">")
3651 };
3652 origin.list = renderer.list = function (body, ordered, start) {
3653 var isTaskList = /<li class="task-list-item">/.test(body.split('class="task-list"')[0]);
3654 var isStartReq = start && start > 1;
3655 var tag = ordered ? 'ol' : 'ul';
3656 var tagAttrs = [
3657 (isTaskList ? 'class="task-list"' : ''),
3658 (isStartReq ? ("start=\"" + start + "\"") : '')
3659 ].join(' ').trim();
3660
3661 return ("<" + tag + " " + tagAttrs + ">" + body + "</" + tag + ">")
3662 };
3663 origin.listitem = renderer.listitem = function (text) {
3664 var isTaskItem = /^(<input.*type="checkbox"[^>]*>)/.test(text);
3665 var html = isTaskItem ? ("<li class=\"task-list-item\"><label>" + text + "</label></li>") : ("<li>" + text + "</li>");
3666
3667 return html
3668 };
3669
3670 renderer.origin = origin;
3671
3672 return renderer
3673};
3674
3675/**
3676 * Compile sidebar
3677 */
3678Compiler.prototype.sidebar = function sidebar (text, level) {
3679 var ref = this;
3680 var toc = ref.toc;
3681 var currentPath = this.router.getCurrentPath();
3682 var html = '';
3683
3684 if (text) {
3685 html = this.compile(text);
3686 } else {
3687 for (var i = 0; i < toc.length; i++) {
3688 if (toc[i].ignoreSubHeading) {
3689 var deletedHeaderLevel = toc[i].level;
3690 toc.splice(i, 1);
3691 // Remove headers who are under current header
3692 for (var j = i; deletedHeaderLevel < toc[j].level && j < toc.length; j++) {
3693 toc.splice(j, 1) && j-- && i++;
3694 }
3695 i--;
3696 }
3697 }
3698 var tree$$1 = this.cacheTree[currentPath] || genTree(toc, level);
3699 html = tree(tree$$1, '<ul>{inner}</ul>');
3700 this.cacheTree[currentPath] = tree$$1;
3701 }
3702
3703 return html
3704};
3705
3706/**
3707 * Compile sub sidebar
3708 */
3709Compiler.prototype.subSidebar = function subSidebar (level) {
3710 if (!level) {
3711 this.toc = [];
3712 return
3713 }
3714 var currentPath = this.router.getCurrentPath();
3715 var ref = this;
3716 var cacheTree = ref.cacheTree;
3717 var toc = ref.toc;
3718
3719 toc[0] && toc[0].ignoreAllSubs && toc.splice(0);
3720 toc[0] && toc[0].level === 1 && toc.shift();
3721
3722 for (var i = 0; i < toc.length; i++) {
3723 toc[i].ignoreSubHeading && toc.splice(i, 1) && i--;
3724 }
3725 var tree$$1 = cacheTree[currentPath] || genTree(toc, level);
3726
3727 cacheTree[currentPath] = tree$$1;
3728 this.toc = [];
3729 return tree(tree$$1)
3730};
3731
3732Compiler.prototype.article = function article (text) {
3733 return this.compile(text)
3734};
3735
3736/**
3737 * Compile cover page
3738 */
3739Compiler.prototype.cover = function cover$$1 (text) {
3740 var cacheToc = this.toc.slice();
3741 var html = this.compile(text);
3742
3743 this.toc = cacheToc.slice();
3744
3745 return html
3746};
3747
3748var title = $.title;
3749/**
3750 * Toggle button
3751 */
3752function btn(el) {
3753 var toggle = function (_) { return body.classList.toggle('close'); };
3754
3755 el = getNode(el);
3756 if (el == null) {
3757 return
3758 }
3759 on(el, 'click', function (e) {
3760 e.stopPropagation();
3761 toggle();
3762 });
3763
3764 isMobile &&
3765 on(
3766 body,
3767 'click',
3768 function (_) { return body.classList.contains('close') && toggle(); }
3769 );
3770}
3771
3772function collapse(el) {
3773 el = getNode(el);
3774 if (el == null) {
3775 return
3776 }
3777 on(el, 'click', function (ref) {
3778 var target = ref.target;
3779
3780 if (
3781 target.nodeName === 'A' &&
3782 target.nextSibling &&
3783 target.nextSibling.classList.contains('app-sub-sidebar')
3784 ) {
3785 toggleClass(target.parentNode, 'collapse');
3786 }
3787 });
3788}
3789
3790function sticky() {
3791 var cover = getNode('section.cover');
3792 if (!cover) {
3793 return
3794 }
3795 var coverHeight = cover.getBoundingClientRect().height;
3796
3797 if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) {
3798 toggleClass(body, 'add', 'sticky');
3799 } else {
3800 toggleClass(body, 'remove', 'sticky');
3801 }
3802}
3803
3804/**
3805 * Get and active link
3806 * @param {object} router
3807 * @param {string|element} el
3808 * @param {Boolean} isParent acitve parent
3809 * @param {Boolean} autoTitle auto set title
3810 * @return {element}
3811 */
3812function getAndActive(router, el, isParent, autoTitle) {
3813 el = getNode(el);
3814 var links = [];
3815 if (el != null) {
3816 links = findAll(el, 'a');
3817 }
3818 var hash = decodeURI(router.toURL(router.getCurrentPath()));
3819 var target;
3820
3821 links.sort(function (a, b) { return b.href.length - a.href.length; }).forEach(function (a) {
3822 var href = a.getAttribute('href');
3823 var node = isParent ? a.parentNode : a;
3824
3825 if (hash.indexOf(href) === 0 && !target) {
3826 target = a;
3827 toggleClass(node, 'add', 'active');
3828 } else {
3829 toggleClass(node, 'remove', 'active');
3830 }
3831 });
3832
3833 if (autoTitle) {
3834 $.title = target ? (target.title || ((target.innerText) + " - " + title)) : title;
3835 }
3836
3837 return target
3838}
3839
3840var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) { descriptor.writable = true; } Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) { defineProperties(Constructor.prototype, protoProps); } if (staticProps) { defineProperties(Constructor, staticProps); } return Constructor; }; }();
3841
3842function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3843
3844var Tweezer = function () {
3845 function Tweezer() {
3846 var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
3847
3848 _classCallCheck(this, Tweezer);
3849
3850 this.duration = opts.duration || 1000;
3851 this.ease = opts.easing || this._defaultEase;
3852 this.start = opts.start;
3853 this.end = opts.end;
3854
3855 this.frame = null;
3856 this.next = null;
3857 this.isRunning = false;
3858 this.events = {};
3859 this.direction = this.start < this.end ? 'up' : 'down';
3860 }
3861
3862 _createClass(Tweezer, [{
3863 key: 'begin',
3864 value: function begin() {
3865 if (!this.isRunning && this.next !== this.end) {
3866 this.frame = window.requestAnimationFrame(this._tick.bind(this));
3867 }
3868 return this;
3869 }
3870 }, {
3871 key: 'stop',
3872 value: function stop() {
3873 window.cancelAnimationFrame(this.frame);
3874 this.isRunning = false;
3875 this.frame = null;
3876 this.timeStart = null;
3877 this.next = null;
3878 return this;
3879 }
3880 }, {
3881 key: 'on',
3882 value: function on(name, handler) {
3883 this.events[name] = this.events[name] || [];
3884 this.events[name].push(handler);
3885 return this;
3886 }
3887 }, {
3888 key: 'emit',
3889 value: function emit(name, val) {
3890 var _this = this;
3891
3892 var e = this.events[name];
3893 e && e.forEach(function (handler) {
3894 return handler.call(_this, val);
3895 });
3896 }
3897 }, {
3898 key: '_tick',
3899 value: function _tick(currentTime) {
3900 this.isRunning = true;
3901
3902 var lastTick = this.next || this.start;
3903
3904 if (!this.timeStart) { this.timeStart = currentTime; }
3905 this.timeElapsed = currentTime - this.timeStart;
3906 this.next = Math.round(this.ease(this.timeElapsed, this.start, this.end - this.start, this.duration));
3907
3908 if (this._shouldTick(lastTick)) {
3909 this.emit('tick', this.next);
3910 this.frame = window.requestAnimationFrame(this._tick.bind(this));
3911 } else {
3912 this.emit('tick', this.end);
3913 this.emit('done', null);
3914 }
3915 }
3916 }, {
3917 key: '_shouldTick',
3918 value: function _shouldTick(lastTick) {
3919 return {
3920 up: this.next < this.end && lastTick <= this.next,
3921 down: this.next > this.end && lastTick >= this.next
3922 }[this.direction];
3923 }
3924 }, {
3925 key: '_defaultEase',
3926 value: function _defaultEase(t, b, c, d) {
3927 if ((t /= d / 2) < 1) { return c / 2 * t * t + b; }
3928 return -c / 2 * (--t * (t - 2) - 1) + b;
3929 }
3930 }]);
3931
3932 return Tweezer;
3933}();
3934
3935var nav = {};
3936var hoverOver = false;
3937var scroller = null;
3938var enableScrollEvent = true;
3939var coverHeight = 0;
3940
3941function scrollTo(el) {
3942 if (scroller) {
3943 scroller.stop();
3944 }
3945 enableScrollEvent = false;
3946 scroller = new Tweezer({
3947 start: window.pageYOffset,
3948 end: el.getBoundingClientRect().top + window.pageYOffset,
3949 duration: 500
3950 })
3951 .on('tick', function (v) { return window.scrollTo(0, v); })
3952 .on('done', function () {
3953 enableScrollEvent = true;
3954 scroller = null;
3955 })
3956 .begin();
3957}
3958
3959function highlight(path) {
3960 if (!enableScrollEvent) {
3961 return
3962 }
3963 var sidebar = getNode('.sidebar');
3964 var anchors = findAll('.anchor');
3965 var wrap = find(sidebar, '.sidebar-nav');
3966 var active = find(sidebar, 'li.active');
3967 var doc = document.documentElement;
3968 var top = ((doc && doc.scrollTop) || document.body.scrollTop) - coverHeight;
3969 var last;
3970
3971 for (var i = 0, len = anchors.length; i < len; i += 1) {
3972 var node = anchors[i];
3973
3974 if (node.offsetTop > top) {
3975 if (!last) {
3976 last = node;
3977 }
3978 break
3979 } else {
3980 last = node;
3981 }
3982 }
3983 if (!last) {
3984 return
3985 }
3986 var li = nav[getNavKey(decodeURIComponent(path), last.getAttribute('data-id'))];
3987
3988 if (!li || li === active) {
3989 return
3990 }
3991
3992 active && active.classList.remove('active');
3993 li.classList.add('active');
3994 active = li;
3995
3996 // Scroll into view
3997 // https://github.com/vuejs/vuejs.org/blob/master/themes/vue/source/js/common.js#L282-L297
3998 if (!hoverOver && body.classList.contains('sticky')) {
3999 var height = sidebar.clientHeight;
4000 var curOffset = 0;
4001 var cur = active.offsetTop + active.clientHeight + 40;
4002 var isInView =
4003 active.offsetTop >= wrap.scrollTop && cur <= wrap.scrollTop + height;
4004 var notThan = cur - curOffset < height;
4005 var top$1 = isInView ? wrap.scrollTop : notThan ? curOffset : cur - height;
4006
4007 sidebar.scrollTop = top$1;
4008 }
4009}
4010
4011function getNavKey(path, id) {
4012 return (path + "?id=" + id)
4013}
4014
4015function scrollActiveSidebar(router) {
4016 var cover = find('.cover.show');
4017 coverHeight = cover ? cover.offsetHeight : 0;
4018
4019 var sidebar = getNode('.sidebar');
4020 var lis = [];
4021 if (sidebar != null) {
4022 lis = findAll(sidebar, 'li');
4023 }
4024
4025 for (var i = 0, len = lis.length; i < len; i += 1) {
4026 var li = lis[i];
4027 var a = li.querySelector('a');
4028 if (!a) {
4029 continue
4030 }
4031 var href = a.getAttribute('href');
4032
4033 if (href !== '/') {
4034 var ref = router.parse(href);
4035 var id = ref.query.id;
4036 var path$1 = ref.path;
4037 if (id) {
4038 href = getNavKey(path$1, id);
4039 }
4040 }
4041
4042 if (href) {
4043 nav[decodeURIComponent(href)] = li;
4044 }
4045 }
4046
4047 if (isMobile) {
4048 return
4049 }
4050 var path = router.getCurrentPath();
4051 off('scroll', function () { return highlight(path); });
4052 on('scroll', function () { return highlight(path); });
4053 on(sidebar, 'mouseover', function () {
4054 hoverOver = true;
4055 });
4056 on(sidebar, 'mouseleave', function () {
4057 hoverOver = false;
4058 });
4059}
4060
4061function scrollIntoView(path, id) {
4062 if (!id) {
4063 return
4064 }
4065
4066 var section = find('#' + id);
4067 section && scrollTo(section);
4068
4069 var li = nav[getNavKey(path, id)];
4070 var sidebar = getNode('.sidebar');
4071 var active = find(sidebar, 'li.active');
4072 active && active.classList.remove('active');
4073 li && li.classList.add('active');
4074}
4075
4076var scrollEl = $.scrollingElement || $.documentElement;
4077
4078function scroll2Top(offset) {
4079 if ( offset === void 0 ) offset = 0;
4080
4081 scrollEl.scrollTop = offset === true ? 0 : Number(offset);
4082}
4083
4084var cached$1 = {};
4085
4086function walkFetchEmbed(ref, cb) {
4087 var embedTokens = ref.embedTokens;
4088 var compile = ref.compile;
4089 var fetch = ref.fetch;
4090
4091 var token;
4092 var step = 0;
4093 var count = 1;
4094
4095 if (!embedTokens.length) {
4096 return cb({})
4097 }
4098
4099 while ((token = embedTokens[step++])) {
4100 var next = (function (token) {
4101 return function (text) {
4102 var embedToken;
4103 if (text) {
4104 if (token.embed.type === 'markdown') {
4105 embedToken = compile.lexer(text);
4106 } else if (token.embed.type === 'code') {
4107 if (token.embed.fragment) {
4108 var fragment = token.embed.fragment;
4109 var pattern = new RegExp(("(?:###|\\/\\/\\/)\\s*\\[" + fragment + "\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[" + fragment + "\\]"));
4110 text = ((text.match(pattern) || [])[1] || '').trim();
4111 }
4112 embedToken = compile.lexer(
4113 '```' +
4114 token.embed.lang +
4115 '\n' +
4116 text.replace(/`/g, '@DOCSIFY_QM@') +
4117 '\n```\n'
4118 );
4119 } else if (token.embed.type === 'mermaid') {
4120 embedToken = [
4121 {type: 'html', text: ("<div class=\"mermaid\">\n" + text + "\n</div>")}
4122 ];
4123 embedToken.links = {};
4124 } else {
4125 embedToken = [{type: 'html', text: text}];
4126 embedToken.links = {};
4127 }
4128 }
4129 cb({token: token, embedToken: embedToken});
4130 if (++count >= step) {
4131 cb({});
4132 }
4133 }
4134 })(token);
4135
4136 if (token.embed.url) {
4137 {
4138 get(token.embed.url).then(next);
4139 }
4140 } else {
4141 next(token.embed.html);
4142 }
4143 }
4144}
4145
4146function prerenderEmbed(ref, done) {
4147 var compiler = ref.compiler;
4148 var raw = ref.raw; if ( raw === void 0 ) raw = '';
4149 var fetch = ref.fetch;
4150
4151 var hit = cached$1[raw];
4152 if (hit) {
4153 var copy = hit.slice();
4154 copy.links = hit.links;
4155 return done(copy)
4156 }
4157
4158 var compile = compiler._marked;
4159 var tokens = compile.lexer(raw);
4160 var embedTokens = [];
4161 var linkRE = compile.InlineLexer.rules.link;
4162 var links = tokens.links;
4163
4164 tokens.forEach(function (token, index) {
4165 if (token.type === 'paragraph') {
4166 token.text = token.text.replace(
4167 new RegExp(linkRE.source, 'g'),
4168 function (src, filename, href, title) {
4169 var embed = compiler.compileEmbed(href, title);
4170
4171 if (embed) {
4172 embedTokens.push({
4173 index: index,
4174 embed: embed
4175 });
4176 }
4177
4178 return src
4179 }
4180 );
4181 }
4182 });
4183
4184 var moveIndex = 0;
4185 walkFetchEmbed({compile: compile, embedTokens: embedTokens, fetch: fetch}, function (ref) {
4186 var embedToken = ref.embedToken;
4187 var token = ref.token;
4188
4189 if (token) {
4190 var index = token.index + moveIndex;
4191
4192 merge(links, embedToken.links);
4193
4194 tokens = tokens
4195 .slice(0, index)
4196 .concat(embedToken, tokens.slice(index + 1));
4197 moveIndex += embedToken.length - 1;
4198 } else {
4199 cached$1[raw] = tokens.concat();
4200 tokens.links = cached$1[raw].links = links;
4201 done(tokens);
4202 }
4203 });
4204}
4205
4206function executeScript() {
4207 var script = findAll('.markdown-section>script')
4208 .filter(function (s) { return !/template/.test(s.type); })[0];
4209 if (!script) {
4210 return false
4211 }
4212 var code = script.innerText.trim();
4213 if (!code) {
4214 return false
4215 }
4216
4217 setTimeout(function (_) {
4218 window.__EXECUTE_RESULT__ = new Function(code)();
4219 }, 0);
4220}
4221
4222function formatUpdated(html, updated, fn) {
4223 updated =
4224 typeof fn === 'function' ?
4225 fn(updated) :
4226 typeof fn === 'string' ?
4227 tinydate(fn)(new Date(updated)) :
4228 updated;
4229
4230 return html.replace(/{docsify-updated}/g, updated)
4231}
4232
4233function renderMain(html) {
4234 if (!html) {
4235 html = '<h1>404 - Not found</h1>';
4236 }
4237
4238 this._renderTo('.markdown-section', html);
4239 // Render sidebar with the TOC
4240 !this.config.loadSidebar && this._renderSidebar();
4241
4242 // Execute script
4243 if (
4244 this.config.executeScript !== false &&
4245 typeof window.Vue !== 'undefined' &&
4246 !executeScript()
4247 ) {
4248 setTimeout(function (_) {
4249 var vueVM = window.__EXECUTE_RESULT__;
4250 vueVM && vueVM.$destroy && vueVM.$destroy();
4251 window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main');
4252 }, 0);
4253 } else {
4254 this.config.executeScript && executeScript();
4255 }
4256}
4257
4258function renderNameLink(vm) {
4259 var el = getNode('.app-name-link');
4260 var nameLink = vm.config.nameLink;
4261 var path = vm.route.path;
4262
4263 if (!el) {
4264 return
4265 }
4266
4267 if (isPrimitive(vm.config.nameLink)) {
4268 el.setAttribute('href', nameLink);
4269 } else if (typeof nameLink === 'object') {
4270 var match = Object.keys(nameLink).filter(function (key) { return path.indexOf(key) > -1; })[0];
4271
4272 el.setAttribute('href', nameLink[match]);
4273 }
4274}
4275
4276function renderMixin(proto) {
4277 proto._renderTo = function (el, content, replace) {
4278 var node = getNode(el);
4279 if (node) {
4280 node[replace ? 'outerHTML' : 'innerHTML'] = content;
4281 }
4282 };
4283
4284 proto._renderSidebar = function (text) {
4285 var ref = this.config;
4286 var maxLevel = ref.maxLevel;
4287 var subMaxLevel = ref.subMaxLevel;
4288 var loadSidebar = ref.loadSidebar;
4289
4290 this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel));
4291 var activeEl = getAndActive(this.router, '.sidebar-nav', true, true);
4292 if (loadSidebar && activeEl) {
4293 activeEl.parentNode.innerHTML +=
4294 this.compiler.subSidebar(subMaxLevel) || '';
4295 } else {
4296 // Reset toc
4297 this.compiler.subSidebar();
4298 }
4299 // Bind event
4300 this._bindEventOnRendered(activeEl);
4301 };
4302
4303 proto._bindEventOnRendered = function (activeEl) {
4304 var ref = this.config;
4305 var autoHeader = ref.autoHeader;
4306 var auto2top = ref.auto2top;
4307
4308 scrollActiveSidebar(this.router);
4309
4310 if (autoHeader && activeEl) {
4311 var main$$1 = getNode('#main');
4312 var firstNode = main$$1.children[0];
4313 if (firstNode && firstNode.tagName !== 'H1') {
4314 var h1 = create('h1');
4315 h1.innerText = activeEl.innerText;
4316 before(main$$1, h1);
4317 }
4318 }
4319
4320 auto2top && scroll2Top(auto2top);
4321 };
4322
4323 proto._renderNav = function (text) {
4324 text && this._renderTo('nav', this.compiler.compile(text));
4325 if (this.config.loadNavbar) {
4326 getAndActive(this.router, 'nav');
4327 }
4328 };
4329
4330 proto._renderMain = function (text, opt, next) {
4331 var this$1 = this;
4332 if ( opt === void 0 ) opt = {};
4333
4334 if (!text) {
4335 return renderMain.call(this, text)
4336 }
4337
4338 callHook(this, 'beforeEach', text, function (result) {
4339 var html;
4340 var callback = function () {
4341 if (opt.updatedAt) {
4342 html = formatUpdated(html, opt.updatedAt, this$1.config.formatUpdated);
4343 }
4344
4345 callHook(this$1, 'afterEach', html, function (text) { return renderMain.call(this$1, text); });
4346 };
4347 if (this$1.isHTML) {
4348 html = this$1.result = text;
4349 callback();
4350 next();
4351 } else {
4352 prerenderEmbed(
4353 {
4354 compiler: this$1.compiler,
4355 raw: result
4356 },
4357 function (tokens) {
4358 html = this$1.compiler.compile(tokens);
4359 callback();
4360 next();
4361 }
4362 );
4363 }
4364 });
4365 };
4366
4367 proto._renderCover = function (text, coverOnly) {
4368 var el = getNode('.cover');
4369
4370 toggleClass(getNode('main'), coverOnly ? 'add' : 'remove', 'hidden');
4371 if (!text) {
4372 toggleClass(el, 'remove', 'show');
4373 return
4374 }
4375 toggleClass(el, 'add', 'show');
4376
4377 var html = this.coverIsHTML ? text : this.compiler.cover(text);
4378
4379 var m = html
4380 .trim()
4381 .match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$');
4382
4383 if (m) {
4384 if (m[2] === 'color') {
4385 el.style.background = m[1] + (m[3] || '');
4386 } else {
4387 var path = m[1];
4388
4389 toggleClass(el, 'add', 'has-mask');
4390 if (!isAbsolutePath(m[1])) {
4391 path = getPath(this.router.getBasePath(), m[1]);
4392 }
4393 el.style.backgroundImage = "url(" + path + ")";
4394 el.style.backgroundSize = 'cover';
4395 el.style.backgroundPosition = 'center center';
4396 }
4397 html = html.replace(m[0], '');
4398 }
4399
4400 this._renderTo('.cover-main', html);
4401 sticky();
4402 };
4403
4404 proto._updateRender = function () {
4405 // Render name link
4406 renderNameLink(this);
4407 };
4408}
4409
4410function initRender(vm) {
4411 var config = vm.config;
4412
4413 // Init markdown compiler
4414 vm.compiler = new Compiler(config, vm.router);
4415 if (inBrowser) {
4416 window.__current_docsify_compiler__ = vm.compiler;
4417 }
4418
4419 var id = config.el || '#app';
4420 var navEl = find('nav') || create('nav');
4421
4422 var el = find(id);
4423 var html = '';
4424 var navAppendToTarget = body;
4425
4426 if (el) {
4427 if (config.repo) {
4428 html += corner(config.repo);
4429 }
4430 if (config.coverpage) {
4431 html += cover();
4432 }
4433
4434 if (config.logo) {
4435 var isBase64 = /^data:image/.test(config.logo);
4436 var isExternal = /(?:http[s]?:)?\/\//.test(config.logo);
4437 var isRelative = /^\./.test(config.logo);
4438
4439 if (!isBase64 && !isExternal && !isRelative) {
4440 config.logo = getPath(vm.router.getBasePath(), config.logo);
4441 }
4442 }
4443
4444 html += main(config);
4445 // Render main app
4446 vm._renderTo(el, html, true);
4447 } else {
4448 vm.rendered = true;
4449 }
4450
4451 if (config.mergeNavbar && isMobile) {
4452 navAppendToTarget = find('.sidebar');
4453 } else {
4454 navEl.classList.add('app-nav');
4455
4456 if (!config.repo) {
4457 navEl.classList.add('no-badge');
4458 }
4459 }
4460
4461 // Add nav
4462 if (config.loadNavbar) {
4463 before(navAppendToTarget, navEl);
4464 }
4465
4466 if (config.themeColor) {
4467 $.head.appendChild(
4468 create('div', theme(config.themeColor)).firstElementChild
4469 );
4470 // Polyfll
4471 cssVars(config.themeColor);
4472 }
4473 vm._updateRender();
4474 toggleClass(body, 'ready');
4475}
4476
4477var cached$2 = {};
4478
4479function getAlias(path, alias, last) {
4480 var match = Object.keys(alias).filter(function (key) {
4481 var re = cached$2[key] || (cached$2[key] = new RegExp(("^" + key + "$")));
4482 return re.test(path) && path !== last
4483 })[0];
4484
4485 return match ?
4486 getAlias(path.replace(cached$2[match], alias[match]), alias, path) :
4487 path
4488}
4489
4490function getFileName(path, ext) {
4491 return new RegExp(("\\.(" + (ext.replace(/^\./, '')) + "|html)$"), 'g').test(path) ?
4492 path :
4493 /\/$/g.test(path) ? (path + "README" + ext) : ("" + path + ext)
4494}
4495
4496var History = function History(config) {
4497 this.config = config;
4498};
4499
4500History.prototype.getBasePath = function getBasePath () {
4501 return this.config.basePath
4502};
4503
4504History.prototype.getFile = function getFile (path, isRelative) {
4505 if ( path === void 0 ) path = this.getCurrentPath();
4506
4507 var ref = this;
4508 var config = ref.config;
4509 var base = this.getBasePath();
4510 var ext = typeof config.ext === 'string' ? config.ext : '.md';
4511
4512 path = config.alias ? getAlias(path, config.alias) : path;
4513 path = getFileName(path, ext);
4514 path = path === ("/README" + ext) ? config.homepage || path : path;
4515 path = isAbsolutePath(path) ? path : getPath(base, path);
4516
4517 if (isRelative) {
4518 path = path.replace(new RegExp(("^" + base)), '');
4519 }
4520
4521 return path
4522};
4523
4524History.prototype.onchange = function onchange (cb) {
4525 if ( cb === void 0 ) cb = noop;
4526
4527 cb();
4528};
4529
4530History.prototype.getCurrentPath = function getCurrentPath () {};
4531
4532History.prototype.normalize = function normalize () {};
4533
4534History.prototype.parse = function parse () {};
4535
4536History.prototype.toURL = function toURL (path, params, currentRoute) {
4537 var local = currentRoute && path[0] === '#';
4538 var route = this.parse(replaceSlug(path));
4539
4540 route.query = merge({}, route.query, params);
4541 path = route.path + stringifyQuery(route.query);
4542 path = path.replace(/\.md(\?)|\.md$/, '$1');
4543
4544 if (local) {
4545 var idIndex = currentRoute.indexOf('?');
4546 path =
4547 (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path;
4548 }
4549
4550 if (this.config.relativePath && path.indexOf('/') !== 0) {
4551 var currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1);
4552 return cleanPath(resolvePath(currentDir + path))
4553 }
4554 return cleanPath('/' + path)
4555};
4556
4557function replaceHash(path) {
4558 var i = location.href.indexOf('#');
4559 location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path);
4560}
4561
4562var HashHistory = (function (History$$1) {
4563 function HashHistory(config) {
4564 History$$1.call(this, config);
4565 this.mode = 'hash';
4566 }
4567
4568 if ( History$$1 ) HashHistory.__proto__ = History$$1;
4569 HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
4570 HashHistory.prototype.constructor = HashHistory;
4571
4572 HashHistory.prototype.getBasePath = function getBasePath () {
4573 var path = window.location.pathname || '';
4574 var base = this.config.basePath;
4575
4576 return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base)
4577 };
4578
4579 HashHistory.prototype.getCurrentPath = function getCurrentPath () {
4580 // We can't use location.hash here because it's not
4581 // consistent across browsers - Firefox will pre-decode it!
4582 var href = location.href;
4583 var index = href.indexOf('#');
4584 return index === -1 ? '' : href.slice(index + 1)
4585 };
4586
4587 HashHistory.prototype.onchange = function onchange (cb) {
4588 if ( cb === void 0 ) cb = noop;
4589
4590 on('hashchange', cb);
4591 };
4592
4593 HashHistory.prototype.normalize = function normalize () {
4594 var path = this.getCurrentPath();
4595
4596 path = replaceSlug(path);
4597
4598 if (path.charAt(0) === '/') {
4599 return replaceHash(path)
4600 }
4601 replaceHash('/' + path);
4602 };
4603
4604 /**
4605 * Parse the url
4606 * @param {string} [path=location.herf]
4607 * @return {object} { path, query }
4608 */
4609 HashHistory.prototype.parse = function parse (path) {
4610 if ( path === void 0 ) path = location.href;
4611
4612 var query = '';
4613
4614 var hashIndex = path.indexOf('#');
4615 if (hashIndex >= 0) {
4616 path = path.slice(hashIndex + 1);
4617 }
4618
4619 var queryIndex = path.indexOf('?');
4620 if (queryIndex >= 0) {
4621 query = path.slice(queryIndex + 1);
4622 path = path.slice(0, queryIndex);
4623 }
4624
4625 return {
4626 path: path,
4627 file: this.getFile(path, true),
4628 query: parseQuery(query)
4629 }
4630 };
4631
4632 HashHistory.prototype.toURL = function toURL (path, params, currentRoute) {
4633 return '#' + History$$1.prototype.toURL.call(this, path, params, currentRoute)
4634 };
4635
4636 return HashHistory;
4637}(History));
4638
4639var HTML5History = (function (History$$1) {
4640 function HTML5History(config) {
4641 History$$1.call(this, config);
4642 this.mode = 'history';
4643 }
4644
4645 if ( History$$1 ) HTML5History.__proto__ = History$$1;
4646 HTML5History.prototype = Object.create( History$$1 && History$$1.prototype );
4647 HTML5History.prototype.constructor = HTML5History;
4648
4649 HTML5History.prototype.getCurrentPath = function getCurrentPath () {
4650 var base = this.getBasePath();
4651 var path = window.location.pathname;
4652
4653 if (base && path.indexOf(base) === 0) {
4654 path = path.slice(base.length);
4655 }
4656
4657 return (path || '/') + window.location.search + window.location.hash
4658 };
4659
4660 HTML5History.prototype.onchange = function onchange (cb) {
4661 if ( cb === void 0 ) cb = noop;
4662
4663 on('click', function (e) {
4664 var el = e.target.tagName === 'A' ? e.target : e.target.parentNode;
4665
4666 if (el.tagName === 'A' && !/_blank/.test(el.target)) {
4667 e.preventDefault();
4668 var url = el.href;
4669 window.history.pushState({key: url}, '', url);
4670 cb();
4671 }
4672 });
4673
4674 on('popstate', cb);
4675 };
4676
4677 /**
4678 * Parse the url
4679 * @param {string} [path=location.href]
4680 * @return {object} { path, query }
4681 */
4682 HTML5History.prototype.parse = function parse (path) {
4683 if ( path === void 0 ) path = location.href;
4684
4685 var query = '';
4686
4687 var queryIndex = path.indexOf('?');
4688 if (queryIndex >= 0) {
4689 query = path.slice(queryIndex + 1);
4690 path = path.slice(0, queryIndex);
4691 }
4692
4693 var base = getPath(location.origin);
4694 var baseIndex = path.indexOf(base);
4695
4696 if (baseIndex > -1) {
4697 path = path.slice(baseIndex + base.length);
4698 }
4699
4700 return {
4701 path: path,
4702 file: this.getFile(path),
4703 query: parseQuery(query)
4704 }
4705 };
4706
4707 return HTML5History;
4708}(History));
4709
4710function routerMixin(proto) {
4711 proto.route = {};
4712}
4713
4714var lastRoute = {};
4715
4716function updateRender(vm) {
4717 vm.router.normalize();
4718 vm.route = vm.router.parse();
4719 body.setAttribute('data-page', vm.route.file);
4720}
4721
4722function initRouter(vm) {
4723 var config = vm.config;
4724 var mode = config.routerMode || 'hash';
4725 var router;
4726
4727 if (mode === 'history' && supportsPushState) {
4728 router = new HTML5History(config);
4729 } else {
4730 router = new HashHistory(config);
4731 }
4732
4733 vm.router = router;
4734 updateRender(vm);
4735 lastRoute = vm.route;
4736
4737 router.onchange(function (_) {
4738 updateRender(vm);
4739 vm._updateRender();
4740
4741 if (lastRoute.path === vm.route.path) {
4742 vm.$resetEvents();
4743 return
4744 }
4745
4746 vm.$fetch();
4747 lastRoute = vm.route;
4748 });
4749}
4750
4751function eventMixin(proto) {
4752 proto.$resetEvents = function () {
4753 scrollIntoView(this.route.path, this.route.query.id);
4754
4755 if (this.config.loadNavbar) {
4756 getAndActive(this.router, 'nav');
4757 }
4758 };
4759}
4760
4761function initEvent(vm) {
4762 // Bind toggle button
4763 btn('button.sidebar-toggle', vm.router);
4764 collapse('.sidebar', vm.router);
4765 // Bind sticky effect
4766 if (vm.config.coverpage) {
4767 !isMobile && on('scroll', sticky);
4768 } else {
4769 body.classList.add('sticky');
4770 }
4771}
4772
4773function loadNested(path, qs, file, next, vm, first) {
4774 path = first ? path : path.replace(/\/$/, '');
4775 path = getParentPath(path);
4776
4777 if (!path) {
4778 return
4779 }
4780
4781 get(
4782 vm.router.getFile(path + file) + qs,
4783 false,
4784 vm.config.requestHeaders
4785 ).then(next, function (_) { return loadNested(path, qs, file, next, vm); });
4786}
4787
4788function fetchMixin(proto) {
4789 var last;
4790
4791 var abort = function () { return last && last.abort && last.abort(); };
4792 var request = function (url, hasbar, requestHeaders) {
4793 abort();
4794 last = get(url, true, requestHeaders);
4795 return last
4796 };
4797
4798 var get404Path = function (path, config) {
4799 var notFoundPage = config.notFoundPage;
4800 var ext = config.ext;
4801 var defaultPath = '_404' + (ext || '.md');
4802 var key;
4803 var path404;
4804
4805 switch (typeof notFoundPage) {
4806 case 'boolean':
4807 path404 = defaultPath;
4808 break
4809 case 'string':
4810 path404 = notFoundPage;
4811 break
4812
4813 case 'object':
4814 key = Object.keys(notFoundPage)
4815 .sort(function (a, b) { return b.length - a.length; })
4816 .find(function (key) { return path.match(new RegExp('^' + key)); });
4817
4818 path404 = (key && notFoundPage[key]) || defaultPath;
4819 break
4820
4821 default:
4822 break
4823 }
4824
4825 return path404
4826 };
4827
4828 proto._loadSideAndNav = function (path, qs, loadSidebar, cb) {
4829 var this$1 = this;
4830
4831 return function () {
4832 if (!loadSidebar) {
4833 return cb()
4834 }
4835
4836 var fn = function (result) {
4837 this$1._renderSidebar(result);
4838 cb();
4839 };
4840
4841 // Load sidebar
4842 loadNested(path, qs, loadSidebar, fn, this$1, true);
4843 }
4844 };
4845
4846 proto._fetch = function (cb) {
4847 var this$1 = this;
4848 if ( cb === void 0 ) cb = noop;
4849
4850 var ref = this.route;
4851 var path = ref.path;
4852 var query = ref.query;
4853 var qs = stringifyQuery(query, ['id']);
4854 var ref$1 = this.config;
4855 var loadNavbar = ref$1.loadNavbar;
4856 var requestHeaders = ref$1.requestHeaders;
4857 var loadSidebar = ref$1.loadSidebar;
4858 // Abort last request
4859
4860 var file = this.router.getFile(path);
4861 var req = request(file + qs, true, requestHeaders);
4862
4863 // Current page is html
4864 this.isHTML = /\.html$/g.test(file);
4865
4866 // Load main content
4867 req.then(
4868 function (text, opt) { return this$1._renderMain(
4869 text,
4870 opt,
4871 this$1._loadSideAndNav(path, qs, loadSidebar, cb)
4872 ); },
4873 function (_) {
4874 this$1._fetchFallbackPage(file, qs, cb) || this$1._fetch404(file, qs, cb);
4875 }
4876 );
4877
4878 // Load nav
4879 loadNavbar &&
4880 loadNested(
4881 path,
4882 qs,
4883 loadNavbar,
4884 function (text) { return this$1._renderNav(text); },
4885 this,
4886 true
4887 );
4888 };
4889
4890 proto._fetchCover = function () {
4891 var this$1 = this;
4892
4893 var ref = this.config;
4894 var coverpage = ref.coverpage;
4895 var requestHeaders = ref.requestHeaders;
4896 var query = this.route.query;
4897 var root = getParentPath(this.route.path);
4898
4899 if (coverpage) {
4900 var path = null;
4901 var routePath = this.route.path;
4902 if (typeof coverpage === 'string') {
4903 if (routePath === '/') {
4904 path = coverpage;
4905 }
4906 } else if (Array.isArray(coverpage)) {
4907 path = coverpage.indexOf(routePath) > -1 && '_coverpage';
4908 } else {
4909 var cover = coverpage[routePath];
4910 path = cover === true ? '_coverpage' : cover;
4911 }
4912
4913 var coverOnly = Boolean(path) && this.config.onlyCover;
4914 if (path) {
4915 path = this.router.getFile(root + path);
4916 this.coverIsHTML = /\.html$/g.test(path);
4917 get(path + stringifyQuery(query, ['id']), false, requestHeaders).then(
4918 function (text) { return this$1._renderCover(text, coverOnly); }
4919 );
4920 } else {
4921 this._renderCover(null, coverOnly);
4922 }
4923 return coverOnly
4924 }
4925 };
4926
4927 proto.$fetch = function (cb) {
4928 var this$1 = this;
4929 if ( cb === void 0 ) cb = noop;
4930
4931 var done = function () {
4932 callHook(this$1, 'doneEach');
4933 cb();
4934 };
4935
4936 var onlyCover = this._fetchCover();
4937
4938 if (onlyCover) {
4939 done();
4940 } else {
4941 this._fetch(function () {
4942 this$1.$resetEvents();
4943 done();
4944 });
4945 }
4946 };
4947
4948 proto._fetchFallbackPage = function (path, qs, cb) {
4949 var this$1 = this;
4950 if ( cb === void 0 ) cb = noop;
4951
4952 var ref = this.config;
4953 var requestHeaders = ref.requestHeaders;
4954 var fallbackLanguages = ref.fallbackLanguages;
4955 var loadSidebar = ref.loadSidebar;
4956
4957 if (!fallbackLanguages) {
4958 return false
4959 }
4960
4961 var local = path.split('/')[1];
4962
4963 if (fallbackLanguages.indexOf(local) === -1) {
4964 return false
4965 }
4966 var newPath = path.replace(new RegExp(("^/" + local)), '');
4967 var req = request(newPath + qs, true, requestHeaders);
4968
4969 req.then(
4970 function (text, opt) { return this$1._renderMain(
4971 text,
4972 opt,
4973 this$1._loadSideAndNav(path, qs, loadSidebar, cb)
4974 ); },
4975 function () { return this$1._fetch404(path, qs, cb); }
4976 );
4977
4978 return true
4979 };
4980 /**
4981 * Load the 404 page
4982 * @param path
4983 * @param qs
4984 * @param cb
4985 * @returns {*}
4986 * @private
4987 */
4988 proto._fetch404 = function (path, qs, cb) {
4989 var this$1 = this;
4990 if ( cb === void 0 ) cb = noop;
4991
4992 var ref = this.config;
4993 var loadSidebar = ref.loadSidebar;
4994 var requestHeaders = ref.requestHeaders;
4995 var notFoundPage = ref.notFoundPage;
4996
4997 var fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb);
4998 if (notFoundPage) {
4999 var path404 = get404Path(path, this.config);
5000
5001 request(this.router.getFile(path404), true, requestHeaders).then(
5002 function (text, opt) { return this$1._renderMain(text, opt, fnLoadSideAndNav); },
5003 function () { return this$1._renderMain(null, {}, fnLoadSideAndNav); }
5004 );
5005 return true
5006 }
5007
5008 this._renderMain(null, {}, fnLoadSideAndNav);
5009 return false
5010 };
5011}
5012
5013function initFetch(vm) {
5014 var ref = vm.config;
5015 var loadSidebar = ref.loadSidebar;
5016
5017 // Server-Side Rendering
5018 if (vm.rendered) {
5019 var activeEl = getAndActive(vm.router, '.sidebar-nav', true, true);
5020 if (loadSidebar && activeEl) {
5021 activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__;
5022 }
5023 vm._bindEventOnRendered(activeEl);
5024 vm.$resetEvents();
5025 callHook(vm, 'doneEach');
5026 callHook(vm, 'ready');
5027 } else {
5028 vm.$fetch(function (_) { return callHook(vm, 'ready'); });
5029 }
5030}
5031
5032function initMixin(proto) {
5033 proto._init = function () {
5034 var vm = this;
5035 vm.config = config();
5036
5037 initLifecycle(vm); // Init hooks
5038 initPlugin(vm); // Install plugins
5039 callHook(vm, 'init');
5040 initRouter(vm); // Add router
5041 initRender(vm); // Render base DOM
5042 initEvent(vm); // Bind events
5043 initFetch(vm); // Fetch data
5044 callHook(vm, 'mounted');
5045 };
5046}
5047
5048function initPlugin(vm) {
5049 [].concat(vm.config.plugins).forEach(function (fn) { return isFn(fn) && fn(vm._lifecycle, vm); });
5050}
5051
5052
5053
5054var util = Object.freeze({
5055 cached: cached,
5056 hyphenate: hyphenate,
5057 hasOwn: hasOwn,
5058 merge: merge,
5059 isPrimitive: isPrimitive,
5060 noop: noop,
5061 isFn: isFn,
5062 inBrowser: inBrowser,
5063 isMobile: isMobile,
5064 supportsPushState: supportsPushState,
5065 parseQuery: parseQuery,
5066 stringifyQuery: stringifyQuery,
5067 isAbsolutePath: isAbsolutePath,
5068 getParentPath: getParentPath,
5069 cleanPath: cleanPath,
5070 resolvePath: resolvePath,
5071 getPath: getPath,
5072 replaceSlug: replaceSlug
5073});
5074
5075function initGlobalAPI () {
5076 window.Docsify = {
5077 util: util,
5078 dom: dom,
5079 get: get,
5080 slugify: slugify,
5081 version: '4.9.4'
5082 };
5083 window.DocsifyCompiler = Compiler;
5084 window.marked = marked;
5085 window.Prism = prism;
5086}
5087
5088/**
5089 * Fork https://github.com/bendrucker/document-ready/blob/master/index.js
5090 */
5091function ready(callback) {
5092 var state = document.readyState;
5093
5094 if (state === 'complete' || state === 'interactive') {
5095 return setTimeout(callback, 0)
5096 }
5097
5098 document.addEventListener('DOMContentLoaded', callback);
5099}
5100
5101function Docsify() {
5102 this._init();
5103}
5104
5105var proto = Docsify.prototype;
5106
5107initMixin(proto);
5108routerMixin(proto);
5109renderMixin(proto);
5110fetchMixin(proto);
5111eventMixin(proto);
5112
5113/**
5114 * Global API
5115 */
5116initGlobalAPI();
5117
5118/**
5119 * Run Docsify
5120 */
5121ready(function (_) { return new Docsify(); });
5122
5123}());