[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 7734: 5 /***/ ((module) => { 6 7 "use strict"; 8 9 10 // do not edit .js files directly - edit src/index.jst 11 12 13 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; 14 15 16 module.exports = function equal(a, b) { 17 if (a === b) return true; 18 19 if (a && b && typeof a == 'object' && typeof b == 'object') { 20 if (a.constructor !== b.constructor) return false; 21 22 var length, i, keys; 23 if (Array.isArray(a)) { 24 length = a.length; 25 if (length != b.length) return false; 26 for (i = length; i-- !== 0;) 27 if (!equal(a[i], b[i])) return false; 28 return true; 29 } 30 31 32 if ((a instanceof Map) && (b instanceof Map)) { 33 if (a.size !== b.size) return false; 34 for (i of a.entries()) 35 if (!b.has(i[0])) return false; 36 for (i of a.entries()) 37 if (!equal(i[1], b.get(i[0]))) return false; 38 return true; 39 } 40 41 if ((a instanceof Set) && (b instanceof Set)) { 42 if (a.size !== b.size) return false; 43 for (i of a.entries()) 44 if (!b.has(i[0])) return false; 45 return true; 46 } 47 48 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 49 length = a.length; 50 if (length != b.length) return false; 51 for (i = length; i-- !== 0;) 52 if (a[i] !== b[i]) return false; 53 return true; 54 } 55 56 57 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 58 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 59 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 60 61 keys = Object.keys(a); 62 length = keys.length; 63 if (length !== Object.keys(b).length) return false; 64 65 for (i = length; i-- !== 0;) 66 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 67 68 for (i = length; i-- !== 0;) { 69 var key = keys[i]; 70 71 if (!equal(a[key], b[key])) return false; 72 } 73 74 return true; 75 } 76 77 // true if both NaN, false otherwise 78 return a!==a && b!==b; 79 }; 80 81 82 /***/ }), 83 84 /***/ 5373: 85 /***/ ((__unused_webpack_module, exports) => { 86 87 "use strict"; 88 var __webpack_unused_export__; 89 /** 90 * @license React 91 * react-is.production.min.js 92 * 93 * Copyright (c) Facebook, Inc. and its affiliates. 94 * 95 * This source code is licensed under the MIT license found in the 96 * LICENSE file in the root directory of this source tree. 97 */ 98 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"); 99 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; 100 __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}; 101 __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}; 102 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; 103 104 105 /***/ }), 106 107 /***/ 8529: 108 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 109 110 "use strict"; 111 112 113 if (true) { 114 module.exports = __webpack_require__(5373); 115 } else {} 116 117 118 /***/ }), 119 120 /***/ 9681: 121 /***/ ((module) => { 122 123 var characterMap = { 124 "À": "A", 125 "Á": "A", 126 "Â": "A", 127 "Ã": "A", 128 "Ä": "A", 129 "Å": "A", 130 "Ấ": "A", 131 "Ắ": "A", 132 "Ẳ": "A", 133 "Ẵ": "A", 134 "Ặ": "A", 135 "Æ": "AE", 136 "Ầ": "A", 137 "Ằ": "A", 138 "Ȃ": "A", 139 "Ả": "A", 140 "Ạ": "A", 141 "Ẩ": "A", 142 "Ẫ": "A", 143 "Ậ": "A", 144 "Ç": "C", 145 "Ḉ": "C", 146 "È": "E", 147 "É": "E", 148 "Ê": "E", 149 "Ë": "E", 150 "Ế": "E", 151 "Ḗ": "E", 152 "Ề": "E", 153 "Ḕ": "E", 154 "Ḝ": "E", 155 "Ȇ": "E", 156 "Ẻ": "E", 157 "Ẽ": "E", 158 "Ẹ": "E", 159 "Ể": "E", 160 "Ễ": "E", 161 "Ệ": "E", 162 "Ì": "I", 163 "Í": "I", 164 "Î": "I", 165 "Ï": "I", 166 "Ḯ": "I", 167 "Ȋ": "I", 168 "Ỉ": "I", 169 "Ị": "I", 170 "Ð": "D", 171 "Ñ": "N", 172 "Ò": "O", 173 "Ó": "O", 174 "Ô": "O", 175 "Õ": "O", 176 "Ö": "O", 177 "Ø": "O", 178 "Ố": "O", 179 "Ṍ": "O", 180 "Ṓ": "O", 181 "Ȏ": "O", 182 "Ỏ": "O", 183 "Ọ": "O", 184 "Ổ": "O", 185 "Ỗ": "O", 186 "Ộ": "O", 187 "Ờ": "O", 188 "Ở": "O", 189 "Ỡ": "O", 190 "Ớ": "O", 191 "Ợ": "O", 192 "Ù": "U", 193 "Ú": "U", 194 "Û": "U", 195 "Ü": "U", 196 "Ủ": "U", 197 "Ụ": "U", 198 "Ử": "U", 199 "Ữ": "U", 200 "Ự": "U", 201 "Ý": "Y", 202 "à": "a", 203 "á": "a", 204 "â": "a", 205 "ã": "a", 206 "ä": "a", 207 "å": "a", 208 "ấ": "a", 209 "ắ": "a", 210 "ẳ": "a", 211 "ẵ": "a", 212 "ặ": "a", 213 "æ": "ae", 214 "ầ": "a", 215 "ằ": "a", 216 "ȃ": "a", 217 "ả": "a", 218 "ạ": "a", 219 "ẩ": "a", 220 "ẫ": "a", 221 "ậ": "a", 222 "ç": "c", 223 "ḉ": "c", 224 "è": "e", 225 "é": "e", 226 "ê": "e", 227 "ë": "e", 228 "ế": "e", 229 "ḗ": "e", 230 "ề": "e", 231 "ḕ": "e", 232 "ḝ": "e", 233 "ȇ": "e", 234 "ẻ": "e", 235 "ẽ": "e", 236 "ẹ": "e", 237 "ể": "e", 238 "ễ": "e", 239 "ệ": "e", 240 "ì": "i", 241 "í": "i", 242 "î": "i", 243 "ï": "i", 244 "ḯ": "i", 245 "ȋ": "i", 246 "ỉ": "i", 247 "ị": "i", 248 "ð": "d", 249 "ñ": "n", 250 "ò": "o", 251 "ó": "o", 252 "ô": "o", 253 "õ": "o", 254 "ö": "o", 255 "ø": "o", 256 "ố": "o", 257 "ṍ": "o", 258 "ṓ": "o", 259 "ȏ": "o", 260 "ỏ": "o", 261 "ọ": "o", 262 "ổ": "o", 263 "ỗ": "o", 264 "ộ": "o", 265 "ờ": "o", 266 "ở": "o", 267 "ỡ": "o", 268 "ớ": "o", 269 "ợ": "o", 270 "ù": "u", 271 "ú": "u", 272 "û": "u", 273 "ü": "u", 274 "ủ": "u", 275 "ụ": "u", 276 "ử": "u", 277 "ữ": "u", 278 "ự": "u", 279 "ý": "y", 280 "ÿ": "y", 281 "Ā": "A", 282 "ā": "a", 283 "Ă": "A", 284 "ă": "a", 285 "Ą": "A", 286 "ą": "a", 287 "Ć": "C", 288 "ć": "c", 289 "Ĉ": "C", 290 "ĉ": "c", 291 "Ċ": "C", 292 "ċ": "c", 293 "Č": "C", 294 "č": "c", 295 "C̆": "C", 296 "c̆": "c", 297 "Ď": "D", 298 "ď": "d", 299 "Đ": "D", 300 "đ": "d", 301 "Ē": "E", 302 "ē": "e", 303 "Ĕ": "E", 304 "ĕ": "e", 305 "Ė": "E", 306 "ė": "e", 307 "Ę": "E", 308 "ę": "e", 309 "Ě": "E", 310 "ě": "e", 311 "Ĝ": "G", 312 "Ǵ": "G", 313 "ĝ": "g", 314 "ǵ": "g", 315 "Ğ": "G", 316 "ğ": "g", 317 "Ġ": "G", 318 "ġ": "g", 319 "Ģ": "G", 320 "ģ": "g", 321 "Ĥ": "H", 322 "ĥ": "h", 323 "Ħ": "H", 324 "ħ": "h", 325 "Ḫ": "H", 326 "ḫ": "h", 327 "Ĩ": "I", 328 "ĩ": "i", 329 "Ī": "I", 330 "ī": "i", 331 "Ĭ": "I", 332 "ĭ": "i", 333 "Į": "I", 334 "į": "i", 335 "İ": "I", 336 "ı": "i", 337 "IJ": "IJ", 338 "ij": "ij", 339 "Ĵ": "J", 340 "ĵ": "j", 341 "Ķ": "K", 342 "ķ": "k", 343 "Ḱ": "K", 344 "ḱ": "k", 345 "K̆": "K", 346 "k̆": "k", 347 "Ĺ": "L", 348 "ĺ": "l", 349 "Ļ": "L", 350 "ļ": "l", 351 "Ľ": "L", 352 "ľ": "l", 353 "Ŀ": "L", 354 "ŀ": "l", 355 "Ł": "l", 356 "ł": "l", 357 "Ḿ": "M", 358 "ḿ": "m", 359 "M̆": "M", 360 "m̆": "m", 361 "Ń": "N", 362 "ń": "n", 363 "Ņ": "N", 364 "ņ": "n", 365 "Ň": "N", 366 "ň": "n", 367 "ʼn": "n", 368 "N̆": "N", 369 "n̆": "n", 370 "Ō": "O", 371 "ō": "o", 372 "Ŏ": "O", 373 "ŏ": "o", 374 "Ő": "O", 375 "ő": "o", 376 "Œ": "OE", 377 "œ": "oe", 378 "P̆": "P", 379 "p̆": "p", 380 "Ŕ": "R", 381 "ŕ": "r", 382 "Ŗ": "R", 383 "ŗ": "r", 384 "Ř": "R", 385 "ř": "r", 386 "R̆": "R", 387 "r̆": "r", 388 "Ȓ": "R", 389 "ȓ": "r", 390 "Ś": "S", 391 "ś": "s", 392 "Ŝ": "S", 393 "ŝ": "s", 394 "Ş": "S", 395 "Ș": "S", 396 "ș": "s", 397 "ş": "s", 398 "Š": "S", 399 "š": "s", 400 "Ţ": "T", 401 "ţ": "t", 402 "ț": "t", 403 "Ț": "T", 404 "Ť": "T", 405 "ť": "t", 406 "Ŧ": "T", 407 "ŧ": "t", 408 "T̆": "T", 409 "t̆": "t", 410 "Ũ": "U", 411 "ũ": "u", 412 "Ū": "U", 413 "ū": "u", 414 "Ŭ": "U", 415 "ŭ": "u", 416 "Ů": "U", 417 "ů": "u", 418 "Ű": "U", 419 "ű": "u", 420 "Ų": "U", 421 "ų": "u", 422 "Ȗ": "U", 423 "ȗ": "u", 424 "V̆": "V", 425 "v̆": "v", 426 "Ŵ": "W", 427 "ŵ": "w", 428 "Ẃ": "W", 429 "ẃ": "w", 430 "X̆": "X", 431 "x̆": "x", 432 "Ŷ": "Y", 433 "ŷ": "y", 434 "Ÿ": "Y", 435 "Y̆": "Y", 436 "y̆": "y", 437 "Ź": "Z", 438 "ź": "z", 439 "Ż": "Z", 440 "ż": "z", 441 "Ž": "Z", 442 "ž": "z", 443 "ſ": "s", 444 "ƒ": "f", 445 "Ơ": "O", 446 "ơ": "o", 447 "Ư": "U", 448 "ư": "u", 449 "Ǎ": "A", 450 "ǎ": "a", 451 "Ǐ": "I", 452 "ǐ": "i", 453 "Ǒ": "O", 454 "ǒ": "o", 455 "Ǔ": "U", 456 "ǔ": "u", 457 "Ǖ": "U", 458 "ǖ": "u", 459 "Ǘ": "U", 460 "ǘ": "u", 461 "Ǚ": "U", 462 "ǚ": "u", 463 "Ǜ": "U", 464 "ǜ": "u", 465 "Ứ": "U", 466 "ứ": "u", 467 "Ṹ": "U", 468 "ṹ": "u", 469 "Ǻ": "A", 470 "ǻ": "a", 471 "Ǽ": "AE", 472 "ǽ": "ae", 473 "Ǿ": "O", 474 "ǿ": "o", 475 "Þ": "TH", 476 "þ": "th", 477 "Ṕ": "P", 478 "ṕ": "p", 479 "Ṥ": "S", 480 "ṥ": "s", 481 "X́": "X", 482 "x́": "x", 483 "Ѓ": "Г", 484 "ѓ": "г", 485 "Ќ": "К", 486 "ќ": "к", 487 "A̋": "A", 488 "a̋": "a", 489 "E̋": "E", 490 "e̋": "e", 491 "I̋": "I", 492 "i̋": "i", 493 "Ǹ": "N", 494 "ǹ": "n", 495 "Ồ": "O", 496 "ồ": "o", 497 "Ṑ": "O", 498 "ṑ": "o", 499 "Ừ": "U", 500 "ừ": "u", 501 "Ẁ": "W", 502 "ẁ": "w", 503 "Ỳ": "Y", 504 "ỳ": "y", 505 "Ȁ": "A", 506 "ȁ": "a", 507 "Ȅ": "E", 508 "ȅ": "e", 509 "Ȉ": "I", 510 "ȉ": "i", 511 "Ȍ": "O", 512 "ȍ": "o", 513 "Ȑ": "R", 514 "ȑ": "r", 515 "Ȕ": "U", 516 "ȕ": "u", 517 "B̌": "B", 518 "b̌": "b", 519 "Č̣": "C", 520 "č̣": "c", 521 "Ê̌": "E", 522 "ê̌": "e", 523 "F̌": "F", 524 "f̌": "f", 525 "Ǧ": "G", 526 "ǧ": "g", 527 "Ȟ": "H", 528 "ȟ": "h", 529 "J̌": "J", 530 "ǰ": "j", 531 "Ǩ": "K", 532 "ǩ": "k", 533 "M̌": "M", 534 "m̌": "m", 535 "P̌": "P", 536 "p̌": "p", 537 "Q̌": "Q", 538 "q̌": "q", 539 "Ř̩": "R", 540 "ř̩": "r", 541 "Ṧ": "S", 542 "ṧ": "s", 543 "V̌": "V", 544 "v̌": "v", 545 "W̌": "W", 546 "w̌": "w", 547 "X̌": "X", 548 "x̌": "x", 549 "Y̌": "Y", 550 "y̌": "y", 551 "A̧": "A", 552 "a̧": "a", 553 "B̧": "B", 554 "b̧": "b", 555 "Ḑ": "D", 556 "ḑ": "d", 557 "Ȩ": "E", 558 "ȩ": "e", 559 "Ɛ̧": "E", 560 "ɛ̧": "e", 561 "Ḩ": "H", 562 "ḩ": "h", 563 "I̧": "I", 564 "i̧": "i", 565 "Ɨ̧": "I", 566 "ɨ̧": "i", 567 "M̧": "M", 568 "m̧": "m", 569 "O̧": "O", 570 "o̧": "o", 571 "Q̧": "Q", 572 "q̧": "q", 573 "U̧": "U", 574 "u̧": "u", 575 "X̧": "X", 576 "x̧": "x", 577 "Z̧": "Z", 578 "z̧": "z", 579 "й":"и", 580 "Й":"И", 581 "ё":"е", 582 "Ё":"Е", 583 }; 584 585 var chars = Object.keys(characterMap).join('|'); 586 var allAccents = new RegExp(chars, 'g'); 587 var firstAccent = new RegExp(chars, ''); 588 589 function matcher(match) { 590 return characterMap[match]; 591 } 592 593 var removeAccents = function(string) { 594 return string.replace(allAccents, matcher); 595 }; 596 597 var hasAccents = function(string) { 598 return !!string.match(firstAccent); 599 }; 600 601 module.exports = removeAccents; 602 module.exports.has = hasAccents; 603 module.exports.remove = removeAccents; 604 605 606 /***/ }), 607 608 /***/ 1030: 609 /***/ (function(module, exports, __webpack_require__) { 610 611 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */ 612 (function(){ 613 /** 614 * Created by Tivie on 13-07-2015. 615 */ 616 617 function getDefaultOpts (simple) { 618 'use strict'; 619 620 var defaultOptions = { 621 omitExtraWLInCodeBlocks: { 622 defaultValue: false, 623 describe: 'Omit the default extra whiteline added to code blocks', 624 type: 'boolean' 625 }, 626 noHeaderId: { 627 defaultValue: false, 628 describe: 'Turn on/off generated header id', 629 type: 'boolean' 630 }, 631 prefixHeaderId: { 632 defaultValue: false, 633 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', 634 type: 'string' 635 }, 636 rawPrefixHeaderId: { 637 defaultValue: false, 638 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)', 639 type: 'boolean' 640 }, 641 ghCompatibleHeaderId: { 642 defaultValue: false, 643 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)', 644 type: 'boolean' 645 }, 646 rawHeaderId: { 647 defaultValue: false, 648 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids', 649 type: 'boolean' 650 }, 651 headerLevelStart: { 652 defaultValue: false, 653 describe: 'The header blocks level start', 654 type: 'integer' 655 }, 656 parseImgDimensions: { 657 defaultValue: false, 658 describe: 'Turn on/off image dimension parsing', 659 type: 'boolean' 660 }, 661 simplifiedAutoLink: { 662 defaultValue: false, 663 describe: 'Turn on/off GFM autolink style', 664 type: 'boolean' 665 }, 666 excludeTrailingPunctuationFromURLs: { 667 defaultValue: false, 668 describe: 'Excludes trailing punctuation from links generated with autoLinking', 669 type: 'boolean' 670 }, 671 literalMidWordUnderscores: { 672 defaultValue: false, 673 describe: 'Parse midword underscores as literal underscores', 674 type: 'boolean' 675 }, 676 literalMidWordAsterisks: { 677 defaultValue: false, 678 describe: 'Parse midword asterisks as literal asterisks', 679 type: 'boolean' 680 }, 681 strikethrough: { 682 defaultValue: false, 683 describe: 'Turn on/off strikethrough support', 684 type: 'boolean' 685 }, 686 tables: { 687 defaultValue: false, 688 describe: 'Turn on/off tables support', 689 type: 'boolean' 690 }, 691 tablesHeaderId: { 692 defaultValue: false, 693 describe: 'Add an id to table headers', 694 type: 'boolean' 695 }, 696 ghCodeBlocks: { 697 defaultValue: true, 698 describe: 'Turn on/off GFM fenced code blocks support', 699 type: 'boolean' 700 }, 701 tasklists: { 702 defaultValue: false, 703 describe: 'Turn on/off GFM tasklist support', 704 type: 'boolean' 705 }, 706 smoothLivePreview: { 707 defaultValue: false, 708 describe: 'Prevents weird effects in live previews due to incomplete input', 709 type: 'boolean' 710 }, 711 smartIndentationFix: { 712 defaultValue: false, 713 description: 'Tries to smartly fix indentation in es6 strings', 714 type: 'boolean' 715 }, 716 disableForced4SpacesIndentedSublists: { 717 defaultValue: false, 718 description: 'Disables the requirement of indenting nested sublists by 4 spaces', 719 type: 'boolean' 720 }, 721 simpleLineBreaks: { 722 defaultValue: false, 723 description: 'Parses simple line breaks as <br> (GFM Style)', 724 type: 'boolean' 725 }, 726 requireSpaceBeforeHeadingText: { 727 defaultValue: false, 728 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)', 729 type: 'boolean' 730 }, 731 ghMentions: { 732 defaultValue: false, 733 description: 'Enables github @mentions', 734 type: 'boolean' 735 }, 736 ghMentionsLink: { 737 defaultValue: 'https://github.com/{u}', 738 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.', 739 type: 'string' 740 }, 741 encodeEmails: { 742 defaultValue: true, 743 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities', 744 type: 'boolean' 745 }, 746 openLinksInNewWindow: { 747 defaultValue: false, 748 description: 'Open all links in new windows', 749 type: 'boolean' 750 }, 751 backslashEscapesHTMLTags: { 752 defaultValue: false, 753 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>', 754 type: 'boolean' 755 }, 756 emoji: { 757 defaultValue: false, 758 description: 'Enable emoji support. Ex: `this is a :smile: emoji`', 759 type: 'boolean' 760 }, 761 underline: { 762 defaultValue: false, 763 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>`', 764 type: 'boolean' 765 }, 766 completeHTMLDocument: { 767 defaultValue: false, 768 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags', 769 type: 'boolean' 770 }, 771 metadata: { 772 defaultValue: false, 773 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).', 774 type: 'boolean' 775 }, 776 splitAdjacentBlockquotes: { 777 defaultValue: false, 778 description: 'Split adjacent blockquote blocks', 779 type: 'boolean' 780 } 781 }; 782 if (simple === false) { 783 return JSON.parse(JSON.stringify(defaultOptions)); 784 } 785 var ret = {}; 786 for (var opt in defaultOptions) { 787 if (defaultOptions.hasOwnProperty(opt)) { 788 ret[opt] = defaultOptions[opt].defaultValue; 789 } 790 } 791 return ret; 792 } 793 794 function allOptionsOn () { 795 'use strict'; 796 var options = getDefaultOpts(true), 797 ret = {}; 798 for (var opt in options) { 799 if (options.hasOwnProperty(opt)) { 800 ret[opt] = true; 801 } 802 } 803 return ret; 804 } 805 806 /** 807 * Created by Tivie on 06-01-2015. 808 */ 809 810 // Private properties 811 var showdown = {}, 812 parsers = {}, 813 extensions = {}, 814 globalOptions = getDefaultOpts(true), 815 setFlavor = 'vanilla', 816 flavor = { 817 github: { 818 omitExtraWLInCodeBlocks: true, 819 simplifiedAutoLink: true, 820 excludeTrailingPunctuationFromURLs: true, 821 literalMidWordUnderscores: true, 822 strikethrough: true, 823 tables: true, 824 tablesHeaderId: true, 825 ghCodeBlocks: true, 826 tasklists: true, 827 disableForced4SpacesIndentedSublists: true, 828 simpleLineBreaks: true, 829 requireSpaceBeforeHeadingText: true, 830 ghCompatibleHeaderId: true, 831 ghMentions: true, 832 backslashEscapesHTMLTags: true, 833 emoji: true, 834 splitAdjacentBlockquotes: true 835 }, 836 original: { 837 noHeaderId: true, 838 ghCodeBlocks: false 839 }, 840 ghost: { 841 omitExtraWLInCodeBlocks: true, 842 parseImgDimensions: true, 843 simplifiedAutoLink: true, 844 excludeTrailingPunctuationFromURLs: true, 845 literalMidWordUnderscores: true, 846 strikethrough: true, 847 tables: true, 848 tablesHeaderId: true, 849 ghCodeBlocks: true, 850 tasklists: true, 851 smoothLivePreview: true, 852 simpleLineBreaks: true, 853 requireSpaceBeforeHeadingText: true, 854 ghMentions: false, 855 encodeEmails: true 856 }, 857 vanilla: getDefaultOpts(true), 858 allOn: allOptionsOn() 859 }; 860 861 /** 862 * helper namespace 863 * @type {{}} 864 */ 865 showdown.helper = {}; 866 867 /** 868 * TODO LEGACY SUPPORT CODE 869 * @type {{}} 870 */ 871 showdown.extensions = {}; 872 873 /** 874 * Set a global option 875 * @static 876 * @param {string} key 877 * @param {*} value 878 * @returns {showdown} 879 */ 880 showdown.setOption = function (key, value) { 881 'use strict'; 882 globalOptions[key] = value; 883 return this; 884 }; 885 886 /** 887 * Get a global option 888 * @static 889 * @param {string} key 890 * @returns {*} 891 */ 892 showdown.getOption = function (key) { 893 'use strict'; 894 return globalOptions[key]; 895 }; 896 897 /** 898 * Get the global options 899 * @static 900 * @returns {{}} 901 */ 902 showdown.getOptions = function () { 903 'use strict'; 904 return globalOptions; 905 }; 906 907 /** 908 * Reset global options to the default values 909 * @static 910 */ 911 showdown.resetOptions = function () { 912 'use strict'; 913 globalOptions = getDefaultOpts(true); 914 }; 915 916 /** 917 * Set the flavor showdown should use as default 918 * @param {string} name 919 */ 920 showdown.setFlavor = function (name) { 921 'use strict'; 922 if (!flavor.hasOwnProperty(name)) { 923 throw Error(name + ' flavor was not found'); 924 } 925 showdown.resetOptions(); 926 var preset = flavor[name]; 927 setFlavor = name; 928 for (var option in preset) { 929 if (preset.hasOwnProperty(option)) { 930 globalOptions[option] = preset[option]; 931 } 932 } 933 }; 934 935 /** 936 * Get the currently set flavor 937 * @returns {string} 938 */ 939 showdown.getFlavor = function () { 940 'use strict'; 941 return setFlavor; 942 }; 943 944 /** 945 * Get the options of a specified flavor. Returns undefined if the flavor was not found 946 * @param {string} name Name of the flavor 947 * @returns {{}|undefined} 948 */ 949 showdown.getFlavorOptions = function (name) { 950 'use strict'; 951 if (flavor.hasOwnProperty(name)) { 952 return flavor[name]; 953 } 954 }; 955 956 /** 957 * Get the default options 958 * @static 959 * @param {boolean} [simple=true] 960 * @returns {{}} 961 */ 962 showdown.getDefaultOptions = function (simple) { 963 'use strict'; 964 return getDefaultOpts(simple); 965 }; 966 967 /** 968 * Get or set a subParser 969 * 970 * subParser(name) - Get a registered subParser 971 * subParser(name, func) - Register a subParser 972 * @static 973 * @param {string} name 974 * @param {function} [func] 975 * @returns {*} 976 */ 977 showdown.subParser = function (name, func) { 978 'use strict'; 979 if (showdown.helper.isString(name)) { 980 if (typeof func !== 'undefined') { 981 parsers[name] = func; 982 } else { 983 if (parsers.hasOwnProperty(name)) { 984 return parsers[name]; 985 } else { 986 throw Error('SubParser named ' + name + ' not registered!'); 987 } 988 } 989 } 990 }; 991 992 /** 993 * Gets or registers an extension 994 * @static 995 * @param {string} name 996 * @param {object|function=} ext 997 * @returns {*} 998 */ 999 showdown.extension = function (name, ext) { 1000 'use strict'; 1001 1002 if (!showdown.helper.isString(name)) { 1003 throw Error('Extension \'name\' must be a string'); 1004 } 1005 1006 name = showdown.helper.stdExtName(name); 1007 1008 // Getter 1009 if (showdown.helper.isUndefined(ext)) { 1010 if (!extensions.hasOwnProperty(name)) { 1011 throw Error('Extension named ' + name + ' is not registered!'); 1012 } 1013 return extensions[name]; 1014 1015 // Setter 1016 } else { 1017 // Expand extension if it's wrapped in a function 1018 if (typeof ext === 'function') { 1019 ext = ext(); 1020 } 1021 1022 // Ensure extension is an array 1023 if (!showdown.helper.isArray(ext)) { 1024 ext = [ext]; 1025 } 1026 1027 var validExtension = validate(ext, name); 1028 1029 if (validExtension.valid) { 1030 extensions[name] = ext; 1031 } else { 1032 throw Error(validExtension.error); 1033 } 1034 } 1035 }; 1036 1037 /** 1038 * Gets all extensions registered 1039 * @returns {{}} 1040 */ 1041 showdown.getAllExtensions = function () { 1042 'use strict'; 1043 return extensions; 1044 }; 1045 1046 /** 1047 * Remove an extension 1048 * @param {string} name 1049 */ 1050 showdown.removeExtension = function (name) { 1051 'use strict'; 1052 delete extensions[name]; 1053 }; 1054 1055 /** 1056 * Removes all extensions 1057 */ 1058 showdown.resetExtensions = function () { 1059 'use strict'; 1060 extensions = {}; 1061 }; 1062 1063 /** 1064 * Validate extension 1065 * @param {array} extension 1066 * @param {string} name 1067 * @returns {{valid: boolean, error: string}} 1068 */ 1069 function validate (extension, name) { 1070 'use strict'; 1071 1072 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', 1073 ret = { 1074 valid: true, 1075 error: '' 1076 }; 1077 1078 if (!showdown.helper.isArray(extension)) { 1079 extension = [extension]; 1080 } 1081 1082 for (var i = 0; i < extension.length; ++i) { 1083 var baseMsg = errMsg + ' sub-extension ' + i + ': ', 1084 ext = extension[i]; 1085 if (typeof ext !== 'object') { 1086 ret.valid = false; 1087 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; 1088 return ret; 1089 } 1090 1091 if (!showdown.helper.isString(ext.type)) { 1092 ret.valid = false; 1093 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; 1094 return ret; 1095 } 1096 1097 var type = ext.type = ext.type.toLowerCase(); 1098 1099 // normalize extension type 1100 if (type === 'language') { 1101 type = ext.type = 'lang'; 1102 } 1103 1104 if (type === 'html') { 1105 type = ext.type = 'output'; 1106 } 1107 1108 if (type !== 'lang' && type !== 'output' && type !== 'listener') { 1109 ret.valid = false; 1110 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; 1111 return ret; 1112 } 1113 1114 if (type === 'listener') { 1115 if (showdown.helper.isUndefined(ext.listeners)) { 1116 ret.valid = false; 1117 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; 1118 return ret; 1119 } 1120 } else { 1121 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { 1122 ret.valid = false; 1123 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; 1124 return ret; 1125 } 1126 } 1127 1128 if (ext.listeners) { 1129 if (typeof ext.listeners !== 'object') { 1130 ret.valid = false; 1131 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; 1132 return ret; 1133 } 1134 for (var ln in ext.listeners) { 1135 if (ext.listeners.hasOwnProperty(ln)) { 1136 if (typeof ext.listeners[ln] !== 'function') { 1137 ret.valid = false; 1138 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + 1139 ' must be a function but ' + typeof ext.listeners[ln] + ' given'; 1140 return ret; 1141 } 1142 } 1143 } 1144 } 1145 1146 if (ext.filter) { 1147 if (typeof ext.filter !== 'function') { 1148 ret.valid = false; 1149 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; 1150 return ret; 1151 } 1152 } else if (ext.regex) { 1153 if (showdown.helper.isString(ext.regex)) { 1154 ext.regex = new RegExp(ext.regex, 'g'); 1155 } 1156 if (!(ext.regex instanceof RegExp)) { 1157 ret.valid = false; 1158 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; 1159 return ret; 1160 } 1161 if (showdown.helper.isUndefined(ext.replace)) { 1162 ret.valid = false; 1163 ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; 1164 return ret; 1165 } 1166 } 1167 } 1168 return ret; 1169 } 1170 1171 /** 1172 * Validate extension 1173 * @param {object} ext 1174 * @returns {boolean} 1175 */ 1176 showdown.validateExtension = function (ext) { 1177 'use strict'; 1178 1179 var validateExtension = validate(ext, null); 1180 if (!validateExtension.valid) { 1181 console.warn(validateExtension.error); 1182 return false; 1183 } 1184 return true; 1185 }; 1186 1187 /** 1188 * showdownjs helper functions 1189 */ 1190 1191 if (!showdown.hasOwnProperty('helper')) { 1192 showdown.helper = {}; 1193 } 1194 1195 /** 1196 * Check if var is string 1197 * @static 1198 * @param {string} a 1199 * @returns {boolean} 1200 */ 1201 showdown.helper.isString = function (a) { 1202 'use strict'; 1203 return (typeof a === 'string' || a instanceof String); 1204 }; 1205 1206 /** 1207 * Check if var is a function 1208 * @static 1209 * @param {*} a 1210 * @returns {boolean} 1211 */ 1212 showdown.helper.isFunction = function (a) { 1213 'use strict'; 1214 var getType = {}; 1215 return a && getType.toString.call(a) === '[object Function]'; 1216 }; 1217 1218 /** 1219 * isArray helper function 1220 * @static 1221 * @param {*} a 1222 * @returns {boolean} 1223 */ 1224 showdown.helper.isArray = function (a) { 1225 'use strict'; 1226 return Array.isArray(a); 1227 }; 1228 1229 /** 1230 * Check if value is undefined 1231 * @static 1232 * @param {*} value The value to check. 1233 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. 1234 */ 1235 showdown.helper.isUndefined = function (value) { 1236 'use strict'; 1237 return typeof value === 'undefined'; 1238 }; 1239 1240 /** 1241 * ForEach helper function 1242 * Iterates over Arrays and Objects (own properties only) 1243 * @static 1244 * @param {*} obj 1245 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object 1246 */ 1247 showdown.helper.forEach = function (obj, callback) { 1248 'use strict'; 1249 // check if obj is defined 1250 if (showdown.helper.isUndefined(obj)) { 1251 throw new Error('obj param is required'); 1252 } 1253 1254 if (showdown.helper.isUndefined(callback)) { 1255 throw new Error('callback param is required'); 1256 } 1257 1258 if (!showdown.helper.isFunction(callback)) { 1259 throw new Error('callback param must be a function/closure'); 1260 } 1261 1262 if (typeof obj.forEach === 'function') { 1263 obj.forEach(callback); 1264 } else if (showdown.helper.isArray(obj)) { 1265 for (var i = 0; i < obj.length; i++) { 1266 callback(obj[i], i, obj); 1267 } 1268 } else if (typeof (obj) === 'object') { 1269 for (var prop in obj) { 1270 if (obj.hasOwnProperty(prop)) { 1271 callback(obj[prop], prop, obj); 1272 } 1273 } 1274 } else { 1275 throw new Error('obj does not seem to be an array or an iterable object'); 1276 } 1277 }; 1278 1279 /** 1280 * Standardidize extension name 1281 * @static 1282 * @param {string} s extension name 1283 * @returns {string} 1284 */ 1285 showdown.helper.stdExtName = function (s) { 1286 'use strict'; 1287 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase(); 1288 }; 1289 1290 function escapeCharactersCallback (wholeMatch, m1) { 1291 'use strict'; 1292 var charCodeToEscape = m1.charCodeAt(0); 1293 return '¨E' + charCodeToEscape + 'E'; 1294 } 1295 1296 /** 1297 * Callback used to escape characters when passing through String.replace 1298 * @static 1299 * @param {string} wholeMatch 1300 * @param {string} m1 1301 * @returns {string} 1302 */ 1303 showdown.helper.escapeCharactersCallback = escapeCharactersCallback; 1304 1305 /** 1306 * Escape characters in a string 1307 * @static 1308 * @param {string} text 1309 * @param {string} charsToEscape 1310 * @param {boolean} afterBackslash 1311 * @returns {XML|string|void|*} 1312 */ 1313 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) { 1314 'use strict'; 1315 // First we have to escape the escape characters so that 1316 // we can build a character class out of them 1317 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; 1318 1319 if (afterBackslash) { 1320 regexString = '\\\\' + regexString; 1321 } 1322 1323 var regex = new RegExp(regexString, 'g'); 1324 text = text.replace(regex, escapeCharactersCallback); 1325 1326 return text; 1327 }; 1328 1329 /** 1330 * Unescape HTML entities 1331 * @param txt 1332 * @returns {string} 1333 */ 1334 showdown.helper.unescapeHTMLEntities = function (txt) { 1335 'use strict'; 1336 1337 return txt 1338 .replace(/"/g, '"') 1339 .replace(/</g, '<') 1340 .replace(/>/g, '>') 1341 .replace(/&/g, '&'); 1342 }; 1343 1344 var rgxFindMatchPos = function (str, left, right, flags) { 1345 'use strict'; 1346 var f = flags || '', 1347 g = f.indexOf('g') > -1, 1348 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), 1349 l = new RegExp(left, f.replace(/g/g, '')), 1350 pos = [], 1351 t, s, m, start, end; 1352 1353 do { 1354 t = 0; 1355 while ((m = x.exec(str))) { 1356 if (l.test(m[0])) { 1357 if (!(t++)) { 1358 s = x.lastIndex; 1359 start = s - m[0].length; 1360 } 1361 } else if (t) { 1362 if (!--t) { 1363 end = m.index + m[0].length; 1364 var obj = { 1365 left: {start: start, end: s}, 1366 match: {start: s, end: m.index}, 1367 right: {start: m.index, end: end}, 1368 wholeMatch: {start: start, end: end} 1369 }; 1370 pos.push(obj); 1371 if (!g) { 1372 return pos; 1373 } 1374 } 1375 } 1376 } 1377 } while (t && (x.lastIndex = s)); 1378 1379 return pos; 1380 }; 1381 1382 /** 1383 * matchRecursiveRegExp 1384 * 1385 * (c) 2007 Steven Levithan <stevenlevithan.com> 1386 * MIT License 1387 * 1388 * Accepts a string to search, a left and right format delimiter 1389 * as regex patterns, and optional regex flags. Returns an array 1390 * of matches, allowing nested instances of left/right delimiters. 1391 * Use the "g" flag to return all matches, otherwise only the 1392 * first is returned. Be careful to ensure that the left and 1393 * right format delimiters produce mutually exclusive matches. 1394 * Backreferences are not supported within the right delimiter 1395 * due to how it is internally combined with the left delimiter. 1396 * When matching strings whose format delimiters are unbalanced 1397 * to the left or right, the output is intentionally as a 1398 * conventional regex library with recursion support would 1399 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using 1400 * "<" and ">" as the delimiters (both strings contain a single, 1401 * balanced instance of "<x>"). 1402 * 1403 * examples: 1404 * matchRecursiveRegExp("test", "\\(", "\\)") 1405 * returns: [] 1406 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") 1407 * returns: ["t<<e>><s>", ""] 1408 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") 1409 * returns: ["test"] 1410 */ 1411 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { 1412 'use strict'; 1413 1414 var matchPos = rgxFindMatchPos (str, left, right, flags), 1415 results = []; 1416 1417 for (var i = 0; i < matchPos.length; ++i) { 1418 results.push([ 1419 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1420 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1421 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1422 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1423 ]); 1424 } 1425 return results; 1426 }; 1427 1428 /** 1429 * 1430 * @param {string} str 1431 * @param {string|function} replacement 1432 * @param {string} left 1433 * @param {string} right 1434 * @param {string} flags 1435 * @returns {string} 1436 */ 1437 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { 1438 'use strict'; 1439 1440 if (!showdown.helper.isFunction(replacement)) { 1441 var repStr = replacement; 1442 replacement = function () { 1443 return repStr; 1444 }; 1445 } 1446 1447 var matchPos = rgxFindMatchPos(str, left, right, flags), 1448 finalStr = str, 1449 lng = matchPos.length; 1450 1451 if (lng > 0) { 1452 var bits = []; 1453 if (matchPos[0].wholeMatch.start !== 0) { 1454 bits.push(str.slice(0, matchPos[0].wholeMatch.start)); 1455 } 1456 for (var i = 0; i < lng; ++i) { 1457 bits.push( 1458 replacement( 1459 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1460 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1461 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1462 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1463 ) 1464 ); 1465 if (i < lng - 1) { 1466 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); 1467 } 1468 } 1469 if (matchPos[lng - 1].wholeMatch.end < str.length) { 1470 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); 1471 } 1472 finalStr = bits.join(''); 1473 } 1474 return finalStr; 1475 }; 1476 1477 /** 1478 * Returns the index within the passed String object of the first occurrence of the specified regex, 1479 * starting the search at fromIndex. Returns -1 if the value is not found. 1480 * 1481 * @param {string} str string to search 1482 * @param {RegExp} regex Regular expression to search 1483 * @param {int} [fromIndex = 0] Index to start the search 1484 * @returns {Number} 1485 * @throws InvalidArgumentError 1486 */ 1487 showdown.helper.regexIndexOf = function (str, regex, fromIndex) { 1488 'use strict'; 1489 if (!showdown.helper.isString(str)) { 1490 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1491 } 1492 if (regex instanceof RegExp === false) { 1493 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp'; 1494 } 1495 var indexOf = str.substring(fromIndex || 0).search(regex); 1496 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf; 1497 }; 1498 1499 /** 1500 * Splits the passed string object at the defined index, and returns an array composed of the two substrings 1501 * @param {string} str string to split 1502 * @param {int} index index to split string at 1503 * @returns {[string,string]} 1504 * @throws InvalidArgumentError 1505 */ 1506 showdown.helper.splitAtIndex = function (str, index) { 1507 'use strict'; 1508 if (!showdown.helper.isString(str)) { 1509 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1510 } 1511 return [str.substring(0, index), str.substring(index)]; 1512 }; 1513 1514 /** 1515 * Obfuscate an e-mail address through the use of Character Entities, 1516 * transforming ASCII characters into their equivalent decimal or hex entities. 1517 * 1518 * Since it has a random component, subsequent calls to this function produce different results 1519 * 1520 * @param {string} mail 1521 * @returns {string} 1522 */ 1523 showdown.helper.encodeEmailAddress = function (mail) { 1524 'use strict'; 1525 var encode = [ 1526 function (ch) { 1527 return '&#' + ch.charCodeAt(0) + ';'; 1528 }, 1529 function (ch) { 1530 return '&#x' + ch.charCodeAt(0).toString(16) + ';'; 1531 }, 1532 function (ch) { 1533 return ch; 1534 } 1535 ]; 1536 1537 mail = mail.replace(/./g, function (ch) { 1538 if (ch === '@') { 1539 // this *must* be encoded. I insist. 1540 ch = encode[Math.floor(Math.random() * 2)](ch); 1541 } else { 1542 var r = Math.random(); 1543 // roughly 10% raw, 45% hex, 45% dec 1544 ch = ( 1545 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) 1546 ); 1547 } 1548 return ch; 1549 }); 1550 1551 return mail; 1552 }; 1553 1554 /** 1555 * 1556 * @param str 1557 * @param targetLength 1558 * @param padString 1559 * @returns {string} 1560 */ 1561 showdown.helper.padEnd = function padEnd (str, targetLength, padString) { 1562 'use strict'; 1563 /*jshint bitwise: false*/ 1564 // eslint-disable-next-line space-infix-ops 1565 targetLength = targetLength>>0; //floor if number or convert non-number to 0; 1566 /*jshint bitwise: true*/ 1567 padString = String(padString || ' '); 1568 if (str.length > targetLength) { 1569 return String(str); 1570 } else { 1571 targetLength = targetLength - str.length; 1572 if (targetLength > padString.length) { 1573 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 1574 } 1575 return String(str) + padString.slice(0,targetLength); 1576 } 1577 }; 1578 1579 /** 1580 * POLYFILLS 1581 */ 1582 // use this instead of builtin is undefined for IE8 compatibility 1583 if (typeof console === 'undefined') { 1584 console = { 1585 warn: function (msg) { 1586 'use strict'; 1587 alert(msg); 1588 }, 1589 log: function (msg) { 1590 'use strict'; 1591 alert(msg); 1592 }, 1593 error: function (msg) { 1594 'use strict'; 1595 throw msg; 1596 } 1597 }; 1598 } 1599 1600 /** 1601 * Common regexes. 1602 * We declare some common regexes to improve performance 1603 */ 1604 showdown.helper.regexes = { 1605 asteriskDashAndColon: /([*_:~])/g 1606 }; 1607 1608 /** 1609 * EMOJIS LIST 1610 */ 1611 showdown.helper.emojis = { 1612 '+1':'\ud83d\udc4d', 1613 '-1':'\ud83d\udc4e', 1614 '100':'\ud83d\udcaf', 1615 '1234':'\ud83d\udd22', 1616 '1st_place_medal':'\ud83e\udd47', 1617 '2nd_place_medal':'\ud83e\udd48', 1618 '3rd_place_medal':'\ud83e\udd49', 1619 '8ball':'\ud83c\udfb1', 1620 'a':'\ud83c\udd70\ufe0f', 1621 'ab':'\ud83c\udd8e', 1622 'abc':'\ud83d\udd24', 1623 'abcd':'\ud83d\udd21', 1624 'accept':'\ud83c\ude51', 1625 'aerial_tramway':'\ud83d\udea1', 1626 'airplane':'\u2708\ufe0f', 1627 'alarm_clock':'\u23f0', 1628 'alembic':'\u2697\ufe0f', 1629 'alien':'\ud83d\udc7d', 1630 'ambulance':'\ud83d\ude91', 1631 'amphora':'\ud83c\udffa', 1632 'anchor':'\u2693\ufe0f', 1633 'angel':'\ud83d\udc7c', 1634 'anger':'\ud83d\udca2', 1635 'angry':'\ud83d\ude20', 1636 'anguished':'\ud83d\ude27', 1637 'ant':'\ud83d\udc1c', 1638 'apple':'\ud83c\udf4e', 1639 'aquarius':'\u2652\ufe0f', 1640 'aries':'\u2648\ufe0f', 1641 'arrow_backward':'\u25c0\ufe0f', 1642 'arrow_double_down':'\u23ec', 1643 'arrow_double_up':'\u23eb', 1644 'arrow_down':'\u2b07\ufe0f', 1645 'arrow_down_small':'\ud83d\udd3d', 1646 'arrow_forward':'\u25b6\ufe0f', 1647 'arrow_heading_down':'\u2935\ufe0f', 1648 'arrow_heading_up':'\u2934\ufe0f', 1649 'arrow_left':'\u2b05\ufe0f', 1650 'arrow_lower_left':'\u2199\ufe0f', 1651 'arrow_lower_right':'\u2198\ufe0f', 1652 'arrow_right':'\u27a1\ufe0f', 1653 'arrow_right_hook':'\u21aa\ufe0f', 1654 'arrow_up':'\u2b06\ufe0f', 1655 'arrow_up_down':'\u2195\ufe0f', 1656 'arrow_up_small':'\ud83d\udd3c', 1657 'arrow_upper_left':'\u2196\ufe0f', 1658 'arrow_upper_right':'\u2197\ufe0f', 1659 'arrows_clockwise':'\ud83d\udd03', 1660 'arrows_counterclockwise':'\ud83d\udd04', 1661 'art':'\ud83c\udfa8', 1662 'articulated_lorry':'\ud83d\ude9b', 1663 'artificial_satellite':'\ud83d\udef0', 1664 'astonished':'\ud83d\ude32', 1665 'athletic_shoe':'\ud83d\udc5f', 1666 'atm':'\ud83c\udfe7', 1667 'atom_symbol':'\u269b\ufe0f', 1668 'avocado':'\ud83e\udd51', 1669 'b':'\ud83c\udd71\ufe0f', 1670 'baby':'\ud83d\udc76', 1671 'baby_bottle':'\ud83c\udf7c', 1672 'baby_chick':'\ud83d\udc24', 1673 'baby_symbol':'\ud83d\udebc', 1674 'back':'\ud83d\udd19', 1675 'bacon':'\ud83e\udd53', 1676 'badminton':'\ud83c\udff8', 1677 'baggage_claim':'\ud83d\udec4', 1678 'baguette_bread':'\ud83e\udd56', 1679 'balance_scale':'\u2696\ufe0f', 1680 'balloon':'\ud83c\udf88', 1681 'ballot_box':'\ud83d\uddf3', 1682 'ballot_box_with_check':'\u2611\ufe0f', 1683 'bamboo':'\ud83c\udf8d', 1684 'banana':'\ud83c\udf4c', 1685 'bangbang':'\u203c\ufe0f', 1686 'bank':'\ud83c\udfe6', 1687 'bar_chart':'\ud83d\udcca', 1688 'barber':'\ud83d\udc88', 1689 'baseball':'\u26be\ufe0f', 1690 'basketball':'\ud83c\udfc0', 1691 'basketball_man':'\u26f9\ufe0f', 1692 'basketball_woman':'\u26f9\ufe0f‍\u2640\ufe0f', 1693 'bat':'\ud83e\udd87', 1694 'bath':'\ud83d\udec0', 1695 'bathtub':'\ud83d\udec1', 1696 'battery':'\ud83d\udd0b', 1697 'beach_umbrella':'\ud83c\udfd6', 1698 'bear':'\ud83d\udc3b', 1699 'bed':'\ud83d\udecf', 1700 'bee':'\ud83d\udc1d', 1701 'beer':'\ud83c\udf7a', 1702 'beers':'\ud83c\udf7b', 1703 'beetle':'\ud83d\udc1e', 1704 'beginner':'\ud83d\udd30', 1705 'bell':'\ud83d\udd14', 1706 'bellhop_bell':'\ud83d\udece', 1707 'bento':'\ud83c\udf71', 1708 'biking_man':'\ud83d\udeb4', 1709 'bike':'\ud83d\udeb2', 1710 'biking_woman':'\ud83d\udeb4‍\u2640\ufe0f', 1711 'bikini':'\ud83d\udc59', 1712 'biohazard':'\u2623\ufe0f', 1713 'bird':'\ud83d\udc26', 1714 'birthday':'\ud83c\udf82', 1715 'black_circle':'\u26ab\ufe0f', 1716 'black_flag':'\ud83c\udff4', 1717 'black_heart':'\ud83d\udda4', 1718 'black_joker':'\ud83c\udccf', 1719 'black_large_square':'\u2b1b\ufe0f', 1720 'black_medium_small_square':'\u25fe\ufe0f', 1721 'black_medium_square':'\u25fc\ufe0f', 1722 'black_nib':'\u2712\ufe0f', 1723 'black_small_square':'\u25aa\ufe0f', 1724 'black_square_button':'\ud83d\udd32', 1725 'blonde_man':'\ud83d\udc71', 1726 'blonde_woman':'\ud83d\udc71‍\u2640\ufe0f', 1727 'blossom':'\ud83c\udf3c', 1728 'blowfish':'\ud83d\udc21', 1729 'blue_book':'\ud83d\udcd8', 1730 'blue_car':'\ud83d\ude99', 1731 'blue_heart':'\ud83d\udc99', 1732 'blush':'\ud83d\ude0a', 1733 'boar':'\ud83d\udc17', 1734 'boat':'\u26f5\ufe0f', 1735 'bomb':'\ud83d\udca3', 1736 'book':'\ud83d\udcd6', 1737 'bookmark':'\ud83d\udd16', 1738 'bookmark_tabs':'\ud83d\udcd1', 1739 'books':'\ud83d\udcda', 1740 'boom':'\ud83d\udca5', 1741 'boot':'\ud83d\udc62', 1742 'bouquet':'\ud83d\udc90', 1743 'bowing_man':'\ud83d\ude47', 1744 'bow_and_arrow':'\ud83c\udff9', 1745 'bowing_woman':'\ud83d\ude47‍\u2640\ufe0f', 1746 'bowling':'\ud83c\udfb3', 1747 'boxing_glove':'\ud83e\udd4a', 1748 'boy':'\ud83d\udc66', 1749 'bread':'\ud83c\udf5e', 1750 'bride_with_veil':'\ud83d\udc70', 1751 'bridge_at_night':'\ud83c\udf09', 1752 'briefcase':'\ud83d\udcbc', 1753 'broken_heart':'\ud83d\udc94', 1754 'bug':'\ud83d\udc1b', 1755 'building_construction':'\ud83c\udfd7', 1756 'bulb':'\ud83d\udca1', 1757 'bullettrain_front':'\ud83d\ude85', 1758 'bullettrain_side':'\ud83d\ude84', 1759 'burrito':'\ud83c\udf2f', 1760 'bus':'\ud83d\ude8c', 1761 'business_suit_levitating':'\ud83d\udd74', 1762 'busstop':'\ud83d\ude8f', 1763 'bust_in_silhouette':'\ud83d\udc64', 1764 'busts_in_silhouette':'\ud83d\udc65', 1765 'butterfly':'\ud83e\udd8b', 1766 'cactus':'\ud83c\udf35', 1767 'cake':'\ud83c\udf70', 1768 'calendar':'\ud83d\udcc6', 1769 'call_me_hand':'\ud83e\udd19', 1770 'calling':'\ud83d\udcf2', 1771 'camel':'\ud83d\udc2b', 1772 'camera':'\ud83d\udcf7', 1773 'camera_flash':'\ud83d\udcf8', 1774 'camping':'\ud83c\udfd5', 1775 'cancer':'\u264b\ufe0f', 1776 'candle':'\ud83d\udd6f', 1777 'candy':'\ud83c\udf6c', 1778 'canoe':'\ud83d\udef6', 1779 'capital_abcd':'\ud83d\udd20', 1780 'capricorn':'\u2651\ufe0f', 1781 'car':'\ud83d\ude97', 1782 'card_file_box':'\ud83d\uddc3', 1783 'card_index':'\ud83d\udcc7', 1784 'card_index_dividers':'\ud83d\uddc2', 1785 'carousel_horse':'\ud83c\udfa0', 1786 'carrot':'\ud83e\udd55', 1787 'cat':'\ud83d\udc31', 1788 'cat2':'\ud83d\udc08', 1789 'cd':'\ud83d\udcbf', 1790 'chains':'\u26d3', 1791 'champagne':'\ud83c\udf7e', 1792 'chart':'\ud83d\udcb9', 1793 'chart_with_downwards_trend':'\ud83d\udcc9', 1794 'chart_with_upwards_trend':'\ud83d\udcc8', 1795 'checkered_flag':'\ud83c\udfc1', 1796 'cheese':'\ud83e\uddc0', 1797 'cherries':'\ud83c\udf52', 1798 'cherry_blossom':'\ud83c\udf38', 1799 'chestnut':'\ud83c\udf30', 1800 'chicken':'\ud83d\udc14', 1801 'children_crossing':'\ud83d\udeb8', 1802 'chipmunk':'\ud83d\udc3f', 1803 'chocolate_bar':'\ud83c\udf6b', 1804 'christmas_tree':'\ud83c\udf84', 1805 'church':'\u26ea\ufe0f', 1806 'cinema':'\ud83c\udfa6', 1807 'circus_tent':'\ud83c\udfaa', 1808 'city_sunrise':'\ud83c\udf07', 1809 'city_sunset':'\ud83c\udf06', 1810 'cityscape':'\ud83c\udfd9', 1811 'cl':'\ud83c\udd91', 1812 'clamp':'\ud83d\udddc', 1813 'clap':'\ud83d\udc4f', 1814 'clapper':'\ud83c\udfac', 1815 'classical_building':'\ud83c\udfdb', 1816 'clinking_glasses':'\ud83e\udd42', 1817 'clipboard':'\ud83d\udccb', 1818 'clock1':'\ud83d\udd50', 1819 'clock10':'\ud83d\udd59', 1820 'clock1030':'\ud83d\udd65', 1821 'clock11':'\ud83d\udd5a', 1822 'clock1130':'\ud83d\udd66', 1823 'clock12':'\ud83d\udd5b', 1824 'clock1230':'\ud83d\udd67', 1825 'clock130':'\ud83d\udd5c', 1826 'clock2':'\ud83d\udd51', 1827 'clock230':'\ud83d\udd5d', 1828 'clock3':'\ud83d\udd52', 1829 'clock330':'\ud83d\udd5e', 1830 'clock4':'\ud83d\udd53', 1831 'clock430':'\ud83d\udd5f', 1832 'clock5':'\ud83d\udd54', 1833 'clock530':'\ud83d\udd60', 1834 'clock6':'\ud83d\udd55', 1835 'clock630':'\ud83d\udd61', 1836 'clock7':'\ud83d\udd56', 1837 'clock730':'\ud83d\udd62', 1838 'clock8':'\ud83d\udd57', 1839 'clock830':'\ud83d\udd63', 1840 'clock9':'\ud83d\udd58', 1841 'clock930':'\ud83d\udd64', 1842 'closed_book':'\ud83d\udcd5', 1843 'closed_lock_with_key':'\ud83d\udd10', 1844 'closed_umbrella':'\ud83c\udf02', 1845 'cloud':'\u2601\ufe0f', 1846 'cloud_with_lightning':'\ud83c\udf29', 1847 'cloud_with_lightning_and_rain':'\u26c8', 1848 'cloud_with_rain':'\ud83c\udf27', 1849 'cloud_with_snow':'\ud83c\udf28', 1850 'clown_face':'\ud83e\udd21', 1851 'clubs':'\u2663\ufe0f', 1852 'cocktail':'\ud83c\udf78', 1853 'coffee':'\u2615\ufe0f', 1854 'coffin':'\u26b0\ufe0f', 1855 'cold_sweat':'\ud83d\ude30', 1856 'comet':'\u2604\ufe0f', 1857 'computer':'\ud83d\udcbb', 1858 'computer_mouse':'\ud83d\uddb1', 1859 'confetti_ball':'\ud83c\udf8a', 1860 'confounded':'\ud83d\ude16', 1861 'confused':'\ud83d\ude15', 1862 'congratulations':'\u3297\ufe0f', 1863 'construction':'\ud83d\udea7', 1864 'construction_worker_man':'\ud83d\udc77', 1865 'construction_worker_woman':'\ud83d\udc77‍\u2640\ufe0f', 1866 'control_knobs':'\ud83c\udf9b', 1867 'convenience_store':'\ud83c\udfea', 1868 'cookie':'\ud83c\udf6a', 1869 'cool':'\ud83c\udd92', 1870 'policeman':'\ud83d\udc6e', 1871 'copyright':'\u00a9\ufe0f', 1872 'corn':'\ud83c\udf3d', 1873 'couch_and_lamp':'\ud83d\udecb', 1874 'couple':'\ud83d\udc6b', 1875 'couple_with_heart_woman_man':'\ud83d\udc91', 1876 'couple_with_heart_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc68', 1877 'couple_with_heart_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc69', 1878 'couplekiss_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc68', 1879 'couplekiss_man_woman':'\ud83d\udc8f', 1880 'couplekiss_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc69', 1881 'cow':'\ud83d\udc2e', 1882 'cow2':'\ud83d\udc04', 1883 'cowboy_hat_face':'\ud83e\udd20', 1884 'crab':'\ud83e\udd80', 1885 'crayon':'\ud83d\udd8d', 1886 'credit_card':'\ud83d\udcb3', 1887 'crescent_moon':'\ud83c\udf19', 1888 'cricket':'\ud83c\udfcf', 1889 'crocodile':'\ud83d\udc0a', 1890 'croissant':'\ud83e\udd50', 1891 'crossed_fingers':'\ud83e\udd1e', 1892 'crossed_flags':'\ud83c\udf8c', 1893 'crossed_swords':'\u2694\ufe0f', 1894 'crown':'\ud83d\udc51', 1895 'cry':'\ud83d\ude22', 1896 'crying_cat_face':'\ud83d\ude3f', 1897 'crystal_ball':'\ud83d\udd2e', 1898 'cucumber':'\ud83e\udd52', 1899 'cupid':'\ud83d\udc98', 1900 'curly_loop':'\u27b0', 1901 'currency_exchange':'\ud83d\udcb1', 1902 'curry':'\ud83c\udf5b', 1903 'custard':'\ud83c\udf6e', 1904 'customs':'\ud83d\udec3', 1905 'cyclone':'\ud83c\udf00', 1906 'dagger':'\ud83d\udde1', 1907 'dancer':'\ud83d\udc83', 1908 'dancing_women':'\ud83d\udc6f', 1909 'dancing_men':'\ud83d\udc6f‍\u2642\ufe0f', 1910 'dango':'\ud83c\udf61', 1911 'dark_sunglasses':'\ud83d\udd76', 1912 'dart':'\ud83c\udfaf', 1913 'dash':'\ud83d\udca8', 1914 'date':'\ud83d\udcc5', 1915 'deciduous_tree':'\ud83c\udf33', 1916 'deer':'\ud83e\udd8c', 1917 'department_store':'\ud83c\udfec', 1918 'derelict_house':'\ud83c\udfda', 1919 'desert':'\ud83c\udfdc', 1920 'desert_island':'\ud83c\udfdd', 1921 'desktop_computer':'\ud83d\udda5', 1922 'male_detective':'\ud83d\udd75\ufe0f', 1923 'diamond_shape_with_a_dot_inside':'\ud83d\udca0', 1924 'diamonds':'\u2666\ufe0f', 1925 'disappointed':'\ud83d\ude1e', 1926 'disappointed_relieved':'\ud83d\ude25', 1927 'dizzy':'\ud83d\udcab', 1928 'dizzy_face':'\ud83d\ude35', 1929 'do_not_litter':'\ud83d\udeaf', 1930 'dog':'\ud83d\udc36', 1931 'dog2':'\ud83d\udc15', 1932 'dollar':'\ud83d\udcb5', 1933 'dolls':'\ud83c\udf8e', 1934 'dolphin':'\ud83d\udc2c', 1935 'door':'\ud83d\udeaa', 1936 'doughnut':'\ud83c\udf69', 1937 'dove':'\ud83d\udd4a', 1938 'dragon':'\ud83d\udc09', 1939 'dragon_face':'\ud83d\udc32', 1940 'dress':'\ud83d\udc57', 1941 'dromedary_camel':'\ud83d\udc2a', 1942 'drooling_face':'\ud83e\udd24', 1943 'droplet':'\ud83d\udca7', 1944 'drum':'\ud83e\udd41', 1945 'duck':'\ud83e\udd86', 1946 'dvd':'\ud83d\udcc0', 1947 'e-mail':'\ud83d\udce7', 1948 'eagle':'\ud83e\udd85', 1949 'ear':'\ud83d\udc42', 1950 'ear_of_rice':'\ud83c\udf3e', 1951 'earth_africa':'\ud83c\udf0d', 1952 'earth_americas':'\ud83c\udf0e', 1953 'earth_asia':'\ud83c\udf0f', 1954 'egg':'\ud83e\udd5a', 1955 'eggplant':'\ud83c\udf46', 1956 'eight_pointed_black_star':'\u2734\ufe0f', 1957 'eight_spoked_asterisk':'\u2733\ufe0f', 1958 'electric_plug':'\ud83d\udd0c', 1959 'elephant':'\ud83d\udc18', 1960 'email':'\u2709\ufe0f', 1961 'end':'\ud83d\udd1a', 1962 'envelope_with_arrow':'\ud83d\udce9', 1963 'euro':'\ud83d\udcb6', 1964 'european_castle':'\ud83c\udff0', 1965 'european_post_office':'\ud83c\udfe4', 1966 'evergreen_tree':'\ud83c\udf32', 1967 'exclamation':'\u2757\ufe0f', 1968 'expressionless':'\ud83d\ude11', 1969 'eye':'\ud83d\udc41', 1970 'eye_speech_bubble':'\ud83d\udc41‍\ud83d\udde8', 1971 'eyeglasses':'\ud83d\udc53', 1972 'eyes':'\ud83d\udc40', 1973 'face_with_head_bandage':'\ud83e\udd15', 1974 'face_with_thermometer':'\ud83e\udd12', 1975 'fist_oncoming':'\ud83d\udc4a', 1976 'factory':'\ud83c\udfed', 1977 'fallen_leaf':'\ud83c\udf42', 1978 'family_man_woman_boy':'\ud83d\udc6a', 1979 'family_man_boy':'\ud83d\udc68‍\ud83d\udc66', 1980 'family_man_boy_boy':'\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1981 'family_man_girl':'\ud83d\udc68‍\ud83d\udc67', 1982 'family_man_girl_boy':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1983 'family_man_girl_girl':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1984 'family_man_man_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66', 1985 'family_man_man_boy_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1986 'family_man_man_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67', 1987 'family_man_man_girl_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1988 'family_man_man_girl_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1989 'family_man_woman_boy_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1990 'family_man_woman_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67', 1991 'family_man_woman_girl_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1992 'family_man_woman_girl_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1993 'family_woman_boy':'\ud83d\udc69‍\ud83d\udc66', 1994 'family_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1995 'family_woman_girl':'\ud83d\udc69‍\ud83d\udc67', 1996 'family_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1997 'family_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1998 'family_woman_woman_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66', 1999 'family_woman_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 2000 'family_woman_woman_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67', 2001 'family_woman_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 2002 'family_woman_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 2003 'fast_forward':'\u23e9', 2004 'fax':'\ud83d\udce0', 2005 'fearful':'\ud83d\ude28', 2006 'feet':'\ud83d\udc3e', 2007 'female_detective':'\ud83d\udd75\ufe0f‍\u2640\ufe0f', 2008 'ferris_wheel':'\ud83c\udfa1', 2009 'ferry':'\u26f4', 2010 'field_hockey':'\ud83c\udfd1', 2011 'file_cabinet':'\ud83d\uddc4', 2012 'file_folder':'\ud83d\udcc1', 2013 'film_projector':'\ud83d\udcfd', 2014 'film_strip':'\ud83c\udf9e', 2015 'fire':'\ud83d\udd25', 2016 'fire_engine':'\ud83d\ude92', 2017 'fireworks':'\ud83c\udf86', 2018 'first_quarter_moon':'\ud83c\udf13', 2019 'first_quarter_moon_with_face':'\ud83c\udf1b', 2020 'fish':'\ud83d\udc1f', 2021 'fish_cake':'\ud83c\udf65', 2022 'fishing_pole_and_fish':'\ud83c\udfa3', 2023 'fist_raised':'\u270a', 2024 'fist_left':'\ud83e\udd1b', 2025 'fist_right':'\ud83e\udd1c', 2026 'flags':'\ud83c\udf8f', 2027 'flashlight':'\ud83d\udd26', 2028 'fleur_de_lis':'\u269c\ufe0f', 2029 'flight_arrival':'\ud83d\udeec', 2030 'flight_departure':'\ud83d\udeeb', 2031 'floppy_disk':'\ud83d\udcbe', 2032 'flower_playing_cards':'\ud83c\udfb4', 2033 'flushed':'\ud83d\ude33', 2034 'fog':'\ud83c\udf2b', 2035 'foggy':'\ud83c\udf01', 2036 'football':'\ud83c\udfc8', 2037 'footprints':'\ud83d\udc63', 2038 'fork_and_knife':'\ud83c\udf74', 2039 'fountain':'\u26f2\ufe0f', 2040 'fountain_pen':'\ud83d\udd8b', 2041 'four_leaf_clover':'\ud83c\udf40', 2042 'fox_face':'\ud83e\udd8a', 2043 'framed_picture':'\ud83d\uddbc', 2044 'free':'\ud83c\udd93', 2045 'fried_egg':'\ud83c\udf73', 2046 'fried_shrimp':'\ud83c\udf64', 2047 'fries':'\ud83c\udf5f', 2048 'frog':'\ud83d\udc38', 2049 'frowning':'\ud83d\ude26', 2050 'frowning_face':'\u2639\ufe0f', 2051 'frowning_man':'\ud83d\ude4d‍\u2642\ufe0f', 2052 'frowning_woman':'\ud83d\ude4d', 2053 'middle_finger':'\ud83d\udd95', 2054 'fuelpump':'\u26fd\ufe0f', 2055 'full_moon':'\ud83c\udf15', 2056 'full_moon_with_face':'\ud83c\udf1d', 2057 'funeral_urn':'\u26b1\ufe0f', 2058 'game_die':'\ud83c\udfb2', 2059 'gear':'\u2699\ufe0f', 2060 'gem':'\ud83d\udc8e', 2061 'gemini':'\u264a\ufe0f', 2062 'ghost':'\ud83d\udc7b', 2063 'gift':'\ud83c\udf81', 2064 'gift_heart':'\ud83d\udc9d', 2065 'girl':'\ud83d\udc67', 2066 'globe_with_meridians':'\ud83c\udf10', 2067 'goal_net':'\ud83e\udd45', 2068 'goat':'\ud83d\udc10', 2069 'golf':'\u26f3\ufe0f', 2070 'golfing_man':'\ud83c\udfcc\ufe0f', 2071 'golfing_woman':'\ud83c\udfcc\ufe0f‍\u2640\ufe0f', 2072 'gorilla':'\ud83e\udd8d', 2073 'grapes':'\ud83c\udf47', 2074 'green_apple':'\ud83c\udf4f', 2075 'green_book':'\ud83d\udcd7', 2076 'green_heart':'\ud83d\udc9a', 2077 'green_salad':'\ud83e\udd57', 2078 'grey_exclamation':'\u2755', 2079 'grey_question':'\u2754', 2080 'grimacing':'\ud83d\ude2c', 2081 'grin':'\ud83d\ude01', 2082 'grinning':'\ud83d\ude00', 2083 'guardsman':'\ud83d\udc82', 2084 'guardswoman':'\ud83d\udc82‍\u2640\ufe0f', 2085 'guitar':'\ud83c\udfb8', 2086 'gun':'\ud83d\udd2b', 2087 'haircut_woman':'\ud83d\udc87', 2088 'haircut_man':'\ud83d\udc87‍\u2642\ufe0f', 2089 'hamburger':'\ud83c\udf54', 2090 'hammer':'\ud83d\udd28', 2091 'hammer_and_pick':'\u2692', 2092 'hammer_and_wrench':'\ud83d\udee0', 2093 'hamster':'\ud83d\udc39', 2094 'hand':'\u270b', 2095 'handbag':'\ud83d\udc5c', 2096 'handshake':'\ud83e\udd1d', 2097 'hankey':'\ud83d\udca9', 2098 'hatched_chick':'\ud83d\udc25', 2099 'hatching_chick':'\ud83d\udc23', 2100 'headphones':'\ud83c\udfa7', 2101 'hear_no_evil':'\ud83d\ude49', 2102 'heart':'\u2764\ufe0f', 2103 'heart_decoration':'\ud83d\udc9f', 2104 'heart_eyes':'\ud83d\ude0d', 2105 'heart_eyes_cat':'\ud83d\ude3b', 2106 'heartbeat':'\ud83d\udc93', 2107 'heartpulse':'\ud83d\udc97', 2108 'hearts':'\u2665\ufe0f', 2109 'heavy_check_mark':'\u2714\ufe0f', 2110 'heavy_division_sign':'\u2797', 2111 'heavy_dollar_sign':'\ud83d\udcb2', 2112 'heavy_heart_exclamation':'\u2763\ufe0f', 2113 'heavy_minus_sign':'\u2796', 2114 'heavy_multiplication_x':'\u2716\ufe0f', 2115 'heavy_plus_sign':'\u2795', 2116 'helicopter':'\ud83d\ude81', 2117 'herb':'\ud83c\udf3f', 2118 'hibiscus':'\ud83c\udf3a', 2119 'high_brightness':'\ud83d\udd06', 2120 'high_heel':'\ud83d\udc60', 2121 'hocho':'\ud83d\udd2a', 2122 'hole':'\ud83d\udd73', 2123 'honey_pot':'\ud83c\udf6f', 2124 'horse':'\ud83d\udc34', 2125 'horse_racing':'\ud83c\udfc7', 2126 'hospital':'\ud83c\udfe5', 2127 'hot_pepper':'\ud83c\udf36', 2128 'hotdog':'\ud83c\udf2d', 2129 'hotel':'\ud83c\udfe8', 2130 'hotsprings':'\u2668\ufe0f', 2131 'hourglass':'\u231b\ufe0f', 2132 'hourglass_flowing_sand':'\u23f3', 2133 'house':'\ud83c\udfe0', 2134 'house_with_garden':'\ud83c\udfe1', 2135 'houses':'\ud83c\udfd8', 2136 'hugs':'\ud83e\udd17', 2137 'hushed':'\ud83d\ude2f', 2138 'ice_cream':'\ud83c\udf68', 2139 'ice_hockey':'\ud83c\udfd2', 2140 'ice_skate':'\u26f8', 2141 'icecream':'\ud83c\udf66', 2142 'id':'\ud83c\udd94', 2143 'ideograph_advantage':'\ud83c\ude50', 2144 'imp':'\ud83d\udc7f', 2145 'inbox_tray':'\ud83d\udce5', 2146 'incoming_envelope':'\ud83d\udce8', 2147 'tipping_hand_woman':'\ud83d\udc81', 2148 'information_source':'\u2139\ufe0f', 2149 'innocent':'\ud83d\ude07', 2150 'interrobang':'\u2049\ufe0f', 2151 'iphone':'\ud83d\udcf1', 2152 'izakaya_lantern':'\ud83c\udfee', 2153 'jack_o_lantern':'\ud83c\udf83', 2154 'japan':'\ud83d\uddfe', 2155 'japanese_castle':'\ud83c\udfef', 2156 'japanese_goblin':'\ud83d\udc7a', 2157 'japanese_ogre':'\ud83d\udc79', 2158 'jeans':'\ud83d\udc56', 2159 'joy':'\ud83d\ude02', 2160 'joy_cat':'\ud83d\ude39', 2161 'joystick':'\ud83d\udd79', 2162 'kaaba':'\ud83d\udd4b', 2163 'key':'\ud83d\udd11', 2164 'keyboard':'\u2328\ufe0f', 2165 'keycap_ten':'\ud83d\udd1f', 2166 'kick_scooter':'\ud83d\udef4', 2167 'kimono':'\ud83d\udc58', 2168 'kiss':'\ud83d\udc8b', 2169 'kissing':'\ud83d\ude17', 2170 'kissing_cat':'\ud83d\ude3d', 2171 'kissing_closed_eyes':'\ud83d\ude1a', 2172 'kissing_heart':'\ud83d\ude18', 2173 'kissing_smiling_eyes':'\ud83d\ude19', 2174 'kiwi_fruit':'\ud83e\udd5d', 2175 'koala':'\ud83d\udc28', 2176 'koko':'\ud83c\ude01', 2177 'label':'\ud83c\udff7', 2178 'large_blue_circle':'\ud83d\udd35', 2179 'large_blue_diamond':'\ud83d\udd37', 2180 'large_orange_diamond':'\ud83d\udd36', 2181 'last_quarter_moon':'\ud83c\udf17', 2182 'last_quarter_moon_with_face':'\ud83c\udf1c', 2183 'latin_cross':'\u271d\ufe0f', 2184 'laughing':'\ud83d\ude06', 2185 'leaves':'\ud83c\udf43', 2186 'ledger':'\ud83d\udcd2', 2187 'left_luggage':'\ud83d\udec5', 2188 'left_right_arrow':'\u2194\ufe0f', 2189 'leftwards_arrow_with_hook':'\u21a9\ufe0f', 2190 'lemon':'\ud83c\udf4b', 2191 'leo':'\u264c\ufe0f', 2192 'leopard':'\ud83d\udc06', 2193 'level_slider':'\ud83c\udf9a', 2194 'libra':'\u264e\ufe0f', 2195 'light_rail':'\ud83d\ude88', 2196 'link':'\ud83d\udd17', 2197 'lion':'\ud83e\udd81', 2198 'lips':'\ud83d\udc44', 2199 'lipstick':'\ud83d\udc84', 2200 'lizard':'\ud83e\udd8e', 2201 'lock':'\ud83d\udd12', 2202 'lock_with_ink_pen':'\ud83d\udd0f', 2203 'lollipop':'\ud83c\udf6d', 2204 'loop':'\u27bf', 2205 'loud_sound':'\ud83d\udd0a', 2206 'loudspeaker':'\ud83d\udce2', 2207 'love_hotel':'\ud83c\udfe9', 2208 'love_letter':'\ud83d\udc8c', 2209 'low_brightness':'\ud83d\udd05', 2210 'lying_face':'\ud83e\udd25', 2211 'm':'\u24c2\ufe0f', 2212 'mag':'\ud83d\udd0d', 2213 'mag_right':'\ud83d\udd0e', 2214 'mahjong':'\ud83c\udc04\ufe0f', 2215 'mailbox':'\ud83d\udceb', 2216 'mailbox_closed':'\ud83d\udcea', 2217 'mailbox_with_mail':'\ud83d\udcec', 2218 'mailbox_with_no_mail':'\ud83d\udced', 2219 'man':'\ud83d\udc68', 2220 'man_artist':'\ud83d\udc68‍\ud83c\udfa8', 2221 'man_astronaut':'\ud83d\udc68‍\ud83d\ude80', 2222 'man_cartwheeling':'\ud83e\udd38‍\u2642\ufe0f', 2223 'man_cook':'\ud83d\udc68‍\ud83c\udf73', 2224 'man_dancing':'\ud83d\udd7a', 2225 'man_facepalming':'\ud83e\udd26‍\u2642\ufe0f', 2226 'man_factory_worker':'\ud83d\udc68‍\ud83c\udfed', 2227 'man_farmer':'\ud83d\udc68‍\ud83c\udf3e', 2228 'man_firefighter':'\ud83d\udc68‍\ud83d\ude92', 2229 'man_health_worker':'\ud83d\udc68‍\u2695\ufe0f', 2230 'man_in_tuxedo':'\ud83e\udd35', 2231 'man_judge':'\ud83d\udc68‍\u2696\ufe0f', 2232 'man_juggling':'\ud83e\udd39‍\u2642\ufe0f', 2233 'man_mechanic':'\ud83d\udc68‍\ud83d\udd27', 2234 'man_office_worker':'\ud83d\udc68‍\ud83d\udcbc', 2235 'man_pilot':'\ud83d\udc68‍\u2708\ufe0f', 2236 'man_playing_handball':'\ud83e\udd3e‍\u2642\ufe0f', 2237 'man_playing_water_polo':'\ud83e\udd3d‍\u2642\ufe0f', 2238 'man_scientist':'\ud83d\udc68‍\ud83d\udd2c', 2239 'man_shrugging':'\ud83e\udd37‍\u2642\ufe0f', 2240 'man_singer':'\ud83d\udc68‍\ud83c\udfa4', 2241 'man_student':'\ud83d\udc68‍\ud83c\udf93', 2242 'man_teacher':'\ud83d\udc68‍\ud83c\udfeb', 2243 'man_technologist':'\ud83d\udc68‍\ud83d\udcbb', 2244 'man_with_gua_pi_mao':'\ud83d\udc72', 2245 'man_with_turban':'\ud83d\udc73', 2246 'tangerine':'\ud83c\udf4a', 2247 'mans_shoe':'\ud83d\udc5e', 2248 'mantelpiece_clock':'\ud83d\udd70', 2249 'maple_leaf':'\ud83c\udf41', 2250 'martial_arts_uniform':'\ud83e\udd4b', 2251 'mask':'\ud83d\ude37', 2252 'massage_woman':'\ud83d\udc86', 2253 'massage_man':'\ud83d\udc86‍\u2642\ufe0f', 2254 'meat_on_bone':'\ud83c\udf56', 2255 'medal_military':'\ud83c\udf96', 2256 'medal_sports':'\ud83c\udfc5', 2257 'mega':'\ud83d\udce3', 2258 'melon':'\ud83c\udf48', 2259 'memo':'\ud83d\udcdd', 2260 'men_wrestling':'\ud83e\udd3c‍\u2642\ufe0f', 2261 'menorah':'\ud83d\udd4e', 2262 'mens':'\ud83d\udeb9', 2263 'metal':'\ud83e\udd18', 2264 'metro':'\ud83d\ude87', 2265 'microphone':'\ud83c\udfa4', 2266 'microscope':'\ud83d\udd2c', 2267 'milk_glass':'\ud83e\udd5b', 2268 'milky_way':'\ud83c\udf0c', 2269 'minibus':'\ud83d\ude90', 2270 'minidisc':'\ud83d\udcbd', 2271 'mobile_phone_off':'\ud83d\udcf4', 2272 'money_mouth_face':'\ud83e\udd11', 2273 'money_with_wings':'\ud83d\udcb8', 2274 'moneybag':'\ud83d\udcb0', 2275 'monkey':'\ud83d\udc12', 2276 'monkey_face':'\ud83d\udc35', 2277 'monorail':'\ud83d\ude9d', 2278 'moon':'\ud83c\udf14', 2279 'mortar_board':'\ud83c\udf93', 2280 'mosque':'\ud83d\udd4c', 2281 'motor_boat':'\ud83d\udee5', 2282 'motor_scooter':'\ud83d\udef5', 2283 'motorcycle':'\ud83c\udfcd', 2284 'motorway':'\ud83d\udee3', 2285 'mount_fuji':'\ud83d\uddfb', 2286 'mountain':'\u26f0', 2287 'mountain_biking_man':'\ud83d\udeb5', 2288 'mountain_biking_woman':'\ud83d\udeb5‍\u2640\ufe0f', 2289 'mountain_cableway':'\ud83d\udea0', 2290 'mountain_railway':'\ud83d\ude9e', 2291 'mountain_snow':'\ud83c\udfd4', 2292 'mouse':'\ud83d\udc2d', 2293 'mouse2':'\ud83d\udc01', 2294 'movie_camera':'\ud83c\udfa5', 2295 'moyai':'\ud83d\uddff', 2296 'mrs_claus':'\ud83e\udd36', 2297 'muscle':'\ud83d\udcaa', 2298 'mushroom':'\ud83c\udf44', 2299 'musical_keyboard':'\ud83c\udfb9', 2300 'musical_note':'\ud83c\udfb5', 2301 'musical_score':'\ud83c\udfbc', 2302 'mute':'\ud83d\udd07', 2303 'nail_care':'\ud83d\udc85', 2304 'name_badge':'\ud83d\udcdb', 2305 'national_park':'\ud83c\udfde', 2306 'nauseated_face':'\ud83e\udd22', 2307 'necktie':'\ud83d\udc54', 2308 'negative_squared_cross_mark':'\u274e', 2309 'nerd_face':'\ud83e\udd13', 2310 'neutral_face':'\ud83d\ude10', 2311 'new':'\ud83c\udd95', 2312 'new_moon':'\ud83c\udf11', 2313 'new_moon_with_face':'\ud83c\udf1a', 2314 'newspaper':'\ud83d\udcf0', 2315 'newspaper_roll':'\ud83d\uddde', 2316 'next_track_button':'\u23ed', 2317 'ng':'\ud83c\udd96', 2318 'no_good_man':'\ud83d\ude45‍\u2642\ufe0f', 2319 'no_good_woman':'\ud83d\ude45', 2320 'night_with_stars':'\ud83c\udf03', 2321 'no_bell':'\ud83d\udd15', 2322 'no_bicycles':'\ud83d\udeb3', 2323 'no_entry':'\u26d4\ufe0f', 2324 'no_entry_sign':'\ud83d\udeab', 2325 'no_mobile_phones':'\ud83d\udcf5', 2326 'no_mouth':'\ud83d\ude36', 2327 'no_pedestrians':'\ud83d\udeb7', 2328 'no_smoking':'\ud83d\udead', 2329 'non-potable_water':'\ud83d\udeb1', 2330 'nose':'\ud83d\udc43', 2331 'notebook':'\ud83d\udcd3', 2332 'notebook_with_decorative_cover':'\ud83d\udcd4', 2333 'notes':'\ud83c\udfb6', 2334 'nut_and_bolt':'\ud83d\udd29', 2335 'o':'\u2b55\ufe0f', 2336 'o2':'\ud83c\udd7e\ufe0f', 2337 'ocean':'\ud83c\udf0a', 2338 'octopus':'\ud83d\udc19', 2339 'oden':'\ud83c\udf62', 2340 'office':'\ud83c\udfe2', 2341 'oil_drum':'\ud83d\udee2', 2342 'ok':'\ud83c\udd97', 2343 'ok_hand':'\ud83d\udc4c', 2344 'ok_man':'\ud83d\ude46‍\u2642\ufe0f', 2345 'ok_woman':'\ud83d\ude46', 2346 'old_key':'\ud83d\udddd', 2347 'older_man':'\ud83d\udc74', 2348 'older_woman':'\ud83d\udc75', 2349 'om':'\ud83d\udd49', 2350 'on':'\ud83d\udd1b', 2351 'oncoming_automobile':'\ud83d\ude98', 2352 'oncoming_bus':'\ud83d\ude8d', 2353 'oncoming_police_car':'\ud83d\ude94', 2354 'oncoming_taxi':'\ud83d\ude96', 2355 'open_file_folder':'\ud83d\udcc2', 2356 'open_hands':'\ud83d\udc50', 2357 'open_mouth':'\ud83d\ude2e', 2358 'open_umbrella':'\u2602\ufe0f', 2359 'ophiuchus':'\u26ce', 2360 'orange_book':'\ud83d\udcd9', 2361 'orthodox_cross':'\u2626\ufe0f', 2362 'outbox_tray':'\ud83d\udce4', 2363 'owl':'\ud83e\udd89', 2364 'ox':'\ud83d\udc02', 2365 'package':'\ud83d\udce6', 2366 'page_facing_up':'\ud83d\udcc4', 2367 'page_with_curl':'\ud83d\udcc3', 2368 'pager':'\ud83d\udcdf', 2369 'paintbrush':'\ud83d\udd8c', 2370 'palm_tree':'\ud83c\udf34', 2371 'pancakes':'\ud83e\udd5e', 2372 'panda_face':'\ud83d\udc3c', 2373 'paperclip':'\ud83d\udcce', 2374 'paperclips':'\ud83d\udd87', 2375 'parasol_on_ground':'\u26f1', 2376 'parking':'\ud83c\udd7f\ufe0f', 2377 'part_alternation_mark':'\u303d\ufe0f', 2378 'partly_sunny':'\u26c5\ufe0f', 2379 'passenger_ship':'\ud83d\udef3', 2380 'passport_control':'\ud83d\udec2', 2381 'pause_button':'\u23f8', 2382 'peace_symbol':'\u262e\ufe0f', 2383 'peach':'\ud83c\udf51', 2384 'peanuts':'\ud83e\udd5c', 2385 'pear':'\ud83c\udf50', 2386 'pen':'\ud83d\udd8a', 2387 'pencil2':'\u270f\ufe0f', 2388 'penguin':'\ud83d\udc27', 2389 'pensive':'\ud83d\ude14', 2390 'performing_arts':'\ud83c\udfad', 2391 'persevere':'\ud83d\ude23', 2392 'person_fencing':'\ud83e\udd3a', 2393 'pouting_woman':'\ud83d\ude4e', 2394 'phone':'\u260e\ufe0f', 2395 'pick':'\u26cf', 2396 'pig':'\ud83d\udc37', 2397 'pig2':'\ud83d\udc16', 2398 'pig_nose':'\ud83d\udc3d', 2399 'pill':'\ud83d\udc8a', 2400 'pineapple':'\ud83c\udf4d', 2401 'ping_pong':'\ud83c\udfd3', 2402 'pisces':'\u2653\ufe0f', 2403 'pizza':'\ud83c\udf55', 2404 'place_of_worship':'\ud83d\uded0', 2405 'plate_with_cutlery':'\ud83c\udf7d', 2406 'play_or_pause_button':'\u23ef', 2407 'point_down':'\ud83d\udc47', 2408 'point_left':'\ud83d\udc48', 2409 'point_right':'\ud83d\udc49', 2410 'point_up':'\u261d\ufe0f', 2411 'point_up_2':'\ud83d\udc46', 2412 'police_car':'\ud83d\ude93', 2413 'policewoman':'\ud83d\udc6e‍\u2640\ufe0f', 2414 'poodle':'\ud83d\udc29', 2415 'popcorn':'\ud83c\udf7f', 2416 'post_office':'\ud83c\udfe3', 2417 'postal_horn':'\ud83d\udcef', 2418 'postbox':'\ud83d\udcee', 2419 'potable_water':'\ud83d\udeb0', 2420 'potato':'\ud83e\udd54', 2421 'pouch':'\ud83d\udc5d', 2422 'poultry_leg':'\ud83c\udf57', 2423 'pound':'\ud83d\udcb7', 2424 'rage':'\ud83d\ude21', 2425 'pouting_cat':'\ud83d\ude3e', 2426 'pouting_man':'\ud83d\ude4e‍\u2642\ufe0f', 2427 'pray':'\ud83d\ude4f', 2428 'prayer_beads':'\ud83d\udcff', 2429 'pregnant_woman':'\ud83e\udd30', 2430 'previous_track_button':'\u23ee', 2431 'prince':'\ud83e\udd34', 2432 'princess':'\ud83d\udc78', 2433 'printer':'\ud83d\udda8', 2434 'purple_heart':'\ud83d\udc9c', 2435 'purse':'\ud83d\udc5b', 2436 'pushpin':'\ud83d\udccc', 2437 'put_litter_in_its_place':'\ud83d\udeae', 2438 'question':'\u2753', 2439 'rabbit':'\ud83d\udc30', 2440 'rabbit2':'\ud83d\udc07', 2441 'racehorse':'\ud83d\udc0e', 2442 'racing_car':'\ud83c\udfce', 2443 'radio':'\ud83d\udcfb', 2444 'radio_button':'\ud83d\udd18', 2445 'radioactive':'\u2622\ufe0f', 2446 'railway_car':'\ud83d\ude83', 2447 'railway_track':'\ud83d\udee4', 2448 'rainbow':'\ud83c\udf08', 2449 'rainbow_flag':'\ud83c\udff3\ufe0f‍\ud83c\udf08', 2450 'raised_back_of_hand':'\ud83e\udd1a', 2451 'raised_hand_with_fingers_splayed':'\ud83d\udd90', 2452 'raised_hands':'\ud83d\ude4c', 2453 'raising_hand_woman':'\ud83d\ude4b', 2454 'raising_hand_man':'\ud83d\ude4b‍\u2642\ufe0f', 2455 'ram':'\ud83d\udc0f', 2456 'ramen':'\ud83c\udf5c', 2457 'rat':'\ud83d\udc00', 2458 'record_button':'\u23fa', 2459 'recycle':'\u267b\ufe0f', 2460 'red_circle':'\ud83d\udd34', 2461 'registered':'\u00ae\ufe0f', 2462 'relaxed':'\u263a\ufe0f', 2463 'relieved':'\ud83d\ude0c', 2464 'reminder_ribbon':'\ud83c\udf97', 2465 'repeat':'\ud83d\udd01', 2466 'repeat_one':'\ud83d\udd02', 2467 'rescue_worker_helmet':'\u26d1', 2468 'restroom':'\ud83d\udebb', 2469 'revolving_hearts':'\ud83d\udc9e', 2470 'rewind':'\u23ea', 2471 'rhinoceros':'\ud83e\udd8f', 2472 'ribbon':'\ud83c\udf80', 2473 'rice':'\ud83c\udf5a', 2474 'rice_ball':'\ud83c\udf59', 2475 'rice_cracker':'\ud83c\udf58', 2476 'rice_scene':'\ud83c\udf91', 2477 'right_anger_bubble':'\ud83d\uddef', 2478 'ring':'\ud83d\udc8d', 2479 'robot':'\ud83e\udd16', 2480 'rocket':'\ud83d\ude80', 2481 'rofl':'\ud83e\udd23', 2482 'roll_eyes':'\ud83d\ude44', 2483 'roller_coaster':'\ud83c\udfa2', 2484 'rooster':'\ud83d\udc13', 2485 'rose':'\ud83c\udf39', 2486 'rosette':'\ud83c\udff5', 2487 'rotating_light':'\ud83d\udea8', 2488 'round_pushpin':'\ud83d\udccd', 2489 'rowing_man':'\ud83d\udea3', 2490 'rowing_woman':'\ud83d\udea3‍\u2640\ufe0f', 2491 'rugby_football':'\ud83c\udfc9', 2492 'running_man':'\ud83c\udfc3', 2493 'running_shirt_with_sash':'\ud83c\udfbd', 2494 'running_woman':'\ud83c\udfc3‍\u2640\ufe0f', 2495 'sa':'\ud83c\ude02\ufe0f', 2496 'sagittarius':'\u2650\ufe0f', 2497 'sake':'\ud83c\udf76', 2498 'sandal':'\ud83d\udc61', 2499 'santa':'\ud83c\udf85', 2500 'satellite':'\ud83d\udce1', 2501 'saxophone':'\ud83c\udfb7', 2502 'school':'\ud83c\udfeb', 2503 'school_satchel':'\ud83c\udf92', 2504 'scissors':'\u2702\ufe0f', 2505 'scorpion':'\ud83e\udd82', 2506 'scorpius':'\u264f\ufe0f', 2507 'scream':'\ud83d\ude31', 2508 'scream_cat':'\ud83d\ude40', 2509 'scroll':'\ud83d\udcdc', 2510 'seat':'\ud83d\udcba', 2511 'secret':'\u3299\ufe0f', 2512 'see_no_evil':'\ud83d\ude48', 2513 'seedling':'\ud83c\udf31', 2514 'selfie':'\ud83e\udd33', 2515 'shallow_pan_of_food':'\ud83e\udd58', 2516 'shamrock':'\u2618\ufe0f', 2517 'shark':'\ud83e\udd88', 2518 'shaved_ice':'\ud83c\udf67', 2519 'sheep':'\ud83d\udc11', 2520 'shell':'\ud83d\udc1a', 2521 'shield':'\ud83d\udee1', 2522 'shinto_shrine':'\u26e9', 2523 'ship':'\ud83d\udea2', 2524 'shirt':'\ud83d\udc55', 2525 'shopping':'\ud83d\udecd', 2526 'shopping_cart':'\ud83d\uded2', 2527 'shower':'\ud83d\udebf', 2528 'shrimp':'\ud83e\udd90', 2529 'signal_strength':'\ud83d\udcf6', 2530 'six_pointed_star':'\ud83d\udd2f', 2531 'ski':'\ud83c\udfbf', 2532 'skier':'\u26f7', 2533 'skull':'\ud83d\udc80', 2534 'skull_and_crossbones':'\u2620\ufe0f', 2535 'sleeping':'\ud83d\ude34', 2536 'sleeping_bed':'\ud83d\udecc', 2537 'sleepy':'\ud83d\ude2a', 2538 'slightly_frowning_face':'\ud83d\ude41', 2539 'slightly_smiling_face':'\ud83d\ude42', 2540 'slot_machine':'\ud83c\udfb0', 2541 'small_airplane':'\ud83d\udee9', 2542 'small_blue_diamond':'\ud83d\udd39', 2543 'small_orange_diamond':'\ud83d\udd38', 2544 'small_red_triangle':'\ud83d\udd3a', 2545 'small_red_triangle_down':'\ud83d\udd3b', 2546 'smile':'\ud83d\ude04', 2547 'smile_cat':'\ud83d\ude38', 2548 'smiley':'\ud83d\ude03', 2549 'smiley_cat':'\ud83d\ude3a', 2550 'smiling_imp':'\ud83d\ude08', 2551 'smirk':'\ud83d\ude0f', 2552 'smirk_cat':'\ud83d\ude3c', 2553 'smoking':'\ud83d\udeac', 2554 'snail':'\ud83d\udc0c', 2555 'snake':'\ud83d\udc0d', 2556 'sneezing_face':'\ud83e\udd27', 2557 'snowboarder':'\ud83c\udfc2', 2558 'snowflake':'\u2744\ufe0f', 2559 'snowman':'\u26c4\ufe0f', 2560 'snowman_with_snow':'\u2603\ufe0f', 2561 'sob':'\ud83d\ude2d', 2562 'soccer':'\u26bd\ufe0f', 2563 'soon':'\ud83d\udd1c', 2564 'sos':'\ud83c\udd98', 2565 'sound':'\ud83d\udd09', 2566 'space_invader':'\ud83d\udc7e', 2567 'spades':'\u2660\ufe0f', 2568 'spaghetti':'\ud83c\udf5d', 2569 'sparkle':'\u2747\ufe0f', 2570 'sparkler':'\ud83c\udf87', 2571 'sparkles':'\u2728', 2572 'sparkling_heart':'\ud83d\udc96', 2573 'speak_no_evil':'\ud83d\ude4a', 2574 'speaker':'\ud83d\udd08', 2575 'speaking_head':'\ud83d\udde3', 2576 'speech_balloon':'\ud83d\udcac', 2577 'speedboat':'\ud83d\udea4', 2578 'spider':'\ud83d\udd77', 2579 'spider_web':'\ud83d\udd78', 2580 'spiral_calendar':'\ud83d\uddd3', 2581 'spiral_notepad':'\ud83d\uddd2', 2582 'spoon':'\ud83e\udd44', 2583 'squid':'\ud83e\udd91', 2584 'stadium':'\ud83c\udfdf', 2585 'star':'\u2b50\ufe0f', 2586 'star2':'\ud83c\udf1f', 2587 'star_and_crescent':'\u262a\ufe0f', 2588 'star_of_david':'\u2721\ufe0f', 2589 'stars':'\ud83c\udf20', 2590 'station':'\ud83d\ude89', 2591 'statue_of_liberty':'\ud83d\uddfd', 2592 'steam_locomotive':'\ud83d\ude82', 2593 'stew':'\ud83c\udf72', 2594 'stop_button':'\u23f9', 2595 'stop_sign':'\ud83d\uded1', 2596 'stopwatch':'\u23f1', 2597 'straight_ruler':'\ud83d\udccf', 2598 'strawberry':'\ud83c\udf53', 2599 'stuck_out_tongue':'\ud83d\ude1b', 2600 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d', 2601 'stuck_out_tongue_winking_eye':'\ud83d\ude1c', 2602 'studio_microphone':'\ud83c\udf99', 2603 'stuffed_flatbread':'\ud83e\udd59', 2604 'sun_behind_large_cloud':'\ud83c\udf25', 2605 'sun_behind_rain_cloud':'\ud83c\udf26', 2606 'sun_behind_small_cloud':'\ud83c\udf24', 2607 'sun_with_face':'\ud83c\udf1e', 2608 'sunflower':'\ud83c\udf3b', 2609 'sunglasses':'\ud83d\ude0e', 2610 'sunny':'\u2600\ufe0f', 2611 'sunrise':'\ud83c\udf05', 2612 'sunrise_over_mountains':'\ud83c\udf04', 2613 'surfing_man':'\ud83c\udfc4', 2614 'surfing_woman':'\ud83c\udfc4‍\u2640\ufe0f', 2615 'sushi':'\ud83c\udf63', 2616 'suspension_railway':'\ud83d\ude9f', 2617 'sweat':'\ud83d\ude13', 2618 'sweat_drops':'\ud83d\udca6', 2619 'sweat_smile':'\ud83d\ude05', 2620 'sweet_potato':'\ud83c\udf60', 2621 'swimming_man':'\ud83c\udfca', 2622 'swimming_woman':'\ud83c\udfca‍\u2640\ufe0f', 2623 'symbols':'\ud83d\udd23', 2624 'synagogue':'\ud83d\udd4d', 2625 'syringe':'\ud83d\udc89', 2626 'taco':'\ud83c\udf2e', 2627 'tada':'\ud83c\udf89', 2628 'tanabata_tree':'\ud83c\udf8b', 2629 'taurus':'\u2649\ufe0f', 2630 'taxi':'\ud83d\ude95', 2631 'tea':'\ud83c\udf75', 2632 'telephone_receiver':'\ud83d\udcde', 2633 'telescope':'\ud83d\udd2d', 2634 'tennis':'\ud83c\udfbe', 2635 'tent':'\u26fa\ufe0f', 2636 'thermometer':'\ud83c\udf21', 2637 'thinking':'\ud83e\udd14', 2638 'thought_balloon':'\ud83d\udcad', 2639 'ticket':'\ud83c\udfab', 2640 'tickets':'\ud83c\udf9f', 2641 'tiger':'\ud83d\udc2f', 2642 'tiger2':'\ud83d\udc05', 2643 'timer_clock':'\u23f2', 2644 'tipping_hand_man':'\ud83d\udc81‍\u2642\ufe0f', 2645 'tired_face':'\ud83d\ude2b', 2646 'tm':'\u2122\ufe0f', 2647 'toilet':'\ud83d\udebd', 2648 'tokyo_tower':'\ud83d\uddfc', 2649 'tomato':'\ud83c\udf45', 2650 'tongue':'\ud83d\udc45', 2651 'top':'\ud83d\udd1d', 2652 'tophat':'\ud83c\udfa9', 2653 'tornado':'\ud83c\udf2a', 2654 'trackball':'\ud83d\uddb2', 2655 'tractor':'\ud83d\ude9c', 2656 'traffic_light':'\ud83d\udea5', 2657 'train':'\ud83d\ude8b', 2658 'train2':'\ud83d\ude86', 2659 'tram':'\ud83d\ude8a', 2660 'triangular_flag_on_post':'\ud83d\udea9', 2661 'triangular_ruler':'\ud83d\udcd0', 2662 'trident':'\ud83d\udd31', 2663 'triumph':'\ud83d\ude24', 2664 'trolleybus':'\ud83d\ude8e', 2665 'trophy':'\ud83c\udfc6', 2666 'tropical_drink':'\ud83c\udf79', 2667 'tropical_fish':'\ud83d\udc20', 2668 'truck':'\ud83d\ude9a', 2669 'trumpet':'\ud83c\udfba', 2670 'tulip':'\ud83c\udf37', 2671 'tumbler_glass':'\ud83e\udd43', 2672 'turkey':'\ud83e\udd83', 2673 'turtle':'\ud83d\udc22', 2674 'tv':'\ud83d\udcfa', 2675 'twisted_rightwards_arrows':'\ud83d\udd00', 2676 'two_hearts':'\ud83d\udc95', 2677 'two_men_holding_hands':'\ud83d\udc6c', 2678 'two_women_holding_hands':'\ud83d\udc6d', 2679 'u5272':'\ud83c\ude39', 2680 'u5408':'\ud83c\ude34', 2681 'u55b6':'\ud83c\ude3a', 2682 'u6307':'\ud83c\ude2f\ufe0f', 2683 'u6708':'\ud83c\ude37\ufe0f', 2684 'u6709':'\ud83c\ude36', 2685 'u6e80':'\ud83c\ude35', 2686 'u7121':'\ud83c\ude1a\ufe0f', 2687 'u7533':'\ud83c\ude38', 2688 'u7981':'\ud83c\ude32', 2689 'u7a7a':'\ud83c\ude33', 2690 'umbrella':'\u2614\ufe0f', 2691 'unamused':'\ud83d\ude12', 2692 'underage':'\ud83d\udd1e', 2693 'unicorn':'\ud83e\udd84', 2694 'unlock':'\ud83d\udd13', 2695 'up':'\ud83c\udd99', 2696 'upside_down_face':'\ud83d\ude43', 2697 'v':'\u270c\ufe0f', 2698 'vertical_traffic_light':'\ud83d\udea6', 2699 'vhs':'\ud83d\udcfc', 2700 'vibration_mode':'\ud83d\udcf3', 2701 'video_camera':'\ud83d\udcf9', 2702 'video_game':'\ud83c\udfae', 2703 'violin':'\ud83c\udfbb', 2704 'virgo':'\u264d\ufe0f', 2705 'volcano':'\ud83c\udf0b', 2706 'volleyball':'\ud83c\udfd0', 2707 'vs':'\ud83c\udd9a', 2708 'vulcan_salute':'\ud83d\udd96', 2709 'walking_man':'\ud83d\udeb6', 2710 'walking_woman':'\ud83d\udeb6‍\u2640\ufe0f', 2711 'waning_crescent_moon':'\ud83c\udf18', 2712 'waning_gibbous_moon':'\ud83c\udf16', 2713 'warning':'\u26a0\ufe0f', 2714 'wastebasket':'\ud83d\uddd1', 2715 'watch':'\u231a\ufe0f', 2716 'water_buffalo':'\ud83d\udc03', 2717 'watermelon':'\ud83c\udf49', 2718 'wave':'\ud83d\udc4b', 2719 'wavy_dash':'\u3030\ufe0f', 2720 'waxing_crescent_moon':'\ud83c\udf12', 2721 'wc':'\ud83d\udebe', 2722 'weary':'\ud83d\ude29', 2723 'wedding':'\ud83d\udc92', 2724 'weight_lifting_man':'\ud83c\udfcb\ufe0f', 2725 'weight_lifting_woman':'\ud83c\udfcb\ufe0f‍\u2640\ufe0f', 2726 'whale':'\ud83d\udc33', 2727 'whale2':'\ud83d\udc0b', 2728 'wheel_of_dharma':'\u2638\ufe0f', 2729 'wheelchair':'\u267f\ufe0f', 2730 'white_check_mark':'\u2705', 2731 'white_circle':'\u26aa\ufe0f', 2732 'white_flag':'\ud83c\udff3\ufe0f', 2733 'white_flower':'\ud83d\udcae', 2734 'white_large_square':'\u2b1c\ufe0f', 2735 'white_medium_small_square':'\u25fd\ufe0f', 2736 'white_medium_square':'\u25fb\ufe0f', 2737 'white_small_square':'\u25ab\ufe0f', 2738 'white_square_button':'\ud83d\udd33', 2739 'wilted_flower':'\ud83e\udd40', 2740 'wind_chime':'\ud83c\udf90', 2741 'wind_face':'\ud83c\udf2c', 2742 'wine_glass':'\ud83c\udf77', 2743 'wink':'\ud83d\ude09', 2744 'wolf':'\ud83d\udc3a', 2745 'woman':'\ud83d\udc69', 2746 'woman_artist':'\ud83d\udc69‍\ud83c\udfa8', 2747 'woman_astronaut':'\ud83d\udc69‍\ud83d\ude80', 2748 'woman_cartwheeling':'\ud83e\udd38‍\u2640\ufe0f', 2749 'woman_cook':'\ud83d\udc69‍\ud83c\udf73', 2750 'woman_facepalming':'\ud83e\udd26‍\u2640\ufe0f', 2751 'woman_factory_worker':'\ud83d\udc69‍\ud83c\udfed', 2752 'woman_farmer':'\ud83d\udc69‍\ud83c\udf3e', 2753 'woman_firefighter':'\ud83d\udc69‍\ud83d\ude92', 2754 'woman_health_worker':'\ud83d\udc69‍\u2695\ufe0f', 2755 'woman_judge':'\ud83d\udc69‍\u2696\ufe0f', 2756 'woman_juggling':'\ud83e\udd39‍\u2640\ufe0f', 2757 'woman_mechanic':'\ud83d\udc69‍\ud83d\udd27', 2758 'woman_office_worker':'\ud83d\udc69‍\ud83d\udcbc', 2759 'woman_pilot':'\ud83d\udc69‍\u2708\ufe0f', 2760 'woman_playing_handball':'\ud83e\udd3e‍\u2640\ufe0f', 2761 'woman_playing_water_polo':'\ud83e\udd3d‍\u2640\ufe0f', 2762 'woman_scientist':'\ud83d\udc69‍\ud83d\udd2c', 2763 'woman_shrugging':'\ud83e\udd37‍\u2640\ufe0f', 2764 'woman_singer':'\ud83d\udc69‍\ud83c\udfa4', 2765 'woman_student':'\ud83d\udc69‍\ud83c\udf93', 2766 'woman_teacher':'\ud83d\udc69‍\ud83c\udfeb', 2767 'woman_technologist':'\ud83d\udc69‍\ud83d\udcbb', 2768 'woman_with_turban':'\ud83d\udc73‍\u2640\ufe0f', 2769 'womans_clothes':'\ud83d\udc5a', 2770 'womans_hat':'\ud83d\udc52', 2771 'women_wrestling':'\ud83e\udd3c‍\u2640\ufe0f', 2772 'womens':'\ud83d\udeba', 2773 'world_map':'\ud83d\uddfa', 2774 'worried':'\ud83d\ude1f', 2775 'wrench':'\ud83d\udd27', 2776 'writing_hand':'\u270d\ufe0f', 2777 'x':'\u274c', 2778 'yellow_heart':'\ud83d\udc9b', 2779 'yen':'\ud83d\udcb4', 2780 'yin_yang':'\u262f\ufe0f', 2781 'yum':'\ud83d\ude0b', 2782 'zap':'\u26a1\ufe0f', 2783 'zipper_mouth_face':'\ud83e\udd10', 2784 'zzz':'\ud83d\udca4', 2785 2786 /* special emojis :P */ 2787 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">', 2788 '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>' 2789 }; 2790 2791 /** 2792 * Created by Estevao on 31-05-2015. 2793 */ 2794 2795 /** 2796 * Showdown Converter class 2797 * @class 2798 * @param {object} [converterOptions] 2799 * @returns {Converter} 2800 */ 2801 showdown.Converter = function (converterOptions) { 2802 'use strict'; 2803 2804 var 2805 /** 2806 * Options used by this converter 2807 * @private 2808 * @type {{}} 2809 */ 2810 options = {}, 2811 2812 /** 2813 * Language extensions used by this converter 2814 * @private 2815 * @type {Array} 2816 */ 2817 langExtensions = [], 2818 2819 /** 2820 * Output modifiers extensions used by this converter 2821 * @private 2822 * @type {Array} 2823 */ 2824 outputModifiers = [], 2825 2826 /** 2827 * Event listeners 2828 * @private 2829 * @type {{}} 2830 */ 2831 listeners = {}, 2832 2833 /** 2834 * The flavor set in this converter 2835 */ 2836 setConvFlavor = setFlavor, 2837 2838 /** 2839 * Metadata of the document 2840 * @type {{parsed: {}, raw: string, format: string}} 2841 */ 2842 metadata = { 2843 parsed: {}, 2844 raw: '', 2845 format: '' 2846 }; 2847 2848 _constructor(); 2849 2850 /** 2851 * Converter constructor 2852 * @private 2853 */ 2854 function _constructor () { 2855 converterOptions = converterOptions || {}; 2856 2857 for (var gOpt in globalOptions) { 2858 if (globalOptions.hasOwnProperty(gOpt)) { 2859 options[gOpt] = globalOptions[gOpt]; 2860 } 2861 } 2862 2863 // Merge options 2864 if (typeof converterOptions === 'object') { 2865 for (var opt in converterOptions) { 2866 if (converterOptions.hasOwnProperty(opt)) { 2867 options[opt] = converterOptions[opt]; 2868 } 2869 } 2870 } else { 2871 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + 2872 ' was passed instead.'); 2873 } 2874 2875 if (options.extensions) { 2876 showdown.helper.forEach(options.extensions, _parseExtension); 2877 } 2878 } 2879 2880 /** 2881 * Parse extension 2882 * @param {*} ext 2883 * @param {string} [name=''] 2884 * @private 2885 */ 2886 function _parseExtension (ext, name) { 2887 2888 name = name || null; 2889 // If it's a string, the extension was previously loaded 2890 if (showdown.helper.isString(ext)) { 2891 ext = showdown.helper.stdExtName(ext); 2892 name = ext; 2893 2894 // LEGACY_SUPPORT CODE 2895 if (showdown.extensions[ext]) { 2896 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + 2897 'Please inform the developer that the extension should be updated!'); 2898 legacyExtensionLoading(showdown.extensions[ext], ext); 2899 return; 2900 // END LEGACY SUPPORT CODE 2901 2902 } else if (!showdown.helper.isUndefined(extensions[ext])) { 2903 ext = extensions[ext]; 2904 2905 } else { 2906 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); 2907 } 2908 } 2909 2910 if (typeof ext === 'function') { 2911 ext = ext(); 2912 } 2913 2914 if (!showdown.helper.isArray(ext)) { 2915 ext = [ext]; 2916 } 2917 2918 var validExt = validate(ext, name); 2919 if (!validExt.valid) { 2920 throw Error(validExt.error); 2921 } 2922 2923 for (var i = 0; i < ext.length; ++i) { 2924 switch (ext[i].type) { 2925 2926 case 'lang': 2927 langExtensions.push(ext[i]); 2928 break; 2929 2930 case 'output': 2931 outputModifiers.push(ext[i]); 2932 break; 2933 } 2934 if (ext[i].hasOwnProperty('listeners')) { 2935 for (var ln in ext[i].listeners) { 2936 if (ext[i].listeners.hasOwnProperty(ln)) { 2937 listen(ln, ext[i].listeners[ln]); 2938 } 2939 } 2940 } 2941 } 2942 2943 } 2944 2945 /** 2946 * LEGACY_SUPPORT 2947 * @param {*} ext 2948 * @param {string} name 2949 */ 2950 function legacyExtensionLoading (ext, name) { 2951 if (typeof ext === 'function') { 2952 ext = ext(new showdown.Converter()); 2953 } 2954 if (!showdown.helper.isArray(ext)) { 2955 ext = [ext]; 2956 } 2957 var valid = validate(ext, name); 2958 2959 if (!valid.valid) { 2960 throw Error(valid.error); 2961 } 2962 2963 for (var i = 0; i < ext.length; ++i) { 2964 switch (ext[i].type) { 2965 case 'lang': 2966 langExtensions.push(ext[i]); 2967 break; 2968 case 'output': 2969 outputModifiers.push(ext[i]); 2970 break; 2971 default:// should never reach here 2972 throw Error('Extension loader error: Type unrecognized!!!'); 2973 } 2974 } 2975 } 2976 2977 /** 2978 * Listen to an event 2979 * @param {string} name 2980 * @param {function} callback 2981 */ 2982 function listen (name, callback) { 2983 if (!showdown.helper.isString(name)) { 2984 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); 2985 } 2986 2987 if (typeof callback !== 'function') { 2988 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); 2989 } 2990 2991 if (!listeners.hasOwnProperty(name)) { 2992 listeners[name] = []; 2993 } 2994 listeners[name].push(callback); 2995 } 2996 2997 function rTrimInputText (text) { 2998 var rsp = text.match(/^\s*/)[0].length, 2999 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); 3000 return text.replace(rgx, ''); 3001 } 3002 3003 /** 3004 * Dispatch an event 3005 * @private 3006 * @param {string} evtName Event name 3007 * @param {string} text Text 3008 * @param {{}} options Converter Options 3009 * @param {{}} globals 3010 * @returns {string} 3011 */ 3012 this._dispatch = function dispatch (evtName, text, options, globals) { 3013 if (listeners.hasOwnProperty(evtName)) { 3014 for (var ei = 0; ei < listeners[evtName].length; ++ei) { 3015 var nText = listeners[evtName][ei](evtName, text, this, options, globals); 3016 if (nText && typeof nText !== 'undefined') { 3017 text = nText; 3018 } 3019 } 3020 } 3021 return text; 3022 }; 3023 3024 /** 3025 * Listen to an event 3026 * @param {string} name 3027 * @param {function} callback 3028 * @returns {showdown.Converter} 3029 */ 3030 this.listen = function (name, callback) { 3031 listen(name, callback); 3032 return this; 3033 }; 3034 3035 /** 3036 * Converts a markdown string into HTML 3037 * @param {string} text 3038 * @returns {*} 3039 */ 3040 this.makeHtml = function (text) { 3041 //check if text is not falsy 3042 if (!text) { 3043 return text; 3044 } 3045 3046 var globals = { 3047 gHtmlBlocks: [], 3048 gHtmlMdBlocks: [], 3049 gHtmlSpans: [], 3050 gUrls: {}, 3051 gTitles: {}, 3052 gDimensions: {}, 3053 gListLevel: 0, 3054 hashLinkCounts: {}, 3055 langExtensions: langExtensions, 3056 outputModifiers: outputModifiers, 3057 converter: this, 3058 ghCodeBlocks: [], 3059 metadata: { 3060 parsed: {}, 3061 raw: '', 3062 format: '' 3063 } 3064 }; 3065 3066 // This lets us use ¨ trema as an escape char to avoid md5 hashes 3067 // The choice of character is arbitrary; anything that isn't 3068 // magic in Markdown will work. 3069 text = text.replace(/¨/g, '¨T'); 3070 3071 // Replace $ with ¨D 3072 // RegExp interprets $ as a special character 3073 // when it's in a replacement string 3074 text = text.replace(/\$/g, '¨D'); 3075 3076 // Standardize line endings 3077 text = text.replace(/\r\n/g, '\n'); // DOS to Unix 3078 text = text.replace(/\r/g, '\n'); // Mac to Unix 3079 3080 // Stardardize line spaces 3081 text = text.replace(/\u00A0/g, ' '); 3082 3083 if (options.smartIndentationFix) { 3084 text = rTrimInputText(text); 3085 } 3086 3087 // Make sure text begins and ends with a couple of newlines: 3088 text = '\n\n' + text + '\n\n'; 3089 3090 // detab 3091 text = showdown.subParser('detab')(text, options, globals); 3092 3093 /** 3094 * Strip any lines consisting only of spaces and tabs. 3095 * This makes subsequent regexs easier to write, because we can 3096 * match consecutive blank lines with /\n+/ instead of something 3097 * contorted like /[ \t]*\n+/ 3098 */ 3099 text = text.replace(/^[ \t]+$/mg, ''); 3100 3101 //run languageExtensions 3102 showdown.helper.forEach(langExtensions, function (ext) { 3103 text = showdown.subParser('runExtension')(ext, text, options, globals); 3104 }); 3105 3106 // run the sub parsers 3107 text = showdown.subParser('metadata')(text, options, globals); 3108 text = showdown.subParser('hashPreCodeTags')(text, options, globals); 3109 text = showdown.subParser('githubCodeBlocks')(text, options, globals); 3110 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3111 text = showdown.subParser('hashCodeTags')(text, options, globals); 3112 text = showdown.subParser('stripLinkDefinitions')(text, options, globals); 3113 text = showdown.subParser('blockGamut')(text, options, globals); 3114 text = showdown.subParser('unhashHTMLSpans')(text, options, globals); 3115 text = showdown.subParser('unescapeSpecialChars')(text, options, globals); 3116 3117 // attacklab: Restore dollar signs 3118 text = text.replace(/¨D/g, '$$'); 3119 3120 // attacklab: Restore tremas 3121 text = text.replace(/¨T/g, '¨'); 3122 3123 // render a complete html document instead of a partial if the option is enabled 3124 text = showdown.subParser('completeHTMLDocument')(text, options, globals); 3125 3126 // Run output modifiers 3127 showdown.helper.forEach(outputModifiers, function (ext) { 3128 text = showdown.subParser('runExtension')(ext, text, options, globals); 3129 }); 3130 3131 // update metadata 3132 metadata = globals.metadata; 3133 return text; 3134 }; 3135 3136 /** 3137 * Converts an HTML string into a markdown string 3138 * @param src 3139 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used. 3140 * @returns {string} 3141 */ 3142 this.makeMarkdown = this.makeMd = function (src, HTMLParser) { 3143 3144 // replace \r\n with \n 3145 src = src.replace(/\r\n/g, '\n'); 3146 src = src.replace(/\r/g, '\n'); // old macs 3147 3148 // due to an edge case, we need to find this: > < 3149 // to prevent removing of non silent white spaces 3150 // ex: <em>this is</em> <strong>sparta</strong> 3151 src = src.replace(/>[ \t]+</, '>¨NBSP;<'); 3152 3153 if (!HTMLParser) { 3154 if (window && window.document) { 3155 HTMLParser = window.document; 3156 } else { 3157 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'); 3158 } 3159 } 3160 3161 var doc = HTMLParser.createElement('div'); 3162 doc.innerHTML = src; 3163 3164 var globals = { 3165 preList: substitutePreCodeTags(doc) 3166 }; 3167 3168 // remove all newlines and collapse spaces 3169 clean(doc); 3170 3171 // some stuff, like accidental reference links must now be escaped 3172 // TODO 3173 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/); 3174 3175 var nodes = doc.childNodes, 3176 mdDoc = ''; 3177 3178 for (var i = 0; i < nodes.length; i++) { 3179 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals); 3180 } 3181 3182 function clean (node) { 3183 for (var n = 0; n < node.childNodes.length; ++n) { 3184 var child = node.childNodes[n]; 3185 if (child.nodeType === 3) { 3186 if (!/\S/.test(child.nodeValue)) { 3187 node.removeChild(child); 3188 --n; 3189 } else { 3190 child.nodeValue = child.nodeValue.split('\n').join(' '); 3191 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1'); 3192 } 3193 } else if (child.nodeType === 1) { 3194 clean(child); 3195 } 3196 } 3197 } 3198 3199 // find all pre tags and replace contents with placeholder 3200 // we need this so that we can remove all indentation from html 3201 // to ease up parsing 3202 function substitutePreCodeTags (doc) { 3203 3204 var pres = doc.querySelectorAll('pre'), 3205 presPH = []; 3206 3207 for (var i = 0; i < pres.length; ++i) { 3208 3209 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') { 3210 var content = pres[i].firstChild.innerHTML.trim(), 3211 language = pres[i].firstChild.getAttribute('data-language') || ''; 3212 3213 // if data-language attribute is not defined, then we look for class language-* 3214 if (language === '') { 3215 var classes = pres[i].firstChild.className.split(' '); 3216 for (var c = 0; c < classes.length; ++c) { 3217 var matches = classes[c].match(/^language-(.+)$/); 3218 if (matches !== null) { 3219 language = matches[1]; 3220 break; 3221 } 3222 } 3223 } 3224 3225 // unescape html entities in content 3226 content = showdown.helper.unescapeHTMLEntities(content); 3227 3228 presPH.push(content); 3229 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>'; 3230 } else { 3231 presPH.push(pres[i].innerHTML); 3232 pres[i].innerHTML = ''; 3233 pres[i].setAttribute('prenum', i.toString()); 3234 } 3235 } 3236 return presPH; 3237 } 3238 3239 return mdDoc; 3240 }; 3241 3242 /** 3243 * Set an option of this Converter instance 3244 * @param {string} key 3245 * @param {*} value 3246 */ 3247 this.setOption = function (key, value) { 3248 options[key] = value; 3249 }; 3250 3251 /** 3252 * Get the option of this Converter instance 3253 * @param {string} key 3254 * @returns {*} 3255 */ 3256 this.getOption = function (key) { 3257 return options[key]; 3258 }; 3259 3260 /** 3261 * Get the options of this Converter instance 3262 * @returns {{}} 3263 */ 3264 this.getOptions = function () { 3265 return options; 3266 }; 3267 3268 /** 3269 * Add extension to THIS converter 3270 * @param {{}} extension 3271 * @param {string} [name=null] 3272 */ 3273 this.addExtension = function (extension, name) { 3274 name = name || null; 3275 _parseExtension(extension, name); 3276 }; 3277 3278 /** 3279 * Use a global registered extension with THIS converter 3280 * @param {string} extensionName Name of the previously registered extension 3281 */ 3282 this.useExtension = function (extensionName) { 3283 _parseExtension(extensionName); 3284 }; 3285 3286 /** 3287 * Set the flavor THIS converter should use 3288 * @param {string} name 3289 */ 3290 this.setFlavor = function (name) { 3291 if (!flavor.hasOwnProperty(name)) { 3292 throw Error(name + ' flavor was not found'); 3293 } 3294 var preset = flavor[name]; 3295 setConvFlavor = name; 3296 for (var option in preset) { 3297 if (preset.hasOwnProperty(option)) { 3298 options[option] = preset[option]; 3299 } 3300 } 3301 }; 3302 3303 /** 3304 * Get the currently set flavor of this converter 3305 * @returns {string} 3306 */ 3307 this.getFlavor = function () { 3308 return setConvFlavor; 3309 }; 3310 3311 /** 3312 * Remove an extension from THIS converter. 3313 * Note: This is a costly operation. It's better to initialize a new converter 3314 * and specify the extensions you wish to use 3315 * @param {Array} extension 3316 */ 3317 this.removeExtension = function (extension) { 3318 if (!showdown.helper.isArray(extension)) { 3319 extension = [extension]; 3320 } 3321 for (var a = 0; a < extension.length; ++a) { 3322 var ext = extension[a]; 3323 for (var i = 0; i < langExtensions.length; ++i) { 3324 if (langExtensions[i] === ext) { 3325 langExtensions[i].splice(i, 1); 3326 } 3327 } 3328 for (var ii = 0; ii < outputModifiers.length; ++i) { 3329 if (outputModifiers[ii] === ext) { 3330 outputModifiers[ii].splice(i, 1); 3331 } 3332 } 3333 } 3334 }; 3335 3336 /** 3337 * Get all extension of THIS converter 3338 * @returns {{language: Array, output: Array}} 3339 */ 3340 this.getAllExtensions = function () { 3341 return { 3342 language: langExtensions, 3343 output: outputModifiers 3344 }; 3345 }; 3346 3347 /** 3348 * Get the metadata of the previously parsed document 3349 * @param raw 3350 * @returns {string|{}} 3351 */ 3352 this.getMetadata = function (raw) { 3353 if (raw) { 3354 return metadata.raw; 3355 } else { 3356 return metadata.parsed; 3357 } 3358 }; 3359 3360 /** 3361 * Get the metadata format of the previously parsed document 3362 * @returns {string} 3363 */ 3364 this.getMetadataFormat = function () { 3365 return metadata.format; 3366 }; 3367 3368 /** 3369 * Private: set a single key, value metadata pair 3370 * @param {string} key 3371 * @param {string} value 3372 */ 3373 this._setMetadataPair = function (key, value) { 3374 metadata.parsed[key] = value; 3375 }; 3376 3377 /** 3378 * Private: set metadata format 3379 * @param {string} format 3380 */ 3381 this._setMetadataFormat = function (format) { 3382 metadata.format = format; 3383 }; 3384 3385 /** 3386 * Private: set metadata raw text 3387 * @param {string} raw 3388 */ 3389 this._setMetadataRaw = function (raw) { 3390 metadata.raw = raw; 3391 }; 3392 }; 3393 3394 /** 3395 * Turn Markdown link shortcuts into XHTML <a> tags. 3396 */ 3397 showdown.subParser('anchors', function (text, options, globals) { 3398 'use strict'; 3399 3400 text = globals.converter._dispatch('anchors.before', text, options, globals); 3401 3402 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { 3403 if (showdown.helper.isUndefined(title)) { 3404 title = ''; 3405 } 3406 linkId = linkId.toLowerCase(); 3407 3408 // Special case for explicit empty url 3409 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 3410 url = ''; 3411 } else if (!url) { 3412 if (!linkId) { 3413 // lower-case and turn embedded newlines into spaces 3414 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); 3415 } 3416 url = '#' + linkId; 3417 3418 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { 3419 url = globals.gUrls[linkId]; 3420 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { 3421 title = globals.gTitles[linkId]; 3422 } 3423 } else { 3424 return wholeMatch; 3425 } 3426 } 3427 3428 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance 3429 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3430 3431 var result = '<a href="' + url + '"'; 3432 3433 if (title !== '' && title !== null) { 3434 title = title.replace(/"/g, '"'); 3435 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance 3436 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3437 result += ' title="' + title + '"'; 3438 } 3439 3440 // optionLinksInNewWindow only applies 3441 // to external links. Hash links (#) open in same page 3442 if (options.openLinksInNewWindow && !/^#/.test(url)) { 3443 // escaped _ 3444 result += ' rel="noopener noreferrer" target="¨E95Eblank"'; 3445 } 3446 3447 result += '>' + linkText + '</a>'; 3448 3449 return result; 3450 }; 3451 3452 // First, handle reference-style links: [link text] [id] 3453 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); 3454 3455 // Next, inline-style links: [link text](url "optional title") 3456 // cases with crazy urls like ./image/cat1).png 3457 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3458 writeAnchorTag); 3459 3460 // normal cases 3461 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3462 writeAnchorTag); 3463 3464 // handle reference-style shortcuts: [link text] 3465 // These must come last in case you've also got [link test][1] 3466 // or [link test](/foo) 3467 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); 3468 3469 // Lastly handle GithubMentions if option is enabled 3470 if (options.ghMentions) { 3471 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) { 3472 if (escape === '\\') { 3473 return st + mentions; 3474 } 3475 3476 //check if options.ghMentionsLink is a string 3477 if (!showdown.helper.isString(options.ghMentionsLink)) { 3478 throw new Error('ghMentionsLink option must be a string'); 3479 } 3480 var lnk = options.ghMentionsLink.replace(/\{u}/g, username), 3481 target = ''; 3482 if (options.openLinksInNewWindow) { 3483 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3484 } 3485 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>'; 3486 }); 3487 } 3488 3489 text = globals.converter._dispatch('anchors.after', text, options, globals); 3490 return text; 3491 }); 3492 3493 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] 3494 3495 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, 3496 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, 3497 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, 3498 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi, 3499 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 3500 3501 replaceLink = function (options) { 3502 'use strict'; 3503 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) { 3504 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3505 var lnkTxt = link, 3506 append = '', 3507 target = '', 3508 lmc = leadingMagicChars || '', 3509 tmc = trailingMagicChars || ''; 3510 if (/^www\./i.test(link)) { 3511 link = link.replace(/^www\./i, 'http://www.'); 3512 } 3513 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) { 3514 append = trailingPunctuation; 3515 } 3516 if (options.openLinksInNewWindow) { 3517 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3518 } 3519 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc; 3520 }; 3521 }, 3522 3523 replaceMail = function (options, globals) { 3524 'use strict'; 3525 return function (wholeMatch, b, mail) { 3526 var href = 'mailto:'; 3527 b = b || ''; 3528 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals); 3529 if (options.encodeEmails) { 3530 href = showdown.helper.encodeEmailAddress(href + mail); 3531 mail = showdown.helper.encodeEmailAddress(mail); 3532 } else { 3533 href = href + mail; 3534 } 3535 return b + '<a href="' + href + '">' + mail + '</a>'; 3536 }; 3537 }; 3538 3539 showdown.subParser('autoLinks', function (text, options, globals) { 3540 'use strict'; 3541 3542 text = globals.converter._dispatch('autoLinks.before', text, options, globals); 3543 3544 text = text.replace(delimUrlRegex, replaceLink(options)); 3545 text = text.replace(delimMailRegex, replaceMail(options, globals)); 3546 3547 text = globals.converter._dispatch('autoLinks.after', text, options, globals); 3548 3549 return text; 3550 }); 3551 3552 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) { 3553 'use strict'; 3554 3555 if (!options.simplifiedAutoLink) { 3556 return text; 3557 } 3558 3559 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals); 3560 3561 if (options.excludeTrailingPunctuationFromURLs) { 3562 text = text.replace(simpleURLRegex2, replaceLink(options)); 3563 } else { 3564 text = text.replace(simpleURLRegex, replaceLink(options)); 3565 } 3566 text = text.replace(simpleMailRegex, replaceMail(options, globals)); 3567 3568 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals); 3569 3570 return text; 3571 }); 3572 3573 /** 3574 * These are all the transformations that form block-level 3575 * tags like paragraphs, headers, and list items. 3576 */ 3577 showdown.subParser('blockGamut', function (text, options, globals) { 3578 'use strict'; 3579 3580 text = globals.converter._dispatch('blockGamut.before', text, options, globals); 3581 3582 // we parse blockquotes first so that we can have headings and hrs 3583 // inside blockquotes 3584 text = showdown.subParser('blockQuotes')(text, options, globals); 3585 text = showdown.subParser('headers')(text, options, globals); 3586 3587 // Do Horizontal Rules: 3588 text = showdown.subParser('horizontalRule')(text, options, globals); 3589 3590 text = showdown.subParser('lists')(text, options, globals); 3591 text = showdown.subParser('codeBlocks')(text, options, globals); 3592 text = showdown.subParser('tables')(text, options, globals); 3593 3594 // We already ran _HashHTMLBlocks() before, in Markdown(), but that 3595 // was to escape raw HTML in the original Markdown source. This time, 3596 // we're escaping the markup we've just created, so that we don't wrap 3597 // <p> tags around block-level tags. 3598 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3599 text = showdown.subParser('paragraphs')(text, options, globals); 3600 3601 text = globals.converter._dispatch('blockGamut.after', text, options, globals); 3602 3603 return text; 3604 }); 3605 3606 showdown.subParser('blockQuotes', function (text, options, globals) { 3607 'use strict'; 3608 3609 text = globals.converter._dispatch('blockQuotes.before', text, options, globals); 3610 3611 // add a couple extra lines after the text and endtext mark 3612 text = text + '\n\n'; 3613 3614 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm; 3615 3616 if (options.splitAdjacentBlockquotes) { 3617 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm; 3618 } 3619 3620 text = text.replace(rgx, function (bq) { 3621 // attacklab: hack around Konqueror 3.5.4 bug: 3622 // "----------bug".replace(/^-/g,"") == "bug" 3623 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting 3624 3625 // attacklab: clean up hack 3626 bq = bq.replace(/¨0/g, ''); 3627 3628 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines 3629 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); 3630 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse 3631 3632 bq = bq.replace(/(^|\n)/g, '$1 '); 3633 // These leading spaces screw with <pre> content, so we need to fix that: 3634 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { 3635 var pre = m1; 3636 // attacklab: hack around Konqueror 3.5.4 bug: 3637 pre = pre.replace(/^ /mg, '¨0'); 3638 pre = pre.replace(/¨0/g, ''); 3639 return pre; 3640 }); 3641 3642 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); 3643 }); 3644 3645 text = globals.converter._dispatch('blockQuotes.after', text, options, globals); 3646 return text; 3647 }); 3648 3649 /** 3650 * Process Markdown `<pre><code>` blocks. 3651 */ 3652 showdown.subParser('codeBlocks', function (text, options, globals) { 3653 'use strict'; 3654 3655 text = globals.converter._dispatch('codeBlocks.before', text, options, globals); 3656 3657 // sentinel workarounds for lack of \A and \Z, safari\khtml bug 3658 text += '¨0'; 3659 3660 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g; 3661 text = text.replace(pattern, function (wholeMatch, m1, m2) { 3662 var codeblock = m1, 3663 nextChar = m2, 3664 end = '\n'; 3665 3666 codeblock = showdown.subParser('outdent')(codeblock, options, globals); 3667 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3668 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3669 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3670 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines 3671 3672 if (options.omitExtraWLInCodeBlocks) { 3673 end = ''; 3674 } 3675 3676 codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; 3677 3678 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; 3679 }); 3680 3681 // strip sentinel 3682 text = text.replace(/¨0/, ''); 3683 3684 text = globals.converter._dispatch('codeBlocks.after', text, options, globals); 3685 return text; 3686 }); 3687 3688 /** 3689 * 3690 * * Backtick quotes are used for <code></code> spans. 3691 * 3692 * * You can use multiple backticks as the delimiters if you want to 3693 * include literal backticks in the code span. So, this input: 3694 * 3695 * Just type ``foo `bar` baz`` at the prompt. 3696 * 3697 * Will translate to: 3698 * 3699 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> 3700 * 3701 * There's no arbitrary limit to the number of backticks you 3702 * can use as delimters. If you need three consecutive backticks 3703 * in your code, use four for delimiters, etc. 3704 * 3705 * * You can use spaces to get literal backticks at the edges: 3706 * 3707 * ... type `` `bar` `` ... 3708 * 3709 * Turns to: 3710 * 3711 * ... type <code>`bar`</code> ... 3712 */ 3713 showdown.subParser('codeSpans', function (text, options, globals) { 3714 'use strict'; 3715 3716 text = globals.converter._dispatch('codeSpans.before', text, options, globals); 3717 3718 if (typeof text === 'undefined') { 3719 text = ''; 3720 } 3721 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, 3722 function (wholeMatch, m1, m2, m3) { 3723 var c = m3; 3724 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace 3725 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace 3726 c = showdown.subParser('encodeCode')(c, options, globals); 3727 c = m1 + '<code>' + c + '</code>'; 3728 c = showdown.subParser('hashHTMLSpans')(c, options, globals); 3729 return c; 3730 } 3731 ); 3732 3733 text = globals.converter._dispatch('codeSpans.after', text, options, globals); 3734 return text; 3735 }); 3736 3737 /** 3738 * Create a full HTML document from the processed markdown 3739 */ 3740 showdown.subParser('completeHTMLDocument', function (text, options, globals) { 3741 'use strict'; 3742 3743 if (!options.completeHTMLDocument) { 3744 return text; 3745 } 3746 3747 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals); 3748 3749 var doctype = 'html', 3750 doctypeParsed = '<!DOCTYPE HTML>\n', 3751 title = '', 3752 charset = '<meta charset="utf-8">\n', 3753 lang = '', 3754 metadata = ''; 3755 3756 if (typeof globals.metadata.parsed.doctype !== 'undefined') { 3757 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n'; 3758 doctype = globals.metadata.parsed.doctype.toString().toLowerCase(); 3759 if (doctype === 'html' || doctype === 'html5') { 3760 charset = '<meta charset="utf-8">'; 3761 } 3762 } 3763 3764 for (var meta in globals.metadata.parsed) { 3765 if (globals.metadata.parsed.hasOwnProperty(meta)) { 3766 switch (meta.toLowerCase()) { 3767 case 'doctype': 3768 break; 3769 3770 case 'title': 3771 title = '<title>' + globals.metadata.parsed.title + '</title>\n'; 3772 break; 3773 3774 case 'charset': 3775 if (doctype === 'html' || doctype === 'html5') { 3776 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n'; 3777 } else { 3778 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n'; 3779 } 3780 break; 3781 3782 case 'language': 3783 case 'lang': 3784 lang = ' lang="' + globals.metadata.parsed[meta] + '"'; 3785 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3786 break; 3787 3788 default: 3789 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3790 } 3791 } 3792 } 3793 3794 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>'; 3795 3796 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals); 3797 return text; 3798 }); 3799 3800 /** 3801 * Convert all tabs to spaces 3802 */ 3803 showdown.subParser('detab', function (text, options, globals) { 3804 'use strict'; 3805 text = globals.converter._dispatch('detab.before', text, options, globals); 3806 3807 // expand first n-1 tabs 3808 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width 3809 3810 // replace the nth with two sentinels 3811 text = text.replace(/\t/g, '¨A¨B'); 3812 3813 // use the sentinel to anchor our regex so it doesn't explode 3814 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) { 3815 var leadingText = m1, 3816 numSpaces = 4 - leadingText.length % 4; // g_tab_width 3817 3818 // there *must* be a better way to do this: 3819 for (var i = 0; i < numSpaces; i++) { 3820 leadingText += ' '; 3821 } 3822 3823 return leadingText; 3824 }); 3825 3826 // clean up sentinels 3827 text = text.replace(/¨A/g, ' '); // g_tab_width 3828 text = text.replace(/¨B/g, ''); 3829 3830 text = globals.converter._dispatch('detab.after', text, options, globals); 3831 return text; 3832 }); 3833 3834 showdown.subParser('ellipsis', function (text, options, globals) { 3835 'use strict'; 3836 3837 text = globals.converter._dispatch('ellipsis.before', text, options, globals); 3838 3839 text = text.replace(/\.\.\./g, '…'); 3840 3841 text = globals.converter._dispatch('ellipsis.after', text, options, globals); 3842 3843 return text; 3844 }); 3845 3846 /** 3847 * Turn emoji codes into emojis 3848 * 3849 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis 3850 */ 3851 showdown.subParser('emoji', function (text, options, globals) { 3852 'use strict'; 3853 3854 if (!options.emoji) { 3855 return text; 3856 } 3857 3858 text = globals.converter._dispatch('emoji.before', text, options, globals); 3859 3860 var emojiRgx = /:([\S]+?):/g; 3861 3862 text = text.replace(emojiRgx, function (wm, emojiCode) { 3863 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) { 3864 return showdown.helper.emojis[emojiCode]; 3865 } 3866 return wm; 3867 }); 3868 3869 text = globals.converter._dispatch('emoji.after', text, options, globals); 3870 3871 return text; 3872 }); 3873 3874 /** 3875 * Smart processing for ampersands and angle brackets that need to be encoded. 3876 */ 3877 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) { 3878 'use strict'; 3879 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals); 3880 3881 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: 3882 // http://bumppo.net/projects/amputator/ 3883 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); 3884 3885 // Encode naked <'s 3886 text = text.replace(/<(?![a-z\/?$!])/gi, '<'); 3887 3888 // Encode < 3889 text = text.replace(/</g, '<'); 3890 3891 // Encode > 3892 text = text.replace(/>/g, '>'); 3893 3894 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals); 3895 return text; 3896 }); 3897 3898 /** 3899 * Returns the string, with after processing the following backslash escape sequences. 3900 * 3901 * attacklab: The polite way to do this is with the new escapeCharacters() function: 3902 * 3903 * text = escapeCharacters(text,"\\",true); 3904 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); 3905 * 3906 * ...but we're sidestepping its use of the (slow) RegExp constructor 3907 * as an optimization for Firefox. This function gets called a LOT. 3908 */ 3909 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) { 3910 'use strict'; 3911 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals); 3912 3913 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); 3914 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback); 3915 3916 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals); 3917 return text; 3918 }); 3919 3920 /** 3921 * Encode/escape certain characters inside Markdown code runs. 3922 * The point is that in code, these characters are literals, 3923 * and lose their special Markdown meanings. 3924 */ 3925 showdown.subParser('encodeCode', function (text, options, globals) { 3926 'use strict'; 3927 3928 text = globals.converter._dispatch('encodeCode.before', text, options, globals); 3929 3930 // Encode all ampersands; HTML entities are not 3931 // entities within a Markdown code span. 3932 text = text 3933 .replace(/&/g, '&') 3934 // Do the angle bracket song and dance: 3935 .replace(/</g, '<') 3936 .replace(/>/g, '>') 3937 // Now, escape characters that are magic in Markdown: 3938 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback); 3939 3940 text = globals.converter._dispatch('encodeCode.after', text, options, globals); 3941 return text; 3942 }); 3943 3944 /** 3945 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they 3946 * don't conflict with their use in Markdown for code, italics and strong. 3947 */ 3948 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) { 3949 'use strict'; 3950 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals); 3951 3952 // Build a regex to find HTML tags. 3953 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, 3954 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi; 3955 3956 text = text.replace(tags, function (wholeMatch) { 3957 return wholeMatch 3958 .replace(/(.)<\/?code>(?=.)/g, '$1`') 3959 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3960 }); 3961 3962 text = text.replace(comments, function (wholeMatch) { 3963 return wholeMatch 3964 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3965 }); 3966 3967 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals); 3968 return text; 3969 }); 3970 3971 /** 3972 * Handle github codeblocks prior to running HashHTML so that 3973 * HTML contained within the codeblock gets escaped properly 3974 * Example: 3975 * ```ruby 3976 * def hello_world(x) 3977 * puts "Hello, #{x}" 3978 * end 3979 * ``` 3980 */ 3981 showdown.subParser('githubCodeBlocks', function (text, options, globals) { 3982 'use strict'; 3983 3984 // early exit if option is not enabled 3985 if (!options.ghCodeBlocks) { 3986 return text; 3987 } 3988 3989 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); 3990 3991 text += '¨0'; 3992 3993 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) { 3994 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; 3995 3996 // First parse the github code block 3997 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3998 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3999 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 4000 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace 4001 4002 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; 4003 4004 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); 4005 4006 // Since GHCodeblocks can be false positives, we need to 4007 // store the primitive text and the parsed text in a global var, 4008 // and then return a token 4009 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 4010 }); 4011 4012 // attacklab: strip sentinel 4013 text = text.replace(/¨0/, ''); 4014 4015 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); 4016 }); 4017 4018 showdown.subParser('hashBlock', function (text, options, globals) { 4019 'use strict'; 4020 text = globals.converter._dispatch('hashBlock.before', text, options, globals); 4021 text = text.replace(/(^\n+|\n+$)/g, ''); 4022 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; 4023 text = globals.converter._dispatch('hashBlock.after', text, options, globals); 4024 return text; 4025 }); 4026 4027 /** 4028 * Hash and escape <code> elements that should not be parsed as markdown 4029 */ 4030 showdown.subParser('hashCodeTags', function (text, options, globals) { 4031 'use strict'; 4032 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals); 4033 4034 var repFunc = function (wholeMatch, match, left, right) { 4035 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 4036 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C'; 4037 }; 4038 4039 // Hash naked <code> 4040 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim'); 4041 4042 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals); 4043 return text; 4044 }); 4045 4046 showdown.subParser('hashElement', function (text, options, globals) { 4047 'use strict'; 4048 4049 return function (wholeMatch, m1) { 4050 var blockText = m1; 4051 4052 // Undo double lines 4053 blockText = blockText.replace(/\n\n/g, '\n'); 4054 blockText = blockText.replace(/^\n/, ''); 4055 4056 // strip trailing blank lines 4057 blockText = blockText.replace(/\n+$/g, ''); 4058 4059 // Replace the element text with a marker ("¨KxK" where x is its key) 4060 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; 4061 4062 return blockText; 4063 }; 4064 }); 4065 4066 showdown.subParser('hashHTMLBlocks', function (text, options, globals) { 4067 'use strict'; 4068 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals); 4069 4070 var blockTags = [ 4071 'pre', 4072 'div', 4073 'h1', 4074 'h2', 4075 'h3', 4076 'h4', 4077 'h5', 4078 'h6', 4079 'blockquote', 4080 'table', 4081 'dl', 4082 'ol', 4083 'ul', 4084 'script', 4085 'noscript', 4086 'form', 4087 'fieldset', 4088 'iframe', 4089 'math', 4090 'style', 4091 'section', 4092 'header', 4093 'footer', 4094 'nav', 4095 'article', 4096 'aside', 4097 'address', 4098 'audio', 4099 'canvas', 4100 'figure', 4101 'hgroup', 4102 'output', 4103 'video', 4104 'p' 4105 ], 4106 repFunc = function (wholeMatch, match, left, right) { 4107 var txt = wholeMatch; 4108 // check if this html element is marked as markdown 4109 // if so, it's contents should be parsed as markdown 4110 if (left.search(/\bmarkdown\b/) !== -1) { 4111 txt = left + globals.converter.makeHtml(match) + right; 4112 } 4113 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 4114 }; 4115 4116 if (options.backslashEscapesHTMLTags) { 4117 // encode backslash escaped HTML tags 4118 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) { 4119 return '<' + inside + '>'; 4120 }); 4121 } 4122 4123 // hash HTML Blocks 4124 for (var i = 0; i < blockTags.length; ++i) { 4125 4126 var opTagPos, 4127 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'), 4128 patLeft = '<' + blockTags[i] + '\\b[^>]*>', 4129 patRight = '</' + blockTags[i] + '>'; 4130 // 1. Look for the first position of the first opening HTML tag in the text 4131 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) { 4132 4133 // if the HTML tag is \ escaped, we need to escape it and break 4134 4135 4136 //2. Split the text in that position 4137 var subTexts = showdown.helper.splitAtIndex(text, opTagPos), 4138 //3. Match recursively 4139 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im'); 4140 4141 // prevent an infinite loop 4142 if (newSubText1 === subTexts[1]) { 4143 break; 4144 } 4145 text = subTexts[0].concat(newSubText1); 4146 } 4147 } 4148 // HR SPECIAL CASE 4149 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, 4150 showdown.subParser('hashElement')(text, options, globals)); 4151 4152 // Special case for standalone HTML comments 4153 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) { 4154 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 4155 }, '^ {0,3}<!--', '-->', 'gm'); 4156 4157 // PHP and ASP-style processor instructions (<?...?> and <%...%>) 4158 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, 4159 showdown.subParser('hashElement')(text, options, globals)); 4160 4161 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals); 4162 return text; 4163 }); 4164 4165 /** 4166 * Hash span elements that should not be parsed as markdown 4167 */ 4168 showdown.subParser('hashHTMLSpans', function (text, options, globals) { 4169 'use strict'; 4170 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals); 4171 4172 function hashHTMLSpan (html) { 4173 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C'; 4174 } 4175 4176 // Hash Self Closing tags 4177 text = text.replace(/<[^>]+?\/>/gi, function (wm) { 4178 return hashHTMLSpan(wm); 4179 }); 4180 4181 // Hash tags without properties 4182 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) { 4183 return hashHTMLSpan(wm); 4184 }); 4185 4186 // Hash tags with properties 4187 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) { 4188 return hashHTMLSpan(wm); 4189 }); 4190 4191 // Hash self closing tags without /> 4192 text = text.replace(/<[^>]+?>/gi, function (wm) { 4193 return hashHTMLSpan(wm); 4194 }); 4195 4196 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/ 4197 4198 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals); 4199 return text; 4200 }); 4201 4202 /** 4203 * Unhash HTML spans 4204 */ 4205 showdown.subParser('unhashHTMLSpans', function (text, options, globals) { 4206 'use strict'; 4207 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); 4208 4209 for (var i = 0; i < globals.gHtmlSpans.length; ++i) { 4210 var repText = globals.gHtmlSpans[i], 4211 // limiter to prevent infinite loop (assume 10 as limit for recurse) 4212 limit = 0; 4213 4214 while (/¨C(\d+)C/.test(repText)) { 4215 var num = RegExp.$1; 4216 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); 4217 if (limit === 10) { 4218 console.error('maximum nesting of 10 spans reached!!!'); 4219 break; 4220 } 4221 ++limit; 4222 } 4223 text = text.replace('¨C' + i + 'C', repText); 4224 } 4225 4226 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); 4227 return text; 4228 }); 4229 4230 /** 4231 * Hash and escape <pre><code> elements that should not be parsed as markdown 4232 */ 4233 showdown.subParser('hashPreCodeTags', function (text, options, globals) { 4234 'use strict'; 4235 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals); 4236 4237 var repFunc = function (wholeMatch, match, left, right) { 4238 // encode html entities 4239 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 4240 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 4241 }; 4242 4243 // Hash <pre><code> 4244 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim'); 4245 4246 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals); 4247 return text; 4248 }); 4249 4250 showdown.subParser('headers', function (text, options, globals) { 4251 'use strict'; 4252 4253 text = globals.converter._dispatch('headers.before', text, options, globals); 4254 4255 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), 4256 4257 // Set text-style headers: 4258 // Header 1 4259 // ======== 4260 // 4261 // Header 2 4262 // -------- 4263 // 4264 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, 4265 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; 4266 4267 text = text.replace(setextRegexH1, function (wholeMatch, m1) { 4268 4269 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 4270 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 4271 hLevel = headerLevelStart, 4272 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 4273 return showdown.subParser('hashBlock')(hashBlock, options, globals); 4274 }); 4275 4276 text = text.replace(setextRegexH2, function (matchFound, m1) { 4277 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 4278 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 4279 hLevel = headerLevelStart + 1, 4280 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 4281 return showdown.subParser('hashBlock')(hashBlock, options, globals); 4282 }); 4283 4284 // atx-style headers: 4285 // # Header 1 4286 // ## Header 2 4287 // ## Header 2 with closing hashes ## 4288 // ... 4289 // ###### Header 6 4290 // 4291 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm; 4292 4293 text = text.replace(atxStyle, function (wholeMatch, m1, m2) { 4294 var hText = m2; 4295 if (options.customizedHeaderId) { 4296 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, ''); 4297 } 4298 4299 var span = showdown.subParser('spanGamut')(hText, options, globals), 4300 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', 4301 hLevel = headerLevelStart - 1 + m1.length, 4302 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; 4303 4304 return showdown.subParser('hashBlock')(header, options, globals); 4305 }); 4306 4307 function headerId (m) { 4308 var title, 4309 prefix; 4310 4311 // It is separate from other options to allow combining prefix and customized 4312 if (options.customizedHeaderId) { 4313 var match = m.match(/\{([^{]+?)}\s*$/); 4314 if (match && match[1]) { 4315 m = match[1]; 4316 } 4317 } 4318 4319 title = m; 4320 4321 // Prefix id to prevent causing inadvertent pre-existing style matches. 4322 if (showdown.helper.isString(options.prefixHeaderId)) { 4323 prefix = options.prefixHeaderId; 4324 } else if (options.prefixHeaderId === true) { 4325 prefix = 'section-'; 4326 } else { 4327 prefix = ''; 4328 } 4329 4330 if (!options.rawPrefixHeaderId) { 4331 title = prefix + title; 4332 } 4333 4334 if (options.ghCompatibleHeaderId) { 4335 title = title 4336 .replace(/ /g, '-') 4337 // replace previously escaped chars (&, ¨ and $) 4338 .replace(/&/g, '') 4339 .replace(/¨T/g, '') 4340 .replace(/¨D/g, '') 4341 // replace rest of the chars (&~$ are repeated as they might have been escaped) 4342 // borrowed from github's redcarpet (some they should produce similar results) 4343 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '') 4344 .toLowerCase(); 4345 } else if (options.rawHeaderId) { 4346 title = title 4347 .replace(/ /g, '-') 4348 // replace previously escaped chars (&, ¨ and $) 4349 .replace(/&/g, '&') 4350 .replace(/¨T/g, '¨') 4351 .replace(/¨D/g, '$') 4352 // replace " and ' 4353 .replace(/["']/g, '-') 4354 .toLowerCase(); 4355 } else { 4356 title = title 4357 .replace(/[^\w]/g, '') 4358 .toLowerCase(); 4359 } 4360 4361 if (options.rawPrefixHeaderId) { 4362 title = prefix + title; 4363 } 4364 4365 if (globals.hashLinkCounts[title]) { 4366 title = title + '-' + (globals.hashLinkCounts[title]++); 4367 } else { 4368 globals.hashLinkCounts[title] = 1; 4369 } 4370 return title; 4371 } 4372 4373 text = globals.converter._dispatch('headers.after', text, options, globals); 4374 return text; 4375 }); 4376 4377 /** 4378 * Turn Markdown link shortcuts into XHTML <a> tags. 4379 */ 4380 showdown.subParser('horizontalRule', function (text, options, globals) { 4381 'use strict'; 4382 text = globals.converter._dispatch('horizontalRule.before', text, options, globals); 4383 4384 var key = showdown.subParser('hashBlock')('<hr />', options, globals); 4385 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key); 4386 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key); 4387 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key); 4388 4389 text = globals.converter._dispatch('horizontalRule.after', text, options, globals); 4390 return text; 4391 }); 4392 4393 /** 4394 * Turn Markdown image shortcuts into <img> tags. 4395 */ 4396 showdown.subParser('images', function (text, options, globals) { 4397 'use strict'; 4398 4399 text = globals.converter._dispatch('images.before', text, options, globals); 4400 4401 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, 4402 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, 4403 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, 4404 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, 4405 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; 4406 4407 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) { 4408 url = url.replace(/\s/g, ''); 4409 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title); 4410 } 4411 4412 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { 4413 4414 var gUrls = globals.gUrls, 4415 gTitles = globals.gTitles, 4416 gDims = globals.gDimensions; 4417 4418 linkId = linkId.toLowerCase(); 4419 4420 if (!title) { 4421 title = ''; 4422 } 4423 // Special case for explicit empty url 4424 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 4425 url = ''; 4426 4427 } else if (url === '' || url === null) { 4428 if (linkId === '' || linkId === null) { 4429 // lower-case and turn embedded newlines into spaces 4430 linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); 4431 } 4432 url = '#' + linkId; 4433 4434 if (!showdown.helper.isUndefined(gUrls[linkId])) { 4435 url = gUrls[linkId]; 4436 if (!showdown.helper.isUndefined(gTitles[linkId])) { 4437 title = gTitles[linkId]; 4438 } 4439 if (!showdown.helper.isUndefined(gDims[linkId])) { 4440 width = gDims[linkId].width; 4441 height = gDims[linkId].height; 4442 } 4443 } else { 4444 return wholeMatch; 4445 } 4446 } 4447 4448 altText = altText 4449 .replace(/"/g, '"') 4450 //altText = showdown.helper.escapeCharacters(altText, '*_', false); 4451 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4452 //url = showdown.helper.escapeCharacters(url, '*_', false); 4453 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4454 var result = '<img src="' + url + '" alt="' + altText + '"'; 4455 4456 if (title && showdown.helper.isString(title)) { 4457 title = title 4458 .replace(/"/g, '"') 4459 //title = showdown.helper.escapeCharacters(title, '*_', false); 4460 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4461 result += ' title="' + title + '"'; 4462 } 4463 4464 if (width && height) { 4465 width = (width === '*') ? 'auto' : width; 4466 height = (height === '*') ? 'auto' : height; 4467 4468 result += ' width="' + width + '"'; 4469 result += ' height="' + height + '"'; 4470 } 4471 4472 result += ' />'; 4473 4474 return result; 4475 } 4476 4477 // First, handle reference-style labeled images: ![alt text][id] 4478 text = text.replace(referenceRegExp, writeImageTag); 4479 4480 // Next, handle inline images: ![alt text](url =<width>x<height> "optional title") 4481 4482 // base64 encoded images 4483 text = text.replace(base64RegExp, writeImageTagBase64); 4484 4485 // cases with crazy urls like ./image/cat1).png 4486 text = text.replace(crazyRegExp, writeImageTag); 4487 4488 // normal cases 4489 text = text.replace(inlineRegExp, writeImageTag); 4490 4491 // handle reference-style shortcuts: ![img text] 4492 text = text.replace(refShortcutRegExp, writeImageTag); 4493 4494 text = globals.converter._dispatch('images.after', text, options, globals); 4495 return text; 4496 }); 4497 4498 showdown.subParser('italicsAndBold', function (text, options, globals) { 4499 'use strict'; 4500 4501 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); 4502 4503 // it's faster to have 3 separate regexes for each case than have just one 4504 // because of backtracing, in some cases, it could lead to an exponential effect 4505 // called "catastrophic backtrace". Ominous! 4506 4507 function parseInside (txt, left, right) { 4508 /* 4509 if (options.simplifiedAutoLink) { 4510 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4511 } 4512 */ 4513 return left + txt + right; 4514 } 4515 4516 // Parse underscores 4517 if (options.literalMidWordUnderscores) { 4518 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 4519 return parseInside (txt, '<strong><em>', '</em></strong>'); 4520 }); 4521 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 4522 return parseInside (txt, '<strong>', '</strong>'); 4523 }); 4524 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { 4525 return parseInside (txt, '<em>', '</em>'); 4526 }); 4527 } else { 4528 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 4529 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4530 }); 4531 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 4532 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4533 }); 4534 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { 4535 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) 4536 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4537 }); 4538 } 4539 4540 // Now parse asterisks 4541 if (options.literalMidWordAsterisks) { 4542 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) { 4543 return parseInside (txt, lead + '<strong><em>', '</em></strong>'); 4544 }); 4545 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) { 4546 return parseInside (txt, lead + '<strong>', '</strong>'); 4547 }); 4548 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) { 4549 return parseInside (txt, lead + '<em>', '</em>'); 4550 }); 4551 } else { 4552 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) { 4553 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4554 }); 4555 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) { 4556 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4557 }); 4558 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) { 4559 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it) 4560 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4561 }); 4562 } 4563 4564 4565 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); 4566 return text; 4567 }); 4568 4569 /** 4570 * Form HTML ordered (numbered) and unordered (bulleted) lists. 4571 */ 4572 showdown.subParser('lists', function (text, options, globals) { 4573 'use strict'; 4574 4575 /** 4576 * Process the contents of a single ordered or unordered list, splitting it 4577 * into individual list items. 4578 * @param {string} listStr 4579 * @param {boolean} trimTrailing 4580 * @returns {string} 4581 */ 4582 function processListItems (listStr, trimTrailing) { 4583 // The $g_list_level global keeps track of when we're inside a list. 4584 // Each time we enter a list, we increment it; when we leave a list, 4585 // we decrement. If it's zero, we're not in a list anymore. 4586 // 4587 // We do this because when we're not inside a list, we want to treat 4588 // something like this: 4589 // 4590 // I recommend upgrading to version 4591 // 8. Oops, now this line is treated 4592 // as a sub-list. 4593 // 4594 // As a single paragraph, despite the fact that the second line starts 4595 // with a digit-period-space sequence. 4596 // 4597 // Whereas when we're inside a list (or sub-list), that line will be 4598 // treated as the start of a sub-list. What a kludge, huh? This is 4599 // an aspect of Markdown's syntax that's hard to parse perfectly 4600 // without resorting to mind-reading. Perhaps the solution is to 4601 // change the syntax rules such that sub-lists must start with a 4602 // starting cardinal number; e.g. "1." or "a.". 4603 globals.gListLevel++; 4604 4605 // trim trailing blank lines: 4606 listStr = listStr.replace(/\n{2,}$/, '\n'); 4607 4608 // attacklab: add sentinel to emulate \z 4609 listStr += '¨0'; 4610 4611 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, 4612 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr)); 4613 4614 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation, 4615 // which is a syntax breaking change 4616 // activating this option reverts to old behavior 4617 if (options.disableForced4SpacesIndentedSublists) { 4618 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm; 4619 } 4620 4621 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { 4622 checked = (checked && checked.trim() !== ''); 4623 4624 var item = showdown.subParser('outdent')(m4, options, globals), 4625 bulletStyle = ''; 4626 4627 // Support for github tasklists 4628 if (taskbtn && options.tasklists) { 4629 bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; 4630 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { 4631 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; 4632 if (checked) { 4633 otp += ' checked'; 4634 } 4635 otp += '>'; 4636 return otp; 4637 }); 4638 } 4639 4640 // ISSUE #312 4641 // This input: - - - a 4642 // causes trouble to the parser, since it interprets it as: 4643 // <ul><li><li><li>a</li></li></li></ul> 4644 // instead of: 4645 // <ul><li>- - a</li></ul> 4646 // So, to prevent it, we will put a marker (¨A)in the beginning of the line 4647 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser 4648 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) { 4649 return '¨A' + wm2; 4650 }); 4651 4652 // m1 - Leading line or 4653 // Has a double return (multi paragraph) or 4654 // Has sublist 4655 if (m1 || (item.search(/\n{2,}/) > -1)) { 4656 item = showdown.subParser('githubCodeBlocks')(item, options, globals); 4657 item = showdown.subParser('blockGamut')(item, options, globals); 4658 } else { 4659 // Recursion for sub-lists: 4660 item = showdown.subParser('lists')(item, options, globals); 4661 item = item.replace(/\n$/, ''); // chomp(item) 4662 item = showdown.subParser('hashHTMLBlocks')(item, options, globals); 4663 4664 // Colapse double linebreaks 4665 item = item.replace(/\n\n+/g, '\n\n'); 4666 if (isParagraphed) { 4667 item = showdown.subParser('paragraphs')(item, options, globals); 4668 } else { 4669 item = showdown.subParser('spanGamut')(item, options, globals); 4670 } 4671 } 4672 4673 // now we need to remove the marker (¨A) 4674 item = item.replace('¨A', ''); 4675 // we can finally wrap the line in list item tags 4676 item = '<li' + bulletStyle + '>' + item + '</li>\n'; 4677 4678 return item; 4679 }); 4680 4681 // attacklab: strip sentinel 4682 listStr = listStr.replace(/¨0/g, ''); 4683 4684 globals.gListLevel--; 4685 4686 if (trimTrailing) { 4687 listStr = listStr.replace(/\s+$/, ''); 4688 } 4689 4690 return listStr; 4691 } 4692 4693 function styleStartNumber (list, listType) { 4694 // check if ol and starts by a number different than 1 4695 if (listType === 'ol') { 4696 var res = list.match(/^ *(\d+)\./); 4697 if (res && res[1] !== '1') { 4698 return ' start="' + res[1] + '"'; 4699 } 4700 } 4701 return ''; 4702 } 4703 4704 /** 4705 * Check and parse consecutive lists (better fix for issue #142) 4706 * @param {string} list 4707 * @param {string} listType 4708 * @param {boolean} trimTrailing 4709 * @returns {string} 4710 */ 4711 function parseConsecutiveLists (list, listType, trimTrailing) { 4712 // check if we caught 2 or more consecutive lists by mistake 4713 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa 4714 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, 4715 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, 4716 counterRxg = (listType === 'ul') ? olRgx : ulRgx, 4717 result = ''; 4718 4719 if (list.search(counterRxg) !== -1) { 4720 (function parseCL (txt) { 4721 var pos = txt.search(counterRxg), 4722 style = styleStartNumber(list, listType); 4723 if (pos !== -1) { 4724 // slice 4725 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n'; 4726 4727 // invert counterType and listType 4728 listType = (listType === 'ul') ? 'ol' : 'ul'; 4729 counterRxg = (listType === 'ul') ? olRgx : ulRgx; 4730 4731 //recurse 4732 parseCL(txt.slice(pos)); 4733 } else { 4734 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n'; 4735 } 4736 })(list); 4737 } else { 4738 var style = styleStartNumber(list, listType); 4739 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n'; 4740 } 4741 4742 return result; 4743 } 4744 4745 /** Start of list parsing **/ 4746 text = globals.converter._dispatch('lists.before', text, options, globals); 4747 // add sentinel to hack around khtml/safari bug: 4748 // http://bugs.webkit.org/show_bug.cgi?id=11231 4749 text += '¨0'; 4750 4751 if (globals.gListLevel) { 4752 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4753 function (wholeMatch, list, m2) { 4754 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4755 return parseConsecutiveLists(list, listType, true); 4756 } 4757 ); 4758 } else { 4759 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4760 function (wholeMatch, m1, list, m3) { 4761 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4762 return parseConsecutiveLists(list, listType, false); 4763 } 4764 ); 4765 } 4766 4767 // strip sentinel 4768 text = text.replace(/¨0/, ''); 4769 text = globals.converter._dispatch('lists.after', text, options, globals); 4770 return text; 4771 }); 4772 4773 /** 4774 * Parse metadata at the top of the document 4775 */ 4776 showdown.subParser('metadata', function (text, options, globals) { 4777 'use strict'; 4778 4779 if (!options.metadata) { 4780 return text; 4781 } 4782 4783 text = globals.converter._dispatch('metadata.before', text, options, globals); 4784 4785 function parseMetadataContents (content) { 4786 // raw is raw so it's not changed in any way 4787 globals.metadata.raw = content; 4788 4789 // escape chars forbidden in html attributes 4790 // double quotes 4791 content = content 4792 // ampersand first 4793 .replace(/&/g, '&') 4794 // double quotes 4795 .replace(/"/g, '"'); 4796 4797 content = content.replace(/\n {4}/g, ' '); 4798 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) { 4799 globals.metadata.parsed[key] = value; 4800 return ''; 4801 }); 4802 } 4803 4804 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) { 4805 parseMetadataContents(content); 4806 return '¨M'; 4807 }); 4808 4809 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) { 4810 if (format) { 4811 globals.metadata.format = format; 4812 } 4813 parseMetadataContents(content); 4814 return '¨M'; 4815 }); 4816 4817 text = text.replace(/¨M/g, ''); 4818 4819 text = globals.converter._dispatch('metadata.after', text, options, globals); 4820 return text; 4821 }); 4822 4823 /** 4824 * Remove one level of line-leading tabs or spaces 4825 */ 4826 showdown.subParser('outdent', function (text, options, globals) { 4827 'use strict'; 4828 text = globals.converter._dispatch('outdent.before', text, options, globals); 4829 4830 // attacklab: hack around Konqueror 3.5.4 bug: 4831 // "----------bug".replace(/^-/g,"") == "bug" 4832 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width 4833 4834 // attacklab: clean up hack 4835 text = text.replace(/¨0/g, ''); 4836 4837 text = globals.converter._dispatch('outdent.after', text, options, globals); 4838 return text; 4839 }); 4840 4841 /** 4842 * 4843 */ 4844 showdown.subParser('paragraphs', function (text, options, globals) { 4845 'use strict'; 4846 4847 text = globals.converter._dispatch('paragraphs.before', text, options, globals); 4848 // Strip leading and trailing lines: 4849 text = text.replace(/^\n+/g, ''); 4850 text = text.replace(/\n+$/g, ''); 4851 4852 var grafs = text.split(/\n{2,}/g), 4853 grafsOut = [], 4854 end = grafs.length; // Wrap <p> tags 4855 4856 for (var i = 0; i < end; i++) { 4857 var str = grafs[i]; 4858 // if this is an HTML marker, copy it 4859 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) { 4860 grafsOut.push(str); 4861 4862 // test for presence of characters to prevent empty lines being parsed 4863 // as paragraphs (resulting in undesired extra empty paragraphs) 4864 } else if (str.search(/\S/) >= 0) { 4865 str = showdown.subParser('spanGamut')(str, options, globals); 4866 str = str.replace(/^([ \t]*)/g, '<p>'); 4867 str += '</p>'; 4868 grafsOut.push(str); 4869 } 4870 } 4871 4872 /** Unhashify HTML blocks */ 4873 end = grafsOut.length; 4874 for (i = 0; i < end; i++) { 4875 var blockText = '', 4876 grafsOutIt = grafsOut[i], 4877 codeFlag = false; 4878 // if this is a marker for an html block... 4879 // use RegExp.test instead of string.search because of QML bug 4880 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { 4881 var delim = RegExp.$1, 4882 num = RegExp.$2; 4883 4884 if (delim === 'K') { 4885 blockText = globals.gHtmlBlocks[num]; 4886 } else { 4887 // we need to check if ghBlock is a false positive 4888 if (codeFlag) { 4889 // use encoded version of all text 4890 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals); 4891 } else { 4892 blockText = globals.ghCodeBlocks[num].codeblock; 4893 } 4894 } 4895 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs 4896 4897 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); 4898 // Check if grafsOutIt is a pre->code 4899 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { 4900 codeFlag = true; 4901 } 4902 } 4903 grafsOut[i] = grafsOutIt; 4904 } 4905 text = grafsOut.join('\n'); 4906 // Strip leading and trailing lines: 4907 text = text.replace(/^\n+/g, ''); 4908 text = text.replace(/\n+$/g, ''); 4909 return globals.converter._dispatch('paragraphs.after', text, options, globals); 4910 }); 4911 4912 /** 4913 * Run extension 4914 */ 4915 showdown.subParser('runExtension', function (ext, text, options, globals) { 4916 'use strict'; 4917 4918 if (ext.filter) { 4919 text = ext.filter(text, globals.converter, options); 4920 4921 } else if (ext.regex) { 4922 // TODO remove this when old extension loading mechanism is deprecated 4923 var re = ext.regex; 4924 if (!(re instanceof RegExp)) { 4925 re = new RegExp(re, 'g'); 4926 } 4927 text = text.replace(re, ext.replace); 4928 } 4929 4930 return text; 4931 }); 4932 4933 /** 4934 * These are all the transformations that occur *within* block-level 4935 * tags like paragraphs, headers, and list items. 4936 */ 4937 showdown.subParser('spanGamut', function (text, options, globals) { 4938 'use strict'; 4939 4940 text = globals.converter._dispatch('spanGamut.before', text, options, globals); 4941 text = showdown.subParser('codeSpans')(text, options, globals); 4942 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); 4943 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); 4944 4945 // Process anchor and image tags. Images must come first, 4946 // because ![foo][f] looks like an anchor. 4947 text = showdown.subParser('images')(text, options, globals); 4948 text = showdown.subParser('anchors')(text, options, globals); 4949 4950 // Make links out of things like `<http://example.com/>` 4951 // Must come after anchors, because you can use < and > 4952 // delimiters in inline links like [this](<url>). 4953 text = showdown.subParser('autoLinks')(text, options, globals); 4954 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals); 4955 text = showdown.subParser('emoji')(text, options, globals); 4956 text = showdown.subParser('underline')(text, options, globals); 4957 text = showdown.subParser('italicsAndBold')(text, options, globals); 4958 text = showdown.subParser('strikethrough')(text, options, globals); 4959 text = showdown.subParser('ellipsis')(text, options, globals); 4960 4961 // we need to hash HTML tags inside spans 4962 text = showdown.subParser('hashHTMLSpans')(text, options, globals); 4963 4964 // now we encode amps and angles 4965 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); 4966 4967 // Do hard breaks 4968 if (options.simpleLineBreaks) { 4969 // GFM style hard breaks 4970 // only add line breaks if the text does not contain a block (special case for lists) 4971 if (!/\n\n¨K/.test(text)) { 4972 text = text.replace(/\n+/g, '<br />\n'); 4973 } 4974 } else { 4975 // Vanilla hard breaks 4976 text = text.replace(/ +\n/g, '<br />\n'); 4977 } 4978 4979 text = globals.converter._dispatch('spanGamut.after', text, options, globals); 4980 return text; 4981 }); 4982 4983 showdown.subParser('strikethrough', function (text, options, globals) { 4984 'use strict'; 4985 4986 function parseInside (txt) { 4987 if (options.simplifiedAutoLink) { 4988 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4989 } 4990 return '<del>' + txt + '</del>'; 4991 } 4992 4993 if (options.strikethrough) { 4994 text = globals.converter._dispatch('strikethrough.before', text, options, globals); 4995 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); }); 4996 text = globals.converter._dispatch('strikethrough.after', text, options, globals); 4997 } 4998 4999 return text; 5000 }); 5001 5002 /** 5003 * Strips link definitions from text, stores the URLs and titles in 5004 * hash references. 5005 * Link defs are in the form: ^[id]: url "optional title" 5006 */ 5007 showdown.subParser('stripLinkDefinitions', function (text, options, globals) { 5008 'use strict'; 5009 5010 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, 5011 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; 5012 5013 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug 5014 text += '¨0'; 5015 5016 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) { 5017 linkId = linkId.toLowerCase(); 5018 if (url.match(/^data:.+?\/.+?;base64,/)) { 5019 // remove newlines 5020 globals.gUrls[linkId] = url.replace(/\s/g, ''); 5021 } else { 5022 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive 5023 } 5024 5025 if (blankLines) { 5026 // Oops, found blank lines, so it's not a title. 5027 // Put back the parenthetical statement we stole. 5028 return blankLines + title; 5029 5030 } else { 5031 if (title) { 5032 globals.gTitles[linkId] = title.replace(/"|'/g, '"'); 5033 } 5034 if (options.parseImgDimensions && width && height) { 5035 globals.gDimensions[linkId] = { 5036 width: width, 5037 height: height 5038 }; 5039 } 5040 } 5041 // Completely remove the definition from the text 5042 return ''; 5043 }; 5044 5045 // first we try to find base64 link references 5046 text = text.replace(base64Regex, replaceFunc); 5047 5048 text = text.replace(regex, replaceFunc); 5049 5050 // attacklab: strip sentinel 5051 text = text.replace(/¨0/, ''); 5052 5053 return text; 5054 }); 5055 5056 showdown.subParser('tables', function (text, options, globals) { 5057 'use strict'; 5058 5059 if (!options.tables) { 5060 return text; 5061 } 5062 5063 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, 5064 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm; 5065 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm; 5066 5067 function parseStyles (sLine) { 5068 if (/^:[ \t]*--*$/.test(sLine)) { 5069 return ' style="text-align:left;"'; 5070 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { 5071 return ' style="text-align:right;"'; 5072 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { 5073 return ' style="text-align:center;"'; 5074 } else { 5075 return ''; 5076 } 5077 } 5078 5079 function parseHeaders (header, style) { 5080 var id = ''; 5081 header = header.trim(); 5082 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility 5083 if (options.tablesHeaderId || options.tableHeaderId) { 5084 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; 5085 } 5086 header = showdown.subParser('spanGamut')(header, options, globals); 5087 5088 return '<th' + id + style + '>' + header + '</th>\n'; 5089 } 5090 5091 function parseCells (cell, style) { 5092 var subText = showdown.subParser('spanGamut')(cell, options, globals); 5093 return '<td' + style + '>' + subText + '</td>\n'; 5094 } 5095 5096 function buildTable (headers, cells) { 5097 var tb = '<table>\n<thead>\n<tr>\n', 5098 tblLgn = headers.length; 5099 5100 for (var i = 0; i < tblLgn; ++i) { 5101 tb += headers[i]; 5102 } 5103 tb += '</tr>\n</thead>\n<tbody>\n'; 5104 5105 for (i = 0; i < cells.length; ++i) { 5106 tb += '<tr>\n'; 5107 for (var ii = 0; ii < tblLgn; ++ii) { 5108 tb += cells[i][ii]; 5109 } 5110 tb += '</tr>\n'; 5111 } 5112 tb += '</tbody>\n</table>\n'; 5113 return tb; 5114 } 5115 5116 function parseTable (rawTable) { 5117 var i, tableLines = rawTable.split('\n'); 5118 5119 for (i = 0; i < tableLines.length; ++i) { 5120 // strip wrong first and last column if wrapped tables are used 5121 if (/^ {0,3}\|/.test(tableLines[i])) { 5122 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); 5123 } 5124 if (/\|[ \t]*$/.test(tableLines[i])) { 5125 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); 5126 } 5127 // parse code spans first, but we only support one line code spans 5128 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals); 5129 } 5130 5131 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), 5132 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), 5133 rawCells = [], 5134 headers = [], 5135 styles = [], 5136 cells = []; 5137 5138 tableLines.shift(); 5139 tableLines.shift(); 5140 5141 for (i = 0; i < tableLines.length; ++i) { 5142 if (tableLines[i].trim() === '') { 5143 continue; 5144 } 5145 rawCells.push( 5146 tableLines[i] 5147 .split('|') 5148 .map(function (s) { 5149 return s.trim(); 5150 }) 5151 ); 5152 } 5153 5154 if (rawHeaders.length < rawStyles.length) { 5155 return rawTable; 5156 } 5157 5158 for (i = 0; i < rawStyles.length; ++i) { 5159 styles.push(parseStyles(rawStyles[i])); 5160 } 5161 5162 for (i = 0; i < rawHeaders.length; ++i) { 5163 if (showdown.helper.isUndefined(styles[i])) { 5164 styles[i] = ''; 5165 } 5166 headers.push(parseHeaders(rawHeaders[i], styles[i])); 5167 } 5168 5169 for (i = 0; i < rawCells.length; ++i) { 5170 var row = []; 5171 for (var ii = 0; ii < headers.length; ++ii) { 5172 if (showdown.helper.isUndefined(rawCells[i][ii])) { 5173 5174 } 5175 row.push(parseCells(rawCells[i][ii], styles[ii])); 5176 } 5177 cells.push(row); 5178 } 5179 5180 return buildTable(headers, cells); 5181 } 5182 5183 text = globals.converter._dispatch('tables.before', text, options, globals); 5184 5185 // find escaped pipe characters 5186 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback); 5187 5188 // parse multi column tables 5189 text = text.replace(tableRgx, parseTable); 5190 5191 // parse one column tables 5192 text = text.replace(singeColTblRgx, parseTable); 5193 5194 text = globals.converter._dispatch('tables.after', text, options, globals); 5195 5196 return text; 5197 }); 5198 5199 showdown.subParser('underline', function (text, options, globals) { 5200 'use strict'; 5201 5202 if (!options.underline) { 5203 return text; 5204 } 5205 5206 text = globals.converter._dispatch('underline.before', text, options, globals); 5207 5208 if (options.literalMidWordUnderscores) { 5209 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 5210 return '<u>' + txt + '</u>'; 5211 }); 5212 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 5213 return '<u>' + txt + '</u>'; 5214 }); 5215 } else { 5216 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 5217 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 5218 }); 5219 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 5220 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 5221 }); 5222 } 5223 5224 // escape remaining underscores to prevent them being parsed by italic and bold 5225 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback); 5226 5227 text = globals.converter._dispatch('underline.after', text, options, globals); 5228 5229 return text; 5230 }); 5231 5232 /** 5233 * Swap back in all the special characters we've hidden. 5234 */ 5235 showdown.subParser('unescapeSpecialChars', function (text, options, globals) { 5236 'use strict'; 5237 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals); 5238 5239 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) { 5240 var charCodeToReplace = parseInt(m1); 5241 return String.fromCharCode(charCodeToReplace); 5242 }); 5243 5244 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals); 5245 return text; 5246 }); 5247 5248 showdown.subParser('makeMarkdown.blockquote', function (node, globals) { 5249 'use strict'; 5250 5251 var txt = ''; 5252 if (node.hasChildNodes()) { 5253 var children = node.childNodes, 5254 childrenLength = children.length; 5255 5256 for (var i = 0; i < childrenLength; ++i) { 5257 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals); 5258 5259 if (innerTxt === '') { 5260 continue; 5261 } 5262 txt += innerTxt; 5263 } 5264 } 5265 // cleanup 5266 txt = txt.trim(); 5267 txt = '> ' + txt.split('\n').join('\n> '); 5268 return txt; 5269 }); 5270 5271 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) { 5272 'use strict'; 5273 5274 var lang = node.getAttribute('language'), 5275 num = node.getAttribute('precodenum'); 5276 return '```' + lang + '\n' + globals.preList[num] + '\n```'; 5277 }); 5278 5279 showdown.subParser('makeMarkdown.codeSpan', function (node) { 5280 'use strict'; 5281 5282 return '`' + node.innerHTML + '`'; 5283 }); 5284 5285 showdown.subParser('makeMarkdown.emphasis', function (node, globals) { 5286 'use strict'; 5287 5288 var txt = ''; 5289 if (node.hasChildNodes()) { 5290 txt += '*'; 5291 var children = node.childNodes, 5292 childrenLength = children.length; 5293 for (var i = 0; i < childrenLength; ++i) { 5294 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5295 } 5296 txt += '*'; 5297 } 5298 return txt; 5299 }); 5300 5301 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) { 5302 'use strict'; 5303 5304 var headerMark = new Array(headerLevel + 1).join('#'), 5305 txt = ''; 5306 5307 if (node.hasChildNodes()) { 5308 txt = headerMark + ' '; 5309 var children = node.childNodes, 5310 childrenLength = children.length; 5311 5312 for (var i = 0; i < childrenLength; ++i) { 5313 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5314 } 5315 } 5316 return txt; 5317 }); 5318 5319 showdown.subParser('makeMarkdown.hr', function () { 5320 'use strict'; 5321 5322 return '---'; 5323 }); 5324 5325 showdown.subParser('makeMarkdown.image', function (node) { 5326 'use strict'; 5327 5328 var txt = ''; 5329 if (node.hasAttribute('src')) { 5330 txt += '![' + node.getAttribute('alt') + ']('; 5331 txt += '<' + node.getAttribute('src') + '>'; 5332 if (node.hasAttribute('width') && node.hasAttribute('height')) { 5333 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height'); 5334 } 5335 5336 if (node.hasAttribute('title')) { 5337 txt += ' "' + node.getAttribute('title') + '"'; 5338 } 5339 txt += ')'; 5340 } 5341 return txt; 5342 }); 5343 5344 showdown.subParser('makeMarkdown.links', function (node, globals) { 5345 'use strict'; 5346 5347 var txt = ''; 5348 if (node.hasChildNodes() && node.hasAttribute('href')) { 5349 var children = node.childNodes, 5350 childrenLength = children.length; 5351 txt = '['; 5352 for (var i = 0; i < childrenLength; ++i) { 5353 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5354 } 5355 txt += ']('; 5356 txt += '<' + node.getAttribute('href') + '>'; 5357 if (node.hasAttribute('title')) { 5358 txt += ' "' + node.getAttribute('title') + '"'; 5359 } 5360 txt += ')'; 5361 } 5362 return txt; 5363 }); 5364 5365 showdown.subParser('makeMarkdown.list', function (node, globals, type) { 5366 'use strict'; 5367 5368 var txt = ''; 5369 if (!node.hasChildNodes()) { 5370 return ''; 5371 } 5372 var listItems = node.childNodes, 5373 listItemsLenght = listItems.length, 5374 listNum = node.getAttribute('start') || 1; 5375 5376 for (var i = 0; i < listItemsLenght; ++i) { 5377 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') { 5378 continue; 5379 } 5380 5381 // define the bullet to use in list 5382 var bullet = ''; 5383 if (type === 'ol') { 5384 bullet = listNum.toString() + '. '; 5385 } else { 5386 bullet = '- '; 5387 } 5388 5389 // parse list item 5390 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals); 5391 ++listNum; 5392 } 5393 5394 // add comment at the end to prevent consecutive lists to be parsed as one 5395 txt += '\n<!-- -->\n'; 5396 return txt.trim(); 5397 }); 5398 5399 showdown.subParser('makeMarkdown.listItem', function (node, globals) { 5400 'use strict'; 5401 5402 var listItemTxt = ''; 5403 5404 var children = node.childNodes, 5405 childrenLenght = children.length; 5406 5407 for (var i = 0; i < childrenLenght; ++i) { 5408 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5409 } 5410 // if it's only one liner, we need to add a newline at the end 5411 if (!/\n$/.test(listItemTxt)) { 5412 listItemTxt += '\n'; 5413 } else { 5414 // it's multiparagraph, so we need to indent 5415 listItemTxt = listItemTxt 5416 .split('\n') 5417 .join('\n ') 5418 .replace(/^ {4}$/gm, '') 5419 .replace(/\n\n+/g, '\n\n'); 5420 } 5421 5422 return listItemTxt; 5423 }); 5424 5425 5426 5427 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) { 5428 'use strict'; 5429 5430 spansOnly = spansOnly || false; 5431 5432 var txt = ''; 5433 5434 // edge case of text without wrapper paragraph 5435 if (node.nodeType === 3) { 5436 return showdown.subParser('makeMarkdown.txt')(node, globals); 5437 } 5438 5439 // HTML comment 5440 if (node.nodeType === 8) { 5441 return '<!--' + node.data + '-->\n\n'; 5442 } 5443 5444 // process only node elements 5445 if (node.nodeType !== 1) { 5446 return ''; 5447 } 5448 5449 var tagName = node.tagName.toLowerCase(); 5450 5451 switch (tagName) { 5452 5453 // 5454 // BLOCKS 5455 // 5456 case 'h1': 5457 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; } 5458 break; 5459 case 'h2': 5460 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; } 5461 break; 5462 case 'h3': 5463 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; } 5464 break; 5465 case 'h4': 5466 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; } 5467 break; 5468 case 'h5': 5469 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; } 5470 break; 5471 case 'h6': 5472 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; } 5473 break; 5474 5475 case 'p': 5476 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; } 5477 break; 5478 5479 case 'blockquote': 5480 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; } 5481 break; 5482 5483 case 'hr': 5484 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; } 5485 break; 5486 5487 case 'ol': 5488 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; } 5489 break; 5490 5491 case 'ul': 5492 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; } 5493 break; 5494 5495 case 'precode': 5496 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; } 5497 break; 5498 5499 case 'pre': 5500 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; } 5501 break; 5502 5503 case 'table': 5504 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; } 5505 break; 5506 5507 // 5508 // SPANS 5509 // 5510 case 'code': 5511 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals); 5512 break; 5513 5514 case 'em': 5515 case 'i': 5516 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals); 5517 break; 5518 5519 case 'strong': 5520 case 'b': 5521 txt = showdown.subParser('makeMarkdown.strong')(node, globals); 5522 break; 5523 5524 case 'del': 5525 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals); 5526 break; 5527 5528 case 'a': 5529 txt = showdown.subParser('makeMarkdown.links')(node, globals); 5530 break; 5531 5532 case 'img': 5533 txt = showdown.subParser('makeMarkdown.image')(node, globals); 5534 break; 5535 5536 default: 5537 txt = node.outerHTML + '\n\n'; 5538 } 5539 5540 // common normalization 5541 // TODO eventually 5542 5543 return txt; 5544 }); 5545 5546 showdown.subParser('makeMarkdown.paragraph', function (node, globals) { 5547 'use strict'; 5548 5549 var txt = ''; 5550 if (node.hasChildNodes()) { 5551 var children = node.childNodes, 5552 childrenLength = children.length; 5553 for (var i = 0; i < childrenLength; ++i) { 5554 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5555 } 5556 } 5557 5558 // some text normalization 5559 txt = txt.trim(); 5560 5561 return txt; 5562 }); 5563 5564 showdown.subParser('makeMarkdown.pre', function (node, globals) { 5565 'use strict'; 5566 5567 var num = node.getAttribute('prenum'); 5568 return '<pre>' + globals.preList[num] + '</pre>'; 5569 }); 5570 5571 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { 5572 'use strict'; 5573 5574 var txt = ''; 5575 if (node.hasChildNodes()) { 5576 txt += '~~'; 5577 var children = node.childNodes, 5578 childrenLength = children.length; 5579 for (var i = 0; i < childrenLength; ++i) { 5580 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5581 } 5582 txt += '~~'; 5583 } 5584 return txt; 5585 }); 5586 5587 showdown.subParser('makeMarkdown.strong', function (node, globals) { 5588 'use strict'; 5589 5590 var txt = ''; 5591 if (node.hasChildNodes()) { 5592 txt += '**'; 5593 var children = node.childNodes, 5594 childrenLength = children.length; 5595 for (var i = 0; i < childrenLength; ++i) { 5596 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5597 } 5598 txt += '**'; 5599 } 5600 return txt; 5601 }); 5602 5603 showdown.subParser('makeMarkdown.table', function (node, globals) { 5604 'use strict'; 5605 5606 var txt = '', 5607 tableArray = [[], []], 5608 headings = node.querySelectorAll('thead>tr>th'), 5609 rows = node.querySelectorAll('tbody>tr'), 5610 i, ii; 5611 for (i = 0; i < headings.length; ++i) { 5612 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals), 5613 allign = '---'; 5614 5615 if (headings[i].hasAttribute('style')) { 5616 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, ''); 5617 switch (style) { 5618 case 'text-align:left;': 5619 allign = ':---'; 5620 break; 5621 case 'text-align:right;': 5622 allign = '---:'; 5623 break; 5624 case 'text-align:center;': 5625 allign = ':---:'; 5626 break; 5627 } 5628 } 5629 tableArray[0][i] = headContent.trim(); 5630 tableArray[1][i] = allign; 5631 } 5632 5633 for (i = 0; i < rows.length; ++i) { 5634 var r = tableArray.push([]) - 1, 5635 cols = rows[i].getElementsByTagName('td'); 5636 5637 for (ii = 0; ii < headings.length; ++ii) { 5638 var cellContent = ' '; 5639 if (typeof cols[ii] !== 'undefined') { 5640 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals); 5641 } 5642 tableArray[r].push(cellContent); 5643 } 5644 } 5645 5646 var cellSpacesCount = 3; 5647 for (i = 0; i < tableArray.length; ++i) { 5648 for (ii = 0; ii < tableArray[i].length; ++ii) { 5649 var strLen = tableArray[i][ii].length; 5650 if (strLen > cellSpacesCount) { 5651 cellSpacesCount = strLen; 5652 } 5653 } 5654 } 5655 5656 for (i = 0; i < tableArray.length; ++i) { 5657 for (ii = 0; ii < tableArray[i].length; ++ii) { 5658 if (i === 1) { 5659 if (tableArray[i][ii].slice(-1) === ':') { 5660 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':'; 5661 } else { 5662 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-'); 5663 } 5664 } else { 5665 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount); 5666 } 5667 } 5668 txt += '| ' + tableArray[i].join(' | ') + ' |\n'; 5669 } 5670 5671 return txt.trim(); 5672 }); 5673 5674 showdown.subParser('makeMarkdown.tableCell', function (node, globals) { 5675 'use strict'; 5676 5677 var txt = ''; 5678 if (!node.hasChildNodes()) { 5679 return ''; 5680 } 5681 var children = node.childNodes, 5682 childrenLength = children.length; 5683 5684 for (var i = 0; i < childrenLength; ++i) { 5685 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true); 5686 } 5687 return txt.trim(); 5688 }); 5689 5690 showdown.subParser('makeMarkdown.txt', function (node) { 5691 'use strict'; 5692 5693 var txt = node.nodeValue; 5694 5695 // multiple spaces are collapsed 5696 txt = txt.replace(/ +/g, ' '); 5697 5698 // replace the custom ¨NBSP; with a space 5699 txt = txt.replace(/¨NBSP;/g, ' '); 5700 5701 // ", <, > and & should replace escaped html entities 5702 txt = showdown.helper.unescapeHTMLEntities(txt); 5703 5704 // escape markdown magic characters 5705 // emphasis, strong and strikethrough - can appear everywhere 5706 // we also escape pipe (|) because of tables 5707 // and escape ` because of code blocks and spans 5708 txt = txt.replace(/([*_~|`])/g, '\\$1'); 5709 5710 // escape > because of blockquotes 5711 txt = txt.replace(/^(\s*)>/g, '\\$1>'); 5712 5713 // hash character, only troublesome at the beginning of a line because of headers 5714 txt = txt.replace(/^#/gm, '\\#'); 5715 5716 // horizontal rules 5717 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3'); 5718 5719 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer 5720 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.'); 5721 5722 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped) 5723 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2'); 5724 5725 // images and links, ] followed by ( is problematic, so we escape it 5726 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\('); 5727 5728 // reference URIs must also be escaped 5729 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:'); 5730 5731 return txt; 5732 }); 5733 5734 var root = this; 5735 5736 // AMD Loader 5737 if (true) { 5738 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { 5739 'use strict'; 5740 return showdown; 5741 }).call(exports, __webpack_require__, exports, module), 5742 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 5743 5744 // CommonJS/nodeJS Loader 5745 } else {} 5746 }).call(this); 5747 5748 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 need to be wrapped in an IIFE because it need 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 getBlockContent: () => (/* reexport */ getBlockInnerHTML), 5849 getBlockDefaultClassName: () => (/* reexport */ getBlockDefaultClassName), 5850 getBlockFromExample: () => (/* reexport */ getBlockFromExample), 5851 getBlockMenuDefaultClassName: () => (/* reexport */ getBlockMenuDefaultClassName), 5852 getBlockSupport: () => (/* reexport */ getBlockSupport), 5853 getBlockTransforms: () => (/* reexport */ getBlockTransforms), 5854 getBlockType: () => (/* reexport */ getBlockType), 5855 getBlockTypes: () => (/* reexport */ getBlockTypes), 5856 getBlockVariations: () => (/* reexport */ getBlockVariations), 5857 getCategories: () => (/* reexport */ categories_getCategories), 5858 getChildBlockNames: () => (/* reexport */ getChildBlockNames), 5859 getDefaultBlockName: () => (/* reexport */ getDefaultBlockName), 5860 getFreeformContentHandlerName: () => (/* reexport */ getFreeformContentHandlerName), 5861 getGroupingBlockName: () => (/* reexport */ getGroupingBlockName), 5862 getPhrasingContentSchema: () => (/* reexport */ deprecatedGetPhrasingContentSchema), 5863 getPossibleBlockTransformations: () => (/* reexport */ getPossibleBlockTransformations), 5864 getSaveContent: () => (/* reexport */ getSaveContent), 5865 getSaveElement: () => (/* reexport */ getSaveElement), 5866 getUnregisteredTypeHandlerName: () => (/* reexport */ getUnregisteredTypeHandlerName), 5867 hasBlockSupport: () => (/* reexport */ hasBlockSupport), 5868 hasChildBlocks: () => (/* reexport */ hasChildBlocks), 5869 hasChildBlocksWithInserterSupport: () => (/* reexport */ hasChildBlocksWithInserterSupport), 5870 isReusableBlock: () => (/* reexport */ isReusableBlock), 5871 isTemplatePart: () => (/* reexport */ isTemplatePart), 5872 isUnmodifiedBlock: () => (/* reexport */ isUnmodifiedBlock), 5873 isUnmodifiedDefaultBlock: () => (/* reexport */ isUnmodifiedDefaultBlock), 5874 isValidBlockContent: () => (/* reexport */ isValidBlockContent), 5875 isValidIcon: () => (/* reexport */ isValidIcon), 5876 node: () => (/* reexport */ node), 5877 normalizeIconObject: () => (/* reexport */ normalizeIconObject), 5878 parse: () => (/* reexport */ parser_parse), 5879 parseWithAttributeSchema: () => (/* reexport */ parseWithAttributeSchema), 5880 pasteHandler: () => (/* reexport */ pasteHandler), 5881 rawHandler: () => (/* reexport */ rawHandler), 5882 registerBlockCollection: () => (/* reexport */ registerBlockCollection), 5883 registerBlockStyle: () => (/* reexport */ registerBlockStyle), 5884 registerBlockType: () => (/* reexport */ registerBlockType), 5885 registerBlockVariation: () => (/* reexport */ registerBlockVariation), 5886 serialize: () => (/* reexport */ serialize), 5887 serializeRawBlock: () => (/* reexport */ serializeRawBlock), 5888 setCategories: () => (/* reexport */ categories_setCategories), 5889 setDefaultBlockName: () => (/* reexport */ setDefaultBlockName), 5890 setFreeformContentHandlerName: () => (/* reexport */ setFreeformContentHandlerName), 5891 setGroupingBlockName: () => (/* reexport */ setGroupingBlockName), 5892 setUnregisteredTypeHandlerName: () => (/* reexport */ setUnregisteredTypeHandlerName), 5893 store: () => (/* reexport */ store), 5894 switchToBlockType: () => (/* reexport */ switchToBlockType), 5895 synchronizeBlocksWithTemplate: () => (/* reexport */ synchronizeBlocksWithTemplate), 5896 unregisterBlockStyle: () => (/* reexport */ unregisterBlockStyle), 5897 unregisterBlockType: () => (/* reexport */ unregisterBlockType), 5898 unregisterBlockVariation: () => (/* reexport */ unregisterBlockVariation), 5899 unstable__bootstrapServerSideBlockDefinitions: () => (/* reexport */ unstable__bootstrapServerSideBlockDefinitions), 5900 updateCategory: () => (/* reexport */ categories_updateCategory), 5901 validateBlock: () => (/* reexport */ validateBlock), 5902 withBlockContentContext: () => (/* reexport */ withBlockContentContext) 5903 }); 5904 5905 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 5906 var selectors_namespaceObject = {}; 5907 __webpack_require__.r(selectors_namespaceObject); 5908 __webpack_require__.d(selectors_namespaceObject, { 5909 __experimentalHasContentRoleAttribute: () => (__experimentalHasContentRoleAttribute), 5910 getActiveBlockVariation: () => (getActiveBlockVariation), 5911 getBlockStyles: () => (getBlockStyles), 5912 getBlockSupport: () => (selectors_getBlockSupport), 5913 getBlockType: () => (selectors_getBlockType), 5914 getBlockTypes: () => (selectors_getBlockTypes), 5915 getBlockVariations: () => (selectors_getBlockVariations), 5916 getCategories: () => (getCategories), 5917 getChildBlockNames: () => (selectors_getChildBlockNames), 5918 getCollections: () => (getCollections), 5919 getDefaultBlockName: () => (selectors_getDefaultBlockName), 5920 getDefaultBlockVariation: () => (getDefaultBlockVariation), 5921 getFreeformFallbackBlockName: () => (getFreeformFallbackBlockName), 5922 getGroupingBlockName: () => (selectors_getGroupingBlockName), 5923 getUnregisteredFallbackBlockName: () => (getUnregisteredFallbackBlockName), 5924 hasBlockSupport: () => (selectors_hasBlockSupport), 5925 hasChildBlocks: () => (selectors_hasChildBlocks), 5926 hasChildBlocksWithInserterSupport: () => (selectors_hasChildBlocksWithInserterSupport), 5927 isMatchingSearchTerm: () => (isMatchingSearchTerm) 5928 }); 5929 5930 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 5931 var private_selectors_namespaceObject = {}; 5932 __webpack_require__.r(private_selectors_namespaceObject); 5933 __webpack_require__.d(private_selectors_namespaceObject, { 5934 getAllBlockBindingsSources: () => (getAllBlockBindingsSources), 5935 getBlockBindingsSource: () => (getBlockBindingsSource), 5936 getBootstrappedBlockType: () => (getBootstrappedBlockType), 5937 getSupportedStyles: () => (getSupportedStyles), 5938 getUnprocessedBlockTypes: () => (getUnprocessedBlockTypes) 5939 }); 5940 5941 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/actions.js 5942 var actions_namespaceObject = {}; 5943 __webpack_require__.r(actions_namespaceObject); 5944 __webpack_require__.d(actions_namespaceObject, { 5945 __experimentalReapplyBlockFilters: () => (__experimentalReapplyBlockFilters), 5946 addBlockCollection: () => (addBlockCollection), 5947 addBlockStyles: () => (addBlockStyles), 5948 addBlockTypes: () => (addBlockTypes), 5949 addBlockVariations: () => (addBlockVariations), 5950 reapplyBlockTypeFilters: () => (reapplyBlockTypeFilters), 5951 removeBlockCollection: () => (removeBlockCollection), 5952 removeBlockStyles: () => (removeBlockStyles), 5953 removeBlockTypes: () => (removeBlockTypes), 5954 removeBlockVariations: () => (removeBlockVariations), 5955 setCategories: () => (setCategories), 5956 setDefaultBlockName: () => (actions_setDefaultBlockName), 5957 setFreeformFallbackBlockName: () => (setFreeformFallbackBlockName), 5958 setGroupingBlockName: () => (actions_setGroupingBlockName), 5959 setUnregisteredFallbackBlockName: () => (setUnregisteredFallbackBlockName), 5960 updateCategory: () => (updateCategory) 5961 }); 5962 5963 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 5964 var private_actions_namespaceObject = {}; 5965 __webpack_require__.r(private_actions_namespaceObject); 5966 __webpack_require__.d(private_actions_namespaceObject, { 5967 addBootstrappedBlockType: () => (addBootstrappedBlockType), 5968 addUnprocessedBlockType: () => (addUnprocessedBlockType), 5969 registerBlockBindingsSource: () => (registerBlockBindingsSource) 5970 }); 5971 5972 ;// CONCATENATED MODULE: external ["wp","data"] 5973 const external_wp_data_namespaceObject = window["wp"]["data"]; 5974 ;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.mjs 5975 /****************************************************************************** 5976 Copyright (c) Microsoft Corporation. 5977 5978 Permission to use, copy, modify, and/or distribute this software for any 5979 purpose with or without fee is hereby granted. 5980 5981 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 5982 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 5983 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 5984 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 5985 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 5986 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 5987 PERFORMANCE OF THIS SOFTWARE. 5988 ***************************************************************************** */ 5989 /* global Reflect, Promise, SuppressedError, Symbol */ 5990 5991 var extendStatics = function(d, b) { 5992 extendStatics = Object.setPrototypeOf || 5993 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 5994 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 5995 return extendStatics(d, b); 5996 }; 5997 5998 function __extends(d, b) { 5999 if (typeof b !== "function" && b !== null) 6000 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 6001 extendStatics(d, b); 6002 function __() { this.constructor = d; } 6003 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6004 } 6005 6006 var __assign = function() { 6007 __assign = Object.assign || function __assign(t) { 6008 for (var s, i = 1, n = arguments.length; i < n; i++) { 6009 s = arguments[i]; 6010 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 6011 } 6012 return t; 6013 } 6014 return __assign.apply(this, arguments); 6015 } 6016 6017 function __rest(s, e) { 6018 var t = {}; 6019 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 6020 t[p] = s[p]; 6021 if (s != null && typeof Object.getOwnPropertySymbols === "function") 6022 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 6023 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 6024 t[p[i]] = s[p[i]]; 6025 } 6026 return t; 6027 } 6028 6029 function __decorate(decorators, target, key, desc) { 6030 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6031 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 6032 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; 6033 return c > 3 && r && Object.defineProperty(target, key, r), r; 6034 } 6035 6036 function __param(paramIndex, decorator) { 6037 return function (target, key) { decorator(target, key, paramIndex); } 6038 } 6039 6040 function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 6041 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 6042 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 6043 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 6044 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6045 var _, done = false; 6046 for (var i = decorators.length - 1; i >= 0; i--) { 6047 var context = {}; 6048 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 6049 for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 6050 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 6051 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 6052 if (kind === "accessor") { 6053 if (result === void 0) continue; 6054 if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 6055 if (_ = accept(result.get)) descriptor.get = _; 6056 if (_ = accept(result.set)) descriptor.set = _; 6057 if (_ = accept(result.init)) initializers.unshift(_); 6058 } 6059 else if (_ = accept(result)) { 6060 if (kind === "field") initializers.unshift(_); 6061 else descriptor[key] = _; 6062 } 6063 } 6064 if (target) Object.defineProperty(target, contextIn.name, descriptor); 6065 done = true; 6066 }; 6067 6068 function __runInitializers(thisArg, initializers, value) { 6069 var useValue = arguments.length > 2; 6070 for (var i = 0; i < initializers.length; i++) { 6071 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 6072 } 6073 return useValue ? value : void 0; 6074 }; 6075 6076 function __propKey(x) { 6077 return typeof x === "symbol" ? x : "".concat(x); 6078 }; 6079 6080 function __setFunctionName(f, name, prefix) { 6081 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; 6082 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); 6083 }; 6084 6085 function __metadata(metadataKey, metadataValue) { 6086 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 6087 } 6088 6089 function __awaiter(thisArg, _arguments, P, generator) { 6090 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 6091 return new (P || (P = Promise))(function (resolve, reject) { 6092 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6093 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6094 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 6095 step((generator = generator.apply(thisArg, _arguments || [])).next()); 6096 }); 6097 } 6098 6099 function __generator(thisArg, body) { 6100 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 6101 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 6102 function verb(n) { return function (v) { return step([n, v]); }; } 6103 function step(op) { 6104 if (f) throw new TypeError("Generator is already executing."); 6105 while (g && (g = 0, op[0] && (_ = 0)), _) try { 6106 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; 6107 if (y = 0, t) op = [op[0] & 2, t.value]; 6108 switch (op[0]) { 6109 case 0: case 1: t = op; break; 6110 case 4: _.label++; return { value: op[1], done: false }; 6111 case 5: _.label++; y = op[1]; op = [0]; continue; 6112 case 7: op = _.ops.pop(); _.trys.pop(); continue; 6113 default: 6114 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 6115 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 6116 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 6117 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 6118 if (t[2]) _.ops.pop(); 6119 _.trys.pop(); continue; 6120 } 6121 op = body.call(thisArg, _); 6122 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 6123 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 6124 } 6125 } 6126 6127 var __createBinding = Object.create ? (function(o, m, k, k2) { 6128 if (k2 === undefined) k2 = k; 6129 var desc = Object.getOwnPropertyDescriptor(m, k); 6130 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6131 desc = { enumerable: true, get: function() { return m[k]; } }; 6132 } 6133 Object.defineProperty(o, k2, desc); 6134 }) : (function(o, m, k, k2) { 6135 if (k2 === undefined) k2 = k; 6136 o[k2] = m[k]; 6137 }); 6138 6139 function __exportStar(m, o) { 6140 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 6141 } 6142 6143 function __values(o) { 6144 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 6145 if (m) return m.call(o); 6146 if (o && typeof o.length === "number") return { 6147 next: function () { 6148 if (o && i >= o.length) o = void 0; 6149 return { value: o && o[i++], done: !o }; 6150 } 6151 }; 6152 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 6153 } 6154 6155 function __read(o, n) { 6156 var m = typeof Symbol === "function" && o[Symbol.iterator]; 6157 if (!m) return o; 6158 var i = m.call(o), r, ar = [], e; 6159 try { 6160 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 6161 } 6162 catch (error) { e = { error: error }; } 6163 finally { 6164 try { 6165 if (r && !r.done && (m = i["return"])) m.call(i); 6166 } 6167 finally { if (e) throw e.error; } 6168 } 6169 return ar; 6170 } 6171 6172 /** @deprecated */ 6173 function __spread() { 6174 for (var ar = [], i = 0; i < arguments.length; i++) 6175 ar = ar.concat(__read(arguments[i])); 6176 return ar; 6177 } 6178 6179 /** @deprecated */ 6180 function __spreadArrays() { 6181 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 6182 for (var r = Array(s), k = 0, i = 0; i < il; i++) 6183 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 6184 r[k] = a[j]; 6185 return r; 6186 } 6187 6188 function __spreadArray(to, from, pack) { 6189 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 6190 if (ar || !(i in from)) { 6191 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 6192 ar[i] = from[i]; 6193 } 6194 } 6195 return to.concat(ar || Array.prototype.slice.call(from)); 6196 } 6197 6198 function __await(v) { 6199 return this instanceof __await ? (this.v = v, this) : new __await(v); 6200 } 6201 6202 function __asyncGenerator(thisArg, _arguments, generator) { 6203 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6204 var g = generator.apply(thisArg, _arguments || []), i, q = []; 6205 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; 6206 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } 6207 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 6208 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 6209 function fulfill(value) { resume("next", value); } 6210 function reject(value) { resume("throw", value); } 6211 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 6212 } 6213 6214 function __asyncDelegator(o) { 6215 var i, p; 6216 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 6217 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; } 6218 } 6219 6220 function __asyncValues(o) { 6221 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6222 var m = o[Symbol.asyncIterator], i; 6223 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); 6224 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); }); }; } 6225 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 6226 } 6227 6228 function __makeTemplateObject(cooked, raw) { 6229 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 6230 return cooked; 6231 }; 6232 6233 var __setModuleDefault = Object.create ? (function(o, v) { 6234 Object.defineProperty(o, "default", { enumerable: true, value: v }); 6235 }) : function(o, v) { 6236 o["default"] = v; 6237 }; 6238 6239 function __importStar(mod) { 6240 if (mod && mod.__esModule) return mod; 6241 var result = {}; 6242 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 6243 __setModuleDefault(result, mod); 6244 return result; 6245 } 6246 6247 function __importDefault(mod) { 6248 return (mod && mod.__esModule) ? mod : { default: mod }; 6249 } 6250 6251 function __classPrivateFieldGet(receiver, state, kind, f) { 6252 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 6253 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"); 6254 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 6255 } 6256 6257 function __classPrivateFieldSet(receiver, state, value, kind, f) { 6258 if (kind === "m") throw new TypeError("Private method is not writable"); 6259 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 6260 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"); 6261 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 6262 } 6263 6264 function __classPrivateFieldIn(state, receiver) { 6265 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); 6266 return typeof state === "function" ? receiver === state : state.has(receiver); 6267 } 6268 6269 function __addDisposableResource(env, value, async) { 6270 if (value !== null && value !== void 0) { 6271 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 6272 var dispose; 6273 if (async) { 6274 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 6275 dispose = value[Symbol.asyncDispose]; 6276 } 6277 if (dispose === void 0) { 6278 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 6279 dispose = value[Symbol.dispose]; 6280 } 6281 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 6282 env.stack.push({ value: value, dispose: dispose, async: async }); 6283 } 6284 else if (async) { 6285 env.stack.push({ async: true }); 6286 } 6287 return value; 6288 } 6289 6290 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 6291 var e = new Error(message); 6292 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 6293 }; 6294 6295 function __disposeResources(env) { 6296 function fail(e) { 6297 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 6298 env.hasError = true; 6299 } 6300 function next() { 6301 while (env.stack.length) { 6302 var rec = env.stack.pop(); 6303 try { 6304 var result = rec.dispose && rec.dispose.call(rec.value); 6305 if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 6306 } 6307 catch (e) { 6308 fail(e); 6309 } 6310 } 6311 if (env.hasError) throw env.error; 6312 } 6313 return next(); 6314 } 6315 6316 /* harmony default export */ const tslib_es6 = ({ 6317 __extends, 6318 __assign, 6319 __rest, 6320 __decorate, 6321 __param, 6322 __metadata, 6323 __awaiter, 6324 __generator, 6325 __createBinding, 6326 __exportStar, 6327 __values, 6328 __read, 6329 __spread, 6330 __spreadArrays, 6331 __spreadArray, 6332 __await, 6333 __asyncGenerator, 6334 __asyncDelegator, 6335 __asyncValues, 6336 __makeTemplateObject, 6337 __importStar, 6338 __importDefault, 6339 __classPrivateFieldGet, 6340 __classPrivateFieldSet, 6341 __classPrivateFieldIn, 6342 __addDisposableResource, 6343 __disposeResources, 6344 }); 6345 6346 ;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js 6347 /** 6348 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 6349 */ 6350 var SUPPORTED_LOCALE = { 6351 tr: { 6352 regexp: /\u0130|\u0049|\u0049\u0307/g, 6353 map: { 6354 İ: "\u0069", 6355 I: "\u0131", 6356 İ: "\u0069", 6357 }, 6358 }, 6359 az: { 6360 regexp: /\u0130/g, 6361 map: { 6362 İ: "\u0069", 6363 I: "\u0131", 6364 İ: "\u0069", 6365 }, 6366 }, 6367 lt: { 6368 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 6369 map: { 6370 I: "\u0069\u0307", 6371 J: "\u006A\u0307", 6372 Į: "\u012F\u0307", 6373 Ì: "\u0069\u0307\u0300", 6374 Í: "\u0069\u0307\u0301", 6375 Ĩ: "\u0069\u0307\u0303", 6376 }, 6377 }, 6378 }; 6379 /** 6380 * Localized lower case. 6381 */ 6382 function localeLowerCase(str, locale) { 6383 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 6384 if (lang) 6385 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 6386 return lowerCase(str); 6387 } 6388 /** 6389 * Lower case as a function. 6390 */ 6391 function lowerCase(str) { 6392 return str.toLowerCase(); 6393 } 6394 6395 ;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js 6396 6397 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 6398 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 6399 // Remove all non-word characters. 6400 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 6401 /** 6402 * Normalize the string into something other libraries can manipulate easier. 6403 */ 6404 function noCase(input, options) { 6405 if (options === void 0) { options = {}; } 6406 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; 6407 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 6408 var start = 0; 6409 var end = result.length; 6410 // Trim the delimiter from around the output string. 6411 while (result.charAt(start) === "\0") 6412 start++; 6413 while (result.charAt(end - 1) === "\0") 6414 end--; 6415 // Transform each token independently. 6416 return result.slice(start, end).split("\0").map(transform).join(delimiter); 6417 } 6418 /** 6419 * Replace `re` in the input string with the replacement value. 6420 */ 6421 function replace(input, re, value) { 6422 if (re instanceof RegExp) 6423 return input.replace(re, value); 6424 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 6425 } 6426 6427 ;// CONCATENATED MODULE: ./node_modules/pascal-case/dist.es2015/index.js 6428 6429 6430 function pascalCaseTransform(input, index) { 6431 var firstChar = input.charAt(0); 6432 var lowerChars = input.substr(1).toLowerCase(); 6433 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 6434 return "_" + firstChar + lowerChars; 6435 } 6436 return "" + firstChar.toUpperCase() + lowerChars; 6437 } 6438 function dist_es2015_pascalCaseTransformMerge(input) { 6439 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase(); 6440 } 6441 function pascalCase(input, options) { 6442 if (options === void 0) { options = {}; } 6443 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 6444 } 6445 6446 ;// CONCATENATED MODULE: ./node_modules/camel-case/dist.es2015/index.js 6447 6448 6449 function camelCaseTransform(input, index) { 6450 if (index === 0) 6451 return input.toLowerCase(); 6452 return pascalCaseTransform(input, index); 6453 } 6454 function camelCaseTransformMerge(input, index) { 6455 if (index === 0) 6456 return input.toLowerCase(); 6457 return pascalCaseTransformMerge(input); 6458 } 6459 function camelCase(input, options) { 6460 if (options === void 0) { options = {}; } 6461 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 6462 } 6463 6464 ;// CONCATENATED MODULE: external ["wp","i18n"] 6465 const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 6466 ;// CONCATENATED MODULE: ./node_modules/colord/index.mjs 6467 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()})}; 6468 6469 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs 6470 /* 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"])} 6471 6472 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs 6473 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}} 6474 6475 ;// CONCATENATED MODULE: external ["wp","element"] 6476 const external_wp_element_namespaceObject = window["wp"]["element"]; 6477 ;// CONCATENATED MODULE: external ["wp","dom"] 6478 const external_wp_dom_namespaceObject = window["wp"]["dom"]; 6479 ;// CONCATENATED MODULE: external ["wp","richText"] 6480 const external_wp_richText_namespaceObject = window["wp"]["richText"]; 6481 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/constants.js 6482 const BLOCK_ICON_DEFAULT = 'block-default'; 6483 6484 /** 6485 * Array of valid keys in a block type settings deprecation object. 6486 * 6487 * @type {string[]} 6488 */ 6489 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 6490 const __EXPERIMENTAL_STYLE_PROPERTY = { 6491 // Kept for back-compatibility purposes. 6492 '--wp--style--color--link': { 6493 value: ['color', 'link'], 6494 support: ['color', 'link'] 6495 }, 6496 aspectRatio: { 6497 value: ['dimensions', 'aspectRatio'], 6498 support: ['dimensions', 'aspectRatio'], 6499 useEngine: true 6500 }, 6501 background: { 6502 value: ['color', 'gradient'], 6503 support: ['color', 'gradients'], 6504 useEngine: true 6505 }, 6506 backgroundColor: { 6507 value: ['color', 'background'], 6508 support: ['color', 'background'], 6509 requiresOptOut: true, 6510 useEngine: true 6511 }, 6512 backgroundRepeat: { 6513 value: ['background', 'backgroundRepeat'], 6514 support: ['background', 'backgroundRepeat'], 6515 useEngine: true 6516 }, 6517 backgroundSize: { 6518 value: ['background', 'backgroundSize'], 6519 support: ['background', 'backgroundSize'], 6520 useEngine: true 6521 }, 6522 borderColor: { 6523 value: ['border', 'color'], 6524 support: ['__experimentalBorder', 'color'], 6525 useEngine: true 6526 }, 6527 borderRadius: { 6528 value: ['border', 'radius'], 6529 support: ['__experimentalBorder', 'radius'], 6530 properties: { 6531 borderTopLeftRadius: 'topLeft', 6532 borderTopRightRadius: 'topRight', 6533 borderBottomLeftRadius: 'bottomLeft', 6534 borderBottomRightRadius: 'bottomRight' 6535 }, 6536 useEngine: true 6537 }, 6538 borderStyle: { 6539 value: ['border', 'style'], 6540 support: ['__experimentalBorder', 'style'], 6541 useEngine: true 6542 }, 6543 borderWidth: { 6544 value: ['border', 'width'], 6545 support: ['__experimentalBorder', 'width'], 6546 useEngine: true 6547 }, 6548 borderTopColor: { 6549 value: ['border', 'top', 'color'], 6550 support: ['__experimentalBorder', 'color'], 6551 useEngine: true 6552 }, 6553 borderTopStyle: { 6554 value: ['border', 'top', 'style'], 6555 support: ['__experimentalBorder', 'style'], 6556 useEngine: true 6557 }, 6558 borderTopWidth: { 6559 value: ['border', 'top', 'width'], 6560 support: ['__experimentalBorder', 'width'], 6561 useEngine: true 6562 }, 6563 borderRightColor: { 6564 value: ['border', 'right', 'color'], 6565 support: ['__experimentalBorder', 'color'], 6566 useEngine: true 6567 }, 6568 borderRightStyle: { 6569 value: ['border', 'right', 'style'], 6570 support: ['__experimentalBorder', 'style'], 6571 useEngine: true 6572 }, 6573 borderRightWidth: { 6574 value: ['border', 'right', 'width'], 6575 support: ['__experimentalBorder', 'width'], 6576 useEngine: true 6577 }, 6578 borderBottomColor: { 6579 value: ['border', 'bottom', 'color'], 6580 support: ['__experimentalBorder', 'color'], 6581 useEngine: true 6582 }, 6583 borderBottomStyle: { 6584 value: ['border', 'bottom', 'style'], 6585 support: ['__experimentalBorder', 'style'], 6586 useEngine: true 6587 }, 6588 borderBottomWidth: { 6589 value: ['border', 'bottom', 'width'], 6590 support: ['__experimentalBorder', 'width'], 6591 useEngine: true 6592 }, 6593 borderLeftColor: { 6594 value: ['border', 'left', 'color'], 6595 support: ['__experimentalBorder', 'color'], 6596 useEngine: true 6597 }, 6598 borderLeftStyle: { 6599 value: ['border', 'left', 'style'], 6600 support: ['__experimentalBorder', 'style'], 6601 useEngine: true 6602 }, 6603 borderLeftWidth: { 6604 value: ['border', 'left', 'width'], 6605 support: ['__experimentalBorder', 'width'], 6606 useEngine: true 6607 }, 6608 color: { 6609 value: ['color', 'text'], 6610 support: ['color', 'text'], 6611 requiresOptOut: true, 6612 useEngine: true 6613 }, 6614 columnCount: { 6615 value: ['typography', 'textColumns'], 6616 support: ['typography', 'textColumns'], 6617 useEngine: true 6618 }, 6619 filter: { 6620 value: ['filter', 'duotone'], 6621 support: ['filter', 'duotone'] 6622 }, 6623 linkColor: { 6624 value: ['elements', 'link', 'color', 'text'], 6625 support: ['color', 'link'] 6626 }, 6627 captionColor: { 6628 value: ['elements', 'caption', 'color', 'text'], 6629 support: ['color', 'caption'] 6630 }, 6631 buttonColor: { 6632 value: ['elements', 'button', 'color', 'text'], 6633 support: ['color', 'button'] 6634 }, 6635 buttonBackgroundColor: { 6636 value: ['elements', 'button', 'color', 'background'], 6637 support: ['color', 'button'] 6638 }, 6639 headingColor: { 6640 value: ['elements', 'heading', 'color', 'text'], 6641 support: ['color', 'heading'] 6642 }, 6643 headingBackgroundColor: { 6644 value: ['elements', 'heading', 'color', 'background'], 6645 support: ['color', 'heading'] 6646 }, 6647 fontFamily: { 6648 value: ['typography', 'fontFamily'], 6649 support: ['typography', '__experimentalFontFamily'], 6650 useEngine: true 6651 }, 6652 fontSize: { 6653 value: ['typography', 'fontSize'], 6654 support: ['typography', 'fontSize'], 6655 useEngine: true 6656 }, 6657 fontStyle: { 6658 value: ['typography', 'fontStyle'], 6659 support: ['typography', '__experimentalFontStyle'], 6660 useEngine: true 6661 }, 6662 fontWeight: { 6663 value: ['typography', 'fontWeight'], 6664 support: ['typography', '__experimentalFontWeight'], 6665 useEngine: true 6666 }, 6667 lineHeight: { 6668 value: ['typography', 'lineHeight'], 6669 support: ['typography', 'lineHeight'], 6670 useEngine: true 6671 }, 6672 margin: { 6673 value: ['spacing', 'margin'], 6674 support: ['spacing', 'margin'], 6675 properties: { 6676 marginTop: 'top', 6677 marginRight: 'right', 6678 marginBottom: 'bottom', 6679 marginLeft: 'left' 6680 }, 6681 useEngine: true 6682 }, 6683 minHeight: { 6684 value: ['dimensions', 'minHeight'], 6685 support: ['dimensions', 'minHeight'], 6686 useEngine: true 6687 }, 6688 padding: { 6689 value: ['spacing', 'padding'], 6690 support: ['spacing', 'padding'], 6691 properties: { 6692 paddingTop: 'top', 6693 paddingRight: 'right', 6694 paddingBottom: 'bottom', 6695 paddingLeft: 'left' 6696 }, 6697 useEngine: true 6698 }, 6699 textDecoration: { 6700 value: ['typography', 'textDecoration'], 6701 support: ['typography', '__experimentalTextDecoration'], 6702 useEngine: true 6703 }, 6704 textTransform: { 6705 value: ['typography', 'textTransform'], 6706 support: ['typography', '__experimentalTextTransform'], 6707 useEngine: true 6708 }, 6709 letterSpacing: { 6710 value: ['typography', 'letterSpacing'], 6711 support: ['typography', '__experimentalLetterSpacing'], 6712 useEngine: true 6713 }, 6714 writingMode: { 6715 value: ['typography', 'writingMode'], 6716 support: ['typography', '__experimentalWritingMode'], 6717 useEngine: true 6718 }, 6719 '--wp--style--root--padding': { 6720 value: ['spacing', 'padding'], 6721 support: ['spacing', 'padding'], 6722 properties: { 6723 '--wp--style--root--padding-top': 'top', 6724 '--wp--style--root--padding-right': 'right', 6725 '--wp--style--root--padding-bottom': 'bottom', 6726 '--wp--style--root--padding-left': 'left' 6727 }, 6728 rootOnly: true 6729 } 6730 }; 6731 const __EXPERIMENTAL_ELEMENTS = { 6732 link: 'a', 6733 heading: 'h1, h2, h3, h4, h5, h6', 6734 h1: 'h1', 6735 h2: 'h2', 6736 h3: 'h3', 6737 h4: 'h4', 6738 h5: 'h5', 6739 h6: 'h6', 6740 button: '.wp-element-button, .wp-block-button__link', 6741 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', 6742 cite: 'cite' 6743 }; 6744 6745 // These paths may have three origins, custom, theme, and default, 6746 // and are expected to override other origins with custom, theme, 6747 // and default priority. 6748 const __EXPERIMENTAL_PATHS_WITH_OVERRIDE = { 6749 'color.duotone': true, 6750 'color.gradients': true, 6751 'color.palette': true, 6752 'typography.fontSizes': true, 6753 'spacing.spacingSizes': true 6754 }; 6755 6756 ;// CONCATENATED MODULE: external ["wp","privateApis"] 6757 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 6758 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/lock-unlock.js 6759 /** 6760 * WordPress dependencies 6761 */ 6762 6763 const { 6764 lock, 6765 unlock 6766 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/blocks'); 6767 6768 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/registration.js 6769 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ 6770 6771 /** 6772 * WordPress dependencies 6773 */ 6774 6775 6776 6777 /** 6778 * Internal dependencies 6779 */ 6780 const i18nBlockSchema = { 6781 title: "block title", 6782 description: "block description", 6783 keywords: ["block keyword"], 6784 styles: [{ 6785 label: "block style label" 6786 }], 6787 variations: [{ 6788 title: "block variation title", 6789 description: "block variation description", 6790 keywords: ["block variation keyword"] 6791 }] 6792 }; 6793 6794 6795 6796 /** 6797 * An icon type definition. One of a Dashicon slug, an element, 6798 * or a component. 6799 * 6800 * @typedef {(string|Element|Component)} WPIcon 6801 * 6802 * @see https://developer.wordpress.org/resource/dashicons/ 6803 */ 6804 6805 /** 6806 * Render behavior of a block type icon; one of a Dashicon slug, an element, 6807 * or a component. 6808 * 6809 * @typedef {WPIcon} WPBlockTypeIconRender 6810 */ 6811 6812 /** 6813 * An object describing a normalized block type icon. 6814 * 6815 * @typedef {Object} WPBlockTypeIconDescriptor 6816 * 6817 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 6818 * one of a Dashicon slug, an 6819 * element, or a component. 6820 * @property {string} background Optimal background hex string 6821 * color when displaying icon. 6822 * @property {string} foreground Optimal foreground hex string 6823 * color when displaying icon. 6824 * @property {string} shadowColor Optimal shadow hex string 6825 * color when displaying icon. 6826 */ 6827 6828 /** 6829 * Value to use to render the icon for a block type in an editor interface, 6830 * either a Dashicon slug, an element, a component, or an object describing 6831 * the icon. 6832 * 6833 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 6834 */ 6835 6836 /** 6837 * Named block variation scopes. 6838 * 6839 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 6840 */ 6841 6842 /** 6843 * An object describing a variation defined for the block type. 6844 * 6845 * @typedef {Object} WPBlockVariation 6846 * 6847 * @property {string} name The unique and machine-readable name. 6848 * @property {string} title A human-readable variation title. 6849 * @property {string} [description] A detailed variation description. 6850 * @property {string} [category] Block type category classification, 6851 * used in search interfaces to arrange 6852 * block types by category. 6853 * @property {WPIcon} [icon] An icon helping to visualize the variation. 6854 * @property {boolean} [isDefault] Indicates whether the current variation is 6855 * the default one. Defaults to `false`. 6856 * @property {Object} [attributes] Values which override block attributes. 6857 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 6858 * @property {Object} [example] Example provides structured data for 6859 * the block preview. You can set to 6860 * `undefined` to disable the preview shown 6861 * for the block type. 6862 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 6863 * is applicable. When not provided, it 6864 * assumes all available scopes. 6865 * @property {string[]} [keywords] An array of terms (which can be translated) 6866 * that help users discover the variation 6867 * while searching. 6868 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 6869 * Function that accepts a block's attributes and the 6870 * variation's attributes and determines if a variation is active. 6871 * This function doesn't try to find a match dynamically based 6872 * on all block's attributes, as in many cases some attributes are irrelevant. 6873 * An example would be for `embed` block where we only care 6874 * about `providerNameSlug` attribute's value. 6875 * We can also use a `string[]` to tell which attributes 6876 * should be compared as a shorthand. Each attributes will 6877 * be matched and the variation will be active if all of them are matching. 6878 */ 6879 6880 /** 6881 * Defined behavior of a block type. 6882 * 6883 * @typedef {Object} WPBlockType 6884 * 6885 * @property {string} name Block type's namespaced name. 6886 * @property {string} title Human-readable block type label. 6887 * @property {string} [description] A detailed block type description. 6888 * @property {string} [category] Block type category classification, 6889 * used in search interfaces to arrange 6890 * block types by category. 6891 * @property {WPBlockTypeIcon} [icon] Block type icon. 6892 * @property {string[]} [keywords] Additional keywords to produce block 6893 * type as result in search interfaces. 6894 * @property {Object} [attributes] Block type attributes. 6895 * @property {Component} [save] Optional component describing 6896 * serialized markup structure of a 6897 * block type. 6898 * @property {Component} edit Component rendering an element to 6899 * manipulate the attributes of a block 6900 * in the context of an editor. 6901 * @property {WPBlockVariation[]} [variations] The list of block variations. 6902 * @property {Object} [example] Example provides structured data for 6903 * the block preview. When not defined 6904 * then no preview is shown. 6905 */ 6906 6907 function isObject(object) { 6908 return object !== null && typeof object === 'object'; 6909 } 6910 6911 /** 6912 * Sets the server side block definition of blocks. 6913 * 6914 * @param {Object} definitions Server-side block definitions 6915 */ 6916 // eslint-disable-next-line camelcase 6917 function unstable__bootstrapServerSideBlockDefinitions(definitions) { 6918 const { 6919 addBootstrappedBlockType 6920 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 6921 for (const [name, blockType] of Object.entries(definitions)) { 6922 addBootstrappedBlockType(name, blockType); 6923 } 6924 } 6925 6926 /** 6927 * Gets block settings from metadata loaded from `block.json` file. 6928 * 6929 * @param {Object} metadata Block metadata loaded from `block.json`. 6930 * @param {string} metadata.textdomain Textdomain to use with translations. 6931 * 6932 * @return {Object} Block settings. 6933 */ 6934 function getBlockSettingsFromMetadata({ 6935 textdomain, 6936 ...metadata 6937 }) { 6938 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations', 'blockHooks', 'allowedBlocks']; 6939 const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key))); 6940 if (textdomain) { 6941 Object.keys(i18nBlockSchema).forEach(key => { 6942 if (!settings[key]) { 6943 return; 6944 } 6945 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 6946 }); 6947 } 6948 return settings; 6949 } 6950 6951 /** 6952 * Registers a new block provided a unique name and an object defining its 6953 * behavior. Once registered, the block is made available as an option to any 6954 * editor interface where blocks are implemented. 6955 * 6956 * For more in-depth information on registering a custom block see the 6957 * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). 6958 * 6959 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 6960 * @param {Object} settings Block settings. 6961 * 6962 * @example 6963 * ```js 6964 * import { __ } from '@wordpress/i18n'; 6965 * import { registerBlockType } from '@wordpress/blocks' 6966 * 6967 * registerBlockType( 'namespace/block-name', { 6968 * title: __( 'My First Block' ), 6969 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 6970 * save: () => <div>Hello from the saved content!</div>, 6971 * } ); 6972 * ``` 6973 * 6974 * @return {WPBlockType | undefined} The block, if it has been successfully registered; 6975 * otherwise `undefined`. 6976 */ 6977 function registerBlockType(blockNameOrMetadata, settings) { 6978 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 6979 if (typeof name !== 'string') { 6980 console.error('Block names must be strings.'); 6981 return; 6982 } 6983 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 6984 console.error('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block'); 6985 return; 6986 } 6987 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) { 6988 console.error('Block "' + name + '" is already registered.'); 6989 return; 6990 } 6991 const { 6992 addBootstrappedBlockType, 6993 addUnprocessedBlockType 6994 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 6995 if (isObject(blockNameOrMetadata)) { 6996 const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata); 6997 addBootstrappedBlockType(name, metadata); 6998 } 6999 addUnprocessedBlockType(name, settings); 7000 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7001 } 7002 7003 /** 7004 * Translates block settings provided with metadata using the i18n schema. 7005 * 7006 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 7007 * @param {string|string[]|Object[]} settingValue Value for the block setting. 7008 * @param {string} textdomain Textdomain to use with translations. 7009 * 7010 * @return {string|string[]|Object[]} Translated setting. 7011 */ 7012 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 7013 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') { 7014 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 7015 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain); 7016 } 7017 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) { 7018 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 7019 } 7020 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) { 7021 return Object.keys(settingValue).reduce((accumulator, key) => { 7022 if (!i18nSchema[key]) { 7023 accumulator[key] = settingValue[key]; 7024 return accumulator; 7025 } 7026 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 7027 return accumulator; 7028 }, {}); 7029 } 7030 return settingValue; 7031 } 7032 7033 /** 7034 * Registers a new block collection to group blocks in the same namespace in the inserter. 7035 * 7036 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 7037 * @param {Object} settings The block collection settings. 7038 * @param {string} settings.title The title to display in the block inserter. 7039 * @param {Object} [settings.icon] The icon to display in the block inserter. 7040 * 7041 * @example 7042 * ```js 7043 * import { __ } from '@wordpress/i18n'; 7044 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks'; 7045 * 7046 * // Register the collection. 7047 * registerBlockCollection( 'my-collection', { 7048 * title: __( 'Custom Collection' ), 7049 * } ); 7050 * 7051 * // Register a block in the same namespace to add it to the collection. 7052 * registerBlockType( 'my-collection/block-name', { 7053 * title: __( 'My First Block' ), 7054 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7055 * save: () => <div>'Hello from the saved content!</div>, 7056 * } ); 7057 * ``` 7058 */ 7059 function registerBlockCollection(namespace, { 7060 title, 7061 icon 7062 }) { 7063 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon); 7064 } 7065 7066 /** 7067 * Unregisters a block collection 7068 * 7069 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 7070 * 7071 * @example 7072 * ```js 7073 * import { unregisterBlockCollection } from '@wordpress/blocks'; 7074 * 7075 * unregisterBlockCollection( 'my-collection' ); 7076 * ``` 7077 */ 7078 function unregisterBlockCollection(namespace) { 7079 dispatch(blocksStore).removeBlockCollection(namespace); 7080 } 7081 7082 /** 7083 * Unregisters a block. 7084 * 7085 * @param {string} name Block name. 7086 * 7087 * @example 7088 * ```js 7089 * import { __ } from '@wordpress/i18n'; 7090 * import { unregisterBlockType } from '@wordpress/blocks'; 7091 * 7092 * const ExampleComponent = () => { 7093 * return ( 7094 * <Button 7095 * onClick={ () => 7096 * unregisterBlockType( 'my-collection/block-name' ) 7097 * } 7098 * > 7099 * { __( 'Unregister my custom block.' ) } 7100 * </Button> 7101 * ); 7102 * }; 7103 * ``` 7104 * 7105 * @return {WPBlockType | undefined} The previous block value, if it has been successfully 7106 * unregistered; otherwise `undefined`. 7107 */ 7108 function unregisterBlockType(name) { 7109 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7110 if (!oldBlock) { 7111 console.error('Block "' + name + '" is not registered.'); 7112 return; 7113 } 7114 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name); 7115 return oldBlock; 7116 } 7117 7118 /** 7119 * Assigns name of block for handling non-block content. 7120 * 7121 * @param {string} blockName Block name. 7122 */ 7123 function setFreeformContentHandlerName(blockName) { 7124 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName); 7125 } 7126 7127 /** 7128 * Retrieves name of block handling non-block content, or undefined if no 7129 * handler has been defined. 7130 * 7131 * @return {?string} Block name. 7132 */ 7133 function getFreeformContentHandlerName() { 7134 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName(); 7135 } 7136 7137 /** 7138 * Retrieves name of block used for handling grouping interactions. 7139 * 7140 * @return {?string} Block name. 7141 */ 7142 function getGroupingBlockName() { 7143 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName(); 7144 } 7145 7146 /** 7147 * Assigns name of block handling unregistered block types. 7148 * 7149 * @param {string} blockName Block name. 7150 */ 7151 function setUnregisteredTypeHandlerName(blockName) { 7152 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName); 7153 } 7154 7155 /** 7156 * Retrieves name of block handling unregistered block types, or undefined if no 7157 * handler has been defined. 7158 * 7159 * @return {?string} Block name. 7160 */ 7161 function getUnregisteredTypeHandlerName() { 7162 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName(); 7163 } 7164 7165 /** 7166 * Assigns the default block name. 7167 * 7168 * @param {string} name Block name. 7169 * 7170 * @example 7171 * ```js 7172 * import { setDefaultBlockName } from '@wordpress/blocks'; 7173 * 7174 * const ExampleComponent = () => { 7175 * 7176 * return ( 7177 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }> 7178 * { __( 'Set the default block to Heading' ) } 7179 * </Button> 7180 * ); 7181 * }; 7182 * ``` 7183 */ 7184 function setDefaultBlockName(name) { 7185 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name); 7186 } 7187 7188 /** 7189 * Assigns name of block for handling block grouping interactions. 7190 * 7191 * This function lets you select a different block to group other blocks in instead of the 7192 * default `core/group` block. This function must be used in a component or when the DOM is fully 7193 * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/ 7194 * 7195 * @param {string} name Block name. 7196 * 7197 * @example 7198 * ```js 7199 * import { setGroupingBlockName } from '@wordpress/blocks'; 7200 * 7201 * const ExampleComponent = () => { 7202 * 7203 * return ( 7204 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }> 7205 * { __( 'Wrap in columns' ) } 7206 * </Button> 7207 * ); 7208 * }; 7209 * ``` 7210 */ 7211 function setGroupingBlockName(name) { 7212 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name); 7213 } 7214 7215 /** 7216 * Retrieves the default block name. 7217 * 7218 * @return {?string} Block name. 7219 */ 7220 function getDefaultBlockName() { 7221 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName(); 7222 } 7223 7224 /** 7225 * Returns a registered block type. 7226 * 7227 * @param {string} name Block name. 7228 * 7229 * @return {?Object} Block type. 7230 */ 7231 function getBlockType(name) { 7232 return (0,external_wp_data_namespaceObject.select)(store)?.getBlockType(name); 7233 } 7234 7235 /** 7236 * Returns all registered blocks. 7237 * 7238 * @return {Array} Block settings. 7239 */ 7240 function getBlockTypes() { 7241 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes(); 7242 } 7243 7244 /** 7245 * Returns the block support value for a feature, if defined. 7246 * 7247 * @param {(string|Object)} nameOrType Block name or type object 7248 * @param {string} feature Feature to retrieve 7249 * @param {*} defaultSupports Default value to return if not 7250 * explicitly defined 7251 * 7252 * @return {?*} Block support value 7253 */ 7254 function getBlockSupport(nameOrType, feature, defaultSupports) { 7255 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports); 7256 } 7257 7258 /** 7259 * Returns true if the block defines support for a feature, or false otherwise. 7260 * 7261 * @param {(string|Object)} nameOrType Block name or type object. 7262 * @param {string} feature Feature to test. 7263 * @param {boolean} defaultSupports Whether feature is supported by 7264 * default if not explicitly defined. 7265 * 7266 * @return {boolean} Whether block supports feature. 7267 */ 7268 function hasBlockSupport(nameOrType, feature, defaultSupports) { 7269 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports); 7270 } 7271 7272 /** 7273 * Determines whether or not the given block is a reusable block. This is a 7274 * special block type that is used to point to a global block stored via the 7275 * API. 7276 * 7277 * @param {Object} blockOrType Block or Block Type to test. 7278 * 7279 * @return {boolean} Whether the given block is a reusable block. 7280 */ 7281 function isReusableBlock(blockOrType) { 7282 return blockOrType?.name === 'core/block'; 7283 } 7284 7285 /** 7286 * Determines whether or not the given block is a template part. This is a 7287 * special block type that allows composing a page template out of reusable 7288 * design elements. 7289 * 7290 * @param {Object} blockOrType Block or Block Type to test. 7291 * 7292 * @return {boolean} Whether the given block is a template part. 7293 */ 7294 function isTemplatePart(blockOrType) { 7295 return blockOrType?.name === 'core/template-part'; 7296 } 7297 7298 /** 7299 * Returns an array with the child blocks of a given block. 7300 * 7301 * @param {string} blockName Name of block (example: “latest-posts”). 7302 * 7303 * @return {Array} Array of child block names. 7304 */ 7305 const getChildBlockNames = blockName => { 7306 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName); 7307 }; 7308 7309 /** 7310 * Returns a boolean indicating if a block has child blocks or not. 7311 * 7312 * @param {string} blockName Name of block (example: “latest-posts”). 7313 * 7314 * @return {boolean} True if a block contains child blocks and false otherwise. 7315 */ 7316 const hasChildBlocks = blockName => { 7317 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName); 7318 }; 7319 7320 /** 7321 * Returns a boolean indicating if a block has at least one child block with inserter support. 7322 * 7323 * @param {string} blockName Block type name. 7324 * 7325 * @return {boolean} True if a block contains at least one child blocks with inserter support 7326 * and false otherwise. 7327 */ 7328 const hasChildBlocksWithInserterSupport = blockName => { 7329 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName); 7330 }; 7331 7332 /** 7333 * Registers a new block style for the given block. 7334 * 7335 * For more information on connecting the styles with CSS 7336 * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). 7337 * 7338 * @param {string} blockName Name of block (example: “core/latest-posts”). 7339 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 7340 * 7341 * @example 7342 * ```js 7343 * import { __ } from '@wordpress/i18n'; 7344 * import { registerBlockStyle } from '@wordpress/blocks'; 7345 * import { Button } from '@wordpress/components'; 7346 * 7347 * 7348 * const ExampleComponent = () => { 7349 * return ( 7350 * <Button 7351 * onClick={ () => { 7352 * registerBlockStyle( 'core/quote', { 7353 * name: 'fancy-quote', 7354 * label: __( 'Fancy Quote' ), 7355 * } ); 7356 * } } 7357 * > 7358 * { __( 'Add a new block style for core/quote' ) } 7359 * </Button> 7360 * ); 7361 * }; 7362 * ``` 7363 */ 7364 const registerBlockStyle = (blockName, styleVariation) => { 7365 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockName, styleVariation); 7366 }; 7367 7368 /** 7369 * Unregisters a block style for the given block. 7370 * 7371 * @param {string} blockName Name of block (example: “core/latest-posts”). 7372 * @param {string} styleVariationName Name of class applied to the block. 7373 * 7374 * @example 7375 * ```js 7376 * import { __ } from '@wordpress/i18n'; 7377 * import { unregisterBlockStyle } from '@wordpress/blocks'; 7378 * import { Button } from '@wordpress/components'; 7379 * 7380 * const ExampleComponent = () => { 7381 * return ( 7382 * <Button 7383 * onClick={ () => { 7384 * unregisterBlockStyle( 'core/quote', 'plain' ); 7385 * } } 7386 * > 7387 * { __( 'Remove the "Plain" block style for core/quote' ) } 7388 * </Button> 7389 * ); 7390 * }; 7391 * ``` 7392 */ 7393 const unregisterBlockStyle = (blockName, styleVariationName) => { 7394 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName); 7395 }; 7396 7397 /** 7398 * Returns an array with the variations of a given block type. 7399 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 7400 * 7401 * @ignore 7402 * 7403 * @param {string} blockName Name of block (example: “core/columns”). 7404 * @param {WPBlockVariationScope} [scope] Block variation scope name. 7405 * 7406 * @return {(WPBlockVariation[]|void)} Block variations. 7407 */ 7408 const getBlockVariations = (blockName, scope) => { 7409 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope); 7410 }; 7411 7412 /** 7413 * Registers a new block variation for the given block type. 7414 * 7415 * For more information on block variations see 7416 * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). 7417 * 7418 * @param {string} blockName Name of the block (example: “core/columns”). 7419 * @param {WPBlockVariation} variation Object describing a block variation. 7420 * 7421 * @example 7422 * ```js 7423 * import { __ } from '@wordpress/i18n'; 7424 * import { registerBlockVariation } from '@wordpress/blocks'; 7425 * import { Button } from '@wordpress/components'; 7426 * 7427 * const ExampleComponent = () => { 7428 * return ( 7429 * <Button 7430 * onClick={ () => { 7431 * registerBlockVariation( 'core/embed', { 7432 * name: 'custom', 7433 * title: __( 'My Custom Embed' ), 7434 * attributes: { providerNameSlug: 'custom' }, 7435 * } ); 7436 * } } 7437 * > 7438 * __( 'Add a custom variation for core/embed' ) } 7439 * </Button> 7440 * ); 7441 * }; 7442 * ``` 7443 */ 7444 const registerBlockVariation = (blockName, variation) => { 7445 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation); 7446 }; 7447 7448 /** 7449 * Unregisters a block variation defined for the given block type. 7450 * 7451 * @param {string} blockName Name of the block (example: “core/columns”). 7452 * @param {string} variationName Name of the variation defined for the block. 7453 * 7454 * @example 7455 * ```js 7456 * import { __ } from '@wordpress/i18n'; 7457 * import { unregisterBlockVariation } from '@wordpress/blocks'; 7458 * import { Button } from '@wordpress/components'; 7459 * 7460 * const ExampleComponent = () => { 7461 * return ( 7462 * <Button 7463 * onClick={ () => { 7464 * unregisterBlockVariation( 'core/embed', 'youtube' ); 7465 * } } 7466 * > 7467 * { __( 'Remove the YouTube variation from core/embed' ) } 7468 * </Button> 7469 * ); 7470 * }; 7471 * ``` 7472 */ 7473 const unregisterBlockVariation = (blockName, variationName) => { 7474 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName); 7475 }; 7476 7477 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/utils.js 7478 /** 7479 * External dependencies 7480 */ 7481 7482 7483 7484 7485 /** 7486 * WordPress dependencies 7487 */ 7488 7489 7490 7491 7492 7493 /** 7494 * Internal dependencies 7495 */ 7496 7497 7498 k([names, a11y]); 7499 7500 /** 7501 * Array of icon colors containing a color to be used if the icon color 7502 * was not explicitly set but the icon background color was. 7503 * 7504 * @type {Object} 7505 */ 7506 const ICON_COLORS = ['#191e23', '#f8f9f9']; 7507 7508 /** 7509 * Determines whether the block's attributes are equal to the default attributes 7510 * which means the block is unmodified. 7511 * 7512 * @param {WPBlock} block Block Object 7513 * 7514 * @return {boolean} Whether the block is an unmodified block. 7515 */ 7516 function isUnmodifiedBlock(block) { 7517 var _getBlockType$attribu; 7518 return Object.entries((_getBlockType$attribu = getBlockType(block.name)?.attributes) !== null && _getBlockType$attribu !== void 0 ? _getBlockType$attribu : {}).every(([key, definition]) => { 7519 const value = block.attributes[key]; 7520 7521 // Every attribute that has a default must match the default. 7522 if (definition.hasOwnProperty('default')) { 7523 return value === definition.default; 7524 } 7525 7526 // The rich text type is a bit different from the rest because it 7527 // has an implicit default value of an empty RichTextData instance, 7528 // so check the length of the value. 7529 if (definition.type === 'rich-text') { 7530 return !value?.length; 7531 } 7532 7533 // Every attribute that doesn't have a default should be undefined. 7534 return value === undefined; 7535 }); 7536 } 7537 7538 /** 7539 * Determines whether the block is a default block and its attributes are equal 7540 * to the default attributes which means the block is unmodified. 7541 * 7542 * @param {WPBlock} block Block Object 7543 * 7544 * @return {boolean} Whether the block is an unmodified default block. 7545 */ 7546 function isUnmodifiedDefaultBlock(block) { 7547 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block); 7548 } 7549 7550 /** 7551 * Function that checks if the parameter is a valid icon. 7552 * 7553 * @param {*} icon Parameter to be checked. 7554 * 7555 * @return {boolean} True if the parameter is a valid icon and false otherwise. 7556 */ 7557 7558 function isValidIcon(icon) { 7559 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component); 7560 } 7561 7562 /** 7563 * Function that receives an icon as set by the blocks during the registration 7564 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 7565 * in the codebase. 7566 * 7567 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 7568 * one of a Dashicon slug, an element, or a 7569 * component. 7570 * 7571 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 7572 */ 7573 function normalizeIconObject(icon) { 7574 icon = icon || BLOCK_ICON_DEFAULT; 7575 if (isValidIcon(icon)) { 7576 return { 7577 src: icon 7578 }; 7579 } 7580 if ('background' in icon) { 7581 const colordBgColor = w(icon.background); 7582 const getColorContrast = iconColor => colordBgColor.contrast(iconColor); 7583 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast)); 7584 return { 7585 ...icon, 7586 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast), 7587 shadowColor: colordBgColor.alpha(0.3).toRgbString() 7588 }; 7589 } 7590 return icon; 7591 } 7592 7593 /** 7594 * Normalizes block type passed as param. When string is passed then 7595 * it converts it to the matching block type object. 7596 * It passes the original object otherwise. 7597 * 7598 * @param {string|Object} blockTypeOrName Block type or name. 7599 * 7600 * @return {?Object} Block type. 7601 */ 7602 function normalizeBlockType(blockTypeOrName) { 7603 if (typeof blockTypeOrName === 'string') { 7604 return getBlockType(blockTypeOrName); 7605 } 7606 return blockTypeOrName; 7607 } 7608 7609 /** 7610 * Get the label for the block, usually this is either the block title, 7611 * or the value of the block's `label` function when that's specified. 7612 * 7613 * @param {Object} blockType The block type. 7614 * @param {Object} attributes The values of the block's attributes. 7615 * @param {Object} context The intended use for the label. 7616 * 7617 * @return {string} The block label. 7618 */ 7619 function getBlockLabel(blockType, attributes, context = 'visual') { 7620 const { 7621 __experimentalLabel: getLabel, 7622 title 7623 } = blockType; 7624 const label = getLabel && getLabel(attributes, { 7625 context 7626 }); 7627 if (!label) { 7628 return title; 7629 } 7630 7631 // Strip any HTML (i.e. RichText formatting) before returning. 7632 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label); 7633 } 7634 7635 /** 7636 * Get a label for the block for use by screenreaders, this is more descriptive 7637 * than the visual label and includes the block title and the value of the 7638 * `getLabel` function if it's specified. 7639 * 7640 * @param {?Object} blockType The block type. 7641 * @param {Object} attributes The values of the block's attributes. 7642 * @param {?number} position The position of the block in the block list. 7643 * @param {string} [direction='vertical'] The direction of the block layout. 7644 * 7645 * @return {string} The block label. 7646 */ 7647 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') { 7648 // `title` is already localized, `label` is a user-supplied value. 7649 const title = blockType?.title; 7650 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : ''; 7651 const hasPosition = position !== undefined; 7652 7653 // getBlockLabel returns the block title as a fallback when there's no label, 7654 // if it did return the title, this function needs to avoid adding the 7655 // title twice within the accessible label. Use this `hasLabel` boolean to 7656 // handle that. 7657 const hasLabel = label && label !== title; 7658 if (hasPosition && direction === 'vertical') { 7659 if (hasLabel) { 7660 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 7661 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label); 7662 } 7663 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. */ 7664 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position); 7665 } else if (hasPosition && direction === 'horizontal') { 7666 if (hasLabel) { 7667 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 7668 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label); 7669 } 7670 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. */ 7671 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position); 7672 } 7673 if (hasLabel) { 7674 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %1: The block title. %2: The block label. */ 7675 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label); 7676 } 7677 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %s: The block title. */ 7678 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title); 7679 } 7680 function getDefault(attributeSchema) { 7681 if (attributeSchema.default !== undefined) { 7682 return attributeSchema.default; 7683 } 7684 if (attributeSchema.type === 'rich-text') { 7685 return new external_wp_richText_namespaceObject.RichTextData(); 7686 } 7687 } 7688 7689 /** 7690 * Ensure attributes contains only values defined by block type, and merge 7691 * default values for missing attributes. 7692 * 7693 * @param {string} name The block's name. 7694 * @param {Object} attributes The block's attributes. 7695 * @return {Object} The sanitized attributes. 7696 */ 7697 function __experimentalSanitizeBlockAttributes(name, attributes) { 7698 // Get the type definition associated with a registered block. 7699 const blockType = getBlockType(name); 7700 if (undefined === blockType) { 7701 throw new Error(`Block type '$name}' is not registered.`); 7702 } 7703 return Object.entries(blockType.attributes).reduce((accumulator, [key, schema]) => { 7704 const value = attributes[key]; 7705 if (undefined !== value) { 7706 if (schema.type === 'rich-text') { 7707 if (value instanceof external_wp_richText_namespaceObject.RichTextData) { 7708 accumulator[key] = value; 7709 } else if (typeof value === 'string') { 7710 accumulator[key] = external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value); 7711 } 7712 } else if (schema.type === 'string' && value instanceof external_wp_richText_namespaceObject.RichTextData) { 7713 accumulator[key] = value.toHTMLString(); 7714 } else { 7715 accumulator[key] = value; 7716 } 7717 } else { 7718 const _default = getDefault(schema); 7719 if (undefined !== _default) { 7720 accumulator[key] = _default; 7721 } 7722 } 7723 if (['node', 'children'].indexOf(schema.source) !== -1) { 7724 // Ensure value passed is always an array, which we're expecting in 7725 // the RichText component to handle the deprecated value. 7726 if (typeof accumulator[key] === 'string') { 7727 accumulator[key] = [accumulator[key]]; 7728 } else if (!Array.isArray(accumulator[key])) { 7729 accumulator[key] = []; 7730 } 7731 } 7732 return accumulator; 7733 }, {}); 7734 } 7735 7736 /** 7737 * Filter block attributes by `role` and return their names. 7738 * 7739 * @param {string} name Block attribute's name. 7740 * @param {string} role The role of a block attribute. 7741 * 7742 * @return {string[]} The attribute names that have the provided role. 7743 */ 7744 function __experimentalGetBlockAttributesNamesByRole(name, role) { 7745 const attributes = getBlockType(name)?.attributes; 7746 if (!attributes) return []; 7747 const attributesNames = Object.keys(attributes); 7748 if (!role) return attributesNames; 7749 return attributesNames.filter(attributeName => attributes[attributeName]?.__experimentalRole === role); 7750 } 7751 7752 /** 7753 * Return a new object with the specified keys omitted. 7754 * 7755 * @param {Object} object Original object. 7756 * @param {Array} keys Keys to be omitted. 7757 * 7758 * @return {Object} Object with omitted keys. 7759 */ 7760 function omit(object, keys) { 7761 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 7762 } 7763 7764 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/reducer.js 7765 /** 7766 * External dependencies 7767 */ 7768 7769 7770 /** 7771 * WordPress dependencies 7772 */ 7773 7774 7775 7776 /** 7777 * Internal dependencies 7778 */ 7779 7780 7781 /** 7782 * @typedef {Object} WPBlockCategory 7783 * 7784 * @property {string} slug Unique category slug. 7785 * @property {string} title Category label, for display in user interface. 7786 */ 7787 7788 /** 7789 * Default set of categories. 7790 * 7791 * @type {WPBlockCategory[]} 7792 */ 7793 const DEFAULT_CATEGORIES = [{ 7794 slug: 'text', 7795 title: (0,external_wp_i18n_namespaceObject.__)('Text') 7796 }, { 7797 slug: 'media', 7798 title: (0,external_wp_i18n_namespaceObject.__)('Media') 7799 }, { 7800 slug: 'design', 7801 title: (0,external_wp_i18n_namespaceObject.__)('Design') 7802 }, { 7803 slug: 'widgets', 7804 title: (0,external_wp_i18n_namespaceObject.__)('Widgets') 7805 }, { 7806 slug: 'theme', 7807 title: (0,external_wp_i18n_namespaceObject.__)('Theme') 7808 }, { 7809 slug: 'embed', 7810 title: (0,external_wp_i18n_namespaceObject.__)('Embeds') 7811 }, { 7812 slug: 'reusable', 7813 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks') 7814 }]; 7815 7816 // Key block types by their name. 7817 function keyBlockTypesByName(types) { 7818 return types.reduce((newBlockTypes, block) => ({ 7819 ...newBlockTypes, 7820 [block.name]: block 7821 }), {}); 7822 } 7823 7824 // Filter items to ensure they're unique by their name. 7825 function getUniqueItemsByName(items) { 7826 return items.reduce((acc, currentItem) => { 7827 if (!acc.some(item => item.name === currentItem.name)) { 7828 acc.push(currentItem); 7829 } 7830 return acc; 7831 }, []); 7832 } 7833 function bootstrappedBlockTypes(state = {}, action) { 7834 switch (action.type) { 7835 case 'ADD_BOOTSTRAPPED_BLOCK_TYPE': 7836 const { 7837 name, 7838 blockType 7839 } = action; 7840 const serverDefinition = state[name]; 7841 let newDefinition; 7842 // Don't overwrite if already set. It covers the case when metadata 7843 // was initialized from the server. 7844 if (serverDefinition) { 7845 // The `selectors` prop is not yet included in the server provided 7846 // definitions and needs to be polyfilled. This can be removed when the 7847 // minimum supported WordPress is >= 6.3. 7848 if (serverDefinition.selectors === undefined && blockType.selectors) { 7849 newDefinition = { 7850 ...serverDefinition, 7851 selectors: blockType.selectors 7852 }; 7853 } 7854 7855 // The `blockHooks` prop is not yet included in the server provided 7856 // definitions and needs to be polyfilled. This can be removed when the 7857 // minimum supported WordPress is >= 6.4. 7858 if (serverDefinition.blockHooks === undefined && blockType.blockHooks) { 7859 newDefinition = { 7860 ...serverDefinition, 7861 ...newDefinition, 7862 blockHooks: blockType.blockHooks 7863 }; 7864 } 7865 7866 // The `allowedBlocks` prop is not yet included in the server provided 7867 // definitions and needs to be polyfilled. This can be removed when the 7868 // minimum supported WordPress is >= 6.5. 7869 if (serverDefinition.allowedBlocks === undefined && blockType.allowedBlocks) { 7870 newDefinition = { 7871 ...serverDefinition, 7872 ...newDefinition, 7873 allowedBlocks: blockType.allowedBlocks 7874 }; 7875 } 7876 } else { 7877 newDefinition = Object.fromEntries(Object.entries(blockType).filter(([, value]) => value !== null && value !== undefined).map(([key, value]) => [camelCase(key), value])); 7878 newDefinition.name = name; 7879 } 7880 if (newDefinition) { 7881 return { 7882 ...state, 7883 [name]: newDefinition 7884 }; 7885 } 7886 return state; 7887 case 'REMOVE_BLOCK_TYPES': 7888 return omit(state, action.names); 7889 } 7890 return state; 7891 } 7892 7893 /** 7894 * Reducer managing the unprocessed block types in a form passed when registering the by block. 7895 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters 7896 * get added or removed. 7897 * 7898 * @param {Object} state Current state. 7899 * @param {Object} action Dispatched action. 7900 * 7901 * @return {Object} Updated state. 7902 */ 7903 function unprocessedBlockTypes(state = {}, action) { 7904 switch (action.type) { 7905 case 'ADD_UNPROCESSED_BLOCK_TYPE': 7906 return { 7907 ...state, 7908 [action.name]: action.blockType 7909 }; 7910 case 'REMOVE_BLOCK_TYPES': 7911 return omit(state, action.names); 7912 } 7913 return state; 7914 } 7915 7916 /** 7917 * Reducer managing the processed block types with all filters applied. 7918 * The state is derived from the `unprocessedBlockTypes` reducer. 7919 * 7920 * @param {Object} state Current state. 7921 * @param {Object} action Dispatched action. 7922 * 7923 * @return {Object} Updated state. 7924 */ 7925 function blockTypes(state = {}, action) { 7926 switch (action.type) { 7927 case 'ADD_BLOCK_TYPES': 7928 return { 7929 ...state, 7930 ...keyBlockTypesByName(action.blockTypes) 7931 }; 7932 case 'REMOVE_BLOCK_TYPES': 7933 return omit(state, action.names); 7934 } 7935 return state; 7936 } 7937 7938 /** 7939 * Reducer managing the block styles. 7940 * 7941 * @param {Object} state Current state. 7942 * @param {Object} action Dispatched action. 7943 * 7944 * @return {Object} Updated state. 7945 */ 7946 function blockStyles(state = {}, action) { 7947 var _state$action$blockNa, _state$action$blockNa2; 7948 switch (action.type) { 7949 case 'ADD_BLOCK_TYPES': 7950 return { 7951 ...state, 7952 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 7953 var _blockType$styles, _state$blockType$name; 7954 return [name, getUniqueItemsByName([...((_blockType$styles = blockType.styles) !== null && _blockType$styles !== void 0 ? _blockType$styles : []).map(style => ({ 7955 ...style, 7956 source: 'block' 7957 })), ...((_state$blockType$name = state[blockType.name]) !== null && _state$blockType$name !== void 0 ? _state$blockType$name : []).filter(({ 7958 source 7959 }) => 'block' !== source)])]; 7960 })) 7961 }; 7962 case 'ADD_BLOCK_STYLES': 7963 return { 7964 ...state, 7965 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa = state[action.blockName]) !== null && _state$action$blockNa !== void 0 ? _state$action$blockNa : []), ...action.styles]) 7966 }; 7967 case 'REMOVE_BLOCK_STYLES': 7968 return { 7969 ...state, 7970 [action.blockName]: ((_state$action$blockNa2 = state[action.blockName]) !== null && _state$action$blockNa2 !== void 0 ? _state$action$blockNa2 : []).filter(style => action.styleNames.indexOf(style.name) === -1) 7971 }; 7972 } 7973 return state; 7974 } 7975 7976 /** 7977 * Reducer managing the block variations. 7978 * 7979 * @param {Object} state Current state. 7980 * @param {Object} action Dispatched action. 7981 * 7982 * @return {Object} Updated state. 7983 */ 7984 function blockVariations(state = {}, action) { 7985 var _state$action$blockNa3, _state$action$blockNa4; 7986 switch (action.type) { 7987 case 'ADD_BLOCK_TYPES': 7988 return { 7989 ...state, 7990 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 7991 var _blockType$variations, _state$blockType$name2; 7992 return [name, getUniqueItemsByName([...((_blockType$variations = blockType.variations) !== null && _blockType$variations !== void 0 ? _blockType$variations : []).map(variation => ({ 7993 ...variation, 7994 source: 'block' 7995 })), ...((_state$blockType$name2 = state[blockType.name]) !== null && _state$blockType$name2 !== void 0 ? _state$blockType$name2 : []).filter(({ 7996 source 7997 }) => 'block' !== source)])]; 7998 })) 7999 }; 8000 case 'ADD_BLOCK_VARIATIONS': 8001 return { 8002 ...state, 8003 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa3 = state[action.blockName]) !== null && _state$action$blockNa3 !== void 0 ? _state$action$blockNa3 : []), ...action.variations]) 8004 }; 8005 case 'REMOVE_BLOCK_VARIATIONS': 8006 return { 8007 ...state, 8008 [action.blockName]: ((_state$action$blockNa4 = state[action.blockName]) !== null && _state$action$blockNa4 !== void 0 ? _state$action$blockNa4 : []).filter(variation => action.variationNames.indexOf(variation.name) === -1) 8009 }; 8010 } 8011 return state; 8012 } 8013 8014 /** 8015 * Higher-order Reducer creating a reducer keeping track of given block name. 8016 * 8017 * @param {string} setActionType Action type. 8018 * 8019 * @return {Function} Reducer. 8020 */ 8021 function createBlockNameSetterReducer(setActionType) { 8022 return (state = null, action) => { 8023 switch (action.type) { 8024 case 'REMOVE_BLOCK_TYPES': 8025 if (action.names.indexOf(state) !== -1) { 8026 return null; 8027 } 8028 return state; 8029 case setActionType: 8030 return action.name || null; 8031 } 8032 return state; 8033 }; 8034 } 8035 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 8036 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 8037 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 8038 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 8039 8040 /** 8041 * Reducer managing the categories 8042 * 8043 * @param {WPBlockCategory[]} state Current state. 8044 * @param {Object} action Dispatched action. 8045 * 8046 * @return {WPBlockCategory[]} Updated state. 8047 */ 8048 function categories(state = DEFAULT_CATEGORIES, action) { 8049 switch (action.type) { 8050 case 'SET_CATEGORIES': 8051 return action.categories || []; 8052 case 'UPDATE_CATEGORY': 8053 { 8054 if (!action.category || !Object.keys(action.category).length) { 8055 return state; 8056 } 8057 const categoryToChange = state.find(({ 8058 slug 8059 }) => slug === action.slug); 8060 if (categoryToChange) { 8061 return state.map(category => { 8062 if (category.slug === action.slug) { 8063 return { 8064 ...category, 8065 ...action.category 8066 }; 8067 } 8068 return category; 8069 }); 8070 } 8071 } 8072 } 8073 return state; 8074 } 8075 function collections(state = {}, action) { 8076 switch (action.type) { 8077 case 'ADD_BLOCK_COLLECTION': 8078 return { 8079 ...state, 8080 [action.namespace]: { 8081 title: action.title, 8082 icon: action.icon 8083 } 8084 }; 8085 case 'REMOVE_BLOCK_COLLECTION': 8086 return omit(state, action.namespace); 8087 } 8088 return state; 8089 } 8090 function blockBindingsSources(state = {}, action) { 8091 if (action.type === 'REGISTER_BLOCK_BINDINGS_SOURCE') { 8092 var _action$lockAttribute; 8093 return { 8094 ...state, 8095 [action.sourceName]: { 8096 label: action.sourceLabel, 8097 useSource: action.useSource, 8098 lockAttributesEditing: (_action$lockAttribute = action.lockAttributesEditing) !== null && _action$lockAttribute !== void 0 ? _action$lockAttribute : true 8099 } 8100 }; 8101 } 8102 return state; 8103 } 8104 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ 8105 bootstrappedBlockTypes, 8106 unprocessedBlockTypes, 8107 blockTypes, 8108 blockStyles, 8109 blockVariations, 8110 defaultBlockName, 8111 freeformFallbackBlockName, 8112 unregisteredFallbackBlockName, 8113 groupingBlockName, 8114 categories, 8115 collections, 8116 blockBindingsSources 8117 })); 8118 8119 ;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js 8120 8121 8122 /** @typedef {(...args: any[]) => *[]} GetDependants */ 8123 8124 /** @typedef {() => void} Clear */ 8125 8126 /** 8127 * @typedef {{ 8128 * getDependants: GetDependants, 8129 * clear: Clear 8130 * }} EnhancedSelector 8131 */ 8132 8133 /** 8134 * Internal cache entry. 8135 * 8136 * @typedef CacheNode 8137 * 8138 * @property {?CacheNode|undefined} [prev] Previous node. 8139 * @property {?CacheNode|undefined} [next] Next node. 8140 * @property {*[]} args Function arguments for cache entry. 8141 * @property {*} val Function result. 8142 */ 8143 8144 /** 8145 * @typedef Cache 8146 * 8147 * @property {Clear} clear Function to clear cache. 8148 * @property {boolean} [isUniqueByDependants] Whether dependants are valid in 8149 * considering cache uniqueness. A cache is unique if dependents are all arrays 8150 * or objects. 8151 * @property {CacheNode?} [head] Cache head. 8152 * @property {*[]} [lastDependants] Dependants from previous invocation. 8153 */ 8154 8155 /** 8156 * Arbitrary value used as key for referencing cache object in WeakMap tree. 8157 * 8158 * @type {{}} 8159 */ 8160 var LEAF_KEY = {}; 8161 8162 /** 8163 * Returns the first argument as the sole entry in an array. 8164 * 8165 * @template T 8166 * 8167 * @param {T} value Value to return. 8168 * 8169 * @return {[T]} Value returned as entry in array. 8170 */ 8171 function arrayOf(value) { 8172 return [value]; 8173 } 8174 8175 /** 8176 * Returns true if the value passed is object-like, or false otherwise. A value 8177 * is object-like if it can support property assignment, e.g. object or array. 8178 * 8179 * @param {*} value Value to test. 8180 * 8181 * @return {boolean} Whether value is object-like. 8182 */ 8183 function isObjectLike(value) { 8184 return !!value && 'object' === typeof value; 8185 } 8186 8187 /** 8188 * Creates and returns a new cache object. 8189 * 8190 * @return {Cache} Cache object. 8191 */ 8192 function createCache() { 8193 /** @type {Cache} */ 8194 var cache = { 8195 clear: function () { 8196 cache.head = null; 8197 }, 8198 }; 8199 8200 return cache; 8201 } 8202 8203 /** 8204 * Returns true if entries within the two arrays are strictly equal by 8205 * reference from a starting index. 8206 * 8207 * @param {*[]} a First array. 8208 * @param {*[]} b Second array. 8209 * @param {number} fromIndex Index from which to start comparison. 8210 * 8211 * @return {boolean} Whether arrays are shallowly equal. 8212 */ 8213 function isShallowEqual(a, b, fromIndex) { 8214 var i; 8215 8216 if (a.length !== b.length) { 8217 return false; 8218 } 8219 8220 for (i = fromIndex; i < a.length; i++) { 8221 if (a[i] !== b[i]) { 8222 return false; 8223 } 8224 } 8225 8226 return true; 8227 } 8228 8229 /** 8230 * Returns a memoized selector function. The getDependants function argument is 8231 * called before the memoized selector and is expected to return an immutable 8232 * reference or array of references on which the selector depends for computing 8233 * its own return value. The memoize cache is preserved only as long as those 8234 * dependant references remain the same. If getDependants returns a different 8235 * reference(s), the cache is cleared and the selector value regenerated. 8236 * 8237 * @template {(...args: *[]) => *} S 8238 * 8239 * @param {S} selector Selector function. 8240 * @param {GetDependants=} getDependants Dependant getter returning an array of 8241 * references used in cache bust consideration. 8242 */ 8243 /* harmony default export */ function rememo(selector, getDependants) { 8244 /** @type {WeakMap<*,*>} */ 8245 var rootCache; 8246 8247 /** @type {GetDependants} */ 8248 var normalizedGetDependants = getDependants ? getDependants : arrayOf; 8249 8250 /** 8251 * Returns the cache for a given dependants array. When possible, a WeakMap 8252 * will be used to create a unique cache for each set of dependants. This 8253 * is feasible due to the nature of WeakMap in allowing garbage collection 8254 * to occur on entries where the key object is no longer referenced. Since 8255 * WeakMap requires the key to be an object, this is only possible when the 8256 * dependant is object-like. The root cache is created as a hierarchy where 8257 * each top-level key is the first entry in a dependants set, the value a 8258 * WeakMap where each key is the next dependant, and so on. This continues 8259 * so long as the dependants are object-like. If no dependants are object- 8260 * like, then the cache is shared across all invocations. 8261 * 8262 * @see isObjectLike 8263 * 8264 * @param {*[]} dependants Selector dependants. 8265 * 8266 * @return {Cache} Cache object. 8267 */ 8268 function getCache(dependants) { 8269 var caches = rootCache, 8270 isUniqueByDependants = true, 8271 i, 8272 dependant, 8273 map, 8274 cache; 8275 8276 for (i = 0; i < dependants.length; i++) { 8277 dependant = dependants[i]; 8278 8279 // Can only compose WeakMap from object-like key. 8280 if (!isObjectLike(dependant)) { 8281 isUniqueByDependants = false; 8282 break; 8283 } 8284 8285 // Does current segment of cache already have a WeakMap? 8286 if (caches.has(dependant)) { 8287 // Traverse into nested WeakMap. 8288 caches = caches.get(dependant); 8289 } else { 8290 // Create, set, and traverse into a new one. 8291 map = new WeakMap(); 8292 caches.set(dependant, map); 8293 caches = map; 8294 } 8295 } 8296 8297 // We use an arbitrary (but consistent) object as key for the last item 8298 // in the WeakMap to serve as our running cache. 8299 if (!caches.has(LEAF_KEY)) { 8300 cache = createCache(); 8301 cache.isUniqueByDependants = isUniqueByDependants; 8302 caches.set(LEAF_KEY, cache); 8303 } 8304 8305 return caches.get(LEAF_KEY); 8306 } 8307 8308 /** 8309 * Resets root memoization cache. 8310 */ 8311 function clear() { 8312 rootCache = new WeakMap(); 8313 } 8314 8315 /* eslint-disable jsdoc/check-param-names */ 8316 /** 8317 * The augmented selector call, considering first whether dependants have 8318 * changed before passing it to underlying memoize function. 8319 * 8320 * @param {*} source Source object for derivation. 8321 * @param {...*} extraArgs Additional arguments to pass to selector. 8322 * 8323 * @return {*} Selector result. 8324 */ 8325 /* eslint-enable jsdoc/check-param-names */ 8326 function callSelector(/* source, ...extraArgs */) { 8327 var len = arguments.length, 8328 cache, 8329 node, 8330 i, 8331 args, 8332 dependants; 8333 8334 // Create copy of arguments (avoid leaking deoptimization). 8335 args = new Array(len); 8336 for (i = 0; i < len; i++) { 8337 args[i] = arguments[i]; 8338 } 8339 8340 dependants = normalizedGetDependants.apply(null, args); 8341 cache = getCache(dependants); 8342 8343 // If not guaranteed uniqueness by dependants (primitive type), shallow 8344 // compare against last dependants and, if references have changed, 8345 // destroy cache to recalculate result. 8346 if (!cache.isUniqueByDependants) { 8347 if ( 8348 cache.lastDependants && 8349 !isShallowEqual(dependants, cache.lastDependants, 0) 8350 ) { 8351 cache.clear(); 8352 } 8353 8354 cache.lastDependants = dependants; 8355 } 8356 8357 node = cache.head; 8358 while (node) { 8359 // Check whether node arguments match arguments 8360 if (!isShallowEqual(node.args, args, 1)) { 8361 node = node.next; 8362 continue; 8363 } 8364 8365 // At this point we can assume we've found a match 8366 8367 // Surface matched node to head if not already 8368 if (node !== cache.head) { 8369 // Adjust siblings to point to each other. 8370 /** @type {CacheNode} */ (node.prev).next = node.next; 8371 if (node.next) { 8372 node.next.prev = node.prev; 8373 } 8374 8375 node.next = cache.head; 8376 node.prev = null; 8377 /** @type {CacheNode} */ (cache.head).prev = node; 8378 cache.head = node; 8379 } 8380 8381 // Return immediately 8382 return node.val; 8383 } 8384 8385 // No cached value found. Continue to insertion phase: 8386 8387 node = /** @type {CacheNode} */ ({ 8388 // Generate the result from original function 8389 val: selector.apply(null, args), 8390 }); 8391 8392 // Avoid including the source object in the cache. 8393 args[0] = null; 8394 node.args = args; 8395 8396 // Don't need to check whether node is already head, since it would 8397 // have been returned above already if it was 8398 8399 // Shift existing head down list 8400 if (cache.head) { 8401 cache.head.prev = node; 8402 node.next = cache.head; 8403 } 8404 8405 cache.head = node; 8406 8407 return node.val; 8408 } 8409 8410 callSelector.getDependants = normalizedGetDependants; 8411 callSelector.clear = clear; 8412 clear(); 8413 8414 return /** @type {S & EnhancedSelector} */ (callSelector); 8415 } 8416 8417 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js 8418 var remove_accents = __webpack_require__(9681); 8419 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 8420 ;// CONCATENATED MODULE: external ["wp","compose"] 8421 const external_wp_compose_namespaceObject = window["wp"]["compose"]; 8422 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/utils.js 8423 /** 8424 * Helper util to return a value from a certain path of the object. 8425 * Path is specified as either: 8426 * - a string of properties, separated by dots, for example: "x.y". 8427 * - an array of properties, for example `[ 'x', 'y' ]`. 8428 * You can also specify a default value in case the result is nullish. 8429 * 8430 * @param {Object} object Input object. 8431 * @param {string|Array} path Path to the object property. 8432 * @param {*} defaultValue Default value if the value at the specified path is nullish. 8433 * @return {*} Value of the object property at the specified path. 8434 */ 8435 const getValueFromObjectPath = (object, path, defaultValue) => { 8436 var _value; 8437 const normalizedPath = Array.isArray(path) ? path : path.split('.'); 8438 let value = object; 8439 normalizedPath.forEach(fieldName => { 8440 value = value?.[fieldName]; 8441 }); 8442 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 8443 }; 8444 8445 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 8446 /** 8447 * External dependencies 8448 */ 8449 8450 8451 8452 /** 8453 * WordPress dependencies 8454 */ 8455 8456 8457 /** 8458 * Internal dependencies 8459 */ 8460 8461 8462 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 8463 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 8464 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 8465 8466 /** 8467 * Given a block name or block type object, returns the corresponding 8468 * normalized block type object. 8469 * 8470 * @param {Object} state Blocks state. 8471 * @param {(string|Object)} nameOrType Block name or type object 8472 * 8473 * @return {Object} Block type object. 8474 */ 8475 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType; 8476 8477 /** 8478 * Returns all the available block types. 8479 * 8480 * @param {Object} state Data state. 8481 * 8482 * @example 8483 * ```js 8484 * import { store as blocksStore } from '@wordpress/blocks'; 8485 * import { useSelect } from '@wordpress/data'; 8486 * 8487 * const ExampleComponent = () => { 8488 * const blockTypes = useSelect( 8489 * ( select ) => select( blocksStore ).getBlockTypes(), 8490 * [] 8491 * ); 8492 * 8493 * return ( 8494 * <ul> 8495 * { blockTypes.map( ( block ) => ( 8496 * <li key={ block.name }>{ block.title }</li> 8497 * ) ) } 8498 * </ul> 8499 * ); 8500 * }; 8501 * ``` 8502 * 8503 * @return {Array} Block Types. 8504 */ 8505 const selectors_getBlockTypes = rememo(state => Object.values(state.blockTypes), state => [state.blockTypes]); 8506 8507 /** 8508 * Returns a block type by name. 8509 * 8510 * @param {Object} state Data state. 8511 * @param {string} name Block type name. 8512 * 8513 * @example 8514 * ```js 8515 * import { store as blocksStore } from '@wordpress/blocks'; 8516 * import { useSelect } from '@wordpress/data'; 8517 * 8518 * const ExampleComponent = () => { 8519 * const paragraphBlock = useSelect( ( select ) => 8520 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ), 8521 * [] 8522 * ); 8523 * 8524 * return ( 8525 * <ul> 8526 * { paragraphBlock && 8527 * Object.entries( paragraphBlock.supports ).map( 8528 * ( blockSupportsEntry ) => { 8529 * const [ propertyName, value ] = blockSupportsEntry; 8530 * return ( 8531 * <li 8532 * key={ propertyName } 8533 * >{ `${ propertyName } : ${ value }` }</li> 8534 * ); 8535 * } 8536 * ) } 8537 * </ul> 8538 * ); 8539 * }; 8540 * ``` 8541 * 8542 * @return {Object?} Block Type. 8543 */ 8544 function selectors_getBlockType(state, name) { 8545 return state.blockTypes[name]; 8546 } 8547 8548 /** 8549 * Returns block styles by block name. 8550 * 8551 * @param {Object} state Data state. 8552 * @param {string} name Block type name. 8553 * 8554 * @example 8555 * ```js 8556 * import { store as blocksStore } from '@wordpress/blocks'; 8557 * import { useSelect } from '@wordpress/data'; 8558 * 8559 * const ExampleComponent = () => { 8560 * const buttonBlockStyles = useSelect( ( select ) => 8561 * select( blocksStore ).getBlockStyles( 'core/button' ), 8562 * [] 8563 * ); 8564 * 8565 * return ( 8566 * <ul> 8567 * { buttonBlockStyles && 8568 * buttonBlockStyles.map( ( style ) => ( 8569 * <li key={ style.name }>{ style.label }</li> 8570 * ) ) } 8571 * </ul> 8572 * ); 8573 * }; 8574 * ``` 8575 * 8576 * @return {Array?} Block Styles. 8577 */ 8578 function getBlockStyles(state, name) { 8579 return state.blockStyles[name]; 8580 } 8581 8582 /** 8583 * Returns block variations by block name. 8584 * 8585 * @param {Object} state Data state. 8586 * @param {string} blockName Block type name. 8587 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8588 * 8589 * @example 8590 * ```js 8591 * import { store as blocksStore } from '@wordpress/blocks'; 8592 * import { useSelect } from '@wordpress/data'; 8593 * 8594 * const ExampleComponent = () => { 8595 * const socialLinkVariations = useSelect( ( select ) => 8596 * select( blocksStore ).getBlockVariations( 'core/social-link' ), 8597 * [] 8598 * ); 8599 * 8600 * return ( 8601 * <ul> 8602 * { socialLinkVariations && 8603 * socialLinkVariations.map( ( variation ) => ( 8604 * <li key={ variation.name }>{ variation.title }</li> 8605 * ) ) } 8606 * </ul> 8607 * ); 8608 * }; 8609 * ``` 8610 * 8611 * @return {(WPBlockVariation[]|void)} Block variations. 8612 */ 8613 const selectors_getBlockVariations = rememo((state, blockName, scope) => { 8614 const variations = state.blockVariations[blockName]; 8615 if (!variations || !scope) { 8616 return variations; 8617 } 8618 return variations.filter(variation => { 8619 // For backward compatibility reasons, variation's scope defaults to 8620 // `block` and `inserter` when not set. 8621 return (variation.scope || ['block', 'inserter']).includes(scope); 8622 }); 8623 }, (state, blockName) => [state.blockVariations[blockName]]); 8624 8625 /** 8626 * Returns the active block variation for a given block based on its attributes. 8627 * Variations are determined by their `isActive` property. 8628 * Which is either an array of block attribute keys or a function. 8629 * 8630 * In case of an array of block attribute keys, the `attributes` are compared 8631 * to the variation's attributes using strict equality check. 8632 * 8633 * In case of function type, the function should accept a block's attributes 8634 * and the variation's attributes and determines if a variation is active. 8635 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 8636 * 8637 * @param {Object} state Data state. 8638 * @param {string} blockName Name of block (example: “core/columns”). 8639 * @param {Object} attributes Block attributes used to determine active variation. 8640 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8641 * 8642 * @example 8643 * ```js 8644 * import { __ } from '@wordpress/i18n'; 8645 * import { store as blocksStore } from '@wordpress/blocks'; 8646 * import { store as blockEditorStore } from '@wordpress/block-editor'; 8647 * import { useSelect } from '@wordpress/data'; 8648 * 8649 * const ExampleComponent = () => { 8650 * // This example assumes that a core/embed block is the first block in the Block Editor. 8651 * const activeBlockVariation = useSelect( ( select ) => { 8652 * // Retrieve the list of blocks. 8653 * const [ firstBlock ] = select( blockEditorStore ).getBlocks() 8654 * 8655 * // Return the active block variation for the first block. 8656 * return select( blocksStore ).getActiveBlockVariation( 8657 * firstBlock.name, 8658 * firstBlock.attributes 8659 * ); 8660 * }, [] ); 8661 * 8662 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? ( 8663 * <p>{ __( 'Spotify variation' ) }</p> 8664 * ) : ( 8665 * <p>{ __( 'Other variation' ) }</p> 8666 * ); 8667 * }; 8668 * ``` 8669 * 8670 * @return {(WPBlockVariation|undefined)} Active block variation. 8671 */ 8672 function getActiveBlockVariation(state, blockName, attributes, scope) { 8673 const variations = selectors_getBlockVariations(state, blockName, scope); 8674 const match = variations?.find(variation => { 8675 if (Array.isArray(variation.isActive)) { 8676 const blockType = selectors_getBlockType(state, blockName); 8677 const attributeKeys = Object.keys(blockType?.attributes || {}); 8678 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute)); 8679 if (definedAttributes.length === 0) { 8680 return false; 8681 } 8682 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]); 8683 } 8684 return variation.isActive?.(attributes, variation.attributes); 8685 }); 8686 return match; 8687 } 8688 8689 /** 8690 * Returns the default block variation for the given block type. 8691 * When there are multiple variations annotated as the default one, 8692 * the last added item is picked. This simplifies registering overrides. 8693 * When there is no default variation set, it returns the first item. 8694 * 8695 * @param {Object} state Data state. 8696 * @param {string} blockName Block type name. 8697 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8698 * 8699 * @example 8700 * ```js 8701 * import { __, sprintf } from '@wordpress/i18n'; 8702 * import { store as blocksStore } from '@wordpress/blocks'; 8703 * import { useSelect } from '@wordpress/data'; 8704 * 8705 * const ExampleComponent = () => { 8706 * const defaultEmbedBlockVariation = useSelect( ( select ) => 8707 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ), 8708 * [] 8709 * ); 8710 * 8711 * return ( 8712 * defaultEmbedBlockVariation && ( 8713 * <p> 8714 * { sprintf( 8715 * __( 'core/embed default variation: %s' ), 8716 * defaultEmbedBlockVariation.title 8717 * ) } 8718 * </p> 8719 * ) 8720 * ); 8721 * }; 8722 * ``` 8723 * 8724 * @return {?WPBlockVariation} The default block variation. 8725 */ 8726 function getDefaultBlockVariation(state, blockName, scope) { 8727 const variations = selectors_getBlockVariations(state, blockName, scope); 8728 const defaultVariation = [...variations].reverse().find(({ 8729 isDefault 8730 }) => !!isDefault); 8731 return defaultVariation || variations[0]; 8732 } 8733 8734 /** 8735 * Returns all the available block categories. 8736 * 8737 * @param {Object} state Data state. 8738 * 8739 * @example 8740 * ```js 8741 * import { store as blocksStore } from '@wordpress/blocks'; 8742 * import { useSelect, } from '@wordpress/data'; 8743 * 8744 * const ExampleComponent = () => { 8745 * const blockCategories = useSelect( ( select ) => 8746 * select( blocksStore ).getCategories(), 8747 * [] 8748 * ); 8749 * 8750 * return ( 8751 * <ul> 8752 * { blockCategories.map( ( category ) => ( 8753 * <li key={ category.slug }>{ category.title }</li> 8754 * ) ) } 8755 * </ul> 8756 * ); 8757 * }; 8758 * ``` 8759 * 8760 * @return {WPBlockCategory[]} Categories list. 8761 */ 8762 function getCategories(state) { 8763 return state.categories; 8764 } 8765 8766 /** 8767 * Returns all the available collections. 8768 * 8769 * @param {Object} state Data state. 8770 * 8771 * @example 8772 * ```js 8773 * import { store as blocksStore } from '@wordpress/blocks'; 8774 * import { useSelect } from '@wordpress/data'; 8775 * 8776 * const ExampleComponent = () => { 8777 * const blockCollections = useSelect( ( select ) => 8778 * select( blocksStore ).getCollections(), 8779 * [] 8780 * ); 8781 * 8782 * return ( 8783 * <ul> 8784 * { Object.values( blockCollections ).length > 0 && 8785 * Object.values( blockCollections ).map( ( collection ) => ( 8786 * <li key={ collection.title }>{ collection.title }</li> 8787 * ) ) } 8788 * </ul> 8789 * ); 8790 * }; 8791 * ``` 8792 * 8793 * @return {Object} Collections list. 8794 */ 8795 function getCollections(state) { 8796 return state.collections; 8797 } 8798 8799 /** 8800 * Returns the name of the default block name. 8801 * 8802 * @param {Object} state Data state. 8803 * 8804 * @example 8805 * ```js 8806 * import { __, sprintf } from '@wordpress/i18n'; 8807 * import { store as blocksStore } from '@wordpress/blocks'; 8808 * import { useSelect } from '@wordpress/data'; 8809 * 8810 * const ExampleComponent = () => { 8811 * const defaultBlockName = useSelect( ( select ) => 8812 * select( blocksStore ).getDefaultBlockName(), 8813 * [] 8814 * ); 8815 * 8816 * return ( 8817 * defaultBlockName && ( 8818 * <p> 8819 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) } 8820 * </p> 8821 * ) 8822 * ); 8823 * }; 8824 * ``` 8825 * 8826 * @return {string?} Default block name. 8827 */ 8828 function selectors_getDefaultBlockName(state) { 8829 return state.defaultBlockName; 8830 } 8831 8832 /** 8833 * Returns the name of the block for handling non-block content. 8834 * 8835 * @param {Object} state Data state. 8836 * 8837 * @example 8838 * ```js 8839 * import { __, sprintf } from '@wordpress/i18n'; 8840 * import { store as blocksStore } from '@wordpress/blocks'; 8841 * import { useSelect } from '@wordpress/data'; 8842 * 8843 * const ExampleComponent = () => { 8844 * const freeformFallbackBlockName = useSelect( ( select ) => 8845 * select( blocksStore ).getFreeformFallbackBlockName(), 8846 * [] 8847 * ); 8848 * 8849 * return ( 8850 * freeformFallbackBlockName && ( 8851 * <p> 8852 * { sprintf( __( 8853 * 'Freeform fallback block name: %s' ), 8854 * freeformFallbackBlockName 8855 * ) } 8856 * </p> 8857 * ) 8858 * ); 8859 * }; 8860 * ``` 8861 * 8862 * @return {string?} Name of the block for handling non-block content. 8863 */ 8864 function getFreeformFallbackBlockName(state) { 8865 return state.freeformFallbackBlockName; 8866 } 8867 8868 /** 8869 * Returns the name of the block for handling unregistered blocks. 8870 * 8871 * @param {Object} state Data state. 8872 * 8873 * @example 8874 * ```js 8875 * import { __, sprintf } from '@wordpress/i18n'; 8876 * import { store as blocksStore } from '@wordpress/blocks'; 8877 * import { useSelect } from '@wordpress/data'; 8878 * 8879 * const ExampleComponent = () => { 8880 * const unregisteredFallbackBlockName = useSelect( ( select ) => 8881 * select( blocksStore ).getUnregisteredFallbackBlockName(), 8882 * [] 8883 * ); 8884 * 8885 * return ( 8886 * unregisteredFallbackBlockName && ( 8887 * <p> 8888 * { sprintf( __( 8889 * 'Unregistered fallback block name: %s' ), 8890 * unregisteredFallbackBlockName 8891 * ) } 8892 * </p> 8893 * ) 8894 * ); 8895 * }; 8896 * ``` 8897 * 8898 * @return {string?} Name of the block for handling unregistered blocks. 8899 */ 8900 function getUnregisteredFallbackBlockName(state) { 8901 return state.unregisteredFallbackBlockName; 8902 } 8903 8904 /** 8905 * Returns the name of the block for handling the grouping of blocks. 8906 * 8907 * @param {Object} state Data state. 8908 * 8909 * @example 8910 * ```js 8911 * import { __, sprintf } from '@wordpress/i18n'; 8912 * import { store as blocksStore } from '@wordpress/blocks'; 8913 * import { useSelect } from '@wordpress/data'; 8914 * 8915 * const ExampleComponent = () => { 8916 * const groupingBlockName = useSelect( ( select ) => 8917 * select( blocksStore ).getGroupingBlockName(), 8918 * [] 8919 * ); 8920 * 8921 * return ( 8922 * groupingBlockName && ( 8923 * <p> 8924 * { sprintf( 8925 * __( 'Default grouping block name: %s' ), 8926 * groupingBlockName 8927 * ) } 8928 * </p> 8929 * ) 8930 * ); 8931 * }; 8932 * ``` 8933 * 8934 * @return {string?} Name of the block for handling the grouping of blocks. 8935 */ 8936 function selectors_getGroupingBlockName(state) { 8937 return state.groupingBlockName; 8938 } 8939 8940 /** 8941 * Returns an array with the child blocks of a given block. 8942 * 8943 * @param {Object} state Data state. 8944 * @param {string} blockName Block type name. 8945 * 8946 * @example 8947 * ```js 8948 * import { store as blocksStore } from '@wordpress/blocks'; 8949 * import { useSelect } from '@wordpress/data'; 8950 * 8951 * const ExampleComponent = () => { 8952 * const childBlockNames = useSelect( ( select ) => 8953 * select( blocksStore ).getChildBlockNames( 'core/navigation' ), 8954 * [] 8955 * ); 8956 * 8957 * return ( 8958 * <ul> 8959 * { childBlockNames && 8960 * childBlockNames.map( ( child ) => ( 8961 * <li key={ child }>{ child }</li> 8962 * ) ) } 8963 * </ul> 8964 * ); 8965 * }; 8966 * ``` 8967 * 8968 * @return {Array} Array of child block names. 8969 */ 8970 const selectors_getChildBlockNames = rememo((state, blockName) => { 8971 return selectors_getBlockTypes(state).filter(blockType => { 8972 return blockType.parent?.includes(blockName); 8973 }).map(({ 8974 name 8975 }) => name); 8976 }, state => [state.blockTypes]); 8977 8978 /** 8979 * Returns the block support value for a feature, if defined. 8980 * 8981 * @param {Object} state Data state. 8982 * @param {(string|Object)} nameOrType Block name or type object 8983 * @param {Array|string} feature Feature to retrieve 8984 * @param {*} defaultSupports Default value to return if not 8985 * explicitly defined 8986 * 8987 * @example 8988 * ```js 8989 * import { __, sprintf } from '@wordpress/i18n'; 8990 * import { store as blocksStore } from '@wordpress/blocks'; 8991 * import { useSelect } from '@wordpress/data'; 8992 * 8993 * const ExampleComponent = () => { 8994 * const paragraphBlockSupportValue = useSelect( ( select ) => 8995 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ), 8996 * [] 8997 * ); 8998 * 8999 * return ( 9000 * <p> 9001 * { sprintf( 9002 * __( 'core/paragraph supports.anchor value: %s' ), 9003 * paragraphBlockSupportValue 9004 * ) } 9005 * </p> 9006 * ); 9007 * }; 9008 * ``` 9009 * 9010 * @return {?*} Block support value 9011 */ 9012 const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 9013 const blockType = getNormalizedBlockType(state, nameOrType); 9014 if (!blockType?.supports) { 9015 return defaultSupports; 9016 } 9017 return getValueFromObjectPath(blockType.supports, feature, defaultSupports); 9018 }; 9019 9020 /** 9021 * Returns true if the block defines support for a feature, or false otherwise. 9022 * 9023 * @param {Object} state Data state. 9024 * @param {(string|Object)} nameOrType Block name or type object. 9025 * @param {string} feature Feature to test. 9026 * @param {boolean} defaultSupports Whether feature is supported by 9027 * default if not explicitly defined. 9028 * 9029 * @example 9030 * ```js 9031 * import { __, sprintf } from '@wordpress/i18n'; 9032 * import { store as blocksStore } from '@wordpress/blocks'; 9033 * import { useSelect } from '@wordpress/data'; 9034 * 9035 * const ExampleComponent = () => { 9036 * const paragraphBlockSupportClassName = useSelect( ( select ) => 9037 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ), 9038 * [] 9039 * ); 9040 * 9041 * return ( 9042 * <p> 9043 * { sprintf( 9044 * __( 'core/paragraph supports custom class name?: %s' ), 9045 * paragraphBlockSupportClassName 9046 * ) } 9047 * /p> 9048 * ); 9049 * }; 9050 * ``` 9051 * 9052 * @return {boolean} Whether block supports feature. 9053 */ 9054 function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupports) { 9055 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports); 9056 } 9057 9058 /** 9059 * Returns true if the block type by the given name or object value matches a 9060 * search term, or false otherwise. 9061 * 9062 * @param {Object} state Blocks state. 9063 * @param {(string|Object)} nameOrType Block name or type object. 9064 * @param {string} searchTerm Search term by which to filter. 9065 * 9066 * @example 9067 * ```js 9068 * import { __, sprintf } from '@wordpress/i18n'; 9069 * import { store as blocksStore } from '@wordpress/blocks'; 9070 * import { useSelect } from '@wordpress/data'; 9071 * 9072 * const ExampleComponent = () => { 9073 * const termFound = useSelect( 9074 * ( select ) => 9075 * select( blocksStore ).isMatchingSearchTerm( 9076 * 'core/navigation', 9077 * 'theme' 9078 * ), 9079 * [] 9080 * ); 9081 * 9082 * return ( 9083 * <p> 9084 * { sprintf( 9085 * __( 9086 * 'Search term was found in the title, keywords, category or description in block.json: %s' 9087 * ), 9088 * termFound 9089 * ) } 9090 * </p> 9091 * ); 9092 * }; 9093 * ``` 9094 * 9095 * @return {Object[]} Whether block type matches search term. 9096 */ 9097 function isMatchingSearchTerm(state, nameOrType, searchTerm) { 9098 const blockType = getNormalizedBlockType(state, nameOrType); 9099 const getNormalizedSearchTerm = (0,external_wp_compose_namespaceObject.pipe)([ 9100 // Disregard diacritics. 9101 // Input: "média" 9102 term => remove_accents_default()(term !== null && term !== void 0 ? term : ''), 9103 // Lowercase. 9104 // Input: "MEDIA" 9105 term => term.toLowerCase(), 9106 // Strip leading and trailing whitespace. 9107 // Input: " media " 9108 term => term.trim()]); 9109 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 9110 const isSearchMatch = (0,external_wp_compose_namespaceObject.pipe)([getNormalizedSearchTerm, normalizedCandidate => normalizedCandidate.includes(normalizedSearchTerm)]); 9111 return isSearchMatch(blockType.title) || blockType.keywords?.some(isSearchMatch) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description); 9112 } 9113 9114 /** 9115 * Returns a boolean indicating if a block has child blocks or not. 9116 * 9117 * @param {Object} state Data state. 9118 * @param {string} blockName Block type name. 9119 * 9120 * @example 9121 * ```js 9122 * import { __, sprintf } from '@wordpress/i18n'; 9123 * import { store as blocksStore } from '@wordpress/blocks'; 9124 * import { useSelect } from '@wordpress/data'; 9125 * 9126 * const ExampleComponent = () => { 9127 * const navigationBlockHasChildBlocks = useSelect( ( select ) => 9128 * select( blocksStore ).hasChildBlocks( 'core/navigation' ), 9129 * [] 9130 * ); 9131 * 9132 * return ( 9133 * <p> 9134 * { sprintf( 9135 * __( 'core/navigation has child blocks: %s' ), 9136 * navigationBlockHasChildBlocks 9137 * ) } 9138 * </p> 9139 * ); 9140 * }; 9141 * ``` 9142 * 9143 * @return {boolean} True if a block contains child blocks and false otherwise. 9144 */ 9145 const selectors_hasChildBlocks = (state, blockName) => { 9146 return selectors_getChildBlockNames(state, blockName).length > 0; 9147 }; 9148 9149 /** 9150 * Returns a boolean indicating if a block has at least one child block with inserter support. 9151 * 9152 * @param {Object} state Data state. 9153 * @param {string} blockName Block type name. 9154 * 9155 * @example 9156 * ```js 9157 * import { __, sprintf } from '@wordpress/i18n'; 9158 * import { store as blocksStore } from '@wordpress/blocks'; 9159 * import { useSelect } from '@wordpress/data'; 9160 * 9161 * const ExampleComponent = () => { 9162 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) => 9163 * select( blocksStore ).hasChildBlocksWithInserterSupport( 9164 * 'core/navigation' 9165 * ), 9166 * [] 9167 * ); 9168 * 9169 * return ( 9170 * <p> 9171 * { sprintf( 9172 * __( 'core/navigation has child blocks with inserter support: %s' ), 9173 * navigationBlockHasChildBlocksWithInserterSupport 9174 * ) } 9175 * </p> 9176 * ); 9177 * }; 9178 * ``` 9179 * 9180 * @return {boolean} True if a block contains at least one child blocks with inserter support 9181 * and false otherwise. 9182 */ 9183 const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => { 9184 return selectors_getChildBlockNames(state, blockName).some(childBlockName => { 9185 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true); 9186 }); 9187 }; 9188 9189 /** 9190 * DO-NOT-USE in production. 9191 * This selector is created for internal/experimental only usage and may be 9192 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 9193 */ 9194 const __experimentalHasContentRoleAttribute = rememo((state, blockTypeName) => { 9195 const blockType = selectors_getBlockType(state, blockTypeName); 9196 if (!blockType) { 9197 return false; 9198 } 9199 return Object.entries(blockType.attributes).some(([, { 9200 __experimentalRole 9201 }]) => __experimentalRole === 'content'); 9202 }, (state, blockTypeName) => [state.blockTypes[blockTypeName]?.attributes]); 9203 9204 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 9205 /** 9206 * External dependencies 9207 */ 9208 9209 9210 /** 9211 * Internal dependencies 9212 */ 9213 9214 9215 9216 const ROOT_BLOCK_SUPPORTS = ['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'padding', 'contentSize', 'wideSize', 'blockGap', 'textDecoration', 'textTransform', 'letterSpacing']; 9217 9218 /** 9219 * Filters the list of supported styles for a given element. 9220 * 9221 * @param {string[]} blockSupports list of supported styles. 9222 * @param {string|undefined} name block name. 9223 * @param {string|undefined} element element name. 9224 * 9225 * @return {string[]} filtered list of supported styles. 9226 */ 9227 function filterElementBlockSupports(blockSupports, name, element) { 9228 return blockSupports.filter(support => { 9229 if (support === 'fontSize' && element === 'heading') { 9230 return false; 9231 } 9232 9233 // This is only available for links 9234 if (support === 'textDecoration' && !name && element !== 'link') { 9235 return false; 9236 } 9237 9238 // This is only available for heading, button, caption and text 9239 if (support === 'textTransform' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 9240 return false; 9241 } 9242 9243 // This is only available for heading, button, caption and text 9244 if (support === 'letterSpacing' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 9245 return false; 9246 } 9247 9248 // Text columns is only available for blocks. 9249 if (support === 'textColumns' && !name) { 9250 return false; 9251 } 9252 return true; 9253 }); 9254 } 9255 9256 /** 9257 * Returns the list of supported styles for a given block name and element. 9258 */ 9259 const getSupportedStyles = rememo((state, name, element) => { 9260 if (!name) { 9261 return filterElementBlockSupports(ROOT_BLOCK_SUPPORTS, name, element); 9262 } 9263 const blockType = selectors_getBlockType(state, name); 9264 if (!blockType) { 9265 return []; 9266 } 9267 const supportKeys = []; 9268 9269 // Check for blockGap support. 9270 // Block spacing support doesn't map directly to a single style property, so needs to be handled separately. 9271 if (blockType?.supports?.spacing?.blockGap) { 9272 supportKeys.push('blockGap'); 9273 } 9274 9275 // check for shadow support 9276 if (blockType?.supports?.shadow) { 9277 supportKeys.push('shadow'); 9278 } 9279 Object.keys(__EXPERIMENTAL_STYLE_PROPERTY).forEach(styleName => { 9280 if (!__EXPERIMENTAL_STYLE_PROPERTY[styleName].support) { 9281 return; 9282 } 9283 9284 // Opting out means that, for certain support keys like background color, 9285 // blocks have to explicitly set the support value false. If the key is 9286 // unset, we still enable it. 9287 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].requiresOptOut) { 9288 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].support[0] in blockType.supports && getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support) !== false) { 9289 supportKeys.push(styleName); 9290 return; 9291 } 9292 } 9293 if (getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support, false)) { 9294 supportKeys.push(styleName); 9295 } 9296 }); 9297 return filterElementBlockSupports(supportKeys, name, element); 9298 }, (state, name) => [state.blockTypes[name]]); 9299 9300 /** 9301 * Returns the bootstrapped block type metadata for a give block name. 9302 * 9303 * @param {Object} state Data state. 9304 * @param {string} name Block name. 9305 * 9306 * @return {Object} Bootstrapped block type metadata for a block. 9307 */ 9308 function getBootstrappedBlockType(state, name) { 9309 return state.bootstrappedBlockTypes[name]; 9310 } 9311 9312 /** 9313 * Returns all the unprocessed (before applying the `registerBlockType` filter) 9314 * block type settings as passed during block registration. 9315 * 9316 * @param {Object} state Data state. 9317 * 9318 * @return {Array} Unprocessed block type settings for all blocks. 9319 */ 9320 function getUnprocessedBlockTypes(state) { 9321 return state.unprocessedBlockTypes; 9322 } 9323 9324 /** 9325 * Returns all the block bindings sources registered. 9326 * 9327 * @param {Object} state Data state. 9328 * 9329 * @return {Object} All the registered sources and their properties. 9330 */ 9331 function getAllBlockBindingsSources(state) { 9332 return state.blockBindingsSources; 9333 } 9334 9335 /** 9336 * Returns a specific block bindings source. 9337 * 9338 * @param {Object} state Data state. 9339 * @param {string} sourceName Name of the source to get. 9340 * 9341 * @return {Object} The specific block binding source and its properties. 9342 */ 9343 function getBlockBindingsSource(state, sourceName) { 9344 return state.blockBindingsSources[sourceName]; 9345 } 9346 9347 ;// CONCATENATED MODULE: external ["wp","deprecated"] 9348 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 9349 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 9350 ;// CONCATENATED MODULE: ./node_modules/is-plain-object/dist/is-plain-object.mjs 9351 /*! 9352 * is-plain-object <https://github.com/jonschlinkert/is-plain-object> 9353 * 9354 * Copyright (c) 2014-2017, Jon Schlinkert. 9355 * Released under the MIT License. 9356 */ 9357 9358 function is_plain_object_isObject(o) { 9359 return Object.prototype.toString.call(o) === '[object Object]'; 9360 } 9361 9362 function isPlainObject(o) { 9363 var ctor,prot; 9364 9365 if (is_plain_object_isObject(o) === false) return false; 9366 9367 // If has modified constructor 9368 ctor = o.constructor; 9369 if (ctor === undefined) return true; 9370 9371 // If has modified prototype 9372 prot = ctor.prototype; 9373 if (is_plain_object_isObject(prot) === false) return false; 9374 9375 // If constructor does not have an Object-specific method 9376 if (prot.hasOwnProperty('isPrototypeOf') === false) { 9377 return false; 9378 } 9379 9380 // Most likely a plain Object 9381 return true; 9382 } 9383 9384 9385 9386 // EXTERNAL MODULE: ./node_modules/react-is/index.js 9387 var react_is = __webpack_require__(8529); 9388 ;// CONCATENATED MODULE: external ["wp","hooks"] 9389 const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 9390 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/process-block-type.js 9391 /** 9392 * External dependencies 9393 */ 9394 9395 9396 9397 /** 9398 * WordPress dependencies 9399 */ 9400 9401 9402 9403 /** 9404 * Internal dependencies 9405 */ 9406 9407 9408 9409 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9410 9411 const error = (...args) => window?.console?.error?.(...args); 9412 const warn = (...args) => window?.console?.warn?.(...args); 9413 9414 /** 9415 * Mapping of legacy category slugs to their latest normal values, used to 9416 * accommodate updates of the default set of block categories. 9417 * 9418 * @type {Record<string,string>} 9419 */ 9420 const LEGACY_CATEGORY_MAPPING = { 9421 common: 'text', 9422 formatting: 'text', 9423 layout: 'design' 9424 }; 9425 9426 /** 9427 * Takes the unprocessed block type settings, merges them with block type metadata 9428 * and applies all the existing filters for the registered block type. 9429 * Next, it validates all the settings and performs additional processing to the block type definition. 9430 * 9431 * @param {string} name Block name. 9432 * @param {WPBlockType} blockSettings Unprocessed block type settings. 9433 * 9434 * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. 9435 */ 9436 const processBlockType = (name, blockSettings) => ({ 9437 select 9438 }) => { 9439 const blockType = { 9440 name, 9441 icon: BLOCK_ICON_DEFAULT, 9442 keywords: [], 9443 attributes: {}, 9444 providesContext: {}, 9445 usesContext: [], 9446 selectors: {}, 9447 supports: {}, 9448 styles: [], 9449 variations: [], 9450 blockHooks: {}, 9451 save: () => null, 9452 ...select.getBootstrappedBlockType(name), 9453 ...blockSettings 9454 }; 9455 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', blockType, name, null); 9456 if (settings.description && typeof settings.description !== 'string') { 9457 external_wp_deprecated_default()('Declaring non-string block descriptions', { 9458 since: '6.2' 9459 }); 9460 } 9461 if (settings.deprecated) { 9462 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( 9463 // Only keep valid deprecation keys. 9464 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', 9465 // Merge deprecation keys with pre-filter settings 9466 // so that filters that depend on specific keys being 9467 // present don't fail. 9468 { 9469 // Omit deprecation keys here so that deprecations 9470 // can opt out of specific keys like "supports". 9471 ...omit(blockType, DEPRECATED_ENTRY_KEYS), 9472 ...deprecation 9473 }, blockType.name, deprecation)).filter(([key]) => DEPRECATED_ENTRY_KEYS.includes(key)))); 9474 } 9475 if (!isPlainObject(settings)) { 9476 error('Block settings must be a valid object.'); 9477 return; 9478 } 9479 if (typeof settings.save !== 'function') { 9480 error('The "save" property must be a valid function.'); 9481 return; 9482 } 9483 if ('edit' in settings && !(0,react_is.isValidElementType)(settings.edit)) { 9484 error('The "edit" property must be a valid component.'); 9485 return; 9486 } 9487 9488 // Canonicalize legacy categories to equivalent fallback. 9489 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 9490 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 9491 } 9492 if ('category' in settings && !select.getCategories().some(({ 9493 slug 9494 }) => slug === settings.category)) { 9495 warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".'); 9496 delete settings.category; 9497 } 9498 if (!('title' in settings) || settings.title === '') { 9499 error('The block "' + name + '" must have a title.'); 9500 return; 9501 } 9502 if (typeof settings.title !== 'string') { 9503 error('Block titles must be strings.'); 9504 return; 9505 } 9506 settings.icon = normalizeIconObject(settings.icon); 9507 if (!isValidIcon(settings.icon.src)) { 9508 error('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional'); 9509 return; 9510 } 9511 return settings; 9512 }; 9513 9514 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/actions.js 9515 /** 9516 * WordPress dependencies 9517 */ 9518 9519 9520 /** 9521 * Internal dependencies 9522 */ 9523 9524 9525 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 9526 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9527 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 9528 9529 /** 9530 * Returns an action object used in signalling that block types have been added. 9531 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks. 9532 * 9533 * @ignore 9534 * 9535 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added. 9536 * 9537 * 9538 * @return {Object} Action object. 9539 */ 9540 function addBlockTypes(blockTypes) { 9541 return { 9542 type: 'ADD_BLOCK_TYPES', 9543 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes] 9544 }; 9545 } 9546 9547 /** 9548 * Signals that all block types should be computed again. 9549 * It uses stored unprocessed block types and all the most recent list of registered filters. 9550 * 9551 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 9552 * 1. Filter A. 9553 * 2. Block B. 9554 * 3. Block C. 9555 * 4. Filter D. 9556 * 5. Filter E. 9557 * 6. Block F. 9558 * 7. Filter G. 9559 * In this scenario some filters would not get applied for all blocks because they are registered too late. 9560 */ 9561 function reapplyBlockTypeFilters() { 9562 return ({ 9563 dispatch, 9564 select 9565 }) => { 9566 const processedBlockTypes = []; 9567 for (const [name, settings] of Object.entries(select.getUnprocessedBlockTypes())) { 9568 const result = dispatch(processBlockType(name, settings)); 9569 if (result) { 9570 processedBlockTypes.push(result); 9571 } 9572 } 9573 if (!processedBlockTypes.length) { 9574 return; 9575 } 9576 dispatch.addBlockTypes(processedBlockTypes); 9577 }; 9578 } 9579 function __experimentalReapplyBlockFilters() { 9580 external_wp_deprecated_default()('wp.data.dispatch( "core/blocks" ).__experimentalReapplyBlockFilters', { 9581 since: '6.4', 9582 alternative: 'reapplyBlockFilters' 9583 }); 9584 return reapplyBlockTypeFilters(); 9585 } 9586 9587 /** 9588 * Returns an action object used to remove a registered block type. 9589 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks. 9590 * 9591 * @ignore 9592 * 9593 * @param {string|string[]} names Block name or array of block names to be removed. 9594 * 9595 * 9596 * @return {Object} Action object. 9597 */ 9598 function removeBlockTypes(names) { 9599 return { 9600 type: 'REMOVE_BLOCK_TYPES', 9601 names: Array.isArray(names) ? names : [names] 9602 }; 9603 } 9604 9605 /** 9606 * Returns an action object used in signalling that new block styles have been added. 9607 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks. 9608 * 9609 * @param {string} blockName Block name. 9610 * @param {Array|Object} styles Block style object or array of block style objects. 9611 * 9612 * @ignore 9613 * 9614 * @return {Object} Action object. 9615 */ 9616 function addBlockStyles(blockName, styles) { 9617 return { 9618 type: 'ADD_BLOCK_STYLES', 9619 styles: Array.isArray(styles) ? styles : [styles], 9620 blockName 9621 }; 9622 } 9623 9624 /** 9625 * Returns an action object used in signalling that block styles have been removed. 9626 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks. 9627 * 9628 * @ignore 9629 * 9630 * @param {string} blockName Block name. 9631 * @param {Array|string} styleNames Block style names or array of block style names. 9632 * 9633 * @return {Object} Action object. 9634 */ 9635 function removeBlockStyles(blockName, styleNames) { 9636 return { 9637 type: 'REMOVE_BLOCK_STYLES', 9638 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames], 9639 blockName 9640 }; 9641 } 9642 9643 /** 9644 * Returns an action object used in signalling that new block variations have been added. 9645 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks. 9646 * 9647 * @ignore 9648 * 9649 * @param {string} blockName Block name. 9650 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 9651 * 9652 * @return {Object} Action object. 9653 */ 9654 function addBlockVariations(blockName, variations) { 9655 return { 9656 type: 'ADD_BLOCK_VARIATIONS', 9657 variations: Array.isArray(variations) ? variations : [variations], 9658 blockName 9659 }; 9660 } 9661 9662 /** 9663 * Returns an action object used in signalling that block variations have been removed. 9664 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks. 9665 * 9666 * @ignore 9667 * 9668 * @param {string} blockName Block name. 9669 * @param {string|string[]} variationNames Block variation names. 9670 * 9671 * @return {Object} Action object. 9672 */ 9673 function removeBlockVariations(blockName, variationNames) { 9674 return { 9675 type: 'REMOVE_BLOCK_VARIATIONS', 9676 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames], 9677 blockName 9678 }; 9679 } 9680 9681 /** 9682 * Returns an action object used to set the default block name. 9683 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks. 9684 * 9685 * @ignore 9686 * 9687 * @param {string} name Block name. 9688 * 9689 * @return {Object} Action object. 9690 */ 9691 function actions_setDefaultBlockName(name) { 9692 return { 9693 type: 'SET_DEFAULT_BLOCK_NAME', 9694 name 9695 }; 9696 } 9697 9698 /** 9699 * Returns an action object used to set the name of the block used as a fallback 9700 * for non-block content. 9701 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks. 9702 * 9703 * @ignore 9704 * 9705 * @param {string} name Block name. 9706 * 9707 * @return {Object} Action object. 9708 */ 9709 function setFreeformFallbackBlockName(name) { 9710 return { 9711 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 9712 name 9713 }; 9714 } 9715 9716 /** 9717 * Returns an action object used to set the name of the block used as a fallback 9718 * for unregistered blocks. 9719 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks. 9720 * 9721 * @ignore 9722 * 9723 * @param {string} name Block name. 9724 * 9725 * @return {Object} Action object. 9726 */ 9727 function setUnregisteredFallbackBlockName(name) { 9728 return { 9729 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 9730 name 9731 }; 9732 } 9733 9734 /** 9735 * Returns an action object used to set the name of the block used 9736 * when grouping other blocks 9737 * eg: in "Group/Ungroup" interactions 9738 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks. 9739 * 9740 * @ignore 9741 * 9742 * @param {string} name Block name. 9743 * 9744 * @return {Object} Action object. 9745 */ 9746 function actions_setGroupingBlockName(name) { 9747 return { 9748 type: 'SET_GROUPING_BLOCK_NAME', 9749 name 9750 }; 9751 } 9752 9753 /** 9754 * Returns an action object used to set block categories. 9755 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks. 9756 * 9757 * @ignore 9758 * 9759 * @param {WPBlockCategory[]} categories Block categories. 9760 * 9761 * @return {Object} Action object. 9762 */ 9763 function setCategories(categories) { 9764 return { 9765 type: 'SET_CATEGORIES', 9766 categories 9767 }; 9768 } 9769 9770 /** 9771 * Returns an action object used to update a category. 9772 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks. 9773 * 9774 * @ignore 9775 * 9776 * @param {string} slug Block category slug. 9777 * @param {Object} category Object containing the category properties that should be updated. 9778 * 9779 * @return {Object} Action object. 9780 */ 9781 function updateCategory(slug, category) { 9782 return { 9783 type: 'UPDATE_CATEGORY', 9784 slug, 9785 category 9786 }; 9787 } 9788 9789 /** 9790 * Returns an action object used to add block collections 9791 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks. 9792 * 9793 * @ignore 9794 * 9795 * @param {string} namespace The namespace of the blocks to put in the collection 9796 * @param {string} title The title to display in the block inserter 9797 * @param {Object} icon (optional) The icon to display in the block inserter 9798 * 9799 * @return {Object} Action object. 9800 */ 9801 function addBlockCollection(namespace, title, icon) { 9802 return { 9803 type: 'ADD_BLOCK_COLLECTION', 9804 namespace, 9805 title, 9806 icon 9807 }; 9808 } 9809 9810 /** 9811 * Returns an action object used to remove block collections 9812 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks. 9813 * 9814 * @ignore 9815 * 9816 * @param {string} namespace The namespace of the blocks to put in the collection 9817 * 9818 * @return {Object} Action object. 9819 */ 9820 function removeBlockCollection(namespace) { 9821 return { 9822 type: 'REMOVE_BLOCK_COLLECTION', 9823 namespace 9824 }; 9825 } 9826 9827 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 9828 /** 9829 * Internal dependencies 9830 */ 9831 9832 9833 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9834 9835 /** 9836 * Add bootstrapped block type metadata to the store. These metadata usually come from 9837 * the `block.json` file and are either statically boostrapped from the server, or 9838 * passed as the `metadata` parameter to the `registerBlockType` function. 9839 * 9840 * @param {string} name Block name. 9841 * @param {WPBlockType} blockType Block type metadata. 9842 */ 9843 function addBootstrappedBlockType(name, blockType) { 9844 return { 9845 type: 'ADD_BOOTSTRAPPED_BLOCK_TYPE', 9846 name, 9847 blockType 9848 }; 9849 } 9850 9851 /** 9852 * Add unprocessed block type settings to the store. These data are passed as the 9853 * `settings` parameter to the client-side `registerBlockType` function. 9854 * 9855 * @param {string} name Block name. 9856 * @param {WPBlockType} blockType Unprocessed block type settings. 9857 */ 9858 function addUnprocessedBlockType(name, blockType) { 9859 return ({ 9860 dispatch 9861 }) => { 9862 dispatch({ 9863 type: 'ADD_UNPROCESSED_BLOCK_TYPE', 9864 name, 9865 blockType 9866 }); 9867 const processedBlockType = dispatch(processBlockType(name, blockType)); 9868 if (!processedBlockType) { 9869 return; 9870 } 9871 dispatch.addBlockTypes(processedBlockType); 9872 }; 9873 } 9874 9875 /** 9876 * Register new block bindings source. 9877 * 9878 * @param {string} source Name of the source to register. 9879 */ 9880 function registerBlockBindingsSource(source) { 9881 return { 9882 type: 'REGISTER_BLOCK_BINDINGS_SOURCE', 9883 sourceName: source.name, 9884 sourceLabel: source.label, 9885 useSource: source.useSource, 9886 lockAttributesEditing: source.lockAttributesEditing 9887 }; 9888 } 9889 9890 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/constants.js 9891 const STORE_NAME = 'core/blocks'; 9892 9893 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/index.js 9894 /** 9895 * WordPress dependencies 9896 */ 9897 9898 9899 /** 9900 * Internal dependencies 9901 */ 9902 9903 9904 9905 9906 9907 9908 9909 9910 /** 9911 * Store definition for the blocks namespace. 9912 * 9913 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 9914 * 9915 * @type {Object} 9916 */ 9917 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 9918 reducer: reducer, 9919 selectors: selectors_namespaceObject, 9920 actions: actions_namespaceObject 9921 }); 9922 (0,external_wp_data_namespaceObject.register)(store); 9923 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 9924 unlock(store).registerPrivateActions(private_actions_namespaceObject); 9925 9926 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/native.js 9927 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); 9928 /* harmony default export */ const esm_browser_native = ({ 9929 randomUUID 9930 }); 9931 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js 9932 // Unique ID creation requires a high quality random # generator. In the browser we therefore 9933 // require the crypto API and do not support built-in fallback to lower quality random number 9934 // generators (like Math.random()). 9935 let getRandomValues; 9936 const rnds8 = new Uint8Array(16); 9937 function rng() { 9938 // lazy load so that environments that need to polyfill have a chance to do so 9939 if (!getRandomValues) { 9940 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. 9941 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); 9942 9943 if (!getRandomValues) { 9944 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 9945 } 9946 } 9947 9948 return getRandomValues(rnds8); 9949 } 9950 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js 9951 9952 /** 9953 * Convert array of 16 byte values to UUID string format of the form: 9954 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 9955 */ 9956 9957 const byteToHex = []; 9958 9959 for (let i = 0; i < 256; ++i) { 9960 byteToHex.push((i + 0x100).toString(16).slice(1)); 9961 } 9962 9963 function unsafeStringify(arr, offset = 0) { 9964 // Note: Be careful editing this code! It's been tuned for performance 9965 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 9966 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]]; 9967 } 9968 9969 function stringify(arr, offset = 0) { 9970 const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one 9971 // of the following: 9972 // - One or more input array values don't map to a hex octet (leading to 9973 // "undefined" in the uuid) 9974 // - Invalid input values for the RFC `version` or `variant` fields 9975 9976 if (!validate(uuid)) { 9977 throw TypeError('Stringified UUID is invalid'); 9978 } 9979 9980 return uuid; 9981 } 9982 9983 /* harmony default export */ const esm_browser_stringify = ((/* unused pure expression or super */ null && (stringify))); 9984 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js 9985 9986 9987 9988 9989 function v4(options, buf, offset) { 9990 if (esm_browser_native.randomUUID && !buf && !options) { 9991 return esm_browser_native.randomUUID(); 9992 } 9993 9994 options = options || {}; 9995 const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 9996 9997 rnds[6] = rnds[6] & 0x0f | 0x40; 9998 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 9999 10000 if (buf) { 10001 offset = offset || 0; 10002 10003 for (let i = 0; i < 16; ++i) { 10004 buf[offset + i] = rnds[i]; 10005 } 10006 10007 return buf; 10008 } 10009 10010 return unsafeStringify(rnds); 10011 } 10012 10013 /* harmony default export */ const esm_browser_v4 = (v4); 10014 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/factory.js 10015 /** 10016 * External dependencies 10017 */ 10018 10019 10020 /** 10021 * WordPress dependencies 10022 */ 10023 10024 10025 /** 10026 * Internal dependencies 10027 */ 10028 10029 10030 10031 /** 10032 * Returns a block object given its type and attributes. 10033 * 10034 * @param {string} name Block name. 10035 * @param {Object} attributes Block attributes. 10036 * @param {?Array} innerBlocks Nested blocks. 10037 * 10038 * @return {Object} Block object. 10039 */ 10040 function createBlock(name, attributes = {}, innerBlocks = []) { 10041 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 10042 const clientId = esm_browser_v4(); 10043 10044 // Blocks are stored with a unique ID, the assigned type name, the block 10045 // attributes, and their inner blocks. 10046 return { 10047 clientId, 10048 name, 10049 isValid: true, 10050 attributes: sanitizedAttributes, 10051 innerBlocks 10052 }; 10053 } 10054 10055 /** 10056 * Given an array of InnerBlocks templates or Block Objects, 10057 * returns an array of created Blocks from them. 10058 * It handles the case of having InnerBlocks as Blocks by 10059 * converting them to the proper format to continue recursively. 10060 * 10061 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 10062 * 10063 * @return {Object[]} Array of Block objects. 10064 */ 10065 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) { 10066 return innerBlocksOrTemplate.map(innerBlock => { 10067 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 10068 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 10069 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 10070 }); 10071 } 10072 10073 /** 10074 * Given a block object, returns a copy of the block object while sanitizing its attributes, 10075 * optionally merging new attributes and/or replacing its inner blocks. 10076 * 10077 * @param {Object} block Block instance. 10078 * @param {Object} mergeAttributes Block attributes. 10079 * @param {?Array} newInnerBlocks Nested blocks. 10080 * 10081 * @return {Object} A cloned block. 10082 */ 10083 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) { 10084 const clientId = esm_browser_v4(); 10085 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { 10086 ...block.attributes, 10087 ...mergeAttributes 10088 }); 10089 return { 10090 ...block, 10091 clientId, 10092 attributes: sanitizedAttributes, 10093 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 10094 }; 10095 } 10096 10097 /** 10098 * Given a block object, returns a copy of the block object, 10099 * optionally merging new attributes and/or replacing its inner blocks. 10100 * 10101 * @param {Object} block Block instance. 10102 * @param {Object} mergeAttributes Block attributes. 10103 * @param {?Array} newInnerBlocks Nested blocks. 10104 * 10105 * @return {Object} A cloned block. 10106 */ 10107 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) { 10108 const clientId = esm_browser_v4(); 10109 return { 10110 ...block, 10111 clientId, 10112 attributes: { 10113 ...block.attributes, 10114 ...mergeAttributes 10115 }, 10116 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 10117 }; 10118 } 10119 10120 /** 10121 * Returns a boolean indicating whether a transform is possible based on 10122 * various bits of context. 10123 * 10124 * @param {Object} transform The transform object to validate. 10125 * @param {string} direction Is this a 'from' or 'to' transform. 10126 * @param {Array} blocks The blocks to transform from. 10127 * 10128 * @return {boolean} Is the transform possible? 10129 */ 10130 const isPossibleTransformForSource = (transform, direction, blocks) => { 10131 if (!blocks.length) { 10132 return false; 10133 } 10134 10135 // If multiple blocks are selected, only multi block transforms 10136 // or wildcard transforms are allowed. 10137 const isMultiBlock = blocks.length > 1; 10138 const firstBlockName = blocks[0].name; 10139 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 10140 if (!isValidForMultiBlocks) { 10141 return false; 10142 } 10143 10144 // Check non-wildcard transforms to ensure that transform is valid 10145 // for a block selection of multiple blocks of different types. 10146 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) { 10147 return false; 10148 } 10149 10150 // Only consider 'block' type transforms as valid. 10151 const isBlockType = transform.type === 'block'; 10152 if (!isBlockType) { 10153 return false; 10154 } 10155 10156 // Check if the transform's block name matches the source block (or is a wildcard) 10157 // only if this is a transform 'from'. 10158 const sourceBlock = blocks[0]; 10159 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 10160 if (!hasMatchingName) { 10161 return false; 10162 } 10163 10164 // Don't allow single Grouping blocks to be transformed into 10165 // a Grouping block. 10166 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 10167 return false; 10168 } 10169 10170 // If the transform has a `isMatch` function specified, check that it returns true. 10171 if (!maybeCheckTransformIsMatch(transform, blocks)) { 10172 return false; 10173 } 10174 return true; 10175 }; 10176 10177 /** 10178 * Returns block types that the 'blocks' can be transformed into, based on 10179 * 'from' transforms on other blocks. 10180 * 10181 * @param {Array} blocks The blocks to transform from. 10182 * 10183 * @return {Array} Block types that the blocks can be transformed into. 10184 */ 10185 const getBlockTypesForPossibleFromTransforms = blocks => { 10186 if (!blocks.length) { 10187 return []; 10188 } 10189 const allBlockTypes = getBlockTypes(); 10190 10191 // filter all blocks to find those with a 'from' transform. 10192 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => { 10193 const fromTransforms = getBlockTransforms('from', blockType.name); 10194 return !!findTransform(fromTransforms, transform => { 10195 return isPossibleTransformForSource(transform, 'from', blocks); 10196 }); 10197 }); 10198 return blockTypesWithPossibleFromTransforms; 10199 }; 10200 10201 /** 10202 * Returns block types that the 'blocks' can be transformed into, based on 10203 * the source block's own 'to' transforms. 10204 * 10205 * @param {Array} blocks The blocks to transform from. 10206 * 10207 * @return {Array} Block types that the source can be transformed into. 10208 */ 10209 const getBlockTypesForPossibleToTransforms = blocks => { 10210 if (!blocks.length) { 10211 return []; 10212 } 10213 const sourceBlock = blocks[0]; 10214 const blockType = getBlockType(sourceBlock.name); 10215 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; 10216 10217 // filter all 'to' transforms to find those that are possible. 10218 const possibleTransforms = transformsTo.filter(transform => { 10219 return transform && isPossibleTransformForSource(transform, 'to', blocks); 10220 }); 10221 10222 // Build a list of block names using the possible 'to' transforms. 10223 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat(); 10224 10225 // Map block names to block types. 10226 return blockNames.map(getBlockType); 10227 }; 10228 10229 /** 10230 * Determines whether transform is a "block" type 10231 * and if so whether it is a "wildcard" transform 10232 * ie: targets "any" block type 10233 * 10234 * @param {Object} t the Block transform object 10235 * 10236 * @return {boolean} whether transform is a wildcard transform 10237 */ 10238 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 10239 10240 /** 10241 * Determines whether the given Block is the core Block which 10242 * acts as a container Block for other Blocks as part of the 10243 * Grouping mechanics 10244 * 10245 * @param {string} name the name of the Block to test against 10246 * 10247 * @return {boolean} whether or not the Block is the container Block type 10248 */ 10249 const isContainerGroupBlock = name => name === getGroupingBlockName(); 10250 10251 /** 10252 * Returns an array of block types that the set of blocks received as argument 10253 * can be transformed into. 10254 * 10255 * @param {Array} blocks Blocks array. 10256 * 10257 * @return {Array} Block types that the blocks argument can be transformed to. 10258 */ 10259 function getPossibleBlockTransformations(blocks) { 10260 if (!blocks.length) { 10261 return []; 10262 } 10263 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 10264 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 10265 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])]; 10266 } 10267 10268 /** 10269 * Given an array of transforms, returns the highest-priority transform where 10270 * the predicate function returns a truthy value. A higher-priority transform 10271 * is one with a lower priority value (i.e. first in priority order). Returns 10272 * null if the transforms set is empty or the predicate function returns a 10273 * falsey value for all entries. 10274 * 10275 * @param {Object[]} transforms Transforms to search. 10276 * @param {Function} predicate Function returning true on matching transform. 10277 * 10278 * @return {?Object} Highest-priority transform candidate. 10279 */ 10280 function findTransform(transforms, predicate) { 10281 // The hooks library already has built-in mechanisms for managing priority 10282 // queue, so leverage via locally-defined instance. 10283 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)(); 10284 for (let i = 0; i < transforms.length; i++) { 10285 const candidate = transforms[i]; 10286 if (predicate(candidate)) { 10287 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 10288 } 10289 } 10290 10291 // Filter name is arbitrarily chosen but consistent with above aggregation. 10292 return hooks.applyFilters('transform', null); 10293 } 10294 10295 /** 10296 * Returns normal block transforms for a given transform direction, optionally 10297 * for a specific block by name, or an empty array if there are no transforms. 10298 * If no block name is provided, returns transforms for all blocks. A normal 10299 * transform object includes `blockName` as a property. 10300 * 10301 * @param {string} direction Transform direction ("to", "from"). 10302 * @param {string|Object} blockTypeOrName Block type or name. 10303 * 10304 * @return {Array} Block transforms for direction. 10305 */ 10306 function getBlockTransforms(direction, blockTypeOrName) { 10307 // When retrieving transforms for all block types, recurse into self. 10308 if (blockTypeOrName === undefined) { 10309 return getBlockTypes().map(({ 10310 name 10311 }) => getBlockTransforms(direction, name)).flat(); 10312 } 10313 10314 // Validate that block type exists and has array of direction. 10315 const blockType = normalizeBlockType(blockTypeOrName); 10316 const { 10317 name: blockName, 10318 transforms 10319 } = blockType || {}; 10320 if (!transforms || !Array.isArray(transforms[direction])) { 10321 return []; 10322 } 10323 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 10324 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => { 10325 if (t.type === 'raw') { 10326 return true; 10327 } 10328 if (!t.blocks || !t.blocks.length) { 10329 return false; 10330 } 10331 if (isWildcardBlockTransform(t)) { 10332 return true; 10333 } 10334 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 10335 }) : transforms[direction]; 10336 10337 // Map transforms to normal form. 10338 return filteredTransforms.map(transform => ({ 10339 ...transform, 10340 blockName, 10341 usingMobileTransformations 10342 })); 10343 } 10344 10345 /** 10346 * Checks that a given transforms isMatch method passes for given source blocks. 10347 * 10348 * @param {Object} transform A transform object. 10349 * @param {Array} blocks Blocks array. 10350 * 10351 * @return {boolean} True if given blocks are a match for the transform. 10352 */ 10353 function maybeCheckTransformIsMatch(transform, blocks) { 10354 if (typeof transform.isMatch !== 'function') { 10355 return true; 10356 } 10357 const sourceBlock = blocks[0]; 10358 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 10359 const block = transform.isMultiBlock ? blocks : sourceBlock; 10360 return transform.isMatch(attributes, block); 10361 } 10362 10363 /** 10364 * Switch one or more blocks into one or more blocks of the new block type. 10365 * 10366 * @param {Array|Object} blocks Blocks array or block object. 10367 * @param {string} name Block name. 10368 * 10369 * @return {?Array} Array of blocks or null. 10370 */ 10371 function switchToBlockType(blocks, name) { 10372 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10373 const isMultiBlock = blocksArray.length > 1; 10374 const firstBlock = blocksArray[0]; 10375 const sourceName = firstBlock.name; 10376 10377 // Find the right transformation by giving priority to the "to" 10378 // transformation. 10379 const transformationsFrom = getBlockTransforms('from', name); 10380 const transformationsTo = getBlockTransforms('to', sourceName); 10381 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)); 10382 10383 // Stop if there is no valid transformation. 10384 if (!transformation) { 10385 return null; 10386 } 10387 let transformationResults; 10388 if (transformation.isMultiBlock) { 10389 if ('__experimentalConvert' in transformation) { 10390 transformationResults = transformation.__experimentalConvert(blocksArray); 10391 } else { 10392 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 10393 } 10394 } else if ('__experimentalConvert' in transformation) { 10395 transformationResults = transformation.__experimentalConvert(firstBlock); 10396 } else { 10397 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 10398 } 10399 10400 // Ensure that the transformation function returned an object or an array 10401 // of objects. 10402 if (transformationResults === null || typeof transformationResults !== 'object') { 10403 return null; 10404 } 10405 10406 // If the transformation function returned a single object, we want to work 10407 // with an array instead. 10408 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults]; 10409 10410 // Ensure that every block object returned by the transformation has a 10411 // valid block type. 10412 if (transformationResults.some(result => !getBlockType(result.name))) { 10413 return null; 10414 } 10415 const hasSwitchedBlock = transformationResults.some(result => result.name === name); 10416 10417 // Ensure that at least one block object returned by the transformation has 10418 // the expected "destination" block type. 10419 if (!hasSwitchedBlock) { 10420 return null; 10421 } 10422 const ret = transformationResults.map((result, index, results) => { 10423 /** 10424 * Filters an individual transform result from block transformation. 10425 * All of the original blocks are passed, since transformations are 10426 * many-to-many, not one-to-one. 10427 * 10428 * @param {Object} transformedBlock The transformed block. 10429 * @param {Object[]} blocks Original blocks transformed. 10430 * @param {Object[]} index Index of the transformed block on the array of results. 10431 * @param {Object[]} results An array all the blocks that resulted from the transformation. 10432 */ 10433 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results); 10434 }); 10435 return ret; 10436 } 10437 10438 /** 10439 * Create a block object from the example API. 10440 * 10441 * @param {string} name 10442 * @param {Object} example 10443 * 10444 * @return {Object} block. 10445 */ 10446 const getBlockFromExample = (name, example) => { 10447 try { 10448 var _example$innerBlocks; 10449 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 10450 } catch { 10451 return createBlock('core/missing', { 10452 originalName: name, 10453 originalContent: '', 10454 originalUndelimitedContent: '' 10455 }); 10456 } 10457 }; 10458 10459 ;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"] 10460 const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 10461 ;// CONCATENATED MODULE: external ["wp","autop"] 10462 const external_wp_autop_namespaceObject = window["wp"]["autop"]; 10463 ;// CONCATENATED MODULE: external "React" 10464 const external_React_namespaceObject = window["React"]; 10465 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"] 10466 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 10467 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 10468 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/serialize-raw-block.js 10469 /** 10470 * Internal dependencies 10471 */ 10472 10473 10474 /** 10475 * @typedef {Object} Options Serialization options. 10476 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. 10477 */ 10478 10479 /** @typedef {import("./").WPRawBlock} WPRawBlock */ 10480 10481 /** 10482 * Serializes a block node into the native HTML-comment-powered block format. 10483 * CAVEAT: This function is intended for re-serializing blocks as parsed by 10484 * valid parsers and skips any validation steps. This is NOT a generic 10485 * serialization function for in-memory blocks. For most purposes, see the 10486 * following functions available in the `@wordpress/blocks` package: 10487 * 10488 * @see serializeBlock 10489 * @see serialize 10490 * 10491 * For more on the format of block nodes as returned by valid parsers: 10492 * 10493 * @see `@wordpress/block-serialization-default-parser` package 10494 * @see `@wordpress/block-serialization-spec-parser` package 10495 * 10496 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. 10497 * @param {Options} [options={}] Serialization options. 10498 * 10499 * @return {string} An HTML string representing a block. 10500 */ 10501 function serializeRawBlock(rawBlock, options = {}) { 10502 const { 10503 isCommentDelimited = true 10504 } = options; 10505 const { 10506 blockName, 10507 attrs = {}, 10508 innerBlocks = [], 10509 innerContent = [] 10510 } = rawBlock; 10511 let childIndex = 0; 10512 const content = innerContent.map(item => 10513 // `null` denotes a nested block, otherwise we have an HTML fragment. 10514 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 10515 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 10516 } 10517 10518 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/serializer.js 10519 10520 /** 10521 * WordPress dependencies 10522 */ 10523 10524 10525 10526 10527 10528 /** 10529 * Internal dependencies 10530 */ 10531 10532 10533 10534 10535 /** @typedef {import('./parser').WPBlock} WPBlock */ 10536 10537 /** 10538 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 10539 * 10540 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 10541 */ 10542 10543 /** 10544 * Returns the block's default classname from its name. 10545 * 10546 * @param {string} blockName The block name. 10547 * 10548 * @return {string} The block's default class. 10549 */ 10550 function getBlockDefaultClassName(blockName) { 10551 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 10552 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10553 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10554 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName); 10555 } 10556 10557 /** 10558 * Returns the block's default menu item classname from its name. 10559 * 10560 * @param {string} blockName The block name. 10561 * 10562 * @return {string} The block's default menu item class. 10563 */ 10564 function getBlockMenuDefaultClassName(blockName) { 10565 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 10566 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10567 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10568 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName); 10569 } 10570 const blockPropsProvider = {}; 10571 const innerBlocksPropsProvider = {}; 10572 10573 /** 10574 * Call within a save function to get the props for the block wrapper. 10575 * 10576 * @param {Object} props Optional. Props to pass to the element. 10577 */ 10578 function getBlockProps(props = {}) { 10579 const { 10580 blockType, 10581 attributes 10582 } = blockPropsProvider; 10583 return getBlockProps.skipFilters ? props : (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10584 ...props 10585 }, blockType, attributes); 10586 } 10587 10588 /** 10589 * Call within a save function to get the props for the inner blocks wrapper. 10590 * 10591 * @param {Object} props Optional. Props to pass to the element. 10592 */ 10593 function getInnerBlocksProps(props = {}) { 10594 const { 10595 innerBlocks 10596 } = innerBlocksPropsProvider; 10597 // Allow a different component to be passed to getSaveElement to handle 10598 // inner blocks, bypassing the default serialisation. 10599 if (!Array.isArray(innerBlocks)) { 10600 return { 10601 ...props, 10602 children: innerBlocks 10603 }; 10604 } 10605 // Value is an array of blocks, so defer to block serializer. 10606 const html = serialize(innerBlocks, { 10607 isInnerBlocks: true 10608 }); 10609 // Use special-cased raw HTML tag to avoid default escaping. 10610 const children = (0,external_React_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, html); 10611 return { 10612 ...props, 10613 children 10614 }; 10615 } 10616 10617 /** 10618 * Given a block type containing a save render implementation and attributes, returns the 10619 * enhanced element to be saved or string when raw HTML expected. 10620 * 10621 * @param {string|Object} blockTypeOrName Block type or name. 10622 * @param {Object} attributes Block attributes. 10623 * @param {?Array} innerBlocks Nested blocks. 10624 * 10625 * @return {Object|string} Save element or raw HTML string. 10626 */ 10627 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) { 10628 const blockType = normalizeBlockType(blockTypeOrName); 10629 if (!blockType?.save) return null; 10630 let { 10631 save 10632 } = blockType; 10633 10634 // Component classes are unsupported for save since serialization must 10635 // occur synchronously. For improved interoperability with higher-order 10636 // components which often return component class, emulate basic support. 10637 if (save.prototype instanceof external_wp_element_namespaceObject.Component) { 10638 const instance = new save({ 10639 attributes 10640 }); 10641 save = instance.render.bind(instance); 10642 } 10643 blockPropsProvider.blockType = blockType; 10644 blockPropsProvider.attributes = attributes; 10645 innerBlocksPropsProvider.innerBlocks = innerBlocks; 10646 let element = save({ 10647 attributes, 10648 innerBlocks 10649 }); 10650 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) { 10651 /** 10652 * Filters the props applied to the block save result element. 10653 * 10654 * @param {Object} props Props applied to save element. 10655 * @param {WPBlock} blockType Block type definition. 10656 * @param {Object} attributes Block attributes. 10657 */ 10658 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10659 ...element.props 10660 }, blockType, attributes); 10661 if (!external_wp_isShallowEqual_default()(props, element.props)) { 10662 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props); 10663 } 10664 } 10665 10666 /** 10667 * Filters the save result of a block during serialization. 10668 * 10669 * @param {Element} element Block save result. 10670 * @param {WPBlock} blockType Block type definition. 10671 * @param {Object} attributes Block attributes. 10672 */ 10673 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes); 10674 } 10675 10676 /** 10677 * Given a block type containing a save render implementation and attributes, returns the 10678 * static markup to be saved. 10679 * 10680 * @param {string|Object} blockTypeOrName Block type or name. 10681 * @param {Object} attributes Block attributes. 10682 * @param {?Array} innerBlocks Nested blocks. 10683 * 10684 * @return {string} Save content. 10685 */ 10686 function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 10687 const blockType = normalizeBlockType(blockTypeOrName); 10688 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks)); 10689 } 10690 10691 /** 10692 * Returns attributes which are to be saved and serialized into the block 10693 * comment delimiter. 10694 * 10695 * When a block exists in memory it contains as its attributes both those 10696 * parsed the block comment delimiter _and_ those which matched from the 10697 * contents of the block. 10698 * 10699 * This function returns only those attributes which are needed to persist and 10700 * which cannot be matched from the block content. 10701 * 10702 * @param {Object<string,*>} blockType Block type. 10703 * @param {Object<string,*>} attributes Attributes from in-memory block data. 10704 * 10705 * @return {Object<string,*>} Subset of attributes for comment serialization. 10706 */ 10707 function getCommentAttributes(blockType, attributes) { 10708 var _blockType$attributes; 10709 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).reduce((accumulator, [key, attributeSchema]) => { 10710 const value = attributes[key]; 10711 // Ignore undefined values. 10712 if (undefined === value) { 10713 return accumulator; 10714 } 10715 10716 // Ignore all attributes but the ones with an "undefined" source 10717 // "undefined" source refers to attributes saved in the block comment. 10718 if (attributeSchema.source !== undefined) { 10719 return accumulator; 10720 } 10721 10722 // Ignore default value. 10723 if ('default' in attributeSchema && JSON.stringify(attributeSchema.default) === JSON.stringify(value)) { 10724 return accumulator; 10725 } 10726 10727 // Otherwise, include in comment set. 10728 accumulator[key] = value; 10729 return accumulator; 10730 }, {}); 10731 } 10732 10733 /** 10734 * Given an attributes object, returns a string in the serialized attributes 10735 * format prepared for post content. 10736 * 10737 * @param {Object} attributes Attributes object. 10738 * 10739 * @return {string} Serialized attributes. 10740 */ 10741 function serializeAttributes(attributes) { 10742 return JSON.stringify(attributes) 10743 // Don't break HTML comments. 10744 .replace(/--/g, '\\u002d\\u002d') 10745 10746 // Don't break non-standard-compliant tools. 10747 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') 10748 10749 // Bypass server stripslashes behavior which would unescape stringify's 10750 // escaping of quotation mark. 10751 // 10752 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 10753 .replace(/\\"/g, '\\u0022'); 10754 } 10755 10756 /** 10757 * Given a block object, returns the Block's Inner HTML markup. 10758 * 10759 * @param {Object} block Block instance. 10760 * 10761 * @return {string} HTML. 10762 */ 10763 function getBlockInnerHTML(block) { 10764 // If block was parsed as invalid or encounters an error while generating 10765 // save content, use original content instead to avoid content loss. If a 10766 // block contains nested content, exempt it from this condition because we 10767 // otherwise have no access to its original content and content loss would 10768 // still occur. 10769 let saveContent = block.originalContent; 10770 if (block.isValid || block.innerBlocks.length) { 10771 try { 10772 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 10773 } catch (error) {} 10774 } 10775 return saveContent; 10776 } 10777 10778 /** 10779 * Returns the content of a block, including comment delimiters. 10780 * 10781 * @param {string} rawBlockName Block name. 10782 * @param {Object} attributes Block attributes. 10783 * @param {string} content Block save content. 10784 * 10785 * @return {string} Comment-delimited block content. 10786 */ 10787 function getCommentDelimitedContent(rawBlockName, attributes, content) { 10788 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : ''; 10789 10790 // Strip core blocks of their namespace prefix. 10791 const blockName = rawBlockName?.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName; 10792 10793 // @todo make the `wp:` prefix potentially configurable. 10794 10795 if (!content) { 10796 return `<!-- wp:$blockName} $serializedAttributes}/-->`; 10797 } 10798 return `<!-- wp:$blockName} $serializedAttributes}-->\n` + content + `\n<!-- /wp:$blockName} -->`; 10799 } 10800 10801 /** 10802 * Returns the content of a block, including comment delimiters, determining 10803 * serialized attributes and content form from the current state of the block. 10804 * 10805 * @param {WPBlock} block Block instance. 10806 * @param {WPBlockSerializationOptions} options Serialization options. 10807 * 10808 * @return {string} Serialized block. 10809 */ 10810 function serializeBlock(block, { 10811 isInnerBlocks = false 10812 } = {}) { 10813 if (!block.isValid && block.__unstableBlockSource) { 10814 return serializeRawBlock(block.__unstableBlockSource); 10815 } 10816 const blockName = block.name; 10817 const saveContent = getBlockInnerHTML(block); 10818 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 10819 return saveContent; 10820 } 10821 const blockType = getBlockType(blockName); 10822 if (!blockType) { 10823 return saveContent; 10824 } 10825 const saveAttributes = getCommentAttributes(blockType, block.attributes); 10826 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 10827 } 10828 function __unstableSerializeAndClean(blocks) { 10829 // A single unmodified default block is assumed to 10830 // be equivalent to an empty post. 10831 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 10832 blocks = []; 10833 } 10834 let content = serialize(blocks); 10835 10836 // For compatibility, treat a post consisting of a 10837 // single freeform block as legacy content and apply 10838 // pre-block-editor removep'd content formatting. 10839 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName() && blocks[0].name === 'core/freeform') { 10840 content = (0,external_wp_autop_namespaceObject.removep)(content); 10841 } 10842 return content; 10843 } 10844 10845 /** 10846 * Takes a block or set of blocks and returns the serialized post content. 10847 * 10848 * @param {Array} blocks Block(s) to serialize. 10849 * @param {WPBlockSerializationOptions} options Serialization options. 10850 * 10851 * @return {string} The post content. 10852 */ 10853 function serialize(blocks, options) { 10854 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10855 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n'); 10856 } 10857 10858 ;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js 10859 /** 10860 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 10861 * do not edit 10862 */ 10863 var namedCharRefs = { 10864 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" 10865 }; 10866 10867 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 10868 var CHARCODE = /^#([0-9]+)$/; 10869 var NAMED = /^([A-Za-z0-9]+)$/; 10870 var EntityParser = /** @class */ (function () { 10871 function EntityParser(named) { 10872 this.named = named; 10873 } 10874 EntityParser.prototype.parse = function (entity) { 10875 if (!entity) { 10876 return; 10877 } 10878 var matches = entity.match(HEXCHARCODE); 10879 if (matches) { 10880 return String.fromCharCode(parseInt(matches[1], 16)); 10881 } 10882 matches = entity.match(CHARCODE); 10883 if (matches) { 10884 return String.fromCharCode(parseInt(matches[1], 10)); 10885 } 10886 matches = entity.match(NAMED); 10887 if (matches) { 10888 return this.named[matches[1]]; 10889 } 10890 }; 10891 return EntityParser; 10892 }()); 10893 10894 var WSP = /[\t\n\f ]/; 10895 var ALPHA = /[A-Za-z]/; 10896 var CRLF = /\r\n?/g; 10897 function isSpace(char) { 10898 return WSP.test(char); 10899 } 10900 function isAlpha(char) { 10901 return ALPHA.test(char); 10902 } 10903 function preprocessInput(input) { 10904 return input.replace(CRLF, '\n'); 10905 } 10906 10907 var EventedTokenizer = /** @class */ (function () { 10908 function EventedTokenizer(delegate, entityParser, mode) { 10909 if (mode === void 0) { mode = 'precompile'; } 10910 this.delegate = delegate; 10911 this.entityParser = entityParser; 10912 this.mode = mode; 10913 this.state = "beforeData" /* beforeData */; 10914 this.line = -1; 10915 this.column = -1; 10916 this.input = ''; 10917 this.index = -1; 10918 this.tagNameBuffer = ''; 10919 this.states = { 10920 beforeData: function () { 10921 var char = this.peek(); 10922 if (char === '<' && !this.isIgnoredEndTag()) { 10923 this.transitionTo("tagOpen" /* tagOpen */); 10924 this.markTagStart(); 10925 this.consume(); 10926 } 10927 else { 10928 if (this.mode === 'precompile' && char === '\n') { 10929 var tag = this.tagNameBuffer.toLowerCase(); 10930 if (tag === 'pre' || tag === 'textarea') { 10931 this.consume(); 10932 } 10933 } 10934 this.transitionTo("data" /* data */); 10935 this.delegate.beginData(); 10936 } 10937 }, 10938 data: function () { 10939 var char = this.peek(); 10940 var tag = this.tagNameBuffer; 10941 if (char === '<' && !this.isIgnoredEndTag()) { 10942 this.delegate.finishData(); 10943 this.transitionTo("tagOpen" /* tagOpen */); 10944 this.markTagStart(); 10945 this.consume(); 10946 } 10947 else if (char === '&' && tag !== 'script' && tag !== 'style') { 10948 this.consume(); 10949 this.delegate.appendToData(this.consumeCharRef() || '&'); 10950 } 10951 else { 10952 this.consume(); 10953 this.delegate.appendToData(char); 10954 } 10955 }, 10956 tagOpen: function () { 10957 var char = this.consume(); 10958 if (char === '!') { 10959 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 10960 } 10961 else if (char === '/') { 10962 this.transitionTo("endTagOpen" /* endTagOpen */); 10963 } 10964 else if (char === '@' || char === ':' || isAlpha(char)) { 10965 this.transitionTo("tagName" /* tagName */); 10966 this.tagNameBuffer = ''; 10967 this.delegate.beginStartTag(); 10968 this.appendToTagName(char); 10969 } 10970 }, 10971 markupDeclarationOpen: function () { 10972 var char = this.consume(); 10973 if (char === '-' && this.peek() === '-') { 10974 this.consume(); 10975 this.transitionTo("commentStart" /* commentStart */); 10976 this.delegate.beginComment(); 10977 } 10978 else { 10979 var maybeDoctype = char.toUpperCase() + this.input.substring(this.index, this.index + 6).toUpperCase(); 10980 if (maybeDoctype === 'DOCTYPE') { 10981 this.consume(); 10982 this.consume(); 10983 this.consume(); 10984 this.consume(); 10985 this.consume(); 10986 this.consume(); 10987 this.transitionTo("doctype" /* doctype */); 10988 if (this.delegate.beginDoctype) 10989 this.delegate.beginDoctype(); 10990 } 10991 } 10992 }, 10993 doctype: function () { 10994 var char = this.consume(); 10995 if (isSpace(char)) { 10996 this.transitionTo("beforeDoctypeName" /* beforeDoctypeName */); 10997 } 10998 }, 10999 beforeDoctypeName: function () { 11000 var char = this.consume(); 11001 if (isSpace(char)) { 11002 return; 11003 } 11004 else { 11005 this.transitionTo("doctypeName" /* doctypeName */); 11006 if (this.delegate.appendToDoctypeName) 11007 this.delegate.appendToDoctypeName(char.toLowerCase()); 11008 } 11009 }, 11010 doctypeName: function () { 11011 var char = this.consume(); 11012 if (isSpace(char)) { 11013 this.transitionTo("afterDoctypeName" /* afterDoctypeName */); 11014 } 11015 else if (char === '>') { 11016 if (this.delegate.endDoctype) 11017 this.delegate.endDoctype(); 11018 this.transitionTo("beforeData" /* beforeData */); 11019 } 11020 else { 11021 if (this.delegate.appendToDoctypeName) 11022 this.delegate.appendToDoctypeName(char.toLowerCase()); 11023 } 11024 }, 11025 afterDoctypeName: function () { 11026 var char = this.consume(); 11027 if (isSpace(char)) { 11028 return; 11029 } 11030 else if (char === '>') { 11031 if (this.delegate.endDoctype) 11032 this.delegate.endDoctype(); 11033 this.transitionTo("beforeData" /* beforeData */); 11034 } 11035 else { 11036 var nextSixChars = char.toUpperCase() + this.input.substring(this.index, this.index + 5).toUpperCase(); 11037 var isPublic = nextSixChars.toUpperCase() === 'PUBLIC'; 11038 var isSystem = nextSixChars.toUpperCase() === 'SYSTEM'; 11039 if (isPublic || isSystem) { 11040 this.consume(); 11041 this.consume(); 11042 this.consume(); 11043 this.consume(); 11044 this.consume(); 11045 this.consume(); 11046 } 11047 if (isPublic) { 11048 this.transitionTo("afterDoctypePublicKeyword" /* afterDoctypePublicKeyword */); 11049 } 11050 else if (isSystem) { 11051 this.transitionTo("afterDoctypeSystemKeyword" /* afterDoctypeSystemKeyword */); 11052 } 11053 } 11054 }, 11055 afterDoctypePublicKeyword: function () { 11056 var char = this.peek(); 11057 if (isSpace(char)) { 11058 this.transitionTo("beforeDoctypePublicIdentifier" /* beforeDoctypePublicIdentifier */); 11059 this.consume(); 11060 } 11061 else if (char === '"') { 11062 this.transitionTo("doctypePublicIdentifierDoubleQuoted" /* doctypePublicIdentifierDoubleQuoted */); 11063 this.consume(); 11064 } 11065 else if (char === "'") { 11066 this.transitionTo("doctypePublicIdentifierSingleQuoted" /* doctypePublicIdentifierSingleQuoted */); 11067 this.consume(); 11068 } 11069 else if (char === '>') { 11070 this.consume(); 11071 if (this.delegate.endDoctype) 11072 this.delegate.endDoctype(); 11073 this.transitionTo("beforeData" /* beforeData */); 11074 } 11075 }, 11076 doctypePublicIdentifierDoubleQuoted: function () { 11077 var char = this.consume(); 11078 if (char === '"') { 11079 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11080 } 11081 else if (char === '>') { 11082 if (this.delegate.endDoctype) 11083 this.delegate.endDoctype(); 11084 this.transitionTo("beforeData" /* beforeData */); 11085 } 11086 else { 11087 if (this.delegate.appendToDoctypePublicIdentifier) 11088 this.delegate.appendToDoctypePublicIdentifier(char); 11089 } 11090 }, 11091 doctypePublicIdentifierSingleQuoted: function () { 11092 var char = this.consume(); 11093 if (char === "'") { 11094 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11095 } 11096 else if (char === '>') { 11097 if (this.delegate.endDoctype) 11098 this.delegate.endDoctype(); 11099 this.transitionTo("beforeData" /* beforeData */); 11100 } 11101 else { 11102 if (this.delegate.appendToDoctypePublicIdentifier) 11103 this.delegate.appendToDoctypePublicIdentifier(char); 11104 } 11105 }, 11106 afterDoctypePublicIdentifier: function () { 11107 var char = this.consume(); 11108 if (isSpace(char)) { 11109 this.transitionTo("betweenDoctypePublicAndSystemIdentifiers" /* betweenDoctypePublicAndSystemIdentifiers */); 11110 } 11111 else if (char === '>') { 11112 if (this.delegate.endDoctype) 11113 this.delegate.endDoctype(); 11114 this.transitionTo("beforeData" /* beforeData */); 11115 } 11116 else if (char === '"') { 11117 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11118 } 11119 else if (char === "'") { 11120 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11121 } 11122 }, 11123 betweenDoctypePublicAndSystemIdentifiers: function () { 11124 var char = this.consume(); 11125 if (isSpace(char)) { 11126 return; 11127 } 11128 else if (char === '>') { 11129 if (this.delegate.endDoctype) 11130 this.delegate.endDoctype(); 11131 this.transitionTo("beforeData" /* beforeData */); 11132 } 11133 else if (char === '"') { 11134 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11135 } 11136 else if (char === "'") { 11137 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11138 } 11139 }, 11140 doctypeSystemIdentifierDoubleQuoted: function () { 11141 var char = this.consume(); 11142 if (char === '"') { 11143 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11144 } 11145 else if (char === '>') { 11146 if (this.delegate.endDoctype) 11147 this.delegate.endDoctype(); 11148 this.transitionTo("beforeData" /* beforeData */); 11149 } 11150 else { 11151 if (this.delegate.appendToDoctypeSystemIdentifier) 11152 this.delegate.appendToDoctypeSystemIdentifier(char); 11153 } 11154 }, 11155 doctypeSystemIdentifierSingleQuoted: function () { 11156 var char = this.consume(); 11157 if (char === "'") { 11158 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11159 } 11160 else if (char === '>') { 11161 if (this.delegate.endDoctype) 11162 this.delegate.endDoctype(); 11163 this.transitionTo("beforeData" /* beforeData */); 11164 } 11165 else { 11166 if (this.delegate.appendToDoctypeSystemIdentifier) 11167 this.delegate.appendToDoctypeSystemIdentifier(char); 11168 } 11169 }, 11170 afterDoctypeSystemIdentifier: function () { 11171 var char = this.consume(); 11172 if (isSpace(char)) { 11173 return; 11174 } 11175 else if (char === '>') { 11176 if (this.delegate.endDoctype) 11177 this.delegate.endDoctype(); 11178 this.transitionTo("beforeData" /* beforeData */); 11179 } 11180 }, 11181 commentStart: function () { 11182 var char = this.consume(); 11183 if (char === '-') { 11184 this.transitionTo("commentStartDash" /* commentStartDash */); 11185 } 11186 else if (char === '>') { 11187 this.delegate.finishComment(); 11188 this.transitionTo("beforeData" /* beforeData */); 11189 } 11190 else { 11191 this.delegate.appendToCommentData(char); 11192 this.transitionTo("comment" /* comment */); 11193 } 11194 }, 11195 commentStartDash: function () { 11196 var char = this.consume(); 11197 if (char === '-') { 11198 this.transitionTo("commentEnd" /* commentEnd */); 11199 } 11200 else if (char === '>') { 11201 this.delegate.finishComment(); 11202 this.transitionTo("beforeData" /* beforeData */); 11203 } 11204 else { 11205 this.delegate.appendToCommentData('-'); 11206 this.transitionTo("comment" /* comment */); 11207 } 11208 }, 11209 comment: function () { 11210 var char = this.consume(); 11211 if (char === '-') { 11212 this.transitionTo("commentEndDash" /* commentEndDash */); 11213 } 11214 else { 11215 this.delegate.appendToCommentData(char); 11216 } 11217 }, 11218 commentEndDash: function () { 11219 var char = this.consume(); 11220 if (char === '-') { 11221 this.transitionTo("commentEnd" /* commentEnd */); 11222 } 11223 else { 11224 this.delegate.appendToCommentData('-' + char); 11225 this.transitionTo("comment" /* comment */); 11226 } 11227 }, 11228 commentEnd: function () { 11229 var char = this.consume(); 11230 if (char === '>') { 11231 this.delegate.finishComment(); 11232 this.transitionTo("beforeData" /* beforeData */); 11233 } 11234 else { 11235 this.delegate.appendToCommentData('--' + char); 11236 this.transitionTo("comment" /* comment */); 11237 } 11238 }, 11239 tagName: function () { 11240 var char = this.consume(); 11241 if (isSpace(char)) { 11242 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11243 } 11244 else if (char === '/') { 11245 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11246 } 11247 else if (char === '>') { 11248 this.delegate.finishTag(); 11249 this.transitionTo("beforeData" /* beforeData */); 11250 } 11251 else { 11252 this.appendToTagName(char); 11253 } 11254 }, 11255 endTagName: function () { 11256 var char = this.consume(); 11257 if (isSpace(char)) { 11258 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11259 this.tagNameBuffer = ''; 11260 } 11261 else if (char === '/') { 11262 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11263 this.tagNameBuffer = ''; 11264 } 11265 else if (char === '>') { 11266 this.delegate.finishTag(); 11267 this.transitionTo("beforeData" /* beforeData */); 11268 this.tagNameBuffer = ''; 11269 } 11270 else { 11271 this.appendToTagName(char); 11272 } 11273 }, 11274 beforeAttributeName: function () { 11275 var char = this.peek(); 11276 if (isSpace(char)) { 11277 this.consume(); 11278 return; 11279 } 11280 else if (char === '/') { 11281 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11282 this.consume(); 11283 } 11284 else if (char === '>') { 11285 this.consume(); 11286 this.delegate.finishTag(); 11287 this.transitionTo("beforeData" /* beforeData */); 11288 } 11289 else if (char === '=') { 11290 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 11291 this.transitionTo("attributeName" /* attributeName */); 11292 this.delegate.beginAttribute(); 11293 this.consume(); 11294 this.delegate.appendToAttributeName(char); 11295 } 11296 else { 11297 this.transitionTo("attributeName" /* attributeName */); 11298 this.delegate.beginAttribute(); 11299 } 11300 }, 11301 attributeName: function () { 11302 var char = this.peek(); 11303 if (isSpace(char)) { 11304 this.transitionTo("afterAttributeName" /* afterAttributeName */); 11305 this.consume(); 11306 } 11307 else if (char === '/') { 11308 this.delegate.beginAttributeValue(false); 11309 this.delegate.finishAttributeValue(); 11310 this.consume(); 11311 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11312 } 11313 else if (char === '=') { 11314 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11315 this.consume(); 11316 } 11317 else if (char === '>') { 11318 this.delegate.beginAttributeValue(false); 11319 this.delegate.finishAttributeValue(); 11320 this.consume(); 11321 this.delegate.finishTag(); 11322 this.transitionTo("beforeData" /* beforeData */); 11323 } 11324 else if (char === '"' || char === "'" || char === '<') { 11325 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 11326 this.consume(); 11327 this.delegate.appendToAttributeName(char); 11328 } 11329 else { 11330 this.consume(); 11331 this.delegate.appendToAttributeName(char); 11332 } 11333 }, 11334 afterAttributeName: function () { 11335 var char = this.peek(); 11336 if (isSpace(char)) { 11337 this.consume(); 11338 return; 11339 } 11340 else if (char === '/') { 11341 this.delegate.beginAttributeValue(false); 11342 this.delegate.finishAttributeValue(); 11343 this.consume(); 11344 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11345 } 11346 else if (char === '=') { 11347 this.consume(); 11348 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11349 } 11350 else if (char === '>') { 11351 this.delegate.beginAttributeValue(false); 11352 this.delegate.finishAttributeValue(); 11353 this.consume(); 11354 this.delegate.finishTag(); 11355 this.transitionTo("beforeData" /* beforeData */); 11356 } 11357 else { 11358 this.delegate.beginAttributeValue(false); 11359 this.delegate.finishAttributeValue(); 11360 this.transitionTo("attributeName" /* attributeName */); 11361 this.delegate.beginAttribute(); 11362 this.consume(); 11363 this.delegate.appendToAttributeName(char); 11364 } 11365 }, 11366 beforeAttributeValue: function () { 11367 var char = this.peek(); 11368 if (isSpace(char)) { 11369 this.consume(); 11370 } 11371 else if (char === '"') { 11372 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 11373 this.delegate.beginAttributeValue(true); 11374 this.consume(); 11375 } 11376 else if (char === "'") { 11377 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 11378 this.delegate.beginAttributeValue(true); 11379 this.consume(); 11380 } 11381 else if (char === '>') { 11382 this.delegate.beginAttributeValue(false); 11383 this.delegate.finishAttributeValue(); 11384 this.consume(); 11385 this.delegate.finishTag(); 11386 this.transitionTo("beforeData" /* beforeData */); 11387 } 11388 else { 11389 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 11390 this.delegate.beginAttributeValue(false); 11391 this.consume(); 11392 this.delegate.appendToAttributeValue(char); 11393 } 11394 }, 11395 attributeValueDoubleQuoted: function () { 11396 var char = this.consume(); 11397 if (char === '"') { 11398 this.delegate.finishAttributeValue(); 11399 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11400 } 11401 else if (char === '&') { 11402 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11403 } 11404 else { 11405 this.delegate.appendToAttributeValue(char); 11406 } 11407 }, 11408 attributeValueSingleQuoted: function () { 11409 var char = this.consume(); 11410 if (char === "'") { 11411 this.delegate.finishAttributeValue(); 11412 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11413 } 11414 else if (char === '&') { 11415 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11416 } 11417 else { 11418 this.delegate.appendToAttributeValue(char); 11419 } 11420 }, 11421 attributeValueUnquoted: function () { 11422 var char = this.peek(); 11423 if (isSpace(char)) { 11424 this.delegate.finishAttributeValue(); 11425 this.consume(); 11426 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11427 } 11428 else if (char === '/') { 11429 this.delegate.finishAttributeValue(); 11430 this.consume(); 11431 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11432 } 11433 else if (char === '&') { 11434 this.consume(); 11435 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11436 } 11437 else if (char === '>') { 11438 this.delegate.finishAttributeValue(); 11439 this.consume(); 11440 this.delegate.finishTag(); 11441 this.transitionTo("beforeData" /* beforeData */); 11442 } 11443 else { 11444 this.consume(); 11445 this.delegate.appendToAttributeValue(char); 11446 } 11447 }, 11448 afterAttributeValueQuoted: function () { 11449 var char = this.peek(); 11450 if (isSpace(char)) { 11451 this.consume(); 11452 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11453 } 11454 else if (char === '/') { 11455 this.consume(); 11456 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11457 } 11458 else if (char === '>') { 11459 this.consume(); 11460 this.delegate.finishTag(); 11461 this.transitionTo("beforeData" /* beforeData */); 11462 } 11463 else { 11464 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11465 } 11466 }, 11467 selfClosingStartTag: function () { 11468 var char = this.peek(); 11469 if (char === '>') { 11470 this.consume(); 11471 this.delegate.markTagAsSelfClosing(); 11472 this.delegate.finishTag(); 11473 this.transitionTo("beforeData" /* beforeData */); 11474 } 11475 else { 11476 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11477 } 11478 }, 11479 endTagOpen: function () { 11480 var char = this.consume(); 11481 if (char === '@' || char === ':' || isAlpha(char)) { 11482 this.transitionTo("endTagName" /* endTagName */); 11483 this.tagNameBuffer = ''; 11484 this.delegate.beginEndTag(); 11485 this.appendToTagName(char); 11486 } 11487 } 11488 }; 11489 this.reset(); 11490 } 11491 EventedTokenizer.prototype.reset = function () { 11492 this.transitionTo("beforeData" /* beforeData */); 11493 this.input = ''; 11494 this.tagNameBuffer = ''; 11495 this.index = 0; 11496 this.line = 1; 11497 this.column = 0; 11498 this.delegate.reset(); 11499 }; 11500 EventedTokenizer.prototype.transitionTo = function (state) { 11501 this.state = state; 11502 }; 11503 EventedTokenizer.prototype.tokenize = function (input) { 11504 this.reset(); 11505 this.tokenizePart(input); 11506 this.tokenizeEOF(); 11507 }; 11508 EventedTokenizer.prototype.tokenizePart = function (input) { 11509 this.input += preprocessInput(input); 11510 while (this.index < this.input.length) { 11511 var handler = this.states[this.state]; 11512 if (handler !== undefined) { 11513 handler.call(this); 11514 } 11515 else { 11516 throw new Error("unhandled state " + this.state); 11517 } 11518 } 11519 }; 11520 EventedTokenizer.prototype.tokenizeEOF = function () { 11521 this.flushData(); 11522 }; 11523 EventedTokenizer.prototype.flushData = function () { 11524 if (this.state === 'data') { 11525 this.delegate.finishData(); 11526 this.transitionTo("beforeData" /* beforeData */); 11527 } 11528 }; 11529 EventedTokenizer.prototype.peek = function () { 11530 return this.input.charAt(this.index); 11531 }; 11532 EventedTokenizer.prototype.consume = function () { 11533 var char = this.peek(); 11534 this.index++; 11535 if (char === '\n') { 11536 this.line++; 11537 this.column = 0; 11538 } 11539 else { 11540 this.column++; 11541 } 11542 return char; 11543 }; 11544 EventedTokenizer.prototype.consumeCharRef = function () { 11545 var endIndex = this.input.indexOf(';', this.index); 11546 if (endIndex === -1) { 11547 return; 11548 } 11549 var entity = this.input.slice(this.index, endIndex); 11550 var chars = this.entityParser.parse(entity); 11551 if (chars) { 11552 var count = entity.length; 11553 // consume the entity chars 11554 while (count) { 11555 this.consume(); 11556 count--; 11557 } 11558 // consume the `;` 11559 this.consume(); 11560 return chars; 11561 } 11562 }; 11563 EventedTokenizer.prototype.markTagStart = function () { 11564 this.delegate.tagOpen(); 11565 }; 11566 EventedTokenizer.prototype.appendToTagName = function (char) { 11567 this.tagNameBuffer += char; 11568 this.delegate.appendToTagName(char); 11569 }; 11570 EventedTokenizer.prototype.isIgnoredEndTag = function () { 11571 var tag = this.tagNameBuffer; 11572 return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') || 11573 (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') || 11574 (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>'); 11575 }; 11576 return EventedTokenizer; 11577 }()); 11578 11579 var Tokenizer = /** @class */ (function () { 11580 function Tokenizer(entityParser, options) { 11581 if (options === void 0) { options = {}; } 11582 this.options = options; 11583 this.token = null; 11584 this.startLine = 1; 11585 this.startColumn = 0; 11586 this.tokens = []; 11587 this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); 11588 this._currentAttribute = undefined; 11589 } 11590 Tokenizer.prototype.tokenize = function (input) { 11591 this.tokens = []; 11592 this.tokenizer.tokenize(input); 11593 return this.tokens; 11594 }; 11595 Tokenizer.prototype.tokenizePart = function (input) { 11596 this.tokens = []; 11597 this.tokenizer.tokenizePart(input); 11598 return this.tokens; 11599 }; 11600 Tokenizer.prototype.tokenizeEOF = function () { 11601 this.tokens = []; 11602 this.tokenizer.tokenizeEOF(); 11603 return this.tokens[0]; 11604 }; 11605 Tokenizer.prototype.reset = function () { 11606 this.token = null; 11607 this.startLine = 1; 11608 this.startColumn = 0; 11609 }; 11610 Tokenizer.prototype.current = function () { 11611 var token = this.token; 11612 if (token === null) { 11613 throw new Error('token was unexpectedly null'); 11614 } 11615 if (arguments.length === 0) { 11616 return token; 11617 } 11618 for (var i = 0; i < arguments.length; i++) { 11619 if (token.type === arguments[i]) { 11620 return token; 11621 } 11622 } 11623 throw new Error("token type was unexpectedly " + token.type); 11624 }; 11625 Tokenizer.prototype.push = function (token) { 11626 this.token = token; 11627 this.tokens.push(token); 11628 }; 11629 Tokenizer.prototype.currentAttribute = function () { 11630 return this._currentAttribute; 11631 }; 11632 Tokenizer.prototype.addLocInfo = function () { 11633 if (this.options.loc) { 11634 this.current().loc = { 11635 start: { 11636 line: this.startLine, 11637 column: this.startColumn 11638 }, 11639 end: { 11640 line: this.tokenizer.line, 11641 column: this.tokenizer.column 11642 } 11643 }; 11644 } 11645 this.startLine = this.tokenizer.line; 11646 this.startColumn = this.tokenizer.column; 11647 }; 11648 // Data 11649 Tokenizer.prototype.beginDoctype = function () { 11650 this.push({ 11651 type: "Doctype" /* Doctype */, 11652 name: '', 11653 }); 11654 }; 11655 Tokenizer.prototype.appendToDoctypeName = function (char) { 11656 this.current("Doctype" /* Doctype */).name += char; 11657 }; 11658 Tokenizer.prototype.appendToDoctypePublicIdentifier = function (char) { 11659 var doctype = this.current("Doctype" /* Doctype */); 11660 if (doctype.publicIdentifier === undefined) { 11661 doctype.publicIdentifier = char; 11662 } 11663 else { 11664 doctype.publicIdentifier += char; 11665 } 11666 }; 11667 Tokenizer.prototype.appendToDoctypeSystemIdentifier = function (char) { 11668 var doctype = this.current("Doctype" /* Doctype */); 11669 if (doctype.systemIdentifier === undefined) { 11670 doctype.systemIdentifier = char; 11671 } 11672 else { 11673 doctype.systemIdentifier += char; 11674 } 11675 }; 11676 Tokenizer.prototype.endDoctype = function () { 11677 this.addLocInfo(); 11678 }; 11679 Tokenizer.prototype.beginData = function () { 11680 this.push({ 11681 type: "Chars" /* Chars */, 11682 chars: '' 11683 }); 11684 }; 11685 Tokenizer.prototype.appendToData = function (char) { 11686 this.current("Chars" /* Chars */).chars += char; 11687 }; 11688 Tokenizer.prototype.finishData = function () { 11689 this.addLocInfo(); 11690 }; 11691 // Comment 11692 Tokenizer.prototype.beginComment = function () { 11693 this.push({ 11694 type: "Comment" /* Comment */, 11695 chars: '' 11696 }); 11697 }; 11698 Tokenizer.prototype.appendToCommentData = function (char) { 11699 this.current("Comment" /* Comment */).chars += char; 11700 }; 11701 Tokenizer.prototype.finishComment = function () { 11702 this.addLocInfo(); 11703 }; 11704 // Tags - basic 11705 Tokenizer.prototype.tagOpen = function () { }; 11706 Tokenizer.prototype.beginStartTag = function () { 11707 this.push({ 11708 type: "StartTag" /* StartTag */, 11709 tagName: '', 11710 attributes: [], 11711 selfClosing: false 11712 }); 11713 }; 11714 Tokenizer.prototype.beginEndTag = function () { 11715 this.push({ 11716 type: "EndTag" /* EndTag */, 11717 tagName: '' 11718 }); 11719 }; 11720 Tokenizer.prototype.finishTag = function () { 11721 this.addLocInfo(); 11722 }; 11723 Tokenizer.prototype.markTagAsSelfClosing = function () { 11724 this.current("StartTag" /* StartTag */).selfClosing = true; 11725 }; 11726 // Tags - name 11727 Tokenizer.prototype.appendToTagName = function (char) { 11728 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 11729 }; 11730 // Tags - attributes 11731 Tokenizer.prototype.beginAttribute = function () { 11732 this._currentAttribute = ['', '', false]; 11733 }; 11734 Tokenizer.prototype.appendToAttributeName = function (char) { 11735 this.currentAttribute()[0] += char; 11736 }; 11737 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 11738 this.currentAttribute()[2] = isQuoted; 11739 }; 11740 Tokenizer.prototype.appendToAttributeValue = function (char) { 11741 this.currentAttribute()[1] += char; 11742 }; 11743 Tokenizer.prototype.finishAttributeValue = function () { 11744 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 11745 }; 11746 Tokenizer.prototype.reportSyntaxError = function (message) { 11747 this.current().syntaxError = message; 11748 }; 11749 return Tokenizer; 11750 }()); 11751 11752 function tokenize(input, options) { 11753 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 11754 return tokenizer.tokenize(input); 11755 } 11756 11757 11758 11759 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 11760 var es6 = __webpack_require__(7734); 11761 var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 11762 ;// CONCATENATED MODULE: external ["wp","htmlEntities"] 11763 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 11764 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js 11765 /** 11766 * @typedef LoggerItem 11767 * @property {Function} log Which logger recorded the message 11768 * @property {Array<any>} args White arguments were supplied to the logger 11769 */ 11770 11771 function createLogger() { 11772 /** 11773 * Creates a log handler with block validation prefix. 11774 * 11775 * @param {Function} logger Original logger function. 11776 * 11777 * @return {Function} Augmented logger function. 11778 */ 11779 function createLogHandler(logger) { 11780 let log = (message, ...args) => logger('Block validation: ' + message, ...args); 11781 11782 // In test environments, pre-process string substitutions to improve 11783 // readability of error messages. We'd prefer to avoid pulling in this 11784 // dependency in runtime environments, and it can be dropped by a combo 11785 // of Webpack env substitution + UglifyJS dead code elimination. 11786 if (false) {} 11787 return log; 11788 } 11789 return { 11790 // eslint-disable-next-line no-console 11791 error: createLogHandler(console.error), 11792 // eslint-disable-next-line no-console 11793 warning: createLogHandler(console.warn), 11794 getItems() { 11795 return []; 11796 } 11797 }; 11798 } 11799 function createQueuedLogger() { 11800 /** 11801 * The list of enqueued log actions to print. 11802 * 11803 * @type {Array<LoggerItem>} 11804 */ 11805 const queue = []; 11806 const logger = createLogger(); 11807 return { 11808 error(...args) { 11809 queue.push({ 11810 log: logger.error, 11811 args 11812 }); 11813 }, 11814 warning(...args) { 11815 queue.push({ 11816 log: logger.warning, 11817 args 11818 }); 11819 }, 11820 getItems() { 11821 return queue; 11822 } 11823 }; 11824 } 11825 11826 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/index.js 11827 /** 11828 * External dependencies 11829 */ 11830 11831 11832 11833 /** 11834 * WordPress dependencies 11835 */ 11836 11837 11838 11839 /** 11840 * Internal dependencies 11841 */ 11842 11843 11844 11845 11846 11847 /** @typedef {import('../parser').WPBlock} WPBlock */ 11848 /** @typedef {import('../registration').WPBlockType} WPBlockType */ 11849 /** @typedef {import('./logger').LoggerItem} LoggerItem */ 11850 11851 const identity = x => x; 11852 11853 /** 11854 * Globally matches any consecutive whitespace 11855 * 11856 * @type {RegExp} 11857 */ 11858 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 11859 11860 /** 11861 * Matches a string containing only whitespace 11862 * 11863 * @type {RegExp} 11864 */ 11865 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 11866 11867 /** 11868 * Matches a CSS URL type value 11869 * 11870 * @type {RegExp} 11871 */ 11872 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 11873 11874 /** 11875 * Boolean attributes are attributes whose presence as being assigned is 11876 * meaningful, even if only empty. 11877 * 11878 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 11879 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 11880 * 11881 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 11882 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 11883 * .reduce( ( result, tr ) => Object.assign( result, { 11884 * [ tr.firstChild.textContent.trim() ]: true 11885 * } ), {} ) ).sort(); 11886 * 11887 * @type {Array} 11888 */ 11889 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']; 11890 11891 /** 11892 * Enumerated attributes are attributes which must be of a specific value form. 11893 * Like boolean attributes, these are meaningful if specified, even if not of a 11894 * valid enumerated value. 11895 * 11896 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 11897 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 11898 * 11899 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 11900 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 11901 * .reduce( ( result, tr ) => Object.assign( result, { 11902 * [ tr.firstChild.textContent.trim() ]: true 11903 * } ), {} ) ).sort(); 11904 * 11905 * @type {Array} 11906 */ 11907 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']; 11908 11909 /** 11910 * Meaningful attributes are those who cannot be safely ignored when omitted in 11911 * one HTML markup string and not another. 11912 * 11913 * @type {Array} 11914 */ 11915 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 11916 11917 /** 11918 * Array of functions which receive a text string on which to apply normalizing 11919 * behavior for consideration in text token equivalence, carefully ordered from 11920 * least-to-most expensive operations. 11921 * 11922 * @type {Array} 11923 */ 11924 const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace]; 11925 11926 /** 11927 * Regular expression matching a named character reference. In lieu of bundling 11928 * a full set of references, the pattern covers the minimal necessary to test 11929 * positively against the full set. 11930 * 11931 * "The ampersand must be followed by one of the names given in the named 11932 * character references section, using the same case." 11933 * 11934 * Tested aginst "12.5 Named character references": 11935 * 11936 * ``` 11937 * const references = Array.from( document.querySelectorAll( 11938 * '#named-character-references-table tr[id^=entity-] td:first-child' 11939 * ) ).map( ( code ) => code.textContent ) 11940 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 11941 * ``` 11942 * 11943 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 11944 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 11945 * 11946 * @type {RegExp} 11947 */ 11948 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 11949 11950 /** 11951 * Regular expression matching a decimal character reference. 11952 * 11953 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 11954 * followed by one or more ASCII digits, representing a base-ten integer" 11955 * 11956 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 11957 * 11958 * @type {RegExp} 11959 */ 11960 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 11961 11962 /** 11963 * Regular expression matching a hexadecimal character reference. 11964 * 11965 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 11966 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 11967 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 11968 * one or more ASCII hex digits, representing a hexadecimal integer" 11969 * 11970 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 11971 * 11972 * @type {RegExp} 11973 */ 11974 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 11975 11976 /** 11977 * Returns true if the given string is a valid character reference segment, or 11978 * false otherwise. The text should be stripped of `&` and `;` demarcations. 11979 * 11980 * @param {string} text Text to test. 11981 * 11982 * @return {boolean} Whether text is valid character reference. 11983 */ 11984 function isValidCharacterReference(text) { 11985 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 11986 } 11987 11988 /** 11989 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the 11990 * implementation of `decodeEntities` from `html-entities`, in order to avoid 11991 * bundling a massive named character reference. 11992 * 11993 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 11994 */ 11995 class DecodeEntityParser { 11996 /** 11997 * Returns a substitute string for an entity string sequence between `&` 11998 * and `;`, or undefined if no substitution should occur. 11999 * 12000 * @param {string} entity Entity fragment discovered in HTML. 12001 * 12002 * @return {string | undefined} Entity substitute value. 12003 */ 12004 parse(entity) { 12005 if (isValidCharacterReference(entity)) { 12006 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';'); 12007 } 12008 } 12009 } 12010 12011 /** 12012 * Given a specified string, returns an array of strings split by consecutive 12013 * whitespace, ignoring leading or trailing whitespace. 12014 * 12015 * @param {string} text Original text. 12016 * 12017 * @return {string[]} Text pieces split on whitespace. 12018 */ 12019 function getTextPiecesSplitOnWhitespace(text) { 12020 return text.trim().split(REGEXP_WHITESPACE); 12021 } 12022 12023 /** 12024 * Given a specified string, returns a new trimmed string where all consecutive 12025 * whitespace is collapsed to a single space. 12026 * 12027 * @param {string} text Original text. 12028 * 12029 * @return {string} Trimmed text with consecutive whitespace collapsed. 12030 */ 12031 function getTextWithCollapsedWhitespace(text) { 12032 // This is an overly simplified whitespace comparison. The specification is 12033 // more prescriptive of whitespace behavior in inline and block contexts. 12034 // 12035 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33 12036 return getTextPiecesSplitOnWhitespace(text).join(' '); 12037 } 12038 12039 /** 12040 * Returns attribute pairs of the given StartTag token, including only pairs 12041 * where the value is non-empty or the attribute is a boolean attribute, an 12042 * enumerated attribute, or a custom data- attribute. 12043 * 12044 * @see MEANINGFUL_ATTRIBUTES 12045 * 12046 * @param {Object} token StartTag token. 12047 * 12048 * @return {Array[]} Attribute pairs. 12049 */ 12050 function getMeaningfulAttributePairs(token) { 12051 return token.attributes.filter(pair => { 12052 const [key, value] = pair; 12053 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key); 12054 }); 12055 } 12056 12057 /** 12058 * Returns true if two text tokens (with `chars` property) are equivalent, or 12059 * false otherwise. 12060 * 12061 * @param {Object} actual Actual token. 12062 * @param {Object} expected Expected token. 12063 * @param {Object} logger Validation logger object. 12064 * 12065 * @return {boolean} Whether two text tokens are equivalent. 12066 */ 12067 function isEquivalentTextTokens(actual, expected, logger = createLogger()) { 12068 // This function is intentionally written as syntactically "ugly" as a hot 12069 // path optimization. Text is progressively normalized in order from least- 12070 // to-most operationally expensive, until the earliest point at which text 12071 // can be confidently inferred as being equal. 12072 let actualChars = actual.chars; 12073 let expectedChars = expected.chars; 12074 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 12075 const normalize = TEXT_NORMALIZATIONS[i]; 12076 actualChars = normalize(actualChars); 12077 expectedChars = normalize(expectedChars); 12078 if (actualChars === expectedChars) { 12079 return true; 12080 } 12081 } 12082 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 12083 return false; 12084 } 12085 12086 /** 12087 * Given a CSS length value, returns a normalized CSS length value for strict equality 12088 * comparison. 12089 * 12090 * @param {string} value CSS length value. 12091 * 12092 * @return {string} Normalized CSS length value. 12093 */ 12094 function getNormalizedLength(value) { 12095 if (0 === parseFloat(value)) { 12096 return '0'; 12097 } 12098 // Normalize strings with floats to always include a leading zero. 12099 if (value.indexOf('.') === 0) { 12100 return '0' + value; 12101 } 12102 return value; 12103 } 12104 12105 /** 12106 * Given a style value, returns a normalized style value for strict equality 12107 * comparison. 12108 * 12109 * @param {string} value Style value. 12110 * 12111 * @return {string} Normalized style value. 12112 */ 12113 function getNormalizedStyleValue(value) { 12114 const textPieces = getTextPiecesSplitOnWhitespace(value); 12115 const normalizedPieces = textPieces.map(getNormalizedLength); 12116 const result = normalizedPieces.join(' '); 12117 return result 12118 // Normalize URL type to omit whitespace or quotes. 12119 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 12120 } 12121 12122 /** 12123 * Given a style attribute string, returns an object of style properties. 12124 * 12125 * @param {string} text Style attribute. 12126 * 12127 * @return {Object} Style properties. 12128 */ 12129 function getStyleProperties(text) { 12130 const pairs = text 12131 // Trim ending semicolon (avoid including in split) 12132 .replace(/;?\s*$/, '') 12133 // Split on property assignment. 12134 .split(';') 12135 // For each property assignment... 12136 .map(style => { 12137 // ...split further into key-value pairs. 12138 const [key, ...valueParts] = style.split(':'); 12139 const value = valueParts.join(':'); 12140 return [key.trim(), getNormalizedStyleValue(value.trim())]; 12141 }); 12142 return Object.fromEntries(pairs); 12143 } 12144 12145 /** 12146 * Attribute-specific equality handlers 12147 * 12148 * @type {Object} 12149 */ 12150 const isEqualAttributesOfName = { 12151 class: (actual, expected) => { 12152 // Class matches if members are the same, even if out of order or 12153 // superfluous whitespace between. 12154 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace); 12155 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c)); 12156 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c)); 12157 return actualDiff.length === 0 && expectedDiff.length === 0; 12158 }, 12159 style: (actual, expected) => { 12160 return es6_default()(...[actual, expected].map(getStyleProperties)); 12161 }, 12162 // For each boolean attribute, mere presence of attribute in both is enough 12163 // to assume equivalence. 12164 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true])) 12165 }; 12166 12167 /** 12168 * Given two sets of attribute tuples, returns true if the attribute sets are 12169 * equivalent. 12170 * 12171 * @param {Array[]} actual Actual attributes tuples. 12172 * @param {Array[]} expected Expected attributes tuples. 12173 * @param {Object} logger Validation logger object. 12174 * 12175 * @return {boolean} Whether attributes are equivalent. 12176 */ 12177 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) { 12178 // Attributes is tokenized as tuples. Their lengths should match. This also 12179 // avoids us needing to check both attributes sets, since if A has any keys 12180 // which do not exist in B, we know the sets to be different. 12181 if (actual.length !== expected.length) { 12182 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 12183 return false; 12184 } 12185 12186 // Attributes are not guaranteed to occur in the same order. For validating 12187 // actual attributes, first convert the set of expected attribute values to 12188 // an object, for lookup by key. 12189 const expectedAttributes = {}; 12190 for (let i = 0; i < expected.length; i++) { 12191 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 12192 } 12193 for (let i = 0; i < actual.length; i++) { 12194 const [name, actualValue] = actual[i]; 12195 const nameLower = name.toLowerCase(); 12196 12197 // As noted above, if missing member in B, assume different. 12198 if (!expectedAttributes.hasOwnProperty(nameLower)) { 12199 logger.warning('Encountered unexpected attribute `%s`.', name); 12200 return false; 12201 } 12202 const expectedValue = expectedAttributes[nameLower]; 12203 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 12204 if (isEqualAttributes) { 12205 // Defer custom attribute equality handling. 12206 if (!isEqualAttributes(actualValue, expectedValue)) { 12207 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12208 return false; 12209 } 12210 } else if (actualValue !== expectedValue) { 12211 // Otherwise strict inequality should bail. 12212 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12213 return false; 12214 } 12215 } 12216 return true; 12217 } 12218 12219 /** 12220 * Token-type-specific equality handlers 12221 * 12222 * @type {Object} 12223 */ 12224 const isEqualTokensOfType = { 12225 StartTag: (actual, expected, logger = createLogger()) => { 12226 if (actual.tagName !== expected.tagName && 12227 // Optimization: Use short-circuit evaluation to defer case- 12228 // insensitive check on the assumption that the majority case will 12229 // have exactly equal tag names. 12230 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 12231 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 12232 return false; 12233 } 12234 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 12235 }, 12236 Chars: isEquivalentTextTokens, 12237 Comment: isEquivalentTextTokens 12238 }; 12239 12240 /** 12241 * Given an array of tokens, returns the first token which is not purely 12242 * whitespace. 12243 * 12244 * Mutates the tokens array. 12245 * 12246 * @param {Object[]} tokens Set of tokens to search. 12247 * 12248 * @return {Object | undefined} Next non-whitespace token. 12249 */ 12250 function getNextNonWhitespaceToken(tokens) { 12251 let token; 12252 while (token = tokens.shift()) { 12253 if (token.type !== 'Chars') { 12254 return token; 12255 } 12256 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 12257 return token; 12258 } 12259 } 12260 } 12261 12262 /** 12263 * Tokenize an HTML string, gracefully handling any errors thrown during 12264 * underlying tokenization. 12265 * 12266 * @param {string} html HTML string to tokenize. 12267 * @param {Object} logger Validation logger object. 12268 * 12269 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 12270 */ 12271 function getHTMLTokens(html, logger = createLogger()) { 12272 try { 12273 return new Tokenizer(new DecodeEntityParser()).tokenize(html); 12274 } catch (e) { 12275 logger.warning('Malformed HTML detected: %s', html); 12276 } 12277 return null; 12278 } 12279 12280 /** 12281 * Returns true if the next HTML token closes the current token. 12282 * 12283 * @param {Object} currentToken Current token to compare with. 12284 * @param {Object|undefined} nextToken Next token to compare against. 12285 * 12286 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 12287 */ 12288 function isClosedByToken(currentToken, nextToken) { 12289 // Ensure this is a self closed token. 12290 if (!currentToken.selfClosing) { 12291 return false; 12292 } 12293 12294 // Check token names and determine if nextToken is the closing tag for currentToken. 12295 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 12296 return true; 12297 } 12298 return false; 12299 } 12300 12301 /** 12302 * Returns true if the given HTML strings are effectively equivalent, or 12303 * false otherwise. Invalid HTML is not considered equivalent, even if the 12304 * strings directly match. 12305 * 12306 * @param {string} actual Actual HTML string. 12307 * @param {string} expected Expected HTML string. 12308 * @param {Object} logger Validation logger object. 12309 * 12310 * @return {boolean} Whether HTML strings are equivalent. 12311 */ 12312 function isEquivalentHTML(actual, expected, logger = createLogger()) { 12313 // Short-circuit if markup is identical. 12314 if (actual === expected) { 12315 return true; 12316 } 12317 12318 // Tokenize input content and reserialized save content. 12319 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); 12320 12321 // If either is malformed then stop comparing - the strings are not equivalent. 12322 if (!actualTokens || !expectedTokens) { 12323 return false; 12324 } 12325 let actualToken, expectedToken; 12326 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 12327 expectedToken = getNextNonWhitespaceToken(expectedTokens); 12328 12329 // Inequal if exhausted all expected tokens. 12330 if (!expectedToken) { 12331 logger.warning('Expected end of content, instead saw %o.', actualToken); 12332 return false; 12333 } 12334 12335 // Inequal if next non-whitespace token of each set are not same type. 12336 if (actualToken.type !== expectedToken.type) { 12337 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 12338 return false; 12339 } 12340 12341 // Defer custom token type equality handling, otherwise continue and 12342 // assume as equal. 12343 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 12344 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 12345 return false; 12346 } 12347 12348 // Peek at the next tokens (actual and expected) to see if they close 12349 // a self-closing tag. 12350 if (isClosedByToken(actualToken, expectedTokens[0])) { 12351 // Consume the next expected token that closes the current actual 12352 // self-closing token. 12353 getNextNonWhitespaceToken(expectedTokens); 12354 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 12355 // Consume the next actual token that closes the current expected 12356 // self-closing token. 12357 getNextNonWhitespaceToken(actualTokens); 12358 } 12359 } 12360 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 12361 // If any non-whitespace tokens remain in expected token set, this 12362 // indicates inequality. 12363 logger.warning('Expected %o, instead saw end of content.', expectedToken); 12364 return false; 12365 } 12366 return true; 12367 } 12368 12369 /** 12370 * Returns an object with `isValid` property set to `true` if the parsed block 12371 * is valid given the input content. A block is considered valid if, when serialized 12372 * with assumed attributes, the content matches the original value. If block is 12373 * invalid, this function returns all validations issues as well. 12374 * 12375 * @param {string|Object} blockTypeOrName Block type. 12376 * @param {Object} attributes Parsed block attributes. 12377 * @param {string} originalBlockContent Original block content. 12378 * @param {Object} logger Validation logger object. 12379 * 12380 * @return {Object} Whether block is valid and contains validation messages. 12381 */ 12382 12383 /** 12384 * Returns an object with `isValid` property set to `true` if the parsed block 12385 * is valid given the input content. A block is considered valid if, when serialized 12386 * with assumed attributes, the content matches the original value. If block is 12387 * invalid, this function returns all validations issues as well. 12388 * 12389 * @param {WPBlock} block block object. 12390 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. 12391 * 12392 * @return {[boolean,Array<LoggerItem>]} validation results. 12393 */ 12394 function validateBlock(block, blockTypeOrName = block.name) { 12395 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); 12396 12397 // Shortcut to avoid costly validation. 12398 if (isFallbackBlock) { 12399 return [true, []]; 12400 } 12401 const logger = createQueuedLogger(); 12402 const blockType = normalizeBlockType(blockTypeOrName); 12403 let generatedBlockContent; 12404 try { 12405 generatedBlockContent = getSaveContent(blockType, block.attributes); 12406 } catch (error) { 12407 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 12408 return [false, logger.getItems()]; 12409 } 12410 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger); 12411 if (!isValid) { 12412 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); 12413 } 12414 return [isValid, logger.getItems()]; 12415 } 12416 12417 /** 12418 * Returns true if the parsed block is valid given the input content. A block 12419 * is considered valid if, when serialized with assumed attributes, the content 12420 * matches the original value. 12421 * 12422 * Logs to console in development environments when invalid. 12423 * 12424 * @deprecated Use validateBlock instead to avoid data loss. 12425 * 12426 * @param {string|Object} blockTypeOrName Block type. 12427 * @param {Object} attributes Parsed block attributes. 12428 * @param {string} originalBlockContent Original block content. 12429 * 12430 * @return {boolean} Whether block is valid. 12431 */ 12432 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 12433 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', { 12434 since: '12.6', 12435 plugin: 'Gutenberg', 12436 alternative: 'validateBlock' 12437 }); 12438 const blockType = normalizeBlockType(blockTypeOrName); 12439 const block = { 12440 name: blockType.name, 12441 attributes, 12442 innerBlocks: [], 12443 originalContent: originalBlockContent 12444 }; 12445 const [isValid] = validateBlock(block, blockType); 12446 return isValid; 12447 } 12448 12449 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/convert-legacy-block.js 12450 /** 12451 * Convert legacy blocks to their canonical form. This function is used 12452 * both in the parser level for previous content and to convert such blocks 12453 * used in Custom Post Types templates. 12454 * 12455 * @param {string} name The block's name 12456 * @param {Object} attributes The block's attributes 12457 * 12458 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found 12459 */ 12460 function convertLegacyBlockNameAndAttributes(name, attributes) { 12461 const newAttributes = { 12462 ...attributes 12463 }; 12464 // Convert 'core/cover-image' block in existing content to 'core/cover'. 12465 if ('core/cover-image' === name) { 12466 name = 'core/cover'; 12467 } 12468 12469 // Convert 'core/text' blocks in existing content to 'core/paragraph'. 12470 if ('core/text' === name || 'core/cover-text' === name) { 12471 name = 'core/paragraph'; 12472 } 12473 12474 // Convert derivative blocks such as 'core/social-link-wordpress' to the 12475 // canonical form 'core/social-link'. 12476 if (name && name.indexOf('core/social-link-') === 0) { 12477 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 12478 newAttributes.service = name.substring(17); 12479 name = 'core/social-link'; 12480 } 12481 12482 // Convert derivative blocks such as 'core-embed/instagram' to the 12483 // canonical form 'core/embed'. 12484 if (name && name.indexOf('core-embed/') === 0) { 12485 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 12486 const providerSlug = name.substring(11); 12487 const deprecated = { 12488 speaker: 'speaker-deck', 12489 polldaddy: 'crowdsignal' 12490 }; 12491 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; 12492 // This is needed as the `responsive` attribute was passed 12493 // in a different way before the refactoring to block variations. 12494 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 12495 newAttributes.responsive = true; 12496 } 12497 name = 'core/embed'; 12498 } 12499 12500 // Convert Post Comment blocks in existing content to Comment blocks. 12501 // TODO: Remove these checks when WordPress 6.0 is released. 12502 if (name === 'core/post-comment-author') { 12503 name = 'core/comment-author-name'; 12504 } 12505 if (name === 'core/post-comment-content') { 12506 name = 'core/comment-content'; 12507 } 12508 if (name === 'core/post-comment-date') { 12509 name = 'core/comment-date'; 12510 } 12511 if (name === 'core/comments-query-loop') { 12512 name = 'core/comments'; 12513 const { 12514 className = '' 12515 } = newAttributes; 12516 if (!className.includes('wp-block-comments-query-loop')) { 12517 newAttributes.className = ['wp-block-comments-query-loop', className].join(' '); 12518 } 12519 // Note that we also had to add a deprecation to the block in order 12520 // for the ID change to work. 12521 } 12522 if (name === 'core/post-comments') { 12523 name = 'core/comments'; 12524 newAttributes.legacy = true; 12525 } 12526 12527 // The following code is only relevant for the Gutenberg plugin. 12528 // It's a stand-alone if statement for dead-code elimination. 12529 if (false) {} 12530 return [name, newAttributes]; 12531 } 12532 12533 ;// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js 12534 /** 12535 * Given object and string of dot-delimited path segments, returns value at 12536 * path or undefined if path cannot be resolved. 12537 * 12538 * @param {Object} object Lookup object 12539 * @param {string} path Path to resolve 12540 * @return {?*} Resolved value 12541 */ 12542 function getPath(object, path) { 12543 var segments = path.split('.'); 12544 var segment; 12545 12546 while (segment = segments.shift()) { 12547 if (!(segment in object)) { 12548 return; 12549 } 12550 12551 object = object[segment]; 12552 } 12553 12554 return object; 12555 } 12556 ;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js 12557 /** 12558 * Internal dependencies 12559 */ 12560 12561 /** 12562 * Function returning a DOM document created by `createHTMLDocument`. The same 12563 * document is returned between invocations. 12564 * 12565 * @return {Document} DOM document. 12566 */ 12567 12568 var getDocument = function () { 12569 var doc; 12570 return function () { 12571 if (!doc) { 12572 doc = document.implementation.createHTMLDocument(''); 12573 } 12574 12575 return doc; 12576 }; 12577 }(); 12578 /** 12579 * Given a markup string or DOM element, creates an object aligning with the 12580 * shape of the matchers object, or the value returned by the matcher. 12581 * 12582 * @param {(string|Element)} source Source content 12583 * @param {(Object|Function)} matchers Matcher function or object of matchers 12584 * @return {(Object|*)} Matched value(s), shaped by object 12585 */ 12586 12587 12588 function parse(source, matchers) { 12589 if (!matchers) { 12590 return; 12591 } // Coerce to element 12592 12593 12594 if ('string' === typeof source) { 12595 var doc = getDocument(); 12596 doc.body.innerHTML = source; 12597 source = doc.body; 12598 } // Return singular value 12599 12600 12601 if ('function' === typeof matchers) { 12602 return matchers(source); 12603 } // Bail if we can't handle matchers 12604 12605 12606 if (Object !== matchers.constructor) { 12607 return; 12608 } // Shape result by matcher object 12609 12610 12611 return Object.keys(matchers).reduce(function (memo, key) { 12612 memo[key] = parse(source, matchers[key]); 12613 return memo; 12614 }, {}); 12615 } 12616 /** 12617 * Generates a function which matches node of type selector, returning an 12618 * attribute by property if the attribute exists. If no selector is passed, 12619 * returns property of the query element. 12620 * 12621 * @param {?string} selector Optional selector 12622 * @param {string} name Property name 12623 * @return {*} Property value 12624 */ 12625 12626 function prop(selector, name) { 12627 if (1 === arguments.length) { 12628 name = selector; 12629 selector = undefined; 12630 } 12631 12632 return function (node) { 12633 var match = node; 12634 12635 if (selector) { 12636 match = node.querySelector(selector); 12637 } 12638 12639 if (match) { 12640 return getPath(match, name); 12641 } 12642 }; 12643 } 12644 /** 12645 * Generates a function which matches node of type selector, returning an 12646 * attribute by name if the attribute exists. If no selector is passed, 12647 * returns attribute of the query element. 12648 * 12649 * @param {?string} selector Optional selector 12650 * @param {string} name Attribute name 12651 * @return {?string} Attribute value 12652 */ 12653 12654 function attr(selector, name) { 12655 if (1 === arguments.length) { 12656 name = selector; 12657 selector = undefined; 12658 } 12659 12660 return function (node) { 12661 var attributes = prop(selector, 'attributes')(node); 12662 12663 if (attributes && attributes.hasOwnProperty(name)) { 12664 return attributes[name].value; 12665 } 12666 }; 12667 } 12668 /** 12669 * Convenience for `prop( selector, 'innerHTML' )`. 12670 * 12671 * @see prop() 12672 * 12673 * @param {?string} selector Optional selector 12674 * @return {string} Inner HTML 12675 */ 12676 12677 function html(selector) { 12678 return prop(selector, 'innerHTML'); 12679 } 12680 /** 12681 * Convenience for `prop( selector, 'textContent' )`. 12682 * 12683 * @see prop() 12684 * 12685 * @param {?string} selector Optional selector 12686 * @return {string} Text content 12687 */ 12688 12689 function es_text(selector) { 12690 return prop(selector, 'textContent'); 12691 } 12692 /** 12693 * Creates a new matching context by first finding elements matching selector 12694 * using querySelectorAll before then running another `parse` on `matchers` 12695 * scoped to the matched elements. 12696 * 12697 * @see parse() 12698 * 12699 * @param {string} selector Selector to match 12700 * @param {(Object|Function)} matchers Matcher function or object of matchers 12701 * @return {Array.<*,Object>} Array of matched value(s) 12702 */ 12703 12704 function query(selector, matchers) { 12705 return function (node) { 12706 var matches = node.querySelectorAll(selector); 12707 return [].map.call(matches, function (match) { 12708 return parse(match, matchers); 12709 }); 12710 }; 12711 } 12712 ;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js 12713 /** 12714 * Memize options object. 12715 * 12716 * @typedef MemizeOptions 12717 * 12718 * @property {number} [maxSize] Maximum size of the cache. 12719 */ 12720 12721 /** 12722 * Internal cache entry. 12723 * 12724 * @typedef MemizeCacheNode 12725 * 12726 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 12727 * @property {?MemizeCacheNode|undefined} [next] Next node. 12728 * @property {Array<*>} args Function arguments for cache 12729 * entry. 12730 * @property {*} val Function result. 12731 */ 12732 12733 /** 12734 * Properties of the enhanced function for controlling cache. 12735 * 12736 * @typedef MemizeMemoizedFunction 12737 * 12738 * @property {()=>void} clear Clear the cache. 12739 */ 12740 12741 /** 12742 * Accepts a function to be memoized, and returns a new memoized function, with 12743 * optional options. 12744 * 12745 * @template {(...args: any[]) => any} F 12746 * 12747 * @param {F} fn Function to memoize. 12748 * @param {MemizeOptions} [options] Options object. 12749 * 12750 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 12751 */ 12752 function memize(fn, options) { 12753 var size = 0; 12754 12755 /** @type {?MemizeCacheNode|undefined} */ 12756 var head; 12757 12758 /** @type {?MemizeCacheNode|undefined} */ 12759 var tail; 12760 12761 options = options || {}; 12762 12763 function memoized(/* ...args */) { 12764 var node = head, 12765 len = arguments.length, 12766 args, 12767 i; 12768 12769 searchCache: while (node) { 12770 // Perform a shallow equality test to confirm that whether the node 12771 // under test is a candidate for the arguments passed. Two arrays 12772 // are shallowly equal if their length matches and each entry is 12773 // strictly equal between the two sets. Avoid abstracting to a 12774 // function which could incur an arguments leaking deoptimization. 12775 12776 // Check whether node arguments match arguments length 12777 if (node.args.length !== arguments.length) { 12778 node = node.next; 12779 continue; 12780 } 12781 12782 // Check whether node arguments match arguments values 12783 for (i = 0; i < len; i++) { 12784 if (node.args[i] !== arguments[i]) { 12785 node = node.next; 12786 continue searchCache; 12787 } 12788 } 12789 12790 // At this point we can assume we've found a match 12791 12792 // Surface matched node to head if not already 12793 if (node !== head) { 12794 // As tail, shift to previous. Must only shift if not also 12795 // head, since if both head and tail, there is no previous. 12796 if (node === tail) { 12797 tail = node.prev; 12798 } 12799 12800 // Adjust siblings to point to each other. If node was tail, 12801 // this also handles new tail's empty `next` assignment. 12802 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 12803 if (node.next) { 12804 node.next.prev = node.prev; 12805 } 12806 12807 node.next = head; 12808 node.prev = null; 12809 /** @type {MemizeCacheNode} */ (head).prev = node; 12810 head = node; 12811 } 12812 12813 // Return immediately 12814 return node.val; 12815 } 12816 12817 // No cached value found. Continue to insertion phase: 12818 12819 // Create a copy of arguments (avoid leaking deoptimization) 12820 args = new Array(len); 12821 for (i = 0; i < len; i++) { 12822 args[i] = arguments[i]; 12823 } 12824 12825 node = { 12826 args: args, 12827 12828 // Generate the result from original function 12829 val: fn.apply(null, args), 12830 }; 12831 12832 // Don't need to check whether node is already head, since it would 12833 // have been returned above already if it was 12834 12835 // Shift existing head down list 12836 if (head) { 12837 head.prev = node; 12838 node.next = head; 12839 } else { 12840 // If no head, follows that there's no tail (at initial or reset) 12841 tail = node; 12842 } 12843 12844 // Trim tail if we're reached max size and are pending cache insertion 12845 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 12846 tail = /** @type {MemizeCacheNode} */ (tail).prev; 12847 /** @type {MemizeCacheNode} */ (tail).next = null; 12848 } else { 12849 size++; 12850 } 12851 12852 head = node; 12853 12854 return node.val; 12855 } 12856 12857 memoized.clear = function () { 12858 head = null; 12859 tail = null; 12860 size = 0; 12861 }; 12862 12863 // Ignore reason: There's not a clear solution to create an intersection of 12864 // the function with additional properties, where the goal is to retain the 12865 // function signature of the incoming argument and add control properties 12866 // on the return value. 12867 12868 // @ts-ignore 12869 return memoized; 12870 } 12871 12872 12873 12874 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/matchers.js 12875 /** 12876 * External dependencies 12877 */ 12878 12879 12880 /** 12881 * WordPress dependencies 12882 */ 12883 12884 12885 /** 12886 * Internal dependencies 12887 */ 12888 12889 12890 function matchers_html(selector, multilineTag) { 12891 return domNode => { 12892 let match = domNode; 12893 if (selector) { 12894 match = domNode.querySelector(selector); 12895 } 12896 if (!match) { 12897 return ''; 12898 } 12899 if (multilineTag) { 12900 let value = ''; 12901 const length = match.children.length; 12902 for (let index = 0; index < length; index++) { 12903 const child = match.children[index]; 12904 if (child.nodeName.toLowerCase() !== multilineTag) { 12905 continue; 12906 } 12907 value += child.outerHTML; 12908 } 12909 return value; 12910 } 12911 return match.innerHTML; 12912 }; 12913 } 12914 const richText = (selector, preserveWhiteSpace) => el => { 12915 const target = selector ? el.querySelector(selector) : el; 12916 return target ? external_wp_richText_namespaceObject.RichTextData.fromHTMLElement(target, { 12917 preserveWhiteSpace 12918 }) : external_wp_richText_namespaceObject.RichTextData.empty(); 12919 }; 12920 12921 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/node.js 12922 /** 12923 * WordPress dependencies 12924 */ 12925 12926 12927 /** 12928 * Internal dependencies 12929 */ 12930 12931 12932 /** 12933 * A representation of a single node within a block's rich text value. If 12934 * representing a text node, the value is simply a string of the node value. 12935 * As representing an element node, it is an object of: 12936 * 12937 * 1. `type` (string): Tag name. 12938 * 2. `props` (object): Attributes and children array of WPBlockNode. 12939 * 12940 * @typedef {string|Object} WPBlockNode 12941 */ 12942 12943 /** 12944 * Given a single node and a node type (e.g. `'br'`), returns true if the node 12945 * corresponds to that type, false otherwise. 12946 * 12947 * @param {WPBlockNode} node Block node to test 12948 * @param {string} type Node to type to test against. 12949 * 12950 * @return {boolean} Whether node is of intended type. 12951 */ 12952 function isNodeOfType(node, type) { 12953 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', { 12954 since: '6.1', 12955 version: '6.3', 12956 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12957 }); 12958 return node && node.type === type; 12959 } 12960 12961 /** 12962 * Given an object implementing the NamedNodeMap interface, returns a plain 12963 * object equivalent value of name, value key-value pairs. 12964 * 12965 * @see https://dom.spec.whatwg.org/#interface-namednodemap 12966 * 12967 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 12968 * 12969 * @return {Object} Object equivalent value of NamedNodeMap. 12970 */ 12971 function getNamedNodeMapAsObject(nodeMap) { 12972 const result = {}; 12973 for (let i = 0; i < nodeMap.length; i++) { 12974 const { 12975 name, 12976 value 12977 } = nodeMap[i]; 12978 result[name] = value; 12979 } 12980 return result; 12981 } 12982 12983 /** 12984 * Given a DOM Element or Text node, returns an equivalent block node. Throws 12985 * if passed any node type other than element or text. 12986 * 12987 * @throws {TypeError} If non-element/text node is passed. 12988 * 12989 * @param {Node} domNode DOM node to convert. 12990 * 12991 * @return {WPBlockNode} Block node equivalent to DOM node. 12992 */ 12993 function fromDOM(domNode) { 12994 external_wp_deprecated_default()('wp.blocks.node.fromDOM', { 12995 since: '6.1', 12996 version: '6.3', 12997 alternative: 'wp.richText.create', 12998 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12999 }); 13000 if (domNode.nodeType === domNode.TEXT_NODE) { 13001 return domNode.nodeValue; 13002 } 13003 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 13004 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 13005 } 13006 return { 13007 type: domNode.nodeName.toLowerCase(), 13008 props: { 13009 ...getNamedNodeMapAsObject(domNode.attributes), 13010 children: children_fromDOM(domNode.childNodes) 13011 } 13012 }; 13013 } 13014 13015 /** 13016 * Given a block node, returns its HTML string representation. 13017 * 13018 * @param {WPBlockNode} node Block node to convert to string. 13019 * 13020 * @return {string} String HTML representation of block node. 13021 */ 13022 function toHTML(node) { 13023 external_wp_deprecated_default()('wp.blocks.node.toHTML', { 13024 since: '6.1', 13025 version: '6.3', 13026 alternative: 'wp.richText.toHTMLString', 13027 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13028 }); 13029 return children_toHTML([node]); 13030 } 13031 13032 /** 13033 * Given a selector, returns an hpq matcher generating a WPBlockNode value 13034 * matching the selector result. 13035 * 13036 * @param {string} selector DOM selector. 13037 * 13038 * @return {Function} hpq matcher. 13039 */ 13040 function node_matcher(selector) { 13041 external_wp_deprecated_default()('wp.blocks.node.matcher', { 13042 since: '6.1', 13043 version: '6.3', 13044 alternative: 'html source', 13045 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13046 }); 13047 return domNode => { 13048 let match = domNode; 13049 if (selector) { 13050 match = domNode.querySelector(selector); 13051 } 13052 try { 13053 return fromDOM(match); 13054 } catch (error) { 13055 return null; 13056 } 13057 }; 13058 } 13059 13060 /** 13061 * Object of utility functions used in managing block attribute values of 13062 * source `node`. 13063 * 13064 * @see https://github.com/WordPress/gutenberg/pull/10439 13065 * 13066 * @deprecated since 4.0. The `node` source should not be used, and can be 13067 * replaced by the `html` source. 13068 * 13069 * @private 13070 */ 13071 /* harmony default export */ const node = ({ 13072 isNodeOfType, 13073 fromDOM, 13074 toHTML, 13075 matcher: node_matcher 13076 }); 13077 13078 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/children.js 13079 /** 13080 * WordPress dependencies 13081 */ 13082 13083 13084 13085 /** 13086 * Internal dependencies 13087 */ 13088 13089 13090 /** 13091 * A representation of a block's rich text value. 13092 * 13093 * @typedef {WPBlockNode[]} WPBlockChildren 13094 */ 13095 13096 /** 13097 * Given block children, returns a serialize-capable WordPress element. 13098 * 13099 * @param {WPBlockChildren} children Block children object to convert. 13100 * 13101 * @return {Element} A serialize-capable element. 13102 */ 13103 function getSerializeCapableElement(children) { 13104 // The fact that block children are compatible with the element serializer is 13105 // merely an implementation detail that currently serves to be true, but 13106 // should not be mistaken as being a guarantee on the external API. The 13107 // public API only offers guarantees to work with strings (toHTML) and DOM 13108 // elements (fromDOM), and should provide utilities to manipulate the value 13109 // rather than expect consumers to inspect or construct its shape (concat). 13110 return children; 13111 } 13112 13113 /** 13114 * Given block children, returns an array of block nodes. 13115 * 13116 * @param {WPBlockChildren} children Block children object to convert. 13117 * 13118 * @return {Array<WPBlockNode>} An array of individual block nodes. 13119 */ 13120 function getChildrenArray(children) { 13121 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', { 13122 since: '6.1', 13123 version: '6.3', 13124 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13125 }); 13126 13127 // The fact that block children are compatible with the element serializer 13128 // is merely an implementation detail that currently serves to be true, but 13129 // should not be mistaken as being a guarantee on the external API. 13130 return children; 13131 } 13132 13133 /** 13134 * Given two or more block nodes, returns a new block node representing a 13135 * concatenation of its values. 13136 * 13137 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 13138 * 13139 * @return {WPBlockChildren} Concatenated block node. 13140 */ 13141 function concat(...blockNodes) { 13142 external_wp_deprecated_default()('wp.blocks.children.concat', { 13143 since: '6.1', 13144 version: '6.3', 13145 alternative: 'wp.richText.concat', 13146 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13147 }); 13148 const result = []; 13149 for (let i = 0; i < blockNodes.length; i++) { 13150 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]]; 13151 for (let j = 0; j < blockNode.length; j++) { 13152 const child = blockNode[j]; 13153 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 13154 if (canConcatToPreviousString) { 13155 result[result.length - 1] += child; 13156 } else { 13157 result.push(child); 13158 } 13159 } 13160 } 13161 return result; 13162 } 13163 13164 /** 13165 * Given an iterable set of DOM nodes, returns equivalent block children. 13166 * Ignores any non-element/text nodes included in set. 13167 * 13168 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 13169 * 13170 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 13171 */ 13172 function children_fromDOM(domNodes) { 13173 external_wp_deprecated_default()('wp.blocks.children.fromDOM', { 13174 since: '6.1', 13175 version: '6.3', 13176 alternative: 'wp.richText.create', 13177 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13178 }); 13179 const result = []; 13180 for (let i = 0; i < domNodes.length; i++) { 13181 try { 13182 result.push(fromDOM(domNodes[i])); 13183 } catch (error) { 13184 // Simply ignore if DOM node could not be converted. 13185 } 13186 } 13187 return result; 13188 } 13189 13190 /** 13191 * Given a block node, returns its HTML string representation. 13192 * 13193 * @param {WPBlockChildren} children Block node(s) to convert to string. 13194 * 13195 * @return {string} String HTML representation of block node. 13196 */ 13197 function children_toHTML(children) { 13198 external_wp_deprecated_default()('wp.blocks.children.toHTML', { 13199 since: '6.1', 13200 version: '6.3', 13201 alternative: 'wp.richText.toHTMLString', 13202 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13203 }); 13204 const element = getSerializeCapableElement(children); 13205 return (0,external_wp_element_namespaceObject.renderToString)(element); 13206 } 13207 13208 /** 13209 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 13210 * matching the selector result. 13211 * 13212 * @param {string} selector DOM selector. 13213 * 13214 * @return {Function} hpq matcher. 13215 */ 13216 function children_matcher(selector) { 13217 external_wp_deprecated_default()('wp.blocks.children.matcher', { 13218 since: '6.1', 13219 version: '6.3', 13220 alternative: 'html source', 13221 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13222 }); 13223 return domNode => { 13224 let match = domNode; 13225 if (selector) { 13226 match = domNode.querySelector(selector); 13227 } 13228 if (match) { 13229 return children_fromDOM(match.childNodes); 13230 } 13231 return []; 13232 }; 13233 } 13234 13235 /** 13236 * Object of utility functions used in managing block attribute values of 13237 * source `children`. 13238 * 13239 * @see https://github.com/WordPress/gutenberg/pull/10439 13240 * 13241 * @deprecated since 4.0. The `children` source should not be used, and can be 13242 * replaced by the `html` source. 13243 * 13244 * @private 13245 */ 13246 /* harmony default export */ const children = ({ 13247 concat, 13248 getChildrenArray, 13249 fromDOM: children_fromDOM, 13250 toHTML: children_toHTML, 13251 matcher: children_matcher 13252 }); 13253 13254 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/get-block-attributes.js 13255 /** 13256 * External dependencies 13257 */ 13258 13259 13260 13261 /** 13262 * WordPress dependencies 13263 */ 13264 13265 13266 13267 13268 /** 13269 * Internal dependencies 13270 */ 13271 13272 13273 13274 /** 13275 * Higher-order hpq matcher which enhances an attribute matcher to return true 13276 * or false depending on whether the original matcher returns undefined. This 13277 * is useful for boolean attributes (e.g. disabled) whose attribute values may 13278 * be technically falsey (empty string), though their mere presence should be 13279 * enough to infer as true. 13280 * 13281 * @param {Function} matcher Original hpq matcher. 13282 * 13283 * @return {Function} Enhanced hpq matcher. 13284 */ 13285 const toBooleanAttributeMatcher = matcher => (0,external_wp_compose_namespaceObject.pipe)([matcher, 13286 // Expected values from `attr( 'disabled' )`: 13287 // 13288 // <input> 13289 // - Value: `undefined` 13290 // - Transformed: `false` 13291 // 13292 // <input disabled> 13293 // - Value: `''` 13294 // - Transformed: `true` 13295 // 13296 // <input disabled="disabled"> 13297 // - Value: `'disabled'` 13298 // - Transformed: `true` 13299 value => value !== undefined]); 13300 13301 /** 13302 * Returns true if value is of the given JSON schema type, or false otherwise. 13303 * 13304 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13305 * 13306 * @param {*} value Value to test. 13307 * @param {string} type Type to test. 13308 * 13309 * @return {boolean} Whether value is of type. 13310 */ 13311 function isOfType(value, type) { 13312 switch (type) { 13313 case 'rich-text': 13314 return value instanceof external_wp_richText_namespaceObject.RichTextData; 13315 case 'string': 13316 return typeof value === 'string'; 13317 case 'boolean': 13318 return typeof value === 'boolean'; 13319 case 'object': 13320 return !!value && value.constructor === Object; 13321 case 'null': 13322 return value === null; 13323 case 'array': 13324 return Array.isArray(value); 13325 case 'integer': 13326 case 'number': 13327 return typeof value === 'number'; 13328 } 13329 return true; 13330 } 13331 13332 /** 13333 * Returns true if value is of an array of given JSON schema types, or false 13334 * otherwise. 13335 * 13336 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13337 * 13338 * @param {*} value Value to test. 13339 * @param {string[]} types Types to test. 13340 * 13341 * @return {boolean} Whether value is of types. 13342 */ 13343 function isOfTypes(value, types) { 13344 return types.some(type => isOfType(value, type)); 13345 } 13346 13347 /** 13348 * Given an attribute key, an attribute's schema, a block's raw content and the 13349 * commentAttributes returns the attribute value depending on its source 13350 * definition of the given attribute key. 13351 * 13352 * @param {string} attributeKey Attribute key. 13353 * @param {Object} attributeSchema Attribute's schema. 13354 * @param {Node} innerDOM Parsed DOM of block's inner HTML. 13355 * @param {Object} commentAttributes Block's comment attributes. 13356 * @param {string} innerHTML Raw HTML from block node's innerHTML property. 13357 * 13358 * @return {*} Attribute value. 13359 */ 13360 function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) { 13361 let value; 13362 switch (attributeSchema.source) { 13363 // An undefined source means that it's an attribute serialized to the 13364 // block's "comment". 13365 case undefined: 13366 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 13367 break; 13368 // raw source means that it's the original raw block content. 13369 case 'raw': 13370 value = innerHTML; 13371 break; 13372 case 'attribute': 13373 case 'property': 13374 case 'html': 13375 case 'text': 13376 case 'rich-text': 13377 case 'children': 13378 case 'node': 13379 case 'query': 13380 case 'tag': 13381 value = parseWithAttributeSchema(innerDOM, attributeSchema); 13382 break; 13383 } 13384 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) { 13385 // Reject the value if it is not valid. Reverting to the undefined 13386 // value ensures the default is respected, if applicable. 13387 value = undefined; 13388 } 13389 if (value === undefined) { 13390 value = getDefault(attributeSchema); 13391 } 13392 return value; 13393 } 13394 13395 /** 13396 * Returns true if value is valid per the given block attribute schema type 13397 * definition, or false otherwise. 13398 * 13399 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 13400 * 13401 * @param {*} value Value to test. 13402 * @param {?(Array<string>|string)} type Block attribute schema type. 13403 * 13404 * @return {boolean} Whether value is valid. 13405 */ 13406 function isValidByType(value, type) { 13407 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]); 13408 } 13409 13410 /** 13411 * Returns true if value is valid per the given block attribute schema enum 13412 * definition, or false otherwise. 13413 * 13414 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 13415 * 13416 * @param {*} value Value to test. 13417 * @param {?Array} enumSet Block attribute schema enum. 13418 * 13419 * @return {boolean} Whether value is valid. 13420 */ 13421 function isValidByEnum(value, enumSet) { 13422 return !Array.isArray(enumSet) || enumSet.includes(value); 13423 } 13424 13425 /** 13426 * Returns an hpq matcher given a source object. 13427 * 13428 * @param {Object} sourceConfig Attribute Source object. 13429 * 13430 * @return {Function} A hpq Matcher. 13431 */ 13432 const matcherFromSource = memize(sourceConfig => { 13433 switch (sourceConfig.source) { 13434 case 'attribute': 13435 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 13436 if (sourceConfig.type === 'boolean') { 13437 matcher = toBooleanAttributeMatcher(matcher); 13438 } 13439 return matcher; 13440 case 'html': 13441 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 13442 case 'text': 13443 return es_text(sourceConfig.selector); 13444 case 'rich-text': 13445 return richText(sourceConfig.selector, sourceConfig.__unstablePreserveWhiteSpace); 13446 case 'children': 13447 return children_matcher(sourceConfig.selector); 13448 case 'node': 13449 return node_matcher(sourceConfig.selector); 13450 case 'query': 13451 const subMatchers = Object.fromEntries(Object.entries(sourceConfig.query).map(([key, subSourceConfig]) => [key, matcherFromSource(subSourceConfig)])); 13452 return query(sourceConfig.selector, subMatchers); 13453 case 'tag': 13454 return (0,external_wp_compose_namespaceObject.pipe)([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]); 13455 default: 13456 // eslint-disable-next-line no-console 13457 console.error(`Unknown source type "$sourceConfig.source}"`); 13458 } 13459 }); 13460 13461 /** 13462 * Parse a HTML string into DOM tree. 13463 * 13464 * @param {string|Node} innerHTML HTML string or already parsed DOM node. 13465 * 13466 * @return {Node} Parsed DOM node. 13467 */ 13468 function parseHtml(innerHTML) { 13469 return parse(innerHTML, h => h); 13470 } 13471 13472 /** 13473 * Given a block's raw content and an attribute's schema returns the attribute's 13474 * value depending on its source. 13475 * 13476 * @param {string|Node} innerHTML Block's raw content. 13477 * @param {Object} attributeSchema Attribute's schema. 13478 * 13479 * @return {*} Attribute value. 13480 */ 13481 function parseWithAttributeSchema(innerHTML, attributeSchema) { 13482 return matcherFromSource(attributeSchema)(parseHtml(innerHTML)); 13483 } 13484 13485 /** 13486 * Returns the block attributes of a registered block node given its type. 13487 * 13488 * @param {string|Object} blockTypeOrName Block type or name. 13489 * @param {string|Node} innerHTML Raw block content. 13490 * @param {?Object} attributes Known block attributes (from delimiters). 13491 * 13492 * @return {Object} All block attributes. 13493 */ 13494 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) { 13495 var _blockType$attributes; 13496 const doc = parseHtml(innerHTML); 13497 const blockType = normalizeBlockType(blockTypeOrName); 13498 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)])); 13499 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 13500 } 13501 13502 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/fix-custom-classname.js 13503 /** 13504 * Internal dependencies 13505 */ 13506 13507 13508 13509 const CLASS_ATTR_SCHEMA = { 13510 type: 'string', 13511 source: 'attribute', 13512 selector: '[data-custom-class-name] > *', 13513 attribute: 'class' 13514 }; 13515 13516 /** 13517 * Given an HTML string, returns an array of class names assigned to the root 13518 * element in the markup. 13519 * 13520 * @param {string} innerHTML Markup string from which to extract classes. 13521 * 13522 * @return {string[]} Array of class names assigned to the root element. 13523 */ 13524 function getHTMLRootElementClasses(innerHTML) { 13525 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>$innerHTML}</div>`, CLASS_ATTR_SCHEMA); 13526 return parsed ? parsed.trim().split(/\s+/) : []; 13527 } 13528 13529 /** 13530 * Given a parsed set of block attributes, if the block supports custom class 13531 * names and an unknown class (per the block's serialization behavior) is 13532 * found, the unknown classes are treated as custom classes. This prevents the 13533 * block from being considered as invalid. 13534 * 13535 * @param {Object} blockAttributes Original block attributes. 13536 * @param {Object} blockType Block type settings. 13537 * @param {string} innerHTML Original block markup. 13538 * 13539 * @return {Object} Filtered block attributes. 13540 */ 13541 function fixCustomClassname(blockAttributes, blockType, innerHTML) { 13542 if (hasBlockSupport(blockType, 'customClassName', true)) { 13543 // To determine difference, serialize block given the known set of 13544 // attributes, with the exception of `className`. This will determine 13545 // the default set of classes. From there, any difference in innerHTML 13546 // can be considered as custom classes. 13547 const { 13548 className: omittedClassName, 13549 ...attributesSansClassName 13550 } = blockAttributes; 13551 const serialized = getSaveContent(blockType, attributesSansClassName); 13552 const defaultClasses = getHTMLRootElementClasses(serialized); 13553 const actualClasses = getHTMLRootElementClasses(innerHTML); 13554 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className)); 13555 if (customClasses.length) { 13556 blockAttributes.className = customClasses.join(' '); 13557 } else if (serialized) { 13558 delete blockAttributes.className; 13559 } 13560 } 13561 return blockAttributes; 13562 } 13563 13564 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/apply-built-in-validation-fixes.js 13565 /** 13566 * Internal dependencies 13567 */ 13568 13569 13570 /** 13571 * Attempts to fix block invalidation by applying build-in validation fixes 13572 * like moving all extra classNames to the className attribute. 13573 * 13574 * @param {WPBlock} block block object. 13575 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13576 * can be inferred from the block name, 13577 * but it's here for performance reasons. 13578 * 13579 * @return {WPBlock} Fixed block object 13580 */ 13581 function applyBuiltInValidationFixes(block, blockType) { 13582 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent); 13583 return { 13584 ...block, 13585 attributes: updatedBlockAttributes 13586 }; 13587 } 13588 13589 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/apply-block-deprecated-versions.js 13590 /** 13591 * Internal dependencies 13592 */ 13593 13594 13595 13596 13597 13598 13599 /** 13600 * Function that takes no arguments and always returns false. 13601 * 13602 * @return {boolean} Always returns false. 13603 */ 13604 function stubFalse() { 13605 return false; 13606 } 13607 13608 /** 13609 * Given a block object, returns a new copy of the block with any applicable 13610 * deprecated migrations applied, or the original block if it was both valid 13611 * and no eligible migrations exist. 13612 * 13613 * @param {import(".").WPBlock} block Parsed and invalid block object. 13614 * @param {import(".").WPRawBlock} rawBlock Raw block object. 13615 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13616 * can be inferred from the block name, 13617 * but it's here for performance reasons. 13618 * 13619 * @return {import(".").WPBlock} Migrated block object. 13620 */ 13621 function applyBlockDeprecatedVersions(block, rawBlock, blockType) { 13622 const parsedAttributes = rawBlock.attrs; 13623 const { 13624 deprecated: deprecatedDefinitions 13625 } = blockType; 13626 // Bail early if there are no registered deprecations to be handled. 13627 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 13628 return block; 13629 } 13630 13631 // By design, blocks lack any sort of version tracking. Instead, to process 13632 // outdated content the system operates a queue out of all the defined 13633 // attribute shapes and tries each definition until the input produces a 13634 // valid result. This mechanism seeks to avoid polluting the user-space with 13635 // machine-specific code. An invalid block is thus a block that could not be 13636 // matched successfully with any of the registered deprecation definitions. 13637 for (let i = 0; i < deprecatedDefinitions.length; i++) { 13638 // A block can opt into a migration even if the block is valid by 13639 // defining `isEligible` on its deprecation. If the block is both valid 13640 // and does not opt to migrate, skip. 13641 const { 13642 isEligible = stubFalse 13643 } = deprecatedDefinitions[i]; 13644 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks, { 13645 blockNode: rawBlock, 13646 block 13647 })) { 13648 continue; 13649 } 13650 13651 // Block type properties which could impact either serialization or 13652 // parsing are not considered in the deprecated block type by default, 13653 // and must be explicitly provided. 13654 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 13655 let migratedBlock = { 13656 ...block, 13657 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes) 13658 }; 13659 13660 // Ignore the deprecation if it produces a block which is not valid. 13661 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13662 13663 // If the migrated block is not valid initially, try the built-in fixes. 13664 if (!isValid) { 13665 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType); 13666 [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13667 } 13668 13669 // An invalid block does not imply incorrect HTML but the fact block 13670 // source information could be lost on re-serialization. 13671 if (!isValid) { 13672 continue; 13673 } 13674 let migratedInnerBlocks = migratedBlock.innerBlocks; 13675 let migratedAttributes = migratedBlock.attributes; 13676 13677 // A block may provide custom behavior to assign new attributes and/or 13678 // inner blocks. 13679 const { 13680 migrate 13681 } = deprecatedBlockType; 13682 if (migrate) { 13683 let migrated = migrate(migratedAttributes, block.innerBlocks); 13684 if (!Array.isArray(migrated)) { 13685 migrated = [migrated]; 13686 } 13687 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated; 13688 } 13689 block = { 13690 ...block, 13691 attributes: migratedAttributes, 13692 innerBlocks: migratedInnerBlocks, 13693 isValid: true, 13694 validationIssues: [] 13695 }; 13696 } 13697 return block; 13698 } 13699 13700 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/index.js 13701 /** 13702 * WordPress dependencies 13703 */ 13704 13705 13706 13707 /** 13708 * Internal dependencies 13709 */ 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 /** 13721 * The raw structure of a block includes its attributes, inner 13722 * blocks, and inner HTML. It is important to distinguish inner blocks from 13723 * the HTML content of the block as only the latter is relevant for block 13724 * validation and edit operations. 13725 * 13726 * @typedef WPRawBlock 13727 * 13728 * @property {string=} blockName Block name 13729 * @property {Object=} attrs Block raw or comment attributes. 13730 * @property {string} innerHTML HTML content of the block. 13731 * @property {(string|null)[]} innerContent Content without inner blocks. 13732 * @property {WPRawBlock[]} innerBlocks Inner Blocks. 13733 */ 13734 13735 /** 13736 * Fully parsed block object. 13737 * 13738 * @typedef WPBlock 13739 * 13740 * @property {string} name Block name 13741 * @property {Object} attributes Block raw or comment attributes. 13742 * @property {WPBlock[]} innerBlocks Inner Blocks. 13743 * @property {string} originalContent Original content of the block before validation fixes. 13744 * @property {boolean} isValid Whether the block is valid. 13745 * @property {Object[]} validationIssues Validation issues. 13746 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. 13747 */ 13748 13749 /** 13750 * @typedef {Object} ParseOptions 13751 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. 13752 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content. 13753 */ 13754 13755 /** 13756 * Convert legacy blocks to their canonical form. This function is used 13757 * both in the parser level for previous content and to convert such blocks 13758 * used in Custom Post Types templates. 13759 * 13760 * @param {WPRawBlock} rawBlock 13761 * 13762 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found 13763 */ 13764 function convertLegacyBlocks(rawBlock) { 13765 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs); 13766 return { 13767 ...rawBlock, 13768 blockName: correctName, 13769 attrs: correctedAttributes 13770 }; 13771 } 13772 13773 /** 13774 * Normalize the raw block by applying the fallback block name if none given, 13775 * sanitize the parsed HTML... 13776 * 13777 * @param {WPRawBlock} rawBlock The raw block object. 13778 * @param {ParseOptions?} options Extra options for handling block parsing. 13779 * 13780 * @return {WPRawBlock} The normalized block object. 13781 */ 13782 function normalizeRawBlock(rawBlock, options) { 13783 const fallbackBlockName = getFreeformContentHandlerName(); 13784 13785 // If the grammar parsing don't produce any block name, use the freeform block. 13786 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName(); 13787 const rawAttributes = rawBlock.attrs || {}; 13788 const rawInnerBlocks = rawBlock.innerBlocks || []; 13789 let rawInnerHTML = rawBlock.innerHTML.trim(); 13790 13791 // Fallback content may be upgraded from classic content expecting implicit 13792 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 13793 // meaning there are no negative consequences to repeated autop calls. 13794 if (rawBlockName === fallbackBlockName && rawBlockName === 'core/freeform' && !options?.__unstableSkipAutop) { 13795 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim(); 13796 } 13797 return { 13798 ...rawBlock, 13799 blockName: rawBlockName, 13800 attrs: rawAttributes, 13801 innerHTML: rawInnerHTML, 13802 innerBlocks: rawInnerBlocks 13803 }; 13804 } 13805 13806 /** 13807 * Uses the "unregistered blockType" to create a block object. 13808 * 13809 * @param {WPRawBlock} rawBlock block. 13810 * 13811 * @return {WPRawBlock} The unregistered block object. 13812 */ 13813 function createMissingBlockType(rawBlock) { 13814 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); 13815 13816 // Preserve undelimited content for use by the unregistered type 13817 // handler. A block node's `innerHTML` isn't enough, as that field only 13818 // carries the block's own HTML and not its nested blocks. 13819 const originalUndelimitedContent = serializeRawBlock(rawBlock, { 13820 isCommentDelimited: false 13821 }); 13822 13823 // Preserve full block content for use by the unregistered type 13824 // handler, block boundaries included. 13825 const originalContent = serializeRawBlock(rawBlock, { 13826 isCommentDelimited: true 13827 }); 13828 return { 13829 blockName: unregisteredFallbackBlock, 13830 attrs: { 13831 originalName: rawBlock.blockName, 13832 originalContent, 13833 originalUndelimitedContent 13834 }, 13835 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML, 13836 innerBlocks: rawBlock.innerBlocks, 13837 innerContent: rawBlock.innerContent 13838 }; 13839 } 13840 13841 /** 13842 * Validates a block and wraps with validation meta. 13843 * 13844 * The name here is regrettable but `validateBlock` is already taken. 13845 * 13846 * @param {WPBlock} unvalidatedBlock 13847 * @param {import('../registration').WPBlockType} blockType 13848 * @return {WPBlock} validated block, with auto-fixes if initially invalid 13849 */ 13850 function applyBlockValidation(unvalidatedBlock, blockType) { 13851 // Attempt to validate the block. 13852 const [isValid] = validateBlock(unvalidatedBlock, blockType); 13853 if (isValid) { 13854 return { 13855 ...unvalidatedBlock, 13856 isValid, 13857 validationIssues: [] 13858 }; 13859 } 13860 13861 // If the block is invalid, attempt some built-in fixes 13862 // like custom classNames handling. 13863 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); 13864 // Attempt to validate the block once again after the built-in fixes. 13865 const [isFixedValid, validationIssues] = validateBlock(unvalidatedBlock, blockType); 13866 return { 13867 ...fixedBlock, 13868 isValid: isFixedValid, 13869 validationIssues 13870 }; 13871 } 13872 13873 /** 13874 * Given a raw block returned by grammar parsing, returns a fully parsed block. 13875 * 13876 * @param {WPRawBlock} rawBlock The raw block object. 13877 * @param {ParseOptions} options Extra options for handling block parsing. 13878 * 13879 * @return {WPBlock | undefined} Fully parsed block. 13880 */ 13881 function parseRawBlock(rawBlock, options) { 13882 let normalizedBlock = normalizeRawBlock(rawBlock, options); 13883 13884 // During the lifecycle of the project, we renamed some old blocks 13885 // and transformed others to new blocks. To avoid breaking existing content, 13886 // we added this function to properly parse the old content. 13887 normalizedBlock = convertLegacyBlocks(normalizedBlock); 13888 13889 // Try finding the type for known block name. 13890 let blockType = getBlockType(normalizedBlock.blockName); 13891 13892 // If not blockType is found for the specified name, fallback to the "unregistedBlockType". 13893 if (!blockType) { 13894 normalizedBlock = createMissingBlockType(normalizedBlock); 13895 blockType = getBlockType(normalizedBlock.blockName); 13896 } 13897 13898 // If it's an empty freeform block or there's no blockType (no missing block handler) 13899 // Then, just ignore the block. 13900 // It might be a good idea to throw a warning here. 13901 // TODO: I'm unsure about the unregisteredFallbackBlock check, 13902 // it might ignore some dynamic unregistered third party blocks wrongly. 13903 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName(); 13904 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) { 13905 return; 13906 } 13907 13908 // Parse inner blocks recursively. 13909 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) 13910 // See https://github.com/WordPress/gutenberg/pull/17164. 13911 .filter(innerBlock => !!innerBlock); 13912 13913 // Get the fully parsed block. 13914 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks); 13915 parsedBlock.originalContent = normalizedBlock.innerHTML; 13916 const validatedBlock = applyBlockValidation(parsedBlock, blockType); 13917 const { 13918 validationIssues 13919 } = validatedBlock; 13920 13921 // Run the block deprecation and migrations. 13922 // This is performed on both invalid and valid blocks because 13923 // migration using the `migrate` functions should run even 13924 // if the output is deemed valid. 13925 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType); 13926 if (!updatedBlock.isValid) { 13927 // Preserve the original unprocessed version of the block 13928 // that we received (no fixes, no deprecations) so that 13929 // we can save it as close to exactly the same way as 13930 // we loaded it. This is important to avoid corruption 13931 // and data loss caused by block implementations trying 13932 // to process data that isn't fully recognized. 13933 updatedBlock.__unstableBlockSource = rawBlock; 13934 } 13935 if (!validatedBlock.isValid && updatedBlock.isValid && !options?.__unstableSkipMigrationLogs) { 13936 /* eslint-disable no-console */ 13937 console.groupCollapsed('Updated Block: %s', blockType.name); 13938 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); 13939 console.groupEnd(); 13940 /* eslint-enable no-console */ 13941 } else if (!validatedBlock.isValid && !updatedBlock.isValid) { 13942 validationIssues.forEach(({ 13943 log, 13944 args 13945 }) => log(...args)); 13946 } 13947 return updatedBlock; 13948 } 13949 13950 /** 13951 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 13952 * defined through a parsing expression grammar to take advantage of the regular 13953 * cadence provided by block delimiters -- composed syntactically through HTML 13954 * comments -- which, given a general HTML document as an input, returns a block 13955 * list array representation. 13956 * 13957 * This is a recursive-descent parser that scans linearly once through the input 13958 * document. Instead of directly recursing it utilizes a trampoline mechanism to 13959 * prevent stack overflow. This initial pass is mainly interested in separating 13960 * and isolating the blocks serialized in the document and manifestly not in the 13961 * content within the blocks. 13962 * 13963 * @see 13964 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 13965 * 13966 * @param {string} content The post content. 13967 * @param {ParseOptions} options Extra options for handling block parsing. 13968 * 13969 * @return {Array} Block list. 13970 */ 13971 function parser_parse(content, options) { 13972 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => { 13973 const block = parseRawBlock(rawBlock, options); 13974 if (block) { 13975 accumulator.push(block); 13976 } 13977 return accumulator; 13978 }, []); 13979 } 13980 13981 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js 13982 /** 13983 * Internal dependencies 13984 */ 13985 13986 function getRawTransforms() { 13987 return getBlockTransforms('from').filter(({ 13988 type 13989 }) => type === 'raw').map(transform => { 13990 return transform.isMatch ? transform : { 13991 ...transform, 13992 isMatch: node => transform.selector && node.matches(transform.selector) 13993 }; 13994 }); 13995 } 13996 13997 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js 13998 /** 13999 * WordPress dependencies 14000 */ 14001 14002 14003 /** 14004 * Internal dependencies 14005 */ 14006 14007 14008 14009 14010 14011 /** 14012 * Converts HTML directly to blocks. Looks for a matching transform for each 14013 * top-level tag. The HTML should be filtered to not have any text between 14014 * top-level tags and formatted in a way that blocks can handle the HTML. 14015 * 14016 * @param {string} html HTML to convert. 14017 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler 14018 * or pasteHandler. 14019 * 14020 * @return {Array} An array of blocks. 14021 */ 14022 function htmlToBlocks(html, handler) { 14023 const doc = document.implementation.createHTMLDocument(''); 14024 doc.body.innerHTML = html; 14025 return Array.from(doc.body.children).flatMap(node => { 14026 const rawTransform = findTransform(getRawTransforms(), ({ 14027 isMatch 14028 }) => isMatch(node)); 14029 if (!rawTransform) { 14030 // Until the HTML block is supported in the native version, we'll parse it 14031 // instead of creating the block to generate it as an unsupported block. 14032 if (external_wp_element_namespaceObject.Platform.isNative) { 14033 return parser_parse(`<!-- wp:html -->$node.outerHTML}<!-- /wp:html -->`); 14034 } 14035 return createBlock( 14036 // Should not be hardcoded. 14037 'core/html', getBlockAttributes('core/html', node.outerHTML)); 14038 } 14039 const { 14040 transform, 14041 blockName 14042 } = rawTransform; 14043 if (transform) { 14044 return transform(node, handler); 14045 } 14046 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 14047 }); 14048 } 14049 14050 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js 14051 /** 14052 * WordPress dependencies 14053 */ 14054 14055 function normaliseBlocks(HTML) { 14056 const decuDoc = document.implementation.createHTMLDocument(''); 14057 const accuDoc = document.implementation.createHTMLDocument(''); 14058 const decu = decuDoc.body; 14059 const accu = accuDoc.body; 14060 decu.innerHTML = HTML; 14061 while (decu.firstChild) { 14062 const node = decu.firstChild; 14063 14064 // Text nodes: wrap in a paragraph, or append to previous. 14065 if (node.nodeType === node.TEXT_NODE) { 14066 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 14067 decu.removeChild(node); 14068 } else { 14069 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14070 accu.appendChild(accuDoc.createElement('P')); 14071 } 14072 accu.lastChild.appendChild(node); 14073 } 14074 // Element nodes. 14075 } else if (node.nodeType === node.ELEMENT_NODE) { 14076 // BR nodes: create a new paragraph on double, or append to previous. 14077 if (node.nodeName === 'BR') { 14078 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 14079 accu.appendChild(accuDoc.createElement('P')); 14080 decu.removeChild(node.nextSibling); 14081 } 14082 14083 // Don't append to an empty paragraph. 14084 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 14085 accu.lastChild.appendChild(node); 14086 } else { 14087 decu.removeChild(node); 14088 } 14089 } else if (node.nodeName === 'P') { 14090 // Only append non-empty paragraph nodes. 14091 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 14092 decu.removeChild(node); 14093 } else { 14094 accu.appendChild(node); 14095 } 14096 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) { 14097 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14098 accu.appendChild(accuDoc.createElement('P')); 14099 } 14100 accu.lastChild.appendChild(node); 14101 } else { 14102 accu.appendChild(node); 14103 } 14104 } else { 14105 decu.removeChild(node); 14106 } 14107 } 14108 return accu.innerHTML; 14109 } 14110 14111 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js 14112 /** 14113 * WordPress dependencies 14114 */ 14115 14116 14117 /** 14118 * Looks for `<!--nextpage-->` and `<!--more-->` comments and 14119 * replaces them with a custom element representing a future block. 14120 * 14121 * The custom element is a way to bypass the rest of the `raw-handling` 14122 * transforms, which would eliminate other kinds of node with which to carry 14123 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 14124 * 14125 * The custom element is then expected to be recognized by any registered 14126 * block's `raw` transform. 14127 * 14128 * @param {Node} node The node to be processed. 14129 * @param {Document} doc The document of the node. 14130 * @return {void} 14131 */ 14132 function specialCommentConverter(node, doc) { 14133 if (node.nodeType !== node.COMMENT_NODE) { 14134 return; 14135 } 14136 if (node.nodeValue === 'nextpage') { 14137 (0,external_wp_dom_namespaceObject.replace)(node, createNextpage(doc)); 14138 return; 14139 } 14140 if (node.nodeValue.indexOf('more') === 0) { 14141 moreCommentConverter(node, doc); 14142 } 14143 } 14144 14145 /** 14146 * Convert `<!--more-->` as well as the `<!--more Some text-->` variant 14147 * and its `<!--noteaser-->` companion into the custom element 14148 * described in `specialCommentConverter()`. 14149 * 14150 * @param {Node} node The node to be processed. 14151 * @param {Document} doc The document of the node. 14152 * @return {void} 14153 */ 14154 function moreCommentConverter(node, doc) { 14155 // Grab any custom text in the comment. 14156 const customText = node.nodeValue.slice(4).trim(); 14157 14158 /* 14159 * When a `<!--more-->` comment is found, we need to look for any 14160 * `<!--noteaser-->` sibling, but it may not be a direct sibling 14161 * (whitespace typically lies in between) 14162 */ 14163 let sibling = node; 14164 let noTeaser = false; 14165 while (sibling = sibling.nextSibling) { 14166 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 14167 noTeaser = true; 14168 (0,external_wp_dom_namespaceObject.remove)(sibling); 14169 break; 14170 } 14171 } 14172 const moreBlock = createMore(customText, noTeaser, doc); 14173 14174 // If our `<!--more-->` comment is in the middle of a paragraph, we should 14175 // split the paragraph in two and insert the more block in between. If not, 14176 // the more block will eventually end up being inserted after the paragraph. 14177 if (!node.parentNode || node.parentNode.nodeName !== 'P' || node.parentNode.childNodes.length === 1) { 14178 (0,external_wp_dom_namespaceObject.replace)(node, moreBlock); 14179 } else { 14180 const childNodes = Array.from(node.parentNode.childNodes); 14181 const nodeIndex = childNodes.indexOf(node); 14182 const wrapperNode = node.parentNode.parentNode || doc.body; 14183 const paragraphBuilder = (acc, child) => { 14184 if (!acc) { 14185 acc = doc.createElement('p'); 14186 } 14187 acc.appendChild(child); 14188 return acc; 14189 }; 14190 14191 // Split the original parent node and insert our more block 14192 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), moreBlock, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEach(element => element && wrapperNode.insertBefore(element, node.parentNode)); 14193 14194 // Remove the old parent paragraph 14195 (0,external_wp_dom_namespaceObject.remove)(node.parentNode); 14196 } 14197 } 14198 function createMore(customText, noTeaser, doc) { 14199 const node = doc.createElement('wp-block'); 14200 node.dataset.block = 'core/more'; 14201 if (customText) { 14202 node.dataset.customText = customText; 14203 } 14204 if (noTeaser) { 14205 // "Boolean" data attribute. 14206 node.dataset.noTeaser = ''; 14207 } 14208 return node; 14209 } 14210 function createNextpage(doc) { 14211 const node = doc.createElement('wp-block'); 14212 node.dataset.block = 'core/nextpage'; 14213 return node; 14214 } 14215 14216 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/list-reducer.js 14217 /** 14218 * WordPress dependencies 14219 */ 14220 14221 function isList(node) { 14222 return node.nodeName === 'OL' || node.nodeName === 'UL'; 14223 } 14224 function shallowTextContent(element) { 14225 return Array.from(element.childNodes).map(({ 14226 nodeValue = '' 14227 }) => nodeValue).join(''); 14228 } 14229 function listReducer(node) { 14230 if (!isList(node)) { 14231 return; 14232 } 14233 const list = node; 14234 const prevElement = node.previousElementSibling; 14235 14236 // Merge with previous list if: 14237 // * There is a previous list of the same type. 14238 // * There is only one list item. 14239 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 14240 // Move all child nodes, including any text nodes, if any. 14241 while (list.firstChild) { 14242 prevElement.appendChild(list.firstChild); 14243 } 14244 list.parentNode.removeChild(list); 14245 } 14246 const parentElement = node.parentNode; 14247 14248 // Nested list with empty parent item. 14249 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 14250 const parentListItem = parentElement; 14251 const prevListItem = parentListItem.previousElementSibling; 14252 const parentList = parentListItem.parentNode; 14253 if (prevListItem) { 14254 prevListItem.appendChild(list); 14255 parentList.removeChild(parentListItem); 14256 } else { 14257 parentList.parentNode.insertBefore(list, parentList); 14258 parentList.parentNode.removeChild(parentList); 14259 } 14260 } 14261 14262 // Invalid: OL/UL > OL/UL. 14263 if (parentElement && isList(parentElement)) { 14264 const prevListItem = node.previousElementSibling; 14265 if (prevListItem) { 14266 prevListItem.appendChild(node); 14267 } else { 14268 (0,external_wp_dom_namespaceObject.unwrap)(node); 14269 } 14270 } 14271 } 14272 14273 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/blockquote-normaliser.js 14274 /** 14275 * Internal dependencies 14276 */ 14277 14278 function blockquoteNormaliser(node) { 14279 if (node.nodeName !== 'BLOCKQUOTE') { 14280 return; 14281 } 14282 node.innerHTML = normaliseBlocks(node.innerHTML); 14283 } 14284 14285 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/figure-content-reducer.js 14286 /** 14287 * WordPress dependencies 14288 */ 14289 14290 14291 /** 14292 * Whether or not the given node is figure content. 14293 * 14294 * @param {Node} node The node to check. 14295 * @param {Object} schema The schema to use. 14296 * 14297 * @return {boolean} True if figure content, false if not. 14298 */ 14299 function isFigureContent(node, schema) { 14300 var _schema$figure$childr; 14301 const tag = node.nodeName.toLowerCase(); 14302 14303 // We are looking for tags that can be a child of the figure tag, excluding 14304 // `figcaption` and any phrasing content. 14305 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14306 return false; 14307 } 14308 return tag in ((_schema$figure$childr = schema?.figure?.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {}); 14309 } 14310 14311 /** 14312 * Whether or not the given node can have an anchor. 14313 * 14314 * @param {Node} node The node to check. 14315 * @param {Object} schema The schema to use. 14316 * 14317 * @return {boolean} True if it can, false if not. 14318 */ 14319 function canHaveAnchor(node, schema) { 14320 var _schema$figure$childr2; 14321 const tag = node.nodeName.toLowerCase(); 14322 return tag in ((_schema$figure$childr2 = schema?.figure?.children?.a?.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {}); 14323 } 14324 14325 /** 14326 * Wraps the given element in a figure element. 14327 * 14328 * @param {Element} element The element to wrap. 14329 * @param {Element} beforeElement The element before which to place the figure. 14330 */ 14331 function wrapFigureContent(element, beforeElement = element) { 14332 const figure = element.ownerDocument.createElement('figure'); 14333 beforeElement.parentNode.insertBefore(figure, beforeElement); 14334 figure.appendChild(element); 14335 } 14336 14337 /** 14338 * This filter takes figure content out of paragraphs, wraps it in a figure 14339 * element, and moves any anchors with it if needed. 14340 * 14341 * @param {Node} node The node to filter. 14342 * @param {Document} doc The document of the node. 14343 * @param {Object} schema The schema to use. 14344 * 14345 * @return {void} 14346 */ 14347 function figureContentReducer(node, doc, schema) { 14348 if (!isFigureContent(node, schema)) { 14349 return; 14350 } 14351 let nodeToInsert = node; 14352 const parentNode = node.parentNode; 14353 14354 // If the figure content can have an anchor and its parent is an anchor with 14355 // only the figure content, take the anchor out instead of just the content. 14356 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 14357 nodeToInsert = node.parentNode; 14358 } 14359 const wrapper = nodeToInsert.closest('p,div'); 14360 14361 // If wrapped in a paragraph or div, only extract if it's aligned or if 14362 // there is no text content. 14363 // Otherwise, if directly at the root, wrap in a figure element. 14364 if (wrapper) { 14365 // In jsdom-jscore, 'node.classList' can be undefined. 14366 // In this case, default to extract as it offers a better UI experience on mobile. 14367 if (!node.classList) { 14368 wrapFigureContent(nodeToInsert, wrapper); 14369 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 14370 wrapFigureContent(nodeToInsert, wrapper); 14371 } 14372 } else if (nodeToInsert.parentNode.nodeName === 'BODY') { 14373 wrapFigureContent(nodeToInsert); 14374 } 14375 } 14376 14377 ;// CONCATENATED MODULE: external ["wp","shortcode"] 14378 const external_wp_shortcode_namespaceObject = window["wp"]["shortcode"]; 14379 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/shortcode-converter.js 14380 /** 14381 * WordPress dependencies 14382 */ 14383 14384 14385 /** 14386 * Internal dependencies 14387 */ 14388 14389 14390 14391 14392 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14393 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) { 14394 // Get all matches. 14395 const transformsFrom = getBlockTransforms('from'); 14396 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))); 14397 if (!transformation) { 14398 return [HTML]; 14399 } 14400 const transformTags = castArray(transformation.tag); 14401 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)); 14402 let match; 14403 const previousIndex = lastIndex; 14404 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) { 14405 lastIndex = match.index + match.content.length; 14406 const beforeHTML = HTML.substr(0, match.index); 14407 const afterHTML = HTML.substr(lastIndex); 14408 14409 // If the shortcode content does not contain HTML and the shortcode is 14410 // not on a new line (or in paragraph from Markdown converter), 14411 // consider the shortcode as inline text, and thus skip conversion for 14412 // this segment. 14413 if (!match.shortcode.content?.includes('<') && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) { 14414 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 14415 } 14416 14417 // If a transformation's `isMatch` predicate fails for the inbound 14418 // shortcode, try again by excluding the current block type. 14419 // 14420 // This is the only call to `segmentHTMLToShortcodeBlock` that should 14421 // ever carry over `excludedBlockNames`. Other calls in the module 14422 // should skip that argument as a way to reset the exclusion state, so 14423 // that one `isMatch` fail in an HTML fragment doesn't prevent any 14424 // valid matches in subsequent fragments. 14425 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 14426 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 14427 } 14428 let blocks = []; 14429 if (typeof transformation.transform === 'function') { 14430 // Passing all of `match` as second argument is intentionally broad 14431 // but shouldn't be too relied upon. 14432 // 14433 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14434 blocks = [].concat(transformation.transform(match.shortcode.attrs, match)); 14435 14436 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14437 blocks = blocks.map(block => { 14438 block.originalContent = match.shortcode.content; 14439 return applyBuiltInValidationFixes(block, getBlockType(block.name)); 14440 }); 14441 } else { 14442 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(([, schema]) => schema.shortcode) 14443 // Passing all of `match` as second argument is intentionally broad 14444 // but shouldn't be too relied upon. 14445 // 14446 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14447 .map(([key, schema]) => [key, schema.shortcode(match.shortcode.attrs, match)])); 14448 const blockType = getBlockType(transformation.blockName); 14449 if (!blockType) { 14450 return [HTML]; 14451 } 14452 const transformationBlockType = { 14453 ...blockType, 14454 attributes: transformation.attributes 14455 }; 14456 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); 14457 14458 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14459 block.originalContent = match.shortcode.content; 14460 block = applyBuiltInValidationFixes(block, transformationBlockType); 14461 blocks = [block]; 14462 } 14463 return [...segmentHTMLToShortcodeBlock(beforeHTML), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML)]; 14464 } 14465 return [HTML]; 14466 } 14467 /* harmony default export */ const shortcode_converter = (segmentHTMLToShortcodeBlock); 14468 14469 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/utils.js 14470 /** 14471 * WordPress dependencies 14472 */ 14473 14474 14475 /** 14476 * Internal dependencies 14477 */ 14478 14479 14480 function getBlockContentSchemaFromTransforms(transforms, context) { 14481 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14482 const schemaArgs = { 14483 phrasingContentSchema, 14484 isPaste: context === 'paste' 14485 }; 14486 const schemas = transforms.map(({ 14487 isMatch, 14488 blockName, 14489 schema 14490 }) => { 14491 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor'); 14492 schema = typeof schema === 'function' ? schema(schemaArgs) : schema; 14493 14494 // If the block does not has anchor support and the transform does not 14495 // provides an isMatch we can return the schema right away. 14496 if (!hasAnchorSupport && !isMatch) { 14497 return schema; 14498 } 14499 if (!schema) { 14500 return {}; 14501 } 14502 return Object.fromEntries(Object.entries(schema).map(([key, value]) => { 14503 let attributes = value.attributes || []; 14504 // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 14505 if (hasAnchorSupport) { 14506 attributes = [...attributes, 'id']; 14507 } 14508 return [key, { 14509 ...value, 14510 attributes, 14511 isMatch: isMatch ? isMatch : undefined 14512 }]; 14513 })); 14514 }); 14515 function mergeTagNameSchemaProperties(objValue, srcValue, key) { 14516 switch (key) { 14517 case 'children': 14518 { 14519 if (objValue === '*' || srcValue === '*') { 14520 return '*'; 14521 } 14522 return { 14523 ...objValue, 14524 ...srcValue 14525 }; 14526 } 14527 case 'attributes': 14528 case 'require': 14529 { 14530 return [...(objValue || []), ...(srcValue || [])]; 14531 } 14532 case 'isMatch': 14533 { 14534 // If one of the values being merge is undefined (matches everything), 14535 // the result of the merge will be undefined. 14536 if (!objValue || !srcValue) { 14537 return undefined; 14538 } 14539 // When merging two isMatch functions, the result is a new function 14540 // that returns if one of the source functions returns true. 14541 return (...args) => { 14542 return objValue(...args) || srcValue(...args); 14543 }; 14544 } 14545 } 14546 } 14547 14548 // A tagName schema is an object with children, attributes, require, and 14549 // isMatch properties. 14550 function mergeTagNameSchemas(a, b) { 14551 for (const key in b) { 14552 a[key] = a[key] ? mergeTagNameSchemaProperties(a[key], b[key], key) : { 14553 ...b[key] 14554 }; 14555 } 14556 return a; 14557 } 14558 14559 // A schema is an object with tagName schemas by tag name. 14560 function mergeSchemas(a, b) { 14561 for (const key in b) { 14562 a[key] = a[key] ? mergeTagNameSchemas(a[key], b[key]) : { 14563 ...b[key] 14564 }; 14565 } 14566 return a; 14567 } 14568 return schemas.reduce(mergeSchemas, {}); 14569 } 14570 14571 /** 14572 * Gets the block content schema, which is extracted and merged from all 14573 * registered blocks with raw transfroms. 14574 * 14575 * @param {string} context Set to "paste" when in paste context, where the 14576 * schema is more strict. 14577 * 14578 * @return {Object} A complete block content schema. 14579 */ 14580 function getBlockContentSchema(context) { 14581 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 14582 } 14583 14584 /** 14585 * Checks whether HTML can be considered plain text. That is, it does not contain 14586 * any elements that are not line breaks. 14587 * 14588 * @param {string} HTML The HTML to check. 14589 * 14590 * @return {boolean} Whether the HTML can be considered plain text. 14591 */ 14592 function isPlain(HTML) { 14593 return !/<(?!br[ />])/i.test(HTML); 14594 } 14595 14596 /** 14597 * Given node filters, deeply filters and mutates a NodeList. 14598 * 14599 * @param {NodeList} nodeList The nodeList to filter. 14600 * @param {Array} filters An array of functions that can mutate with the provided node. 14601 * @param {Document} doc The document of the nodeList. 14602 * @param {Object} schema The schema to use. 14603 */ 14604 function deepFilterNodeList(nodeList, filters, doc, schema) { 14605 Array.from(nodeList).forEach(node => { 14606 deepFilterNodeList(node.childNodes, filters, doc, schema); 14607 filters.forEach(item => { 14608 // Make sure the node is still attached to the document. 14609 if (!doc.contains(node)) { 14610 return; 14611 } 14612 item(node, doc, schema); 14613 }); 14614 }); 14615 } 14616 14617 /** 14618 * Given node filters, deeply filters HTML tags. 14619 * Filters from the deepest nodes to the top. 14620 * 14621 * @param {string} HTML The HTML to filter. 14622 * @param {Array} filters An array of functions that can mutate with the provided node. 14623 * @param {Object} schema The schema to use. 14624 * 14625 * @return {string} The filtered HTML. 14626 */ 14627 function deepFilterHTML(HTML, filters = [], schema) { 14628 const doc = document.implementation.createHTMLDocument(''); 14629 doc.body.innerHTML = HTML; 14630 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 14631 return doc.body.innerHTML; 14632 } 14633 14634 /** 14635 * Gets a sibling within text-level context. 14636 * 14637 * @param {Element} node The subject node. 14638 * @param {string} which "next" or "previous". 14639 */ 14640 function getSibling(node, which) { 14641 const sibling = node[`$which}Sibling`]; 14642 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) { 14643 return sibling; 14644 } 14645 const { 14646 parentNode 14647 } = node; 14648 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) { 14649 return; 14650 } 14651 return getSibling(parentNode, which); 14652 } 14653 14654 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/index.js 14655 /** 14656 * WordPress dependencies 14657 */ 14658 14659 14660 14661 /** 14662 * Internal dependencies 14663 */ 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 function deprecatedGetPhrasingContentSchema(context) { 14675 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 14676 since: '5.6', 14677 alternative: 'wp.dom.getPhrasingContentSchema' 14678 }); 14679 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14680 } 14681 14682 /** 14683 * Converts an HTML string to known blocks. 14684 * 14685 * @param {Object} $1 14686 * @param {string} $1.HTML The HTML to convert. 14687 * 14688 * @return {Array} A list of blocks. 14689 */ 14690 function rawHandler({ 14691 HTML = '' 14692 }) { 14693 // If we detect block delimiters, parse entirely as blocks. 14694 if (HTML.indexOf('<!-- wp:') !== -1) { 14695 return parser_parse(HTML); 14696 } 14697 14698 // An array of HTML strings and block objects. The blocks replace matched 14699 // shortcodes. 14700 const pieces = shortcode_converter(HTML); 14701 const blockContentSchema = getBlockContentSchema(); 14702 return pieces.map(piece => { 14703 // Already a block from shortcode. 14704 if (typeof piece !== 'string') { 14705 return piece; 14706 } 14707 14708 // These filters are essential for some blocks to be able to transform 14709 // from raw HTML. These filters move around some content or add 14710 // additional tags, they do not remove any content. 14711 const filters = [ 14712 // Needed to adjust invalid lists. 14713 listReducer, 14714 // Needed to create more and nextpage blocks. 14715 specialCommentConverter, 14716 // Needed to create media blocks. 14717 figureContentReducer, 14718 // Needed to create the quote block, which cannot handle text 14719 // without wrapper paragraphs. 14720 blockquoteNormaliser]; 14721 piece = deepFilterHTML(piece, filters, blockContentSchema); 14722 piece = normaliseBlocks(piece); 14723 return htmlToBlocks(piece, rawHandler); 14724 }).flat().filter(Boolean); 14725 } 14726 14727 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js 14728 /** 14729 * WordPress dependencies 14730 */ 14731 14732 14733 /** 14734 * Looks for comments, and removes them. 14735 * 14736 * @param {Node} node The node to be processed. 14737 * @return {void} 14738 */ 14739 function commentRemover(node) { 14740 if (node.nodeType === node.COMMENT_NODE) { 14741 (0,external_wp_dom_namespaceObject.remove)(node); 14742 } 14743 } 14744 14745 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js 14746 /** 14747 * WordPress dependencies 14748 */ 14749 14750 14751 /** 14752 * Checks if the given node should be considered inline content, optionally 14753 * depending on a context tag. 14754 * 14755 * @param {Node} node Node name. 14756 * @param {string} contextTag Tag name. 14757 * 14758 * @return {boolean} True if the node is inline content, false if nohe. 14759 */ 14760 function isInline(node, contextTag) { 14761 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14762 return true; 14763 } 14764 if (!contextTag) { 14765 return false; 14766 } 14767 const tag = node.nodeName.toLowerCase(); 14768 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 14769 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0); 14770 } 14771 function deepCheck(nodes, contextTag) { 14772 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 14773 } 14774 function isDoubleBR(node) { 14775 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 14776 } 14777 function isInlineContent(HTML, contextTag) { 14778 const doc = document.implementation.createHTMLDocument(''); 14779 doc.body.innerHTML = HTML; 14780 const nodes = Array.from(doc.body.children); 14781 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 14782 } 14783 14784 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 14785 /** 14786 * WordPress dependencies 14787 */ 14788 14789 function phrasingContentReducer(node, doc) { 14790 // In jsdom-jscore, 'node.style' can be null. 14791 // TODO: Explore fixing this by patching jsdom-jscore. 14792 if (node.nodeName === 'SPAN' && node.style) { 14793 const { 14794 fontWeight, 14795 fontStyle, 14796 textDecorationLine, 14797 textDecoration, 14798 verticalAlign 14799 } = node.style; 14800 if (fontWeight === 'bold' || fontWeight === '700') { 14801 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node); 14802 } 14803 if (fontStyle === 'italic') { 14804 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node); 14805 } 14806 14807 // Some DOM implementations (Safari, JSDom) don't support 14808 // style.textDecorationLine, so we check style.textDecoration as a 14809 // fallback. 14810 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) { 14811 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node); 14812 } 14813 if (verticalAlign === 'super') { 14814 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node); 14815 } else if (verticalAlign === 'sub') { 14816 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node); 14817 } 14818 } else if (node.nodeName === 'B') { 14819 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong'); 14820 } else if (node.nodeName === 'I') { 14821 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em'); 14822 } else if (node.nodeName === 'A') { 14823 // In jsdom-jscore, 'node.target' can be null. 14824 // TODO: Explore fixing this by patching jsdom-jscore. 14825 if (node.target && node.target.toLowerCase() === '_blank') { 14826 node.rel = 'noreferrer noopener'; 14827 } else { 14828 node.removeAttribute('target'); 14829 node.removeAttribute('rel'); 14830 } 14831 14832 // Saves anchor elements name attribute as id 14833 if (node.name && !node.id) { 14834 node.id = node.name; 14835 } 14836 14837 // Keeps id only if there is an internal link pointing to it 14838 if (node.id && !node.ownerDocument.querySelector(`[href="#$node.id}"]`)) { 14839 node.removeAttribute('id'); 14840 } 14841 } 14842 } 14843 14844 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js 14845 function headRemover(node) { 14846 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 14847 return; 14848 } 14849 node.parentNode.removeChild(node); 14850 } 14851 14852 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-ignore.js 14853 /** 14854 * Looks for comments, and removes them. 14855 * 14856 * @param {Node} node The node to be processed. 14857 * @return {void} 14858 */ 14859 function msListIgnore(node) { 14860 if (node.nodeType !== node.ELEMENT_NODE) { 14861 return; 14862 } 14863 const style = node.getAttribute('style'); 14864 if (!style || !style.includes('mso-list')) { 14865 return; 14866 } 14867 const rules = style.split(';').reduce((acc, rule) => { 14868 const [key, value] = rule.split(':'); 14869 acc[key.trim().toLowerCase()] = value.trim().toLowerCase(); 14870 return acc; 14871 }, {}); 14872 if (rules['mso-list'] === 'ignore') { 14873 node.remove(); 14874 } 14875 } 14876 14877 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js 14878 /** 14879 * Internal dependencies 14880 */ 14881 14882 14883 function ms_list_converter_isList(node) { 14884 return node.nodeName === 'OL' || node.nodeName === 'UL'; 14885 } 14886 function msListConverter(node, doc) { 14887 if (node.nodeName !== 'P') { 14888 return; 14889 } 14890 const style = node.getAttribute('style'); 14891 if (!style || !style.includes('mso-list')) { 14892 return; 14893 } 14894 const prevNode = node.previousElementSibling; 14895 14896 // Add new list if no previous. 14897 if (!prevNode || !ms_list_converter_isList(prevNode)) { 14898 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 14899 const type = node.textContent.trim().slice(0, 1); 14900 const isNumeric = /[1iIaA]/.test(type); 14901 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 14902 if (isNumeric) { 14903 newListNode.setAttribute('type', type); 14904 } 14905 node.parentNode.insertBefore(newListNode, node); 14906 } 14907 const listNode = node.previousElementSibling; 14908 const listType = listNode.nodeName; 14909 const listItem = doc.createElement('li'); 14910 let receivingNode = listNode; 14911 14912 // Add content. 14913 listItem.innerHTML = deepFilterHTML(node.innerHTML, [msListIgnore]); 14914 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 14915 let level = matches ? parseInt(matches[1], 10) - 1 || 0 : 0; 14916 14917 // Change pointer depending on indentation level. 14918 while (level--) { 14919 receivingNode = receivingNode.lastChild || receivingNode; 14920 14921 // If it's a list, move pointer to the last item. 14922 if (ms_list_converter_isList(receivingNode)) { 14923 receivingNode = receivingNode.lastChild || receivingNode; 14924 } 14925 } 14926 14927 // Make sure we append to a list. 14928 if (!ms_list_converter_isList(receivingNode)) { 14929 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 14930 } 14931 14932 // Append the list item to the list. 14933 receivingNode.appendChild(listItem); 14934 14935 // Remove the wrapper paragraph. 14936 node.parentNode.removeChild(node); 14937 } 14938 14939 ;// CONCATENATED MODULE: external ["wp","blob"] 14940 const external_wp_blob_namespaceObject = window["wp"]["blob"]; 14941 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/image-corrector.js 14942 /** 14943 * WordPress dependencies 14944 */ 14945 14946 function imageCorrector(node) { 14947 if (node.nodeName !== 'IMG') { 14948 return; 14949 } 14950 if (node.src.indexOf('file:') === 0) { 14951 node.src = ''; 14952 } 14953 14954 // This piece cannot be tested outside a browser env. 14955 if (node.src.indexOf('data:') === 0) { 14956 const [properties, data] = node.src.split(','); 14957 const [type] = properties.slice(5).split(';'); 14958 if (!data || !type) { 14959 node.src = ''; 14960 return; 14961 } 14962 let decoded; 14963 14964 // Can throw DOMException! 14965 try { 14966 decoded = atob(data); 14967 } catch (e) { 14968 node.src = ''; 14969 return; 14970 } 14971 const uint8Array = new Uint8Array(decoded.length); 14972 for (let i = 0; i < uint8Array.length; i++) { 14973 uint8Array[i] = decoded.charCodeAt(i); 14974 } 14975 const name = type.replace('/', '.'); 14976 const file = new window.File([uint8Array], name, { 14977 type 14978 }); 14979 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 14980 } 14981 14982 // Remove trackers and hardly visible images. 14983 if (node.height === 1 || node.width === 1) { 14984 node.parentNode.removeChild(node); 14985 } 14986 } 14987 14988 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/div-normaliser.js 14989 /** 14990 * Internal dependencies 14991 */ 14992 14993 function divNormaliser(node) { 14994 if (node.nodeName !== 'DIV') { 14995 return; 14996 } 14997 node.innerHTML = normaliseBlocks(node.innerHTML); 14998 } 14999 15000 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 15001 var showdown = __webpack_require__(1030); 15002 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 15003 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/markdown-converter.js 15004 /** 15005 * External dependencies 15006 */ 15007 15008 15009 // Reuse the same showdown converter. 15010 const converter = new (showdown_default()).Converter({ 15011 noHeaderId: true, 15012 tables: true, 15013 literalMidWordUnderscores: true, 15014 omitExtraWLInCodeBlocks: true, 15015 simpleLineBreaks: true, 15016 strikethrough: true 15017 }); 15018 15019 /** 15020 * Corrects the Slack Markdown variant of the code block. 15021 * If uncorrected, it will be converted to inline code. 15022 * 15023 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks 15024 * 15025 * @param {string} text The potential Markdown text to correct. 15026 * 15027 * @return {string} The corrected Markdown. 15028 */ 15029 function slackMarkdownVariantCorrector(text) { 15030 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `$p1}\n$p2}\n$p3}`); 15031 } 15032 function bulletsToAsterisks(text) { 15033 return text.replace(/(^|\n)•( +)/g, '$1*$2'); 15034 } 15035 15036 /** 15037 * Converts a piece of text into HTML based on any Markdown present. 15038 * Also decodes any encoded HTML. 15039 * 15040 * @param {string} text The plain text to convert. 15041 * 15042 * @return {string} HTML. 15043 */ 15044 function markdownConverter(text) { 15045 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text))); 15046 } 15047 15048 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/iframe-remover.js 15049 /** 15050 * Removes iframes. 15051 * 15052 * @param {Node} node The node to check. 15053 * 15054 * @return {void} 15055 */ 15056 function iframeRemover(node) { 15057 if (node.nodeName === 'IFRAME') { 15058 const text = node.ownerDocument.createTextNode(node.src); 15059 node.parentNode.replaceChild(text, node); 15060 } 15061 } 15062 15063 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 15064 /** 15065 * WordPress dependencies 15066 */ 15067 15068 function googleDocsUIdRemover(node) { 15069 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 15070 return; 15071 } 15072 15073 // Google Docs sometimes wraps the content in a B tag. We don't want to keep 15074 // this. 15075 if (node.tagName === 'B') { 15076 (0,external_wp_dom_namespaceObject.unwrap)(node); 15077 } else { 15078 node.removeAttribute('id'); 15079 } 15080 } 15081 15082 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-formatting-remover.js 15083 /** 15084 * Internal dependencies 15085 */ 15086 15087 function isFormattingSpace(character) { 15088 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 15089 } 15090 15091 /** 15092 * Removes spacing that formats HTML. 15093 * 15094 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 15095 * 15096 * @param {Node} node The node to be processed. 15097 * @return {void} 15098 */ 15099 function htmlFormattingRemover(node) { 15100 if (node.nodeType !== node.TEXT_NODE) { 15101 return; 15102 } 15103 15104 // Ignore pre content. Note that this does not use Element#closest due to 15105 // a combination of (a) node may not be Element and (b) node.parentElement 15106 // does not have full support in all browsers (Internet Exporer). 15107 // 15108 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 15109 15110 /** @type {Node?} */ 15111 let parent = node; 15112 while (parent = parent.parentNode) { 15113 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 15114 return; 15115 } 15116 } 15117 15118 // First, replace any sequence of HTML formatting space with a single space. 15119 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); 15120 15121 // Remove the leading space if the text element is at the start of a block, 15122 // is preceded by a line break element, or has a space in the previous 15123 // node. 15124 if (newData[0] === ' ') { 15125 const previousSibling = getSibling(node, 'previous'); 15126 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 15127 newData = newData.slice(1); 15128 } 15129 } 15130 15131 // Remove the trailing space if the text element is at the end of a block, 15132 // is succeded by a line break element, or has a space in the next text 15133 // node. 15134 if (newData[newData.length - 1] === ' ') { 15135 const nextSibling = getSibling(node, 'next'); 15136 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 15137 newData = newData.slice(0, -1); 15138 } 15139 } 15140 15141 // If there's no data left, remove the node, so `previousSibling` stays 15142 // accurate. Otherwise, update the node data. 15143 if (!newData) { 15144 node.parentNode.removeChild(node); 15145 } else { 15146 node.data = newData; 15147 } 15148 } 15149 15150 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/br-remover.js 15151 /** 15152 * Internal dependencies 15153 */ 15154 15155 15156 /** 15157 * Removes trailing br elements from text-level content. 15158 * 15159 * @param {Element} node Node to check. 15160 */ 15161 function brRemover(node) { 15162 if (node.nodeName !== 'BR') { 15163 return; 15164 } 15165 if (getSibling(node, 'next')) { 15166 return; 15167 } 15168 node.parentNode.removeChild(node); 15169 } 15170 15171 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 15172 /** 15173 * Removes empty paragraph elements. 15174 * 15175 * @param {Element} node Node to check. 15176 */ 15177 function emptyParagraphRemover(node) { 15178 if (node.nodeName !== 'P') { 15179 return; 15180 } 15181 if (node.hasChildNodes()) { 15182 return; 15183 } 15184 node.parentNode.removeChild(node); 15185 } 15186 15187 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js 15188 /** 15189 * Replaces Slack paragraph markup with a double line break (later converted to 15190 * a proper paragraph). 15191 * 15192 * @param {Element} node Node to check. 15193 */ 15194 function slackParagraphCorrector(node) { 15195 if (node.nodeName !== 'SPAN') { 15196 return; 15197 } 15198 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') { 15199 return; 15200 } 15201 const { 15202 parentNode 15203 } = node; 15204 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15205 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15206 parentNode.removeChild(node); 15207 } 15208 15209 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/paste-handler.js 15210 /** 15211 * WordPress dependencies 15212 */ 15213 15214 15215 /** 15216 * Internal dependencies 15217 */ 15218 15219 15220 15221 15222 15223 15224 15225 15226 15227 15228 15229 15230 15231 15232 15233 15234 15235 15236 15237 15238 15239 15240 15241 15242 15243 15244 const log = (...args) => window?.console?.log?.(...args); 15245 15246 /** 15247 * Filters HTML to only contain phrasing content. 15248 * 15249 * @param {string} HTML The HTML to filter. 15250 * 15251 * @return {string} HTML only containing phrasing content. 15252 */ 15253 function filterInlineHTML(HTML) { 15254 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, msListIgnore, phrasingContentReducer, commentRemover]); 15255 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), { 15256 inline: true 15257 }); 15258 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 15259 15260 // Allows us to ask for this information when we get a report. 15261 log('Processed inline HTML:\n\n', HTML); 15262 return HTML; 15263 } 15264 15265 /** 15266 * Converts an HTML string to known blocks. Strips everything else. 15267 * 15268 * @param {Object} options 15269 * @param {string} [options.HTML] The HTML to convert. 15270 * @param {string} [options.plainText] Plain text version. 15271 * @param {string} [options.mode] Handle content as blocks or inline content. 15272 * * 'AUTO': Decide based on the content passed. 15273 * * 'INLINE': Always handle as inline content, and return string. 15274 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 15275 * @param {Array} [options.tagName] The tag into which content will be inserted. 15276 * 15277 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 15278 */ 15279 function pasteHandler({ 15280 HTML = '', 15281 plainText = '', 15282 mode = 'AUTO', 15283 tagName 15284 }) { 15285 // First of all, strip any meta tags. 15286 HTML = HTML.replace(/<meta[^>]+>/g, ''); 15287 // Strip Windows markers. 15288 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 15289 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); 15290 15291 // If we detect block delimiters in HTML, parse entirely as blocks. 15292 if (mode !== 'INLINE') { 15293 // Check plain text if there is no HTML. 15294 const content = HTML ? HTML : plainText; 15295 if (content.indexOf('<!-- wp:') !== -1) { 15296 return parser_parse(content); 15297 } 15298 } 15299 15300 // Normalize unicode to use composed characters. 15301 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory. 15302 // Not normalizing the content will only affect older browsers and won't 15303 // entirely break the app. 15304 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 15305 // See: https://core.trac.wordpress.org/ticket/30130 15306 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 15307 if (String.prototype.normalize) { 15308 HTML = HTML.normalize(); 15309 } 15310 15311 // Must be run before checking if it's inline content. 15312 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]); 15313 15314 // Consider plain text if: 15315 // * There is a plain text version. 15316 // * There is no HTML version, or it has no formatting. 15317 const isPlainText = plainText && (!HTML || isPlain(HTML)); 15318 15319 // Parse Markdown (and encoded HTML) if it's considered plain text. 15320 if (isPlainText) { 15321 HTML = plainText; 15322 15323 // The markdown converter (Showdown) trims whitespace. 15324 if (!/^\s+$/.test(plainText)) { 15325 HTML = markdownConverter(HTML); 15326 } 15327 } 15328 15329 // An array of HTML strings and block objects. The blocks replace matched 15330 // shortcodes. 15331 const pieces = shortcode_converter(HTML); 15332 15333 // The call to shortcodeConverter will always return more than one element 15334 // if shortcodes are matched. The reason is when shortcodes are matched 15335 // empty HTML strings are included. 15336 const hasShortcodes = pieces.length > 1; 15337 if (isPlainText && !hasShortcodes) { 15338 // Switch to inline mode if: 15339 // * The current mode is AUTO. 15340 // * The original plain text had no line breaks. 15341 // * The original plain text was not an HTML paragraph. 15342 // * The converted text is just a paragraph. 15343 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 15344 mode = 'INLINE'; 15345 } 15346 } 15347 if (mode === 'INLINE') { 15348 return filterInlineHTML(HTML); 15349 } 15350 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 15351 return filterInlineHTML(HTML); 15352 } 15353 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'); 15354 const blockContentSchema = getBlockContentSchema('paste'); 15355 const blocks = pieces.map(piece => { 15356 // Already a block from shortcode. 15357 if (typeof piece !== 'string') { 15358 return piece; 15359 } 15360 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser, divNormaliser]; 15361 const schema = { 15362 ...blockContentSchema, 15363 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 15364 ...phrasingContentSchema 15365 }; 15366 piece = deepFilterHTML(piece, filters, blockContentSchema); 15367 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema); 15368 piece = normaliseBlocks(piece); 15369 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); 15370 15371 // Allows us to ask for this information when we get a report. 15372 log('Processed HTML piece:\n\n', piece); 15373 return htmlToBlocks(piece, pasteHandler); 15374 }).flat().filter(Boolean); 15375 15376 // If we're allowed to return inline content, and there is only one 15377 // inlineable block, and the original plain text content does not have any 15378 // line breaks, then treat it as inline paste. 15379 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 15380 const trimRegex = /^[\n]+|[\n]+$/g; 15381 // Don't catch line breaks at the start or end. 15382 const trimmedPlainText = plainText.replace(trimRegex, ''); 15383 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 15384 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema).replace(trimRegex, ''); 15385 } 15386 } 15387 return blocks; 15388 } 15389 15390 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/categories.js 15391 /** 15392 * WordPress dependencies 15393 */ 15394 15395 15396 /** 15397 * Internal dependencies 15398 */ 15399 15400 15401 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 15402 15403 /** 15404 * Returns all the block categories. 15405 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 15406 * 15407 * @ignore 15408 * 15409 * @return {WPBlockCategory[]} Block categories. 15410 */ 15411 function categories_getCategories() { 15412 return (0,external_wp_data_namespaceObject.select)(store).getCategories(); 15413 } 15414 15415 /** 15416 * Sets the block categories. 15417 * 15418 * @param {WPBlockCategory[]} categories Block categories. 15419 * 15420 * @example 15421 * ```js 15422 * import { __ } from '@wordpress/i18n'; 15423 * import { store as blocksStore, setCategories } from '@wordpress/blocks'; 15424 * import { useSelect } from '@wordpress/data'; 15425 * import { Button } from '@wordpress/components'; 15426 * 15427 * const ExampleComponent = () => { 15428 * // Retrieve the list of current categories. 15429 * const blockCategories = useSelect( 15430 * ( select ) => select( blocksStore ).getCategories(), 15431 * [] 15432 * ); 15433 * 15434 * return ( 15435 * <Button 15436 * onClick={ () => { 15437 * // Add a custom category to the existing list. 15438 * setCategories( [ 15439 * ...blockCategories, 15440 * { title: 'Custom Category', slug: 'custom-category' }, 15441 * ] ); 15442 * } } 15443 * > 15444 * { __( 'Add a new custom block category' ) } 15445 * </Button> 15446 * ); 15447 * }; 15448 * ``` 15449 */ 15450 function categories_setCategories(categories) { 15451 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories); 15452 } 15453 15454 /** 15455 * Updates a category. 15456 * 15457 * @param {string} slug Block category slug. 15458 * @param {WPBlockCategory} category Object containing the category properties 15459 * that should be updated. 15460 * 15461 * @example 15462 * ```js 15463 * import { __ } from '@wordpress/i18n'; 15464 * import { updateCategory } from '@wordpress/blocks'; 15465 * import { Button } from '@wordpress/components'; 15466 * 15467 * const ExampleComponent = () => { 15468 * return ( 15469 * <Button 15470 * onClick={ () => { 15471 * updateCategory( 'text', { title: __( 'Written Word' ) } ); 15472 * } } 15473 * > 15474 * { __( 'Update Text category title' ) } 15475 * </Button> 15476 * ) ; 15477 * }; 15478 * ``` 15479 */ 15480 function categories_updateCategory(slug, category) { 15481 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category); 15482 } 15483 15484 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/templates.js 15485 /** 15486 * WordPress dependencies 15487 */ 15488 15489 15490 /** 15491 * Internal dependencies 15492 */ 15493 15494 15495 15496 15497 /** 15498 * Checks whether a list of blocks matches a template by comparing the block names. 15499 * 15500 * @param {Array} blocks Block list. 15501 * @param {Array} template Block template. 15502 * 15503 * @return {boolean} Whether the list of blocks matches a templates. 15504 */ 15505 function doBlocksMatchTemplate(blocks = [], template = []) { 15506 return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => { 15507 const block = blocks[index]; 15508 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 15509 }); 15510 } 15511 15512 /** 15513 * Synchronize a block list with a block template. 15514 * 15515 * Synchronizing a block list with a block template means that we loop over the blocks 15516 * keep the block as is if it matches the block at the same position in the template 15517 * (If it has the same name) and if doesn't match, we create a new block based on the template. 15518 * Extra blocks not present in the template are removed. 15519 * 15520 * @param {Array} blocks Block list. 15521 * @param {Array} template Block template. 15522 * 15523 * @return {Array} Updated Block list. 15524 */ 15525 function synchronizeBlocksWithTemplate(blocks = [], template) { 15526 // If no template is provided, return blocks unmodified. 15527 if (!template) { 15528 return blocks; 15529 } 15530 return template.map(([name, attributes, innerBlocksTemplate], index) => { 15531 var _blockType$attributes; 15532 const block = blocks[index]; 15533 if (block && block.name === name) { 15534 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 15535 return { 15536 ...block, 15537 innerBlocks 15538 }; 15539 } 15540 15541 // To support old templates that were using the "children" format 15542 // for the attributes using "html" strings now, we normalize the template attributes 15543 // before creating the blocks. 15544 15545 const blockType = getBlockType(name); 15546 const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html'; 15547 const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query'; 15548 const normalizeAttributes = (schema, values) => { 15549 if (!values) { 15550 return {}; 15551 } 15552 return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)])); 15553 }; 15554 const normalizeAttribute = (definition, value) => { 15555 if (isHTMLAttribute(definition) && Array.isArray(value)) { 15556 // Introduce a deprecated call at this point 15557 // When we're confident that "children" format should be removed from the templates. 15558 15559 return (0,external_wp_element_namespaceObject.renderToString)(value); 15560 } 15561 if (isQueryAttribute(definition) && value) { 15562 return value.map(subValues => { 15563 return normalizeAttributes(definition.query, subValues); 15564 }); 15565 } 15566 return value; 15567 }; 15568 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes); 15569 let [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); 15570 15571 // If a Block is undefined at this point, use the core/missing block as 15572 // a placeholder for a better user experience. 15573 if (undefined === getBlockType(blockName)) { 15574 blockAttributes = { 15575 originalName: name, 15576 originalContent: '', 15577 originalUndelimitedContent: '' 15578 }; 15579 blockName = 'core/missing'; 15580 } 15581 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 15582 }); 15583 } 15584 15585 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/index.js 15586 // The blocktype is the most important concept within the block API. It defines 15587 // all aspects of the block configuration and its interfaces, including `edit` 15588 // and `save`. The transforms specification allows converting one blocktype to 15589 // another through formulas defined by either the source or the destination. 15590 // Switching a blocktype is to be considered a one-way operation implying a 15591 // transformation in the opposite way has to be handled explicitly. 15592 15593 15594 // The block tree is composed of a collection of block nodes. Blocks contained 15595 // within other blocks are called inner blocks. An important design 15596 // consideration is that inner blocks are -- conceptually -- not part of the 15597 // territory established by the parent block that contains them. 15598 // 15599 // This has multiple practical implications: when parsing, we can safely dispose 15600 // of any block boundary found within a block from the innerHTML property when 15601 // transfering to state. Not doing so would have a compounding effect on memory 15602 // and uncertainty over the source of truth. This can be illustrated in how, 15603 // given a tree of `n` nested blocks, the entry node would have to contain the 15604 // actual content of each block while each subsequent block node in the state 15605 // tree would replicate the entire chain `n-1`, meaning the extreme end node 15606 // would have been replicated `n` times as the tree is traversed and would 15607 // generate uncertainty as to which one is to hold the current value of the 15608 // block. For composition, it also means inner blocks can effectively be child 15609 // components whose mechanisms can be shielded from the `edit` implementation 15610 // and just passed along. 15611 15612 15613 15614 15615 // While block transformations account for a specific surface of the API, there 15616 // are also raw transformations which handle arbitrary sources not made out of 15617 // blocks but producing block basaed on various heursitics. This includes 15618 // pasting rich text or HTML data. 15619 15620 15621 // The process of serialization aims to deflate the internal memory of the block 15622 // editor and its state representation back into an HTML valid string. This 15623 // process restores the document integrity and inserts invisible delimiters 15624 // around each block with HTML comment boundaries which can contain any extra 15625 // attributes needed to operate with the block later on. 15626 15627 15628 // Validation is the process of comparing a block source with its output before 15629 // there is any user input or interaction with a block. When this operation 15630 // fails -- for whatever reason -- the block is to be considered invalid. As 15631 // part of validating a block the system will attempt to run the source against 15632 // any provided deprecation definitions. 15633 // 15634 // Worth emphasizing that validation is not a case of whether the markup is 15635 // merely HTML spec-compliant but about how the editor knows to create such 15636 // markup and that its inability to create an identical result can be a strong 15637 // indicator of potential data loss (the invalidation is then a protective 15638 // measure). 15639 // 15640 // The invalidation process can also be deconstructed in phases: 1) validate the 15641 // block exists; 2) validate the source matches the output; 3) validate the 15642 // source matches deprecated outputs; 4) work through the significance of 15643 // differences. These are stacked in a way that favors performance and optimizes 15644 // for the majority of cases. That is to say, the evaluation logic can become 15645 // more sophisticated the further down it goes in the process as the cost is 15646 // accounted for. The first logic checks have to be extremely efficient since 15647 // they will be run for all valid and invalid blocks alike. However, once a 15648 // block is detected as invalid -- failing the three first steps -- it is 15649 // adequate to spend more time determining validity before throwing a conflict. 15650 15651 15652 15653 // Blocks are inherently indifferent about where the data they operate with ends 15654 // up being saved. For example, all blocks can have a static and dynamic aspect 15655 // to them depending on the needs. The static nature of a block is the `save()` 15656 // definition that is meant to be serialized into HTML and which can be left 15657 // void. Any block can also register a `render_callback` on the server, which 15658 // makes its output dynamic either in part or in its totality. 15659 // 15660 // Child blocks are defined as a relationship that builds on top of the inner 15661 // blocks mechanism. A child block is a block node of a particular type that can 15662 // only exist within the inner block boundaries of a specific parent type. This 15663 // allows block authors to compose specific blocks that are not meant to be used 15664 // outside of a specified parent block context. Thus, child blocks extend the 15665 // concept of inner blocks to support a more direct relationship between sets of 15666 // blocks. The addition of parent–child would be a subset of the inner block 15667 // functionality under the premise that certain blocks only make sense as 15668 // children of another block. 15669 15670 15671 15672 // Templates are, in a general sense, a basic collection of block nodes with any 15673 // given set of predefined attributes that are supplied as the initial state of 15674 // an inner blocks group. These nodes can, in turn, contain any number of nested 15675 // blocks within their definition. Templates allow both to specify a default 15676 // state for an editor session or a default set of blocks for any inner block 15677 // implementation within a specific block. 15678 15679 15680 15681 15682 15683 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/deprecated.js 15684 /** 15685 * WordPress dependencies 15686 */ 15687 15688 15689 /** 15690 * A Higher Order Component used to inject BlockContent using context to the 15691 * wrapped component. 15692 * 15693 * @deprecated 15694 * 15695 * @param {Component} OriginalComponent The component to enhance. 15696 * @return {Component} The same component. 15697 */ 15698 function withBlockContentContext(OriginalComponent) { 15699 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', { 15700 since: '6.1' 15701 }); 15702 return OriginalComponent; 15703 } 15704 15705 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/index.js 15706 // A "block" is the abstract term used to describe units of markup that, 15707 // when composed together, form the content or layout of a page. 15708 // The API for blocks is exposed via `wp.blocks`. 15709 // 15710 // Supported blocks are registered by calling `registerBlockType`. Once registered, 15711 // the block is made available as an option to the editor interface. 15712 // 15713 // Blocks are inferred from the HTML source of a post through a parsing mechanism 15714 // and then stored as objects in state, from which it is then rendered for editing. 15715 15716 15717 15718 15719 15720 })(); 15721 15722 (window.wp = window.wp || {}).blocks = __webpack_exports__; 15723 /******/ })() 15724 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Tue Mar 19 08:20:01 2024 | Cross-referenced by PHPXref |