[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 1030: 5 /***/ (function(module, exports, __webpack_require__) { 6 7 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */ 8 (function(){ 9 /** 10 * Created by Tivie on 13-07-2015. 11 */ 12 13 function getDefaultOpts (simple) { 14 'use strict'; 15 16 var defaultOptions = { 17 omitExtraWLInCodeBlocks: { 18 defaultValue: false, 19 describe: 'Omit the default extra whiteline added to code blocks', 20 type: 'boolean' 21 }, 22 noHeaderId: { 23 defaultValue: false, 24 describe: 'Turn on/off generated header id', 25 type: 'boolean' 26 }, 27 prefixHeaderId: { 28 defaultValue: false, 29 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', 30 type: 'string' 31 }, 32 rawPrefixHeaderId: { 33 defaultValue: false, 34 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)', 35 type: 'boolean' 36 }, 37 ghCompatibleHeaderId: { 38 defaultValue: false, 39 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)', 40 type: 'boolean' 41 }, 42 rawHeaderId: { 43 defaultValue: false, 44 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids', 45 type: 'boolean' 46 }, 47 headerLevelStart: { 48 defaultValue: false, 49 describe: 'The header blocks level start', 50 type: 'integer' 51 }, 52 parseImgDimensions: { 53 defaultValue: false, 54 describe: 'Turn on/off image dimension parsing', 55 type: 'boolean' 56 }, 57 simplifiedAutoLink: { 58 defaultValue: false, 59 describe: 'Turn on/off GFM autolink style', 60 type: 'boolean' 61 }, 62 excludeTrailingPunctuationFromURLs: { 63 defaultValue: false, 64 describe: 'Excludes trailing punctuation from links generated with autoLinking', 65 type: 'boolean' 66 }, 67 literalMidWordUnderscores: { 68 defaultValue: false, 69 describe: 'Parse midword underscores as literal underscores', 70 type: 'boolean' 71 }, 72 literalMidWordAsterisks: { 73 defaultValue: false, 74 describe: 'Parse midword asterisks as literal asterisks', 75 type: 'boolean' 76 }, 77 strikethrough: { 78 defaultValue: false, 79 describe: 'Turn on/off strikethrough support', 80 type: 'boolean' 81 }, 82 tables: { 83 defaultValue: false, 84 describe: 'Turn on/off tables support', 85 type: 'boolean' 86 }, 87 tablesHeaderId: { 88 defaultValue: false, 89 describe: 'Add an id to table headers', 90 type: 'boolean' 91 }, 92 ghCodeBlocks: { 93 defaultValue: true, 94 describe: 'Turn on/off GFM fenced code blocks support', 95 type: 'boolean' 96 }, 97 tasklists: { 98 defaultValue: false, 99 describe: 'Turn on/off GFM tasklist support', 100 type: 'boolean' 101 }, 102 smoothLivePreview: { 103 defaultValue: false, 104 describe: 'Prevents weird effects in live previews due to incomplete input', 105 type: 'boolean' 106 }, 107 smartIndentationFix: { 108 defaultValue: false, 109 description: 'Tries to smartly fix indentation in es6 strings', 110 type: 'boolean' 111 }, 112 disableForced4SpacesIndentedSublists: { 113 defaultValue: false, 114 description: 'Disables the requirement of indenting nested sublists by 4 spaces', 115 type: 'boolean' 116 }, 117 simpleLineBreaks: { 118 defaultValue: false, 119 description: 'Parses simple line breaks as <br> (GFM Style)', 120 type: 'boolean' 121 }, 122 requireSpaceBeforeHeadingText: { 123 defaultValue: false, 124 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)', 125 type: 'boolean' 126 }, 127 ghMentions: { 128 defaultValue: false, 129 description: 'Enables github @mentions', 130 type: 'boolean' 131 }, 132 ghMentionsLink: { 133 defaultValue: 'https://github.com/{u}', 134 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.', 135 type: 'string' 136 }, 137 encodeEmails: { 138 defaultValue: true, 139 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities', 140 type: 'boolean' 141 }, 142 openLinksInNewWindow: { 143 defaultValue: false, 144 description: 'Open all links in new windows', 145 type: 'boolean' 146 }, 147 backslashEscapesHTMLTags: { 148 defaultValue: false, 149 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>', 150 type: 'boolean' 151 }, 152 emoji: { 153 defaultValue: false, 154 description: 'Enable emoji support. Ex: `this is a :smile: emoji`', 155 type: 'boolean' 156 }, 157 underline: { 158 defaultValue: false, 159 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>`', 160 type: 'boolean' 161 }, 162 completeHTMLDocument: { 163 defaultValue: false, 164 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags', 165 type: 'boolean' 166 }, 167 metadata: { 168 defaultValue: false, 169 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).', 170 type: 'boolean' 171 }, 172 splitAdjacentBlockquotes: { 173 defaultValue: false, 174 description: 'Split adjacent blockquote blocks', 175 type: 'boolean' 176 } 177 }; 178 if (simple === false) { 179 return JSON.parse(JSON.stringify(defaultOptions)); 180 } 181 var ret = {}; 182 for (var opt in defaultOptions) { 183 if (defaultOptions.hasOwnProperty(opt)) { 184 ret[opt] = defaultOptions[opt].defaultValue; 185 } 186 } 187 return ret; 188 } 189 190 function allOptionsOn () { 191 'use strict'; 192 var options = getDefaultOpts(true), 193 ret = {}; 194 for (var opt in options) { 195 if (options.hasOwnProperty(opt)) { 196 ret[opt] = true; 197 } 198 } 199 return ret; 200 } 201 202 /** 203 * Created by Tivie on 06-01-2015. 204 */ 205 206 // Private properties 207 var showdown = {}, 208 parsers = {}, 209 extensions = {}, 210 globalOptions = getDefaultOpts(true), 211 setFlavor = 'vanilla', 212 flavor = { 213 github: { 214 omitExtraWLInCodeBlocks: true, 215 simplifiedAutoLink: true, 216 excludeTrailingPunctuationFromURLs: true, 217 literalMidWordUnderscores: true, 218 strikethrough: true, 219 tables: true, 220 tablesHeaderId: true, 221 ghCodeBlocks: true, 222 tasklists: true, 223 disableForced4SpacesIndentedSublists: true, 224 simpleLineBreaks: true, 225 requireSpaceBeforeHeadingText: true, 226 ghCompatibleHeaderId: true, 227 ghMentions: true, 228 backslashEscapesHTMLTags: true, 229 emoji: true, 230 splitAdjacentBlockquotes: true 231 }, 232 original: { 233 noHeaderId: true, 234 ghCodeBlocks: false 235 }, 236 ghost: { 237 omitExtraWLInCodeBlocks: true, 238 parseImgDimensions: true, 239 simplifiedAutoLink: true, 240 excludeTrailingPunctuationFromURLs: true, 241 literalMidWordUnderscores: true, 242 strikethrough: true, 243 tables: true, 244 tablesHeaderId: true, 245 ghCodeBlocks: true, 246 tasklists: true, 247 smoothLivePreview: true, 248 simpleLineBreaks: true, 249 requireSpaceBeforeHeadingText: true, 250 ghMentions: false, 251 encodeEmails: true 252 }, 253 vanilla: getDefaultOpts(true), 254 allOn: allOptionsOn() 255 }; 256 257 /** 258 * helper namespace 259 * @type {{}} 260 */ 261 showdown.helper = {}; 262 263 /** 264 * TODO LEGACY SUPPORT CODE 265 * @type {{}} 266 */ 267 showdown.extensions = {}; 268 269 /** 270 * Set a global option 271 * @static 272 * @param {string} key 273 * @param {*} value 274 * @returns {showdown} 275 */ 276 showdown.setOption = function (key, value) { 277 'use strict'; 278 globalOptions[key] = value; 279 return this; 280 }; 281 282 /** 283 * Get a global option 284 * @static 285 * @param {string} key 286 * @returns {*} 287 */ 288 showdown.getOption = function (key) { 289 'use strict'; 290 return globalOptions[key]; 291 }; 292 293 /** 294 * Get the global options 295 * @static 296 * @returns {{}} 297 */ 298 showdown.getOptions = function () { 299 'use strict'; 300 return globalOptions; 301 }; 302 303 /** 304 * Reset global options to the default values 305 * @static 306 */ 307 showdown.resetOptions = function () { 308 'use strict'; 309 globalOptions = getDefaultOpts(true); 310 }; 311 312 /** 313 * Set the flavor showdown should use as default 314 * @param {string} name 315 */ 316 showdown.setFlavor = function (name) { 317 'use strict'; 318 if (!flavor.hasOwnProperty(name)) { 319 throw Error(name + ' flavor was not found'); 320 } 321 showdown.resetOptions(); 322 var preset = flavor[name]; 323 setFlavor = name; 324 for (var option in preset) { 325 if (preset.hasOwnProperty(option)) { 326 globalOptions[option] = preset[option]; 327 } 328 } 329 }; 330 331 /** 332 * Get the currently set flavor 333 * @returns {string} 334 */ 335 showdown.getFlavor = function () { 336 'use strict'; 337 return setFlavor; 338 }; 339 340 /** 341 * Get the options of a specified flavor. Returns undefined if the flavor was not found 342 * @param {string} name Name of the flavor 343 * @returns {{}|undefined} 344 */ 345 showdown.getFlavorOptions = function (name) { 346 'use strict'; 347 if (flavor.hasOwnProperty(name)) { 348 return flavor[name]; 349 } 350 }; 351 352 /** 353 * Get the default options 354 * @static 355 * @param {boolean} [simple=true] 356 * @returns {{}} 357 */ 358 showdown.getDefaultOptions = function (simple) { 359 'use strict'; 360 return getDefaultOpts(simple); 361 }; 362 363 /** 364 * Get or set a subParser 365 * 366 * subParser(name) - Get a registered subParser 367 * subParser(name, func) - Register a subParser 368 * @static 369 * @param {string} name 370 * @param {function} [func] 371 * @returns {*} 372 */ 373 showdown.subParser = function (name, func) { 374 'use strict'; 375 if (showdown.helper.isString(name)) { 376 if (typeof func !== 'undefined') { 377 parsers[name] = func; 378 } else { 379 if (parsers.hasOwnProperty(name)) { 380 return parsers[name]; 381 } else { 382 throw Error('SubParser named ' + name + ' not registered!'); 383 } 384 } 385 } 386 }; 387 388 /** 389 * Gets or registers an extension 390 * @static 391 * @param {string} name 392 * @param {object|function=} ext 393 * @returns {*} 394 */ 395 showdown.extension = function (name, ext) { 396 'use strict'; 397 398 if (!showdown.helper.isString(name)) { 399 throw Error('Extension \'name\' must be a string'); 400 } 401 402 name = showdown.helper.stdExtName(name); 403 404 // Getter 405 if (showdown.helper.isUndefined(ext)) { 406 if (!extensions.hasOwnProperty(name)) { 407 throw Error('Extension named ' + name + ' is not registered!'); 408 } 409 return extensions[name]; 410 411 // Setter 412 } else { 413 // Expand extension if it's wrapped in a function 414 if (typeof ext === 'function') { 415 ext = ext(); 416 } 417 418 // Ensure extension is an array 419 if (!showdown.helper.isArray(ext)) { 420 ext = [ext]; 421 } 422 423 var validExtension = validate(ext, name); 424 425 if (validExtension.valid) { 426 extensions[name] = ext; 427 } else { 428 throw Error(validExtension.error); 429 } 430 } 431 }; 432 433 /** 434 * Gets all extensions registered 435 * @returns {{}} 436 */ 437 showdown.getAllExtensions = function () { 438 'use strict'; 439 return extensions; 440 }; 441 442 /** 443 * Remove an extension 444 * @param {string} name 445 */ 446 showdown.removeExtension = function (name) { 447 'use strict'; 448 delete extensions[name]; 449 }; 450 451 /** 452 * Removes all extensions 453 */ 454 showdown.resetExtensions = function () { 455 'use strict'; 456 extensions = {}; 457 }; 458 459 /** 460 * Validate extension 461 * @param {array} extension 462 * @param {string} name 463 * @returns {{valid: boolean, error: string}} 464 */ 465 function validate (extension, name) { 466 'use strict'; 467 468 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', 469 ret = { 470 valid: true, 471 error: '' 472 }; 473 474 if (!showdown.helper.isArray(extension)) { 475 extension = [extension]; 476 } 477 478 for (var i = 0; i < extension.length; ++i) { 479 var baseMsg = errMsg + ' sub-extension ' + i + ': ', 480 ext = extension[i]; 481 if (typeof ext !== 'object') { 482 ret.valid = false; 483 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; 484 return ret; 485 } 486 487 if (!showdown.helper.isString(ext.type)) { 488 ret.valid = false; 489 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; 490 return ret; 491 } 492 493 var type = ext.type = ext.type.toLowerCase(); 494 495 // normalize extension type 496 if (type === 'language') { 497 type = ext.type = 'lang'; 498 } 499 500 if (type === 'html') { 501 type = ext.type = 'output'; 502 } 503 504 if (type !== 'lang' && type !== 'output' && type !== 'listener') { 505 ret.valid = false; 506 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; 507 return ret; 508 } 509 510 if (type === 'listener') { 511 if (showdown.helper.isUndefined(ext.listeners)) { 512 ret.valid = false; 513 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; 514 return ret; 515 } 516 } else { 517 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { 518 ret.valid = false; 519 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; 520 return ret; 521 } 522 } 523 524 if (ext.listeners) { 525 if (typeof ext.listeners !== 'object') { 526 ret.valid = false; 527 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; 528 return ret; 529 } 530 for (var ln in ext.listeners) { 531 if (ext.listeners.hasOwnProperty(ln)) { 532 if (typeof ext.listeners[ln] !== 'function') { 533 ret.valid = false; 534 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + 535 ' must be a function but ' + typeof ext.listeners[ln] + ' given'; 536 return ret; 537 } 538 } 539 } 540 } 541 542 if (ext.filter) { 543 if (typeof ext.filter !== 'function') { 544 ret.valid = false; 545 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; 546 return ret; 547 } 548 } else if (ext.regex) { 549 if (showdown.helper.isString(ext.regex)) { 550 ext.regex = new RegExp(ext.regex, 'g'); 551 } 552 if (!(ext.regex instanceof RegExp)) { 553 ret.valid = false; 554 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; 555 return ret; 556 } 557 if (showdown.helper.isUndefined(ext.replace)) { 558 ret.valid = false; 559 ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; 560 return ret; 561 } 562 } 563 } 564 return ret; 565 } 566 567 /** 568 * Validate extension 569 * @param {object} ext 570 * @returns {boolean} 571 */ 572 showdown.validateExtension = function (ext) { 573 'use strict'; 574 575 var validateExtension = validate(ext, null); 576 if (!validateExtension.valid) { 577 console.warn(validateExtension.error); 578 return false; 579 } 580 return true; 581 }; 582 583 /** 584 * showdownjs helper functions 585 */ 586 587 if (!showdown.hasOwnProperty('helper')) { 588 showdown.helper = {}; 589 } 590 591 /** 592 * Check if var is string 593 * @static 594 * @param {string} a 595 * @returns {boolean} 596 */ 597 showdown.helper.isString = function (a) { 598 'use strict'; 599 return (typeof a === 'string' || a instanceof String); 600 }; 601 602 /** 603 * Check if var is a function 604 * @static 605 * @param {*} a 606 * @returns {boolean} 607 */ 608 showdown.helper.isFunction = function (a) { 609 'use strict'; 610 var getType = {}; 611 return a && getType.toString.call(a) === '[object Function]'; 612 }; 613 614 /** 615 * isArray helper function 616 * @static 617 * @param {*} a 618 * @returns {boolean} 619 */ 620 showdown.helper.isArray = function (a) { 621 'use strict'; 622 return Array.isArray(a); 623 }; 624 625 /** 626 * Check if value is undefined 627 * @static 628 * @param {*} value The value to check. 629 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. 630 */ 631 showdown.helper.isUndefined = function (value) { 632 'use strict'; 633 return typeof value === 'undefined'; 634 }; 635 636 /** 637 * ForEach helper function 638 * Iterates over Arrays and Objects (own properties only) 639 * @static 640 * @param {*} obj 641 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object 642 */ 643 showdown.helper.forEach = function (obj, callback) { 644 'use strict'; 645 // check if obj is defined 646 if (showdown.helper.isUndefined(obj)) { 647 throw new Error('obj param is required'); 648 } 649 650 if (showdown.helper.isUndefined(callback)) { 651 throw new Error('callback param is required'); 652 } 653 654 if (!showdown.helper.isFunction(callback)) { 655 throw new Error('callback param must be a function/closure'); 656 } 657 658 if (typeof obj.forEach === 'function') { 659 obj.forEach(callback); 660 } else if (showdown.helper.isArray(obj)) { 661 for (var i = 0; i < obj.length; i++) { 662 callback(obj[i], i, obj); 663 } 664 } else if (typeof (obj) === 'object') { 665 for (var prop in obj) { 666 if (obj.hasOwnProperty(prop)) { 667 callback(obj[prop], prop, obj); 668 } 669 } 670 } else { 671 throw new Error('obj does not seem to be an array or an iterable object'); 672 } 673 }; 674 675 /** 676 * Standardidize extension name 677 * @static 678 * @param {string} s extension name 679 * @returns {string} 680 */ 681 showdown.helper.stdExtName = function (s) { 682 'use strict'; 683 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase(); 684 }; 685 686 function escapeCharactersCallback (wholeMatch, m1) { 687 'use strict'; 688 var charCodeToEscape = m1.charCodeAt(0); 689 return '¨E' + charCodeToEscape + 'E'; 690 } 691 692 /** 693 * Callback used to escape characters when passing through String.replace 694 * @static 695 * @param {string} wholeMatch 696 * @param {string} m1 697 * @returns {string} 698 */ 699 showdown.helper.escapeCharactersCallback = escapeCharactersCallback; 700 701 /** 702 * Escape characters in a string 703 * @static 704 * @param {string} text 705 * @param {string} charsToEscape 706 * @param {boolean} afterBackslash 707 * @returns {XML|string|void|*} 708 */ 709 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) { 710 'use strict'; 711 // First we have to escape the escape characters so that 712 // we can build a character class out of them 713 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; 714 715 if (afterBackslash) { 716 regexString = '\\\\' + regexString; 717 } 718 719 var regex = new RegExp(regexString, 'g'); 720 text = text.replace(regex, escapeCharactersCallback); 721 722 return text; 723 }; 724 725 /** 726 * Unescape HTML entities 727 * @param txt 728 * @returns {string} 729 */ 730 showdown.helper.unescapeHTMLEntities = function (txt) { 731 'use strict'; 732 733 return txt 734 .replace(/"/g, '"') 735 .replace(/</g, '<') 736 .replace(/>/g, '>') 737 .replace(/&/g, '&'); 738 }; 739 740 var rgxFindMatchPos = function (str, left, right, flags) { 741 'use strict'; 742 var f = flags || '', 743 g = f.indexOf('g') > -1, 744 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), 745 l = new RegExp(left, f.replace(/g/g, '')), 746 pos = [], 747 t, s, m, start, end; 748 749 do { 750 t = 0; 751 while ((m = x.exec(str))) { 752 if (l.test(m[0])) { 753 if (!(t++)) { 754 s = x.lastIndex; 755 start = s - m[0].length; 756 } 757 } else if (t) { 758 if (!--t) { 759 end = m.index + m[0].length; 760 var obj = { 761 left: {start: start, end: s}, 762 match: {start: s, end: m.index}, 763 right: {start: m.index, end: end}, 764 wholeMatch: {start: start, end: end} 765 }; 766 pos.push(obj); 767 if (!g) { 768 return pos; 769 } 770 } 771 } 772 } 773 } while (t && (x.lastIndex = s)); 774 775 return pos; 776 }; 777 778 /** 779 * matchRecursiveRegExp 780 * 781 * (c) 2007 Steven Levithan <stevenlevithan.com> 782 * MIT License 783 * 784 * Accepts a string to search, a left and right format delimiter 785 * as regex patterns, and optional regex flags. Returns an array 786 * of matches, allowing nested instances of left/right delimiters. 787 * Use the "g" flag to return all matches, otherwise only the 788 * first is returned. Be careful to ensure that the left and 789 * right format delimiters produce mutually exclusive matches. 790 * Backreferences are not supported within the right delimiter 791 * due to how it is internally combined with the left delimiter. 792 * When matching strings whose format delimiters are unbalanced 793 * to the left or right, the output is intentionally as a 794 * conventional regex library with recursion support would 795 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using 796 * "<" and ">" as the delimiters (both strings contain a single, 797 * balanced instance of "<x>"). 798 * 799 * examples: 800 * matchRecursiveRegExp("test", "\\(", "\\)") 801 * returns: [] 802 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") 803 * returns: ["t<<e>><s>", ""] 804 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") 805 * returns: ["test"] 806 */ 807 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { 808 'use strict'; 809 810 var matchPos = rgxFindMatchPos (str, left, right, flags), 811 results = []; 812 813 for (var i = 0; i < matchPos.length; ++i) { 814 results.push([ 815 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 816 str.slice(matchPos[i].match.start, matchPos[i].match.end), 817 str.slice(matchPos[i].left.start, matchPos[i].left.end), 818 str.slice(matchPos[i].right.start, matchPos[i].right.end) 819 ]); 820 } 821 return results; 822 }; 823 824 /** 825 * 826 * @param {string} str 827 * @param {string|function} replacement 828 * @param {string} left 829 * @param {string} right 830 * @param {string} flags 831 * @returns {string} 832 */ 833 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { 834 'use strict'; 835 836 if (!showdown.helper.isFunction(replacement)) { 837 var repStr = replacement; 838 replacement = function () { 839 return repStr; 840 }; 841 } 842 843 var matchPos = rgxFindMatchPos(str, left, right, flags), 844 finalStr = str, 845 lng = matchPos.length; 846 847 if (lng > 0) { 848 var bits = []; 849 if (matchPos[0].wholeMatch.start !== 0) { 850 bits.push(str.slice(0, matchPos[0].wholeMatch.start)); 851 } 852 for (var i = 0; i < lng; ++i) { 853 bits.push( 854 replacement( 855 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 856 str.slice(matchPos[i].match.start, matchPos[i].match.end), 857 str.slice(matchPos[i].left.start, matchPos[i].left.end), 858 str.slice(matchPos[i].right.start, matchPos[i].right.end) 859 ) 860 ); 861 if (i < lng - 1) { 862 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); 863 } 864 } 865 if (matchPos[lng - 1].wholeMatch.end < str.length) { 866 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); 867 } 868 finalStr = bits.join(''); 869 } 870 return finalStr; 871 }; 872 873 /** 874 * Returns the index within the passed String object of the first occurrence of the specified regex, 875 * starting the search at fromIndex. Returns -1 if the value is not found. 876 * 877 * @param {string} str string to search 878 * @param {RegExp} regex Regular expression to search 879 * @param {int} [fromIndex = 0] Index to start the search 880 * @returns {Number} 881 * @throws InvalidArgumentError 882 */ 883 showdown.helper.regexIndexOf = function (str, regex, fromIndex) { 884 'use strict'; 885 if (!showdown.helper.isString(str)) { 886 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 887 } 888 if (regex instanceof RegExp === false) { 889 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp'; 890 } 891 var indexOf = str.substring(fromIndex || 0).search(regex); 892 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf; 893 }; 894 895 /** 896 * Splits the passed string object at the defined index, and returns an array composed of the two substrings 897 * @param {string} str string to split 898 * @param {int} index index to split string at 899 * @returns {[string,string]} 900 * @throws InvalidArgumentError 901 */ 902 showdown.helper.splitAtIndex = function (str, index) { 903 'use strict'; 904 if (!showdown.helper.isString(str)) { 905 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 906 } 907 return [str.substring(0, index), str.substring(index)]; 908 }; 909 910 /** 911 * Obfuscate an e-mail address through the use of Character Entities, 912 * transforming ASCII characters into their equivalent decimal or hex entities. 913 * 914 * Since it has a random component, subsequent calls to this function produce different results 915 * 916 * @param {string} mail 917 * @returns {string} 918 */ 919 showdown.helper.encodeEmailAddress = function (mail) { 920 'use strict'; 921 var encode = [ 922 function (ch) { 923 return '&#' + ch.charCodeAt(0) + ';'; 924 }, 925 function (ch) { 926 return '&#x' + ch.charCodeAt(0).toString(16) + ';'; 927 }, 928 function (ch) { 929 return ch; 930 } 931 ]; 932 933 mail = mail.replace(/./g, function (ch) { 934 if (ch === '@') { 935 // this *must* be encoded. I insist. 936 ch = encode[Math.floor(Math.random() * 2)](ch); 937 } else { 938 var r = Math.random(); 939 // roughly 10% raw, 45% hex, 45% dec 940 ch = ( 941 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) 942 ); 943 } 944 return ch; 945 }); 946 947 return mail; 948 }; 949 950 /** 951 * 952 * @param str 953 * @param targetLength 954 * @param padString 955 * @returns {string} 956 */ 957 showdown.helper.padEnd = function padEnd (str, targetLength, padString) { 958 'use strict'; 959 /*jshint bitwise: false*/ 960 // eslint-disable-next-line space-infix-ops 961 targetLength = targetLength>>0; //floor if number or convert non-number to 0; 962 /*jshint bitwise: true*/ 963 padString = String(padString || ' '); 964 if (str.length > targetLength) { 965 return String(str); 966 } else { 967 targetLength = targetLength - str.length; 968 if (targetLength > padString.length) { 969 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 970 } 971 return String(str) + padString.slice(0,targetLength); 972 } 973 }; 974 975 /** 976 * POLYFILLS 977 */ 978 // use this instead of builtin is undefined for IE8 compatibility 979 if (typeof console === 'undefined') { 980 console = { 981 warn: function (msg) { 982 'use strict'; 983 alert(msg); 984 }, 985 log: function (msg) { 986 'use strict'; 987 alert(msg); 988 }, 989 error: function (msg) { 990 'use strict'; 991 throw msg; 992 } 993 }; 994 } 995 996 /** 997 * Common regexes. 998 * We declare some common regexes to improve performance 999 */ 1000 showdown.helper.regexes = { 1001 asteriskDashAndColon: /([*_:~])/g 1002 }; 1003 1004 /** 1005 * EMOJIS LIST 1006 */ 1007 showdown.helper.emojis = { 1008 '+1':'\ud83d\udc4d', 1009 '-1':'\ud83d\udc4e', 1010 '100':'\ud83d\udcaf', 1011 '1234':'\ud83d\udd22', 1012 '1st_place_medal':'\ud83e\udd47', 1013 '2nd_place_medal':'\ud83e\udd48', 1014 '3rd_place_medal':'\ud83e\udd49', 1015 '8ball':'\ud83c\udfb1', 1016 'a':'\ud83c\udd70\ufe0f', 1017 'ab':'\ud83c\udd8e', 1018 'abc':'\ud83d\udd24', 1019 'abcd':'\ud83d\udd21', 1020 'accept':'\ud83c\ude51', 1021 'aerial_tramway':'\ud83d\udea1', 1022 'airplane':'\u2708\ufe0f', 1023 'alarm_clock':'\u23f0', 1024 'alembic':'\u2697\ufe0f', 1025 'alien':'\ud83d\udc7d', 1026 'ambulance':'\ud83d\ude91', 1027 'amphora':'\ud83c\udffa', 1028 'anchor':'\u2693\ufe0f', 1029 'angel':'\ud83d\udc7c', 1030 'anger':'\ud83d\udca2', 1031 'angry':'\ud83d\ude20', 1032 'anguished':'\ud83d\ude27', 1033 'ant':'\ud83d\udc1c', 1034 'apple':'\ud83c\udf4e', 1035 'aquarius':'\u2652\ufe0f', 1036 'aries':'\u2648\ufe0f', 1037 'arrow_backward':'\u25c0\ufe0f', 1038 'arrow_double_down':'\u23ec', 1039 'arrow_double_up':'\u23eb', 1040 'arrow_down':'\u2b07\ufe0f', 1041 'arrow_down_small':'\ud83d\udd3d', 1042 'arrow_forward':'\u25b6\ufe0f', 1043 'arrow_heading_down':'\u2935\ufe0f', 1044 'arrow_heading_up':'\u2934\ufe0f', 1045 'arrow_left':'\u2b05\ufe0f', 1046 'arrow_lower_left':'\u2199\ufe0f', 1047 'arrow_lower_right':'\u2198\ufe0f', 1048 'arrow_right':'\u27a1\ufe0f', 1049 'arrow_right_hook':'\u21aa\ufe0f', 1050 'arrow_up':'\u2b06\ufe0f', 1051 'arrow_up_down':'\u2195\ufe0f', 1052 'arrow_up_small':'\ud83d\udd3c', 1053 'arrow_upper_left':'\u2196\ufe0f', 1054 'arrow_upper_right':'\u2197\ufe0f', 1055 'arrows_clockwise':'\ud83d\udd03', 1056 'arrows_counterclockwise':'\ud83d\udd04', 1057 'art':'\ud83c\udfa8', 1058 'articulated_lorry':'\ud83d\ude9b', 1059 'artificial_satellite':'\ud83d\udef0', 1060 'astonished':'\ud83d\ude32', 1061 'athletic_shoe':'\ud83d\udc5f', 1062 'atm':'\ud83c\udfe7', 1063 'atom_symbol':'\u269b\ufe0f', 1064 'avocado':'\ud83e\udd51', 1065 'b':'\ud83c\udd71\ufe0f', 1066 'baby':'\ud83d\udc76', 1067 'baby_bottle':'\ud83c\udf7c', 1068 'baby_chick':'\ud83d\udc24', 1069 'baby_symbol':'\ud83d\udebc', 1070 'back':'\ud83d\udd19', 1071 'bacon':'\ud83e\udd53', 1072 'badminton':'\ud83c\udff8', 1073 'baggage_claim':'\ud83d\udec4', 1074 'baguette_bread':'\ud83e\udd56', 1075 'balance_scale':'\u2696\ufe0f', 1076 'balloon':'\ud83c\udf88', 1077 'ballot_box':'\ud83d\uddf3', 1078 'ballot_box_with_check':'\u2611\ufe0f', 1079 'bamboo':'\ud83c\udf8d', 1080 'banana':'\ud83c\udf4c', 1081 'bangbang':'\u203c\ufe0f', 1082 'bank':'\ud83c\udfe6', 1083 'bar_chart':'\ud83d\udcca', 1084 'barber':'\ud83d\udc88', 1085 'baseball':'\u26be\ufe0f', 1086 'basketball':'\ud83c\udfc0', 1087 'basketball_man':'\u26f9\ufe0f', 1088 'basketball_woman':'\u26f9\ufe0f‍\u2640\ufe0f', 1089 'bat':'\ud83e\udd87', 1090 'bath':'\ud83d\udec0', 1091 'bathtub':'\ud83d\udec1', 1092 'battery':'\ud83d\udd0b', 1093 'beach_umbrella':'\ud83c\udfd6', 1094 'bear':'\ud83d\udc3b', 1095 'bed':'\ud83d\udecf', 1096 'bee':'\ud83d\udc1d', 1097 'beer':'\ud83c\udf7a', 1098 'beers':'\ud83c\udf7b', 1099 'beetle':'\ud83d\udc1e', 1100 'beginner':'\ud83d\udd30', 1101 'bell':'\ud83d\udd14', 1102 'bellhop_bell':'\ud83d\udece', 1103 'bento':'\ud83c\udf71', 1104 'biking_man':'\ud83d\udeb4', 1105 'bike':'\ud83d\udeb2', 1106 'biking_woman':'\ud83d\udeb4‍\u2640\ufe0f', 1107 'bikini':'\ud83d\udc59', 1108 'biohazard':'\u2623\ufe0f', 1109 'bird':'\ud83d\udc26', 1110 'birthday':'\ud83c\udf82', 1111 'black_circle':'\u26ab\ufe0f', 1112 'black_flag':'\ud83c\udff4', 1113 'black_heart':'\ud83d\udda4', 1114 'black_joker':'\ud83c\udccf', 1115 'black_large_square':'\u2b1b\ufe0f', 1116 'black_medium_small_square':'\u25fe\ufe0f', 1117 'black_medium_square':'\u25fc\ufe0f', 1118 'black_nib':'\u2712\ufe0f', 1119 'black_small_square':'\u25aa\ufe0f', 1120 'black_square_button':'\ud83d\udd32', 1121 'blonde_man':'\ud83d\udc71', 1122 'blonde_woman':'\ud83d\udc71‍\u2640\ufe0f', 1123 'blossom':'\ud83c\udf3c', 1124 'blowfish':'\ud83d\udc21', 1125 'blue_book':'\ud83d\udcd8', 1126 'blue_car':'\ud83d\ude99', 1127 'blue_heart':'\ud83d\udc99', 1128 'blush':'\ud83d\ude0a', 1129 'boar':'\ud83d\udc17', 1130 'boat':'\u26f5\ufe0f', 1131 'bomb':'\ud83d\udca3', 1132 'book':'\ud83d\udcd6', 1133 'bookmark':'\ud83d\udd16', 1134 'bookmark_tabs':'\ud83d\udcd1', 1135 'books':'\ud83d\udcda', 1136 'boom':'\ud83d\udca5', 1137 'boot':'\ud83d\udc62', 1138 'bouquet':'\ud83d\udc90', 1139 'bowing_man':'\ud83d\ude47', 1140 'bow_and_arrow':'\ud83c\udff9', 1141 'bowing_woman':'\ud83d\ude47‍\u2640\ufe0f', 1142 'bowling':'\ud83c\udfb3', 1143 'boxing_glove':'\ud83e\udd4a', 1144 'boy':'\ud83d\udc66', 1145 'bread':'\ud83c\udf5e', 1146 'bride_with_veil':'\ud83d\udc70', 1147 'bridge_at_night':'\ud83c\udf09', 1148 'briefcase':'\ud83d\udcbc', 1149 'broken_heart':'\ud83d\udc94', 1150 'bug':'\ud83d\udc1b', 1151 'building_construction':'\ud83c\udfd7', 1152 'bulb':'\ud83d\udca1', 1153 'bullettrain_front':'\ud83d\ude85', 1154 'bullettrain_side':'\ud83d\ude84', 1155 'burrito':'\ud83c\udf2f', 1156 'bus':'\ud83d\ude8c', 1157 'business_suit_levitating':'\ud83d\udd74', 1158 'busstop':'\ud83d\ude8f', 1159 'bust_in_silhouette':'\ud83d\udc64', 1160 'busts_in_silhouette':'\ud83d\udc65', 1161 'butterfly':'\ud83e\udd8b', 1162 'cactus':'\ud83c\udf35', 1163 'cake':'\ud83c\udf70', 1164 'calendar':'\ud83d\udcc6', 1165 'call_me_hand':'\ud83e\udd19', 1166 'calling':'\ud83d\udcf2', 1167 'camel':'\ud83d\udc2b', 1168 'camera':'\ud83d\udcf7', 1169 'camera_flash':'\ud83d\udcf8', 1170 'camping':'\ud83c\udfd5', 1171 'cancer':'\u264b\ufe0f', 1172 'candle':'\ud83d\udd6f', 1173 'candy':'\ud83c\udf6c', 1174 'canoe':'\ud83d\udef6', 1175 'capital_abcd':'\ud83d\udd20', 1176 'capricorn':'\u2651\ufe0f', 1177 'car':'\ud83d\ude97', 1178 'card_file_box':'\ud83d\uddc3', 1179 'card_index':'\ud83d\udcc7', 1180 'card_index_dividers':'\ud83d\uddc2', 1181 'carousel_horse':'\ud83c\udfa0', 1182 'carrot':'\ud83e\udd55', 1183 'cat':'\ud83d\udc31', 1184 'cat2':'\ud83d\udc08', 1185 'cd':'\ud83d\udcbf', 1186 'chains':'\u26d3', 1187 'champagne':'\ud83c\udf7e', 1188 'chart':'\ud83d\udcb9', 1189 'chart_with_downwards_trend':'\ud83d\udcc9', 1190 'chart_with_upwards_trend':'\ud83d\udcc8', 1191 'checkered_flag':'\ud83c\udfc1', 1192 'cheese':'\ud83e\uddc0', 1193 'cherries':'\ud83c\udf52', 1194 'cherry_blossom':'\ud83c\udf38', 1195 'chestnut':'\ud83c\udf30', 1196 'chicken':'\ud83d\udc14', 1197 'children_crossing':'\ud83d\udeb8', 1198 'chipmunk':'\ud83d\udc3f', 1199 'chocolate_bar':'\ud83c\udf6b', 1200 'christmas_tree':'\ud83c\udf84', 1201 'church':'\u26ea\ufe0f', 1202 'cinema':'\ud83c\udfa6', 1203 'circus_tent':'\ud83c\udfaa', 1204 'city_sunrise':'\ud83c\udf07', 1205 'city_sunset':'\ud83c\udf06', 1206 'cityscape':'\ud83c\udfd9', 1207 'cl':'\ud83c\udd91', 1208 'clamp':'\ud83d\udddc', 1209 'clap':'\ud83d\udc4f', 1210 'clapper':'\ud83c\udfac', 1211 'classical_building':'\ud83c\udfdb', 1212 'clinking_glasses':'\ud83e\udd42', 1213 'clipboard':'\ud83d\udccb', 1214 'clock1':'\ud83d\udd50', 1215 'clock10':'\ud83d\udd59', 1216 'clock1030':'\ud83d\udd65', 1217 'clock11':'\ud83d\udd5a', 1218 'clock1130':'\ud83d\udd66', 1219 'clock12':'\ud83d\udd5b', 1220 'clock1230':'\ud83d\udd67', 1221 'clock130':'\ud83d\udd5c', 1222 'clock2':'\ud83d\udd51', 1223 'clock230':'\ud83d\udd5d', 1224 'clock3':'\ud83d\udd52', 1225 'clock330':'\ud83d\udd5e', 1226 'clock4':'\ud83d\udd53', 1227 'clock430':'\ud83d\udd5f', 1228 'clock5':'\ud83d\udd54', 1229 'clock530':'\ud83d\udd60', 1230 'clock6':'\ud83d\udd55', 1231 'clock630':'\ud83d\udd61', 1232 'clock7':'\ud83d\udd56', 1233 'clock730':'\ud83d\udd62', 1234 'clock8':'\ud83d\udd57', 1235 'clock830':'\ud83d\udd63', 1236 'clock9':'\ud83d\udd58', 1237 'clock930':'\ud83d\udd64', 1238 'closed_book':'\ud83d\udcd5', 1239 'closed_lock_with_key':'\ud83d\udd10', 1240 'closed_umbrella':'\ud83c\udf02', 1241 'cloud':'\u2601\ufe0f', 1242 'cloud_with_lightning':'\ud83c\udf29', 1243 'cloud_with_lightning_and_rain':'\u26c8', 1244 'cloud_with_rain':'\ud83c\udf27', 1245 'cloud_with_snow':'\ud83c\udf28', 1246 'clown_face':'\ud83e\udd21', 1247 'clubs':'\u2663\ufe0f', 1248 'cocktail':'\ud83c\udf78', 1249 'coffee':'\u2615\ufe0f', 1250 'coffin':'\u26b0\ufe0f', 1251 'cold_sweat':'\ud83d\ude30', 1252 'comet':'\u2604\ufe0f', 1253 'computer':'\ud83d\udcbb', 1254 'computer_mouse':'\ud83d\uddb1', 1255 'confetti_ball':'\ud83c\udf8a', 1256 'confounded':'\ud83d\ude16', 1257 'confused':'\ud83d\ude15', 1258 'congratulations':'\u3297\ufe0f', 1259 'construction':'\ud83d\udea7', 1260 'construction_worker_man':'\ud83d\udc77', 1261 'construction_worker_woman':'\ud83d\udc77‍\u2640\ufe0f', 1262 'control_knobs':'\ud83c\udf9b', 1263 'convenience_store':'\ud83c\udfea', 1264 'cookie':'\ud83c\udf6a', 1265 'cool':'\ud83c\udd92', 1266 'policeman':'\ud83d\udc6e', 1267 'copyright':'\u00a9\ufe0f', 1268 'corn':'\ud83c\udf3d', 1269 'couch_and_lamp':'\ud83d\udecb', 1270 'couple':'\ud83d\udc6b', 1271 'couple_with_heart_woman_man':'\ud83d\udc91', 1272 'couple_with_heart_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc68', 1273 'couple_with_heart_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc69', 1274 'couplekiss_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc68', 1275 'couplekiss_man_woman':'\ud83d\udc8f', 1276 'couplekiss_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc69', 1277 'cow':'\ud83d\udc2e', 1278 'cow2':'\ud83d\udc04', 1279 'cowboy_hat_face':'\ud83e\udd20', 1280 'crab':'\ud83e\udd80', 1281 'crayon':'\ud83d\udd8d', 1282 'credit_card':'\ud83d\udcb3', 1283 'crescent_moon':'\ud83c\udf19', 1284 'cricket':'\ud83c\udfcf', 1285 'crocodile':'\ud83d\udc0a', 1286 'croissant':'\ud83e\udd50', 1287 'crossed_fingers':'\ud83e\udd1e', 1288 'crossed_flags':'\ud83c\udf8c', 1289 'crossed_swords':'\u2694\ufe0f', 1290 'crown':'\ud83d\udc51', 1291 'cry':'\ud83d\ude22', 1292 'crying_cat_face':'\ud83d\ude3f', 1293 'crystal_ball':'\ud83d\udd2e', 1294 'cucumber':'\ud83e\udd52', 1295 'cupid':'\ud83d\udc98', 1296 'curly_loop':'\u27b0', 1297 'currency_exchange':'\ud83d\udcb1', 1298 'curry':'\ud83c\udf5b', 1299 'custard':'\ud83c\udf6e', 1300 'customs':'\ud83d\udec3', 1301 'cyclone':'\ud83c\udf00', 1302 'dagger':'\ud83d\udde1', 1303 'dancer':'\ud83d\udc83', 1304 'dancing_women':'\ud83d\udc6f', 1305 'dancing_men':'\ud83d\udc6f‍\u2642\ufe0f', 1306 'dango':'\ud83c\udf61', 1307 'dark_sunglasses':'\ud83d\udd76', 1308 'dart':'\ud83c\udfaf', 1309 'dash':'\ud83d\udca8', 1310 'date':'\ud83d\udcc5', 1311 'deciduous_tree':'\ud83c\udf33', 1312 'deer':'\ud83e\udd8c', 1313 'department_store':'\ud83c\udfec', 1314 'derelict_house':'\ud83c\udfda', 1315 'desert':'\ud83c\udfdc', 1316 'desert_island':'\ud83c\udfdd', 1317 'desktop_computer':'\ud83d\udda5', 1318 'male_detective':'\ud83d\udd75\ufe0f', 1319 'diamond_shape_with_a_dot_inside':'\ud83d\udca0', 1320 'diamonds':'\u2666\ufe0f', 1321 'disappointed':'\ud83d\ude1e', 1322 'disappointed_relieved':'\ud83d\ude25', 1323 'dizzy':'\ud83d\udcab', 1324 'dizzy_face':'\ud83d\ude35', 1325 'do_not_litter':'\ud83d\udeaf', 1326 'dog':'\ud83d\udc36', 1327 'dog2':'\ud83d\udc15', 1328 'dollar':'\ud83d\udcb5', 1329 'dolls':'\ud83c\udf8e', 1330 'dolphin':'\ud83d\udc2c', 1331 'door':'\ud83d\udeaa', 1332 'doughnut':'\ud83c\udf69', 1333 'dove':'\ud83d\udd4a', 1334 'dragon':'\ud83d\udc09', 1335 'dragon_face':'\ud83d\udc32', 1336 'dress':'\ud83d\udc57', 1337 'dromedary_camel':'\ud83d\udc2a', 1338 'drooling_face':'\ud83e\udd24', 1339 'droplet':'\ud83d\udca7', 1340 'drum':'\ud83e\udd41', 1341 'duck':'\ud83e\udd86', 1342 'dvd':'\ud83d\udcc0', 1343 'e-mail':'\ud83d\udce7', 1344 'eagle':'\ud83e\udd85', 1345 'ear':'\ud83d\udc42', 1346 'ear_of_rice':'\ud83c\udf3e', 1347 'earth_africa':'\ud83c\udf0d', 1348 'earth_americas':'\ud83c\udf0e', 1349 'earth_asia':'\ud83c\udf0f', 1350 'egg':'\ud83e\udd5a', 1351 'eggplant':'\ud83c\udf46', 1352 'eight_pointed_black_star':'\u2734\ufe0f', 1353 'eight_spoked_asterisk':'\u2733\ufe0f', 1354 'electric_plug':'\ud83d\udd0c', 1355 'elephant':'\ud83d\udc18', 1356 'email':'\u2709\ufe0f', 1357 'end':'\ud83d\udd1a', 1358 'envelope_with_arrow':'\ud83d\udce9', 1359 'euro':'\ud83d\udcb6', 1360 'european_castle':'\ud83c\udff0', 1361 'european_post_office':'\ud83c\udfe4', 1362 'evergreen_tree':'\ud83c\udf32', 1363 'exclamation':'\u2757\ufe0f', 1364 'expressionless':'\ud83d\ude11', 1365 'eye':'\ud83d\udc41', 1366 'eye_speech_bubble':'\ud83d\udc41‍\ud83d\udde8', 1367 'eyeglasses':'\ud83d\udc53', 1368 'eyes':'\ud83d\udc40', 1369 'face_with_head_bandage':'\ud83e\udd15', 1370 'face_with_thermometer':'\ud83e\udd12', 1371 'fist_oncoming':'\ud83d\udc4a', 1372 'factory':'\ud83c\udfed', 1373 'fallen_leaf':'\ud83c\udf42', 1374 'family_man_woman_boy':'\ud83d\udc6a', 1375 'family_man_boy':'\ud83d\udc68‍\ud83d\udc66', 1376 'family_man_boy_boy':'\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1377 'family_man_girl':'\ud83d\udc68‍\ud83d\udc67', 1378 'family_man_girl_boy':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1379 'family_man_girl_girl':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1380 'family_man_man_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66', 1381 'family_man_man_boy_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1382 'family_man_man_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67', 1383 'family_man_man_girl_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1384 'family_man_man_girl_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1385 'family_man_woman_boy_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1386 'family_man_woman_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67', 1387 'family_man_woman_girl_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1388 'family_man_woman_girl_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1389 'family_woman_boy':'\ud83d\udc69‍\ud83d\udc66', 1390 'family_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1391 'family_woman_girl':'\ud83d\udc69‍\ud83d\udc67', 1392 'family_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1393 'family_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1394 'family_woman_woman_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66', 1395 'family_woman_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1396 'family_woman_woman_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67', 1397 'family_woman_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1398 'family_woman_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1399 'fast_forward':'\u23e9', 1400 'fax':'\ud83d\udce0', 1401 'fearful':'\ud83d\ude28', 1402 'feet':'\ud83d\udc3e', 1403 'female_detective':'\ud83d\udd75\ufe0f‍\u2640\ufe0f', 1404 'ferris_wheel':'\ud83c\udfa1', 1405 'ferry':'\u26f4', 1406 'field_hockey':'\ud83c\udfd1', 1407 'file_cabinet':'\ud83d\uddc4', 1408 'file_folder':'\ud83d\udcc1', 1409 'film_projector':'\ud83d\udcfd', 1410 'film_strip':'\ud83c\udf9e', 1411 'fire':'\ud83d\udd25', 1412 'fire_engine':'\ud83d\ude92', 1413 'fireworks':'\ud83c\udf86', 1414 'first_quarter_moon':'\ud83c\udf13', 1415 'first_quarter_moon_with_face':'\ud83c\udf1b', 1416 'fish':'\ud83d\udc1f', 1417 'fish_cake':'\ud83c\udf65', 1418 'fishing_pole_and_fish':'\ud83c\udfa3', 1419 'fist_raised':'\u270a', 1420 'fist_left':'\ud83e\udd1b', 1421 'fist_right':'\ud83e\udd1c', 1422 'flags':'\ud83c\udf8f', 1423 'flashlight':'\ud83d\udd26', 1424 'fleur_de_lis':'\u269c\ufe0f', 1425 'flight_arrival':'\ud83d\udeec', 1426 'flight_departure':'\ud83d\udeeb', 1427 'floppy_disk':'\ud83d\udcbe', 1428 'flower_playing_cards':'\ud83c\udfb4', 1429 'flushed':'\ud83d\ude33', 1430 'fog':'\ud83c\udf2b', 1431 'foggy':'\ud83c\udf01', 1432 'football':'\ud83c\udfc8', 1433 'footprints':'\ud83d\udc63', 1434 'fork_and_knife':'\ud83c\udf74', 1435 'fountain':'\u26f2\ufe0f', 1436 'fountain_pen':'\ud83d\udd8b', 1437 'four_leaf_clover':'\ud83c\udf40', 1438 'fox_face':'\ud83e\udd8a', 1439 'framed_picture':'\ud83d\uddbc', 1440 'free':'\ud83c\udd93', 1441 'fried_egg':'\ud83c\udf73', 1442 'fried_shrimp':'\ud83c\udf64', 1443 'fries':'\ud83c\udf5f', 1444 'frog':'\ud83d\udc38', 1445 'frowning':'\ud83d\ude26', 1446 'frowning_face':'\u2639\ufe0f', 1447 'frowning_man':'\ud83d\ude4d‍\u2642\ufe0f', 1448 'frowning_woman':'\ud83d\ude4d', 1449 'middle_finger':'\ud83d\udd95', 1450 'fuelpump':'\u26fd\ufe0f', 1451 'full_moon':'\ud83c\udf15', 1452 'full_moon_with_face':'\ud83c\udf1d', 1453 'funeral_urn':'\u26b1\ufe0f', 1454 'game_die':'\ud83c\udfb2', 1455 'gear':'\u2699\ufe0f', 1456 'gem':'\ud83d\udc8e', 1457 'gemini':'\u264a\ufe0f', 1458 'ghost':'\ud83d\udc7b', 1459 'gift':'\ud83c\udf81', 1460 'gift_heart':'\ud83d\udc9d', 1461 'girl':'\ud83d\udc67', 1462 'globe_with_meridians':'\ud83c\udf10', 1463 'goal_net':'\ud83e\udd45', 1464 'goat':'\ud83d\udc10', 1465 'golf':'\u26f3\ufe0f', 1466 'golfing_man':'\ud83c\udfcc\ufe0f', 1467 'golfing_woman':'\ud83c\udfcc\ufe0f‍\u2640\ufe0f', 1468 'gorilla':'\ud83e\udd8d', 1469 'grapes':'\ud83c\udf47', 1470 'green_apple':'\ud83c\udf4f', 1471 'green_book':'\ud83d\udcd7', 1472 'green_heart':'\ud83d\udc9a', 1473 'green_salad':'\ud83e\udd57', 1474 'grey_exclamation':'\u2755', 1475 'grey_question':'\u2754', 1476 'grimacing':'\ud83d\ude2c', 1477 'grin':'\ud83d\ude01', 1478 'grinning':'\ud83d\ude00', 1479 'guardsman':'\ud83d\udc82', 1480 'guardswoman':'\ud83d\udc82‍\u2640\ufe0f', 1481 'guitar':'\ud83c\udfb8', 1482 'gun':'\ud83d\udd2b', 1483 'haircut_woman':'\ud83d\udc87', 1484 'haircut_man':'\ud83d\udc87‍\u2642\ufe0f', 1485 'hamburger':'\ud83c\udf54', 1486 'hammer':'\ud83d\udd28', 1487 'hammer_and_pick':'\u2692', 1488 'hammer_and_wrench':'\ud83d\udee0', 1489 'hamster':'\ud83d\udc39', 1490 'hand':'\u270b', 1491 'handbag':'\ud83d\udc5c', 1492 'handshake':'\ud83e\udd1d', 1493 'hankey':'\ud83d\udca9', 1494 'hatched_chick':'\ud83d\udc25', 1495 'hatching_chick':'\ud83d\udc23', 1496 'headphones':'\ud83c\udfa7', 1497 'hear_no_evil':'\ud83d\ude49', 1498 'heart':'\u2764\ufe0f', 1499 'heart_decoration':'\ud83d\udc9f', 1500 'heart_eyes':'\ud83d\ude0d', 1501 'heart_eyes_cat':'\ud83d\ude3b', 1502 'heartbeat':'\ud83d\udc93', 1503 'heartpulse':'\ud83d\udc97', 1504 'hearts':'\u2665\ufe0f', 1505 'heavy_check_mark':'\u2714\ufe0f', 1506 'heavy_division_sign':'\u2797', 1507 'heavy_dollar_sign':'\ud83d\udcb2', 1508 'heavy_heart_exclamation':'\u2763\ufe0f', 1509 'heavy_minus_sign':'\u2796', 1510 'heavy_multiplication_x':'\u2716\ufe0f', 1511 'heavy_plus_sign':'\u2795', 1512 'helicopter':'\ud83d\ude81', 1513 'herb':'\ud83c\udf3f', 1514 'hibiscus':'\ud83c\udf3a', 1515 'high_brightness':'\ud83d\udd06', 1516 'high_heel':'\ud83d\udc60', 1517 'hocho':'\ud83d\udd2a', 1518 'hole':'\ud83d\udd73', 1519 'honey_pot':'\ud83c\udf6f', 1520 'horse':'\ud83d\udc34', 1521 'horse_racing':'\ud83c\udfc7', 1522 'hospital':'\ud83c\udfe5', 1523 'hot_pepper':'\ud83c\udf36', 1524 'hotdog':'\ud83c\udf2d', 1525 'hotel':'\ud83c\udfe8', 1526 'hotsprings':'\u2668\ufe0f', 1527 'hourglass':'\u231b\ufe0f', 1528 'hourglass_flowing_sand':'\u23f3', 1529 'house':'\ud83c\udfe0', 1530 'house_with_garden':'\ud83c\udfe1', 1531 'houses':'\ud83c\udfd8', 1532 'hugs':'\ud83e\udd17', 1533 'hushed':'\ud83d\ude2f', 1534 'ice_cream':'\ud83c\udf68', 1535 'ice_hockey':'\ud83c\udfd2', 1536 'ice_skate':'\u26f8', 1537 'icecream':'\ud83c\udf66', 1538 'id':'\ud83c\udd94', 1539 'ideograph_advantage':'\ud83c\ude50', 1540 'imp':'\ud83d\udc7f', 1541 'inbox_tray':'\ud83d\udce5', 1542 'incoming_envelope':'\ud83d\udce8', 1543 'tipping_hand_woman':'\ud83d\udc81', 1544 'information_source':'\u2139\ufe0f', 1545 'innocent':'\ud83d\ude07', 1546 'interrobang':'\u2049\ufe0f', 1547 'iphone':'\ud83d\udcf1', 1548 'izakaya_lantern':'\ud83c\udfee', 1549 'jack_o_lantern':'\ud83c\udf83', 1550 'japan':'\ud83d\uddfe', 1551 'japanese_castle':'\ud83c\udfef', 1552 'japanese_goblin':'\ud83d\udc7a', 1553 'japanese_ogre':'\ud83d\udc79', 1554 'jeans':'\ud83d\udc56', 1555 'joy':'\ud83d\ude02', 1556 'joy_cat':'\ud83d\ude39', 1557 'joystick':'\ud83d\udd79', 1558 'kaaba':'\ud83d\udd4b', 1559 'key':'\ud83d\udd11', 1560 'keyboard':'\u2328\ufe0f', 1561 'keycap_ten':'\ud83d\udd1f', 1562 'kick_scooter':'\ud83d\udef4', 1563 'kimono':'\ud83d\udc58', 1564 'kiss':'\ud83d\udc8b', 1565 'kissing':'\ud83d\ude17', 1566 'kissing_cat':'\ud83d\ude3d', 1567 'kissing_closed_eyes':'\ud83d\ude1a', 1568 'kissing_heart':'\ud83d\ude18', 1569 'kissing_smiling_eyes':'\ud83d\ude19', 1570 'kiwi_fruit':'\ud83e\udd5d', 1571 'koala':'\ud83d\udc28', 1572 'koko':'\ud83c\ude01', 1573 'label':'\ud83c\udff7', 1574 'large_blue_circle':'\ud83d\udd35', 1575 'large_blue_diamond':'\ud83d\udd37', 1576 'large_orange_diamond':'\ud83d\udd36', 1577 'last_quarter_moon':'\ud83c\udf17', 1578 'last_quarter_moon_with_face':'\ud83c\udf1c', 1579 'latin_cross':'\u271d\ufe0f', 1580 'laughing':'\ud83d\ude06', 1581 'leaves':'\ud83c\udf43', 1582 'ledger':'\ud83d\udcd2', 1583 'left_luggage':'\ud83d\udec5', 1584 'left_right_arrow':'\u2194\ufe0f', 1585 'leftwards_arrow_with_hook':'\u21a9\ufe0f', 1586 'lemon':'\ud83c\udf4b', 1587 'leo':'\u264c\ufe0f', 1588 'leopard':'\ud83d\udc06', 1589 'level_slider':'\ud83c\udf9a', 1590 'libra':'\u264e\ufe0f', 1591 'light_rail':'\ud83d\ude88', 1592 'link':'\ud83d\udd17', 1593 'lion':'\ud83e\udd81', 1594 'lips':'\ud83d\udc44', 1595 'lipstick':'\ud83d\udc84', 1596 'lizard':'\ud83e\udd8e', 1597 'lock':'\ud83d\udd12', 1598 'lock_with_ink_pen':'\ud83d\udd0f', 1599 'lollipop':'\ud83c\udf6d', 1600 'loop':'\u27bf', 1601 'loud_sound':'\ud83d\udd0a', 1602 'loudspeaker':'\ud83d\udce2', 1603 'love_hotel':'\ud83c\udfe9', 1604 'love_letter':'\ud83d\udc8c', 1605 'low_brightness':'\ud83d\udd05', 1606 'lying_face':'\ud83e\udd25', 1607 'm':'\u24c2\ufe0f', 1608 'mag':'\ud83d\udd0d', 1609 'mag_right':'\ud83d\udd0e', 1610 'mahjong':'\ud83c\udc04\ufe0f', 1611 'mailbox':'\ud83d\udceb', 1612 'mailbox_closed':'\ud83d\udcea', 1613 'mailbox_with_mail':'\ud83d\udcec', 1614 'mailbox_with_no_mail':'\ud83d\udced', 1615 'man':'\ud83d\udc68', 1616 'man_artist':'\ud83d\udc68‍\ud83c\udfa8', 1617 'man_astronaut':'\ud83d\udc68‍\ud83d\ude80', 1618 'man_cartwheeling':'\ud83e\udd38‍\u2642\ufe0f', 1619 'man_cook':'\ud83d\udc68‍\ud83c\udf73', 1620 'man_dancing':'\ud83d\udd7a', 1621 'man_facepalming':'\ud83e\udd26‍\u2642\ufe0f', 1622 'man_factory_worker':'\ud83d\udc68‍\ud83c\udfed', 1623 'man_farmer':'\ud83d\udc68‍\ud83c\udf3e', 1624 'man_firefighter':'\ud83d\udc68‍\ud83d\ude92', 1625 'man_health_worker':'\ud83d\udc68‍\u2695\ufe0f', 1626 'man_in_tuxedo':'\ud83e\udd35', 1627 'man_judge':'\ud83d\udc68‍\u2696\ufe0f', 1628 'man_juggling':'\ud83e\udd39‍\u2642\ufe0f', 1629 'man_mechanic':'\ud83d\udc68‍\ud83d\udd27', 1630 'man_office_worker':'\ud83d\udc68‍\ud83d\udcbc', 1631 'man_pilot':'\ud83d\udc68‍\u2708\ufe0f', 1632 'man_playing_handball':'\ud83e\udd3e‍\u2642\ufe0f', 1633 'man_playing_water_polo':'\ud83e\udd3d‍\u2642\ufe0f', 1634 'man_scientist':'\ud83d\udc68‍\ud83d\udd2c', 1635 'man_shrugging':'\ud83e\udd37‍\u2642\ufe0f', 1636 'man_singer':'\ud83d\udc68‍\ud83c\udfa4', 1637 'man_student':'\ud83d\udc68‍\ud83c\udf93', 1638 'man_teacher':'\ud83d\udc68‍\ud83c\udfeb', 1639 'man_technologist':'\ud83d\udc68‍\ud83d\udcbb', 1640 'man_with_gua_pi_mao':'\ud83d\udc72', 1641 'man_with_turban':'\ud83d\udc73', 1642 'tangerine':'\ud83c\udf4a', 1643 'mans_shoe':'\ud83d\udc5e', 1644 'mantelpiece_clock':'\ud83d\udd70', 1645 'maple_leaf':'\ud83c\udf41', 1646 'martial_arts_uniform':'\ud83e\udd4b', 1647 'mask':'\ud83d\ude37', 1648 'massage_woman':'\ud83d\udc86', 1649 'massage_man':'\ud83d\udc86‍\u2642\ufe0f', 1650 'meat_on_bone':'\ud83c\udf56', 1651 'medal_military':'\ud83c\udf96', 1652 'medal_sports':'\ud83c\udfc5', 1653 'mega':'\ud83d\udce3', 1654 'melon':'\ud83c\udf48', 1655 'memo':'\ud83d\udcdd', 1656 'men_wrestling':'\ud83e\udd3c‍\u2642\ufe0f', 1657 'menorah':'\ud83d\udd4e', 1658 'mens':'\ud83d\udeb9', 1659 'metal':'\ud83e\udd18', 1660 'metro':'\ud83d\ude87', 1661 'microphone':'\ud83c\udfa4', 1662 'microscope':'\ud83d\udd2c', 1663 'milk_glass':'\ud83e\udd5b', 1664 'milky_way':'\ud83c\udf0c', 1665 'minibus':'\ud83d\ude90', 1666 'minidisc':'\ud83d\udcbd', 1667 'mobile_phone_off':'\ud83d\udcf4', 1668 'money_mouth_face':'\ud83e\udd11', 1669 'money_with_wings':'\ud83d\udcb8', 1670 'moneybag':'\ud83d\udcb0', 1671 'monkey':'\ud83d\udc12', 1672 'monkey_face':'\ud83d\udc35', 1673 'monorail':'\ud83d\ude9d', 1674 'moon':'\ud83c\udf14', 1675 'mortar_board':'\ud83c\udf93', 1676 'mosque':'\ud83d\udd4c', 1677 'motor_boat':'\ud83d\udee5', 1678 'motor_scooter':'\ud83d\udef5', 1679 'motorcycle':'\ud83c\udfcd', 1680 'motorway':'\ud83d\udee3', 1681 'mount_fuji':'\ud83d\uddfb', 1682 'mountain':'\u26f0', 1683 'mountain_biking_man':'\ud83d\udeb5', 1684 'mountain_biking_woman':'\ud83d\udeb5‍\u2640\ufe0f', 1685 'mountain_cableway':'\ud83d\udea0', 1686 'mountain_railway':'\ud83d\ude9e', 1687 'mountain_snow':'\ud83c\udfd4', 1688 'mouse':'\ud83d\udc2d', 1689 'mouse2':'\ud83d\udc01', 1690 'movie_camera':'\ud83c\udfa5', 1691 'moyai':'\ud83d\uddff', 1692 'mrs_claus':'\ud83e\udd36', 1693 'muscle':'\ud83d\udcaa', 1694 'mushroom':'\ud83c\udf44', 1695 'musical_keyboard':'\ud83c\udfb9', 1696 'musical_note':'\ud83c\udfb5', 1697 'musical_score':'\ud83c\udfbc', 1698 'mute':'\ud83d\udd07', 1699 'nail_care':'\ud83d\udc85', 1700 'name_badge':'\ud83d\udcdb', 1701 'national_park':'\ud83c\udfde', 1702 'nauseated_face':'\ud83e\udd22', 1703 'necktie':'\ud83d\udc54', 1704 'negative_squared_cross_mark':'\u274e', 1705 'nerd_face':'\ud83e\udd13', 1706 'neutral_face':'\ud83d\ude10', 1707 'new':'\ud83c\udd95', 1708 'new_moon':'\ud83c\udf11', 1709 'new_moon_with_face':'\ud83c\udf1a', 1710 'newspaper':'\ud83d\udcf0', 1711 'newspaper_roll':'\ud83d\uddde', 1712 'next_track_button':'\u23ed', 1713 'ng':'\ud83c\udd96', 1714 'no_good_man':'\ud83d\ude45‍\u2642\ufe0f', 1715 'no_good_woman':'\ud83d\ude45', 1716 'night_with_stars':'\ud83c\udf03', 1717 'no_bell':'\ud83d\udd15', 1718 'no_bicycles':'\ud83d\udeb3', 1719 'no_entry':'\u26d4\ufe0f', 1720 'no_entry_sign':'\ud83d\udeab', 1721 'no_mobile_phones':'\ud83d\udcf5', 1722 'no_mouth':'\ud83d\ude36', 1723 'no_pedestrians':'\ud83d\udeb7', 1724 'no_smoking':'\ud83d\udead', 1725 'non-potable_water':'\ud83d\udeb1', 1726 'nose':'\ud83d\udc43', 1727 'notebook':'\ud83d\udcd3', 1728 'notebook_with_decorative_cover':'\ud83d\udcd4', 1729 'notes':'\ud83c\udfb6', 1730 'nut_and_bolt':'\ud83d\udd29', 1731 'o':'\u2b55\ufe0f', 1732 'o2':'\ud83c\udd7e\ufe0f', 1733 'ocean':'\ud83c\udf0a', 1734 'octopus':'\ud83d\udc19', 1735 'oden':'\ud83c\udf62', 1736 'office':'\ud83c\udfe2', 1737 'oil_drum':'\ud83d\udee2', 1738 'ok':'\ud83c\udd97', 1739 'ok_hand':'\ud83d\udc4c', 1740 'ok_man':'\ud83d\ude46‍\u2642\ufe0f', 1741 'ok_woman':'\ud83d\ude46', 1742 'old_key':'\ud83d\udddd', 1743 'older_man':'\ud83d\udc74', 1744 'older_woman':'\ud83d\udc75', 1745 'om':'\ud83d\udd49', 1746 'on':'\ud83d\udd1b', 1747 'oncoming_automobile':'\ud83d\ude98', 1748 'oncoming_bus':'\ud83d\ude8d', 1749 'oncoming_police_car':'\ud83d\ude94', 1750 'oncoming_taxi':'\ud83d\ude96', 1751 'open_file_folder':'\ud83d\udcc2', 1752 'open_hands':'\ud83d\udc50', 1753 'open_mouth':'\ud83d\ude2e', 1754 'open_umbrella':'\u2602\ufe0f', 1755 'ophiuchus':'\u26ce', 1756 'orange_book':'\ud83d\udcd9', 1757 'orthodox_cross':'\u2626\ufe0f', 1758 'outbox_tray':'\ud83d\udce4', 1759 'owl':'\ud83e\udd89', 1760 'ox':'\ud83d\udc02', 1761 'package':'\ud83d\udce6', 1762 'page_facing_up':'\ud83d\udcc4', 1763 'page_with_curl':'\ud83d\udcc3', 1764 'pager':'\ud83d\udcdf', 1765 'paintbrush':'\ud83d\udd8c', 1766 'palm_tree':'\ud83c\udf34', 1767 'pancakes':'\ud83e\udd5e', 1768 'panda_face':'\ud83d\udc3c', 1769 'paperclip':'\ud83d\udcce', 1770 'paperclips':'\ud83d\udd87', 1771 'parasol_on_ground':'\u26f1', 1772 'parking':'\ud83c\udd7f\ufe0f', 1773 'part_alternation_mark':'\u303d\ufe0f', 1774 'partly_sunny':'\u26c5\ufe0f', 1775 'passenger_ship':'\ud83d\udef3', 1776 'passport_control':'\ud83d\udec2', 1777 'pause_button':'\u23f8', 1778 'peace_symbol':'\u262e\ufe0f', 1779 'peach':'\ud83c\udf51', 1780 'peanuts':'\ud83e\udd5c', 1781 'pear':'\ud83c\udf50', 1782 'pen':'\ud83d\udd8a', 1783 'pencil2':'\u270f\ufe0f', 1784 'penguin':'\ud83d\udc27', 1785 'pensive':'\ud83d\ude14', 1786 'performing_arts':'\ud83c\udfad', 1787 'persevere':'\ud83d\ude23', 1788 'person_fencing':'\ud83e\udd3a', 1789 'pouting_woman':'\ud83d\ude4e', 1790 'phone':'\u260e\ufe0f', 1791 'pick':'\u26cf', 1792 'pig':'\ud83d\udc37', 1793 'pig2':'\ud83d\udc16', 1794 'pig_nose':'\ud83d\udc3d', 1795 'pill':'\ud83d\udc8a', 1796 'pineapple':'\ud83c\udf4d', 1797 'ping_pong':'\ud83c\udfd3', 1798 'pisces':'\u2653\ufe0f', 1799 'pizza':'\ud83c\udf55', 1800 'place_of_worship':'\ud83d\uded0', 1801 'plate_with_cutlery':'\ud83c\udf7d', 1802 'play_or_pause_button':'\u23ef', 1803 'point_down':'\ud83d\udc47', 1804 'point_left':'\ud83d\udc48', 1805 'point_right':'\ud83d\udc49', 1806 'point_up':'\u261d\ufe0f', 1807 'point_up_2':'\ud83d\udc46', 1808 'police_car':'\ud83d\ude93', 1809 'policewoman':'\ud83d\udc6e‍\u2640\ufe0f', 1810 'poodle':'\ud83d\udc29', 1811 'popcorn':'\ud83c\udf7f', 1812 'post_office':'\ud83c\udfe3', 1813 'postal_horn':'\ud83d\udcef', 1814 'postbox':'\ud83d\udcee', 1815 'potable_water':'\ud83d\udeb0', 1816 'potato':'\ud83e\udd54', 1817 'pouch':'\ud83d\udc5d', 1818 'poultry_leg':'\ud83c\udf57', 1819 'pound':'\ud83d\udcb7', 1820 'rage':'\ud83d\ude21', 1821 'pouting_cat':'\ud83d\ude3e', 1822 'pouting_man':'\ud83d\ude4e‍\u2642\ufe0f', 1823 'pray':'\ud83d\ude4f', 1824 'prayer_beads':'\ud83d\udcff', 1825 'pregnant_woman':'\ud83e\udd30', 1826 'previous_track_button':'\u23ee', 1827 'prince':'\ud83e\udd34', 1828 'princess':'\ud83d\udc78', 1829 'printer':'\ud83d\udda8', 1830 'purple_heart':'\ud83d\udc9c', 1831 'purse':'\ud83d\udc5b', 1832 'pushpin':'\ud83d\udccc', 1833 'put_litter_in_its_place':'\ud83d\udeae', 1834 'question':'\u2753', 1835 'rabbit':'\ud83d\udc30', 1836 'rabbit2':'\ud83d\udc07', 1837 'racehorse':'\ud83d\udc0e', 1838 'racing_car':'\ud83c\udfce', 1839 'radio':'\ud83d\udcfb', 1840 'radio_button':'\ud83d\udd18', 1841 'radioactive':'\u2622\ufe0f', 1842 'railway_car':'\ud83d\ude83', 1843 'railway_track':'\ud83d\udee4', 1844 'rainbow':'\ud83c\udf08', 1845 'rainbow_flag':'\ud83c\udff3\ufe0f‍\ud83c\udf08', 1846 'raised_back_of_hand':'\ud83e\udd1a', 1847 'raised_hand_with_fingers_splayed':'\ud83d\udd90', 1848 'raised_hands':'\ud83d\ude4c', 1849 'raising_hand_woman':'\ud83d\ude4b', 1850 'raising_hand_man':'\ud83d\ude4b‍\u2642\ufe0f', 1851 'ram':'\ud83d\udc0f', 1852 'ramen':'\ud83c\udf5c', 1853 'rat':'\ud83d\udc00', 1854 'record_button':'\u23fa', 1855 'recycle':'\u267b\ufe0f', 1856 'red_circle':'\ud83d\udd34', 1857 'registered':'\u00ae\ufe0f', 1858 'relaxed':'\u263a\ufe0f', 1859 'relieved':'\ud83d\ude0c', 1860 'reminder_ribbon':'\ud83c\udf97', 1861 'repeat':'\ud83d\udd01', 1862 'repeat_one':'\ud83d\udd02', 1863 'rescue_worker_helmet':'\u26d1', 1864 'restroom':'\ud83d\udebb', 1865 'revolving_hearts':'\ud83d\udc9e', 1866 'rewind':'\u23ea', 1867 'rhinoceros':'\ud83e\udd8f', 1868 'ribbon':'\ud83c\udf80', 1869 'rice':'\ud83c\udf5a', 1870 'rice_ball':'\ud83c\udf59', 1871 'rice_cracker':'\ud83c\udf58', 1872 'rice_scene':'\ud83c\udf91', 1873 'right_anger_bubble':'\ud83d\uddef', 1874 'ring':'\ud83d\udc8d', 1875 'robot':'\ud83e\udd16', 1876 'rocket':'\ud83d\ude80', 1877 'rofl':'\ud83e\udd23', 1878 'roll_eyes':'\ud83d\ude44', 1879 'roller_coaster':'\ud83c\udfa2', 1880 'rooster':'\ud83d\udc13', 1881 'rose':'\ud83c\udf39', 1882 'rosette':'\ud83c\udff5', 1883 'rotating_light':'\ud83d\udea8', 1884 'round_pushpin':'\ud83d\udccd', 1885 'rowing_man':'\ud83d\udea3', 1886 'rowing_woman':'\ud83d\udea3‍\u2640\ufe0f', 1887 'rugby_football':'\ud83c\udfc9', 1888 'running_man':'\ud83c\udfc3', 1889 'running_shirt_with_sash':'\ud83c\udfbd', 1890 'running_woman':'\ud83c\udfc3‍\u2640\ufe0f', 1891 'sa':'\ud83c\ude02\ufe0f', 1892 'sagittarius':'\u2650\ufe0f', 1893 'sake':'\ud83c\udf76', 1894 'sandal':'\ud83d\udc61', 1895 'santa':'\ud83c\udf85', 1896 'satellite':'\ud83d\udce1', 1897 'saxophone':'\ud83c\udfb7', 1898 'school':'\ud83c\udfeb', 1899 'school_satchel':'\ud83c\udf92', 1900 'scissors':'\u2702\ufe0f', 1901 'scorpion':'\ud83e\udd82', 1902 'scorpius':'\u264f\ufe0f', 1903 'scream':'\ud83d\ude31', 1904 'scream_cat':'\ud83d\ude40', 1905 'scroll':'\ud83d\udcdc', 1906 'seat':'\ud83d\udcba', 1907 'secret':'\u3299\ufe0f', 1908 'see_no_evil':'\ud83d\ude48', 1909 'seedling':'\ud83c\udf31', 1910 'selfie':'\ud83e\udd33', 1911 'shallow_pan_of_food':'\ud83e\udd58', 1912 'shamrock':'\u2618\ufe0f', 1913 'shark':'\ud83e\udd88', 1914 'shaved_ice':'\ud83c\udf67', 1915 'sheep':'\ud83d\udc11', 1916 'shell':'\ud83d\udc1a', 1917 'shield':'\ud83d\udee1', 1918 'shinto_shrine':'\u26e9', 1919 'ship':'\ud83d\udea2', 1920 'shirt':'\ud83d\udc55', 1921 'shopping':'\ud83d\udecd', 1922 'shopping_cart':'\ud83d\uded2', 1923 'shower':'\ud83d\udebf', 1924 'shrimp':'\ud83e\udd90', 1925 'signal_strength':'\ud83d\udcf6', 1926 'six_pointed_star':'\ud83d\udd2f', 1927 'ski':'\ud83c\udfbf', 1928 'skier':'\u26f7', 1929 'skull':'\ud83d\udc80', 1930 'skull_and_crossbones':'\u2620\ufe0f', 1931 'sleeping':'\ud83d\ude34', 1932 'sleeping_bed':'\ud83d\udecc', 1933 'sleepy':'\ud83d\ude2a', 1934 'slightly_frowning_face':'\ud83d\ude41', 1935 'slightly_smiling_face':'\ud83d\ude42', 1936 'slot_machine':'\ud83c\udfb0', 1937 'small_airplane':'\ud83d\udee9', 1938 'small_blue_diamond':'\ud83d\udd39', 1939 'small_orange_diamond':'\ud83d\udd38', 1940 'small_red_triangle':'\ud83d\udd3a', 1941 'small_red_triangle_down':'\ud83d\udd3b', 1942 'smile':'\ud83d\ude04', 1943 'smile_cat':'\ud83d\ude38', 1944 'smiley':'\ud83d\ude03', 1945 'smiley_cat':'\ud83d\ude3a', 1946 'smiling_imp':'\ud83d\ude08', 1947 'smirk':'\ud83d\ude0f', 1948 'smirk_cat':'\ud83d\ude3c', 1949 'smoking':'\ud83d\udeac', 1950 'snail':'\ud83d\udc0c', 1951 'snake':'\ud83d\udc0d', 1952 'sneezing_face':'\ud83e\udd27', 1953 'snowboarder':'\ud83c\udfc2', 1954 'snowflake':'\u2744\ufe0f', 1955 'snowman':'\u26c4\ufe0f', 1956 'snowman_with_snow':'\u2603\ufe0f', 1957 'sob':'\ud83d\ude2d', 1958 'soccer':'\u26bd\ufe0f', 1959 'soon':'\ud83d\udd1c', 1960 'sos':'\ud83c\udd98', 1961 'sound':'\ud83d\udd09', 1962 'space_invader':'\ud83d\udc7e', 1963 'spades':'\u2660\ufe0f', 1964 'spaghetti':'\ud83c\udf5d', 1965 'sparkle':'\u2747\ufe0f', 1966 'sparkler':'\ud83c\udf87', 1967 'sparkles':'\u2728', 1968 'sparkling_heart':'\ud83d\udc96', 1969 'speak_no_evil':'\ud83d\ude4a', 1970 'speaker':'\ud83d\udd08', 1971 'speaking_head':'\ud83d\udde3', 1972 'speech_balloon':'\ud83d\udcac', 1973 'speedboat':'\ud83d\udea4', 1974 'spider':'\ud83d\udd77', 1975 'spider_web':'\ud83d\udd78', 1976 'spiral_calendar':'\ud83d\uddd3', 1977 'spiral_notepad':'\ud83d\uddd2', 1978 'spoon':'\ud83e\udd44', 1979 'squid':'\ud83e\udd91', 1980 'stadium':'\ud83c\udfdf', 1981 'star':'\u2b50\ufe0f', 1982 'star2':'\ud83c\udf1f', 1983 'star_and_crescent':'\u262a\ufe0f', 1984 'star_of_david':'\u2721\ufe0f', 1985 'stars':'\ud83c\udf20', 1986 'station':'\ud83d\ude89', 1987 'statue_of_liberty':'\ud83d\uddfd', 1988 'steam_locomotive':'\ud83d\ude82', 1989 'stew':'\ud83c\udf72', 1990 'stop_button':'\u23f9', 1991 'stop_sign':'\ud83d\uded1', 1992 'stopwatch':'\u23f1', 1993 'straight_ruler':'\ud83d\udccf', 1994 'strawberry':'\ud83c\udf53', 1995 'stuck_out_tongue':'\ud83d\ude1b', 1996 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d', 1997 'stuck_out_tongue_winking_eye':'\ud83d\ude1c', 1998 'studio_microphone':'\ud83c\udf99', 1999 'stuffed_flatbread':'\ud83e\udd59', 2000 'sun_behind_large_cloud':'\ud83c\udf25', 2001 'sun_behind_rain_cloud':'\ud83c\udf26', 2002 'sun_behind_small_cloud':'\ud83c\udf24', 2003 'sun_with_face':'\ud83c\udf1e', 2004 'sunflower':'\ud83c\udf3b', 2005 'sunglasses':'\ud83d\ude0e', 2006 'sunny':'\u2600\ufe0f', 2007 'sunrise':'\ud83c\udf05', 2008 'sunrise_over_mountains':'\ud83c\udf04', 2009 'surfing_man':'\ud83c\udfc4', 2010 'surfing_woman':'\ud83c\udfc4‍\u2640\ufe0f', 2011 'sushi':'\ud83c\udf63', 2012 'suspension_railway':'\ud83d\ude9f', 2013 'sweat':'\ud83d\ude13', 2014 'sweat_drops':'\ud83d\udca6', 2015 'sweat_smile':'\ud83d\ude05', 2016 'sweet_potato':'\ud83c\udf60', 2017 'swimming_man':'\ud83c\udfca', 2018 'swimming_woman':'\ud83c\udfca‍\u2640\ufe0f', 2019 'symbols':'\ud83d\udd23', 2020 'synagogue':'\ud83d\udd4d', 2021 'syringe':'\ud83d\udc89', 2022 'taco':'\ud83c\udf2e', 2023 'tada':'\ud83c\udf89', 2024 'tanabata_tree':'\ud83c\udf8b', 2025 'taurus':'\u2649\ufe0f', 2026 'taxi':'\ud83d\ude95', 2027 'tea':'\ud83c\udf75', 2028 'telephone_receiver':'\ud83d\udcde', 2029 'telescope':'\ud83d\udd2d', 2030 'tennis':'\ud83c\udfbe', 2031 'tent':'\u26fa\ufe0f', 2032 'thermometer':'\ud83c\udf21', 2033 'thinking':'\ud83e\udd14', 2034 'thought_balloon':'\ud83d\udcad', 2035 'ticket':'\ud83c\udfab', 2036 'tickets':'\ud83c\udf9f', 2037 'tiger':'\ud83d\udc2f', 2038 'tiger2':'\ud83d\udc05', 2039 'timer_clock':'\u23f2', 2040 'tipping_hand_man':'\ud83d\udc81‍\u2642\ufe0f', 2041 'tired_face':'\ud83d\ude2b', 2042 'tm':'\u2122\ufe0f', 2043 'toilet':'\ud83d\udebd', 2044 'tokyo_tower':'\ud83d\uddfc', 2045 'tomato':'\ud83c\udf45', 2046 'tongue':'\ud83d\udc45', 2047 'top':'\ud83d\udd1d', 2048 'tophat':'\ud83c\udfa9', 2049 'tornado':'\ud83c\udf2a', 2050 'trackball':'\ud83d\uddb2', 2051 'tractor':'\ud83d\ude9c', 2052 'traffic_light':'\ud83d\udea5', 2053 'train':'\ud83d\ude8b', 2054 'train2':'\ud83d\ude86', 2055 'tram':'\ud83d\ude8a', 2056 'triangular_flag_on_post':'\ud83d\udea9', 2057 'triangular_ruler':'\ud83d\udcd0', 2058 'trident':'\ud83d\udd31', 2059 'triumph':'\ud83d\ude24', 2060 'trolleybus':'\ud83d\ude8e', 2061 'trophy':'\ud83c\udfc6', 2062 'tropical_drink':'\ud83c\udf79', 2063 'tropical_fish':'\ud83d\udc20', 2064 'truck':'\ud83d\ude9a', 2065 'trumpet':'\ud83c\udfba', 2066 'tulip':'\ud83c\udf37', 2067 'tumbler_glass':'\ud83e\udd43', 2068 'turkey':'\ud83e\udd83', 2069 'turtle':'\ud83d\udc22', 2070 'tv':'\ud83d\udcfa', 2071 'twisted_rightwards_arrows':'\ud83d\udd00', 2072 'two_hearts':'\ud83d\udc95', 2073 'two_men_holding_hands':'\ud83d\udc6c', 2074 'two_women_holding_hands':'\ud83d\udc6d', 2075 'u5272':'\ud83c\ude39', 2076 'u5408':'\ud83c\ude34', 2077 'u55b6':'\ud83c\ude3a', 2078 'u6307':'\ud83c\ude2f\ufe0f', 2079 'u6708':'\ud83c\ude37\ufe0f', 2080 'u6709':'\ud83c\ude36', 2081 'u6e80':'\ud83c\ude35', 2082 'u7121':'\ud83c\ude1a\ufe0f', 2083 'u7533':'\ud83c\ude38', 2084 'u7981':'\ud83c\ude32', 2085 'u7a7a':'\ud83c\ude33', 2086 'umbrella':'\u2614\ufe0f', 2087 'unamused':'\ud83d\ude12', 2088 'underage':'\ud83d\udd1e', 2089 'unicorn':'\ud83e\udd84', 2090 'unlock':'\ud83d\udd13', 2091 'up':'\ud83c\udd99', 2092 'upside_down_face':'\ud83d\ude43', 2093 'v':'\u270c\ufe0f', 2094 'vertical_traffic_light':'\ud83d\udea6', 2095 'vhs':'\ud83d\udcfc', 2096 'vibration_mode':'\ud83d\udcf3', 2097 'video_camera':'\ud83d\udcf9', 2098 'video_game':'\ud83c\udfae', 2099 'violin':'\ud83c\udfbb', 2100 'virgo':'\u264d\ufe0f', 2101 'volcano':'\ud83c\udf0b', 2102 'volleyball':'\ud83c\udfd0', 2103 'vs':'\ud83c\udd9a', 2104 'vulcan_salute':'\ud83d\udd96', 2105 'walking_man':'\ud83d\udeb6', 2106 'walking_woman':'\ud83d\udeb6‍\u2640\ufe0f', 2107 'waning_crescent_moon':'\ud83c\udf18', 2108 'waning_gibbous_moon':'\ud83c\udf16', 2109 'warning':'\u26a0\ufe0f', 2110 'wastebasket':'\ud83d\uddd1', 2111 'watch':'\u231a\ufe0f', 2112 'water_buffalo':'\ud83d\udc03', 2113 'watermelon':'\ud83c\udf49', 2114 'wave':'\ud83d\udc4b', 2115 'wavy_dash':'\u3030\ufe0f', 2116 'waxing_crescent_moon':'\ud83c\udf12', 2117 'wc':'\ud83d\udebe', 2118 'weary':'\ud83d\ude29', 2119 'wedding':'\ud83d\udc92', 2120 'weight_lifting_man':'\ud83c\udfcb\ufe0f', 2121 'weight_lifting_woman':'\ud83c\udfcb\ufe0f‍\u2640\ufe0f', 2122 'whale':'\ud83d\udc33', 2123 'whale2':'\ud83d\udc0b', 2124 'wheel_of_dharma':'\u2638\ufe0f', 2125 'wheelchair':'\u267f\ufe0f', 2126 'white_check_mark':'\u2705', 2127 'white_circle':'\u26aa\ufe0f', 2128 'white_flag':'\ud83c\udff3\ufe0f', 2129 'white_flower':'\ud83d\udcae', 2130 'white_large_square':'\u2b1c\ufe0f', 2131 'white_medium_small_square':'\u25fd\ufe0f', 2132 'white_medium_square':'\u25fb\ufe0f', 2133 'white_small_square':'\u25ab\ufe0f', 2134 'white_square_button':'\ud83d\udd33', 2135 'wilted_flower':'\ud83e\udd40', 2136 'wind_chime':'\ud83c\udf90', 2137 'wind_face':'\ud83c\udf2c', 2138 'wine_glass':'\ud83c\udf77', 2139 'wink':'\ud83d\ude09', 2140 'wolf':'\ud83d\udc3a', 2141 'woman':'\ud83d\udc69', 2142 'woman_artist':'\ud83d\udc69‍\ud83c\udfa8', 2143 'woman_astronaut':'\ud83d\udc69‍\ud83d\ude80', 2144 'woman_cartwheeling':'\ud83e\udd38‍\u2640\ufe0f', 2145 'woman_cook':'\ud83d\udc69‍\ud83c\udf73', 2146 'woman_facepalming':'\ud83e\udd26‍\u2640\ufe0f', 2147 'woman_factory_worker':'\ud83d\udc69‍\ud83c\udfed', 2148 'woman_farmer':'\ud83d\udc69‍\ud83c\udf3e', 2149 'woman_firefighter':'\ud83d\udc69‍\ud83d\ude92', 2150 'woman_health_worker':'\ud83d\udc69‍\u2695\ufe0f', 2151 'woman_judge':'\ud83d\udc69‍\u2696\ufe0f', 2152 'woman_juggling':'\ud83e\udd39‍\u2640\ufe0f', 2153 'woman_mechanic':'\ud83d\udc69‍\ud83d\udd27', 2154 'woman_office_worker':'\ud83d\udc69‍\ud83d\udcbc', 2155 'woman_pilot':'\ud83d\udc69‍\u2708\ufe0f', 2156 'woman_playing_handball':'\ud83e\udd3e‍\u2640\ufe0f', 2157 'woman_playing_water_polo':'\ud83e\udd3d‍\u2640\ufe0f', 2158 'woman_scientist':'\ud83d\udc69‍\ud83d\udd2c', 2159 'woman_shrugging':'\ud83e\udd37‍\u2640\ufe0f', 2160 'woman_singer':'\ud83d\udc69‍\ud83c\udfa4', 2161 'woman_student':'\ud83d\udc69‍\ud83c\udf93', 2162 'woman_teacher':'\ud83d\udc69‍\ud83c\udfeb', 2163 'woman_technologist':'\ud83d\udc69‍\ud83d\udcbb', 2164 'woman_with_turban':'\ud83d\udc73‍\u2640\ufe0f', 2165 'womans_clothes':'\ud83d\udc5a', 2166 'womans_hat':'\ud83d\udc52', 2167 'women_wrestling':'\ud83e\udd3c‍\u2640\ufe0f', 2168 'womens':'\ud83d\udeba', 2169 'world_map':'\ud83d\uddfa', 2170 'worried':'\ud83d\ude1f', 2171 'wrench':'\ud83d\udd27', 2172 'writing_hand':'\u270d\ufe0f', 2173 'x':'\u274c', 2174 'yellow_heart':'\ud83d\udc9b', 2175 'yen':'\ud83d\udcb4', 2176 'yin_yang':'\u262f\ufe0f', 2177 'yum':'\ud83d\ude0b', 2178 'zap':'\u26a1\ufe0f', 2179 'zipper_mouth_face':'\ud83e\udd10', 2180 'zzz':'\ud83d\udca4', 2181 2182 /* special emojis :P */ 2183 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">', 2184 '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>' 2185 }; 2186 2187 /** 2188 * Created by Estevao on 31-05-2015. 2189 */ 2190 2191 /** 2192 * Showdown Converter class 2193 * @class 2194 * @param {object} [converterOptions] 2195 * @returns {Converter} 2196 */ 2197 showdown.Converter = function (converterOptions) { 2198 'use strict'; 2199 2200 var 2201 /** 2202 * Options used by this converter 2203 * @private 2204 * @type {{}} 2205 */ 2206 options = {}, 2207 2208 /** 2209 * Language extensions used by this converter 2210 * @private 2211 * @type {Array} 2212 */ 2213 langExtensions = [], 2214 2215 /** 2216 * Output modifiers extensions used by this converter 2217 * @private 2218 * @type {Array} 2219 */ 2220 outputModifiers = [], 2221 2222 /** 2223 * Event listeners 2224 * @private 2225 * @type {{}} 2226 */ 2227 listeners = {}, 2228 2229 /** 2230 * The flavor set in this converter 2231 */ 2232 setConvFlavor = setFlavor, 2233 2234 /** 2235 * Metadata of the document 2236 * @type {{parsed: {}, raw: string, format: string}} 2237 */ 2238 metadata = { 2239 parsed: {}, 2240 raw: '', 2241 format: '' 2242 }; 2243 2244 _constructor(); 2245 2246 /** 2247 * Converter constructor 2248 * @private 2249 */ 2250 function _constructor () { 2251 converterOptions = converterOptions || {}; 2252 2253 for (var gOpt in globalOptions) { 2254 if (globalOptions.hasOwnProperty(gOpt)) { 2255 options[gOpt] = globalOptions[gOpt]; 2256 } 2257 } 2258 2259 // Merge options 2260 if (typeof converterOptions === 'object') { 2261 for (var opt in converterOptions) { 2262 if (converterOptions.hasOwnProperty(opt)) { 2263 options[opt] = converterOptions[opt]; 2264 } 2265 } 2266 } else { 2267 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + 2268 ' was passed instead.'); 2269 } 2270 2271 if (options.extensions) { 2272 showdown.helper.forEach(options.extensions, _parseExtension); 2273 } 2274 } 2275 2276 /** 2277 * Parse extension 2278 * @param {*} ext 2279 * @param {string} [name=''] 2280 * @private 2281 */ 2282 function _parseExtension (ext, name) { 2283 2284 name = name || null; 2285 // If it's a string, the extension was previously loaded 2286 if (showdown.helper.isString(ext)) { 2287 ext = showdown.helper.stdExtName(ext); 2288 name = ext; 2289 2290 // LEGACY_SUPPORT CODE 2291 if (showdown.extensions[ext]) { 2292 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + 2293 'Please inform the developer that the extension should be updated!'); 2294 legacyExtensionLoading(showdown.extensions[ext], ext); 2295 return; 2296 // END LEGACY SUPPORT CODE 2297 2298 } else if (!showdown.helper.isUndefined(extensions[ext])) { 2299 ext = extensions[ext]; 2300 2301 } else { 2302 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); 2303 } 2304 } 2305 2306 if (typeof ext === 'function') { 2307 ext = ext(); 2308 } 2309 2310 if (!showdown.helper.isArray(ext)) { 2311 ext = [ext]; 2312 } 2313 2314 var validExt = validate(ext, name); 2315 if (!validExt.valid) { 2316 throw Error(validExt.error); 2317 } 2318 2319 for (var i = 0; i < ext.length; ++i) { 2320 switch (ext[i].type) { 2321 2322 case 'lang': 2323 langExtensions.push(ext[i]); 2324 break; 2325 2326 case 'output': 2327 outputModifiers.push(ext[i]); 2328 break; 2329 } 2330 if (ext[i].hasOwnProperty('listeners')) { 2331 for (var ln in ext[i].listeners) { 2332 if (ext[i].listeners.hasOwnProperty(ln)) { 2333 listen(ln, ext[i].listeners[ln]); 2334 } 2335 } 2336 } 2337 } 2338 2339 } 2340 2341 /** 2342 * LEGACY_SUPPORT 2343 * @param {*} ext 2344 * @param {string} name 2345 */ 2346 function legacyExtensionLoading (ext, name) { 2347 if (typeof ext === 'function') { 2348 ext = ext(new showdown.Converter()); 2349 } 2350 if (!showdown.helper.isArray(ext)) { 2351 ext = [ext]; 2352 } 2353 var valid = validate(ext, name); 2354 2355 if (!valid.valid) { 2356 throw Error(valid.error); 2357 } 2358 2359 for (var i = 0; i < ext.length; ++i) { 2360 switch (ext[i].type) { 2361 case 'lang': 2362 langExtensions.push(ext[i]); 2363 break; 2364 case 'output': 2365 outputModifiers.push(ext[i]); 2366 break; 2367 default:// should never reach here 2368 throw Error('Extension loader error: Type unrecognized!!!'); 2369 } 2370 } 2371 } 2372 2373 /** 2374 * Listen to an event 2375 * @param {string} name 2376 * @param {function} callback 2377 */ 2378 function listen (name, callback) { 2379 if (!showdown.helper.isString(name)) { 2380 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); 2381 } 2382 2383 if (typeof callback !== 'function') { 2384 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); 2385 } 2386 2387 if (!listeners.hasOwnProperty(name)) { 2388 listeners[name] = []; 2389 } 2390 listeners[name].push(callback); 2391 } 2392 2393 function rTrimInputText (text) { 2394 var rsp = text.match(/^\s*/)[0].length, 2395 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); 2396 return text.replace(rgx, ''); 2397 } 2398 2399 /** 2400 * Dispatch an event 2401 * @private 2402 * @param {string} evtName Event name 2403 * @param {string} text Text 2404 * @param {{}} options Converter Options 2405 * @param {{}} globals 2406 * @returns {string} 2407 */ 2408 this._dispatch = function dispatch (evtName, text, options, globals) { 2409 if (listeners.hasOwnProperty(evtName)) { 2410 for (var ei = 0; ei < listeners[evtName].length; ++ei) { 2411 var nText = listeners[evtName][ei](evtName, text, this, options, globals); 2412 if (nText && typeof nText !== 'undefined') { 2413 text = nText; 2414 } 2415 } 2416 } 2417 return text; 2418 }; 2419 2420 /** 2421 * Listen to an event 2422 * @param {string} name 2423 * @param {function} callback 2424 * @returns {showdown.Converter} 2425 */ 2426 this.listen = function (name, callback) { 2427 listen(name, callback); 2428 return this; 2429 }; 2430 2431 /** 2432 * Converts a markdown string into HTML 2433 * @param {string} text 2434 * @returns {*} 2435 */ 2436 this.makeHtml = function (text) { 2437 //check if text is not falsy 2438 if (!text) { 2439 return text; 2440 } 2441 2442 var globals = { 2443 gHtmlBlocks: [], 2444 gHtmlMdBlocks: [], 2445 gHtmlSpans: [], 2446 gUrls: {}, 2447 gTitles: {}, 2448 gDimensions: {}, 2449 gListLevel: 0, 2450 hashLinkCounts: {}, 2451 langExtensions: langExtensions, 2452 outputModifiers: outputModifiers, 2453 converter: this, 2454 ghCodeBlocks: [], 2455 metadata: { 2456 parsed: {}, 2457 raw: '', 2458 format: '' 2459 } 2460 }; 2461 2462 // This lets us use ¨ trema as an escape char to avoid md5 hashes 2463 // The choice of character is arbitrary; anything that isn't 2464 // magic in Markdown will work. 2465 text = text.replace(/¨/g, '¨T'); 2466 2467 // Replace $ with ¨D 2468 // RegExp interprets $ as a special character 2469 // when it's in a replacement string 2470 text = text.replace(/\$/g, '¨D'); 2471 2472 // Standardize line endings 2473 text = text.replace(/\r\n/g, '\n'); // DOS to Unix 2474 text = text.replace(/\r/g, '\n'); // Mac to Unix 2475 2476 // Stardardize line spaces 2477 text = text.replace(/\u00A0/g, ' '); 2478 2479 if (options.smartIndentationFix) { 2480 text = rTrimInputText(text); 2481 } 2482 2483 // Make sure text begins and ends with a couple of newlines: 2484 text = '\n\n' + text + '\n\n'; 2485 2486 // detab 2487 text = showdown.subParser('detab')(text, options, globals); 2488 2489 /** 2490 * Strip any lines consisting only of spaces and tabs. 2491 * This makes subsequent regexs easier to write, because we can 2492 * match consecutive blank lines with /\n+/ instead of something 2493 * contorted like /[ \t]*\n+/ 2494 */ 2495 text = text.replace(/^[ \t]+$/mg, ''); 2496 2497 //run languageExtensions 2498 showdown.helper.forEach(langExtensions, function (ext) { 2499 text = showdown.subParser('runExtension')(ext, text, options, globals); 2500 }); 2501 2502 // run the sub parsers 2503 text = showdown.subParser('metadata')(text, options, globals); 2504 text = showdown.subParser('hashPreCodeTags')(text, options, globals); 2505 text = showdown.subParser('githubCodeBlocks')(text, options, globals); 2506 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 2507 text = showdown.subParser('hashCodeTags')(text, options, globals); 2508 text = showdown.subParser('stripLinkDefinitions')(text, options, globals); 2509 text = showdown.subParser('blockGamut')(text, options, globals); 2510 text = showdown.subParser('unhashHTMLSpans')(text, options, globals); 2511 text = showdown.subParser('unescapeSpecialChars')(text, options, globals); 2512 2513 // attacklab: Restore dollar signs 2514 text = text.replace(/¨D/g, '$$'); 2515 2516 // attacklab: Restore tremas 2517 text = text.replace(/¨T/g, '¨'); 2518 2519 // render a complete html document instead of a partial if the option is enabled 2520 text = showdown.subParser('completeHTMLDocument')(text, options, globals); 2521 2522 // Run output modifiers 2523 showdown.helper.forEach(outputModifiers, function (ext) { 2524 text = showdown.subParser('runExtension')(ext, text, options, globals); 2525 }); 2526 2527 // update metadata 2528 metadata = globals.metadata; 2529 return text; 2530 }; 2531 2532 /** 2533 * Converts an HTML string into a markdown string 2534 * @param src 2535 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used. 2536 * @returns {string} 2537 */ 2538 this.makeMarkdown = this.makeMd = function (src, HTMLParser) { 2539 2540 // replace \r\n with \n 2541 src = src.replace(/\r\n/g, '\n'); 2542 src = src.replace(/\r/g, '\n'); // old macs 2543 2544 // due to an edge case, we need to find this: > < 2545 // to prevent removing of non silent white spaces 2546 // ex: <em>this is</em> <strong>sparta</strong> 2547 src = src.replace(/>[ \t]+</, '>¨NBSP;<'); 2548 2549 if (!HTMLParser) { 2550 if (window && window.document) { 2551 HTMLParser = window.document; 2552 } else { 2553 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'); 2554 } 2555 } 2556 2557 var doc = HTMLParser.createElement('div'); 2558 doc.innerHTML = src; 2559 2560 var globals = { 2561 preList: substitutePreCodeTags(doc) 2562 }; 2563 2564 // remove all newlines and collapse spaces 2565 clean(doc); 2566 2567 // some stuff, like accidental reference links must now be escaped 2568 // TODO 2569 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/); 2570 2571 var nodes = doc.childNodes, 2572 mdDoc = ''; 2573 2574 for (var i = 0; i < nodes.length; i++) { 2575 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals); 2576 } 2577 2578 function clean (node) { 2579 for (var n = 0; n < node.childNodes.length; ++n) { 2580 var child = node.childNodes[n]; 2581 if (child.nodeType === 3) { 2582 if (!/\S/.test(child.nodeValue)) { 2583 node.removeChild(child); 2584 --n; 2585 } else { 2586 child.nodeValue = child.nodeValue.split('\n').join(' '); 2587 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1'); 2588 } 2589 } else if (child.nodeType === 1) { 2590 clean(child); 2591 } 2592 } 2593 } 2594 2595 // find all pre tags and replace contents with placeholder 2596 // we need this so that we can remove all indentation from html 2597 // to ease up parsing 2598 function substitutePreCodeTags (doc) { 2599 2600 var pres = doc.querySelectorAll('pre'), 2601 presPH = []; 2602 2603 for (var i = 0; i < pres.length; ++i) { 2604 2605 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') { 2606 var content = pres[i].firstChild.innerHTML.trim(), 2607 language = pres[i].firstChild.getAttribute('data-language') || ''; 2608 2609 // if data-language attribute is not defined, then we look for class language-* 2610 if (language === '') { 2611 var classes = pres[i].firstChild.className.split(' '); 2612 for (var c = 0; c < classes.length; ++c) { 2613 var matches = classes[c].match(/^language-(.+)$/); 2614 if (matches !== null) { 2615 language = matches[1]; 2616 break; 2617 } 2618 } 2619 } 2620 2621 // unescape html entities in content 2622 content = showdown.helper.unescapeHTMLEntities(content); 2623 2624 presPH.push(content); 2625 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>'; 2626 } else { 2627 presPH.push(pres[i].innerHTML); 2628 pres[i].innerHTML = ''; 2629 pres[i].setAttribute('prenum', i.toString()); 2630 } 2631 } 2632 return presPH; 2633 } 2634 2635 return mdDoc; 2636 }; 2637 2638 /** 2639 * Set an option of this Converter instance 2640 * @param {string} key 2641 * @param {*} value 2642 */ 2643 this.setOption = function (key, value) { 2644 options[key] = value; 2645 }; 2646 2647 /** 2648 * Get the option of this Converter instance 2649 * @param {string} key 2650 * @returns {*} 2651 */ 2652 this.getOption = function (key) { 2653 return options[key]; 2654 }; 2655 2656 /** 2657 * Get the options of this Converter instance 2658 * @returns {{}} 2659 */ 2660 this.getOptions = function () { 2661 return options; 2662 }; 2663 2664 /** 2665 * Add extension to THIS converter 2666 * @param {{}} extension 2667 * @param {string} [name=null] 2668 */ 2669 this.addExtension = function (extension, name) { 2670 name = name || null; 2671 _parseExtension(extension, name); 2672 }; 2673 2674 /** 2675 * Use a global registered extension with THIS converter 2676 * @param {string} extensionName Name of the previously registered extension 2677 */ 2678 this.useExtension = function (extensionName) { 2679 _parseExtension(extensionName); 2680 }; 2681 2682 /** 2683 * Set the flavor THIS converter should use 2684 * @param {string} name 2685 */ 2686 this.setFlavor = function (name) { 2687 if (!flavor.hasOwnProperty(name)) { 2688 throw Error(name + ' flavor was not found'); 2689 } 2690 var preset = flavor[name]; 2691 setConvFlavor = name; 2692 for (var option in preset) { 2693 if (preset.hasOwnProperty(option)) { 2694 options[option] = preset[option]; 2695 } 2696 } 2697 }; 2698 2699 /** 2700 * Get the currently set flavor of this converter 2701 * @returns {string} 2702 */ 2703 this.getFlavor = function () { 2704 return setConvFlavor; 2705 }; 2706 2707 /** 2708 * Remove an extension from THIS converter. 2709 * Note: This is a costly operation. It's better to initialize a new converter 2710 * and specify the extensions you wish to use 2711 * @param {Array} extension 2712 */ 2713 this.removeExtension = function (extension) { 2714 if (!showdown.helper.isArray(extension)) { 2715 extension = [extension]; 2716 } 2717 for (var a = 0; a < extension.length; ++a) { 2718 var ext = extension[a]; 2719 for (var i = 0; i < langExtensions.length; ++i) { 2720 if (langExtensions[i] === ext) { 2721 langExtensions[i].splice(i, 1); 2722 } 2723 } 2724 for (var ii = 0; ii < outputModifiers.length; ++i) { 2725 if (outputModifiers[ii] === ext) { 2726 outputModifiers[ii].splice(i, 1); 2727 } 2728 } 2729 } 2730 }; 2731 2732 /** 2733 * Get all extension of THIS converter 2734 * @returns {{language: Array, output: Array}} 2735 */ 2736 this.getAllExtensions = function () { 2737 return { 2738 language: langExtensions, 2739 output: outputModifiers 2740 }; 2741 }; 2742 2743 /** 2744 * Get the metadata of the previously parsed document 2745 * @param raw 2746 * @returns {string|{}} 2747 */ 2748 this.getMetadata = function (raw) { 2749 if (raw) { 2750 return metadata.raw; 2751 } else { 2752 return metadata.parsed; 2753 } 2754 }; 2755 2756 /** 2757 * Get the metadata format of the previously parsed document 2758 * @returns {string} 2759 */ 2760 this.getMetadataFormat = function () { 2761 return metadata.format; 2762 }; 2763 2764 /** 2765 * Private: set a single key, value metadata pair 2766 * @param {string} key 2767 * @param {string} value 2768 */ 2769 this._setMetadataPair = function (key, value) { 2770 metadata.parsed[key] = value; 2771 }; 2772 2773 /** 2774 * Private: set metadata format 2775 * @param {string} format 2776 */ 2777 this._setMetadataFormat = function (format) { 2778 metadata.format = format; 2779 }; 2780 2781 /** 2782 * Private: set metadata raw text 2783 * @param {string} raw 2784 */ 2785 this._setMetadataRaw = function (raw) { 2786 metadata.raw = raw; 2787 }; 2788 }; 2789 2790 /** 2791 * Turn Markdown link shortcuts into XHTML <a> tags. 2792 */ 2793 showdown.subParser('anchors', function (text, options, globals) { 2794 'use strict'; 2795 2796 text = globals.converter._dispatch('anchors.before', text, options, globals); 2797 2798 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { 2799 if (showdown.helper.isUndefined(title)) { 2800 title = ''; 2801 } 2802 linkId = linkId.toLowerCase(); 2803 2804 // Special case for explicit empty url 2805 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 2806 url = ''; 2807 } else if (!url) { 2808 if (!linkId) { 2809 // lower-case and turn embedded newlines into spaces 2810 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); 2811 } 2812 url = '#' + linkId; 2813 2814 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { 2815 url = globals.gUrls[linkId]; 2816 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { 2817 title = globals.gTitles[linkId]; 2818 } 2819 } else { 2820 return wholeMatch; 2821 } 2822 } 2823 2824 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance 2825 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 2826 2827 var result = '<a href="' + url + '"'; 2828 2829 if (title !== '' && title !== null) { 2830 title = title.replace(/"/g, '"'); 2831 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance 2832 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 2833 result += ' title="' + title + '"'; 2834 } 2835 2836 // optionLinksInNewWindow only applies 2837 // to external links. Hash links (#) open in same page 2838 if (options.openLinksInNewWindow && !/^#/.test(url)) { 2839 // escaped _ 2840 result += ' rel="noopener noreferrer" target="¨E95Eblank"'; 2841 } 2842 2843 result += '>' + linkText + '</a>'; 2844 2845 return result; 2846 }; 2847 2848 // First, handle reference-style links: [link text] [id] 2849 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); 2850 2851 // Next, inline-style links: [link text](url "optional title") 2852 // cases with crazy urls like ./image/cat1).png 2853 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 2854 writeAnchorTag); 2855 2856 // normal cases 2857 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 2858 writeAnchorTag); 2859 2860 // handle reference-style shortcuts: [link text] 2861 // These must come last in case you've also got [link test][1] 2862 // or [link test](/foo) 2863 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); 2864 2865 // Lastly handle GithubMentions if option is enabled 2866 if (options.ghMentions) { 2867 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) { 2868 if (escape === '\\') { 2869 return st + mentions; 2870 } 2871 2872 //check if options.ghMentionsLink is a string 2873 if (!showdown.helper.isString(options.ghMentionsLink)) { 2874 throw new Error('ghMentionsLink option must be a string'); 2875 } 2876 var lnk = options.ghMentionsLink.replace(/\{u}/g, username), 2877 target = ''; 2878 if (options.openLinksInNewWindow) { 2879 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 2880 } 2881 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>'; 2882 }); 2883 } 2884 2885 text = globals.converter._dispatch('anchors.after', text, options, globals); 2886 return text; 2887 }); 2888 2889 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] 2890 2891 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, 2892 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, 2893 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, 2894 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi, 2895 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 2896 2897 replaceLink = function (options) { 2898 'use strict'; 2899 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) { 2900 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 2901 var lnkTxt = link, 2902 append = '', 2903 target = '', 2904 lmc = leadingMagicChars || '', 2905 tmc = trailingMagicChars || ''; 2906 if (/^www\./i.test(link)) { 2907 link = link.replace(/^www\./i, 'http://www.'); 2908 } 2909 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) { 2910 append = trailingPunctuation; 2911 } 2912 if (options.openLinksInNewWindow) { 2913 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 2914 } 2915 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc; 2916 }; 2917 }, 2918 2919 replaceMail = function (options, globals) { 2920 'use strict'; 2921 return function (wholeMatch, b, mail) { 2922 var href = 'mailto:'; 2923 b = b || ''; 2924 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals); 2925 if (options.encodeEmails) { 2926 href = showdown.helper.encodeEmailAddress(href + mail); 2927 mail = showdown.helper.encodeEmailAddress(mail); 2928 } else { 2929 href = href + mail; 2930 } 2931 return b + '<a href="' + href + '">' + mail + '</a>'; 2932 }; 2933 }; 2934 2935 showdown.subParser('autoLinks', function (text, options, globals) { 2936 'use strict'; 2937 2938 text = globals.converter._dispatch('autoLinks.before', text, options, globals); 2939 2940 text = text.replace(delimUrlRegex, replaceLink(options)); 2941 text = text.replace(delimMailRegex, replaceMail(options, globals)); 2942 2943 text = globals.converter._dispatch('autoLinks.after', text, options, globals); 2944 2945 return text; 2946 }); 2947 2948 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) { 2949 'use strict'; 2950 2951 if (!options.simplifiedAutoLink) { 2952 return text; 2953 } 2954 2955 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals); 2956 2957 if (options.excludeTrailingPunctuationFromURLs) { 2958 text = text.replace(simpleURLRegex2, replaceLink(options)); 2959 } else { 2960 text = text.replace(simpleURLRegex, replaceLink(options)); 2961 } 2962 text = text.replace(simpleMailRegex, replaceMail(options, globals)); 2963 2964 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals); 2965 2966 return text; 2967 }); 2968 2969 /** 2970 * These are all the transformations that form block-level 2971 * tags like paragraphs, headers, and list items. 2972 */ 2973 showdown.subParser('blockGamut', function (text, options, globals) { 2974 'use strict'; 2975 2976 text = globals.converter._dispatch('blockGamut.before', text, options, globals); 2977 2978 // we parse blockquotes first so that we can have headings and hrs 2979 // inside blockquotes 2980 text = showdown.subParser('blockQuotes')(text, options, globals); 2981 text = showdown.subParser('headers')(text, options, globals); 2982 2983 // Do Horizontal Rules: 2984 text = showdown.subParser('horizontalRule')(text, options, globals); 2985 2986 text = showdown.subParser('lists')(text, options, globals); 2987 text = showdown.subParser('codeBlocks')(text, options, globals); 2988 text = showdown.subParser('tables')(text, options, globals); 2989 2990 // We already ran _HashHTMLBlocks() before, in Markdown(), but that 2991 // was to escape raw HTML in the original Markdown source. This time, 2992 // we're escaping the markup we've just created, so that we don't wrap 2993 // <p> tags around block-level tags. 2994 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 2995 text = showdown.subParser('paragraphs')(text, options, globals); 2996 2997 text = globals.converter._dispatch('blockGamut.after', text, options, globals); 2998 2999 return text; 3000 }); 3001 3002 showdown.subParser('blockQuotes', function (text, options, globals) { 3003 'use strict'; 3004 3005 text = globals.converter._dispatch('blockQuotes.before', text, options, globals); 3006 3007 // add a couple extra lines after the text and endtext mark 3008 text = text + '\n\n'; 3009 3010 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm; 3011 3012 if (options.splitAdjacentBlockquotes) { 3013 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm; 3014 } 3015 3016 text = text.replace(rgx, function (bq) { 3017 // attacklab: hack around Konqueror 3.5.4 bug: 3018 // "----------bug".replace(/^-/g,"") == "bug" 3019 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting 3020 3021 // attacklab: clean up hack 3022 bq = bq.replace(/¨0/g, ''); 3023 3024 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines 3025 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); 3026 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse 3027 3028 bq = bq.replace(/(^|\n)/g, '$1 '); 3029 // These leading spaces screw with <pre> content, so we need to fix that: 3030 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { 3031 var pre = m1; 3032 // attacklab: hack around Konqueror 3.5.4 bug: 3033 pre = pre.replace(/^ /mg, '¨0'); 3034 pre = pre.replace(/¨0/g, ''); 3035 return pre; 3036 }); 3037 3038 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); 3039 }); 3040 3041 text = globals.converter._dispatch('blockQuotes.after', text, options, globals); 3042 return text; 3043 }); 3044 3045 /** 3046 * Process Markdown `<pre><code>` blocks. 3047 */ 3048 showdown.subParser('codeBlocks', function (text, options, globals) { 3049 'use strict'; 3050 3051 text = globals.converter._dispatch('codeBlocks.before', text, options, globals); 3052 3053 // sentinel workarounds for lack of \A and \Z, safari\khtml bug 3054 text += '¨0'; 3055 3056 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g; 3057 text = text.replace(pattern, function (wholeMatch, m1, m2) { 3058 var codeblock = m1, 3059 nextChar = m2, 3060 end = '\n'; 3061 3062 codeblock = showdown.subParser('outdent')(codeblock, options, globals); 3063 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3064 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3065 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3066 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines 3067 3068 if (options.omitExtraWLInCodeBlocks) { 3069 end = ''; 3070 } 3071 3072 codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; 3073 3074 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; 3075 }); 3076 3077 // strip sentinel 3078 text = text.replace(/¨0/, ''); 3079 3080 text = globals.converter._dispatch('codeBlocks.after', text, options, globals); 3081 return text; 3082 }); 3083 3084 /** 3085 * 3086 * * Backtick quotes are used for <code></code> spans. 3087 * 3088 * * You can use multiple backticks as the delimiters if you want to 3089 * include literal backticks in the code span. So, this input: 3090 * 3091 * Just type ``foo `bar` baz`` at the prompt. 3092 * 3093 * Will translate to: 3094 * 3095 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> 3096 * 3097 * There's no arbitrary limit to the number of backticks you 3098 * can use as delimters. If you need three consecutive backticks 3099 * in your code, use four for delimiters, etc. 3100 * 3101 * * You can use spaces to get literal backticks at the edges: 3102 * 3103 * ... type `` `bar` `` ... 3104 * 3105 * Turns to: 3106 * 3107 * ... type <code>`bar`</code> ... 3108 */ 3109 showdown.subParser('codeSpans', function (text, options, globals) { 3110 'use strict'; 3111 3112 text = globals.converter._dispatch('codeSpans.before', text, options, globals); 3113 3114 if (typeof text === 'undefined') { 3115 text = ''; 3116 } 3117 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, 3118 function (wholeMatch, m1, m2, m3) { 3119 var c = m3; 3120 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace 3121 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace 3122 c = showdown.subParser('encodeCode')(c, options, globals); 3123 c = m1 + '<code>' + c + '</code>'; 3124 c = showdown.subParser('hashHTMLSpans')(c, options, globals); 3125 return c; 3126 } 3127 ); 3128 3129 text = globals.converter._dispatch('codeSpans.after', text, options, globals); 3130 return text; 3131 }); 3132 3133 /** 3134 * Create a full HTML document from the processed markdown 3135 */ 3136 showdown.subParser('completeHTMLDocument', function (text, options, globals) { 3137 'use strict'; 3138 3139 if (!options.completeHTMLDocument) { 3140 return text; 3141 } 3142 3143 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals); 3144 3145 var doctype = 'html', 3146 doctypeParsed = '<!DOCTYPE HTML>\n', 3147 title = '', 3148 charset = '<meta charset="utf-8">\n', 3149 lang = '', 3150 metadata = ''; 3151 3152 if (typeof globals.metadata.parsed.doctype !== 'undefined') { 3153 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n'; 3154 doctype = globals.metadata.parsed.doctype.toString().toLowerCase(); 3155 if (doctype === 'html' || doctype === 'html5') { 3156 charset = '<meta charset="utf-8">'; 3157 } 3158 } 3159 3160 for (var meta in globals.metadata.parsed) { 3161 if (globals.metadata.parsed.hasOwnProperty(meta)) { 3162 switch (meta.toLowerCase()) { 3163 case 'doctype': 3164 break; 3165 3166 case 'title': 3167 title = '<title>' + globals.metadata.parsed.title + '</title>\n'; 3168 break; 3169 3170 case 'charset': 3171 if (doctype === 'html' || doctype === 'html5') { 3172 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n'; 3173 } else { 3174 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n'; 3175 } 3176 break; 3177 3178 case 'language': 3179 case 'lang': 3180 lang = ' lang="' + globals.metadata.parsed[meta] + '"'; 3181 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3182 break; 3183 3184 default: 3185 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3186 } 3187 } 3188 } 3189 3190 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>'; 3191 3192 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals); 3193 return text; 3194 }); 3195 3196 /** 3197 * Convert all tabs to spaces 3198 */ 3199 showdown.subParser('detab', function (text, options, globals) { 3200 'use strict'; 3201 text = globals.converter._dispatch('detab.before', text, options, globals); 3202 3203 // expand first n-1 tabs 3204 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width 3205 3206 // replace the nth with two sentinels 3207 text = text.replace(/\t/g, '¨A¨B'); 3208 3209 // use the sentinel to anchor our regex so it doesn't explode 3210 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) { 3211 var leadingText = m1, 3212 numSpaces = 4 - leadingText.length % 4; // g_tab_width 3213 3214 // there *must* be a better way to do this: 3215 for (var i = 0; i < numSpaces; i++) { 3216 leadingText += ' '; 3217 } 3218 3219 return leadingText; 3220 }); 3221 3222 // clean up sentinels 3223 text = text.replace(/¨A/g, ' '); // g_tab_width 3224 text = text.replace(/¨B/g, ''); 3225 3226 text = globals.converter._dispatch('detab.after', text, options, globals); 3227 return text; 3228 }); 3229 3230 showdown.subParser('ellipsis', function (text, options, globals) { 3231 'use strict'; 3232 3233 text = globals.converter._dispatch('ellipsis.before', text, options, globals); 3234 3235 text = text.replace(/\.\.\./g, '…'); 3236 3237 text = globals.converter._dispatch('ellipsis.after', text, options, globals); 3238 3239 return text; 3240 }); 3241 3242 /** 3243 * Turn emoji codes into emojis 3244 * 3245 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis 3246 */ 3247 showdown.subParser('emoji', function (text, options, globals) { 3248 'use strict'; 3249 3250 if (!options.emoji) { 3251 return text; 3252 } 3253 3254 text = globals.converter._dispatch('emoji.before', text, options, globals); 3255 3256 var emojiRgx = /:([\S]+?):/g; 3257 3258 text = text.replace(emojiRgx, function (wm, emojiCode) { 3259 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) { 3260 return showdown.helper.emojis[emojiCode]; 3261 } 3262 return wm; 3263 }); 3264 3265 text = globals.converter._dispatch('emoji.after', text, options, globals); 3266 3267 return text; 3268 }); 3269 3270 /** 3271 * Smart processing for ampersands and angle brackets that need to be encoded. 3272 */ 3273 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) { 3274 'use strict'; 3275 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals); 3276 3277 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: 3278 // http://bumppo.net/projects/amputator/ 3279 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); 3280 3281 // Encode naked <'s 3282 text = text.replace(/<(?![a-z\/?$!])/gi, '<'); 3283 3284 // Encode < 3285 text = text.replace(/</g, '<'); 3286 3287 // Encode > 3288 text = text.replace(/>/g, '>'); 3289 3290 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals); 3291 return text; 3292 }); 3293 3294 /** 3295 * Returns the string, with after processing the following backslash escape sequences. 3296 * 3297 * attacklab: The polite way to do this is with the new escapeCharacters() function: 3298 * 3299 * text = escapeCharacters(text,"\\",true); 3300 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); 3301 * 3302 * ...but we're sidestepping its use of the (slow) RegExp constructor 3303 * as an optimization for Firefox. This function gets called a LOT. 3304 */ 3305 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) { 3306 'use strict'; 3307 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals); 3308 3309 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); 3310 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback); 3311 3312 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals); 3313 return text; 3314 }); 3315 3316 /** 3317 * Encode/escape certain characters inside Markdown code runs. 3318 * The point is that in code, these characters are literals, 3319 * and lose their special Markdown meanings. 3320 */ 3321 showdown.subParser('encodeCode', function (text, options, globals) { 3322 'use strict'; 3323 3324 text = globals.converter._dispatch('encodeCode.before', text, options, globals); 3325 3326 // Encode all ampersands; HTML entities are not 3327 // entities within a Markdown code span. 3328 text = text 3329 .replace(/&/g, '&') 3330 // Do the angle bracket song and dance: 3331 .replace(/</g, '<') 3332 .replace(/>/g, '>') 3333 // Now, escape characters that are magic in Markdown: 3334 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback); 3335 3336 text = globals.converter._dispatch('encodeCode.after', text, options, globals); 3337 return text; 3338 }); 3339 3340 /** 3341 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they 3342 * don't conflict with their use in Markdown for code, italics and strong. 3343 */ 3344 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) { 3345 'use strict'; 3346 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals); 3347 3348 // Build a regex to find HTML tags. 3349 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, 3350 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi; 3351 3352 text = text.replace(tags, function (wholeMatch) { 3353 return wholeMatch 3354 .replace(/(.)<\/?code>(?=.)/g, '$1`') 3355 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3356 }); 3357 3358 text = text.replace(comments, function (wholeMatch) { 3359 return wholeMatch 3360 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3361 }); 3362 3363 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals); 3364 return text; 3365 }); 3366 3367 /** 3368 * Handle github codeblocks prior to running HashHTML so that 3369 * HTML contained within the codeblock gets escaped properly 3370 * Example: 3371 * ```ruby 3372 * def hello_world(x) 3373 * puts "Hello, #{x}" 3374 * end 3375 * ``` 3376 */ 3377 showdown.subParser('githubCodeBlocks', function (text, options, globals) { 3378 'use strict'; 3379 3380 // early exit if option is not enabled 3381 if (!options.ghCodeBlocks) { 3382 return text; 3383 } 3384 3385 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); 3386 3387 text += '¨0'; 3388 3389 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) { 3390 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; 3391 3392 // First parse the github code block 3393 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3394 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3395 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3396 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace 3397 3398 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; 3399 3400 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); 3401 3402 // Since GHCodeblocks can be false positives, we need to 3403 // store the primitive text and the parsed text in a global var, 3404 // and then return a token 3405 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 3406 }); 3407 3408 // attacklab: strip sentinel 3409 text = text.replace(/¨0/, ''); 3410 3411 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); 3412 }); 3413 3414 showdown.subParser('hashBlock', function (text, options, globals) { 3415 'use strict'; 3416 text = globals.converter._dispatch('hashBlock.before', text, options, globals); 3417 text = text.replace(/(^\n+|\n+$)/g, ''); 3418 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; 3419 text = globals.converter._dispatch('hashBlock.after', text, options, globals); 3420 return text; 3421 }); 3422 3423 /** 3424 * Hash and escape <code> elements that should not be parsed as markdown 3425 */ 3426 showdown.subParser('hashCodeTags', function (text, options, globals) { 3427 'use strict'; 3428 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals); 3429 3430 var repFunc = function (wholeMatch, match, left, right) { 3431 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 3432 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C'; 3433 }; 3434 3435 // Hash naked <code> 3436 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim'); 3437 3438 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals); 3439 return text; 3440 }); 3441 3442 showdown.subParser('hashElement', function (text, options, globals) { 3443 'use strict'; 3444 3445 return function (wholeMatch, m1) { 3446 var blockText = m1; 3447 3448 // Undo double lines 3449 blockText = blockText.replace(/\n\n/g, '\n'); 3450 blockText = blockText.replace(/^\n/, ''); 3451 3452 // strip trailing blank lines 3453 blockText = blockText.replace(/\n+$/g, ''); 3454 3455 // Replace the element text with a marker ("¨KxK" where x is its key) 3456 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; 3457 3458 return blockText; 3459 }; 3460 }); 3461 3462 showdown.subParser('hashHTMLBlocks', function (text, options, globals) { 3463 'use strict'; 3464 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals); 3465 3466 var blockTags = [ 3467 'pre', 3468 'div', 3469 'h1', 3470 'h2', 3471 'h3', 3472 'h4', 3473 'h5', 3474 'h6', 3475 'blockquote', 3476 'table', 3477 'dl', 3478 'ol', 3479 'ul', 3480 'script', 3481 'noscript', 3482 'form', 3483 'fieldset', 3484 'iframe', 3485 'math', 3486 'style', 3487 'section', 3488 'header', 3489 'footer', 3490 'nav', 3491 'article', 3492 'aside', 3493 'address', 3494 'audio', 3495 'canvas', 3496 'figure', 3497 'hgroup', 3498 'output', 3499 'video', 3500 'p' 3501 ], 3502 repFunc = function (wholeMatch, match, left, right) { 3503 var txt = wholeMatch; 3504 // check if this html element is marked as markdown 3505 // if so, it's contents should be parsed as markdown 3506 if (left.search(/\bmarkdown\b/) !== -1) { 3507 txt = left + globals.converter.makeHtml(match) + right; 3508 } 3509 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 3510 }; 3511 3512 if (options.backslashEscapesHTMLTags) { 3513 // encode backslash escaped HTML tags 3514 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) { 3515 return '<' + inside + '>'; 3516 }); 3517 } 3518 3519 // hash HTML Blocks 3520 for (var i = 0; i < blockTags.length; ++i) { 3521 3522 var opTagPos, 3523 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'), 3524 patLeft = '<' + blockTags[i] + '\\b[^>]*>', 3525 patRight = '</' + blockTags[i] + '>'; 3526 // 1. Look for the first position of the first opening HTML tag in the text 3527 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) { 3528 3529 // if the HTML tag is \ escaped, we need to escape it and break 3530 3531 3532 //2. Split the text in that position 3533 var subTexts = showdown.helper.splitAtIndex(text, opTagPos), 3534 //3. Match recursively 3535 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im'); 3536 3537 // prevent an infinite loop 3538 if (newSubText1 === subTexts[1]) { 3539 break; 3540 } 3541 text = subTexts[0].concat(newSubText1); 3542 } 3543 } 3544 // HR SPECIAL CASE 3545 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, 3546 showdown.subParser('hashElement')(text, options, globals)); 3547 3548 // Special case for standalone HTML comments 3549 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) { 3550 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 3551 }, '^ {0,3}<!--', '-->', 'gm'); 3552 3553 // PHP and ASP-style processor instructions (<?...?> and <%...%>) 3554 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, 3555 showdown.subParser('hashElement')(text, options, globals)); 3556 3557 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals); 3558 return text; 3559 }); 3560 3561 /** 3562 * Hash span elements that should not be parsed as markdown 3563 */ 3564 showdown.subParser('hashHTMLSpans', function (text, options, globals) { 3565 'use strict'; 3566 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals); 3567 3568 function hashHTMLSpan (html) { 3569 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C'; 3570 } 3571 3572 // Hash Self Closing tags 3573 text = text.replace(/<[^>]+?\/>/gi, function (wm) { 3574 return hashHTMLSpan(wm); 3575 }); 3576 3577 // Hash tags without properties 3578 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) { 3579 return hashHTMLSpan(wm); 3580 }); 3581 3582 // Hash tags with properties 3583 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) { 3584 return hashHTMLSpan(wm); 3585 }); 3586 3587 // Hash self closing tags without /> 3588 text = text.replace(/<[^>]+?>/gi, function (wm) { 3589 return hashHTMLSpan(wm); 3590 }); 3591 3592 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/ 3593 3594 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals); 3595 return text; 3596 }); 3597 3598 /** 3599 * Unhash HTML spans 3600 */ 3601 showdown.subParser('unhashHTMLSpans', function (text, options, globals) { 3602 'use strict'; 3603 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); 3604 3605 for (var i = 0; i < globals.gHtmlSpans.length; ++i) { 3606 var repText = globals.gHtmlSpans[i], 3607 // limiter to prevent infinite loop (assume 10 as limit for recurse) 3608 limit = 0; 3609 3610 while (/¨C(\d+)C/.test(repText)) { 3611 var num = RegExp.$1; 3612 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); 3613 if (limit === 10) { 3614 console.error('maximum nesting of 10 spans reached!!!'); 3615 break; 3616 } 3617 ++limit; 3618 } 3619 text = text.replace('¨C' + i + 'C', repText); 3620 } 3621 3622 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); 3623 return text; 3624 }); 3625 3626 /** 3627 * Hash and escape <pre><code> elements that should not be parsed as markdown 3628 */ 3629 showdown.subParser('hashPreCodeTags', function (text, options, globals) { 3630 'use strict'; 3631 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals); 3632 3633 var repFunc = function (wholeMatch, match, left, right) { 3634 // encode html entities 3635 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 3636 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 3637 }; 3638 3639 // Hash <pre><code> 3640 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim'); 3641 3642 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals); 3643 return text; 3644 }); 3645 3646 showdown.subParser('headers', function (text, options, globals) { 3647 'use strict'; 3648 3649 text = globals.converter._dispatch('headers.before', text, options, globals); 3650 3651 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), 3652 3653 // Set text-style headers: 3654 // Header 1 3655 // ======== 3656 // 3657 // Header 2 3658 // -------- 3659 // 3660 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, 3661 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; 3662 3663 text = text.replace(setextRegexH1, function (wholeMatch, m1) { 3664 3665 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 3666 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 3667 hLevel = headerLevelStart, 3668 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 3669 return showdown.subParser('hashBlock')(hashBlock, options, globals); 3670 }); 3671 3672 text = text.replace(setextRegexH2, function (matchFound, m1) { 3673 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 3674 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 3675 hLevel = headerLevelStart + 1, 3676 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 3677 return showdown.subParser('hashBlock')(hashBlock, options, globals); 3678 }); 3679 3680 // atx-style headers: 3681 // # Header 1 3682 // ## Header 2 3683 // ## Header 2 with closing hashes ## 3684 // ... 3685 // ###### Header 6 3686 // 3687 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm; 3688 3689 text = text.replace(atxStyle, function (wholeMatch, m1, m2) { 3690 var hText = m2; 3691 if (options.customizedHeaderId) { 3692 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, ''); 3693 } 3694 3695 var span = showdown.subParser('spanGamut')(hText, options, globals), 3696 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', 3697 hLevel = headerLevelStart - 1 + m1.length, 3698 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; 3699 3700 return showdown.subParser('hashBlock')(header, options, globals); 3701 }); 3702 3703 function headerId (m) { 3704 var title, 3705 prefix; 3706 3707 // It is separate from other options to allow combining prefix and customized 3708 if (options.customizedHeaderId) { 3709 var match = m.match(/\{([^{]+?)}\s*$/); 3710 if (match && match[1]) { 3711 m = match[1]; 3712 } 3713 } 3714 3715 title = m; 3716 3717 // Prefix id to prevent causing inadvertent pre-existing style matches. 3718 if (showdown.helper.isString(options.prefixHeaderId)) { 3719 prefix = options.prefixHeaderId; 3720 } else if (options.prefixHeaderId === true) { 3721 prefix = 'section-'; 3722 } else { 3723 prefix = ''; 3724 } 3725 3726 if (!options.rawPrefixHeaderId) { 3727 title = prefix + title; 3728 } 3729 3730 if (options.ghCompatibleHeaderId) { 3731 title = title 3732 .replace(/ /g, '-') 3733 // replace previously escaped chars (&, ¨ and $) 3734 .replace(/&/g, '') 3735 .replace(/¨T/g, '') 3736 .replace(/¨D/g, '') 3737 // replace rest of the chars (&~$ are repeated as they might have been escaped) 3738 // borrowed from github's redcarpet (some they should produce similar results) 3739 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '') 3740 .toLowerCase(); 3741 } else if (options.rawHeaderId) { 3742 title = title 3743 .replace(/ /g, '-') 3744 // replace previously escaped chars (&, ¨ and $) 3745 .replace(/&/g, '&') 3746 .replace(/¨T/g, '¨') 3747 .replace(/¨D/g, '$') 3748 // replace " and ' 3749 .replace(/["']/g, '-') 3750 .toLowerCase(); 3751 } else { 3752 title = title 3753 .replace(/[^\w]/g, '') 3754 .toLowerCase(); 3755 } 3756 3757 if (options.rawPrefixHeaderId) { 3758 title = prefix + title; 3759 } 3760 3761 if (globals.hashLinkCounts[title]) { 3762 title = title + '-' + (globals.hashLinkCounts[title]++); 3763 } else { 3764 globals.hashLinkCounts[title] = 1; 3765 } 3766 return title; 3767 } 3768 3769 text = globals.converter._dispatch('headers.after', text, options, globals); 3770 return text; 3771 }); 3772 3773 /** 3774 * Turn Markdown link shortcuts into XHTML <a> tags. 3775 */ 3776 showdown.subParser('horizontalRule', function (text, options, globals) { 3777 'use strict'; 3778 text = globals.converter._dispatch('horizontalRule.before', text, options, globals); 3779 3780 var key = showdown.subParser('hashBlock')('<hr />', options, globals); 3781 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key); 3782 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key); 3783 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key); 3784 3785 text = globals.converter._dispatch('horizontalRule.after', text, options, globals); 3786 return text; 3787 }); 3788 3789 /** 3790 * Turn Markdown image shortcuts into <img> tags. 3791 */ 3792 showdown.subParser('images', function (text, options, globals) { 3793 'use strict'; 3794 3795 text = globals.converter._dispatch('images.before', text, options, globals); 3796 3797 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, 3798 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, 3799 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, 3800 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, 3801 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; 3802 3803 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) { 3804 url = url.replace(/\s/g, ''); 3805 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title); 3806 } 3807 3808 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { 3809 3810 var gUrls = globals.gUrls, 3811 gTitles = globals.gTitles, 3812 gDims = globals.gDimensions; 3813 3814 linkId = linkId.toLowerCase(); 3815 3816 if (!title) { 3817 title = ''; 3818 } 3819 // Special case for explicit empty url 3820 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 3821 url = ''; 3822 3823 } else if (url === '' || url === null) { 3824 if (linkId === '' || linkId === null) { 3825 // lower-case and turn embedded newlines into spaces 3826 linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); 3827 } 3828 url = '#' + linkId; 3829 3830 if (!showdown.helper.isUndefined(gUrls[linkId])) { 3831 url = gUrls[linkId]; 3832 if (!showdown.helper.isUndefined(gTitles[linkId])) { 3833 title = gTitles[linkId]; 3834 } 3835 if (!showdown.helper.isUndefined(gDims[linkId])) { 3836 width = gDims[linkId].width; 3837 height = gDims[linkId].height; 3838 } 3839 } else { 3840 return wholeMatch; 3841 } 3842 } 3843 3844 altText = altText 3845 .replace(/"/g, '"') 3846 //altText = showdown.helper.escapeCharacters(altText, '*_', false); 3847 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3848 //url = showdown.helper.escapeCharacters(url, '*_', false); 3849 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3850 var result = '<img src="' + url + '" alt="' + altText + '"'; 3851 3852 if (title && showdown.helper.isString(title)) { 3853 title = title 3854 .replace(/"/g, '"') 3855 //title = showdown.helper.escapeCharacters(title, '*_', false); 3856 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3857 result += ' title="' + title + '"'; 3858 } 3859 3860 if (width && height) { 3861 width = (width === '*') ? 'auto' : width; 3862 height = (height === '*') ? 'auto' : height; 3863 3864 result += ' width="' + width + '"'; 3865 result += ' height="' + height + '"'; 3866 } 3867 3868 result += ' />'; 3869 3870 return result; 3871 } 3872 3873 // First, handle reference-style labeled images: ![alt text][id] 3874 text = text.replace(referenceRegExp, writeImageTag); 3875 3876 // Next, handle inline images:  3877 3878 // base64 encoded images 3879 text = text.replace(base64RegExp, writeImageTagBase64); 3880 3881 // cases with crazy urls like ./image/cat1).png 3882 text = text.replace(crazyRegExp, writeImageTag); 3883 3884 // normal cases 3885 text = text.replace(inlineRegExp, writeImageTag); 3886 3887 // handle reference-style shortcuts: ![img text] 3888 text = text.replace(refShortcutRegExp, writeImageTag); 3889 3890 text = globals.converter._dispatch('images.after', text, options, globals); 3891 return text; 3892 }); 3893 3894 showdown.subParser('italicsAndBold', function (text, options, globals) { 3895 'use strict'; 3896 3897 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); 3898 3899 // it's faster to have 3 separate regexes for each case than have just one 3900 // because of backtracing, in some cases, it could lead to an exponential effect 3901 // called "catastrophic backtrace". Ominous! 3902 3903 function parseInside (txt, left, right) { 3904 /* 3905 if (options.simplifiedAutoLink) { 3906 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 3907 } 3908 */ 3909 return left + txt + right; 3910 } 3911 3912 // Parse underscores 3913 if (options.literalMidWordUnderscores) { 3914 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 3915 return parseInside (txt, '<strong><em>', '</em></strong>'); 3916 }); 3917 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 3918 return parseInside (txt, '<strong>', '</strong>'); 3919 }); 3920 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { 3921 return parseInside (txt, '<em>', '</em>'); 3922 }); 3923 } else { 3924 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 3925 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 3926 }); 3927 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 3928 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 3929 }); 3930 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { 3931 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) 3932 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 3933 }); 3934 } 3935 3936 // Now parse asterisks 3937 if (options.literalMidWordAsterisks) { 3938 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) { 3939 return parseInside (txt, lead + '<strong><em>', '</em></strong>'); 3940 }); 3941 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) { 3942 return parseInside (txt, lead + '<strong>', '</strong>'); 3943 }); 3944 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) { 3945 return parseInside (txt, lead + '<em>', '</em>'); 3946 }); 3947 } else { 3948 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) { 3949 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 3950 }); 3951 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) { 3952 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 3953 }); 3954 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) { 3955 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it) 3956 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 3957 }); 3958 } 3959 3960 3961 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); 3962 return text; 3963 }); 3964 3965 /** 3966 * Form HTML ordered (numbered) and unordered (bulleted) lists. 3967 */ 3968 showdown.subParser('lists', function (text, options, globals) { 3969 'use strict'; 3970 3971 /** 3972 * Process the contents of a single ordered or unordered list, splitting it 3973 * into individual list items. 3974 * @param {string} listStr 3975 * @param {boolean} trimTrailing 3976 * @returns {string} 3977 */ 3978 function processListItems (listStr, trimTrailing) { 3979 // The $g_list_level global keeps track of when we're inside a list. 3980 // Each time we enter a list, we increment it; when we leave a list, 3981 // we decrement. If it's zero, we're not in a list anymore. 3982 // 3983 // We do this because when we're not inside a list, we want to treat 3984 // something like this: 3985 // 3986 // I recommend upgrading to version 3987 // 8. Oops, now this line is treated 3988 // as a sub-list. 3989 // 3990 // As a single paragraph, despite the fact that the second line starts 3991 // with a digit-period-space sequence. 3992 // 3993 // Whereas when we're inside a list (or sub-list), that line will be 3994 // treated as the start of a sub-list. What a kludge, huh? This is 3995 // an aspect of Markdown's syntax that's hard to parse perfectly 3996 // without resorting to mind-reading. Perhaps the solution is to 3997 // change the syntax rules such that sub-lists must start with a 3998 // starting cardinal number; e.g. "1." or "a.". 3999 globals.gListLevel++; 4000 4001 // trim trailing blank lines: 4002 listStr = listStr.replace(/\n{2,}$/, '\n'); 4003 4004 // attacklab: add sentinel to emulate \z 4005 listStr += '¨0'; 4006 4007 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, 4008 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr)); 4009 4010 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation, 4011 // which is a syntax breaking change 4012 // activating this option reverts to old behavior 4013 if (options.disableForced4SpacesIndentedSublists) { 4014 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm; 4015 } 4016 4017 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { 4018 checked = (checked && checked.trim() !== ''); 4019 4020 var item = showdown.subParser('outdent')(m4, options, globals), 4021 bulletStyle = ''; 4022 4023 // Support for github tasklists 4024 if (taskbtn && options.tasklists) { 4025 bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; 4026 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { 4027 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; 4028 if (checked) { 4029 otp += ' checked'; 4030 } 4031 otp += '>'; 4032 return otp; 4033 }); 4034 } 4035 4036 // ISSUE #312 4037 // This input: - - - a 4038 // causes trouble to the parser, since it interprets it as: 4039 // <ul><li><li><li>a</li></li></li></ul> 4040 // instead of: 4041 // <ul><li>- - a</li></ul> 4042 // So, to prevent it, we will put a marker (¨A)in the beginning of the line 4043 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser 4044 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) { 4045 return '¨A' + wm2; 4046 }); 4047 4048 // m1 - Leading line or 4049 // Has a double return (multi paragraph) or 4050 // Has sublist 4051 if (m1 || (item.search(/\n{2,}/) > -1)) { 4052 item = showdown.subParser('githubCodeBlocks')(item, options, globals); 4053 item = showdown.subParser('blockGamut')(item, options, globals); 4054 } else { 4055 // Recursion for sub-lists: 4056 item = showdown.subParser('lists')(item, options, globals); 4057 item = item.replace(/\n$/, ''); // chomp(item) 4058 item = showdown.subParser('hashHTMLBlocks')(item, options, globals); 4059 4060 // Colapse double linebreaks 4061 item = item.replace(/\n\n+/g, '\n\n'); 4062 if (isParagraphed) { 4063 item = showdown.subParser('paragraphs')(item, options, globals); 4064 } else { 4065 item = showdown.subParser('spanGamut')(item, options, globals); 4066 } 4067 } 4068 4069 // now we need to remove the marker (¨A) 4070 item = item.replace('¨A', ''); 4071 // we can finally wrap the line in list item tags 4072 item = '<li' + bulletStyle + '>' + item + '</li>\n'; 4073 4074 return item; 4075 }); 4076 4077 // attacklab: strip sentinel 4078 listStr = listStr.replace(/¨0/g, ''); 4079 4080 globals.gListLevel--; 4081 4082 if (trimTrailing) { 4083 listStr = listStr.replace(/\s+$/, ''); 4084 } 4085 4086 return listStr; 4087 } 4088 4089 function styleStartNumber (list, listType) { 4090 // check if ol and starts by a number different than 1 4091 if (listType === 'ol') { 4092 var res = list.match(/^ *(\d+)\./); 4093 if (res && res[1] !== '1') { 4094 return ' start="' + res[1] + '"'; 4095 } 4096 } 4097 return ''; 4098 } 4099 4100 /** 4101 * Check and parse consecutive lists (better fix for issue #142) 4102 * @param {string} list 4103 * @param {string} listType 4104 * @param {boolean} trimTrailing 4105 * @returns {string} 4106 */ 4107 function parseConsecutiveLists (list, listType, trimTrailing) { 4108 // check if we caught 2 or more consecutive lists by mistake 4109 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa 4110 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, 4111 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, 4112 counterRxg = (listType === 'ul') ? olRgx : ulRgx, 4113 result = ''; 4114 4115 if (list.search(counterRxg) !== -1) { 4116 (function parseCL (txt) { 4117 var pos = txt.search(counterRxg), 4118 style = styleStartNumber(list, listType); 4119 if (pos !== -1) { 4120 // slice 4121 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n'; 4122 4123 // invert counterType and listType 4124 listType = (listType === 'ul') ? 'ol' : 'ul'; 4125 counterRxg = (listType === 'ul') ? olRgx : ulRgx; 4126 4127 //recurse 4128 parseCL(txt.slice(pos)); 4129 } else { 4130 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n'; 4131 } 4132 })(list); 4133 } else { 4134 var style = styleStartNumber(list, listType); 4135 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n'; 4136 } 4137 4138 return result; 4139 } 4140 4141 /** Start of list parsing **/ 4142 text = globals.converter._dispatch('lists.before', text, options, globals); 4143 // add sentinel to hack around khtml/safari bug: 4144 // http://bugs.webkit.org/show_bug.cgi?id=11231 4145 text += '¨0'; 4146 4147 if (globals.gListLevel) { 4148 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4149 function (wholeMatch, list, m2) { 4150 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4151 return parseConsecutiveLists(list, listType, true); 4152 } 4153 ); 4154 } else { 4155 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4156 function (wholeMatch, m1, list, m3) { 4157 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4158 return parseConsecutiveLists(list, listType, false); 4159 } 4160 ); 4161 } 4162 4163 // strip sentinel 4164 text = text.replace(/¨0/, ''); 4165 text = globals.converter._dispatch('lists.after', text, options, globals); 4166 return text; 4167 }); 4168 4169 /** 4170 * Parse metadata at the top of the document 4171 */ 4172 showdown.subParser('metadata', function (text, options, globals) { 4173 'use strict'; 4174 4175 if (!options.metadata) { 4176 return text; 4177 } 4178 4179 text = globals.converter._dispatch('metadata.before', text, options, globals); 4180 4181 function parseMetadataContents (content) { 4182 // raw is raw so it's not changed in any way 4183 globals.metadata.raw = content; 4184 4185 // escape chars forbidden in html attributes 4186 // double quotes 4187 content = content 4188 // ampersand first 4189 .replace(/&/g, '&') 4190 // double quotes 4191 .replace(/"/g, '"'); 4192 4193 content = content.replace(/\n {4}/g, ' '); 4194 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) { 4195 globals.metadata.parsed[key] = value; 4196 return ''; 4197 }); 4198 } 4199 4200 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) { 4201 parseMetadataContents(content); 4202 return '¨M'; 4203 }); 4204 4205 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) { 4206 if (format) { 4207 globals.metadata.format = format; 4208 } 4209 parseMetadataContents(content); 4210 return '¨M'; 4211 }); 4212 4213 text = text.replace(/¨M/g, ''); 4214 4215 text = globals.converter._dispatch('metadata.after', text, options, globals); 4216 return text; 4217 }); 4218 4219 /** 4220 * Remove one level of line-leading tabs or spaces 4221 */ 4222 showdown.subParser('outdent', function (text, options, globals) { 4223 'use strict'; 4224 text = globals.converter._dispatch('outdent.before', text, options, globals); 4225 4226 // attacklab: hack around Konqueror 3.5.4 bug: 4227 // "----------bug".replace(/^-/g,"") == "bug" 4228 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width 4229 4230 // attacklab: clean up hack 4231 text = text.replace(/¨0/g, ''); 4232 4233 text = globals.converter._dispatch('outdent.after', text, options, globals); 4234 return text; 4235 }); 4236 4237 /** 4238 * 4239 */ 4240 showdown.subParser('paragraphs', function (text, options, globals) { 4241 'use strict'; 4242 4243 text = globals.converter._dispatch('paragraphs.before', text, options, globals); 4244 // Strip leading and trailing lines: 4245 text = text.replace(/^\n+/g, ''); 4246 text = text.replace(/\n+$/g, ''); 4247 4248 var grafs = text.split(/\n{2,}/g), 4249 grafsOut = [], 4250 end = grafs.length; // Wrap <p> tags 4251 4252 for (var i = 0; i < end; i++) { 4253 var str = grafs[i]; 4254 // if this is an HTML marker, copy it 4255 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) { 4256 grafsOut.push(str); 4257 4258 // test for presence of characters to prevent empty lines being parsed 4259 // as paragraphs (resulting in undesired extra empty paragraphs) 4260 } else if (str.search(/\S/) >= 0) { 4261 str = showdown.subParser('spanGamut')(str, options, globals); 4262 str = str.replace(/^([ \t]*)/g, '<p>'); 4263 str += '</p>'; 4264 grafsOut.push(str); 4265 } 4266 } 4267 4268 /** Unhashify HTML blocks */ 4269 end = grafsOut.length; 4270 for (i = 0; i < end; i++) { 4271 var blockText = '', 4272 grafsOutIt = grafsOut[i], 4273 codeFlag = false; 4274 // if this is a marker for an html block... 4275 // use RegExp.test instead of string.search because of QML bug 4276 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { 4277 var delim = RegExp.$1, 4278 num = RegExp.$2; 4279 4280 if (delim === 'K') { 4281 blockText = globals.gHtmlBlocks[num]; 4282 } else { 4283 // we need to check if ghBlock is a false positive 4284 if (codeFlag) { 4285 // use encoded version of all text 4286 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals); 4287 } else { 4288 blockText = globals.ghCodeBlocks[num].codeblock; 4289 } 4290 } 4291 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs 4292 4293 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); 4294 // Check if grafsOutIt is a pre->code 4295 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { 4296 codeFlag = true; 4297 } 4298 } 4299 grafsOut[i] = grafsOutIt; 4300 } 4301 text = grafsOut.join('\n'); 4302 // Strip leading and trailing lines: 4303 text = text.replace(/^\n+/g, ''); 4304 text = text.replace(/\n+$/g, ''); 4305 return globals.converter._dispatch('paragraphs.after', text, options, globals); 4306 }); 4307 4308 /** 4309 * Run extension 4310 */ 4311 showdown.subParser('runExtension', function (ext, text, options, globals) { 4312 'use strict'; 4313 4314 if (ext.filter) { 4315 text = ext.filter(text, globals.converter, options); 4316 4317 } else if (ext.regex) { 4318 // TODO remove this when old extension loading mechanism is deprecated 4319 var re = ext.regex; 4320 if (!(re instanceof RegExp)) { 4321 re = new RegExp(re, 'g'); 4322 } 4323 text = text.replace(re, ext.replace); 4324 } 4325 4326 return text; 4327 }); 4328 4329 /** 4330 * These are all the transformations that occur *within* block-level 4331 * tags like paragraphs, headers, and list items. 4332 */ 4333 showdown.subParser('spanGamut', function (text, options, globals) { 4334 'use strict'; 4335 4336 text = globals.converter._dispatch('spanGamut.before', text, options, globals); 4337 text = showdown.subParser('codeSpans')(text, options, globals); 4338 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); 4339 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); 4340 4341 // Process anchor and image tags. Images must come first, 4342 // because ![foo][f] looks like an anchor. 4343 text = showdown.subParser('images')(text, options, globals); 4344 text = showdown.subParser('anchors')(text, options, globals); 4345 4346 // Make links out of things like `<http://example.com/>` 4347 // Must come after anchors, because you can use < and > 4348 // delimiters in inline links like [this](<url>). 4349 text = showdown.subParser('autoLinks')(text, options, globals); 4350 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals); 4351 text = showdown.subParser('emoji')(text, options, globals); 4352 text = showdown.subParser('underline')(text, options, globals); 4353 text = showdown.subParser('italicsAndBold')(text, options, globals); 4354 text = showdown.subParser('strikethrough')(text, options, globals); 4355 text = showdown.subParser('ellipsis')(text, options, globals); 4356 4357 // we need to hash HTML tags inside spans 4358 text = showdown.subParser('hashHTMLSpans')(text, options, globals); 4359 4360 // now we encode amps and angles 4361 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); 4362 4363 // Do hard breaks 4364 if (options.simpleLineBreaks) { 4365 // GFM style hard breaks 4366 // only add line breaks if the text does not contain a block (special case for lists) 4367 if (!/\n\n¨K/.test(text)) { 4368 text = text.replace(/\n+/g, '<br />\n'); 4369 } 4370 } else { 4371 // Vanilla hard breaks 4372 text = text.replace(/ +\n/g, '<br />\n'); 4373 } 4374 4375 text = globals.converter._dispatch('spanGamut.after', text, options, globals); 4376 return text; 4377 }); 4378 4379 showdown.subParser('strikethrough', function (text, options, globals) { 4380 'use strict'; 4381 4382 function parseInside (txt) { 4383 if (options.simplifiedAutoLink) { 4384 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4385 } 4386 return '<del>' + txt + '</del>'; 4387 } 4388 4389 if (options.strikethrough) { 4390 text = globals.converter._dispatch('strikethrough.before', text, options, globals); 4391 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); }); 4392 text = globals.converter._dispatch('strikethrough.after', text, options, globals); 4393 } 4394 4395 return text; 4396 }); 4397 4398 /** 4399 * Strips link definitions from text, stores the URLs and titles in 4400 * hash references. 4401 * Link defs are in the form: ^[id]: url "optional title" 4402 */ 4403 showdown.subParser('stripLinkDefinitions', function (text, options, globals) { 4404 'use strict'; 4405 4406 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, 4407 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; 4408 4409 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug 4410 text += '¨0'; 4411 4412 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) { 4413 linkId = linkId.toLowerCase(); 4414 if (url.match(/^data:.+?\/.+?;base64,/)) { 4415 // remove newlines 4416 globals.gUrls[linkId] = url.replace(/\s/g, ''); 4417 } else { 4418 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive 4419 } 4420 4421 if (blankLines) { 4422 // Oops, found blank lines, so it's not a title. 4423 // Put back the parenthetical statement we stole. 4424 return blankLines + title; 4425 4426 } else { 4427 if (title) { 4428 globals.gTitles[linkId] = title.replace(/"|'/g, '"'); 4429 } 4430 if (options.parseImgDimensions && width && height) { 4431 globals.gDimensions[linkId] = { 4432 width: width, 4433 height: height 4434 }; 4435 } 4436 } 4437 // Completely remove the definition from the text 4438 return ''; 4439 }; 4440 4441 // first we try to find base64 link references 4442 text = text.replace(base64Regex, replaceFunc); 4443 4444 text = text.replace(regex, replaceFunc); 4445 4446 // attacklab: strip sentinel 4447 text = text.replace(/¨0/, ''); 4448 4449 return text; 4450 }); 4451 4452 showdown.subParser('tables', function (text, options, globals) { 4453 'use strict'; 4454 4455 if (!options.tables) { 4456 return text; 4457 } 4458 4459 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, 4460 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm; 4461 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm; 4462 4463 function parseStyles (sLine) { 4464 if (/^:[ \t]*--*$/.test(sLine)) { 4465 return ' style="text-align:left;"'; 4466 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { 4467 return ' style="text-align:right;"'; 4468 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { 4469 return ' style="text-align:center;"'; 4470 } else { 4471 return ''; 4472 } 4473 } 4474 4475 function parseHeaders (header, style) { 4476 var id = ''; 4477 header = header.trim(); 4478 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility 4479 if (options.tablesHeaderId || options.tableHeaderId) { 4480 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; 4481 } 4482 header = showdown.subParser('spanGamut')(header, options, globals); 4483 4484 return '<th' + id + style + '>' + header + '</th>\n'; 4485 } 4486 4487 function parseCells (cell, style) { 4488 var subText = showdown.subParser('spanGamut')(cell, options, globals); 4489 return '<td' + style + '>' + subText + '</td>\n'; 4490 } 4491 4492 function buildTable (headers, cells) { 4493 var tb = '<table>\n<thead>\n<tr>\n', 4494 tblLgn = headers.length; 4495 4496 for (var i = 0; i < tblLgn; ++i) { 4497 tb += headers[i]; 4498 } 4499 tb += '</tr>\n</thead>\n<tbody>\n'; 4500 4501 for (i = 0; i < cells.length; ++i) { 4502 tb += '<tr>\n'; 4503 for (var ii = 0; ii < tblLgn; ++ii) { 4504 tb += cells[i][ii]; 4505 } 4506 tb += '</tr>\n'; 4507 } 4508 tb += '</tbody>\n</table>\n'; 4509 return tb; 4510 } 4511 4512 function parseTable (rawTable) { 4513 var i, tableLines = rawTable.split('\n'); 4514 4515 for (i = 0; i < tableLines.length; ++i) { 4516 // strip wrong first and last column if wrapped tables are used 4517 if (/^ {0,3}\|/.test(tableLines[i])) { 4518 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); 4519 } 4520 if (/\|[ \t]*$/.test(tableLines[i])) { 4521 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); 4522 } 4523 // parse code spans first, but we only support one line code spans 4524 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals); 4525 } 4526 4527 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), 4528 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), 4529 rawCells = [], 4530 headers = [], 4531 styles = [], 4532 cells = []; 4533 4534 tableLines.shift(); 4535 tableLines.shift(); 4536 4537 for (i = 0; i < tableLines.length; ++i) { 4538 if (tableLines[i].trim() === '') { 4539 continue; 4540 } 4541 rawCells.push( 4542 tableLines[i] 4543 .split('|') 4544 .map(function (s) { 4545 return s.trim(); 4546 }) 4547 ); 4548 } 4549 4550 if (rawHeaders.length < rawStyles.length) { 4551 return rawTable; 4552 } 4553 4554 for (i = 0; i < rawStyles.length; ++i) { 4555 styles.push(parseStyles(rawStyles[i])); 4556 } 4557 4558 for (i = 0; i < rawHeaders.length; ++i) { 4559 if (showdown.helper.isUndefined(styles[i])) { 4560 styles[i] = ''; 4561 } 4562 headers.push(parseHeaders(rawHeaders[i], styles[i])); 4563 } 4564 4565 for (i = 0; i < rawCells.length; ++i) { 4566 var row = []; 4567 for (var ii = 0; ii < headers.length; ++ii) { 4568 if (showdown.helper.isUndefined(rawCells[i][ii])) { 4569 4570 } 4571 row.push(parseCells(rawCells[i][ii], styles[ii])); 4572 } 4573 cells.push(row); 4574 } 4575 4576 return buildTable(headers, cells); 4577 } 4578 4579 text = globals.converter._dispatch('tables.before', text, options, globals); 4580 4581 // find escaped pipe characters 4582 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback); 4583 4584 // parse multi column tables 4585 text = text.replace(tableRgx, parseTable); 4586 4587 // parse one column tables 4588 text = text.replace(singeColTblRgx, parseTable); 4589 4590 text = globals.converter._dispatch('tables.after', text, options, globals); 4591 4592 return text; 4593 }); 4594 4595 showdown.subParser('underline', function (text, options, globals) { 4596 'use strict'; 4597 4598 if (!options.underline) { 4599 return text; 4600 } 4601 4602 text = globals.converter._dispatch('underline.before', text, options, globals); 4603 4604 if (options.literalMidWordUnderscores) { 4605 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 4606 return '<u>' + txt + '</u>'; 4607 }); 4608 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 4609 return '<u>' + txt + '</u>'; 4610 }); 4611 } else { 4612 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 4613 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 4614 }); 4615 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 4616 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 4617 }); 4618 } 4619 4620 // escape remaining underscores to prevent them being parsed by italic and bold 4621 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback); 4622 4623 text = globals.converter._dispatch('underline.after', text, options, globals); 4624 4625 return text; 4626 }); 4627 4628 /** 4629 * Swap back in all the special characters we've hidden. 4630 */ 4631 showdown.subParser('unescapeSpecialChars', function (text, options, globals) { 4632 'use strict'; 4633 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals); 4634 4635 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) { 4636 var charCodeToReplace = parseInt(m1); 4637 return String.fromCharCode(charCodeToReplace); 4638 }); 4639 4640 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals); 4641 return text; 4642 }); 4643 4644 showdown.subParser('makeMarkdown.blockquote', function (node, globals) { 4645 'use strict'; 4646 4647 var txt = ''; 4648 if (node.hasChildNodes()) { 4649 var children = node.childNodes, 4650 childrenLength = children.length; 4651 4652 for (var i = 0; i < childrenLength; ++i) { 4653 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals); 4654 4655 if (innerTxt === '') { 4656 continue; 4657 } 4658 txt += innerTxt; 4659 } 4660 } 4661 // cleanup 4662 txt = txt.trim(); 4663 txt = '> ' + txt.split('\n').join('\n> '); 4664 return txt; 4665 }); 4666 4667 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) { 4668 'use strict'; 4669 4670 var lang = node.getAttribute('language'), 4671 num = node.getAttribute('precodenum'); 4672 return '```' + lang + '\n' + globals.preList[num] + '\n```'; 4673 }); 4674 4675 showdown.subParser('makeMarkdown.codeSpan', function (node) { 4676 'use strict'; 4677 4678 return '`' + node.innerHTML + '`'; 4679 }); 4680 4681 showdown.subParser('makeMarkdown.emphasis', function (node, globals) { 4682 'use strict'; 4683 4684 var txt = ''; 4685 if (node.hasChildNodes()) { 4686 txt += '*'; 4687 var children = node.childNodes, 4688 childrenLength = children.length; 4689 for (var i = 0; i < childrenLength; ++i) { 4690 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4691 } 4692 txt += '*'; 4693 } 4694 return txt; 4695 }); 4696 4697 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) { 4698 'use strict'; 4699 4700 var headerMark = new Array(headerLevel + 1).join('#'), 4701 txt = ''; 4702 4703 if (node.hasChildNodes()) { 4704 txt = headerMark + ' '; 4705 var children = node.childNodes, 4706 childrenLength = children.length; 4707 4708 for (var i = 0; i < childrenLength; ++i) { 4709 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4710 } 4711 } 4712 return txt; 4713 }); 4714 4715 showdown.subParser('makeMarkdown.hr', function () { 4716 'use strict'; 4717 4718 return '---'; 4719 }); 4720 4721 showdown.subParser('makeMarkdown.image', function (node) { 4722 'use strict'; 4723 4724 var txt = ''; 4725 if (node.hasAttribute('src')) { 4726 txt += ' + '>'; 4728 if (node.hasAttribute('width') && node.hasAttribute('height')) { 4729 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height'); 4730 } 4731 4732 if (node.hasAttribute('title')) { 4733 txt += ' "' + node.getAttribute('title') + '"'; 4734 } 4735 txt += ')'; 4736 } 4737 return txt; 4738 }); 4739 4740 showdown.subParser('makeMarkdown.links', function (node, globals) { 4741 'use strict'; 4742 4743 var txt = ''; 4744 if (node.hasChildNodes() && node.hasAttribute('href')) { 4745 var children = node.childNodes, 4746 childrenLength = children.length; 4747 txt = '['; 4748 for (var i = 0; i < childrenLength; ++i) { 4749 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4750 } 4751 txt += ']('; 4752 txt += '<' + node.getAttribute('href') + '>'; 4753 if (node.hasAttribute('title')) { 4754 txt += ' "' + node.getAttribute('title') + '"'; 4755 } 4756 txt += ')'; 4757 } 4758 return txt; 4759 }); 4760 4761 showdown.subParser('makeMarkdown.list', function (node, globals, type) { 4762 'use strict'; 4763 4764 var txt = ''; 4765 if (!node.hasChildNodes()) { 4766 return ''; 4767 } 4768 var listItems = node.childNodes, 4769 listItemsLenght = listItems.length, 4770 listNum = node.getAttribute('start') || 1; 4771 4772 for (var i = 0; i < listItemsLenght; ++i) { 4773 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') { 4774 continue; 4775 } 4776 4777 // define the bullet to use in list 4778 var bullet = ''; 4779 if (type === 'ol') { 4780 bullet = listNum.toString() + '. '; 4781 } else { 4782 bullet = '- '; 4783 } 4784 4785 // parse list item 4786 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals); 4787 ++listNum; 4788 } 4789 4790 // add comment at the end to prevent consecutive lists to be parsed as one 4791 txt += '\n<!-- -->\n'; 4792 return txt.trim(); 4793 }); 4794 4795 showdown.subParser('makeMarkdown.listItem', function (node, globals) { 4796 'use strict'; 4797 4798 var listItemTxt = ''; 4799 4800 var children = node.childNodes, 4801 childrenLenght = children.length; 4802 4803 for (var i = 0; i < childrenLenght; ++i) { 4804 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4805 } 4806 // if it's only one liner, we need to add a newline at the end 4807 if (!/\n$/.test(listItemTxt)) { 4808 listItemTxt += '\n'; 4809 } else { 4810 // it's multiparagraph, so we need to indent 4811 listItemTxt = listItemTxt 4812 .split('\n') 4813 .join('\n ') 4814 .replace(/^ {4}$/gm, '') 4815 .replace(/\n\n+/g, '\n\n'); 4816 } 4817 4818 return listItemTxt; 4819 }); 4820 4821 4822 4823 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) { 4824 'use strict'; 4825 4826 spansOnly = spansOnly || false; 4827 4828 var txt = ''; 4829 4830 // edge case of text without wrapper paragraph 4831 if (node.nodeType === 3) { 4832 return showdown.subParser('makeMarkdown.txt')(node, globals); 4833 } 4834 4835 // HTML comment 4836 if (node.nodeType === 8) { 4837 return '<!--' + node.data + '-->\n\n'; 4838 } 4839 4840 // process only node elements 4841 if (node.nodeType !== 1) { 4842 return ''; 4843 } 4844 4845 var tagName = node.tagName.toLowerCase(); 4846 4847 switch (tagName) { 4848 4849 // 4850 // BLOCKS 4851 // 4852 case 'h1': 4853 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; } 4854 break; 4855 case 'h2': 4856 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; } 4857 break; 4858 case 'h3': 4859 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; } 4860 break; 4861 case 'h4': 4862 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; } 4863 break; 4864 case 'h5': 4865 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; } 4866 break; 4867 case 'h6': 4868 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; } 4869 break; 4870 4871 case 'p': 4872 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; } 4873 break; 4874 4875 case 'blockquote': 4876 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; } 4877 break; 4878 4879 case 'hr': 4880 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; } 4881 break; 4882 4883 case 'ol': 4884 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; } 4885 break; 4886 4887 case 'ul': 4888 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; } 4889 break; 4890 4891 case 'precode': 4892 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; } 4893 break; 4894 4895 case 'pre': 4896 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; } 4897 break; 4898 4899 case 'table': 4900 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; } 4901 break; 4902 4903 // 4904 // SPANS 4905 // 4906 case 'code': 4907 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals); 4908 break; 4909 4910 case 'em': 4911 case 'i': 4912 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals); 4913 break; 4914 4915 case 'strong': 4916 case 'b': 4917 txt = showdown.subParser('makeMarkdown.strong')(node, globals); 4918 break; 4919 4920 case 'del': 4921 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals); 4922 break; 4923 4924 case 'a': 4925 txt = showdown.subParser('makeMarkdown.links')(node, globals); 4926 break; 4927 4928 case 'img': 4929 txt = showdown.subParser('makeMarkdown.image')(node, globals); 4930 break; 4931 4932 default: 4933 txt = node.outerHTML + '\n\n'; 4934 } 4935 4936 // common normalization 4937 // TODO eventually 4938 4939 return txt; 4940 }); 4941 4942 showdown.subParser('makeMarkdown.paragraph', function (node, globals) { 4943 'use strict'; 4944 4945 var txt = ''; 4946 if (node.hasChildNodes()) { 4947 var children = node.childNodes, 4948 childrenLength = children.length; 4949 for (var i = 0; i < childrenLength; ++i) { 4950 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4951 } 4952 } 4953 4954 // some text normalization 4955 txt = txt.trim(); 4956 4957 return txt; 4958 }); 4959 4960 showdown.subParser('makeMarkdown.pre', function (node, globals) { 4961 'use strict'; 4962 4963 var num = node.getAttribute('prenum'); 4964 return '<pre>' + globals.preList[num] + '</pre>'; 4965 }); 4966 4967 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { 4968 'use strict'; 4969 4970 var txt = ''; 4971 if (node.hasChildNodes()) { 4972 txt += '~~'; 4973 var children = node.childNodes, 4974 childrenLength = children.length; 4975 for (var i = 0; i < childrenLength; ++i) { 4976 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4977 } 4978 txt += '~~'; 4979 } 4980 return txt; 4981 }); 4982 4983 showdown.subParser('makeMarkdown.strong', function (node, globals) { 4984 'use strict'; 4985 4986 var txt = ''; 4987 if (node.hasChildNodes()) { 4988 txt += '**'; 4989 var children = node.childNodes, 4990 childrenLength = children.length; 4991 for (var i = 0; i < childrenLength; ++i) { 4992 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4993 } 4994 txt += '**'; 4995 } 4996 return txt; 4997 }); 4998 4999 showdown.subParser('makeMarkdown.table', function (node, globals) { 5000 'use strict'; 5001 5002 var txt = '', 5003 tableArray = [[], []], 5004 headings = node.querySelectorAll('thead>tr>th'), 5005 rows = node.querySelectorAll('tbody>tr'), 5006 i, ii; 5007 for (i = 0; i < headings.length; ++i) { 5008 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals), 5009 allign = '---'; 5010 5011 if (headings[i].hasAttribute('style')) { 5012 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, ''); 5013 switch (style) { 5014 case 'text-align:left;': 5015 allign = ':---'; 5016 break; 5017 case 'text-align:right;': 5018 allign = '---:'; 5019 break; 5020 case 'text-align:center;': 5021 allign = ':---:'; 5022 break; 5023 } 5024 } 5025 tableArray[0][i] = headContent.trim(); 5026 tableArray[1][i] = allign; 5027 } 5028 5029 for (i = 0; i < rows.length; ++i) { 5030 var r = tableArray.push([]) - 1, 5031 cols = rows[i].getElementsByTagName('td'); 5032 5033 for (ii = 0; ii < headings.length; ++ii) { 5034 var cellContent = ' '; 5035 if (typeof cols[ii] !== 'undefined') { 5036 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals); 5037 } 5038 tableArray[r].push(cellContent); 5039 } 5040 } 5041 5042 var cellSpacesCount = 3; 5043 for (i = 0; i < tableArray.length; ++i) { 5044 for (ii = 0; ii < tableArray[i].length; ++ii) { 5045 var strLen = tableArray[i][ii].length; 5046 if (strLen > cellSpacesCount) { 5047 cellSpacesCount = strLen; 5048 } 5049 } 5050 } 5051 5052 for (i = 0; i < tableArray.length; ++i) { 5053 for (ii = 0; ii < tableArray[i].length; ++ii) { 5054 if (i === 1) { 5055 if (tableArray[i][ii].slice(-1) === ':') { 5056 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':'; 5057 } else { 5058 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-'); 5059 } 5060 } else { 5061 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount); 5062 } 5063 } 5064 txt += '| ' + tableArray[i].join(' | ') + ' |\n'; 5065 } 5066 5067 return txt.trim(); 5068 }); 5069 5070 showdown.subParser('makeMarkdown.tableCell', function (node, globals) { 5071 'use strict'; 5072 5073 var txt = ''; 5074 if (!node.hasChildNodes()) { 5075 return ''; 5076 } 5077 var children = node.childNodes, 5078 childrenLength = children.length; 5079 5080 for (var i = 0; i < childrenLength; ++i) { 5081 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true); 5082 } 5083 return txt.trim(); 5084 }); 5085 5086 showdown.subParser('makeMarkdown.txt', function (node) { 5087 'use strict'; 5088 5089 var txt = node.nodeValue; 5090 5091 // multiple spaces are collapsed 5092 txt = txt.replace(/ +/g, ' '); 5093 5094 // replace the custom ¨NBSP; with a space 5095 txt = txt.replace(/¨NBSP;/g, ' '); 5096 5097 // ", <, > and & should replace escaped html entities 5098 txt = showdown.helper.unescapeHTMLEntities(txt); 5099 5100 // escape markdown magic characters 5101 // emphasis, strong and strikethrough - can appear everywhere 5102 // we also escape pipe (|) because of tables 5103 // and escape ` because of code blocks and spans 5104 txt = txt.replace(/([*_~|`])/g, '\\$1'); 5105 5106 // escape > because of blockquotes 5107 txt = txt.replace(/^(\s*)>/g, '\\$1>'); 5108 5109 // hash character, only troublesome at the beginning of a line because of headers 5110 txt = txt.replace(/^#/gm, '\\#'); 5111 5112 // horizontal rules 5113 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3'); 5114 5115 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer 5116 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.'); 5117 5118 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped) 5119 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2'); 5120 5121 // images and links, ] followed by ( is problematic, so we escape it 5122 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\('); 5123 5124 // reference URIs must also be escaped 5125 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:'); 5126 5127 return txt; 5128 }); 5129 5130 var root = this; 5131 5132 // AMD Loader 5133 if (true) { 5134 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { 5135 'use strict'; 5136 return showdown; 5137 }).call(exports, __webpack_require__, exports, module), 5138 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 5139 5140 // CommonJS/nodeJS Loader 5141 } else {} 5142 }).call(this); 5143 5144 5145 5146 5147 /***/ }), 5148 5149 /***/ 5373: 5150 /***/ ((__unused_webpack_module, exports) => { 5151 5152 "use strict"; 5153 var __webpack_unused_export__; 5154 /** 5155 * @license React 5156 * react-is.production.min.js 5157 * 5158 * Copyright (c) Facebook, Inc. and its affiliates. 5159 * 5160 * This source code is licensed under the MIT license found in the 5161 * LICENSE file in the root directory of this source tree. 5162 */ 5163 var b=Symbol.for("react.element"),c=Symbol.for("react.portal"),d=Symbol.for("react.fragment"),e=Symbol.for("react.strict_mode"),f=Symbol.for("react.profiler"),g=Symbol.for("react.provider"),h=Symbol.for("react.context"),k=Symbol.for("react.server_context"),l=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),n=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),q=Symbol.for("react.lazy"),t=Symbol.for("react.offscreen"),u;u=Symbol.for("react.module.reference"); 5164 function v(a){if("object"===typeof a&&null!==a){var r=a.$$typeof;switch(r){case b:switch(a=a.type,a){case d:case f:case e:case m:case n:return a;default:switch(a=a&&a.$$typeof,a){case k:case h:case l:case q:case p:case g:return a;default:return r}}case c:return r}}}__webpack_unused_export__=h;__webpack_unused_export__=g;__webpack_unused_export__=b;__webpack_unused_export__=l;__webpack_unused_export__=d;__webpack_unused_export__=q;__webpack_unused_export__=p;__webpack_unused_export__=c;__webpack_unused_export__=f;__webpack_unused_export__=e;__webpack_unused_export__=m; 5165 __webpack_unused_export__=n;__webpack_unused_export__=function(){return!1};__webpack_unused_export__=function(){return!1};__webpack_unused_export__=function(a){return v(a)===h};__webpack_unused_export__=function(a){return v(a)===g};__webpack_unused_export__=function(a){return"object"===typeof a&&null!==a&&a.$$typeof===b};__webpack_unused_export__=function(a){return v(a)===l};__webpack_unused_export__=function(a){return v(a)===d};__webpack_unused_export__=function(a){return v(a)===q};__webpack_unused_export__=function(a){return v(a)===p}; 5166 __webpack_unused_export__=function(a){return v(a)===c};__webpack_unused_export__=function(a){return v(a)===f};__webpack_unused_export__=function(a){return v(a)===e};__webpack_unused_export__=function(a){return v(a)===m};__webpack_unused_export__=function(a){return v(a)===n}; 5167 exports.isValidElementType=function(a){return"string"===typeof a||"function"===typeof a||a===d||a===f||a===e||a===m||a===n||a===t||"object"===typeof a&&null!==a&&(a.$$typeof===q||a.$$typeof===p||a.$$typeof===g||a.$$typeof===h||a.$$typeof===l||a.$$typeof===u||void 0!==a.getModuleId)?!0:!1};__webpack_unused_export__=v; 5168 5169 5170 /***/ }), 5171 5172 /***/ 7734: 5173 /***/ ((module) => { 5174 5175 "use strict"; 5176 5177 5178 // do not edit .js files directly - edit src/index.jst 5179 5180 5181 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; 5182 5183 5184 module.exports = function equal(a, b) { 5185 if (a === b) return true; 5186 5187 if (a && b && typeof a == 'object' && typeof b == 'object') { 5188 if (a.constructor !== b.constructor) return false; 5189 5190 var length, i, keys; 5191 if (Array.isArray(a)) { 5192 length = a.length; 5193 if (length != b.length) return false; 5194 for (i = length; i-- !== 0;) 5195 if (!equal(a[i], b[i])) return false; 5196 return true; 5197 } 5198 5199 5200 if ((a instanceof Map) && (b instanceof Map)) { 5201 if (a.size !== b.size) return false; 5202 for (i of a.entries()) 5203 if (!b.has(i[0])) return false; 5204 for (i of a.entries()) 5205 if (!equal(i[1], b.get(i[0]))) return false; 5206 return true; 5207 } 5208 5209 if ((a instanceof Set) && (b instanceof Set)) { 5210 if (a.size !== b.size) return false; 5211 for (i of a.entries()) 5212 if (!b.has(i[0])) return false; 5213 return true; 5214 } 5215 5216 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 5217 length = a.length; 5218 if (length != b.length) return false; 5219 for (i = length; i-- !== 0;) 5220 if (a[i] !== b[i]) return false; 5221 return true; 5222 } 5223 5224 5225 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 5226 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 5227 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 5228 5229 keys = Object.keys(a); 5230 length = keys.length; 5231 if (length !== Object.keys(b).length) return false; 5232 5233 for (i = length; i-- !== 0;) 5234 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 5235 5236 for (i = length; i-- !== 0;) { 5237 var key = keys[i]; 5238 5239 if (!equal(a[key], b[key])) return false; 5240 } 5241 5242 return true; 5243 } 5244 5245 // true if both NaN, false otherwise 5246 return a!==a && b!==b; 5247 }; 5248 5249 5250 /***/ }), 5251 5252 /***/ 8529: 5253 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 5254 5255 "use strict"; 5256 5257 5258 if (true) { 5259 module.exports = __webpack_require__(5373); 5260 } else {} 5261 5262 5263 /***/ }), 5264 5265 /***/ 9681: 5266 /***/ ((module) => { 5267 5268 var characterMap = { 5269 "À": "A", 5270 "Á": "A", 5271 "Â": "A", 5272 "Ã": "A", 5273 "Ä": "A", 5274 "Å": "A", 5275 "Ấ": "A", 5276 "Ắ": "A", 5277 "Ẳ": "A", 5278 "Ẵ": "A", 5279 "Ặ": "A", 5280 "Æ": "AE", 5281 "Ầ": "A", 5282 "Ằ": "A", 5283 "Ȃ": "A", 5284 "Ả": "A", 5285 "Ạ": "A", 5286 "Ẩ": "A", 5287 "Ẫ": "A", 5288 "Ậ": "A", 5289 "Ç": "C", 5290 "Ḉ": "C", 5291 "È": "E", 5292 "É": "E", 5293 "Ê": "E", 5294 "Ë": "E", 5295 "Ế": "E", 5296 "Ḗ": "E", 5297 "Ề": "E", 5298 "Ḕ": "E", 5299 "Ḝ": "E", 5300 "Ȇ": "E", 5301 "Ẻ": "E", 5302 "Ẽ": "E", 5303 "Ẹ": "E", 5304 "Ể": "E", 5305 "Ễ": "E", 5306 "Ệ": "E", 5307 "Ì": "I", 5308 "Í": "I", 5309 "Î": "I", 5310 "Ï": "I", 5311 "Ḯ": "I", 5312 "Ȋ": "I", 5313 "Ỉ": "I", 5314 "Ị": "I", 5315 "Ð": "D", 5316 "Ñ": "N", 5317 "Ò": "O", 5318 "Ó": "O", 5319 "Ô": "O", 5320 "Õ": "O", 5321 "Ö": "O", 5322 "Ø": "O", 5323 "Ố": "O", 5324 "Ṍ": "O", 5325 "Ṓ": "O", 5326 "Ȏ": "O", 5327 "Ỏ": "O", 5328 "Ọ": "O", 5329 "Ổ": "O", 5330 "Ỗ": "O", 5331 "Ộ": "O", 5332 "Ờ": "O", 5333 "Ở": "O", 5334 "Ỡ": "O", 5335 "Ớ": "O", 5336 "Ợ": "O", 5337 "Ù": "U", 5338 "Ú": "U", 5339 "Û": "U", 5340 "Ü": "U", 5341 "Ủ": "U", 5342 "Ụ": "U", 5343 "Ử": "U", 5344 "Ữ": "U", 5345 "Ự": "U", 5346 "Ý": "Y", 5347 "à": "a", 5348 "á": "a", 5349 "â": "a", 5350 "ã": "a", 5351 "ä": "a", 5352 "å": "a", 5353 "ấ": "a", 5354 "ắ": "a", 5355 "ẳ": "a", 5356 "ẵ": "a", 5357 "ặ": "a", 5358 "æ": "ae", 5359 "ầ": "a", 5360 "ằ": "a", 5361 "ȃ": "a", 5362 "ả": "a", 5363 "ạ": "a", 5364 "ẩ": "a", 5365 "ẫ": "a", 5366 "ậ": "a", 5367 "ç": "c", 5368 "ḉ": "c", 5369 "è": "e", 5370 "é": "e", 5371 "ê": "e", 5372 "ë": "e", 5373 "ế": "e", 5374 "ḗ": "e", 5375 "ề": "e", 5376 "ḕ": "e", 5377 "ḝ": "e", 5378 "ȇ": "e", 5379 "ẻ": "e", 5380 "ẽ": "e", 5381 "ẹ": "e", 5382 "ể": "e", 5383 "ễ": "e", 5384 "ệ": "e", 5385 "ì": "i", 5386 "í": "i", 5387 "î": "i", 5388 "ï": "i", 5389 "ḯ": "i", 5390 "ȋ": "i", 5391 "ỉ": "i", 5392 "ị": "i", 5393 "ð": "d", 5394 "ñ": "n", 5395 "ò": "o", 5396 "ó": "o", 5397 "ô": "o", 5398 "õ": "o", 5399 "ö": "o", 5400 "ø": "o", 5401 "ố": "o", 5402 "ṍ": "o", 5403 "ṓ": "o", 5404 "ȏ": "o", 5405 "ỏ": "o", 5406 "ọ": "o", 5407 "ổ": "o", 5408 "ỗ": "o", 5409 "ộ": "o", 5410 "ờ": "o", 5411 "ở": "o", 5412 "ỡ": "o", 5413 "ớ": "o", 5414 "ợ": "o", 5415 "ù": "u", 5416 "ú": "u", 5417 "û": "u", 5418 "ü": "u", 5419 "ủ": "u", 5420 "ụ": "u", 5421 "ử": "u", 5422 "ữ": "u", 5423 "ự": "u", 5424 "ý": "y", 5425 "ÿ": "y", 5426 "Ā": "A", 5427 "ā": "a", 5428 "Ă": "A", 5429 "ă": "a", 5430 "Ą": "A", 5431 "ą": "a", 5432 "Ć": "C", 5433 "ć": "c", 5434 "Ĉ": "C", 5435 "ĉ": "c", 5436 "Ċ": "C", 5437 "ċ": "c", 5438 "Č": "C", 5439 "č": "c", 5440 "C̆": "C", 5441 "c̆": "c", 5442 "Ď": "D", 5443 "ď": "d", 5444 "Đ": "D", 5445 "đ": "d", 5446 "Ē": "E", 5447 "ē": "e", 5448 "Ĕ": "E", 5449 "ĕ": "e", 5450 "Ė": "E", 5451 "ė": "e", 5452 "Ę": "E", 5453 "ę": "e", 5454 "Ě": "E", 5455 "ě": "e", 5456 "Ĝ": "G", 5457 "Ǵ": "G", 5458 "ĝ": "g", 5459 "ǵ": "g", 5460 "Ğ": "G", 5461 "ğ": "g", 5462 "Ġ": "G", 5463 "ġ": "g", 5464 "Ģ": "G", 5465 "ģ": "g", 5466 "Ĥ": "H", 5467 "ĥ": "h", 5468 "Ħ": "H", 5469 "ħ": "h", 5470 "Ḫ": "H", 5471 "ḫ": "h", 5472 "Ĩ": "I", 5473 "ĩ": "i", 5474 "Ī": "I", 5475 "ī": "i", 5476 "Ĭ": "I", 5477 "ĭ": "i", 5478 "Į": "I", 5479 "į": "i", 5480 "İ": "I", 5481 "ı": "i", 5482 "IJ": "IJ", 5483 "ij": "ij", 5484 "Ĵ": "J", 5485 "ĵ": "j", 5486 "Ķ": "K", 5487 "ķ": "k", 5488 "Ḱ": "K", 5489 "ḱ": "k", 5490 "K̆": "K", 5491 "k̆": "k", 5492 "Ĺ": "L", 5493 "ĺ": "l", 5494 "Ļ": "L", 5495 "ļ": "l", 5496 "Ľ": "L", 5497 "ľ": "l", 5498 "Ŀ": "L", 5499 "ŀ": "l", 5500 "Ł": "l", 5501 "ł": "l", 5502 "Ḿ": "M", 5503 "ḿ": "m", 5504 "M̆": "M", 5505 "m̆": "m", 5506 "Ń": "N", 5507 "ń": "n", 5508 "Ņ": "N", 5509 "ņ": "n", 5510 "Ň": "N", 5511 "ň": "n", 5512 "ʼn": "n", 5513 "N̆": "N", 5514 "n̆": "n", 5515 "Ō": "O", 5516 "ō": "o", 5517 "Ŏ": "O", 5518 "ŏ": "o", 5519 "Ő": "O", 5520 "ő": "o", 5521 "Œ": "OE", 5522 "œ": "oe", 5523 "P̆": "P", 5524 "p̆": "p", 5525 "Ŕ": "R", 5526 "ŕ": "r", 5527 "Ŗ": "R", 5528 "ŗ": "r", 5529 "Ř": "R", 5530 "ř": "r", 5531 "R̆": "R", 5532 "r̆": "r", 5533 "Ȓ": "R", 5534 "ȓ": "r", 5535 "Ś": "S", 5536 "ś": "s", 5537 "Ŝ": "S", 5538 "ŝ": "s", 5539 "Ş": "S", 5540 "Ș": "S", 5541 "ș": "s", 5542 "ş": "s", 5543 "Š": "S", 5544 "š": "s", 5545 "Ţ": "T", 5546 "ţ": "t", 5547 "ț": "t", 5548 "Ț": "T", 5549 "Ť": "T", 5550 "ť": "t", 5551 "Ŧ": "T", 5552 "ŧ": "t", 5553 "T̆": "T", 5554 "t̆": "t", 5555 "Ũ": "U", 5556 "ũ": "u", 5557 "Ū": "U", 5558 "ū": "u", 5559 "Ŭ": "U", 5560 "ŭ": "u", 5561 "Ů": "U", 5562 "ů": "u", 5563 "Ű": "U", 5564 "ű": "u", 5565 "Ų": "U", 5566 "ų": "u", 5567 "Ȗ": "U", 5568 "ȗ": "u", 5569 "V̆": "V", 5570 "v̆": "v", 5571 "Ŵ": "W", 5572 "ŵ": "w", 5573 "Ẃ": "W", 5574 "ẃ": "w", 5575 "X̆": "X", 5576 "x̆": "x", 5577 "Ŷ": "Y", 5578 "ŷ": "y", 5579 "Ÿ": "Y", 5580 "Y̆": "Y", 5581 "y̆": "y", 5582 "Ź": "Z", 5583 "ź": "z", 5584 "Ż": "Z", 5585 "ż": "z", 5586 "Ž": "Z", 5587 "ž": "z", 5588 "ſ": "s", 5589 "ƒ": "f", 5590 "Ơ": "O", 5591 "ơ": "o", 5592 "Ư": "U", 5593 "ư": "u", 5594 "Ǎ": "A", 5595 "ǎ": "a", 5596 "Ǐ": "I", 5597 "ǐ": "i", 5598 "Ǒ": "O", 5599 "ǒ": "o", 5600 "Ǔ": "U", 5601 "ǔ": "u", 5602 "Ǖ": "U", 5603 "ǖ": "u", 5604 "Ǘ": "U", 5605 "ǘ": "u", 5606 "Ǚ": "U", 5607 "ǚ": "u", 5608 "Ǜ": "U", 5609 "ǜ": "u", 5610 "Ứ": "U", 5611 "ứ": "u", 5612 "Ṹ": "U", 5613 "ṹ": "u", 5614 "Ǻ": "A", 5615 "ǻ": "a", 5616 "Ǽ": "AE", 5617 "ǽ": "ae", 5618 "Ǿ": "O", 5619 "ǿ": "o", 5620 "Þ": "TH", 5621 "þ": "th", 5622 "Ṕ": "P", 5623 "ṕ": "p", 5624 "Ṥ": "S", 5625 "ṥ": "s", 5626 "X́": "X", 5627 "x́": "x", 5628 "Ѓ": "Г", 5629 "ѓ": "г", 5630 "Ќ": "К", 5631 "ќ": "к", 5632 "A̋": "A", 5633 "a̋": "a", 5634 "E̋": "E", 5635 "e̋": "e", 5636 "I̋": "I", 5637 "i̋": "i", 5638 "Ǹ": "N", 5639 "ǹ": "n", 5640 "Ồ": "O", 5641 "ồ": "o", 5642 "Ṑ": "O", 5643 "ṑ": "o", 5644 "Ừ": "U", 5645 "ừ": "u", 5646 "Ẁ": "W", 5647 "ẁ": "w", 5648 "Ỳ": "Y", 5649 "ỳ": "y", 5650 "Ȁ": "A", 5651 "ȁ": "a", 5652 "Ȅ": "E", 5653 "ȅ": "e", 5654 "Ȉ": "I", 5655 "ȉ": "i", 5656 "Ȍ": "O", 5657 "ȍ": "o", 5658 "Ȑ": "R", 5659 "ȑ": "r", 5660 "Ȕ": "U", 5661 "ȕ": "u", 5662 "B̌": "B", 5663 "b̌": "b", 5664 "Č̣": "C", 5665 "č̣": "c", 5666 "Ê̌": "E", 5667 "ê̌": "e", 5668 "F̌": "F", 5669 "f̌": "f", 5670 "Ǧ": "G", 5671 "ǧ": "g", 5672 "Ȟ": "H", 5673 "ȟ": "h", 5674 "J̌": "J", 5675 "ǰ": "j", 5676 "Ǩ": "K", 5677 "ǩ": "k", 5678 "M̌": "M", 5679 "m̌": "m", 5680 "P̌": "P", 5681 "p̌": "p", 5682 "Q̌": "Q", 5683 "q̌": "q", 5684 "Ř̩": "R", 5685 "ř̩": "r", 5686 "Ṧ": "S", 5687 "ṧ": "s", 5688 "V̌": "V", 5689 "v̌": "v", 5690 "W̌": "W", 5691 "w̌": "w", 5692 "X̌": "X", 5693 "x̌": "x", 5694 "Y̌": "Y", 5695 "y̌": "y", 5696 "A̧": "A", 5697 "a̧": "a", 5698 "B̧": "B", 5699 "b̧": "b", 5700 "Ḑ": "D", 5701 "ḑ": "d", 5702 "Ȩ": "E", 5703 "ȩ": "e", 5704 "Ɛ̧": "E", 5705 "ɛ̧": "e", 5706 "Ḩ": "H", 5707 "ḩ": "h", 5708 "I̧": "I", 5709 "i̧": "i", 5710 "Ɨ̧": "I", 5711 "ɨ̧": "i", 5712 "M̧": "M", 5713 "m̧": "m", 5714 "O̧": "O", 5715 "o̧": "o", 5716 "Q̧": "Q", 5717 "q̧": "q", 5718 "U̧": "U", 5719 "u̧": "u", 5720 "X̧": "X", 5721 "x̧": "x", 5722 "Z̧": "Z", 5723 "z̧": "z", 5724 "й":"и", 5725 "Й":"И", 5726 "ё":"е", 5727 "Ё":"Е", 5728 }; 5729 5730 var chars = Object.keys(characterMap).join('|'); 5731 var allAccents = new RegExp(chars, 'g'); 5732 var firstAccent = new RegExp(chars, ''); 5733 5734 function matcher(match) { 5735 return characterMap[match]; 5736 } 5737 5738 var removeAccents = function(string) { 5739 return string.replace(allAccents, matcher); 5740 }; 5741 5742 var hasAccents = function(string) { 5743 return !!string.match(firstAccent); 5744 }; 5745 5746 module.exports = removeAccents; 5747 module.exports.has = hasAccents; 5748 module.exports.remove = removeAccents; 5749 5750 5751 /***/ }) 5752 5753 /******/ }); 5754 /************************************************************************/ 5755 /******/ // The module cache 5756 /******/ var __webpack_module_cache__ = {}; 5757 /******/ 5758 /******/ // The require function 5759 /******/ function __webpack_require__(moduleId) { 5760 /******/ // Check if module is in cache 5761 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 5762 /******/ if (cachedModule !== undefined) { 5763 /******/ return cachedModule.exports; 5764 /******/ } 5765 /******/ // Create a new module (and put it into the cache) 5766 /******/ var module = __webpack_module_cache__[moduleId] = { 5767 /******/ // no module.id needed 5768 /******/ // no module.loaded needed 5769 /******/ exports: {} 5770 /******/ }; 5771 /******/ 5772 /******/ // Execute the module function 5773 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 5774 /******/ 5775 /******/ // Return the exports of the module 5776 /******/ return module.exports; 5777 /******/ } 5778 /******/ 5779 /************************************************************************/ 5780 /******/ /* webpack/runtime/compat get default export */ 5781 /******/ (() => { 5782 /******/ // getDefaultExport function for compatibility with non-harmony modules 5783 /******/ __webpack_require__.n = (module) => { 5784 /******/ var getter = module && module.__esModule ? 5785 /******/ () => (module['default']) : 5786 /******/ () => (module); 5787 /******/ __webpack_require__.d(getter, { a: getter }); 5788 /******/ return getter; 5789 /******/ }; 5790 /******/ })(); 5791 /******/ 5792 /******/ /* webpack/runtime/define property getters */ 5793 /******/ (() => { 5794 /******/ // define getter functions for harmony exports 5795 /******/ __webpack_require__.d = (exports, definition) => { 5796 /******/ for(var key in definition) { 5797 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 5798 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 5799 /******/ } 5800 /******/ } 5801 /******/ }; 5802 /******/ })(); 5803 /******/ 5804 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 5805 /******/ (() => { 5806 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 5807 /******/ })(); 5808 /******/ 5809 /******/ /* webpack/runtime/make namespace object */ 5810 /******/ (() => { 5811 /******/ // define __esModule on exports 5812 /******/ __webpack_require__.r = (exports) => { 5813 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5814 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5815 /******/ } 5816 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 5817 /******/ }; 5818 /******/ })(); 5819 /******/ 5820 /************************************************************************/ 5821 var __webpack_exports__ = {}; 5822 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode. 5823 (() => { 5824 "use strict"; 5825 // ESM COMPAT FLAG 5826 __webpack_require__.r(__webpack_exports__); 5827 5828 // EXPORTS 5829 __webpack_require__.d(__webpack_exports__, { 5830 __EXPERIMENTAL_ELEMENTS: () => (/* reexport */ __EXPERIMENTAL_ELEMENTS), 5831 __EXPERIMENTAL_PATHS_WITH_OVERRIDE: () => (/* reexport */ __EXPERIMENTAL_PATHS_WITH_OVERRIDE), 5832 __EXPERIMENTAL_STYLE_PROPERTY: () => (/* reexport */ __EXPERIMENTAL_STYLE_PROPERTY), 5833 __experimentalCloneSanitizedBlock: () => (/* reexport */ __experimentalCloneSanitizedBlock), 5834 __experimentalGetAccessibleBlockLabel: () => (/* reexport */ getAccessibleBlockLabel), 5835 __experimentalGetBlockAttributesNamesByRole: () => (/* reexport */ __experimentalGetBlockAttributesNamesByRole), 5836 __experimentalGetBlockLabel: () => (/* reexport */ getBlockLabel), 5837 __experimentalSanitizeBlockAttributes: () => (/* reexport */ __experimentalSanitizeBlockAttributes), 5838 __unstableGetBlockProps: () => (/* reexport */ getBlockProps), 5839 __unstableGetInnerBlocksProps: () => (/* reexport */ getInnerBlocksProps), 5840 __unstableSerializeAndClean: () => (/* reexport */ __unstableSerializeAndClean), 5841 children: () => (/* reexport */ children), 5842 cloneBlock: () => (/* reexport */ cloneBlock), 5843 createBlock: () => (/* reexport */ createBlock), 5844 createBlocksFromInnerBlocksTemplate: () => (/* reexport */ createBlocksFromInnerBlocksTemplate), 5845 doBlocksMatchTemplate: () => (/* reexport */ doBlocksMatchTemplate), 5846 findTransform: () => (/* reexport */ findTransform), 5847 getBlockAttributes: () => (/* reexport */ getBlockAttributes), 5848 getBlockAttributesNamesByRole: () => (/* reexport */ getBlockAttributesNamesByRole), 5849 getBlockBindingsSource: () => (/* reexport */ getBlockBindingsSource), 5850 getBlockBindingsSources: () => (/* reexport */ getBlockBindingsSources), 5851 getBlockContent: () => (/* reexport */ getBlockInnerHTML), 5852 getBlockDefaultClassName: () => (/* reexport */ getBlockDefaultClassName), 5853 getBlockFromExample: () => (/* reexport */ getBlockFromExample), 5854 getBlockMenuDefaultClassName: () => (/* reexport */ getBlockMenuDefaultClassName), 5855 getBlockSupport: () => (/* reexport */ getBlockSupport), 5856 getBlockTransforms: () => (/* reexport */ getBlockTransforms), 5857 getBlockType: () => (/* reexport */ getBlockType), 5858 getBlockTypes: () => (/* reexport */ getBlockTypes), 5859 getBlockVariations: () => (/* reexport */ getBlockVariations), 5860 getCategories: () => (/* reexport */ categories_getCategories), 5861 getChildBlockNames: () => (/* reexport */ getChildBlockNames), 5862 getDefaultBlockName: () => (/* reexport */ getDefaultBlockName), 5863 getFreeformContentHandlerName: () => (/* reexport */ getFreeformContentHandlerName), 5864 getGroupingBlockName: () => (/* reexport */ getGroupingBlockName), 5865 getPhrasingContentSchema: () => (/* reexport */ deprecatedGetPhrasingContentSchema), 5866 getPossibleBlockTransformations: () => (/* reexport */ getPossibleBlockTransformations), 5867 getSaveContent: () => (/* reexport */ getSaveContent), 5868 getSaveElement: () => (/* reexport */ getSaveElement), 5869 getUnregisteredTypeHandlerName: () => (/* reexport */ getUnregisteredTypeHandlerName), 5870 hasBlockSupport: () => (/* reexport */ hasBlockSupport), 5871 hasChildBlocks: () => (/* reexport */ hasChildBlocks), 5872 hasChildBlocksWithInserterSupport: () => (/* reexport */ hasChildBlocksWithInserterSupport), 5873 isReusableBlock: () => (/* reexport */ isReusableBlock), 5874 isTemplatePart: () => (/* reexport */ isTemplatePart), 5875 isUnmodifiedBlock: () => (/* reexport */ isUnmodifiedBlock), 5876 isUnmodifiedDefaultBlock: () => (/* reexport */ isUnmodifiedDefaultBlock), 5877 isValidBlockContent: () => (/* reexport */ isValidBlockContent), 5878 isValidIcon: () => (/* reexport */ isValidIcon), 5879 node: () => (/* reexport */ node), 5880 normalizeIconObject: () => (/* reexport */ normalizeIconObject), 5881 parse: () => (/* reexport */ parser_parse), 5882 parseWithAttributeSchema: () => (/* reexport */ parseWithAttributeSchema), 5883 pasteHandler: () => (/* reexport */ pasteHandler), 5884 privateApis: () => (/* reexport */ privateApis), 5885 rawHandler: () => (/* reexport */ rawHandler), 5886 registerBlockBindingsSource: () => (/* reexport */ registerBlockBindingsSource), 5887 registerBlockCollection: () => (/* reexport */ registerBlockCollection), 5888 registerBlockStyle: () => (/* reexport */ registerBlockStyle), 5889 registerBlockType: () => (/* reexport */ registerBlockType), 5890 registerBlockVariation: () => (/* reexport */ registerBlockVariation), 5891 serialize: () => (/* reexport */ serialize), 5892 serializeRawBlock: () => (/* reexport */ serializeRawBlock), 5893 setCategories: () => (/* reexport */ categories_setCategories), 5894 setDefaultBlockName: () => (/* reexport */ setDefaultBlockName), 5895 setFreeformContentHandlerName: () => (/* reexport */ setFreeformContentHandlerName), 5896 setGroupingBlockName: () => (/* reexport */ setGroupingBlockName), 5897 setUnregisteredTypeHandlerName: () => (/* reexport */ setUnregisteredTypeHandlerName), 5898 store: () => (/* reexport */ store), 5899 switchToBlockType: () => (/* reexport */ switchToBlockType), 5900 synchronizeBlocksWithTemplate: () => (/* reexport */ synchronizeBlocksWithTemplate), 5901 unregisterBlockBindingsSource: () => (/* reexport */ unregisterBlockBindingsSource), 5902 unregisterBlockStyle: () => (/* reexport */ unregisterBlockStyle), 5903 unregisterBlockType: () => (/* reexport */ unregisterBlockType), 5904 unregisterBlockVariation: () => (/* reexport */ unregisterBlockVariation), 5905 unstable__bootstrapServerSideBlockDefinitions: () => (/* reexport */ unstable__bootstrapServerSideBlockDefinitions), 5906 updateCategory: () => (/* reexport */ categories_updateCategory), 5907 validateBlock: () => (/* reexport */ validateBlock), 5908 withBlockContentContext: () => (/* reexport */ withBlockContentContext) 5909 }); 5910 5911 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 5912 var private_selectors_namespaceObject = {}; 5913 __webpack_require__.r(private_selectors_namespaceObject); 5914 __webpack_require__.d(private_selectors_namespaceObject, { 5915 getAllBlockBindingsSources: () => (getAllBlockBindingsSources), 5916 getBlockBindingsSource: () => (private_selectors_getBlockBindingsSource), 5917 getBootstrappedBlockType: () => (getBootstrappedBlockType), 5918 getSupportedStyles: () => (getSupportedStyles), 5919 getUnprocessedBlockTypes: () => (getUnprocessedBlockTypes), 5920 hasContentRoleAttribute: () => (hasContentRoleAttribute) 5921 }); 5922 5923 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 5924 var selectors_namespaceObject = {}; 5925 __webpack_require__.r(selectors_namespaceObject); 5926 __webpack_require__.d(selectors_namespaceObject, { 5927 __experimentalHasContentRoleAttribute: () => (__experimentalHasContentRoleAttribute), 5928 getActiveBlockVariation: () => (getActiveBlockVariation), 5929 getBlockStyles: () => (getBlockStyles), 5930 getBlockSupport: () => (selectors_getBlockSupport), 5931 getBlockType: () => (selectors_getBlockType), 5932 getBlockTypes: () => (selectors_getBlockTypes), 5933 getBlockVariations: () => (selectors_getBlockVariations), 5934 getCategories: () => (getCategories), 5935 getChildBlockNames: () => (selectors_getChildBlockNames), 5936 getCollections: () => (getCollections), 5937 getDefaultBlockName: () => (selectors_getDefaultBlockName), 5938 getDefaultBlockVariation: () => (getDefaultBlockVariation), 5939 getFreeformFallbackBlockName: () => (getFreeformFallbackBlockName), 5940 getGroupingBlockName: () => (selectors_getGroupingBlockName), 5941 getUnregisteredFallbackBlockName: () => (getUnregisteredFallbackBlockName), 5942 hasBlockSupport: () => (selectors_hasBlockSupport), 5943 hasChildBlocks: () => (selectors_hasChildBlocks), 5944 hasChildBlocksWithInserterSupport: () => (selectors_hasChildBlocksWithInserterSupport), 5945 isMatchingSearchTerm: () => (isMatchingSearchTerm) 5946 }); 5947 5948 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/actions.js 5949 var actions_namespaceObject = {}; 5950 __webpack_require__.r(actions_namespaceObject); 5951 __webpack_require__.d(actions_namespaceObject, { 5952 __experimentalReapplyBlockFilters: () => (__experimentalReapplyBlockFilters), 5953 addBlockCollection: () => (addBlockCollection), 5954 addBlockStyles: () => (addBlockStyles), 5955 addBlockTypes: () => (addBlockTypes), 5956 addBlockVariations: () => (addBlockVariations), 5957 reapplyBlockTypeFilters: () => (reapplyBlockTypeFilters), 5958 removeBlockCollection: () => (removeBlockCollection), 5959 removeBlockStyles: () => (removeBlockStyles), 5960 removeBlockTypes: () => (removeBlockTypes), 5961 removeBlockVariations: () => (removeBlockVariations), 5962 setCategories: () => (setCategories), 5963 setDefaultBlockName: () => (actions_setDefaultBlockName), 5964 setFreeformFallbackBlockName: () => (setFreeformFallbackBlockName), 5965 setGroupingBlockName: () => (actions_setGroupingBlockName), 5966 setUnregisteredFallbackBlockName: () => (setUnregisteredFallbackBlockName), 5967 updateCategory: () => (updateCategory) 5968 }); 5969 5970 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 5971 var private_actions_namespaceObject = {}; 5972 __webpack_require__.r(private_actions_namespaceObject); 5973 __webpack_require__.d(private_actions_namespaceObject, { 5974 addBlockBindingsSource: () => (addBlockBindingsSource), 5975 addBootstrappedBlockType: () => (addBootstrappedBlockType), 5976 addUnprocessedBlockType: () => (addUnprocessedBlockType), 5977 removeBlockBindingsSource: () => (removeBlockBindingsSource) 5978 }); 5979 5980 ;// external ["wp","data"] 5981 const external_wp_data_namespaceObject = window["wp"]["data"]; 5982 ;// ./node_modules/tslib/tslib.es6.mjs 5983 /****************************************************************************** 5984 Copyright (c) Microsoft Corporation. 5985 5986 Permission to use, copy, modify, and/or distribute this software for any 5987 purpose with or without fee is hereby granted. 5988 5989 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 5990 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 5991 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 5992 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 5993 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 5994 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 5995 PERFORMANCE OF THIS SOFTWARE. 5996 ***************************************************************************** */ 5997 /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ 5998 5999 var extendStatics = function(d, b) { 6000 extendStatics = Object.setPrototypeOf || 6001 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 6002 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 6003 return extendStatics(d, b); 6004 }; 6005 6006 function __extends(d, b) { 6007 if (typeof b !== "function" && b !== null) 6008 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 6009 extendStatics(d, b); 6010 function __() { this.constructor = d; } 6011 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6012 } 6013 6014 var __assign = function() { 6015 __assign = Object.assign || function __assign(t) { 6016 for (var s, i = 1, n = arguments.length; i < n; i++) { 6017 s = arguments[i]; 6018 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 6019 } 6020 return t; 6021 } 6022 return __assign.apply(this, arguments); 6023 } 6024 6025 function __rest(s, e) { 6026 var t = {}; 6027 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 6028 t[p] = s[p]; 6029 if (s != null && typeof Object.getOwnPropertySymbols === "function") 6030 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 6031 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 6032 t[p[i]] = s[p[i]]; 6033 } 6034 return t; 6035 } 6036 6037 function __decorate(decorators, target, key, desc) { 6038 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6039 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 6040 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; 6041 return c > 3 && r && Object.defineProperty(target, key, r), r; 6042 } 6043 6044 function __param(paramIndex, decorator) { 6045 return function (target, key) { decorator(target, key, paramIndex); } 6046 } 6047 6048 function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 6049 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 6050 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 6051 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 6052 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6053 var _, done = false; 6054 for (var i = decorators.length - 1; i >= 0; i--) { 6055 var context = {}; 6056 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 6057 for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 6058 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 6059 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 6060 if (kind === "accessor") { 6061 if (result === void 0) continue; 6062 if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 6063 if (_ = accept(result.get)) descriptor.get = _; 6064 if (_ = accept(result.set)) descriptor.set = _; 6065 if (_ = accept(result.init)) initializers.unshift(_); 6066 } 6067 else if (_ = accept(result)) { 6068 if (kind === "field") initializers.unshift(_); 6069 else descriptor[key] = _; 6070 } 6071 } 6072 if (target) Object.defineProperty(target, contextIn.name, descriptor); 6073 done = true; 6074 }; 6075 6076 function __runInitializers(thisArg, initializers, value) { 6077 var useValue = arguments.length > 2; 6078 for (var i = 0; i < initializers.length; i++) { 6079 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 6080 } 6081 return useValue ? value : void 0; 6082 }; 6083 6084 function __propKey(x) { 6085 return typeof x === "symbol" ? x : "".concat(x); 6086 }; 6087 6088 function __setFunctionName(f, name, prefix) { 6089 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; 6090 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); 6091 }; 6092 6093 function __metadata(metadataKey, metadataValue) { 6094 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 6095 } 6096 6097 function __awaiter(thisArg, _arguments, P, generator) { 6098 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 6099 return new (P || (P = Promise))(function (resolve, reject) { 6100 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6101 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6102 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 6103 step((generator = generator.apply(thisArg, _arguments || [])).next()); 6104 }); 6105 } 6106 6107 function __generator(thisArg, body) { 6108 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); 6109 return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 6110 function verb(n) { return function (v) { return step([n, v]); }; } 6111 function step(op) { 6112 if (f) throw new TypeError("Generator is already executing."); 6113 while (g && (g = 0, op[0] && (_ = 0)), _) try { 6114 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; 6115 if (y = 0, t) op = [op[0] & 2, t.value]; 6116 switch (op[0]) { 6117 case 0: case 1: t = op; break; 6118 case 4: _.label++; return { value: op[1], done: false }; 6119 case 5: _.label++; y = op[1]; op = [0]; continue; 6120 case 7: op = _.ops.pop(); _.trys.pop(); continue; 6121 default: 6122 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 6123 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 6124 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 6125 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 6126 if (t[2]) _.ops.pop(); 6127 _.trys.pop(); continue; 6128 } 6129 op = body.call(thisArg, _); 6130 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 6131 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 6132 } 6133 } 6134 6135 var __createBinding = Object.create ? (function(o, m, k, k2) { 6136 if (k2 === undefined) k2 = k; 6137 var desc = Object.getOwnPropertyDescriptor(m, k); 6138 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6139 desc = { enumerable: true, get: function() { return m[k]; } }; 6140 } 6141 Object.defineProperty(o, k2, desc); 6142 }) : (function(o, m, k, k2) { 6143 if (k2 === undefined) k2 = k; 6144 o[k2] = m[k]; 6145 }); 6146 6147 function __exportStar(m, o) { 6148 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 6149 } 6150 6151 function __values(o) { 6152 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 6153 if (m) return m.call(o); 6154 if (o && typeof o.length === "number") return { 6155 next: function () { 6156 if (o && i >= o.length) o = void 0; 6157 return { value: o && o[i++], done: !o }; 6158 } 6159 }; 6160 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 6161 } 6162 6163 function __read(o, n) { 6164 var m = typeof Symbol === "function" && o[Symbol.iterator]; 6165 if (!m) return o; 6166 var i = m.call(o), r, ar = [], e; 6167 try { 6168 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 6169 } 6170 catch (error) { e = { error: error }; } 6171 finally { 6172 try { 6173 if (r && !r.done && (m = i["return"])) m.call(i); 6174 } 6175 finally { if (e) throw e.error; } 6176 } 6177 return ar; 6178 } 6179 6180 /** @deprecated */ 6181 function __spread() { 6182 for (var ar = [], i = 0; i < arguments.length; i++) 6183 ar = ar.concat(__read(arguments[i])); 6184 return ar; 6185 } 6186 6187 /** @deprecated */ 6188 function __spreadArrays() { 6189 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 6190 for (var r = Array(s), k = 0, i = 0; i < il; i++) 6191 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 6192 r[k] = a[j]; 6193 return r; 6194 } 6195 6196 function __spreadArray(to, from, pack) { 6197 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 6198 if (ar || !(i in from)) { 6199 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 6200 ar[i] = from[i]; 6201 } 6202 } 6203 return to.concat(ar || Array.prototype.slice.call(from)); 6204 } 6205 6206 function __await(v) { 6207 return this instanceof __await ? (this.v = v, this) : new __await(v); 6208 } 6209 6210 function __asyncGenerator(thisArg, _arguments, generator) { 6211 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6212 var g = generator.apply(thisArg, _arguments || []), i, q = []; 6213 return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; 6214 function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } 6215 function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } 6216 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 6217 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 6218 function fulfill(value) { resume("next", value); } 6219 function reject(value) { resume("throw", value); } 6220 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 6221 } 6222 6223 function __asyncDelegator(o) { 6224 var i, p; 6225 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 6226 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } 6227 } 6228 6229 function __asyncValues(o) { 6230 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6231 var m = o[Symbol.asyncIterator], i; 6232 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); 6233 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); }); }; } 6234 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 6235 } 6236 6237 function __makeTemplateObject(cooked, raw) { 6238 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 6239 return cooked; 6240 }; 6241 6242 var __setModuleDefault = Object.create ? (function(o, v) { 6243 Object.defineProperty(o, "default", { enumerable: true, value: v }); 6244 }) : function(o, v) { 6245 o["default"] = v; 6246 }; 6247 6248 var ownKeys = function(o) { 6249 ownKeys = Object.getOwnPropertyNames || function (o) { 6250 var ar = []; 6251 for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; 6252 return ar; 6253 }; 6254 return ownKeys(o); 6255 }; 6256 6257 function __importStar(mod) { 6258 if (mod && mod.__esModule) return mod; 6259 var result = {}; 6260 if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); 6261 __setModuleDefault(result, mod); 6262 return result; 6263 } 6264 6265 function __importDefault(mod) { 6266 return (mod && mod.__esModule) ? mod : { default: mod }; 6267 } 6268 6269 function __classPrivateFieldGet(receiver, state, kind, f) { 6270 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 6271 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"); 6272 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 6273 } 6274 6275 function __classPrivateFieldSet(receiver, state, value, kind, f) { 6276 if (kind === "m") throw new TypeError("Private method is not writable"); 6277 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 6278 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"); 6279 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 6280 } 6281 6282 function __classPrivateFieldIn(state, receiver) { 6283 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); 6284 return typeof state === "function" ? receiver === state : state.has(receiver); 6285 } 6286 6287 function __addDisposableResource(env, value, async) { 6288 if (value !== null && value !== void 0) { 6289 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 6290 var dispose, inner; 6291 if (async) { 6292 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 6293 dispose = value[Symbol.asyncDispose]; 6294 } 6295 if (dispose === void 0) { 6296 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 6297 dispose = value[Symbol.dispose]; 6298 if (async) inner = dispose; 6299 } 6300 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 6301 if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; 6302 env.stack.push({ value: value, dispose: dispose, async: async }); 6303 } 6304 else if (async) { 6305 env.stack.push({ async: true }); 6306 } 6307 return value; 6308 } 6309 6310 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 6311 var e = new Error(message); 6312 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 6313 }; 6314 6315 function __disposeResources(env) { 6316 function fail(e) { 6317 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 6318 env.hasError = true; 6319 } 6320 var r, s = 0; 6321 function next() { 6322 while (r = env.stack.pop()) { 6323 try { 6324 if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); 6325 if (r.dispose) { 6326 var result = r.dispose.call(r.value); 6327 if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 6328 } 6329 else s |= 1; 6330 } 6331 catch (e) { 6332 fail(e); 6333 } 6334 } 6335 if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); 6336 if (env.hasError) throw env.error; 6337 } 6338 return next(); 6339 } 6340 6341 function __rewriteRelativeImportExtension(path, preserveJsx) { 6342 if (typeof path === "string" && /^\.\.?\//.test(path)) { 6343 return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { 6344 return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); 6345 }); 6346 } 6347 return path; 6348 } 6349 6350 /* harmony default export */ const tslib_es6 = ({ 6351 __extends, 6352 __assign, 6353 __rest, 6354 __decorate, 6355 __param, 6356 __esDecorate, 6357 __runInitializers, 6358 __propKey, 6359 __setFunctionName, 6360 __metadata, 6361 __awaiter, 6362 __generator, 6363 __createBinding, 6364 __exportStar, 6365 __values, 6366 __read, 6367 __spread, 6368 __spreadArrays, 6369 __spreadArray, 6370 __await, 6371 __asyncGenerator, 6372 __asyncDelegator, 6373 __asyncValues, 6374 __makeTemplateObject, 6375 __importStar, 6376 __importDefault, 6377 __classPrivateFieldGet, 6378 __classPrivateFieldSet, 6379 __classPrivateFieldIn, 6380 __addDisposableResource, 6381 __disposeResources, 6382 __rewriteRelativeImportExtension, 6383 }); 6384 6385 ;// ./node_modules/lower-case/dist.es2015/index.js 6386 /** 6387 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 6388 */ 6389 var SUPPORTED_LOCALE = { 6390 tr: { 6391 regexp: /\u0130|\u0049|\u0049\u0307/g, 6392 map: { 6393 İ: "\u0069", 6394 I: "\u0131", 6395 İ: "\u0069", 6396 }, 6397 }, 6398 az: { 6399 regexp: /\u0130/g, 6400 map: { 6401 İ: "\u0069", 6402 I: "\u0131", 6403 İ: "\u0069", 6404 }, 6405 }, 6406 lt: { 6407 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 6408 map: { 6409 I: "\u0069\u0307", 6410 J: "\u006A\u0307", 6411 Į: "\u012F\u0307", 6412 Ì: "\u0069\u0307\u0300", 6413 Í: "\u0069\u0307\u0301", 6414 Ĩ: "\u0069\u0307\u0303", 6415 }, 6416 }, 6417 }; 6418 /** 6419 * Localized lower case. 6420 */ 6421 function localeLowerCase(str, locale) { 6422 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 6423 if (lang) 6424 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 6425 return lowerCase(str); 6426 } 6427 /** 6428 * Lower case as a function. 6429 */ 6430 function lowerCase(str) { 6431 return str.toLowerCase(); 6432 } 6433 6434 ;// ./node_modules/no-case/dist.es2015/index.js 6435 6436 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 6437 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 6438 // Remove all non-word characters. 6439 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 6440 /** 6441 * Normalize the string into something other libraries can manipulate easier. 6442 */ 6443 function noCase(input, options) { 6444 if (options === void 0) { options = {}; } 6445 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; 6446 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 6447 var start = 0; 6448 var end = result.length; 6449 // Trim the delimiter from around the output string. 6450 while (result.charAt(start) === "\0") 6451 start++; 6452 while (result.charAt(end - 1) === "\0") 6453 end--; 6454 // Transform each token independently. 6455 return result.slice(start, end).split("\0").map(transform).join(delimiter); 6456 } 6457 /** 6458 * Replace `re` in the input string with the replacement value. 6459 */ 6460 function replace(input, re, value) { 6461 if (re instanceof RegExp) 6462 return input.replace(re, value); 6463 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 6464 } 6465 6466 ;// ./node_modules/pascal-case/dist.es2015/index.js 6467 6468 6469 function pascalCaseTransform(input, index) { 6470 var firstChar = input.charAt(0); 6471 var lowerChars = input.substr(1).toLowerCase(); 6472 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 6473 return "_" + firstChar + lowerChars; 6474 } 6475 return "" + firstChar.toUpperCase() + lowerChars; 6476 } 6477 function dist_es2015_pascalCaseTransformMerge(input) { 6478 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase(); 6479 } 6480 function pascalCase(input, options) { 6481 if (options === void 0) { options = {}; } 6482 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 6483 } 6484 6485 ;// ./node_modules/camel-case/dist.es2015/index.js 6486 6487 6488 function camelCaseTransform(input, index) { 6489 if (index === 0) 6490 return input.toLowerCase(); 6491 return pascalCaseTransform(input, index); 6492 } 6493 function camelCaseTransformMerge(input, index) { 6494 if (index === 0) 6495 return input.toLowerCase(); 6496 return pascalCaseTransformMerge(input); 6497 } 6498 function camelCase(input, options) { 6499 if (options === void 0) { options = {}; } 6500 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 6501 } 6502 6503 ;// external ["wp","i18n"] 6504 const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 6505 ;// ./node_modules/colord/index.mjs 6506 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()})}; 6507 6508 ;// ./node_modules/colord/plugins/names.mjs 6509 /* 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"])} 6510 6511 ;// ./node_modules/colord/plugins/a11y.mjs 6512 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}} 6513 6514 ;// external ["wp","element"] 6515 const external_wp_element_namespaceObject = window["wp"]["element"]; 6516 ;// external ["wp","dom"] 6517 const external_wp_dom_namespaceObject = window["wp"]["dom"]; 6518 ;// external ["wp","richText"] 6519 const external_wp_richText_namespaceObject = window["wp"]["richText"]; 6520 ;// external ["wp","deprecated"] 6521 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 6522 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 6523 ;// ./node_modules/@wordpress/blocks/build-module/api/constants.js 6524 const BLOCK_ICON_DEFAULT = 'block-default'; 6525 6526 /** 6527 * Array of valid keys in a block type settings deprecation object. 6528 * 6529 * @type {string[]} 6530 */ 6531 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 6532 const __EXPERIMENTAL_STYLE_PROPERTY = { 6533 // Kept for back-compatibility purposes. 6534 '--wp--style--color--link': { 6535 value: ['color', 'link'], 6536 support: ['color', 'link'] 6537 }, 6538 aspectRatio: { 6539 value: ['dimensions', 'aspectRatio'], 6540 support: ['dimensions', 'aspectRatio'], 6541 useEngine: true 6542 }, 6543 background: { 6544 value: ['color', 'gradient'], 6545 support: ['color', 'gradients'], 6546 useEngine: true 6547 }, 6548 backgroundColor: { 6549 value: ['color', 'background'], 6550 support: ['color', 'background'], 6551 requiresOptOut: true, 6552 useEngine: true 6553 }, 6554 backgroundImage: { 6555 value: ['background', 'backgroundImage'], 6556 support: ['background', 'backgroundImage'], 6557 useEngine: true 6558 }, 6559 backgroundRepeat: { 6560 value: ['background', 'backgroundRepeat'], 6561 support: ['background', 'backgroundRepeat'], 6562 useEngine: true 6563 }, 6564 backgroundSize: { 6565 value: ['background', 'backgroundSize'], 6566 support: ['background', 'backgroundSize'], 6567 useEngine: true 6568 }, 6569 backgroundPosition: { 6570 value: ['background', 'backgroundPosition'], 6571 support: ['background', 'backgroundPosition'], 6572 useEngine: true 6573 }, 6574 borderColor: { 6575 value: ['border', 'color'], 6576 support: ['__experimentalBorder', 'color'], 6577 useEngine: true 6578 }, 6579 borderRadius: { 6580 value: ['border', 'radius'], 6581 support: ['__experimentalBorder', 'radius'], 6582 properties: { 6583 borderTopLeftRadius: 'topLeft', 6584 borderTopRightRadius: 'topRight', 6585 borderBottomLeftRadius: 'bottomLeft', 6586 borderBottomRightRadius: 'bottomRight' 6587 }, 6588 useEngine: true 6589 }, 6590 borderStyle: { 6591 value: ['border', 'style'], 6592 support: ['__experimentalBorder', 'style'], 6593 useEngine: true 6594 }, 6595 borderWidth: { 6596 value: ['border', 'width'], 6597 support: ['__experimentalBorder', 'width'], 6598 useEngine: true 6599 }, 6600 borderTopColor: { 6601 value: ['border', 'top', 'color'], 6602 support: ['__experimentalBorder', 'color'], 6603 useEngine: true 6604 }, 6605 borderTopStyle: { 6606 value: ['border', 'top', 'style'], 6607 support: ['__experimentalBorder', 'style'], 6608 useEngine: true 6609 }, 6610 borderTopWidth: { 6611 value: ['border', 'top', 'width'], 6612 support: ['__experimentalBorder', 'width'], 6613 useEngine: true 6614 }, 6615 borderRightColor: { 6616 value: ['border', 'right', 'color'], 6617 support: ['__experimentalBorder', 'color'], 6618 useEngine: true 6619 }, 6620 borderRightStyle: { 6621 value: ['border', 'right', 'style'], 6622 support: ['__experimentalBorder', 'style'], 6623 useEngine: true 6624 }, 6625 borderRightWidth: { 6626 value: ['border', 'right', 'width'], 6627 support: ['__experimentalBorder', 'width'], 6628 useEngine: true 6629 }, 6630 borderBottomColor: { 6631 value: ['border', 'bottom', 'color'], 6632 support: ['__experimentalBorder', 'color'], 6633 useEngine: true 6634 }, 6635 borderBottomStyle: { 6636 value: ['border', 'bottom', 'style'], 6637 support: ['__experimentalBorder', 'style'], 6638 useEngine: true 6639 }, 6640 borderBottomWidth: { 6641 value: ['border', 'bottom', 'width'], 6642 support: ['__experimentalBorder', 'width'], 6643 useEngine: true 6644 }, 6645 borderLeftColor: { 6646 value: ['border', 'left', 'color'], 6647 support: ['__experimentalBorder', 'color'], 6648 useEngine: true 6649 }, 6650 borderLeftStyle: { 6651 value: ['border', 'left', 'style'], 6652 support: ['__experimentalBorder', 'style'], 6653 useEngine: true 6654 }, 6655 borderLeftWidth: { 6656 value: ['border', 'left', 'width'], 6657 support: ['__experimentalBorder', 'width'], 6658 useEngine: true 6659 }, 6660 color: { 6661 value: ['color', 'text'], 6662 support: ['color', 'text'], 6663 requiresOptOut: true, 6664 useEngine: true 6665 }, 6666 columnCount: { 6667 value: ['typography', 'textColumns'], 6668 support: ['typography', 'textColumns'], 6669 useEngine: true 6670 }, 6671 filter: { 6672 value: ['filter', 'duotone'], 6673 support: ['filter', 'duotone'] 6674 }, 6675 linkColor: { 6676 value: ['elements', 'link', 'color', 'text'], 6677 support: ['color', 'link'] 6678 }, 6679 captionColor: { 6680 value: ['elements', 'caption', 'color', 'text'], 6681 support: ['color', 'caption'] 6682 }, 6683 buttonColor: { 6684 value: ['elements', 'button', 'color', 'text'], 6685 support: ['color', 'button'] 6686 }, 6687 buttonBackgroundColor: { 6688 value: ['elements', 'button', 'color', 'background'], 6689 support: ['color', 'button'] 6690 }, 6691 headingColor: { 6692 value: ['elements', 'heading', 'color', 'text'], 6693 support: ['color', 'heading'] 6694 }, 6695 headingBackgroundColor: { 6696 value: ['elements', 'heading', 'color', 'background'], 6697 support: ['color', 'heading'] 6698 }, 6699 fontFamily: { 6700 value: ['typography', 'fontFamily'], 6701 support: ['typography', '__experimentalFontFamily'], 6702 useEngine: true 6703 }, 6704 fontSize: { 6705 value: ['typography', 'fontSize'], 6706 support: ['typography', 'fontSize'], 6707 useEngine: true 6708 }, 6709 fontStyle: { 6710 value: ['typography', 'fontStyle'], 6711 support: ['typography', '__experimentalFontStyle'], 6712 useEngine: true 6713 }, 6714 fontWeight: { 6715 value: ['typography', 'fontWeight'], 6716 support: ['typography', '__experimentalFontWeight'], 6717 useEngine: true 6718 }, 6719 lineHeight: { 6720 value: ['typography', 'lineHeight'], 6721 support: ['typography', 'lineHeight'], 6722 useEngine: true 6723 }, 6724 margin: { 6725 value: ['spacing', 'margin'], 6726 support: ['spacing', 'margin'], 6727 properties: { 6728 marginTop: 'top', 6729 marginRight: 'right', 6730 marginBottom: 'bottom', 6731 marginLeft: 'left' 6732 }, 6733 useEngine: true 6734 }, 6735 minHeight: { 6736 value: ['dimensions', 'minHeight'], 6737 support: ['dimensions', 'minHeight'], 6738 useEngine: true 6739 }, 6740 padding: { 6741 value: ['spacing', 'padding'], 6742 support: ['spacing', 'padding'], 6743 properties: { 6744 paddingTop: 'top', 6745 paddingRight: 'right', 6746 paddingBottom: 'bottom', 6747 paddingLeft: 'left' 6748 }, 6749 useEngine: true 6750 }, 6751 textAlign: { 6752 value: ['typography', 'textAlign'], 6753 support: ['typography', 'textAlign'], 6754 useEngine: false 6755 }, 6756 textDecoration: { 6757 value: ['typography', 'textDecoration'], 6758 support: ['typography', '__experimentalTextDecoration'], 6759 useEngine: true 6760 }, 6761 textTransform: { 6762 value: ['typography', 'textTransform'], 6763 support: ['typography', '__experimentalTextTransform'], 6764 useEngine: true 6765 }, 6766 letterSpacing: { 6767 value: ['typography', 'letterSpacing'], 6768 support: ['typography', '__experimentalLetterSpacing'], 6769 useEngine: true 6770 }, 6771 writingMode: { 6772 value: ['typography', 'writingMode'], 6773 support: ['typography', '__experimentalWritingMode'], 6774 useEngine: true 6775 }, 6776 '--wp--style--root--padding': { 6777 value: ['spacing', 'padding'], 6778 support: ['spacing', 'padding'], 6779 properties: { 6780 '--wp--style--root--padding-top': 'top', 6781 '--wp--style--root--padding-right': 'right', 6782 '--wp--style--root--padding-bottom': 'bottom', 6783 '--wp--style--root--padding-left': 'left' 6784 }, 6785 rootOnly: true 6786 } 6787 }; 6788 const __EXPERIMENTAL_ELEMENTS = { 6789 link: 'a:where(:not(.wp-element-button))', 6790 heading: 'h1, h2, h3, h4, h5, h6', 6791 h1: 'h1', 6792 h2: 'h2', 6793 h3: 'h3', 6794 h4: 'h4', 6795 h5: 'h5', 6796 h6: 'h6', 6797 button: '.wp-element-button, .wp-block-button__link', 6798 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', 6799 cite: 'cite' 6800 }; 6801 6802 // These paths may have three origins, custom, theme, and default, 6803 // and are expected to override other origins with custom, theme, 6804 // and default priority. 6805 const __EXPERIMENTAL_PATHS_WITH_OVERRIDE = { 6806 'color.duotone': true, 6807 'color.gradients': true, 6808 'color.palette': true, 6809 'dimensions.aspectRatios': true, 6810 'typography.fontSizes': true, 6811 'spacing.spacingSizes': true 6812 }; 6813 6814 ;// external ["wp","warning"] 6815 const external_wp_warning_namespaceObject = window["wp"]["warning"]; 6816 var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject); 6817 ;// external ["wp","privateApis"] 6818 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 6819 ;// ./node_modules/@wordpress/blocks/build-module/lock-unlock.js 6820 /** 6821 * WordPress dependencies 6822 */ 6823 6824 const { 6825 lock, 6826 unlock 6827 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/blocks'); 6828 6829 ;// ./node_modules/@wordpress/blocks/build-module/api/registration.js 6830 /** 6831 * WordPress dependencies 6832 */ 6833 6834 6835 6836 6837 /** 6838 * Internal dependencies 6839 */ 6840 const i18nBlockSchema = { 6841 title: "block title", 6842 description: "block description", 6843 keywords: ["block keyword"], 6844 styles: [{ 6845 label: "block style label" 6846 }], 6847 variations: [{ 6848 title: "block variation title", 6849 description: "block variation description", 6850 keywords: ["block variation keyword"] 6851 }] 6852 }; 6853 6854 6855 6856 /** 6857 * An icon type definition. One of a Dashicon slug, an element, 6858 * or a component. 6859 * 6860 * @typedef {(string|Element|Component)} WPIcon 6861 * 6862 * @see https://developer.wordpress.org/resource/dashicons/ 6863 */ 6864 6865 /** 6866 * Render behavior of a block type icon; one of a Dashicon slug, an element, 6867 * or a component. 6868 * 6869 * @typedef {WPIcon} WPBlockTypeIconRender 6870 */ 6871 6872 /** 6873 * An object describing a normalized block type icon. 6874 * 6875 * @typedef {Object} WPBlockTypeIconDescriptor 6876 * 6877 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 6878 * one of a Dashicon slug, an 6879 * element, or a component. 6880 * @property {string} background Optimal background hex string 6881 * color when displaying icon. 6882 * @property {string} foreground Optimal foreground hex string 6883 * color when displaying icon. 6884 * @property {string} shadowColor Optimal shadow hex string 6885 * color when displaying icon. 6886 */ 6887 6888 /** 6889 * Value to use to render the icon for a block type in an editor interface, 6890 * either a Dashicon slug, an element, a component, or an object describing 6891 * the icon. 6892 * 6893 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 6894 */ 6895 6896 /** 6897 * Named block variation scopes. 6898 * 6899 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 6900 */ 6901 6902 /** 6903 * An object describing a variation defined for the block type. 6904 * 6905 * @typedef {Object} WPBlockVariation 6906 * 6907 * @property {string} name The unique and machine-readable name. 6908 * @property {string} title A human-readable variation title. 6909 * @property {string} [description] A detailed variation description. 6910 * @property {string} [category] Block type category classification, 6911 * used in search interfaces to arrange 6912 * block types by category. 6913 * @property {WPIcon} [icon] An icon helping to visualize the variation. 6914 * @property {boolean} [isDefault] Indicates whether the current variation is 6915 * the default one. Defaults to `false`. 6916 * @property {Object} [attributes] Values which override block attributes. 6917 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 6918 * @property {Object} [example] Example provides structured data for 6919 * the block preview. You can set to 6920 * `undefined` to disable the preview shown 6921 * for the block type. 6922 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 6923 * is applicable. When not provided, it 6924 * assumes all available scopes. 6925 * @property {string[]} [keywords] An array of terms (which can be translated) 6926 * that help users discover the variation 6927 * while searching. 6928 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 6929 * Function that accepts a block's attributes and the 6930 * variation's attributes and determines if a variation is active. 6931 * This function doesn't try to find a match dynamically based 6932 * on all block's attributes, as in many cases some attributes are irrelevant. 6933 * An example would be for `embed` block where we only care 6934 * about `providerNameSlug` attribute's value. 6935 * We can also use a `string[]` to tell which attributes 6936 * should be compared as a shorthand. Each attributes will 6937 * be matched and the variation will be active if all of them are matching. 6938 */ 6939 6940 /** 6941 * Defined behavior of a block type. 6942 * 6943 * @typedef {Object} WPBlockType 6944 * 6945 * @property {string} name Block type's namespaced name. 6946 * @property {string} title Human-readable block type label. 6947 * @property {string} [description] A detailed block type description. 6948 * @property {string} [category] Block type category classification, 6949 * used in search interfaces to arrange 6950 * block types by category. 6951 * @property {WPBlockTypeIcon} [icon] Block type icon. 6952 * @property {string[]} [keywords] Additional keywords to produce block 6953 * type as result in search interfaces. 6954 * @property {Object} [attributes] Block type attributes. 6955 * @property {Component} [save] Optional component describing 6956 * serialized markup structure of a 6957 * block type. 6958 * @property {Component} edit Component rendering an element to 6959 * manipulate the attributes of a block 6960 * in the context of an editor. 6961 * @property {WPBlockVariation[]} [variations] The list of block variations. 6962 * @property {Object} [example] Example provides structured data for 6963 * the block preview. When not defined 6964 * then no preview is shown. 6965 */ 6966 6967 function isObject(object) { 6968 return object !== null && typeof object === 'object'; 6969 } 6970 6971 /** 6972 * Sets the server side block definition of blocks. 6973 * 6974 * Ignored from documentation due to being marked as unstable. 6975 * 6976 * @ignore 6977 * 6978 * @param {Object} definitions Server-side block definitions 6979 */ 6980 // eslint-disable-next-line camelcase 6981 function unstable__bootstrapServerSideBlockDefinitions(definitions) { 6982 const { 6983 addBootstrappedBlockType 6984 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 6985 for (const [name, blockType] of Object.entries(definitions)) { 6986 addBootstrappedBlockType(name, blockType); 6987 } 6988 } 6989 6990 /** 6991 * Gets block settings from metadata loaded from `block.json` file 6992 * 6993 * @param {Object} metadata Block metadata loaded from `block.json`. 6994 * @param {string} metadata.textdomain Textdomain to use with translations. 6995 * 6996 * @return {Object} Block settings. 6997 */ 6998 function getBlockSettingsFromMetadata({ 6999 textdomain, 7000 ...metadata 7001 }) { 7002 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations', 'blockHooks', 'allowedBlocks']; 7003 const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key))); 7004 if (textdomain) { 7005 Object.keys(i18nBlockSchema).forEach(key => { 7006 if (!settings[key]) { 7007 return; 7008 } 7009 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 7010 }); 7011 } 7012 return settings; 7013 } 7014 7015 /** 7016 * Registers a new block provided a unique name and an object defining its 7017 * behavior. Once registered, the block is made available as an option to any 7018 * editor interface where blocks are implemented. 7019 * 7020 * For more in-depth information on registering a custom block see the 7021 * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). 7022 * 7023 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 7024 * @param {Object} settings Block settings. 7025 * 7026 * @example 7027 * ```js 7028 * import { __ } from '@wordpress/i18n'; 7029 * import { registerBlockType } from '@wordpress/blocks' 7030 * 7031 * registerBlockType( 'namespace/block-name', { 7032 * title: __( 'My First Block' ), 7033 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7034 * save: () => <div>Hello from the saved content!</div>, 7035 * } ); 7036 * ``` 7037 * 7038 * @return {WPBlockType | undefined} The block, if it has been successfully registered; 7039 * otherwise `undefined`. 7040 */ 7041 function registerBlockType(blockNameOrMetadata, settings) { 7042 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 7043 if (typeof name !== 'string') { 7044 true ? external_wp_warning_default()('Block names must be strings.') : 0; 7045 return; 7046 } 7047 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 7048 true ? external_wp_warning_default()('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') : 0; 7049 return; 7050 } 7051 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) { 7052 true ? external_wp_warning_default()('Block "' + name + '" is already registered.') : 0; 7053 return; 7054 } 7055 const { 7056 addBootstrappedBlockType, 7057 addUnprocessedBlockType 7058 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 7059 if (isObject(blockNameOrMetadata)) { 7060 const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata); 7061 addBootstrappedBlockType(name, metadata); 7062 } 7063 addUnprocessedBlockType(name, settings); 7064 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7065 } 7066 7067 /** 7068 * Translates block settings provided with metadata using the i18n schema. 7069 * 7070 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 7071 * @param {string|string[]|Object[]} settingValue Value for the block setting. 7072 * @param {string} textdomain Textdomain to use with translations. 7073 * 7074 * @return {string|string[]|Object[]} Translated setting. 7075 */ 7076 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 7077 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') { 7078 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 7079 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain); 7080 } 7081 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) { 7082 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 7083 } 7084 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) { 7085 return Object.keys(settingValue).reduce((accumulator, key) => { 7086 if (!i18nSchema[key]) { 7087 accumulator[key] = settingValue[key]; 7088 return accumulator; 7089 } 7090 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 7091 return accumulator; 7092 }, {}); 7093 } 7094 return settingValue; 7095 } 7096 7097 /** 7098 * Registers a new block collection to group blocks in the same namespace in the inserter. 7099 * 7100 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 7101 * @param {Object} settings The block collection settings. 7102 * @param {string} settings.title The title to display in the block inserter. 7103 * @param {Object} [settings.icon] The icon to display in the block inserter. 7104 * 7105 * @example 7106 * ```js 7107 * import { __ } from '@wordpress/i18n'; 7108 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks'; 7109 * 7110 * // Register the collection. 7111 * registerBlockCollection( 'my-collection', { 7112 * title: __( 'Custom Collection' ), 7113 * } ); 7114 * 7115 * // Register a block in the same namespace to add it to the collection. 7116 * registerBlockType( 'my-collection/block-name', { 7117 * title: __( 'My First Block' ), 7118 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7119 * save: () => <div>'Hello from the saved content!</div>, 7120 * } ); 7121 * ``` 7122 */ 7123 function registerBlockCollection(namespace, { 7124 title, 7125 icon 7126 }) { 7127 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon); 7128 } 7129 7130 /** 7131 * Unregisters a block collection 7132 * 7133 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 7134 * 7135 * @example 7136 * ```js 7137 * import { unregisterBlockCollection } from '@wordpress/blocks'; 7138 * 7139 * unregisterBlockCollection( 'my-collection' ); 7140 * ``` 7141 */ 7142 function unregisterBlockCollection(namespace) { 7143 dispatch(blocksStore).removeBlockCollection(namespace); 7144 } 7145 7146 /** 7147 * Unregisters a block. 7148 * 7149 * @param {string} name Block name. 7150 * 7151 * @example 7152 * ```js 7153 * import { __ } from '@wordpress/i18n'; 7154 * import { unregisterBlockType } from '@wordpress/blocks'; 7155 * 7156 * const ExampleComponent = () => { 7157 * return ( 7158 * <Button 7159 * onClick={ () => 7160 * unregisterBlockType( 'my-collection/block-name' ) 7161 * } 7162 * > 7163 * { __( 'Unregister my custom block.' ) } 7164 * </Button> 7165 * ); 7166 * }; 7167 * ``` 7168 * 7169 * @return {WPBlockType | undefined} The previous block value, if it has been successfully 7170 * unregistered; otherwise `undefined`. 7171 */ 7172 function unregisterBlockType(name) { 7173 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7174 if (!oldBlock) { 7175 true ? external_wp_warning_default()('Block "' + name + '" is not registered.') : 0; 7176 return; 7177 } 7178 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name); 7179 return oldBlock; 7180 } 7181 7182 /** 7183 * Assigns name of block for handling non-block content. 7184 * 7185 * @param {string} blockName Block name. 7186 */ 7187 function setFreeformContentHandlerName(blockName) { 7188 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName); 7189 } 7190 7191 /** 7192 * Retrieves name of block handling non-block content, or undefined if no 7193 * handler has been defined. 7194 * 7195 * @return {?string} Block name. 7196 */ 7197 function getFreeformContentHandlerName() { 7198 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName(); 7199 } 7200 7201 /** 7202 * Retrieves name of block used for handling grouping interactions. 7203 * 7204 * @return {?string} Block name. 7205 */ 7206 function getGroupingBlockName() { 7207 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName(); 7208 } 7209 7210 /** 7211 * Assigns name of block handling unregistered block types. 7212 * 7213 * @param {string} blockName Block name. 7214 */ 7215 function setUnregisteredTypeHandlerName(blockName) { 7216 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName); 7217 } 7218 7219 /** 7220 * Retrieves name of block handling unregistered block types, or undefined if no 7221 * handler has been defined. 7222 * 7223 * @return {?string} Block name. 7224 */ 7225 function getUnregisteredTypeHandlerName() { 7226 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName(); 7227 } 7228 7229 /** 7230 * Assigns the default block name. 7231 * 7232 * @param {string} name Block name. 7233 * 7234 * @example 7235 * ```js 7236 * import { setDefaultBlockName } from '@wordpress/blocks'; 7237 * 7238 * const ExampleComponent = () => { 7239 * 7240 * return ( 7241 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }> 7242 * { __( 'Set the default block to Heading' ) } 7243 * </Button> 7244 * ); 7245 * }; 7246 * ``` 7247 */ 7248 function setDefaultBlockName(name) { 7249 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name); 7250 } 7251 7252 /** 7253 * Assigns name of block for handling block grouping interactions. 7254 * 7255 * This function lets you select a different block to group other blocks in instead of the 7256 * default `core/group` block. This function must be used in a component or when the DOM is fully 7257 * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/ 7258 * 7259 * @param {string} name Block name. 7260 * 7261 * @example 7262 * ```js 7263 * import { setGroupingBlockName } from '@wordpress/blocks'; 7264 * 7265 * const ExampleComponent = () => { 7266 * 7267 * return ( 7268 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }> 7269 * { __( 'Wrap in columns' ) } 7270 * </Button> 7271 * ); 7272 * }; 7273 * ``` 7274 */ 7275 function setGroupingBlockName(name) { 7276 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name); 7277 } 7278 7279 /** 7280 * Retrieves the default block name. 7281 * 7282 * @return {?string} Block name. 7283 */ 7284 function getDefaultBlockName() { 7285 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName(); 7286 } 7287 7288 /** 7289 * Returns a registered block type. 7290 * 7291 * @param {string} name Block name. 7292 * 7293 * @return {?Object} Block type. 7294 */ 7295 function getBlockType(name) { 7296 return (0,external_wp_data_namespaceObject.select)(store)?.getBlockType(name); 7297 } 7298 7299 /** 7300 * Returns all registered blocks. 7301 * 7302 * @return {Array} Block settings. 7303 */ 7304 function getBlockTypes() { 7305 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes(); 7306 } 7307 7308 /** 7309 * Returns the block support value for a feature, if defined. 7310 * 7311 * @param {(string|Object)} nameOrType Block name or type object 7312 * @param {string} feature Feature to retrieve 7313 * @param {*} defaultSupports Default value to return if not 7314 * explicitly defined 7315 * 7316 * @return {?*} Block support value 7317 */ 7318 function getBlockSupport(nameOrType, feature, defaultSupports) { 7319 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports); 7320 } 7321 7322 /** 7323 * Returns true if the block defines support for a feature, or false otherwise. 7324 * 7325 * @param {(string|Object)} nameOrType Block name or type object. 7326 * @param {string} feature Feature to test. 7327 * @param {boolean} defaultSupports Whether feature is supported by 7328 * default if not explicitly defined. 7329 * 7330 * @return {boolean} Whether block supports feature. 7331 */ 7332 function hasBlockSupport(nameOrType, feature, defaultSupports) { 7333 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports); 7334 } 7335 7336 /** 7337 * Determines whether or not the given block is a reusable block. This is a 7338 * special block type that is used to point to a global block stored via the 7339 * API. 7340 * 7341 * @param {Object} blockOrType Block or Block Type to test. 7342 * 7343 * @return {boolean} Whether the given block is a reusable block. 7344 */ 7345 function isReusableBlock(blockOrType) { 7346 return blockOrType?.name === 'core/block'; 7347 } 7348 7349 /** 7350 * Determines whether or not the given block is a template part. This is a 7351 * special block type that allows composing a page template out of reusable 7352 * design elements. 7353 * 7354 * @param {Object} blockOrType Block or Block Type to test. 7355 * 7356 * @return {boolean} Whether the given block is a template part. 7357 */ 7358 function isTemplatePart(blockOrType) { 7359 return blockOrType?.name === 'core/template-part'; 7360 } 7361 7362 /** 7363 * Returns an array with the child blocks of a given block. 7364 * 7365 * @param {string} blockName Name of block (example: “latest-posts”). 7366 * 7367 * @return {Array} Array of child block names. 7368 */ 7369 const getChildBlockNames = blockName => { 7370 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName); 7371 }; 7372 7373 /** 7374 * Returns a boolean indicating if a block has child blocks or not. 7375 * 7376 * @param {string} blockName Name of block (example: “latest-posts”). 7377 * 7378 * @return {boolean} True if a block contains child blocks and false otherwise. 7379 */ 7380 const hasChildBlocks = blockName => { 7381 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName); 7382 }; 7383 7384 /** 7385 * Returns a boolean indicating if a block has at least one child block with inserter support. 7386 * 7387 * @param {string} blockName Block type name. 7388 * 7389 * @return {boolean} True if a block contains at least one child blocks with inserter support 7390 * and false otherwise. 7391 */ 7392 const hasChildBlocksWithInserterSupport = blockName => { 7393 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName); 7394 }; 7395 7396 /** 7397 * Registers a new block style for the given block types. 7398 * 7399 * For more information on connecting the styles with CSS 7400 * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). 7401 * 7402 * @param {string|Array} blockNames Name of blocks e.g. “core/latest-posts” or `["core/group", "core/columns"]`. 7403 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 7404 * 7405 * @example 7406 * ```js 7407 * import { __ } from '@wordpress/i18n'; 7408 * import { registerBlockStyle } from '@wordpress/blocks'; 7409 * import { Button } from '@wordpress/components'; 7410 * 7411 * 7412 * const ExampleComponent = () => { 7413 * return ( 7414 * <Button 7415 * onClick={ () => { 7416 * registerBlockStyle( 'core/quote', { 7417 * name: 'fancy-quote', 7418 * label: __( 'Fancy Quote' ), 7419 * } ); 7420 * } } 7421 * > 7422 * { __( 'Add a new block style for core/quote' ) } 7423 * </Button> 7424 * ); 7425 * }; 7426 * ``` 7427 */ 7428 const registerBlockStyle = (blockNames, styleVariation) => { 7429 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockNames, styleVariation); 7430 }; 7431 7432 /** 7433 * Unregisters a block style for the given block. 7434 * 7435 * @param {string} blockName Name of block (example: “core/latest-posts”). 7436 * @param {string} styleVariationName Name of class applied to the block. 7437 * 7438 * @example 7439 * ```js 7440 * import { __ } from '@wordpress/i18n'; 7441 * import { unregisterBlockStyle } from '@wordpress/blocks'; 7442 * import { Button } from '@wordpress/components'; 7443 * 7444 * const ExampleComponent = () => { 7445 * return ( 7446 * <Button 7447 * onClick={ () => { 7448 * unregisterBlockStyle( 'core/quote', 'plain' ); 7449 * } } 7450 * > 7451 * { __( 'Remove the "Plain" block style for core/quote' ) } 7452 * </Button> 7453 * ); 7454 * }; 7455 * ``` 7456 */ 7457 const unregisterBlockStyle = (blockName, styleVariationName) => { 7458 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName); 7459 }; 7460 7461 /** 7462 * Returns an array with the variations of a given block type. 7463 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 7464 * 7465 * @ignore 7466 * 7467 * @param {string} blockName Name of block (example: “core/columns”). 7468 * @param {WPBlockVariationScope} [scope] Block variation scope name. 7469 * 7470 * @return {(WPBlockVariation[]|void)} Block variations. 7471 */ 7472 const getBlockVariations = (blockName, scope) => { 7473 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope); 7474 }; 7475 7476 /** 7477 * Registers a new block variation for the given block type. 7478 * 7479 * For more information on block variations see 7480 * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). 7481 * 7482 * @param {string} blockName Name of the block (example: “core/columns”). 7483 * @param {WPBlockVariation} variation Object describing a block variation. 7484 * 7485 * @example 7486 * ```js 7487 * import { __ } from '@wordpress/i18n'; 7488 * import { registerBlockVariation } from '@wordpress/blocks'; 7489 * import { Button } from '@wordpress/components'; 7490 * 7491 * const ExampleComponent = () => { 7492 * return ( 7493 * <Button 7494 * onClick={ () => { 7495 * registerBlockVariation( 'core/embed', { 7496 * name: 'custom', 7497 * title: __( 'My Custom Embed' ), 7498 * attributes: { providerNameSlug: 'custom' }, 7499 * } ); 7500 * } } 7501 * > 7502 * __( 'Add a custom variation for core/embed' ) } 7503 * </Button> 7504 * ); 7505 * }; 7506 * ``` 7507 */ 7508 const registerBlockVariation = (blockName, variation) => { 7509 if (typeof variation.name !== 'string') { 7510 true ? external_wp_warning_default()('Variation names must be unique strings.') : 0; 7511 } 7512 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation); 7513 }; 7514 7515 /** 7516 * Unregisters a block variation defined for the given block type. 7517 * 7518 * @param {string} blockName Name of the block (example: “core/columns”). 7519 * @param {string} variationName Name of the variation defined for the block. 7520 * 7521 * @example 7522 * ```js 7523 * import { __ } from '@wordpress/i18n'; 7524 * import { unregisterBlockVariation } from '@wordpress/blocks'; 7525 * import { Button } from '@wordpress/components'; 7526 * 7527 * const ExampleComponent = () => { 7528 * return ( 7529 * <Button 7530 * onClick={ () => { 7531 * unregisterBlockVariation( 'core/embed', 'youtube' ); 7532 * } } 7533 * > 7534 * { __( 'Remove the YouTube variation from core/embed' ) } 7535 * </Button> 7536 * ); 7537 * }; 7538 * ``` 7539 */ 7540 const unregisterBlockVariation = (blockName, variationName) => { 7541 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName); 7542 }; 7543 7544 /** 7545 * Registers a new block bindings source with an object defining its 7546 * behavior. Once registered, the source is available to be connected 7547 * to the supported block attributes. 7548 * 7549 * @since 6.7.0 Introduced in WordPress core. 7550 * 7551 * @param {Object} source Properties of the source to be registered. 7552 * @param {string} source.name The unique and machine-readable name. 7553 * @param {string} [source.label] Human-readable label. Optional when it is defined in the server. 7554 * @param {Array} [source.usesContext] Optional array of context needed by the source only in the editor. 7555 * @param {Function} [source.getValues] Optional function to get the values from the source. 7556 * @param {Function} [source.setValues] Optional function to update multiple values connected to the source. 7557 * @param {Function} [source.canUserEditValue] Optional function to determine if the user can edit the value. 7558 * 7559 * @example 7560 * ```js 7561 * import { _x } from '@wordpress/i18n'; 7562 * import { registerBlockBindingsSource } from '@wordpress/blocks' 7563 * 7564 * registerBlockBindingsSource( { 7565 * name: 'plugin/my-custom-source', 7566 * label: _x( 'My Custom Source', 'block bindings source' ), 7567 * usesContext: [ 'postType' ], 7568 * getValues: getSourceValues, 7569 * setValues: updateMyCustomValuesInBatch, 7570 * canUserEditValue: () => true, 7571 * } ); 7572 * ``` 7573 */ 7574 const registerBlockBindingsSource = source => { 7575 const { 7576 name, 7577 label, 7578 usesContext, 7579 getValues, 7580 setValues, 7581 canUserEditValue, 7582 getFieldsList 7583 } = source; 7584 const existingSource = unlock((0,external_wp_data_namespaceObject.select)(store)).getBlockBindingsSource(name); 7585 7586 /* 7587 * Check if the source has been already registered on the client. 7588 * If any property expected to be "client-only" is defined, return a warning. 7589 */ 7590 const serverProps = ['label', 'usesContext']; 7591 for (const prop in existingSource) { 7592 if (!serverProps.includes(prop) && existingSource[prop]) { 7593 true ? external_wp_warning_default()('Block bindings source "' + name + '" is already registered.') : 0; 7594 return; 7595 } 7596 } 7597 7598 // Check the `name` property is correct. 7599 if (!name) { 7600 true ? external_wp_warning_default()('Block bindings source must contain a name.') : 0; 7601 return; 7602 } 7603 if (typeof name !== 'string') { 7604 true ? external_wp_warning_default()('Block bindings source name must be a string.') : 0; 7605 return; 7606 } 7607 if (/[A-Z]+/.test(name)) { 7608 true ? external_wp_warning_default()('Block bindings source name must not contain uppercase characters.') : 0; 7609 return; 7610 } 7611 if (!/^[a-z0-9/-]+$/.test(name)) { 7612 true ? external_wp_warning_default()('Block bindings source name must contain only valid characters: lowercase characters, hyphens, or digits. Example: my-plugin/my-custom-source.') : 0; 7613 return; 7614 } 7615 if (!/^[a-z0-9-]+\/[a-z0-9-]+$/.test(name)) { 7616 true ? external_wp_warning_default()('Block bindings source name must contain a namespace and valid characters. Example: my-plugin/my-custom-source.') : 0; 7617 return; 7618 } 7619 7620 // Check the `label` property is correct. 7621 7622 if (!label && !existingSource?.label) { 7623 true ? external_wp_warning_default()('Block bindings source must contain a label.') : 0; 7624 return; 7625 } 7626 if (label && typeof label !== 'string') { 7627 true ? external_wp_warning_default()('Block bindings source label must be a string.') : 0; 7628 return; 7629 } 7630 if (label && existingSource?.label && label !== existingSource?.label) { 7631 true ? external_wp_warning_default()('Block bindings "' + name + '" source label was overridden.') : 0; 7632 } 7633 7634 // Check the `usesContext` property is correct. 7635 if (usesContext && !Array.isArray(usesContext)) { 7636 true ? external_wp_warning_default()('Block bindings source usesContext must be an array.') : 0; 7637 return; 7638 } 7639 7640 // Check the `getValues` property is correct. 7641 if (getValues && typeof getValues !== 'function') { 7642 true ? external_wp_warning_default()('Block bindings source getValues must be a function.') : 0; 7643 return; 7644 } 7645 7646 // Check the `setValues` property is correct. 7647 if (setValues && typeof setValues !== 'function') { 7648 true ? external_wp_warning_default()('Block bindings source setValues must be a function.') : 0; 7649 return; 7650 } 7651 7652 // Check the `canUserEditValue` property is correct. 7653 if (canUserEditValue && typeof canUserEditValue !== 'function') { 7654 true ? external_wp_warning_default()('Block bindings source canUserEditValue must be a function.') : 0; 7655 return; 7656 } 7657 7658 // Check the `getFieldsList` property is correct. 7659 if (getFieldsList && typeof getFieldsList !== 'function') { 7660 // eslint-disable-next-line no-console 7661 true ? external_wp_warning_default()('Block bindings source getFieldsList must be a function.') : 0; 7662 return; 7663 } 7664 return unlock((0,external_wp_data_namespaceObject.dispatch)(store)).addBlockBindingsSource(source); 7665 }; 7666 7667 /** 7668 * Unregisters a block bindings source by providing its name. 7669 * 7670 * @since 6.7.0 Introduced in WordPress core. 7671 * 7672 * @param {string} name The name of the block bindings source to unregister. 7673 * 7674 * @example 7675 * ```js 7676 * import { unregisterBlockBindingsSource } from '@wordpress/blocks'; 7677 * 7678 * unregisterBlockBindingsSource( 'plugin/my-custom-source' ); 7679 * ``` 7680 */ 7681 function unregisterBlockBindingsSource(name) { 7682 const oldSource = getBlockBindingsSource(name); 7683 if (!oldSource) { 7684 true ? external_wp_warning_default()('Block bindings source "' + name + '" is not registered.') : 0; 7685 return; 7686 } 7687 unlock((0,external_wp_data_namespaceObject.dispatch)(store)).removeBlockBindingsSource(name); 7688 } 7689 7690 /** 7691 * Returns a registered block bindings source by its name. 7692 * 7693 * @since 6.7.0 Introduced in WordPress core. 7694 * 7695 * @param {string} name Block bindings source name. 7696 * 7697 * @return {?Object} Block bindings source. 7698 */ 7699 function getBlockBindingsSource(name) { 7700 return unlock((0,external_wp_data_namespaceObject.select)(store)).getBlockBindingsSource(name); 7701 } 7702 7703 /** 7704 * Returns all registered block bindings sources. 7705 * 7706 * @since 6.7.0 Introduced in WordPress core. 7707 * 7708 * @return {Array} Block bindings sources. 7709 */ 7710 function getBlockBindingsSources() { 7711 return unlock((0,external_wp_data_namespaceObject.select)(store)).getAllBlockBindingsSources(); 7712 } 7713 7714 ;// ./node_modules/@wordpress/blocks/build-module/api/utils.js 7715 /** 7716 * External dependencies 7717 */ 7718 7719 7720 7721 7722 /** 7723 * WordPress dependencies 7724 */ 7725 7726 7727 7728 7729 7730 7731 /** 7732 * Internal dependencies 7733 */ 7734 7735 7736 k([names, a11y]); 7737 7738 /** 7739 * Array of icon colors containing a color to be used if the icon color 7740 * was not explicitly set but the icon background color was. 7741 * 7742 * @type {Object} 7743 */ 7744 const ICON_COLORS = ['#191e23', '#f8f9f9']; 7745 7746 /** 7747 * Determines whether the block's attributes are equal to the default attributes 7748 * which means the block is unmodified. 7749 * 7750 * @param {WPBlock} block Block Object 7751 * 7752 * @return {boolean} Whether the block is an unmodified block. 7753 */ 7754 function isUnmodifiedBlock(block) { 7755 var _getBlockType$attribu; 7756 return Object.entries((_getBlockType$attribu = getBlockType(block.name)?.attributes) !== null && _getBlockType$attribu !== void 0 ? _getBlockType$attribu : {}).every(([key, definition]) => { 7757 const value = block.attributes[key]; 7758 7759 // Every attribute that has a default must match the default. 7760 if (definition.hasOwnProperty('default')) { 7761 return value === definition.default; 7762 } 7763 7764 // The rich text type is a bit different from the rest because it 7765 // has an implicit default value of an empty RichTextData instance, 7766 // so check the length of the value. 7767 if (definition.type === 'rich-text') { 7768 return !value?.length; 7769 } 7770 7771 // Every attribute that doesn't have a default should be undefined. 7772 return value === undefined; 7773 }); 7774 } 7775 7776 /** 7777 * Determines whether the block is a default block and its attributes are equal 7778 * to the default attributes which means the block is unmodified. 7779 * 7780 * @param {WPBlock} block Block Object 7781 * 7782 * @return {boolean} Whether the block is an unmodified default block. 7783 */ 7784 function isUnmodifiedDefaultBlock(block) { 7785 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block); 7786 } 7787 7788 /** 7789 * Function that checks if the parameter is a valid icon. 7790 * 7791 * @param {*} icon Parameter to be checked. 7792 * 7793 * @return {boolean} True if the parameter is a valid icon and false otherwise. 7794 */ 7795 7796 function isValidIcon(icon) { 7797 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component); 7798 } 7799 7800 /** 7801 * Function that receives an icon as set by the blocks during the registration 7802 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 7803 * in the codebase. 7804 * 7805 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 7806 * one of a Dashicon slug, an element, or a 7807 * component. 7808 * 7809 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 7810 */ 7811 function normalizeIconObject(icon) { 7812 icon = icon || BLOCK_ICON_DEFAULT; 7813 if (isValidIcon(icon)) { 7814 return { 7815 src: icon 7816 }; 7817 } 7818 if ('background' in icon) { 7819 const colordBgColor = w(icon.background); 7820 const getColorContrast = iconColor => colordBgColor.contrast(iconColor); 7821 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast)); 7822 return { 7823 ...icon, 7824 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast), 7825 shadowColor: colordBgColor.alpha(0.3).toRgbString() 7826 }; 7827 } 7828 return icon; 7829 } 7830 7831 /** 7832 * Normalizes block type passed as param. When string is passed then 7833 * it converts it to the matching block type object. 7834 * It passes the original object otherwise. 7835 * 7836 * @param {string|Object} blockTypeOrName Block type or name. 7837 * 7838 * @return {?Object} Block type. 7839 */ 7840 function normalizeBlockType(blockTypeOrName) { 7841 if (typeof blockTypeOrName === 'string') { 7842 return getBlockType(blockTypeOrName); 7843 } 7844 return blockTypeOrName; 7845 } 7846 7847 /** 7848 * Get the label for the block, usually this is either the block title, 7849 * or the value of the block's `label` function when that's specified. 7850 * 7851 * @param {Object} blockType The block type. 7852 * @param {Object} attributes The values of the block's attributes. 7853 * @param {Object} context The intended use for the label. 7854 * 7855 * @return {string} The block label. 7856 */ 7857 function getBlockLabel(blockType, attributes, context = 'visual') { 7858 const { 7859 __experimentalLabel: getLabel, 7860 title 7861 } = blockType; 7862 const label = getLabel && getLabel(attributes, { 7863 context 7864 }); 7865 if (!label) { 7866 return title; 7867 } 7868 if (label.toPlainText) { 7869 return label.toPlainText(); 7870 } 7871 7872 // Strip any HTML (i.e. RichText formatting) before returning. 7873 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label); 7874 } 7875 7876 /** 7877 * Get a label for the block for use by screenreaders, this is more descriptive 7878 * than the visual label and includes the block title and the value of the 7879 * `getLabel` function if it's specified. 7880 * 7881 * @param {?Object} blockType The block type. 7882 * @param {Object} attributes The values of the block's attributes. 7883 * @param {?number} position The position of the block in the block list. 7884 * @param {string} [direction='vertical'] The direction of the block layout. 7885 * 7886 * @return {string} The block label. 7887 */ 7888 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') { 7889 // `title` is already localized, `label` is a user-supplied value. 7890 const title = blockType?.title; 7891 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : ''; 7892 const hasPosition = position !== undefined; 7893 7894 // getBlockLabel returns the block title as a fallback when there's no label, 7895 // if it did return the title, this function needs to avoid adding the 7896 // title twice within the accessible label. Use this `hasLabel` boolean to 7897 // handle that. 7898 const hasLabel = label && label !== title; 7899 if (hasPosition && direction === 'vertical') { 7900 if (hasLabel) { 7901 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 7902 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label); 7903 } 7904 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block row number. */ 7905 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position); 7906 } else if (hasPosition && direction === 'horizontal') { 7907 if (hasLabel) { 7908 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 7909 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label); 7910 } 7911 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block column number. */ 7912 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position); 7913 } 7914 if (hasLabel) { 7915 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. %1: The block title. %2: The block label. */ 7916 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label); 7917 } 7918 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. %s: The block title. */ 7919 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title); 7920 } 7921 function getDefault(attributeSchema) { 7922 if (attributeSchema.default !== undefined) { 7923 return attributeSchema.default; 7924 } 7925 if (attributeSchema.type === 'rich-text') { 7926 return new external_wp_richText_namespaceObject.RichTextData(); 7927 } 7928 } 7929 7930 /** 7931 * Check if a block is registered. 7932 * 7933 * @param {string} name The block's name. 7934 * 7935 * @return {boolean} Whether the block is registered. 7936 */ 7937 function isBlockRegistered(name) { 7938 return getBlockType(name) !== undefined; 7939 } 7940 7941 /** 7942 * Ensure attributes contains only values defined by block type, and merge 7943 * default values for missing attributes. 7944 * 7945 * @param {string} name The block's name. 7946 * @param {Object} attributes The block's attributes. 7947 * @return {Object} The sanitized attributes. 7948 */ 7949 function __experimentalSanitizeBlockAttributes(name, attributes) { 7950 // Get the type definition associated with a registered block. 7951 const blockType = getBlockType(name); 7952 if (undefined === blockType) { 7953 throw new Error(`Block type '$name}' is not registered.`); 7954 } 7955 return Object.entries(blockType.attributes).reduce((accumulator, [key, schema]) => { 7956 const value = attributes[key]; 7957 if (undefined !== value) { 7958 if (schema.type === 'rich-text') { 7959 if (value instanceof external_wp_richText_namespaceObject.RichTextData) { 7960 accumulator[key] = value; 7961 } else if (typeof value === 'string') { 7962 accumulator[key] = external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value); 7963 } 7964 } else if (schema.type === 'string' && value instanceof external_wp_richText_namespaceObject.RichTextData) { 7965 accumulator[key] = value.toHTMLString(); 7966 } else { 7967 accumulator[key] = value; 7968 } 7969 } else { 7970 const _default = getDefault(schema); 7971 if (undefined !== _default) { 7972 accumulator[key] = _default; 7973 } 7974 } 7975 if (['node', 'children'].indexOf(schema.source) !== -1) { 7976 // Ensure value passed is always an array, which we're expecting in 7977 // the RichText component to handle the deprecated value. 7978 if (typeof accumulator[key] === 'string') { 7979 accumulator[key] = [accumulator[key]]; 7980 } else if (!Array.isArray(accumulator[key])) { 7981 accumulator[key] = []; 7982 } 7983 } 7984 return accumulator; 7985 }, {}); 7986 } 7987 7988 /** 7989 * Filter block attributes by `role` and return their names. 7990 * 7991 * @param {string} name Block attribute's name. 7992 * @param {string} role The role of a block attribute. 7993 * 7994 * @return {string[]} The attribute names that have the provided role. 7995 */ 7996 function getBlockAttributesNamesByRole(name, role) { 7997 const attributes = getBlockType(name)?.attributes; 7998 if (!attributes) { 7999 return []; 8000 } 8001 const attributesNames = Object.keys(attributes); 8002 if (!role) { 8003 return attributesNames; 8004 } 8005 return attributesNames.filter(attributeName => { 8006 const attribute = attributes[attributeName]; 8007 if (attribute?.role === role) { 8008 return true; 8009 } 8010 if (attribute?.__experimentalRole === role) { 8011 external_wp_deprecated_default()('__experimentalRole attribute', { 8012 since: '6.7', 8013 version: '6.8', 8014 alternative: 'role attribute', 8015 hint: `Check the block.json of the $name} block.` 8016 }); 8017 return true; 8018 } 8019 return false; 8020 }); 8021 } 8022 const __experimentalGetBlockAttributesNamesByRole = (...args) => { 8023 external_wp_deprecated_default()('__experimentalGetBlockAttributesNamesByRole', { 8024 since: '6.7', 8025 version: '6.8', 8026 alternative: 'getBlockAttributesNamesByRole' 8027 }); 8028 return getBlockAttributesNamesByRole(...args); 8029 }; 8030 8031 /** 8032 * Checks if a block is a content block by examining its attributes. 8033 * A block is considered a content block if it has at least one attribute 8034 * with a role of 'content'. 8035 * 8036 * @param {string} name The name of the block to check. 8037 * @return {boolean} Whether the block is a content block. 8038 */ 8039 function isContentBlock(name) { 8040 const attributes = getBlockType(name)?.attributes; 8041 if (!attributes) { 8042 return false; 8043 } 8044 return !!Object.keys(attributes)?.some(attributeKey => { 8045 const attribute = attributes[attributeKey]; 8046 return attribute?.role === 'content' || attribute?.__experimentalRole === 'content'; 8047 }); 8048 } 8049 8050 /** 8051 * Return a new object with the specified keys omitted. 8052 * 8053 * @param {Object} object Original object. 8054 * @param {Array} keys Keys to be omitted. 8055 * 8056 * @return {Object} Object with omitted keys. 8057 */ 8058 function omit(object, keys) { 8059 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 8060 } 8061 8062 ;// ./node_modules/@wordpress/blocks/build-module/store/reducer.js 8063 /** 8064 * External dependencies 8065 */ 8066 8067 8068 /** 8069 * WordPress dependencies 8070 */ 8071 8072 8073 8074 /** 8075 * Internal dependencies 8076 */ 8077 8078 8079 /** 8080 * @typedef {Object} WPBlockCategory 8081 * 8082 * @property {string} slug Unique category slug. 8083 * @property {string} title Category label, for display in user interface. 8084 */ 8085 8086 /** 8087 * Default set of categories. 8088 * 8089 * @type {WPBlockCategory[]} 8090 */ 8091 const DEFAULT_CATEGORIES = [{ 8092 slug: 'text', 8093 title: (0,external_wp_i18n_namespaceObject.__)('Text') 8094 }, { 8095 slug: 'media', 8096 title: (0,external_wp_i18n_namespaceObject.__)('Media') 8097 }, { 8098 slug: 'design', 8099 title: (0,external_wp_i18n_namespaceObject.__)('Design') 8100 }, { 8101 slug: 'widgets', 8102 title: (0,external_wp_i18n_namespaceObject.__)('Widgets') 8103 }, { 8104 slug: 'theme', 8105 title: (0,external_wp_i18n_namespaceObject.__)('Theme') 8106 }, { 8107 slug: 'embed', 8108 title: (0,external_wp_i18n_namespaceObject.__)('Embeds') 8109 }, { 8110 slug: 'reusable', 8111 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks') 8112 }]; 8113 8114 // Key block types by their name. 8115 function keyBlockTypesByName(types) { 8116 return types.reduce((newBlockTypes, block) => ({ 8117 ...newBlockTypes, 8118 [block.name]: block 8119 }), {}); 8120 } 8121 8122 // Filter items to ensure they're unique by their name. 8123 function getUniqueItemsByName(items) { 8124 return items.reduce((acc, currentItem) => { 8125 if (!acc.some(item => item.name === currentItem.name)) { 8126 acc.push(currentItem); 8127 } 8128 return acc; 8129 }, []); 8130 } 8131 function bootstrappedBlockTypes(state = {}, action) { 8132 switch (action.type) { 8133 case 'ADD_BOOTSTRAPPED_BLOCK_TYPE': 8134 const { 8135 name, 8136 blockType 8137 } = action; 8138 const serverDefinition = state[name]; 8139 let newDefinition; 8140 // Don't overwrite if already set. It covers the case when metadata 8141 // was initialized from the server. 8142 if (serverDefinition) { 8143 // The `blockHooks` prop is not yet included in the server provided 8144 // definitions and needs to be polyfilled. This can be removed when the 8145 // minimum supported WordPress is >= 6.4. 8146 if (serverDefinition.blockHooks === undefined && blockType.blockHooks) { 8147 newDefinition = { 8148 ...serverDefinition, 8149 ...newDefinition, 8150 blockHooks: blockType.blockHooks 8151 }; 8152 } 8153 8154 // The `allowedBlocks` prop is not yet included in the server provided 8155 // definitions and needs to be polyfilled. This can be removed when the 8156 // minimum supported WordPress is >= 6.5. 8157 if (serverDefinition.allowedBlocks === undefined && blockType.allowedBlocks) { 8158 newDefinition = { 8159 ...serverDefinition, 8160 ...newDefinition, 8161 allowedBlocks: blockType.allowedBlocks 8162 }; 8163 } 8164 } else { 8165 newDefinition = Object.fromEntries(Object.entries(blockType).filter(([, value]) => value !== null && value !== undefined).map(([key, value]) => [camelCase(key), value])); 8166 newDefinition.name = name; 8167 } 8168 if (newDefinition) { 8169 return { 8170 ...state, 8171 [name]: newDefinition 8172 }; 8173 } 8174 return state; 8175 case 'REMOVE_BLOCK_TYPES': 8176 return omit(state, action.names); 8177 } 8178 return state; 8179 } 8180 8181 /** 8182 * Reducer managing the unprocessed block types in a form passed when registering the by block. 8183 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters 8184 * get added or removed. 8185 * 8186 * @param {Object} state Current state. 8187 * @param {Object} action Dispatched action. 8188 * 8189 * @return {Object} Updated state. 8190 */ 8191 function unprocessedBlockTypes(state = {}, action) { 8192 switch (action.type) { 8193 case 'ADD_UNPROCESSED_BLOCK_TYPE': 8194 return { 8195 ...state, 8196 [action.name]: action.blockType 8197 }; 8198 case 'REMOVE_BLOCK_TYPES': 8199 return omit(state, action.names); 8200 } 8201 return state; 8202 } 8203 8204 /** 8205 * Reducer managing the processed block types with all filters applied. 8206 * The state is derived from the `unprocessedBlockTypes` reducer. 8207 * 8208 * @param {Object} state Current state. 8209 * @param {Object} action Dispatched action. 8210 * 8211 * @return {Object} Updated state. 8212 */ 8213 function blockTypes(state = {}, action) { 8214 switch (action.type) { 8215 case 'ADD_BLOCK_TYPES': 8216 return { 8217 ...state, 8218 ...keyBlockTypesByName(action.blockTypes) 8219 }; 8220 case 'REMOVE_BLOCK_TYPES': 8221 return omit(state, action.names); 8222 } 8223 return state; 8224 } 8225 8226 /** 8227 * Reducer managing the block styles. 8228 * 8229 * @param {Object} state Current state. 8230 * @param {Object} action Dispatched action. 8231 * 8232 * @return {Object} Updated state. 8233 */ 8234 function blockStyles(state = {}, action) { 8235 var _state$action$blockNa; 8236 switch (action.type) { 8237 case 'ADD_BLOCK_TYPES': 8238 return { 8239 ...state, 8240 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8241 var _blockType$styles, _state$blockType$name; 8242 return [name, getUniqueItemsByName([...((_blockType$styles = blockType.styles) !== null && _blockType$styles !== void 0 ? _blockType$styles : []).map(style => ({ 8243 ...style, 8244 source: 'block' 8245 })), ...((_state$blockType$name = state[blockType.name]) !== null && _state$blockType$name !== void 0 ? _state$blockType$name : []).filter(({ 8246 source 8247 }) => 'block' !== source)])]; 8248 })) 8249 }; 8250 case 'ADD_BLOCK_STYLES': 8251 const updatedStyles = {}; 8252 action.blockNames.forEach(blockName => { 8253 var _state$blockName; 8254 updatedStyles[blockName] = getUniqueItemsByName([...((_state$blockName = state[blockName]) !== null && _state$blockName !== void 0 ? _state$blockName : []), ...action.styles]); 8255 }); 8256 return { 8257 ...state, 8258 ...updatedStyles 8259 }; 8260 case 'REMOVE_BLOCK_STYLES': 8261 return { 8262 ...state, 8263 [action.blockName]: ((_state$action$blockNa = state[action.blockName]) !== null && _state$action$blockNa !== void 0 ? _state$action$blockNa : []).filter(style => action.styleNames.indexOf(style.name) === -1) 8264 }; 8265 } 8266 return state; 8267 } 8268 8269 /** 8270 * Reducer managing the block variations. 8271 * 8272 * @param {Object} state Current state. 8273 * @param {Object} action Dispatched action. 8274 * 8275 * @return {Object} Updated state. 8276 */ 8277 function blockVariations(state = {}, action) { 8278 var _state$action$blockNa2, _state$action$blockNa3; 8279 switch (action.type) { 8280 case 'ADD_BLOCK_TYPES': 8281 return { 8282 ...state, 8283 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8284 var _blockType$variations, _state$blockType$name2; 8285 return [name, getUniqueItemsByName([...((_blockType$variations = blockType.variations) !== null && _blockType$variations !== void 0 ? _blockType$variations : []).map(variation => ({ 8286 ...variation, 8287 source: 'block' 8288 })), ...((_state$blockType$name2 = state[blockType.name]) !== null && _state$blockType$name2 !== void 0 ? _state$blockType$name2 : []).filter(({ 8289 source 8290 }) => 'block' !== source)])]; 8291 })) 8292 }; 8293 case 'ADD_BLOCK_VARIATIONS': 8294 return { 8295 ...state, 8296 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa2 = state[action.blockName]) !== null && _state$action$blockNa2 !== void 0 ? _state$action$blockNa2 : []), ...action.variations]) 8297 }; 8298 case 'REMOVE_BLOCK_VARIATIONS': 8299 return { 8300 ...state, 8301 [action.blockName]: ((_state$action$blockNa3 = state[action.blockName]) !== null && _state$action$blockNa3 !== void 0 ? _state$action$blockNa3 : []).filter(variation => action.variationNames.indexOf(variation.name) === -1) 8302 }; 8303 } 8304 return state; 8305 } 8306 8307 /** 8308 * Higher-order Reducer creating a reducer keeping track of given block name. 8309 * 8310 * @param {string} setActionType Action type. 8311 * 8312 * @return {Function} Reducer. 8313 */ 8314 function createBlockNameSetterReducer(setActionType) { 8315 return (state = null, action) => { 8316 switch (action.type) { 8317 case 'REMOVE_BLOCK_TYPES': 8318 if (action.names.indexOf(state) !== -1) { 8319 return null; 8320 } 8321 return state; 8322 case setActionType: 8323 return action.name || null; 8324 } 8325 return state; 8326 }; 8327 } 8328 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 8329 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 8330 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 8331 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 8332 8333 /** 8334 * Reducer managing the categories 8335 * 8336 * @param {WPBlockCategory[]} state Current state. 8337 * @param {Object} action Dispatched action. 8338 * 8339 * @return {WPBlockCategory[]} Updated state. 8340 */ 8341 function categories(state = DEFAULT_CATEGORIES, action) { 8342 switch (action.type) { 8343 case 'SET_CATEGORIES': 8344 // Ensure, that categories are unique by slug. 8345 const uniqueCategories = new Map(); 8346 (action.categories || []).forEach(category => { 8347 uniqueCategories.set(category.slug, category); 8348 }); 8349 return [...uniqueCategories.values()]; 8350 case 'UPDATE_CATEGORY': 8351 { 8352 if (!action.category || !Object.keys(action.category).length) { 8353 return state; 8354 } 8355 const categoryToChange = state.find(({ 8356 slug 8357 }) => slug === action.slug); 8358 if (categoryToChange) { 8359 return state.map(category => { 8360 if (category.slug === action.slug) { 8361 return { 8362 ...category, 8363 ...action.category 8364 }; 8365 } 8366 return category; 8367 }); 8368 } 8369 } 8370 } 8371 return state; 8372 } 8373 function collections(state = {}, action) { 8374 switch (action.type) { 8375 case 'ADD_BLOCK_COLLECTION': 8376 return { 8377 ...state, 8378 [action.namespace]: { 8379 title: action.title, 8380 icon: action.icon 8381 } 8382 }; 8383 case 'REMOVE_BLOCK_COLLECTION': 8384 return omit(state, action.namespace); 8385 } 8386 return state; 8387 } 8388 8389 /** 8390 * Merges usesContext with existing values, potentially defined in the server registration. 8391 * 8392 * @param {string[]} existingUsesContext Existing `usesContext`. 8393 * @param {string[]} newUsesContext Newly added `usesContext`. 8394 * @return {string[]|undefined} Merged `usesContext`. 8395 */ 8396 function getMergedUsesContext(existingUsesContext = [], newUsesContext = []) { 8397 const mergedArrays = Array.from(new Set(existingUsesContext.concat(newUsesContext))); 8398 return mergedArrays.length > 0 ? mergedArrays : undefined; 8399 } 8400 function blockBindingsSources(state = {}, action) { 8401 switch (action.type) { 8402 case 'ADD_BLOCK_BINDINGS_SOURCE': 8403 // Only open this API in Gutenberg and for `core/post-meta` for the moment. 8404 let getFieldsList; 8405 if (false) {} else if (action.name === 'core/post-meta') { 8406 getFieldsList = action.getFieldsList; 8407 } 8408 return { 8409 ...state, 8410 [action.name]: { 8411 label: action.label || state[action.name]?.label, 8412 usesContext: getMergedUsesContext(state[action.name]?.usesContext, action.usesContext), 8413 getValues: action.getValues, 8414 setValues: action.setValues, 8415 // Only set `canUserEditValue` if `setValues` is also defined. 8416 canUserEditValue: action.setValues && action.canUserEditValue, 8417 getFieldsList 8418 } 8419 }; 8420 case 'REMOVE_BLOCK_BINDINGS_SOURCE': 8421 return omit(state, action.name); 8422 } 8423 return state; 8424 } 8425 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ 8426 bootstrappedBlockTypes, 8427 unprocessedBlockTypes, 8428 blockTypes, 8429 blockStyles, 8430 blockVariations, 8431 defaultBlockName, 8432 freeformFallbackBlockName, 8433 unregisteredFallbackBlockName, 8434 groupingBlockName, 8435 categories, 8436 collections, 8437 blockBindingsSources 8438 })); 8439 8440 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js 8441 var remove_accents = __webpack_require__(9681); 8442 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 8443 ;// ./node_modules/@wordpress/blocks/build-module/store/utils.js 8444 /** 8445 * Helper util to return a value from a certain path of the object. 8446 * Path is specified as either: 8447 * - a string of properties, separated by dots, for example: "x.y". 8448 * - an array of properties, for example `[ 'x', 'y' ]`. 8449 * You can also specify a default value in case the result is nullish. 8450 * 8451 * @param {Object} object Input object. 8452 * @param {string|Array} path Path to the object property. 8453 * @param {*} defaultValue Default value if the value at the specified path is nullish. 8454 * @return {*} Value of the object property at the specified path. 8455 */ 8456 const getValueFromObjectPath = (object, path, defaultValue) => { 8457 var _value; 8458 const normalizedPath = Array.isArray(path) ? path : path.split('.'); 8459 let value = object; 8460 normalizedPath.forEach(fieldName => { 8461 value = value?.[fieldName]; 8462 }); 8463 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 8464 }; 8465 function utils_isObject(candidate) { 8466 return typeof candidate === 'object' && candidate.constructor === Object && candidate !== null; 8467 } 8468 8469 /** 8470 * Determine whether a set of object properties matches a given object. 8471 * 8472 * Given an object of block attributes and an object of variation attributes, 8473 * this function checks recursively whether all the variation attributes are 8474 * present in the block attributes object. 8475 * 8476 * @param {Object} blockAttributes The object to inspect. 8477 * @param {Object} variationAttributes The object of property values to match. 8478 * @return {boolean} Whether the block attributes match the variation attributes. 8479 */ 8480 function matchesAttributes(blockAttributes, variationAttributes) { 8481 if (utils_isObject(blockAttributes) && utils_isObject(variationAttributes)) { 8482 return Object.entries(variationAttributes).every(([key, value]) => matchesAttributes(blockAttributes?.[key], value)); 8483 } 8484 return blockAttributes === variationAttributes; 8485 } 8486 8487 ;// ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 8488 /** 8489 * WordPress dependencies 8490 */ 8491 8492 8493 8494 /** 8495 * Internal dependencies 8496 */ 8497 8498 8499 8500 const ROOT_BLOCK_SUPPORTS = ['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'padding', 'contentSize', 'wideSize', 'blockGap', 'textDecoration', 'textTransform', 'letterSpacing']; 8501 8502 /** 8503 * Filters the list of supported styles for a given element. 8504 * 8505 * @param {string[]} blockSupports list of supported styles. 8506 * @param {string|undefined} name block name. 8507 * @param {string|undefined} element element name. 8508 * 8509 * @return {string[]} filtered list of supported styles. 8510 */ 8511 function filterElementBlockSupports(blockSupports, name, element) { 8512 return blockSupports.filter(support => { 8513 if (support === 'fontSize' && element === 'heading') { 8514 return false; 8515 } 8516 8517 // This is only available for links 8518 if (support === 'textDecoration' && !name && element !== 'link') { 8519 return false; 8520 } 8521 8522 // This is only available for heading, button, caption and text 8523 if (support === 'textTransform' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 8524 return false; 8525 } 8526 8527 // This is only available for heading, button, caption and text 8528 if (support === 'letterSpacing' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 8529 return false; 8530 } 8531 8532 // Text columns is only available for blocks. 8533 if (support === 'textColumns' && !name) { 8534 return false; 8535 } 8536 return true; 8537 }); 8538 } 8539 8540 /** 8541 * Returns the list of supported styles for a given block name and element. 8542 */ 8543 const getSupportedStyles = (0,external_wp_data_namespaceObject.createSelector)((state, name, element) => { 8544 if (!name) { 8545 return filterElementBlockSupports(ROOT_BLOCK_SUPPORTS, name, element); 8546 } 8547 const blockType = selectors_getBlockType(state, name); 8548 if (!blockType) { 8549 return []; 8550 } 8551 const supportKeys = []; 8552 8553 // Check for blockGap support. 8554 // Block spacing support doesn't map directly to a single style property, so needs to be handled separately. 8555 if (blockType?.supports?.spacing?.blockGap) { 8556 supportKeys.push('blockGap'); 8557 } 8558 8559 // check for shadow support 8560 if (blockType?.supports?.shadow) { 8561 supportKeys.push('shadow'); 8562 } 8563 Object.keys(__EXPERIMENTAL_STYLE_PROPERTY).forEach(styleName => { 8564 if (!__EXPERIMENTAL_STYLE_PROPERTY[styleName].support) { 8565 return; 8566 } 8567 8568 // Opting out means that, for certain support keys like background color, 8569 // blocks have to explicitly set the support value false. If the key is 8570 // unset, we still enable it. 8571 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].requiresOptOut) { 8572 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].support[0] in blockType.supports && getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support) !== false) { 8573 supportKeys.push(styleName); 8574 return; 8575 } 8576 } 8577 if (getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support, false)) { 8578 supportKeys.push(styleName); 8579 } 8580 }); 8581 return filterElementBlockSupports(supportKeys, name, element); 8582 }, (state, name) => [state.blockTypes[name]]); 8583 8584 /** 8585 * Returns the bootstrapped block type metadata for a give block name. 8586 * 8587 * @param {Object} state Data state. 8588 * @param {string} name Block name. 8589 * 8590 * @return {Object} Bootstrapped block type metadata for a block. 8591 */ 8592 function getBootstrappedBlockType(state, name) { 8593 return state.bootstrappedBlockTypes[name]; 8594 } 8595 8596 /** 8597 * Returns all the unprocessed (before applying the `registerBlockType` filter) 8598 * block type settings as passed during block registration. 8599 * 8600 * @param {Object} state Data state. 8601 * 8602 * @return {Array} Unprocessed block type settings for all blocks. 8603 */ 8604 function getUnprocessedBlockTypes(state) { 8605 return state.unprocessedBlockTypes; 8606 } 8607 8608 /** 8609 * Returns all the block bindings sources registered. 8610 * 8611 * @param {Object} state Data state. 8612 * 8613 * @return {Object} All the registered sources and their properties. 8614 */ 8615 function getAllBlockBindingsSources(state) { 8616 return state.blockBindingsSources; 8617 } 8618 8619 /** 8620 * Returns a specific block bindings source. 8621 * 8622 * @param {Object} state Data state. 8623 * @param {string} sourceName Name of the source to get. 8624 * 8625 * @return {Object} The specific block binding source and its properties. 8626 */ 8627 function private_selectors_getBlockBindingsSource(state, sourceName) { 8628 return state.blockBindingsSources[sourceName]; 8629 } 8630 8631 /** 8632 * Determines if any of the block type's attributes have 8633 * the content role attribute. 8634 * 8635 * @param {Object} state Data state. 8636 * @param {string} blockTypeName Block type name. 8637 * @return {boolean} Whether block type has content role attribute. 8638 */ 8639 const hasContentRoleAttribute = (state, blockTypeName) => { 8640 const blockType = selectors_getBlockType(state, blockTypeName); 8641 if (!blockType) { 8642 return false; 8643 } 8644 return Object.values(blockType.attributes).some(({ 8645 role, 8646 __experimentalRole 8647 }) => { 8648 if (role === 'content') { 8649 return true; 8650 } 8651 if (__experimentalRole === 'content') { 8652 external_wp_deprecated_default()('__experimentalRole attribute', { 8653 since: '6.7', 8654 version: '6.8', 8655 alternative: 'role attribute', 8656 hint: `Check the block.json of the $blockTypeName} block.` 8657 }); 8658 return true; 8659 } 8660 return false; 8661 }); 8662 }; 8663 8664 ;// ./node_modules/@wordpress/blocks/build-module/store/selectors.js 8665 /** 8666 * External dependencies 8667 */ 8668 8669 8670 /** 8671 * WordPress dependencies 8672 */ 8673 8674 8675 8676 8677 /** 8678 * Internal dependencies 8679 */ 8680 8681 8682 8683 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 8684 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 8685 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 8686 8687 /** 8688 * Given a block name or block type object, returns the corresponding 8689 * normalized block type object. 8690 * 8691 * @param {Object} state Blocks state. 8692 * @param {(string|Object)} nameOrType Block name or type object 8693 * 8694 * @return {Object} Block type object. 8695 */ 8696 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType; 8697 8698 /** 8699 * Returns all the available block types. 8700 * 8701 * @param {Object} state Data state. 8702 * 8703 * @example 8704 * ```js 8705 * import { store as blocksStore } from '@wordpress/blocks'; 8706 * import { useSelect } from '@wordpress/data'; 8707 * 8708 * const ExampleComponent = () => { 8709 * const blockTypes = useSelect( 8710 * ( select ) => select( blocksStore ).getBlockTypes(), 8711 * [] 8712 * ); 8713 * 8714 * return ( 8715 * <ul> 8716 * { blockTypes.map( ( block ) => ( 8717 * <li key={ block.name }>{ block.title }</li> 8718 * ) ) } 8719 * </ul> 8720 * ); 8721 * }; 8722 * ``` 8723 * 8724 * @return {Array} Block Types. 8725 */ 8726 const selectors_getBlockTypes = (0,external_wp_data_namespaceObject.createSelector)(state => Object.values(state.blockTypes), state => [state.blockTypes]); 8727 8728 /** 8729 * Returns a block type by name. 8730 * 8731 * @param {Object} state Data state. 8732 * @param {string} name Block type name. 8733 * 8734 * @example 8735 * ```js 8736 * import { store as blocksStore } from '@wordpress/blocks'; 8737 * import { useSelect } from '@wordpress/data'; 8738 * 8739 * const ExampleComponent = () => { 8740 * const paragraphBlock = useSelect( ( select ) => 8741 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ), 8742 * [] 8743 * ); 8744 * 8745 * return ( 8746 * <ul> 8747 * { paragraphBlock && 8748 * Object.entries( paragraphBlock.supports ).map( 8749 * ( blockSupportsEntry ) => { 8750 * const [ propertyName, value ] = blockSupportsEntry; 8751 * return ( 8752 * <li 8753 * key={ propertyName } 8754 * >{ `${ propertyName } : ${ value }` }</li> 8755 * ); 8756 * } 8757 * ) } 8758 * </ul> 8759 * ); 8760 * }; 8761 * ``` 8762 * 8763 * @return {?Object} Block Type. 8764 */ 8765 function selectors_getBlockType(state, name) { 8766 return state.blockTypes[name]; 8767 } 8768 8769 /** 8770 * Returns block styles by block name. 8771 * 8772 * @param {Object} state Data state. 8773 * @param {string} name Block type name. 8774 * 8775 * @example 8776 * ```js 8777 * import { store as blocksStore } from '@wordpress/blocks'; 8778 * import { useSelect } from '@wordpress/data'; 8779 * 8780 * const ExampleComponent = () => { 8781 * const buttonBlockStyles = useSelect( ( select ) => 8782 * select( blocksStore ).getBlockStyles( 'core/button' ), 8783 * [] 8784 * ); 8785 * 8786 * return ( 8787 * <ul> 8788 * { buttonBlockStyles && 8789 * buttonBlockStyles.map( ( style ) => ( 8790 * <li key={ style.name }>{ style.label }</li> 8791 * ) ) } 8792 * </ul> 8793 * ); 8794 * }; 8795 * ``` 8796 * 8797 * @return {Array?} Block Styles. 8798 */ 8799 function getBlockStyles(state, name) { 8800 return state.blockStyles[name]; 8801 } 8802 8803 /** 8804 * Returns block variations by block name. 8805 * 8806 * @param {Object} state Data state. 8807 * @param {string} blockName Block type name. 8808 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8809 * 8810 * @example 8811 * ```js 8812 * import { store as blocksStore } from '@wordpress/blocks'; 8813 * import { useSelect } from '@wordpress/data'; 8814 * 8815 * const ExampleComponent = () => { 8816 * const socialLinkVariations = useSelect( ( select ) => 8817 * select( blocksStore ).getBlockVariations( 'core/social-link' ), 8818 * [] 8819 * ); 8820 * 8821 * return ( 8822 * <ul> 8823 * { socialLinkVariations && 8824 * socialLinkVariations.map( ( variation ) => ( 8825 * <li key={ variation.name }>{ variation.title }</li> 8826 * ) ) } 8827 * </ul> 8828 * ); 8829 * }; 8830 * ``` 8831 * 8832 * @return {(WPBlockVariation[]|void)} Block variations. 8833 */ 8834 const selectors_getBlockVariations = (0,external_wp_data_namespaceObject.createSelector)((state, blockName, scope) => { 8835 const variations = state.blockVariations[blockName]; 8836 if (!variations || !scope) { 8837 return variations; 8838 } 8839 return variations.filter(variation => { 8840 // For backward compatibility reasons, variation's scope defaults to 8841 // `block` and `inserter` when not set. 8842 return (variation.scope || ['block', 'inserter']).includes(scope); 8843 }); 8844 }, (state, blockName) => [state.blockVariations[blockName]]); 8845 8846 /** 8847 * Returns the active block variation for a given block based on its attributes. 8848 * Variations are determined by their `isActive` property. 8849 * Which is either an array of block attribute keys or a function. 8850 * 8851 * In case of an array of block attribute keys, the `attributes` are compared 8852 * to the variation's attributes using strict equality check. 8853 * 8854 * In case of function type, the function should accept a block's attributes 8855 * and the variation's attributes and determines if a variation is active. 8856 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 8857 * 8858 * @param {Object} state Data state. 8859 * @param {string} blockName Name of block (example: “core/columns”). 8860 * @param {Object} attributes Block attributes used to determine active variation. 8861 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8862 * 8863 * @example 8864 * ```js 8865 * import { __ } from '@wordpress/i18n'; 8866 * import { store as blocksStore } from '@wordpress/blocks'; 8867 * import { store as blockEditorStore } from '@wordpress/block-editor'; 8868 * import { useSelect } from '@wordpress/data'; 8869 * 8870 * const ExampleComponent = () => { 8871 * // This example assumes that a core/embed block is the first block in the Block Editor. 8872 * const activeBlockVariation = useSelect( ( select ) => { 8873 * // Retrieve the list of blocks. 8874 * const [ firstBlock ] = select( blockEditorStore ).getBlocks() 8875 * 8876 * // Return the active block variation for the first block. 8877 * return select( blocksStore ).getActiveBlockVariation( 8878 * firstBlock.name, 8879 * firstBlock.attributes 8880 * ); 8881 * }, [] ); 8882 * 8883 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? ( 8884 * <p>{ __( 'Spotify variation' ) }</p> 8885 * ) : ( 8886 * <p>{ __( 'Other variation' ) }</p> 8887 * ); 8888 * }; 8889 * ``` 8890 * 8891 * @return {(WPBlockVariation|undefined)} Active block variation. 8892 */ 8893 function getActiveBlockVariation(state, blockName, attributes, scope) { 8894 const variations = selectors_getBlockVariations(state, blockName, scope); 8895 if (!variations) { 8896 return variations; 8897 } 8898 const blockType = selectors_getBlockType(state, blockName); 8899 const attributeKeys = Object.keys(blockType?.attributes || {}); 8900 let match; 8901 let maxMatchedAttributes = 0; 8902 for (const variation of variations) { 8903 if (Array.isArray(variation.isActive)) { 8904 const definedAttributes = variation.isActive.filter(attribute => { 8905 // We support nested attribute paths, e.g. `layout.type`. 8906 // In this case, we need to check if the part before the 8907 // first dot is a known attribute. 8908 const topLevelAttribute = attribute.split('.')[0]; 8909 return attributeKeys.includes(topLevelAttribute); 8910 }); 8911 const definedAttributesLength = definedAttributes.length; 8912 if (definedAttributesLength === 0) { 8913 continue; 8914 } 8915 const isMatch = definedAttributes.every(attribute => { 8916 const variationAttributeValue = getValueFromObjectPath(variation.attributes, attribute); 8917 if (variationAttributeValue === undefined) { 8918 return false; 8919 } 8920 let blockAttributeValue = getValueFromObjectPath(attributes, attribute); 8921 if (blockAttributeValue instanceof external_wp_richText_namespaceObject.RichTextData) { 8922 blockAttributeValue = blockAttributeValue.toHTMLString(); 8923 } 8924 return matchesAttributes(blockAttributeValue, variationAttributeValue); 8925 }); 8926 if (isMatch && definedAttributesLength > maxMatchedAttributes) { 8927 match = variation; 8928 maxMatchedAttributes = definedAttributesLength; 8929 } 8930 } else if (variation.isActive?.(attributes, variation.attributes)) { 8931 // If isActive is a function, we cannot know how many attributes it matches. 8932 // This means that we cannot compare the specificity of our matches, 8933 // and simply return the best match we have found. 8934 return match || variation; 8935 } 8936 } 8937 return match; 8938 } 8939 8940 /** 8941 * Returns the default block variation for the given block type. 8942 * When there are multiple variations annotated as the default one, 8943 * the last added item is picked. This simplifies registering overrides. 8944 * When there is no default variation set, it returns the first item. 8945 * 8946 * @param {Object} state Data state. 8947 * @param {string} blockName Block type name. 8948 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8949 * 8950 * @example 8951 * ```js 8952 * import { __, sprintf } from '@wordpress/i18n'; 8953 * import { store as blocksStore } from '@wordpress/blocks'; 8954 * import { useSelect } from '@wordpress/data'; 8955 * 8956 * const ExampleComponent = () => { 8957 * const defaultEmbedBlockVariation = useSelect( ( select ) => 8958 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ), 8959 * [] 8960 * ); 8961 * 8962 * return ( 8963 * defaultEmbedBlockVariation && ( 8964 * <p> 8965 * { sprintf( 8966 * __( 'core/embed default variation: %s' ), 8967 * defaultEmbedBlockVariation.title 8968 * ) } 8969 * </p> 8970 * ) 8971 * ); 8972 * }; 8973 * ``` 8974 * 8975 * @return {?WPBlockVariation} The default block variation. 8976 */ 8977 function getDefaultBlockVariation(state, blockName, scope) { 8978 const variations = selectors_getBlockVariations(state, blockName, scope); 8979 const defaultVariation = [...variations].reverse().find(({ 8980 isDefault 8981 }) => !!isDefault); 8982 return defaultVariation || variations[0]; 8983 } 8984 8985 /** 8986 * Returns all the available block categories. 8987 * 8988 * @param {Object} state Data state. 8989 * 8990 * @example 8991 * ```js 8992 * import { store as blocksStore } from '@wordpress/blocks'; 8993 * import { useSelect, } from '@wordpress/data'; 8994 * 8995 * const ExampleComponent = () => { 8996 * const blockCategories = useSelect( ( select ) => 8997 * select( blocksStore ).getCategories(), 8998 * [] 8999 * ); 9000 * 9001 * return ( 9002 * <ul> 9003 * { blockCategories.map( ( category ) => ( 9004 * <li key={ category.slug }>{ category.title }</li> 9005 * ) ) } 9006 * </ul> 9007 * ); 9008 * }; 9009 * ``` 9010 * 9011 * @return {WPBlockCategory[]} Categories list. 9012 */ 9013 function getCategories(state) { 9014 return state.categories; 9015 } 9016 9017 /** 9018 * Returns all the available collections. 9019 * 9020 * @param {Object} state Data state. 9021 * 9022 * @example 9023 * ```js 9024 * import { store as blocksStore } from '@wordpress/blocks'; 9025 * import { useSelect } from '@wordpress/data'; 9026 * 9027 * const ExampleComponent = () => { 9028 * const blockCollections = useSelect( ( select ) => 9029 * select( blocksStore ).getCollections(), 9030 * [] 9031 * ); 9032 * 9033 * return ( 9034 * <ul> 9035 * { Object.values( blockCollections ).length > 0 && 9036 * Object.values( blockCollections ).map( ( collection ) => ( 9037 * <li key={ collection.title }>{ collection.title }</li> 9038 * ) ) } 9039 * </ul> 9040 * ); 9041 * }; 9042 * ``` 9043 * 9044 * @return {Object} Collections list. 9045 */ 9046 function getCollections(state) { 9047 return state.collections; 9048 } 9049 9050 /** 9051 * Returns the name of the default block name. 9052 * 9053 * @param {Object} state Data state. 9054 * 9055 * @example 9056 * ```js 9057 * import { __, sprintf } from '@wordpress/i18n'; 9058 * import { store as blocksStore } from '@wordpress/blocks'; 9059 * import { useSelect } from '@wordpress/data'; 9060 * 9061 * const ExampleComponent = () => { 9062 * const defaultBlockName = useSelect( ( select ) => 9063 * select( blocksStore ).getDefaultBlockName(), 9064 * [] 9065 * ); 9066 * 9067 * return ( 9068 * defaultBlockName && ( 9069 * <p> 9070 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) } 9071 * </p> 9072 * ) 9073 * ); 9074 * }; 9075 * ``` 9076 * 9077 * @return {?string} Default block name. 9078 */ 9079 function selectors_getDefaultBlockName(state) { 9080 return state.defaultBlockName; 9081 } 9082 9083 /** 9084 * Returns the name of the block for handling non-block content. 9085 * 9086 * @param {Object} state Data state. 9087 * 9088 * @example 9089 * ```js 9090 * import { __, sprintf } from '@wordpress/i18n'; 9091 * import { store as blocksStore } from '@wordpress/blocks'; 9092 * import { useSelect } from '@wordpress/data'; 9093 * 9094 * const ExampleComponent = () => { 9095 * const freeformFallbackBlockName = useSelect( ( select ) => 9096 * select( blocksStore ).getFreeformFallbackBlockName(), 9097 * [] 9098 * ); 9099 * 9100 * return ( 9101 * freeformFallbackBlockName && ( 9102 * <p> 9103 * { sprintf( __( 9104 * 'Freeform fallback block name: %s' ), 9105 * freeformFallbackBlockName 9106 * ) } 9107 * </p> 9108 * ) 9109 * ); 9110 * }; 9111 * ``` 9112 * 9113 * @return {?string} Name of the block for handling non-block content. 9114 */ 9115 function getFreeformFallbackBlockName(state) { 9116 return state.freeformFallbackBlockName; 9117 } 9118 9119 /** 9120 * Returns the name of the block for handling unregistered blocks. 9121 * 9122 * @param {Object} state Data state. 9123 * 9124 * @example 9125 * ```js 9126 * import { __, sprintf } from '@wordpress/i18n'; 9127 * import { store as blocksStore } from '@wordpress/blocks'; 9128 * import { useSelect } from '@wordpress/data'; 9129 * 9130 * const ExampleComponent = () => { 9131 * const unregisteredFallbackBlockName = useSelect( ( select ) => 9132 * select( blocksStore ).getUnregisteredFallbackBlockName(), 9133 * [] 9134 * ); 9135 * 9136 * return ( 9137 * unregisteredFallbackBlockName && ( 9138 * <p> 9139 * { sprintf( __( 9140 * 'Unregistered fallback block name: %s' ), 9141 * unregisteredFallbackBlockName 9142 * ) } 9143 * </p> 9144 * ) 9145 * ); 9146 * }; 9147 * ``` 9148 * 9149 * @return {?string} Name of the block for handling unregistered blocks. 9150 */ 9151 function getUnregisteredFallbackBlockName(state) { 9152 return state.unregisteredFallbackBlockName; 9153 } 9154 9155 /** 9156 * Returns the name of the block for handling the grouping of blocks. 9157 * 9158 * @param {Object} state Data state. 9159 * 9160 * @example 9161 * ```js 9162 * import { __, sprintf } from '@wordpress/i18n'; 9163 * import { store as blocksStore } from '@wordpress/blocks'; 9164 * import { useSelect } from '@wordpress/data'; 9165 * 9166 * const ExampleComponent = () => { 9167 * const groupingBlockName = useSelect( ( select ) => 9168 * select( blocksStore ).getGroupingBlockName(), 9169 * [] 9170 * ); 9171 * 9172 * return ( 9173 * groupingBlockName && ( 9174 * <p> 9175 * { sprintf( 9176 * __( 'Default grouping block name: %s' ), 9177 * groupingBlockName 9178 * ) } 9179 * </p> 9180 * ) 9181 * ); 9182 * }; 9183 * ``` 9184 * 9185 * @return {?string} Name of the block for handling the grouping of blocks. 9186 */ 9187 function selectors_getGroupingBlockName(state) { 9188 return state.groupingBlockName; 9189 } 9190 9191 /** 9192 * Returns an array with the child blocks of a given block. 9193 * 9194 * @param {Object} state Data state. 9195 * @param {string} blockName Block type name. 9196 * 9197 * @example 9198 * ```js 9199 * import { store as blocksStore } from '@wordpress/blocks'; 9200 * import { useSelect } from '@wordpress/data'; 9201 * 9202 * const ExampleComponent = () => { 9203 * const childBlockNames = useSelect( ( select ) => 9204 * select( blocksStore ).getChildBlockNames( 'core/navigation' ), 9205 * [] 9206 * ); 9207 * 9208 * return ( 9209 * <ul> 9210 * { childBlockNames && 9211 * childBlockNames.map( ( child ) => ( 9212 * <li key={ child }>{ child }</li> 9213 * ) ) } 9214 * </ul> 9215 * ); 9216 * }; 9217 * ``` 9218 * 9219 * @return {Array} Array of child block names. 9220 */ 9221 const selectors_getChildBlockNames = (0,external_wp_data_namespaceObject.createSelector)((state, blockName) => { 9222 return selectors_getBlockTypes(state).filter(blockType => { 9223 return blockType.parent?.includes(blockName); 9224 }).map(({ 9225 name 9226 }) => name); 9227 }, state => [state.blockTypes]); 9228 9229 /** 9230 * Returns the block support value for a feature, if defined. 9231 * 9232 * @param {Object} state Data state. 9233 * @param {(string|Object)} nameOrType Block name or type object 9234 * @param {Array|string} feature Feature to retrieve 9235 * @param {*} defaultSupports Default value to return if not 9236 * explicitly defined 9237 * 9238 * @example 9239 * ```js 9240 * import { __, sprintf } from '@wordpress/i18n'; 9241 * import { store as blocksStore } from '@wordpress/blocks'; 9242 * import { useSelect } from '@wordpress/data'; 9243 * 9244 * const ExampleComponent = () => { 9245 * const paragraphBlockSupportValue = useSelect( ( select ) => 9246 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ), 9247 * [] 9248 * ); 9249 * 9250 * return ( 9251 * <p> 9252 * { sprintf( 9253 * __( 'core/paragraph supports.anchor value: %s' ), 9254 * paragraphBlockSupportValue 9255 * ) } 9256 * </p> 9257 * ); 9258 * }; 9259 * ``` 9260 * 9261 * @return {?*} Block support value 9262 */ 9263 const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 9264 const blockType = getNormalizedBlockType(state, nameOrType); 9265 if (!blockType?.supports) { 9266 return defaultSupports; 9267 } 9268 return getValueFromObjectPath(blockType.supports, feature, defaultSupports); 9269 }; 9270 9271 /** 9272 * Returns true if the block defines support for a feature, or false otherwise. 9273 * 9274 * @param {Object} state Data state. 9275 * @param {(string|Object)} nameOrType Block name or type object. 9276 * @param {string} feature Feature to test. 9277 * @param {boolean} defaultSupports Whether feature is supported by 9278 * default if not explicitly defined. 9279 * 9280 * @example 9281 * ```js 9282 * import { __, sprintf } from '@wordpress/i18n'; 9283 * import { store as blocksStore } from '@wordpress/blocks'; 9284 * import { useSelect } from '@wordpress/data'; 9285 * 9286 * const ExampleComponent = () => { 9287 * const paragraphBlockSupportClassName = useSelect( ( select ) => 9288 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ), 9289 * [] 9290 * ); 9291 * 9292 * return ( 9293 * <p> 9294 * { sprintf( 9295 * __( 'core/paragraph supports custom class name?: %s' ), 9296 * paragraphBlockSupportClassName 9297 * ) } 9298 * /p> 9299 * ); 9300 * }; 9301 * ``` 9302 * 9303 * @return {boolean} Whether block supports feature. 9304 */ 9305 function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupports) { 9306 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports); 9307 } 9308 9309 /** 9310 * Normalizes a search term string: removes accents, converts to lowercase, removes extra whitespace. 9311 * 9312 * @param {string|null|undefined} term Search term to normalize. 9313 * @return {string} Normalized search term. 9314 */ 9315 function getNormalizedSearchTerm(term) { 9316 return remove_accents_default()(term !== null && term !== void 0 ? term : '').toLowerCase().trim(); 9317 } 9318 9319 /** 9320 * Returns true if the block type by the given name or object value matches a 9321 * search term, or false otherwise. 9322 * 9323 * @param {Object} state Blocks state. 9324 * @param {(string|Object)} nameOrType Block name or type object. 9325 * @param {string} searchTerm Search term by which to filter. 9326 * 9327 * @example 9328 * ```js 9329 * import { __, sprintf } from '@wordpress/i18n'; 9330 * import { store as blocksStore } from '@wordpress/blocks'; 9331 * import { useSelect } from '@wordpress/data'; 9332 * 9333 * const ExampleComponent = () => { 9334 * const termFound = useSelect( 9335 * ( select ) => 9336 * select( blocksStore ).isMatchingSearchTerm( 9337 * 'core/navigation', 9338 * 'theme' 9339 * ), 9340 * [] 9341 * ); 9342 * 9343 * return ( 9344 * <p> 9345 * { sprintf( 9346 * __( 9347 * 'Search term was found in the title, keywords, category or description in block.json: %s' 9348 * ), 9349 * termFound 9350 * ) } 9351 * </p> 9352 * ); 9353 * }; 9354 * ``` 9355 * 9356 * @return {Object[]} Whether block type matches search term. 9357 */ 9358 function isMatchingSearchTerm(state, nameOrType, searchTerm = '') { 9359 const blockType = getNormalizedBlockType(state, nameOrType); 9360 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 9361 const isSearchMatch = candidate => getNormalizedSearchTerm(candidate).includes(normalizedSearchTerm); 9362 return isSearchMatch(blockType.title) || blockType.keywords?.some(isSearchMatch) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description); 9363 } 9364 9365 /** 9366 * Returns a boolean indicating if a block has child blocks or not. 9367 * 9368 * @param {Object} state Data state. 9369 * @param {string} blockName Block type name. 9370 * 9371 * @example 9372 * ```js 9373 * import { __, sprintf } from '@wordpress/i18n'; 9374 * import { store as blocksStore } from '@wordpress/blocks'; 9375 * import { useSelect } from '@wordpress/data'; 9376 * 9377 * const ExampleComponent = () => { 9378 * const navigationBlockHasChildBlocks = useSelect( ( select ) => 9379 * select( blocksStore ).hasChildBlocks( 'core/navigation' ), 9380 * [] 9381 * ); 9382 * 9383 * return ( 9384 * <p> 9385 * { sprintf( 9386 * __( 'core/navigation has child blocks: %s' ), 9387 * navigationBlockHasChildBlocks 9388 * ) } 9389 * </p> 9390 * ); 9391 * }; 9392 * ``` 9393 * 9394 * @return {boolean} True if a block contains child blocks and false otherwise. 9395 */ 9396 const selectors_hasChildBlocks = (state, blockName) => { 9397 return selectors_getChildBlockNames(state, blockName).length > 0; 9398 }; 9399 9400 /** 9401 * Returns a boolean indicating if a block has at least one child block with inserter support. 9402 * 9403 * @param {Object} state Data state. 9404 * @param {string} blockName Block type name. 9405 * 9406 * @example 9407 * ```js 9408 * import { __, sprintf } from '@wordpress/i18n'; 9409 * import { store as blocksStore } from '@wordpress/blocks'; 9410 * import { useSelect } from '@wordpress/data'; 9411 * 9412 * const ExampleComponent = () => { 9413 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) => 9414 * select( blocksStore ).hasChildBlocksWithInserterSupport( 9415 * 'core/navigation' 9416 * ), 9417 * [] 9418 * ); 9419 * 9420 * return ( 9421 * <p> 9422 * { sprintf( 9423 * __( 'core/navigation has child blocks with inserter support: %s' ), 9424 * navigationBlockHasChildBlocksWithInserterSupport 9425 * ) } 9426 * </p> 9427 * ); 9428 * }; 9429 * ``` 9430 * 9431 * @return {boolean} True if a block contains at least one child blocks with inserter support 9432 * and false otherwise. 9433 */ 9434 const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => { 9435 return selectors_getChildBlockNames(state, blockName).some(childBlockName => { 9436 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true); 9437 }); 9438 }; 9439 const __experimentalHasContentRoleAttribute = (...args) => { 9440 external_wp_deprecated_default()('__experimentalHasContentRoleAttribute', { 9441 since: '6.7', 9442 version: '6.8', 9443 hint: 'This is a private selector.' 9444 }); 9445 return hasContentRoleAttribute(...args); 9446 }; 9447 9448 ;// ./node_modules/is-plain-object/dist/is-plain-object.mjs 9449 /*! 9450 * is-plain-object <https://github.com/jonschlinkert/is-plain-object> 9451 * 9452 * Copyright (c) 2014-2017, Jon Schlinkert. 9453 * Released under the MIT License. 9454 */ 9455 9456 function is_plain_object_isObject(o) { 9457 return Object.prototype.toString.call(o) === '[object Object]'; 9458 } 9459 9460 function isPlainObject(o) { 9461 var ctor,prot; 9462 9463 if (is_plain_object_isObject(o) === false) return false; 9464 9465 // If has modified constructor 9466 ctor = o.constructor; 9467 if (ctor === undefined) return true; 9468 9469 // If has modified prototype 9470 prot = ctor.prototype; 9471 if (is_plain_object_isObject(prot) === false) return false; 9472 9473 // If constructor does not have an Object-specific method 9474 if (prot.hasOwnProperty('isPrototypeOf') === false) { 9475 return false; 9476 } 9477 9478 // Most likely a plain Object 9479 return true; 9480 } 9481 9482 9483 9484 // EXTERNAL MODULE: ./node_modules/react-is/index.js 9485 var react_is = __webpack_require__(8529); 9486 ;// external ["wp","hooks"] 9487 const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 9488 ;// ./node_modules/@wordpress/blocks/build-module/store/process-block-type.js 9489 /** 9490 * External dependencies 9491 */ 9492 9493 9494 9495 /** 9496 * WordPress dependencies 9497 */ 9498 9499 9500 9501 9502 /** 9503 * Internal dependencies 9504 */ 9505 9506 9507 9508 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9509 9510 /** 9511 * Mapping of legacy category slugs to their latest normal values, used to 9512 * accommodate updates of the default set of block categories. 9513 * 9514 * @type {Record<string,string>} 9515 */ 9516 const LEGACY_CATEGORY_MAPPING = { 9517 common: 'text', 9518 formatting: 'text', 9519 layout: 'design' 9520 }; 9521 9522 /** 9523 * Merge block variations bootstrapped from the server and client. 9524 * 9525 * When a variation is registered in both places, its properties are merged. 9526 * 9527 * @param {Array} bootstrappedVariations - A block type variations from the server. 9528 * @param {Array} clientVariations - A block type variations from the client. 9529 * @return {Array} The merged array of block variations. 9530 */ 9531 function mergeBlockVariations(bootstrappedVariations = [], clientVariations = []) { 9532 const result = [...bootstrappedVariations]; 9533 clientVariations.forEach(clientVariation => { 9534 const index = result.findIndex(bootstrappedVariation => bootstrappedVariation.name === clientVariation.name); 9535 if (index !== -1) { 9536 result[index] = { 9537 ...result[index], 9538 ...clientVariation 9539 }; 9540 } else { 9541 result.push(clientVariation); 9542 } 9543 }); 9544 return result; 9545 } 9546 9547 /** 9548 * Takes the unprocessed block type settings, merges them with block type metadata 9549 * and applies all the existing filters for the registered block type. 9550 * Next, it validates all the settings and performs additional processing to the block type definition. 9551 * 9552 * @param {string} name Block name. 9553 * @param {WPBlockType} blockSettings Unprocessed block type settings. 9554 * 9555 * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. 9556 */ 9557 const processBlockType = (name, blockSettings) => ({ 9558 select 9559 }) => { 9560 const bootstrappedBlockType = select.getBootstrappedBlockType(name); 9561 const blockType = { 9562 name, 9563 icon: BLOCK_ICON_DEFAULT, 9564 keywords: [], 9565 attributes: {}, 9566 providesContext: {}, 9567 usesContext: [], 9568 selectors: {}, 9569 supports: {}, 9570 styles: [], 9571 blockHooks: {}, 9572 save: () => null, 9573 ...bootstrappedBlockType, 9574 ...blockSettings, 9575 // blockType.variations can be defined as a filePath. 9576 variations: mergeBlockVariations(Array.isArray(bootstrappedBlockType?.variations) ? bootstrappedBlockType.variations : [], Array.isArray(blockSettings?.variations) ? blockSettings.variations : []) 9577 }; 9578 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', blockType, name, null); 9579 if (settings.description && typeof settings.description !== 'string') { 9580 external_wp_deprecated_default()('Declaring non-string block descriptions', { 9581 since: '6.2' 9582 }); 9583 } 9584 if (settings.deprecated) { 9585 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( 9586 // Only keep valid deprecation keys. 9587 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', 9588 // Merge deprecation keys with pre-filter settings 9589 // so that filters that depend on specific keys being 9590 // present don't fail. 9591 { 9592 // Omit deprecation keys here so that deprecations 9593 // can opt out of specific keys like "supports". 9594 ...omit(blockType, DEPRECATED_ENTRY_KEYS), 9595 ...deprecation 9596 }, blockType.name, deprecation)).filter(([key]) => DEPRECATED_ENTRY_KEYS.includes(key)))); 9597 } 9598 if (!isPlainObject(settings)) { 9599 true ? external_wp_warning_default()('Block settings must be a valid object.') : 0; 9600 return; 9601 } 9602 if (typeof settings.save !== 'function') { 9603 true ? external_wp_warning_default()('The "save" property must be a valid function.') : 0; 9604 return; 9605 } 9606 if ('edit' in settings && !(0,react_is.isValidElementType)(settings.edit)) { 9607 true ? external_wp_warning_default()('The "edit" property must be a valid component.') : 0; 9608 return; 9609 } 9610 9611 // Canonicalize legacy categories to equivalent fallback. 9612 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 9613 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 9614 } 9615 if ('category' in settings && !select.getCategories().some(({ 9616 slug 9617 }) => slug === settings.category)) { 9618 true ? external_wp_warning_default()('The block "' + name + '" is registered with an invalid category "' + settings.category + '".') : 0; 9619 delete settings.category; 9620 } 9621 if (!('title' in settings) || settings.title === '') { 9622 true ? external_wp_warning_default()('The block "' + name + '" must have a title.') : 0; 9623 return; 9624 } 9625 if (typeof settings.title !== 'string') { 9626 true ? external_wp_warning_default()('Block titles must be strings.') : 0; 9627 return; 9628 } 9629 settings.icon = normalizeIconObject(settings.icon); 9630 if (!isValidIcon(settings.icon.src)) { 9631 true ? external_wp_warning_default()('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') : 0; 9632 return; 9633 } 9634 if (typeof settings?.parent === 'string' || settings?.parent instanceof String) { 9635 settings.parent = [settings.parent]; 9636 true ? external_wp_warning_default()('Parent must be undefined or an array of strings (block types), but it is a string.') : 0; 9637 // Intentionally continue: 9638 // 9639 // While string values were never supported, they appeared to work with some unintended side-effects 9640 // that have been fixed by [#66250](https://github.com/WordPress/gutenberg/pull/66250). 9641 // 9642 // To be backwards-compatible, this code that automatically migrates strings to arrays. 9643 } 9644 if (!Array.isArray(settings?.parent) && settings?.parent !== undefined) { 9645 true ? external_wp_warning_default()('Parent must be undefined or an array of block types, but it is ', settings.parent) : 0; 9646 return; 9647 } 9648 if (1 === settings?.parent?.length && name === settings.parent[0]) { 9649 true ? external_wp_warning_default()('Block "' + name + '" cannot be a parent of itself. Please remove the block name from the parent list.') : 0; 9650 return; 9651 } 9652 return settings; 9653 }; 9654 9655 ;// ./node_modules/@wordpress/blocks/build-module/store/actions.js 9656 /** 9657 * WordPress dependencies 9658 */ 9659 9660 9661 /** 9662 * Internal dependencies 9663 */ 9664 9665 9666 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 9667 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9668 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 9669 9670 /** 9671 * Returns an action object used in signalling that block types have been added. 9672 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks. 9673 * 9674 * @ignore 9675 * 9676 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added. 9677 * 9678 * 9679 * @return {Object} Action object. 9680 */ 9681 function addBlockTypes(blockTypes) { 9682 return { 9683 type: 'ADD_BLOCK_TYPES', 9684 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes] 9685 }; 9686 } 9687 9688 /** 9689 * Signals that all block types should be computed again. 9690 * It uses stored unprocessed block types and all the most recent list of registered filters. 9691 * 9692 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 9693 * 1. Filter A. 9694 * 2. Block B. 9695 * 3. Block C. 9696 * 4. Filter D. 9697 * 5. Filter E. 9698 * 6. Block F. 9699 * 7. Filter G. 9700 * In this scenario some filters would not get applied for all blocks because they are registered too late. 9701 */ 9702 function reapplyBlockTypeFilters() { 9703 return ({ 9704 dispatch, 9705 select 9706 }) => { 9707 const processedBlockTypes = []; 9708 for (const [name, settings] of Object.entries(select.getUnprocessedBlockTypes())) { 9709 const result = dispatch(processBlockType(name, settings)); 9710 if (result) { 9711 processedBlockTypes.push(result); 9712 } 9713 } 9714 if (!processedBlockTypes.length) { 9715 return; 9716 } 9717 dispatch.addBlockTypes(processedBlockTypes); 9718 }; 9719 } 9720 function __experimentalReapplyBlockFilters() { 9721 external_wp_deprecated_default()('wp.data.dispatch( "core/blocks" ).__experimentalReapplyBlockFilters', { 9722 since: '6.4', 9723 alternative: 'reapplyBlockFilters' 9724 }); 9725 return reapplyBlockTypeFilters(); 9726 } 9727 9728 /** 9729 * Returns an action object used to remove a registered block type. 9730 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks. 9731 * 9732 * @ignore 9733 * 9734 * @param {string|string[]} names Block name or array of block names to be removed. 9735 * 9736 * 9737 * @return {Object} Action object. 9738 */ 9739 function removeBlockTypes(names) { 9740 return { 9741 type: 'REMOVE_BLOCK_TYPES', 9742 names: Array.isArray(names) ? names : [names] 9743 }; 9744 } 9745 9746 /** 9747 * Returns an action object used in signalling that new block styles have been added. 9748 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks. 9749 * 9750 * @param {string|Array} blockNames Block names to register new styles for. 9751 * @param {Array|Object} styles Block style object or array of block style objects. 9752 * 9753 * @ignore 9754 * 9755 * @return {Object} Action object. 9756 */ 9757 function addBlockStyles(blockNames, styles) { 9758 return { 9759 type: 'ADD_BLOCK_STYLES', 9760 styles: Array.isArray(styles) ? styles : [styles], 9761 blockNames: Array.isArray(blockNames) ? blockNames : [blockNames] 9762 }; 9763 } 9764 9765 /** 9766 * Returns an action object used in signalling that block styles have been removed. 9767 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks. 9768 * 9769 * @ignore 9770 * 9771 * @param {string} blockName Block name. 9772 * @param {Array|string} styleNames Block style names or array of block style names. 9773 * 9774 * @return {Object} Action object. 9775 */ 9776 function removeBlockStyles(blockName, styleNames) { 9777 return { 9778 type: 'REMOVE_BLOCK_STYLES', 9779 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames], 9780 blockName 9781 }; 9782 } 9783 9784 /** 9785 * Returns an action object used in signalling that new block variations have been added. 9786 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks. 9787 * 9788 * @ignore 9789 * 9790 * @param {string} blockName Block name. 9791 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 9792 * 9793 * @return {Object} Action object. 9794 */ 9795 function addBlockVariations(blockName, variations) { 9796 return { 9797 type: 'ADD_BLOCK_VARIATIONS', 9798 variations: Array.isArray(variations) ? variations : [variations], 9799 blockName 9800 }; 9801 } 9802 9803 /** 9804 * Returns an action object used in signalling that block variations have been removed. 9805 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks. 9806 * 9807 * @ignore 9808 * 9809 * @param {string} blockName Block name. 9810 * @param {string|string[]} variationNames Block variation names. 9811 * 9812 * @return {Object} Action object. 9813 */ 9814 function removeBlockVariations(blockName, variationNames) { 9815 return { 9816 type: 'REMOVE_BLOCK_VARIATIONS', 9817 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames], 9818 blockName 9819 }; 9820 } 9821 9822 /** 9823 * Returns an action object used to set the default block name. 9824 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks. 9825 * 9826 * @ignore 9827 * 9828 * @param {string} name Block name. 9829 * 9830 * @return {Object} Action object. 9831 */ 9832 function actions_setDefaultBlockName(name) { 9833 return { 9834 type: 'SET_DEFAULT_BLOCK_NAME', 9835 name 9836 }; 9837 } 9838 9839 /** 9840 * Returns an action object used to set the name of the block used as a fallback 9841 * for non-block content. 9842 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks. 9843 * 9844 * @ignore 9845 * 9846 * @param {string} name Block name. 9847 * 9848 * @return {Object} Action object. 9849 */ 9850 function setFreeformFallbackBlockName(name) { 9851 return { 9852 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 9853 name 9854 }; 9855 } 9856 9857 /** 9858 * Returns an action object used to set the name of the block used as a fallback 9859 * for unregistered blocks. 9860 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks. 9861 * 9862 * @ignore 9863 * 9864 * @param {string} name Block name. 9865 * 9866 * @return {Object} Action object. 9867 */ 9868 function setUnregisteredFallbackBlockName(name) { 9869 return { 9870 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 9871 name 9872 }; 9873 } 9874 9875 /** 9876 * Returns an action object used to set the name of the block used 9877 * when grouping other blocks 9878 * eg: in "Group/Ungroup" interactions 9879 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks. 9880 * 9881 * @ignore 9882 * 9883 * @param {string} name Block name. 9884 * 9885 * @return {Object} Action object. 9886 */ 9887 function actions_setGroupingBlockName(name) { 9888 return { 9889 type: 'SET_GROUPING_BLOCK_NAME', 9890 name 9891 }; 9892 } 9893 9894 /** 9895 * Returns an action object used to set block categories. 9896 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks. 9897 * 9898 * @ignore 9899 * 9900 * @param {WPBlockCategory[]} categories Block categories. 9901 * 9902 * @return {Object} Action object. 9903 */ 9904 function setCategories(categories) { 9905 return { 9906 type: 'SET_CATEGORIES', 9907 categories 9908 }; 9909 } 9910 9911 /** 9912 * Returns an action object used to update a category. 9913 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks. 9914 * 9915 * @ignore 9916 * 9917 * @param {string} slug Block category slug. 9918 * @param {Object} category Object containing the category properties that should be updated. 9919 * 9920 * @return {Object} Action object. 9921 */ 9922 function updateCategory(slug, category) { 9923 return { 9924 type: 'UPDATE_CATEGORY', 9925 slug, 9926 category 9927 }; 9928 } 9929 9930 /** 9931 * Returns an action object used to add block collections 9932 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks. 9933 * 9934 * @ignore 9935 * 9936 * @param {string} namespace The namespace of the blocks to put in the collection 9937 * @param {string} title The title to display in the block inserter 9938 * @param {Object} icon (optional) The icon to display in the block inserter 9939 * 9940 * @return {Object} Action object. 9941 */ 9942 function addBlockCollection(namespace, title, icon) { 9943 return { 9944 type: 'ADD_BLOCK_COLLECTION', 9945 namespace, 9946 title, 9947 icon 9948 }; 9949 } 9950 9951 /** 9952 * Returns an action object used to remove block collections 9953 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks. 9954 * 9955 * @ignore 9956 * 9957 * @param {string} namespace The namespace of the blocks to put in the collection 9958 * 9959 * @return {Object} Action object. 9960 */ 9961 function removeBlockCollection(namespace) { 9962 return { 9963 type: 'REMOVE_BLOCK_COLLECTION', 9964 namespace 9965 }; 9966 } 9967 9968 ;// ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 9969 /** 9970 * Internal dependencies 9971 */ 9972 9973 9974 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9975 9976 /** 9977 * Add bootstrapped block type metadata to the store. These metadata usually come from 9978 * the `block.json` file and are either statically bootstrapped from the server, or 9979 * passed as the `metadata` parameter to the `registerBlockType` function. 9980 * 9981 * @param {string} name Block name. 9982 * @param {WPBlockType} blockType Block type metadata. 9983 */ 9984 function addBootstrappedBlockType(name, blockType) { 9985 return { 9986 type: 'ADD_BOOTSTRAPPED_BLOCK_TYPE', 9987 name, 9988 blockType 9989 }; 9990 } 9991 9992 /** 9993 * Add unprocessed block type settings to the store. These data are passed as the 9994 * `settings` parameter to the client-side `registerBlockType` function. 9995 * 9996 * @param {string} name Block name. 9997 * @param {WPBlockType} blockType Unprocessed block type settings. 9998 */ 9999 function addUnprocessedBlockType(name, blockType) { 10000 return ({ 10001 dispatch 10002 }) => { 10003 dispatch({ 10004 type: 'ADD_UNPROCESSED_BLOCK_TYPE', 10005 name, 10006 blockType 10007 }); 10008 const processedBlockType = dispatch(processBlockType(name, blockType)); 10009 if (!processedBlockType) { 10010 return; 10011 } 10012 dispatch.addBlockTypes(processedBlockType); 10013 }; 10014 } 10015 10016 /** 10017 * Adds new block bindings source. 10018 * 10019 * @param {string} source Name of the source to register. 10020 */ 10021 function addBlockBindingsSource(source) { 10022 return { 10023 type: 'ADD_BLOCK_BINDINGS_SOURCE', 10024 name: source.name, 10025 label: source.label, 10026 usesContext: source.usesContext, 10027 getValues: source.getValues, 10028 setValues: source.setValues, 10029 canUserEditValue: source.canUserEditValue, 10030 getFieldsList: source.getFieldsList 10031 }; 10032 } 10033 10034 /** 10035 * Removes existing block bindings source. 10036 * 10037 * @param {string} name Name of the source to remove. 10038 */ 10039 function removeBlockBindingsSource(name) { 10040 return { 10041 type: 'REMOVE_BLOCK_BINDINGS_SOURCE', 10042 name 10043 }; 10044 } 10045 10046 ;// ./node_modules/@wordpress/blocks/build-module/store/constants.js 10047 const STORE_NAME = 'core/blocks'; 10048 10049 ;// ./node_modules/@wordpress/blocks/build-module/store/index.js 10050 /** 10051 * WordPress dependencies 10052 */ 10053 10054 10055 /** 10056 * Internal dependencies 10057 */ 10058 10059 10060 10061 10062 10063 10064 10065 10066 /** 10067 * Store definition for the blocks namespace. 10068 * 10069 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 10070 * 10071 * @type {Object} 10072 */ 10073 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 10074 reducer: reducer, 10075 selectors: selectors_namespaceObject, 10076 actions: actions_namespaceObject 10077 }); 10078 (0,external_wp_data_namespaceObject.register)(store); 10079 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 10080 unlock(store).registerPrivateActions(private_actions_namespaceObject); 10081 10082 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/native.js 10083 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); 10084 /* harmony default export */ const esm_browser_native = ({ 10085 randomUUID 10086 }); 10087 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/rng.js 10088 // Unique ID creation requires a high quality random # generator. In the browser we therefore 10089 // require the crypto API and do not support built-in fallback to lower quality random number 10090 // generators (like Math.random()). 10091 let getRandomValues; 10092 const rnds8 = new Uint8Array(16); 10093 function rng() { 10094 // lazy load so that environments that need to polyfill have a chance to do so 10095 if (!getRandomValues) { 10096 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. 10097 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); 10098 10099 if (!getRandomValues) { 10100 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 10101 } 10102 } 10103 10104 return getRandomValues(rnds8); 10105 } 10106 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/stringify.js 10107 10108 /** 10109 * Convert array of 16 byte values to UUID string format of the form: 10110 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 10111 */ 10112 10113 const byteToHex = []; 10114 10115 for (let i = 0; i < 256; ++i) { 10116 byteToHex.push((i + 0x100).toString(16).slice(1)); 10117 } 10118 10119 function unsafeStringify(arr, offset = 0) { 10120 // Note: Be careful editing this code! It's been tuned for performance 10121 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 10122 return 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]]; 10123 } 10124 10125 function stringify(arr, offset = 0) { 10126 const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one 10127 // of the following: 10128 // - One or more input array values don't map to a hex octet (leading to 10129 // "undefined" in the uuid) 10130 // - Invalid input values for the RFC `version` or `variant` fields 10131 10132 if (!validate(uuid)) { 10133 throw TypeError('Stringified UUID is invalid'); 10134 } 10135 10136 return uuid; 10137 } 10138 10139 /* harmony default export */ const esm_browser_stringify = ((/* unused pure expression or super */ null && (stringify))); 10140 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/v4.js 10141 10142 10143 10144 10145 function v4(options, buf, offset) { 10146 if (esm_browser_native.randomUUID && !buf && !options) { 10147 return esm_browser_native.randomUUID(); 10148 } 10149 10150 options = options || {}; 10151 const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 10152 10153 rnds[6] = rnds[6] & 0x0f | 0x40; 10154 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 10155 10156 if (buf) { 10157 offset = offset || 0; 10158 10159 for (let i = 0; i < 16; ++i) { 10160 buf[offset + i] = rnds[i]; 10161 } 10162 10163 return buf; 10164 } 10165 10166 return unsafeStringify(rnds); 10167 } 10168 10169 /* harmony default export */ const esm_browser_v4 = (v4); 10170 ;// ./node_modules/@wordpress/blocks/build-module/api/factory.js 10171 /** 10172 * External dependencies 10173 */ 10174 10175 10176 /** 10177 * WordPress dependencies 10178 */ 10179 10180 10181 /** 10182 * Internal dependencies 10183 */ 10184 10185 10186 10187 /** 10188 * Returns a block object given its type and attributes. 10189 * 10190 * @param {string} name Block name. 10191 * @param {Object} attributes Block attributes. 10192 * @param {?Array} innerBlocks Nested blocks. 10193 * 10194 * @return {Object} Block object. 10195 */ 10196 function createBlock(name, attributes = {}, innerBlocks = []) { 10197 if (!isBlockRegistered(name)) { 10198 return createBlock('core/missing', { 10199 originalName: name, 10200 originalContent: '', 10201 originalUndelimitedContent: '' 10202 }); 10203 } 10204 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 10205 const clientId = esm_browser_v4(); 10206 10207 // Blocks are stored with a unique ID, the assigned type name, the block 10208 // attributes, and their inner blocks. 10209 return { 10210 clientId, 10211 name, 10212 isValid: true, 10213 attributes: sanitizedAttributes, 10214 innerBlocks 10215 }; 10216 } 10217 10218 /** 10219 * Given an array of InnerBlocks templates or Block Objects, 10220 * returns an array of created Blocks from them. 10221 * It handles the case of having InnerBlocks as Blocks by 10222 * converting them to the proper format to continue recursively. 10223 * 10224 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 10225 * 10226 * @return {Object[]} Array of Block objects. 10227 */ 10228 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) { 10229 return innerBlocksOrTemplate.map(innerBlock => { 10230 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 10231 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 10232 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 10233 }); 10234 } 10235 10236 /** 10237 * Given a block object, returns a copy of the block object while sanitizing its attributes, 10238 * optionally merging new attributes and/or replacing its inner blocks. 10239 * 10240 * @param {Object} block Block instance. 10241 * @param {Object} mergeAttributes Block attributes. 10242 * @param {?Array} newInnerBlocks Nested blocks. 10243 * 10244 * @return {Object} A cloned block. 10245 */ 10246 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) { 10247 const { 10248 name 10249 } = block; 10250 if (!isBlockRegistered(name)) { 10251 return createBlock('core/missing', { 10252 originalName: name, 10253 originalContent: '', 10254 originalUndelimitedContent: '' 10255 }); 10256 } 10257 const clientId = esm_browser_v4(); 10258 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, { 10259 ...block.attributes, 10260 ...mergeAttributes 10261 }); 10262 return { 10263 ...block, 10264 clientId, 10265 attributes: sanitizedAttributes, 10266 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 10267 }; 10268 } 10269 10270 /** 10271 * Given a block object, returns a copy of the block object, 10272 * optionally merging new attributes and/or replacing its inner blocks. 10273 * 10274 * @param {Object} block Block instance. 10275 * @param {Object} mergeAttributes Block attributes. 10276 * @param {?Array} newInnerBlocks Nested blocks. 10277 * 10278 * @return {Object} A cloned block. 10279 */ 10280 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) { 10281 const clientId = esm_browser_v4(); 10282 return { 10283 ...block, 10284 clientId, 10285 attributes: { 10286 ...block.attributes, 10287 ...mergeAttributes 10288 }, 10289 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 10290 }; 10291 } 10292 10293 /** 10294 * Returns a boolean indicating whether a transform is possible based on 10295 * various bits of context. 10296 * 10297 * @param {Object} transform The transform object to validate. 10298 * @param {string} direction Is this a 'from' or 'to' transform. 10299 * @param {Array} blocks The blocks to transform from. 10300 * 10301 * @return {boolean} Is the transform possible? 10302 */ 10303 const isPossibleTransformForSource = (transform, direction, blocks) => { 10304 if (!blocks.length) { 10305 return false; 10306 } 10307 10308 // If multiple blocks are selected, only multi block transforms 10309 // or wildcard transforms are allowed. 10310 const isMultiBlock = blocks.length > 1; 10311 const firstBlockName = blocks[0].name; 10312 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 10313 if (!isValidForMultiBlocks) { 10314 return false; 10315 } 10316 10317 // Check non-wildcard transforms to ensure that transform is valid 10318 // for a block selection of multiple blocks of different types. 10319 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) { 10320 return false; 10321 } 10322 10323 // Only consider 'block' type transforms as valid. 10324 const isBlockType = transform.type === 'block'; 10325 if (!isBlockType) { 10326 return false; 10327 } 10328 10329 // Check if the transform's block name matches the source block (or is a wildcard) 10330 // only if this is a transform 'from'. 10331 const sourceBlock = blocks[0]; 10332 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 10333 if (!hasMatchingName) { 10334 return false; 10335 } 10336 10337 // Don't allow single Grouping blocks to be transformed into 10338 // a Grouping block. 10339 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 10340 return false; 10341 } 10342 10343 // If the transform has a `isMatch` function specified, check that it returns true. 10344 if (!maybeCheckTransformIsMatch(transform, blocks)) { 10345 return false; 10346 } 10347 return true; 10348 }; 10349 10350 /** 10351 * Returns block types that the 'blocks' can be transformed into, based on 10352 * 'from' transforms on other blocks. 10353 * 10354 * @param {Array} blocks The blocks to transform from. 10355 * 10356 * @return {Array} Block types that the blocks can be transformed into. 10357 */ 10358 const getBlockTypesForPossibleFromTransforms = blocks => { 10359 if (!blocks.length) { 10360 return []; 10361 } 10362 const allBlockTypes = getBlockTypes(); 10363 10364 // filter all blocks to find those with a 'from' transform. 10365 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => { 10366 const fromTransforms = getBlockTransforms('from', blockType.name); 10367 return !!findTransform(fromTransforms, transform => { 10368 return isPossibleTransformForSource(transform, 'from', blocks); 10369 }); 10370 }); 10371 return blockTypesWithPossibleFromTransforms; 10372 }; 10373 10374 /** 10375 * Returns block types that the 'blocks' can be transformed into, based on 10376 * the source block's own 'to' transforms. 10377 * 10378 * @param {Array} blocks The blocks to transform from. 10379 * 10380 * @return {Array} Block types that the source can be transformed into. 10381 */ 10382 const getBlockTypesForPossibleToTransforms = blocks => { 10383 if (!blocks.length) { 10384 return []; 10385 } 10386 const sourceBlock = blocks[0]; 10387 const blockType = getBlockType(sourceBlock.name); 10388 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; 10389 10390 // filter all 'to' transforms to find those that are possible. 10391 const possibleTransforms = transformsTo.filter(transform => { 10392 return transform && isPossibleTransformForSource(transform, 'to', blocks); 10393 }); 10394 10395 // Build a list of block names using the possible 'to' transforms. 10396 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat(); 10397 10398 // Map block names to block types. 10399 return blockNames.map(getBlockType); 10400 }; 10401 10402 /** 10403 * Determines whether transform is a "block" type 10404 * and if so whether it is a "wildcard" transform 10405 * ie: targets "any" block type 10406 * 10407 * @param {Object} t the Block transform object 10408 * 10409 * @return {boolean} whether transform is a wildcard transform 10410 */ 10411 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 10412 10413 /** 10414 * Determines whether the given Block is the core Block which 10415 * acts as a container Block for other Blocks as part of the 10416 * Grouping mechanics 10417 * 10418 * @param {string} name the name of the Block to test against 10419 * 10420 * @return {boolean} whether or not the Block is the container Block type 10421 */ 10422 const isContainerGroupBlock = name => name === getGroupingBlockName(); 10423 10424 /** 10425 * Returns an array of block types that the set of blocks received as argument 10426 * can be transformed into. 10427 * 10428 * @param {Array} blocks Blocks array. 10429 * 10430 * @return {Array} Block types that the blocks argument can be transformed to. 10431 */ 10432 function getPossibleBlockTransformations(blocks) { 10433 if (!blocks.length) { 10434 return []; 10435 } 10436 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 10437 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 10438 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])]; 10439 } 10440 10441 /** 10442 * Given an array of transforms, returns the highest-priority transform where 10443 * the predicate function returns a truthy value. A higher-priority transform 10444 * is one with a lower priority value (i.e. first in priority order). Returns 10445 * null if the transforms set is empty or the predicate function returns a 10446 * falsey value for all entries. 10447 * 10448 * @param {Object[]} transforms Transforms to search. 10449 * @param {Function} predicate Function returning true on matching transform. 10450 * 10451 * @return {?Object} Highest-priority transform candidate. 10452 */ 10453 function findTransform(transforms, predicate) { 10454 // The hooks library already has built-in mechanisms for managing priority 10455 // queue, so leverage via locally-defined instance. 10456 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)(); 10457 for (let i = 0; i < transforms.length; i++) { 10458 const candidate = transforms[i]; 10459 if (predicate(candidate)) { 10460 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 10461 } 10462 } 10463 10464 // Filter name is arbitrarily chosen but consistent with above aggregation. 10465 return hooks.applyFilters('transform', null); 10466 } 10467 10468 /** 10469 * Returns normal block transforms for a given transform direction, optionally 10470 * for a specific block by name, or an empty array if there are no transforms. 10471 * If no block name is provided, returns transforms for all blocks. A normal 10472 * transform object includes `blockName` as a property. 10473 * 10474 * @param {string} direction Transform direction ("to", "from"). 10475 * @param {string|Object} blockTypeOrName Block type or name. 10476 * 10477 * @return {Array} Block transforms for direction. 10478 */ 10479 function getBlockTransforms(direction, blockTypeOrName) { 10480 // When retrieving transforms for all block types, recurse into self. 10481 if (blockTypeOrName === undefined) { 10482 return getBlockTypes().map(({ 10483 name 10484 }) => getBlockTransforms(direction, name)).flat(); 10485 } 10486 10487 // Validate that block type exists and has array of direction. 10488 const blockType = normalizeBlockType(blockTypeOrName); 10489 const { 10490 name: blockName, 10491 transforms 10492 } = blockType || {}; 10493 if (!transforms || !Array.isArray(transforms[direction])) { 10494 return []; 10495 } 10496 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 10497 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => { 10498 if (t.type === 'raw') { 10499 return true; 10500 } 10501 if (t.type === 'prefix') { 10502 return true; 10503 } 10504 if (!t.blocks || !t.blocks.length) { 10505 return false; 10506 } 10507 if (isWildcardBlockTransform(t)) { 10508 return true; 10509 } 10510 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 10511 }) : transforms[direction]; 10512 10513 // Map transforms to normal form. 10514 return filteredTransforms.map(transform => ({ 10515 ...transform, 10516 blockName, 10517 usingMobileTransformations 10518 })); 10519 } 10520 10521 /** 10522 * Checks that a given transforms isMatch method passes for given source blocks. 10523 * 10524 * @param {Object} transform A transform object. 10525 * @param {Array} blocks Blocks array. 10526 * 10527 * @return {boolean} True if given blocks are a match for the transform. 10528 */ 10529 function maybeCheckTransformIsMatch(transform, blocks) { 10530 if (typeof transform.isMatch !== 'function') { 10531 return true; 10532 } 10533 const sourceBlock = blocks[0]; 10534 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 10535 const block = transform.isMultiBlock ? blocks : sourceBlock; 10536 return transform.isMatch(attributes, block); 10537 } 10538 10539 /** 10540 * Switch one or more blocks into one or more blocks of the new block type. 10541 * 10542 * @param {Array|Object} blocks Blocks array or block object. 10543 * @param {string} name Block name. 10544 * 10545 * @return {?Array} Array of blocks or null. 10546 */ 10547 function switchToBlockType(blocks, name) { 10548 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10549 const isMultiBlock = blocksArray.length > 1; 10550 const firstBlock = blocksArray[0]; 10551 const sourceName = firstBlock.name; 10552 10553 // Find the right transformation by giving priority to the "to" 10554 // transformation. 10555 const transformationsFrom = getBlockTransforms('from', name); 10556 const transformationsTo = getBlockTransforms('to', sourceName); 10557 const transformation = findTransform(transformationsTo, t => t.type === 'block' && (isWildcardBlockTransform(t) || 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)); 10558 10559 // Stop if there is no valid transformation. 10560 if (!transformation) { 10561 return null; 10562 } 10563 let transformationResults; 10564 if (transformation.isMultiBlock) { 10565 if ('__experimentalConvert' in transformation) { 10566 transformationResults = transformation.__experimentalConvert(blocksArray); 10567 } else { 10568 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 10569 } 10570 } else if ('__experimentalConvert' in transformation) { 10571 transformationResults = transformation.__experimentalConvert(firstBlock); 10572 } else { 10573 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 10574 } 10575 10576 // Ensure that the transformation function returned an object or an array 10577 // of objects. 10578 if (transformationResults === null || typeof transformationResults !== 'object') { 10579 return null; 10580 } 10581 10582 // If the transformation function returned a single object, we want to work 10583 // with an array instead. 10584 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults]; 10585 10586 // Ensure that every block object returned by the transformation has a 10587 // valid block type. 10588 if (transformationResults.some(result => !getBlockType(result.name))) { 10589 return null; 10590 } 10591 const hasSwitchedBlock = transformationResults.some(result => result.name === name); 10592 10593 // Ensure that at least one block object returned by the transformation has 10594 // the expected "destination" block type. 10595 if (!hasSwitchedBlock) { 10596 return null; 10597 } 10598 const ret = transformationResults.map((result, index, results) => { 10599 /** 10600 * Filters an individual transform result from block transformation. 10601 * All of the original blocks are passed, since transformations are 10602 * many-to-many, not one-to-one. 10603 * 10604 * @param {Object} transformedBlock The transformed block. 10605 * @param {Object[]} blocks Original blocks transformed. 10606 * @param {Object[]} index Index of the transformed block on the array of results. 10607 * @param {Object[]} results An array all the blocks that resulted from the transformation. 10608 */ 10609 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results); 10610 }); 10611 return ret; 10612 } 10613 10614 /** 10615 * Create a block object from the example API. 10616 * 10617 * @param {string} name 10618 * @param {Object} example 10619 * 10620 * @return {Object} block. 10621 */ 10622 const getBlockFromExample = (name, example) => { 10623 var _example$innerBlocks; 10624 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 10625 }; 10626 10627 ;// external ["wp","blockSerializationDefaultParser"] 10628 const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 10629 ;// external ["wp","autop"] 10630 const external_wp_autop_namespaceObject = window["wp"]["autop"]; 10631 ;// external ["wp","isShallowEqual"] 10632 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 10633 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 10634 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/serialize-raw-block.js 10635 /** 10636 * Internal dependencies 10637 */ 10638 10639 10640 /** 10641 * @typedef {Object} Options Serialization options. 10642 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. 10643 */ 10644 10645 /** @typedef {import("./").WPRawBlock} WPRawBlock */ 10646 10647 /** 10648 * Serializes a block node into the native HTML-comment-powered block format. 10649 * CAVEAT: This function is intended for re-serializing blocks as parsed by 10650 * valid parsers and skips any validation steps. This is NOT a generic 10651 * serialization function for in-memory blocks. For most purposes, see the 10652 * following functions available in the `@wordpress/blocks` package: 10653 * 10654 * @see serializeBlock 10655 * @see serialize 10656 * 10657 * For more on the format of block nodes as returned by valid parsers: 10658 * 10659 * @see `@wordpress/block-serialization-default-parser` package 10660 * @see `@wordpress/block-serialization-spec-parser` package 10661 * 10662 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. 10663 * @param {Options} [options={}] Serialization options. 10664 * 10665 * @return {string} An HTML string representing a block. 10666 */ 10667 function serializeRawBlock(rawBlock, options = {}) { 10668 const { 10669 isCommentDelimited = true 10670 } = options; 10671 const { 10672 blockName, 10673 attrs = {}, 10674 innerBlocks = [], 10675 innerContent = [] 10676 } = rawBlock; 10677 let childIndex = 0; 10678 const content = innerContent.map(item => 10679 // `null` denotes a nested block, otherwise we have an HTML fragment. 10680 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 10681 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 10682 } 10683 10684 ;// external "ReactJSXRuntime" 10685 const external_ReactJSXRuntime_namespaceObject = window["ReactJSXRuntime"]; 10686 ;// ./node_modules/@wordpress/blocks/build-module/api/serializer.js 10687 /** 10688 * WordPress dependencies 10689 */ 10690 10691 10692 10693 10694 10695 10696 /** 10697 * Internal dependencies 10698 */ 10699 10700 10701 10702 10703 /** @typedef {import('./parser').WPBlock} WPBlock */ 10704 10705 /** 10706 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 10707 * 10708 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 10709 */ 10710 10711 /** 10712 * Returns the block's default classname from its name. 10713 * 10714 * @param {string} blockName The block name. 10715 * 10716 * @return {string} The block's default class. 10717 */ 10718 10719 function getBlockDefaultClassName(blockName) { 10720 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 10721 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10722 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10723 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName); 10724 } 10725 10726 /** 10727 * Returns the block's default menu item classname from its name. 10728 * 10729 * @param {string} blockName The block name. 10730 * 10731 * @return {string} The block's default menu item class. 10732 */ 10733 function getBlockMenuDefaultClassName(blockName) { 10734 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 10735 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10736 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10737 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName); 10738 } 10739 const blockPropsProvider = {}; 10740 const innerBlocksPropsProvider = {}; 10741 10742 /** 10743 * Call within a save function to get the props for the block wrapper. 10744 * 10745 * @param {Object} props Optional. Props to pass to the element. 10746 */ 10747 function getBlockProps(props = {}) { 10748 const { 10749 blockType, 10750 attributes 10751 } = blockPropsProvider; 10752 return getBlockProps.skipFilters ? props : (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10753 ...props 10754 }, blockType, attributes); 10755 } 10756 10757 /** 10758 * Call within a save function to get the props for the inner blocks wrapper. 10759 * 10760 * @param {Object} props Optional. Props to pass to the element. 10761 */ 10762 function getInnerBlocksProps(props = {}) { 10763 const { 10764 innerBlocks 10765 } = innerBlocksPropsProvider; 10766 // Allow a different component to be passed to getSaveElement to handle 10767 // inner blocks, bypassing the default serialisation. 10768 if (!Array.isArray(innerBlocks)) { 10769 return { 10770 ...props, 10771 children: innerBlocks 10772 }; 10773 } 10774 // Value is an array of blocks, so defer to block serializer. 10775 const html = serialize(innerBlocks, { 10776 isInnerBlocks: true 10777 }); 10778 // Use special-cased raw HTML tag to avoid default escaping. 10779 const children = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.RawHTML, { 10780 children: html 10781 }); 10782 return { 10783 ...props, 10784 children 10785 }; 10786 } 10787 10788 /** 10789 * Given a block type containing a save render implementation and attributes, returns the 10790 * enhanced element to be saved or string when raw HTML expected. 10791 * 10792 * @param {string|Object} blockTypeOrName Block type or name. 10793 * @param {Object} attributes Block attributes. 10794 * @param {?Array} innerBlocks Nested blocks. 10795 * 10796 * @return {Object|string} Save element or raw HTML string. 10797 */ 10798 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) { 10799 const blockType = normalizeBlockType(blockTypeOrName); 10800 if (!blockType?.save) { 10801 return null; 10802 } 10803 let { 10804 save 10805 } = blockType; 10806 10807 // Component classes are unsupported for save since serialization must 10808 // occur synchronously. For improved interoperability with higher-order 10809 // components which often return component class, emulate basic support. 10810 if (save.prototype instanceof external_wp_element_namespaceObject.Component) { 10811 const instance = new save({ 10812 attributes 10813 }); 10814 save = instance.render.bind(instance); 10815 } 10816 blockPropsProvider.blockType = blockType; 10817 blockPropsProvider.attributes = attributes; 10818 innerBlocksPropsProvider.innerBlocks = innerBlocks; 10819 let element = save({ 10820 attributes, 10821 innerBlocks 10822 }); 10823 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) { 10824 /** 10825 * Filters the props applied to the block save result element. 10826 * 10827 * @param {Object} props Props applied to save element. 10828 * @param {WPBlock} blockType Block type definition. 10829 * @param {Object} attributes Block attributes. 10830 */ 10831 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10832 ...element.props 10833 }, blockType, attributes); 10834 if (!external_wp_isShallowEqual_default()(props, element.props)) { 10835 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props); 10836 } 10837 } 10838 10839 /** 10840 * Filters the save result of a block during serialization. 10841 * 10842 * @param {Element} element Block save result. 10843 * @param {WPBlock} blockType Block type definition. 10844 * @param {Object} attributes Block attributes. 10845 */ 10846 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes); 10847 } 10848 10849 /** 10850 * Given a block type containing a save render implementation and attributes, returns the 10851 * static markup to be saved. 10852 * 10853 * @param {string|Object} blockTypeOrName Block type or name. 10854 * @param {Object} attributes Block attributes. 10855 * @param {?Array} innerBlocks Nested blocks. 10856 * 10857 * @return {string} Save content. 10858 */ 10859 function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 10860 const blockType = normalizeBlockType(blockTypeOrName); 10861 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks)); 10862 } 10863 10864 /** 10865 * Returns attributes which are to be saved and serialized into the block 10866 * comment delimiter. 10867 * 10868 * When a block exists in memory it contains as its attributes both those 10869 * parsed the block comment delimiter _and_ those which matched from the 10870 * contents of the block. 10871 * 10872 * This function returns only those attributes which are needed to persist and 10873 * which cannot be matched from the block content. 10874 * 10875 * @param {Object<string,*>} blockType Block type. 10876 * @param {Object<string,*>} attributes Attributes from in-memory block data. 10877 * 10878 * @return {Object<string,*>} Subset of attributes for comment serialization. 10879 */ 10880 function getCommentAttributes(blockType, attributes) { 10881 var _blockType$attributes; 10882 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).reduce((accumulator, [key, attributeSchema]) => { 10883 const value = attributes[key]; 10884 // Ignore undefined values. 10885 if (undefined === value) { 10886 return accumulator; 10887 } 10888 10889 // Ignore all attributes but the ones with an "undefined" source 10890 // "undefined" source refers to attributes saved in the block comment. 10891 if (attributeSchema.source !== undefined) { 10892 return accumulator; 10893 } 10894 10895 // Ignore all local attributes 10896 if (attributeSchema.role === 'local') { 10897 return accumulator; 10898 } 10899 if (attributeSchema.__experimentalRole === 'local') { 10900 external_wp_deprecated_default()('__experimentalRole attribute', { 10901 since: '6.7', 10902 version: '6.8', 10903 alternative: 'role attribute', 10904 hint: `Check the block.json of the $blockType?.name} block.` 10905 }); 10906 return accumulator; 10907 } 10908 10909 // Ignore default value. 10910 if ('default' in attributeSchema && JSON.stringify(attributeSchema.default) === JSON.stringify(value)) { 10911 return accumulator; 10912 } 10913 10914 // Otherwise, include in comment set. 10915 accumulator[key] = value; 10916 return accumulator; 10917 }, {}); 10918 } 10919 10920 /** 10921 * Given an attributes object, returns a string in the serialized attributes 10922 * format prepared for post content. 10923 * 10924 * @param {Object} attributes Attributes object. 10925 * 10926 * @return {string} Serialized attributes. 10927 */ 10928 function serializeAttributes(attributes) { 10929 return JSON.stringify(attributes) 10930 // Don't break HTML comments. 10931 .replace(/--/g, '\\u002d\\u002d') 10932 10933 // Don't break non-standard-compliant tools. 10934 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') 10935 10936 // Bypass server stripslashes behavior which would unescape stringify's 10937 // escaping of quotation mark. 10938 // 10939 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 10940 .replace(/\\"/g, '\\u0022'); 10941 } 10942 10943 /** 10944 * Given a block object, returns the Block's Inner HTML markup. 10945 * 10946 * @param {Object} block Block instance. 10947 * 10948 * @return {string} HTML. 10949 */ 10950 function getBlockInnerHTML(block) { 10951 // If block was parsed as invalid or encounters an error while generating 10952 // save content, use original content instead to avoid content loss. If a 10953 // block contains nested content, exempt it from this condition because we 10954 // otherwise have no access to its original content and content loss would 10955 // still occur. 10956 let saveContent = block.originalContent; 10957 if (block.isValid || block.innerBlocks.length) { 10958 try { 10959 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 10960 } catch (error) {} 10961 } 10962 return saveContent; 10963 } 10964 10965 /** 10966 * Returns the content of a block, including comment delimiters. 10967 * 10968 * @param {string} rawBlockName Block name. 10969 * @param {Object} attributes Block attributes. 10970 * @param {string} content Block save content. 10971 * 10972 * @return {string} Comment-delimited block content. 10973 */ 10974 function getCommentDelimitedContent(rawBlockName, attributes, content) { 10975 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : ''; 10976 10977 // Strip core blocks of their namespace prefix. 10978 const blockName = rawBlockName?.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName; 10979 10980 // @todo make the `wp:` prefix potentially configurable. 10981 10982 if (!content) { 10983 return `<!-- wp:$blockName} $serializedAttributes}/-->`; 10984 } 10985 return `<!-- wp:$blockName} $serializedAttributes}-->\n` + content + `\n<!-- /wp:$blockName} -->`; 10986 } 10987 10988 /** 10989 * Returns the content of a block, including comment delimiters, determining 10990 * serialized attributes and content form from the current state of the block. 10991 * 10992 * @param {WPBlock} block Block instance. 10993 * @param {WPBlockSerializationOptions} options Serialization options. 10994 * 10995 * @return {string} Serialized block. 10996 */ 10997 function serializeBlock(block, { 10998 isInnerBlocks = false 10999 } = {}) { 11000 if (!block.isValid && block.__unstableBlockSource) { 11001 return serializeRawBlock(block.__unstableBlockSource); 11002 } 11003 const blockName = block.name; 11004 const saveContent = getBlockInnerHTML(block); 11005 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 11006 return saveContent; 11007 } 11008 const blockType = getBlockType(blockName); 11009 if (!blockType) { 11010 return saveContent; 11011 } 11012 const saveAttributes = getCommentAttributes(blockType, block.attributes); 11013 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 11014 } 11015 function __unstableSerializeAndClean(blocks) { 11016 // A single unmodified default block is assumed to 11017 // be equivalent to an empty post. 11018 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 11019 blocks = []; 11020 } 11021 let content = serialize(blocks); 11022 11023 // For compatibility, treat a post consisting of a 11024 // single freeform block as legacy content and apply 11025 // pre-block-editor removep'd content formatting. 11026 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName() && blocks[0].name === 'core/freeform') { 11027 content = (0,external_wp_autop_namespaceObject.removep)(content); 11028 } 11029 return content; 11030 } 11031 11032 /** 11033 * Takes a block or set of blocks and returns the serialized post content. 11034 * 11035 * @param {Array} blocks Block(s) to serialize. 11036 * @param {WPBlockSerializationOptions} options Serialization options. 11037 * 11038 * @return {string} The post content. 11039 */ 11040 function serialize(blocks, options) { 11041 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 11042 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n'); 11043 } 11044 11045 ;// ./node_modules/simple-html-tokenizer/dist/es6/index.js 11046 /** 11047 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 11048 * do not edit 11049 */ 11050 var namedCharRefs = { 11051 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" 11052 }; 11053 11054 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 11055 var CHARCODE = /^#([0-9]+)$/; 11056 var NAMED = /^([A-Za-z0-9]+)$/; 11057 var EntityParser = /** @class */ (function () { 11058 function EntityParser(named) { 11059 this.named = named; 11060 } 11061 EntityParser.prototype.parse = function (entity) { 11062 if (!entity) { 11063 return; 11064 } 11065 var matches = entity.match(HEXCHARCODE); 11066 if (matches) { 11067 return String.fromCharCode(parseInt(matches[1], 16)); 11068 } 11069 matches = entity.match(CHARCODE); 11070 if (matches) { 11071 return String.fromCharCode(parseInt(matches[1], 10)); 11072 } 11073 matches = entity.match(NAMED); 11074 if (matches) { 11075 return this.named[matches[1]]; 11076 } 11077 }; 11078 return EntityParser; 11079 }()); 11080 11081 var WSP = /[\t\n\f ]/; 11082 var ALPHA = /[A-Za-z]/; 11083 var CRLF = /\r\n?/g; 11084 function isSpace(char) { 11085 return WSP.test(char); 11086 } 11087 function isAlpha(char) { 11088 return ALPHA.test(char); 11089 } 11090 function preprocessInput(input) { 11091 return input.replace(CRLF, '\n'); 11092 } 11093 11094 var EventedTokenizer = /** @class */ (function () { 11095 function EventedTokenizer(delegate, entityParser, mode) { 11096 if (mode === void 0) { mode = 'precompile'; } 11097 this.delegate = delegate; 11098 this.entityParser = entityParser; 11099 this.mode = mode; 11100 this.state = "beforeData" /* beforeData */; 11101 this.line = -1; 11102 this.column = -1; 11103 this.input = ''; 11104 this.index = -1; 11105 this.tagNameBuffer = ''; 11106 this.states = { 11107 beforeData: function () { 11108 var char = this.peek(); 11109 if (char === '<' && !this.isIgnoredEndTag()) { 11110 this.transitionTo("tagOpen" /* tagOpen */); 11111 this.markTagStart(); 11112 this.consume(); 11113 } 11114 else { 11115 if (this.mode === 'precompile' && char === '\n') { 11116 var tag = this.tagNameBuffer.toLowerCase(); 11117 if (tag === 'pre' || tag === 'textarea') { 11118 this.consume(); 11119 } 11120 } 11121 this.transitionTo("data" /* data */); 11122 this.delegate.beginData(); 11123 } 11124 }, 11125 data: function () { 11126 var char = this.peek(); 11127 var tag = this.tagNameBuffer; 11128 if (char === '<' && !this.isIgnoredEndTag()) { 11129 this.delegate.finishData(); 11130 this.transitionTo("tagOpen" /* tagOpen */); 11131 this.markTagStart(); 11132 this.consume(); 11133 } 11134 else if (char === '&' && tag !== 'script' && tag !== 'style') { 11135 this.consume(); 11136 this.delegate.appendToData(this.consumeCharRef() || '&'); 11137 } 11138 else { 11139 this.consume(); 11140 this.delegate.appendToData(char); 11141 } 11142 }, 11143 tagOpen: function () { 11144 var char = this.consume(); 11145 if (char === '!') { 11146 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 11147 } 11148 else if (char === '/') { 11149 this.transitionTo("endTagOpen" /* endTagOpen */); 11150 } 11151 else if (char === '@' || char === ':' || isAlpha(char)) { 11152 this.transitionTo("tagName" /* tagName */); 11153 this.tagNameBuffer = ''; 11154 this.delegate.beginStartTag(); 11155 this.appendToTagName(char); 11156 } 11157 }, 11158 markupDeclarationOpen: function () { 11159 var char = this.consume(); 11160 if (char === '-' && this.peek() === '-') { 11161 this.consume(); 11162 this.transitionTo("commentStart" /* commentStart */); 11163 this.delegate.beginComment(); 11164 } 11165 else { 11166 var maybeDoctype = char.toUpperCase() + this.input.substring(this.index, this.index + 6).toUpperCase(); 11167 if (maybeDoctype === 'DOCTYPE') { 11168 this.consume(); 11169 this.consume(); 11170 this.consume(); 11171 this.consume(); 11172 this.consume(); 11173 this.consume(); 11174 this.transitionTo("doctype" /* doctype */); 11175 if (this.delegate.beginDoctype) 11176 this.delegate.beginDoctype(); 11177 } 11178 } 11179 }, 11180 doctype: function () { 11181 var char = this.consume(); 11182 if (isSpace(char)) { 11183 this.transitionTo("beforeDoctypeName" /* beforeDoctypeName */); 11184 } 11185 }, 11186 beforeDoctypeName: function () { 11187 var char = this.consume(); 11188 if (isSpace(char)) { 11189 return; 11190 } 11191 else { 11192 this.transitionTo("doctypeName" /* doctypeName */); 11193 if (this.delegate.appendToDoctypeName) 11194 this.delegate.appendToDoctypeName(char.toLowerCase()); 11195 } 11196 }, 11197 doctypeName: function () { 11198 var char = this.consume(); 11199 if (isSpace(char)) { 11200 this.transitionTo("afterDoctypeName" /* afterDoctypeName */); 11201 } 11202 else if (char === '>') { 11203 if (this.delegate.endDoctype) 11204 this.delegate.endDoctype(); 11205 this.transitionTo("beforeData" /* beforeData */); 11206 } 11207 else { 11208 if (this.delegate.appendToDoctypeName) 11209 this.delegate.appendToDoctypeName(char.toLowerCase()); 11210 } 11211 }, 11212 afterDoctypeName: function () { 11213 var char = this.consume(); 11214 if (isSpace(char)) { 11215 return; 11216 } 11217 else if (char === '>') { 11218 if (this.delegate.endDoctype) 11219 this.delegate.endDoctype(); 11220 this.transitionTo("beforeData" /* beforeData */); 11221 } 11222 else { 11223 var nextSixChars = char.toUpperCase() + this.input.substring(this.index, this.index + 5).toUpperCase(); 11224 var isPublic = nextSixChars.toUpperCase() === 'PUBLIC'; 11225 var isSystem = nextSixChars.toUpperCase() === 'SYSTEM'; 11226 if (isPublic || isSystem) { 11227 this.consume(); 11228 this.consume(); 11229 this.consume(); 11230 this.consume(); 11231 this.consume(); 11232 this.consume(); 11233 } 11234 if (isPublic) { 11235 this.transitionTo("afterDoctypePublicKeyword" /* afterDoctypePublicKeyword */); 11236 } 11237 else if (isSystem) { 11238 this.transitionTo("afterDoctypeSystemKeyword" /* afterDoctypeSystemKeyword */); 11239 } 11240 } 11241 }, 11242 afterDoctypePublicKeyword: function () { 11243 var char = this.peek(); 11244 if (isSpace(char)) { 11245 this.transitionTo("beforeDoctypePublicIdentifier" /* beforeDoctypePublicIdentifier */); 11246 this.consume(); 11247 } 11248 else if (char === '"') { 11249 this.transitionTo("doctypePublicIdentifierDoubleQuoted" /* doctypePublicIdentifierDoubleQuoted */); 11250 this.consume(); 11251 } 11252 else if (char === "'") { 11253 this.transitionTo("doctypePublicIdentifierSingleQuoted" /* doctypePublicIdentifierSingleQuoted */); 11254 this.consume(); 11255 } 11256 else if (char === '>') { 11257 this.consume(); 11258 if (this.delegate.endDoctype) 11259 this.delegate.endDoctype(); 11260 this.transitionTo("beforeData" /* beforeData */); 11261 } 11262 }, 11263 doctypePublicIdentifierDoubleQuoted: function () { 11264 var char = this.consume(); 11265 if (char === '"') { 11266 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11267 } 11268 else if (char === '>') { 11269 if (this.delegate.endDoctype) 11270 this.delegate.endDoctype(); 11271 this.transitionTo("beforeData" /* beforeData */); 11272 } 11273 else { 11274 if (this.delegate.appendToDoctypePublicIdentifier) 11275 this.delegate.appendToDoctypePublicIdentifier(char); 11276 } 11277 }, 11278 doctypePublicIdentifierSingleQuoted: function () { 11279 var char = this.consume(); 11280 if (char === "'") { 11281 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11282 } 11283 else if (char === '>') { 11284 if (this.delegate.endDoctype) 11285 this.delegate.endDoctype(); 11286 this.transitionTo("beforeData" /* beforeData */); 11287 } 11288 else { 11289 if (this.delegate.appendToDoctypePublicIdentifier) 11290 this.delegate.appendToDoctypePublicIdentifier(char); 11291 } 11292 }, 11293 afterDoctypePublicIdentifier: function () { 11294 var char = this.consume(); 11295 if (isSpace(char)) { 11296 this.transitionTo("betweenDoctypePublicAndSystemIdentifiers" /* betweenDoctypePublicAndSystemIdentifiers */); 11297 } 11298 else if (char === '>') { 11299 if (this.delegate.endDoctype) 11300 this.delegate.endDoctype(); 11301 this.transitionTo("beforeData" /* beforeData */); 11302 } 11303 else if (char === '"') { 11304 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11305 } 11306 else if (char === "'") { 11307 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11308 } 11309 }, 11310 betweenDoctypePublicAndSystemIdentifiers: function () { 11311 var char = this.consume(); 11312 if (isSpace(char)) { 11313 return; 11314 } 11315 else if (char === '>') { 11316 if (this.delegate.endDoctype) 11317 this.delegate.endDoctype(); 11318 this.transitionTo("beforeData" /* beforeData */); 11319 } 11320 else if (char === '"') { 11321 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11322 } 11323 else if (char === "'") { 11324 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11325 } 11326 }, 11327 doctypeSystemIdentifierDoubleQuoted: function () { 11328 var char = this.consume(); 11329 if (char === '"') { 11330 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11331 } 11332 else if (char === '>') { 11333 if (this.delegate.endDoctype) 11334 this.delegate.endDoctype(); 11335 this.transitionTo("beforeData" /* beforeData */); 11336 } 11337 else { 11338 if (this.delegate.appendToDoctypeSystemIdentifier) 11339 this.delegate.appendToDoctypeSystemIdentifier(char); 11340 } 11341 }, 11342 doctypeSystemIdentifierSingleQuoted: function () { 11343 var char = this.consume(); 11344 if (char === "'") { 11345 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11346 } 11347 else if (char === '>') { 11348 if (this.delegate.endDoctype) 11349 this.delegate.endDoctype(); 11350 this.transitionTo("beforeData" /* beforeData */); 11351 } 11352 else { 11353 if (this.delegate.appendToDoctypeSystemIdentifier) 11354 this.delegate.appendToDoctypeSystemIdentifier(char); 11355 } 11356 }, 11357 afterDoctypeSystemIdentifier: function () { 11358 var char = this.consume(); 11359 if (isSpace(char)) { 11360 return; 11361 } 11362 else if (char === '>') { 11363 if (this.delegate.endDoctype) 11364 this.delegate.endDoctype(); 11365 this.transitionTo("beforeData" /* beforeData */); 11366 } 11367 }, 11368 commentStart: function () { 11369 var char = this.consume(); 11370 if (char === '-') { 11371 this.transitionTo("commentStartDash" /* commentStartDash */); 11372 } 11373 else if (char === '>') { 11374 this.delegate.finishComment(); 11375 this.transitionTo("beforeData" /* beforeData */); 11376 } 11377 else { 11378 this.delegate.appendToCommentData(char); 11379 this.transitionTo("comment" /* comment */); 11380 } 11381 }, 11382 commentStartDash: function () { 11383 var char = this.consume(); 11384 if (char === '-') { 11385 this.transitionTo("commentEnd" /* commentEnd */); 11386 } 11387 else if (char === '>') { 11388 this.delegate.finishComment(); 11389 this.transitionTo("beforeData" /* beforeData */); 11390 } 11391 else { 11392 this.delegate.appendToCommentData('-'); 11393 this.transitionTo("comment" /* comment */); 11394 } 11395 }, 11396 comment: function () { 11397 var char = this.consume(); 11398 if (char === '-') { 11399 this.transitionTo("commentEndDash" /* commentEndDash */); 11400 } 11401 else { 11402 this.delegate.appendToCommentData(char); 11403 } 11404 }, 11405 commentEndDash: function () { 11406 var char = this.consume(); 11407 if (char === '-') { 11408 this.transitionTo("commentEnd" /* commentEnd */); 11409 } 11410 else { 11411 this.delegate.appendToCommentData('-' + char); 11412 this.transitionTo("comment" /* comment */); 11413 } 11414 }, 11415 commentEnd: function () { 11416 var char = this.consume(); 11417 if (char === '>') { 11418 this.delegate.finishComment(); 11419 this.transitionTo("beforeData" /* beforeData */); 11420 } 11421 else { 11422 this.delegate.appendToCommentData('--' + char); 11423 this.transitionTo("comment" /* comment */); 11424 } 11425 }, 11426 tagName: function () { 11427 var char = this.consume(); 11428 if (isSpace(char)) { 11429 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11430 } 11431 else if (char === '/') { 11432 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11433 } 11434 else if (char === '>') { 11435 this.delegate.finishTag(); 11436 this.transitionTo("beforeData" /* beforeData */); 11437 } 11438 else { 11439 this.appendToTagName(char); 11440 } 11441 }, 11442 endTagName: function () { 11443 var char = this.consume(); 11444 if (isSpace(char)) { 11445 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11446 this.tagNameBuffer = ''; 11447 } 11448 else if (char === '/') { 11449 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11450 this.tagNameBuffer = ''; 11451 } 11452 else if (char === '>') { 11453 this.delegate.finishTag(); 11454 this.transitionTo("beforeData" /* beforeData */); 11455 this.tagNameBuffer = ''; 11456 } 11457 else { 11458 this.appendToTagName(char); 11459 } 11460 }, 11461 beforeAttributeName: function () { 11462 var char = this.peek(); 11463 if (isSpace(char)) { 11464 this.consume(); 11465 return; 11466 } 11467 else if (char === '/') { 11468 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11469 this.consume(); 11470 } 11471 else if (char === '>') { 11472 this.consume(); 11473 this.delegate.finishTag(); 11474 this.transitionTo("beforeData" /* beforeData */); 11475 } 11476 else if (char === '=') { 11477 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 11478 this.transitionTo("attributeName" /* attributeName */); 11479 this.delegate.beginAttribute(); 11480 this.consume(); 11481 this.delegate.appendToAttributeName(char); 11482 } 11483 else { 11484 this.transitionTo("attributeName" /* attributeName */); 11485 this.delegate.beginAttribute(); 11486 } 11487 }, 11488 attributeName: function () { 11489 var char = this.peek(); 11490 if (isSpace(char)) { 11491 this.transitionTo("afterAttributeName" /* afterAttributeName */); 11492 this.consume(); 11493 } 11494 else if (char === '/') { 11495 this.delegate.beginAttributeValue(false); 11496 this.delegate.finishAttributeValue(); 11497 this.consume(); 11498 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11499 } 11500 else if (char === '=') { 11501 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11502 this.consume(); 11503 } 11504 else if (char === '>') { 11505 this.delegate.beginAttributeValue(false); 11506 this.delegate.finishAttributeValue(); 11507 this.consume(); 11508 this.delegate.finishTag(); 11509 this.transitionTo("beforeData" /* beforeData */); 11510 } 11511 else if (char === '"' || char === "'" || char === '<') { 11512 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 11513 this.consume(); 11514 this.delegate.appendToAttributeName(char); 11515 } 11516 else { 11517 this.consume(); 11518 this.delegate.appendToAttributeName(char); 11519 } 11520 }, 11521 afterAttributeName: function () { 11522 var char = this.peek(); 11523 if (isSpace(char)) { 11524 this.consume(); 11525 return; 11526 } 11527 else if (char === '/') { 11528 this.delegate.beginAttributeValue(false); 11529 this.delegate.finishAttributeValue(); 11530 this.consume(); 11531 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11532 } 11533 else if (char === '=') { 11534 this.consume(); 11535 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11536 } 11537 else if (char === '>') { 11538 this.delegate.beginAttributeValue(false); 11539 this.delegate.finishAttributeValue(); 11540 this.consume(); 11541 this.delegate.finishTag(); 11542 this.transitionTo("beforeData" /* beforeData */); 11543 } 11544 else { 11545 this.delegate.beginAttributeValue(false); 11546 this.delegate.finishAttributeValue(); 11547 this.transitionTo("attributeName" /* attributeName */); 11548 this.delegate.beginAttribute(); 11549 this.consume(); 11550 this.delegate.appendToAttributeName(char); 11551 } 11552 }, 11553 beforeAttributeValue: function () { 11554 var char = this.peek(); 11555 if (isSpace(char)) { 11556 this.consume(); 11557 } 11558 else if (char === '"') { 11559 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 11560 this.delegate.beginAttributeValue(true); 11561 this.consume(); 11562 } 11563 else if (char === "'") { 11564 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 11565 this.delegate.beginAttributeValue(true); 11566 this.consume(); 11567 } 11568 else if (char === '>') { 11569 this.delegate.beginAttributeValue(false); 11570 this.delegate.finishAttributeValue(); 11571 this.consume(); 11572 this.delegate.finishTag(); 11573 this.transitionTo("beforeData" /* beforeData */); 11574 } 11575 else { 11576 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 11577 this.delegate.beginAttributeValue(false); 11578 this.consume(); 11579 this.delegate.appendToAttributeValue(char); 11580 } 11581 }, 11582 attributeValueDoubleQuoted: function () { 11583 var char = this.consume(); 11584 if (char === '"') { 11585 this.delegate.finishAttributeValue(); 11586 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11587 } 11588 else if (char === '&') { 11589 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11590 } 11591 else { 11592 this.delegate.appendToAttributeValue(char); 11593 } 11594 }, 11595 attributeValueSingleQuoted: function () { 11596 var char = this.consume(); 11597 if (char === "'") { 11598 this.delegate.finishAttributeValue(); 11599 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11600 } 11601 else if (char === '&') { 11602 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11603 } 11604 else { 11605 this.delegate.appendToAttributeValue(char); 11606 } 11607 }, 11608 attributeValueUnquoted: function () { 11609 var char = this.peek(); 11610 if (isSpace(char)) { 11611 this.delegate.finishAttributeValue(); 11612 this.consume(); 11613 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11614 } 11615 else if (char === '/') { 11616 this.delegate.finishAttributeValue(); 11617 this.consume(); 11618 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11619 } 11620 else if (char === '&') { 11621 this.consume(); 11622 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11623 } 11624 else if (char === '>') { 11625 this.delegate.finishAttributeValue(); 11626 this.consume(); 11627 this.delegate.finishTag(); 11628 this.transitionTo("beforeData" /* beforeData */); 11629 } 11630 else { 11631 this.consume(); 11632 this.delegate.appendToAttributeValue(char); 11633 } 11634 }, 11635 afterAttributeValueQuoted: function () { 11636 var char = this.peek(); 11637 if (isSpace(char)) { 11638 this.consume(); 11639 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11640 } 11641 else if (char === '/') { 11642 this.consume(); 11643 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11644 } 11645 else if (char === '>') { 11646 this.consume(); 11647 this.delegate.finishTag(); 11648 this.transitionTo("beforeData" /* beforeData */); 11649 } 11650 else { 11651 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11652 } 11653 }, 11654 selfClosingStartTag: function () { 11655 var char = this.peek(); 11656 if (char === '>') { 11657 this.consume(); 11658 this.delegate.markTagAsSelfClosing(); 11659 this.delegate.finishTag(); 11660 this.transitionTo("beforeData" /* beforeData */); 11661 } 11662 else { 11663 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11664 } 11665 }, 11666 endTagOpen: function () { 11667 var char = this.consume(); 11668 if (char === '@' || char === ':' || isAlpha(char)) { 11669 this.transitionTo("endTagName" /* endTagName */); 11670 this.tagNameBuffer = ''; 11671 this.delegate.beginEndTag(); 11672 this.appendToTagName(char); 11673 } 11674 } 11675 }; 11676 this.reset(); 11677 } 11678 EventedTokenizer.prototype.reset = function () { 11679 this.transitionTo("beforeData" /* beforeData */); 11680 this.input = ''; 11681 this.tagNameBuffer = ''; 11682 this.index = 0; 11683 this.line = 1; 11684 this.column = 0; 11685 this.delegate.reset(); 11686 }; 11687 EventedTokenizer.prototype.transitionTo = function (state) { 11688 this.state = state; 11689 }; 11690 EventedTokenizer.prototype.tokenize = function (input) { 11691 this.reset(); 11692 this.tokenizePart(input); 11693 this.tokenizeEOF(); 11694 }; 11695 EventedTokenizer.prototype.tokenizePart = function (input) { 11696 this.input += preprocessInput(input); 11697 while (this.index < this.input.length) { 11698 var handler = this.states[this.state]; 11699 if (handler !== undefined) { 11700 handler.call(this); 11701 } 11702 else { 11703 throw new Error("unhandled state " + this.state); 11704 } 11705 } 11706 }; 11707 EventedTokenizer.prototype.tokenizeEOF = function () { 11708 this.flushData(); 11709 }; 11710 EventedTokenizer.prototype.flushData = function () { 11711 if (this.state === 'data') { 11712 this.delegate.finishData(); 11713 this.transitionTo("beforeData" /* beforeData */); 11714 } 11715 }; 11716 EventedTokenizer.prototype.peek = function () { 11717 return this.input.charAt(this.index); 11718 }; 11719 EventedTokenizer.prototype.consume = function () { 11720 var char = this.peek(); 11721 this.index++; 11722 if (char === '\n') { 11723 this.line++; 11724 this.column = 0; 11725 } 11726 else { 11727 this.column++; 11728 } 11729 return char; 11730 }; 11731 EventedTokenizer.prototype.consumeCharRef = function () { 11732 var endIndex = this.input.indexOf(';', this.index); 11733 if (endIndex === -1) { 11734 return; 11735 } 11736 var entity = this.input.slice(this.index, endIndex); 11737 var chars = this.entityParser.parse(entity); 11738 if (chars) { 11739 var count = entity.length; 11740 // consume the entity chars 11741 while (count) { 11742 this.consume(); 11743 count--; 11744 } 11745 // consume the `;` 11746 this.consume(); 11747 return chars; 11748 } 11749 }; 11750 EventedTokenizer.prototype.markTagStart = function () { 11751 this.delegate.tagOpen(); 11752 }; 11753 EventedTokenizer.prototype.appendToTagName = function (char) { 11754 this.tagNameBuffer += char; 11755 this.delegate.appendToTagName(char); 11756 }; 11757 EventedTokenizer.prototype.isIgnoredEndTag = function () { 11758 var tag = this.tagNameBuffer; 11759 return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') || 11760 (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') || 11761 (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>'); 11762 }; 11763 return EventedTokenizer; 11764 }()); 11765 11766 var Tokenizer = /** @class */ (function () { 11767 function Tokenizer(entityParser, options) { 11768 if (options === void 0) { options = {}; } 11769 this.options = options; 11770 this.token = null; 11771 this.startLine = 1; 11772 this.startColumn = 0; 11773 this.tokens = []; 11774 this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); 11775 this._currentAttribute = undefined; 11776 } 11777 Tokenizer.prototype.tokenize = function (input) { 11778 this.tokens = []; 11779 this.tokenizer.tokenize(input); 11780 return this.tokens; 11781 }; 11782 Tokenizer.prototype.tokenizePart = function (input) { 11783 this.tokens = []; 11784 this.tokenizer.tokenizePart(input); 11785 return this.tokens; 11786 }; 11787 Tokenizer.prototype.tokenizeEOF = function () { 11788 this.tokens = []; 11789 this.tokenizer.tokenizeEOF(); 11790 return this.tokens[0]; 11791 }; 11792 Tokenizer.prototype.reset = function () { 11793 this.token = null; 11794 this.startLine = 1; 11795 this.startColumn = 0; 11796 }; 11797 Tokenizer.prototype.current = function () { 11798 var token = this.token; 11799 if (token === null) { 11800 throw new Error('token was unexpectedly null'); 11801 } 11802 if (arguments.length === 0) { 11803 return token; 11804 } 11805 for (var i = 0; i < arguments.length; i++) { 11806 if (token.type === arguments[i]) { 11807 return token; 11808 } 11809 } 11810 throw new Error("token type was unexpectedly " + token.type); 11811 }; 11812 Tokenizer.prototype.push = function (token) { 11813 this.token = token; 11814 this.tokens.push(token); 11815 }; 11816 Tokenizer.prototype.currentAttribute = function () { 11817 return this._currentAttribute; 11818 }; 11819 Tokenizer.prototype.addLocInfo = function () { 11820 if (this.options.loc) { 11821 this.current().loc = { 11822 start: { 11823 line: this.startLine, 11824 column: this.startColumn 11825 }, 11826 end: { 11827 line: this.tokenizer.line, 11828 column: this.tokenizer.column 11829 } 11830 }; 11831 } 11832 this.startLine = this.tokenizer.line; 11833 this.startColumn = this.tokenizer.column; 11834 }; 11835 // Data 11836 Tokenizer.prototype.beginDoctype = function () { 11837 this.push({ 11838 type: "Doctype" /* Doctype */, 11839 name: '', 11840 }); 11841 }; 11842 Tokenizer.prototype.appendToDoctypeName = function (char) { 11843 this.current("Doctype" /* Doctype */).name += char; 11844 }; 11845 Tokenizer.prototype.appendToDoctypePublicIdentifier = function (char) { 11846 var doctype = this.current("Doctype" /* Doctype */); 11847 if (doctype.publicIdentifier === undefined) { 11848 doctype.publicIdentifier = char; 11849 } 11850 else { 11851 doctype.publicIdentifier += char; 11852 } 11853 }; 11854 Tokenizer.prototype.appendToDoctypeSystemIdentifier = function (char) { 11855 var doctype = this.current("Doctype" /* Doctype */); 11856 if (doctype.systemIdentifier === undefined) { 11857 doctype.systemIdentifier = char; 11858 } 11859 else { 11860 doctype.systemIdentifier += char; 11861 } 11862 }; 11863 Tokenizer.prototype.endDoctype = function () { 11864 this.addLocInfo(); 11865 }; 11866 Tokenizer.prototype.beginData = function () { 11867 this.push({ 11868 type: "Chars" /* Chars */, 11869 chars: '' 11870 }); 11871 }; 11872 Tokenizer.prototype.appendToData = function (char) { 11873 this.current("Chars" /* Chars */).chars += char; 11874 }; 11875 Tokenizer.prototype.finishData = function () { 11876 this.addLocInfo(); 11877 }; 11878 // Comment 11879 Tokenizer.prototype.beginComment = function () { 11880 this.push({ 11881 type: "Comment" /* Comment */, 11882 chars: '' 11883 }); 11884 }; 11885 Tokenizer.prototype.appendToCommentData = function (char) { 11886 this.current("Comment" /* Comment */).chars += char; 11887 }; 11888 Tokenizer.prototype.finishComment = function () { 11889 this.addLocInfo(); 11890 }; 11891 // Tags - basic 11892 Tokenizer.prototype.tagOpen = function () { }; 11893 Tokenizer.prototype.beginStartTag = function () { 11894 this.push({ 11895 type: "StartTag" /* StartTag */, 11896 tagName: '', 11897 attributes: [], 11898 selfClosing: false 11899 }); 11900 }; 11901 Tokenizer.prototype.beginEndTag = function () { 11902 this.push({ 11903 type: "EndTag" /* EndTag */, 11904 tagName: '' 11905 }); 11906 }; 11907 Tokenizer.prototype.finishTag = function () { 11908 this.addLocInfo(); 11909 }; 11910 Tokenizer.prototype.markTagAsSelfClosing = function () { 11911 this.current("StartTag" /* StartTag */).selfClosing = true; 11912 }; 11913 // Tags - name 11914 Tokenizer.prototype.appendToTagName = function (char) { 11915 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 11916 }; 11917 // Tags - attributes 11918 Tokenizer.prototype.beginAttribute = function () { 11919 this._currentAttribute = ['', '', false]; 11920 }; 11921 Tokenizer.prototype.appendToAttributeName = function (char) { 11922 this.currentAttribute()[0] += char; 11923 }; 11924 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 11925 this.currentAttribute()[2] = isQuoted; 11926 }; 11927 Tokenizer.prototype.appendToAttributeValue = function (char) { 11928 this.currentAttribute()[1] += char; 11929 }; 11930 Tokenizer.prototype.finishAttributeValue = function () { 11931 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 11932 }; 11933 Tokenizer.prototype.reportSyntaxError = function (message) { 11934 this.current().syntaxError = message; 11935 }; 11936 return Tokenizer; 11937 }()); 11938 11939 function tokenize(input, options) { 11940 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 11941 return tokenizer.tokenize(input); 11942 } 11943 11944 11945 11946 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 11947 var es6 = __webpack_require__(7734); 11948 var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 11949 ;// external ["wp","htmlEntities"] 11950 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 11951 ;// ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js 11952 /** 11953 * @typedef LoggerItem 11954 * @property {Function} log Which logger recorded the message 11955 * @property {Array<any>} args White arguments were supplied to the logger 11956 */ 11957 11958 function createLogger() { 11959 /** 11960 * Creates a log handler with block validation prefix. 11961 * 11962 * @param {Function} logger Original logger function. 11963 * 11964 * @return {Function} Augmented logger function. 11965 */ 11966 function createLogHandler(logger) { 11967 let log = (message, ...args) => logger('Block validation: ' + message, ...args); 11968 11969 // In test environments, pre-process string substitutions to improve 11970 // readability of error messages. We'd prefer to avoid pulling in this 11971 // dependency in runtime environments, and it can be dropped by a combo 11972 // of Webpack env substitution + UglifyJS dead code elimination. 11973 if (false) {} 11974 return log; 11975 } 11976 return { 11977 // eslint-disable-next-line no-console 11978 error: createLogHandler(console.error), 11979 // eslint-disable-next-line no-console 11980 warning: createLogHandler(console.warn), 11981 getItems() { 11982 return []; 11983 } 11984 }; 11985 } 11986 function createQueuedLogger() { 11987 /** 11988 * The list of enqueued log actions to print. 11989 * 11990 * @type {Array<LoggerItem>} 11991 */ 11992 const queue = []; 11993 const logger = createLogger(); 11994 return { 11995 error(...args) { 11996 queue.push({ 11997 log: logger.error, 11998 args 11999 }); 12000 }, 12001 warning(...args) { 12002 queue.push({ 12003 log: logger.warning, 12004 args 12005 }); 12006 }, 12007 getItems() { 12008 return queue; 12009 } 12010 }; 12011 } 12012 12013 ;// ./node_modules/@wordpress/blocks/build-module/api/validation/index.js 12014 /** 12015 * External dependencies 12016 */ 12017 12018 12019 12020 /** 12021 * WordPress dependencies 12022 */ 12023 12024 12025 12026 /** 12027 * Internal dependencies 12028 */ 12029 12030 12031 12032 12033 12034 /** @typedef {import('../parser').WPBlock} WPBlock */ 12035 /** @typedef {import('../registration').WPBlockType} WPBlockType */ 12036 /** @typedef {import('./logger').LoggerItem} LoggerItem */ 12037 12038 const identity = x => x; 12039 12040 /** 12041 * Globally matches any consecutive whitespace 12042 * 12043 * @type {RegExp} 12044 */ 12045 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 12046 12047 /** 12048 * Matches a string containing only whitespace 12049 * 12050 * @type {RegExp} 12051 */ 12052 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 12053 12054 /** 12055 * Matches a CSS URL type value 12056 * 12057 * @type {RegExp} 12058 */ 12059 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 12060 12061 /** 12062 * Boolean attributes are attributes whose presence as being assigned is 12063 * meaningful, even if only empty. 12064 * 12065 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 12066 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 12067 * 12068 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 12069 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 12070 * .reduce( ( result, tr ) => Object.assign( result, { 12071 * [ tr.firstChild.textContent.trim() ]: true 12072 * } ), {} ) ).sort(); 12073 * 12074 * @type {Array} 12075 */ 12076 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']; 12077 12078 /** 12079 * Enumerated attributes are attributes which must be of a specific value form. 12080 * Like boolean attributes, these are meaningful if specified, even if not of a 12081 * valid enumerated value. 12082 * 12083 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 12084 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 12085 * 12086 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 12087 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 12088 * .reduce( ( result, tr ) => Object.assign( result, { 12089 * [ tr.firstChild.textContent.trim() ]: true 12090 * } ), {} ) ).sort(); 12091 * 12092 * @type {Array} 12093 */ 12094 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']; 12095 12096 /** 12097 * Meaningful attributes are those who cannot be safely ignored when omitted in 12098 * one HTML markup string and not another. 12099 * 12100 * @type {Array} 12101 */ 12102 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 12103 12104 /** 12105 * Array of functions which receive a text string on which to apply normalizing 12106 * behavior for consideration in text token equivalence, carefully ordered from 12107 * least-to-most expensive operations. 12108 * 12109 * @type {Array} 12110 */ 12111 const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace]; 12112 12113 /** 12114 * Regular expression matching a named character reference. In lieu of bundling 12115 * a full set of references, the pattern covers the minimal necessary to test 12116 * positively against the full set. 12117 * 12118 * "The ampersand must be followed by one of the names given in the named 12119 * character references section, using the same case." 12120 * 12121 * Tested against "12.5 Named character references": 12122 * 12123 * ``` 12124 * const references = Array.from( document.querySelectorAll( 12125 * '#named-character-references-table tr[id^=entity-] td:first-child' 12126 * ) ).map( ( code ) => code.textContent ) 12127 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 12128 * ``` 12129 * 12130 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12131 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 12132 * 12133 * @type {RegExp} 12134 */ 12135 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 12136 12137 /** 12138 * Regular expression matching a decimal character reference. 12139 * 12140 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 12141 * followed by one or more ASCII digits, representing a base-ten integer" 12142 * 12143 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12144 * 12145 * @type {RegExp} 12146 */ 12147 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 12148 12149 /** 12150 * Regular expression matching a hexadecimal character reference. 12151 * 12152 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 12153 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 12154 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 12155 * one or more ASCII hex digits, representing a hexadecimal integer" 12156 * 12157 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12158 * 12159 * @type {RegExp} 12160 */ 12161 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 12162 12163 /** 12164 * Returns true if the given string is a valid character reference segment, or 12165 * false otherwise. The text should be stripped of `&` and `;` demarcations. 12166 * 12167 * @param {string} text Text to test. 12168 * 12169 * @return {boolean} Whether text is valid character reference. 12170 */ 12171 function isValidCharacterReference(text) { 12172 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 12173 } 12174 12175 /** 12176 * Substitute EntityParser class for `simple-html-tokenizer` which uses the 12177 * implementation of `decodeEntities` from `html-entities`, in order to avoid 12178 * bundling a massive named character reference. 12179 * 12180 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 12181 */ 12182 class DecodeEntityParser { 12183 /** 12184 * Returns a substitute string for an entity string sequence between `&` 12185 * and `;`, or undefined if no substitution should occur. 12186 * 12187 * @param {string} entity Entity fragment discovered in HTML. 12188 * 12189 * @return {string | undefined} Entity substitute value. 12190 */ 12191 parse(entity) { 12192 if (isValidCharacterReference(entity)) { 12193 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';'); 12194 } 12195 } 12196 } 12197 12198 /** 12199 * Given a specified string, returns an array of strings split by consecutive 12200 * whitespace, ignoring leading or trailing whitespace. 12201 * 12202 * @param {string} text Original text. 12203 * 12204 * @return {string[]} Text pieces split on whitespace. 12205 */ 12206 function getTextPiecesSplitOnWhitespace(text) { 12207 return text.trim().split(REGEXP_WHITESPACE); 12208 } 12209 12210 /** 12211 * Given a specified string, returns a new trimmed string where all consecutive 12212 * whitespace is collapsed to a single space. 12213 * 12214 * @param {string} text Original text. 12215 * 12216 * @return {string} Trimmed text with consecutive whitespace collapsed. 12217 */ 12218 function getTextWithCollapsedWhitespace(text) { 12219 // This is an overly simplified whitespace comparison. The specification is 12220 // more prescriptive of whitespace behavior in inline and block contexts. 12221 // 12222 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33 12223 return getTextPiecesSplitOnWhitespace(text).join(' '); 12224 } 12225 12226 /** 12227 * Returns attribute pairs of the given StartTag token, including only pairs 12228 * where the value is non-empty or the attribute is a boolean attribute, an 12229 * enumerated attribute, or a custom data- attribute. 12230 * 12231 * @see MEANINGFUL_ATTRIBUTES 12232 * 12233 * @param {Object} token StartTag token. 12234 * 12235 * @return {Array[]} Attribute pairs. 12236 */ 12237 function getMeaningfulAttributePairs(token) { 12238 return token.attributes.filter(pair => { 12239 const [key, value] = pair; 12240 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key); 12241 }); 12242 } 12243 12244 /** 12245 * Returns true if two text tokens (with `chars` property) are equivalent, or 12246 * false otherwise. 12247 * 12248 * @param {Object} actual Actual token. 12249 * @param {Object} expected Expected token. 12250 * @param {Object} logger Validation logger object. 12251 * 12252 * @return {boolean} Whether two text tokens are equivalent. 12253 */ 12254 function isEquivalentTextTokens(actual, expected, logger = createLogger()) { 12255 // This function is intentionally written as syntactically "ugly" as a hot 12256 // path optimization. Text is progressively normalized in order from least- 12257 // to-most operationally expensive, until the earliest point at which text 12258 // can be confidently inferred as being equal. 12259 let actualChars = actual.chars; 12260 let expectedChars = expected.chars; 12261 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 12262 const normalize = TEXT_NORMALIZATIONS[i]; 12263 actualChars = normalize(actualChars); 12264 expectedChars = normalize(expectedChars); 12265 if (actualChars === expectedChars) { 12266 return true; 12267 } 12268 } 12269 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 12270 return false; 12271 } 12272 12273 /** 12274 * Given a CSS length value, returns a normalized CSS length value for strict equality 12275 * comparison. 12276 * 12277 * @param {string} value CSS length value. 12278 * 12279 * @return {string} Normalized CSS length value. 12280 */ 12281 function getNormalizedLength(value) { 12282 if (0 === parseFloat(value)) { 12283 return '0'; 12284 } 12285 // Normalize strings with floats to always include a leading zero. 12286 if (value.indexOf('.') === 0) { 12287 return '0' + value; 12288 } 12289 return value; 12290 } 12291 12292 /** 12293 * Given a style value, returns a normalized style value for strict equality 12294 * comparison. 12295 * 12296 * @param {string} value Style value. 12297 * 12298 * @return {string} Normalized style value. 12299 */ 12300 function getNormalizedStyleValue(value) { 12301 const textPieces = getTextPiecesSplitOnWhitespace(value); 12302 const normalizedPieces = textPieces.map(getNormalizedLength); 12303 const result = normalizedPieces.join(' '); 12304 return result 12305 // Normalize URL type to omit whitespace or quotes. 12306 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 12307 } 12308 12309 /** 12310 * Given a style attribute string, returns an object of style properties. 12311 * 12312 * @param {string} text Style attribute. 12313 * 12314 * @return {Object} Style properties. 12315 */ 12316 function getStyleProperties(text) { 12317 const pairs = text 12318 // Trim ending semicolon (avoid including in split) 12319 .replace(/;?\s*$/, '') 12320 // Split on property assignment. 12321 .split(';') 12322 // For each property assignment... 12323 .map(style => { 12324 // ...split further into key-value pairs. 12325 const [key, ...valueParts] = style.split(':'); 12326 const value = valueParts.join(':'); 12327 return [key.trim(), getNormalizedStyleValue(value.trim())]; 12328 }); 12329 return Object.fromEntries(pairs); 12330 } 12331 12332 /** 12333 * Attribute-specific equality handlers 12334 * 12335 * @type {Object} 12336 */ 12337 const isEqualAttributesOfName = { 12338 class: (actual, expected) => { 12339 // Class matches if members are the same, even if out of order or 12340 // superfluous whitespace between. 12341 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace); 12342 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c)); 12343 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c)); 12344 return actualDiff.length === 0 && expectedDiff.length === 0; 12345 }, 12346 style: (actual, expected) => { 12347 return es6_default()(...[actual, expected].map(getStyleProperties)); 12348 }, 12349 // For each boolean attribute, mere presence of attribute in both is enough 12350 // to assume equivalence. 12351 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true])) 12352 }; 12353 12354 /** 12355 * Given two sets of attribute tuples, returns true if the attribute sets are 12356 * equivalent. 12357 * 12358 * @param {Array[]} actual Actual attributes tuples. 12359 * @param {Array[]} expected Expected attributes tuples. 12360 * @param {Object} logger Validation logger object. 12361 * 12362 * @return {boolean} Whether attributes are equivalent. 12363 */ 12364 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) { 12365 // Attributes is tokenized as tuples. Their lengths should match. This also 12366 // avoids us needing to check both attributes sets, since if A has any keys 12367 // which do not exist in B, we know the sets to be different. 12368 if (actual.length !== expected.length) { 12369 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 12370 return false; 12371 } 12372 12373 // Attributes are not guaranteed to occur in the same order. For validating 12374 // actual attributes, first convert the set of expected attribute values to 12375 // an object, for lookup by key. 12376 const expectedAttributes = {}; 12377 for (let i = 0; i < expected.length; i++) { 12378 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 12379 } 12380 for (let i = 0; i < actual.length; i++) { 12381 const [name, actualValue] = actual[i]; 12382 const nameLower = name.toLowerCase(); 12383 12384 // As noted above, if missing member in B, assume different. 12385 if (!expectedAttributes.hasOwnProperty(nameLower)) { 12386 logger.warning('Encountered unexpected attribute `%s`.', name); 12387 return false; 12388 } 12389 const expectedValue = expectedAttributes[nameLower]; 12390 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 12391 if (isEqualAttributes) { 12392 // Defer custom attribute equality handling. 12393 if (!isEqualAttributes(actualValue, expectedValue)) { 12394 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12395 return false; 12396 } 12397 } else if (actualValue !== expectedValue) { 12398 // Otherwise strict inequality should bail. 12399 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12400 return false; 12401 } 12402 } 12403 return true; 12404 } 12405 12406 /** 12407 * Token-type-specific equality handlers 12408 * 12409 * @type {Object} 12410 */ 12411 const isEqualTokensOfType = { 12412 StartTag: (actual, expected, logger = createLogger()) => { 12413 if (actual.tagName !== expected.tagName && 12414 // Optimization: Use short-circuit evaluation to defer case- 12415 // insensitive check on the assumption that the majority case will 12416 // have exactly equal tag names. 12417 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 12418 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 12419 return false; 12420 } 12421 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 12422 }, 12423 Chars: isEquivalentTextTokens, 12424 Comment: isEquivalentTextTokens 12425 }; 12426 12427 /** 12428 * Given an array of tokens, returns the first token which is not purely 12429 * whitespace. 12430 * 12431 * Mutates the tokens array. 12432 * 12433 * @param {Object[]} tokens Set of tokens to search. 12434 * 12435 * @return {Object | undefined} Next non-whitespace token. 12436 */ 12437 function getNextNonWhitespaceToken(tokens) { 12438 let token; 12439 while (token = tokens.shift()) { 12440 if (token.type !== 'Chars') { 12441 return token; 12442 } 12443 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 12444 return token; 12445 } 12446 } 12447 } 12448 12449 /** 12450 * Tokenize an HTML string, gracefully handling any errors thrown during 12451 * underlying tokenization. 12452 * 12453 * @param {string} html HTML string to tokenize. 12454 * @param {Object} logger Validation logger object. 12455 * 12456 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 12457 */ 12458 function getHTMLTokens(html, logger = createLogger()) { 12459 try { 12460 return new Tokenizer(new DecodeEntityParser()).tokenize(html); 12461 } catch (e) { 12462 logger.warning('Malformed HTML detected: %s', html); 12463 } 12464 return null; 12465 } 12466 12467 /** 12468 * Returns true if the next HTML token closes the current token. 12469 * 12470 * @param {Object} currentToken Current token to compare with. 12471 * @param {Object|undefined} nextToken Next token to compare against. 12472 * 12473 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 12474 */ 12475 function isClosedByToken(currentToken, nextToken) { 12476 // Ensure this is a self closed token. 12477 if (!currentToken.selfClosing) { 12478 return false; 12479 } 12480 12481 // Check token names and determine if nextToken is the closing tag for currentToken. 12482 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 12483 return true; 12484 } 12485 return false; 12486 } 12487 12488 /** 12489 * Returns true if the given HTML strings are effectively equivalent, or 12490 * false otherwise. Invalid HTML is not considered equivalent, even if the 12491 * strings directly match. 12492 * 12493 * @param {string} actual Actual HTML string. 12494 * @param {string} expected Expected HTML string. 12495 * @param {Object} logger Validation logger object. 12496 * 12497 * @return {boolean} Whether HTML strings are equivalent. 12498 */ 12499 function isEquivalentHTML(actual, expected, logger = createLogger()) { 12500 // Short-circuit if markup is identical. 12501 if (actual === expected) { 12502 return true; 12503 } 12504 12505 // Tokenize input content and reserialized save content. 12506 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); 12507 12508 // If either is malformed then stop comparing - the strings are not equivalent. 12509 if (!actualTokens || !expectedTokens) { 12510 return false; 12511 } 12512 let actualToken, expectedToken; 12513 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 12514 expectedToken = getNextNonWhitespaceToken(expectedTokens); 12515 12516 // Inequal if exhausted all expected tokens. 12517 if (!expectedToken) { 12518 logger.warning('Expected end of content, instead saw %o.', actualToken); 12519 return false; 12520 } 12521 12522 // Inequal if next non-whitespace token of each set are not same type. 12523 if (actualToken.type !== expectedToken.type) { 12524 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 12525 return false; 12526 } 12527 12528 // Defer custom token type equality handling, otherwise continue and 12529 // assume as equal. 12530 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 12531 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 12532 return false; 12533 } 12534 12535 // Peek at the next tokens (actual and expected) to see if they close 12536 // a self-closing tag. 12537 if (isClosedByToken(actualToken, expectedTokens[0])) { 12538 // Consume the next expected token that closes the current actual 12539 // self-closing token. 12540 getNextNonWhitespaceToken(expectedTokens); 12541 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 12542 // Consume the next actual token that closes the current expected 12543 // self-closing token. 12544 getNextNonWhitespaceToken(actualTokens); 12545 } 12546 } 12547 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 12548 // If any non-whitespace tokens remain in expected token set, this 12549 // indicates inequality. 12550 logger.warning('Expected %o, instead saw end of content.', expectedToken); 12551 return false; 12552 } 12553 return true; 12554 } 12555 12556 /** 12557 * Returns an object with `isValid` property set to `true` if the parsed block 12558 * is valid given the input content. A block is considered valid if, when serialized 12559 * with assumed attributes, the content matches the original value. If block is 12560 * invalid, this function returns all validations issues as well. 12561 * 12562 * @param {string|Object} blockTypeOrName Block type. 12563 * @param {Object} attributes Parsed block attributes. 12564 * @param {string} originalBlockContent Original block content. 12565 * @param {Object} logger Validation logger object. 12566 * 12567 * @return {Object} Whether block is valid and contains validation messages. 12568 */ 12569 12570 /** 12571 * Returns an object with `isValid` property set to `true` if the parsed block 12572 * is valid given the input content. A block is considered valid if, when serialized 12573 * with assumed attributes, the content matches the original value. If block is 12574 * invalid, this function returns all validations issues as well. 12575 * 12576 * @param {WPBlock} block block object. 12577 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. 12578 * 12579 * @return {[boolean,Array<LoggerItem>]} validation results. 12580 */ 12581 function validateBlock(block, blockTypeOrName = block.name) { 12582 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); 12583 12584 // Shortcut to avoid costly validation. 12585 if (isFallbackBlock) { 12586 return [true, []]; 12587 } 12588 const logger = createQueuedLogger(); 12589 const blockType = normalizeBlockType(blockTypeOrName); 12590 let generatedBlockContent; 12591 try { 12592 generatedBlockContent = getSaveContent(blockType, block.attributes); 12593 } catch (error) { 12594 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 12595 return [false, logger.getItems()]; 12596 } 12597 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger); 12598 if (!isValid) { 12599 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); 12600 } 12601 return [isValid, logger.getItems()]; 12602 } 12603 12604 /** 12605 * Returns true if the parsed block is valid given the input content. A block 12606 * is considered valid if, when serialized with assumed attributes, the content 12607 * matches the original value. 12608 * 12609 * Logs to console in development environments when invalid. 12610 * 12611 * @deprecated Use validateBlock instead to avoid data loss. 12612 * 12613 * @param {string|Object} blockTypeOrName Block type. 12614 * @param {Object} attributes Parsed block attributes. 12615 * @param {string} originalBlockContent Original block content. 12616 * 12617 * @return {boolean} Whether block is valid. 12618 */ 12619 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 12620 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', { 12621 since: '12.6', 12622 plugin: 'Gutenberg', 12623 alternative: 'validateBlock' 12624 }); 12625 const blockType = normalizeBlockType(blockTypeOrName); 12626 const block = { 12627 name: blockType.name, 12628 attributes, 12629 innerBlocks: [], 12630 originalContent: originalBlockContent 12631 }; 12632 const [isValid] = validateBlock(block, blockType); 12633 return isValid; 12634 } 12635 12636 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/convert-legacy-block.js 12637 /** 12638 * Convert legacy blocks to their canonical form. This function is used 12639 * both in the parser level for previous content and to convert such blocks 12640 * used in Custom Post Types templates. 12641 * 12642 * @param {string} name The block's name 12643 * @param {Object} attributes The block's attributes 12644 * 12645 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found 12646 */ 12647 function convertLegacyBlockNameAndAttributes(name, attributes) { 12648 const newAttributes = { 12649 ...attributes 12650 }; 12651 // Convert 'core/cover-image' block in existing content to 'core/cover'. 12652 if ('core/cover-image' === name) { 12653 name = 'core/cover'; 12654 } 12655 12656 // Convert 'core/text' blocks in existing content to 'core/paragraph'. 12657 if ('core/text' === name || 'core/cover-text' === name) { 12658 name = 'core/paragraph'; 12659 } 12660 12661 // Convert derivative blocks such as 'core/social-link-wordpress' to the 12662 // canonical form 'core/social-link'. 12663 if (name && name.indexOf('core/social-link-') === 0) { 12664 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 12665 newAttributes.service = name.substring(17); 12666 name = 'core/social-link'; 12667 } 12668 12669 // Convert derivative blocks such as 'core-embed/instagram' to the 12670 // canonical form 'core/embed'. 12671 if (name && name.indexOf('core-embed/') === 0) { 12672 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 12673 const providerSlug = name.substring(11); 12674 const deprecated = { 12675 speaker: 'speaker-deck', 12676 polldaddy: 'crowdsignal' 12677 }; 12678 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; 12679 // This is needed as the `responsive` attribute was passed 12680 // in a different way before the refactoring to block variations. 12681 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 12682 newAttributes.responsive = true; 12683 } 12684 name = 'core/embed'; 12685 } 12686 12687 // Convert Post Comment blocks in existing content to Comment blocks. 12688 // TODO: Remove these checks when WordPress 6.0 is released. 12689 if (name === 'core/post-comment-author') { 12690 name = 'core/comment-author-name'; 12691 } 12692 if (name === 'core/post-comment-content') { 12693 name = 'core/comment-content'; 12694 } 12695 if (name === 'core/post-comment-date') { 12696 name = 'core/comment-date'; 12697 } 12698 if (name === 'core/comments-query-loop') { 12699 name = 'core/comments'; 12700 const { 12701 className = '' 12702 } = newAttributes; 12703 if (!className.includes('wp-block-comments-query-loop')) { 12704 newAttributes.className = ['wp-block-comments-query-loop', className].join(' '); 12705 } 12706 // Note that we also had to add a deprecation to the block in order 12707 // for the ID change to work. 12708 } 12709 if (name === 'core/post-comments') { 12710 name = 'core/comments'; 12711 newAttributes.legacy = true; 12712 } 12713 12714 // Column count was stored as a string from WP 6.3-6.6. Convert it to a number. 12715 if (attributes.layout?.type === 'grid' && typeof attributes.layout?.columnCount === 'string') { 12716 newAttributes.layout = { 12717 ...newAttributes.layout, 12718 columnCount: parseInt(attributes.layout.columnCount, 10) 12719 }; 12720 } 12721 12722 // Column span and row span were stored as strings in WP 6.6. Convert them to numbers. 12723 if (typeof attributes.style?.layout?.columnSpan === 'string') { 12724 const columnSpanNumber = parseInt(attributes.style.layout.columnSpan, 10); 12725 newAttributes.style = { 12726 ...newAttributes.style, 12727 layout: { 12728 ...newAttributes.style.layout, 12729 columnSpan: isNaN(columnSpanNumber) ? undefined : columnSpanNumber 12730 } 12731 }; 12732 } 12733 if (typeof attributes.style?.layout?.rowSpan === 'string') { 12734 const rowSpanNumber = parseInt(attributes.style.layout.rowSpan, 10); 12735 newAttributes.style = { 12736 ...newAttributes.style, 12737 layout: { 12738 ...newAttributes.style.layout, 12739 rowSpan: isNaN(rowSpanNumber) ? undefined : rowSpanNumber 12740 } 12741 }; 12742 } 12743 12744 // The following code is only relevant for the Gutenberg plugin. 12745 // It's a stand-alone if statement for dead-code elimination. 12746 if (false) {} 12747 return [name, newAttributes]; 12748 } 12749 12750 ;// ./node_modules/hpq/es/get-path.js 12751 /** 12752 * Given object and string of dot-delimited path segments, returns value at 12753 * path or undefined if path cannot be resolved. 12754 * 12755 * @param {Object} object Lookup object 12756 * @param {string} path Path to resolve 12757 * @return {?*} Resolved value 12758 */ 12759 function getPath(object, path) { 12760 var segments = path.split('.'); 12761 var segment; 12762 12763 while (segment = segments.shift()) { 12764 if (!(segment in object)) { 12765 return; 12766 } 12767 12768 object = object[segment]; 12769 } 12770 12771 return object; 12772 } 12773 ;// ./node_modules/hpq/es/index.js 12774 /** 12775 * Internal dependencies 12776 */ 12777 12778 /** 12779 * Function returning a DOM document created by `createHTMLDocument`. The same 12780 * document is returned between invocations. 12781 * 12782 * @return {Document} DOM document. 12783 */ 12784 12785 var getDocument = function () { 12786 var doc; 12787 return function () { 12788 if (!doc) { 12789 doc = document.implementation.createHTMLDocument(''); 12790 } 12791 12792 return doc; 12793 }; 12794 }(); 12795 /** 12796 * Given a markup string or DOM element, creates an object aligning with the 12797 * shape of the matchers object, or the value returned by the matcher. 12798 * 12799 * @param {(string|Element)} source Source content 12800 * @param {(Object|Function)} matchers Matcher function or object of matchers 12801 * @return {(Object|*)} Matched value(s), shaped by object 12802 */ 12803 12804 12805 function parse(source, matchers) { 12806 if (!matchers) { 12807 return; 12808 } // Coerce to element 12809 12810 12811 if ('string' === typeof source) { 12812 var doc = getDocument(); 12813 doc.body.innerHTML = source; 12814 source = doc.body; 12815 } // Return singular value 12816 12817 12818 if ('function' === typeof matchers) { 12819 return matchers(source); 12820 } // Bail if we can't handle matchers 12821 12822 12823 if (Object !== matchers.constructor) { 12824 return; 12825 } // Shape result by matcher object 12826 12827 12828 return Object.keys(matchers).reduce(function (memo, key) { 12829 memo[key] = parse(source, matchers[key]); 12830 return memo; 12831 }, {}); 12832 } 12833 /** 12834 * Generates a function which matches node of type selector, returning an 12835 * attribute by property if the attribute exists. If no selector is passed, 12836 * returns property of the query element. 12837 * 12838 * @param {?string} selector Optional selector 12839 * @param {string} name Property name 12840 * @return {*} Property value 12841 */ 12842 12843 function prop(selector, name) { 12844 if (1 === arguments.length) { 12845 name = selector; 12846 selector = undefined; 12847 } 12848 12849 return function (node) { 12850 var match = node; 12851 12852 if (selector) { 12853 match = node.querySelector(selector); 12854 } 12855 12856 if (match) { 12857 return getPath(match, name); 12858 } 12859 }; 12860 } 12861 /** 12862 * Generates a function which matches node of type selector, returning an 12863 * attribute by name if the attribute exists. If no selector is passed, 12864 * returns attribute of the query element. 12865 * 12866 * @param {?string} selector Optional selector 12867 * @param {string} name Attribute name 12868 * @return {?string} Attribute value 12869 */ 12870 12871 function attr(selector, name) { 12872 if (1 === arguments.length) { 12873 name = selector; 12874 selector = undefined; 12875 } 12876 12877 return function (node) { 12878 var attributes = prop(selector, 'attributes')(node); 12879 12880 if (attributes && attributes.hasOwnProperty(name)) { 12881 return attributes[name].value; 12882 } 12883 }; 12884 } 12885 /** 12886 * Convenience for `prop( selector, 'innerHTML' )`. 12887 * 12888 * @see prop() 12889 * 12890 * @param {?string} selector Optional selector 12891 * @return {string} Inner HTML 12892 */ 12893 12894 function html(selector) { 12895 return prop(selector, 'innerHTML'); 12896 } 12897 /** 12898 * Convenience for `prop( selector, 'textContent' )`. 12899 * 12900 * @see prop() 12901 * 12902 * @param {?string} selector Optional selector 12903 * @return {string} Text content 12904 */ 12905 12906 function es_text(selector) { 12907 return prop(selector, 'textContent'); 12908 } 12909 /** 12910 * Creates a new matching context by first finding elements matching selector 12911 * using querySelectorAll before then running another `parse` on `matchers` 12912 * scoped to the matched elements. 12913 * 12914 * @see parse() 12915 * 12916 * @param {string} selector Selector to match 12917 * @param {(Object|Function)} matchers Matcher function or object of matchers 12918 * @return {Array.<*,Object>} Array of matched value(s) 12919 */ 12920 12921 function query(selector, matchers) { 12922 return function (node) { 12923 var matches = node.querySelectorAll(selector); 12924 return [].map.call(matches, function (match) { 12925 return parse(match, matchers); 12926 }); 12927 }; 12928 } 12929 ;// ./node_modules/memize/dist/index.js 12930 /** 12931 * Memize options object. 12932 * 12933 * @typedef MemizeOptions 12934 * 12935 * @property {number} [maxSize] Maximum size of the cache. 12936 */ 12937 12938 /** 12939 * Internal cache entry. 12940 * 12941 * @typedef MemizeCacheNode 12942 * 12943 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 12944 * @property {?MemizeCacheNode|undefined} [next] Next node. 12945 * @property {Array<*>} args Function arguments for cache 12946 * entry. 12947 * @property {*} val Function result. 12948 */ 12949 12950 /** 12951 * Properties of the enhanced function for controlling cache. 12952 * 12953 * @typedef MemizeMemoizedFunction 12954 * 12955 * @property {()=>void} clear Clear the cache. 12956 */ 12957 12958 /** 12959 * Accepts a function to be memoized, and returns a new memoized function, with 12960 * optional options. 12961 * 12962 * @template {(...args: any[]) => any} F 12963 * 12964 * @param {F} fn Function to memoize. 12965 * @param {MemizeOptions} [options] Options object. 12966 * 12967 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 12968 */ 12969 function memize(fn, options) { 12970 var size = 0; 12971 12972 /** @type {?MemizeCacheNode|undefined} */ 12973 var head; 12974 12975 /** @type {?MemizeCacheNode|undefined} */ 12976 var tail; 12977 12978 options = options || {}; 12979 12980 function memoized(/* ...args */) { 12981 var node = head, 12982 len = arguments.length, 12983 args, 12984 i; 12985 12986 searchCache: while (node) { 12987 // Perform a shallow equality test to confirm that whether the node 12988 // under test is a candidate for the arguments passed. Two arrays 12989 // are shallowly equal if their length matches and each entry is 12990 // strictly equal between the two sets. Avoid abstracting to a 12991 // function which could incur an arguments leaking deoptimization. 12992 12993 // Check whether node arguments match arguments length 12994 if (node.args.length !== arguments.length) { 12995 node = node.next; 12996 continue; 12997 } 12998 12999 // Check whether node arguments match arguments values 13000 for (i = 0; i < len; i++) { 13001 if (node.args[i] !== arguments[i]) { 13002 node = node.next; 13003 continue searchCache; 13004 } 13005 } 13006 13007 // At this point we can assume we've found a match 13008 13009 // Surface matched node to head if not already 13010 if (node !== head) { 13011 // As tail, shift to previous. Must only shift if not also 13012 // head, since if both head and tail, there is no previous. 13013 if (node === tail) { 13014 tail = node.prev; 13015 } 13016 13017 // Adjust siblings to point to each other. If node was tail, 13018 // this also handles new tail's empty `next` assignment. 13019 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 13020 if (node.next) { 13021 node.next.prev = node.prev; 13022 } 13023 13024 node.next = head; 13025 node.prev = null; 13026 /** @type {MemizeCacheNode} */ (head).prev = node; 13027 head = node; 13028 } 13029 13030 // Return immediately 13031 return node.val; 13032 } 13033 13034 // No cached value found. Continue to insertion phase: 13035 13036 // Create a copy of arguments (avoid leaking deoptimization) 13037 args = new Array(len); 13038 for (i = 0; i < len; i++) { 13039 args[i] = arguments[i]; 13040 } 13041 13042 node = { 13043 args: args, 13044 13045 // Generate the result from original function 13046 val: fn.apply(null, args), 13047 }; 13048 13049 // Don't need to check whether node is already head, since it would 13050 // have been returned above already if it was 13051 13052 // Shift existing head down list 13053 if (head) { 13054 head.prev = node; 13055 node.next = head; 13056 } else { 13057 // If no head, follows that there's no tail (at initial or reset) 13058 tail = node; 13059 } 13060 13061 // Trim tail if we're reached max size and are pending cache insertion 13062 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 13063 tail = /** @type {MemizeCacheNode} */ (tail).prev; 13064 /** @type {MemizeCacheNode} */ (tail).next = null; 13065 } else { 13066 size++; 13067 } 13068 13069 head = node; 13070 13071 return node.val; 13072 } 13073 13074 memoized.clear = function () { 13075 head = null; 13076 tail = null; 13077 size = 0; 13078 }; 13079 13080 // Ignore reason: There's not a clear solution to create an intersection of 13081 // the function with additional properties, where the goal is to retain the 13082 // function signature of the incoming argument and add control properties 13083 // on the return value. 13084 13085 // @ts-ignore 13086 return memoized; 13087 } 13088 13089 13090 13091 ;// ./node_modules/@wordpress/blocks/build-module/api/matchers.js 13092 /** 13093 * External dependencies 13094 */ 13095 13096 13097 /** 13098 * WordPress dependencies 13099 */ 13100 13101 13102 /** 13103 * Internal dependencies 13104 */ 13105 13106 13107 function matchers_html(selector, multilineTag) { 13108 return domNode => { 13109 let match = domNode; 13110 if (selector) { 13111 match = domNode.querySelector(selector); 13112 } 13113 if (!match) { 13114 return ''; 13115 } 13116 if (multilineTag) { 13117 let value = ''; 13118 const length = match.children.length; 13119 for (let index = 0; index < length; index++) { 13120 const child = match.children[index]; 13121 if (child.nodeName.toLowerCase() !== multilineTag) { 13122 continue; 13123 } 13124 value += child.outerHTML; 13125 } 13126 return value; 13127 } 13128 return match.innerHTML; 13129 }; 13130 } 13131 const richText = (selector, preserveWhiteSpace) => el => { 13132 const target = selector ? el.querySelector(selector) : el; 13133 return target ? external_wp_richText_namespaceObject.RichTextData.fromHTMLElement(target, { 13134 preserveWhiteSpace 13135 }) : external_wp_richText_namespaceObject.RichTextData.empty(); 13136 }; 13137 13138 ;// ./node_modules/@wordpress/blocks/build-module/api/node.js 13139 /** 13140 * WordPress dependencies 13141 */ 13142 13143 13144 /** 13145 * Internal dependencies 13146 */ 13147 13148 13149 /** 13150 * A representation of a single node within a block's rich text value. If 13151 * representing a text node, the value is simply a string of the node value. 13152 * As representing an element node, it is an object of: 13153 * 13154 * 1. `type` (string): Tag name. 13155 * 2. `props` (object): Attributes and children array of WPBlockNode. 13156 * 13157 * @typedef {string|Object} WPBlockNode 13158 */ 13159 13160 /** 13161 * Given a single node and a node type (e.g. `'br'`), returns true if the node 13162 * corresponds to that type, false otherwise. 13163 * 13164 * @param {WPBlockNode} node Block node to test 13165 * @param {string} type Node to type to test against. 13166 * 13167 * @return {boolean} Whether node is of intended type. 13168 */ 13169 function isNodeOfType(node, type) { 13170 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', { 13171 since: '6.1', 13172 version: '6.3', 13173 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13174 }); 13175 return node && node.type === type; 13176 } 13177 13178 /** 13179 * Given an object implementing the NamedNodeMap interface, returns a plain 13180 * object equivalent value of name, value key-value pairs. 13181 * 13182 * @see https://dom.spec.whatwg.org/#interface-namednodemap 13183 * 13184 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 13185 * 13186 * @return {Object} Object equivalent value of NamedNodeMap. 13187 */ 13188 function getNamedNodeMapAsObject(nodeMap) { 13189 const result = {}; 13190 for (let i = 0; i < nodeMap.length; i++) { 13191 const { 13192 name, 13193 value 13194 } = nodeMap[i]; 13195 result[name] = value; 13196 } 13197 return result; 13198 } 13199 13200 /** 13201 * Given a DOM Element or Text node, returns an equivalent block node. Throws 13202 * if passed any node type other than element or text. 13203 * 13204 * @throws {TypeError} If non-element/text node is passed. 13205 * 13206 * @param {Node} domNode DOM node to convert. 13207 * 13208 * @return {WPBlockNode} Block node equivalent to DOM node. 13209 */ 13210 function fromDOM(domNode) { 13211 external_wp_deprecated_default()('wp.blocks.node.fromDOM', { 13212 since: '6.1', 13213 version: '6.3', 13214 alternative: 'wp.richText.create', 13215 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13216 }); 13217 if (domNode.nodeType === domNode.TEXT_NODE) { 13218 return domNode.nodeValue; 13219 } 13220 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 13221 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 13222 } 13223 return { 13224 type: domNode.nodeName.toLowerCase(), 13225 props: { 13226 ...getNamedNodeMapAsObject(domNode.attributes), 13227 children: children_fromDOM(domNode.childNodes) 13228 } 13229 }; 13230 } 13231 13232 /** 13233 * Given a block node, returns its HTML string representation. 13234 * 13235 * @param {WPBlockNode} node Block node to convert to string. 13236 * 13237 * @return {string} String HTML representation of block node. 13238 */ 13239 function toHTML(node) { 13240 external_wp_deprecated_default()('wp.blocks.node.toHTML', { 13241 since: '6.1', 13242 version: '6.3', 13243 alternative: 'wp.richText.toHTMLString', 13244 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13245 }); 13246 return children_toHTML([node]); 13247 } 13248 13249 /** 13250 * Given a selector, returns an hpq matcher generating a WPBlockNode value 13251 * matching the selector result. 13252 * 13253 * @param {string} selector DOM selector. 13254 * 13255 * @return {Function} hpq matcher. 13256 */ 13257 function matcher(selector) { 13258 external_wp_deprecated_default()('wp.blocks.node.matcher', { 13259 since: '6.1', 13260 version: '6.3', 13261 alternative: 'html source', 13262 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13263 }); 13264 return domNode => { 13265 let match = domNode; 13266 if (selector) { 13267 match = domNode.querySelector(selector); 13268 } 13269 try { 13270 return fromDOM(match); 13271 } catch (error) { 13272 return null; 13273 } 13274 }; 13275 } 13276 13277 /** 13278 * Object of utility functions used in managing block attribute values of 13279 * source `node`. 13280 * 13281 * @see https://github.com/WordPress/gutenberg/pull/10439 13282 * 13283 * @deprecated since 4.0. The `node` source should not be used, and can be 13284 * replaced by the `html` source. 13285 * 13286 * @private 13287 */ 13288 /* harmony default export */ const node = ({ 13289 isNodeOfType, 13290 fromDOM, 13291 toHTML, 13292 matcher 13293 }); 13294 13295 ;// ./node_modules/@wordpress/blocks/build-module/api/children.js 13296 /** 13297 * WordPress dependencies 13298 */ 13299 13300 13301 13302 /** 13303 * Internal dependencies 13304 */ 13305 13306 13307 /** 13308 * A representation of a block's rich text value. 13309 * 13310 * @typedef {WPBlockNode[]} WPBlockChildren 13311 */ 13312 13313 /** 13314 * Given block children, returns a serialize-capable WordPress element. 13315 * 13316 * @param {WPBlockChildren} children Block children object to convert. 13317 * 13318 * @return {Element} A serialize-capable element. 13319 */ 13320 function getSerializeCapableElement(children) { 13321 // The fact that block children are compatible with the element serializer is 13322 // merely an implementation detail that currently serves to be true, but 13323 // should not be mistaken as being a guarantee on the external API. The 13324 // public API only offers guarantees to work with strings (toHTML) and DOM 13325 // elements (fromDOM), and should provide utilities to manipulate the value 13326 // rather than expect consumers to inspect or construct its shape (concat). 13327 return children; 13328 } 13329 13330 /** 13331 * Given block children, returns an array of block nodes. 13332 * 13333 * @param {WPBlockChildren} children Block children object to convert. 13334 * 13335 * @return {Array<WPBlockNode>} An array of individual block nodes. 13336 */ 13337 function getChildrenArray(children) { 13338 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', { 13339 since: '6.1', 13340 version: '6.3', 13341 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13342 }); 13343 13344 // The fact that block children are compatible with the element serializer 13345 // is merely an implementation detail that currently serves to be true, but 13346 // should not be mistaken as being a guarantee on the external API. 13347 return children; 13348 } 13349 13350 /** 13351 * Given two or more block nodes, returns a new block node representing a 13352 * concatenation of its values. 13353 * 13354 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 13355 * 13356 * @return {WPBlockChildren} Concatenated block node. 13357 */ 13358 function concat(...blockNodes) { 13359 external_wp_deprecated_default()('wp.blocks.children.concat', { 13360 since: '6.1', 13361 version: '6.3', 13362 alternative: 'wp.richText.concat', 13363 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13364 }); 13365 const result = []; 13366 for (let i = 0; i < blockNodes.length; i++) { 13367 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]]; 13368 for (let j = 0; j < blockNode.length; j++) { 13369 const child = blockNode[j]; 13370 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 13371 if (canConcatToPreviousString) { 13372 result[result.length - 1] += child; 13373 } else { 13374 result.push(child); 13375 } 13376 } 13377 } 13378 return result; 13379 } 13380 13381 /** 13382 * Given an iterable set of DOM nodes, returns equivalent block children. 13383 * Ignores any non-element/text nodes included in set. 13384 * 13385 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 13386 * 13387 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 13388 */ 13389 function children_fromDOM(domNodes) { 13390 external_wp_deprecated_default()('wp.blocks.children.fromDOM', { 13391 since: '6.1', 13392 version: '6.3', 13393 alternative: 'wp.richText.create', 13394 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13395 }); 13396 const result = []; 13397 for (let i = 0; i < domNodes.length; i++) { 13398 try { 13399 result.push(fromDOM(domNodes[i])); 13400 } catch (error) { 13401 // Simply ignore if DOM node could not be converted. 13402 } 13403 } 13404 return result; 13405 } 13406 13407 /** 13408 * Given a block node, returns its HTML string representation. 13409 * 13410 * @param {WPBlockChildren} children Block node(s) to convert to string. 13411 * 13412 * @return {string} String HTML representation of block node. 13413 */ 13414 function children_toHTML(children) { 13415 external_wp_deprecated_default()('wp.blocks.children.toHTML', { 13416 since: '6.1', 13417 version: '6.3', 13418 alternative: 'wp.richText.toHTMLString', 13419 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13420 }); 13421 const element = getSerializeCapableElement(children); 13422 return (0,external_wp_element_namespaceObject.renderToString)(element); 13423 } 13424 13425 /** 13426 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 13427 * matching the selector result. 13428 * 13429 * @param {string} selector DOM selector. 13430 * 13431 * @return {Function} hpq matcher. 13432 */ 13433 function children_matcher(selector) { 13434 external_wp_deprecated_default()('wp.blocks.children.matcher', { 13435 since: '6.1', 13436 version: '6.3', 13437 alternative: 'html source', 13438 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13439 }); 13440 return domNode => { 13441 let match = domNode; 13442 if (selector) { 13443 match = domNode.querySelector(selector); 13444 } 13445 if (match) { 13446 return children_fromDOM(match.childNodes); 13447 } 13448 return []; 13449 }; 13450 } 13451 13452 /** 13453 * Object of utility functions used in managing block attribute values of 13454 * source `children`. 13455 * 13456 * @see https://github.com/WordPress/gutenberg/pull/10439 13457 * 13458 * @deprecated since 4.0. The `children` source should not be used, and can be 13459 * replaced by the `html` source. 13460 * 13461 * @private 13462 */ 13463 /* harmony default export */ const children = ({ 13464 concat, 13465 getChildrenArray, 13466 fromDOM: children_fromDOM, 13467 toHTML: children_toHTML, 13468 matcher: children_matcher 13469 }); 13470 13471 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/get-block-attributes.js 13472 /** 13473 * External dependencies 13474 */ 13475 13476 13477 13478 /** 13479 * WordPress dependencies 13480 */ 13481 13482 13483 13484 /** 13485 * Internal dependencies 13486 */ 13487 13488 13489 13490 /** 13491 * Higher-order hpq matcher which enhances an attribute matcher to return true 13492 * or false depending on whether the original matcher returns undefined. This 13493 * is useful for boolean attributes (e.g. disabled) whose attribute values may 13494 * be technically falsey (empty string), though their mere presence should be 13495 * enough to infer as true. 13496 * 13497 * @param {Function} matcher Original hpq matcher. 13498 * 13499 * @return {Function} Enhanced hpq matcher. 13500 */ 13501 const toBooleanAttributeMatcher = matcher => value => matcher(value) !== undefined; 13502 13503 /** 13504 * Returns true if value is of the given JSON schema type, or false otherwise. 13505 * 13506 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13507 * 13508 * @param {*} value Value to test. 13509 * @param {string} type Type to test. 13510 * 13511 * @return {boolean} Whether value is of type. 13512 */ 13513 function isOfType(value, type) { 13514 switch (type) { 13515 case 'rich-text': 13516 return value instanceof external_wp_richText_namespaceObject.RichTextData; 13517 case 'string': 13518 return typeof value === 'string'; 13519 case 'boolean': 13520 return typeof value === 'boolean'; 13521 case 'object': 13522 return !!value && value.constructor === Object; 13523 case 'null': 13524 return value === null; 13525 case 'array': 13526 return Array.isArray(value); 13527 case 'integer': 13528 case 'number': 13529 return typeof value === 'number'; 13530 } 13531 return true; 13532 } 13533 13534 /** 13535 * Returns true if value is of an array of given JSON schema types, or false 13536 * otherwise. 13537 * 13538 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13539 * 13540 * @param {*} value Value to test. 13541 * @param {string[]} types Types to test. 13542 * 13543 * @return {boolean} Whether value is of types. 13544 */ 13545 function isOfTypes(value, types) { 13546 return types.some(type => isOfType(value, type)); 13547 } 13548 13549 /** 13550 * Given an attribute key, an attribute's schema, a block's raw content and the 13551 * commentAttributes returns the attribute value depending on its source 13552 * definition of the given attribute key. 13553 * 13554 * @param {string} attributeKey Attribute key. 13555 * @param {Object} attributeSchema Attribute's schema. 13556 * @param {Node} innerDOM Parsed DOM of block's inner HTML. 13557 * @param {Object} commentAttributes Block's comment attributes. 13558 * @param {string} innerHTML Raw HTML from block node's innerHTML property. 13559 * 13560 * @return {*} Attribute value. 13561 */ 13562 function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) { 13563 let value; 13564 switch (attributeSchema.source) { 13565 // An undefined source means that it's an attribute serialized to the 13566 // block's "comment". 13567 case undefined: 13568 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 13569 break; 13570 // raw source means that it's the original raw block content. 13571 case 'raw': 13572 value = innerHTML; 13573 break; 13574 case 'attribute': 13575 case 'property': 13576 case 'html': 13577 case 'text': 13578 case 'rich-text': 13579 case 'children': 13580 case 'node': 13581 case 'query': 13582 case 'tag': 13583 value = parseWithAttributeSchema(innerDOM, attributeSchema); 13584 break; 13585 } 13586 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) { 13587 // Reject the value if it is not valid. Reverting to the undefined 13588 // value ensures the default is respected, if applicable. 13589 value = undefined; 13590 } 13591 if (value === undefined) { 13592 value = getDefault(attributeSchema); 13593 } 13594 return value; 13595 } 13596 13597 /** 13598 * Returns true if value is valid per the given block attribute schema type 13599 * definition, or false otherwise. 13600 * 13601 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 13602 * 13603 * @param {*} value Value to test. 13604 * @param {?(Array<string>|string)} type Block attribute schema type. 13605 * 13606 * @return {boolean} Whether value is valid. 13607 */ 13608 function isValidByType(value, type) { 13609 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]); 13610 } 13611 13612 /** 13613 * Returns true if value is valid per the given block attribute schema enum 13614 * definition, or false otherwise. 13615 * 13616 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 13617 * 13618 * @param {*} value Value to test. 13619 * @param {?Array} enumSet Block attribute schema enum. 13620 * 13621 * @return {boolean} Whether value is valid. 13622 */ 13623 function isValidByEnum(value, enumSet) { 13624 return !Array.isArray(enumSet) || enumSet.includes(value); 13625 } 13626 13627 /** 13628 * Returns an hpq matcher given a source object. 13629 * 13630 * @param {Object} sourceConfig Attribute Source object. 13631 * 13632 * @return {Function} A hpq Matcher. 13633 */ 13634 const matcherFromSource = memize(sourceConfig => { 13635 switch (sourceConfig.source) { 13636 case 'attribute': 13637 { 13638 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 13639 if (sourceConfig.type === 'boolean') { 13640 matcher = toBooleanAttributeMatcher(matcher); 13641 } 13642 return matcher; 13643 } 13644 case 'html': 13645 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 13646 case 'text': 13647 return es_text(sourceConfig.selector); 13648 case 'rich-text': 13649 return richText(sourceConfig.selector, sourceConfig.__unstablePreserveWhiteSpace); 13650 case 'children': 13651 return children_matcher(sourceConfig.selector); 13652 case 'node': 13653 return matcher(sourceConfig.selector); 13654 case 'query': 13655 const subMatchers = Object.fromEntries(Object.entries(sourceConfig.query).map(([key, subSourceConfig]) => [key, matcherFromSource(subSourceConfig)])); 13656 return query(sourceConfig.selector, subMatchers); 13657 case 'tag': 13658 { 13659 const matcher = prop(sourceConfig.selector, 'nodeName'); 13660 return domNode => matcher(domNode)?.toLowerCase(); 13661 } 13662 default: 13663 // eslint-disable-next-line no-console 13664 console.error(`Unknown source type "$sourceConfig.source}"`); 13665 } 13666 }); 13667 13668 /** 13669 * Parse a HTML string into DOM tree. 13670 * 13671 * @param {string|Node} innerHTML HTML string or already parsed DOM node. 13672 * 13673 * @return {Node} Parsed DOM node. 13674 */ 13675 function parseHtml(innerHTML) { 13676 return parse(innerHTML, h => h); 13677 } 13678 13679 /** 13680 * Given a block's raw content and an attribute's schema returns the attribute's 13681 * value depending on its source. 13682 * 13683 * @param {string|Node} innerHTML Block's raw content. 13684 * @param {Object} attributeSchema Attribute's schema. 13685 * 13686 * @return {*} Attribute value. 13687 */ 13688 function parseWithAttributeSchema(innerHTML, attributeSchema) { 13689 return matcherFromSource(attributeSchema)(parseHtml(innerHTML)); 13690 } 13691 13692 /** 13693 * Returns the block attributes of a registered block node given its type. 13694 * 13695 * @param {string|Object} blockTypeOrName Block type or name. 13696 * @param {string|Node} innerHTML Raw block content. 13697 * @param {?Object} attributes Known block attributes (from delimiters). 13698 * 13699 * @return {Object} All block attributes. 13700 */ 13701 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) { 13702 var _blockType$attributes; 13703 const doc = parseHtml(innerHTML); 13704 const blockType = normalizeBlockType(blockTypeOrName); 13705 const blockAttributes = Object.fromEntries(Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).map(([key, schema]) => [key, getBlockAttribute(key, schema, doc, attributes, innerHTML)])); 13706 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 13707 } 13708 13709 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/fix-custom-classname.js 13710 /** 13711 * Internal dependencies 13712 */ 13713 13714 13715 13716 const CLASS_ATTR_SCHEMA = { 13717 type: 'string', 13718 source: 'attribute', 13719 selector: '[data-custom-class-name] > *', 13720 attribute: 'class' 13721 }; 13722 13723 /** 13724 * Given an HTML string, returns an array of class names assigned to the root 13725 * element in the markup. 13726 * 13727 * @param {string} innerHTML Markup string from which to extract classes. 13728 * 13729 * @return {string[]} Array of class names assigned to the root element. 13730 */ 13731 function getHTMLRootElementClasses(innerHTML) { 13732 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>$innerHTML}</div>`, CLASS_ATTR_SCHEMA); 13733 return parsed ? parsed.trim().split(/\s+/) : []; 13734 } 13735 13736 /** 13737 * Given a parsed set of block attributes, if the block supports custom class 13738 * names and an unknown class (per the block's serialization behavior) is 13739 * found, the unknown classes are treated as custom classes. This prevents the 13740 * block from being considered as invalid. 13741 * 13742 * @param {Object} blockAttributes Original block attributes. 13743 * @param {Object} blockType Block type settings. 13744 * @param {string} innerHTML Original block markup. 13745 * 13746 * @return {Object} Filtered block attributes. 13747 */ 13748 function fixCustomClassname(blockAttributes, blockType, innerHTML) { 13749 if (!hasBlockSupport(blockType, 'customClassName', true)) { 13750 return blockAttributes; 13751 } 13752 const modifiedBlockAttributes = { 13753 ...blockAttributes 13754 }; 13755 // To determine difference, serialize block given the known set of 13756 // attributes, with the exception of `className`. This will determine 13757 // the default set of classes. From there, any difference in innerHTML 13758 // can be considered as custom classes. 13759 const { 13760 className: omittedClassName, 13761 ...attributesSansClassName 13762 } = modifiedBlockAttributes; 13763 const serialized = getSaveContent(blockType, attributesSansClassName); 13764 const defaultClasses = getHTMLRootElementClasses(serialized); 13765 const actualClasses = getHTMLRootElementClasses(innerHTML); 13766 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className)); 13767 if (customClasses.length) { 13768 modifiedBlockAttributes.className = customClasses.join(' '); 13769 } else if (serialized) { 13770 delete modifiedBlockAttributes.className; 13771 } 13772 return modifiedBlockAttributes; 13773 } 13774 13775 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/fix-aria-label.js 13776 /** 13777 * Internal dependencies 13778 */ 13779 13780 13781 const ARIA_LABEL_ATTR_SCHEMA = { 13782 type: 'string', 13783 source: 'attribute', 13784 selector: '[data-aria-label] > *', 13785 attribute: 'aria-label' 13786 }; 13787 13788 /** 13789 * Given an HTML string, returns the aria-label attribute assigned to 13790 * the root element in the markup. 13791 * 13792 * @param {string} innerHTML Markup string from which to extract the aria-label. 13793 * 13794 * @return {string} The aria-label assigned to the root element. 13795 */ 13796 function getHTMLRootElementAriaLabel(innerHTML) { 13797 const parsed = parseWithAttributeSchema(`<div data-aria-label>$innerHTML}</div>`, ARIA_LABEL_ATTR_SCHEMA); 13798 return parsed; 13799 } 13800 13801 /** 13802 * Given a parsed set of block attributes, if the block supports ariaLabel 13803 * and an aria-label attribute is found, the aria-label attribute is assigned 13804 * to the block attributes. 13805 * 13806 * @param {Object} blockAttributes Original block attributes. 13807 * @param {Object} blockType Block type settings. 13808 * @param {string} innerHTML Original block markup. 13809 * 13810 * @return {Object} Filtered block attributes. 13811 */ 13812 function fixAriaLabel(blockAttributes, blockType, innerHTML) { 13813 if (!hasBlockSupport(blockType, 'ariaLabel', false)) { 13814 return blockAttributes; 13815 } 13816 const modifiedBlockAttributes = { 13817 ...blockAttributes 13818 }; 13819 const ariaLabel = getHTMLRootElementAriaLabel(innerHTML); 13820 if (ariaLabel) { 13821 modifiedBlockAttributes.ariaLabel = ariaLabel; 13822 } 13823 return modifiedBlockAttributes; 13824 } 13825 13826 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/apply-built-in-validation-fixes.js 13827 /** 13828 * Internal dependencies 13829 */ 13830 13831 13832 13833 /** 13834 * Attempts to fix block invalidation by applying build-in validation fixes 13835 * like moving all extra classNames to the className attribute. 13836 * 13837 * @param {WPBlock} block block object. 13838 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13839 * can be inferred from the block name, 13840 * but it's here for performance reasons. 13841 * 13842 * @return {WPBlock} Fixed block object 13843 */ 13844 function applyBuiltInValidationFixes(block, blockType) { 13845 const { 13846 attributes, 13847 originalContent 13848 } = block; 13849 let updatedBlockAttributes = attributes; 13850 13851 // Fix block invalidation for className attribute. 13852 updatedBlockAttributes = fixCustomClassname(attributes, blockType, originalContent); 13853 // Fix block invalidation for ariaLabel attribute. 13854 updatedBlockAttributes = fixAriaLabel(updatedBlockAttributes, blockType, originalContent); 13855 return { 13856 ...block, 13857 attributes: updatedBlockAttributes 13858 }; 13859 } 13860 13861 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/apply-block-deprecated-versions.js 13862 /** 13863 * Internal dependencies 13864 */ 13865 13866 13867 13868 13869 13870 13871 /** 13872 * Function that takes no arguments and always returns false. 13873 * 13874 * @return {boolean} Always returns false. 13875 */ 13876 function stubFalse() { 13877 return false; 13878 } 13879 13880 /** 13881 * Given a block object, returns a new copy of the block with any applicable 13882 * deprecated migrations applied, or the original block if it was both valid 13883 * and no eligible migrations exist. 13884 * 13885 * @param {import(".").WPBlock} block Parsed and invalid block object. 13886 * @param {import(".").WPRawBlock} rawBlock Raw block object. 13887 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13888 * can be inferred from the block name, 13889 * but it's here for performance reasons. 13890 * 13891 * @return {import(".").WPBlock} Migrated block object. 13892 */ 13893 function applyBlockDeprecatedVersions(block, rawBlock, blockType) { 13894 const parsedAttributes = rawBlock.attrs; 13895 const { 13896 deprecated: deprecatedDefinitions 13897 } = blockType; 13898 // Bail early if there are no registered deprecations to be handled. 13899 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 13900 return block; 13901 } 13902 13903 // By design, blocks lack any sort of version tracking. Instead, to process 13904 // outdated content the system operates a queue out of all the defined 13905 // attribute shapes and tries each definition until the input produces a 13906 // valid result. This mechanism seeks to avoid polluting the user-space with 13907 // machine-specific code. An invalid block is thus a block that could not be 13908 // matched successfully with any of the registered deprecation definitions. 13909 for (let i = 0; i < deprecatedDefinitions.length; i++) { 13910 // A block can opt into a migration even if the block is valid by 13911 // defining `isEligible` on its deprecation. If the block is both valid 13912 // and does not opt to migrate, skip. 13913 const { 13914 isEligible = stubFalse 13915 } = deprecatedDefinitions[i]; 13916 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks, { 13917 blockNode: rawBlock, 13918 block 13919 })) { 13920 continue; 13921 } 13922 13923 // Block type properties which could impact either serialization or 13924 // parsing are not considered in the deprecated block type by default, 13925 // and must be explicitly provided. 13926 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 13927 let migratedBlock = { 13928 ...block, 13929 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes) 13930 }; 13931 13932 // Ignore the deprecation if it produces a block which is not valid. 13933 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13934 13935 // If the migrated block is not valid initially, try the built-in fixes. 13936 if (!isValid) { 13937 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType); 13938 [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13939 } 13940 13941 // An invalid block does not imply incorrect HTML but the fact block 13942 // source information could be lost on re-serialization. 13943 if (!isValid) { 13944 continue; 13945 } 13946 let migratedInnerBlocks = migratedBlock.innerBlocks; 13947 let migratedAttributes = migratedBlock.attributes; 13948 13949 // A block may provide custom behavior to assign new attributes and/or 13950 // inner blocks. 13951 const { 13952 migrate 13953 } = deprecatedBlockType; 13954 if (migrate) { 13955 let migrated = migrate(migratedAttributes, block.innerBlocks); 13956 if (!Array.isArray(migrated)) { 13957 migrated = [migrated]; 13958 } 13959 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated; 13960 } 13961 block = { 13962 ...block, 13963 attributes: migratedAttributes, 13964 innerBlocks: migratedInnerBlocks, 13965 isValid: true, 13966 validationIssues: [] 13967 }; 13968 } 13969 return block; 13970 } 13971 13972 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/index.js 13973 /** 13974 * WordPress dependencies 13975 */ 13976 13977 13978 13979 /** 13980 * Internal dependencies 13981 */ 13982 13983 13984 13985 13986 13987 13988 13989 13990 13991 13992 /** 13993 * The raw structure of a block includes its attributes, inner 13994 * blocks, and inner HTML. It is important to distinguish inner blocks from 13995 * the HTML content of the block as only the latter is relevant for block 13996 * validation and edit operations. 13997 * 13998 * @typedef WPRawBlock 13999 * 14000 * @property {string=} blockName Block name 14001 * @property {Object=} attrs Block raw or comment attributes. 14002 * @property {string} innerHTML HTML content of the block. 14003 * @property {(string|null)[]} innerContent Content without inner blocks. 14004 * @property {WPRawBlock[]} innerBlocks Inner Blocks. 14005 */ 14006 14007 /** 14008 * Fully parsed block object. 14009 * 14010 * @typedef WPBlock 14011 * 14012 * @property {string} name Block name 14013 * @property {Object} attributes Block raw or comment attributes. 14014 * @property {WPBlock[]} innerBlocks Inner Blocks. 14015 * @property {string} originalContent Original content of the block before validation fixes. 14016 * @property {boolean} isValid Whether the block is valid. 14017 * @property {Object[]} validationIssues Validation issues. 14018 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. 14019 */ 14020 14021 /** 14022 * @typedef {Object} ParseOptions 14023 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. 14024 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content. 14025 */ 14026 14027 /** 14028 * Convert legacy blocks to their canonical form. This function is used 14029 * both in the parser level for previous content and to convert such blocks 14030 * used in Custom Post Types templates. 14031 * 14032 * @param {WPRawBlock} rawBlock 14033 * 14034 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found 14035 */ 14036 function convertLegacyBlocks(rawBlock) { 14037 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs); 14038 return { 14039 ...rawBlock, 14040 blockName: correctName, 14041 attrs: correctedAttributes 14042 }; 14043 } 14044 14045 /** 14046 * Normalize the raw block by applying the fallback block name if none given, 14047 * sanitize the parsed HTML... 14048 * 14049 * @param {WPRawBlock} rawBlock The raw block object. 14050 * @param {ParseOptions?} options Extra options for handling block parsing. 14051 * 14052 * @return {WPRawBlock} The normalized block object. 14053 */ 14054 function normalizeRawBlock(rawBlock, options) { 14055 const fallbackBlockName = getFreeformContentHandlerName(); 14056 14057 // If the grammar parsing don't produce any block name, use the freeform block. 14058 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName(); 14059 const rawAttributes = rawBlock.attrs || {}; 14060 const rawInnerBlocks = rawBlock.innerBlocks || []; 14061 let rawInnerHTML = rawBlock.innerHTML.trim(); 14062 14063 // Fallback content may be upgraded from classic content expecting implicit 14064 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 14065 // meaning there are no negative consequences to repeated autop calls. 14066 if (rawBlockName === fallbackBlockName && rawBlockName === 'core/freeform' && !options?.__unstableSkipAutop) { 14067 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim(); 14068 } 14069 return { 14070 ...rawBlock, 14071 blockName: rawBlockName, 14072 attrs: rawAttributes, 14073 innerHTML: rawInnerHTML, 14074 innerBlocks: rawInnerBlocks 14075 }; 14076 } 14077 14078 /** 14079 * Uses the "unregistered blockType" to create a block object. 14080 * 14081 * @param {WPRawBlock} rawBlock block. 14082 * 14083 * @return {WPRawBlock} The unregistered block object. 14084 */ 14085 function createMissingBlockType(rawBlock) { 14086 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); 14087 14088 // Preserve undelimited content for use by the unregistered type 14089 // handler. A block node's `innerHTML` isn't enough, as that field only 14090 // carries the block's own HTML and not its nested blocks. 14091 const originalUndelimitedContent = serializeRawBlock(rawBlock, { 14092 isCommentDelimited: false 14093 }); 14094 14095 // Preserve full block content for use by the unregistered type 14096 // handler, block boundaries included. 14097 const originalContent = serializeRawBlock(rawBlock, { 14098 isCommentDelimited: true 14099 }); 14100 return { 14101 blockName: unregisteredFallbackBlock, 14102 attrs: { 14103 originalName: rawBlock.blockName, 14104 originalContent, 14105 originalUndelimitedContent 14106 }, 14107 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML, 14108 innerBlocks: rawBlock.innerBlocks, 14109 innerContent: rawBlock.innerContent 14110 }; 14111 } 14112 14113 /** 14114 * Validates a block and wraps with validation meta. 14115 * 14116 * The name here is regrettable but `validateBlock` is already taken. 14117 * 14118 * @param {WPBlock} unvalidatedBlock 14119 * @param {import('../registration').WPBlockType} blockType 14120 * @return {WPBlock} validated block, with auto-fixes if initially invalid 14121 */ 14122 function applyBlockValidation(unvalidatedBlock, blockType) { 14123 // Attempt to validate the block. 14124 const [isValid] = validateBlock(unvalidatedBlock, blockType); 14125 if (isValid) { 14126 return { 14127 ...unvalidatedBlock, 14128 isValid, 14129 validationIssues: [] 14130 }; 14131 } 14132 14133 // If the block is invalid, attempt some built-in fixes 14134 // like custom classNames handling. 14135 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); 14136 // Attempt to validate the block once again after the built-in fixes. 14137 const [isFixedValid, validationIssues] = validateBlock(fixedBlock, blockType); 14138 return { 14139 ...fixedBlock, 14140 isValid: isFixedValid, 14141 validationIssues 14142 }; 14143 } 14144 14145 /** 14146 * Given a raw block returned by grammar parsing, returns a fully parsed block. 14147 * 14148 * @param {WPRawBlock} rawBlock The raw block object. 14149 * @param {ParseOptions} options Extra options for handling block parsing. 14150 * 14151 * @return {WPBlock | undefined} Fully parsed block. 14152 */ 14153 function parseRawBlock(rawBlock, options) { 14154 let normalizedBlock = normalizeRawBlock(rawBlock, options); 14155 14156 // During the lifecycle of the project, we renamed some old blocks 14157 // and transformed others to new blocks. To avoid breaking existing content, 14158 // we added this function to properly parse the old content. 14159 normalizedBlock = convertLegacyBlocks(normalizedBlock); 14160 14161 // Try finding the type for known block name. 14162 let blockType = getBlockType(normalizedBlock.blockName); 14163 14164 // If not blockType is found for the specified name, fallback to the "unregisteredBlockType". 14165 if (!blockType) { 14166 normalizedBlock = createMissingBlockType(normalizedBlock); 14167 blockType = getBlockType(normalizedBlock.blockName); 14168 } 14169 14170 // If it's an empty freeform block or there's no blockType (no missing block handler) 14171 // Then, just ignore the block. 14172 // It might be a good idea to throw a warning here. 14173 // TODO: I'm unsure about the unregisteredFallbackBlock check, 14174 // it might ignore some dynamic unregistered third party blocks wrongly. 14175 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName(); 14176 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) { 14177 return; 14178 } 14179 14180 // Parse inner blocks recursively. 14181 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) 14182 // See https://github.com/WordPress/gutenberg/pull/17164. 14183 .filter(innerBlock => !!innerBlock); 14184 14185 // Get the fully parsed block. 14186 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks); 14187 parsedBlock.originalContent = normalizedBlock.innerHTML; 14188 const validatedBlock = applyBlockValidation(parsedBlock, blockType); 14189 const { 14190 validationIssues 14191 } = validatedBlock; 14192 14193 // Run the block deprecation and migrations. 14194 // This is performed on both invalid and valid blocks because 14195 // migration using the `migrate` functions should run even 14196 // if the output is deemed valid. 14197 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType); 14198 if (!updatedBlock.isValid) { 14199 // Preserve the original unprocessed version of the block 14200 // that we received (no fixes, no deprecations) so that 14201 // we can save it as close to exactly the same way as 14202 // we loaded it. This is important to avoid corruption 14203 // and data loss caused by block implementations trying 14204 // to process data that isn't fully recognized. 14205 updatedBlock.__unstableBlockSource = rawBlock; 14206 } 14207 if (!validatedBlock.isValid && updatedBlock.isValid && !options?.__unstableSkipMigrationLogs) { 14208 /* eslint-disable no-console */ 14209 console.groupCollapsed('Updated Block: %s', blockType.name); 14210 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); 14211 console.groupEnd(); 14212 /* eslint-enable no-console */ 14213 } else if (!validatedBlock.isValid && !updatedBlock.isValid) { 14214 validationIssues.forEach(({ 14215 log, 14216 args 14217 }) => log(...args)); 14218 } 14219 return updatedBlock; 14220 } 14221 14222 /** 14223 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 14224 * defined through a parsing expression grammar to take advantage of the regular 14225 * cadence provided by block delimiters -- composed syntactically through HTML 14226 * comments -- which, given a general HTML document as an input, returns a block 14227 * list array representation. 14228 * 14229 * This is a recursive-descent parser that scans linearly once through the input 14230 * document. Instead of directly recursing it utilizes a trampoline mechanism to 14231 * prevent stack overflow. This initial pass is mainly interested in separating 14232 * and isolating the blocks serialized in the document and manifestly not in the 14233 * content within the blocks. 14234 * 14235 * @see 14236 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 14237 * 14238 * @param {string} content The post content. 14239 * @param {ParseOptions} options Extra options for handling block parsing. 14240 * 14241 * @return {Array} Block list. 14242 */ 14243 function parser_parse(content, options) { 14244 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => { 14245 const block = parseRawBlock(rawBlock, options); 14246 if (block) { 14247 accumulator.push(block); 14248 } 14249 return accumulator; 14250 }, []); 14251 } 14252 14253 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js 14254 /** 14255 * Internal dependencies 14256 */ 14257 14258 function getRawTransforms() { 14259 return getBlockTransforms('from').filter(({ 14260 type 14261 }) => type === 'raw').map(transform => { 14262 return transform.isMatch ? transform : { 14263 ...transform, 14264 isMatch: node => transform.selector && node.matches(transform.selector) 14265 }; 14266 }); 14267 } 14268 14269 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js 14270 /** 14271 * WordPress dependencies 14272 */ 14273 14274 14275 /** 14276 * Internal dependencies 14277 */ 14278 14279 14280 14281 14282 14283 /** 14284 * Converts HTML directly to blocks. Looks for a matching transform for each 14285 * top-level tag. The HTML should be filtered to not have any text between 14286 * top-level tags and formatted in a way that blocks can handle the HTML. 14287 * 14288 * @param {string} html HTML to convert. 14289 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler 14290 * or pasteHandler. 14291 * 14292 * @return {Array} An array of blocks. 14293 */ 14294 function htmlToBlocks(html, handler) { 14295 const doc = document.implementation.createHTMLDocument(''); 14296 doc.body.innerHTML = html; 14297 return Array.from(doc.body.children).flatMap(node => { 14298 const rawTransform = findTransform(getRawTransforms(), ({ 14299 isMatch 14300 }) => isMatch(node)); 14301 if (!rawTransform) { 14302 // Until the HTML block is supported in the native version, we'll parse it 14303 // instead of creating the block to generate it as an unsupported block. 14304 if (external_wp_element_namespaceObject.Platform.isNative) { 14305 return parser_parse(`<!-- wp:html -->$node.outerHTML}<!-- /wp:html -->`); 14306 } 14307 return createBlock( 14308 // Should not be hardcoded. 14309 'core/html', getBlockAttributes('core/html', node.outerHTML)); 14310 } 14311 const { 14312 transform, 14313 blockName 14314 } = rawTransform; 14315 if (transform) { 14316 const block = transform(node, handler); 14317 if (node.hasAttribute('class')) { 14318 block.attributes.className = node.getAttribute('class'); 14319 } 14320 return block; 14321 } 14322 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 14323 }); 14324 } 14325 14326 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js 14327 /** 14328 * WordPress dependencies 14329 */ 14330 14331 function normaliseBlocks(HTML, options = {}) { 14332 const decuDoc = document.implementation.createHTMLDocument(''); 14333 const accuDoc = document.implementation.createHTMLDocument(''); 14334 const decu = decuDoc.body; 14335 const accu = accuDoc.body; 14336 decu.innerHTML = HTML; 14337 while (decu.firstChild) { 14338 const node = decu.firstChild; 14339 14340 // Text nodes: wrap in a paragraph, or append to previous. 14341 if (node.nodeType === node.TEXT_NODE) { 14342 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 14343 decu.removeChild(node); 14344 } else { 14345 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14346 accu.appendChild(accuDoc.createElement('P')); 14347 } 14348 accu.lastChild.appendChild(node); 14349 } 14350 // Element nodes. 14351 } else if (node.nodeType === node.ELEMENT_NODE) { 14352 // BR nodes: create a new paragraph on double, or append to previous. 14353 if (node.nodeName === 'BR') { 14354 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 14355 accu.appendChild(accuDoc.createElement('P')); 14356 decu.removeChild(node.nextSibling); 14357 } 14358 14359 // Don't append to an empty paragraph. 14360 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 14361 accu.lastChild.appendChild(node); 14362 } else { 14363 decu.removeChild(node); 14364 } 14365 } else if (node.nodeName === 'P') { 14366 // Only append non-empty paragraph nodes. 14367 if ((0,external_wp_dom_namespaceObject.isEmpty)(node) && !options.raw) { 14368 decu.removeChild(node); 14369 } else { 14370 accu.appendChild(node); 14371 } 14372 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) { 14373 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14374 accu.appendChild(accuDoc.createElement('P')); 14375 } 14376 accu.lastChild.appendChild(node); 14377 } else { 14378 accu.appendChild(node); 14379 } 14380 } else { 14381 decu.removeChild(node); 14382 } 14383 } 14384 return accu.innerHTML; 14385 } 14386 14387 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js 14388 /** 14389 * WordPress dependencies 14390 */ 14391 14392 14393 /** 14394 * Looks for `<!--nextpage-->` and `<!--more-->` comments and 14395 * replaces them with a custom element representing a future block. 14396 * 14397 * The custom element is a way to bypass the rest of the `raw-handling` 14398 * transforms, which would eliminate other kinds of node with which to carry 14399 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 14400 * 14401 * The custom element is then expected to be recognized by any registered 14402 * block's `raw` transform. 14403 * 14404 * @param {Node} node The node to be processed. 14405 * @param {Document} doc The document of the node. 14406 * @return {void} 14407 */ 14408 function specialCommentConverter(node, doc) { 14409 if (node.nodeType !== node.COMMENT_NODE) { 14410 return; 14411 } 14412 if (node.nodeValue !== 'nextpage' && node.nodeValue.indexOf('more') !== 0) { 14413 return; 14414 } 14415 const block = special_comment_converter_createBlock(node, doc); 14416 14417 // If our `<!--more-->` comment is in the middle of a paragraph, we should 14418 // split the paragraph in two and insert the more block in between. If it's 14419 // inside an empty paragraph, we should still move it out of the paragraph 14420 // and remove the paragraph. If there's no paragraph, fall back to simply 14421 // replacing the comment. 14422 if (!node.parentNode || node.parentNode.nodeName !== 'P') { 14423 (0,external_wp_dom_namespaceObject.replace)(node, block); 14424 } else { 14425 const childNodes = Array.from(node.parentNode.childNodes); 14426 const nodeIndex = childNodes.indexOf(node); 14427 const wrapperNode = node.parentNode.parentNode || doc.body; 14428 const paragraphBuilder = (acc, child) => { 14429 if (!acc) { 14430 acc = doc.createElement('p'); 14431 } 14432 acc.appendChild(child); 14433 return acc; 14434 }; 14435 14436 // Split the original parent node and insert our more block 14437 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), block, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEach(element => element && wrapperNode.insertBefore(element, node.parentNode)); 14438 14439 // Remove the old parent paragraph 14440 (0,external_wp_dom_namespaceObject.remove)(node.parentNode); 14441 } 14442 } 14443 function special_comment_converter_createBlock(commentNode, doc) { 14444 if (commentNode.nodeValue === 'nextpage') { 14445 return createNextpage(doc); 14446 } 14447 14448 // Grab any custom text in the comment. 14449 const customText = commentNode.nodeValue.slice(4).trim(); 14450 14451 /* 14452 * When a `<!--more-->` comment is found, we need to look for any 14453 * `<!--noteaser-->` sibling, but it may not be a direct sibling 14454 * (whitespace typically lies in between) 14455 */ 14456 let sibling = commentNode; 14457 let noTeaser = false; 14458 while (sibling = sibling.nextSibling) { 14459 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 14460 noTeaser = true; 14461 (0,external_wp_dom_namespaceObject.remove)(sibling); 14462 break; 14463 } 14464 } 14465 return createMore(customText, noTeaser, doc); 14466 } 14467 function createMore(customText, noTeaser, doc) { 14468 const node = doc.createElement('wp-block'); 14469 node.dataset.block = 'core/more'; 14470 if (customText) { 14471 node.dataset.customText = customText; 14472 } 14473 if (noTeaser) { 14474 // "Boolean" data attribute. 14475 node.dataset.noTeaser = ''; 14476 } 14477 return node; 14478 } 14479 function createNextpage(doc) { 14480 const node = doc.createElement('wp-block'); 14481 node.dataset.block = 'core/nextpage'; 14482 return node; 14483 } 14484 14485 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/list-reducer.js 14486 /** 14487 * WordPress dependencies 14488 */ 14489 14490 function isList(node) { 14491 return node.nodeName === 'OL' || node.nodeName === 'UL'; 14492 } 14493 function shallowTextContent(element) { 14494 return Array.from(element.childNodes).map(({ 14495 nodeValue = '' 14496 }) => nodeValue).join(''); 14497 } 14498 function listReducer(node) { 14499 if (!isList(node)) { 14500 return; 14501 } 14502 const list = node; 14503 const prevElement = node.previousElementSibling; 14504 14505 // Merge with previous list if: 14506 // * There is a previous list of the same type. 14507 // * There is only one list item. 14508 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 14509 // Move all child nodes, including any text nodes, if any. 14510 while (list.firstChild) { 14511 prevElement.appendChild(list.firstChild); 14512 } 14513 list.parentNode.removeChild(list); 14514 } 14515 const parentElement = node.parentNode; 14516 14517 // Nested list with empty parent item. 14518 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 14519 const parentListItem = parentElement; 14520 const prevListItem = parentListItem.previousElementSibling; 14521 const parentList = parentListItem.parentNode; 14522 if (prevListItem) { 14523 prevListItem.appendChild(list); 14524 parentList.removeChild(parentListItem); 14525 } 14526 } 14527 14528 // Invalid: OL/UL > OL/UL. 14529 if (parentElement && isList(parentElement)) { 14530 const prevListItem = node.previousElementSibling; 14531 if (prevListItem) { 14532 prevListItem.appendChild(node); 14533 } else { 14534 (0,external_wp_dom_namespaceObject.unwrap)(node); 14535 } 14536 } 14537 } 14538 14539 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/blockquote-normaliser.js 14540 /** 14541 * Internal dependencies 14542 */ 14543 14544 function blockquoteNormaliser(options) { 14545 return node => { 14546 if (node.nodeName !== 'BLOCKQUOTE') { 14547 return; 14548 } 14549 node.innerHTML = normaliseBlocks(node.innerHTML, options); 14550 }; 14551 } 14552 14553 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/figure-content-reducer.js 14554 /** 14555 * WordPress dependencies 14556 */ 14557 14558 14559 /** 14560 * Whether or not the given node is figure content. 14561 * 14562 * @param {Node} node The node to check. 14563 * @param {Object} schema The schema to use. 14564 * 14565 * @return {boolean} True if figure content, false if not. 14566 */ 14567 function isFigureContent(node, schema) { 14568 var _schema$figure$childr; 14569 const tag = node.nodeName.toLowerCase(); 14570 14571 // We are looking for tags that can be a child of the figure tag, excluding 14572 // `figcaption` and any phrasing content. 14573 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14574 return false; 14575 } 14576 return tag in ((_schema$figure$childr = schema?.figure?.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {}); 14577 } 14578 14579 /** 14580 * Whether or not the given node can have an anchor. 14581 * 14582 * @param {Node} node The node to check. 14583 * @param {Object} schema The schema to use. 14584 * 14585 * @return {boolean} True if it can, false if not. 14586 */ 14587 function canHaveAnchor(node, schema) { 14588 var _schema$figure$childr2; 14589 const tag = node.nodeName.toLowerCase(); 14590 return tag in ((_schema$figure$childr2 = schema?.figure?.children?.a?.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {}); 14591 } 14592 14593 /** 14594 * Wraps the given element in a figure element. 14595 * 14596 * @param {Element} element The element to wrap. 14597 * @param {Element} beforeElement The element before which to place the figure. 14598 */ 14599 function wrapFigureContent(element, beforeElement = element) { 14600 const figure = element.ownerDocument.createElement('figure'); 14601 beforeElement.parentNode.insertBefore(figure, beforeElement); 14602 figure.appendChild(element); 14603 } 14604 14605 /** 14606 * This filter takes figure content out of paragraphs, wraps it in a figure 14607 * element, and moves any anchors with it if needed. 14608 * 14609 * @param {Node} node The node to filter. 14610 * @param {Document} doc The document of the node. 14611 * @param {Object} schema The schema to use. 14612 * 14613 * @return {void} 14614 */ 14615 function figureContentReducer(node, doc, schema) { 14616 if (!isFigureContent(node, schema)) { 14617 return; 14618 } 14619 let nodeToInsert = node; 14620 const parentNode = node.parentNode; 14621 14622 // If the figure content can have an anchor and its parent is an anchor with 14623 // only the figure content, take the anchor out instead of just the content. 14624 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 14625 nodeToInsert = node.parentNode; 14626 } 14627 const wrapper = nodeToInsert.closest('p,div'); 14628 14629 // If wrapped in a paragraph or div, only extract if it's aligned or if 14630 // there is no text content. 14631 // Otherwise, if directly at the root, wrap in a figure element. 14632 if (wrapper) { 14633 // In jsdom-jscore, 'node.classList' can be undefined. 14634 // In this case, default to extract as it offers a better UI experience on mobile. 14635 if (!node.classList) { 14636 wrapFigureContent(nodeToInsert, wrapper); 14637 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 14638 wrapFigureContent(nodeToInsert, wrapper); 14639 } 14640 } else { 14641 wrapFigureContent(nodeToInsert); 14642 } 14643 } 14644 14645 ;// external ["wp","shortcode"] 14646 const external_wp_shortcode_namespaceObject = window["wp"]["shortcode"]; 14647 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/shortcode-converter.js 14648 /** 14649 * WordPress dependencies 14650 */ 14651 14652 14653 /** 14654 * Internal dependencies 14655 */ 14656 14657 14658 14659 14660 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14661 const beforeLineRegexp = /(\n|<p>)\s*$/; 14662 const afterLineRegexp = /^\s*(\n|<\/p>)/; 14663 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) { 14664 // Get all matches. 14665 const transformsFrom = getBlockTransforms('from'); 14666 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))); 14667 if (!transformation) { 14668 return [HTML]; 14669 } 14670 const transformTags = castArray(transformation.tag); 14671 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)); 14672 let match; 14673 const previousIndex = lastIndex; 14674 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) { 14675 lastIndex = match.index + match.content.length; 14676 const beforeHTML = HTML.substr(0, match.index); 14677 const afterHTML = HTML.substr(lastIndex); 14678 14679 // If the shortcode content does not contain HTML and the shortcode is 14680 // not on a new line (or in paragraph from Markdown converter), 14681 // consider the shortcode as inline text, and thus skip conversion for 14682 // this segment. 14683 if (!match.shortcode.content?.includes('<') && !(beforeLineRegexp.test(beforeHTML) && afterLineRegexp.test(afterHTML))) { 14684 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 14685 } 14686 14687 // If a transformation's `isMatch` predicate fails for the inbound 14688 // shortcode, try again by excluding the current block type. 14689 // 14690 // This is the only call to `segmentHTMLToShortcodeBlock` that should 14691 // ever carry over `excludedBlockNames`. Other calls in the module 14692 // should skip that argument as a way to reset the exclusion state, so 14693 // that one `isMatch` fail in an HTML fragment doesn't prevent any 14694 // valid matches in subsequent fragments. 14695 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 14696 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 14697 } 14698 let blocks = []; 14699 if (typeof transformation.transform === 'function') { 14700 // Passing all of `match` as second argument is intentionally broad 14701 // but shouldn't be too relied upon. 14702 // 14703 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14704 blocks = [].concat(transformation.transform(match.shortcode.attrs, match)); 14705 14706 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14707 blocks = blocks.map(block => { 14708 block.originalContent = match.shortcode.content; 14709 return applyBuiltInValidationFixes(block, getBlockType(block.name)); 14710 }); 14711 } else { 14712 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(([, schema]) => schema.shortcode) 14713 // Passing all of `match` as second argument is intentionally broad 14714 // but shouldn't be too relied upon. 14715 // 14716 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14717 .map(([key, schema]) => [key, schema.shortcode(match.shortcode.attrs, match)])); 14718 const blockType = getBlockType(transformation.blockName); 14719 if (!blockType) { 14720 return [HTML]; 14721 } 14722 const transformationBlockType = { 14723 ...blockType, 14724 attributes: transformation.attributes 14725 }; 14726 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); 14727 14728 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14729 block.originalContent = match.shortcode.content; 14730 block = applyBuiltInValidationFixes(block, transformationBlockType); 14731 blocks = [block]; 14732 } 14733 return [...segmentHTMLToShortcodeBlock(beforeHTML.replace(beforeLineRegexp, '')), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML.replace(afterLineRegexp, ''))]; 14734 } 14735 return [HTML]; 14736 } 14737 /* harmony default export */ const shortcode_converter = (segmentHTMLToShortcodeBlock); 14738 14739 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/utils.js 14740 /** 14741 * WordPress dependencies 14742 */ 14743 14744 14745 /** 14746 * Internal dependencies 14747 */ 14748 14749 14750 function getBlockContentSchemaFromTransforms(transforms, context) { 14751 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14752 const schemaArgs = { 14753 phrasingContentSchema, 14754 isPaste: context === 'paste' 14755 }; 14756 const schemas = transforms.map(({ 14757 isMatch, 14758 blockName, 14759 schema 14760 }) => { 14761 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor'); 14762 schema = typeof schema === 'function' ? schema(schemaArgs) : schema; 14763 14764 // If the block does not has anchor support and the transform does not 14765 // provides an isMatch we can return the schema right away. 14766 if (!hasAnchorSupport && !isMatch) { 14767 return schema; 14768 } 14769 if (!schema) { 14770 return {}; 14771 } 14772 return Object.fromEntries(Object.entries(schema).map(([key, value]) => { 14773 let attributes = value.attributes || []; 14774 // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 14775 if (hasAnchorSupport) { 14776 attributes = [...attributes, 'id']; 14777 } 14778 return [key, { 14779 ...value, 14780 attributes, 14781 isMatch: isMatch ? isMatch : undefined 14782 }]; 14783 })); 14784 }); 14785 function mergeTagNameSchemaProperties(objValue, srcValue, key) { 14786 switch (key) { 14787 case 'children': 14788 { 14789 if (objValue === '*' || srcValue === '*') { 14790 return '*'; 14791 } 14792 return { 14793 ...objValue, 14794 ...srcValue 14795 }; 14796 } 14797 case 'attributes': 14798 case 'require': 14799 { 14800 return [...(objValue || []), ...(srcValue || [])]; 14801 } 14802 case 'isMatch': 14803 { 14804 // If one of the values being merge is undefined (matches everything), 14805 // the result of the merge will be undefined. 14806 if (!objValue || !srcValue) { 14807 return undefined; 14808 } 14809 // When merging two isMatch functions, the result is a new function 14810 // that returns if one of the source functions returns true. 14811 return (...args) => { 14812 return objValue(...args) || srcValue(...args); 14813 }; 14814 } 14815 } 14816 } 14817 14818 // A tagName schema is an object with children, attributes, require, and 14819 // isMatch properties. 14820 function mergeTagNameSchemas(a, b) { 14821 for (const key in b) { 14822 a[key] = a[key] ? mergeTagNameSchemaProperties(a[key], b[key], key) : { 14823 ...b[key] 14824 }; 14825 } 14826 return a; 14827 } 14828 14829 // A schema is an object with tagName schemas by tag name. 14830 function mergeSchemas(a, b) { 14831 for (const key in b) { 14832 a[key] = a[key] ? mergeTagNameSchemas(a[key], b[key]) : { 14833 ...b[key] 14834 }; 14835 } 14836 return a; 14837 } 14838 return schemas.reduce(mergeSchemas, {}); 14839 } 14840 14841 /** 14842 * Gets the block content schema, which is extracted and merged from all 14843 * registered blocks with raw transforms. 14844 * 14845 * @param {string} context Set to "paste" when in paste context, where the 14846 * schema is more strict. 14847 * 14848 * @return {Object} A complete block content schema. 14849 */ 14850 function getBlockContentSchema(context) { 14851 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 14852 } 14853 14854 /** 14855 * Checks whether HTML can be considered plain text. That is, it does not contain 14856 * any elements that are not line breaks. 14857 * 14858 * @param {string} HTML The HTML to check. 14859 * 14860 * @return {boolean} Whether the HTML can be considered plain text. 14861 */ 14862 function isPlain(HTML) { 14863 return !/<(?!br[ />])/i.test(HTML); 14864 } 14865 14866 /** 14867 * Given node filters, deeply filters and mutates a NodeList. 14868 * 14869 * @param {NodeList} nodeList The nodeList to filter. 14870 * @param {Array} filters An array of functions that can mutate with the provided node. 14871 * @param {Document} doc The document of the nodeList. 14872 * @param {Object} schema The schema to use. 14873 */ 14874 function deepFilterNodeList(nodeList, filters, doc, schema) { 14875 Array.from(nodeList).forEach(node => { 14876 deepFilterNodeList(node.childNodes, filters, doc, schema); 14877 filters.forEach(item => { 14878 // Make sure the node is still attached to the document. 14879 if (!doc.contains(node)) { 14880 return; 14881 } 14882 item(node, doc, schema); 14883 }); 14884 }); 14885 } 14886 14887 /** 14888 * Given node filters, deeply filters HTML tags. 14889 * Filters from the deepest nodes to the top. 14890 * 14891 * @param {string} HTML The HTML to filter. 14892 * @param {Array} filters An array of functions that can mutate with the provided node. 14893 * @param {Object} schema The schema to use. 14894 * 14895 * @return {string} The filtered HTML. 14896 */ 14897 function deepFilterHTML(HTML, filters = [], schema) { 14898 const doc = document.implementation.createHTMLDocument(''); 14899 doc.body.innerHTML = HTML; 14900 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 14901 return doc.body.innerHTML; 14902 } 14903 14904 /** 14905 * Gets a sibling within text-level context. 14906 * 14907 * @param {Element} node The subject node. 14908 * @param {string} which "next" or "previous". 14909 */ 14910 function getSibling(node, which) { 14911 const sibling = node[`$which}Sibling`]; 14912 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) { 14913 return sibling; 14914 } 14915 const { 14916 parentNode 14917 } = node; 14918 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) { 14919 return; 14920 } 14921 return getSibling(parentNode, which); 14922 } 14923 14924 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/index.js 14925 /** 14926 * WordPress dependencies 14927 */ 14928 14929 14930 14931 /** 14932 * Internal dependencies 14933 */ 14934 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 function deprecatedGetPhrasingContentSchema(context) { 14945 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 14946 since: '5.6', 14947 alternative: 'wp.dom.getPhrasingContentSchema' 14948 }); 14949 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14950 } 14951 14952 /** 14953 * Converts an HTML string to known blocks. 14954 * 14955 * @param {Object} $1 14956 * @param {string} $1.HTML The HTML to convert. 14957 * 14958 * @return {Array} A list of blocks. 14959 */ 14960 function rawHandler({ 14961 HTML = '' 14962 }) { 14963 // If we detect block delimiters, parse entirely as blocks. 14964 if (HTML.indexOf('<!-- wp:') !== -1) { 14965 const parseResult = parser_parse(HTML); 14966 const isSingleFreeFormBlock = parseResult.length === 1 && parseResult[0].name === 'core/freeform'; 14967 if (!isSingleFreeFormBlock) { 14968 return parseResult; 14969 } 14970 } 14971 14972 // An array of HTML strings and block objects. The blocks replace matched 14973 // shortcodes. 14974 const pieces = shortcode_converter(HTML); 14975 const blockContentSchema = getBlockContentSchema(); 14976 return pieces.map(piece => { 14977 // Already a block from shortcode. 14978 if (typeof piece !== 'string') { 14979 return piece; 14980 } 14981 14982 // These filters are essential for some blocks to be able to transform 14983 // from raw HTML. These filters move around some content or add 14984 // additional tags, they do not remove any content. 14985 const filters = [ 14986 // Needed to adjust invalid lists. 14987 listReducer, 14988 // Needed to create more and nextpage blocks. 14989 specialCommentConverter, 14990 // Needed to create media blocks. 14991 figureContentReducer, 14992 // Needed to create the quote block, which cannot handle text 14993 // without wrapper paragraphs. 14994 blockquoteNormaliser({ 14995 raw: true 14996 })]; 14997 piece = deepFilterHTML(piece, filters, blockContentSchema); 14998 piece = normaliseBlocks(piece, { 14999 raw: true 15000 }); 15001 return htmlToBlocks(piece, rawHandler); 15002 }).flat().filter(Boolean); 15003 } 15004 15005 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js 15006 /** 15007 * WordPress dependencies 15008 */ 15009 15010 15011 /** 15012 * Looks for comments, and removes them. 15013 * 15014 * @param {Node} node The node to be processed. 15015 * @return {void} 15016 */ 15017 function commentRemover(node) { 15018 if (node.nodeType === node.COMMENT_NODE) { 15019 (0,external_wp_dom_namespaceObject.remove)(node); 15020 } 15021 } 15022 15023 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js 15024 /** 15025 * WordPress dependencies 15026 */ 15027 15028 15029 /** 15030 * Checks if the given node should be considered inline content, optionally 15031 * depending on a context tag. 15032 * 15033 * @param {Node} node Node name. 15034 * @param {string} contextTag Tag name. 15035 * 15036 * @return {boolean} True if the node is inline content, false if nohe. 15037 */ 15038 function isInline(node, contextTag) { 15039 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) { 15040 return true; 15041 } 15042 if (!contextTag) { 15043 return false; 15044 } 15045 const tag = node.nodeName.toLowerCase(); 15046 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 15047 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0); 15048 } 15049 function deepCheck(nodes, contextTag) { 15050 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 15051 } 15052 function isDoubleBR(node) { 15053 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 15054 } 15055 function isInlineContent(HTML, contextTag) { 15056 const doc = document.implementation.createHTMLDocument(''); 15057 doc.body.innerHTML = HTML; 15058 const nodes = Array.from(doc.body.children); 15059 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 15060 } 15061 15062 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 15063 /** 15064 * WordPress dependencies 15065 */ 15066 15067 function phrasingContentReducer(node, doc) { 15068 // In jsdom-jscore, 'node.style' can be null. 15069 // TODO: Explore fixing this by patching jsdom-jscore. 15070 if (node.nodeName === 'SPAN' && node.style) { 15071 const { 15072 fontWeight, 15073 fontStyle, 15074 textDecorationLine, 15075 textDecoration, 15076 verticalAlign 15077 } = node.style; 15078 if (fontWeight === 'bold' || fontWeight === '700') { 15079 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node); 15080 } 15081 if (fontStyle === 'italic') { 15082 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node); 15083 } 15084 15085 // Some DOM implementations (Safari, JSDom) don't support 15086 // style.textDecorationLine, so we check style.textDecoration as a 15087 // fallback. 15088 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) { 15089 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node); 15090 } 15091 if (verticalAlign === 'super') { 15092 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node); 15093 } else if (verticalAlign === 'sub') { 15094 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node); 15095 } 15096 } else if (node.nodeName === 'B') { 15097 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong'); 15098 } else if (node.nodeName === 'I') { 15099 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em'); 15100 } else if (node.nodeName === 'A') { 15101 // In jsdom-jscore, 'node.target' can be null. 15102 // TODO: Explore fixing this by patching jsdom-jscore. 15103 if (node.target && node.target.toLowerCase() === '_blank') { 15104 node.rel = 'noreferrer noopener'; 15105 } else { 15106 node.removeAttribute('target'); 15107 node.removeAttribute('rel'); 15108 } 15109 15110 // Saves anchor elements name attribute as id 15111 if (node.name && !node.id) { 15112 node.id = node.name; 15113 } 15114 15115 // Keeps id only if there is an internal link pointing to it 15116 if (node.id && !node.ownerDocument.querySelector(`[href="#$node.id}"]`)) { 15117 node.removeAttribute('id'); 15118 } 15119 } 15120 } 15121 15122 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js 15123 function headRemover(node) { 15124 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 15125 return; 15126 } 15127 node.parentNode.removeChild(node); 15128 } 15129 15130 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-ignore.js 15131 /** 15132 * Looks for comments, and removes them. 15133 * 15134 * @param {Node} node The node to be processed. 15135 * @return {void} 15136 */ 15137 function msListIgnore(node) { 15138 if (node.nodeType !== node.ELEMENT_NODE) { 15139 return; 15140 } 15141 const style = node.getAttribute('style'); 15142 if (!style || !style.includes('mso-list')) { 15143 return; 15144 } 15145 const rules = style.split(';').reduce((acc, rule) => { 15146 const [key, value] = rule.split(':'); 15147 if (key && value) { 15148 acc[key.trim().toLowerCase()] = value.trim().toLowerCase(); 15149 } 15150 return acc; 15151 }, {}); 15152 if (rules['mso-list'] === 'ignore') { 15153 node.remove(); 15154 } 15155 } 15156 15157 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js 15158 /** 15159 * Internal dependencies 15160 */ 15161 15162 15163 function ms_list_converter_isList(node) { 15164 return node.nodeName === 'OL' || node.nodeName === 'UL'; 15165 } 15166 function msListConverter(node, doc) { 15167 if (node.nodeName !== 'P') { 15168 return; 15169 } 15170 const style = node.getAttribute('style'); 15171 if (!style || !style.includes('mso-list')) { 15172 return; 15173 } 15174 const prevNode = node.previousElementSibling; 15175 15176 // Add new list if no previous. 15177 if (!prevNode || !ms_list_converter_isList(prevNode)) { 15178 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 15179 const type = node.textContent.trim().slice(0, 1); 15180 const isNumeric = /[1iIaA]/.test(type); 15181 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 15182 if (isNumeric) { 15183 newListNode.setAttribute('type', type); 15184 } 15185 node.parentNode.insertBefore(newListNode, node); 15186 } 15187 const listNode = node.previousElementSibling; 15188 const listType = listNode.nodeName; 15189 const listItem = doc.createElement('li'); 15190 let receivingNode = listNode; 15191 15192 // Add content. 15193 listItem.innerHTML = deepFilterHTML(node.innerHTML, [msListIgnore]); 15194 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 15195 let level = matches ? parseInt(matches[1], 10) - 1 || 0 : 0; 15196 15197 // Change pointer depending on indentation level. 15198 while (level--) { 15199 receivingNode = receivingNode.lastChild || receivingNode; 15200 15201 // If it's a list, move pointer to the last item. 15202 if (ms_list_converter_isList(receivingNode)) { 15203 receivingNode = receivingNode.lastChild || receivingNode; 15204 } 15205 } 15206 15207 // Make sure we append to a list. 15208 if (!ms_list_converter_isList(receivingNode)) { 15209 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 15210 } 15211 15212 // Append the list item to the list. 15213 receivingNode.appendChild(listItem); 15214 15215 // Remove the wrapper paragraph. 15216 node.parentNode.removeChild(node); 15217 } 15218 15219 ;// external ["wp","blob"] 15220 const external_wp_blob_namespaceObject = window["wp"]["blob"]; 15221 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/image-corrector.js 15222 /* wp:polyfill */ 15223 /** 15224 * WordPress dependencies 15225 */ 15226 15227 function imageCorrector(node) { 15228 if (node.nodeName !== 'IMG') { 15229 return; 15230 } 15231 if (node.src.indexOf('file:') === 0) { 15232 node.src = ''; 15233 } 15234 15235 // This piece cannot be tested outside a browser env. 15236 if (node.src.indexOf('data:') === 0) { 15237 const [properties, data] = node.src.split(','); 15238 const [type] = properties.slice(5).split(';'); 15239 if (!data || !type) { 15240 node.src = ''; 15241 return; 15242 } 15243 let decoded; 15244 15245 // Can throw DOMException! 15246 try { 15247 decoded = atob(data); 15248 } catch (e) { 15249 node.src = ''; 15250 return; 15251 } 15252 const uint8Array = new Uint8Array(decoded.length); 15253 for (let i = 0; i < uint8Array.length; i++) { 15254 uint8Array[i] = decoded.charCodeAt(i); 15255 } 15256 const name = type.replace('/', '.'); 15257 const file = new window.File([uint8Array], name, { 15258 type 15259 }); 15260 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 15261 } 15262 15263 // Remove trackers and hardly visible images. 15264 if (node.height === 1 || node.width === 1) { 15265 node.parentNode.removeChild(node); 15266 } 15267 } 15268 15269 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/div-normaliser.js 15270 /** 15271 * Internal dependencies 15272 */ 15273 15274 function divNormaliser(node) { 15275 if (node.nodeName !== 'DIV') { 15276 return; 15277 } 15278 node.innerHTML = normaliseBlocks(node.innerHTML); 15279 } 15280 15281 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 15282 var showdown = __webpack_require__(1030); 15283 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 15284 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/markdown-converter.js 15285 /** 15286 * External dependencies 15287 */ 15288 15289 15290 // Reuse the same showdown converter. 15291 const converter = new (showdown_default()).Converter({ 15292 noHeaderId: true, 15293 tables: true, 15294 literalMidWordUnderscores: true, 15295 omitExtraWLInCodeBlocks: true, 15296 simpleLineBreaks: true, 15297 strikethrough: true 15298 }); 15299 15300 /** 15301 * Corrects the Slack Markdown variant of the code block. 15302 * If uncorrected, it will be converted to inline code. 15303 * 15304 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks 15305 * 15306 * @param {string} text The potential Markdown text to correct. 15307 * 15308 * @return {string} The corrected Markdown. 15309 */ 15310 function slackMarkdownVariantCorrector(text) { 15311 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `$p1}\n$p2}\n$p3}`); 15312 } 15313 function bulletsToAsterisks(text) { 15314 return text.replace(/(^|\n)•( +)/g, '$1*$2'); 15315 } 15316 15317 /** 15318 * Converts a piece of text into HTML based on any Markdown present. 15319 * Also decodes any encoded HTML. 15320 * 15321 * @param {string} text The plain text to convert. 15322 * 15323 * @return {string} HTML. 15324 */ 15325 function markdownConverter(text) { 15326 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text))); 15327 } 15328 15329 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/iframe-remover.js 15330 /** 15331 * Removes iframes. 15332 * 15333 * @param {Node} node The node to check. 15334 * 15335 * @return {void} 15336 */ 15337 function iframeRemover(node) { 15338 if (node.nodeName === 'IFRAME') { 15339 const text = node.ownerDocument.createTextNode(node.src); 15340 node.parentNode.replaceChild(text, node); 15341 } 15342 } 15343 15344 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 15345 /** 15346 * WordPress dependencies 15347 */ 15348 15349 function googleDocsUIdRemover(node) { 15350 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 15351 return; 15352 } 15353 15354 // Google Docs sometimes wraps the content in a B tag. We don't want to keep 15355 // this. 15356 if (node.tagName === 'B') { 15357 (0,external_wp_dom_namespaceObject.unwrap)(node); 15358 } else { 15359 node.removeAttribute('id'); 15360 } 15361 } 15362 15363 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-formatting-remover.js 15364 /** 15365 * Internal dependencies 15366 */ 15367 15368 function isFormattingSpace(character) { 15369 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 15370 } 15371 15372 /** 15373 * Removes spacing that formats HTML. 15374 * 15375 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 15376 * 15377 * @param {Node} node The node to be processed. 15378 * @return {void} 15379 */ 15380 function htmlFormattingRemover(node) { 15381 if (node.nodeType !== node.TEXT_NODE) { 15382 return; 15383 } 15384 15385 // Ignore pre content. Note that this does not use Element#closest due to 15386 // a combination of (a) node may not be Element and (b) node.parentElement 15387 // does not have full support in all browsers (Internet Exporer). 15388 // 15389 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 15390 15391 /** @type {Node?} */ 15392 let parent = node; 15393 while (parent = parent.parentNode) { 15394 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 15395 return; 15396 } 15397 } 15398 15399 // First, replace any sequence of HTML formatting space with a single space. 15400 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); 15401 15402 // Remove the leading space if the text element is at the start of a block, 15403 // is preceded by a line break element, or has a space in the previous 15404 // node. 15405 if (newData[0] === ' ') { 15406 const previousSibling = getSibling(node, 'previous'); 15407 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 15408 newData = newData.slice(1); 15409 } 15410 } 15411 15412 // Remove the trailing space if the text element is at the end of a block, 15413 // is succeeded by a line break element, or has a space in the next text 15414 // node. 15415 if (newData[newData.length - 1] === ' ') { 15416 const nextSibling = getSibling(node, 'next'); 15417 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 15418 newData = newData.slice(0, -1); 15419 } 15420 } 15421 15422 // If there's no data left, remove the node, so `previousSibling` stays 15423 // accurate. Otherwise, update the node data. 15424 if (!newData) { 15425 node.parentNode.removeChild(node); 15426 } else { 15427 node.data = newData; 15428 } 15429 } 15430 15431 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/br-remover.js 15432 /** 15433 * Internal dependencies 15434 */ 15435 15436 15437 /** 15438 * Removes trailing br elements from text-level content. 15439 * 15440 * @param {Element} node Node to check. 15441 */ 15442 function brRemover(node) { 15443 if (node.nodeName !== 'BR') { 15444 return; 15445 } 15446 if (getSibling(node, 'next')) { 15447 return; 15448 } 15449 node.parentNode.removeChild(node); 15450 } 15451 15452 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 15453 /** 15454 * Removes empty paragraph elements. 15455 * 15456 * @param {Element} node Node to check. 15457 */ 15458 function emptyParagraphRemover(node) { 15459 if (node.nodeName !== 'P') { 15460 return; 15461 } 15462 if (node.hasChildNodes()) { 15463 return; 15464 } 15465 node.parentNode.removeChild(node); 15466 } 15467 15468 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js 15469 /** 15470 * Replaces Slack paragraph markup with a double line break (later converted to 15471 * a proper paragraph). 15472 * 15473 * @param {Element} node Node to check. 15474 */ 15475 function slackParagraphCorrector(node) { 15476 if (node.nodeName !== 'SPAN') { 15477 return; 15478 } 15479 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') { 15480 return; 15481 } 15482 const { 15483 parentNode 15484 } = node; 15485 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15486 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15487 parentNode.removeChild(node); 15488 } 15489 15490 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/paste-handler.js 15491 /** 15492 * WordPress dependencies 15493 */ 15494 15495 15496 /** 15497 * Internal dependencies 15498 */ 15499 15500 15501 15502 15503 15504 15505 15506 15507 15508 15509 15510 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 const log = (...args) => window?.console?.log?.(...args); 15526 15527 /** 15528 * Filters HTML to only contain phrasing content. 15529 * 15530 * @param {string} HTML The HTML to filter. 15531 * 15532 * @return {string} HTML only containing phrasing content. 15533 */ 15534 function filterInlineHTML(HTML) { 15535 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, msListIgnore, phrasingContentReducer, commentRemover]); 15536 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), { 15537 inline: true 15538 }); 15539 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 15540 15541 // Allows us to ask for this information when we get a report. 15542 log('Processed inline HTML:\n\n', HTML); 15543 return HTML; 15544 } 15545 15546 /** 15547 * Converts an HTML string to known blocks. Strips everything else. 15548 * 15549 * @param {Object} options 15550 * @param {string} [options.HTML] The HTML to convert. 15551 * @param {string} [options.plainText] Plain text version. 15552 * @param {string} [options.mode] Handle content as blocks or inline content. 15553 * * 'AUTO': Decide based on the content passed. 15554 * * 'INLINE': Always handle as inline content, and return string. 15555 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 15556 * @param {Array} [options.tagName] The tag into which content will be inserted. 15557 * 15558 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 15559 */ 15560 function pasteHandler({ 15561 HTML = '', 15562 plainText = '', 15563 mode = 'AUTO', 15564 tagName 15565 }) { 15566 // First of all, strip any meta tags. 15567 HTML = HTML.replace(/<meta[^>]+>/g, ''); 15568 // Strip Windows markers. 15569 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 15570 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); 15571 15572 // If we detect block delimiters in HTML, parse entirely as blocks. 15573 if (mode !== 'INLINE') { 15574 // Check plain text if there is no HTML. 15575 const content = HTML ? HTML : plainText; 15576 if (content.indexOf('<!-- wp:') !== -1) { 15577 const parseResult = parser_parse(content); 15578 const isSingleFreeFormBlock = parseResult.length === 1 && parseResult[0].name === 'core/freeform'; 15579 if (!isSingleFreeFormBlock) { 15580 return parseResult; 15581 } 15582 } 15583 } 15584 15585 // Normalize unicode to use composed characters. 15586 // Not normalizing the content will only affect older browsers and won't 15587 // entirely break the app. 15588 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 15589 // See: https://core.trac.wordpress.org/ticket/30130 15590 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 15591 if (String.prototype.normalize) { 15592 HTML = HTML.normalize(); 15593 } 15594 15595 // Must be run before checking if it's inline content. 15596 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]); 15597 15598 // Consider plain text if: 15599 // * There is a plain text version. 15600 // * There is no HTML version, or it has no formatting. 15601 const isPlainText = plainText && (!HTML || isPlain(HTML)); 15602 15603 // Parse Markdown (and encoded HTML) if it's considered plain text. 15604 if (isPlainText) { 15605 HTML = plainText; 15606 15607 // The markdown converter (Showdown) trims whitespace. 15608 if (!/^\s+$/.test(plainText)) { 15609 HTML = markdownConverter(HTML); 15610 } 15611 } 15612 15613 // An array of HTML strings and block objects. The blocks replace matched 15614 // shortcodes. 15615 const pieces = shortcode_converter(HTML); 15616 15617 // The call to shortcodeConverter will always return more than one element 15618 // if shortcodes are matched. The reason is when shortcodes are matched 15619 // empty HTML strings are included. 15620 const hasShortcodes = pieces.length > 1; 15621 if (isPlainText && !hasShortcodes) { 15622 // Switch to inline mode if: 15623 // * The current mode is AUTO. 15624 // * The original plain text had no line breaks. 15625 // * The original plain text was not an HTML paragraph. 15626 // * The converted text is just a paragraph. 15627 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 15628 mode = 'INLINE'; 15629 } 15630 } 15631 if (mode === 'INLINE') { 15632 return filterInlineHTML(HTML); 15633 } 15634 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 15635 return filterInlineHTML(HTML); 15636 } 15637 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'); 15638 const blockContentSchema = getBlockContentSchema('paste'); 15639 const blocks = pieces.map(piece => { 15640 // Already a block from shortcode. 15641 if (typeof piece !== 'string') { 15642 return piece; 15643 } 15644 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser(), divNormaliser]; 15645 const schema = { 15646 ...blockContentSchema, 15647 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 15648 ...phrasingContentSchema 15649 }; 15650 piece = deepFilterHTML(piece, filters, blockContentSchema); 15651 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema); 15652 piece = normaliseBlocks(piece); 15653 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); 15654 15655 // Allows us to ask for this information when we get a report. 15656 log('Processed HTML piece:\n\n', piece); 15657 return htmlToBlocks(piece, pasteHandler); 15658 }).flat().filter(Boolean); 15659 15660 // If we're allowed to return inline content, and there is only one 15661 // inlineable block, and the original plain text content does not have any 15662 // line breaks, then treat it as inline paste. 15663 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 15664 const trimRegex = /^[\n]+|[\n]+$/g; 15665 // Don't catch line breaks at the start or end. 15666 const trimmedPlainText = plainText.replace(trimRegex, ''); 15667 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 15668 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema).replace(trimRegex, ''); 15669 } 15670 } 15671 return blocks; 15672 } 15673 15674 ;// ./node_modules/@wordpress/blocks/build-module/api/categories.js 15675 /** 15676 * WordPress dependencies 15677 */ 15678 15679 15680 /** 15681 * Internal dependencies 15682 */ 15683 15684 15685 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 15686 15687 /** 15688 * Returns all the block categories. 15689 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 15690 * 15691 * @ignore 15692 * 15693 * @return {WPBlockCategory[]} Block categories. 15694 */ 15695 function categories_getCategories() { 15696 return (0,external_wp_data_namespaceObject.select)(store).getCategories(); 15697 } 15698 15699 /** 15700 * Sets the block categories. 15701 * 15702 * @param {WPBlockCategory[]} categories Block categories. 15703 * 15704 * @example 15705 * ```js 15706 * import { __ } from '@wordpress/i18n'; 15707 * import { store as blocksStore, setCategories } from '@wordpress/blocks'; 15708 * import { useSelect } from '@wordpress/data'; 15709 * import { Button } from '@wordpress/components'; 15710 * 15711 * const ExampleComponent = () => { 15712 * // Retrieve the list of current categories. 15713 * const blockCategories = useSelect( 15714 * ( select ) => select( blocksStore ).getCategories(), 15715 * [] 15716 * ); 15717 * 15718 * return ( 15719 * <Button 15720 * onClick={ () => { 15721 * // Add a custom category to the existing list. 15722 * setCategories( [ 15723 * ...blockCategories, 15724 * { title: 'Custom Category', slug: 'custom-category' }, 15725 * ] ); 15726 * } } 15727 * > 15728 * { __( 'Add a new custom block category' ) } 15729 * </Button> 15730 * ); 15731 * }; 15732 * ``` 15733 */ 15734 function categories_setCategories(categories) { 15735 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories); 15736 } 15737 15738 /** 15739 * Updates a category. 15740 * 15741 * @param {string} slug Block category slug. 15742 * @param {WPBlockCategory} category Object containing the category properties 15743 * that should be updated. 15744 * 15745 * @example 15746 * ```js 15747 * import { __ } from '@wordpress/i18n'; 15748 * import { updateCategory } from '@wordpress/blocks'; 15749 * import { Button } from '@wordpress/components'; 15750 * 15751 * const ExampleComponent = () => { 15752 * return ( 15753 * <Button 15754 * onClick={ () => { 15755 * updateCategory( 'text', { title: __( 'Written Word' ) } ); 15756 * } } 15757 * > 15758 * { __( 'Update Text category title' ) } 15759 * </Button> 15760 * ) ; 15761 * }; 15762 * ``` 15763 */ 15764 function categories_updateCategory(slug, category) { 15765 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category); 15766 } 15767 15768 ;// ./node_modules/@wordpress/blocks/build-module/api/templates.js 15769 /** 15770 * WordPress dependencies 15771 */ 15772 15773 15774 /** 15775 * Internal dependencies 15776 */ 15777 15778 15779 15780 15781 /** 15782 * Checks whether a list of blocks matches a template by comparing the block names. 15783 * 15784 * @param {Array} blocks Block list. 15785 * @param {Array} template Block template. 15786 * 15787 * @return {boolean} Whether the list of blocks matches a templates. 15788 */ 15789 function doBlocksMatchTemplate(blocks = [], template = []) { 15790 return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => { 15791 const block = blocks[index]; 15792 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 15793 }); 15794 } 15795 const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html'; 15796 const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query'; 15797 function normalizeAttributes(schema, values) { 15798 if (!values) { 15799 return {}; 15800 } 15801 return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)])); 15802 } 15803 function normalizeAttribute(definition, value) { 15804 if (isHTMLAttribute(definition) && Array.isArray(value)) { 15805 // Introduce a deprecated call at this point 15806 // When we're confident that "children" format should be removed from the templates. 15807 15808 return (0,external_wp_element_namespaceObject.renderToString)(value); 15809 } 15810 if (isQueryAttribute(definition) && value) { 15811 return value.map(subValues => { 15812 return normalizeAttributes(definition.query, subValues); 15813 }); 15814 } 15815 return value; 15816 } 15817 15818 /** 15819 * Synchronize a block list with a block template. 15820 * 15821 * Synchronizing a block list with a block template means that we loop over the blocks 15822 * keep the block as is if it matches the block at the same position in the template 15823 * (If it has the same name) and if doesn't match, we create a new block based on the template. 15824 * Extra blocks not present in the template are removed. 15825 * 15826 * @param {Array} blocks Block list. 15827 * @param {Array} template Block template. 15828 * 15829 * @return {Array} Updated Block list. 15830 */ 15831 function synchronizeBlocksWithTemplate(blocks = [], template) { 15832 // If no template is provided, return blocks unmodified. 15833 if (!template) { 15834 return blocks; 15835 } 15836 return template.map(([name, attributes, innerBlocksTemplate], index) => { 15837 var _blockType$attributes; 15838 const block = blocks[index]; 15839 if (block && block.name === name) { 15840 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 15841 return { 15842 ...block, 15843 innerBlocks 15844 }; 15845 } 15846 15847 // To support old templates that were using the "children" format 15848 // for the attributes using "html" strings now, we normalize the template attributes 15849 // before creating the blocks. 15850 15851 const blockType = getBlockType(name); 15852 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes); 15853 const [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); 15854 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 15855 }); 15856 } 15857 15858 ;// ./node_modules/@wordpress/blocks/build-module/api/index.js 15859 /** 15860 * Internal dependencies 15861 */ 15862 15863 15864 15865 // The blocktype is the most important concept within the block API. It defines 15866 // all aspects of the block configuration and its interfaces, including `edit` 15867 // and `save`. The transforms specification allows converting one blocktype to 15868 // another through formulas defined by either the source or the destination. 15869 // Switching a blocktype is to be considered a one-way operation implying a 15870 // transformation in the opposite way has to be handled explicitly. 15871 15872 15873 // The block tree is composed of a collection of block nodes. Blocks contained 15874 // within other blocks are called inner blocks. An important design 15875 // consideration is that inner blocks are -- conceptually -- not part of the 15876 // territory established by the parent block that contains them. 15877 // 15878 // This has multiple practical implications: when parsing, we can safely dispose 15879 // of any block boundary found within a block from the innerHTML property when 15880 // transferring to state. Not doing so would have a compounding effect on memory 15881 // and uncertainty over the source of truth. This can be illustrated in how, 15882 // given a tree of `n` nested blocks, the entry node would have to contain the 15883 // actual content of each block while each subsequent block node in the state 15884 // tree would replicate the entire chain `n-1`, meaning the extreme end node 15885 // would have been replicated `n` times as the tree is traversed and would 15886 // generate uncertainty as to which one is to hold the current value of the 15887 // block. For composition, it also means inner blocks can effectively be child 15888 // components whose mechanisms can be shielded from the `edit` implementation 15889 // and just passed along. 15890 15891 15892 15893 15894 // While block transformations account for a specific surface of the API, there 15895 // are also raw transformations which handle arbitrary sources not made out of 15896 // blocks but producing block basaed on various heuristics. This includes 15897 // pasting rich text or HTML data. 15898 15899 15900 // The process of serialization aims to deflate the internal memory of the block 15901 // editor and its state representation back into an HTML valid string. This 15902 // process restores the document integrity and inserts invisible delimiters 15903 // around each block with HTML comment boundaries which can contain any extra 15904 // attributes needed to operate with the block later on. 15905 15906 15907 // Validation is the process of comparing a block source with its output before 15908 // there is any user input or interaction with a block. When this operation 15909 // fails -- for whatever reason -- the block is to be considered invalid. As 15910 // part of validating a block the system will attempt to run the source against 15911 // any provided deprecation definitions. 15912 // 15913 // Worth emphasizing that validation is not a case of whether the markup is 15914 // merely HTML spec-compliant but about how the editor knows to create such 15915 // markup and that its inability to create an identical result can be a strong 15916 // indicator of potential data loss (the invalidation is then a protective 15917 // measure). 15918 // 15919 // The invalidation process can also be deconstructed in phases: 1) validate the 15920 // block exists; 2) validate the source matches the output; 3) validate the 15921 // source matches deprecated outputs; 4) work through the significance of 15922 // differences. These are stacked in a way that favors performance and optimizes 15923 // for the majority of cases. That is to say, the evaluation logic can become 15924 // more sophisticated the further down it goes in the process as the cost is 15925 // accounted for. The first logic checks have to be extremely efficient since 15926 // they will be run for all valid and invalid blocks alike. However, once a 15927 // block is detected as invalid -- failing the three first steps -- it is 15928 // adequate to spend more time determining validity before throwing a conflict. 15929 15930 15931 15932 // Blocks are inherently indifferent about where the data they operate with ends 15933 // up being saved. For example, all blocks can have a static and dynamic aspect 15934 // to them depending on the needs. The static nature of a block is the `save()` 15935 // definition that is meant to be serialized into HTML and which can be left 15936 // void. Any block can also register a `render_callback` on the server, which 15937 // makes its output dynamic either in part or in its totality. 15938 // 15939 // Child blocks are defined as a relationship that builds on top of the inner 15940 // blocks mechanism. A child block is a block node of a particular type that can 15941 // only exist within the inner block boundaries of a specific parent type. This 15942 // allows block authors to compose specific blocks that are not meant to be used 15943 // outside of a specified parent block context. Thus, child blocks extend the 15944 // concept of inner blocks to support a more direct relationship between sets of 15945 // blocks. The addition of parent–child would be a subset of the inner block 15946 // functionality under the premise that certain blocks only make sense as 15947 // children of another block. 15948 15949 15950 15951 // Templates are, in a general sense, a basic collection of block nodes with any 15952 // given set of predefined attributes that are supplied as the initial state of 15953 // an inner blocks group. These nodes can, in turn, contain any number of nested 15954 // blocks within their definition. Templates allow both to specify a default 15955 // state for an editor session or a default set of blocks for any inner block 15956 // implementation within a specific block. 15957 15958 15959 15960 15961 const privateApis = {}; 15962 lock(privateApis, { 15963 isContentBlock: isContentBlock 15964 }); 15965 15966 ;// ./node_modules/@wordpress/blocks/build-module/deprecated.js 15967 /** 15968 * WordPress dependencies 15969 */ 15970 15971 15972 /** 15973 * A Higher Order Component used to inject BlockContent using context to the 15974 * wrapped component. 15975 * 15976 * @deprecated 15977 * 15978 * @param {Component} OriginalComponent The component to enhance. 15979 * @return {Component} The same component. 15980 */ 15981 function withBlockContentContext(OriginalComponent) { 15982 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', { 15983 since: '6.1' 15984 }); 15985 return OriginalComponent; 15986 } 15987 15988 ;// ./node_modules/@wordpress/blocks/build-module/index.js 15989 // A "block" is the abstract term used to describe units of markup that, 15990 // when composed together, form the content or layout of a page. 15991 // The API for blocks is exposed via `wp.blocks`. 15992 // 15993 // Supported blocks are registered by calling `registerBlockType`. Once registered, 15994 // the block is made available as an option to the editor interface. 15995 // 15996 // Blocks are inferred from the HTML source of a post through a parsing mechanism 15997 // and then stored as objects in state, from which it is then rendered for editing. 15998 15999 16000 16001 16002 16003 })(); 16004 16005 (window.wp = window.wp || {}).blocks = __webpack_exports__; 16006 /******/ })() 16007 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Apr 3 08:20:01 2025 | Cross-referenced by PHPXref |