PluginProbe
Gutenberg / 15.1.1
Gutenberg v15.1.1
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / blocks / index.js

index.js in Gutenberg 15.1.1, at build/blocks/index.js

15,200 lines 516.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (function() { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ 5619:
5 /***/ (function(module) {
6
7 "use strict";
8
9
10 // do not edit .js files directly - edit src/index.jst
11
12
13 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined';
14
15
16 module.exports = function equal(a, b) {
17 if (a === b) return true;
18
19 if (a && b && typeof a == 'object' && typeof b == 'object') {
20 if (a.constructor !== b.constructor) return false;
21
22 var length, i, keys;
23 if (Array.isArray(a)) {
24 length = a.length;
25 if (length != b.length) return false;
26 for (i = length; i-- !== 0;)
27 if (!equal(a[i], b[i])) return false;
28 return true;
29 }
30
31
32 if ((a instanceof Map) && (b instanceof Map)) {
33 if (a.size !== b.size) return false;
34 for (i of a.entries())
35 if (!b.has(i[0])) return false;
36 for (i of a.entries())
37 if (!equal(i[1], b.get(i[0]))) return false;
38 return true;
39 }
40
41 if ((a instanceof Set) && (b instanceof Set)) {
42 if (a.size !== b.size) return false;
43 for (i of a.entries())
44 if (!b.has(i[0])) return false;
45 return true;
46 }
47
48 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
49 length = a.length;
50 if (length != b.length) return false;
51 for (i = length; i-- !== 0;)
52 if (a[i] !== b[i]) return false;
53 return true;
54 }
55
56
57 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
58 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
59 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
60
61 keys = Object.keys(a);
62 length = keys.length;
63 if (length !== Object.keys(b).length) return false;
64
65 for (i = length; i-- !== 0;)
66 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
67
68 for (i = length; i-- !== 0;) {
69 var key = keys[i];
70
71 if (!equal(a[key], b[key])) return false;
72 }
73
74 return true;
75 }
76
77 // true if both NaN, false otherwise
78 return a!==a && b!==b;
79 };
80
81
82 /***/ }),
83
84 /***/ 9756:
85 /***/ (function(module) {
86
87 /**
88 * Memize options object.
89 *
90 * @typedef MemizeOptions
91 *
92 * @property {number} [maxSize] Maximum size of the cache.
93 */
94
95 /**
96 * Internal cache entry.
97 *
98 * @typedef MemizeCacheNode
99 *
100 * @property {?MemizeCacheNode|undefined} [prev] Previous node.
101 * @property {?MemizeCacheNode|undefined} [next] Next node.
102 * @property {Array<*>} args Function arguments for cache
103 * entry.
104 * @property {*} val Function result.
105 */
106
107 /**
108 * Properties of the enhanced function for controlling cache.
109 *
110 * @typedef MemizeMemoizedFunction
111 *
112 * @property {()=>void} clear Clear the cache.
113 */
114
115 /**
116 * Accepts a function to be memoized, and returns a new memoized function, with
117 * optional options.
118 *
119 * @template {Function} F
120 *
121 * @param {F} fn Function to memoize.
122 * @param {MemizeOptions} [options] Options object.
123 *
124 * @return {F & MemizeMemoizedFunction} Memoized function.
125 */
126 function memize( fn, options ) {
127 var size = 0;
128
129 /** @type {?MemizeCacheNode|undefined} */
130 var head;
131
132 /** @type {?MemizeCacheNode|undefined} */
133 var tail;
134
135 options = options || {};
136
137 function memoized( /* ...args */ ) {
138 var node = head,
139 len = arguments.length,
140 args, i;
141
142 searchCache: while ( node ) {
143 // Perform a shallow equality test to confirm that whether the node
144 // under test is a candidate for the arguments passed. Two arrays
145 // are shallowly equal if their length matches and each entry is
146 // strictly equal between the two sets. Avoid abstracting to a
147 // function which could incur an arguments leaking deoptimization.
148
149 // Check whether node arguments match arguments length
150 if ( node.args.length !== arguments.length ) {
151 node = node.next;
152 continue;
153 }
154
155 // Check whether node arguments match arguments values
156 for ( i = 0; i < len; i++ ) {
157 if ( node.args[ i ] !== arguments[ i ] ) {
158 node = node.next;
159 continue searchCache;
160 }
161 }
162
163 // At this point we can assume we've found a match
164
165 // Surface matched node to head if not already
166 if ( node !== head ) {
167 // As tail, shift to previous. Must only shift if not also
168 // head, since if both head and tail, there is no previous.
169 if ( node === tail ) {
170 tail = node.prev;
171 }
172
173 // Adjust siblings to point to each other. If node was tail,
174 // this also handles new tail's empty `next` assignment.
175 /** @type {MemizeCacheNode} */ ( node.prev ).next = node.next;
176 if ( node.next ) {
177 node.next.prev = node.prev;
178 }
179
180 node.next = head;
181 node.prev = null;
182 /** @type {MemizeCacheNode} */ ( head ).prev = node;
183 head = node;
184 }
185
186 // Return immediately
187 return node.val;
188 }
189
190 // No cached value found. Continue to insertion phase:
191
192 // Create a copy of arguments (avoid leaking deoptimization)
193 args = new Array( len );
194 for ( i = 0; i < len; i++ ) {
195 args[ i ] = arguments[ i ];
196 }
197
198 node = {
199 args: args,
200
201 // Generate the result from original function
202 val: fn.apply( null, args ),
203 };
204
205 // Don't need to check whether node is already head, since it would
206 // have been returned above already if it was
207
208 // Shift existing head down list
209 if ( head ) {
210 head.prev = node;
211 node.next = head;
212 } else {
213 // If no head, follows that there's no tail (at initial or reset)
214 tail = node;
215 }
216
217 // Trim tail if we're reached max size and are pending cache insertion
218 if ( size === /** @type {MemizeOptions} */ ( options ).maxSize ) {
219 tail = /** @type {MemizeCacheNode} */ ( tail ).prev;
220 /** @type {MemizeCacheNode} */ ( tail ).next = null;
221 } else {
222 size++;
223 }
224
225 head = node;
226
227 return node.val;
228 }
229
230 memoized.clear = function() {
231 head = null;
232 tail = null;
233 size = 0;
234 };
235
236 if ( false ) {}
237
238 // Ignore reason: There's not a clear solution to create an intersection of
239 // the function with additional properties, where the goal is to retain the
240 // function signature of the incoming argument and add control properties
241 // on the return value.
242
243 // @ts-ignore
244 return memoized;
245 }
246
247 module.exports = memize;
248
249
250 /***/ }),
251
252 /***/ 4793:
253 /***/ (function(module) {
254
255 var characterMap = {
256 "À": "A",
257 "Á": "A",
258 "Â": "A",
259 "Ã": "A",
260 "Ä": "A",
261 "Å": "A",
262 "Ấ": "A",
263 "Ắ": "A",
264 "Ẳ": "A",
265 "Ẵ": "A",
266 "Ặ": "A",
267 "Æ": "AE",
268 "Ầ": "A",
269 "Ằ": "A",
270 "Ȃ": "A",
271 "Ç": "C",
272 "Ḉ": "C",
273 "È": "E",
274 "É": "E",
275 "Ê": "E",
276 "Ë": "E",
277 "Ế": "E",
278 "Ḗ": "E",
279 "Ề": "E",
280 "Ḕ": "E",
281 "Ḝ": "E",
282 "Ȇ": "E",
283 "Ì": "I",
284 "Í": "I",
285 "Î": "I",
286 "Ï": "I",
287 "Ḯ": "I",
288 "Ȋ": "I",
289 "Ð": "D",
290 "Ñ": "N",
291 "Ò": "O",
292 "Ó": "O",
293 "Ô": "O",
294 "Õ": "O",
295 "Ö": "O",
296 "Ø": "O",
297 "Ố": "O",
298 "Ṍ": "O",
299 "Ṓ": "O",
300 "Ȏ": "O",
301 "Ù": "U",
302 "Ú": "U",
303 "Û": "U",
304 "Ü": "U",
305 "Ý": "Y",
306 "à": "a",
307 "á": "a",
308 "â": "a",
309 "ã": "a",
310 "ä": "a",
311 "å": "a",
312 "ấ": "a",
313 "ắ": "a",
314 "ẳ": "a",
315 "ẵ": "a",
316 "ặ": "a",
317 "æ": "ae",
318 "ầ": "a",
319 "ằ": "a",
320 "ȃ": "a",
321 "ç": "c",
322 "ḉ": "c",
323 "è": "e",
324 "é": "e",
325 "ê": "e",
326 "ë": "e",
327 "ế": "e",
328 "ḗ": "e",
329 "ề": "e",
330 "ḕ": "e",
331 "ḝ": "e",
332 "ȇ": "e",
333 "ì": "i",
334 "í": "i",
335 "î": "i",
336 "ï": "i",
337 "ḯ": "i",
338 "ȋ": "i",
339 "ð": "d",
340 "ñ": "n",
341 "ò": "o",
342 "ó": "o",
343 "ô": "o",
344 "õ": "o",
345 "ö": "o",
346 "ø": "o",
347 "ố": "o",
348 "ṍ": "o",
349 "ṓ": "o",
350 "ȏ": "o",
351 "ù": "u",
352 "ú": "u",
353 "û": "u",
354 "ü": "u",
355 "ý": "y",
356 "ÿ": "y",
357 "Ā": "A",
358 "ā": "a",
359 "Ă": "A",
360 "ă": "a",
361 "Ą": "A",
362 "ą": "a",
363 "Ć": "C",
364 "ć": "c",
365 "Ĉ": "C",
366 "ĉ": "c",
367 "Ċ": "C",
368 "ċ": "c",
369 "Č": "C",
370 "č": "c",
371 "C̆": "C",
372 "c̆": "c",
373 "Ď": "D",
374 "ď": "d",
375 "Đ": "D",
376 "đ": "d",
377 "Ē": "E",
378 "ē": "e",
379 "Ĕ": "E",
380 "ĕ": "e",
381 "Ė": "E",
382 "ė": "e",
383 "Ę": "E",
384 "ę": "e",
385 "Ě": "E",
386 "ě": "e",
387 "Ĝ": "G",
388 "Ǵ": "G",
389 "ĝ": "g",
390 "ǵ": "g",
391 "Ğ": "G",
392 "ğ": "g",
393 "Ġ": "G",
394 "ġ": "g",
395 "Ģ": "G",
396 "ģ": "g",
397 "Ĥ": "H",
398 "ĥ": "h",
399 "Ħ": "H",
400 "ħ": "h",
401 "Ḫ": "H",
402 "ḫ": "h",
403 "Ĩ": "I",
404 "ĩ": "i",
405 "Ī": "I",
406 "ī": "i",
407 "Ĭ": "I",
408 "ĭ": "i",
409 "Į": "I",
410 "į": "i",
411 "İ": "I",
412 "ı": "i",
413 "IJ": "IJ",
414 "ij": "ij",
415 "Ĵ": "J",
416 "ĵ": "j",
417 "Ķ": "K",
418 "ķ": "k",
419 "Ḱ": "K",
420 "ḱ": "k",
421 "K̆": "K",
422 "k̆": "k",
423 "Ĺ": "L",
424 "ĺ": "l",
425 "Ļ": "L",
426 "ļ": "l",
427 "Ľ": "L",
428 "ľ": "l",
429 "Ŀ": "L",
430 "ŀ": "l",
431 "Ł": "l",
432 "ł": "l",
433 "Ḿ": "M",
434 "ḿ": "m",
435 "M̆": "M",
436 "m̆": "m",
437 "Ń": "N",
438 "ń": "n",
439 "Ņ": "N",
440 "ņ": "n",
441 "Ň": "N",
442 "ň": "n",
443 "ʼn": "n",
444 "N̆": "N",
445 "n̆": "n",
446 "Ō": "O",
447 "ō": "o",
448 "Ŏ": "O",
449 "ŏ": "o",
450 "Ő": "O",
451 "ő": "o",
452 "Œ": "OE",
453 "œ": "oe",
454 "P̆": "P",
455 "p̆": "p",
456 "Ŕ": "R",
457 "ŕ": "r",
458 "Ŗ": "R",
459 "ŗ": "r",
460 "Ř": "R",
461 "ř": "r",
462 "R̆": "R",
463 "r̆": "r",
464 "Ȓ": "R",
465 "ȓ": "r",
466 "Ś": "S",
467 "ś": "s",
468 "Ŝ": "S",
469 "ŝ": "s",
470 "Ş": "S",
471 "Ș": "S",
472 "ș": "s",
473 "ş": "s",
474 "Š": "S",
475 "š": "s",
476 "Ţ": "T",
477 "ţ": "t",
478 "ț": "t",
479 "Ț": "T",
480 "Ť": "T",
481 "ť": "t",
482 "Ŧ": "T",
483 "ŧ": "t",
484 "T̆": "T",
485 "t̆": "t",
486 "Ũ": "U",
487 "ũ": "u",
488 "Ū": "U",
489 "ū": "u",
490 "Ŭ": "U",
491 "ŭ": "u",
492 "Ů": "U",
493 "ů": "u",
494 "Ű": "U",
495 "ű": "u",
496 "Ų": "U",
497 "ų": "u",
498 "Ȗ": "U",
499 "ȗ": "u",
500 "V̆": "V",
501 "v̆": "v",
502 "Ŵ": "W",
503 "ŵ": "w",
504 "Ẃ": "W",
505 "ẃ": "w",
506 "X̆": "X",
507 "x̆": "x",
508 "Ŷ": "Y",
509 "ŷ": "y",
510 "Ÿ": "Y",
511 "Y̆": "Y",
512 "y̆": "y",
513 "Ź": "Z",
514 "ź": "z",
515 "Ż": "Z",
516 "ż": "z",
517 "Ž": "Z",
518 "ž": "z",
519 "ſ": "s",
520 "ƒ": "f",
521 "Ơ": "O",
522 "ơ": "o",
523 "Ư": "U",
524 "ư": "u",
525 "Ǎ": "A",
526 "ǎ": "a",
527 "Ǐ": "I",
528 "ǐ": "i",
529 "Ǒ": "O",
530 "ǒ": "o",
531 "Ǔ": "U",
532 "ǔ": "u",
533 "Ǖ": "U",
534 "ǖ": "u",
535 "Ǘ": "U",
536 "ǘ": "u",
537 "Ǚ": "U",
538 "ǚ": "u",
539 "Ǜ": "U",
540 "ǜ": "u",
541 "Ứ": "U",
542 "ứ": "u",
543 "Ṹ": "U",
544 "ṹ": "u",
545 "Ǻ": "A",
546 "ǻ": "a",
547 "Ǽ": "AE",
548 "ǽ": "ae",
549 "Ǿ": "O",
550 "ǿ": "o",
551 "Þ": "TH",
552 "þ": "th",
553 "Ṕ": "P",
554 "ṕ": "p",
555 "Ṥ": "S",
556 "ṥ": "s",
557 "X́": "X",
558 "x́": "x",
559 "Ѓ": "Г",
560 "ѓ": "г",
561 "Ќ": "К",
562 "ќ": "к",
563 "A̋": "A",
564 "a̋": "a",
565 "E̋": "E",
566 "e̋": "e",
567 "I̋": "I",
568 "i̋": "i",
569 "Ǹ": "N",
570 "ǹ": "n",
571 "Ồ": "O",
572 "ồ": "o",
573 "Ṑ": "O",
574 "ṑ": "o",
575 "Ừ": "U",
576 "ừ": "u",
577 "Ẁ": "W",
578 "ẁ": "w",
579 "Ỳ": "Y",
580 "ỳ": "y",
581 "Ȁ": "A",
582 "ȁ": "a",
583 "Ȅ": "E",
584 "ȅ": "e",
585 "Ȉ": "I",
586 "ȉ": "i",
587 "Ȍ": "O",
588 "ȍ": "o",
589 "Ȑ": "R",
590 "ȑ": "r",
591 "Ȕ": "U",
592 "ȕ": "u",
593 "B̌": "B",
594 "b̌": "b",
595 "Č̣": "C",
596 "č̣": "c",
597 "Ê̌": "E",
598 "ê̌": "e",
599 "F̌": "F",
600 "f̌": "f",
601 "Ǧ": "G",
602 "ǧ": "g",
603 "Ȟ": "H",
604 "ȟ": "h",
605 "J̌": "J",
606 "ǰ": "j",
607 "Ǩ": "K",
608 "ǩ": "k",
609 "M̌": "M",
610 "m̌": "m",
611 "P̌": "P",
612 "p̌": "p",
613 "Q̌": "Q",
614 "q̌": "q",
615 "Ř̩": "R",
616 "ř̩": "r",
617 "Ṧ": "S",
618 "ṧ": "s",
619 "V̌": "V",
620 "v̌": "v",
621 "W̌": "W",
622 "w̌": "w",
623 "X̌": "X",
624 "x̌": "x",
625 "Y̌": "Y",
626 "y̌": "y",
627 "A̧": "A",
628 "a̧": "a",
629 "B̧": "B",
630 "b̧": "b",
631 "Ḑ": "D",
632 "ḑ": "d",
633 "Ȩ": "E",
634 "ȩ": "e",
635 "Ɛ̧": "E",
636 "ɛ̧": "e",
637 "Ḩ": "H",
638 "ḩ": "h",
639 "I̧": "I",
640 "i̧": "i",
641 "Ɨ̧": "I",
642 "ɨ̧": "i",
643 "M̧": "M",
644 "m̧": "m",
645 "O̧": "O",
646 "o̧": "o",
647 "Q̧": "Q",
648 "q̧": "q",
649 "U̧": "U",
650 "u̧": "u",
651 "X̧": "X",
652 "x̧": "x",
653 "Z̧": "Z",
654 "z̧": "z",
655 };
656
657 var chars = Object.keys(characterMap).join('|');
658 var allAccents = new RegExp(chars, 'g');
659 var firstAccent = new RegExp(chars, '');
660
661 var removeAccents = function(string) {
662 return string.replace(allAccents, function(match) {
663 return characterMap[match];
664 });
665 };
666
667 var hasAccents = function(string) {
668 return !!string.match(firstAccent);
669 };
670
671 module.exports = removeAccents;
672 module.exports.has = hasAccents;
673 module.exports.remove = removeAccents;
674
675
676 /***/ }),
677
678 /***/ 7308:
679 /***/ (function(module, exports, __webpack_require__) {
680
681 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */
682 (function(){
683 /**
684 * Created by Tivie on 13-07-2015.
685 */
686
687 function getDefaultOpts (simple) {
688 'use strict';
689
690 var defaultOptions = {
691 omitExtraWLInCodeBlocks: {
692 defaultValue: false,
693 describe: 'Omit the default extra whiteline added to code blocks',
694 type: 'boolean'
695 },
696 noHeaderId: {
697 defaultValue: false,
698 describe: 'Turn on/off generated header id',
699 type: 'boolean'
700 },
701 prefixHeaderId: {
702 defaultValue: false,
703 describe: 'Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic \'section-\' prefix',
704 type: 'string'
705 },
706 rawPrefixHeaderId: {
707 defaultValue: false,
708 describe: 'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',
709 type: 'boolean'
710 },
711 ghCompatibleHeaderId: {
712 defaultValue: false,
713 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)',
714 type: 'boolean'
715 },
716 rawHeaderId: {
717 defaultValue: false,
718 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids',
719 type: 'boolean'
720 },
721 headerLevelStart: {
722 defaultValue: false,
723 describe: 'The header blocks level start',
724 type: 'integer'
725 },
726 parseImgDimensions: {
727 defaultValue: false,
728 describe: 'Turn on/off image dimension parsing',
729 type: 'boolean'
730 },
731 simplifiedAutoLink: {
732 defaultValue: false,
733 describe: 'Turn on/off GFM autolink style',
734 type: 'boolean'
735 },
736 excludeTrailingPunctuationFromURLs: {
737 defaultValue: false,
738 describe: 'Excludes trailing punctuation from links generated with autoLinking',
739 type: 'boolean'
740 },
741 literalMidWordUnderscores: {
742 defaultValue: false,
743 describe: 'Parse midword underscores as literal underscores',
744 type: 'boolean'
745 },
746 literalMidWordAsterisks: {
747 defaultValue: false,
748 describe: 'Parse midword asterisks as literal asterisks',
749 type: 'boolean'
750 },
751 strikethrough: {
752 defaultValue: false,
753 describe: 'Turn on/off strikethrough support',
754 type: 'boolean'
755 },
756 tables: {
757 defaultValue: false,
758 describe: 'Turn on/off tables support',
759 type: 'boolean'
760 },
761 tablesHeaderId: {
762 defaultValue: false,
763 describe: 'Add an id to table headers',
764 type: 'boolean'
765 },
766 ghCodeBlocks: {
767 defaultValue: true,
768 describe: 'Turn on/off GFM fenced code blocks support',
769 type: 'boolean'
770 },
771 tasklists: {
772 defaultValue: false,
773 describe: 'Turn on/off GFM tasklist support',
774 type: 'boolean'
775 },
776 smoothLivePreview: {
777 defaultValue: false,
778 describe: 'Prevents weird effects in live previews due to incomplete input',
779 type: 'boolean'
780 },
781 smartIndentationFix: {
782 defaultValue: false,
783 description: 'Tries to smartly fix indentation in es6 strings',
784 type: 'boolean'
785 },
786 disableForced4SpacesIndentedSublists: {
787 defaultValue: false,
788 description: 'Disables the requirement of indenting nested sublists by 4 spaces',
789 type: 'boolean'
790 },
791 simpleLineBreaks: {
792 defaultValue: false,
793 description: 'Parses simple line breaks as <br> (GFM Style)',
794 type: 'boolean'
795 },
796 requireSpaceBeforeHeadingText: {
797 defaultValue: false,
798 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
799 type: 'boolean'
800 },
801 ghMentions: {
802 defaultValue: false,
803 description: 'Enables github @mentions',
804 type: 'boolean'
805 },
806 ghMentionsLink: {
807 defaultValue: 'https://github.com/{u}',
808 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
809 type: 'string'
810 },
811 encodeEmails: {
812 defaultValue: true,
813 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
814 type: 'boolean'
815 },
816 openLinksInNewWindow: {
817 defaultValue: false,
818 description: 'Open all links in new windows',
819 type: 'boolean'
820 },
821 backslashEscapesHTMLTags: {
822 defaultValue: false,
823 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
824 type: 'boolean'
825 },
826 emoji: {
827 defaultValue: false,
828 description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
829 type: 'boolean'
830 },
831 underline: {
832 defaultValue: false,
833 description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
834 type: 'boolean'
835 },
836 completeHTMLDocument: {
837 defaultValue: false,
838 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
839 type: 'boolean'
840 },
841 metadata: {
842 defaultValue: false,
843 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
844 type: 'boolean'
845 },
846 splitAdjacentBlockquotes: {
847 defaultValue: false,
848 description: 'Split adjacent blockquote blocks',
849 type: 'boolean'
850 }
851 };
852 if (simple === false) {
853 return JSON.parse(JSON.stringify(defaultOptions));
854 }
855 var ret = {};
856 for (var opt in defaultOptions) {
857 if (defaultOptions.hasOwnProperty(opt)) {
858 ret[opt] = defaultOptions[opt].defaultValue;
859 }
860 }
861 return ret;
862 }
863
864 function allOptionsOn () {
865 'use strict';
866 var options = getDefaultOpts(true),
867 ret = {};
868 for (var opt in options) {
869 if (options.hasOwnProperty(opt)) {
870 ret[opt] = true;
871 }
872 }
873 return ret;
874 }
875
876 /**
877 * Created by Tivie on 06-01-2015.
878 */
879
880 // Private properties
881 var showdown = {},
882 parsers = {},
883 extensions = {},
884 globalOptions = getDefaultOpts(true),
885 setFlavor = 'vanilla',
886 flavor = {
887 github: {
888 omitExtraWLInCodeBlocks: true,
889 simplifiedAutoLink: true,
890 excludeTrailingPunctuationFromURLs: true,
891 literalMidWordUnderscores: true,
892 strikethrough: true,
893 tables: true,
894 tablesHeaderId: true,
895 ghCodeBlocks: true,
896 tasklists: true,
897 disableForced4SpacesIndentedSublists: true,
898 simpleLineBreaks: true,
899 requireSpaceBeforeHeadingText: true,
900 ghCompatibleHeaderId: true,
901 ghMentions: true,
902 backslashEscapesHTMLTags: true,
903 emoji: true,
904 splitAdjacentBlockquotes: true
905 },
906 original: {
907 noHeaderId: true,
908 ghCodeBlocks: false
909 },
910 ghost: {
911 omitExtraWLInCodeBlocks: true,
912 parseImgDimensions: true,
913 simplifiedAutoLink: true,
914 excludeTrailingPunctuationFromURLs: true,
915 literalMidWordUnderscores: true,
916 strikethrough: true,
917 tables: true,
918 tablesHeaderId: true,
919 ghCodeBlocks: true,
920 tasklists: true,
921 smoothLivePreview: true,
922 simpleLineBreaks: true,
923 requireSpaceBeforeHeadingText: true,
924 ghMentions: false,
925 encodeEmails: true
926 },
927 vanilla: getDefaultOpts(true),
928 allOn: allOptionsOn()
929 };
930
931 /**
932 * helper namespace
933 * @type {{}}
934 */
935 showdown.helper = {};
936
937 /**
938 * TODO LEGACY SUPPORT CODE
939 * @type {{}}
940 */
941 showdown.extensions = {};
942
943 /**
944 * Set a global option
945 * @static
946 * @param {string} key
947 * @param {*} value
948 * @returns {showdown}
949 */
950 showdown.setOption = function (key, value) {
951 'use strict';
952 globalOptions[key] = value;
953 return this;
954 };
955
956 /**
957 * Get a global option
958 * @static
959 * @param {string} key
960 * @returns {*}
961 */
962 showdown.getOption = function (key) {
963 'use strict';
964 return globalOptions[key];
965 };
966
967 /**
968 * Get the global options
969 * @static
970 * @returns {{}}
971 */
972 showdown.getOptions = function () {
973 'use strict';
974 return globalOptions;
975 };
976
977 /**
978 * Reset global options to the default values
979 * @static
980 */
981 showdown.resetOptions = function () {
982 'use strict';
983 globalOptions = getDefaultOpts(true);
984 };
985
986 /**
987 * Set the flavor showdown should use as default
988 * @param {string} name
989 */
990 showdown.setFlavor = function (name) {
991 'use strict';
992 if (!flavor.hasOwnProperty(name)) {
993 throw Error(name + ' flavor was not found');
994 }
995 showdown.resetOptions();
996 var preset = flavor[name];
997 setFlavor = name;
998 for (var option in preset) {
999 if (preset.hasOwnProperty(option)) {
1000 globalOptions[option] = preset[option];
1001 }
1002 }
1003 };
1004
1005 /**
1006 * Get the currently set flavor
1007 * @returns {string}
1008 */
1009 showdown.getFlavor = function () {
1010 'use strict';
1011 return setFlavor;
1012 };
1013
1014 /**
1015 * Get the options of a specified flavor. Returns undefined if the flavor was not found
1016 * @param {string} name Name of the flavor
1017 * @returns {{}|undefined}
1018 */
1019 showdown.getFlavorOptions = function (name) {
1020 'use strict';
1021 if (flavor.hasOwnProperty(name)) {
1022 return flavor[name];
1023 }
1024 };
1025
1026 /**
1027 * Get the default options
1028 * @static
1029 * @param {boolean} [simple=true]
1030 * @returns {{}}
1031 */
1032 showdown.getDefaultOptions = function (simple) {
1033 'use strict';
1034 return getDefaultOpts(simple);
1035 };
1036
1037 /**
1038 * Get or set a subParser
1039 *
1040 * subParser(name) - Get a registered subParser
1041 * subParser(name, func) - Register a subParser
1042 * @static
1043 * @param {string} name
1044 * @param {function} [func]
1045 * @returns {*}
1046 */
1047 showdown.subParser = function (name, func) {
1048 'use strict';
1049 if (showdown.helper.isString(name)) {
1050 if (typeof func !== 'undefined') {
1051 parsers[name] = func;
1052 } else {
1053 if (parsers.hasOwnProperty(name)) {
1054 return parsers[name];
1055 } else {
1056 throw Error('SubParser named ' + name + ' not registered!');
1057 }
1058 }
1059 }
1060 };
1061
1062 /**
1063 * Gets or registers an extension
1064 * @static
1065 * @param {string} name
1066 * @param {object|function=} ext
1067 * @returns {*}
1068 */
1069 showdown.extension = function (name, ext) {
1070 'use strict';
1071
1072 if (!showdown.helper.isString(name)) {
1073 throw Error('Extension \'name\' must be a string');
1074 }
1075
1076 name = showdown.helper.stdExtName(name);
1077
1078 // Getter
1079 if (showdown.helper.isUndefined(ext)) {
1080 if (!extensions.hasOwnProperty(name)) {
1081 throw Error('Extension named ' + name + ' is not registered!');
1082 }
1083 return extensions[name];
1084
1085 // Setter
1086 } else {
1087 // Expand extension if it's wrapped in a function
1088 if (typeof ext === 'function') {
1089 ext = ext();
1090 }
1091
1092 // Ensure extension is an array
1093 if (!showdown.helper.isArray(ext)) {
1094 ext = [ext];
1095 }
1096
1097 var validExtension = validate(ext, name);
1098
1099 if (validExtension.valid) {
1100 extensions[name] = ext;
1101 } else {
1102 throw Error(validExtension.error);
1103 }
1104 }
1105 };
1106
1107 /**
1108 * Gets all extensions registered
1109 * @returns {{}}
1110 */
1111 showdown.getAllExtensions = function () {
1112 'use strict';
1113 return extensions;
1114 };
1115
1116 /**
1117 * Remove an extension
1118 * @param {string} name
1119 */
1120 showdown.removeExtension = function (name) {
1121 'use strict';
1122 delete extensions[name];
1123 };
1124
1125 /**
1126 * Removes all extensions
1127 */
1128 showdown.resetExtensions = function () {
1129 'use strict';
1130 extensions = {};
1131 };
1132
1133 /**
1134 * Validate extension
1135 * @param {array} extension
1136 * @param {string} name
1137 * @returns {{valid: boolean, error: string}}
1138 */
1139 function validate (extension, name) {
1140 'use strict';
1141
1142 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension',
1143 ret = {
1144 valid: true,
1145 error: ''
1146 };
1147
1148 if (!showdown.helper.isArray(extension)) {
1149 extension = [extension];
1150 }
1151
1152 for (var i = 0; i < extension.length; ++i) {
1153 var baseMsg = errMsg + ' sub-extension ' + i + ': ',
1154 ext = extension[i];
1155 if (typeof ext !== 'object') {
1156 ret.valid = false;
1157 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given';
1158 return ret;
1159 }
1160
1161 if (!showdown.helper.isString(ext.type)) {
1162 ret.valid = false;
1163 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given';
1164 return ret;
1165 }
1166
1167 var type = ext.type = ext.type.toLowerCase();
1168
1169 // normalize extension type
1170 if (type === 'language') {
1171 type = ext.type = 'lang';
1172 }
1173
1174 if (type === 'html') {
1175 type = ext.type = 'output';
1176 }
1177
1178 if (type !== 'lang' && type !== 'output' && type !== 'listener') {
1179 ret.valid = false;
1180 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"';
1181 return ret;
1182 }
1183
1184 if (type === 'listener') {
1185 if (showdown.helper.isUndefined(ext.listeners)) {
1186 ret.valid = false;
1187 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"';
1188 return ret;
1189 }
1190 } else {
1191 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) {
1192 ret.valid = false;
1193 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method';
1194 return ret;
1195 }
1196 }
1197
1198 if (ext.listeners) {
1199 if (typeof ext.listeners !== 'object') {
1200 ret.valid = false;
1201 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given';
1202 return ret;
1203 }
1204 for (var ln in ext.listeners) {
1205 if (ext.listeners.hasOwnProperty(ln)) {
1206 if (typeof ext.listeners[ln] !== 'function') {
1207 ret.valid = false;
1208 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln +
1209 ' must be a function but ' + typeof ext.listeners[ln] + ' given';
1210 return ret;
1211 }
1212 }
1213 }
1214 }
1215
1216 if (ext.filter) {
1217 if (typeof ext.filter !== 'function') {
1218 ret.valid = false;
1219 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given';
1220 return ret;
1221 }
1222 } else if (ext.regex) {
1223 if (showdown.helper.isString(ext.regex)) {
1224 ext.regex = new RegExp(ext.regex, 'g');
1225 }
1226 if (!(ext.regex instanceof RegExp)) {
1227 ret.valid = false;
1228 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given';
1229 return ret;
1230 }
1231 if (showdown.helper.isUndefined(ext.replace)) {
1232 ret.valid = false;
1233 ret.error = baseMsg + '"regex" extensions must implement a replace string or function';
1234 return ret;
1235 }
1236 }
1237 }
1238 return ret;
1239 }
1240
1241 /**
1242 * Validate extension
1243 * @param {object} ext
1244 * @returns {boolean}
1245 */
1246 showdown.validateExtension = function (ext) {
1247 'use strict';
1248
1249 var validateExtension = validate(ext, null);
1250 if (!validateExtension.valid) {
1251 console.warn(validateExtension.error);
1252 return false;
1253 }
1254 return true;
1255 };
1256
1257 /**
1258 * showdownjs helper functions
1259 */
1260
1261 if (!showdown.hasOwnProperty('helper')) {
1262 showdown.helper = {};
1263 }
1264
1265 /**
1266 * Check if var is string
1267 * @static
1268 * @param {string} a
1269 * @returns {boolean}
1270 */
1271 showdown.helper.isString = function (a) {
1272 'use strict';
1273 return (typeof a === 'string' || a instanceof String);
1274 };
1275
1276 /**
1277 * Check if var is a function
1278 * @static
1279 * @param {*} a
1280 * @returns {boolean}
1281 */
1282 showdown.helper.isFunction = function (a) {
1283 'use strict';
1284 var getType = {};
1285 return a && getType.toString.call(a) === '[object Function]';
1286 };
1287
1288 /**
1289 * isArray helper function
1290 * @static
1291 * @param {*} a
1292 * @returns {boolean}
1293 */
1294 showdown.helper.isArray = function (a) {
1295 'use strict';
1296 return Array.isArray(a);
1297 };
1298
1299 /**
1300 * Check if value is undefined
1301 * @static
1302 * @param {*} value The value to check.
1303 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
1304 */
1305 showdown.helper.isUndefined = function (value) {
1306 'use strict';
1307 return typeof value === 'undefined';
1308 };
1309
1310 /**
1311 * ForEach helper function
1312 * Iterates over Arrays and Objects (own properties only)
1313 * @static
1314 * @param {*} obj
1315 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object
1316 */
1317 showdown.helper.forEach = function (obj, callback) {
1318 'use strict';
1319 // check if obj is defined
1320 if (showdown.helper.isUndefined(obj)) {
1321 throw new Error('obj param is required');
1322 }
1323
1324 if (showdown.helper.isUndefined(callback)) {
1325 throw new Error('callback param is required');
1326 }
1327
1328 if (!showdown.helper.isFunction(callback)) {
1329 throw new Error('callback param must be a function/closure');
1330 }
1331
1332 if (typeof obj.forEach === 'function') {
1333 obj.forEach(callback);
1334 } else if (showdown.helper.isArray(obj)) {
1335 for (var i = 0; i < obj.length; i++) {
1336 callback(obj[i], i, obj);
1337 }
1338 } else if (typeof (obj) === 'object') {
1339 for (var prop in obj) {
1340 if (obj.hasOwnProperty(prop)) {
1341 callback(obj[prop], prop, obj);
1342 }
1343 }
1344 } else {
1345 throw new Error('obj does not seem to be an array or an iterable object');
1346 }
1347 };
1348
1349 /**
1350 * Standardidize extension name
1351 * @static
1352 * @param {string} s extension name
1353 * @returns {string}
1354 */
1355 showdown.helper.stdExtName = function (s) {
1356 'use strict';
1357 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase();
1358 };
1359
1360 function escapeCharactersCallback (wholeMatch, m1) {
1361 'use strict';
1362 var charCodeToEscape = m1.charCodeAt(0);
1363 return '¨E' + charCodeToEscape + 'E';
1364 }
1365
1366 /**
1367 * Callback used to escape characters when passing through String.replace
1368 * @static
1369 * @param {string} wholeMatch
1370 * @param {string} m1
1371 * @returns {string}
1372 */
1373 showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
1374
1375 /**
1376 * Escape characters in a string
1377 * @static
1378 * @param {string} text
1379 * @param {string} charsToEscape
1380 * @param {boolean} afterBackslash
1381 * @returns {XML|string|void|*}
1382 */
1383 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) {
1384 'use strict';
1385 // First we have to escape the escape characters so that
1386 // we can build a character class out of them
1387 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])';
1388
1389 if (afterBackslash) {
1390 regexString = '\\\\' + regexString;
1391 }
1392
1393 var regex = new RegExp(regexString, 'g');
1394 text = text.replace(regex, escapeCharactersCallback);
1395
1396 return text;
1397 };
1398
1399 /**
1400 * Unescape HTML entities
1401 * @param txt
1402 * @returns {string}
1403 */
1404 showdown.helper.unescapeHTMLEntities = function (txt) {
1405 'use strict';
1406
1407 return txt
1408 .replace(/&quot;/g, '"')
1409 .replace(/&lt;/g, '<')
1410 .replace(/&gt;/g, '>')
1411 .replace(/&amp;/g, '&');
1412 };
1413
1414 var rgxFindMatchPos = function (str, left, right, flags) {
1415 'use strict';
1416 var f = flags || '',
1417 g = f.indexOf('g') > -1,
1418 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')),
1419 l = new RegExp(left, f.replace(/g/g, '')),
1420 pos = [],
1421 t, s, m, start, end;
1422
1423 do {
1424 t = 0;
1425 while ((m = x.exec(str))) {
1426 if (l.test(m[0])) {
1427 if (!(t++)) {
1428 s = x.lastIndex;
1429 start = s - m[0].length;
1430 }
1431 } else if (t) {
1432 if (!--t) {
1433 end = m.index + m[0].length;
1434 var obj = {
1435 left: {start: start, end: s},
1436 match: {start: s, end: m.index},
1437 right: {start: m.index, end: end},
1438 wholeMatch: {start: start, end: end}
1439 };
1440 pos.push(obj);
1441 if (!g) {
1442 return pos;
1443 }
1444 }
1445 }
1446 }
1447 } while (t && (x.lastIndex = s));
1448
1449 return pos;
1450 };
1451
1452 /**
1453 * matchRecursiveRegExp
1454 *
1455 * (c) 2007 Steven Levithan <stevenlevithan.com>
1456 * MIT License
1457 *
1458 * Accepts a string to search, a left and right format delimiter
1459 * as regex patterns, and optional regex flags. Returns an array
1460 * of matches, allowing nested instances of left/right delimiters.
1461 * Use the "g" flag to return all matches, otherwise only the
1462 * first is returned. Be careful to ensure that the left and
1463 * right format delimiters produce mutually exclusive matches.
1464 * Backreferences are not supported within the right delimiter
1465 * due to how it is internally combined with the left delimiter.
1466 * When matching strings whose format delimiters are unbalanced
1467 * to the left or right, the output is intentionally as a
1468 * conventional regex library with recursion support would
1469 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using
1470 * "<" and ">" as the delimiters (both strings contain a single,
1471 * balanced instance of "<x>").
1472 *
1473 * examples:
1474 * matchRecursiveRegExp("test", "\\(", "\\)")
1475 * returns: []
1476 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g")
1477 * returns: ["t<<e>><s>", ""]
1478 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi")
1479 * returns: ["test"]
1480 */
1481 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) {
1482 'use strict';
1483
1484 var matchPos = rgxFindMatchPos (str, left, right, flags),
1485 results = [];
1486
1487 for (var i = 0; i < matchPos.length; ++i) {
1488 results.push([
1489 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
1490 str.slice(matchPos[i].match.start, matchPos[i].match.end),
1491 str.slice(matchPos[i].left.start, matchPos[i].left.end),
1492 str.slice(matchPos[i].right.start, matchPos[i].right.end)
1493 ]);
1494 }
1495 return results;
1496 };
1497
1498 /**
1499 *
1500 * @param {string} str
1501 * @param {string|function} replacement
1502 * @param {string} left
1503 * @param {string} right
1504 * @param {string} flags
1505 * @returns {string}
1506 */
1507 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {
1508 'use strict';
1509
1510 if (!showdown.helper.isFunction(replacement)) {
1511 var repStr = replacement;
1512 replacement = function () {
1513 return repStr;
1514 };
1515 }
1516
1517 var matchPos = rgxFindMatchPos(str, left, right, flags),
1518 finalStr = str,
1519 lng = matchPos.length;
1520
1521 if (lng > 0) {
1522 var bits = [];
1523 if (matchPos[0].wholeMatch.start !== 0) {
1524 bits.push(str.slice(0, matchPos[0].wholeMatch.start));
1525 }
1526 for (var i = 0; i < lng; ++i) {
1527 bits.push(
1528 replacement(
1529 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
1530 str.slice(matchPos[i].match.start, matchPos[i].match.end),
1531 str.slice(matchPos[i].left.start, matchPos[i].left.end),
1532 str.slice(matchPos[i].right.start, matchPos[i].right.end)
1533 )
1534 );
1535 if (i < lng - 1) {
1536 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start));
1537 }
1538 }
1539 if (matchPos[lng - 1].wholeMatch.end < str.length) {
1540 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end));
1541 }
1542 finalStr = bits.join('');
1543 }
1544 return finalStr;
1545 };
1546
1547 /**
1548 * Returns the index within the passed String object of the first occurrence of the specified regex,
1549 * starting the search at fromIndex. Returns -1 if the value is not found.
1550 *
1551 * @param {string} str string to search
1552 * @param {RegExp} regex Regular expression to search
1553 * @param {int} [fromIndex = 0] Index to start the search
1554 * @returns {Number}
1555 * @throws InvalidArgumentError
1556 */
1557 showdown.helper.regexIndexOf = function (str, regex, fromIndex) {
1558 'use strict';
1559 if (!showdown.helper.isString(str)) {
1560 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
1561 }
1562 if (regex instanceof RegExp === false) {
1563 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp';
1564 }
1565 var indexOf = str.substring(fromIndex || 0).search(regex);
1566 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf;
1567 };
1568
1569 /**
1570 * Splits the passed string object at the defined index, and returns an array composed of the two substrings
1571 * @param {string} str string to split
1572 * @param {int} index index to split string at
1573 * @returns {[string,string]}
1574 * @throws InvalidArgumentError
1575 */
1576 showdown.helper.splitAtIndex = function (str, index) {
1577 'use strict';
1578 if (!showdown.helper.isString(str)) {
1579 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
1580 }
1581 return [str.substring(0, index), str.substring(index)];
1582 };
1583
1584 /**
1585 * Obfuscate an e-mail address through the use of Character Entities,
1586 * transforming ASCII characters into their equivalent decimal or hex entities.
1587 *
1588 * Since it has a random component, subsequent calls to this function produce different results
1589 *
1590 * @param {string} mail
1591 * @returns {string}
1592 */
1593 showdown.helper.encodeEmailAddress = function (mail) {
1594 'use strict';
1595 var encode = [
1596 function (ch) {
1597 return '&#' + ch.charCodeAt(0) + ';';
1598 },
1599 function (ch) {
1600 return '&#x' + ch.charCodeAt(0).toString(16) + ';';
1601 },
1602 function (ch) {
1603 return ch;
1604 }
1605 ];
1606
1607 mail = mail.replace(/./g, function (ch) {
1608 if (ch === '@') {
1609 // this *must* be encoded. I insist.
1610 ch = encode[Math.floor(Math.random() * 2)](ch);
1611 } else {
1612 var r = Math.random();
1613 // roughly 10% raw, 45% hex, 45% dec
1614 ch = (
1615 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch)
1616 );
1617 }
1618 return ch;
1619 });
1620
1621 return mail;
1622 };
1623
1624 /**
1625 *
1626 * @param str
1627 * @param targetLength
1628 * @param padString
1629 * @returns {string}
1630 */
1631 showdown.helper.padEnd = function padEnd (str, targetLength, padString) {
1632 'use strict';
1633 /*jshint bitwise: false*/
1634 // eslint-disable-next-line space-infix-ops
1635 targetLength = targetLength>>0; //floor if number or convert non-number to 0;
1636 /*jshint bitwise: true*/
1637 padString = String(padString || ' ');
1638 if (str.length > targetLength) {
1639 return String(str);
1640 } else {
1641 targetLength = targetLength - str.length;
1642 if (targetLength > padString.length) {
1643 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
1644 }
1645 return String(str) + padString.slice(0,targetLength);
1646 }
1647 };
1648
1649 /**
1650 * POLYFILLS
1651 */
1652 // use this instead of builtin is undefined for IE8 compatibility
1653 if (typeof console === 'undefined') {
1654 console = {
1655 warn: function (msg) {
1656 'use strict';
1657 alert(msg);
1658 },
1659 log: function (msg) {
1660 'use strict';
1661 alert(msg);
1662 },
1663 error: function (msg) {
1664 'use strict';
1665 throw msg;
1666 }
1667 };
1668 }
1669
1670 /**
1671 * Common regexes.
1672 * We declare some common regexes to improve performance
1673 */
1674 showdown.helper.regexes = {
1675 asteriskDashAndColon: /([*_:~])/g
1676 };
1677
1678 /**
1679 * EMOJIS LIST
1680 */
1681 showdown.helper.emojis = {
1682 '+1':'\ud83d\udc4d',
1683 '-1':'\ud83d\udc4e',
1684 '100':'\ud83d\udcaf',
1685 '1234':'\ud83d\udd22',
1686 '1st_place_medal':'\ud83e\udd47',
1687 '2nd_place_medal':'\ud83e\udd48',
1688 '3rd_place_medal':'\ud83e\udd49',
1689 '8ball':'\ud83c\udfb1',
1690 'a':'\ud83c\udd70\ufe0f',
1691 'ab':'\ud83c\udd8e',
1692 'abc':'\ud83d\udd24',
1693 'abcd':'\ud83d\udd21',
1694 'accept':'\ud83c\ude51',
1695 'aerial_tramway':'\ud83d\udea1',
1696 'airplane':'\u2708\ufe0f',
1697 'alarm_clock':'\u23f0',
1698 'alembic':'\u2697\ufe0f',
1699 'alien':'\ud83d\udc7d',
1700 'ambulance':'\ud83d\ude91',
1701 'amphora':'\ud83c\udffa',
1702 'anchor':'\u2693\ufe0f',
1703 'angel':'\ud83d\udc7c',
1704 'anger':'\ud83d\udca2',
1705 'angry':'\ud83d\ude20',
1706 'anguished':'\ud83d\ude27',
1707 'ant':'\ud83d\udc1c',
1708 'apple':'\ud83c\udf4e',
1709 'aquarius':'\u2652\ufe0f',
1710 'aries':'\u2648\ufe0f',
1711 'arrow_backward':'\u25c0\ufe0f',
1712 'arrow_double_down':'\u23ec',
1713 'arrow_double_up':'\u23eb',
1714 'arrow_down':'\u2b07\ufe0f',
1715 'arrow_down_small':'\ud83d\udd3d',
1716 'arrow_forward':'\u25b6\ufe0f',
1717 'arrow_heading_down':'\u2935\ufe0f',
1718 'arrow_heading_up':'\u2934\ufe0f',
1719 'arrow_left':'\u2b05\ufe0f',
1720 'arrow_lower_left':'\u2199\ufe0f',
1721 'arrow_lower_right':'\u2198\ufe0f',
1722 'arrow_right':'\u27a1\ufe0f',
1723 'arrow_right_hook':'\u21aa\ufe0f',
1724 'arrow_up':'\u2b06\ufe0f',
1725 'arrow_up_down':'\u2195\ufe0f',
1726 'arrow_up_small':'\ud83d\udd3c',
1727 'arrow_upper_left':'\u2196\ufe0f',
1728 'arrow_upper_right':'\u2197\ufe0f',
1729 'arrows_clockwise':'\ud83d\udd03',
1730 'arrows_counterclockwise':'\ud83d\udd04',
1731 'art':'\ud83c\udfa8',
1732 'articulated_lorry':'\ud83d\ude9b',
1733 'artificial_satellite':'\ud83d\udef0',
1734 'astonished':'\ud83d\ude32',
1735 'athletic_shoe':'\ud83d\udc5f',
1736 'atm':'\ud83c\udfe7',
1737 'atom_symbol':'\u269b\ufe0f',
1738 'avocado':'\ud83e\udd51',
1739 'b':'\ud83c\udd71\ufe0f',
1740 'baby':'\ud83d\udc76',
1741 'baby_bottle':'\ud83c\udf7c',
1742 'baby_chick':'\ud83d\udc24',
1743 'baby_symbol':'\ud83d\udebc',
1744 'back':'\ud83d\udd19',
1745 'bacon':'\ud83e\udd53',
1746 'badminton':'\ud83c\udff8',
1747 'baggage_claim':'\ud83d\udec4',
1748 'baguette_bread':'\ud83e\udd56',
1749 'balance_scale':'\u2696\ufe0f',
1750 'balloon':'\ud83c\udf88',
1751 'ballot_box':'\ud83d\uddf3',
1752 'ballot_box_with_check':'\u2611\ufe0f',
1753 'bamboo':'\ud83c\udf8d',
1754 'banana':'\ud83c\udf4c',
1755 'bangbang':'\u203c\ufe0f',
1756 'bank':'\ud83c\udfe6',
1757 'bar_chart':'\ud83d\udcca',
1758 'barber':'\ud83d\udc88',
1759 'baseball':'\u26be\ufe0f',
1760 'basketball':'\ud83c\udfc0',
1761 'basketball_man':'\u26f9\ufe0f',
1762 'basketball_woman':'\u26f9\ufe0f&zwj;\u2640\ufe0f',
1763 'bat':'\ud83e\udd87',
1764 'bath':'\ud83d\udec0',
1765 'bathtub':'\ud83d\udec1',
1766 'battery':'\ud83d\udd0b',
1767 'beach_umbrella':'\ud83c\udfd6',
1768 'bear':'\ud83d\udc3b',
1769 'bed':'\ud83d\udecf',
1770 'bee':'\ud83d\udc1d',
1771 'beer':'\ud83c\udf7a',
1772 'beers':'\ud83c\udf7b',
1773 'beetle':'\ud83d\udc1e',
1774 'beginner':'\ud83d\udd30',
1775 'bell':'\ud83d\udd14',
1776 'bellhop_bell':'\ud83d\udece',
1777 'bento':'\ud83c\udf71',
1778 'biking_man':'\ud83d\udeb4',
1779 'bike':'\ud83d\udeb2',
1780 'biking_woman':'\ud83d\udeb4&zwj;\u2640\ufe0f',
1781 'bikini':'\ud83d\udc59',
1782 'biohazard':'\u2623\ufe0f',
1783 'bird':'\ud83d\udc26',
1784 'birthday':'\ud83c\udf82',
1785 'black_circle':'\u26ab\ufe0f',
1786 'black_flag':'\ud83c\udff4',
1787 'black_heart':'\ud83d\udda4',
1788 'black_joker':'\ud83c\udccf',
1789 'black_large_square':'\u2b1b\ufe0f',
1790 'black_medium_small_square':'\u25fe\ufe0f',
1791 'black_medium_square':'\u25fc\ufe0f',
1792 'black_nib':'\u2712\ufe0f',
1793 'black_small_square':'\u25aa\ufe0f',
1794 'black_square_button':'\ud83d\udd32',
1795 'blonde_man':'\ud83d\udc71',
1796 'blonde_woman':'\ud83d\udc71&zwj;\u2640\ufe0f',
1797 'blossom':'\ud83c\udf3c',
1798 'blowfish':'\ud83d\udc21',
1799 'blue_book':'\ud83d\udcd8',
1800 'blue_car':'\ud83d\ude99',
1801 'blue_heart':'\ud83d\udc99',
1802 'blush':'\ud83d\ude0a',
1803 'boar':'\ud83d\udc17',
1804 'boat':'\u26f5\ufe0f',
1805 'bomb':'\ud83d\udca3',
1806 'book':'\ud83d\udcd6',
1807 'bookmark':'\ud83d\udd16',
1808 'bookmark_tabs':'\ud83d\udcd1',
1809 'books':'\ud83d\udcda',
1810 'boom':'\ud83d\udca5',
1811 'boot':'\ud83d\udc62',
1812 'bouquet':'\ud83d\udc90',
1813 'bowing_man':'\ud83d\ude47',
1814 'bow_and_arrow':'\ud83c\udff9',
1815 'bowing_woman':'\ud83d\ude47&zwj;\u2640\ufe0f',
1816 'bowling':'\ud83c\udfb3',
1817 'boxing_glove':'\ud83e\udd4a',
1818 'boy':'\ud83d\udc66',
1819 'bread':'\ud83c\udf5e',
1820 'bride_with_veil':'\ud83d\udc70',
1821 'bridge_at_night':'\ud83c\udf09',
1822 'briefcase':'\ud83d\udcbc',
1823 'broken_heart':'\ud83d\udc94',
1824 'bug':'\ud83d\udc1b',
1825 'building_construction':'\ud83c\udfd7',
1826 'bulb':'\ud83d\udca1',
1827 'bullettrain_front':'\ud83d\ude85',
1828 'bullettrain_side':'\ud83d\ude84',
1829 'burrito':'\ud83c\udf2f',
1830 'bus':'\ud83d\ude8c',
1831 'business_suit_levitating':'\ud83d\udd74',
1832 'busstop':'\ud83d\ude8f',
1833 'bust_in_silhouette':'\ud83d\udc64',
1834 'busts_in_silhouette':'\ud83d\udc65',
1835 'butterfly':'\ud83e\udd8b',
1836 'cactus':'\ud83c\udf35',
1837 'cake':'\ud83c\udf70',
1838 'calendar':'\ud83d\udcc6',
1839 'call_me_hand':'\ud83e\udd19',
1840 'calling':'\ud83d\udcf2',
1841 'camel':'\ud83d\udc2b',
1842 'camera':'\ud83d\udcf7',
1843 'camera_flash':'\ud83d\udcf8',
1844 'camping':'\ud83c\udfd5',
1845 'cancer':'\u264b\ufe0f',
1846 'candle':'\ud83d\udd6f',
1847 'candy':'\ud83c\udf6c',
1848 'canoe':'\ud83d\udef6',
1849 'capital_abcd':'\ud83d\udd20',
1850 'capricorn':'\u2651\ufe0f',
1851 'car':'\ud83d\ude97',
1852 'card_file_box':'\ud83d\uddc3',
1853 'card_index':'\ud83d\udcc7',
1854 'card_index_dividers':'\ud83d\uddc2',
1855 'carousel_horse':'\ud83c\udfa0',
1856 'carrot':'\ud83e\udd55',
1857 'cat':'\ud83d\udc31',
1858 'cat2':'\ud83d\udc08',
1859 'cd':'\ud83d\udcbf',
1860 'chains':'\u26d3',
1861 'champagne':'\ud83c\udf7e',
1862 'chart':'\ud83d\udcb9',
1863 'chart_with_downwards_trend':'\ud83d\udcc9',
1864 'chart_with_upwards_trend':'\ud83d\udcc8',
1865 'checkered_flag':'\ud83c\udfc1',
1866 'cheese':'\ud83e\uddc0',
1867 'cherries':'\ud83c\udf52',
1868 'cherry_blossom':'\ud83c\udf38',
1869 'chestnut':'\ud83c\udf30',
1870 'chicken':'\ud83d\udc14',
1871 'children_crossing':'\ud83d\udeb8',
1872 'chipmunk':'\ud83d\udc3f',
1873 'chocolate_bar':'\ud83c\udf6b',
1874 'christmas_tree':'\ud83c\udf84',
1875 'church':'\u26ea\ufe0f',
1876 'cinema':'\ud83c\udfa6',
1877 'circus_tent':'\ud83c\udfaa',
1878 'city_sunrise':'\ud83c\udf07',
1879 'city_sunset':'\ud83c\udf06',
1880 'cityscape':'\ud83c\udfd9',
1881 'cl':'\ud83c\udd91',
1882 'clamp':'\ud83d\udddc',
1883 'clap':'\ud83d\udc4f',
1884 'clapper':'\ud83c\udfac',
1885 'classical_building':'\ud83c\udfdb',
1886 'clinking_glasses':'\ud83e\udd42',
1887 'clipboard':'\ud83d\udccb',
1888 'clock1':'\ud83d\udd50',
1889 'clock10':'\ud83d\udd59',
1890 'clock1030':'\ud83d\udd65',
1891 'clock11':'\ud83d\udd5a',
1892 'clock1130':'\ud83d\udd66',
1893 'clock12':'\ud83d\udd5b',
1894 'clock1230':'\ud83d\udd67',
1895 'clock130':'\ud83d\udd5c',
1896 'clock2':'\ud83d\udd51',
1897 'clock230':'\ud83d\udd5d',
1898 'clock3':'\ud83d\udd52',
1899 'clock330':'\ud83d\udd5e',
1900 'clock4':'\ud83d\udd53',
1901 'clock430':'\ud83d\udd5f',
1902 'clock5':'\ud83d\udd54',
1903 'clock530':'\ud83d\udd60',
1904 'clock6':'\ud83d\udd55',
1905 'clock630':'\ud83d\udd61',
1906 'clock7':'\ud83d\udd56',
1907 'clock730':'\ud83d\udd62',
1908 'clock8':'\ud83d\udd57',
1909 'clock830':'\ud83d\udd63',
1910 'clock9':'\ud83d\udd58',
1911 'clock930':'\ud83d\udd64',
1912 'closed_book':'\ud83d\udcd5',
1913 'closed_lock_with_key':'\ud83d\udd10',
1914 'closed_umbrella':'\ud83c\udf02',
1915 'cloud':'\u2601\ufe0f',
1916 'cloud_with_lightning':'\ud83c\udf29',
1917 'cloud_with_lightning_and_rain':'\u26c8',
1918 'cloud_with_rain':'\ud83c\udf27',
1919 'cloud_with_snow':'\ud83c\udf28',
1920 'clown_face':'\ud83e\udd21',
1921 'clubs':'\u2663\ufe0f',
1922 'cocktail':'\ud83c\udf78',
1923 'coffee':'\u2615\ufe0f',
1924 'coffin':'\u26b0\ufe0f',
1925 'cold_sweat':'\ud83d\ude30',
1926 'comet':'\u2604\ufe0f',
1927 'computer':'\ud83d\udcbb',
1928 'computer_mouse':'\ud83d\uddb1',
1929 'confetti_ball':'\ud83c\udf8a',
1930 'confounded':'\ud83d\ude16',
1931 'confused':'\ud83d\ude15',
1932 'congratulations':'\u3297\ufe0f',
1933 'construction':'\ud83d\udea7',
1934 'construction_worker_man':'\ud83d\udc77',
1935 'construction_worker_woman':'\ud83d\udc77&zwj;\u2640\ufe0f',
1936 'control_knobs':'\ud83c\udf9b',
1937 'convenience_store':'\ud83c\udfea',
1938 'cookie':'\ud83c\udf6a',
1939 'cool':'\ud83c\udd92',
1940 'policeman':'\ud83d\udc6e',
1941 'copyright':'\u00a9\ufe0f',
1942 'corn':'\ud83c\udf3d',
1943 'couch_and_lamp':'\ud83d\udecb',
1944 'couple':'\ud83d\udc6b',
1945 'couple_with_heart_woman_man':'\ud83d\udc91',
1946 'couple_with_heart_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc68',
1947 'couple_with_heart_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc69',
1948 'couplekiss_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc68',
1949 'couplekiss_man_woman':'\ud83d\udc8f',
1950 'couplekiss_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc69',
1951 'cow':'\ud83d\udc2e',
1952 'cow2':'\ud83d\udc04',
1953 'cowboy_hat_face':'\ud83e\udd20',
1954 'crab':'\ud83e\udd80',
1955 'crayon':'\ud83d\udd8d',
1956 'credit_card':'\ud83d\udcb3',
1957 'crescent_moon':'\ud83c\udf19',
1958 'cricket':'\ud83c\udfcf',
1959 'crocodile':'\ud83d\udc0a',
1960 'croissant':'\ud83e\udd50',
1961 'crossed_fingers':'\ud83e\udd1e',
1962 'crossed_flags':'\ud83c\udf8c',
1963 'crossed_swords':'\u2694\ufe0f',
1964 'crown':'\ud83d\udc51',
1965 'cry':'\ud83d\ude22',
1966 'crying_cat_face':'\ud83d\ude3f',
1967 'crystal_ball':'\ud83d\udd2e',
1968 'cucumber':'\ud83e\udd52',
1969 'cupid':'\ud83d\udc98',
1970 'curly_loop':'\u27b0',
1971 'currency_exchange':'\ud83d\udcb1',
1972 'curry':'\ud83c\udf5b',
1973 'custard':'\ud83c\udf6e',
1974 'customs':'\ud83d\udec3',
1975 'cyclone':'\ud83c\udf00',
1976 'dagger':'\ud83d\udde1',
1977 'dancer':'\ud83d\udc83',
1978 'dancing_women':'\ud83d\udc6f',
1979 'dancing_men':'\ud83d\udc6f&zwj;\u2642\ufe0f',
1980 'dango':'\ud83c\udf61',
1981 'dark_sunglasses':'\ud83d\udd76',
1982 'dart':'\ud83c\udfaf',
1983 'dash':'\ud83d\udca8',
1984 'date':'\ud83d\udcc5',
1985 'deciduous_tree':'\ud83c\udf33',
1986 'deer':'\ud83e\udd8c',
1987 'department_store':'\ud83c\udfec',
1988 'derelict_house':'\ud83c\udfda',
1989 'desert':'\ud83c\udfdc',
1990 'desert_island':'\ud83c\udfdd',
1991 'desktop_computer':'\ud83d\udda5',
1992 'male_detective':'\ud83d\udd75\ufe0f',
1993 'diamond_shape_with_a_dot_inside':'\ud83d\udca0',
1994 'diamonds':'\u2666\ufe0f',
1995 'disappointed':'\ud83d\ude1e',
1996 'disappointed_relieved':'\ud83d\ude25',
1997 'dizzy':'\ud83d\udcab',
1998 'dizzy_face':'\ud83d\ude35',
1999 'do_not_litter':'\ud83d\udeaf',
2000 'dog':'\ud83d\udc36',
2001 'dog2':'\ud83d\udc15',
2002 'dollar':'\ud83d\udcb5',
2003 'dolls':'\ud83c\udf8e',
2004 'dolphin':'\ud83d\udc2c',
2005 'door':'\ud83d\udeaa',
2006 'doughnut':'\ud83c\udf69',
2007 'dove':'\ud83d\udd4a',
2008 'dragon':'\ud83d\udc09',
2009 'dragon_face':'\ud83d\udc32',
2010 'dress':'\ud83d\udc57',
2011 'dromedary_camel':'\ud83d\udc2a',
2012 'drooling_face':'\ud83e\udd24',
2013 'droplet':'\ud83d\udca7',
2014 'drum':'\ud83e\udd41',
2015 'duck':'\ud83e\udd86',
2016 'dvd':'\ud83d\udcc0',
2017 'e-mail':'\ud83d\udce7',
2018 'eagle':'\ud83e\udd85',
2019 'ear':'\ud83d\udc42',
2020 'ear_of_rice':'\ud83c\udf3e',
2021 'earth_africa':'\ud83c\udf0d',
2022 'earth_americas':'\ud83c\udf0e',
2023 'earth_asia':'\ud83c\udf0f',
2024 'egg':'\ud83e\udd5a',
2025 'eggplant':'\ud83c\udf46',
2026 'eight_pointed_black_star':'\u2734\ufe0f',
2027 'eight_spoked_asterisk':'\u2733\ufe0f',
2028 'electric_plug':'\ud83d\udd0c',
2029 'elephant':'\ud83d\udc18',
2030 'email':'\u2709\ufe0f',
2031 'end':'\ud83d\udd1a',
2032 'envelope_with_arrow':'\ud83d\udce9',
2033 'euro':'\ud83d\udcb6',
2034 'european_castle':'\ud83c\udff0',
2035 'european_post_office':'\ud83c\udfe4',
2036 'evergreen_tree':'\ud83c\udf32',
2037 'exclamation':'\u2757\ufe0f',
2038 'expressionless':'\ud83d\ude11',
2039 'eye':'\ud83d\udc41',
2040 'eye_speech_bubble':'\ud83d\udc41&zwj;\ud83d\udde8',
2041 'eyeglasses':'\ud83d\udc53',
2042 'eyes':'\ud83d\udc40',
2043 'face_with_head_bandage':'\ud83e\udd15',
2044 'face_with_thermometer':'\ud83e\udd12',
2045 'fist_oncoming':'\ud83d\udc4a',
2046 'factory':'\ud83c\udfed',
2047 'fallen_leaf':'\ud83c\udf42',
2048 'family_man_woman_boy':'\ud83d\udc6a',
2049 'family_man_boy':'\ud83d\udc68&zwj;\ud83d\udc66',
2050 'family_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2051 'family_man_girl':'\ud83d\udc68&zwj;\ud83d\udc67',
2052 'family_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2053 'family_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2054 'family_man_man_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66',
2055 'family_man_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2056 'family_man_man_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67',
2057 'family_man_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2058 'family_man_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2059 'family_man_woman_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2060 'family_man_woman_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
2061 'family_man_woman_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2062 'family_man_woman_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2063 'family_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc66',
2064 'family_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2065 'family_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc67',
2066 'family_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2067 'family_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2068 'family_woman_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66',
2069 'family_woman_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2070 'family_woman_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
2071 'family_woman_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2072 'family_woman_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2073 'fast_forward':'\u23e9',
2074 'fax':'\ud83d\udce0',
2075 'fearful':'\ud83d\ude28',
2076 'feet':'\ud83d\udc3e',
2077 'female_detective':'\ud83d\udd75\ufe0f&zwj;\u2640\ufe0f',
2078 'ferris_wheel':'\ud83c\udfa1',
2079 'ferry':'\u26f4',
2080 'field_hockey':'\ud83c\udfd1',
2081 'file_cabinet':'\ud83d\uddc4',
2082 'file_folder':'\ud83d\udcc1',
2083 'film_projector':'\ud83d\udcfd',
2084 'film_strip':'\ud83c\udf9e',
2085 'fire':'\ud83d\udd25',
2086 'fire_engine':'\ud83d\ude92',
2087 'fireworks':'\ud83c\udf86',
2088 'first_quarter_moon':'\ud83c\udf13',
2089 'first_quarter_moon_with_face':'\ud83c\udf1b',
2090 'fish':'\ud83d\udc1f',
2091 'fish_cake':'\ud83c\udf65',
2092 'fishing_pole_and_fish':'\ud83c\udfa3',
2093 'fist_raised':'\u270a',
2094 'fist_left':'\ud83e\udd1b',
2095 'fist_right':'\ud83e\udd1c',
2096 'flags':'\ud83c\udf8f',
2097 'flashlight':'\ud83d\udd26',
2098 'fleur_de_lis':'\u269c\ufe0f',
2099 'flight_arrival':'\ud83d\udeec',
2100 'flight_departure':'\ud83d\udeeb',
2101 'floppy_disk':'\ud83d\udcbe',
2102 'flower_playing_cards':'\ud83c\udfb4',
2103 'flushed':'\ud83d\ude33',
2104 'fog':'\ud83c\udf2b',
2105 'foggy':'\ud83c\udf01',
2106 'football':'\ud83c\udfc8',
2107 'footprints':'\ud83d\udc63',
2108 'fork_and_knife':'\ud83c\udf74',
2109 'fountain':'\u26f2\ufe0f',
2110 'fountain_pen':'\ud83d\udd8b',
2111 'four_leaf_clover':'\ud83c\udf40',
2112 'fox_face':'\ud83e\udd8a',
2113 'framed_picture':'\ud83d\uddbc',
2114 'free':'\ud83c\udd93',
2115 'fried_egg':'\ud83c\udf73',
2116 'fried_shrimp':'\ud83c\udf64',
2117 'fries':'\ud83c\udf5f',
2118 'frog':'\ud83d\udc38',
2119 'frowning':'\ud83d\ude26',
2120 'frowning_face':'\u2639\ufe0f',
2121 'frowning_man':'\ud83d\ude4d&zwj;\u2642\ufe0f',
2122 'frowning_woman':'\ud83d\ude4d',
2123 'middle_finger':'\ud83d\udd95',
2124 'fuelpump':'\u26fd\ufe0f',
2125 'full_moon':'\ud83c\udf15',
2126 'full_moon_with_face':'\ud83c\udf1d',
2127 'funeral_urn':'\u26b1\ufe0f',
2128 'game_die':'\ud83c\udfb2',
2129 'gear':'\u2699\ufe0f',
2130 'gem':'\ud83d\udc8e',
2131 'gemini':'\u264a\ufe0f',
2132 'ghost':'\ud83d\udc7b',
2133 'gift':'\ud83c\udf81',
2134 'gift_heart':'\ud83d\udc9d',
2135 'girl':'\ud83d\udc67',
2136 'globe_with_meridians':'\ud83c\udf10',
2137 'goal_net':'\ud83e\udd45',
2138 'goat':'\ud83d\udc10',
2139 'golf':'\u26f3\ufe0f',
2140 'golfing_man':'\ud83c\udfcc\ufe0f',
2141 'golfing_woman':'\ud83c\udfcc\ufe0f&zwj;\u2640\ufe0f',
2142 'gorilla':'\ud83e\udd8d',
2143 'grapes':'\ud83c\udf47',
2144 'green_apple':'\ud83c\udf4f',
2145 'green_book':'\ud83d\udcd7',
2146 'green_heart':'\ud83d\udc9a',
2147 'green_salad':'\ud83e\udd57',
2148 'grey_exclamation':'\u2755',
2149 'grey_question':'\u2754',
2150 'grimacing':'\ud83d\ude2c',
2151 'grin':'\ud83d\ude01',
2152 'grinning':'\ud83d\ude00',
2153 'guardsman':'\ud83d\udc82',
2154 'guardswoman':'\ud83d\udc82&zwj;\u2640\ufe0f',
2155 'guitar':'\ud83c\udfb8',
2156 'gun':'\ud83d\udd2b',
2157 'haircut_woman':'\ud83d\udc87',
2158 'haircut_man':'\ud83d\udc87&zwj;\u2642\ufe0f',
2159 'hamburger':'\ud83c\udf54',
2160 'hammer':'\ud83d\udd28',
2161 'hammer_and_pick':'\u2692',
2162 'hammer_and_wrench':'\ud83d\udee0',
2163 'hamster':'\ud83d\udc39',
2164 'hand':'\u270b',
2165 'handbag':'\ud83d\udc5c',
2166 'handshake':'\ud83e\udd1d',
2167 'hankey':'\ud83d\udca9',
2168 'hatched_chick':'\ud83d\udc25',
2169 'hatching_chick':'\ud83d\udc23',
2170 'headphones':'\ud83c\udfa7',
2171 'hear_no_evil':'\ud83d\ude49',
2172 'heart':'\u2764\ufe0f',
2173 'heart_decoration':'\ud83d\udc9f',
2174 'heart_eyes':'\ud83d\ude0d',
2175 'heart_eyes_cat':'\ud83d\ude3b',
2176 'heartbeat':'\ud83d\udc93',
2177 'heartpulse':'\ud83d\udc97',
2178 'hearts':'\u2665\ufe0f',
2179 'heavy_check_mark':'\u2714\ufe0f',
2180 'heavy_division_sign':'\u2797',
2181 'heavy_dollar_sign':'\ud83d\udcb2',
2182 'heavy_heart_exclamation':'\u2763\ufe0f',
2183 'heavy_minus_sign':'\u2796',
2184 'heavy_multiplication_x':'\u2716\ufe0f',
2185 'heavy_plus_sign':'\u2795',
2186 'helicopter':'\ud83d\ude81',
2187 'herb':'\ud83c\udf3f',
2188 'hibiscus':'\ud83c\udf3a',
2189 'high_brightness':'\ud83d\udd06',
2190 'high_heel':'\ud83d\udc60',
2191 'hocho':'\ud83d\udd2a',
2192 'hole':'\ud83d\udd73',
2193 'honey_pot':'\ud83c\udf6f',
2194 'horse':'\ud83d\udc34',
2195 'horse_racing':'\ud83c\udfc7',
2196 'hospital':'\ud83c\udfe5',
2197 'hot_pepper':'\ud83c\udf36',
2198 'hotdog':'\ud83c\udf2d',
2199 'hotel':'\ud83c\udfe8',
2200 'hotsprings':'\u2668\ufe0f',
2201 'hourglass':'\u231b\ufe0f',
2202 'hourglass_flowing_sand':'\u23f3',
2203 'house':'\ud83c\udfe0',
2204 'house_with_garden':'\ud83c\udfe1',
2205 'houses':'\ud83c\udfd8',
2206 'hugs':'\ud83e\udd17',
2207 'hushed':'\ud83d\ude2f',
2208 'ice_cream':'\ud83c\udf68',
2209 'ice_hockey':'\ud83c\udfd2',
2210 'ice_skate':'\u26f8',
2211 'icecream':'\ud83c\udf66',
2212 'id':'\ud83c\udd94',
2213 'ideograph_advantage':'\ud83c\ude50',
2214 'imp':'\ud83d\udc7f',
2215 'inbox_tray':'\ud83d\udce5',
2216 'incoming_envelope':'\ud83d\udce8',
2217 'tipping_hand_woman':'\ud83d\udc81',
2218 'information_source':'\u2139\ufe0f',
2219 'innocent':'\ud83d\ude07',
2220 'interrobang':'\u2049\ufe0f',
2221 'iphone':'\ud83d\udcf1',
2222 'izakaya_lantern':'\ud83c\udfee',
2223 'jack_o_lantern':'\ud83c\udf83',
2224 'japan':'\ud83d\uddfe',
2225 'japanese_castle':'\ud83c\udfef',
2226 'japanese_goblin':'\ud83d\udc7a',
2227 'japanese_ogre':'\ud83d\udc79',
2228 'jeans':'\ud83d\udc56',
2229 'joy':'\ud83d\ude02',
2230 'joy_cat':'\ud83d\ude39',
2231 'joystick':'\ud83d\udd79',
2232 'kaaba':'\ud83d\udd4b',
2233 'key':'\ud83d\udd11',
2234 'keyboard':'\u2328\ufe0f',
2235 'keycap_ten':'\ud83d\udd1f',
2236 'kick_scooter':'\ud83d\udef4',
2237 'kimono':'\ud83d\udc58',
2238 'kiss':'\ud83d\udc8b',
2239 'kissing':'\ud83d\ude17',
2240 'kissing_cat':'\ud83d\ude3d',
2241 'kissing_closed_eyes':'\ud83d\ude1a',
2242 'kissing_heart':'\ud83d\ude18',
2243 'kissing_smiling_eyes':'\ud83d\ude19',
2244 'kiwi_fruit':'\ud83e\udd5d',
2245 'koala':'\ud83d\udc28',
2246 'koko':'\ud83c\ude01',
2247 'label':'\ud83c\udff7',
2248 'large_blue_circle':'\ud83d\udd35',
2249 'large_blue_diamond':'\ud83d\udd37',
2250 'large_orange_diamond':'\ud83d\udd36',
2251 'last_quarter_moon':'\ud83c\udf17',
2252 'last_quarter_moon_with_face':'\ud83c\udf1c',
2253 'latin_cross':'\u271d\ufe0f',
2254 'laughing':'\ud83d\ude06',
2255 'leaves':'\ud83c\udf43',
2256 'ledger':'\ud83d\udcd2',
2257 'left_luggage':'\ud83d\udec5',
2258 'left_right_arrow':'\u2194\ufe0f',
2259 'leftwards_arrow_with_hook':'\u21a9\ufe0f',
2260 'lemon':'\ud83c\udf4b',
2261 'leo':'\u264c\ufe0f',
2262 'leopard':'\ud83d\udc06',
2263 'level_slider':'\ud83c\udf9a',
2264 'libra':'\u264e\ufe0f',
2265 'light_rail':'\ud83d\ude88',
2266 'link':'\ud83d\udd17',
2267 'lion':'\ud83e\udd81',
2268 'lips':'\ud83d\udc44',
2269 'lipstick':'\ud83d\udc84',
2270 'lizard':'\ud83e\udd8e',
2271 'lock':'\ud83d\udd12',
2272 'lock_with_ink_pen':'\ud83d\udd0f',
2273 'lollipop':'\ud83c\udf6d',
2274 'loop':'\u27bf',
2275 'loud_sound':'\ud83d\udd0a',
2276 'loudspeaker':'\ud83d\udce2',
2277 'love_hotel':'\ud83c\udfe9',
2278 'love_letter':'\ud83d\udc8c',
2279 'low_brightness':'\ud83d\udd05',
2280 'lying_face':'\ud83e\udd25',
2281 'm':'\u24c2\ufe0f',
2282 'mag':'\ud83d\udd0d',
2283 'mag_right':'\ud83d\udd0e',
2284 'mahjong':'\ud83c\udc04\ufe0f',
2285 'mailbox':'\ud83d\udceb',
2286 'mailbox_closed':'\ud83d\udcea',
2287 'mailbox_with_mail':'\ud83d\udcec',
2288 'mailbox_with_no_mail':'\ud83d\udced',
2289 'man':'\ud83d\udc68',
2290 'man_artist':'\ud83d\udc68&zwj;\ud83c\udfa8',
2291 'man_astronaut':'\ud83d\udc68&zwj;\ud83d\ude80',
2292 'man_cartwheeling':'\ud83e\udd38&zwj;\u2642\ufe0f',
2293 'man_cook':'\ud83d\udc68&zwj;\ud83c\udf73',
2294 'man_dancing':'\ud83d\udd7a',
2295 'man_facepalming':'\ud83e\udd26&zwj;\u2642\ufe0f',
2296 'man_factory_worker':'\ud83d\udc68&zwj;\ud83c\udfed',
2297 'man_farmer':'\ud83d\udc68&zwj;\ud83c\udf3e',
2298 'man_firefighter':'\ud83d\udc68&zwj;\ud83d\ude92',
2299 'man_health_worker':'\ud83d\udc68&zwj;\u2695\ufe0f',
2300 'man_in_tuxedo':'\ud83e\udd35',
2301 'man_judge':'\ud83d\udc68&zwj;\u2696\ufe0f',
2302 'man_juggling':'\ud83e\udd39&zwj;\u2642\ufe0f',
2303 'man_mechanic':'\ud83d\udc68&zwj;\ud83d\udd27',
2304 'man_office_worker':'\ud83d\udc68&zwj;\ud83d\udcbc',
2305 'man_pilot':'\ud83d\udc68&zwj;\u2708\ufe0f',
2306 'man_playing_handball':'\ud83e\udd3e&zwj;\u2642\ufe0f',
2307 'man_playing_water_polo':'\ud83e\udd3d&zwj;\u2642\ufe0f',
2308 'man_scientist':'\ud83d\udc68&zwj;\ud83d\udd2c',
2309 'man_shrugging':'\ud83e\udd37&zwj;\u2642\ufe0f',
2310 'man_singer':'\ud83d\udc68&zwj;\ud83c\udfa4',
2311 'man_student':'\ud83d\udc68&zwj;\ud83c\udf93',
2312 'man_teacher':'\ud83d\udc68&zwj;\ud83c\udfeb',
2313 'man_technologist':'\ud83d\udc68&zwj;\ud83d\udcbb',
2314 'man_with_gua_pi_mao':'\ud83d\udc72',
2315 'man_with_turban':'\ud83d\udc73',
2316 'tangerine':'\ud83c\udf4a',
2317 'mans_shoe':'\ud83d\udc5e',
2318 'mantelpiece_clock':'\ud83d\udd70',
2319 'maple_leaf':'\ud83c\udf41',
2320 'martial_arts_uniform':'\ud83e\udd4b',
2321 'mask':'\ud83d\ude37',
2322 'massage_woman':'\ud83d\udc86',
2323 'massage_man':'\ud83d\udc86&zwj;\u2642\ufe0f',
2324 'meat_on_bone':'\ud83c\udf56',
2325 'medal_military':'\ud83c\udf96',
2326 'medal_sports':'\ud83c\udfc5',
2327 'mega':'\ud83d\udce3',
2328 'melon':'\ud83c\udf48',
2329 'memo':'\ud83d\udcdd',
2330 'men_wrestling':'\ud83e\udd3c&zwj;\u2642\ufe0f',
2331 'menorah':'\ud83d\udd4e',
2332 'mens':'\ud83d\udeb9',
2333 'metal':'\ud83e\udd18',
2334 'metro':'\ud83d\ude87',
2335 'microphone':'\ud83c\udfa4',
2336 'microscope':'\ud83d\udd2c',
2337 'milk_glass':'\ud83e\udd5b',
2338 'milky_way':'\ud83c\udf0c',
2339 'minibus':'\ud83d\ude90',
2340 'minidisc':'\ud83d\udcbd',
2341 'mobile_phone_off':'\ud83d\udcf4',
2342 'money_mouth_face':'\ud83e\udd11',
2343 'money_with_wings':'\ud83d\udcb8',
2344 'moneybag':'\ud83d\udcb0',
2345 'monkey':'\ud83d\udc12',
2346 'monkey_face':'\ud83d\udc35',
2347 'monorail':'\ud83d\ude9d',
2348 'moon':'\ud83c\udf14',
2349 'mortar_board':'\ud83c\udf93',
2350 'mosque':'\ud83d\udd4c',
2351 'motor_boat':'\ud83d\udee5',
2352 'motor_scooter':'\ud83d\udef5',
2353 'motorcycle':'\ud83c\udfcd',
2354 'motorway':'\ud83d\udee3',
2355 'mount_fuji':'\ud83d\uddfb',
2356 'mountain':'\u26f0',
2357 'mountain_biking_man':'\ud83d\udeb5',
2358 'mountain_biking_woman':'\ud83d\udeb5&zwj;\u2640\ufe0f',
2359 'mountain_cableway':'\ud83d\udea0',
2360 'mountain_railway':'\ud83d\ude9e',
2361 'mountain_snow':'\ud83c\udfd4',
2362 'mouse':'\ud83d\udc2d',
2363 'mouse2':'\ud83d\udc01',
2364 'movie_camera':'\ud83c\udfa5',
2365 'moyai':'\ud83d\uddff',
2366 'mrs_claus':'\ud83e\udd36',
2367 'muscle':'\ud83d\udcaa',
2368 'mushroom':'\ud83c\udf44',
2369 'musical_keyboard':'\ud83c\udfb9',
2370 'musical_note':'\ud83c\udfb5',
2371 'musical_score':'\ud83c\udfbc',
2372 'mute':'\ud83d\udd07',
2373 'nail_care':'\ud83d\udc85',
2374 'name_badge':'\ud83d\udcdb',
2375 'national_park':'\ud83c\udfde',
2376 'nauseated_face':'\ud83e\udd22',
2377 'necktie':'\ud83d\udc54',
2378 'negative_squared_cross_mark':'\u274e',
2379 'nerd_face':'\ud83e\udd13',
2380 'neutral_face':'\ud83d\ude10',
2381 'new':'\ud83c\udd95',
2382 'new_moon':'\ud83c\udf11',
2383 'new_moon_with_face':'\ud83c\udf1a',
2384 'newspaper':'\ud83d\udcf0',
2385 'newspaper_roll':'\ud83d\uddde',
2386 'next_track_button':'\u23ed',
2387 'ng':'\ud83c\udd96',
2388 'no_good_man':'\ud83d\ude45&zwj;\u2642\ufe0f',
2389 'no_good_woman':'\ud83d\ude45',
2390 'night_with_stars':'\ud83c\udf03',
2391 'no_bell':'\ud83d\udd15',
2392 'no_bicycles':'\ud83d\udeb3',
2393 'no_entry':'\u26d4\ufe0f',
2394 'no_entry_sign':'\ud83d\udeab',
2395 'no_mobile_phones':'\ud83d\udcf5',
2396 'no_mouth':'\ud83d\ude36',
2397 'no_pedestrians':'\ud83d\udeb7',
2398 'no_smoking':'\ud83d\udead',
2399 'non-potable_water':'\ud83d\udeb1',
2400 'nose':'\ud83d\udc43',
2401 'notebook':'\ud83d\udcd3',
2402 'notebook_with_decorative_cover':'\ud83d\udcd4',
2403 'notes':'\ud83c\udfb6',
2404 'nut_and_bolt':'\ud83d\udd29',
2405 'o':'\u2b55\ufe0f',
2406 'o2':'\ud83c\udd7e\ufe0f',
2407 'ocean':'\ud83c\udf0a',
2408 'octopus':'\ud83d\udc19',
2409 'oden':'\ud83c\udf62',
2410 'office':'\ud83c\udfe2',
2411 'oil_drum':'\ud83d\udee2',
2412 'ok':'\ud83c\udd97',
2413 'ok_hand':'\ud83d\udc4c',
2414 'ok_man':'\ud83d\ude46&zwj;\u2642\ufe0f',
2415 'ok_woman':'\ud83d\ude46',
2416 'old_key':'\ud83d\udddd',
2417 'older_man':'\ud83d\udc74',
2418 'older_woman':'\ud83d\udc75',
2419 'om':'\ud83d\udd49',
2420 'on':'\ud83d\udd1b',
2421 'oncoming_automobile':'\ud83d\ude98',
2422 'oncoming_bus':'\ud83d\ude8d',
2423 'oncoming_police_car':'\ud83d\ude94',
2424 'oncoming_taxi':'\ud83d\ude96',
2425 'open_file_folder':'\ud83d\udcc2',
2426 'open_hands':'\ud83d\udc50',
2427 'open_mouth':'\ud83d\ude2e',
2428 'open_umbrella':'\u2602\ufe0f',
2429 'ophiuchus':'\u26ce',
2430 'orange_book':'\ud83d\udcd9',
2431 'orthodox_cross':'\u2626\ufe0f',
2432 'outbox_tray':'\ud83d\udce4',
2433 'owl':'\ud83e\udd89',
2434 'ox':'\ud83d\udc02',
2435 'package':'\ud83d\udce6',
2436 'page_facing_up':'\ud83d\udcc4',
2437 'page_with_curl':'\ud83d\udcc3',
2438 'pager':'\ud83d\udcdf',
2439 'paintbrush':'\ud83d\udd8c',
2440 'palm_tree':'\ud83c\udf34',
2441 'pancakes':'\ud83e\udd5e',
2442 'panda_face':'\ud83d\udc3c',
2443 'paperclip':'\ud83d\udcce',
2444 'paperclips':'\ud83d\udd87',
2445 'parasol_on_ground':'\u26f1',
2446 'parking':'\ud83c\udd7f\ufe0f',
2447 'part_alternation_mark':'\u303d\ufe0f',
2448 'partly_sunny':'\u26c5\ufe0f',
2449 'passenger_ship':'\ud83d\udef3',
2450 'passport_control':'\ud83d\udec2',
2451 'pause_button':'\u23f8',
2452 'peace_symbol':'\u262e\ufe0f',
2453 'peach':'\ud83c\udf51',
2454 'peanuts':'\ud83e\udd5c',
2455 'pear':'\ud83c\udf50',
2456 'pen':'\ud83d\udd8a',
2457 'pencil2':'\u270f\ufe0f',
2458 'penguin':'\ud83d\udc27',
2459 'pensive':'\ud83d\ude14',
2460 'performing_arts':'\ud83c\udfad',
2461 'persevere':'\ud83d\ude23',
2462 'person_fencing':'\ud83e\udd3a',
2463 'pouting_woman':'\ud83d\ude4e',
2464 'phone':'\u260e\ufe0f',
2465 'pick':'\u26cf',
2466 'pig':'\ud83d\udc37',
2467 'pig2':'\ud83d\udc16',
2468 'pig_nose':'\ud83d\udc3d',
2469 'pill':'\ud83d\udc8a',
2470 'pineapple':'\ud83c\udf4d',
2471 'ping_pong':'\ud83c\udfd3',
2472 'pisces':'\u2653\ufe0f',
2473 'pizza':'\ud83c\udf55',
2474 'place_of_worship':'\ud83d\uded0',
2475 'plate_with_cutlery':'\ud83c\udf7d',
2476 'play_or_pause_button':'\u23ef',
2477 'point_down':'\ud83d\udc47',
2478 'point_left':'\ud83d\udc48',
2479 'point_right':'\ud83d\udc49',
2480 'point_up':'\u261d\ufe0f',
2481 'point_up_2':'\ud83d\udc46',
2482 'police_car':'\ud83d\ude93',
2483 'policewoman':'\ud83d\udc6e&zwj;\u2640\ufe0f',
2484 'poodle':'\ud83d\udc29',
2485 'popcorn':'\ud83c\udf7f',
2486 'post_office':'\ud83c\udfe3',
2487 'postal_horn':'\ud83d\udcef',
2488 'postbox':'\ud83d\udcee',
2489 'potable_water':'\ud83d\udeb0',
2490 'potato':'\ud83e\udd54',
2491 'pouch':'\ud83d\udc5d',
2492 'poultry_leg':'\ud83c\udf57',
2493 'pound':'\ud83d\udcb7',
2494 'rage':'\ud83d\ude21',
2495 'pouting_cat':'\ud83d\ude3e',
2496 'pouting_man':'\ud83d\ude4e&zwj;\u2642\ufe0f',
2497 'pray':'\ud83d\ude4f',
2498 'prayer_beads':'\ud83d\udcff',
2499 'pregnant_woman':'\ud83e\udd30',
2500 'previous_track_button':'\u23ee',
2501 'prince':'\ud83e\udd34',
2502 'princess':'\ud83d\udc78',
2503 'printer':'\ud83d\udda8',
2504 'purple_heart':'\ud83d\udc9c',
2505 'purse':'\ud83d\udc5b',
2506 'pushpin':'\ud83d\udccc',
2507 'put_litter_in_its_place':'\ud83d\udeae',
2508 'question':'\u2753',
2509 'rabbit':'\ud83d\udc30',
2510 'rabbit2':'\ud83d\udc07',
2511 'racehorse':'\ud83d\udc0e',
2512 'racing_car':'\ud83c\udfce',
2513 'radio':'\ud83d\udcfb',
2514 'radio_button':'\ud83d\udd18',
2515 'radioactive':'\u2622\ufe0f',
2516 'railway_car':'\ud83d\ude83',
2517 'railway_track':'\ud83d\udee4',
2518 'rainbow':'\ud83c\udf08',
2519 'rainbow_flag':'\ud83c\udff3\ufe0f&zwj;\ud83c\udf08',
2520 'raised_back_of_hand':'\ud83e\udd1a',
2521 'raised_hand_with_fingers_splayed':'\ud83d\udd90',
2522 'raised_hands':'\ud83d\ude4c',
2523 'raising_hand_woman':'\ud83d\ude4b',
2524 'raising_hand_man':'\ud83d\ude4b&zwj;\u2642\ufe0f',
2525 'ram':'\ud83d\udc0f',
2526 'ramen':'\ud83c\udf5c',
2527 'rat':'\ud83d\udc00',
2528 'record_button':'\u23fa',
2529 'recycle':'\u267b\ufe0f',
2530 'red_circle':'\ud83d\udd34',
2531 'registered':'\u00ae\ufe0f',
2532 'relaxed':'\u263a\ufe0f',
2533 'relieved':'\ud83d\ude0c',
2534 'reminder_ribbon':'\ud83c\udf97',
2535 'repeat':'\ud83d\udd01',
2536 'repeat_one':'\ud83d\udd02',
2537 'rescue_worker_helmet':'\u26d1',
2538 'restroom':'\ud83d\udebb',
2539 'revolving_hearts':'\ud83d\udc9e',
2540 'rewind':'\u23ea',
2541 'rhinoceros':'\ud83e\udd8f',
2542 'ribbon':'\ud83c\udf80',
2543 'rice':'\ud83c\udf5a',
2544 'rice_ball':'\ud83c\udf59',
2545 'rice_cracker':'\ud83c\udf58',
2546 'rice_scene':'\ud83c\udf91',
2547 'right_anger_bubble':'\ud83d\uddef',
2548 'ring':'\ud83d\udc8d',
2549 'robot':'\ud83e\udd16',
2550 'rocket':'\ud83d\ude80',
2551 'rofl':'\ud83e\udd23',
2552 'roll_eyes':'\ud83d\ude44',
2553 'roller_coaster':'\ud83c\udfa2',
2554 'rooster':'\ud83d\udc13',
2555 'rose':'\ud83c\udf39',
2556 'rosette':'\ud83c\udff5',
2557 'rotating_light':'\ud83d\udea8',
2558 'round_pushpin':'\ud83d\udccd',
2559 'rowing_man':'\ud83d\udea3',
2560 'rowing_woman':'\ud83d\udea3&zwj;\u2640\ufe0f',
2561 'rugby_football':'\ud83c\udfc9',
2562 'running_man':'\ud83c\udfc3',
2563 'running_shirt_with_sash':'\ud83c\udfbd',
2564 'running_woman':'\ud83c\udfc3&zwj;\u2640\ufe0f',
2565 'sa':'\ud83c\ude02\ufe0f',
2566 'sagittarius':'\u2650\ufe0f',
2567 'sake':'\ud83c\udf76',
2568 'sandal':'\ud83d\udc61',
2569 'santa':'\ud83c\udf85',
2570 'satellite':'\ud83d\udce1',
2571 'saxophone':'\ud83c\udfb7',
2572 'school':'\ud83c\udfeb',
2573 'school_satchel':'\ud83c\udf92',
2574 'scissors':'\u2702\ufe0f',
2575 'scorpion':'\ud83e\udd82',
2576 'scorpius':'\u264f\ufe0f',
2577 'scream':'\ud83d\ude31',
2578 'scream_cat':'\ud83d\ude40',
2579 'scroll':'\ud83d\udcdc',
2580 'seat':'\ud83d\udcba',
2581 'secret':'\u3299\ufe0f',
2582 'see_no_evil':'\ud83d\ude48',
2583 'seedling':'\ud83c\udf31',
2584 'selfie':'\ud83e\udd33',
2585 'shallow_pan_of_food':'\ud83e\udd58',
2586 'shamrock':'\u2618\ufe0f',
2587 'shark':'\ud83e\udd88',
2588 'shaved_ice':'\ud83c\udf67',
2589 'sheep':'\ud83d\udc11',
2590 'shell':'\ud83d\udc1a',
2591 'shield':'\ud83d\udee1',
2592 'shinto_shrine':'\u26e9',
2593 'ship':'\ud83d\udea2',
2594 'shirt':'\ud83d\udc55',
2595 'shopping':'\ud83d\udecd',
2596 'shopping_cart':'\ud83d\uded2',
2597 'shower':'\ud83d\udebf',
2598 'shrimp':'\ud83e\udd90',
2599 'signal_strength':'\ud83d\udcf6',
2600 'six_pointed_star':'\ud83d\udd2f',
2601 'ski':'\ud83c\udfbf',
2602 'skier':'\u26f7',
2603 'skull':'\ud83d\udc80',
2604 'skull_and_crossbones':'\u2620\ufe0f',
2605 'sleeping':'\ud83d\ude34',
2606 'sleeping_bed':'\ud83d\udecc',
2607 'sleepy':'\ud83d\ude2a',
2608 'slightly_frowning_face':'\ud83d\ude41',
2609 'slightly_smiling_face':'\ud83d\ude42',
2610 'slot_machine':'\ud83c\udfb0',
2611 'small_airplane':'\ud83d\udee9',
2612 'small_blue_diamond':'\ud83d\udd39',
2613 'small_orange_diamond':'\ud83d\udd38',
2614 'small_red_triangle':'\ud83d\udd3a',
2615 'small_red_triangle_down':'\ud83d\udd3b',
2616 'smile':'\ud83d\ude04',
2617 'smile_cat':'\ud83d\ude38',
2618 'smiley':'\ud83d\ude03',
2619 'smiley_cat':'\ud83d\ude3a',
2620 'smiling_imp':'\ud83d\ude08',
2621 'smirk':'\ud83d\ude0f',
2622 'smirk_cat':'\ud83d\ude3c',
2623 'smoking':'\ud83d\udeac',
2624 'snail':'\ud83d\udc0c',
2625 'snake':'\ud83d\udc0d',
2626 'sneezing_face':'\ud83e\udd27',
2627 'snowboarder':'\ud83c\udfc2',
2628 'snowflake':'\u2744\ufe0f',
2629 'snowman':'\u26c4\ufe0f',
2630 'snowman_with_snow':'\u2603\ufe0f',
2631 'sob':'\ud83d\ude2d',
2632 'soccer':'\u26bd\ufe0f',
2633 'soon':'\ud83d\udd1c',
2634 'sos':'\ud83c\udd98',
2635 'sound':'\ud83d\udd09',
2636 'space_invader':'\ud83d\udc7e',
2637 'spades':'\u2660\ufe0f',
2638 'spaghetti':'\ud83c\udf5d',
2639 'sparkle':'\u2747\ufe0f',
2640 'sparkler':'\ud83c\udf87',
2641 'sparkles':'\u2728',
2642 'sparkling_heart':'\ud83d\udc96',
2643 'speak_no_evil':'\ud83d\ude4a',
2644 'speaker':'\ud83d\udd08',
2645 'speaking_head':'\ud83d\udde3',
2646 'speech_balloon':'\ud83d\udcac',
2647 'speedboat':'\ud83d\udea4',
2648 'spider':'\ud83d\udd77',
2649 'spider_web':'\ud83d\udd78',
2650 'spiral_calendar':'\ud83d\uddd3',
2651 'spiral_notepad':'\ud83d\uddd2',
2652 'spoon':'\ud83e\udd44',
2653 'squid':'\ud83e\udd91',
2654 'stadium':'\ud83c\udfdf',
2655 'star':'\u2b50\ufe0f',
2656 'star2':'\ud83c\udf1f',
2657 'star_and_crescent':'\u262a\ufe0f',
2658 'star_of_david':'\u2721\ufe0f',
2659 'stars':'\ud83c\udf20',
2660 'station':'\ud83d\ude89',
2661 'statue_of_liberty':'\ud83d\uddfd',
2662 'steam_locomotive':'\ud83d\ude82',
2663 'stew':'\ud83c\udf72',
2664 'stop_button':'\u23f9',
2665 'stop_sign':'\ud83d\uded1',
2666 'stopwatch':'\u23f1',
2667 'straight_ruler':'\ud83d\udccf',
2668 'strawberry':'\ud83c\udf53',
2669 'stuck_out_tongue':'\ud83d\ude1b',
2670 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d',
2671 'stuck_out_tongue_winking_eye':'\ud83d\ude1c',
2672 'studio_microphone':'\ud83c\udf99',
2673 'stuffed_flatbread':'\ud83e\udd59',
2674 'sun_behind_large_cloud':'\ud83c\udf25',
2675 'sun_behind_rain_cloud':'\ud83c\udf26',
2676 'sun_behind_small_cloud':'\ud83c\udf24',
2677 'sun_with_face':'\ud83c\udf1e',
2678 'sunflower':'\ud83c\udf3b',
2679 'sunglasses':'\ud83d\ude0e',
2680 'sunny':'\u2600\ufe0f',
2681 'sunrise':'\ud83c\udf05',
2682 'sunrise_over_mountains':'\ud83c\udf04',
2683 'surfing_man':'\ud83c\udfc4',
2684 'surfing_woman':'\ud83c\udfc4&zwj;\u2640\ufe0f',
2685 'sushi':'\ud83c\udf63',
2686 'suspension_railway':'\ud83d\ude9f',
2687 'sweat':'\ud83d\ude13',
2688 'sweat_drops':'\ud83d\udca6',
2689 'sweat_smile':'\ud83d\ude05',
2690 'sweet_potato':'\ud83c\udf60',
2691 'swimming_man':'\ud83c\udfca',
2692 'swimming_woman':'\ud83c\udfca&zwj;\u2640\ufe0f',
2693 'symbols':'\ud83d\udd23',
2694 'synagogue':'\ud83d\udd4d',
2695 'syringe':'\ud83d\udc89',
2696 'taco':'\ud83c\udf2e',
2697 'tada':'\ud83c\udf89',
2698 'tanabata_tree':'\ud83c\udf8b',
2699 'taurus':'\u2649\ufe0f',
2700 'taxi':'\ud83d\ude95',
2701 'tea':'\ud83c\udf75',
2702 'telephone_receiver':'\ud83d\udcde',
2703 'telescope':'\ud83d\udd2d',
2704 'tennis':'\ud83c\udfbe',
2705 'tent':'\u26fa\ufe0f',
2706 'thermometer':'\ud83c\udf21',
2707 'thinking':'\ud83e\udd14',
2708 'thought_balloon':'\ud83d\udcad',
2709 'ticket':'\ud83c\udfab',
2710 'tickets':'\ud83c\udf9f',
2711 'tiger':'\ud83d\udc2f',
2712 'tiger2':'\ud83d\udc05',
2713 'timer_clock':'\u23f2',
2714 'tipping_hand_man':'\ud83d\udc81&zwj;\u2642\ufe0f',
2715 'tired_face':'\ud83d\ude2b',
2716 'tm':'\u2122\ufe0f',
2717 'toilet':'\ud83d\udebd',
2718 'tokyo_tower':'\ud83d\uddfc',
2719 'tomato':'\ud83c\udf45',
2720 'tongue':'\ud83d\udc45',
2721 'top':'\ud83d\udd1d',
2722 'tophat':'\ud83c\udfa9',
2723 'tornado':'\ud83c\udf2a',
2724 'trackball':'\ud83d\uddb2',
2725 'tractor':'\ud83d\ude9c',
2726 'traffic_light':'\ud83d\udea5',
2727 'train':'\ud83d\ude8b',
2728 'train2':'\ud83d\ude86',
2729 'tram':'\ud83d\ude8a',
2730 'triangular_flag_on_post':'\ud83d\udea9',
2731 'triangular_ruler':'\ud83d\udcd0',
2732 'trident':'\ud83d\udd31',
2733 'triumph':'\ud83d\ude24',
2734 'trolleybus':'\ud83d\ude8e',
2735 'trophy':'\ud83c\udfc6',
2736 'tropical_drink':'\ud83c\udf79',
2737 'tropical_fish':'\ud83d\udc20',
2738 'truck':'\ud83d\ude9a',
2739 'trumpet':'\ud83c\udfba',
2740 'tulip':'\ud83c\udf37',
2741 'tumbler_glass':'\ud83e\udd43',
2742 'turkey':'\ud83e\udd83',
2743 'turtle':'\ud83d\udc22',
2744 'tv':'\ud83d\udcfa',
2745 'twisted_rightwards_arrows':'\ud83d\udd00',
2746 'two_hearts':'\ud83d\udc95',
2747 'two_men_holding_hands':'\ud83d\udc6c',
2748 'two_women_holding_hands':'\ud83d\udc6d',
2749 'u5272':'\ud83c\ude39',
2750 'u5408':'\ud83c\ude34',
2751 'u55b6':'\ud83c\ude3a',
2752 'u6307':'\ud83c\ude2f\ufe0f',
2753 'u6708':'\ud83c\ude37\ufe0f',
2754 'u6709':'\ud83c\ude36',
2755 'u6e80':'\ud83c\ude35',
2756 'u7121':'\ud83c\ude1a\ufe0f',
2757 'u7533':'\ud83c\ude38',
2758 'u7981':'\ud83c\ude32',
2759 'u7a7a':'\ud83c\ude33',
2760 'umbrella':'\u2614\ufe0f',
2761 'unamused':'\ud83d\ude12',
2762 'underage':'\ud83d\udd1e',
2763 'unicorn':'\ud83e\udd84',
2764 'unlock':'\ud83d\udd13',
2765 'up':'\ud83c\udd99',
2766 'upside_down_face':'\ud83d\ude43',
2767 'v':'\u270c\ufe0f',
2768 'vertical_traffic_light':'\ud83d\udea6',
2769 'vhs':'\ud83d\udcfc',
2770 'vibration_mode':'\ud83d\udcf3',
2771 'video_camera':'\ud83d\udcf9',
2772 'video_game':'\ud83c\udfae',
2773 'violin':'\ud83c\udfbb',
2774 'virgo':'\u264d\ufe0f',
2775 'volcano':'\ud83c\udf0b',
2776 'volleyball':'\ud83c\udfd0',
2777 'vs':'\ud83c\udd9a',
2778 'vulcan_salute':'\ud83d\udd96',
2779 'walking_man':'\ud83d\udeb6',
2780 'walking_woman':'\ud83d\udeb6&zwj;\u2640\ufe0f',
2781 'waning_crescent_moon':'\ud83c\udf18',
2782 'waning_gibbous_moon':'\ud83c\udf16',
2783 'warning':'\u26a0\ufe0f',
2784 'wastebasket':'\ud83d\uddd1',
2785 'watch':'\u231a\ufe0f',
2786 'water_buffalo':'\ud83d\udc03',
2787 'watermelon':'\ud83c\udf49',
2788 'wave':'\ud83d\udc4b',
2789 'wavy_dash':'\u3030\ufe0f',
2790 'waxing_crescent_moon':'\ud83c\udf12',
2791 'wc':'\ud83d\udebe',
2792 'weary':'\ud83d\ude29',
2793 'wedding':'\ud83d\udc92',
2794 'weight_lifting_man':'\ud83c\udfcb\ufe0f',
2795 'weight_lifting_woman':'\ud83c\udfcb\ufe0f&zwj;\u2640\ufe0f',
2796 'whale':'\ud83d\udc33',
2797 'whale2':'\ud83d\udc0b',
2798 'wheel_of_dharma':'\u2638\ufe0f',
2799 'wheelchair':'\u267f\ufe0f',
2800 'white_check_mark':'\u2705',
2801 'white_circle':'\u26aa\ufe0f',
2802 'white_flag':'\ud83c\udff3\ufe0f',
2803 'white_flower':'\ud83d\udcae',
2804 'white_large_square':'\u2b1c\ufe0f',
2805 'white_medium_small_square':'\u25fd\ufe0f',
2806 'white_medium_square':'\u25fb\ufe0f',
2807 'white_small_square':'\u25ab\ufe0f',
2808 'white_square_button':'\ud83d\udd33',
2809 'wilted_flower':'\ud83e\udd40',
2810 'wind_chime':'\ud83c\udf90',
2811 'wind_face':'\ud83c\udf2c',
2812 'wine_glass':'\ud83c\udf77',
2813 'wink':'\ud83d\ude09',
2814 'wolf':'\ud83d\udc3a',
2815 'woman':'\ud83d\udc69',
2816 'woman_artist':'\ud83d\udc69&zwj;\ud83c\udfa8',
2817 'woman_astronaut':'\ud83d\udc69&zwj;\ud83d\ude80',
2818 'woman_cartwheeling':'\ud83e\udd38&zwj;\u2640\ufe0f',
2819 'woman_cook':'\ud83d\udc69&zwj;\ud83c\udf73',
2820 'woman_facepalming':'\ud83e\udd26&zwj;\u2640\ufe0f',
2821 'woman_factory_worker':'\ud83d\udc69&zwj;\ud83c\udfed',
2822 'woman_farmer':'\ud83d\udc69&zwj;\ud83c\udf3e',
2823 'woman_firefighter':'\ud83d\udc69&zwj;\ud83d\ude92',
2824 'woman_health_worker':'\ud83d\udc69&zwj;\u2695\ufe0f',
2825 'woman_judge':'\ud83d\udc69&zwj;\u2696\ufe0f',
2826 'woman_juggling':'\ud83e\udd39&zwj;\u2640\ufe0f',
2827 'woman_mechanic':'\ud83d\udc69&zwj;\ud83d\udd27',
2828 'woman_office_worker':'\ud83d\udc69&zwj;\ud83d\udcbc',
2829 'woman_pilot':'\ud83d\udc69&zwj;\u2708\ufe0f',
2830 'woman_playing_handball':'\ud83e\udd3e&zwj;\u2640\ufe0f',
2831 'woman_playing_water_polo':'\ud83e\udd3d&zwj;\u2640\ufe0f',
2832 'woman_scientist':'\ud83d\udc69&zwj;\ud83d\udd2c',
2833 'woman_shrugging':'\ud83e\udd37&zwj;\u2640\ufe0f',
2834 'woman_singer':'\ud83d\udc69&zwj;\ud83c\udfa4',
2835 'woman_student':'\ud83d\udc69&zwj;\ud83c\udf93',
2836 'woman_teacher':'\ud83d\udc69&zwj;\ud83c\udfeb',
2837 'woman_technologist':'\ud83d\udc69&zwj;\ud83d\udcbb',
2838 'woman_with_turban':'\ud83d\udc73&zwj;\u2640\ufe0f',
2839 'womans_clothes':'\ud83d\udc5a',
2840 'womans_hat':'\ud83d\udc52',
2841 'women_wrestling':'\ud83e\udd3c&zwj;\u2640\ufe0f',
2842 'womens':'\ud83d\udeba',
2843 'world_map':'\ud83d\uddfa',
2844 'worried':'\ud83d\ude1f',
2845 'wrench':'\ud83d\udd27',
2846 'writing_hand':'\u270d\ufe0f',
2847 'x':'\u274c',
2848 'yellow_heart':'\ud83d\udc9b',
2849 'yen':'\ud83d\udcb4',
2850 'yin_yang':'\u262f\ufe0f',
2851 'yum':'\ud83d\ude0b',
2852 'zap':'\u26a1\ufe0f',
2853 'zipper_mouth_face':'\ud83e\udd10',
2854 'zzz':'\ud83d\udca4',
2855
2856 /* special emojis :P */
2857 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">',
2858 'showdown': '<span style="font-family: \'Anonymous Pro\', monospace; text-decoration: underline; text-decoration-style: dashed; text-decoration-color: #3e8b8a;text-underline-position: under;">S</span>'
2859 };
2860
2861 /**
2862 * Created by Estevao on 31-05-2015.
2863 */
2864
2865 /**
2866 * Showdown Converter class
2867 * @class
2868 * @param {object} [converterOptions]
2869 * @returns {Converter}
2870 */
2871 showdown.Converter = function (converterOptions) {
2872 'use strict';
2873
2874 var
2875 /**
2876 * Options used by this converter
2877 * @private
2878 * @type {{}}
2879 */
2880 options = {},
2881
2882 /**
2883 * Language extensions used by this converter
2884 * @private
2885 * @type {Array}
2886 */
2887 langExtensions = [],
2888
2889 /**
2890 * Output modifiers extensions used by this converter
2891 * @private
2892 * @type {Array}
2893 */
2894 outputModifiers = [],
2895
2896 /**
2897 * Event listeners
2898 * @private
2899 * @type {{}}
2900 */
2901 listeners = {},
2902
2903 /**
2904 * The flavor set in this converter
2905 */
2906 setConvFlavor = setFlavor,
2907
2908 /**
2909 * Metadata of the document
2910 * @type {{parsed: {}, raw: string, format: string}}
2911 */
2912 metadata = {
2913 parsed: {},
2914 raw: '',
2915 format: ''
2916 };
2917
2918 _constructor();
2919
2920 /**
2921 * Converter constructor
2922 * @private
2923 */
2924 function _constructor () {
2925 converterOptions = converterOptions || {};
2926
2927 for (var gOpt in globalOptions) {
2928 if (globalOptions.hasOwnProperty(gOpt)) {
2929 options[gOpt] = globalOptions[gOpt];
2930 }
2931 }
2932
2933 // Merge options
2934 if (typeof converterOptions === 'object') {
2935 for (var opt in converterOptions) {
2936 if (converterOptions.hasOwnProperty(opt)) {
2937 options[opt] = converterOptions[opt];
2938 }
2939 }
2940 } else {
2941 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions +
2942 ' was passed instead.');
2943 }
2944
2945 if (options.extensions) {
2946 showdown.helper.forEach(options.extensions, _parseExtension);
2947 }
2948 }
2949
2950 /**
2951 * Parse extension
2952 * @param {*} ext
2953 * @param {string} [name='']
2954 * @private
2955 */
2956 function _parseExtension (ext, name) {
2957
2958 name = name || null;
2959 // If it's a string, the extension was previously loaded
2960 if (showdown.helper.isString(ext)) {
2961 ext = showdown.helper.stdExtName(ext);
2962 name = ext;
2963
2964 // LEGACY_SUPPORT CODE
2965 if (showdown.extensions[ext]) {
2966 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' +
2967 'Please inform the developer that the extension should be updated!');
2968 legacyExtensionLoading(showdown.extensions[ext], ext);
2969 return;
2970 // END LEGACY SUPPORT CODE
2971
2972 } else if (!showdown.helper.isUndefined(extensions[ext])) {
2973 ext = extensions[ext];
2974
2975 } else {
2976 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.');
2977 }
2978 }
2979
2980 if (typeof ext === 'function') {
2981 ext = ext();
2982 }
2983
2984 if (!showdown.helper.isArray(ext)) {
2985 ext = [ext];
2986 }
2987
2988 var validExt = validate(ext, name);
2989 if (!validExt.valid) {
2990 throw Error(validExt.error);
2991 }
2992
2993 for (var i = 0; i < ext.length; ++i) {
2994 switch (ext[i].type) {
2995
2996 case 'lang':
2997 langExtensions.push(ext[i]);
2998 break;
2999
3000 case 'output':
3001 outputModifiers.push(ext[i]);
3002 break;
3003 }
3004 if (ext[i].hasOwnProperty('listeners')) {
3005 for (var ln in ext[i].listeners) {
3006 if (ext[i].listeners.hasOwnProperty(ln)) {
3007 listen(ln, ext[i].listeners[ln]);
3008 }
3009 }
3010 }
3011 }
3012
3013 }
3014
3015 /**
3016 * LEGACY_SUPPORT
3017 * @param {*} ext
3018 * @param {string} name
3019 */
3020 function legacyExtensionLoading (ext, name) {
3021 if (typeof ext === 'function') {
3022 ext = ext(new showdown.Converter());
3023 }
3024 if (!showdown.helper.isArray(ext)) {
3025 ext = [ext];
3026 }
3027 var valid = validate(ext, name);
3028
3029 if (!valid.valid) {
3030 throw Error(valid.error);
3031 }
3032
3033 for (var i = 0; i < ext.length; ++i) {
3034 switch (ext[i].type) {
3035 case 'lang':
3036 langExtensions.push(ext[i]);
3037 break;
3038 case 'output':
3039 outputModifiers.push(ext[i]);
3040 break;
3041 default:// should never reach here
3042 throw Error('Extension loader error: Type unrecognized!!!');
3043 }
3044 }
3045 }
3046
3047 /**
3048 * Listen to an event
3049 * @param {string} name
3050 * @param {function} callback
3051 */
3052 function listen (name, callback) {
3053 if (!showdown.helper.isString(name)) {
3054 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given');
3055 }
3056
3057 if (typeof callback !== 'function') {
3058 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given');
3059 }
3060
3061 if (!listeners.hasOwnProperty(name)) {
3062 listeners[name] = [];
3063 }
3064 listeners[name].push(callback);
3065 }
3066
3067 function rTrimInputText (text) {
3068 var rsp = text.match(/^\s*/)[0].length,
3069 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm');
3070 return text.replace(rgx, '');
3071 }
3072
3073 /**
3074 * Dispatch an event
3075 * @private
3076 * @param {string} evtName Event name
3077 * @param {string} text Text
3078 * @param {{}} options Converter Options
3079 * @param {{}} globals
3080 * @returns {string}
3081 */
3082 this._dispatch = function dispatch (evtName, text, options, globals) {
3083 if (listeners.hasOwnProperty(evtName)) {
3084 for (var ei = 0; ei < listeners[evtName].length; ++ei) {
3085 var nText = listeners[evtName][ei](evtName, text, this, options, globals);
3086 if (nText && typeof nText !== 'undefined') {
3087 text = nText;
3088 }
3089 }
3090 }
3091 return text;
3092 };
3093
3094 /**
3095 * Listen to an event
3096 * @param {string} name
3097 * @param {function} callback
3098 * @returns {showdown.Converter}
3099 */
3100 this.listen = function (name, callback) {
3101 listen(name, callback);
3102 return this;
3103 };
3104
3105 /**
3106 * Converts a markdown string into HTML
3107 * @param {string} text
3108 * @returns {*}
3109 */
3110 this.makeHtml = function (text) {
3111 //check if text is not falsy
3112 if (!text) {
3113 return text;
3114 }
3115
3116 var globals = {
3117 gHtmlBlocks: [],
3118 gHtmlMdBlocks: [],
3119 gHtmlSpans: [],
3120 gUrls: {},
3121 gTitles: {},
3122 gDimensions: {},
3123 gListLevel: 0,
3124 hashLinkCounts: {},
3125 langExtensions: langExtensions,
3126 outputModifiers: outputModifiers,
3127 converter: this,
3128 ghCodeBlocks: [],
3129 metadata: {
3130 parsed: {},
3131 raw: '',
3132 format: ''
3133 }
3134 };
3135
3136 // This lets us use ¨ trema as an escape char to avoid md5 hashes
3137 // The choice of character is arbitrary; anything that isn't
3138 // magic in Markdown will work.
3139 text = text.replace(/¨/g, '¨T');
3140
3141 // Replace $ with ¨D
3142 // RegExp interprets $ as a special character
3143 // when it's in a replacement string
3144 text = text.replace(/\$/g, '¨D');
3145
3146 // Standardize line endings
3147 text = text.replace(/\r\n/g, '\n'); // DOS to Unix
3148 text = text.replace(/\r/g, '\n'); // Mac to Unix
3149
3150 // Stardardize line spaces
3151 text = text.replace(/\u00A0/g, '&nbsp;');
3152
3153 if (options.smartIndentationFix) {
3154 text = rTrimInputText(text);
3155 }
3156
3157 // Make sure text begins and ends with a couple of newlines:
3158 text = '\n\n' + text + '\n\n';
3159
3160 // detab
3161 text = showdown.subParser('detab')(text, options, globals);
3162
3163 /**
3164 * Strip any lines consisting only of spaces and tabs.
3165 * This makes subsequent regexs easier to write, because we can
3166 * match consecutive blank lines with /\n+/ instead of something
3167 * contorted like /[ \t]*\n+/
3168 */
3169 text = text.replace(/^[ \t]+$/mg, '');
3170
3171 //run languageExtensions
3172 showdown.helper.forEach(langExtensions, function (ext) {
3173 text = showdown.subParser('runExtension')(ext, text, options, globals);
3174 });
3175
3176 // run the sub parsers
3177 text = showdown.subParser('metadata')(text, options, globals);
3178 text = showdown.subParser('hashPreCodeTags')(text, options, globals);
3179 text = showdown.subParser('githubCodeBlocks')(text, options, globals);
3180 text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
3181 text = showdown.subParser('hashCodeTags')(text, options, globals);
3182 text = showdown.subParser('stripLinkDefinitions')(text, options, globals);
3183 text = showdown.subParser('blockGamut')(text, options, globals);
3184 text = showdown.subParser('unhashHTMLSpans')(text, options, globals);
3185 text = showdown.subParser('unescapeSpecialChars')(text, options, globals);
3186
3187 // attacklab: Restore dollar signs
3188 text = text.replace(/¨D/g, '$$');
3189
3190 // attacklab: Restore tremas
3191 text = text.replace(/¨T/g, '¨');
3192
3193 // render a complete html document instead of a partial if the option is enabled
3194 text = showdown.subParser('completeHTMLDocument')(text, options, globals);
3195
3196 // Run output modifiers
3197 showdown.helper.forEach(outputModifiers, function (ext) {
3198 text = showdown.subParser('runExtension')(ext, text, options, globals);
3199 });
3200
3201 // update metadata
3202 metadata = globals.metadata;
3203 return text;
3204 };
3205
3206 /**
3207 * Converts an HTML string into a markdown string
3208 * @param src
3209 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used.
3210 * @returns {string}
3211 */
3212 this.makeMarkdown = this.makeMd = function (src, HTMLParser) {
3213
3214 // replace \r\n with \n
3215 src = src.replace(/\r\n/g, '\n');
3216 src = src.replace(/\r/g, '\n'); // old macs
3217
3218 // due to an edge case, we need to find this: > <
3219 // to prevent removing of non silent white spaces
3220 // ex: <em>this is</em> <strong>sparta</strong>
3221 src = src.replace(/>[ \t]+</, '>¨NBSP;<');
3222
3223 if (!HTMLParser) {
3224 if (window && window.document) {
3225 HTMLParser = window.document;
3226 } else {
3227 throw new Error('HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM');
3228 }
3229 }
3230
3231 var doc = HTMLParser.createElement('div');
3232 doc.innerHTML = src;
3233
3234 var globals = {
3235 preList: substitutePreCodeTags(doc)
3236 };
3237
3238 // remove all newlines and collapse spaces
3239 clean(doc);
3240
3241 // some stuff, like accidental reference links must now be escaped
3242 // TODO
3243 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/);
3244
3245 var nodes = doc.childNodes,
3246 mdDoc = '';
3247
3248 for (var i = 0; i < nodes.length; i++) {
3249 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals);
3250 }
3251
3252 function clean (node) {
3253 for (var n = 0; n < node.childNodes.length; ++n) {
3254 var child = node.childNodes[n];
3255 if (child.nodeType === 3) {
3256 if (!/\S/.test(child.nodeValue)) {
3257 node.removeChild(child);
3258 --n;
3259 } else {
3260 child.nodeValue = child.nodeValue.split('\n').join(' ');
3261 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1');
3262 }
3263 } else if (child.nodeType === 1) {
3264 clean(child);
3265 }
3266 }
3267 }
3268
3269 // find all pre tags and replace contents with placeholder
3270 // we need this so that we can remove all indentation from html
3271 // to ease up parsing
3272 function substitutePreCodeTags (doc) {
3273
3274 var pres = doc.querySelectorAll('pre'),
3275 presPH = [];
3276
3277 for (var i = 0; i < pres.length; ++i) {
3278
3279 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') {
3280 var content = pres[i].firstChild.innerHTML.trim(),
3281 language = pres[i].firstChild.getAttribute('data-language') || '';
3282
3283 // if data-language attribute is not defined, then we look for class language-*
3284 if (language === '') {
3285 var classes = pres[i].firstChild.className.split(' ');
3286 for (var c = 0; c < classes.length; ++c) {
3287 var matches = classes[c].match(/^language-(.+)$/);
3288 if (matches !== null) {
3289 language = matches[1];
3290 break;
3291 }
3292 }
3293 }
3294
3295 // unescape html entities in content
3296 content = showdown.helper.unescapeHTMLEntities(content);
3297
3298 presPH.push(content);
3299 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>';
3300 } else {
3301 presPH.push(pres[i].innerHTML);
3302 pres[i].innerHTML = '';
3303 pres[i].setAttribute('prenum', i.toString());
3304 }
3305 }
3306 return presPH;
3307 }
3308
3309 return mdDoc;
3310 };
3311
3312 /**
3313 * Set an option of this Converter instance
3314 * @param {string} key
3315 * @param {*} value
3316 */
3317 this.setOption = function (key, value) {
3318 options[key] = value;
3319 };
3320
3321 /**
3322 * Get the option of this Converter instance
3323 * @param {string} key
3324 * @returns {*}
3325 */
3326 this.getOption = function (key) {
3327 return options[key];
3328 };
3329
3330 /**
3331 * Get the options of this Converter instance
3332 * @returns {{}}
3333 */
3334 this.getOptions = function () {
3335 return options;
3336 };
3337
3338 /**
3339 * Add extension to THIS converter
3340 * @param {{}} extension
3341 * @param {string} [name=null]
3342 */
3343 this.addExtension = function (extension, name) {
3344 name = name || null;
3345 _parseExtension(extension, name);
3346 };
3347
3348 /**
3349 * Use a global registered extension with THIS converter
3350 * @param {string} extensionName Name of the previously registered extension
3351 */
3352 this.useExtension = function (extensionName) {
3353 _parseExtension(extensionName);
3354 };
3355
3356 /**
3357 * Set the flavor THIS converter should use
3358 * @param {string} name
3359 */
3360 this.setFlavor = function (name) {
3361 if (!flavor.hasOwnProperty(name)) {
3362 throw Error(name + ' flavor was not found');
3363 }
3364 var preset = flavor[name];
3365 setConvFlavor = name;
3366 for (var option in preset) {
3367 if (preset.hasOwnProperty(option)) {
3368 options[option] = preset[option];
3369 }
3370 }
3371 };
3372
3373 /**
3374 * Get the currently set flavor of this converter
3375 * @returns {string}
3376 */
3377 this.getFlavor = function () {
3378 return setConvFlavor;
3379 };
3380
3381 /**
3382 * Remove an extension from THIS converter.
3383 * Note: This is a costly operation. It's better to initialize a new converter
3384 * and specify the extensions you wish to use
3385 * @param {Array} extension
3386 */
3387 this.removeExtension = function (extension) {
3388 if (!showdown.helper.isArray(extension)) {
3389 extension = [extension];
3390 }
3391 for (var a = 0; a < extension.length; ++a) {
3392 var ext = extension[a];
3393 for (var i = 0; i < langExtensions.length; ++i) {
3394 if (langExtensions[i] === ext) {
3395 langExtensions[i].splice(i, 1);
3396 }
3397 }
3398 for (var ii = 0; ii < outputModifiers.length; ++i) {
3399 if (outputModifiers[ii] === ext) {
3400 outputModifiers[ii].splice(i, 1);
3401 }
3402 }
3403 }
3404 };
3405
3406 /**
3407 * Get all extension of THIS converter
3408 * @returns {{language: Array, output: Array}}
3409 */
3410 this.getAllExtensions = function () {
3411 return {
3412 language: langExtensions,
3413 output: outputModifiers
3414 };
3415 };
3416
3417 /**
3418 * Get the metadata of the previously parsed document
3419 * @param raw
3420 * @returns {string|{}}
3421 */
3422 this.getMetadata = function (raw) {
3423 if (raw) {
3424 return metadata.raw;
3425 } else {
3426 return metadata.parsed;
3427 }
3428 };
3429
3430 /**
3431 * Get the metadata format of the previously parsed document
3432 * @returns {string}
3433 */
3434 this.getMetadataFormat = function () {
3435 return metadata.format;
3436 };
3437
3438 /**
3439 * Private: set a single key, value metadata pair
3440 * @param {string} key
3441 * @param {string} value
3442 */
3443 this._setMetadataPair = function (key, value) {
3444 metadata.parsed[key] = value;
3445 };
3446
3447 /**
3448 * Private: set metadata format
3449 * @param {string} format
3450 */
3451 this._setMetadataFormat = function (format) {
3452 metadata.format = format;
3453 };
3454
3455 /**
3456 * Private: set metadata raw text
3457 * @param {string} raw
3458 */
3459 this._setMetadataRaw = function (raw) {
3460 metadata.raw = raw;
3461 };
3462 };
3463
3464 /**
3465 * Turn Markdown link shortcuts into XHTML <a> tags.
3466 */
3467 showdown.subParser('anchors', function (text, options, globals) {
3468 'use strict';
3469
3470 text = globals.converter._dispatch('anchors.before', text, options, globals);
3471
3472 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) {
3473 if (showdown.helper.isUndefined(title)) {
3474 title = '';
3475 }
3476 linkId = linkId.toLowerCase();
3477
3478 // Special case for explicit empty url
3479 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
3480 url = '';
3481 } else if (!url) {
3482 if (!linkId) {
3483 // lower-case and turn embedded newlines into spaces
3484 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
3485 }
3486 url = '#' + linkId;
3487
3488 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {
3489 url = globals.gUrls[linkId];
3490 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
3491 title = globals.gTitles[linkId];
3492 }
3493 } else {
3494 return wholeMatch;
3495 }
3496 }
3497
3498 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance
3499 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3500
3501 var result = '<a href="' + url + '"';
3502
3503 if (title !== '' && title !== null) {
3504 title = title.replace(/"/g, '&quot;');
3505 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance
3506 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3507 result += ' title="' + title + '"';
3508 }
3509
3510 // optionLinksInNewWindow only applies
3511 // to external links. Hash links (#) open in same page
3512 if (options.openLinksInNewWindow && !/^#/.test(url)) {
3513 // escaped _
3514 result += ' rel="noopener noreferrer" target="¨E95Eblank"';
3515 }
3516
3517 result += '>' + linkText + '</a>';
3518
3519 return result;
3520 };
3521
3522 // First, handle reference-style links: [link text] [id]
3523 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag);
3524
3525 // Next, inline-style links: [link text](url "optional title")
3526 // cases with crazy urls like ./image/cat1).png
3527 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
3528 writeAnchorTag);
3529
3530 // normal cases
3531 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
3532 writeAnchorTag);
3533
3534 // handle reference-style shortcuts: [link text]
3535 // These must come last in case you've also got [link test][1]
3536 // or [link test](/foo)
3537 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag);
3538
3539 // Lastly handle GithubMentions if option is enabled
3540 if (options.ghMentions) {
3541 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) {
3542 if (escape === '\\') {
3543 return st + mentions;
3544 }
3545
3546 //check if options.ghMentionsLink is a string
3547 if (!showdown.helper.isString(options.ghMentionsLink)) {
3548 throw new Error('ghMentionsLink option must be a string');
3549 }
3550 var lnk = options.ghMentionsLink.replace(/\{u}/g, username),
3551 target = '';
3552 if (options.openLinksInNewWindow) {
3553 target = ' rel="noopener noreferrer" target="¨E95Eblank"';
3554 }
3555 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>';
3556 });
3557 }
3558
3559 text = globals.converter._dispatch('anchors.after', text, options, globals);
3560 return text;
3561 });
3562
3563 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-]
3564
3565 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,
3566 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,
3567 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,
3568 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi,
3569 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
3570
3571 replaceLink = function (options) {
3572 'use strict';
3573 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) {
3574 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3575 var lnkTxt = link,
3576 append = '',
3577 target = '',
3578 lmc = leadingMagicChars || '',
3579 tmc = trailingMagicChars || '';
3580 if (/^www\./i.test(link)) {
3581 link = link.replace(/^www\./i, 'http://www.');
3582 }
3583 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) {
3584 append = trailingPunctuation;
3585 }
3586 if (options.openLinksInNewWindow) {
3587 target = ' rel="noopener noreferrer" target="¨E95Eblank"';
3588 }
3589 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc;
3590 };
3591 },
3592
3593 replaceMail = function (options, globals) {
3594 'use strict';
3595 return function (wholeMatch, b, mail) {
3596 var href = 'mailto:';
3597 b = b || '';
3598 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals);
3599 if (options.encodeEmails) {
3600 href = showdown.helper.encodeEmailAddress(href + mail);
3601 mail = showdown.helper.encodeEmailAddress(mail);
3602 } else {
3603 href = href + mail;
3604 }
3605 return b + '<a href="' + href + '">' + mail + '</a>';
3606 };
3607 };
3608
3609 showdown.subParser('autoLinks', function (text, options, globals) {
3610 'use strict';
3611
3612 text = globals.converter._dispatch('autoLinks.before', text, options, globals);
3613
3614 text = text.replace(delimUrlRegex, replaceLink(options));
3615 text = text.replace(delimMailRegex, replaceMail(options, globals));
3616
3617 text = globals.converter._dispatch('autoLinks.after', text, options, globals);
3618
3619 return text;
3620 });
3621
3622 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) {
3623 'use strict';
3624
3625 if (!options.simplifiedAutoLink) {
3626 return text;
3627 }
3628
3629 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals);
3630
3631 if (options.excludeTrailingPunctuationFromURLs) {
3632 text = text.replace(simpleURLRegex2, replaceLink(options));
3633 } else {
3634 text = text.replace(simpleURLRegex, replaceLink(options));
3635 }
3636 text = text.replace(simpleMailRegex, replaceMail(options, globals));
3637
3638 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals);
3639
3640 return text;
3641 });
3642
3643 /**
3644 * These are all the transformations that form block-level
3645 * tags like paragraphs, headers, and list items.
3646 */
3647 showdown.subParser('blockGamut', function (text, options, globals) {
3648 'use strict';
3649
3650 text = globals.converter._dispatch('blockGamut.before', text, options, globals);
3651
3652 // we parse blockquotes first so that we can have headings and hrs
3653 // inside blockquotes
3654 text = showdown.subParser('blockQuotes')(text, options, globals);
3655 text = showdown.subParser('headers')(text, options, globals);
3656
3657 // Do Horizontal Rules:
3658 text = showdown.subParser('horizontalRule')(text, options, globals);
3659
3660 text = showdown.subParser('lists')(text, options, globals);
3661 text = showdown.subParser('codeBlocks')(text, options, globals);
3662 text = showdown.subParser('tables')(text, options, globals);
3663
3664 // We already ran _HashHTMLBlocks() before, in Markdown(), but that
3665 // was to escape raw HTML in the original Markdown source. This time,
3666 // we're escaping the markup we've just created, so that we don't wrap
3667 // <p> tags around block-level tags.
3668 text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
3669 text = showdown.subParser('paragraphs')(text, options, globals);
3670
3671 text = globals.converter._dispatch('blockGamut.after', text, options, globals);
3672
3673 return text;
3674 });
3675
3676 showdown.subParser('blockQuotes', function (text, options, globals) {
3677 'use strict';
3678
3679 text = globals.converter._dispatch('blockQuotes.before', text, options, globals);
3680
3681 // add a couple extra lines after the text and endtext mark
3682 text = text + '\n\n';
3683
3684 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;
3685
3686 if (options.splitAdjacentBlockquotes) {
3687 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm;
3688 }
3689
3690 text = text.replace(rgx, function (bq) {
3691 // attacklab: hack around Konqueror 3.5.4 bug:
3692 // "----------bug".replace(/^-/g,"") == "bug"
3693 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting
3694
3695 // attacklab: clean up hack
3696 bq = bq.replace(/¨0/g, '');
3697
3698 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines
3699 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals);
3700 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse
3701
3702 bq = bq.replace(/(^|\n)/g, '$1 ');
3703 // These leading spaces screw with <pre> content, so we need to fix that:
3704 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) {
3705 var pre = m1;
3706 // attacklab: hack around Konqueror 3.5.4 bug:
3707 pre = pre.replace(/^ /mg, '¨0');
3708 pre = pre.replace(/¨0/g, '');
3709 return pre;
3710 });
3711
3712 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals);
3713 });
3714
3715 text = globals.converter._dispatch('blockQuotes.after', text, options, globals);
3716 return text;
3717 });
3718
3719 /**
3720 * Process Markdown `<pre><code>` blocks.
3721 */
3722 showdown.subParser('codeBlocks', function (text, options, globals) {
3723 'use strict';
3724
3725 text = globals.converter._dispatch('codeBlocks.before', text, options, globals);
3726
3727 // sentinel workarounds for lack of \A and \Z, safari\khtml bug
3728 text += '¨0';
3729
3730 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;
3731 text = text.replace(pattern, function (wholeMatch, m1, m2) {
3732 var codeblock = m1,
3733 nextChar = m2,
3734 end = '\n';
3735
3736 codeblock = showdown.subParser('outdent')(codeblock, options, globals);
3737 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
3738 codeblock = showdown.subParser('detab')(codeblock, options, globals);
3739 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
3740 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
3741
3742 if (options.omitExtraWLInCodeBlocks) {
3743 end = '';
3744 }
3745
3746 codeblock = '<pre><code>' + codeblock + end + '</code></pre>';
3747
3748 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar;
3749 });
3750
3751 // strip sentinel
3752 text = text.replace(/¨0/, '');
3753
3754 text = globals.converter._dispatch('codeBlocks.after', text, options, globals);
3755 return text;
3756 });
3757
3758 /**
3759 *
3760 * * Backtick quotes are used for <code></code> spans.
3761 *
3762 * * You can use multiple backticks as the delimiters if you want to
3763 * include literal backticks in the code span. So, this input:
3764 *
3765 * Just type ``foo `bar` baz`` at the prompt.
3766 *
3767 * Will translate to:
3768 *
3769 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
3770 *
3771 * There's no arbitrary limit to the number of backticks you
3772 * can use as delimters. If you need three consecutive backticks
3773 * in your code, use four for delimiters, etc.
3774 *
3775 * * You can use spaces to get literal backticks at the edges:
3776 *
3777 * ... type `` `bar` `` ...
3778 *
3779 * Turns to:
3780 *
3781 * ... type <code>`bar`</code> ...
3782 */
3783 showdown.subParser('codeSpans', function (text, options, globals) {
3784 'use strict';
3785
3786 text = globals.converter._dispatch('codeSpans.before', text, options, globals);
3787
3788 if (typeof text === 'undefined') {
3789 text = '';
3790 }
3791 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
3792 function (wholeMatch, m1, m2, m3) {
3793 var c = m3;
3794 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace
3795 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace
3796 c = showdown.subParser('encodeCode')(c, options, globals);
3797 c = m1 + '<code>' + c + '</code>';
3798 c = showdown.subParser('hashHTMLSpans')(c, options, globals);
3799 return c;
3800 }
3801 );
3802
3803 text = globals.converter._dispatch('codeSpans.after', text, options, globals);
3804 return text;
3805 });
3806
3807 /**
3808 * Create a full HTML document from the processed markdown
3809 */
3810 showdown.subParser('completeHTMLDocument', function (text, options, globals) {
3811 'use strict';
3812
3813 if (!options.completeHTMLDocument) {
3814 return text;
3815 }
3816
3817 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);
3818
3819 var doctype = 'html',
3820 doctypeParsed = '<!DOCTYPE HTML>\n',
3821 title = '',
3822 charset = '<meta charset="utf-8">\n',
3823 lang = '',
3824 metadata = '';
3825
3826 if (typeof globals.metadata.parsed.doctype !== 'undefined') {
3827 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n';
3828 doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
3829 if (doctype === 'html' || doctype === 'html5') {
3830 charset = '<meta charset="utf-8">';
3831 }
3832 }
3833
3834 for (var meta in globals.metadata.parsed) {
3835 if (globals.metadata.parsed.hasOwnProperty(meta)) {
3836 switch (meta.toLowerCase()) {
3837 case 'doctype':
3838 break;
3839
3840 case 'title':
3841 title = '<title>' + globals.metadata.parsed.title + '</title>\n';
3842 break;
3843
3844 case 'charset':
3845 if (doctype === 'html' || doctype === 'html5') {
3846 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n';
3847 } else {
3848 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n';
3849 }
3850 break;
3851
3852 case 'language':
3853 case 'lang':
3854 lang = ' lang="' + globals.metadata.parsed[meta] + '"';
3855 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3856 break;
3857
3858 default:
3859 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3860 }
3861 }
3862 }
3863
3864 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
3865
3866 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
3867 return text;
3868 });
3869
3870 /**
3871 * Convert all tabs to spaces
3872 */
3873 showdown.subParser('detab', function (text, options, globals) {
3874 'use strict';
3875 text = globals.converter._dispatch('detab.before', text, options, globals);
3876
3877 // expand first n-1 tabs
3878 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width
3879
3880 // replace the nth with two sentinels
3881 text = text.replace(/\t/g, '¨A¨B');
3882
3883 // use the sentinel to anchor our regex so it doesn't explode
3884 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) {
3885 var leadingText = m1,
3886 numSpaces = 4 - leadingText.length % 4; // g_tab_width
3887
3888 // there *must* be a better way to do this:
3889 for (var i = 0; i < numSpaces; i++) {
3890 leadingText += ' ';
3891 }
3892
3893 return leadingText;
3894 });
3895
3896 // clean up sentinels
3897 text = text.replace(/¨A/g, ' '); // g_tab_width
3898 text = text.replace(/¨B/g, '');
3899
3900 text = globals.converter._dispatch('detab.after', text, options, globals);
3901 return text;
3902 });
3903
3904 showdown.subParser('ellipsis', function (text, options, globals) {
3905 'use strict';
3906
3907 text = globals.converter._dispatch('ellipsis.before', text, options, globals);
3908
3909 text = text.replace(/\.\.\./g, '…');
3910
3911 text = globals.converter._dispatch('ellipsis.after', text, options, globals);
3912
3913 return text;
3914 });
3915
3916 /**
3917 * Turn emoji codes into emojis
3918 *
3919 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis
3920 */
3921 showdown.subParser('emoji', function (text, options, globals) {
3922 'use strict';
3923
3924 if (!options.emoji) {
3925 return text;
3926 }
3927
3928 text = globals.converter._dispatch('emoji.before', text, options, globals);
3929
3930 var emojiRgx = /:([\S]+?):/g;
3931
3932 text = text.replace(emojiRgx, function (wm, emojiCode) {
3933 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) {
3934 return showdown.helper.emojis[emojiCode];
3935 }
3936 return wm;
3937 });
3938
3939 text = globals.converter._dispatch('emoji.after', text, options, globals);
3940
3941 return text;
3942 });
3943
3944 /**
3945 * Smart processing for ampersands and angle brackets that need to be encoded.
3946 */
3947 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) {
3948 'use strict';
3949 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals);
3950
3951 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
3952 // http://bumppo.net/projects/amputator/
3953 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&amp;');
3954
3955 // Encode naked <'s
3956 text = text.replace(/<(?![a-z\/?$!])/gi, '&lt;');
3957
3958 // Encode <
3959 text = text.replace(/</g, '&lt;');
3960
3961 // Encode >
3962 text = text.replace(/>/g, '&gt;');
3963
3964 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals);
3965 return text;
3966 });
3967
3968 /**
3969 * Returns the string, with after processing the following backslash escape sequences.
3970 *
3971 * attacklab: The polite way to do this is with the new escapeCharacters() function:
3972 *
3973 * text = escapeCharacters(text,"\\",true);
3974 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
3975 *
3976 * ...but we're sidestepping its use of the (slow) RegExp constructor
3977 * as an optimization for Firefox. This function gets called a LOT.
3978 */
3979 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) {
3980 'use strict';
3981 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals);
3982
3983 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback);
3984 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback);
3985
3986 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals);
3987 return text;
3988 });
3989
3990 /**
3991 * Encode/escape certain characters inside Markdown code runs.
3992 * The point is that in code, these characters are literals,
3993 * and lose their special Markdown meanings.
3994 */
3995 showdown.subParser('encodeCode', function (text, options, globals) {
3996 'use strict';
3997
3998 text = globals.converter._dispatch('encodeCode.before', text, options, globals);
3999
4000 // Encode all ampersands; HTML entities are not
4001 // entities within a Markdown code span.
4002 text = text
4003 .replace(/&/g, '&amp;')
4004 // Do the angle bracket song and dance:
4005 .replace(/</g, '&lt;')
4006 .replace(/>/g, '&gt;')
4007 // Now, escape characters that are magic in Markdown:
4008 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback);
4009
4010 text = globals.converter._dispatch('encodeCode.after', text, options, globals);
4011 return text;
4012 });
4013
4014 /**
4015 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they
4016 * don't conflict with their use in Markdown for code, italics and strong.
4017 */
4018 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) {
4019 'use strict';
4020 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals);
4021
4022 // Build a regex to find HTML tags.
4023 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,
4024 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi;
4025
4026 text = text.replace(tags, function (wholeMatch) {
4027 return wholeMatch
4028 .replace(/(.)<\/?code>(?=.)/g, '$1`')
4029 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
4030 });
4031
4032 text = text.replace(comments, function (wholeMatch) {
4033 return wholeMatch
4034 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
4035 });
4036
4037 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals);
4038 return text;
4039 });
4040
4041 /**
4042 * Handle github codeblocks prior to running HashHTML so that
4043 * HTML contained within the codeblock gets escaped properly
4044 * Example:
4045 * ```ruby
4046 * def hello_world(x)
4047 * puts "Hello, #{x}"
4048 * end
4049 * ```
4050 */
4051 showdown.subParser('githubCodeBlocks', function (text, options, globals) {
4052 'use strict';
4053
4054 // early exit if option is not enabled
4055 if (!options.ghCodeBlocks) {
4056 return text;
4057 }
4058
4059 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals);
4060
4061 text += '¨0';
4062
4063 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) {
4064 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
4065
4066 // First parse the github code block
4067 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
4068 codeblock = showdown.subParser('detab')(codeblock, options, globals);
4069 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
4070 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace
4071
4072 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
4073
4074 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);
4075
4076 // Since GHCodeblocks can be false positives, we need to
4077 // store the primitive text and the parsed text in a global var,
4078 // and then return a token
4079 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
4080 });
4081
4082 // attacklab: strip sentinel
4083 text = text.replace(/¨0/, '');
4084
4085 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);
4086 });
4087
4088 showdown.subParser('hashBlock', function (text, options, globals) {
4089 'use strict';
4090 text = globals.converter._dispatch('hashBlock.before', text, options, globals);
4091 text = text.replace(/(^\n+|\n+$)/g, '');
4092 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n';
4093 text = globals.converter._dispatch('hashBlock.after', text, options, globals);
4094 return text;
4095 });
4096
4097 /**
4098 * Hash and escape <code> elements that should not be parsed as markdown
4099 */
4100 showdown.subParser('hashCodeTags', function (text, options, globals) {
4101 'use strict';
4102 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals);
4103
4104 var repFunc = function (wholeMatch, match, left, right) {
4105 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
4106 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C';
4107 };
4108
4109 // Hash naked <code>
4110 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim');
4111
4112 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals);
4113 return text;
4114 });
4115
4116 showdown.subParser('hashElement', function (text, options, globals) {
4117 'use strict';
4118
4119 return function (wholeMatch, m1) {
4120 var blockText = m1;
4121
4122 // Undo double lines
4123 blockText = blockText.replace(/\n\n/g, '\n');
4124 blockText = blockText.replace(/^\n/, '');
4125
4126 // strip trailing blank lines
4127 blockText = blockText.replace(/\n+$/g, '');
4128
4129 // Replace the element text with a marker ("¨KxK" where x is its key)
4130 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n';
4131
4132 return blockText;
4133 };
4134 });
4135
4136 showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
4137 'use strict';
4138 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals);
4139
4140 var blockTags = [
4141 'pre',
4142 'div',
4143 'h1',
4144 'h2',
4145 'h3',
4146 'h4',
4147 'h5',
4148 'h6',
4149 'blockquote',
4150 'table',
4151 'dl',
4152 'ol',
4153 'ul',
4154 'script',
4155 'noscript',
4156 'form',
4157 'fieldset',
4158 'iframe',
4159 'math',
4160 'style',
4161 'section',
4162 'header',
4163 'footer',
4164 'nav',
4165 'article',
4166 'aside',
4167 'address',
4168 'audio',
4169 'canvas',
4170 'figure',
4171 'hgroup',
4172 'output',
4173 'video',
4174 'p'
4175 ],
4176 repFunc = function (wholeMatch, match, left, right) {
4177 var txt = wholeMatch;
4178 // check if this html element is marked as markdown
4179 // if so, it's contents should be parsed as markdown
4180 if (left.search(/\bmarkdown\b/) !== -1) {
4181 txt = left + globals.converter.makeHtml(match) + right;
4182 }
4183 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
4184 };
4185
4186 if (options.backslashEscapesHTMLTags) {
4187 // encode backslash escaped HTML tags
4188 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) {
4189 return '&lt;' + inside + '&gt;';
4190 });
4191 }
4192
4193 // hash HTML Blocks
4194 for (var i = 0; i < blockTags.length; ++i) {
4195
4196 var opTagPos,
4197 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'),
4198 patLeft = '<' + blockTags[i] + '\\b[^>]*>',
4199 patRight = '</' + blockTags[i] + '>';
4200 // 1. Look for the first position of the first opening HTML tag in the text
4201 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {
4202
4203 // if the HTML tag is \ escaped, we need to escape it and break
4204
4205
4206 //2. Split the text in that position
4207 var subTexts = showdown.helper.splitAtIndex(text, opTagPos),
4208 //3. Match recursively
4209 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im');
4210
4211 // prevent an infinite loop
4212 if (newSubText1 === subTexts[1]) {
4213 break;
4214 }
4215 text = subTexts[0].concat(newSubText1);
4216 }
4217 }
4218 // HR SPECIAL CASE
4219 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,
4220 showdown.subParser('hashElement')(text, options, globals));
4221
4222 // Special case for standalone HTML comments
4223 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) {
4224 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
4225 }, '^ {0,3}<!--', '-->', 'gm');
4226
4227 // PHP and ASP-style processor instructions (<?...?> and <%...%>)
4228 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,
4229 showdown.subParser('hashElement')(text, options, globals));
4230
4231 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals);
4232 return text;
4233 });
4234
4235 /**
4236 * Hash span elements that should not be parsed as markdown
4237 */
4238 showdown.subParser('hashHTMLSpans', function (text, options, globals) {
4239 'use strict';
4240 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals);
4241
4242 function hashHTMLSpan (html) {
4243 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C';
4244 }
4245
4246 // Hash Self Closing tags
4247 text = text.replace(/<[^>]+?\/>/gi, function (wm) {
4248 return hashHTMLSpan(wm);
4249 });
4250
4251 // Hash tags without properties
4252 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) {
4253 return hashHTMLSpan(wm);
4254 });
4255
4256 // Hash tags with properties
4257 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) {
4258 return hashHTMLSpan(wm);
4259 });
4260
4261 // Hash self closing tags without />
4262 text = text.replace(/<[^>]+?>/gi, function (wm) {
4263 return hashHTMLSpan(wm);
4264 });
4265
4266 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/
4267
4268 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals);
4269 return text;
4270 });
4271
4272 /**
4273 * Unhash HTML spans
4274 */
4275 showdown.subParser('unhashHTMLSpans', function (text, options, globals) {
4276 'use strict';
4277 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals);
4278
4279 for (var i = 0; i < globals.gHtmlSpans.length; ++i) {
4280 var repText = globals.gHtmlSpans[i],
4281 // limiter to prevent infinite loop (assume 10 as limit for recurse)
4282 limit = 0;
4283
4284 while (/¨C(\d+)C/.test(repText)) {
4285 var num = RegExp.$1;
4286 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]);
4287 if (limit === 10) {
4288 console.error('maximum nesting of 10 spans reached!!!');
4289 break;
4290 }
4291 ++limit;
4292 }
4293 text = text.replace('¨C' + i + 'C', repText);
4294 }
4295
4296 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals);
4297 return text;
4298 });
4299
4300 /**
4301 * Hash and escape <pre><code> elements that should not be parsed as markdown
4302 */
4303 showdown.subParser('hashPreCodeTags', function (text, options, globals) {
4304 'use strict';
4305 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals);
4306
4307 var repFunc = function (wholeMatch, match, left, right) {
4308 // encode html entities
4309 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
4310 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
4311 };
4312
4313 // Hash <pre><code>
4314 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim');
4315
4316 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals);
4317 return text;
4318 });
4319
4320 showdown.subParser('headers', function (text, options, globals) {
4321 'use strict';
4322
4323 text = globals.converter._dispatch('headers.before', text, options, globals);
4324
4325 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
4326
4327 // Set text-style headers:
4328 // Header 1
4329 // ========
4330 //
4331 // Header 2
4332 // --------
4333 //
4334 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm,
4335 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;
4336
4337 text = text.replace(setextRegexH1, function (wholeMatch, m1) {
4338
4339 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
4340 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
4341 hLevel = headerLevelStart,
4342 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
4343 return showdown.subParser('hashBlock')(hashBlock, options, globals);
4344 });
4345
4346 text = text.replace(setextRegexH2, function (matchFound, m1) {
4347 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
4348 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
4349 hLevel = headerLevelStart + 1,
4350 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
4351 return showdown.subParser('hashBlock')(hashBlock, options, globals);
4352 });
4353
4354 // atx-style headers:
4355 // # Header 1
4356 // ## Header 2
4357 // ## Header 2 with closing hashes ##
4358 // ...
4359 // ###### Header 6
4360 //
4361 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;
4362
4363 text = text.replace(atxStyle, function (wholeMatch, m1, m2) {
4364 var hText = m2;
4365 if (options.customizedHeaderId) {
4366 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, '');
4367 }
4368
4369 var span = showdown.subParser('spanGamut')(hText, options, globals),
4370 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"',
4371 hLevel = headerLevelStart - 1 + m1.length,
4372 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>';
4373
4374 return showdown.subParser('hashBlock')(header, options, globals);
4375 });
4376
4377 function headerId (m) {
4378 var title,
4379 prefix;
4380
4381 // It is separate from other options to allow combining prefix and customized
4382 if (options.customizedHeaderId) {
4383 var match = m.match(/\{([^{]+?)}\s*$/);
4384 if (match && match[1]) {
4385 m = match[1];
4386 }
4387 }
4388
4389 title = m;
4390
4391 // Prefix id to prevent causing inadvertent pre-existing style matches.
4392 if (showdown.helper.isString(options.prefixHeaderId)) {
4393 prefix = options.prefixHeaderId;
4394 } else if (options.prefixHeaderId === true) {
4395 prefix = 'section-';
4396 } else {
4397 prefix = '';
4398 }
4399
4400 if (!options.rawPrefixHeaderId) {
4401 title = prefix + title;
4402 }
4403
4404 if (options.ghCompatibleHeaderId) {
4405 title = title
4406 .replace(/ /g, '-')
4407 // replace previously escaped chars (&, ¨ and $)
4408 .replace(/&amp;/g, '')
4409 .replace(/¨T/g, '')
4410 .replace(/¨D/g, '')
4411 // replace rest of the chars (&~$ are repeated as they might have been escaped)
4412 // borrowed from github's redcarpet (some they should produce similar results)
4413 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '')
4414 .toLowerCase();
4415 } else if (options.rawHeaderId) {
4416 title = title
4417 .replace(/ /g, '-')
4418 // replace previously escaped chars (&, ¨ and $)
4419 .replace(/&amp;/g, '&')
4420 .replace(/¨T/g, '¨')
4421 .replace(/¨D/g, '$')
4422 // replace " and '
4423 .replace(/["']/g, '-')
4424 .toLowerCase();
4425 } else {
4426 title = title
4427 .replace(/[^\w]/g, '')
4428 .toLowerCase();
4429 }
4430
4431 if (options.rawPrefixHeaderId) {
4432 title = prefix + title;
4433 }
4434
4435 if (globals.hashLinkCounts[title]) {
4436 title = title + '-' + (globals.hashLinkCounts[title]++);
4437 } else {
4438 globals.hashLinkCounts[title] = 1;
4439 }
4440 return title;
4441 }
4442
4443 text = globals.converter._dispatch('headers.after', text, options, globals);
4444 return text;
4445 });
4446
4447 /**
4448 * Turn Markdown link shortcuts into XHTML <a> tags.
4449 */
4450 showdown.subParser('horizontalRule', function (text, options, globals) {
4451 'use strict';
4452 text = globals.converter._dispatch('horizontalRule.before', text, options, globals);
4453
4454 var key = showdown.subParser('hashBlock')('<hr />', options, globals);
4455 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key);
4456 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key);
4457 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key);
4458
4459 text = globals.converter._dispatch('horizontalRule.after', text, options, globals);
4460 return text;
4461 });
4462
4463 /**
4464 * Turn Markdown image shortcuts into <img> tags.
4465 */
4466 showdown.subParser('images', function (text, options, globals) {
4467 'use strict';
4468
4469 text = globals.converter._dispatch('images.before', text, options, globals);
4470
4471 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
4472 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,
4473 base64RegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
4474 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,
4475 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g;
4476
4477 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) {
4478 url = url.replace(/\s/g, '');
4479 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title);
4480 }
4481
4482 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) {
4483
4484 var gUrls = globals.gUrls,
4485 gTitles = globals.gTitles,
4486 gDims = globals.gDimensions;
4487
4488 linkId = linkId.toLowerCase();
4489
4490 if (!title) {
4491 title = '';
4492 }
4493 // Special case for explicit empty url
4494 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
4495 url = '';
4496
4497 } else if (url === '' || url === null) {
4498 if (linkId === '' || linkId === null) {
4499 // lower-case and turn embedded newlines into spaces
4500 linkId = altText.toLowerCase().replace(/ ?\n/g, ' ');
4501 }
4502 url = '#' + linkId;
4503
4504 if (!showdown.helper.isUndefined(gUrls[linkId])) {
4505 url = gUrls[linkId];
4506 if (!showdown.helper.isUndefined(gTitles[linkId])) {
4507 title = gTitles[linkId];
4508 }
4509 if (!showdown.helper.isUndefined(gDims[linkId])) {
4510 width = gDims[linkId].width;
4511 height = gDims[linkId].height;
4512 }
4513 } else {
4514 return wholeMatch;
4515 }
4516 }
4517
4518 altText = altText
4519 .replace(/"/g, '&quot;')
4520 //altText = showdown.helper.escapeCharacters(altText, '*_', false);
4521 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4522 //url = showdown.helper.escapeCharacters(url, '*_', false);
4523 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4524 var result = '<img src="' + url + '" alt="' + altText + '"';
4525
4526 if (title && showdown.helper.isString(title)) {
4527 title = title
4528 .replace(/"/g, '&quot;')
4529 //title = showdown.helper.escapeCharacters(title, '*_', false);
4530 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4531 result += ' title="' + title + '"';
4532 }
4533
4534 if (width && height) {
4535 width = (width === '*') ? 'auto' : width;
4536 height = (height === '*') ? 'auto' : height;
4537
4538 result += ' width="' + width + '"';
4539 result += ' height="' + height + '"';
4540 }
4541
4542 result += ' />';
4543
4544 return result;
4545 }
4546
4547 // First, handle reference-style labeled images: ![alt text][id]
4548 text = text.replace(referenceRegExp, writeImageTag);
4549
4550 // Next, handle inline images: ![alt text](url =<width>x<height> "optional title")
4551
4552 // base64 encoded images
4553 text = text.replace(base64RegExp, writeImageTagBase64);
4554
4555 // cases with crazy urls like ./image/cat1).png
4556 text = text.replace(crazyRegExp, writeImageTag);
4557
4558 // normal cases
4559 text = text.replace(inlineRegExp, writeImageTag);
4560
4561 // handle reference-style shortcuts: ![img text]
4562 text = text.replace(refShortcutRegExp, writeImageTag);
4563
4564 text = globals.converter._dispatch('images.after', text, options, globals);
4565 return text;
4566 });
4567
4568 showdown.subParser('italicsAndBold', function (text, options, globals) {
4569 'use strict';
4570
4571 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
4572
4573 // it's faster to have 3 separate regexes for each case than have just one
4574 // because of backtracing, in some cases, it could lead to an exponential effect
4575 // called "catastrophic backtrace". Ominous!
4576
4577 function parseInside (txt, left, right) {
4578 /*
4579 if (options.simplifiedAutoLink) {
4580 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
4581 }
4582 */
4583 return left + txt + right;
4584 }
4585
4586 // Parse underscores
4587 if (options.literalMidWordUnderscores) {
4588 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
4589 return parseInside (txt, '<strong><em>', '</em></strong>');
4590 });
4591 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
4592 return parseInside (txt, '<strong>', '</strong>');
4593 });
4594 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) {
4595 return parseInside (txt, '<em>', '</em>');
4596 });
4597 } else {
4598 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
4599 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
4600 });
4601 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
4602 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
4603 });
4604 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) {
4605 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it)
4606 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
4607 });
4608 }
4609
4610 // Now parse asterisks
4611 if (options.literalMidWordAsterisks) {
4612 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) {
4613 return parseInside (txt, lead + '<strong><em>', '</em></strong>');
4614 });
4615 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) {
4616 return parseInside (txt, lead + '<strong>', '</strong>');
4617 });
4618 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) {
4619 return parseInside (txt, lead + '<em>', '</em>');
4620 });
4621 } else {
4622 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
4623 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
4624 });
4625 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
4626 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
4627 });
4628 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
4629 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
4630 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
4631 });
4632 }
4633
4634
4635 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
4636 return text;
4637 });
4638
4639 /**
4640 * Form HTML ordered (numbered) and unordered (bulleted) lists.
4641 */
4642 showdown.subParser('lists', function (text, options, globals) {
4643 'use strict';
4644
4645 /**
4646 * Process the contents of a single ordered or unordered list, splitting it
4647 * into individual list items.
4648 * @param {string} listStr
4649 * @param {boolean} trimTrailing
4650 * @returns {string}
4651 */
4652 function processListItems (listStr, trimTrailing) {
4653 // The $g_list_level global keeps track of when we're inside a list.
4654 // Each time we enter a list, we increment it; when we leave a list,
4655 // we decrement. If it's zero, we're not in a list anymore.
4656 //
4657 // We do this because when we're not inside a list, we want to treat
4658 // something like this:
4659 //
4660 // I recommend upgrading to version
4661 // 8. Oops, now this line is treated
4662 // as a sub-list.
4663 //
4664 // As a single paragraph, despite the fact that the second line starts
4665 // with a digit-period-space sequence.
4666 //
4667 // Whereas when we're inside a list (or sub-list), that line will be
4668 // treated as the start of a sub-list. What a kludge, huh? This is
4669 // an aspect of Markdown's syntax that's hard to parse perfectly
4670 // without resorting to mind-reading. Perhaps the solution is to
4671 // change the syntax rules such that sub-lists must start with a
4672 // starting cardinal number; e.g. "1." or "a.".
4673 globals.gListLevel++;
4674
4675 // trim trailing blank lines:
4676 listStr = listStr.replace(/\n{2,}$/, '\n');
4677
4678 // attacklab: add sentinel to emulate \z
4679 listStr += '¨0';
4680
4681 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,
4682 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr));
4683
4684 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation,
4685 // which is a syntax breaking change
4686 // activating this option reverts to old behavior
4687 if (options.disableForced4SpacesIndentedSublists) {
4688 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm;
4689 }
4690
4691 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
4692 checked = (checked && checked.trim() !== '');
4693
4694 var item = showdown.subParser('outdent')(m4, options, globals),
4695 bulletStyle = '';
4696
4697 // Support for github tasklists
4698 if (taskbtn && options.tasklists) {
4699 bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
4700 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () {
4701 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
4702 if (checked) {
4703 otp += ' checked';
4704 }
4705 otp += '>';
4706 return otp;
4707 });
4708 }
4709
4710 // ISSUE #312
4711 // This input: - - - a
4712 // causes trouble to the parser, since it interprets it as:
4713 // <ul><li><li><li>a</li></li></li></ul>
4714 // instead of:
4715 // <ul><li>- - a</li></ul>
4716 // So, to prevent it, we will put a marker (¨A)in the beginning of the line
4717 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser
4718 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) {
4719 return '¨A' + wm2;
4720 });
4721
4722 // m1 - Leading line or
4723 // Has a double return (multi paragraph) or
4724 // Has sublist
4725 if (m1 || (item.search(/\n{2,}/) > -1)) {
4726 item = showdown.subParser('githubCodeBlocks')(item, options, globals);
4727 item = showdown.subParser('blockGamut')(item, options, globals);
4728 } else {
4729 // Recursion for sub-lists:
4730 item = showdown.subParser('lists')(item, options, globals);
4731 item = item.replace(/\n$/, ''); // chomp(item)
4732 item = showdown.subParser('hashHTMLBlocks')(item, options, globals);
4733
4734 // Colapse double linebreaks
4735 item = item.replace(/\n\n+/g, '\n\n');
4736 if (isParagraphed) {
4737 item = showdown.subParser('paragraphs')(item, options, globals);
4738 } else {
4739 item = showdown.subParser('spanGamut')(item, options, globals);
4740 }
4741 }
4742
4743 // now we need to remove the marker (¨A)
4744 item = item.replace('¨A', '');
4745 // we can finally wrap the line in list item tags
4746 item = '<li' + bulletStyle + '>' + item + '</li>\n';
4747
4748 return item;
4749 });
4750
4751 // attacklab: strip sentinel
4752 listStr = listStr.replace(/¨0/g, '');
4753
4754 globals.gListLevel--;
4755
4756 if (trimTrailing) {
4757 listStr = listStr.replace(/\s+$/, '');
4758 }
4759
4760 return listStr;
4761 }
4762
4763 function styleStartNumber (list, listType) {
4764 // check if ol and starts by a number different than 1
4765 if (listType === 'ol') {
4766 var res = list.match(/^ *(\d+)\./);
4767 if (res && res[1] !== '1') {
4768 return ' start="' + res[1] + '"';
4769 }
4770 }
4771 return '';
4772 }
4773
4774 /**
4775 * Check and parse consecutive lists (better fix for issue #142)
4776 * @param {string} list
4777 * @param {string} listType
4778 * @param {boolean} trimTrailing
4779 * @returns {string}
4780 */
4781 function parseConsecutiveLists (list, listType, trimTrailing) {
4782 // check if we caught 2 or more consecutive lists by mistake
4783 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa
4784 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm,
4785 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm,
4786 counterRxg = (listType === 'ul') ? olRgx : ulRgx,
4787 result = '';
4788
4789 if (list.search(counterRxg) !== -1) {
4790 (function parseCL (txt) {
4791 var pos = txt.search(counterRxg),
4792 style = styleStartNumber(list, listType);
4793 if (pos !== -1) {
4794 // slice
4795 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n';
4796
4797 // invert counterType and listType
4798 listType = (listType === 'ul') ? 'ol' : 'ul';
4799 counterRxg = (listType === 'ul') ? olRgx : ulRgx;
4800
4801 //recurse
4802 parseCL(txt.slice(pos));
4803 } else {
4804 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n';
4805 }
4806 })(list);
4807 } else {
4808 var style = styleStartNumber(list, listType);
4809 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n';
4810 }
4811
4812 return result;
4813 }
4814
4815 /** Start of list parsing **/
4816 text = globals.converter._dispatch('lists.before', text, options, globals);
4817 // add sentinel to hack around khtml/safari bug:
4818 // http://bugs.webkit.org/show_bug.cgi?id=11231
4819 text += '¨0';
4820
4821 if (globals.gListLevel) {
4822 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4823 function (wholeMatch, list, m2) {
4824 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4825 return parseConsecutiveLists(list, listType, true);
4826 }
4827 );
4828 } else {
4829 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4830 function (wholeMatch, m1, list, m3) {
4831 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4832 return parseConsecutiveLists(list, listType, false);
4833 }
4834 );
4835 }
4836
4837 // strip sentinel
4838 text = text.replace(/¨0/, '');
4839 text = globals.converter._dispatch('lists.after', text, options, globals);
4840 return text;
4841 });
4842
4843 /**
4844 * Parse metadata at the top of the document
4845 */
4846 showdown.subParser('metadata', function (text, options, globals) {
4847 'use strict';
4848
4849 if (!options.metadata) {
4850 return text;
4851 }
4852
4853 text = globals.converter._dispatch('metadata.before', text, options, globals);
4854
4855 function parseMetadataContents (content) {
4856 // raw is raw so it's not changed in any way
4857 globals.metadata.raw = content;
4858
4859 // escape chars forbidden in html attributes
4860 // double quotes
4861 content = content
4862 // ampersand first
4863 .replace(/&/g, '&amp;')
4864 // double quotes
4865 .replace(/"/g, '&quot;');
4866
4867 content = content.replace(/\n {4}/g, ' ');
4868 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) {
4869 globals.metadata.parsed[key] = value;
4870 return '';
4871 });
4872 }
4873
4874 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) {
4875 parseMetadataContents(content);
4876 return '¨M';
4877 });
4878
4879 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) {
4880 if (format) {
4881 globals.metadata.format = format;
4882 }
4883 parseMetadataContents(content);
4884 return '¨M';
4885 });
4886
4887 text = text.replace(/¨M/g, '');
4888
4889 text = globals.converter._dispatch('metadata.after', text, options, globals);
4890 return text;
4891 });
4892
4893 /**
4894 * Remove one level of line-leading tabs or spaces
4895 */
4896 showdown.subParser('outdent', function (text, options, globals) {
4897 'use strict';
4898 text = globals.converter._dispatch('outdent.before', text, options, globals);
4899
4900 // attacklab: hack around Konqueror 3.5.4 bug:
4901 // "----------bug".replace(/^-/g,"") == "bug"
4902 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width
4903
4904 // attacklab: clean up hack
4905 text = text.replace(/¨0/g, '');
4906
4907 text = globals.converter._dispatch('outdent.after', text, options, globals);
4908 return text;
4909 });
4910
4911 /**
4912 *
4913 */
4914 showdown.subParser('paragraphs', function (text, options, globals) {
4915 'use strict';
4916
4917 text = globals.converter._dispatch('paragraphs.before', text, options, globals);
4918 // Strip leading and trailing lines:
4919 text = text.replace(/^\n+/g, '');
4920 text = text.replace(/\n+$/g, '');
4921
4922 var grafs = text.split(/\n{2,}/g),
4923 grafsOut = [],
4924 end = grafs.length; // Wrap <p> tags
4925
4926 for (var i = 0; i < end; i++) {
4927 var str = grafs[i];
4928 // if this is an HTML marker, copy it
4929 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) {
4930 grafsOut.push(str);
4931
4932 // test for presence of characters to prevent empty lines being parsed
4933 // as paragraphs (resulting in undesired extra empty paragraphs)
4934 } else if (str.search(/\S/) >= 0) {
4935 str = showdown.subParser('spanGamut')(str, options, globals);
4936 str = str.replace(/^([ \t]*)/g, '<p>');
4937 str += '</p>';
4938 grafsOut.push(str);
4939 }
4940 }
4941
4942 /** Unhashify HTML blocks */
4943 end = grafsOut.length;
4944 for (i = 0; i < end; i++) {
4945 var blockText = '',
4946 grafsOutIt = grafsOut[i],
4947 codeFlag = false;
4948 // if this is a marker for an html block...
4949 // use RegExp.test instead of string.search because of QML bug
4950 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) {
4951 var delim = RegExp.$1,
4952 num = RegExp.$2;
4953
4954 if (delim === 'K') {
4955 blockText = globals.gHtmlBlocks[num];
4956 } else {
4957 // we need to check if ghBlock is a false positive
4958 if (codeFlag) {
4959 // use encoded version of all text
4960 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals);
4961 } else {
4962 blockText = globals.ghCodeBlocks[num].codeblock;
4963 }
4964 }
4965 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
4966
4967 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText);
4968 // Check if grafsOutIt is a pre->code
4969 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) {
4970 codeFlag = true;
4971 }
4972 }
4973 grafsOut[i] = grafsOutIt;
4974 }
4975 text = grafsOut.join('\n');
4976 // Strip leading and trailing lines:
4977 text = text.replace(/^\n+/g, '');
4978 text = text.replace(/\n+$/g, '');
4979 return globals.converter._dispatch('paragraphs.after', text, options, globals);
4980 });
4981
4982 /**
4983 * Run extension
4984 */
4985 showdown.subParser('runExtension', function (ext, text, options, globals) {
4986 'use strict';
4987
4988 if (ext.filter) {
4989 text = ext.filter(text, globals.converter, options);
4990
4991 } else if (ext.regex) {
4992 // TODO remove this when old extension loading mechanism is deprecated
4993 var re = ext.regex;
4994 if (!(re instanceof RegExp)) {
4995 re = new RegExp(re, 'g');
4996 }
4997 text = text.replace(re, ext.replace);
4998 }
4999
5000 return text;
5001 });
5002
5003 /**
5004 * These are all the transformations that occur *within* block-level
5005 * tags like paragraphs, headers, and list items.
5006 */
5007 showdown.subParser('spanGamut', function (text, options, globals) {
5008 'use strict';
5009
5010 text = globals.converter._dispatch('spanGamut.before', text, options, globals);
5011 text = showdown.subParser('codeSpans')(text, options, globals);
5012 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals);
5013 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals);
5014
5015 // Process anchor and image tags. Images must come first,
5016 // because ![foo][f] looks like an anchor.
5017 text = showdown.subParser('images')(text, options, globals);
5018 text = showdown.subParser('anchors')(text, options, globals);
5019
5020 // Make links out of things like `<http://example.com/>`
5021 // Must come after anchors, because you can use < and >
5022 // delimiters in inline links like [this](<url>).
5023 text = showdown.subParser('autoLinks')(text, options, globals);
5024 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals);
5025 text = showdown.subParser('emoji')(text, options, globals);
5026 text = showdown.subParser('underline')(text, options, globals);
5027 text = showdown.subParser('italicsAndBold')(text, options, globals);
5028 text = showdown.subParser('strikethrough')(text, options, globals);
5029 text = showdown.subParser('ellipsis')(text, options, globals);
5030
5031 // we need to hash HTML tags inside spans
5032 text = showdown.subParser('hashHTMLSpans')(text, options, globals);
5033
5034 // now we encode amps and angles
5035 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals);
5036
5037 // Do hard breaks
5038 if (options.simpleLineBreaks) {
5039 // GFM style hard breaks
5040 // only add line breaks if the text does not contain a block (special case for lists)
5041 if (!/\n\n¨K/.test(text)) {
5042 text = text.replace(/\n+/g, '<br />\n');
5043 }
5044 } else {
5045 // Vanilla hard breaks
5046 text = text.replace(/ +\n/g, '<br />\n');
5047 }
5048
5049 text = globals.converter._dispatch('spanGamut.after', text, options, globals);
5050 return text;
5051 });
5052
5053 showdown.subParser('strikethrough', function (text, options, globals) {
5054 'use strict';
5055
5056 function parseInside (txt) {
5057 if (options.simplifiedAutoLink) {
5058 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
5059 }
5060 return '<del>' + txt + '</del>';
5061 }
5062
5063 if (options.strikethrough) {
5064 text = globals.converter._dispatch('strikethrough.before', text, options, globals);
5065 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); });
5066 text = globals.converter._dispatch('strikethrough.after', text, options, globals);
5067 }
5068
5069 return text;
5070 });
5071
5072 /**
5073 * Strips link definitions from text, stores the URLs and titles in
5074 * hash references.
5075 * Link defs are in the form: ^[id]: url "optional title"
5076 */
5077 showdown.subParser('stripLinkDefinitions', function (text, options, globals) {
5078 'use strict';
5079
5080 var regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,
5081 base64Regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm;
5082
5083 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
5084 text += '¨0';
5085
5086 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) {
5087 linkId = linkId.toLowerCase();
5088 if (url.match(/^data:.+?\/.+?;base64,/)) {
5089 // remove newlines
5090 globals.gUrls[linkId] = url.replace(/\s/g, '');
5091 } else {
5092 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive
5093 }
5094
5095 if (blankLines) {
5096 // Oops, found blank lines, so it's not a title.
5097 // Put back the parenthetical statement we stole.
5098 return blankLines + title;
5099
5100 } else {
5101 if (title) {
5102 globals.gTitles[linkId] = title.replace(/"|'/g, '&quot;');
5103 }
5104 if (options.parseImgDimensions && width && height) {
5105 globals.gDimensions[linkId] = {
5106 width: width,
5107 height: height
5108 };
5109 }
5110 }
5111 // Completely remove the definition from the text
5112 return '';
5113 };
5114
5115 // first we try to find base64 link references
5116 text = text.replace(base64Regex, replaceFunc);
5117
5118 text = text.replace(regex, replaceFunc);
5119
5120 // attacklab: strip sentinel
5121 text = text.replace(/¨0/, '');
5122
5123 return text;
5124 });
5125
5126 showdown.subParser('tables', function (text, options, globals) {
5127 'use strict';
5128
5129 if (!options.tables) {
5130 return text;
5131 }
5132
5133 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,
5134 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm;
5135 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm;
5136
5137 function parseStyles (sLine) {
5138 if (/^:[ \t]*--*$/.test(sLine)) {
5139 return ' style="text-align:left;"';
5140 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) {
5141 return ' style="text-align:right;"';
5142 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) {
5143 return ' style="text-align:center;"';
5144 } else {
5145 return '';
5146 }
5147 }
5148
5149 function parseHeaders (header, style) {
5150 var id = '';
5151 header = header.trim();
5152 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility
5153 if (options.tablesHeaderId || options.tableHeaderId) {
5154 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
5155 }
5156 header = showdown.subParser('spanGamut')(header, options, globals);
5157
5158 return '<th' + id + style + '>' + header + '</th>\n';
5159 }
5160
5161 function parseCells (cell, style) {
5162 var subText = showdown.subParser('spanGamut')(cell, options, globals);
5163 return '<td' + style + '>' + subText + '</td>\n';
5164 }
5165
5166 function buildTable (headers, cells) {
5167 var tb = '<table>\n<thead>\n<tr>\n',
5168 tblLgn = headers.length;
5169
5170 for (var i = 0; i < tblLgn; ++i) {
5171 tb += headers[i];
5172 }
5173 tb += '</tr>\n</thead>\n<tbody>\n';
5174
5175 for (i = 0; i < cells.length; ++i) {
5176 tb += '<tr>\n';
5177 for (var ii = 0; ii < tblLgn; ++ii) {
5178 tb += cells[i][ii];
5179 }
5180 tb += '</tr>\n';
5181 }
5182 tb += '</tbody>\n</table>\n';
5183 return tb;
5184 }
5185
5186 function parseTable (rawTable) {
5187 var i, tableLines = rawTable.split('\n');
5188
5189 for (i = 0; i < tableLines.length; ++i) {
5190 // strip wrong first and last column if wrapped tables are used
5191 if (/^ {0,3}\|/.test(tableLines[i])) {
5192 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, '');
5193 }
5194 if (/\|[ \t]*$/.test(tableLines[i])) {
5195 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, '');
5196 }
5197 // parse code spans first, but we only support one line code spans
5198 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals);
5199 }
5200
5201 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),
5202 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),
5203 rawCells = [],
5204 headers = [],
5205 styles = [],
5206 cells = [];
5207
5208 tableLines.shift();
5209 tableLines.shift();
5210
5211 for (i = 0; i < tableLines.length; ++i) {
5212 if (tableLines[i].trim() === '') {
5213 continue;
5214 }
5215 rawCells.push(
5216 tableLines[i]
5217 .split('|')
5218 .map(function (s) {
5219 return s.trim();
5220 })
5221 );
5222 }
5223
5224 if (rawHeaders.length < rawStyles.length) {
5225 return rawTable;
5226 }
5227
5228 for (i = 0; i < rawStyles.length; ++i) {
5229 styles.push(parseStyles(rawStyles[i]));
5230 }
5231
5232 for (i = 0; i < rawHeaders.length; ++i) {
5233 if (showdown.helper.isUndefined(styles[i])) {
5234 styles[i] = '';
5235 }
5236 headers.push(parseHeaders(rawHeaders[i], styles[i]));
5237 }
5238
5239 for (i = 0; i < rawCells.length; ++i) {
5240 var row = [];
5241 for (var ii = 0; ii < headers.length; ++ii) {
5242 if (showdown.helper.isUndefined(rawCells[i][ii])) {
5243
5244 }
5245 row.push(parseCells(rawCells[i][ii], styles[ii]));
5246 }
5247 cells.push(row);
5248 }
5249
5250 return buildTable(headers, cells);
5251 }
5252
5253 text = globals.converter._dispatch('tables.before', text, options, globals);
5254
5255 // find escaped pipe characters
5256 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback);
5257
5258 // parse multi column tables
5259 text = text.replace(tableRgx, parseTable);
5260
5261 // parse one column tables
5262 text = text.replace(singeColTblRgx, parseTable);
5263
5264 text = globals.converter._dispatch('tables.after', text, options, globals);
5265
5266 return text;
5267 });
5268
5269 showdown.subParser('underline', function (text, options, globals) {
5270 'use strict';
5271
5272 if (!options.underline) {
5273 return text;
5274 }
5275
5276 text = globals.converter._dispatch('underline.before', text, options, globals);
5277
5278 if (options.literalMidWordUnderscores) {
5279 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
5280 return '<u>' + txt + '</u>';
5281 });
5282 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
5283 return '<u>' + txt + '</u>';
5284 });
5285 } else {
5286 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
5287 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
5288 });
5289 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
5290 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
5291 });
5292 }
5293
5294 // escape remaining underscores to prevent them being parsed by italic and bold
5295 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback);
5296
5297 text = globals.converter._dispatch('underline.after', text, options, globals);
5298
5299 return text;
5300 });
5301
5302 /**
5303 * Swap back in all the special characters we've hidden.
5304 */
5305 showdown.subParser('unescapeSpecialChars', function (text, options, globals) {
5306 'use strict';
5307 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals);
5308
5309 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) {
5310 var charCodeToReplace = parseInt(m1);
5311 return String.fromCharCode(charCodeToReplace);
5312 });
5313
5314 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals);
5315 return text;
5316 });
5317
5318 showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
5319 'use strict';
5320
5321 var txt = '';
5322 if (node.hasChildNodes()) {
5323 var children = node.childNodes,
5324 childrenLength = children.length;
5325
5326 for (var i = 0; i < childrenLength; ++i) {
5327 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals);
5328
5329 if (innerTxt === '') {
5330 continue;
5331 }
5332 txt += innerTxt;
5333 }
5334 }
5335 // cleanup
5336 txt = txt.trim();
5337 txt = '> ' + txt.split('\n').join('\n> ');
5338 return txt;
5339 });
5340
5341 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
5342 'use strict';
5343
5344 var lang = node.getAttribute('language'),
5345 num = node.getAttribute('precodenum');
5346 return '```' + lang + '\n' + globals.preList[num] + '\n```';
5347 });
5348
5349 showdown.subParser('makeMarkdown.codeSpan', function (node) {
5350 'use strict';
5351
5352 return '`' + node.innerHTML + '`';
5353 });
5354
5355 showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
5356 'use strict';
5357
5358 var txt = '';
5359 if (node.hasChildNodes()) {
5360 txt += '*';
5361 var children = node.childNodes,
5362 childrenLength = children.length;
5363 for (var i = 0; i < childrenLength; ++i) {
5364 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5365 }
5366 txt += '*';
5367 }
5368 return txt;
5369 });
5370
5371 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {
5372 'use strict';
5373
5374 var headerMark = new Array(headerLevel + 1).join('#'),
5375 txt = '';
5376
5377 if (node.hasChildNodes()) {
5378 txt = headerMark + ' ';
5379 var children = node.childNodes,
5380 childrenLength = children.length;
5381
5382 for (var i = 0; i < childrenLength; ++i) {
5383 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5384 }
5385 }
5386 return txt;
5387 });
5388
5389 showdown.subParser('makeMarkdown.hr', function () {
5390 'use strict';
5391
5392 return '---';
5393 });
5394
5395 showdown.subParser('makeMarkdown.image', function (node) {
5396 'use strict';
5397
5398 var txt = '';
5399 if (node.hasAttribute('src')) {
5400 txt += '![' + node.getAttribute('alt') + '](';
5401 txt += '<' + node.getAttribute('src') + '>';
5402 if (node.hasAttribute('width') && node.hasAttribute('height')) {
5403 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height');
5404 }
5405
5406 if (node.hasAttribute('title')) {
5407 txt += ' "' + node.getAttribute('title') + '"';
5408 }
5409 txt += ')';
5410 }
5411 return txt;
5412 });
5413
5414 showdown.subParser('makeMarkdown.links', function (node, globals) {
5415 'use strict';
5416
5417 var txt = '';
5418 if (node.hasChildNodes() && node.hasAttribute('href')) {
5419 var children = node.childNodes,
5420 childrenLength = children.length;
5421 txt = '[';
5422 for (var i = 0; i < childrenLength; ++i) {
5423 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5424 }
5425 txt += '](';
5426 txt += '<' + node.getAttribute('href') + '>';
5427 if (node.hasAttribute('title')) {
5428 txt += ' "' + node.getAttribute('title') + '"';
5429 }
5430 txt += ')';
5431 }
5432 return txt;
5433 });
5434
5435 showdown.subParser('makeMarkdown.list', function (node, globals, type) {
5436 'use strict';
5437
5438 var txt = '';
5439 if (!node.hasChildNodes()) {
5440 return '';
5441 }
5442 var listItems = node.childNodes,
5443 listItemsLenght = listItems.length,
5444 listNum = node.getAttribute('start') || 1;
5445
5446 for (var i = 0; i < listItemsLenght; ++i) {
5447 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') {
5448 continue;
5449 }
5450
5451 // define the bullet to use in list
5452 var bullet = '';
5453 if (type === 'ol') {
5454 bullet = listNum.toString() + '. ';
5455 } else {
5456 bullet = '- ';
5457 }
5458
5459 // parse list item
5460 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals);
5461 ++listNum;
5462 }
5463
5464 // add comment at the end to prevent consecutive lists to be parsed as one
5465 txt += '\n<!-- -->\n';
5466 return txt.trim();
5467 });
5468
5469 showdown.subParser('makeMarkdown.listItem', function (node, globals) {
5470 'use strict';
5471
5472 var listItemTxt = '';
5473
5474 var children = node.childNodes,
5475 childrenLenght = children.length;
5476
5477 for (var i = 0; i < childrenLenght; ++i) {
5478 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5479 }
5480 // if it's only one liner, we need to add a newline at the end
5481 if (!/\n$/.test(listItemTxt)) {
5482 listItemTxt += '\n';
5483 } else {
5484 // it's multiparagraph, so we need to indent
5485 listItemTxt = listItemTxt
5486 .split('\n')
5487 .join('\n ')
5488 .replace(/^ {4}$/gm, '')
5489 .replace(/\n\n+/g, '\n\n');
5490 }
5491
5492 return listItemTxt;
5493 });
5494
5495
5496
5497 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
5498 'use strict';
5499
5500 spansOnly = spansOnly || false;
5501
5502 var txt = '';
5503
5504 // edge case of text without wrapper paragraph
5505 if (node.nodeType === 3) {
5506 return showdown.subParser('makeMarkdown.txt')(node, globals);
5507 }
5508
5509 // HTML comment
5510 if (node.nodeType === 8) {
5511 return '<!--' + node.data + '-->\n\n';
5512 }
5513
5514 // process only node elements
5515 if (node.nodeType !== 1) {
5516 return '';
5517 }
5518
5519 var tagName = node.tagName.toLowerCase();
5520
5521 switch (tagName) {
5522
5523 //
5524 // BLOCKS
5525 //
5526 case 'h1':
5527 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; }
5528 break;
5529 case 'h2':
5530 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; }
5531 break;
5532 case 'h3':
5533 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; }
5534 break;
5535 case 'h4':
5536 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; }
5537 break;
5538 case 'h5':
5539 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; }
5540 break;
5541 case 'h6':
5542 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; }
5543 break;
5544
5545 case 'p':
5546 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; }
5547 break;
5548
5549 case 'blockquote':
5550 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; }
5551 break;
5552
5553 case 'hr':
5554 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; }
5555 break;
5556
5557 case 'ol':
5558 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; }
5559 break;
5560
5561 case 'ul':
5562 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; }
5563 break;
5564
5565 case 'precode':
5566 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; }
5567 break;
5568
5569 case 'pre':
5570 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; }
5571 break;
5572
5573 case 'table':
5574 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; }
5575 break;
5576
5577 //
5578 // SPANS
5579 //
5580 case 'code':
5581 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals);
5582 break;
5583
5584 case 'em':
5585 case 'i':
5586 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals);
5587 break;
5588
5589 case 'strong':
5590 case 'b':
5591 txt = showdown.subParser('makeMarkdown.strong')(node, globals);
5592 break;
5593
5594 case 'del':
5595 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals);
5596 break;
5597
5598 case 'a':
5599 txt = showdown.subParser('makeMarkdown.links')(node, globals);
5600 break;
5601
5602 case 'img':
5603 txt = showdown.subParser('makeMarkdown.image')(node, globals);
5604 break;
5605
5606 default:
5607 txt = node.outerHTML + '\n\n';
5608 }
5609
5610 // common normalization
5611 // TODO eventually
5612
5613 return txt;
5614 });
5615
5616 showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
5617 'use strict';
5618
5619 var txt = '';
5620 if (node.hasChildNodes()) {
5621 var children = node.childNodes,
5622 childrenLength = children.length;
5623 for (var i = 0; i < childrenLength; ++i) {
5624 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5625 }
5626 }
5627
5628 // some text normalization
5629 txt = txt.trim();
5630
5631 return txt;
5632 });
5633
5634 showdown.subParser('makeMarkdown.pre', function (node, globals) {
5635 'use strict';
5636
5637 var num = node.getAttribute('prenum');
5638 return '<pre>' + globals.preList[num] + '</pre>';
5639 });
5640
5641 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) {
5642 'use strict';
5643
5644 var txt = '';
5645 if (node.hasChildNodes()) {
5646 txt += '~~';
5647 var children = node.childNodes,
5648 childrenLength = children.length;
5649 for (var i = 0; i < childrenLength; ++i) {
5650 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5651 }
5652 txt += '~~';
5653 }
5654 return txt;
5655 });
5656
5657 showdown.subParser('makeMarkdown.strong', function (node, globals) {
5658 'use strict';
5659
5660 var txt = '';
5661 if (node.hasChildNodes()) {
5662 txt += '**';
5663 var children = node.childNodes,
5664 childrenLength = children.length;
5665 for (var i = 0; i < childrenLength; ++i) {
5666 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5667 }
5668 txt += '**';
5669 }
5670 return txt;
5671 });
5672
5673 showdown.subParser('makeMarkdown.table', function (node, globals) {
5674 'use strict';
5675
5676 var txt = '',
5677 tableArray = [[], []],
5678 headings = node.querySelectorAll('thead>tr>th'),
5679 rows = node.querySelectorAll('tbody>tr'),
5680 i, ii;
5681 for (i = 0; i < headings.length; ++i) {
5682 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals),
5683 allign = '---';
5684
5685 if (headings[i].hasAttribute('style')) {
5686 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, '');
5687 switch (style) {
5688 case 'text-align:left;':
5689 allign = ':---';
5690 break;
5691 case 'text-align:right;':
5692 allign = '---:';
5693 break;
5694 case 'text-align:center;':
5695 allign = ':---:';
5696 break;
5697 }
5698 }
5699 tableArray[0][i] = headContent.trim();
5700 tableArray[1][i] = allign;
5701 }
5702
5703 for (i = 0; i < rows.length; ++i) {
5704 var r = tableArray.push([]) - 1,
5705 cols = rows[i].getElementsByTagName('td');
5706
5707 for (ii = 0; ii < headings.length; ++ii) {
5708 var cellContent = ' ';
5709 if (typeof cols[ii] !== 'undefined') {
5710 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals);
5711 }
5712 tableArray[r].push(cellContent);
5713 }
5714 }
5715
5716 var cellSpacesCount = 3;
5717 for (i = 0; i < tableArray.length; ++i) {
5718 for (ii = 0; ii < tableArray[i].length; ++ii) {
5719 var strLen = tableArray[i][ii].length;
5720 if (strLen > cellSpacesCount) {
5721 cellSpacesCount = strLen;
5722 }
5723 }
5724 }
5725
5726 for (i = 0; i < tableArray.length; ++i) {
5727 for (ii = 0; ii < tableArray[i].length; ++ii) {
5728 if (i === 1) {
5729 if (tableArray[i][ii].slice(-1) === ':') {
5730 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':';
5731 } else {
5732 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-');
5733 }
5734 } else {
5735 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount);
5736 }
5737 }
5738 txt += '| ' + tableArray[i].join(' | ') + ' |\n';
5739 }
5740
5741 return txt.trim();
5742 });
5743
5744 showdown.subParser('makeMarkdown.tableCell', function (node, globals) {
5745 'use strict';
5746
5747 var txt = '';
5748 if (!node.hasChildNodes()) {
5749 return '';
5750 }
5751 var children = node.childNodes,
5752 childrenLength = children.length;
5753
5754 for (var i = 0; i < childrenLength; ++i) {
5755 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true);
5756 }
5757 return txt.trim();
5758 });
5759
5760 showdown.subParser('makeMarkdown.txt', function (node) {
5761 'use strict';
5762
5763 var txt = node.nodeValue;
5764
5765 // multiple spaces are collapsed
5766 txt = txt.replace(/ +/g, ' ');
5767
5768 // replace the custom ¨NBSP; with a space
5769 txt = txt.replace(/¨NBSP;/g, ' ');
5770
5771 // ", <, > and & should replace escaped html entities
5772 txt = showdown.helper.unescapeHTMLEntities(txt);
5773
5774 // escape markdown magic characters
5775 // emphasis, strong and strikethrough - can appear everywhere
5776 // we also escape pipe (|) because of tables
5777 // and escape ` because of code blocks and spans
5778 txt = txt.replace(/([*_~|`])/g, '\\$1');
5779
5780 // escape > because of blockquotes
5781 txt = txt.replace(/^(\s*)>/g, '\\$1>');
5782
5783 // hash character, only troublesome at the beginning of a line because of headers
5784 txt = txt.replace(/^#/gm, '\\#');
5785
5786 // horizontal rules
5787 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3');
5788
5789 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer
5790 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.');
5791
5792 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped)
5793 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2');
5794
5795 // images and links, ] followed by ( is problematic, so we escape it
5796 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\(');
5797
5798 // reference URIs must also be escaped
5799 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:');
5800
5801 return txt;
5802 });
5803
5804 var root = this;
5805
5806 // AMD Loader
5807 if (true) {
5808 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
5809 'use strict';
5810 return showdown;
5811 }).call(exports, __webpack_require__, exports, module),
5812 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
5813
5814 // CommonJS/nodeJS Loader
5815 } else {}
5816 }).call(this);
5817
5818
5819
5820
5821 /***/ })
5822
5823 /******/ });
5824 /************************************************************************/
5825 /******/ // The module cache
5826 /******/ var __webpack_module_cache__ = {};
5827 /******/
5828 /******/ // The require function
5829 /******/ function __webpack_require__(moduleId) {
5830 /******/ // Check if module is in cache
5831 /******/ var cachedModule = __webpack_module_cache__[moduleId];
5832 /******/ if (cachedModule !== undefined) {
5833 /******/ return cachedModule.exports;
5834 /******/ }
5835 /******/ // Create a new module (and put it into the cache)
5836 /******/ var module = __webpack_module_cache__[moduleId] = {
5837 /******/ // no module.id needed
5838 /******/ // no module.loaded needed
5839 /******/ exports: {}
5840 /******/ };
5841 /******/
5842 /******/ // Execute the module function
5843 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
5844 /******/
5845 /******/ // Return the exports of the module
5846 /******/ return module.exports;
5847 /******/ }
5848 /******/
5849 /************************************************************************/
5850 /******/ /* webpack/runtime/compat get default export */
5851 /******/ !function() {
5852 /******/ // getDefaultExport function for compatibility with non-harmony modules
5853 /******/ __webpack_require__.n = function(module) {
5854 /******/ var getter = module && module.__esModule ?
5855 /******/ function() { return module['default']; } :
5856 /******/ function() { return module; };
5857 /******/ __webpack_require__.d(getter, { a: getter });
5858 /******/ return getter;
5859 /******/ };
5860 /******/ }();
5861 /******/
5862 /******/ /* webpack/runtime/define property getters */
5863 /******/ !function() {
5864 /******/ // define getter functions for harmony exports
5865 /******/ __webpack_require__.d = function(exports, definition) {
5866 /******/ for(var key in definition) {
5867 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
5868 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
5869 /******/ }
5870 /******/ }
5871 /******/ };
5872 /******/ }();
5873 /******/
5874 /******/ /* webpack/runtime/hasOwnProperty shorthand */
5875 /******/ !function() {
5876 /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
5877 /******/ }();
5878 /******/
5879 /******/ /* webpack/runtime/make namespace object */
5880 /******/ !function() {
5881 /******/ // define __esModule on exports
5882 /******/ __webpack_require__.r = function(exports) {
5883 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
5884 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5885 /******/ }
5886 /******/ Object.defineProperty(exports, '__esModule', { value: true });
5887 /******/ };
5888 /******/ }();
5889 /******/
5890 /************************************************************************/
5891 var __webpack_exports__ = {};
5892 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
5893 !function() {
5894 "use strict";
5895 // ESM COMPAT FLAG
5896 __webpack_require__.r(__webpack_exports__);
5897
5898 // EXPORTS
5899 __webpack_require__.d(__webpack_exports__, {
5900 "__EXPERIMENTAL_ELEMENTS": function() { return /* reexport */ __EXPERIMENTAL_ELEMENTS; },
5901 "__EXPERIMENTAL_PATHS_WITH_MERGE": function() { return /* reexport */ __EXPERIMENTAL_PATHS_WITH_MERGE; },
5902 "__EXPERIMENTAL_STYLE_PROPERTY": function() { return /* reexport */ __EXPERIMENTAL_STYLE_PROPERTY; },
5903 "__experimentalCloneSanitizedBlock": function() { return /* reexport */ __experimentalCloneSanitizedBlock; },
5904 "__experimentalGetAccessibleBlockLabel": function() { return /* reexport */ getAccessibleBlockLabel; },
5905 "__experimentalGetBlockAttributesNamesByRole": function() { return /* reexport */ __experimentalGetBlockAttributesNamesByRole; },
5906 "__experimentalGetBlockLabel": function() { return /* reexport */ getBlockLabel; },
5907 "__experimentalSanitizeBlockAttributes": function() { return /* reexport */ __experimentalSanitizeBlockAttributes; },
5908 "__unstableGetBlockProps": function() { return /* reexport */ getBlockProps; },
5909 "__unstableGetInnerBlocksProps": function() { return /* reexport */ getInnerBlocksProps; },
5910 "__unstableSerializeAndClean": function() { return /* reexport */ __unstableSerializeAndClean; },
5911 "children": function() { return /* reexport */ children; },
5912 "cloneBlock": function() { return /* reexport */ cloneBlock; },
5913 "createBlock": function() { return /* reexport */ createBlock; },
5914 "createBlocksFromInnerBlocksTemplate": function() { return /* reexport */ createBlocksFromInnerBlocksTemplate; },
5915 "doBlocksMatchTemplate": function() { return /* reexport */ doBlocksMatchTemplate; },
5916 "findTransform": function() { return /* reexport */ findTransform; },
5917 "getBlockAttributes": function() { return /* reexport */ getBlockAttributes; },
5918 "getBlockContent": function() { return /* reexport */ getBlockInnerHTML; },
5919 "getBlockDefaultClassName": function() { return /* reexport */ getBlockDefaultClassName; },
5920 "getBlockFromExample": function() { return /* reexport */ getBlockFromExample; },
5921 "getBlockMenuDefaultClassName": function() { return /* reexport */ getBlockMenuDefaultClassName; },
5922 "getBlockSupport": function() { return /* reexport */ getBlockSupport; },
5923 "getBlockTransforms": function() { return /* reexport */ getBlockTransforms; },
5924 "getBlockType": function() { return /* reexport */ getBlockType; },
5925 "getBlockTypes": function() { return /* reexport */ getBlockTypes; },
5926 "getBlockVariations": function() { return /* reexport */ getBlockVariations; },
5927 "getCategories": function() { return /* reexport */ categories_getCategories; },
5928 "getChildBlockNames": function() { return /* reexport */ getChildBlockNames; },
5929 "getDefaultBlockName": function() { return /* reexport */ getDefaultBlockName; },
5930 "getFreeformContentHandlerName": function() { return /* reexport */ getFreeformContentHandlerName; },
5931 "getGroupingBlockName": function() { return /* reexport */ getGroupingBlockName; },
5932 "getPhrasingContentSchema": function() { return /* reexport */ deprecatedGetPhrasingContentSchema; },
5933 "getPossibleBlockTransformations": function() { return /* reexport */ getPossibleBlockTransformations; },
5934 "getSaveContent": function() { return /* reexport */ getSaveContent; },
5935 "getSaveElement": function() { return /* reexport */ getSaveElement; },
5936 "getUnregisteredTypeHandlerName": function() { return /* reexport */ getUnregisteredTypeHandlerName; },
5937 "hasBlockSupport": function() { return /* reexport */ hasBlockSupport; },
5938 "hasChildBlocks": function() { return /* reexport */ hasChildBlocks; },
5939 "hasChildBlocksWithInserterSupport": function() { return /* reexport */ hasChildBlocksWithInserterSupport; },
5940 "isReusableBlock": function() { return /* reexport */ isReusableBlock; },
5941 "isTemplatePart": function() { return /* reexport */ isTemplatePart; },
5942 "isUnmodifiedBlock": function() { return /* reexport */ isUnmodifiedBlock; },
5943 "isUnmodifiedDefaultBlock": function() { return /* reexport */ isUnmodifiedDefaultBlock; },
5944 "isValidBlockContent": function() { return /* reexport */ isValidBlockContent; },
5945 "isValidIcon": function() { return /* reexport */ isValidIcon; },
5946 "node": function() { return /* reexport */ node; },
5947 "normalizeIconObject": function() { return /* reexport */ normalizeIconObject; },
5948 "parse": function() { return /* reexport */ parser_parse; },
5949 "parseWithAttributeSchema": function() { return /* reexport */ parseWithAttributeSchema; },
5950 "pasteHandler": function() { return /* reexport */ pasteHandler; },
5951 "rawHandler": function() { return /* reexport */ rawHandler; },
5952 "registerBlockCollection": function() { return /* reexport */ registerBlockCollection; },
5953 "registerBlockStyle": function() { return /* reexport */ registerBlockStyle; },
5954 "registerBlockType": function() { return /* reexport */ registerBlockType; },
5955 "registerBlockVariation": function() { return /* reexport */ registerBlockVariation; },
5956 "serialize": function() { return /* reexport */ serialize; },
5957 "serializeRawBlock": function() { return /* reexport */ serializeRawBlock; },
5958 "setCategories": function() { return /* reexport */ categories_setCategories; },
5959 "setDefaultBlockName": function() { return /* reexport */ setDefaultBlockName; },
5960 "setFreeformContentHandlerName": function() { return /* reexport */ setFreeformContentHandlerName; },
5961 "setGroupingBlockName": function() { return /* reexport */ setGroupingBlockName; },
5962 "setUnregisteredTypeHandlerName": function() { return /* reexport */ setUnregisteredTypeHandlerName; },
5963 "store": function() { return /* reexport */ store; },
5964 "switchToBlockType": function() { return /* reexport */ switchToBlockType; },
5965 "synchronizeBlocksWithTemplate": function() { return /* reexport */ synchronizeBlocksWithTemplate; },
5966 "unregisterBlockStyle": function() { return /* reexport */ unregisterBlockStyle; },
5967 "unregisterBlockType": function() { return /* reexport */ unregisterBlockType; },
5968 "unregisterBlockVariation": function() { return /* reexport */ unregisterBlockVariation; },
5969 "unstable__bootstrapServerSideBlockDefinitions": function() { return /* reexport */ unstable__bootstrapServerSideBlockDefinitions; },
5970 "updateCategory": function() { return /* reexport */ categories_updateCategory; },
5971 "validateBlock": function() { return /* reexport */ validateBlock; },
5972 "withBlockContentContext": function() { return /* reexport */ withBlockContentContext; }
5973 });
5974
5975 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/selectors.js
5976 var selectors_namespaceObject = {};
5977 __webpack_require__.r(selectors_namespaceObject);
5978 __webpack_require__.d(selectors_namespaceObject, {
5979 "__experimentalGetUnprocessedBlockTypes": function() { return __experimentalGetUnprocessedBlockTypes; },
5980 "__experimentalHasContentRoleAttribute": function() { return __experimentalHasContentRoleAttribute; },
5981 "getActiveBlockVariation": function() { return getActiveBlockVariation; },
5982 "getBlockStyles": function() { return getBlockStyles; },
5983 "getBlockSupport": function() { return selectors_getBlockSupport; },
5984 "getBlockType": function() { return selectors_getBlockType; },
5985 "getBlockTypes": function() { return selectors_getBlockTypes; },
5986 "getBlockVariations": function() { return selectors_getBlockVariations; },
5987 "getCategories": function() { return getCategories; },
5988 "getChildBlockNames": function() { return selectors_getChildBlockNames; },
5989 "getCollections": function() { return getCollections; },
5990 "getDefaultBlockName": function() { return selectors_getDefaultBlockName; },
5991 "getDefaultBlockVariation": function() { return getDefaultBlockVariation; },
5992 "getFreeformFallbackBlockName": function() { return getFreeformFallbackBlockName; },
5993 "getGroupingBlockName": function() { return selectors_getGroupingBlockName; },
5994 "getUnregisteredFallbackBlockName": function() { return getUnregisteredFallbackBlockName; },
5995 "hasBlockSupport": function() { return selectors_hasBlockSupport; },
5996 "hasChildBlocks": function() { return selectors_hasChildBlocks; },
5997 "hasChildBlocksWithInserterSupport": function() { return selectors_hasChildBlocksWithInserterSupport; },
5998 "isMatchingSearchTerm": function() { return isMatchingSearchTerm; }
5999 });
6000
6001 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/actions.js
6002 var actions_namespaceObject = {};
6003 __webpack_require__.r(actions_namespaceObject);
6004 __webpack_require__.d(actions_namespaceObject, {
6005 "__experimentalReapplyBlockTypeFilters": function() { return __experimentalReapplyBlockTypeFilters; },
6006 "__experimentalRegisterBlockType": function() { return __experimentalRegisterBlockType; },
6007 "addBlockCollection": function() { return addBlockCollection; },
6008 "addBlockStyles": function() { return addBlockStyles; },
6009 "addBlockTypes": function() { return addBlockTypes; },
6010 "addBlockVariations": function() { return addBlockVariations; },
6011 "removeBlockCollection": function() { return removeBlockCollection; },
6012 "removeBlockStyles": function() { return removeBlockStyles; },
6013 "removeBlockTypes": function() { return removeBlockTypes; },
6014 "removeBlockVariations": function() { return removeBlockVariations; },
6015 "setCategories": function() { return setCategories; },
6016 "setDefaultBlockName": function() { return actions_setDefaultBlockName; },
6017 "setFreeformFallbackBlockName": function() { return setFreeformFallbackBlockName; },
6018 "setGroupingBlockName": function() { return actions_setGroupingBlockName; },
6019 "setUnregisteredFallbackBlockName": function() { return setUnregisteredFallbackBlockName; },
6020 "updateCategory": function() { return updateCategory; }
6021 });
6022
6023 ;// CONCATENATED MODULE: external ["wp","data"]
6024 var external_wp_data_namespaceObject = window["wp"]["data"];
6025 ;// CONCATENATED MODULE: external "lodash"
6026 var external_lodash_namespaceObject = window["lodash"];
6027 ;// CONCATENATED MODULE: external ["wp","i18n"]
6028 var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
6029 ;// CONCATENATED MODULE: ./node_modules/colord/index.mjs
6030 var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return"string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return{r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return{h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return{r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return{h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return{h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e},c=function(r){return{h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return{h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n<t.length;n++){var e=t[n][0](r);if(e)return[e,t[n][1]]}return[null,void 0]},x=function(r){return"string"==typeof r?N(r.trim(),y.string):"object"==typeof r&&null!==r?N(r,y.object):[null,void 0]},I=function(r){return x(r)[1]},M=function(r,t){var n=c(r);return{h:n.h,s:e(n.s+100*t,0,100),l:n.l,a:n.a}},H=function(r){return(299*r.r+587*r.g+114*r.b)/1e3/255},$=function(r,t){var n=c(r);return{h:n.h,s:n.s,l:e(n.l+100*t,0,100),a:n.a}},j=function(){function r(r){this.parsed=x(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1}}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(H(this.rgba),2)},r.prototype.isDark=function(){return H(this.rgba)<.5},r.prototype.isLight=function(){return H(this.rgba)>=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return"number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=c(this.rgba);return"number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r))})},E=function(){return new j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})};
6031
6032 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs
6033 /* harmony default export */ function names(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return"transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g)}return b}};f.string.push([function(f){var r=f.toLowerCase(),d="transparent"===r?"#0000":a[r];return d?new e(d).toRgb():null},"name"])}
6034
6035 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs
6036 var a11y_o=function(o){var t=o/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},a11y_t=function(t){return.2126*a11y_o(t.r)+.7152*a11y_o(t.g)+.0722*a11y_o(t.b)};/* harmony default export */ function a11y(o){o.prototype.luminance=function(){return o=a11y_t(this.rgba),void 0===(r=2)&&(r=0),void 0===n&&(n=Math.pow(10,r)),Math.round(n*o)/n+0;var o,r,n},o.prototype.contrast=function(r){void 0===r&&(r="#FFF");var n,a,i,e,v,u,d,c=r instanceof o?r:new o(r);return e=this.rgba,v=c.toRgb(),u=a11y_t(e),d=a11y_t(v),n=u>d?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o="#FFF"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?"normal":i,"AAA"===(a=void 0===(n=r.level)?"AA":n)&&"normal"===e?7:"AA"===a&&"large"===e?3:4.5);var r,n,a,i,e}}
6037
6038 ;// CONCATENATED MODULE: external ["wp","element"]
6039 var external_wp_element_namespaceObject = window["wp"]["element"];
6040 ;// CONCATENATED MODULE: external ["wp","dom"]
6041 var external_wp_dom_namespaceObject = window["wp"]["dom"];
6042 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/constants.js
6043 const BLOCK_ICON_DEFAULT = 'block-default';
6044 /**
6045 * Array of valid keys in a block type settings deprecation object.
6046 *
6047 * @type {string[]}
6048 */
6049
6050 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion'];
6051 const __EXPERIMENTAL_STYLE_PROPERTY = {
6052 // Kept for back-compatibility purposes.
6053 '--wp--style--color--link': {
6054 value: ['color', 'link'],
6055 support: ['color', 'link']
6056 },
6057 background: {
6058 value: ['color', 'gradient'],
6059 support: ['color', 'gradients'],
6060 useEngine: true
6061 },
6062 backgroundColor: {
6063 value: ['color', 'background'],
6064 support: ['color', 'background'],
6065 requiresOptOut: true,
6066 useEngine: true
6067 },
6068 borderColor: {
6069 value: ['border', 'color'],
6070 support: ['__experimentalBorder', 'color'],
6071 useEngine: true
6072 },
6073 borderRadius: {
6074 value: ['border', 'radius'],
6075 support: ['__experimentalBorder', 'radius'],
6076 properties: {
6077 borderTopLeftRadius: 'topLeft',
6078 borderTopRightRadius: 'topRight',
6079 borderBottomLeftRadius: 'bottomLeft',
6080 borderBottomRightRadius: 'bottomRight'
6081 },
6082 useEngine: true
6083 },
6084 borderStyle: {
6085 value: ['border', 'style'],
6086 support: ['__experimentalBorder', 'style'],
6087 useEngine: true
6088 },
6089 borderWidth: {
6090 value: ['border', 'width'],
6091 support: ['__experimentalBorder', 'width'],
6092 useEngine: true
6093 },
6094 borderTopColor: {
6095 value: ['border', 'top', 'color'],
6096 support: ['__experimentalBorder', 'color'],
6097 useEngine: true
6098 },
6099 borderTopStyle: {
6100 value: ['border', 'top', 'style'],
6101 support: ['__experimentalBorder', 'style'],
6102 useEngine: true
6103 },
6104 borderTopWidth: {
6105 value: ['border', 'top', 'width'],
6106 support: ['__experimentalBorder', 'width'],
6107 useEngine: true
6108 },
6109 borderRightColor: {
6110 value: ['border', 'right', 'color'],
6111 support: ['__experimentalBorder', 'color'],
6112 useEngine: true
6113 },
6114 borderRightStyle: {
6115 value: ['border', 'right', 'style'],
6116 support: ['__experimentalBorder', 'style'],
6117 useEngine: true
6118 },
6119 borderRightWidth: {
6120 value: ['border', 'right', 'width'],
6121 support: ['__experimentalBorder', 'width'],
6122 useEngine: true
6123 },
6124 borderBottomColor: {
6125 value: ['border', 'bottom', 'color'],
6126 support: ['__experimentalBorder', 'color'],
6127 useEngine: true
6128 },
6129 borderBottomStyle: {
6130 value: ['border', 'bottom', 'style'],
6131 support: ['__experimentalBorder', 'style'],
6132 useEngine: true
6133 },
6134 borderBottomWidth: {
6135 value: ['border', 'bottom', 'width'],
6136 support: ['__experimentalBorder', 'width'],
6137 useEngine: true
6138 },
6139 borderLeftColor: {
6140 value: ['border', 'left', 'color'],
6141 support: ['__experimentalBorder', 'color'],
6142 useEngine: true
6143 },
6144 borderLeftStyle: {
6145 value: ['border', 'left', 'style'],
6146 support: ['__experimentalBorder', 'style'],
6147 useEngine: true
6148 },
6149 borderLeftWidth: {
6150 value: ['border', 'left', 'width'],
6151 support: ['__experimentalBorder', 'width'],
6152 useEngine: true
6153 },
6154 color: {
6155 value: ['color', 'text'],
6156 support: ['color', 'text'],
6157 requiresOptOut: true,
6158 useEngine: true
6159 },
6160 filter: {
6161 value: ['filter', 'duotone'],
6162 support: ['color', '__experimentalDuotone']
6163 },
6164 linkColor: {
6165 value: ['elements', 'link', 'color', 'text'],
6166 support: ['color', 'link']
6167 },
6168 buttonColor: {
6169 value: ['elements', 'button', 'color', 'text'],
6170 support: ['color', 'button']
6171 },
6172 buttonBackgroundColor: {
6173 value: ['elements', 'button', 'color', 'background'],
6174 support: ['color', 'button']
6175 },
6176 fontFamily: {
6177 value: ['typography', 'fontFamily'],
6178 support: ['typography', '__experimentalFontFamily'],
6179 useEngine: true
6180 },
6181 fontSize: {
6182 value: ['typography', 'fontSize'],
6183 support: ['typography', 'fontSize'],
6184 useEngine: true
6185 },
6186 fontStyle: {
6187 value: ['typography', 'fontStyle'],
6188 support: ['typography', '__experimentalFontStyle'],
6189 useEngine: true
6190 },
6191 fontWeight: {
6192 value: ['typography', 'fontWeight'],
6193 support: ['typography', '__experimentalFontWeight'],
6194 useEngine: true
6195 },
6196 lineHeight: {
6197 value: ['typography', 'lineHeight'],
6198 support: ['typography', 'lineHeight'],
6199 useEngine: true
6200 },
6201 margin: {
6202 value: ['spacing', 'margin'],
6203 support: ['spacing', 'margin'],
6204 properties: {
6205 marginTop: 'top',
6206 marginRight: 'right',
6207 marginBottom: 'bottom',
6208 marginLeft: 'left'
6209 },
6210 useEngine: true
6211 },
6212 minHeight: {
6213 value: ['dimensions', 'minHeight'],
6214 support: ['dimensions', 'minHeight'],
6215 useEngine: true
6216 },
6217 padding: {
6218 value: ['spacing', 'padding'],
6219 support: ['spacing', 'padding'],
6220 properties: {
6221 paddingTop: 'top',
6222 paddingRight: 'right',
6223 paddingBottom: 'bottom',
6224 paddingLeft: 'left'
6225 },
6226 useEngine: true
6227 },
6228 textDecoration: {
6229 value: ['typography', 'textDecoration'],
6230 support: ['typography', '__experimentalTextDecoration'],
6231 useEngine: true
6232 },
6233 textTransform: {
6234 value: ['typography', 'textTransform'],
6235 support: ['typography', '__experimentalTextTransform'],
6236 useEngine: true
6237 },
6238 letterSpacing: {
6239 value: ['typography', 'letterSpacing'],
6240 support: ['typography', '__experimentalLetterSpacing'],
6241 useEngine: true
6242 },
6243 '--wp--style--root--padding': {
6244 value: ['spacing', 'padding'],
6245 support: ['spacing', 'padding'],
6246 properties: {
6247 '--wp--style--root--padding-top': 'top',
6248 '--wp--style--root--padding-right': 'right',
6249 '--wp--style--root--padding-bottom': 'bottom',
6250 '--wp--style--root--padding-left': 'left'
6251 },
6252 rootOnly: true
6253 }
6254 };
6255 const __EXPERIMENTAL_ELEMENTS = {
6256 link: 'a',
6257 heading: 'h1, h2, h3, h4, h5, h6',
6258 h1: 'h1',
6259 h2: 'h2',
6260 h3: 'h3',
6261 h4: 'h4',
6262 h5: 'h5',
6263 h6: 'h6',
6264 button: '.wp-element-button, .wp-block-button__link',
6265 caption: '.wp-element-caption, .wp-block-audio figcaption, .wp-block-embed figcaption, .wp-block-gallery figcaption, .wp-block-image figcaption, .wp-block-table figcaption, .wp-block-video figcaption',
6266 cite: 'cite'
6267 };
6268 const __EXPERIMENTAL_PATHS_WITH_MERGE = {
6269 'color.duotone': true,
6270 'color.gradients': true,
6271 'color.palette': true,
6272 'typography.fontFamilies': true,
6273 'typography.fontSizes': true,
6274 'spacing.spacingSizes': true
6275 };
6276
6277 ;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.js
6278 /*! *****************************************************************************
6279 Copyright (c) Microsoft Corporation.
6280
6281 Permission to use, copy, modify, and/or distribute this software for any
6282 purpose with or without fee is hereby granted.
6283
6284 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
6285 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
6286 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
6287 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
6288 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
6289 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
6290 PERFORMANCE OF THIS SOFTWARE.
6291 ***************************************************************************** */
6292 /* global Reflect, Promise */
6293
6294 var extendStatics = function(d, b) {
6295 extendStatics = Object.setPrototypeOf ||
6296 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6297 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6298 return extendStatics(d, b);
6299 };
6300
6301 function __extends(d, b) {
6302 if (typeof b !== "function" && b !== null)
6303 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
6304 extendStatics(d, b);
6305 function __() { this.constructor = d; }
6306 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6307 }
6308
6309 var __assign = function() {
6310 __assign = Object.assign || function __assign(t) {
6311 for (var s, i = 1, n = arguments.length; i < n; i++) {
6312 s = arguments[i];
6313 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6314 }
6315 return t;
6316 }
6317 return __assign.apply(this, arguments);
6318 }
6319
6320 function __rest(s, e) {
6321 var t = {};
6322 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
6323 t[p] = s[p];
6324 if (s != null && typeof Object.getOwnPropertySymbols === "function")
6325 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
6326 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
6327 t[p[i]] = s[p[i]];
6328 }
6329 return t;
6330 }
6331
6332 function __decorate(decorators, target, key, desc) {
6333 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6334 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
6335 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6336 return c > 3 && r && Object.defineProperty(target, key, r), r;
6337 }
6338
6339 function __param(paramIndex, decorator) {
6340 return function (target, key) { decorator(target, key, paramIndex); }
6341 }
6342
6343 function __metadata(metadataKey, metadataValue) {
6344 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
6345 }
6346
6347 function __awaiter(thisArg, _arguments, P, generator) {
6348 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6349 return new (P || (P = Promise))(function (resolve, reject) {
6350 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6351 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6352 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6353 step((generator = generator.apply(thisArg, _arguments || [])).next());
6354 });
6355 }
6356
6357 function __generator(thisArg, body) {
6358 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
6359 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
6360 function verb(n) { return function (v) { return step([n, v]); }; }
6361 function step(op) {
6362 if (f) throw new TypeError("Generator is already executing.");
6363 while (_) try {
6364 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
6365 if (y = 0, t) op = [op[0] & 2, t.value];
6366 switch (op[0]) {
6367 case 0: case 1: t = op; break;
6368 case 4: _.label++; return { value: op[1], done: false };
6369 case 5: _.label++; y = op[1]; op = [0]; continue;
6370 case 7: op = _.ops.pop(); _.trys.pop(); continue;
6371 default:
6372 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
6373 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
6374 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
6375 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
6376 if (t[2]) _.ops.pop();
6377 _.trys.pop(); continue;
6378 }
6379 op = body.call(thisArg, _);
6380 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
6381 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
6382 }
6383 }
6384
6385 var __createBinding = Object.create ? (function(o, m, k, k2) {
6386 if (k2 === undefined) k2 = k;
6387 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
6388 }) : (function(o, m, k, k2) {
6389 if (k2 === undefined) k2 = k;
6390 o[k2] = m[k];
6391 });
6392
6393 function __exportStar(m, o) {
6394 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
6395 }
6396
6397 function __values(o) {
6398 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
6399 if (m) return m.call(o);
6400 if (o && typeof o.length === "number") return {
6401 next: function () {
6402 if (o && i >= o.length) o = void 0;
6403 return { value: o && o[i++], done: !o };
6404 }
6405 };
6406 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
6407 }
6408
6409 function __read(o, n) {
6410 var m = typeof Symbol === "function" && o[Symbol.iterator];
6411 if (!m) return o;
6412 var i = m.call(o), r, ar = [], e;
6413 try {
6414 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
6415 }
6416 catch (error) { e = { error: error }; }
6417 finally {
6418 try {
6419 if (r && !r.done && (m = i["return"])) m.call(i);
6420 }
6421 finally { if (e) throw e.error; }
6422 }
6423 return ar;
6424 }
6425
6426 /** @deprecated */
6427 function __spread() {
6428 for (var ar = [], i = 0; i < arguments.length; i++)
6429 ar = ar.concat(__read(arguments[i]));
6430 return ar;
6431 }
6432
6433 /** @deprecated */
6434 function __spreadArrays() {
6435 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
6436 for (var r = Array(s), k = 0, i = 0; i < il; i++)
6437 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
6438 r[k] = a[j];
6439 return r;
6440 }
6441
6442 function __spreadArray(to, from, pack) {
6443 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
6444 if (ar || !(i in from)) {
6445 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6446 ar[i] = from[i];
6447 }
6448 }
6449 return to.concat(ar || from);
6450 }
6451
6452 function __await(v) {
6453 return this instanceof __await ? (this.v = v, this) : new __await(v);
6454 }
6455
6456 function __asyncGenerator(thisArg, _arguments, generator) {
6457 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
6458 var g = generator.apply(thisArg, _arguments || []), i, q = [];
6459 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
6460 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
6461 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
6462 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
6463 function fulfill(value) { resume("next", value); }
6464 function reject(value) { resume("throw", value); }
6465 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
6466 }
6467
6468 function __asyncDelegator(o) {
6469 var i, p;
6470 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
6471 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
6472 }
6473
6474 function __asyncValues(o) {
6475 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
6476 var m = o[Symbol.asyncIterator], i;
6477 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
6478 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
6479 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
6480 }
6481
6482 function __makeTemplateObject(cooked, raw) {
6483 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
6484 return cooked;
6485 };
6486
6487 var __setModuleDefault = Object.create ? (function(o, v) {
6488 Object.defineProperty(o, "default", { enumerable: true, value: v });
6489 }) : function(o, v) {
6490 o["default"] = v;
6491 };
6492
6493 function __importStar(mod) {
6494 if (mod && mod.__esModule) return mod;
6495 var result = {};
6496 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
6497 __setModuleDefault(result, mod);
6498 return result;
6499 }
6500
6501 function __importDefault(mod) {
6502 return (mod && mod.__esModule) ? mod : { default: mod };
6503 }
6504
6505 function __classPrivateFieldGet(receiver, state, kind, f) {
6506 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6507 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6508 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6509 }
6510
6511 function __classPrivateFieldSet(receiver, state, value, kind, f) {
6512 if (kind === "m") throw new TypeError("Private method is not writable");
6513 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6514 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6515 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6516 }
6517
6518 ;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js
6519 /**
6520 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
6521 */
6522 var SUPPORTED_LOCALE = {
6523 tr: {
6524 regexp: /\u0130|\u0049|\u0049\u0307/g,
6525 map: {
6526 İ: "\u0069",
6527 I: "\u0131",
6528 İ: "\u0069",
6529 },
6530 },
6531 az: {
6532 regexp: /\u0130/g,
6533 map: {
6534 İ: "\u0069",
6535 I: "\u0131",
6536 İ: "\u0069",
6537 },
6538 },
6539 lt: {
6540 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g,
6541 map: {
6542 I: "\u0069\u0307",
6543 J: "\u006A\u0307",
6544 Į: "\u012F\u0307",
6545 Ì: "\u0069\u0307\u0300",
6546 Í: "\u0069\u0307\u0301",
6547 Ĩ: "\u0069\u0307\u0303",
6548 },
6549 },
6550 };
6551 /**
6552 * Localized lower case.
6553 */
6554 function localeLowerCase(str, locale) {
6555 var lang = SUPPORTED_LOCALE[locale.toLowerCase()];
6556 if (lang)
6557 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; }));
6558 return lowerCase(str);
6559 }
6560 /**
6561 * Lower case as a function.
6562 */
6563 function lowerCase(str) {
6564 return str.toLowerCase();
6565 }
6566
6567 ;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js
6568
6569 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case").
6570 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
6571 // Remove all non-word characters.
6572 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
6573 /**
6574 * Normalize the string into something other libraries can manipulate easier.
6575 */
6576 function noCase(input, options) {
6577 if (options === void 0) { options = {}; }
6578 var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d;
6579 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
6580 var start = 0;
6581 var end = result.length;
6582 // Trim the delimiter from around the output string.
6583 while (result.charAt(start) === "\0")
6584 start++;
6585 while (result.charAt(end - 1) === "\0")
6586 end--;
6587 // Transform each token independently.
6588 return result.slice(start, end).split("\0").map(transform).join(delimiter);
6589 }
6590 /**
6591 * Replace `re` in the input string with the replacement value.
6592 */
6593 function replace(input, re, value) {
6594 if (re instanceof RegExp)
6595 return input.replace(re, value);
6596 return re.reduce(function (input, re) { return input.replace(re, value); }, input);
6597 }
6598
6599 ;// CONCATENATED MODULE: ./node_modules/pascal-case/dist.es2015/index.js
6600
6601
6602 function pascalCaseTransform(input, index) {
6603 var firstChar = input.charAt(0);
6604 var lowerChars = input.substr(1).toLowerCase();
6605 if (index > 0 && firstChar >= "0" && firstChar <= "9") {
6606 return "_" + firstChar + lowerChars;
6607 }
6608 return "" + firstChar.toUpperCase() + lowerChars;
6609 }
6610 function dist_es2015_pascalCaseTransformMerge(input) {
6611 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
6612 }
6613 function pascalCase(input, options) {
6614 if (options === void 0) { options = {}; }
6615 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options));
6616 }
6617
6618 ;// CONCATENATED MODULE: ./node_modules/camel-case/dist.es2015/index.js
6619
6620
6621 function camelCaseTransform(input, index) {
6622 if (index === 0)
6623 return input.toLowerCase();
6624 return pascalCaseTransform(input, index);
6625 }
6626 function camelCaseTransformMerge(input, index) {
6627 if (index === 0)
6628 return input.toLowerCase();
6629 return pascalCaseTransformMerge(input);
6630 }
6631 function camelCase(input, options) {
6632 if (options === void 0) { options = {}; }
6633 return pascalCase(input, __assign({ transform: camelCaseTransform }, options));
6634 }
6635
6636 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/registration.js
6637 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */
6638
6639 /**
6640 * External dependencies
6641 */
6642
6643 /**
6644 * WordPress dependencies
6645 */
6646
6647
6648
6649 /**
6650 * Internal dependencies
6651 */
6652
6653 const i18nBlockSchema = {
6654 title: "block title",
6655 description: "block description",
6656 keywords: ["block keyword"],
6657 styles: [{
6658 label: "block style label"
6659 }],
6660 variations: [{
6661 title: "block variation title",
6662 description: "block variation description",
6663 keywords: ["block variation keyword"]
6664 }]
6665 };
6666
6667
6668 /**
6669 * An icon type definition. One of a Dashicon slug, an element,
6670 * or a component.
6671 *
6672 * @typedef {(string|WPElement|WPComponent)} WPIcon
6673 *
6674 * @see https://developer.wordpress.org/resource/dashicons/
6675 */
6676
6677 /**
6678 * Render behavior of a block type icon; one of a Dashicon slug, an element,
6679 * or a component.
6680 *
6681 * @typedef {WPIcon} WPBlockTypeIconRender
6682 */
6683
6684 /**
6685 * An object describing a normalized block type icon.
6686 *
6687 * @typedef {Object} WPBlockTypeIconDescriptor
6688 *
6689 * @property {WPBlockTypeIconRender} src Render behavior of the icon,
6690 * one of a Dashicon slug, an
6691 * element, or a component.
6692 * @property {string} background Optimal background hex string
6693 * color when displaying icon.
6694 * @property {string} foreground Optimal foreground hex string
6695 * color when displaying icon.
6696 * @property {string} shadowColor Optimal shadow hex string
6697 * color when displaying icon.
6698 */
6699
6700 /**
6701 * Value to use to render the icon for a block type in an editor interface,
6702 * either a Dashicon slug, an element, a component, or an object describing
6703 * the icon.
6704 *
6705 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon
6706 */
6707
6708 /**
6709 * Named block variation scopes.
6710 *
6711 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope
6712 */
6713
6714 /**
6715 * An object describing a variation defined for the block type.
6716 *
6717 * @typedef {Object} WPBlockVariation
6718 *
6719 * @property {string} name The unique and machine-readable name.
6720 * @property {string} title A human-readable variation title.
6721 * @property {string} [description] A detailed variation description.
6722 * @property {string} [category] Block type category classification,
6723 * used in search interfaces to arrange
6724 * block types by category.
6725 * @property {WPIcon} [icon] An icon helping to visualize the variation.
6726 * @property {boolean} [isDefault] Indicates whether the current variation is
6727 * the default one. Defaults to `false`.
6728 * @property {Object} [attributes] Values which override block attributes.
6729 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks.
6730 * @property {Object} [example] Example provides structured data for
6731 * the block preview. You can set to
6732 * `undefined` to disable the preview shown
6733 * for the block type.
6734 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation
6735 * is applicable. When not provided, it
6736 * assumes all available scopes.
6737 * @property {string[]} [keywords] An array of terms (which can be translated)
6738 * that help users discover the variation
6739 * while searching.
6740 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes.
6741 * Function that accepts a block's attributes and the
6742 * variation's attributes and determines if a variation is active.
6743 * This function doesn't try to find a match dynamically based
6744 * on all block's attributes, as in many cases some attributes are irrelevant.
6745 * An example would be for `embed` block where we only care
6746 * about `providerNameSlug` attribute's value.
6747 * We can also use a `string[]` to tell which attributes
6748 * should be compared as a shorthand. Each attributes will
6749 * be matched and the variation will be active if all of them are matching.
6750 */
6751
6752 /**
6753 * Defined behavior of a block type.
6754 *
6755 * @typedef {Object} WPBlockType
6756 *
6757 * @property {string} name Block type's namespaced name.
6758 * @property {string} title Human-readable block type label.
6759 * @property {string} [description] A detailed block type description.
6760 * @property {string} [category] Block type category classification,
6761 * used in search interfaces to arrange
6762 * block types by category.
6763 * @property {WPBlockTypeIcon} [icon] Block type icon.
6764 * @property {string[]} [keywords] Additional keywords to produce block
6765 * type as result in search interfaces.
6766 * @property {Object} [attributes] Block type attributes.
6767 * @property {WPComponent} [save] Optional component describing
6768 * serialized markup structure of a
6769 * block type.
6770 * @property {WPComponent} edit Component rendering an element to
6771 * manipulate the attributes of a block
6772 * in the context of an editor.
6773 * @property {WPBlockVariation[]} [variations] The list of block variations.
6774 * @property {Object} [example] Example provides structured data for
6775 * the block preview. When not defined
6776 * then no preview is shown.
6777 */
6778
6779 const serverSideBlockDefinitions = {};
6780
6781 function isObject(object) {
6782 return object !== null && typeof object === 'object';
6783 }
6784 /**
6785 * Sets the server side block definition of blocks.
6786 *
6787 * @param {Object} definitions Server-side block definitions
6788 */
6789 // eslint-disable-next-line camelcase
6790
6791
6792 function unstable__bootstrapServerSideBlockDefinitions(definitions) {
6793 for (const blockName of Object.keys(definitions)) {
6794 // Don't overwrite if already set. It covers the case when metadata
6795 // was initialized from the server.
6796 if (serverSideBlockDefinitions[blockName]) {
6797 // We still need to polyfill `apiVersion` for WordPress version
6798 // lower than 5.7. If it isn't present in the definition shared
6799 // from the server, we try to fallback to the definition passed.
6800 // @see https://github.com/WordPress/gutenberg/pull/29279
6801 if (serverSideBlockDefinitions[blockName].apiVersion === undefined && definitions[blockName].apiVersion) {
6802 serverSideBlockDefinitions[blockName].apiVersion = definitions[blockName].apiVersion;
6803 } // The `ancestor` prop is not included in the definitions shared
6804 // from the server yet, so it needs to be polyfilled as well.
6805 // @see https://github.com/WordPress/gutenberg/pull/39894
6806
6807
6808 if (serverSideBlockDefinitions[blockName].ancestor === undefined && definitions[blockName].ancestor) {
6809 serverSideBlockDefinitions[blockName].ancestor = definitions[blockName].ancestor;
6810 }
6811
6812 continue;
6813 }
6814
6815 serverSideBlockDefinitions[blockName] = Object.fromEntries(Object.entries(definitions[blockName]).filter(_ref => {
6816 let [, value] = _ref;
6817 return value !== null && value !== undefined;
6818 }).map(_ref2 => {
6819 let [key, value] = _ref2;
6820 return [camelCase(key), value];
6821 }));
6822 }
6823 }
6824 /**
6825 * Gets block settings from metadata loaded from `block.json` file.
6826 *
6827 * @param {Object} metadata Block metadata loaded from `block.json`.
6828 * @param {string} metadata.textdomain Textdomain to use with translations.
6829 *
6830 * @return {Object} Block settings.
6831 */
6832
6833 function getBlockSettingsFromMetadata(_ref3) {
6834 let {
6835 textdomain,
6836 ...metadata
6837 } = _ref3;
6838 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'supports', 'styles', 'example', 'variations'];
6839 const settings = Object.fromEntries(Object.entries(metadata).filter(_ref4 => {
6840 let [key] = _ref4;
6841 return allowedFields.includes(key);
6842 }));
6843
6844 if (textdomain) {
6845 Object.keys(i18nBlockSchema).forEach(key => {
6846 if (!settings[key]) {
6847 return;
6848 }
6849
6850 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain);
6851 });
6852 }
6853
6854 return settings;
6855 }
6856 /**
6857 * Registers a new block provided a unique name and an object defining its
6858 * behavior. Once registered, the block is made available as an option to any
6859 * editor interface where blocks are implemented.
6860 *
6861 * For more in-depth information on registering a custom block see the [Create a block tutorial](docs/how-to-guides/block-tutorial/README.md)
6862 *
6863 * @param {string|Object} blockNameOrMetadata Block type name or its metadata.
6864 * @param {Object} settings Block settings.
6865 *
6866 * @example
6867 * ```js
6868 * import { __ } from '@wordpress/i18n';
6869 * import { registerBlockType } from '@wordpress/blocks'
6870 *
6871 * registerBlockType( 'namespace/block-name', {
6872 * title: __( 'My First Block' ),
6873 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>,
6874 * save: () => <div>Hello from the saved content!</div>,
6875 * } );
6876 * ```
6877 *
6878 * @return {WPBlockType | undefined} The block, if it has been successfully registered;
6879 * otherwise `undefined`.
6880 */
6881
6882
6883 function registerBlockType(blockNameOrMetadata, settings) {
6884 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata;
6885
6886 if (typeof name !== 'string') {
6887 console.error('Block names must be strings.');
6888 return;
6889 }
6890
6891 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) {
6892 console.error('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block');
6893 return;
6894 }
6895
6896 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) {
6897 console.error('Block "' + name + '" is already registered.');
6898 return;
6899 }
6900
6901 if (isObject(blockNameOrMetadata)) {
6902 unstable__bootstrapServerSideBlockDefinitions({
6903 [name]: getBlockSettingsFromMetadata(blockNameOrMetadata)
6904 });
6905 }
6906
6907 const blockType = {
6908 name,
6909 icon: BLOCK_ICON_DEFAULT,
6910 keywords: [],
6911 attributes: {},
6912 providesContext: {},
6913 usesContext: [],
6914 supports: {},
6915 styles: [],
6916 variations: [],
6917 save: () => null,
6918 ...(serverSideBlockDefinitions === null || serverSideBlockDefinitions === void 0 ? void 0 : serverSideBlockDefinitions[name]),
6919 ...settings
6920 };
6921
6922 (0,external_wp_data_namespaceObject.dispatch)(store).__experimentalRegisterBlockType(blockType);
6923
6924 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name);
6925 }
6926 /**
6927 * Translates block settings provided with metadata using the i18n schema.
6928 *
6929 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting.
6930 * @param {string|string[]|Object[]} settingValue Value for the block setting.
6931 * @param {string} textdomain Textdomain to use with translations.
6932 *
6933 * @return {string|string[]|Object[]} Translated setting.
6934 */
6935
6936 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) {
6937 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') {
6938 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain
6939 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain);
6940 }
6941
6942 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) {
6943 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain));
6944 }
6945
6946 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) {
6947 return Object.keys(settingValue).reduce((accumulator, key) => {
6948 if (!i18nSchema[key]) {
6949 accumulator[key] = settingValue[key];
6950 return accumulator;
6951 }
6952
6953 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain);
6954 return accumulator;
6955 }, {});
6956 }
6957
6958 return settingValue;
6959 }
6960 /**
6961 * Registers a new block collection to group blocks in the same namespace in the inserter.
6962 *
6963 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace.
6964 * @param {Object} settings The block collection settings.
6965 * @param {string} settings.title The title to display in the block inserter.
6966 * @param {Object} [settings.icon] The icon to display in the block inserter.
6967 *
6968 * @example
6969 * ```js
6970 * import { __ } from '@wordpress/i18n';
6971 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks';
6972 *
6973 * // Register the collection.
6974 * registerBlockCollection( 'my-collection', {
6975 * title: __( 'Custom Collection' ),
6976 * } );
6977 *
6978 * // Register a block in the same namespace to add it to the collection.
6979 * registerBlockType( 'my-collection/block-name', {
6980 * title: __( 'My First Block' ),
6981 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>,
6982 * save: () => <div>'Hello from the saved content!</div>,
6983 * } );
6984 * ```
6985 */
6986
6987
6988 function registerBlockCollection(namespace, _ref5) {
6989 let {
6990 title,
6991 icon
6992 } = _ref5;
6993 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon);
6994 }
6995 /**
6996 * Unregisters a block collection
6997 *
6998 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace
6999 *
7000 * @example
7001 * ```js
7002 * import { unregisterBlockCollection } from '@wordpress/blocks';
7003 *
7004 * unregisterBlockCollection( 'my-collection' );
7005 * ```
7006 */
7007
7008 function unregisterBlockCollection(namespace) {
7009 dispatch(blocksStore).removeBlockCollection(namespace);
7010 }
7011 /**
7012 * Unregisters a block.
7013 *
7014 * @param {string} name Block name.
7015 *
7016 * @example
7017 * ```js
7018 * import { __ } from '@wordpress/i18n';
7019 * import { unregisterBlockType } from '@wordpress/blocks';
7020 *
7021 * const ExampleComponent = () => {
7022 * return (
7023 * <Button
7024 * onClick={ () =>
7025 * unregisterBlockType( 'my-collection/block-name' )
7026 * }
7027 * >
7028 * { __( 'Unregister my custom block.' ) }
7029 * </Button>
7030 * );
7031 * };
7032 * ```
7033 *
7034 * @return {WPBlockType | undefined} The previous block value, if it has been successfully
7035 * unregistered; otherwise `undefined`.
7036 */
7037
7038 function unregisterBlockType(name) {
7039 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name);
7040
7041 if (!oldBlock) {
7042 console.error('Block "' + name + '" is not registered.');
7043 return;
7044 }
7045
7046 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name);
7047 return oldBlock;
7048 }
7049 /**
7050 * Assigns name of block for handling non-block content.
7051 *
7052 * @param {string} blockName Block name.
7053 */
7054
7055 function setFreeformContentHandlerName(blockName) {
7056 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName);
7057 }
7058 /**
7059 * Retrieves name of block handling non-block content, or undefined if no
7060 * handler has been defined.
7061 *
7062 * @return {?string} Block name.
7063 */
7064
7065 function getFreeformContentHandlerName() {
7066 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName();
7067 }
7068 /**
7069 * Retrieves name of block used for handling grouping interactions.
7070 *
7071 * @return {?string} Block name.
7072 */
7073
7074 function getGroupingBlockName() {
7075 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName();
7076 }
7077 /**
7078 * Assigns name of block handling unregistered block types.
7079 *
7080 * @param {string} blockName Block name.
7081 */
7082
7083 function setUnregisteredTypeHandlerName(blockName) {
7084 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName);
7085 }
7086 /**
7087 * Retrieves name of block handling unregistered block types, or undefined if no
7088 * handler has been defined.
7089 *
7090 * @return {?string} Block name.
7091 */
7092
7093 function getUnregisteredTypeHandlerName() {
7094 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName();
7095 }
7096 /**
7097 * Assigns the default block name.
7098 *
7099 * @param {string} name Block name.
7100 *
7101 * @example
7102 * ```js
7103 * import { setDefaultBlockName } from '@wordpress/blocks';
7104 *
7105 * const ExampleComponent = () => {
7106 *
7107 * return (
7108 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }>
7109 * { __( 'Set the default block to Heading' ) }
7110 * </Button>
7111 * );
7112 * };
7113 * ```
7114 */
7115
7116 function setDefaultBlockName(name) {
7117 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name);
7118 }
7119 /**
7120 * Assigns name of block for handling block grouping interactions.
7121 *
7122 * @param {string} name Block name.
7123 *
7124 * @example
7125 * ```js
7126 * import { setGroupingBlockName } from '@wordpress/blocks';
7127 *
7128 * const ExampleComponent = () => {
7129 *
7130 * return (
7131 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }>
7132 * { __( 'Set the default block to Heading' ) }
7133 * </Button>
7134 * );
7135 * };
7136 * ```
7137 */
7138
7139 function setGroupingBlockName(name) {
7140 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name);
7141 }
7142 /**
7143 * Retrieves the default block name.
7144 *
7145 * @return {?string} Block name.
7146 */
7147
7148 function getDefaultBlockName() {
7149 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName();
7150 }
7151 /**
7152 * Returns a registered block type.
7153 *
7154 * @param {string} name Block name.
7155 *
7156 * @return {?Object} Block type.
7157 */
7158
7159 function getBlockType(name) {
7160 var _select;
7161
7162 return (_select = (0,external_wp_data_namespaceObject.select)(store)) === null || _select === void 0 ? void 0 : _select.getBlockType(name);
7163 }
7164 /**
7165 * Returns all registered blocks.
7166 *
7167 * @return {Array} Block settings.
7168 */
7169
7170 function getBlockTypes() {
7171 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes();
7172 }
7173 /**
7174 * Returns the block support value for a feature, if defined.
7175 *
7176 * @param {(string|Object)} nameOrType Block name or type object
7177 * @param {string} feature Feature to retrieve
7178 * @param {*} defaultSupports Default value to return if not
7179 * explicitly defined
7180 *
7181 * @return {?*} Block support value
7182 */
7183
7184 function getBlockSupport(nameOrType, feature, defaultSupports) {
7185 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports);
7186 }
7187 /**
7188 * Returns true if the block defines support for a feature, or false otherwise.
7189 *
7190 * @param {(string|Object)} nameOrType Block name or type object.
7191 * @param {string} feature Feature to test.
7192 * @param {boolean} defaultSupports Whether feature is supported by
7193 * default if not explicitly defined.
7194 *
7195 * @return {boolean} Whether block supports feature.
7196 */
7197
7198 function hasBlockSupport(nameOrType, feature, defaultSupports) {
7199 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports);
7200 }
7201 /**
7202 * Determines whether or not the given block is a reusable block. This is a
7203 * special block type that is used to point to a global block stored via the
7204 * API.
7205 *
7206 * @param {Object} blockOrType Block or Block Type to test.
7207 *
7208 * @return {boolean} Whether the given block is a reusable block.
7209 */
7210
7211 function isReusableBlock(blockOrType) {
7212 return (blockOrType === null || blockOrType === void 0 ? void 0 : blockOrType.name) === 'core/block';
7213 }
7214 /**
7215 * Determines whether or not the given block is a template part. This is a
7216 * special block type that allows composing a page template out of reusable
7217 * design elements.
7218 *
7219 * @param {Object} blockOrType Block or Block Type to test.
7220 *
7221 * @return {boolean} Whether the given block is a template part.
7222 */
7223
7224 function isTemplatePart(blockOrType) {
7225 return (blockOrType === null || blockOrType === void 0 ? void 0 : blockOrType.name) === 'core/template-part';
7226 }
7227 /**
7228 * Returns an array with the child blocks of a given block.
7229 *
7230 * @param {string} blockName Name of block (example: “latest-posts”).
7231 *
7232 * @return {Array} Array of child block names.
7233 */
7234
7235 const getChildBlockNames = blockName => {
7236 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName);
7237 };
7238 /**
7239 * Returns a boolean indicating if a block has child blocks or not.
7240 *
7241 * @param {string} blockName Name of block (example: “latest-posts”).
7242 *
7243 * @return {boolean} True if a block contains child blocks and false otherwise.
7244 */
7245
7246 const hasChildBlocks = blockName => {
7247 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName);
7248 };
7249 /**
7250 * Returns a boolean indicating if a block has at least one child block with inserter support.
7251 *
7252 * @param {string} blockName Block type name.
7253 *
7254 * @return {boolean} True if a block contains at least one child blocks with inserter support
7255 * and false otherwise.
7256 */
7257
7258 const hasChildBlocksWithInserterSupport = blockName => {
7259 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName);
7260 };
7261 /**
7262 * Registers a new block style for the given block.
7263 *
7264 * For more information on connecting the styles with CSS [the official documentation](/docs/reference-guides/block-api/block-styles.md#styles)
7265 *
7266 * @param {string} blockName Name of block (example: “core/latest-posts”).
7267 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user.
7268 *
7269 * @example
7270 * ```js
7271 * import { __ } from '@wordpress/i18n';
7272 * import { registerBlockStyle } from '@wordpress/blocks';
7273 * import { Button } from '@wordpress/components';
7274 *
7275 *
7276 * const ExampleComponent = () => {
7277 * return (
7278 * <Button
7279 * onClick={ () => {
7280 * registerBlockStyle( 'core/quote', {
7281 * name: 'fancy-quote',
7282 * label: __( 'Fancy Quote' ),
7283 * } );
7284 * } }
7285 * >
7286 * { __( 'Add a new block style for core/quote' ) }
7287 * </Button>
7288 * );
7289 * };
7290 * ```
7291 */
7292
7293 const registerBlockStyle = (blockName, styleVariation) => {
7294 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockName, styleVariation);
7295 };
7296 /**
7297 * Unregisters a block style for the given block.
7298 *
7299 * @param {string} blockName Name of block (example: “core/latest-posts”).
7300 * @param {string} styleVariationName Name of class applied to the block.
7301 *
7302 * @example
7303 * ```js
7304 * import { __ } from '@wordpress/i18n';
7305 * import { unregisterBlockStyle } from '@wordpress/blocks';
7306 * import { Button } from '@wordpress/components';
7307 *
7308 * const ExampleComponent = () => {
7309 * return (
7310 * <Button
7311 * onClick={ () => {
7312 * unregisterBlockStyle( 'core/quote', 'plain' );
7313 * } }
7314 * >
7315 * { __( 'Remove the "Plain" block style for core/quote' ) }
7316 * </Button>
7317 * );
7318 * };
7319 * ```
7320 */
7321
7322 const unregisterBlockStyle = (blockName, styleVariationName) => {
7323 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName);
7324 };
7325 /**
7326 * Returns an array with the variations of a given block type.
7327 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data.
7328 *
7329 * @ignore
7330 *
7331 * @param {string} blockName Name of block (example: “core/columns”).
7332 * @param {WPBlockVariationScope} [scope] Block variation scope name.
7333 *
7334 * @return {(WPBlockVariation[]|void)} Block variations.
7335 */
7336
7337 const getBlockVariations = (blockName, scope) => {
7338 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope);
7339 };
7340 /**
7341 * Registers a new block variation for the given block type.
7342 *
7343 * For more information on block variations see [the official documentation ](/docs/reference-guides/block-api/block-variations.md)
7344 *
7345 * @param {string} blockName Name of the block (example: “core/columns”).
7346 * @param {WPBlockVariation} variation Object describing a block variation.
7347 *
7348 * @example
7349 * ```js
7350 * import { __ } from '@wordpress/i18n';
7351 * import { registerBlockVariation } from '@wordpress/blocks';
7352 * import { Button } from '@wordpress/components';
7353 *
7354 * const ExampleComponent = () => {
7355 * return (
7356 * <Button
7357 * onClick={ () => {
7358 * registerBlockVariation( 'core/embed', {
7359 * name: 'custom',
7360 * title: __( 'My Custom Embed' ),
7361 * attributes: { providerNameSlug: 'custom' },
7362 * } );
7363 * } }
7364 * >
7365 * __( 'Add a custom variation for core/embed' ) }
7366 * </Button>
7367 * );
7368 * };
7369 * ```
7370 */
7371
7372 const registerBlockVariation = (blockName, variation) => {
7373 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation);
7374 };
7375 /**
7376 * Unregisters a block variation defined for the given block type.
7377 *
7378 * @param {string} blockName Name of the block (example: “core/columns”).
7379 * @param {string} variationName Name of the variation defined for the block.
7380 *
7381 * @example
7382 * ```js
7383 * import { __ } from '@wordpress/i18n';
7384 * import { unregisterBlockVariation } from '@wordpress/blocks';
7385 * import { Button } from '@wordpress/components';
7386 *
7387 * const ExampleComponent = () => {
7388 * return (
7389 * <Button
7390 * onClick={ () => {
7391 * unregisterBlockVariation( 'core/embed', 'youtube' );
7392 * } }
7393 * >
7394 * { __( 'Remove the YouTube variation from core/embed' ) }
7395 * </Button>
7396 * );
7397 * };
7398 * ```
7399 */
7400
7401 const unregisterBlockVariation = (blockName, variationName) => {
7402 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName);
7403 };
7404
7405 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js
7406 // Unique ID creation requires a high quality random # generator. In the browser we therefore
7407 // require the crypto API and do not support built-in fallback to lower quality random number
7408 // generators (like Math.random()).
7409 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
7410 // find the complete implementation of crypto (msCrypto) on IE11.
7411 var getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
7412 var rnds8 = new Uint8Array(16);
7413 function rng() {
7414 if (!getRandomValues) {
7415 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
7416 }
7417
7418 return getRandomValues(rnds8);
7419 }
7420 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js
7421 /* harmony default export */ var regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i);
7422 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js
7423
7424
7425 function validate(uuid) {
7426 return typeof uuid === 'string' && regex.test(uuid);
7427 }
7428
7429 /* harmony default export */ var esm_browser_validate = (validate);
7430 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js
7431
7432 /**
7433 * Convert array of 16 byte values to UUID string format of the form:
7434 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
7435 */
7436
7437 var byteToHex = [];
7438
7439 for (var stringify_i = 0; stringify_i < 256; ++stringify_i) {
7440 byteToHex.push((stringify_i + 0x100).toString(16).substr(1));
7441 }
7442
7443 function stringify(arr) {
7444 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
7445 // Note: Be careful editing this code! It's been tuned for performance
7446 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
7447 var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
7448 // of the following:
7449 // - One or more input array values don't map to a hex octet (leading to
7450 // "undefined" in the uuid)
7451 // - Invalid input values for the RFC `version` or `variant` fields
7452
7453 if (!esm_browser_validate(uuid)) {
7454 throw TypeError('Stringified UUID is invalid');
7455 }
7456
7457 return uuid;
7458 }
7459
7460 /* harmony default export */ var esm_browser_stringify = (stringify);
7461 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js
7462
7463
7464
7465 function v4(options, buf, offset) {
7466 options = options || {};
7467 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
7468
7469 rnds[6] = rnds[6] & 0x0f | 0x40;
7470 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
7471
7472 if (buf) {
7473 offset = offset || 0;
7474
7475 for (var i = 0; i < 16; ++i) {
7476 buf[offset + i] = rnds[i];
7477 }
7478
7479 return buf;
7480 }
7481
7482 return esm_browser_stringify(rnds);
7483 }
7484
7485 /* harmony default export */ var esm_browser_v4 = (v4);
7486 ;// CONCATENATED MODULE: external ["wp","hooks"]
7487 var external_wp_hooks_namespaceObject = window["wp"]["hooks"];
7488 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/factory.js
7489 /**
7490 * External dependencies
7491 */
7492
7493 /**
7494 * WordPress dependencies
7495 */
7496
7497
7498 /**
7499 * Internal dependencies
7500 */
7501
7502
7503
7504 /**
7505 * Returns a block object given its type and attributes.
7506 *
7507 * @param {string} name Block name.
7508 * @param {Object} attributes Block attributes.
7509 * @param {?Array} innerBlocks Nested blocks.
7510 *
7511 * @return {Object} Block object.
7512 */
7513
7514 function createBlock(name) {
7515 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7516 let innerBlocks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
7517
7518 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes);
7519
7520 const clientId = esm_browser_v4(); // Blocks are stored with a unique ID, the assigned type name, the block
7521 // attributes, and their inner blocks.
7522
7523 return {
7524 clientId,
7525 name,
7526 isValid: true,
7527 attributes: sanitizedAttributes,
7528 innerBlocks
7529 };
7530 }
7531 /**
7532 * Given an array of InnerBlocks templates or Block Objects,
7533 * returns an array of created Blocks from them.
7534 * It handles the case of having InnerBlocks as Blocks by
7535 * converting them to the proper format to continue recursively.
7536 *
7537 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates.
7538 *
7539 * @return {Object[]} Array of Block objects.
7540 */
7541
7542 function createBlocksFromInnerBlocksTemplate() {
7543 let innerBlocksOrTemplate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
7544 return innerBlocksOrTemplate.map(innerBlock => {
7545 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks];
7546 const [name, attributes, innerBlocks = []] = innerBlockTemplate;
7547 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks));
7548 });
7549 }
7550 /**
7551 * Given a block object, returns a copy of the block object while sanitizing its attributes,
7552 * optionally merging new attributes and/or replacing its inner blocks.
7553 *
7554 * @param {Object} block Block instance.
7555 * @param {Object} mergeAttributes Block attributes.
7556 * @param {?Array} newInnerBlocks Nested blocks.
7557 *
7558 * @return {Object} A cloned block.
7559 */
7560
7561 function __experimentalCloneSanitizedBlock(block) {
7562 let mergeAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7563 let newInnerBlocks = arguments.length > 2 ? arguments[2] : undefined;
7564 const clientId = esm_browser_v4();
7565
7566 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { ...block.attributes,
7567 ...mergeAttributes
7568 });
7569
7570 return { ...block,
7571 clientId,
7572 attributes: sanitizedAttributes,
7573 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock))
7574 };
7575 }
7576 /**
7577 * Given a block object, returns a copy of the block object,
7578 * optionally merging new attributes and/or replacing its inner blocks.
7579 *
7580 * @param {Object} block Block instance.
7581 * @param {Object} mergeAttributes Block attributes.
7582 * @param {?Array} newInnerBlocks Nested blocks.
7583 *
7584 * @return {Object} A cloned block.
7585 */
7586
7587 function cloneBlock(block) {
7588 let mergeAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7589 let newInnerBlocks = arguments.length > 2 ? arguments[2] : undefined;
7590 const clientId = esm_browser_v4();
7591 return { ...block,
7592 clientId,
7593 attributes: { ...block.attributes,
7594 ...mergeAttributes
7595 },
7596 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock))
7597 };
7598 }
7599 /**
7600 * Returns a boolean indicating whether a transform is possible based on
7601 * various bits of context.
7602 *
7603 * @param {Object} transform The transform object to validate.
7604 * @param {string} direction Is this a 'from' or 'to' transform.
7605 * @param {Array} blocks The blocks to transform from.
7606 *
7607 * @return {boolean} Is the transform possible?
7608 */
7609
7610 const isPossibleTransformForSource = (transform, direction, blocks) => {
7611 if (!blocks.length) {
7612 return false;
7613 } // If multiple blocks are selected, only multi block transforms
7614 // or wildcard transforms are allowed.
7615
7616
7617 const isMultiBlock = blocks.length > 1;
7618 const firstBlockName = blocks[0].name;
7619 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock;
7620
7621 if (!isValidForMultiBlocks) {
7622 return false;
7623 } // Check non-wildcard transforms to ensure that transform is valid
7624 // for a block selection of multiple blocks of different types.
7625
7626
7627 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) {
7628 return false;
7629 } // Only consider 'block' type transforms as valid.
7630
7631
7632 const isBlockType = transform.type === 'block';
7633
7634 if (!isBlockType) {
7635 return false;
7636 } // Check if the transform's block name matches the source block (or is a wildcard)
7637 // only if this is a transform 'from'.
7638
7639
7640 const sourceBlock = blocks[0];
7641 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform);
7642
7643 if (!hasMatchingName) {
7644 return false;
7645 } // Don't allow single Grouping blocks to be transformed into
7646 // a Grouping block.
7647
7648
7649 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) {
7650 return false;
7651 } // If the transform has a `isMatch` function specified, check that it returns true.
7652
7653
7654 if (!maybeCheckTransformIsMatch(transform, blocks)) {
7655 return false;
7656 }
7657
7658 if (transform.usingMobileTransformations && isWildcardBlockTransform(transform) && !isContainerGroupBlock(sourceBlock.name)) {
7659 return false;
7660 }
7661
7662 return true;
7663 };
7664 /**
7665 * Returns block types that the 'blocks' can be transformed into, based on
7666 * 'from' transforms on other blocks.
7667 *
7668 * @param {Array} blocks The blocks to transform from.
7669 *
7670 * @return {Array} Block types that the blocks can be transformed into.
7671 */
7672
7673
7674 const getBlockTypesForPossibleFromTransforms = blocks => {
7675 if (!blocks.length) {
7676 return [];
7677 }
7678
7679 const allBlockTypes = getBlockTypes(); // filter all blocks to find those with a 'from' transform.
7680
7681 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => {
7682 const fromTransforms = getBlockTransforms('from', blockType.name);
7683 return !!findTransform(fromTransforms, transform => {
7684 return isPossibleTransformForSource(transform, 'from', blocks);
7685 });
7686 });
7687 return blockTypesWithPossibleFromTransforms;
7688 };
7689 /**
7690 * Returns block types that the 'blocks' can be transformed into, based on
7691 * the source block's own 'to' transforms.
7692 *
7693 * @param {Array} blocks The blocks to transform from.
7694 *
7695 * @return {Array} Block types that the source can be transformed into.
7696 */
7697
7698
7699 const getBlockTypesForPossibleToTransforms = blocks => {
7700 if (!blocks.length) {
7701 return [];
7702 }
7703
7704 const sourceBlock = blocks[0];
7705 const blockType = getBlockType(sourceBlock.name);
7706 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; // filter all 'to' transforms to find those that are possible.
7707
7708 const possibleTransforms = transformsTo.filter(transform => {
7709 return transform && isPossibleTransformForSource(transform, 'to', blocks);
7710 }); // Build a list of block names using the possible 'to' transforms.
7711
7712 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat(); // Map block names to block types.
7713
7714 return blockNames.map(name => name === '*' ? name : getBlockType(name));
7715 };
7716 /**
7717 * Determines whether transform is a "block" type
7718 * and if so whether it is a "wildcard" transform
7719 * ie: targets "any" block type
7720 *
7721 * @param {Object} t the Block transform object
7722 *
7723 * @return {boolean} whether transform is a wildcard transform
7724 */
7725
7726
7727 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*');
7728 /**
7729 * Determines whether the given Block is the core Block which
7730 * acts as a container Block for other Blocks as part of the
7731 * Grouping mechanics
7732 *
7733 * @param {string} name the name of the Block to test against
7734 *
7735 * @return {boolean} whether or not the Block is the container Block type
7736 */
7737
7738 const isContainerGroupBlock = name => name === getGroupingBlockName();
7739 /**
7740 * Returns an array of block types that the set of blocks received as argument
7741 * can be transformed into.
7742 *
7743 * @param {Array} blocks Blocks array.
7744 *
7745 * @return {Array} Block types that the blocks argument can be transformed to.
7746 */
7747
7748 function getPossibleBlockTransformations(blocks) {
7749 if (!blocks.length) {
7750 return [];
7751 }
7752
7753 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks);
7754 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks);
7755 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])];
7756 }
7757 /**
7758 * Given an array of transforms, returns the highest-priority transform where
7759 * the predicate function returns a truthy value. A higher-priority transform
7760 * is one with a lower priority value (i.e. first in priority order). Returns
7761 * null if the transforms set is empty or the predicate function returns a
7762 * falsey value for all entries.
7763 *
7764 * @param {Object[]} transforms Transforms to search.
7765 * @param {Function} predicate Function returning true on matching transform.
7766 *
7767 * @return {?Object} Highest-priority transform candidate.
7768 */
7769
7770 function findTransform(transforms, predicate) {
7771 // The hooks library already has built-in mechanisms for managing priority
7772 // queue, so leverage via locally-defined instance.
7773 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)();
7774
7775 for (let i = 0; i < transforms.length; i++) {
7776 const candidate = transforms[i];
7777
7778 if (predicate(candidate)) {
7779 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority);
7780 }
7781 } // Filter name is arbitrarily chosen but consistent with above aggregation.
7782
7783
7784 return hooks.applyFilters('transform', null);
7785 }
7786 /**
7787 * Returns normal block transforms for a given transform direction, optionally
7788 * for a specific block by name, or an empty array if there are no transforms.
7789 * If no block name is provided, returns transforms for all blocks. A normal
7790 * transform object includes `blockName` as a property.
7791 *
7792 * @param {string} direction Transform direction ("to", "from").
7793 * @param {string|Object} blockTypeOrName Block type or name.
7794 *
7795 * @return {Array} Block transforms for direction.
7796 */
7797
7798 function getBlockTransforms(direction, blockTypeOrName) {
7799 // When retrieving transforms for all block types, recurse into self.
7800 if (blockTypeOrName === undefined) {
7801 return getBlockTypes().map(_ref => {
7802 let {
7803 name
7804 } = _ref;
7805 return getBlockTransforms(direction, name);
7806 }).flat();
7807 } // Validate that block type exists and has array of direction.
7808
7809
7810 const blockType = normalizeBlockType(blockTypeOrName);
7811 const {
7812 name: blockName,
7813 transforms
7814 } = blockType || {};
7815
7816 if (!transforms || !Array.isArray(transforms[direction])) {
7817 return [];
7818 }
7819
7820 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms);
7821 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => {
7822 if (t.type === 'raw') {
7823 return true;
7824 }
7825
7826 if (!t.blocks || !t.blocks.length) {
7827 return false;
7828 }
7829
7830 if (isWildcardBlockTransform(t)) {
7831 return true;
7832 }
7833
7834 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName));
7835 }) : transforms[direction]; // Map transforms to normal form.
7836
7837 return filteredTransforms.map(transform => ({ ...transform,
7838 blockName,
7839 usingMobileTransformations
7840 }));
7841 }
7842 /**
7843 * Checks that a given transforms isMatch method passes for given source blocks.
7844 *
7845 * @param {Object} transform A transform object.
7846 * @param {Array} blocks Blocks array.
7847 *
7848 * @return {boolean} True if given blocks are a match for the transform.
7849 */
7850
7851 function maybeCheckTransformIsMatch(transform, blocks) {
7852 if (typeof transform.isMatch !== 'function') {
7853 return true;
7854 }
7855
7856 const sourceBlock = blocks[0];
7857 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes;
7858 const block = transform.isMultiBlock ? blocks : sourceBlock;
7859 return transform.isMatch(attributes, block);
7860 }
7861 /**
7862 * Switch one or more blocks into one or more blocks of the new block type.
7863 *
7864 * @param {Array|Object} blocks Blocks array or block object.
7865 * @param {string} name Block name.
7866 *
7867 * @return {?Array} Array of blocks or null.
7868 */
7869
7870
7871 function switchToBlockType(blocks, name) {
7872 const blocksArray = Array.isArray(blocks) ? blocks : [blocks];
7873 const isMultiBlock = blocksArray.length > 1;
7874 const firstBlock = blocksArray[0];
7875 const sourceName = firstBlock.name; // Find the right transformation by giving priority to the "to"
7876 // transformation.
7877
7878 const transformationsFrom = getBlockTransforms('from', name);
7879 const transformationsTo = getBlockTransforms('to', sourceName);
7880 const transformation = findTransform(transformationsTo, t => t.type === 'block' && t.blocks.indexOf(name) !== -1 && (!isMultiBlock || t.isMultiBlock) && maybeCheckTransformIsMatch(t, blocksArray)) || findTransform(transformationsFrom, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(sourceName) !== -1) && (!isMultiBlock || t.isMultiBlock) && maybeCheckTransformIsMatch(t, blocksArray)); // Stop if there is no valid transformation.
7881
7882 if (!transformation) {
7883 return null;
7884 }
7885
7886 let transformationResults;
7887
7888 if (transformation.isMultiBlock) {
7889 if ('__experimentalConvert' in transformation) {
7890 transformationResults = transformation.__experimentalConvert(blocksArray);
7891 } else {
7892 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks));
7893 }
7894 } else if ('__experimentalConvert' in transformation) {
7895 transformationResults = transformation.__experimentalConvert(firstBlock);
7896 } else {
7897 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks);
7898 } // Ensure that the transformation function returned an object or an array
7899 // of objects.
7900
7901
7902 if (transformationResults === null || typeof transformationResults !== 'object') {
7903 return null;
7904 } // If the transformation function returned a single object, we want to work
7905 // with an array instead.
7906
7907
7908 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults]; // Ensure that every block object returned by the transformation has a
7909 // valid block type.
7910
7911 if (transformationResults.some(result => !getBlockType(result.name))) {
7912 return null;
7913 } // When unwrapping blocks (`switchToBlockType( wrapperblocks, '*' )`), do
7914 // not run filters on the unwrapped blocks. They shoud remain as they are.
7915
7916
7917 if (name === '*') {
7918 return transformationResults;
7919 }
7920
7921 const hasSwitchedBlock = transformationResults.some(result => result.name === name); // Ensure that at least one block object returned by the transformation has
7922 // the expected "destination" block type.
7923
7924 if (!hasSwitchedBlock) {
7925 return null;
7926 }
7927
7928 const ret = transformationResults.map((result, index, results) => {
7929 /**
7930 * Filters an individual transform result from block transformation.
7931 * All of the original blocks are passed, since transformations are
7932 * many-to-many, not one-to-one.
7933 *
7934 * @param {Object} transformedBlock The transformed block.
7935 * @param {Object[]} blocks Original blocks transformed.
7936 * @param {Object[]} index Index of the transformed block on the array of results.
7937 * @param {Object[]} results An array all the blocks that resulted from the transformation.
7938 */
7939 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results);
7940 });
7941 return ret;
7942 }
7943 /**
7944 * Create a block object from the example API.
7945 *
7946 * @param {string} name
7947 * @param {Object} example
7948 *
7949 * @return {Object} block.
7950 */
7951
7952 const getBlockFromExample = (name, example) => {
7953 var _example$innerBlocks;
7954
7955 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock)));
7956 };
7957
7958 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/utils.js
7959 /**
7960 * External dependencies
7961 */
7962
7963
7964
7965 /**
7966 * WordPress dependencies
7967 */
7968
7969
7970
7971
7972 /**
7973 * Internal dependencies
7974 */
7975
7976
7977
7978
7979 k([names, a11y]);
7980 /**
7981 * Array of icon colors containing a color to be used if the icon color
7982 * was not explicitly set but the icon background color was.
7983 *
7984 * @type {Object}
7985 */
7986
7987 const ICON_COLORS = ['#191e23', '#f8f9f9'];
7988 /**
7989 * Determines whether the block's attributes are equal to the default attributes
7990 * which means the block is unmodified.
7991 *
7992 * @param {WPBlock} block Block Object
7993 *
7994 * @return {boolean} Whether the block is an unmodified block.
7995 */
7996
7997 function isUnmodifiedBlock(block) {
7998 var _blockType$attributes;
7999
8000 // Cache a created default block if no cache exists or the default block
8001 // name changed.
8002 if (!isUnmodifiedBlock[block.name]) {
8003 isUnmodifiedBlock[block.name] = createBlock(block.name);
8004 }
8005
8006 const newBlock = isUnmodifiedBlock[block.name];
8007 const blockType = getBlockType(block.name);
8008 return Object.keys((_blockType$attributes = blockType === null || blockType === void 0 ? void 0 : blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).every(key => newBlock.attributes[key] === block.attributes[key]);
8009 }
8010 /**
8011 * Determines whether the block is a default block and its attributes are equal
8012 * to the default attributes which means the block is unmodified.
8013 *
8014 * @param {WPBlock} block Block Object
8015 *
8016 * @return {boolean} Whether the block is an unmodified default block.
8017 */
8018
8019 function isUnmodifiedDefaultBlock(block) {
8020 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block);
8021 }
8022 /**
8023 * Function that checks if the parameter is a valid icon.
8024 *
8025 * @param {*} icon Parameter to be checked.
8026 *
8027 * @return {boolean} True if the parameter is a valid icon and false otherwise.
8028 */
8029
8030 function isValidIcon(icon) {
8031 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component);
8032 }
8033 /**
8034 * Function that receives an icon as set by the blocks during the registration
8035 * and returns a new icon object that is normalized so we can rely on just on possible icon structure
8036 * in the codebase.
8037 *
8038 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon;
8039 * one of a Dashicon slug, an element, or a
8040 * component.
8041 *
8042 * @return {WPBlockTypeIconDescriptor} Object describing the icon.
8043 */
8044
8045 function normalizeIconObject(icon) {
8046 icon = icon || BLOCK_ICON_DEFAULT;
8047
8048 if (isValidIcon(icon)) {
8049 return {
8050 src: icon
8051 };
8052 }
8053
8054 if ('background' in icon) {
8055 const colordBgColor = w(icon.background);
8056
8057 const getColorContrast = iconColor => colordBgColor.contrast(iconColor);
8058
8059 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast));
8060 return { ...icon,
8061 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast),
8062 shadowColor: colordBgColor.alpha(0.3).toRgbString()
8063 };
8064 }
8065
8066 return icon;
8067 }
8068 /**
8069 * Normalizes block type passed as param. When string is passed then
8070 * it converts it to the matching block type object.
8071 * It passes the original object otherwise.
8072 *
8073 * @param {string|Object} blockTypeOrName Block type or name.
8074 *
8075 * @return {?Object} Block type.
8076 */
8077
8078 function normalizeBlockType(blockTypeOrName) {
8079 if (typeof blockTypeOrName === 'string') {
8080 return getBlockType(blockTypeOrName);
8081 }
8082
8083 return blockTypeOrName;
8084 }
8085 /**
8086 * Get the label for the block, usually this is either the block title,
8087 * or the value of the block's `label` function when that's specified.
8088 *
8089 * @param {Object} blockType The block type.
8090 * @param {Object} attributes The values of the block's attributes.
8091 * @param {Object} context The intended use for the label.
8092 *
8093 * @return {string} The block label.
8094 */
8095
8096 function getBlockLabel(blockType, attributes) {
8097 let context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'visual';
8098 const {
8099 __experimentalLabel: getLabel,
8100 title
8101 } = blockType;
8102 const label = getLabel && getLabel(attributes, {
8103 context
8104 });
8105
8106 if (!label) {
8107 return title;
8108 } // Strip any HTML (i.e. RichText formatting) before returning.
8109
8110
8111 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label);
8112 }
8113 /**
8114 * Get a label for the block for use by screenreaders, this is more descriptive
8115 * than the visual label and includes the block title and the value of the
8116 * `getLabel` function if it's specified.
8117 *
8118 * @param {?Object} blockType The block type.
8119 * @param {Object} attributes The values of the block's attributes.
8120 * @param {?number} position The position of the block in the block list.
8121 * @param {string} [direction='vertical'] The direction of the block layout.
8122 *
8123 * @return {string} The block label.
8124 */
8125
8126 function getAccessibleBlockLabel(blockType, attributes, position) {
8127 let direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'vertical';
8128 // `title` is already localized, `label` is a user-supplied value.
8129 const title = blockType === null || blockType === void 0 ? void 0 : blockType.title;
8130 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : '';
8131 const hasPosition = position !== undefined; // getBlockLabel returns the block title as a fallback when there's no label,
8132 // if it did return the title, this function needs to avoid adding the
8133 // title twice within the accessible label. Use this `hasLabel` boolean to
8134 // handle that.
8135
8136 const hasLabel = label && label !== title;
8137
8138 if (hasPosition && direction === 'vertical') {
8139 if (hasLabel) {
8140 return (0,external_wp_i18n_namespaceObject.sprintf)(
8141 /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */
8142 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label);
8143 }
8144
8145 return (0,external_wp_i18n_namespaceObject.sprintf)(
8146 /* translators: accessibility text. 1: The block title. 2: The block row number. */
8147 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position);
8148 } else if (hasPosition && direction === 'horizontal') {
8149 if (hasLabel) {
8150 return (0,external_wp_i18n_namespaceObject.sprintf)(
8151 /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */
8152 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label);
8153 }
8154
8155 return (0,external_wp_i18n_namespaceObject.sprintf)(
8156 /* translators: accessibility text. 1: The block title. 2: The block column number. */
8157 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position);
8158 }
8159
8160 if (hasLabel) {
8161 return (0,external_wp_i18n_namespaceObject.sprintf)(
8162 /* translators: accessibility text. %1: The block title. %2: The block label. */
8163 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label);
8164 }
8165
8166 return (0,external_wp_i18n_namespaceObject.sprintf)(
8167 /* translators: accessibility text. %s: The block title. */
8168 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title);
8169 }
8170 /**
8171 * Ensure attributes contains only values defined by block type, and merge
8172 * default values for missing attributes.
8173 *
8174 * @param {string} name The block's name.
8175 * @param {Object} attributes The block's attributes.
8176 * @return {Object} The sanitized attributes.
8177 */
8178
8179 function __experimentalSanitizeBlockAttributes(name, attributes) {
8180 // Get the type definition associated with a registered block.
8181 const blockType = getBlockType(name);
8182
8183 if (undefined === blockType) {
8184 throw new Error(`Block type '${name}' is not registered.`);
8185 }
8186
8187 return Object.entries(blockType.attributes).reduce((accumulator, _ref) => {
8188 let [key, schema] = _ref;
8189 const value = attributes[key];
8190
8191 if (undefined !== value) {
8192 accumulator[key] = value;
8193 } else if (schema.hasOwnProperty('default')) {
8194 accumulator[key] = schema.default;
8195 }
8196
8197 if (['node', 'children'].indexOf(schema.source) !== -1) {
8198 // Ensure value passed is always an array, which we're expecting in
8199 // the RichText component to handle the deprecated value.
8200 if (typeof accumulator[key] === 'string') {
8201 accumulator[key] = [accumulator[key]];
8202 } else if (!Array.isArray(accumulator[key])) {
8203 accumulator[key] = [];
8204 }
8205 }
8206
8207 return accumulator;
8208 }, {});
8209 }
8210 /**
8211 * Filter block attributes by `role` and return their names.
8212 *
8213 * @param {string} name Block attribute's name.
8214 * @param {string} role The role of a block attribute.
8215 *
8216 * @return {string[]} The attribute names that have the provided role.
8217 */
8218
8219 function __experimentalGetBlockAttributesNamesByRole(name, role) {
8220 var _getBlockType;
8221
8222 const attributes = (_getBlockType = getBlockType(name)) === null || _getBlockType === void 0 ? void 0 : _getBlockType.attributes;
8223 if (!attributes) return [];
8224 const attributesNames = Object.keys(attributes);
8225 if (!role) return attributesNames;
8226 return attributesNames.filter(attributeName => {
8227 var _attributes$attribute;
8228
8229 return ((_attributes$attribute = attributes[attributeName]) === null || _attributes$attribute === void 0 ? void 0 : _attributes$attribute.__experimentalRole) === role;
8230 });
8231 }
8232 /**
8233 * Return a new object with the specified keys omitted.
8234 *
8235 * @param {Object} object Original object.
8236 * @param {Array} keys Keys to be omitted.
8237 *
8238 * @return {Object} Object with omitted keys.
8239 */
8240
8241 function omit(object, keys) {
8242 return Object.fromEntries(Object.entries(object).filter(_ref2 => {
8243 let [key] = _ref2;
8244 return !keys.includes(key);
8245 }));
8246 }
8247
8248 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/reducer.js
8249 /**
8250 * External dependencies
8251 */
8252
8253 /**
8254 * WordPress dependencies
8255 */
8256
8257
8258
8259 /**
8260 * Internal dependencies
8261 */
8262
8263
8264 /**
8265 * @typedef {Object} WPBlockCategory
8266 *
8267 * @property {string} slug Unique category slug.
8268 * @property {string} title Category label, for display in user interface.
8269 */
8270
8271 /**
8272 * Default set of categories.
8273 *
8274 * @type {WPBlockCategory[]}
8275 */
8276
8277 const DEFAULT_CATEGORIES = [{
8278 slug: 'text',
8279 title: (0,external_wp_i18n_namespaceObject.__)('Text')
8280 }, {
8281 slug: 'media',
8282 title: (0,external_wp_i18n_namespaceObject.__)('Media')
8283 }, {
8284 slug: 'design',
8285 title: (0,external_wp_i18n_namespaceObject.__)('Design')
8286 }, {
8287 slug: 'widgets',
8288 title: (0,external_wp_i18n_namespaceObject.__)('Widgets')
8289 }, {
8290 slug: 'theme',
8291 title: (0,external_wp_i18n_namespaceObject.__)('Theme')
8292 }, {
8293 slug: 'embed',
8294 title: (0,external_wp_i18n_namespaceObject.__)('Embeds')
8295 }, {
8296 slug: 'reusable',
8297 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks')
8298 }]; // Key block types by their name.
8299
8300 function keyBlockTypesByName(types) {
8301 return types.reduce((newBlockTypes, block) => ({ ...newBlockTypes,
8302 [block.name]: block
8303 }), {});
8304 } // Filter items to ensure they're unique by their name.
8305
8306
8307 function getUniqueItemsByName(items) {
8308 return items.reduce((acc, currentItem) => {
8309 if (!acc.some(item => item.name === currentItem.name)) {
8310 acc.push(currentItem);
8311 }
8312
8313 return acc;
8314 }, []);
8315 }
8316 /**
8317 * Reducer managing the unprocessed block types in a form passed when registering the by block.
8318 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters
8319 * get added or removed.
8320 *
8321 * @param {Object} state Current state.
8322 * @param {Object} action Dispatched action.
8323 *
8324 * @return {Object} Updated state.
8325 */
8326
8327
8328 function unprocessedBlockTypes() {
8329 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8330 let action = arguments.length > 1 ? arguments[1] : undefined;
8331
8332 switch (action.type) {
8333 case 'ADD_UNPROCESSED_BLOCK_TYPE':
8334 return { ...state,
8335 [action.blockType.name]: action.blockType
8336 };
8337
8338 case 'REMOVE_BLOCK_TYPES':
8339 return omit(state, action.names);
8340 }
8341
8342 return state;
8343 }
8344 /**
8345 * Reducer managing the processed block types with all filters applied.
8346 * The state is derived from the `unprocessedBlockTypes` reducer.
8347 *
8348 * @param {Object} state Current state.
8349 * @param {Object} action Dispatched action.
8350 *
8351 * @return {Object} Updated state.
8352 */
8353
8354 function blockTypes() {
8355 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8356 let action = arguments.length > 1 ? arguments[1] : undefined;
8357
8358 switch (action.type) {
8359 case 'ADD_BLOCK_TYPES':
8360 return { ...state,
8361 ...keyBlockTypesByName(action.blockTypes)
8362 };
8363
8364 case 'REMOVE_BLOCK_TYPES':
8365 return omit(state, action.names);
8366 }
8367
8368 return state;
8369 }
8370 /**
8371 * Reducer managing the block styles.
8372 *
8373 * @param {Object} state Current state.
8374 * @param {Object} action Dispatched action.
8375 *
8376 * @return {Object} Updated state.
8377 */
8378
8379 function blockStyles() {
8380 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8381 let action = arguments.length > 1 ? arguments[1] : undefined;
8382
8383 switch (action.type) {
8384 case 'ADD_BLOCK_TYPES':
8385 return { ...state,
8386 ...(0,external_lodash_namespaceObject.mapValues)(keyBlockTypesByName(action.blockTypes), blockType => getUniqueItemsByName([...(0,external_lodash_namespaceObject.get)(blockType, ['styles'], []).map(style => ({ ...style,
8387 source: 'block'
8388 })), ...(0,external_lodash_namespaceObject.get)(state, [blockType.name], []).filter(_ref => {
8389 let {
8390 source
8391 } = _ref;
8392 return 'block' !== source;
8393 })]))
8394 };
8395
8396 case 'ADD_BLOCK_STYLES':
8397 return { ...state,
8398 [action.blockName]: getUniqueItemsByName([...(0,external_lodash_namespaceObject.get)(state, [action.blockName], []), ...action.styles])
8399 };
8400
8401 case 'REMOVE_BLOCK_STYLES':
8402 return { ...state,
8403 [action.blockName]: (0,external_lodash_namespaceObject.get)(state, [action.blockName], []).filter(style => action.styleNames.indexOf(style.name) === -1)
8404 };
8405 }
8406
8407 return state;
8408 }
8409 /**
8410 * Reducer managing the block variations.
8411 *
8412 * @param {Object} state Current state.
8413 * @param {Object} action Dispatched action.
8414 *
8415 * @return {Object} Updated state.
8416 */
8417
8418 function blockVariations() {
8419 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8420 let action = arguments.length > 1 ? arguments[1] : undefined;
8421
8422 switch (action.type) {
8423 case 'ADD_BLOCK_TYPES':
8424 return { ...state,
8425 ...(0,external_lodash_namespaceObject.mapValues)(keyBlockTypesByName(action.blockTypes), blockType => {
8426 return getUniqueItemsByName([...(0,external_lodash_namespaceObject.get)(blockType, ['variations'], []).map(variation => ({ ...variation,
8427 source: 'block'
8428 })), ...(0,external_lodash_namespaceObject.get)(state, [blockType.name], []).filter(_ref2 => {
8429 let {
8430 source
8431 } = _ref2;
8432 return 'block' !== source;
8433 })]);
8434 })
8435 };
8436
8437 case 'ADD_BLOCK_VARIATIONS':
8438 return { ...state,
8439 [action.blockName]: getUniqueItemsByName([...(0,external_lodash_namespaceObject.get)(state, [action.blockName], []), ...action.variations])
8440 };
8441
8442 case 'REMOVE_BLOCK_VARIATIONS':
8443 return { ...state,
8444 [action.blockName]: (0,external_lodash_namespaceObject.get)(state, [action.blockName], []).filter(variation => action.variationNames.indexOf(variation.name) === -1)
8445 };
8446 }
8447
8448 return state;
8449 }
8450 /**
8451 * Higher-order Reducer creating a reducer keeping track of given block name.
8452 *
8453 * @param {string} setActionType Action type.
8454 *
8455 * @return {Function} Reducer.
8456 */
8457
8458 function createBlockNameSetterReducer(setActionType) {
8459 return function () {
8460 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
8461 let action = arguments.length > 1 ? arguments[1] : undefined;
8462
8463 switch (action.type) {
8464 case 'REMOVE_BLOCK_TYPES':
8465 if (action.names.indexOf(state) !== -1) {
8466 return null;
8467 }
8468
8469 return state;
8470
8471 case setActionType:
8472 return action.name || null;
8473 }
8474
8475 return state;
8476 };
8477 }
8478 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME');
8479 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME');
8480 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME');
8481 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME');
8482 /**
8483 * Reducer managing the categories
8484 *
8485 * @param {WPBlockCategory[]} state Current state.
8486 * @param {Object} action Dispatched action.
8487 *
8488 * @return {WPBlockCategory[]} Updated state.
8489 */
8490
8491 function categories() {
8492 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_CATEGORIES;
8493 let action = arguments.length > 1 ? arguments[1] : undefined;
8494
8495 switch (action.type) {
8496 case 'SET_CATEGORIES':
8497 return action.categories || [];
8498
8499 case 'UPDATE_CATEGORY':
8500 {
8501 if (!action.category || (0,external_lodash_namespaceObject.isEmpty)(action.category)) {
8502 return state;
8503 }
8504
8505 const categoryToChange = state.find(_ref3 => {
8506 let {
8507 slug
8508 } = _ref3;
8509 return slug === action.slug;
8510 });
8511
8512 if (categoryToChange) {
8513 return state.map(category => {
8514 if (category.slug === action.slug) {
8515 return { ...category,
8516 ...action.category
8517 };
8518 }
8519
8520 return category;
8521 });
8522 }
8523 }
8524 }
8525
8526 return state;
8527 }
8528 function collections() {
8529 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
8530 let action = arguments.length > 1 ? arguments[1] : undefined;
8531
8532 switch (action.type) {
8533 case 'ADD_BLOCK_COLLECTION':
8534 return { ...state,
8535 [action.namespace]: {
8536 title: action.title,
8537 icon: action.icon
8538 }
8539 };
8540
8541 case 'REMOVE_BLOCK_COLLECTION':
8542 return omit(state, action.namespace);
8543 }
8544
8545 return state;
8546 }
8547 /* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
8548 unprocessedBlockTypes,
8549 blockTypes,
8550 blockStyles,
8551 blockVariations,
8552 defaultBlockName,
8553 freeformFallbackBlockName,
8554 unregisteredFallbackBlockName,
8555 groupingBlockName,
8556 categories,
8557 collections
8558 }));
8559
8560 ;// CONCATENATED MODULE: ./node_modules/rememo/es/rememo.js
8561
8562
8563 /** @typedef {(...args: any[]) => *[]} GetDependants */
8564
8565 /** @typedef {() => void} Clear */
8566
8567 /**
8568 * @typedef {{
8569 * getDependants: GetDependants,
8570 * clear: Clear
8571 * }} EnhancedSelector
8572 */
8573
8574 /**
8575 * Internal cache entry.
8576 *
8577 * @typedef CacheNode
8578 *
8579 * @property {?CacheNode|undefined} [prev] Previous node.
8580 * @property {?CacheNode|undefined} [next] Next node.
8581 * @property {*[]} args Function arguments for cache entry.
8582 * @property {*} val Function result.
8583 */
8584
8585 /**
8586 * @typedef Cache
8587 *
8588 * @property {Clear} clear Function to clear cache.
8589 * @property {boolean} [isUniqueByDependants] Whether dependants are valid in
8590 * considering cache uniqueness. A cache is unique if dependents are all arrays
8591 * or objects.
8592 * @property {CacheNode?} [head] Cache head.
8593 * @property {*[]} [lastDependants] Dependants from previous invocation.
8594 */
8595
8596 /**
8597 * Arbitrary value used as key for referencing cache object in WeakMap tree.
8598 *
8599 * @type {{}}
8600 */
8601 var LEAF_KEY = {};
8602
8603 /**
8604 * Returns the first argument as the sole entry in an array.
8605 *
8606 * @template T
8607 *
8608 * @param {T} value Value to return.
8609 *
8610 * @return {[T]} Value returned as entry in array.
8611 */
8612 function arrayOf(value) {
8613 return [value];
8614 }
8615
8616 /**
8617 * Returns true if the value passed is object-like, or false otherwise. A value
8618 * is object-like if it can support property assignment, e.g. object or array.
8619 *
8620 * @param {*} value Value to test.
8621 *
8622 * @return {boolean} Whether value is object-like.
8623 */
8624 function isObjectLike(value) {
8625 return !!value && 'object' === typeof value;
8626 }
8627
8628 /**
8629 * Creates and returns a new cache object.
8630 *
8631 * @return {Cache} Cache object.
8632 */
8633 function createCache() {
8634 /** @type {Cache} */
8635 var cache = {
8636 clear: function () {
8637 cache.head = null;
8638 },
8639 };
8640
8641 return cache;
8642 }
8643
8644 /**
8645 * Returns true if entries within the two arrays are strictly equal by
8646 * reference from a starting index.
8647 *
8648 * @param {*[]} a First array.
8649 * @param {*[]} b Second array.
8650 * @param {number} fromIndex Index from which to start comparison.
8651 *
8652 * @return {boolean} Whether arrays are shallowly equal.
8653 */
8654 function isShallowEqual(a, b, fromIndex) {
8655 var i;
8656
8657 if (a.length !== b.length) {
8658 return false;
8659 }
8660
8661 for (i = fromIndex; i < a.length; i++) {
8662 if (a[i] !== b[i]) {
8663 return false;
8664 }
8665 }
8666
8667 return true;
8668 }
8669
8670 /**
8671 * Returns a memoized selector function. The getDependants function argument is
8672 * called before the memoized selector and is expected to return an immutable
8673 * reference or array of references on which the selector depends for computing
8674 * its own return value. The memoize cache is preserved only as long as those
8675 * dependant references remain the same. If getDependants returns a different
8676 * reference(s), the cache is cleared and the selector value regenerated.
8677 *
8678 * @template {(...args: *[]) => *} S
8679 *
8680 * @param {S} selector Selector function.
8681 * @param {GetDependants=} getDependants Dependant getter returning an array of
8682 * references used in cache bust consideration.
8683 */
8684 /* harmony default export */ function rememo(selector, getDependants) {
8685 /** @type {WeakMap<*,*>} */
8686 var rootCache;
8687
8688 /** @type {GetDependants} */
8689 var normalizedGetDependants = getDependants ? getDependants : arrayOf;
8690
8691 /**
8692 * Returns the cache for a given dependants array. When possible, a WeakMap
8693 * will be used to create a unique cache for each set of dependants. This
8694 * is feasible due to the nature of WeakMap in allowing garbage collection
8695 * to occur on entries where the key object is no longer referenced. Since
8696 * WeakMap requires the key to be an object, this is only possible when the
8697 * dependant is object-like. The root cache is created as a hierarchy where
8698 * each top-level key is the first entry in a dependants set, the value a
8699 * WeakMap where each key is the next dependant, and so on. This continues
8700 * so long as the dependants are object-like. If no dependants are object-
8701 * like, then the cache is shared across all invocations.
8702 *
8703 * @see isObjectLike
8704 *
8705 * @param {*[]} dependants Selector dependants.
8706 *
8707 * @return {Cache} Cache object.
8708 */
8709 function getCache(dependants) {
8710 var caches = rootCache,
8711 isUniqueByDependants = true,
8712 i,
8713 dependant,
8714 map,
8715 cache;
8716
8717 for (i = 0; i < dependants.length; i++) {
8718 dependant = dependants[i];
8719
8720 // Can only compose WeakMap from object-like key.
8721 if (!isObjectLike(dependant)) {
8722 isUniqueByDependants = false;
8723 break;
8724 }
8725
8726 // Does current segment of cache already have a WeakMap?
8727 if (caches.has(dependant)) {
8728 // Traverse into nested WeakMap.
8729 caches = caches.get(dependant);
8730 } else {
8731 // Create, set, and traverse into a new one.
8732 map = new WeakMap();
8733 caches.set(dependant, map);
8734 caches = map;
8735 }
8736 }
8737
8738 // We use an arbitrary (but consistent) object as key for the last item
8739 // in the WeakMap to serve as our running cache.
8740 if (!caches.has(LEAF_KEY)) {
8741 cache = createCache();
8742 cache.isUniqueByDependants = isUniqueByDependants;
8743 caches.set(LEAF_KEY, cache);
8744 }
8745
8746 return caches.get(LEAF_KEY);
8747 }
8748
8749 /**
8750 * Resets root memoization cache.
8751 */
8752 function clear() {
8753 rootCache = new WeakMap();
8754 }
8755
8756 /* eslint-disable jsdoc/check-param-names */
8757 /**
8758 * The augmented selector call, considering first whether dependants have
8759 * changed before passing it to underlying memoize function.
8760 *
8761 * @param {*} source Source object for derivation.
8762 * @param {...*} extraArgs Additional arguments to pass to selector.
8763 *
8764 * @return {*} Selector result.
8765 */
8766 /* eslint-enable jsdoc/check-param-names */
8767 function callSelector(/* source, ...extraArgs */) {
8768 var len = arguments.length,
8769 cache,
8770 node,
8771 i,
8772 args,
8773 dependants;
8774
8775 // Create copy of arguments (avoid leaking deoptimization).
8776 args = new Array(len);
8777 for (i = 0; i < len; i++) {
8778 args[i] = arguments[i];
8779 }
8780
8781 dependants = normalizedGetDependants.apply(null, args);
8782 cache = getCache(dependants);
8783
8784 // If not guaranteed uniqueness by dependants (primitive type), shallow
8785 // compare against last dependants and, if references have changed,
8786 // destroy cache to recalculate result.
8787 if (!cache.isUniqueByDependants) {
8788 if (
8789 cache.lastDependants &&
8790 !isShallowEqual(dependants, cache.lastDependants, 0)
8791 ) {
8792 cache.clear();
8793 }
8794
8795 cache.lastDependants = dependants;
8796 }
8797
8798 node = cache.head;
8799 while (node) {
8800 // Check whether node arguments match arguments
8801 if (!isShallowEqual(node.args, args, 1)) {
8802 node = node.next;
8803 continue;
8804 }
8805
8806 // At this point we can assume we've found a match
8807
8808 // Surface matched node to head if not already
8809 if (node !== cache.head) {
8810 // Adjust siblings to point to each other.
8811 /** @type {CacheNode} */ (node.prev).next = node.next;
8812 if (node.next) {
8813 node.next.prev = node.prev;
8814 }
8815
8816 node.next = cache.head;
8817 node.prev = null;
8818 /** @type {CacheNode} */ (cache.head).prev = node;
8819 cache.head = node;
8820 }
8821
8822 // Return immediately
8823 return node.val;
8824 }
8825
8826 // No cached value found. Continue to insertion phase:
8827
8828 node = /** @type {CacheNode} */ ({
8829 // Generate the result from original function
8830 val: selector.apply(null, args),
8831 });
8832
8833 // Avoid including the source object in the cache.
8834 args[0] = null;
8835 node.args = args;
8836
8837 // Don't need to check whether node is already head, since it would
8838 // have been returned above already if it was
8839
8840 // Shift existing head down list
8841 if (cache.head) {
8842 cache.head.prev = node;
8843 node.next = cache.head;
8844 }
8845
8846 cache.head = node;
8847
8848 return node.val;
8849 }
8850
8851 callSelector.getDependants = normalizedGetDependants;
8852 callSelector.clear = clear;
8853 clear();
8854
8855 return /** @type {S & EnhancedSelector} */ (callSelector);
8856 }
8857
8858 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js
8859 var remove_accents = __webpack_require__(4793);
8860 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents);
8861 ;// CONCATENATED MODULE: external ["wp","compose"]
8862 var external_wp_compose_namespaceObject = window["wp"]["compose"];
8863 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/selectors.js
8864 /**
8865 * External dependencies
8866 */
8867
8868
8869
8870 /**
8871 * WordPress dependencies
8872 */
8873
8874
8875 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
8876
8877 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */
8878
8879 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */
8880
8881 /**
8882 * Given a block name or block type object, returns the corresponding
8883 * normalized block type object.
8884 *
8885 * @param {Object} state Blocks state.
8886 * @param {(string|Object)} nameOrType Block name or type object
8887 *
8888 * @return {Object} Block type object.
8889 */
8890
8891 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType;
8892 /**
8893 * Returns all the unprocessed block types as passed during the registration.
8894 *
8895 * @param {Object} state Data state.
8896 *
8897 * @return {Array} Unprocessed block types.
8898 */
8899
8900
8901 function __experimentalGetUnprocessedBlockTypes(state) {
8902 return state.unprocessedBlockTypes;
8903 }
8904 /**
8905 * Returns all the available block types.
8906 *
8907 * @param {Object} state Data state.
8908 *
8909 * @example
8910 * ```js
8911 * import { store as blocksStore } from '@wordpress/blocks';
8912 * import { useSelect } from '@wordpress/data';
8913 *
8914 * const ExampleComponent = () => {
8915 * const blockTypes = useSelect(
8916 * ( select ) => select( blocksStore ).getBlockTypes(),
8917 * []
8918 * );
8919 *
8920 * return (
8921 * <ul>
8922 * { blockTypes.map( ( block ) => (
8923 * <li key={ block.name }>{ block.title }</li>
8924 * ) ) }
8925 * </ul>
8926 * );
8927 * };
8928 * ```
8929 *
8930 * @return {Array} Block Types.
8931 */
8932
8933 const selectors_getBlockTypes = rememo(state => Object.values(state.blockTypes), state => [state.blockTypes]);
8934 /**
8935 * Returns a block type by name.
8936 *
8937 * @param {Object} state Data state.
8938 * @param {string} name Block type name.
8939 *
8940 * @example
8941 * ```js
8942 * import { store as blocksStore } from '@wordpress/blocks';
8943 * import { useSelect } from '@wordpress/data';
8944 *
8945 * const ExampleComponent = () => {
8946 * const paragraphBlock = useSelect( ( select ) =>
8947 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ),
8948 * []
8949 * );
8950 *
8951 * return (
8952 * <ul>
8953 * { paragraphBlock &&
8954 * Object.entries( paragraphBlock.supports ).map(
8955 * ( blockSupportsEntry ) => {
8956 * const [ propertyName, value ] = blockSupportsEntry;
8957 * return (
8958 * <li
8959 * key={ propertyName }
8960 * >{ `${ propertyName } : ${ value }` }</li>
8961 * );
8962 * }
8963 * ) }
8964 * </ul>
8965 * );
8966 * };
8967 * ```
8968 *
8969 * @return {Object?} Block Type.
8970 */
8971
8972 function selectors_getBlockType(state, name) {
8973 return state.blockTypes[name];
8974 }
8975 /**
8976 * Returns block styles by block name.
8977 *
8978 * @param {Object} state Data state.
8979 * @param {string} name Block type name.
8980 *
8981 * @example
8982 * ```js
8983 * import { store as blocksStore } from '@wordpress/blocks';
8984 * import { useSelect } from '@wordpress/data';
8985 *
8986 * const ExampleComponent = () => {
8987 * const buttonBlockStyles = useSelect( ( select ) =>
8988 * select( blocksStore ).getBlockStyles( 'core/button' ),
8989 * []
8990 * );
8991 *
8992 * return (
8993 * <ul>
8994 * { buttonBlockStyles &&
8995 * buttonBlockStyles.map( ( style ) => (
8996 * <li key={ style.name }>{ style.label }</li>
8997 * ) ) }
8998 * </ul>
8999 * );
9000 * };
9001 * ```
9002 *
9003 * @return {Array?} Block Styles.
9004 */
9005
9006 function getBlockStyles(state, name) {
9007 return state.blockStyles[name];
9008 }
9009 /**
9010 * Returns block variations by block name.
9011 *
9012 * @param {Object} state Data state.
9013 * @param {string} blockName Block type name.
9014 * @param {WPBlockVariationScope} [scope] Block variation scope name.
9015 *
9016 * @example
9017 * ```js
9018 * import { store as blocksStore } from '@wordpress/blocks';
9019 * import { useSelect } from '@wordpress/data';
9020 *
9021 * const ExampleComponent = () => {
9022 * const socialLinkVariations = useSelect( ( select ) =>
9023 * select( blocksStore ).getBlockVariations( 'core/social-link' ),
9024 * []
9025 * );
9026 *
9027 * return (
9028 * <ul>
9029 * { socialLinkVariations &&
9030 * socialLinkVariations.map( ( variation ) => (
9031 * <li key={ variation.name }>{ variation.title }</li>
9032 * ) ) }
9033 * </ul>
9034 * );
9035 * };
9036 * ```
9037 *
9038 * @return {(WPBlockVariation[]|void)} Block variations.
9039 */
9040
9041 const selectors_getBlockVariations = rememo((state, blockName, scope) => {
9042 const variations = state.blockVariations[blockName];
9043
9044 if (!variations || !scope) {
9045 return variations;
9046 }
9047
9048 return variations.filter(variation => {
9049 // For backward compatibility reasons, variation's scope defaults to
9050 // `block` and `inserter` when not set.
9051 return (variation.scope || ['block', 'inserter']).includes(scope);
9052 });
9053 }, (state, blockName) => [state.blockVariations[blockName]]);
9054 /**
9055 * Returns the active block variation for a given block based on its attributes.
9056 * Variations are determined by their `isActive` property.
9057 * Which is either an array of block attribute keys or a function.
9058 *
9059 * In case of an array of block attribute keys, the `attributes` are compared
9060 * to the variation's attributes using strict equality check.
9061 *
9062 * In case of function type, the function should accept a block's attributes
9063 * and the variation's attributes and determines if a variation is active.
9064 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active.
9065 *
9066 * @param {Object} state Data state.
9067 * @param {string} blockName Name of block (example: “core/columns”).
9068 * @param {Object} attributes Block attributes used to determine active variation.
9069 * @param {WPBlockVariationScope} [scope] Block variation scope name.
9070 *
9071 * @example
9072 * ```js
9073 * import { __ } from '@wordpress/i18n';
9074 * import { store as blocksStore } from '@wordpress/blocks';
9075 * import { store as blockEditorStore } from '@wordpress/block-editor';
9076 * import { useSelect } from '@wordpress/data';
9077 *
9078 * const ExampleComponent = () => {
9079 * // This example assumes that a core/embed block is the first block in the Block Editor.
9080 * const activeBlockVariation = useSelect( ( select ) => {
9081 * // Retrieve the list of blocks.
9082 * const [ firstBlock ] = select( blockEditorStore ).getBlocks()
9083 *
9084 * // Return the active block variation for the first block.
9085 * return select( blocksStore ).getActiveBlockVariation(
9086 * firstBlock.name,
9087 * firstBlock.attributes
9088 * );
9089 * }, [] );
9090 *
9091 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? (
9092 * <p>{ __( 'Spotify variation' ) }</p>
9093 * ) : (
9094 * <p>{ __( 'Other variation' ) }</p>
9095 * );
9096 * };
9097 * ```
9098 *
9099 * @return {(WPBlockVariation|undefined)} Active block variation.
9100 */
9101
9102 function getActiveBlockVariation(state, blockName, attributes, scope) {
9103 const variations = selectors_getBlockVariations(state, blockName, scope);
9104 const match = variations === null || variations === void 0 ? void 0 : variations.find(variation => {
9105 var _variation$isActive;
9106
9107 if (Array.isArray(variation.isActive)) {
9108 const blockType = selectors_getBlockType(state, blockName);
9109 const attributeKeys = Object.keys((blockType === null || blockType === void 0 ? void 0 : blockType.attributes) || {});
9110 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute));
9111
9112 if (definedAttributes.length === 0) {
9113 return false;
9114 }
9115
9116 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]);
9117 }
9118
9119 return (_variation$isActive = variation.isActive) === null || _variation$isActive === void 0 ? void 0 : _variation$isActive.call(variation, attributes, variation.attributes);
9120 });
9121 return match;
9122 }
9123 /**
9124 * Returns the default block variation for the given block type.
9125 * When there are multiple variations annotated as the default one,
9126 * the last added item is picked. This simplifies registering overrides.
9127 * When there is no default variation set, it returns the first item.
9128 *
9129 * @param {Object} state Data state.
9130 * @param {string} blockName Block type name.
9131 * @param {WPBlockVariationScope} [scope] Block variation scope name.
9132 *
9133 * @example
9134 * ```js
9135 * import { __, sprintf } from '@wordpress/i18n';
9136 * import { store as blocksStore } from '@wordpress/blocks';
9137 * import { useSelect } from '@wordpress/data';
9138 *
9139 * const ExampleComponent = () => {
9140 * const defaultEmbedBlockVariation = useSelect( ( select ) =>
9141 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ),
9142 * []
9143 * );
9144 *
9145 * return (
9146 * defaultEmbedBlockVariation && (
9147 * <p>
9148 * { sprintf(
9149 * __( 'core/embed default variation: %s' ),
9150 * defaultEmbedBlockVariation.title
9151 * ) }
9152 * </p>
9153 * )
9154 * );
9155 * };
9156 * ```
9157 *
9158 * @return {?WPBlockVariation} The default block variation.
9159 */
9160
9161 function getDefaultBlockVariation(state, blockName, scope) {
9162 const variations = selectors_getBlockVariations(state, blockName, scope);
9163 const defaultVariation = [...variations].reverse().find(_ref => {
9164 let {
9165 isDefault
9166 } = _ref;
9167 return !!isDefault;
9168 });
9169 return defaultVariation || variations[0];
9170 }
9171 /**
9172 * Returns all the available block categories.
9173 *
9174 * @param {Object} state Data state.
9175 *
9176 * @example
9177 * ```js
9178 * import { store as blocksStore } from '@wordpress/blocks';
9179 * import { useSelect, } from '@wordpress/data';
9180 *
9181 * const ExampleComponent = () => {
9182 * const blockCategories = useSelect( ( select ) =>
9183 * select( blocksStore ).getCategories(),
9184 * []
9185 * );
9186 *
9187 * return (
9188 * <ul>
9189 * { blockCategories.map( ( category ) => (
9190 * <li key={ category.slug }>{ category.title }</li>
9191 * ) ) }
9192 * </ul>
9193 * );
9194 * };
9195 * ```
9196 *
9197 * @return {WPBlockCategory[]} Categories list.
9198 */
9199
9200 function getCategories(state) {
9201 return state.categories;
9202 }
9203 /**
9204 * Returns all the available collections.
9205 *
9206 * @param {Object} state Data state.
9207 *
9208 * @example
9209 * ```js
9210 * import { store as blocksStore } from '@wordpress/blocks';
9211 * import { useSelect } from '@wordpress/data';
9212 *
9213 * const ExampleComponent = () => {
9214 * const blockCollections = useSelect( ( select ) =>
9215 * select( blocksStore ).getCollections(),
9216 * []
9217 * );
9218 *
9219 * return (
9220 * <ul>
9221 * { Object.values( blockCollections ).length > 0 &&
9222 * Object.values( blockCollections ).map( ( collection ) => (
9223 * <li key={ collection.title }>{ collection.title }</li>
9224 * ) ) }
9225 * </ul>
9226 * );
9227 * };
9228 * ```
9229 *
9230 * @return {Object} Collections list.
9231 */
9232
9233 function getCollections(state) {
9234 return state.collections;
9235 }
9236 /**
9237 * Returns the name of the default block name.
9238 *
9239 * @param {Object} state Data state.
9240 *
9241 * @example
9242 * ```js
9243 * import { __, sprintf } from '@wordpress/i18n';
9244 * import { store as blocksStore } from '@wordpress/blocks';
9245 * import { useSelect } from '@wordpress/data';
9246 *
9247 * const ExampleComponent = () => {
9248 * const defaultBlockName = useSelect( ( select ) =>
9249 * select( blocksStore ).getDefaultBlockName(),
9250 * []
9251 * );
9252 *
9253 * return (
9254 * defaultBlockName && (
9255 * <p>
9256 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) }
9257 * </p>
9258 * )
9259 * );
9260 * };
9261 * ```
9262 *
9263 * @return {string?} Default block name.
9264 */
9265
9266 function selectors_getDefaultBlockName(state) {
9267 return state.defaultBlockName;
9268 }
9269 /**
9270 * Returns the name of the block for handling non-block content.
9271 *
9272 * @param {Object} state Data state.
9273 *
9274 * @example
9275 * ```js
9276 * import { __, sprintf } from '@wordpress/i18n';
9277 * import { store as blocksStore } from '@wordpress/blocks';
9278 * import { useSelect } from '@wordpress/data';
9279 *
9280 * const ExampleComponent = () => {
9281 * const freeformFallbackBlockName = useSelect( ( select ) =>
9282 * select( blocksStore ).getFreeformFallbackBlockName(),
9283 * []
9284 * );
9285 *
9286 * return (
9287 * freeformFallbackBlockName && (
9288 * <p>
9289 * { sprintf( __(
9290 * 'Freeform fallback block name: %s' ),
9291 * freeformFallbackBlockName
9292 * ) }
9293 * </p>
9294 * )
9295 * );
9296 * };
9297 * ```
9298 *
9299 * @return {string?} Name of the block for handling non-block content.
9300 */
9301
9302 function getFreeformFallbackBlockName(state) {
9303 return state.freeformFallbackBlockName;
9304 }
9305 /**
9306 * Returns the name of the block for handling unregistered blocks.
9307 *
9308 * @param {Object} state Data state.
9309 *
9310 * @example
9311 * ```js
9312 * import { __, sprintf } from '@wordpress/i18n';
9313 * import { store as blocksStore } from '@wordpress/blocks';
9314 * import { useSelect } from '@wordpress/data';
9315 *
9316 * const ExampleComponent = () => {
9317 * const unregisteredFallbackBlockName = useSelect( ( select ) =>
9318 * select( blocksStore ).getUnregisteredFallbackBlockName(),
9319 * []
9320 * );
9321 *
9322 * return (
9323 * unregisteredFallbackBlockName && (
9324 * <p>
9325 * { sprintf( __(
9326 * 'Unregistered fallback block name: %s' ),
9327 * unregisteredFallbackBlockName
9328 * ) }
9329 * </p>
9330 * )
9331 * );
9332 * };
9333 * ```
9334 *
9335 * @return {string?} Name of the block for handling unregistered blocks.
9336 */
9337
9338 function getUnregisteredFallbackBlockName(state) {
9339 return state.unregisteredFallbackBlockName;
9340 }
9341 /**
9342 * Returns the name of the block for handling the grouping of blocks.
9343 *
9344 * @param {Object} state Data state.
9345 *
9346 * @example
9347 * ```js
9348 * import { __, sprintf } from '@wordpress/i18n';
9349 * import { store as blocksStore } from '@wordpress/blocks';
9350 * import { useSelect } from '@wordpress/data';
9351 *
9352 * const ExampleComponent = () => {
9353 * const groupingBlockName = useSelect( ( select ) =>
9354 * select( blocksStore ).getGroupingBlockName(),
9355 * []
9356 * );
9357 *
9358 * return (
9359 * groupingBlockName && (
9360 * <p>
9361 * { sprintf(
9362 * __( 'Default grouping block name: %s' ),
9363 * groupingBlockName
9364 * ) }
9365 * </p>
9366 * )
9367 * );
9368 * };
9369 * ```
9370 *
9371 * @return {string?} Name of the block for handling the grouping of blocks.
9372 */
9373
9374 function selectors_getGroupingBlockName(state) {
9375 return state.groupingBlockName;
9376 }
9377 /**
9378 * Returns an array with the child blocks of a given block.
9379 *
9380 * @param {Object} state Data state.
9381 * @param {string} blockName Block type name.
9382 *
9383 * @example
9384 * ```js
9385 * import { store as blocksStore } from '@wordpress/blocks';
9386 * import { useSelect } from '@wordpress/data';
9387 *
9388 * const ExampleComponent = () => {
9389 * const childBlockNames = useSelect( ( select ) =>
9390 * select( blocksStore ).getChildBlockNames( 'core/navigation' ),
9391 * []
9392 * );
9393 *
9394 * return (
9395 * <ul>
9396 * { childBlockNames &&
9397 * childBlockNames.map( ( child ) => (
9398 * <li key={ child }>{ child }</li>
9399 * ) ) }
9400 * </ul>
9401 * );
9402 * };
9403 * ```
9404 *
9405 * @return {Array} Array of child block names.
9406 */
9407
9408 const selectors_getChildBlockNames = rememo((state, blockName) => {
9409 return selectors_getBlockTypes(state).filter(blockType => {
9410 var _blockType$parent;
9411
9412 return (_blockType$parent = blockType.parent) === null || _blockType$parent === void 0 ? void 0 : _blockType$parent.includes(blockName);
9413 }).map(_ref2 => {
9414 let {
9415 name
9416 } = _ref2;
9417 return name;
9418 });
9419 }, state => [state.blockTypes]);
9420 /**
9421 * Returns the block support value for a feature, if defined.
9422 *
9423 * @param {Object} state Data state.
9424 * @param {(string|Object)} nameOrType Block name or type object
9425 * @param {Array|string} feature Feature to retrieve
9426 * @param {*} defaultSupports Default value to return if not
9427 * explicitly defined
9428 *
9429 * @example
9430 * ```js
9431 * import { __, sprintf } from '@wordpress/i18n';
9432 * import { store as blocksStore } from '@wordpress/blocks';
9433 * import { useSelect } from '@wordpress/data';
9434 *
9435 * const ExampleComponent = () => {
9436 * const paragraphBlockSupportValue = useSelect( ( select ) =>
9437 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ),
9438 * []
9439 * );
9440 *
9441 * return (
9442 * <p>
9443 * { sprintf(
9444 * __( 'core/paragraph supports.anchor value: %s' ),
9445 * paragraphBlockSupportValue
9446 * ) }
9447 * </p>
9448 * );
9449 * };
9450 * ```
9451 *
9452 * @return {?*} Block support value
9453 */
9454
9455 const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => {
9456 const blockType = getNormalizedBlockType(state, nameOrType);
9457
9458 if (!(blockType !== null && blockType !== void 0 && blockType.supports)) {
9459 return defaultSupports;
9460 }
9461
9462 return (0,external_lodash_namespaceObject.get)(blockType.supports, feature, defaultSupports);
9463 };
9464 /**
9465 * Returns true if the block defines support for a feature, or false otherwise.
9466 *
9467 * @param {Object} state Data state.
9468 * @param {(string|Object)} nameOrType Block name or type object.
9469 * @param {string} feature Feature to test.
9470 * @param {boolean} defaultSupports Whether feature is supported by
9471 * default if not explicitly defined.
9472 *
9473 * @example
9474 * ```js
9475 * import { __, sprintf } from '@wordpress/i18n';
9476 * import { store as blocksStore } from '@wordpress/blocks';
9477 * import { useSelect } from '@wordpress/data';
9478 *
9479 * const ExampleComponent = () => {
9480 * const paragraphBlockSupportClassName = useSelect( ( select ) =>
9481 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ),
9482 * []
9483 * );
9484 *
9485 * return (
9486 * <p>
9487 * { sprintf(
9488 * __( 'core/paragraph supports custom class name?: %s' ),
9489 * paragraphBlockSupportClassName
9490 * ) }
9491 * /p>
9492 * );
9493 * };
9494 * ```
9495 *
9496 * @return {boolean} Whether block supports feature.
9497 */
9498
9499 function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupports) {
9500 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports);
9501 }
9502 /**
9503 * Returns true if the block type by the given name or object value matches a
9504 * search term, or false otherwise.
9505 *
9506 * @param {Object} state Blocks state.
9507 * @param {(string|Object)} nameOrType Block name or type object.
9508 * @param {string} searchTerm Search term by which to filter.
9509 *
9510 * @example
9511 * ```js
9512 * import { __, sprintf } from '@wordpress/i18n';
9513 * import { store as blocksStore } from '@wordpress/blocks';
9514 * import { useSelect } from '@wordpress/data';
9515 *
9516 * const ExampleComponent = () => {
9517 * const termFound = useSelect(
9518 * ( select ) =>
9519 * select( blocksStore ).isMatchingSearchTerm(
9520 * 'core/navigation',
9521 * 'theme'
9522 * ),
9523 * []
9524 * );
9525 *
9526 * return (
9527 * <p>
9528 * { sprintf(
9529 * __(
9530 * 'Search term was found in the title, keywords, category or description in block.json: %s'
9531 * ),
9532 * termFound
9533 * ) }
9534 * </p>
9535 * );
9536 * };
9537 * ```
9538 *
9539 * @return {Object[]} Whether block type matches search term.
9540 */
9541
9542 function isMatchingSearchTerm(state, nameOrType, searchTerm) {
9543 var _blockType$keywords;
9544
9545 const blockType = getNormalizedBlockType(state, nameOrType);
9546 const getNormalizedSearchTerm = (0,external_wp_compose_namespaceObject.pipe)([// Disregard diacritics.
9547 // Input: "média"
9548 term => remove_accents_default()(term !== null && term !== void 0 ? term : ''), // Lowercase.
9549 // Input: "MEDIA"
9550 term => term.toLowerCase(), // Strip leading and trailing whitespace.
9551 // Input: " media "
9552 term => term.trim()]);
9553 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm);
9554 const isSearchMatch = (0,external_wp_compose_namespaceObject.pipe)([getNormalizedSearchTerm, normalizedCandidate => normalizedCandidate.includes(normalizedSearchTerm)]);
9555 return isSearchMatch(blockType.title) || ((_blockType$keywords = blockType.keywords) === null || _blockType$keywords === void 0 ? void 0 : _blockType$keywords.some(isSearchMatch)) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description);
9556 }
9557 /**
9558 * Returns a boolean indicating if a block has child blocks or not.
9559 *
9560 * @param {Object} state Data state.
9561 * @param {string} blockName Block type name.
9562 *
9563 * @example
9564 * ```js
9565 * import { __, sprintf } from '@wordpress/i18n';
9566 * import { store as blocksStore } from '@wordpress/blocks';
9567 * import { useSelect } from '@wordpress/data';
9568 *
9569 * const ExampleComponent = () => {
9570 * const navigationBlockHasChildBlocks = useSelect( ( select ) =>
9571 * select( blocksStore ).hasChildBlocks( 'core/navigation' ),
9572 * []
9573 * );
9574 *
9575 * return (
9576 * <p>
9577 * { sprintf(
9578 * __( 'core/navigation has child blocks: %s' ),
9579 * navigationBlockHasChildBlocks
9580 * ) }
9581 * </p>
9582 * );
9583 * };
9584 * ```
9585 *
9586 * @return {boolean} True if a block contains child blocks and false otherwise.
9587 */
9588
9589 const selectors_hasChildBlocks = (state, blockName) => {
9590 return selectors_getChildBlockNames(state, blockName).length > 0;
9591 };
9592 /**
9593 * Returns a boolean indicating if a block has at least one child block with inserter support.
9594 *
9595 * @param {Object} state Data state.
9596 * @param {string} blockName Block type name.
9597 *
9598 * @example
9599 * ```js
9600 * import { __, sprintf } from '@wordpress/i18n';
9601 * import { store as blocksStore } from '@wordpress/blocks';
9602 * import { useSelect } from '@wordpress/data';
9603 *
9604 * const ExampleComponent = () => {
9605 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) =>
9606 * select( blocksStore ).hasChildBlocksWithInserterSupport(
9607 * 'core/navigation'
9608 * ),
9609 * []
9610 * );
9611 *
9612 * return (
9613 * <p>
9614 * { sprintf(
9615 * __( 'core/navigation has child blocks with inserter support: %s' ),
9616 * navigationBlockHasChildBlocksWithInserterSupport
9617 * ) }
9618 * </p>
9619 * );
9620 * };
9621 * ```
9622 *
9623 * @return {boolean} True if a block contains at least one child blocks with inserter support
9624 * and false otherwise.
9625 */
9626
9627 const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => {
9628 return selectors_getChildBlockNames(state, blockName).some(childBlockName => {
9629 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true);
9630 });
9631 };
9632 /**
9633 * DO-NOT-USE in production.
9634 * This selector is created for internal/experimental only usage and may be
9635 * removed anytime without any warning, causing breakage on any plugin or theme invoking it.
9636 */
9637
9638 const __experimentalHasContentRoleAttribute = rememo((state, blockTypeName) => {
9639 const blockType = selectors_getBlockType(state, blockTypeName);
9640
9641 if (!blockType) {
9642 return false;
9643 }
9644
9645 return Object.entries(blockType.attributes).some(_ref3 => {
9646 let [, {
9647 __experimentalRole
9648 }] = _ref3;
9649 return __experimentalRole === 'content';
9650 });
9651 }, (state, blockTypeName) => {
9652 var _state$blockTypes$blo;
9653
9654 return [(_state$blockTypes$blo = state.blockTypes[blockTypeName]) === null || _state$blockTypes$blo === void 0 ? void 0 : _state$blockTypes$blo.attributes];
9655 });
9656
9657 ;// CONCATENATED MODULE: ./node_modules/is-plain-object/dist/is-plain-object.mjs
9658 /*!
9659 * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
9660 *
9661 * Copyright (c) 2014-2017, Jon Schlinkert.
9662 * Released under the MIT License.
9663 */
9664
9665 function is_plain_object_isObject(o) {
9666 return Object.prototype.toString.call(o) === '[object Object]';
9667 }
9668
9669 function isPlainObject(o) {
9670 var ctor,prot;
9671
9672 if (is_plain_object_isObject(o) === false) return false;
9673
9674 // If has modified constructor
9675 ctor = o.constructor;
9676 if (ctor === undefined) return true;
9677
9678 // If has modified prototype
9679 prot = ctor.prototype;
9680 if (is_plain_object_isObject(prot) === false) return false;
9681
9682 // If constructor does not have an Object-specific method
9683 if (prot.hasOwnProperty('isPrototypeOf') === false) {
9684 return false;
9685 }
9686
9687 // Most likely a plain Object
9688 return true;
9689 }
9690
9691
9692
9693 ;// CONCATENATED MODULE: external ["wp","deprecated"]
9694 var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
9695 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
9696 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/actions.js
9697 /**
9698 * External dependencies
9699 */
9700
9701 /**
9702 * WordPress dependencies
9703 */
9704
9705
9706
9707 /**
9708 * Internal dependencies
9709 */
9710
9711
9712
9713 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
9714
9715 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */
9716
9717 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */
9718
9719 const {
9720 error,
9721 warn
9722 } = window.console;
9723 /**
9724 * Mapping of legacy category slugs to their latest normal values, used to
9725 * accommodate updates of the default set of block categories.
9726 *
9727 * @type {Record<string,string>}
9728 */
9729
9730 const LEGACY_CATEGORY_MAPPING = {
9731 common: 'text',
9732 formatting: 'text',
9733 layout: 'design'
9734 };
9735 /**
9736 * Whether the argument is a function.
9737 *
9738 * @param {*} maybeFunc The argument to check.
9739 * @return {boolean} True if the argument is a function, false otherwise.
9740 */
9741
9742 function isFunction(maybeFunc) {
9743 return typeof maybeFunc === 'function';
9744 }
9745 /**
9746 * Takes the unprocessed block type data and applies all the existing filters for the registered block type.
9747 * Next, it validates all the settings and performs additional processing to the block type definition.
9748 *
9749 * @param {WPBlockType} blockType Unprocessed block type settings.
9750 * @param {Object} thunkArgs Argument object for the thunk middleware.
9751 * @param {Function} thunkArgs.select Function to select from the store.
9752 *
9753 * @return {WPBlockType | undefined} The block, if it has been successfully registered; otherwise `undefined`.
9754 */
9755
9756
9757 const processBlockType = (blockType, _ref) => {
9758 let {
9759 select
9760 } = _ref;
9761 const {
9762 name
9763 } = blockType;
9764 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', { ...blockType
9765 }, name, null);
9766
9767 if (settings.description && typeof settings.description !== 'string') {
9768 external_wp_deprecated_default()('Declaring non-string block descriptions', {
9769 since: '6.2'
9770 });
9771 }
9772
9773 if (settings.deprecated) {
9774 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( // Only keep valid deprecation keys.
9775 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', // Merge deprecation keys with pre-filter settings
9776 // so that filters that depend on specific keys being
9777 // present don't fail.
9778 { // Omit deprecation keys here so that deprecations
9779 // can opt out of specific keys like "supports".
9780 ...omit(blockType, DEPRECATED_ENTRY_KEYS),
9781 ...deprecation
9782 }, name, deprecation)).filter(_ref2 => {
9783 let [key] = _ref2;
9784 return DEPRECATED_ENTRY_KEYS.includes(key);
9785 })));
9786 }
9787
9788 if (!isPlainObject(settings)) {
9789 error('Block settings must be a valid object.');
9790 return;
9791 }
9792
9793 if (!isFunction(settings.save)) {
9794 error('The "save" property must be a valid function.');
9795 return;
9796 }
9797
9798 if ('edit' in settings && !isFunction(settings.edit)) {
9799 error('The "edit" property must be a valid function.');
9800 return;
9801 } // Canonicalize legacy categories to equivalent fallback.
9802
9803
9804 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) {
9805 settings.category = LEGACY_CATEGORY_MAPPING[settings.category];
9806 }
9807
9808 if ('category' in settings && !select.getCategories().some(_ref3 => {
9809 let {
9810 slug
9811 } = _ref3;
9812 return slug === settings.category;
9813 })) {
9814 warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".');
9815 delete settings.category;
9816 }
9817
9818 if (!('title' in settings) || settings.title === '') {
9819 error('The block "' + name + '" must have a title.');
9820 return;
9821 }
9822
9823 if (typeof settings.title !== 'string') {
9824 error('Block titles must be strings.');
9825 return;
9826 }
9827
9828 settings.icon = normalizeIconObject(settings.icon);
9829
9830 if (!isValidIcon(settings.icon.src)) {
9831 error('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional');
9832 return;
9833 }
9834
9835 return settings;
9836 };
9837 /**
9838 * Returns an action object used in signalling that block types have been added.
9839 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks.
9840 *
9841 * @ignore
9842 *
9843 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added.
9844 *
9845 *
9846 * @return {Object} Action object.
9847 */
9848
9849
9850 function addBlockTypes(blockTypes) {
9851 return {
9852 type: 'ADD_BLOCK_TYPES',
9853 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes]
9854 };
9855 }
9856 /**
9857 * Signals that the passed block type's settings should be stored in the state.
9858 *
9859 * @param {WPBlockType} blockType Unprocessed block type settings.
9860 */
9861
9862 const __experimentalRegisterBlockType = blockType => _ref4 => {
9863 let {
9864 dispatch,
9865 select
9866 } = _ref4;
9867 dispatch({
9868 type: 'ADD_UNPROCESSED_BLOCK_TYPE',
9869 blockType
9870 });
9871 const processedBlockType = processBlockType(blockType, {
9872 select
9873 });
9874
9875 if (!processedBlockType) {
9876 return;
9877 }
9878
9879 dispatch.addBlockTypes(processedBlockType);
9880 };
9881 /**
9882 * Signals that all block types should be computed again.
9883 * It uses stored unprocessed block types and all the most recent list of registered filters.
9884 *
9885 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence:
9886 * 1. Filter A.
9887 * 2. Block B.
9888 * 3. Block C.
9889 * 4. Filter D.
9890 * 5. Filter E.
9891 * 6. Block F.
9892 * 7. Filter G.
9893 * In this scenario some filters would not get applied for all blocks because they are registered too late.
9894 */
9895
9896 const __experimentalReapplyBlockTypeFilters = () => _ref5 => {
9897 let {
9898 dispatch,
9899 select
9900 } = _ref5;
9901
9902 const unprocessedBlockTypes = select.__experimentalGetUnprocessedBlockTypes();
9903
9904 const processedBlockTypes = Object.keys(unprocessedBlockTypes).reduce((accumulator, blockName) => {
9905 const result = processBlockType(unprocessedBlockTypes[blockName], {
9906 select
9907 });
9908
9909 if (result) {
9910 accumulator.push(result);
9911 }
9912
9913 return accumulator;
9914 }, []);
9915
9916 if (!processedBlockTypes.length) {
9917 return;
9918 }
9919
9920 dispatch.addBlockTypes(processedBlockTypes);
9921 };
9922 /**
9923 * Returns an action object used to remove a registered block type.
9924 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks.
9925 *
9926 * @ignore
9927 *
9928 * @param {string|string[]} names Block name or array of block names to be removed.
9929 *
9930 *
9931 * @return {Object} Action object.
9932 */
9933
9934 function removeBlockTypes(names) {
9935 return {
9936 type: 'REMOVE_BLOCK_TYPES',
9937 names: Array.isArray(names) ? names : [names]
9938 };
9939 }
9940 /**
9941 * Returns an action object used in signalling that new block styles have been added.
9942 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks.
9943 *
9944 * @param {string} blockName Block name.
9945 * @param {Array|Object} styles Block style object or array of block style objects.
9946 *
9947 * @ignore
9948 *
9949 * @return {Object} Action object.
9950 */
9951
9952 function addBlockStyles(blockName, styles) {
9953 return {
9954 type: 'ADD_BLOCK_STYLES',
9955 styles: Array.isArray(styles) ? styles : [styles],
9956 blockName
9957 };
9958 }
9959 /**
9960 * Returns an action object used in signalling that block styles have been removed.
9961 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks.
9962 *
9963 * @ignore
9964 *
9965 * @param {string} blockName Block name.
9966 * @param {Array|string} styleNames Block style names or array of block style names.
9967 *
9968 * @return {Object} Action object.
9969 */
9970
9971 function removeBlockStyles(blockName, styleNames) {
9972 return {
9973 type: 'REMOVE_BLOCK_STYLES',
9974 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames],
9975 blockName
9976 };
9977 }
9978 /**
9979 * Returns an action object used in signalling that new block variations have been added.
9980 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks.
9981 *
9982 * @ignore
9983 *
9984 * @param {string} blockName Block name.
9985 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations.
9986 *
9987 * @return {Object} Action object.
9988 */
9989
9990 function addBlockVariations(blockName, variations) {
9991 return {
9992 type: 'ADD_BLOCK_VARIATIONS',
9993 variations: Array.isArray(variations) ? variations : [variations],
9994 blockName
9995 };
9996 }
9997 /**
9998 * Returns an action object used in signalling that block variations have been removed.
9999 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks.
10000 *
10001 * @ignore
10002 *
10003 * @param {string} blockName Block name.
10004 * @param {string|string[]} variationNames Block variation names.
10005 *
10006 * @return {Object} Action object.
10007 */
10008
10009 function removeBlockVariations(blockName, variationNames) {
10010 return {
10011 type: 'REMOVE_BLOCK_VARIATIONS',
10012 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames],
10013 blockName
10014 };
10015 }
10016 /**
10017 * Returns an action object used to set the default block name.
10018 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks.
10019 *
10020 * @ignore
10021 *
10022 * @param {string} name Block name.
10023 *
10024 * @return {Object} Action object.
10025 */
10026
10027 function actions_setDefaultBlockName(name) {
10028 return {
10029 type: 'SET_DEFAULT_BLOCK_NAME',
10030 name
10031 };
10032 }
10033 /**
10034 * Returns an action object used to set the name of the block used as a fallback
10035 * for non-block content.
10036 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks.
10037 *
10038 * @ignore
10039 *
10040 * @param {string} name Block name.
10041 *
10042 * @return {Object} Action object.
10043 */
10044
10045 function setFreeformFallbackBlockName(name) {
10046 return {
10047 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME',
10048 name
10049 };
10050 }
10051 /**
10052 * Returns an action object used to set the name of the block used as a fallback
10053 * for unregistered blocks.
10054 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks.
10055 *
10056 * @ignore
10057 *
10058 * @param {string} name Block name.
10059 *
10060 * @return {Object} Action object.
10061 */
10062
10063 function setUnregisteredFallbackBlockName(name) {
10064 return {
10065 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME',
10066 name
10067 };
10068 }
10069 /**
10070 * Returns an action object used to set the name of the block used
10071 * when grouping other blocks
10072 * eg: in "Group/Ungroup" interactions
10073 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks.
10074 *
10075 * @ignore
10076 *
10077 * @param {string} name Block name.
10078 *
10079 * @return {Object} Action object.
10080 */
10081
10082 function actions_setGroupingBlockName(name) {
10083 return {
10084 type: 'SET_GROUPING_BLOCK_NAME',
10085 name
10086 };
10087 }
10088 /**
10089 * Returns an action object used to set block categories.
10090 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks.
10091 *
10092 * @ignore
10093 *
10094 * @param {WPBlockCategory[]} categories Block categories.
10095 *
10096 * @return {Object} Action object.
10097 */
10098
10099 function setCategories(categories) {
10100 return {
10101 type: 'SET_CATEGORIES',
10102 categories
10103 };
10104 }
10105 /**
10106 * Returns an action object used to update a category.
10107 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks.
10108 *
10109 * @ignore
10110 *
10111 * @param {string} slug Block category slug.
10112 * @param {Object} category Object containing the category properties that should be updated.
10113 *
10114 * @return {Object} Action object.
10115 */
10116
10117 function updateCategory(slug, category) {
10118 return {
10119 type: 'UPDATE_CATEGORY',
10120 slug,
10121 category
10122 };
10123 }
10124 /**
10125 * Returns an action object used to add block collections
10126 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks.
10127 *
10128 * @ignore
10129 *
10130 * @param {string} namespace The namespace of the blocks to put in the collection
10131 * @param {string} title The title to display in the block inserter
10132 * @param {Object} icon (optional) The icon to display in the block inserter
10133 *
10134 * @return {Object} Action object.
10135 */
10136
10137 function addBlockCollection(namespace, title, icon) {
10138 return {
10139 type: 'ADD_BLOCK_COLLECTION',
10140 namespace,
10141 title,
10142 icon
10143 };
10144 }
10145 /**
10146 * Returns an action object used to remove block collections
10147 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks.
10148 *
10149 * @ignore
10150 *
10151 * @param {string} namespace The namespace of the blocks to put in the collection
10152 *
10153 * @return {Object} Action object.
10154 */
10155
10156 function removeBlockCollection(namespace) {
10157 return {
10158 type: 'REMOVE_BLOCK_COLLECTION',
10159 namespace
10160 };
10161 }
10162
10163 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/constants.js
10164 const STORE_NAME = 'core/blocks';
10165
10166 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/index.js
10167 /**
10168 * WordPress dependencies
10169 */
10170
10171 /**
10172 * Internal dependencies
10173 */
10174
10175
10176
10177
10178
10179 /**
10180 * Store definition for the blocks namespace.
10181 *
10182 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
10183 *
10184 * @type {Object}
10185 */
10186
10187 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
10188 reducer: reducer,
10189 selectors: selectors_namespaceObject,
10190 actions: actions_namespaceObject
10191 });
10192 (0,external_wp_data_namespaceObject.register)(store);
10193
10194 ;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"]
10195 var external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"];
10196 ;// CONCATENATED MODULE: external ["wp","autop"]
10197 var external_wp_autop_namespaceObject = window["wp"]["autop"];
10198 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
10199 var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
10200 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
10201 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/serialize-raw-block.js
10202 /**
10203 * Internal dependencies
10204 */
10205
10206 /**
10207 * @typedef {Object} Options Serialization options.
10208 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks.
10209 */
10210
10211 /** @typedef {import("./").WPRawBlock} WPRawBlock */
10212
10213 /**
10214 * Serializes a block node into the native HTML-comment-powered block format.
10215 * CAVEAT: This function is intended for re-serializing blocks as parsed by
10216 * valid parsers and skips any validation steps. This is NOT a generic
10217 * serialization function for in-memory blocks. For most purposes, see the
10218 * following functions available in the `@wordpress/blocks` package:
10219 *
10220 * @see serializeBlock
10221 * @see serialize
10222 *
10223 * For more on the format of block nodes as returned by valid parsers:
10224 *
10225 * @see `@wordpress/block-serialization-default-parser` package
10226 * @see `@wordpress/block-serialization-spec-parser` package
10227 *
10228 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser.
10229 * @param {Options} [options={}] Serialization options.
10230 *
10231 * @return {string} An HTML string representing a block.
10232 */
10233
10234 function serializeRawBlock(rawBlock) {
10235 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
10236 const {
10237 isCommentDelimited = true
10238 } = options;
10239 const {
10240 blockName,
10241 attrs = {},
10242 innerBlocks = [],
10243 innerContent = []
10244 } = rawBlock;
10245 let childIndex = 0;
10246 const content = innerContent.map(item => // `null` denotes a nested block, otherwise we have an HTML fragment.
10247 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim();
10248 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content;
10249 }
10250
10251 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/serializer.js
10252
10253
10254 /**
10255 * WordPress dependencies
10256 */
10257
10258
10259
10260
10261 /**
10262 * Internal dependencies
10263 */
10264
10265
10266
10267
10268 /** @typedef {import('./parser').WPBlock} WPBlock */
10269
10270 /**
10271 * @typedef {Object} WPBlockSerializationOptions Serialization Options.
10272 *
10273 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks.
10274 */
10275
10276 /**
10277 * Returns the block's default classname from its name.
10278 *
10279 * @param {string} blockName The block name.
10280 *
10281 * @return {string} The block's default class.
10282 */
10283
10284 function getBlockDefaultClassName(blockName) {
10285 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature.
10286 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
10287 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, '');
10288 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName);
10289 }
10290 /**
10291 * Returns the block's default menu item classname from its name.
10292 *
10293 * @param {string} blockName The block name.
10294 *
10295 * @return {string} The block's default menu item class.
10296 */
10297
10298 function getBlockMenuDefaultClassName(blockName) {
10299 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature.
10300 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
10301 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, '');
10302 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName);
10303 }
10304 const blockPropsProvider = {};
10305 const innerBlocksPropsProvider = {};
10306 /**
10307 * Call within a save function to get the props for the block wrapper.
10308 *
10309 * @param {Object} props Optional. Props to pass to the element.
10310 */
10311
10312 function getBlockProps() {
10313 let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10314 const {
10315 blockType,
10316 attributes
10317 } = blockPropsProvider;
10318 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { ...props
10319 }, blockType, attributes);
10320 }
10321 /**
10322 * Call within a save function to get the props for the inner blocks wrapper.
10323 *
10324 * @param {Object} props Optional. Props to pass to the element.
10325 */
10326
10327 function getInnerBlocksProps() {
10328 let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10329 const {
10330 innerBlocks
10331 } = innerBlocksPropsProvider; // Value is an array of blocks, so defer to block serializer.
10332
10333 const html = serialize(innerBlocks, {
10334 isInnerBlocks: true
10335 }); // Use special-cased raw HTML tag to avoid default escaping.
10336
10337 const children = (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, html);
10338 return { ...props,
10339 children
10340 };
10341 }
10342 /**
10343 * Given a block type containing a save render implementation and attributes, returns the
10344 * enhanced element to be saved or string when raw HTML expected.
10345 *
10346 * @param {string|Object} blockTypeOrName Block type or name.
10347 * @param {Object} attributes Block attributes.
10348 * @param {?Array} innerBlocks Nested blocks.
10349 *
10350 * @return {Object|string} Save element or raw HTML string.
10351 */
10352
10353 function getSaveElement(blockTypeOrName, attributes) {
10354 let innerBlocks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
10355 const blockType = normalizeBlockType(blockTypeOrName);
10356 let {
10357 save
10358 } = blockType; // Component classes are unsupported for save since serialization must
10359 // occur synchronously. For improved interoperability with higher-order
10360 // components which often return component class, emulate basic support.
10361
10362 if (save.prototype instanceof external_wp_element_namespaceObject.Component) {
10363 const instance = new save({
10364 attributes
10365 });
10366 save = instance.render.bind(instance);
10367 }
10368
10369 blockPropsProvider.blockType = blockType;
10370 blockPropsProvider.attributes = attributes;
10371 innerBlocksPropsProvider.innerBlocks = innerBlocks;
10372 let element = save({
10373 attributes,
10374 innerBlocks
10375 });
10376
10377 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) {
10378 /**
10379 * Filters the props applied to the block save result element.
10380 *
10381 * @param {Object} props Props applied to save element.
10382 * @param {WPBlock} blockType Block type definition.
10383 * @param {Object} attributes Block attributes.
10384 */
10385 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { ...element.props
10386 }, blockType, attributes);
10387
10388 if (!external_wp_isShallowEqual_default()(props, element.props)) {
10389 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props);
10390 }
10391 }
10392 /**
10393 * Filters the save result of a block during serialization.
10394 *
10395 * @param {WPElement} element Block save result.
10396 * @param {WPBlock} blockType Block type definition.
10397 * @param {Object} attributes Block attributes.
10398 */
10399
10400
10401 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes);
10402 }
10403 /**
10404 * Given a block type containing a save render implementation and attributes, returns the
10405 * static markup to be saved.
10406 *
10407 * @param {string|Object} blockTypeOrName Block type or name.
10408 * @param {Object} attributes Block attributes.
10409 * @param {?Array} innerBlocks Nested blocks.
10410 *
10411 * @return {string} Save content.
10412 */
10413
10414 function getSaveContent(blockTypeOrName, attributes, innerBlocks) {
10415 const blockType = normalizeBlockType(blockTypeOrName);
10416 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks));
10417 }
10418 /**
10419 * Returns attributes which are to be saved and serialized into the block
10420 * comment delimiter.
10421 *
10422 * When a block exists in memory it contains as its attributes both those
10423 * parsed the block comment delimiter _and_ those which matched from the
10424 * contents of the block.
10425 *
10426 * This function returns only those attributes which are needed to persist and
10427 * which cannot be matched from the block content.
10428 *
10429 * @param {Object<string,*>} blockType Block type.
10430 * @param {Object<string,*>} attributes Attributes from in-memory block data.
10431 *
10432 * @return {Object<string,*>} Subset of attributes for comment serialization.
10433 */
10434
10435 function getCommentAttributes(blockType, attributes) {
10436 var _blockType$attributes;
10437
10438 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).reduce((accumulator, _ref) => {
10439 let [key, attributeSchema] = _ref;
10440 const value = attributes[key]; // Ignore undefined values.
10441
10442 if (undefined === value) {
10443 return accumulator;
10444 } // Ignore all attributes but the ones with an "undefined" source
10445 // "undefined" source refers to attributes saved in the block comment.
10446
10447
10448 if (attributeSchema.source !== undefined) {
10449 return accumulator;
10450 } // Ignore default value.
10451
10452
10453 if ('default' in attributeSchema && attributeSchema.default === value) {
10454 return accumulator;
10455 } // Otherwise, include in comment set.
10456
10457
10458 accumulator[key] = value;
10459 return accumulator;
10460 }, {});
10461 }
10462 /**
10463 * Given an attributes object, returns a string in the serialized attributes
10464 * format prepared for post content.
10465 *
10466 * @param {Object} attributes Attributes object.
10467 *
10468 * @return {string} Serialized attributes.
10469 */
10470
10471 function serializeAttributes(attributes) {
10472 return JSON.stringify(attributes) // Don't break HTML comments.
10473 .replace(/--/g, '\\u002d\\u002d') // Don't break non-standard-compliant tools.
10474 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') // Bypass server stripslashes behavior which would unescape stringify's
10475 // escaping of quotation mark.
10476 //
10477 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/
10478 .replace(/\\"/g, '\\u0022');
10479 }
10480 /**
10481 * Given a block object, returns the Block's Inner HTML markup.
10482 *
10483 * @param {Object} block Block instance.
10484 *
10485 * @return {string} HTML.
10486 */
10487
10488 function getBlockInnerHTML(block) {
10489 // If block was parsed as invalid or encounters an error while generating
10490 // save content, use original content instead to avoid content loss. If a
10491 // block contains nested content, exempt it from this condition because we
10492 // otherwise have no access to its original content and content loss would
10493 // still occur.
10494 let saveContent = block.originalContent;
10495
10496 if (block.isValid || block.innerBlocks.length) {
10497 try {
10498 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks);
10499 } catch (error) {}
10500 }
10501
10502 return saveContent;
10503 }
10504 /**
10505 * Returns the content of a block, including comment delimiters.
10506 *
10507 * @param {string} rawBlockName Block name.
10508 * @param {Object} attributes Block attributes.
10509 * @param {string} content Block save content.
10510 *
10511 * @return {string} Comment-delimited block content.
10512 */
10513
10514 function getCommentDelimitedContent(rawBlockName, attributes, content) {
10515 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : ''; // Strip core blocks of their namespace prefix.
10516
10517 const blockName = rawBlockName !== null && rawBlockName !== void 0 && rawBlockName.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName; // @todo make the `wp:` prefix potentially configurable.
10518
10519 if (!content) {
10520 return `<!-- wp:${blockName} ${serializedAttributes}/-->`;
10521 }
10522
10523 return `<!-- wp:${blockName} ${serializedAttributes}-->\n` + content + `\n<!-- /wp:${blockName} -->`;
10524 }
10525 /**
10526 * Returns the content of a block, including comment delimiters, determining
10527 * serialized attributes and content form from the current state of the block.
10528 *
10529 * @param {WPBlock} block Block instance.
10530 * @param {WPBlockSerializationOptions} options Serialization options.
10531 *
10532 * @return {string} Serialized block.
10533 */
10534
10535 function serializeBlock(block) {
10536 let {
10537 isInnerBlocks = false
10538 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
10539
10540 if (!block.isValid && block.__unstableBlockSource) {
10541 return serializeRawBlock(block.__unstableBlockSource);
10542 }
10543
10544 const blockName = block.name;
10545 const saveContent = getBlockInnerHTML(block);
10546
10547 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) {
10548 return saveContent;
10549 }
10550
10551 const blockType = getBlockType(blockName);
10552
10553 if (!blockType) {
10554 return saveContent;
10555 }
10556
10557 const saveAttributes = getCommentAttributes(blockType, block.attributes);
10558 return getCommentDelimitedContent(blockName, saveAttributes, saveContent);
10559 }
10560 function __unstableSerializeAndClean(blocks) {
10561 // A single unmodified default block is assumed to
10562 // be equivalent to an empty post.
10563 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) {
10564 blocks = [];
10565 }
10566
10567 let content = serialize(blocks); // For compatibility, treat a post consisting of a
10568 // single freeform block as legacy content and apply
10569 // pre-block-editor removep'd content formatting.
10570
10571 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName()) {
10572 content = (0,external_wp_autop_namespaceObject.removep)(content);
10573 }
10574
10575 return content;
10576 }
10577 /**
10578 * Takes a block or set of blocks and returns the serialized post content.
10579 *
10580 * @param {Array} blocks Block(s) to serialize.
10581 * @param {WPBlockSerializationOptions} options Serialization options.
10582 *
10583 * @return {string} The post content.
10584 */
10585
10586 function serialize(blocks, options) {
10587 const blocksArray = Array.isArray(blocks) ? blocks : [blocks];
10588 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n');
10589 }
10590
10591 ;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js
10592 /**
10593 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json
10594 * do not edit
10595 */
10596 var namedCharRefs = {
10597 Aacute: "Á", aacute: "á", Abreve: "Ă", abreve: "ă", ac: "∾", acd: "∿", acE: "∾̳", Acirc: "Â", acirc: "â", acute: "´", Acy: "А", acy: "а", AElig: "Æ", aelig: "æ", af: "\u2061", Afr: "𝔄", afr: "𝔞", Agrave: "À", agrave: "à", alefsym: "ℵ", aleph: "ℵ", Alpha: "Α", alpha: "α", Amacr: "Ā", amacr: "ā", amalg: "⨿", amp: "&", AMP: "&", andand: "⩕", And: "⩓", and: "∧", andd: "⩜", andslope: "⩘", andv: "⩚", ang: "∠", ange: "⦤", angle: "∠", angmsdaa: "⦨", angmsdab: "⦩", angmsdac: "⦪", angmsdad: "⦫", angmsdae: "⦬", angmsdaf: "⦭", angmsdag: "⦮", angmsdah: "⦯", angmsd: "∡", angrt: "∟", angrtvb: "⊾", angrtvbd: "⦝", angsph: "∢", angst: "Å", angzarr: "⍼", Aogon: "Ą", aogon: "ą", Aopf: "𝔸", aopf: "𝕒", apacir: "⩯", ap: "≈", apE: "⩰", ape: "≊", apid: "≋", apos: "'", ApplyFunction: "\u2061", approx: "≈", approxeq: "≊", Aring: "Å", aring: "å", Ascr: "𝒜", ascr: "𝒶", Assign: "≔", ast: "*", asymp: "≈", asympeq: "≍", Atilde: "Ã", atilde: "ã", Auml: "Ä", auml: "ä", awconint: "∳", awint: "⨑", backcong: "≌", backepsilon: "϶", backprime: "‵", backsim: "∽", backsimeq: "⋍", Backslash: "∖", Barv: "⫧", barvee: "⊽", barwed: "⌅", Barwed: "⌆", barwedge: "⌅", bbrk: "⎵", bbrktbrk: "⎶", bcong: "≌", Bcy: "Б", bcy: "б", bdquo: "„", becaus: "∵", because: "∵", Because: "∵", bemptyv: "⦰", bepsi: "϶", bernou: "ℬ", Bernoullis: "ℬ", Beta: "Β", beta: "β", beth: "ℶ", between: "≬", Bfr: "𝔅", bfr: "𝔟", bigcap: "⋂", bigcirc: "◯", bigcup: "⋃", bigodot: "⨀", bigoplus: "⨁", bigotimes: "⨂", bigsqcup: "⨆", bigstar: "★", bigtriangledown: "▽", bigtriangleup: "△", biguplus: "⨄", bigvee: "⋁", bigwedge: "⋀", bkarow: "⤍", blacklozenge: "⧫", blacksquare: "▪", blacktriangle: "▴", blacktriangledown: "▾", blacktriangleleft: "◂", blacktriangleright: "▸", blank: "␣", blk12: "▒", blk14: "░", blk34: "▓", block: "█", bne: "=⃥", bnequiv: "≡⃥", bNot: "⫭", bnot: "⌐", Bopf: "𝔹", bopf: "𝕓", bot: "⊥", bottom: "⊥", bowtie: "⋈", boxbox: "⧉", boxdl: "┐", boxdL: "╕", boxDl: "╖", boxDL: "╗", boxdr: "┌", boxdR: "╒", boxDr: "╓", boxDR: "╔", boxh: "─", boxH: "═", boxhd: "┬", boxHd: "╤", boxhD: "╥", boxHD: "╦", boxhu: "┴", boxHu: "╧", boxhU: "╨", boxHU: "╩", boxminus: "⊟", boxplus: "⊞", boxtimes: "⊠", boxul: "┘", boxuL: "╛", boxUl: "╜", boxUL: "╝", boxur: "└", boxuR: "╘", boxUr: "╙", boxUR: "╚", boxv: "│", boxV: "║", boxvh: "┼", boxvH: "╪", boxVh: "╫", boxVH: "╬", boxvl: "┤", boxvL: "╡", boxVl: "╢", boxVL: "╣", boxvr: "├", boxvR: "╞", boxVr: "╟", boxVR: "╠", bprime: "‵", breve: "˘", Breve: "˘", brvbar: "¦", bscr: "𝒷", Bscr: "ℬ", bsemi: "⁏", bsim: "∽", bsime: "⋍", bsolb: "⧅", bsol: "\\", bsolhsub: "⟈", bull: "•", bullet: "•", bump: "≎", bumpE: "⪮", bumpe: "≏", Bumpeq: "≎", bumpeq: "≏", Cacute: "Ć", cacute: "ć", capand: "⩄", capbrcup: "⩉", capcap: "⩋", cap: "∩", Cap: "⋒", capcup: "⩇", capdot: "⩀", CapitalDifferentialD: "ⅅ", caps: "∩︀", caret: "⁁", caron: "ˇ", Cayleys: "ℭ", ccaps: "⩍", Ccaron: "Č", ccaron: "č", Ccedil: "Ç", ccedil: "ç", Ccirc: "Ĉ", ccirc: "ĉ", Cconint: "∰", ccups: "⩌", ccupssm: "⩐", Cdot: "Ċ", cdot: "ċ", cedil: "¸", Cedilla: "¸", cemptyv: "⦲", cent: "¢", centerdot: "·", CenterDot: "·", cfr: "𝔠", Cfr: "ℭ", CHcy: "Ч", chcy: "ч", check: "✓", checkmark: "✓", Chi: "Χ", chi: "χ", circ: "ˆ", circeq: "≗", circlearrowleft: "↺", circlearrowright: "↻", circledast: "⊛", circledcirc: "⊚", circleddash: "⊝", CircleDot: "⊙", circledR: "®", circledS: "Ⓢ", CircleMinus: "⊖", CirclePlus: "⊕", CircleTimes: "⊗", cir: "○", cirE: "⧃", cire: "≗", cirfnint: "⨐", cirmid: "⫯", cirscir: "⧂", ClockwiseContourIntegral: "∲", CloseCurlyDoubleQuote: "”", CloseCurlyQuote: "’", clubs: "♣", clubsuit: "♣", colon: ":", Colon: "∷", Colone: "⩴", colone: "≔", coloneq: "≔", comma: ",", commat: "@", comp: "∁", compfn: "∘", complement: "∁", complexes: "ℂ", cong: "≅", congdot: "⩭", Congruent: "≡", conint: "∮", Conint: "∯", ContourIntegral: "∮", copf: "𝕔", Copf: "ℂ", coprod: "∐", Coproduct: "∐", copy: "©", COPY: "©", copysr: "℗", CounterClockwiseContourIntegral: "∳", crarr: "↵", cross: "✗", Cross: "⨯", Cscr: "𝒞", cscr: "𝒸", csub: "⫏", csube: "⫑", csup: "⫐", csupe: "⫒", ctdot: "⋯", cudarrl: "⤸", cudarrr: "⤵", cuepr: "⋞", cuesc: "⋟", cularr: "↶", cularrp: "⤽", cupbrcap: "⩈", cupcap: "⩆", CupCap: "≍", cup: "∪", Cup: "⋓", cupcup: "⩊", cupdot: "⊍", cupor: "⩅", cups: "∪︀", curarr: "↷", curarrm: "⤼", curlyeqprec: "⋞", curlyeqsucc: "⋟", curlyvee: "⋎", curlywedge: "⋏", curren: "¤", curvearrowleft: "↶", curvearrowright: "↷", cuvee: "⋎", cuwed: "⋏", cwconint: "∲", cwint: "∱", cylcty: "⌭", dagger: "†", Dagger: "‡", daleth: "ℸ", darr: "↓", Darr: "↡", dArr: "⇓", dash: "‐", Dashv: "⫤", dashv: "⊣", dbkarow: "⤏", dblac: "˝", Dcaron: "Ď", dcaron: "ď", Dcy: "Д", dcy: "д", ddagger: "‡", ddarr: "⇊", DD: "ⅅ", dd: "ⅆ", DDotrahd: "⤑", ddotseq: "⩷", deg: "°", Del: "∇", Delta: "Δ", delta: "δ", demptyv: "⦱", dfisht: "⥿", Dfr: "𝔇", dfr: "𝔡", dHar: "⥥", dharl: "⇃", dharr: "⇂", DiacriticalAcute: "´", DiacriticalDot: "˙", DiacriticalDoubleAcute: "˝", DiacriticalGrave: "`", DiacriticalTilde: "˜", diam: "⋄", diamond: "⋄", Diamond: "⋄", diamondsuit: "♦", diams: "♦", die: "¨", DifferentialD: "ⅆ", digamma: "ϝ", disin: "⋲", div: "÷", divide: "÷", divideontimes: "⋇", divonx: "⋇", DJcy: "Ђ", djcy: "ђ", dlcorn: "⌞", dlcrop: "⌍", dollar: "$", Dopf: "𝔻", dopf: "𝕕", Dot: "¨", dot: "˙", DotDot: "⃜", doteq: "≐", doteqdot: "≑", DotEqual: "≐", dotminus: "∸", dotplus: "∔", dotsquare: "⊡", doublebarwedge: "⌆", DoubleContourIntegral: "∯", DoubleDot: "¨", DoubleDownArrow: "⇓", DoubleLeftArrow: "⇐", DoubleLeftRightArrow: "⇔", DoubleLeftTee: "⫤", DoubleLongLeftArrow: "⟸", DoubleLongLeftRightArrow: "⟺", DoubleLongRightArrow: "⟹", DoubleRightArrow: "⇒", DoubleRightTee: "⊨", DoubleUpArrow: "⇑", DoubleUpDownArrow: "⇕", DoubleVerticalBar: "∥", DownArrowBar: "⤓", downarrow: "↓", DownArrow: "↓", Downarrow: "⇓", DownArrowUpArrow: "⇵", DownBreve: "̑", downdownarrows: "⇊", downharpoonleft: "⇃", downharpoonright: "⇂", DownLeftRightVector: "⥐", DownLeftTeeVector: "⥞", DownLeftVectorBar: "⥖", DownLeftVector: "↽", DownRightTeeVector: "⥟", DownRightVectorBar: "⥗", DownRightVector: "⇁", DownTeeArrow: "↧", DownTee: "⊤", drbkarow: "⤐", drcorn: "⌟", drcrop: "⌌", Dscr: "𝒟", dscr: "𝒹", DScy: "Ѕ", dscy: "ѕ", dsol: "⧶", Dstrok: "Đ", dstrok: "đ", dtdot: "⋱", dtri: "▿", dtrif: "▾", duarr: "⇵", duhar: "⥯", dwangle: "⦦", DZcy: "Џ", dzcy: "џ", dzigrarr: "⟿", Eacute: "É", eacute: "é", easter: "⩮", Ecaron: "Ě", ecaron: "ě", Ecirc: "Ê", ecirc: "ê", ecir: "≖", ecolon: "≕", Ecy: "Э", ecy: "э", eDDot: "⩷", Edot: "Ė", edot: "ė", eDot: "≑", ee: "ⅇ", efDot: "≒", Efr: "𝔈", efr: "𝔢", eg: "⪚", Egrave: "È", egrave: "è", egs: "⪖", egsdot: "⪘", el: "⪙", Element: "∈", elinters: "⏧", ell: "ℓ", els: "⪕", elsdot: "⪗", Emacr: "Ē", emacr: "ē", empty: "∅", emptyset: "∅", EmptySmallSquare: "◻", emptyv: "∅", EmptyVerySmallSquare: "▫", emsp13: " ", emsp14: " ", emsp: " ", ENG: "Ŋ", eng: "ŋ", ensp: " ", Eogon: "Ę", eogon: "ę", Eopf: "𝔼", eopf: "𝕖", epar: "⋕", eparsl: "⧣", eplus: "⩱", epsi: "ε", Epsilon: "Ε", epsilon: "ε", epsiv: "ϵ", eqcirc: "≖", eqcolon: "≕", eqsim: "≂", eqslantgtr: "⪖", eqslantless: "⪕", Equal: "⩵", equals: "=", EqualTilde: "≂", equest: "≟", Equilibrium: "⇌", equiv: "≡", equivDD: "⩸", eqvparsl: "⧥", erarr: "⥱", erDot: "≓", escr: "ℯ", Escr: "ℰ", esdot: "≐", Esim: "⩳", esim: "≂", Eta: "Η", eta: "η", ETH: "Ð", eth: "ð", Euml: "Ë", euml: "ë", euro: "€", excl: "!", exist: "∃", Exists: "∃", expectation: "ℰ", exponentiale: "ⅇ", ExponentialE: "ⅇ", fallingdotseq: "≒", Fcy: "Ф", fcy: "ф", female: "♀", ffilig: "ffi", fflig: "ff", ffllig: "ffl", Ffr: "𝔉", ffr: "𝔣", filig: "fi", FilledSmallSquare: "◼", FilledVerySmallSquare: "▪", fjlig: "fj", flat: "♭", fllig: "fl", fltns: "▱", fnof: "ƒ", Fopf: "𝔽", fopf: "𝕗", forall: "∀", ForAll: "∀", fork: "⋔", forkv: "⫙", Fouriertrf: "ℱ", fpartint: "⨍", frac12: "½", frac13: "⅓", frac14: "¼", frac15: "⅕", frac16: "⅙", frac18: "⅛", frac23: "⅔", frac25: "⅖", frac34: "¾", frac35: "⅗", frac38: "⅜", frac45: "⅘", frac56: "⅚", frac58: "⅝", frac78: "⅞", frasl: "⁄", frown: "⌢", fscr: "𝒻", Fscr: "ℱ", gacute: "ǵ", Gamma: "Γ", gamma: "γ", Gammad: "Ϝ", gammad: "ϝ", gap: "⪆", Gbreve: "Ğ", gbreve: "ğ", Gcedil: "Ģ", Gcirc: "Ĝ", gcirc: "ĝ", Gcy: "Г", gcy: "г", Gdot: "Ġ", gdot: "ġ", ge: "≥", gE: "≧", gEl: "⪌", gel: "⋛", geq: "≥", geqq: "≧", geqslant: "⩾", gescc: "⪩", ges: "⩾", gesdot: "⪀", gesdoto: "⪂", gesdotol: "⪄", gesl: "⋛︀", gesles: "⪔", Gfr: "𝔊", gfr: "𝔤", gg: "≫", Gg: "⋙", ggg: "⋙", gimel: "ℷ", GJcy: "Ѓ", gjcy: "ѓ", gla: "⪥", gl: "≷", glE: "⪒", glj: "⪤", gnap: "⪊", gnapprox: "⪊", gne: "⪈", gnE: "≩", gneq: "⪈", gneqq: "≩", gnsim: "⋧", Gopf: "𝔾", gopf: "𝕘", grave: "`", GreaterEqual: "≥", GreaterEqualLess: "⋛", GreaterFullEqual: "≧", GreaterGreater: "⪢", GreaterLess: "≷", GreaterSlantEqual: "⩾", GreaterTilde: "≳", Gscr: "𝒢", gscr: "ℊ", gsim: "≳", gsime: "⪎", gsiml: "⪐", gtcc: "⪧", gtcir: "⩺", gt: ">", GT: ">", Gt: "≫", gtdot: "⋗", gtlPar: "⦕", gtquest: "⩼", gtrapprox: "⪆", gtrarr: "⥸", gtrdot: "⋗", gtreqless: "⋛", gtreqqless: "⪌", gtrless: "≷", gtrsim: "≳", gvertneqq: "≩︀", gvnE: "≩︀", Hacek: "ˇ", hairsp: " ", half: "½", hamilt: "ℋ", HARDcy: "Ъ", hardcy: "ъ", harrcir: "⥈", harr: "↔", hArr: "⇔", harrw: "↭", Hat: "^", hbar: "ℏ", Hcirc: "Ĥ", hcirc: "ĥ", hearts: "♥", heartsuit: "♥", hellip: "…", hercon: "⊹", hfr: "𝔥", Hfr: "ℌ", HilbertSpace: "ℋ", hksearow: "⤥", hkswarow: "⤦", hoarr: "⇿", homtht: "∻", hookleftarrow: "↩", hookrightarrow: "↪", hopf: "𝕙", Hopf: "ℍ", horbar: "―", HorizontalLine: "─", hscr: "𝒽", Hscr: "ℋ", hslash: "ℏ", Hstrok: "Ħ", hstrok: "ħ", HumpDownHump: "≎", HumpEqual: "≏", hybull: "⁃", hyphen: "‐", Iacute: "Í", iacute: "í", ic: "\u2063", Icirc: "Î", icirc: "î", Icy: "И", icy: "и", Idot: "İ", IEcy: "Е", iecy: "е", iexcl: "¡", iff: "⇔", ifr: "𝔦", Ifr: "ℑ", Igrave: "Ì", igrave: "ì", ii: "ⅈ", iiiint: "⨌", iiint: "∭", iinfin: "⧜", iiota: "℩", IJlig: "IJ", ijlig: "ij", Imacr: "Ī", imacr: "ī", image: "ℑ", ImaginaryI: "ⅈ", imagline: "ℐ", imagpart: "ℑ", imath: "ı", Im: "ℑ", imof: "⊷", imped: "Ƶ", Implies: "⇒", incare: "℅", in: "∈", infin: "∞", infintie: "⧝", inodot: "ı", intcal: "⊺", int: "∫", Int: "∬", integers: "ℤ", Integral: "∫", intercal: "⊺", Intersection: "⋂", intlarhk: "⨗", intprod: "⨼", InvisibleComma: "\u2063", InvisibleTimes: "\u2062", IOcy: "Ё", iocy: "ё", Iogon: "Į", iogon: "į", Iopf: "𝕀", iopf: "𝕚", Iota: "Ι", iota: "ι", iprod: "⨼", iquest: "¿", iscr: "𝒾", Iscr: "ℐ", isin: "∈", isindot: "⋵", isinE: "⋹", isins: "⋴", isinsv: "⋳", isinv: "∈", it: "\u2062", Itilde: "Ĩ", itilde: "ĩ", Iukcy: "І", iukcy: "і", Iuml: "Ï", iuml: "ï", Jcirc: "Ĵ", jcirc: "ĵ", Jcy: "Й", jcy: "й", Jfr: "𝔍", jfr: "𝔧", jmath: "ȷ", Jopf: "𝕁", jopf: "𝕛", Jscr: "𝒥", jscr: "𝒿", Jsercy: "Ј", jsercy: "ј", Jukcy: "Є", jukcy: "є", Kappa: "Κ", kappa: "κ", kappav: "ϰ", Kcedil: "Ķ", kcedil: "ķ", Kcy: "К", kcy: "к", Kfr: "𝔎", kfr: "𝔨", kgreen: "ĸ", KHcy: "Х", khcy: "х", KJcy: "Ќ", kjcy: "ќ", Kopf: "𝕂", kopf: "𝕜", Kscr: "𝒦", kscr: "𝓀", lAarr: "⇚", Lacute: "Ĺ", lacute: "ĺ", laemptyv: "⦴", lagran: "ℒ", Lambda: "Λ", lambda: "λ", lang: "⟨", Lang: "⟪", langd: "⦑", langle: "⟨", lap: "⪅", Laplacetrf: "ℒ", laquo: "«", larrb: "⇤", larrbfs: "⤟", larr: "←", Larr: "↞", lArr: "⇐", larrfs: "⤝", larrhk: "↩", larrlp: "↫", larrpl: "⤹", larrsim: "⥳", larrtl: "↢", latail: "⤙", lAtail: "⤛", lat: "⪫", late: "⪭", lates: "⪭︀", lbarr: "⤌", lBarr: "⤎", lbbrk: "❲", lbrace: "{", lbrack: "[", lbrke: "⦋", lbrksld: "⦏", lbrkslu: "⦍", Lcaron: "Ľ", lcaron: "ľ", Lcedil: "Ļ", lcedil: "ļ", lceil: "⌈", lcub: "{", Lcy: "Л", lcy: "л", ldca: "⤶", ldquo: "“", ldquor: "„", ldrdhar: "⥧", ldrushar: "⥋", ldsh: "↲", le: "≤", lE: "≦", LeftAngleBracket: "⟨", LeftArrowBar: "⇤", leftarrow: "←", LeftArrow: "←", Leftarrow: "⇐", LeftArrowRightArrow: "⇆", leftarrowtail: "↢", LeftCeiling: "⌈", LeftDoubleBracket: "⟦", LeftDownTeeVector: "⥡", LeftDownVectorBar: "⥙", LeftDownVector: "⇃", LeftFloor: "⌊", leftharpoondown: "↽", leftharpoonup: "↼", leftleftarrows: "⇇", leftrightarrow: "↔", LeftRightArrow: "↔", Leftrightarrow: "⇔", leftrightarrows: "⇆", leftrightharpoons: "⇋", leftrightsquigarrow: "↭", LeftRightVector: "⥎", LeftTeeArrow: "↤", LeftTee: "⊣", LeftTeeVector: "⥚", leftthreetimes: "⋋", LeftTriangleBar: "⧏", LeftTriangle: "⊲", LeftTriangleEqual: "⊴", LeftUpDownVector: "⥑", LeftUpTeeVector: "⥠", LeftUpVectorBar: "⥘", LeftUpVector: "↿", LeftVectorBar: "⥒", LeftVector: "↼", lEg: "⪋", leg: "⋚", leq: "≤", leqq: "≦", leqslant: "⩽", lescc: "⪨", les: "⩽", lesdot: "⩿", lesdoto: "⪁", lesdotor: "⪃", lesg: "⋚︀", lesges: "⪓", lessapprox: "⪅", lessdot: "⋖", lesseqgtr: "⋚", lesseqqgtr: "⪋", LessEqualGreater: "⋚", LessFullEqual: "≦", LessGreater: "≶", lessgtr: "≶", LessLess: "⪡", lesssim: "≲", LessSlantEqual: "⩽", LessTilde: "≲", lfisht: "⥼", lfloor: "⌊", Lfr: "𝔏", lfr: "𝔩", lg: "≶", lgE: "⪑", lHar: "⥢", lhard: "↽", lharu: "↼", lharul: "⥪", lhblk: "▄", LJcy: "Љ", ljcy: "љ", llarr: "⇇", ll: "≪", Ll: "⋘", llcorner: "⌞", Lleftarrow: "⇚", llhard: "⥫", lltri: "◺", Lmidot: "Ŀ", lmidot: "ŀ", lmoustache: "⎰", lmoust: "⎰", lnap: "⪉", lnapprox: "⪉", lne: "⪇", lnE: "≨", lneq: "⪇", lneqq: "≨", lnsim: "⋦", loang: "⟬", loarr: "⇽", lobrk: "⟦", longleftarrow: "⟵", LongLeftArrow: "⟵", Longleftarrow: "⟸", longleftrightarrow: "⟷", LongLeftRightArrow: "⟷", Longleftrightarrow: "⟺", longmapsto: "⟼", longrightarrow: "⟶", LongRightArrow: "⟶", Longrightarrow: "⟹", looparrowleft: "↫", looparrowright: "↬", lopar: "⦅", Lopf: "𝕃", lopf: "𝕝", loplus: "⨭", lotimes: "⨴", lowast: "∗", lowbar: "_", LowerLeftArrow: "↙", LowerRightArrow: "↘", loz: "◊", lozenge: "◊", lozf: "⧫", lpar: "(", lparlt: "⦓", lrarr: "⇆", lrcorner: "⌟", lrhar: "⇋", lrhard: "⥭", lrm: "\u200e", lrtri: "⊿", lsaquo: "‹", lscr: "𝓁", Lscr: "ℒ", lsh: "↰", Lsh: "↰", lsim: "≲", lsime: "⪍", lsimg: "⪏", lsqb: "[", lsquo: "‘", lsquor: "‚", Lstrok: "Ł", lstrok: "ł", ltcc: "⪦", ltcir: "⩹", lt: "<", LT: "<", Lt: "≪", ltdot: "⋖", lthree: "⋋", ltimes: "⋉", ltlarr: "⥶", ltquest: "⩻", ltri: "◃", ltrie: "⊴", ltrif: "◂", ltrPar: "⦖", lurdshar: "⥊", luruhar: "⥦", lvertneqq: "≨︀", lvnE: "≨︀", macr: "¯", male: "♂", malt: "✠", maltese: "✠", Map: "⤅", map: "↦", mapsto: "↦", mapstodown: "↧", mapstoleft: "↤", mapstoup: "↥", marker: "▮", mcomma: "⨩", Mcy: "М", mcy: "м", mdash: "—", mDDot: "∺", measuredangle: "∡", MediumSpace: " ", Mellintrf: "ℳ", Mfr: "𝔐", mfr: "𝔪", mho: "℧", micro: "µ", midast: "*", midcir: "⫰", mid: "∣", middot: "·", minusb: "⊟", minus: "−", minusd: "∸", minusdu: "⨪", MinusPlus: "∓", mlcp: "⫛", mldr: "…", mnplus: "∓", models: "⊧", Mopf: "𝕄", mopf: "𝕞", mp: "∓", mscr: "𝓂", Mscr: "ℳ", mstpos: "∾", Mu: "Μ", mu: "μ", multimap: "⊸", mumap: "⊸", nabla: "∇", Nacute: "Ń", nacute: "ń", nang: "∠⃒", nap: "≉", napE: "⩰̸", napid: "≋̸", napos: "ʼn", napprox: "≉", natural: "♮", naturals: "ℕ", natur: "♮", nbsp: " ", nbump: "≎̸", nbumpe: "≏̸", ncap: "⩃", Ncaron: "Ň", ncaron: "ň", Ncedil: "Ņ", ncedil: "ņ", ncong: "≇", ncongdot: "⩭̸", ncup: "⩂", Ncy: "Н", ncy: "н", ndash: "–", nearhk: "⤤", nearr: "↗", neArr: "⇗", nearrow: "↗", ne: "≠", nedot: "≐̸", NegativeMediumSpace: "​", NegativeThickSpace: "​", NegativeThinSpace: "​", NegativeVeryThinSpace: "​", nequiv: "≢", nesear: "⤨", nesim: "≂̸", NestedGreaterGreater: "≫", NestedLessLess: "≪", NewLine: "\u000a", nexist: "∄", nexists: "∄", Nfr: "𝔑", nfr: "𝔫", ngE: "≧̸", nge: "≱", ngeq: "≱", ngeqq: "≧̸", ngeqslant: "⩾̸", nges: "⩾̸", nGg: "⋙̸", ngsim: "≵", nGt: "≫⃒", ngt: "≯", ngtr: "≯", nGtv: "≫̸", nharr: "↮", nhArr: "⇎", nhpar: "⫲", ni: "∋", nis: "⋼", nisd: "⋺", niv: "∋", NJcy: "Њ", njcy: "њ", nlarr: "↚", nlArr: "⇍", nldr: "‥", nlE: "≦̸", nle: "≰", nleftarrow: "↚", nLeftarrow: "⇍", nleftrightarrow: "↮", nLeftrightarrow: "⇎", nleq: "≰", nleqq: "≦̸", nleqslant: "⩽̸", nles: "⩽̸", nless: "≮", nLl: "⋘̸", nlsim: "≴", nLt: "≪⃒", nlt: "≮", nltri: "⋪", nltrie: "⋬", nLtv: "≪̸", nmid: "∤", NoBreak: "\u2060", NonBreakingSpace: " ", nopf: "𝕟", Nopf: "ℕ", Not: "⫬", not: "¬", NotCongruent: "≢", NotCupCap: "≭", NotDoubleVerticalBar: "∦", NotElement: "∉", NotEqual: "≠", NotEqualTilde: "≂̸", NotExists: "∄", NotGreater: "≯", NotGreaterEqual: "≱", NotGreaterFullEqual: "≧̸", NotGreaterGreater: "≫̸", NotGreaterLess: "≹", NotGreaterSlantEqual: "⩾̸", NotGreaterTilde: "≵", NotHumpDownHump: "≎̸", NotHumpEqual: "≏̸", notin: "∉", notindot: "⋵̸", notinE: "⋹̸", notinva: "∉", notinvb: "⋷", notinvc: "⋶", NotLeftTriangleBar: "⧏̸", NotLeftTriangle: "⋪", NotLeftTriangleEqual: "⋬", NotLess: "≮", NotLessEqual: "≰", NotLessGreater: "≸", NotLessLess: "≪̸", NotLessSlantEqual: "⩽̸", NotLessTilde: "≴", NotNestedGreaterGreater: "⪢̸", NotNestedLessLess: "⪡̸", notni: "∌", notniva: "∌", notnivb: "⋾", notnivc: "⋽", NotPrecedes: "⊀", NotPrecedesEqual: "⪯̸", NotPrecedesSlantEqual: "⋠", NotReverseElement: "∌", NotRightTriangleBar: "⧐̸", NotRightTriangle: "⋫", NotRightTriangleEqual: "⋭", NotSquareSubset: "⊏̸", NotSquareSubsetEqual: "⋢", NotSquareSuperset: "⊐̸", NotSquareSupersetEqual: "⋣", NotSubset: "⊂⃒", NotSubsetEqual: "⊈", NotSucceeds: "⊁", NotSucceedsEqual: "⪰̸", NotSucceedsSlantEqual: "⋡", NotSucceedsTilde: "≿̸", NotSuperset: "⊃⃒", NotSupersetEqual: "⊉", NotTilde: "≁", NotTildeEqual: "≄", NotTildeFullEqual: "≇", NotTildeTilde: "≉", NotVerticalBar: "∤", nparallel: "∦", npar: "∦", nparsl: "⫽⃥", npart: "∂̸", npolint: "⨔", npr: "⊀", nprcue: "⋠", nprec: "⊀", npreceq: "⪯̸", npre: "⪯̸", nrarrc: "⤳̸", nrarr: "↛", nrArr: "⇏", nrarrw: "↝̸", nrightarrow: "↛", nRightarrow: "⇏", nrtri: "⋫", nrtrie: "⋭", nsc: "⊁", nsccue: "⋡", nsce: "⪰̸", Nscr: "𝒩", nscr: "𝓃", nshortmid: "∤", nshortparallel: "∦", nsim: "≁", nsime: "≄", nsimeq: "≄", nsmid: "∤", nspar: "∦", nsqsube: "⋢", nsqsupe: "⋣", nsub: "⊄", nsubE: "⫅̸", nsube: "⊈", nsubset: "⊂⃒", nsubseteq: "⊈", nsubseteqq: "⫅̸", nsucc: "⊁", nsucceq: "⪰̸", nsup: "⊅", nsupE: "⫆̸", nsupe: "⊉", nsupset: "⊃⃒", nsupseteq: "⊉", nsupseteqq: "⫆̸", ntgl: "≹", Ntilde: "Ñ", ntilde: "ñ", ntlg: "≸", ntriangleleft: "⋪", ntrianglelefteq: "⋬", ntriangleright: "⋫", ntrianglerighteq: "⋭", Nu: "Ν", nu: "ν", num: "#", numero: "№", numsp: " ", nvap: "≍⃒", nvdash: "⊬", nvDash: "⊭", nVdash: "⊮", nVDash: "⊯", nvge: "≥⃒", nvgt: ">⃒", nvHarr: "⤄", nvinfin: "⧞", nvlArr: "⤂", nvle: "≤⃒", nvlt: "<⃒", nvltrie: "⊴⃒", nvrArr: "⤃", nvrtrie: "⊵⃒", nvsim: "∼⃒", nwarhk: "⤣", nwarr: "↖", nwArr: "⇖", nwarrow: "↖", nwnear: "⤧", Oacute: "Ó", oacute: "ó", oast: "⊛", Ocirc: "Ô", ocirc: "ô", ocir: "⊚", Ocy: "О", ocy: "о", odash: "⊝", Odblac: "Ő", odblac: "ő", odiv: "⨸", odot: "⊙", odsold: "⦼", OElig: "Œ", oelig: "œ", ofcir: "⦿", Ofr: "𝔒", ofr: "𝔬", ogon: "˛", Ograve: "Ò", ograve: "ò", ogt: "⧁", ohbar: "⦵", ohm: "Ω", oint: "∮", olarr: "↺", olcir: "⦾", olcross: "⦻", oline: "‾", olt: "⧀", Omacr: "Ō", omacr: "ō", Omega: "Ω", omega: "ω", Omicron: "Ο", omicron: "ο", omid: "⦶", ominus: "⊖", Oopf: "𝕆", oopf: "𝕠", opar: "⦷", OpenCurlyDoubleQuote: "“", OpenCurlyQuote: "‘", operp: "⦹", oplus: "⊕", orarr: "↻", Or: "⩔", or: "∨", ord: "⩝", order: "ℴ", orderof: "ℴ", ordf: "ª", ordm: "º", origof: "⊶", oror: "⩖", orslope: "⩗", orv: "⩛", oS: "Ⓢ", Oscr: "𝒪", oscr: "ℴ", Oslash: "Ø", oslash: "ø", osol: "⊘", Otilde: "Õ", otilde: "õ", otimesas: "⨶", Otimes: "⨷", otimes: "⊗", Ouml: "Ö", ouml: "ö", ovbar: "⌽", OverBar: "‾", OverBrace: "⏞", OverBracket: "⎴", OverParenthesis: "⏜", para: "¶", parallel: "∥", par: "∥", parsim: "⫳", parsl: "⫽", part: "∂", PartialD: "∂", Pcy: "П", pcy: "п", percnt: "%", period: ".", permil: "‰", perp: "⊥", pertenk: "‱", Pfr: "𝔓", pfr: "𝔭", Phi: "Φ", phi: "φ", phiv: "ϕ", phmmat: "ℳ", phone: "☎", Pi: "Π", pi: "π", pitchfork: "⋔", piv: "ϖ", planck: "ℏ", planckh: "ℎ", plankv: "ℏ", plusacir: "⨣", plusb: "⊞", pluscir: "⨢", plus: "+", plusdo: "∔", plusdu: "⨥", pluse: "⩲", PlusMinus: "±", plusmn: "±", plussim: "⨦", plustwo: "⨧", pm: "±", Poincareplane: "ℌ", pointint: "⨕", popf: "𝕡", Popf: "ℙ", pound: "£", prap: "⪷", Pr: "⪻", pr: "≺", prcue: "≼", precapprox: "⪷", prec: "≺", preccurlyeq: "≼", Precedes: "≺", PrecedesEqual: "⪯", PrecedesSlantEqual: "≼", PrecedesTilde: "≾", preceq: "⪯", precnapprox: "⪹", precneqq: "⪵", precnsim: "⋨", pre: "⪯", prE: "⪳", precsim: "≾", prime: "′", Prime: "″", primes: "ℙ", prnap: "⪹", prnE: "⪵", prnsim: "⋨", prod: "∏", Product: "∏", profalar: "⌮", profline: "⌒", profsurf: "⌓", prop: "∝", Proportional: "∝", Proportion: "∷", propto: "∝", prsim: "≾", prurel: "⊰", Pscr: "𝒫", pscr: "𝓅", Psi: "Ψ", psi: "ψ", puncsp: " ", Qfr: "𝔔", qfr: "𝔮", qint: "⨌", qopf: "𝕢", Qopf: "ℚ", qprime: "⁗", Qscr: "𝒬", qscr: "𝓆", quaternions: "ℍ", quatint: "⨖", quest: "?", questeq: "≟", quot: "\"", QUOT: "\"", rAarr: "⇛", race: "∽̱", Racute: "Ŕ", racute: "ŕ", radic: "√", raemptyv: "⦳", rang: "⟩", Rang: "⟫", rangd: "⦒", range: "⦥", rangle: "⟩", raquo: "»", rarrap: "⥵", rarrb: "⇥", rarrbfs: "⤠", rarrc: "⤳", rarr: "→", Rarr: "↠", rArr: "⇒", rarrfs: "⤞", rarrhk: "↪", rarrlp: "↬", rarrpl: "⥅", rarrsim: "⥴", Rarrtl: "⤖", rarrtl: "↣", rarrw: "↝", ratail: "⤚", rAtail: "⤜", ratio: "∶", rationals: "ℚ", rbarr: "⤍", rBarr: "⤏", RBarr: "⤐", rbbrk: "❳", rbrace: "}", rbrack: "]", rbrke: "⦌", rbrksld: "⦎", rbrkslu: "⦐", Rcaron: "Ř", rcaron: "ř", Rcedil: "Ŗ", rcedil: "ŗ", rceil: "⌉", rcub: "}", Rcy: "Р", rcy: "р", rdca: "⤷", rdldhar: "⥩", rdquo: "”", rdquor: "”", rdsh: "↳", real: "ℜ", realine: "ℛ", realpart: "ℜ", reals: "ℝ", Re: "ℜ", rect: "▭", reg: "®", REG: "®", ReverseElement: "∋", ReverseEquilibrium: "⇋", ReverseUpEquilibrium: "⥯", rfisht: "⥽", rfloor: "⌋", rfr: "𝔯", Rfr: "ℜ", rHar: "⥤", rhard: "⇁", rharu: "⇀", rharul: "⥬", Rho: "Ρ", rho: "ρ", rhov: "ϱ", RightAngleBracket: "⟩", RightArrowBar: "⇥", rightarrow: "→", RightArrow: "→", Rightarrow: "⇒", RightArrowLeftArrow: "⇄", rightarrowtail: "↣", RightCeiling: "⌉", RightDoubleBracket: "⟧", RightDownTeeVector: "⥝", RightDownVectorBar: "⥕", RightDownVector: "⇂", RightFloor: "⌋", rightharpoondown: "⇁", rightharpoonup: "⇀", rightleftarrows: "⇄", rightleftharpoons: "⇌", rightrightarrows: "⇉", rightsquigarrow: "↝", RightTeeArrow: "↦", RightTee: "⊢", RightTeeVector: "⥛", rightthreetimes: "⋌", RightTriangleBar: "⧐", RightTriangle: "⊳", RightTriangleEqual: "⊵", RightUpDownVector: "⥏", RightUpTeeVector: "⥜", RightUpVectorBar: "⥔", RightUpVector: "↾", RightVectorBar: "⥓", RightVector: "⇀", ring: "˚", risingdotseq: "≓", rlarr: "⇄", rlhar: "⇌", rlm: "\u200f", rmoustache: "⎱", rmoust: "⎱", rnmid: "⫮", roang: "⟭", roarr: "⇾", robrk: "⟧", ropar: "⦆", ropf: "𝕣", Ropf: "ℝ", roplus: "⨮", rotimes: "⨵", RoundImplies: "⥰", rpar: ")", rpargt: "⦔", rppolint: "⨒", rrarr: "⇉", Rrightarrow: "⇛", rsaquo: "›", rscr: "𝓇", Rscr: "ℛ", rsh: "↱", Rsh: "↱", rsqb: "]", rsquo: "’", rsquor: "’", rthree: "⋌", rtimes: "⋊", rtri: "▹", rtrie: "⊵", rtrif: "▸", rtriltri: "⧎", RuleDelayed: "⧴", ruluhar: "⥨", rx: "℞", Sacute: "Ś", sacute: "ś", sbquo: "‚", scap: "⪸", Scaron: "Š", scaron: "š", Sc: "⪼", sc: "≻", sccue: "≽", sce: "⪰", scE: "⪴", Scedil: "Ş", scedil: "ş", Scirc: "Ŝ", scirc: "ŝ", scnap: "⪺", scnE: "⪶", scnsim: "⋩", scpolint: "⨓", scsim: "≿", Scy: "С", scy: "с", sdotb: "⊡", sdot: "⋅", sdote: "⩦", searhk: "⤥", searr: "↘", seArr: "⇘", searrow: "↘", sect: "§", semi: ";", seswar: "⤩", setminus: "∖", setmn: "∖", sext: "✶", Sfr: "𝔖", sfr: "𝔰", sfrown: "⌢", sharp: "♯", SHCHcy: "Щ", shchcy: "щ", SHcy: "Ш", shcy: "ш", ShortDownArrow: "↓", ShortLeftArrow: "←", shortmid: "∣", shortparallel: "∥", ShortRightArrow: "→", ShortUpArrow: "↑", shy: "\u00ad", Sigma: "Σ", sigma: "σ", sigmaf: "ς", sigmav: "ς", sim: "∼", simdot: "⩪", sime: "≃", simeq: "≃", simg: "⪞", simgE: "⪠", siml: "⪝", simlE: "⪟", simne: "≆", simplus: "⨤", simrarr: "⥲", slarr: "←", SmallCircle: "∘", smallsetminus: "∖", smashp: "⨳", smeparsl: "⧤", smid: "∣", smile: "⌣", smt: "⪪", smte: "⪬", smtes: "⪬︀", SOFTcy: "Ь", softcy: "ь", solbar: "⌿", solb: "⧄", sol: "/", Sopf: "𝕊", sopf: "𝕤", spades: "♠", spadesuit: "♠", spar: "∥", sqcap: "⊓", sqcaps: "⊓︀", sqcup: "⊔", sqcups: "⊔︀", Sqrt: "√", sqsub: "⊏", sqsube: "⊑", sqsubset: "⊏", sqsubseteq: "⊑", sqsup: "⊐", sqsupe: "⊒", sqsupset: "⊐", sqsupseteq: "⊒", square: "□", Square: "□", SquareIntersection: "⊓", SquareSubset: "⊏", SquareSubsetEqual: "⊑", SquareSuperset: "⊐", SquareSupersetEqual: "⊒", SquareUnion: "⊔", squarf: "▪", squ: "□", squf: "▪", srarr: "→", Sscr: "𝒮", sscr: "𝓈", ssetmn: "∖", ssmile: "⌣", sstarf: "⋆", Star: "⋆", star: "☆", starf: "★", straightepsilon: "ϵ", straightphi: "ϕ", strns: "¯", sub: "⊂", Sub: "⋐", subdot: "⪽", subE: "⫅", sube: "⊆", subedot: "⫃", submult: "⫁", subnE: "⫋", subne: "⊊", subplus: "⪿", subrarr: "⥹", subset: "⊂", Subset: "⋐", subseteq: "⊆", subseteqq: "⫅", SubsetEqual: "⊆", subsetneq: "⊊", subsetneqq: "⫋", subsim: "⫇", subsub: "⫕", subsup: "⫓", succapprox: "⪸", succ: "≻", succcurlyeq: "≽", Succeeds: "≻", SucceedsEqual: "⪰", SucceedsSlantEqual: "≽", SucceedsTilde: "≿", succeq: "⪰", succnapprox: "⪺", succneqq: "⪶", succnsim: "⋩", succsim: "≿", SuchThat: "∋", sum: "∑", Sum: "∑", sung: "♪", sup1: "¹", sup2: "²", sup3: "³", sup: "⊃", Sup: "⋑", supdot: "⪾", supdsub: "⫘", supE: "⫆", supe: "⊇", supedot: "⫄", Superset: "⊃", SupersetEqual: "⊇", suphsol: "⟉", suphsub: "⫗", suplarr: "⥻", supmult: "⫂", supnE: "⫌", supne: "⊋", supplus: "⫀", supset: "⊃", Supset: "⋑", supseteq: "⊇", supseteqq: "⫆", supsetneq: "⊋", supsetneqq: "⫌", supsim: "⫈", supsub: "⫔", supsup: "⫖", swarhk: "⤦", swarr: "↙", swArr: "⇙", swarrow: "↙", swnwar: "⤪", szlig: "ß", Tab: "\u0009", target: "⌖", Tau: "Τ", tau: "τ", tbrk: "⎴", Tcaron: "Ť", tcaron: "ť", Tcedil: "Ţ", tcedil: "ţ", Tcy: "Т", tcy: "т", tdot: "⃛", telrec: "⌕", Tfr: "𝔗", tfr: "𝔱", there4: "∴", therefore: "∴", Therefore: "∴", Theta: "Θ", theta: "θ", thetasym: "ϑ", thetav: "ϑ", thickapprox: "≈", thicksim: "∼", ThickSpace: "  ", ThinSpace: " ", thinsp: " ", thkap: "≈", thksim: "∼", THORN: "Þ", thorn: "þ", tilde: "˜", Tilde: "∼", TildeEqual: "≃", TildeFullEqual: "≅", TildeTilde: "≈", timesbar: "⨱", timesb: "⊠", times: "×", timesd: "⨰", tint: "∭", toea: "⤨", topbot: "⌶", topcir: "⫱", top: "⊤", Topf: "𝕋", topf: "𝕥", topfork: "⫚", tosa: "⤩", tprime: "‴", trade: "™", TRADE: "™", triangle: "▵", triangledown: "▿", triangleleft: "◃", trianglelefteq: "⊴", triangleq: "≜", triangleright: "▹", trianglerighteq: "⊵", tridot: "◬", trie: "≜", triminus: "⨺", TripleDot: "⃛", triplus: "⨹", trisb: "⧍", tritime: "⨻", trpezium: "⏢", Tscr: "𝒯", tscr: "𝓉", TScy: "Ц", tscy: "ц", TSHcy: "Ћ", tshcy: "ћ", Tstrok: "Ŧ", tstrok: "ŧ", twixt: "≬", twoheadleftarrow: "↞", twoheadrightarrow: "↠", Uacute: "Ú", uacute: "ú", uarr: "↑", Uarr: "↟", uArr: "⇑", Uarrocir: "⥉", Ubrcy: "Ў", ubrcy: "ў", Ubreve: "Ŭ", ubreve: "ŭ", Ucirc: "Û", ucirc: "û", Ucy: "У", ucy: "у", udarr: "⇅", Udblac: "Ű", udblac: "ű", udhar: "⥮", ufisht: "⥾", Ufr: "𝔘", ufr: "𝔲", Ugrave: "Ù", ugrave: "ù", uHar: "⥣", uharl: "↿", uharr: "↾", uhblk: "▀", ulcorn: "⌜", ulcorner: "⌜", ulcrop: "⌏", ultri: "◸", Umacr: "Ū", umacr: "ū", uml: "¨", UnderBar: "_", UnderBrace: "⏟", UnderBracket: "⎵", UnderParenthesis: "⏝", Union: "⋃", UnionPlus: "⊎", Uogon: "Ų", uogon: "ų", Uopf: "𝕌", uopf: "𝕦", UpArrowBar: "⤒", uparrow: "↑", UpArrow: "↑", Uparrow: "⇑", UpArrowDownArrow: "⇅", updownarrow: "↕", UpDownArrow: "↕", Updownarrow: "⇕", UpEquilibrium: "⥮", upharpoonleft: "↿", upharpoonright: "↾", uplus: "⊎", UpperLeftArrow: "↖", UpperRightArrow: "↗", upsi: "υ", Upsi: "ϒ", upsih: "ϒ", Upsilon: "Υ", upsilon: "υ", UpTeeArrow: "↥", UpTee: "⊥", upuparrows: "⇈", urcorn: "⌝", urcorner: "⌝", urcrop: "⌎", Uring: "Ů", uring: "ů", urtri: "◹", Uscr: "𝒰", uscr: "𝓊", utdot: "⋰", Utilde: "Ũ", utilde: "ũ", utri: "▵", utrif: "▴", uuarr: "⇈", Uuml: "Ü", uuml: "ü", uwangle: "⦧", vangrt: "⦜", varepsilon: "ϵ", varkappa: "ϰ", varnothing: "∅", varphi: "ϕ", varpi: "ϖ", varpropto: "∝", varr: "↕", vArr: "⇕", varrho: "ϱ", varsigma: "ς", varsubsetneq: "⊊︀", varsubsetneqq: "⫋︀", varsupsetneq: "⊋︀", varsupsetneqq: "⫌︀", vartheta: "ϑ", vartriangleleft: "⊲", vartriangleright: "⊳", vBar: "⫨", Vbar: "⫫", vBarv: "⫩", Vcy: "В", vcy: "в", vdash: "⊢", vDash: "⊨", Vdash: "⊩", VDash: "⊫", Vdashl: "⫦", veebar: "⊻", vee: "∨", Vee: "⋁", veeeq: "≚", vellip: "⋮", verbar: "|", Verbar: "‖", vert: "|", Vert: "‖", VerticalBar: "∣", VerticalLine: "|", VerticalSeparator: "❘", VerticalTilde: "≀", VeryThinSpace: " ", Vfr: "𝔙", vfr: "𝔳", vltri: "⊲", vnsub: "⊂⃒", vnsup: "⊃⃒", Vopf: "𝕍", vopf: "𝕧", vprop: "∝", vrtri: "⊳", Vscr: "𝒱", vscr: "𝓋", vsubnE: "⫋︀", vsubne: "⊊︀", vsupnE: "⫌︀", vsupne: "⊋︀", Vvdash: "⊪", vzigzag: "⦚", Wcirc: "Ŵ", wcirc: "ŵ", wedbar: "⩟", wedge: "∧", Wedge: "⋀", wedgeq: "≙", weierp: "℘", Wfr: "𝔚", wfr: "𝔴", Wopf: "𝕎", wopf: "𝕨", wp: "℘", wr: "≀", wreath: "≀", Wscr: "𝒲", wscr: "𝓌", xcap: "⋂", xcirc: "◯", xcup: "⋃", xdtri: "▽", Xfr: "𝔛", xfr: "𝔵", xharr: "⟷", xhArr: "⟺", Xi: "Ξ", xi: "ξ", xlarr: "⟵", xlArr: "⟸", xmap: "⟼", xnis: "⋻", xodot: "⨀", Xopf: "𝕏", xopf: "𝕩", xoplus: "⨁", xotime: "⨂", xrarr: "⟶", xrArr: "⟹", Xscr: "𝒳", xscr: "𝓍", xsqcup: "⨆", xuplus: "⨄", xutri: "△", xvee: "⋁", xwedge: "⋀", Yacute: "Ý", yacute: "ý", YAcy: "Я", yacy: "я", Ycirc: "Ŷ", ycirc: "ŷ", Ycy: "Ы", ycy: "ы", yen: "¥", Yfr: "𝔜", yfr: "𝔶", YIcy: "Ї", yicy: "ї", Yopf: "𝕐", yopf: "𝕪", Yscr: "𝒴", yscr: "𝓎", YUcy: "Ю", yucy: "ю", yuml: "ÿ", Yuml: "Ÿ", Zacute: "Ź", zacute: "ź", Zcaron: "Ž", zcaron: "ž", Zcy: "З", zcy: "з", Zdot: "Ż", zdot: "ż", zeetrf: "ℨ", ZeroWidthSpace: "​", Zeta: "Ζ", zeta: "ζ", zfr: "𝔷", Zfr: "ℨ", ZHcy: "Ж", zhcy: "ж", zigrarr: "⇝", zopf: "𝕫", Zopf: "ℤ", Zscr: "𝒵", zscr: "𝓏", zwj: "\u200d", zwnj: "\u200c"
10598 };
10599
10600 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/;
10601 var CHARCODE = /^#([0-9]+)$/;
10602 var NAMED = /^([A-Za-z0-9]+)$/;
10603 var EntityParser = /** @class */ (function () {
10604 function EntityParser(named) {
10605 this.named = named;
10606 }
10607 EntityParser.prototype.parse = function (entity) {
10608 if (!entity) {
10609 return;
10610 }
10611 var matches = entity.match(HEXCHARCODE);
10612 if (matches) {
10613 return String.fromCharCode(parseInt(matches[1], 16));
10614 }
10615 matches = entity.match(CHARCODE);
10616 if (matches) {
10617 return String.fromCharCode(parseInt(matches[1], 10));
10618 }
10619 matches = entity.match(NAMED);
10620 if (matches) {
10621 return this.named[matches[1]];
10622 }
10623 };
10624 return EntityParser;
10625 }());
10626
10627 var WSP = /[\t\n\f ]/;
10628 var ALPHA = /[A-Za-z]/;
10629 var CRLF = /\r\n?/g;
10630 function isSpace(char) {
10631 return WSP.test(char);
10632 }
10633 function isAlpha(char) {
10634 return ALPHA.test(char);
10635 }
10636 function preprocessInput(input) {
10637 return input.replace(CRLF, '\n');
10638 }
10639
10640 var EventedTokenizer = /** @class */ (function () {
10641 function EventedTokenizer(delegate, entityParser) {
10642 this.delegate = delegate;
10643 this.entityParser = entityParser;
10644 this.state = "beforeData" /* beforeData */;
10645 this.line = -1;
10646 this.column = -1;
10647 this.input = '';
10648 this.index = -1;
10649 this.tagNameBuffer = '';
10650 this.states = {
10651 beforeData: function () {
10652 var char = this.peek();
10653 if (char === '<') {
10654 this.transitionTo("tagOpen" /* tagOpen */);
10655 this.markTagStart();
10656 this.consume();
10657 }
10658 else {
10659 if (char === '\n') {
10660 var tag = this.tagNameBuffer.toLowerCase();
10661 if (tag === 'pre' || tag === 'textarea') {
10662 this.consume();
10663 }
10664 }
10665 this.transitionTo("data" /* data */);
10666 this.delegate.beginData();
10667 }
10668 },
10669 data: function () {
10670 var char = this.peek();
10671 if (char === '<') {
10672 this.delegate.finishData();
10673 this.transitionTo("tagOpen" /* tagOpen */);
10674 this.markTagStart();
10675 this.consume();
10676 }
10677 else if (char === '&') {
10678 this.consume();
10679 this.delegate.appendToData(this.consumeCharRef() || '&');
10680 }
10681 else {
10682 this.consume();
10683 this.delegate.appendToData(char);
10684 }
10685 },
10686 tagOpen: function () {
10687 var char = this.consume();
10688 if (char === '!') {
10689 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */);
10690 }
10691 else if (char === '/') {
10692 this.transitionTo("endTagOpen" /* endTagOpen */);
10693 }
10694 else if (char === '@' || char === ':' || isAlpha(char)) {
10695 this.transitionTo("tagName" /* tagName */);
10696 this.tagNameBuffer = '';
10697 this.delegate.beginStartTag();
10698 this.appendToTagName(char);
10699 }
10700 },
10701 markupDeclarationOpen: function () {
10702 var char = this.consume();
10703 if (char === '-' && this.input.charAt(this.index) === '-') {
10704 this.consume();
10705 this.transitionTo("commentStart" /* commentStart */);
10706 this.delegate.beginComment();
10707 }
10708 },
10709 commentStart: function () {
10710 var char = this.consume();
10711 if (char === '-') {
10712 this.transitionTo("commentStartDash" /* commentStartDash */);
10713 }
10714 else if (char === '>') {
10715 this.delegate.finishComment();
10716 this.transitionTo("beforeData" /* beforeData */);
10717 }
10718 else {
10719 this.delegate.appendToCommentData(char);
10720 this.transitionTo("comment" /* comment */);
10721 }
10722 },
10723 commentStartDash: function () {
10724 var char = this.consume();
10725 if (char === '-') {
10726 this.transitionTo("commentEnd" /* commentEnd */);
10727 }
10728 else if (char === '>') {
10729 this.delegate.finishComment();
10730 this.transitionTo("beforeData" /* beforeData */);
10731 }
10732 else {
10733 this.delegate.appendToCommentData('-');
10734 this.transitionTo("comment" /* comment */);
10735 }
10736 },
10737 comment: function () {
10738 var char = this.consume();
10739 if (char === '-') {
10740 this.transitionTo("commentEndDash" /* commentEndDash */);
10741 }
10742 else {
10743 this.delegate.appendToCommentData(char);
10744 }
10745 },
10746 commentEndDash: function () {
10747 var char = this.consume();
10748 if (char === '-') {
10749 this.transitionTo("commentEnd" /* commentEnd */);
10750 }
10751 else {
10752 this.delegate.appendToCommentData('-' + char);
10753 this.transitionTo("comment" /* comment */);
10754 }
10755 },
10756 commentEnd: function () {
10757 var char = this.consume();
10758 if (char === '>') {
10759 this.delegate.finishComment();
10760 this.transitionTo("beforeData" /* beforeData */);
10761 }
10762 else {
10763 this.delegate.appendToCommentData('--' + char);
10764 this.transitionTo("comment" /* comment */);
10765 }
10766 },
10767 tagName: function () {
10768 var char = this.consume();
10769 if (isSpace(char)) {
10770 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
10771 }
10772 else if (char === '/') {
10773 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10774 }
10775 else if (char === '>') {
10776 this.delegate.finishTag();
10777 this.transitionTo("beforeData" /* beforeData */);
10778 }
10779 else {
10780 this.appendToTagName(char);
10781 }
10782 },
10783 beforeAttributeName: function () {
10784 var char = this.peek();
10785 if (isSpace(char)) {
10786 this.consume();
10787 return;
10788 }
10789 else if (char === '/') {
10790 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10791 this.consume();
10792 }
10793 else if (char === '>') {
10794 this.consume();
10795 this.delegate.finishTag();
10796 this.transitionTo("beforeData" /* beforeData */);
10797 }
10798 else if (char === '=') {
10799 this.delegate.reportSyntaxError('attribute name cannot start with equals sign');
10800 this.transitionTo("attributeName" /* attributeName */);
10801 this.delegate.beginAttribute();
10802 this.consume();
10803 this.delegate.appendToAttributeName(char);
10804 }
10805 else {
10806 this.transitionTo("attributeName" /* attributeName */);
10807 this.delegate.beginAttribute();
10808 }
10809 },
10810 attributeName: function () {
10811 var char = this.peek();
10812 if (isSpace(char)) {
10813 this.transitionTo("afterAttributeName" /* afterAttributeName */);
10814 this.consume();
10815 }
10816 else if (char === '/') {
10817 this.delegate.beginAttributeValue(false);
10818 this.delegate.finishAttributeValue();
10819 this.consume();
10820 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10821 }
10822 else if (char === '=') {
10823 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
10824 this.consume();
10825 }
10826 else if (char === '>') {
10827 this.delegate.beginAttributeValue(false);
10828 this.delegate.finishAttributeValue();
10829 this.consume();
10830 this.delegate.finishTag();
10831 this.transitionTo("beforeData" /* beforeData */);
10832 }
10833 else if (char === '"' || char === "'" || char === '<') {
10834 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names');
10835 this.consume();
10836 this.delegate.appendToAttributeName(char);
10837 }
10838 else {
10839 this.consume();
10840 this.delegate.appendToAttributeName(char);
10841 }
10842 },
10843 afterAttributeName: function () {
10844 var char = this.peek();
10845 if (isSpace(char)) {
10846 this.consume();
10847 return;
10848 }
10849 else if (char === '/') {
10850 this.delegate.beginAttributeValue(false);
10851 this.delegate.finishAttributeValue();
10852 this.consume();
10853 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10854 }
10855 else if (char === '=') {
10856 this.consume();
10857 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
10858 }
10859 else if (char === '>') {
10860 this.delegate.beginAttributeValue(false);
10861 this.delegate.finishAttributeValue();
10862 this.consume();
10863 this.delegate.finishTag();
10864 this.transitionTo("beforeData" /* beforeData */);
10865 }
10866 else {
10867 this.delegate.beginAttributeValue(false);
10868 this.delegate.finishAttributeValue();
10869 this.transitionTo("attributeName" /* attributeName */);
10870 this.delegate.beginAttribute();
10871 this.consume();
10872 this.delegate.appendToAttributeName(char);
10873 }
10874 },
10875 beforeAttributeValue: function () {
10876 var char = this.peek();
10877 if (isSpace(char)) {
10878 this.consume();
10879 }
10880 else if (char === '"') {
10881 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */);
10882 this.delegate.beginAttributeValue(true);
10883 this.consume();
10884 }
10885 else if (char === "'") {
10886 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */);
10887 this.delegate.beginAttributeValue(true);
10888 this.consume();
10889 }
10890 else if (char === '>') {
10891 this.delegate.beginAttributeValue(false);
10892 this.delegate.finishAttributeValue();
10893 this.consume();
10894 this.delegate.finishTag();
10895 this.transitionTo("beforeData" /* beforeData */);
10896 }
10897 else {
10898 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */);
10899 this.delegate.beginAttributeValue(false);
10900 this.consume();
10901 this.delegate.appendToAttributeValue(char);
10902 }
10903 },
10904 attributeValueDoubleQuoted: function () {
10905 var char = this.consume();
10906 if (char === '"') {
10907 this.delegate.finishAttributeValue();
10908 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
10909 }
10910 else if (char === '&') {
10911 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
10912 }
10913 else {
10914 this.delegate.appendToAttributeValue(char);
10915 }
10916 },
10917 attributeValueSingleQuoted: function () {
10918 var char = this.consume();
10919 if (char === "'") {
10920 this.delegate.finishAttributeValue();
10921 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
10922 }
10923 else if (char === '&') {
10924 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
10925 }
10926 else {
10927 this.delegate.appendToAttributeValue(char);
10928 }
10929 },
10930 attributeValueUnquoted: function () {
10931 var char = this.peek();
10932 if (isSpace(char)) {
10933 this.delegate.finishAttributeValue();
10934 this.consume();
10935 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
10936 }
10937 else if (char === '/') {
10938 this.delegate.finishAttributeValue();
10939 this.consume();
10940 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10941 }
10942 else if (char === '&') {
10943 this.consume();
10944 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
10945 }
10946 else if (char === '>') {
10947 this.delegate.finishAttributeValue();
10948 this.consume();
10949 this.delegate.finishTag();
10950 this.transitionTo("beforeData" /* beforeData */);
10951 }
10952 else {
10953 this.consume();
10954 this.delegate.appendToAttributeValue(char);
10955 }
10956 },
10957 afterAttributeValueQuoted: function () {
10958 var char = this.peek();
10959 if (isSpace(char)) {
10960 this.consume();
10961 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
10962 }
10963 else if (char === '/') {
10964 this.consume();
10965 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10966 }
10967 else if (char === '>') {
10968 this.consume();
10969 this.delegate.finishTag();
10970 this.transitionTo("beforeData" /* beforeData */);
10971 }
10972 else {
10973 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
10974 }
10975 },
10976 selfClosingStartTag: function () {
10977 var char = this.peek();
10978 if (char === '>') {
10979 this.consume();
10980 this.delegate.markTagAsSelfClosing();
10981 this.delegate.finishTag();
10982 this.transitionTo("beforeData" /* beforeData */);
10983 }
10984 else {
10985 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
10986 }
10987 },
10988 endTagOpen: function () {
10989 var char = this.consume();
10990 if (char === '@' || char === ':' || isAlpha(char)) {
10991 this.transitionTo("tagName" /* tagName */);
10992 this.tagNameBuffer = '';
10993 this.delegate.beginEndTag();
10994 this.appendToTagName(char);
10995 }
10996 }
10997 };
10998 this.reset();
10999 }
11000 EventedTokenizer.prototype.reset = function () {
11001 this.transitionTo("beforeData" /* beforeData */);
11002 this.input = '';
11003 this.index = 0;
11004 this.line = 1;
11005 this.column = 0;
11006 this.delegate.reset();
11007 };
11008 EventedTokenizer.prototype.transitionTo = function (state) {
11009 this.state = state;
11010 };
11011 EventedTokenizer.prototype.tokenize = function (input) {
11012 this.reset();
11013 this.tokenizePart(input);
11014 this.tokenizeEOF();
11015 };
11016 EventedTokenizer.prototype.tokenizePart = function (input) {
11017 this.input += preprocessInput(input);
11018 while (this.index < this.input.length) {
11019 var handler = this.states[this.state];
11020 if (handler !== undefined) {
11021 handler.call(this);
11022 }
11023 else {
11024 throw new Error("unhandled state " + this.state);
11025 }
11026 }
11027 };
11028 EventedTokenizer.prototype.tokenizeEOF = function () {
11029 this.flushData();
11030 };
11031 EventedTokenizer.prototype.flushData = function () {
11032 if (this.state === 'data') {
11033 this.delegate.finishData();
11034 this.transitionTo("beforeData" /* beforeData */);
11035 }
11036 };
11037 EventedTokenizer.prototype.peek = function () {
11038 return this.input.charAt(this.index);
11039 };
11040 EventedTokenizer.prototype.consume = function () {
11041 var char = this.peek();
11042 this.index++;
11043 if (char === '\n') {
11044 this.line++;
11045 this.column = 0;
11046 }
11047 else {
11048 this.column++;
11049 }
11050 return char;
11051 };
11052 EventedTokenizer.prototype.consumeCharRef = function () {
11053 var endIndex = this.input.indexOf(';', this.index);
11054 if (endIndex === -1) {
11055 return;
11056 }
11057 var entity = this.input.slice(this.index, endIndex);
11058 var chars = this.entityParser.parse(entity);
11059 if (chars) {
11060 var count = entity.length;
11061 // consume the entity chars
11062 while (count) {
11063 this.consume();
11064 count--;
11065 }
11066 // consume the `;`
11067 this.consume();
11068 return chars;
11069 }
11070 };
11071 EventedTokenizer.prototype.markTagStart = function () {
11072 this.delegate.tagOpen();
11073 };
11074 EventedTokenizer.prototype.appendToTagName = function (char) {
11075 this.tagNameBuffer += char;
11076 this.delegate.appendToTagName(char);
11077 };
11078 return EventedTokenizer;
11079 }());
11080
11081 var Tokenizer = /** @class */ (function () {
11082 function Tokenizer(entityParser, options) {
11083 if (options === void 0) { options = {}; }
11084 this.options = options;
11085 this.token = null;
11086 this.startLine = 1;
11087 this.startColumn = 0;
11088 this.tokens = [];
11089 this.tokenizer = new EventedTokenizer(this, entityParser);
11090 this._currentAttribute = undefined;
11091 }
11092 Tokenizer.prototype.tokenize = function (input) {
11093 this.tokens = [];
11094 this.tokenizer.tokenize(input);
11095 return this.tokens;
11096 };
11097 Tokenizer.prototype.tokenizePart = function (input) {
11098 this.tokens = [];
11099 this.tokenizer.tokenizePart(input);
11100 return this.tokens;
11101 };
11102 Tokenizer.prototype.tokenizeEOF = function () {
11103 this.tokens = [];
11104 this.tokenizer.tokenizeEOF();
11105 return this.tokens[0];
11106 };
11107 Tokenizer.prototype.reset = function () {
11108 this.token = null;
11109 this.startLine = 1;
11110 this.startColumn = 0;
11111 };
11112 Tokenizer.prototype.current = function () {
11113 var token = this.token;
11114 if (token === null) {
11115 throw new Error('token was unexpectedly null');
11116 }
11117 if (arguments.length === 0) {
11118 return token;
11119 }
11120 for (var i = 0; i < arguments.length; i++) {
11121 if (token.type === arguments[i]) {
11122 return token;
11123 }
11124 }
11125 throw new Error("token type was unexpectedly " + token.type);
11126 };
11127 Tokenizer.prototype.push = function (token) {
11128 this.token = token;
11129 this.tokens.push(token);
11130 };
11131 Tokenizer.prototype.currentAttribute = function () {
11132 return this._currentAttribute;
11133 };
11134 Tokenizer.prototype.addLocInfo = function () {
11135 if (this.options.loc) {
11136 this.current().loc = {
11137 start: {
11138 line: this.startLine,
11139 column: this.startColumn
11140 },
11141 end: {
11142 line: this.tokenizer.line,
11143 column: this.tokenizer.column
11144 }
11145 };
11146 }
11147 this.startLine = this.tokenizer.line;
11148 this.startColumn = this.tokenizer.column;
11149 };
11150 // Data
11151 Tokenizer.prototype.beginData = function () {
11152 this.push({
11153 type: "Chars" /* Chars */,
11154 chars: ''
11155 });
11156 };
11157 Tokenizer.prototype.appendToData = function (char) {
11158 this.current("Chars" /* Chars */).chars += char;
11159 };
11160 Tokenizer.prototype.finishData = function () {
11161 this.addLocInfo();
11162 };
11163 // Comment
11164 Tokenizer.prototype.beginComment = function () {
11165 this.push({
11166 type: "Comment" /* Comment */,
11167 chars: ''
11168 });
11169 };
11170 Tokenizer.prototype.appendToCommentData = function (char) {
11171 this.current("Comment" /* Comment */).chars += char;
11172 };
11173 Tokenizer.prototype.finishComment = function () {
11174 this.addLocInfo();
11175 };
11176 // Tags - basic
11177 Tokenizer.prototype.tagOpen = function () { };
11178 Tokenizer.prototype.beginStartTag = function () {
11179 this.push({
11180 type: "StartTag" /* StartTag */,
11181 tagName: '',
11182 attributes: [],
11183 selfClosing: false
11184 });
11185 };
11186 Tokenizer.prototype.beginEndTag = function () {
11187 this.push({
11188 type: "EndTag" /* EndTag */,
11189 tagName: ''
11190 });
11191 };
11192 Tokenizer.prototype.finishTag = function () {
11193 this.addLocInfo();
11194 };
11195 Tokenizer.prototype.markTagAsSelfClosing = function () {
11196 this.current("StartTag" /* StartTag */).selfClosing = true;
11197 };
11198 // Tags - name
11199 Tokenizer.prototype.appendToTagName = function (char) {
11200 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char;
11201 };
11202 // Tags - attributes
11203 Tokenizer.prototype.beginAttribute = function () {
11204 this._currentAttribute = ['', '', false];
11205 };
11206 Tokenizer.prototype.appendToAttributeName = function (char) {
11207 this.currentAttribute()[0] += char;
11208 };
11209 Tokenizer.prototype.beginAttributeValue = function (isQuoted) {
11210 this.currentAttribute()[2] = isQuoted;
11211 };
11212 Tokenizer.prototype.appendToAttributeValue = function (char) {
11213 this.currentAttribute()[1] += char;
11214 };
11215 Tokenizer.prototype.finishAttributeValue = function () {
11216 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute);
11217 };
11218 Tokenizer.prototype.reportSyntaxError = function (message) {
11219 this.current().syntaxError = message;
11220 };
11221 return Tokenizer;
11222 }());
11223
11224 function tokenize(input, options) {
11225 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options);
11226 return tokenizer.tokenize(input);
11227 }
11228
11229
11230
11231 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js
11232 var es6 = __webpack_require__(5619);
11233 var es6_default = /*#__PURE__*/__webpack_require__.n(es6);
11234 ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
11235 var external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
11236 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/logger.js
11237 /**
11238 * @typedef LoggerItem
11239 * @property {Function} log Which logger recorded the message
11240 * @property {Array<any>} args White arguments were supplied to the logger
11241 */
11242 function createLogger() {
11243 /**
11244 * Creates a log handler with block validation prefix.
11245 *
11246 * @param {Function} logger Original logger function.
11247 *
11248 * @return {Function} Augmented logger function.
11249 */
11250 function createLogHandler(logger) {
11251 let log = function (message) {
11252 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
11253 args[_key - 1] = arguments[_key];
11254 }
11255
11256 return logger('Block validation: ' + message, ...args);
11257 }; // In test environments, pre-process string substitutions to improve
11258 // readability of error messages. We'd prefer to avoid pulling in this
11259 // dependency in runtime environments, and it can be dropped by a combo
11260 // of Webpack env substitution + UglifyJS dead code elimination.
11261
11262
11263 if (false) {}
11264
11265 return log;
11266 }
11267
11268 return {
11269 // eslint-disable-next-line no-console
11270 error: createLogHandler(console.error),
11271 // eslint-disable-next-line no-console
11272 warning: createLogHandler(console.warn),
11273
11274 getItems() {
11275 return [];
11276 }
11277
11278 };
11279 }
11280 function createQueuedLogger() {
11281 /**
11282 * The list of enqueued log actions to print.
11283 *
11284 * @type {Array<LoggerItem>}
11285 */
11286 const queue = [];
11287 const logger = createLogger();
11288 return {
11289 error() {
11290 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
11291 args[_key2] = arguments[_key2];
11292 }
11293
11294 queue.push({
11295 log: logger.error,
11296 args
11297 });
11298 },
11299
11300 warning() {
11301 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
11302 args[_key3] = arguments[_key3];
11303 }
11304
11305 queue.push({
11306 log: logger.warning,
11307 args
11308 });
11309 },
11310
11311 getItems() {
11312 return queue;
11313 }
11314
11315 };
11316 }
11317
11318 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/index.js
11319 /**
11320 * External dependencies
11321 */
11322
11323
11324 /**
11325 * WordPress dependencies
11326 */
11327
11328
11329
11330 /**
11331 * Internal dependencies
11332 */
11333
11334
11335
11336
11337
11338 /** @typedef {import('../parser').WPBlock} WPBlock */
11339
11340 /** @typedef {import('../registration').WPBlockType} WPBlockType */
11341
11342 /** @typedef {import('./logger').LoggerItem} LoggerItem */
11343
11344 const identity = x => x;
11345 /**
11346 * Globally matches any consecutive whitespace
11347 *
11348 * @type {RegExp}
11349 */
11350
11351
11352 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g;
11353 /**
11354 * Matches a string containing only whitespace
11355 *
11356 * @type {RegExp}
11357 */
11358
11359 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/;
11360 /**
11361 * Matches a CSS URL type value
11362 *
11363 * @type {RegExp}
11364 */
11365
11366 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/;
11367 /**
11368 * Boolean attributes are attributes whose presence as being assigned is
11369 * meaningful, even if only empty.
11370 *
11371 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
11372 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
11373 *
11374 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
11375 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 )
11376 * .reduce( ( result, tr ) => Object.assign( result, {
11377 * [ tr.firstChild.textContent.trim() ]: true
11378 * } ), {} ) ).sort();
11379 *
11380 * @type {Array}
11381 */
11382
11383 const BOOLEAN_ATTRIBUTES = ['allowfullscreen', 'allowpaymentrequest', 'allowusermedia', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'download', 'formnovalidate', 'hidden', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected', 'typemustmatch'];
11384 /**
11385 * Enumerated attributes are attributes which must be of a specific value form.
11386 * Like boolean attributes, these are meaningful if specified, even if not of a
11387 * valid enumerated value.
11388 *
11389 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute
11390 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
11391 *
11392 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
11393 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) )
11394 * .reduce( ( result, tr ) => Object.assign( result, {
11395 * [ tr.firstChild.textContent.trim() ]: true
11396 * } ), {} ) ).sort();
11397 *
11398 * @type {Array}
11399 */
11400
11401 const ENUMERATED_ATTRIBUTES = ['autocapitalize', 'autocomplete', 'charset', 'contenteditable', 'crossorigin', 'decoding', 'dir', 'draggable', 'enctype', 'formenctype', 'formmethod', 'http-equiv', 'inputmode', 'kind', 'method', 'preload', 'scope', 'shape', 'spellcheck', 'translate', 'type', 'wrap'];
11402 /**
11403 * Meaningful attributes are those who cannot be safely ignored when omitted in
11404 * one HTML markup string and not another.
11405 *
11406 * @type {Array}
11407 */
11408
11409 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES];
11410 /**
11411 * Array of functions which receive a text string on which to apply normalizing
11412 * behavior for consideration in text token equivalence, carefully ordered from
11413 * least-to-most expensive operations.
11414 *
11415 * @type {Array}
11416 */
11417
11418 const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace];
11419 /**
11420 * Regular expression matching a named character reference. In lieu of bundling
11421 * a full set of references, the pattern covers the minimal necessary to test
11422 * positively against the full set.
11423 *
11424 * "The ampersand must be followed by one of the names given in the named
11425 * character references section, using the same case."
11426 *
11427 * Tested aginst "12.5 Named character references":
11428 *
11429 * ```
11430 * const references = Array.from( document.querySelectorAll(
11431 * '#named-character-references-table tr[id^=entity-] td:first-child'
11432 * ) ).map( ( code ) => code.textContent )
11433 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) )
11434 * ```
11435 *
11436 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
11437 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
11438 *
11439 * @type {RegExp}
11440 */
11441
11442 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i;
11443 /**
11444 * Regular expression matching a decimal character reference.
11445 *
11446 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#),
11447 * followed by one or more ASCII digits, representing a base-ten integer"
11448 *
11449 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
11450 *
11451 * @type {RegExp}
11452 */
11453
11454 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/;
11455 /**
11456 * Regular expression matching a hexadecimal character reference.
11457 *
11458 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which
11459 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a
11460 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by
11461 * one or more ASCII hex digits, representing a hexadecimal integer"
11462 *
11463 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
11464 *
11465 * @type {RegExp}
11466 */
11467
11468 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i;
11469 /**
11470 * Returns true if the given string is a valid character reference segment, or
11471 * false otherwise. The text should be stripped of `&` and `;` demarcations.
11472 *
11473 * @param {string} text Text to test.
11474 *
11475 * @return {boolean} Whether text is valid character reference.
11476 */
11477
11478 function isValidCharacterReference(text) {
11479 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text);
11480 }
11481 /**
11482 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the
11483 * implementation of `decodeEntities` from `html-entities`, in order to avoid
11484 * bundling a massive named character reference.
11485 *
11486 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts
11487 */
11488
11489 class DecodeEntityParser {
11490 /**
11491 * Returns a substitute string for an entity string sequence between `&`
11492 * and `;`, or undefined if no substitution should occur.
11493 *
11494 * @param {string} entity Entity fragment discovered in HTML.
11495 *
11496 * @return {string | undefined} Entity substitute value.
11497 */
11498 parse(entity) {
11499 if (isValidCharacterReference(entity)) {
11500 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';');
11501 }
11502 }
11503
11504 }
11505 /**
11506 * Given a specified string, returns an array of strings split by consecutive
11507 * whitespace, ignoring leading or trailing whitespace.
11508 *
11509 * @param {string} text Original text.
11510 *
11511 * @return {string[]} Text pieces split on whitespace.
11512 */
11513
11514 function getTextPiecesSplitOnWhitespace(text) {
11515 return text.trim().split(REGEXP_WHITESPACE);
11516 }
11517 /**
11518 * Given a specified string, returns a new trimmed string where all consecutive
11519 * whitespace is collapsed to a single space.
11520 *
11521 * @param {string} text Original text.
11522 *
11523 * @return {string} Trimmed text with consecutive whitespace collapsed.
11524 */
11525
11526 function getTextWithCollapsedWhitespace(text) {
11527 // This is an overly simplified whitespace comparison. The specification is
11528 // more prescriptive of whitespace behavior in inline and block contexts.
11529 //
11530 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33
11531 return getTextPiecesSplitOnWhitespace(text).join(' ');
11532 }
11533 /**
11534 * Returns attribute pairs of the given StartTag token, including only pairs
11535 * where the value is non-empty or the attribute is a boolean attribute, an
11536 * enumerated attribute, or a custom data- attribute.
11537 *
11538 * @see MEANINGFUL_ATTRIBUTES
11539 *
11540 * @param {Object} token StartTag token.
11541 *
11542 * @return {Array[]} Attribute pairs.
11543 */
11544
11545 function getMeaningfulAttributePairs(token) {
11546 return token.attributes.filter(pair => {
11547 const [key, value] = pair;
11548 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key);
11549 });
11550 }
11551 /**
11552 * Returns true if two text tokens (with `chars` property) are equivalent, or
11553 * false otherwise.
11554 *
11555 * @param {Object} actual Actual token.
11556 * @param {Object} expected Expected token.
11557 * @param {Object} logger Validation logger object.
11558 *
11559 * @return {boolean} Whether two text tokens are equivalent.
11560 */
11561
11562 function isEquivalentTextTokens(actual, expected) {
11563 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger();
11564 // This function is intentionally written as syntactically "ugly" as a hot
11565 // path optimization. Text is progressively normalized in order from least-
11566 // to-most operationally expensive, until the earliest point at which text
11567 // can be confidently inferred as being equal.
11568 let actualChars = actual.chars;
11569 let expectedChars = expected.chars;
11570
11571 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) {
11572 const normalize = TEXT_NORMALIZATIONS[i];
11573 actualChars = normalize(actualChars);
11574 expectedChars = normalize(expectedChars);
11575
11576 if (actualChars === expectedChars) {
11577 return true;
11578 }
11579 }
11580
11581 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars);
11582 return false;
11583 }
11584 /**
11585 * Given a CSS length value, returns a normalized CSS length value for strict equality
11586 * comparison.
11587 *
11588 * @param {string} value CSS length value.
11589 *
11590 * @return {string} Normalized CSS length value.
11591 */
11592
11593 function getNormalizedLength(value) {
11594 if (0 === parseFloat(value)) {
11595 return '0';
11596 } // Normalize strings with floats to always include a leading zero.
11597
11598
11599 if (value.indexOf('.') === 0) {
11600 return '0' + value;
11601 }
11602
11603 return value;
11604 }
11605 /**
11606 * Given a style value, returns a normalized style value for strict equality
11607 * comparison.
11608 *
11609 * @param {string} value Style value.
11610 *
11611 * @return {string} Normalized style value.
11612 */
11613
11614 function getNormalizedStyleValue(value) {
11615 const textPieces = getTextPiecesSplitOnWhitespace(value);
11616 const normalizedPieces = textPieces.map(getNormalizedLength);
11617 const result = normalizedPieces.join(' ');
11618 return result // Normalize URL type to omit whitespace or quotes.
11619 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)');
11620 }
11621 /**
11622 * Given a style attribute string, returns an object of style properties.
11623 *
11624 * @param {string} text Style attribute.
11625 *
11626 * @return {Object} Style properties.
11627 */
11628
11629 function getStyleProperties(text) {
11630 const pairs = text // Trim ending semicolon (avoid including in split)
11631 .replace(/;?\s*$/, '') // Split on property assignment.
11632 .split(';') // For each property assignment...
11633 .map(style => {
11634 // ...split further into key-value pairs.
11635 const [key, ...valueParts] = style.split(':');
11636 const value = valueParts.join(':');
11637 return [key.trim(), getNormalizedStyleValue(value.trim())];
11638 });
11639 return Object.fromEntries(pairs);
11640 }
11641 /**
11642 * Attribute-specific equality handlers
11643 *
11644 * @type {Object}
11645 */
11646
11647 const isEqualAttributesOfName = {
11648 class: (actual, expected) => {
11649 // Class matches if members are the same, even if out of order or
11650 // superfluous whitespace between.
11651 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace);
11652 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c));
11653 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c));
11654 return actualDiff.length === 0 && expectedDiff.length === 0;
11655 },
11656 style: (actual, expected) => {
11657 return es6_default()(...[actual, expected].map(getStyleProperties));
11658 },
11659 // For each boolean attribute, mere presence of attribute in both is enough
11660 // to assume equivalence.
11661 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true]))
11662 };
11663 /**
11664 * Given two sets of attribute tuples, returns true if the attribute sets are
11665 * equivalent.
11666 *
11667 * @param {Array[]} actual Actual attributes tuples.
11668 * @param {Array[]} expected Expected attributes tuples.
11669 * @param {Object} logger Validation logger object.
11670 *
11671 * @return {boolean} Whether attributes are equivalent.
11672 */
11673
11674 function isEqualTagAttributePairs(actual, expected) {
11675 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger();
11676
11677 // Attributes is tokenized as tuples. Their lengths should match. This also
11678 // avoids us needing to check both attributes sets, since if A has any keys
11679 // which do not exist in B, we know the sets to be different.
11680 if (actual.length !== expected.length) {
11681 logger.warning('Expected attributes %o, instead saw %o.', expected, actual);
11682 return false;
11683 } // Attributes are not guaranteed to occur in the same order. For validating
11684 // actual attributes, first convert the set of expected attribute values to
11685 // an object, for lookup by key.
11686
11687
11688 const expectedAttributes = {};
11689
11690 for (let i = 0; i < expected.length; i++) {
11691 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1];
11692 }
11693
11694 for (let i = 0; i < actual.length; i++) {
11695 const [name, actualValue] = actual[i];
11696 const nameLower = name.toLowerCase(); // As noted above, if missing member in B, assume different.
11697
11698 if (!expectedAttributes.hasOwnProperty(nameLower)) {
11699 logger.warning('Encountered unexpected attribute `%s`.', name);
11700 return false;
11701 }
11702
11703 const expectedValue = expectedAttributes[nameLower];
11704 const isEqualAttributes = isEqualAttributesOfName[nameLower];
11705
11706 if (isEqualAttributes) {
11707 // Defer custom attribute equality handling.
11708 if (!isEqualAttributes(actualValue, expectedValue)) {
11709 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue);
11710 return false;
11711 }
11712 } else if (actualValue !== expectedValue) {
11713 // Otherwise strict inequality should bail.
11714 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue);
11715 return false;
11716 }
11717 }
11718
11719 return true;
11720 }
11721 /**
11722 * Token-type-specific equality handlers
11723 *
11724 * @type {Object}
11725 */
11726
11727 const isEqualTokensOfType = {
11728 StartTag: function (actual, expected) {
11729 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger();
11730
11731 if (actual.tagName !== expected.tagName && // Optimization: Use short-circuit evaluation to defer case-
11732 // insensitive check on the assumption that the majority case will
11733 // have exactly equal tag names.
11734 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) {
11735 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName);
11736 return false;
11737 }
11738
11739 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger);
11740 },
11741 Chars: isEquivalentTextTokens,
11742 Comment: isEquivalentTextTokens
11743 };
11744 /**
11745 * Given an array of tokens, returns the first token which is not purely
11746 * whitespace.
11747 *
11748 * Mutates the tokens array.
11749 *
11750 * @param {Object[]} tokens Set of tokens to search.
11751 *
11752 * @return {Object | undefined} Next non-whitespace token.
11753 */
11754
11755 function getNextNonWhitespaceToken(tokens) {
11756 let token;
11757
11758 while (token = tokens.shift()) {
11759 if (token.type !== 'Chars') {
11760 return token;
11761 }
11762
11763 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) {
11764 return token;
11765 }
11766 }
11767 }
11768 /**
11769 * Tokenize an HTML string, gracefully handling any errors thrown during
11770 * underlying tokenization.
11771 *
11772 * @param {string} html HTML string to tokenize.
11773 * @param {Object} logger Validation logger object.
11774 *
11775 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error
11776 */
11777
11778 function getHTMLTokens(html) {
11779 let logger = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createLogger();
11780
11781 try {
11782 return new Tokenizer(new DecodeEntityParser()).tokenize(html);
11783 } catch (e) {
11784 logger.warning('Malformed HTML detected: %s', html);
11785 }
11786
11787 return null;
11788 }
11789 /**
11790 * Returns true if the next HTML token closes the current token.
11791 *
11792 * @param {Object} currentToken Current token to compare with.
11793 * @param {Object|undefined} nextToken Next token to compare against.
11794 *
11795 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise
11796 */
11797
11798
11799 function isClosedByToken(currentToken, nextToken) {
11800 // Ensure this is a self closed token.
11801 if (!currentToken.selfClosing) {
11802 return false;
11803 } // Check token names and determine if nextToken is the closing tag for currentToken.
11804
11805
11806 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') {
11807 return true;
11808 }
11809
11810 return false;
11811 }
11812 /**
11813 * Returns true if the given HTML strings are effectively equivalent, or
11814 * false otherwise. Invalid HTML is not considered equivalent, even if the
11815 * strings directly match.
11816 *
11817 * @param {string} actual Actual HTML string.
11818 * @param {string} expected Expected HTML string.
11819 * @param {Object} logger Validation logger object.
11820 *
11821 * @return {boolean} Whether HTML strings are equivalent.
11822 */
11823
11824 function isEquivalentHTML(actual, expected) {
11825 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger();
11826
11827 // Short-circuit if markup is identical.
11828 if (actual === expected) {
11829 return true;
11830 } // Tokenize input content and reserialized save content.
11831
11832
11833 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); // If either is malformed then stop comparing - the strings are not equivalent.
11834
11835 if (!actualTokens || !expectedTokens) {
11836 return false;
11837 }
11838
11839 let actualToken, expectedToken;
11840
11841 while (actualToken = getNextNonWhitespaceToken(actualTokens)) {
11842 expectedToken = getNextNonWhitespaceToken(expectedTokens); // Inequal if exhausted all expected tokens.
11843
11844 if (!expectedToken) {
11845 logger.warning('Expected end of content, instead saw %o.', actualToken);
11846 return false;
11847 } // Inequal if next non-whitespace token of each set are not same type.
11848
11849
11850 if (actualToken.type !== expectedToken.type) {
11851 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken);
11852 return false;
11853 } // Defer custom token type equality handling, otherwise continue and
11854 // assume as equal.
11855
11856
11857 const isEqualTokens = isEqualTokensOfType[actualToken.type];
11858
11859 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) {
11860 return false;
11861 } // Peek at the next tokens (actual and expected) to see if they close
11862 // a self-closing tag.
11863
11864
11865 if (isClosedByToken(actualToken, expectedTokens[0])) {
11866 // Consume the next expected token that closes the current actual
11867 // self-closing token.
11868 getNextNonWhitespaceToken(expectedTokens);
11869 } else if (isClosedByToken(expectedToken, actualTokens[0])) {
11870 // Consume the next actual token that closes the current expected
11871 // self-closing token.
11872 getNextNonWhitespaceToken(actualTokens);
11873 }
11874 }
11875
11876 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) {
11877 // If any non-whitespace tokens remain in expected token set, this
11878 // indicates inequality.
11879 logger.warning('Expected %o, instead saw end of content.', expectedToken);
11880 return false;
11881 }
11882
11883 return true;
11884 }
11885 /**
11886 * Returns an object with `isValid` property set to `true` if the parsed block
11887 * is valid given the input content. A block is considered valid if, when serialized
11888 * with assumed attributes, the content matches the original value. If block is
11889 * invalid, this function returns all validations issues as well.
11890 *
11891 * @param {string|Object} blockTypeOrName Block type.
11892 * @param {Object} attributes Parsed block attributes.
11893 * @param {string} originalBlockContent Original block content.
11894 * @param {Object} logger Validation logger object.
11895 *
11896 * @return {Object} Whether block is valid and contains validation messages.
11897 */
11898
11899 /**
11900 * Returns an object with `isValid` property set to `true` if the parsed block
11901 * is valid given the input content. A block is considered valid if, when serialized
11902 * with assumed attributes, the content matches the original value. If block is
11903 * invalid, this function returns all validations issues as well.
11904 *
11905 * @param {WPBlock} block block object.
11906 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given.
11907 *
11908 * @return {[boolean,Array<LoggerItem>]} validation results.
11909 */
11910
11911 function validateBlock(block) {
11912 let blockTypeOrName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : block.name;
11913 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); // Shortcut to avoid costly validation.
11914
11915 if (isFallbackBlock) {
11916 return [true, []];
11917 }
11918
11919 const logger = createQueuedLogger();
11920 const blockType = normalizeBlockType(blockTypeOrName);
11921 let generatedBlockContent;
11922
11923 try {
11924 generatedBlockContent = getSaveContent(blockType, block.attributes);
11925 } catch (error) {
11926 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString());
11927 return [false, logger.getItems()];
11928 }
11929
11930 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger);
11931
11932 if (!isValid) {
11933 logger.error('Block validation failed for `%s` (%o).\n\nContent generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', blockType.name, blockType, generatedBlockContent, block.originalContent);
11934 }
11935
11936 return [isValid, logger.getItems()];
11937 }
11938 /**
11939 * Returns true if the parsed block is valid given the input content. A block
11940 * is considered valid if, when serialized with assumed attributes, the content
11941 * matches the original value.
11942 *
11943 * Logs to console in development environments when invalid.
11944 *
11945 * @deprecated Use validateBlock instead to avoid data loss.
11946 *
11947 * @param {string|Object} blockTypeOrName Block type.
11948 * @param {Object} attributes Parsed block attributes.
11949 * @param {string} originalBlockContent Original block content.
11950 *
11951 * @return {boolean} Whether block is valid.
11952 */
11953
11954 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) {
11955 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', {
11956 since: '12.6',
11957 plugin: 'Gutenberg',
11958 alternative: 'validateBlock'
11959 });
11960 const blockType = normalizeBlockType(blockTypeOrName);
11961 const block = {
11962 name: blockType.name,
11963 attributes,
11964 innerBlocks: [],
11965 originalContent: originalBlockContent
11966 };
11967 const [isValid] = validateBlock(block, blockType);
11968 return isValid;
11969 }
11970
11971 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/convert-legacy-block.js
11972 /**
11973 * Convert legacy blocks to their canonical form. This function is used
11974 * both in the parser level for previous content and to convert such blocks
11975 * used in Custom Post Types templates.
11976 *
11977 * @param {string} name The block's name
11978 * @param {Object} attributes The block's attributes
11979 *
11980 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found
11981 */
11982 function convertLegacyBlockNameAndAttributes(name, attributes) {
11983 const newAttributes = { ...attributes
11984 }; // Convert 'core/cover-image' block in existing content to 'core/cover'.
11985
11986 if ('core/cover-image' === name) {
11987 name = 'core/cover';
11988 } // Convert 'core/text' blocks in existing content to 'core/paragraph'.
11989
11990
11991 if ('core/text' === name || 'core/cover-text' === name) {
11992 name = 'core/paragraph';
11993 } // Convert derivative blocks such as 'core/social-link-wordpress' to the
11994 // canonical form 'core/social-link'.
11995
11996
11997 if (name && name.indexOf('core/social-link-') === 0) {
11998 // Capture `social-link-wordpress` into `{"service":"wordpress"}`
11999 newAttributes.service = name.substring(17);
12000 name = 'core/social-link';
12001 } // Convert derivative blocks such as 'core-embed/instagram' to the
12002 // canonical form 'core/embed'.
12003
12004
12005 if (name && name.indexOf('core-embed/') === 0) {
12006 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}`
12007 const providerSlug = name.substring(11);
12008 const deprecated = {
12009 speaker: 'speaker-deck',
12010 polldaddy: 'crowdsignal'
12011 };
12012 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; // This is needed as the `responsive` attribute was passed
12013 // in a different way before the refactoring to block variations.
12014
12015 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) {
12016 newAttributes.responsive = true;
12017 }
12018
12019 name = 'core/embed';
12020 } // Convert Post Comment blocks in existing content to Comment blocks.
12021 // TODO: Remove these checks when WordPress 6.0 is released.
12022
12023
12024 if (name === 'core/post-comment-author') {
12025 name = 'core/comment-author-name';
12026 }
12027
12028 if (name === 'core/post-comment-content') {
12029 name = 'core/comment-content';
12030 }
12031
12032 if (name === 'core/post-comment-date') {
12033 name = 'core/comment-date';
12034 }
12035
12036 if (name === 'core/comments-query-loop') {
12037 name = 'core/comments';
12038 const {
12039 className = ''
12040 } = newAttributes;
12041
12042 if (!className.includes('wp-block-comments-query-loop')) {
12043 newAttributes.className = ['wp-block-comments-query-loop', className].join(' ');
12044 } // Note that we also had to add a deprecation to the block in order
12045 // for the ID change to work.
12046
12047 }
12048
12049 if (name === 'core/post-comments') {
12050 name = 'core/comments';
12051 newAttributes.legacy = true;
12052 }
12053
12054 return [name, newAttributes];
12055 }
12056
12057 ;// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js
12058 /**
12059 * Given object and string of dot-delimited path segments, returns value at
12060 * path or undefined if path cannot be resolved.
12061 *
12062 * @param {Object} object Lookup object
12063 * @param {string} path Path to resolve
12064 * @return {?*} Resolved value
12065 */
12066 function getPath(object, path) {
12067 var segments = path.split('.');
12068 var segment;
12069
12070 while (segment = segments.shift()) {
12071 if (!(segment in object)) {
12072 return;
12073 }
12074
12075 object = object[segment];
12076 }
12077
12078 return object;
12079 }
12080 ;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js
12081 /**
12082 * Internal dependencies
12083 */
12084
12085 /**
12086 * Function returning a DOM document created by `createHTMLDocument`. The same
12087 * document is returned between invocations.
12088 *
12089 * @return {Document} DOM document.
12090 */
12091
12092 var getDocument = function () {
12093 var doc;
12094 return function () {
12095 if (!doc) {
12096 doc = document.implementation.createHTMLDocument('');
12097 }
12098
12099 return doc;
12100 };
12101 }();
12102 /**
12103 * Given a markup string or DOM element, creates an object aligning with the
12104 * shape of the matchers object, or the value returned by the matcher.
12105 *
12106 * @param {(string|Element)} source Source content
12107 * @param {(Object|Function)} matchers Matcher function or object of matchers
12108 * @return {(Object|*)} Matched value(s), shaped by object
12109 */
12110
12111
12112 function parse(source, matchers) {
12113 if (!matchers) {
12114 return;
12115 } // Coerce to element
12116
12117
12118 if ('string' === typeof source) {
12119 var doc = getDocument();
12120 doc.body.innerHTML = source;
12121 source = doc.body;
12122 } // Return singular value
12123
12124
12125 if ('function' === typeof matchers) {
12126 return matchers(source);
12127 } // Bail if we can't handle matchers
12128
12129
12130 if (Object !== matchers.constructor) {
12131 return;
12132 } // Shape result by matcher object
12133
12134
12135 return Object.keys(matchers).reduce(function (memo, key) {
12136 memo[key] = parse(source, matchers[key]);
12137 return memo;
12138 }, {});
12139 }
12140 /**
12141 * Generates a function which matches node of type selector, returning an
12142 * attribute by property if the attribute exists. If no selector is passed,
12143 * returns property of the query element.
12144 *
12145 * @param {?string} selector Optional selector
12146 * @param {string} name Property name
12147 * @return {*} Property value
12148 */
12149
12150 function prop(selector, name) {
12151 if (1 === arguments.length) {
12152 name = selector;
12153 selector = undefined;
12154 }
12155
12156 return function (node) {
12157 var match = node;
12158
12159 if (selector) {
12160 match = node.querySelector(selector);
12161 }
12162
12163 if (match) {
12164 return getPath(match, name);
12165 }
12166 };
12167 }
12168 /**
12169 * Generates a function which matches node of type selector, returning an
12170 * attribute by name if the attribute exists. If no selector is passed,
12171 * returns attribute of the query element.
12172 *
12173 * @param {?string} selector Optional selector
12174 * @param {string} name Attribute name
12175 * @return {?string} Attribute value
12176 */
12177
12178 function attr(selector, name) {
12179 if (1 === arguments.length) {
12180 name = selector;
12181 selector = undefined;
12182 }
12183
12184 return function (node) {
12185 var attributes = prop(selector, 'attributes')(node);
12186
12187 if (attributes && attributes.hasOwnProperty(name)) {
12188 return attributes[name].value;
12189 }
12190 };
12191 }
12192 /**
12193 * Convenience for `prop( selector, 'innerHTML' )`.
12194 *
12195 * @see prop()
12196 *
12197 * @param {?string} selector Optional selector
12198 * @return {string} Inner HTML
12199 */
12200
12201 function html(selector) {
12202 return prop(selector, 'innerHTML');
12203 }
12204 /**
12205 * Convenience for `prop( selector, 'textContent' )`.
12206 *
12207 * @see prop()
12208 *
12209 * @param {?string} selector Optional selector
12210 * @return {string} Text content
12211 */
12212
12213 function es_text(selector) {
12214 return prop(selector, 'textContent');
12215 }
12216 /**
12217 * Creates a new matching context by first finding elements matching selector
12218 * using querySelectorAll before then running another `parse` on `matchers`
12219 * scoped to the matched elements.
12220 *
12221 * @see parse()
12222 *
12223 * @param {string} selector Selector to match
12224 * @param {(Object|Function)} matchers Matcher function or object of matchers
12225 * @return {Array.<*,Object>} Array of matched value(s)
12226 */
12227
12228 function query(selector, matchers) {
12229 return function (node) {
12230 var matches = node.querySelectorAll(selector);
12231 return [].map.call(matches, function (match) {
12232 return parse(match, matchers);
12233 });
12234 };
12235 }
12236 // EXTERNAL MODULE: ./node_modules/memize/index.js
12237 var memize = __webpack_require__(9756);
12238 var memize_default = /*#__PURE__*/__webpack_require__.n(memize);
12239 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/matchers.js
12240 /**
12241 * External dependencies
12242 */
12243
12244 /**
12245 * Internal dependencies
12246 */
12247
12248
12249
12250 function matchers_html(selector, multilineTag) {
12251 return domNode => {
12252 let match = domNode;
12253
12254 if (selector) {
12255 match = domNode.querySelector(selector);
12256 }
12257
12258 if (!match) {
12259 return '';
12260 }
12261
12262 if (multilineTag) {
12263 let value = '';
12264 const length = match.children.length;
12265
12266 for (let index = 0; index < length; index++) {
12267 const child = match.children[index];
12268
12269 if (child.nodeName.toLowerCase() !== multilineTag) {
12270 continue;
12271 }
12272
12273 value += child.outerHTML;
12274 }
12275
12276 return value;
12277 }
12278
12279 return match.innerHTML;
12280 };
12281 }
12282
12283 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/node.js
12284 /**
12285 * WordPress dependencies
12286 */
12287
12288 /**
12289 * Internal dependencies
12290 */
12291
12292
12293 /**
12294 * A representation of a single node within a block's rich text value. If
12295 * representing a text node, the value is simply a string of the node value.
12296 * As representing an element node, it is an object of:
12297 *
12298 * 1. `type` (string): Tag name.
12299 * 2. `props` (object): Attributes and children array of WPBlockNode.
12300 *
12301 * @typedef {string|Object} WPBlockNode
12302 */
12303
12304 /**
12305 * Given a single node and a node type (e.g. `'br'`), returns true if the node
12306 * corresponds to that type, false otherwise.
12307 *
12308 * @param {WPBlockNode} node Block node to test
12309 * @param {string} type Node to type to test against.
12310 *
12311 * @return {boolean} Whether node is of intended type.
12312 */
12313
12314 function isNodeOfType(node, type) {
12315 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', {
12316 since: '6.1',
12317 version: '6.3',
12318 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12319 });
12320 return node && node.type === type;
12321 }
12322 /**
12323 * Given an object implementing the NamedNodeMap interface, returns a plain
12324 * object equivalent value of name, value key-value pairs.
12325 *
12326 * @see https://dom.spec.whatwg.org/#interface-namednodemap
12327 *
12328 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object.
12329 *
12330 * @return {Object} Object equivalent value of NamedNodeMap.
12331 */
12332
12333
12334 function getNamedNodeMapAsObject(nodeMap) {
12335 const result = {};
12336
12337 for (let i = 0; i < nodeMap.length; i++) {
12338 const {
12339 name,
12340 value
12341 } = nodeMap[i];
12342 result[name] = value;
12343 }
12344
12345 return result;
12346 }
12347 /**
12348 * Given a DOM Element or Text node, returns an equivalent block node. Throws
12349 * if passed any node type other than element or text.
12350 *
12351 * @throws {TypeError} If non-element/text node is passed.
12352 *
12353 * @param {Node} domNode DOM node to convert.
12354 *
12355 * @return {WPBlockNode} Block node equivalent to DOM node.
12356 */
12357
12358 function fromDOM(domNode) {
12359 external_wp_deprecated_default()('wp.blocks.node.fromDOM', {
12360 since: '6.1',
12361 version: '6.3',
12362 alternative: 'wp.richText.create',
12363 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12364 });
12365
12366 if (domNode.nodeType === domNode.TEXT_NODE) {
12367 return domNode.nodeValue;
12368 }
12369
12370 if (domNode.nodeType !== domNode.ELEMENT_NODE) {
12371 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.');
12372 }
12373
12374 return {
12375 type: domNode.nodeName.toLowerCase(),
12376 props: { ...getNamedNodeMapAsObject(domNode.attributes),
12377 children: children_fromDOM(domNode.childNodes)
12378 }
12379 };
12380 }
12381 /**
12382 * Given a block node, returns its HTML string representation.
12383 *
12384 * @param {WPBlockNode} node Block node to convert to string.
12385 *
12386 * @return {string} String HTML representation of block node.
12387 */
12388
12389 function toHTML(node) {
12390 external_wp_deprecated_default()('wp.blocks.node.toHTML', {
12391 since: '6.1',
12392 version: '6.3',
12393 alternative: 'wp.richText.toHTMLString',
12394 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12395 });
12396 return children_toHTML([node]);
12397 }
12398 /**
12399 * Given a selector, returns an hpq matcher generating a WPBlockNode value
12400 * matching the selector result.
12401 *
12402 * @param {string} selector DOM selector.
12403 *
12404 * @return {Function} hpq matcher.
12405 */
12406
12407 function node_matcher(selector) {
12408 external_wp_deprecated_default()('wp.blocks.node.matcher', {
12409 since: '6.1',
12410 version: '6.3',
12411 alternative: 'html source',
12412 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12413 });
12414 return domNode => {
12415 let match = domNode;
12416
12417 if (selector) {
12418 match = domNode.querySelector(selector);
12419 }
12420
12421 try {
12422 return fromDOM(match);
12423 } catch (error) {
12424 return null;
12425 }
12426 };
12427 }
12428 /**
12429 * Object of utility functions used in managing block attribute values of
12430 * source `node`.
12431 *
12432 * @see https://github.com/WordPress/gutenberg/pull/10439
12433 *
12434 * @deprecated since 4.0. The `node` source should not be used, and can be
12435 * replaced by the `html` source.
12436 *
12437 * @private
12438 */
12439
12440 /* harmony default export */ var node = ({
12441 isNodeOfType,
12442 fromDOM,
12443 toHTML,
12444 matcher: node_matcher
12445 });
12446
12447 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/children.js
12448 /**
12449 * WordPress dependencies
12450 */
12451
12452
12453 /**
12454 * Internal dependencies
12455 */
12456
12457
12458 /**
12459 * A representation of a block's rich text value.
12460 *
12461 * @typedef {WPBlockNode[]} WPBlockChildren
12462 */
12463
12464 /**
12465 * Given block children, returns a serialize-capable WordPress element.
12466 *
12467 * @param {WPBlockChildren} children Block children object to convert.
12468 *
12469 * @return {WPElement} A serialize-capable element.
12470 */
12471
12472 function getSerializeCapableElement(children) {
12473 // The fact that block children are compatible with the element serializer is
12474 // merely an implementation detail that currently serves to be true, but
12475 // should not be mistaken as being a guarantee on the external API. The
12476 // public API only offers guarantees to work with strings (toHTML) and DOM
12477 // elements (fromDOM), and should provide utilities to manipulate the value
12478 // rather than expect consumers to inspect or construct its shape (concat).
12479 return children;
12480 }
12481 /**
12482 * Given block children, returns an array of block nodes.
12483 *
12484 * @param {WPBlockChildren} children Block children object to convert.
12485 *
12486 * @return {Array<WPBlockNode>} An array of individual block nodes.
12487 */
12488
12489 function getChildrenArray(children) {
12490 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', {
12491 since: '6.1',
12492 version: '6.3',
12493 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12494 }); // The fact that block children are compatible with the element serializer
12495 // is merely an implementation detail that currently serves to be true, but
12496 // should not be mistaken as being a guarantee on the external API.
12497
12498 return children;
12499 }
12500 /**
12501 * Given two or more block nodes, returns a new block node representing a
12502 * concatenation of its values.
12503 *
12504 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate.
12505 *
12506 * @return {WPBlockChildren} Concatenated block node.
12507 */
12508
12509
12510 function concat() {
12511 external_wp_deprecated_default()('wp.blocks.children.concat', {
12512 since: '6.1',
12513 version: '6.3',
12514 alternative: 'wp.richText.concat',
12515 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12516 });
12517 const result = [];
12518
12519 for (var _len = arguments.length, blockNodes = new Array(_len), _key = 0; _key < _len; _key++) {
12520 blockNodes[_key] = arguments[_key];
12521 }
12522
12523 for (let i = 0; i < blockNodes.length; i++) {
12524 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]];
12525
12526 for (let j = 0; j < blockNode.length; j++) {
12527 const child = blockNode[j];
12528 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string';
12529
12530 if (canConcatToPreviousString) {
12531 result[result.length - 1] += child;
12532 } else {
12533 result.push(child);
12534 }
12535 }
12536 }
12537
12538 return result;
12539 }
12540 /**
12541 * Given an iterable set of DOM nodes, returns equivalent block children.
12542 * Ignores any non-element/text nodes included in set.
12543 *
12544 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert.
12545 *
12546 * @return {WPBlockChildren} Block children equivalent to DOM nodes.
12547 */
12548
12549 function children_fromDOM(domNodes) {
12550 external_wp_deprecated_default()('wp.blocks.children.fromDOM', {
12551 since: '6.1',
12552 version: '6.3',
12553 alternative: 'wp.richText.create',
12554 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12555 });
12556 const result = [];
12557
12558 for (let i = 0; i < domNodes.length; i++) {
12559 try {
12560 result.push(fromDOM(domNodes[i]));
12561 } catch (error) {// Simply ignore if DOM node could not be converted.
12562 }
12563 }
12564
12565 return result;
12566 }
12567 /**
12568 * Given a block node, returns its HTML string representation.
12569 *
12570 * @param {WPBlockChildren} children Block node(s) to convert to string.
12571 *
12572 * @return {string} String HTML representation of block node.
12573 */
12574
12575 function children_toHTML(children) {
12576 external_wp_deprecated_default()('wp.blocks.children.toHTML', {
12577 since: '6.1',
12578 version: '6.3',
12579 alternative: 'wp.richText.toHTMLString',
12580 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12581 });
12582 const element = getSerializeCapableElement(children);
12583 return (0,external_wp_element_namespaceObject.renderToString)(element);
12584 }
12585 /**
12586 * Given a selector, returns an hpq matcher generating a WPBlockChildren value
12587 * matching the selector result.
12588 *
12589 * @param {string} selector DOM selector.
12590 *
12591 * @return {Function} hpq matcher.
12592 */
12593
12594 function children_matcher(selector) {
12595 external_wp_deprecated_default()('wp.blocks.children.matcher', {
12596 since: '6.1',
12597 version: '6.3',
12598 alternative: 'html source',
12599 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12600 });
12601 return domNode => {
12602 let match = domNode;
12603
12604 if (selector) {
12605 match = domNode.querySelector(selector);
12606 }
12607
12608 if (match) {
12609 return children_fromDOM(match.childNodes);
12610 }
12611
12612 return [];
12613 };
12614 }
12615 /**
12616 * Object of utility functions used in managing block attribute values of
12617 * source `children`.
12618 *
12619 * @see https://github.com/WordPress/gutenberg/pull/10439
12620 *
12621 * @deprecated since 4.0. The `children` source should not be used, and can be
12622 * replaced by the `html` source.
12623 *
12624 * @private
12625 */
12626
12627 /* harmony default export */ var children = ({
12628 concat,
12629 getChildrenArray,
12630 fromDOM: children_fromDOM,
12631 toHTML: children_toHTML,
12632 matcher: children_matcher
12633 });
12634
12635 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/get-block-attributes.js
12636 /**
12637 * External dependencies
12638 */
12639
12640
12641
12642 /**
12643 * WordPress dependencies
12644 */
12645
12646
12647
12648 /**
12649 * Internal dependencies
12650 */
12651
12652
12653
12654 /**
12655 * Higher-order hpq matcher which enhances an attribute matcher to return true
12656 * or false depending on whether the original matcher returns undefined. This
12657 * is useful for boolean attributes (e.g. disabled) whose attribute values may
12658 * be technically falsey (empty string), though their mere presence should be
12659 * enough to infer as true.
12660 *
12661 * @param {Function} matcher Original hpq matcher.
12662 *
12663 * @return {Function} Enhanced hpq matcher.
12664 */
12665
12666 const toBooleanAttributeMatcher = matcher => (0,external_wp_compose_namespaceObject.pipe)([matcher, // Expected values from `attr( 'disabled' )`:
12667 //
12668 // <input>
12669 // - Value: `undefined`
12670 // - Transformed: `false`
12671 //
12672 // <input disabled>
12673 // - Value: `''`
12674 // - Transformed: `true`
12675 //
12676 // <input disabled="disabled">
12677 // - Value: `'disabled'`
12678 // - Transformed: `true`
12679 value => value !== undefined]);
12680 /**
12681 * Returns true if value is of the given JSON schema type, or false otherwise.
12682 *
12683 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25
12684 *
12685 * @param {*} value Value to test.
12686 * @param {string} type Type to test.
12687 *
12688 * @return {boolean} Whether value is of type.
12689 */
12690
12691 function isOfType(value, type) {
12692 switch (type) {
12693 case 'string':
12694 return typeof value === 'string';
12695
12696 case 'boolean':
12697 return typeof value === 'boolean';
12698
12699 case 'object':
12700 return !!value && value.constructor === Object;
12701
12702 case 'null':
12703 return value === null;
12704
12705 case 'array':
12706 return Array.isArray(value);
12707
12708 case 'integer':
12709 case 'number':
12710 return typeof value === 'number';
12711 }
12712
12713 return true;
12714 }
12715 /**
12716 * Returns true if value is of an array of given JSON schema types, or false
12717 * otherwise.
12718 *
12719 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25
12720 *
12721 * @param {*} value Value to test.
12722 * @param {string[]} types Types to test.
12723 *
12724 * @return {boolean} Whether value is of types.
12725 */
12726
12727 function isOfTypes(value, types) {
12728 return types.some(type => isOfType(value, type));
12729 }
12730 /**
12731 * Given an attribute key, an attribute's schema, a block's raw content and the
12732 * commentAttributes returns the attribute value depending on its source
12733 * definition of the given attribute key.
12734 *
12735 * @param {string} attributeKey Attribute key.
12736 * @param {Object} attributeSchema Attribute's schema.
12737 * @param {Node} innerDOM Parsed DOM of block's inner HTML.
12738 * @param {Object} commentAttributes Block's comment attributes.
12739 * @param {string} innerHTML Raw HTML from block node's innerHTML property.
12740 *
12741 * @return {*} Attribute value.
12742 */
12743
12744 function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) {
12745 let value;
12746
12747 switch (attributeSchema.source) {
12748 // An undefined source means that it's an attribute serialized to the
12749 // block's "comment".
12750 case undefined:
12751 value = commentAttributes ? commentAttributes[attributeKey] : undefined;
12752 break;
12753 // raw source means that it's the original raw block content.
12754
12755 case 'raw':
12756 value = innerHTML;
12757 break;
12758
12759 case 'attribute':
12760 case 'property':
12761 case 'html':
12762 case 'text':
12763 case 'children':
12764 case 'node':
12765 case 'query':
12766 case 'tag':
12767 value = parseWithAttributeSchema(innerDOM, attributeSchema);
12768 break;
12769 }
12770
12771 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) {
12772 // Reject the value if it is not valid. Reverting to the undefined
12773 // value ensures the default is respected, if applicable.
12774 value = undefined;
12775 }
12776
12777 if (value === undefined) {
12778 value = attributeSchema.default;
12779 }
12780
12781 return value;
12782 }
12783 /**
12784 * Returns true if value is valid per the given block attribute schema type
12785 * definition, or false otherwise.
12786 *
12787 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1
12788 *
12789 * @param {*} value Value to test.
12790 * @param {?(Array<string>|string)} type Block attribute schema type.
12791 *
12792 * @return {boolean} Whether value is valid.
12793 */
12794
12795 function isValidByType(value, type) {
12796 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]);
12797 }
12798 /**
12799 * Returns true if value is valid per the given block attribute schema enum
12800 * definition, or false otherwise.
12801 *
12802 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2
12803 *
12804 * @param {*} value Value to test.
12805 * @param {?Array} enumSet Block attribute schema enum.
12806 *
12807 * @return {boolean} Whether value is valid.
12808 */
12809
12810 function isValidByEnum(value, enumSet) {
12811 return !Array.isArray(enumSet) || enumSet.includes(value);
12812 }
12813 /**
12814 * Returns an hpq matcher given a source object.
12815 *
12816 * @param {Object} sourceConfig Attribute Source object.
12817 *
12818 * @return {Function} A hpq Matcher.
12819 */
12820
12821 const matcherFromSource = memize_default()(sourceConfig => {
12822 switch (sourceConfig.source) {
12823 case 'attribute':
12824 let matcher = attr(sourceConfig.selector, sourceConfig.attribute);
12825
12826 if (sourceConfig.type === 'boolean') {
12827 matcher = toBooleanAttributeMatcher(matcher);
12828 }
12829
12830 return matcher;
12831
12832 case 'html':
12833 return matchers_html(sourceConfig.selector, sourceConfig.multiline);
12834
12835 case 'text':
12836 return es_text(sourceConfig.selector);
12837
12838 case 'children':
12839 return children_matcher(sourceConfig.selector);
12840
12841 case 'node':
12842 return node_matcher(sourceConfig.selector);
12843
12844 case 'query':
12845 const subMatchers = (0,external_lodash_namespaceObject.mapValues)(sourceConfig.query, matcherFromSource);
12846 return query(sourceConfig.selector, subMatchers);
12847
12848 case 'tag':
12849 return (0,external_wp_compose_namespaceObject.pipe)([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]);
12850
12851 default:
12852 // eslint-disable-next-line no-console
12853 console.error(`Unknown source type "${sourceConfig.source}"`);
12854 }
12855 });
12856 /**
12857 * Parse a HTML string into DOM tree.
12858 *
12859 * @param {string|Node} innerHTML HTML string or already parsed DOM node.
12860 *
12861 * @return {Node} Parsed DOM node.
12862 */
12863
12864 function parseHtml(innerHTML) {
12865 return parse(innerHTML, h => h);
12866 }
12867 /**
12868 * Given a block's raw content and an attribute's schema returns the attribute's
12869 * value depending on its source.
12870 *
12871 * @param {string|Node} innerHTML Block's raw content.
12872 * @param {Object} attributeSchema Attribute's schema.
12873 *
12874 * @return {*} Attribute value.
12875 */
12876
12877
12878 function parseWithAttributeSchema(innerHTML, attributeSchema) {
12879 return matcherFromSource(attributeSchema)(parseHtml(innerHTML));
12880 }
12881 /**
12882 * Returns the block attributes of a registered block node given its type.
12883 *
12884 * @param {string|Object} blockTypeOrName Block type or name.
12885 * @param {string|Node} innerHTML Raw block content.
12886 * @param {?Object} attributes Known block attributes (from delimiters).
12887 *
12888 * @return {Object} All block attributes.
12889 */
12890
12891 function getBlockAttributes(blockTypeOrName, innerHTML) {
12892 let attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
12893 const doc = parseHtml(innerHTML);
12894 const blockType = normalizeBlockType(blockTypeOrName);
12895 const blockAttributes = (0,external_lodash_namespaceObject.mapValues)(blockType.attributes, (schema, key) => getBlockAttribute(key, schema, doc, attributes, innerHTML));
12896 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes);
12897 }
12898
12899 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/fix-custom-classname.js
12900 /**
12901 * Internal dependencies
12902 */
12903
12904
12905
12906 const CLASS_ATTR_SCHEMA = {
12907 type: 'string',
12908 source: 'attribute',
12909 selector: '[data-custom-class-name] > *',
12910 attribute: 'class'
12911 };
12912 /**
12913 * Given an HTML string, returns an array of class names assigned to the root
12914 * element in the markup.
12915 *
12916 * @param {string} innerHTML Markup string from which to extract classes.
12917 *
12918 * @return {string[]} Array of class names assigned to the root element.
12919 */
12920
12921 function getHTMLRootElementClasses(innerHTML) {
12922 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>${innerHTML}</div>`, CLASS_ATTR_SCHEMA);
12923 return parsed ? parsed.trim().split(/\s+/) : [];
12924 }
12925 /**
12926 * Given a parsed set of block attributes, if the block supports custom class
12927 * names and an unknown class (per the block's serialization behavior) is
12928 * found, the unknown classes are treated as custom classes. This prevents the
12929 * block from being considered as invalid.
12930 *
12931 * @param {Object} blockAttributes Original block attributes.
12932 * @param {Object} blockType Block type settings.
12933 * @param {string} innerHTML Original block markup.
12934 *
12935 * @return {Object} Filtered block attributes.
12936 */
12937
12938 function fixCustomClassname(blockAttributes, blockType, innerHTML) {
12939 if (hasBlockSupport(blockType, 'customClassName', true)) {
12940 // To determine difference, serialize block given the known set of
12941 // attributes, with the exception of `className`. This will determine
12942 // the default set of classes. From there, any difference in innerHTML
12943 // can be considered as custom classes.
12944 const {
12945 className: omittedClassName,
12946 ...attributesSansClassName
12947 } = blockAttributes;
12948 const serialized = getSaveContent(blockType, attributesSansClassName);
12949 const defaultClasses = getHTMLRootElementClasses(serialized);
12950 const actualClasses = getHTMLRootElementClasses(innerHTML);
12951 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className));
12952
12953 if (customClasses.length) {
12954 blockAttributes.className = customClasses.join(' ');
12955 } else if (serialized) {
12956 delete blockAttributes.className;
12957 }
12958 }
12959
12960 return blockAttributes;
12961 }
12962
12963 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-built-in-validation-fixes.js
12964 /**
12965 * Internal dependencies
12966 */
12967
12968 /**
12969 * Attempts to fix block invalidation by applying build-in validation fixes
12970 * like moving all extra classNames to the className attribute.
12971 *
12972 * @param {WPBlock} block block object.
12973 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and
12974 * can be inferred from the block name,
12975 * but it's here for performance reasons.
12976 *
12977 * @return {WPBlock} Fixed block object
12978 */
12979
12980 function applyBuiltInValidationFixes(block, blockType) {
12981 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent);
12982 return { ...block,
12983 attributes: updatedBlockAttributes
12984 };
12985 }
12986
12987 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-block-deprecated-versions.js
12988 /**
12989 * Internal dependencies
12990 */
12991
12992
12993
12994
12995
12996 /**
12997 * Function that takes no arguments and always returns false.
12998 *
12999 * @return {boolean} Always returns false.
13000 */
13001
13002 function stubFalse() {
13003 return false;
13004 }
13005 /**
13006 * Given a block object, returns a new copy of the block with any applicable
13007 * deprecated migrations applied, or the original block if it was both valid
13008 * and no eligible migrations exist.
13009 *
13010 * @param {import(".").WPBlock} block Parsed and invalid block object.
13011 * @param {import(".").WPRawBlock} rawBlock Raw block object.
13012 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and
13013 * can be inferred from the block name,
13014 * but it's here for performance reasons.
13015 *
13016 * @return {import(".").WPBlock} Migrated block object.
13017 */
13018
13019
13020 function applyBlockDeprecatedVersions(block, rawBlock, blockType) {
13021 const parsedAttributes = rawBlock.attrs;
13022 const {
13023 deprecated: deprecatedDefinitions
13024 } = blockType; // Bail early if there are no registered deprecations to be handled.
13025
13026 if (!deprecatedDefinitions || !deprecatedDefinitions.length) {
13027 return block;
13028 } // By design, blocks lack any sort of version tracking. Instead, to process
13029 // outdated content the system operates a queue out of all the defined
13030 // attribute shapes and tries each definition until the input produces a
13031 // valid result. This mechanism seeks to avoid polluting the user-space with
13032 // machine-specific code. An invalid block is thus a block that could not be
13033 // matched successfully with any of the registered deprecation definitions.
13034
13035
13036 for (let i = 0; i < deprecatedDefinitions.length; i++) {
13037 // A block can opt into a migration even if the block is valid by
13038 // defining `isEligible` on its deprecation. If the block is both valid
13039 // and does not opt to migrate, skip.
13040 const {
13041 isEligible = stubFalse
13042 } = deprecatedDefinitions[i];
13043
13044 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks)) {
13045 continue;
13046 } // Block type properties which could impact either serialization or
13047 // parsing are not considered in the deprecated block type by default,
13048 // and must be explicitly provided.
13049
13050
13051 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]);
13052 let migratedBlock = { ...block,
13053 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes)
13054 }; // Ignore the deprecation if it produces a block which is not valid.
13055
13056 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); // If the migrated block is not valid initially, try the built-in fixes.
13057
13058 if (!isValid) {
13059 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType);
13060 [isValid] = validateBlock(migratedBlock, deprecatedBlockType);
13061 } // An invalid block does not imply incorrect HTML but the fact block
13062 // source information could be lost on re-serialization.
13063
13064
13065 if (!isValid) {
13066 continue;
13067 }
13068
13069 let migratedInnerBlocks = migratedBlock.innerBlocks;
13070 let migratedAttributes = migratedBlock.attributes; // A block may provide custom behavior to assign new attributes and/or
13071 // inner blocks.
13072
13073 const {
13074 migrate
13075 } = deprecatedBlockType;
13076
13077 if (migrate) {
13078 let migrated = migrate(migratedAttributes, block.innerBlocks);
13079
13080 if (!Array.isArray(migrated)) {
13081 migrated = [migrated];
13082 }
13083
13084 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated;
13085 }
13086
13087 block = { ...block,
13088 attributes: migratedAttributes,
13089 innerBlocks: migratedInnerBlocks,
13090 isValid: true,
13091 validationIssues: []
13092 };
13093 }
13094
13095 return block;
13096 }
13097
13098 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/index.js
13099 /**
13100 * WordPress dependencies
13101 */
13102
13103
13104 /**
13105 * Internal dependencies
13106 */
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117 /**
13118 * The raw structure of a block includes its attributes, inner
13119 * blocks, and inner HTML. It is important to distinguish inner blocks from
13120 * the HTML content of the block as only the latter is relevant for block
13121 * validation and edit operations.
13122 *
13123 * @typedef WPRawBlock
13124 *
13125 * @property {string=} blockName Block name
13126 * @property {Object=} attrs Block raw or comment attributes.
13127 * @property {string} innerHTML HTML content of the block.
13128 * @property {(string|null)[]} innerContent Content without inner blocks.
13129 * @property {WPRawBlock[]} innerBlocks Inner Blocks.
13130 */
13131
13132 /**
13133 * Fully parsed block object.
13134 *
13135 * @typedef WPBlock
13136 *
13137 * @property {string} name Block name
13138 * @property {Object} attributes Block raw or comment attributes.
13139 * @property {WPBlock[]} innerBlocks Inner Blocks.
13140 * @property {string} originalContent Original content of the block before validation fixes.
13141 * @property {boolean} isValid Whether the block is valid.
13142 * @property {Object[]} validationIssues Validation issues.
13143 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser.
13144 */
13145
13146 /**
13147 * @typedef {Object} ParseOptions
13148 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details.
13149 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content.
13150 */
13151
13152 /**
13153 * Convert legacy blocks to their canonical form. This function is used
13154 * both in the parser level for previous content and to convert such blocks
13155 * used in Custom Post Types templates.
13156 *
13157 * @param {WPRawBlock} rawBlock
13158 *
13159 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found
13160 */
13161
13162 function convertLegacyBlocks(rawBlock) {
13163 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs);
13164 return { ...rawBlock,
13165 blockName: correctName,
13166 attrs: correctedAttributes
13167 };
13168 }
13169 /**
13170 * Normalize the raw block by applying the fallback block name if none given,
13171 * sanitize the parsed HTML...
13172 *
13173 * @param {WPRawBlock} rawBlock The raw block object.
13174 * @param {ParseOptions?} options Extra options for handling block parsing.
13175 *
13176 * @return {WPRawBlock} The normalized block object.
13177 */
13178
13179
13180 function normalizeRawBlock(rawBlock, options) {
13181 const fallbackBlockName = getFreeformContentHandlerName(); // If the grammar parsing don't produce any block name, use the freeform block.
13182
13183 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName();
13184 const rawAttributes = rawBlock.attrs || {};
13185 const rawInnerBlocks = rawBlock.innerBlocks || [];
13186 let rawInnerHTML = rawBlock.innerHTML.trim(); // Fallback content may be upgraded from classic content expecting implicit
13187 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent,
13188 // meaning there are no negative consequences to repeated autop calls.
13189
13190 if (rawBlockName === fallbackBlockName && !(options !== null && options !== void 0 && options.__unstableSkipAutop)) {
13191 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim();
13192 }
13193
13194 return { ...rawBlock,
13195 blockName: rawBlockName,
13196 attrs: rawAttributes,
13197 innerHTML: rawInnerHTML,
13198 innerBlocks: rawInnerBlocks
13199 };
13200 }
13201 /**
13202 * Uses the "unregistered blockType" to create a block object.
13203 *
13204 * @param {WPRawBlock} rawBlock block.
13205 *
13206 * @return {WPRawBlock} The unregistered block object.
13207 */
13208
13209 function createMissingBlockType(rawBlock) {
13210 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); // Preserve undelimited content for use by the unregistered type
13211 // handler. A block node's `innerHTML` isn't enough, as that field only
13212 // carries the block's own HTML and not its nested blocks.
13213
13214 const originalUndelimitedContent = serializeRawBlock(rawBlock, {
13215 isCommentDelimited: false
13216 }); // Preserve full block content for use by the unregistered type
13217 // handler, block boundaries included.
13218
13219 const originalContent = serializeRawBlock(rawBlock, {
13220 isCommentDelimited: true
13221 });
13222 return {
13223 blockName: unregisteredFallbackBlock,
13224 attrs: {
13225 originalName: rawBlock.blockName,
13226 originalContent,
13227 originalUndelimitedContent
13228 },
13229 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML,
13230 innerBlocks: rawBlock.innerBlocks,
13231 innerContent: rawBlock.innerContent
13232 };
13233 }
13234 /**
13235 * Validates a block and wraps with validation meta.
13236 *
13237 * The name here is regrettable but `validateBlock` is already taken.
13238 *
13239 * @param {WPBlock} unvalidatedBlock
13240 * @param {import('../registration').WPBlockType} blockType
13241 * @return {WPBlock} validated block, with auto-fixes if initially invalid
13242 */
13243
13244
13245 function applyBlockValidation(unvalidatedBlock, blockType) {
13246 // Attempt to validate the block.
13247 const [isValid] = validateBlock(unvalidatedBlock, blockType);
13248
13249 if (isValid) {
13250 return { ...unvalidatedBlock,
13251 isValid,
13252 validationIssues: []
13253 };
13254 } // If the block is invalid, attempt some built-in fixes
13255 // like custom classNames handling.
13256
13257
13258 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); // Attempt to validate the block once again after the built-in fixes.
13259
13260 const [isFixedValid, validationIssues] = validateBlock(unvalidatedBlock, blockType);
13261 return { ...fixedBlock,
13262 isValid: isFixedValid,
13263 validationIssues
13264 };
13265 }
13266 /**
13267 * Given a raw block returned by grammar parsing, returns a fully parsed block.
13268 *
13269 * @param {WPRawBlock} rawBlock The raw block object.
13270 * @param {ParseOptions} options Extra options for handling block parsing.
13271 *
13272 * @return {WPBlock | undefined} Fully parsed block.
13273 */
13274
13275
13276 function parseRawBlock(rawBlock, options) {
13277 let normalizedBlock = normalizeRawBlock(rawBlock, options); // During the lifecycle of the project, we renamed some old blocks
13278 // and transformed others to new blocks. To avoid breaking existing content,
13279 // we added this function to properly parse the old content.
13280
13281 normalizedBlock = convertLegacyBlocks(normalizedBlock); // Try finding the type for known block name.
13282
13283 let blockType = getBlockType(normalizedBlock.blockName); // If not blockType is found for the specified name, fallback to the "unregistedBlockType".
13284
13285 if (!blockType) {
13286 normalizedBlock = createMissingBlockType(normalizedBlock);
13287 blockType = getBlockType(normalizedBlock.blockName);
13288 } // If it's an empty freeform block or there's no blockType (no missing block handler)
13289 // Then, just ignore the block.
13290 // It might be a good idea to throw a warning here.
13291 // TODO: I'm unsure about the unregisteredFallbackBlock check,
13292 // it might ignore some dynamic unregistered third party blocks wrongly.
13293
13294
13295 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName();
13296
13297 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) {
13298 return;
13299 } // Parse inner blocks recursively.
13300
13301
13302 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) // See https://github.com/WordPress/gutenberg/pull/17164.
13303 .filter(innerBlock => !!innerBlock); // Get the fully parsed block.
13304
13305 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks);
13306 parsedBlock.originalContent = normalizedBlock.innerHTML;
13307 const validatedBlock = applyBlockValidation(parsedBlock, blockType);
13308 const {
13309 validationIssues
13310 } = validatedBlock; // Run the block deprecation and migrations.
13311 // This is performed on both invalid and valid blocks because
13312 // migration using the `migrate` functions should run even
13313 // if the output is deemed valid.
13314
13315 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType);
13316
13317 if (!updatedBlock.isValid) {
13318 // Preserve the original unprocessed version of the block
13319 // that we received (no fixes, no deprecations) so that
13320 // we can save it as close to exactly the same way as
13321 // we loaded it. This is important to avoid corruption
13322 // and data loss caused by block implementations trying
13323 // to process data that isn't fully recognized.
13324 updatedBlock.__unstableBlockSource = rawBlock;
13325 }
13326
13327 if (!validatedBlock.isValid && updatedBlock.isValid && !(options !== null && options !== void 0 && options.__unstableSkipMigrationLogs)) {
13328 /* eslint-disable no-console */
13329 console.groupCollapsed('Updated Block: %s', blockType.name);
13330 console.info('Block successfully updated for `%s` (%o).\n\nNew content generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', blockType.name, blockType, getSaveContent(blockType, updatedBlock.attributes), updatedBlock.originalContent);
13331 console.groupEnd();
13332 /* eslint-enable no-console */
13333 } else if (!validatedBlock.isValid && !updatedBlock.isValid) {
13334 validationIssues.forEach(_ref => {
13335 let {
13336 log,
13337 args
13338 } = _ref;
13339 return log(...args);
13340 });
13341 }
13342
13343 return updatedBlock;
13344 }
13345 /**
13346 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec
13347 * defined through a parsing expression grammar to take advantage of the regular
13348 * cadence provided by block delimiters -- composed syntactically through HTML
13349 * comments -- which, given a general HTML document as an input, returns a block
13350 * list array representation.
13351 *
13352 * This is a recursive-descent parser that scans linearly once through the input
13353 * document. Instead of directly recursing it utilizes a trampoline mechanism to
13354 * prevent stack overflow. This initial pass is mainly interested in separating
13355 * and isolating the blocks serialized in the document and manifestly not in the
13356 * content within the blocks.
13357 *
13358 * @see
13359 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/
13360 *
13361 * @param {string} content The post content.
13362 * @param {ParseOptions} options Extra options for handling block parsing.
13363 *
13364 * @return {Array} Block list.
13365 */
13366
13367 function parser_parse(content, options) {
13368 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => {
13369 const block = parseRawBlock(rawBlock, options);
13370
13371 if (block) {
13372 accumulator.push(block);
13373 }
13374
13375 return accumulator;
13376 }, []);
13377 }
13378
13379 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/get-raw-transforms.js
13380 /**
13381 * Internal dependencies
13382 */
13383
13384 function getRawTransforms() {
13385 return getBlockTransforms('from').filter(_ref => {
13386 let {
13387 type
13388 } = _ref;
13389 return type === 'raw';
13390 }).map(transform => {
13391 return transform.isMatch ? transform : { ...transform,
13392 isMatch: node => transform.selector && node.matches(transform.selector)
13393 };
13394 });
13395 }
13396
13397 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-to-blocks.js
13398 /**
13399 * Internal dependencies
13400 */
13401
13402
13403
13404 /**
13405 * Converts HTML directly to blocks. Looks for a matching transform for each
13406 * top-level tag. The HTML should be filtered to not have any text between
13407 * top-level tags and formatted in a way that blocks can handle the HTML.
13408 *
13409 * @param {string} html HTML to convert.
13410 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler
13411 * or pasteHandler.
13412 *
13413 * @return {Array} An array of blocks.
13414 */
13415
13416 function htmlToBlocks(html, handler) {
13417 const doc = document.implementation.createHTMLDocument('');
13418 doc.body.innerHTML = html;
13419 return Array.from(doc.body.children).flatMap(node => {
13420 const rawTransform = findTransform(getRawTransforms(), _ref => {
13421 let {
13422 isMatch
13423 } = _ref;
13424 return isMatch(node);
13425 });
13426
13427 if (!rawTransform) {
13428 return createBlock( // Should not be hardcoded.
13429 'core/html', getBlockAttributes('core/html', node.outerHTML));
13430 }
13431
13432 const {
13433 transform,
13434 blockName
13435 } = rawTransform;
13436
13437 if (transform) {
13438 return transform(node, handler);
13439 }
13440
13441 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML));
13442 });
13443 }
13444
13445 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/normalise-blocks.js
13446 /**
13447 * WordPress dependencies
13448 */
13449
13450 function normaliseBlocks(HTML) {
13451 const decuDoc = document.implementation.createHTMLDocument('');
13452 const accuDoc = document.implementation.createHTMLDocument('');
13453 const decu = decuDoc.body;
13454 const accu = accuDoc.body;
13455 decu.innerHTML = HTML;
13456
13457 while (decu.firstChild) {
13458 const node = decu.firstChild; // Text nodes: wrap in a paragraph, or append to previous.
13459
13460 if (node.nodeType === node.TEXT_NODE) {
13461 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) {
13462 decu.removeChild(node);
13463 } else {
13464 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
13465 accu.appendChild(accuDoc.createElement('P'));
13466 }
13467
13468 accu.lastChild.appendChild(node);
13469 } // Element nodes.
13470
13471 } else if (node.nodeType === node.ELEMENT_NODE) {
13472 // BR nodes: create a new paragraph on double, or append to previous.
13473 if (node.nodeName === 'BR') {
13474 if (node.nextSibling && node.nextSibling.nodeName === 'BR') {
13475 accu.appendChild(accuDoc.createElement('P'));
13476 decu.removeChild(node.nextSibling);
13477 } // Don't append to an empty paragraph.
13478
13479
13480 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) {
13481 accu.lastChild.appendChild(node);
13482 } else {
13483 decu.removeChild(node);
13484 }
13485 } else if (node.nodeName === 'P') {
13486 // Only append non-empty paragraph nodes.
13487 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) {
13488 decu.removeChild(node);
13489 } else {
13490 accu.appendChild(node);
13491 }
13492 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) {
13493 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
13494 accu.appendChild(accuDoc.createElement('P'));
13495 }
13496
13497 accu.lastChild.appendChild(node);
13498 } else {
13499 accu.appendChild(node);
13500 }
13501 } else {
13502 decu.removeChild(node);
13503 }
13504 }
13505
13506 return accu.innerHTML;
13507 }
13508
13509 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/special-comment-converter.js
13510 /**
13511 * WordPress dependencies
13512 */
13513
13514 /**
13515 * Looks for `<!--nextpage-->` and `<!--more-->` comments and
13516 * replaces them with a custom element representing a future block.
13517 *
13518 * The custom element is a way to bypass the rest of the `raw-handling`
13519 * transforms, which would eliminate other kinds of node with which to carry
13520 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc.
13521 *
13522 * The custom element is then expected to be recognized by any registered
13523 * block's `raw` transform.
13524 *
13525 * @param {Node} node The node to be processed.
13526 * @param {Document} doc The document of the node.
13527 * @return {void}
13528 */
13529
13530 function specialCommentConverter(node, doc) {
13531 if (node.nodeType !== node.COMMENT_NODE) {
13532 return;
13533 }
13534
13535 if (node.nodeValue === 'nextpage') {
13536 (0,external_wp_dom_namespaceObject.replace)(node, createNextpage(doc));
13537 return;
13538 }
13539
13540 if (node.nodeValue.indexOf('more') === 0) {
13541 moreCommentConverter(node, doc);
13542 }
13543 }
13544 /**
13545 * Convert `<!--more-->` as well as the `<!--more Some text-->` variant
13546 * and its `<!--noteaser-->` companion into the custom element
13547 * described in `specialCommentConverter()`.
13548 *
13549 * @param {Node} node The node to be processed.
13550 * @param {Document} doc The document of the node.
13551 * @return {void}
13552 */
13553
13554 function moreCommentConverter(node, doc) {
13555 // Grab any custom text in the comment.
13556 const customText = node.nodeValue.slice(4).trim();
13557 /*
13558 * When a `<!--more-->` comment is found, we need to look for any
13559 * `<!--noteaser-->` sibling, but it may not be a direct sibling
13560 * (whitespace typically lies in between)
13561 */
13562
13563 let sibling = node;
13564 let noTeaser = false;
13565
13566 while (sibling = sibling.nextSibling) {
13567 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') {
13568 noTeaser = true;
13569 (0,external_wp_dom_namespaceObject.remove)(sibling);
13570 break;
13571 }
13572 }
13573
13574 const moreBlock = createMore(customText, noTeaser, doc); // If our `<!--more-->` comment is in the middle of a paragraph, we should
13575 // split the paragraph in two and insert the more block in between. If not,
13576 // the more block will eventually end up being inserted after the paragraph.
13577
13578 if (!node.parentNode || node.parentNode.nodeName !== 'P' || node.parentNode.childNodes.length === 1) {
13579 (0,external_wp_dom_namespaceObject.replace)(node, moreBlock);
13580 } else {
13581 const childNodes = Array.from(node.parentNode.childNodes);
13582 const nodeIndex = childNodes.indexOf(node);
13583 const wrapperNode = node.parentNode.parentNode || doc.body;
13584
13585 const paragraphBuilder = (acc, child) => {
13586 if (!acc) {
13587 acc = doc.createElement('p');
13588 }
13589
13590 acc.appendChild(child);
13591 return acc;
13592 }; // Split the original parent node and insert our more block
13593
13594
13595 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), moreBlock, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEach(element => element && wrapperNode.insertBefore(element, node.parentNode)); // Remove the old parent paragraph
13596
13597 (0,external_wp_dom_namespaceObject.remove)(node.parentNode);
13598 }
13599 }
13600
13601 function createMore(customText, noTeaser, doc) {
13602 const node = doc.createElement('wp-block');
13603 node.dataset.block = 'core/more';
13604
13605 if (customText) {
13606 node.dataset.customText = customText;
13607 }
13608
13609 if (noTeaser) {
13610 // "Boolean" data attribute.
13611 node.dataset.noTeaser = '';
13612 }
13613
13614 return node;
13615 }
13616
13617 function createNextpage(doc) {
13618 const node = doc.createElement('wp-block');
13619 node.dataset.block = 'core/nextpage';
13620 return node;
13621 }
13622
13623 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/list-reducer.js
13624 /**
13625 * WordPress dependencies
13626 */
13627
13628
13629 function isList(node) {
13630 return node.nodeName === 'OL' || node.nodeName === 'UL';
13631 }
13632
13633 function shallowTextContent(element) {
13634 return Array.from(element.childNodes).map(_ref => {
13635 let {
13636 nodeValue = ''
13637 } = _ref;
13638 return nodeValue;
13639 }).join('');
13640 }
13641
13642 function listReducer(node) {
13643 if (!isList(node)) {
13644 return;
13645 }
13646
13647 const list = node;
13648 const prevElement = node.previousElementSibling; // Merge with previous list if:
13649 // * There is a previous list of the same type.
13650 // * There is only one list item.
13651
13652 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) {
13653 // Move all child nodes, including any text nodes, if any.
13654 while (list.firstChild) {
13655 prevElement.appendChild(list.firstChild);
13656 }
13657
13658 list.parentNode.removeChild(list);
13659 }
13660
13661 const parentElement = node.parentNode; // Nested list with empty parent item.
13662
13663 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) {
13664 const parentListItem = parentElement;
13665 const prevListItem = parentListItem.previousElementSibling;
13666 const parentList = parentListItem.parentNode;
13667
13668 if (prevListItem) {
13669 prevListItem.appendChild(list);
13670 parentList.removeChild(parentListItem);
13671 } else {
13672 parentList.parentNode.insertBefore(list, parentList);
13673 parentList.parentNode.removeChild(parentList);
13674 }
13675 } // Invalid: OL/UL > OL/UL.
13676
13677
13678 if (parentElement && isList(parentElement)) {
13679 const prevListItem = node.previousElementSibling;
13680
13681 if (prevListItem) {
13682 prevListItem.appendChild(node);
13683 } else {
13684 (0,external_wp_dom_namespaceObject.unwrap)(node);
13685 }
13686 }
13687 }
13688
13689 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/blockquote-normaliser.js
13690 /**
13691 * Internal dependencies
13692 */
13693
13694 function blockquoteNormaliser(node) {
13695 if (node.nodeName !== 'BLOCKQUOTE') {
13696 return;
13697 }
13698
13699 node.innerHTML = normaliseBlocks(node.innerHTML);
13700 }
13701
13702 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/figure-content-reducer.js
13703 /**
13704 * WordPress dependencies
13705 */
13706
13707 /**
13708 * Whether or not the given node is figure content.
13709 *
13710 * @param {Node} node The node to check.
13711 * @param {Object} schema The schema to use.
13712 *
13713 * @return {boolean} True if figure content, false if not.
13714 */
13715
13716 function isFigureContent(node, schema) {
13717 var _schema$figure$childr, _schema$figure;
13718
13719 const tag = node.nodeName.toLowerCase(); // We are looking for tags that can be a child of the figure tag, excluding
13720 // `figcaption` and any phrasing content.
13721
13722 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) {
13723 return false;
13724 }
13725
13726 return tag in ((_schema$figure$childr = schema === null || schema === void 0 ? void 0 : (_schema$figure = schema.figure) === null || _schema$figure === void 0 ? void 0 : _schema$figure.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {});
13727 }
13728 /**
13729 * Whether or not the given node can have an anchor.
13730 *
13731 * @param {Node} node The node to check.
13732 * @param {Object} schema The schema to use.
13733 *
13734 * @return {boolean} True if it can, false if not.
13735 */
13736
13737
13738 function canHaveAnchor(node, schema) {
13739 var _schema$figure$childr2, _schema$figure2, _schema$figure2$child, _schema$figure2$child2;
13740
13741 const tag = node.nodeName.toLowerCase();
13742 return tag in ((_schema$figure$childr2 = schema === null || schema === void 0 ? void 0 : (_schema$figure2 = schema.figure) === null || _schema$figure2 === void 0 ? void 0 : (_schema$figure2$child = _schema$figure2.children) === null || _schema$figure2$child === void 0 ? void 0 : (_schema$figure2$child2 = _schema$figure2$child.a) === null || _schema$figure2$child2 === void 0 ? void 0 : _schema$figure2$child2.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {});
13743 }
13744 /**
13745 * Wraps the given element in a figure element.
13746 *
13747 * @param {Element} element The element to wrap.
13748 * @param {Element} beforeElement The element before which to place the figure.
13749 */
13750
13751
13752 function wrapFigureContent(element) {
13753 let beforeElement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : element;
13754 const figure = element.ownerDocument.createElement('figure');
13755 beforeElement.parentNode.insertBefore(figure, beforeElement);
13756 figure.appendChild(element);
13757 }
13758 /**
13759 * This filter takes figure content out of paragraphs, wraps it in a figure
13760 * element, and moves any anchors with it if needed.
13761 *
13762 * @param {Node} node The node to filter.
13763 * @param {Document} doc The document of the node.
13764 * @param {Object} schema The schema to use.
13765 *
13766 * @return {void}
13767 */
13768
13769
13770 function figureContentReducer(node, doc, schema) {
13771 if (!isFigureContent(node, schema)) {
13772 return;
13773 }
13774
13775 let nodeToInsert = node;
13776 const parentNode = node.parentNode; // If the figure content can have an anchor and its parent is an anchor with
13777 // only the figure content, take the anchor out instead of just the content.
13778
13779 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) {
13780 nodeToInsert = node.parentNode;
13781 }
13782
13783 const wrapper = nodeToInsert.closest('p,div'); // If wrapped in a paragraph or div, only extract if it's aligned or if
13784 // there is no text content.
13785 // Otherwise, if directly at the root, wrap in a figure element.
13786
13787 if (wrapper) {
13788 // In jsdom-jscore, 'node.classList' can be undefined.
13789 // In this case, default to extract as it offers a better UI experience on mobile.
13790 if (!node.classList) {
13791 wrapFigureContent(nodeToInsert, wrapper);
13792 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) {
13793 wrapFigureContent(nodeToInsert, wrapper);
13794 }
13795 } else if (nodeToInsert.parentNode.nodeName === 'BODY') {
13796 wrapFigureContent(nodeToInsert);
13797 }
13798 }
13799
13800 ;// CONCATENATED MODULE: external ["wp","shortcode"]
13801 var external_wp_shortcode_namespaceObject = window["wp"]["shortcode"];
13802 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/shortcode-converter.js
13803 /**
13804 * WordPress dependencies
13805 */
13806
13807 /**
13808 * Internal dependencies
13809 */
13810
13811
13812
13813
13814
13815
13816 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray];
13817
13818 function segmentHTMLToShortcodeBlock(HTML) {
13819 let lastIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
13820 let excludedBlockNames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
13821 // Get all matches.
13822 const transformsFrom = getBlockTransforms('from');
13823 const transformation = findTransform(transformsFrom, transform => excludedBlockNames.indexOf(transform.blockName) === -1 && transform.type === 'shortcode' && castArray(transform.tag).some(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)));
13824
13825 if (!transformation) {
13826 return [HTML];
13827 }
13828
13829 const transformTags = castArray(transformation.tag);
13830 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML));
13831 let match;
13832 const previousIndex = lastIndex;
13833
13834 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) {
13835 var _match$shortcode$cont;
13836
13837 lastIndex = match.index + match.content.length;
13838 const beforeHTML = HTML.substr(0, match.index);
13839 const afterHTML = HTML.substr(lastIndex); // If the shortcode content does not contain HTML and the shortcode is
13840 // not on a new line (or in paragraph from Markdown converter),
13841 // consider the shortcode as inline text, and thus skip conversion for
13842 // this segment.
13843
13844 if (!((_match$shortcode$cont = match.shortcode.content) !== null && _match$shortcode$cont !== void 0 && _match$shortcode$cont.includes('<')) && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) {
13845 return segmentHTMLToShortcodeBlock(HTML, lastIndex);
13846 } // If a transformation's `isMatch` predicate fails for the inbound
13847 // shortcode, try again by excluding the current block type.
13848 //
13849 // This is the only call to `segmentHTMLToShortcodeBlock` that should
13850 // ever carry over `excludedBlockNames`. Other calls in the module
13851 // should skip that argument as a way to reset the exclusion state, so
13852 // that one `isMatch` fail in an HTML fragment doesn't prevent any
13853 // valid matches in subsequent fragments.
13854
13855
13856 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) {
13857 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]);
13858 }
13859
13860 let blocks = [];
13861
13862 if (typeof transformation.transform === 'function') {
13863 // Passing all of `match` as second argument is intentionally broad
13864 // but shouldn't be too relied upon.
13865 //
13866 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926
13867 blocks = [].concat(transformation.transform(match.shortcode.attrs, match)); // Applying the built-in fixes can enhance the attributes with missing content like "className".
13868
13869 blocks = blocks.map(block => {
13870 block.originalContent = match.shortcode.content;
13871 return applyBuiltInValidationFixes(block, getBlockType(block.name));
13872 });
13873 } else {
13874 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(_ref => {
13875 let [, schema] = _ref;
13876 return schema.shortcode;
13877 }) // Passing all of `match` as second argument is intentionally broad
13878 // but shouldn't be too relied upon.
13879 //
13880 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926
13881 .map(_ref2 => {
13882 let [key, schema] = _ref2;
13883 return [key, schema.shortcode(match.shortcode.attrs, match)];
13884 }));
13885 const blockType = getBlockType(transformation.blockName);
13886
13887 if (!blockType) {
13888 return [HTML];
13889 }
13890
13891 const transformationBlockType = { ...blockType,
13892 attributes: transformation.attributes
13893 };
13894 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); // Applying the built-in fixes can enhance the attributes with missing content like "className".
13895
13896 block.originalContent = match.shortcode.content;
13897 block = applyBuiltInValidationFixes(block, transformationBlockType);
13898 blocks = [block];
13899 }
13900
13901 return [...segmentHTMLToShortcodeBlock(beforeHTML), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML)];
13902 }
13903
13904 return [HTML];
13905 }
13906
13907 /* harmony default export */ var shortcode_converter = (segmentHTMLToShortcodeBlock);
13908
13909 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/utils.js
13910 /**
13911 * External dependencies
13912 */
13913
13914 /**
13915 * WordPress dependencies
13916 */
13917
13918
13919 /**
13920 * Internal dependencies
13921 */
13922
13923
13924
13925 function getBlockContentSchemaFromTransforms(transforms, context) {
13926 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context);
13927 const schemaArgs = {
13928 phrasingContentSchema,
13929 isPaste: context === 'paste'
13930 };
13931 const schemas = transforms.map(_ref => {
13932 let {
13933 isMatch,
13934 blockName,
13935 schema
13936 } = _ref;
13937 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor');
13938 schema = typeof schema === 'function' ? schema(schemaArgs) : schema; // If the block does not has anchor support and the transform does not
13939 // provides an isMatch we can return the schema right away.
13940
13941 if (!hasAnchorSupport && !isMatch) {
13942 return schema;
13943 }
13944
13945 return (0,external_lodash_namespaceObject.mapValues)(schema, value => {
13946 let attributes = value.attributes || []; // If the block supports the "anchor" functionality, it needs to keep its ID attribute.
13947
13948 if (hasAnchorSupport) {
13949 attributes = [...attributes, 'id'];
13950 }
13951
13952 return { ...value,
13953 attributes,
13954 isMatch: isMatch ? isMatch : undefined
13955 };
13956 });
13957 });
13958 return (0,external_lodash_namespaceObject.mergeWith)({}, ...schemas, (objValue, srcValue, key) => {
13959 switch (key) {
13960 case 'children':
13961 {
13962 if (objValue === '*' || srcValue === '*') {
13963 return '*';
13964 }
13965
13966 return { ...objValue,
13967 ...srcValue
13968 };
13969 }
13970
13971 case 'attributes':
13972 case 'require':
13973 {
13974 return [...(objValue || []), ...(srcValue || [])];
13975 }
13976
13977 case 'isMatch':
13978 {
13979 // If one of the values being merge is undefined (matches everything),
13980 // the result of the merge will be undefined.
13981 if (!objValue || !srcValue) {
13982 return undefined;
13983 } // When merging two isMatch functions, the result is a new function
13984 // that returns if one of the source functions returns true.
13985
13986
13987 return function () {
13988 return objValue(...arguments) || srcValue(...arguments);
13989 };
13990 }
13991 }
13992 });
13993 }
13994 /**
13995 * Gets the block content schema, which is extracted and merged from all
13996 * registered blocks with raw transfroms.
13997 *
13998 * @param {string} context Set to "paste" when in paste context, where the
13999 * schema is more strict.
14000 *
14001 * @return {Object} A complete block content schema.
14002 */
14003
14004 function getBlockContentSchema(context) {
14005 return getBlockContentSchemaFromTransforms(getRawTransforms(), context);
14006 }
14007 /**
14008 * Checks whether HTML can be considered plain text. That is, it does not contain
14009 * any elements that are not line breaks.
14010 *
14011 * @param {string} HTML The HTML to check.
14012 *
14013 * @return {boolean} Whether the HTML can be considered plain text.
14014 */
14015
14016 function isPlain(HTML) {
14017 return !/<(?!br[ />])/i.test(HTML);
14018 }
14019 /**
14020 * Given node filters, deeply filters and mutates a NodeList.
14021 *
14022 * @param {NodeList} nodeList The nodeList to filter.
14023 * @param {Array} filters An array of functions that can mutate with the provided node.
14024 * @param {Document} doc The document of the nodeList.
14025 * @param {Object} schema The schema to use.
14026 */
14027
14028 function deepFilterNodeList(nodeList, filters, doc, schema) {
14029 Array.from(nodeList).forEach(node => {
14030 deepFilterNodeList(node.childNodes, filters, doc, schema);
14031 filters.forEach(item => {
14032 // Make sure the node is still attached to the document.
14033 if (!doc.contains(node)) {
14034 return;
14035 }
14036
14037 item(node, doc, schema);
14038 });
14039 });
14040 }
14041 /**
14042 * Given node filters, deeply filters HTML tags.
14043 * Filters from the deepest nodes to the top.
14044 *
14045 * @param {string} HTML The HTML to filter.
14046 * @param {Array} filters An array of functions that can mutate with the provided node.
14047 * @param {Object} schema The schema to use.
14048 *
14049 * @return {string} The filtered HTML.
14050 */
14051
14052 function deepFilterHTML(HTML) {
14053 let filters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
14054 let schema = arguments.length > 2 ? arguments[2] : undefined;
14055 const doc = document.implementation.createHTMLDocument('');
14056 doc.body.innerHTML = HTML;
14057 deepFilterNodeList(doc.body.childNodes, filters, doc, schema);
14058 return doc.body.innerHTML;
14059 }
14060 /**
14061 * Gets a sibling within text-level context.
14062 *
14063 * @param {Element} node The subject node.
14064 * @param {string} which "next" or "previous".
14065 */
14066
14067 function getSibling(node, which) {
14068 const sibling = node[`${which}Sibling`];
14069
14070 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) {
14071 return sibling;
14072 }
14073
14074 const {
14075 parentNode
14076 } = node;
14077
14078 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) {
14079 return;
14080 }
14081
14082 return getSibling(parentNode, which);
14083 }
14084
14085 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/index.js
14086 /**
14087 * WordPress dependencies
14088 */
14089
14090
14091 /**
14092 * Internal dependencies
14093 */
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105 function deprecatedGetPhrasingContentSchema(context) {
14106 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', {
14107 since: '5.6',
14108 alternative: 'wp.dom.getPhrasingContentSchema'
14109 });
14110 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context);
14111 }
14112 /**
14113 * Converts an HTML string to known blocks.
14114 *
14115 * @param {Object} $1
14116 * @param {string} $1.HTML The HTML to convert.
14117 *
14118 * @return {Array} A list of blocks.
14119 */
14120
14121 function rawHandler(_ref) {
14122 let {
14123 HTML = ''
14124 } = _ref;
14125
14126 // If we detect block delimiters, parse entirely as blocks.
14127 if (HTML.indexOf('<!-- wp:') !== -1) {
14128 return parser_parse(HTML);
14129 } // An array of HTML strings and block objects. The blocks replace matched
14130 // shortcodes.
14131
14132
14133 const pieces = shortcode_converter(HTML);
14134 const blockContentSchema = getBlockContentSchema();
14135 return pieces.map(piece => {
14136 // Already a block from shortcode.
14137 if (typeof piece !== 'string') {
14138 return piece;
14139 } // These filters are essential for some blocks to be able to transform
14140 // from raw HTML. These filters move around some content or add
14141 // additional tags, they do not remove any content.
14142
14143
14144 const filters = [// Needed to adjust invalid lists.
14145 listReducer, // Needed to create more and nextpage blocks.
14146 specialCommentConverter, // Needed to create media blocks.
14147 figureContentReducer, // Needed to create the quote block, which cannot handle text
14148 // without wrapper paragraphs.
14149 blockquoteNormaliser];
14150 piece = deepFilterHTML(piece, filters, blockContentSchema);
14151 piece = normaliseBlocks(piece);
14152 return htmlToBlocks(piece, rawHandler);
14153 }).flat().filter(Boolean);
14154 }
14155
14156 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/comment-remover.js
14157 /**
14158 * WordPress dependencies
14159 */
14160
14161 /**
14162 * Looks for comments, and removes them.
14163 *
14164 * @param {Node} node The node to be processed.
14165 * @return {void}
14166 */
14167
14168 function commentRemover(node) {
14169 if (node.nodeType === node.COMMENT_NODE) {
14170 (0,external_wp_dom_namespaceObject.remove)(node);
14171 }
14172 }
14173
14174 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/is-inline-content.js
14175 /**
14176 * WordPress dependencies
14177 */
14178
14179 /**
14180 * Checks if the given node should be considered inline content, optionally
14181 * depending on a context tag.
14182 *
14183 * @param {Node} node Node name.
14184 * @param {string} contextTag Tag name.
14185 *
14186 * @return {boolean} True if the node is inline content, false if nohe.
14187 */
14188
14189 function isInline(node, contextTag) {
14190 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) {
14191 return true;
14192 }
14193
14194 if (!contextTag) {
14195 return false;
14196 }
14197
14198 const tag = node.nodeName.toLowerCase();
14199 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']];
14200 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0);
14201 }
14202
14203 function deepCheck(nodes, contextTag) {
14204 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag));
14205 }
14206
14207 function isDoubleBR(node) {
14208 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR';
14209 }
14210
14211 function isInlineContent(HTML, contextTag) {
14212 const doc = document.implementation.createHTMLDocument('');
14213 doc.body.innerHTML = HTML;
14214 const nodes = Array.from(doc.body.children);
14215 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag);
14216 }
14217
14218 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/phrasing-content-reducer.js
14219 /**
14220 * WordPress dependencies
14221 */
14222
14223 function phrasingContentReducer(node, doc) {
14224 // In jsdom-jscore, 'node.style' can be null.
14225 // TODO: Explore fixing this by patching jsdom-jscore.
14226 if (node.nodeName === 'SPAN' && node.style) {
14227 const {
14228 fontWeight,
14229 fontStyle,
14230 textDecorationLine,
14231 textDecoration,
14232 verticalAlign
14233 } = node.style;
14234
14235 if (fontWeight === 'bold' || fontWeight === '700') {
14236 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node);
14237 }
14238
14239 if (fontStyle === 'italic') {
14240 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node);
14241 } // Some DOM implementations (Safari, JSDom) don't support
14242 // style.textDecorationLine, so we check style.textDecoration as a
14243 // fallback.
14244
14245
14246 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) {
14247 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node);
14248 }
14249
14250 if (verticalAlign === 'super') {
14251 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node);
14252 } else if (verticalAlign === 'sub') {
14253 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node);
14254 }
14255 } else if (node.nodeName === 'B') {
14256 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong');
14257 } else if (node.nodeName === 'I') {
14258 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em');
14259 } else if (node.nodeName === 'A') {
14260 // In jsdom-jscore, 'node.target' can be null.
14261 // TODO: Explore fixing this by patching jsdom-jscore.
14262 if (node.target && node.target.toLowerCase() === '_blank') {
14263 node.rel = 'noreferrer noopener';
14264 } else {
14265 node.removeAttribute('target');
14266 node.removeAttribute('rel');
14267 } // Saves anchor elements name attribute as id
14268
14269
14270 if (node.name && !node.id) {
14271 node.id = node.name;
14272 } // Keeps id only if there is an internal link pointing to it
14273
14274
14275 if (node.id && !node.ownerDocument.querySelector(`[href="#${node.id}"]`)) {
14276 node.removeAttribute('id');
14277 }
14278 }
14279 }
14280
14281 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/head-remover.js
14282 function headRemover(node) {
14283 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') {
14284 return;
14285 }
14286
14287 node.parentNode.removeChild(node);
14288 }
14289
14290 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/ms-list-converter.js
14291 /**
14292 * Browser dependencies
14293 */
14294 const {
14295 parseInt: ms_list_converter_parseInt
14296 } = window;
14297
14298 function ms_list_converter_isList(node) {
14299 return node.nodeName === 'OL' || node.nodeName === 'UL';
14300 }
14301
14302 function msListConverter(node, doc) {
14303 if (node.nodeName !== 'P') {
14304 return;
14305 }
14306
14307 const style = node.getAttribute('style');
14308
14309 if (!style) {
14310 return;
14311 } // Quick check.
14312
14313
14314 if (style.indexOf('mso-list') === -1) {
14315 return;
14316 }
14317
14318 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style);
14319
14320 if (!matches) {
14321 return;
14322 }
14323
14324 let level = ms_list_converter_parseInt(matches[1], 10) - 1 || 0;
14325 const prevNode = node.previousElementSibling; // Add new list if no previous.
14326
14327 if (!prevNode || !ms_list_converter_isList(prevNode)) {
14328 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type.
14329 const type = node.textContent.trim().slice(0, 1);
14330 const isNumeric = /[1iIaA]/.test(type);
14331 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul');
14332
14333 if (isNumeric) {
14334 newListNode.setAttribute('type', type);
14335 }
14336
14337 node.parentNode.insertBefore(newListNode, node);
14338 }
14339
14340 const listNode = node.previousElementSibling;
14341 const listType = listNode.nodeName;
14342 const listItem = doc.createElement('li');
14343 let receivingNode = listNode; // Remove the first span with list info.
14344
14345 node.removeChild(node.firstChild); // Add content.
14346
14347 while (node.firstChild) {
14348 listItem.appendChild(node.firstChild);
14349 } // Change pointer depending on indentation level.
14350
14351
14352 while (level--) {
14353 receivingNode = receivingNode.lastChild || receivingNode; // If it's a list, move pointer to the last item.
14354
14355 if (ms_list_converter_isList(receivingNode)) {
14356 receivingNode = receivingNode.lastChild || receivingNode;
14357 }
14358 } // Make sure we append to a list.
14359
14360
14361 if (!ms_list_converter_isList(receivingNode)) {
14362 receivingNode = receivingNode.appendChild(doc.createElement(listType));
14363 } // Append the list item to the list.
14364
14365
14366 receivingNode.appendChild(listItem); // Remove the wrapper paragraph.
14367
14368 node.parentNode.removeChild(node);
14369 }
14370
14371 ;// CONCATENATED MODULE: external ["wp","blob"]
14372 var external_wp_blob_namespaceObject = window["wp"]["blob"];
14373 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/image-corrector.js
14374 /**
14375 * WordPress dependencies
14376 */
14377
14378 /**
14379 * Browser dependencies
14380 */
14381
14382 const {
14383 atob,
14384 File
14385 } = window;
14386 function imageCorrector(node) {
14387 if (node.nodeName !== 'IMG') {
14388 return;
14389 }
14390
14391 if (node.src.indexOf('file:') === 0) {
14392 node.src = '';
14393 } // This piece cannot be tested outside a browser env.
14394
14395
14396 if (node.src.indexOf('data:') === 0) {
14397 const [properties, data] = node.src.split(',');
14398 const [type] = properties.slice(5).split(';');
14399
14400 if (!data || !type) {
14401 node.src = '';
14402 return;
14403 }
14404
14405 let decoded; // Can throw DOMException!
14406
14407 try {
14408 decoded = atob(data);
14409 } catch (e) {
14410 node.src = '';
14411 return;
14412 }
14413
14414 const uint8Array = new Uint8Array(decoded.length);
14415
14416 for (let i = 0; i < uint8Array.length; i++) {
14417 uint8Array[i] = decoded.charCodeAt(i);
14418 }
14419
14420 const name = type.replace('/', '.');
14421 const file = new File([uint8Array], name, {
14422 type
14423 });
14424 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file);
14425 } // Remove trackers and hardly visible images.
14426
14427
14428 if (node.height === 1 || node.width === 1) {
14429 node.parentNode.removeChild(node);
14430 }
14431 }
14432
14433 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/div-normaliser.js
14434 /**
14435 * Internal dependencies
14436 */
14437
14438 function divNormaliser(node) {
14439 if (node.nodeName !== 'DIV') {
14440 return;
14441 }
14442
14443 node.innerHTML = normaliseBlocks(node.innerHTML);
14444 }
14445
14446 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js
14447 var showdown = __webpack_require__(7308);
14448 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown);
14449 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/markdown-converter.js
14450 /**
14451 * External dependencies
14452 */
14453 // Reuse the same showdown converter.
14454
14455 const converter = new (showdown_default()).Converter({
14456 noHeaderId: true,
14457 tables: true,
14458 literalMidWordUnderscores: true,
14459 omitExtraWLInCodeBlocks: true,
14460 simpleLineBreaks: true,
14461 strikethrough: true
14462 });
14463 /**
14464 * Corrects the Slack Markdown variant of the code block.
14465 * If uncorrected, it will be converted to inline code.
14466 *
14467 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks
14468 *
14469 * @param {string} text The potential Markdown text to correct.
14470 *
14471 * @return {string} The corrected Markdown.
14472 */
14473
14474 function slackMarkdownVariantCorrector(text) {
14475 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `${p1}\n${p2}\n${p3}`);
14476 }
14477
14478 function bulletsToAsterisks(text) {
14479 return text.replace(/(^|\n)•( +)/g, '$1*$2');
14480 }
14481 /**
14482 * Converts a piece of text into HTML based on any Markdown present.
14483 * Also decodes any encoded HTML.
14484 *
14485 * @param {string} text The plain text to convert.
14486 *
14487 * @return {string} HTML.
14488 */
14489
14490
14491 function markdownConverter(text) {
14492 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text)));
14493 }
14494
14495 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/iframe-remover.js
14496 /**
14497 * Removes iframes.
14498 *
14499 * @param {Node} node The node to check.
14500 *
14501 * @return {void}
14502 */
14503 function iframeRemover(node) {
14504 if (node.nodeName === 'IFRAME') {
14505 const text = node.ownerDocument.createTextNode(node.src);
14506 node.parentNode.replaceChild(text, node);
14507 }
14508 }
14509
14510 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/google-docs-uid-remover.js
14511 /**
14512 * WordPress dependencies
14513 */
14514
14515 function googleDocsUIdRemover(node) {
14516 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) {
14517 return;
14518 } // Google Docs sometimes wraps the content in a B tag. We don't want to keep
14519 // this.
14520
14521
14522 if (node.tagName === 'B') {
14523 (0,external_wp_dom_namespaceObject.unwrap)(node);
14524 } else {
14525 node.removeAttribute('id');
14526 }
14527 }
14528
14529 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-formatting-remover.js
14530 /**
14531 * Internal dependencies
14532 */
14533
14534
14535 function isFormattingSpace(character) {
14536 return character === ' ' || character === '\r' || character === '\n' || character === '\t';
14537 }
14538 /**
14539 * Removes spacing that formats HTML.
14540 *
14541 * @see https://www.w3.org/TR/css-text-3/#white-space-processing
14542 *
14543 * @param {Node} node The node to be processed.
14544 * @return {void}
14545 */
14546
14547
14548 function htmlFormattingRemover(node) {
14549 if (node.nodeType !== node.TEXT_NODE) {
14550 return;
14551 } // Ignore pre content. Note that this does not use Element#closest due to
14552 // a combination of (a) node may not be Element and (b) node.parentElement
14553 // does not have full support in all browsers (Internet Exporer).
14554 //
14555 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility
14556
14557 /** @type {Node?} */
14558
14559
14560 let parent = node;
14561
14562 while (parent = parent.parentNode) {
14563 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') {
14564 return;
14565 }
14566 } // First, replace any sequence of HTML formatting space with a single space.
14567
14568
14569 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); // Remove the leading space if the text element is at the start of a block,
14570 // is preceded by a line break element, or has a space in the previous
14571 // node.
14572
14573 if (newData[0] === ' ') {
14574 const previousSibling = getSibling(node, 'previous');
14575
14576 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') {
14577 newData = newData.slice(1);
14578 }
14579 } // Remove the trailing space if the text element is at the end of a block,
14580 // is succeded by a line break element, or has a space in the next text
14581 // node.
14582
14583
14584 if (newData[newData.length - 1] === ' ') {
14585 const nextSibling = getSibling(node, 'next');
14586
14587 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) {
14588 newData = newData.slice(0, -1);
14589 }
14590 } // If there's no data left, remove the node, so `previousSibling` stays
14591 // accurate. Otherwise, update the node data.
14592
14593
14594 if (!newData) {
14595 node.parentNode.removeChild(node);
14596 } else {
14597 node.data = newData;
14598 }
14599 }
14600
14601 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/br-remover.js
14602 /**
14603 * Internal dependencies
14604 */
14605
14606 /**
14607 * Removes trailing br elements from text-level content.
14608 *
14609 * @param {Element} node Node to check.
14610 */
14611
14612 function brRemover(node) {
14613 if (node.nodeName !== 'BR') {
14614 return;
14615 }
14616
14617 if (getSibling(node, 'next')) {
14618 return;
14619 }
14620
14621 node.parentNode.removeChild(node);
14622 }
14623
14624 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/empty-paragraph-remover.js
14625 /**
14626 * Removes empty paragraph elements.
14627 *
14628 * @param {Element} node Node to check.
14629 */
14630 function emptyParagraphRemover(node) {
14631 if (node.nodeName !== 'P') {
14632 return;
14633 }
14634
14635 if (node.hasChildNodes()) {
14636 return;
14637 }
14638
14639 node.parentNode.removeChild(node);
14640 }
14641
14642 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js
14643 /**
14644 * Replaces Slack paragraph markup with a double line break (later converted to
14645 * a proper paragraph).
14646 *
14647 * @param {Element} node Node to check.
14648 */
14649 function slackParagraphCorrector(node) {
14650 if (node.nodeName !== 'SPAN') {
14651 return;
14652 }
14653
14654 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') {
14655 return;
14656 }
14657
14658 const {
14659 parentNode
14660 } = node;
14661 parentNode.insertBefore(node.ownerDocument.createElement('br'), node);
14662 parentNode.insertBefore(node.ownerDocument.createElement('br'), node);
14663 parentNode.removeChild(node);
14664 }
14665
14666 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/paste-handler.js
14667 /**
14668 * WordPress dependencies
14669 */
14670
14671 /**
14672 * Internal dependencies
14673 */
14674
14675
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685
14686
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700 /**
14701 * Browser dependencies
14702 */
14703
14704 const {
14705 console: paste_handler_console
14706 } = window;
14707 /**
14708 * Filters HTML to only contain phrasing content.
14709 *
14710 * @param {string} HTML The HTML to filter.
14711 * @param {boolean} preserveWhiteSpace Whether or not to preserve consequent white space.
14712 *
14713 * @return {string} HTML only containing phrasing content.
14714 */
14715
14716 function filterInlineHTML(HTML, preserveWhiteSpace) {
14717 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, phrasingContentReducer, commentRemover]);
14718 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), {
14719 inline: true
14720 });
14721
14722 if (!preserveWhiteSpace) {
14723 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]);
14724 } // Allows us to ask for this information when we get a report.
14725
14726
14727 paste_handler_console.log('Processed inline HTML:\n\n', HTML);
14728 return HTML;
14729 }
14730 /**
14731 * Converts an HTML string to known blocks. Strips everything else.
14732 *
14733 * @param {Object} options
14734 * @param {string} [options.HTML] The HTML to convert.
14735 * @param {string} [options.plainText] Plain text version.
14736 * @param {string} [options.mode] Handle content as blocks or inline content.
14737 * * 'AUTO': Decide based on the content passed.
14738 * * 'INLINE': Always handle as inline content, and return string.
14739 * * 'BLOCKS': Always handle as blocks, and return array of blocks.
14740 * @param {Array} [options.tagName] The tag into which content will be inserted.
14741 * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space.
14742 *
14743 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`.
14744 */
14745
14746
14747 function pasteHandler(_ref) {
14748 let {
14749 HTML = '',
14750 plainText = '',
14751 mode = 'AUTO',
14752 tagName,
14753 preserveWhiteSpace
14754 } = _ref;
14755 // First of all, strip any meta tags.
14756 HTML = HTML.replace(/<meta[^>]+>/g, ''); // Strip Windows markers.
14757
14758 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, '');
14759 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); // If we detect block delimiters in HTML, parse entirely as blocks.
14760
14761 if (mode !== 'INLINE') {
14762 // Check plain text if there is no HTML.
14763 const content = HTML ? HTML : plainText;
14764
14765 if (content.indexOf('<!-- wp:') !== -1) {
14766 return parser_parse(content);
14767 }
14768 } // Normalize unicode to use composed characters.
14769 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory.
14770 // Not normalizing the content will only affect older browsers and won't
14771 // entirely break the app.
14772 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
14773 // See: https://core.trac.wordpress.org/ticket/30130
14774 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075
14775
14776
14777 if (String.prototype.normalize) {
14778 HTML = HTML.normalize();
14779 } // Parse Markdown (and encoded HTML) if:
14780 // * There is a plain text version.
14781 // * There is no HTML version, or it has no formatting.
14782
14783
14784 if (plainText && (!HTML || isPlain(HTML))) {
14785 HTML = plainText; // The markdown converter (Showdown) trims whitespace.
14786
14787 if (!/^\s+$/.test(plainText)) {
14788 HTML = markdownConverter(HTML);
14789 } // Switch to inline mode if:
14790 // * The current mode is AUTO.
14791 // * The original plain text had no line breaks.
14792 // * The original plain text was not an HTML paragraph.
14793 // * The converted text is just a paragraph.
14794
14795
14796 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) {
14797 mode = 'INLINE';
14798 }
14799 }
14800
14801 if (mode === 'INLINE') {
14802 return filterInlineHTML(HTML, preserveWhiteSpace);
14803 } // Must be run before checking if it's inline content.
14804
14805
14806 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]); // An array of HTML strings and block objects. The blocks replace matched
14807 // shortcodes.
14808
14809 const pieces = shortcode_converter(HTML); // The call to shortcodeConverter will always return more than one element
14810 // if shortcodes are matched. The reason is when shortcodes are matched
14811 // empty HTML strings are included.
14812
14813 const hasShortcodes = pieces.length > 1;
14814
14815 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) {
14816 return filterInlineHTML(HTML, preserveWhiteSpace);
14817 }
14818
14819 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste');
14820 const blockContentSchema = getBlockContentSchema('paste');
14821 const blocks = pieces.map(piece => {
14822 // Already a block from shortcode.
14823 if (typeof piece !== 'string') {
14824 return piece;
14825 }
14826
14827 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser, divNormaliser];
14828 const schema = { ...blockContentSchema,
14829 // Keep top-level phrasing content, normalised by `normaliseBlocks`.
14830 ...phrasingContentSchema
14831 };
14832 piece = deepFilterHTML(piece, filters, blockContentSchema);
14833 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema);
14834 piece = normaliseBlocks(piece);
14835 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); // Allows us to ask for this information when we get a report.
14836
14837 paste_handler_console.log('Processed HTML piece:\n\n', piece);
14838 return htmlToBlocks(piece, pasteHandler);
14839 }).flat().filter(Boolean); // If we're allowed to return inline content, and there is only one
14840 // inlineable block, and the original plain text content does not have any
14841 // line breaks, then treat it as inline paste.
14842
14843 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) {
14844 const trimRegex = /^[\n]+|[\n]+$/g; // Don't catch line breaks at the start or end.
14845
14846 const trimmedPlainText = plainText.replace(trimRegex, '');
14847
14848 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) {
14849 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema).replace(trimRegex, '');
14850 }
14851 }
14852
14853 return blocks;
14854 }
14855
14856 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/categories.js
14857 /**
14858 * WordPress dependencies
14859 */
14860
14861 /**
14862 * Internal dependencies
14863 */
14864
14865
14866 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */
14867
14868 /**
14869 * Returns all the block categories.
14870 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data.
14871 *
14872 * @ignore
14873 *
14874 * @return {WPBlockCategory[]} Block categories.
14875 */
14876
14877 function categories_getCategories() {
14878 return (0,external_wp_data_namespaceObject.select)(store).getCategories();
14879 }
14880 /**
14881 * Sets the block categories.
14882 *
14883 * @param {WPBlockCategory[]} categories Block categories.
14884 *
14885 * @example
14886 * ```js
14887 * import { __ } from '@wordpress/i18n';
14888 * import { store as blocksStore, setCategories } from '@wordpress/blocks';
14889 * import { useSelect } from '@wordpress/data';
14890 * import { Button } from '@wordpress/components';
14891 *
14892 * const ExampleComponent = () => {
14893 * // Retrieve the list of current categories.
14894 * const blockCategories = useSelect(
14895 * ( select ) => select( blocksStore ).getCategories(),
14896 * []
14897 * );
14898 *
14899 * return (
14900 * <Button
14901 * onClick={ () => {
14902 * // Add a custom category to the existing list.
14903 * setCategories( [
14904 * ...blockCategories,
14905 * { title: 'Custom Category', slug: 'custom-category' },
14906 * ] );
14907 * } }
14908 * >
14909 * { __( 'Add a new custom block category' ) }
14910 * </Button>
14911 * );
14912 * };
14913 * ```
14914 */
14915
14916 function categories_setCategories(categories) {
14917 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories);
14918 }
14919 /**
14920 * Updates a category.
14921 *
14922 * @param {string} slug Block category slug.
14923 * @param {WPBlockCategory} category Object containing the category properties
14924 * that should be updated.
14925 *
14926 * @example
14927 * ```js
14928 * import { __ } from '@wordpress/i18n';
14929 * import { updateCategory } from '@wordpress/blocks';
14930 * import { Button } from '@wordpress/components';
14931 *
14932 * const ExampleComponent = () => {
14933 * return (
14934 * <Button
14935 * onClick={ () => {
14936 * updateCategory( 'text', { title: __( 'Written Word' ) } );
14937 * } }
14938 * >
14939 * { __( 'Update Text category title' ) }
14940 * </Button>
14941 * ) ;
14942 * };
14943 * ```
14944 */
14945
14946 function categories_updateCategory(slug, category) {
14947 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category);
14948 }
14949
14950 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/templates.js
14951 /**
14952 * WordPress dependencies
14953 */
14954
14955 /**
14956 * Internal dependencies
14957 */
14958
14959
14960
14961
14962 /**
14963 * Checks whether a list of blocks matches a template by comparing the block names.
14964 *
14965 * @param {Array} blocks Block list.
14966 * @param {Array} template Block template.
14967 *
14968 * @return {boolean} Whether the list of blocks matches a templates.
14969 */
14970
14971 function doBlocksMatchTemplate() {
14972 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
14973 let template = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
14974 return blocks.length === template.length && template.every((_ref, index) => {
14975 let [name,, innerBlocksTemplate] = _ref;
14976 const block = blocks[index];
14977 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate);
14978 });
14979 }
14980 /**
14981 * Synchronize a block list with a block template.
14982 *
14983 * Synchronizing a block list with a block template means that we loop over the blocks
14984 * keep the block as is if it matches the block at the same position in the template
14985 * (If it has the same name) and if doesn't match, we create a new block based on the template.
14986 * Extra blocks not present in the template are removed.
14987 *
14988 * @param {Array} blocks Block list.
14989 * @param {Array} template Block template.
14990 *
14991 * @return {Array} Updated Block list.
14992 */
14993
14994 function synchronizeBlocksWithTemplate() {
14995 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
14996 let template = arguments.length > 1 ? arguments[1] : undefined;
14997
14998 // If no template is provided, return blocks unmodified.
14999 if (!template) {
15000 return blocks;
15001 }
15002
15003 return template.map((_ref2, index) => {
15004 var _blockType$attributes;
15005
15006 let [name, attributes, innerBlocksTemplate] = _ref2;
15007 const block = blocks[index];
15008
15009 if (block && block.name === name) {
15010 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate);
15011 return { ...block,
15012 innerBlocks
15013 };
15014 } // To support old templates that were using the "children" format
15015 // for the attributes using "html" strings now, we normalize the template attributes
15016 // before creating the blocks.
15017
15018
15019 const blockType = getBlockType(name);
15020
15021 const isHTMLAttribute = attributeDefinition => (attributeDefinition === null || attributeDefinition === void 0 ? void 0 : attributeDefinition.source) === 'html';
15022
15023 const isQueryAttribute = attributeDefinition => (attributeDefinition === null || attributeDefinition === void 0 ? void 0 : attributeDefinition.source) === 'query';
15024
15025 const normalizeAttributes = (schema, values) => {
15026 if (!values) {
15027 return {};
15028 }
15029
15030 return Object.fromEntries(Object.entries(values).map(_ref3 => {
15031 let [key, value] = _ref3;
15032 return [key, normalizeAttribute(schema[key], value)];
15033 }));
15034 };
15035
15036 const normalizeAttribute = (definition, value) => {
15037 if (isHTMLAttribute(definition) && Array.isArray(value)) {
15038 // Introduce a deprecated call at this point
15039 // When we're confident that "children" format should be removed from the templates.
15040 return (0,external_wp_element_namespaceObject.renderToString)(value);
15041 }
15042
15043 if (isQueryAttribute(definition) && value) {
15044 return value.map(subValues => {
15045 return normalizeAttributes(definition.query, subValues);
15046 });
15047 }
15048
15049 return value;
15050 };
15051
15052 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType === null || blockType === void 0 ? void 0 : blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes);
15053 let [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); // If a Block is undefined at this point, use the core/missing block as
15054 // a placeholder for a better user experience.
15055
15056 if (undefined === getBlockType(blockName)) {
15057 blockAttributes = {
15058 originalName: name,
15059 originalContent: '',
15060 originalUndelimitedContent: ''
15061 };
15062 blockName = 'core/missing';
15063 }
15064
15065 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate));
15066 });
15067 }
15068
15069 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/index.js
15070 // The blocktype is the most important concept within the block API. It defines
15071 // all aspects of the block configuration and its interfaces, including `edit`
15072 // and `save`. The transforms specification allows converting one blocktype to
15073 // another through formulas defined by either the source or the destination.
15074 // Switching a blocktype is to be considered a one-way operation implying a
15075 // transformation in the opposite way has to be handled explicitly.
15076 // The block tree is composed of a collection of block nodes. Blocks contained
15077 // within other blocks are called inner blocks. An important design
15078 // consideration is that inner blocks are -- conceptually -- not part of the
15079 // territory established by the parent block that contains them.
15080 //
15081 // This has multiple practical implications: when parsing, we can safely dispose
15082 // of any block boundary found within a block from the innerHTML property when
15083 // transfering to state. Not doing so would have a compounding effect on memory
15084 // and uncertainty over the source of truth. This can be illustrated in how,
15085 // given a tree of `n` nested blocks, the entry node would have to contain the
15086 // actual content of each block while each subsequent block node in the state
15087 // tree would replicate the entire chain `n-1`, meaning the extreme end node
15088 // would have been replicated `n` times as the tree is traversed and would
15089 // generate uncertainty as to which one is to hold the current value of the
15090 // block. For composition, it also means inner blocks can effectively be child
15091 // components whose mechanisms can be shielded from the `edit` implementation
15092 // and just passed along.
15093
15094
15095
15096 // While block transformations account for a specific surface of the API, there
15097 // are also raw transformations which handle arbitrary sources not made out of
15098 // blocks but producing block basaed on various heursitics. This includes
15099 // pasting rich text or HTML data.
15100
15101 // The process of serialization aims to deflate the internal memory of the block
15102 // editor and its state representation back into an HTML valid string. This
15103 // process restores the document integrity and inserts invisible delimiters
15104 // around each block with HTML comment boundaries which can contain any extra
15105 // attributes needed to operate with the block later on.
15106
15107 // Validation is the process of comparing a block source with its output before
15108 // there is any user input or interaction with a block. When this operation
15109 // fails -- for whatever reason -- the block is to be considered invalid. As
15110 // part of validating a block the system will attempt to run the source against
15111 // any provided deprecation definitions.
15112 //
15113 // Worth emphasizing that validation is not a case of whether the markup is
15114 // merely HTML spec-compliant but about how the editor knows to create such
15115 // markup and that its inability to create an identical result can be a strong
15116 // indicator of potential data loss (the invalidation is then a protective
15117 // measure).
15118 //
15119 // The invalidation process can also be deconstructed in phases: 1) validate the
15120 // block exists; 2) validate the source matches the output; 3) validate the
15121 // source matches deprecated outputs; 4) work through the significance of
15122 // differences. These are stacked in a way that favors performance and optimizes
15123 // for the majority of cases. That is to say, the evaluation logic can become
15124 // more sophisticated the further down it goes in the process as the cost is
15125 // accounted for. The first logic checks have to be extremely efficient since
15126 // they will be run for all valid and invalid blocks alike. However, once a
15127 // block is detected as invalid -- failing the three first steps -- it is
15128 // adequate to spend more time determining validity before throwing a conflict.
15129
15130
15131 // Blocks are inherently indifferent about where the data they operate with ends
15132 // up being saved. For example, all blocks can have a static and dynamic aspect
15133 // to them depending on the needs. The static nature of a block is the `save()`
15134 // definition that is meant to be serialized into HTML and which can be left
15135 // void. Any block can also register a `render_callback` on the server, which
15136 // makes its output dynamic either in part or in its totality.
15137 //
15138 // Child blocks are defined as a relationship that builds on top of the inner
15139 // blocks mechanism. A child block is a block node of a particular type that can
15140 // only exist within the inner block boundaries of a specific parent type. This
15141 // allows block authors to compose specific blocks that are not meant to be used
15142 // outside of a specified parent block context. Thus, child blocks extend the
15143 // concept of inner blocks to support a more direct relationship between sets of
15144 // blocks. The addition of parent–child would be a subset of the inner block
15145 // functionality under the premise that certain blocks only make sense as
15146 // children of another block.
15147
15148
15149 // Templates are, in a general sense, a basic collection of block nodes with any
15150 // given set of predefined attributes that are supplied as the initial state of
15151 // an inner blocks group. These nodes can, in turn, contain any number of nested
15152 // blocks within their definition. Templates allow both to specify a default
15153 // state for an editor session or a default set of blocks for any inner block
15154 // implementation within a specific block.
15155
15156
15157
15158
15159
15160
15161 ;// CONCATENATED MODULE: ./packages/blocks/build-module/deprecated.js
15162 /**
15163 * WordPress dependencies
15164 */
15165
15166 /**
15167 * A Higher Order Component used to inject BlockContent using context to the
15168 * wrapped component.
15169 *
15170 * @deprecated
15171 *
15172 * @param {WPComponent} OriginalComponent The component to enhance.
15173 * @return {WPComponent} The same component.
15174 */
15175
15176 function withBlockContentContext(OriginalComponent) {
15177 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', {
15178 since: '6.1'
15179 });
15180 return OriginalComponent;
15181 }
15182
15183 ;// CONCATENATED MODULE: ./packages/blocks/build-module/index.js
15184 // A "block" is the abstract term used to describe units of markup that,
15185 // when composed together, form the content or layout of a page.
15186 // The API for blocks is exposed via `wp.blocks`.
15187 //
15188 // Supported blocks are registered by calling `registerBlockType`. Once registered,
15189 // the block is made available as an option to the editor interface.
15190 //
15191 // Blocks are inferred from the HTML source of a post through a parsing mechanism
15192 // and then stored as objects in state, from which it is then rendered for editing.
15193
15194
15195
15196
15197 }();
15198 (window.wp = window.wp || {}).blocks = __webpack_exports__;
15199 /******/ })()
15200 ;