[ 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 getBlockAttributesNamesByRole: () => (/* reexport */ getBlockAttributesNamesByRole), 5849 getBlockBindingsSource: () => (/* reexport */ getBlockBindingsSource), 5850 getBlockBindingsSources: () => (/* reexport */ getBlockBindingsSources), 5851 getBlockContent: () => (/* reexport */ getBlockInnerHTML), 5852 getBlockDefaultClassName: () => (/* reexport */ getBlockDefaultClassName), 5853 getBlockFromExample: () => (/* reexport */ getBlockFromExample), 5854 getBlockMenuDefaultClassName: () => (/* reexport */ getBlockMenuDefaultClassName), 5855 getBlockSupport: () => (/* reexport */ getBlockSupport), 5856 getBlockTransforms: () => (/* reexport */ getBlockTransforms), 5857 getBlockType: () => (/* reexport */ getBlockType), 5858 getBlockTypes: () => (/* reexport */ getBlockTypes), 5859 getBlockVariations: () => (/* reexport */ getBlockVariations), 5860 getCategories: () => (/* reexport */ categories_getCategories), 5861 getChildBlockNames: () => (/* reexport */ getChildBlockNames), 5862 getDefaultBlockName: () => (/* reexport */ getDefaultBlockName), 5863 getFreeformContentHandlerName: () => (/* reexport */ getFreeformContentHandlerName), 5864 getGroupingBlockName: () => (/* reexport */ getGroupingBlockName), 5865 getPhrasingContentSchema: () => (/* reexport */ deprecatedGetPhrasingContentSchema), 5866 getPossibleBlockTransformations: () => (/* reexport */ getPossibleBlockTransformations), 5867 getSaveContent: () => (/* reexport */ getSaveContent), 5868 getSaveElement: () => (/* reexport */ getSaveElement), 5869 getUnregisteredTypeHandlerName: () => (/* reexport */ getUnregisteredTypeHandlerName), 5870 hasBlockSupport: () => (/* reexport */ hasBlockSupport), 5871 hasChildBlocks: () => (/* reexport */ hasChildBlocks), 5872 hasChildBlocksWithInserterSupport: () => (/* reexport */ hasChildBlocksWithInserterSupport), 5873 isReusableBlock: () => (/* reexport */ isReusableBlock), 5874 isTemplatePart: () => (/* reexport */ isTemplatePart), 5875 isUnmodifiedBlock: () => (/* reexport */ isUnmodifiedBlock), 5876 isUnmodifiedDefaultBlock: () => (/* reexport */ isUnmodifiedDefaultBlock), 5877 isValidBlockContent: () => (/* reexport */ isValidBlockContent), 5878 isValidIcon: () => (/* reexport */ isValidIcon), 5879 node: () => (/* reexport */ node), 5880 normalizeIconObject: () => (/* reexport */ normalizeIconObject), 5881 parse: () => (/* reexport */ parser_parse), 5882 parseWithAttributeSchema: () => (/* reexport */ parseWithAttributeSchema), 5883 pasteHandler: () => (/* reexport */ pasteHandler), 5884 privateApis: () => (/* reexport */ privateApis), 5885 rawHandler: () => (/* reexport */ rawHandler), 5886 registerBlockBindingsSource: () => (/* reexport */ registerBlockBindingsSource), 5887 registerBlockCollection: () => (/* reexport */ registerBlockCollection), 5888 registerBlockStyle: () => (/* reexport */ registerBlockStyle), 5889 registerBlockType: () => (/* reexport */ registerBlockType), 5890 registerBlockVariation: () => (/* reexport */ registerBlockVariation), 5891 serialize: () => (/* reexport */ serialize), 5892 serializeRawBlock: () => (/* reexport */ serializeRawBlock), 5893 setCategories: () => (/* reexport */ categories_setCategories), 5894 setDefaultBlockName: () => (/* reexport */ setDefaultBlockName), 5895 setFreeformContentHandlerName: () => (/* reexport */ setFreeformContentHandlerName), 5896 setGroupingBlockName: () => (/* reexport */ setGroupingBlockName), 5897 setUnregisteredTypeHandlerName: () => (/* reexport */ setUnregisteredTypeHandlerName), 5898 store: () => (/* reexport */ store), 5899 switchToBlockType: () => (/* reexport */ switchToBlockType), 5900 synchronizeBlocksWithTemplate: () => (/* reexport */ synchronizeBlocksWithTemplate), 5901 unregisterBlockBindingsSource: () => (/* reexport */ unregisterBlockBindingsSource), 5902 unregisterBlockStyle: () => (/* reexport */ unregisterBlockStyle), 5903 unregisterBlockType: () => (/* reexport */ unregisterBlockType), 5904 unregisterBlockVariation: () => (/* reexport */ unregisterBlockVariation), 5905 unstable__bootstrapServerSideBlockDefinitions: () => (/* reexport */ unstable__bootstrapServerSideBlockDefinitions), 5906 updateCategory: () => (/* reexport */ categories_updateCategory), 5907 validateBlock: () => (/* reexport */ validateBlock), 5908 withBlockContentContext: () => (/* reexport */ withBlockContentContext) 5909 }); 5910 5911 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 5912 var private_selectors_namespaceObject = {}; 5913 __webpack_require__.r(private_selectors_namespaceObject); 5914 __webpack_require__.d(private_selectors_namespaceObject, { 5915 getAllBlockBindingsSources: () => (getAllBlockBindingsSources), 5916 getBlockBindingsSource: () => (private_selectors_getBlockBindingsSource), 5917 getBootstrappedBlockType: () => (getBootstrappedBlockType), 5918 getSupportedStyles: () => (getSupportedStyles), 5919 getUnprocessedBlockTypes: () => (getUnprocessedBlockTypes), 5920 hasContentRoleAttribute: () => (hasContentRoleAttribute) 5921 }); 5922 5923 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 5924 var selectors_namespaceObject = {}; 5925 __webpack_require__.r(selectors_namespaceObject); 5926 __webpack_require__.d(selectors_namespaceObject, { 5927 __experimentalHasContentRoleAttribute: () => (__experimentalHasContentRoleAttribute), 5928 getActiveBlockVariation: () => (getActiveBlockVariation), 5929 getBlockStyles: () => (getBlockStyles), 5930 getBlockSupport: () => (selectors_getBlockSupport), 5931 getBlockType: () => (selectors_getBlockType), 5932 getBlockTypes: () => (selectors_getBlockTypes), 5933 getBlockVariations: () => (selectors_getBlockVariations), 5934 getCategories: () => (getCategories), 5935 getChildBlockNames: () => (selectors_getChildBlockNames), 5936 getCollections: () => (getCollections), 5937 getDefaultBlockName: () => (selectors_getDefaultBlockName), 5938 getDefaultBlockVariation: () => (getDefaultBlockVariation), 5939 getFreeformFallbackBlockName: () => (getFreeformFallbackBlockName), 5940 getGroupingBlockName: () => (selectors_getGroupingBlockName), 5941 getUnregisteredFallbackBlockName: () => (getUnregisteredFallbackBlockName), 5942 hasBlockSupport: () => (selectors_hasBlockSupport), 5943 hasChildBlocks: () => (selectors_hasChildBlocks), 5944 hasChildBlocksWithInserterSupport: () => (selectors_hasChildBlocksWithInserterSupport), 5945 isMatchingSearchTerm: () => (isMatchingSearchTerm) 5946 }); 5947 5948 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/actions.js 5949 var actions_namespaceObject = {}; 5950 __webpack_require__.r(actions_namespaceObject); 5951 __webpack_require__.d(actions_namespaceObject, { 5952 __experimentalReapplyBlockFilters: () => (__experimentalReapplyBlockFilters), 5953 addBlockCollection: () => (addBlockCollection), 5954 addBlockStyles: () => (addBlockStyles), 5955 addBlockTypes: () => (addBlockTypes), 5956 addBlockVariations: () => (addBlockVariations), 5957 reapplyBlockTypeFilters: () => (reapplyBlockTypeFilters), 5958 removeBlockCollection: () => (removeBlockCollection), 5959 removeBlockStyles: () => (removeBlockStyles), 5960 removeBlockTypes: () => (removeBlockTypes), 5961 removeBlockVariations: () => (removeBlockVariations), 5962 setCategories: () => (setCategories), 5963 setDefaultBlockName: () => (actions_setDefaultBlockName), 5964 setFreeformFallbackBlockName: () => (setFreeformFallbackBlockName), 5965 setGroupingBlockName: () => (actions_setGroupingBlockName), 5966 setUnregisteredFallbackBlockName: () => (setUnregisteredFallbackBlockName), 5967 updateCategory: () => (updateCategory) 5968 }); 5969 5970 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 5971 var private_actions_namespaceObject = {}; 5972 __webpack_require__.r(private_actions_namespaceObject); 5973 __webpack_require__.d(private_actions_namespaceObject, { 5974 addBlockBindingsSource: () => (addBlockBindingsSource), 5975 addBootstrappedBlockType: () => (addBootstrappedBlockType), 5976 addUnprocessedBlockType: () => (addUnprocessedBlockType), 5977 removeBlockBindingsSource: () => (removeBlockBindingsSource) 5978 }); 5979 5980 ;// CONCATENATED MODULE: external ["wp","data"] 5981 const external_wp_data_namespaceObject = window["wp"]["data"]; 5982 ;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.mjs 5983 /****************************************************************************** 5984 Copyright (c) Microsoft Corporation. 5985 5986 Permission to use, copy, modify, and/or distribute this software for any 5987 purpose with or without fee is hereby granted. 5988 5989 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 5990 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 5991 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 5992 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 5993 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 5994 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 5995 PERFORMANCE OF THIS SOFTWARE. 5996 ***************************************************************************** */ 5997 /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ 5998 5999 var extendStatics = function(d, b) { 6000 extendStatics = Object.setPrototypeOf || 6001 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 6002 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 6003 return extendStatics(d, b); 6004 }; 6005 6006 function __extends(d, b) { 6007 if (typeof b !== "function" && b !== null) 6008 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 6009 extendStatics(d, b); 6010 function __() { this.constructor = d; } 6011 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6012 } 6013 6014 var __assign = function() { 6015 __assign = Object.assign || function __assign(t) { 6016 for (var s, i = 1, n = arguments.length; i < n; i++) { 6017 s = arguments[i]; 6018 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 6019 } 6020 return t; 6021 } 6022 return __assign.apply(this, arguments); 6023 } 6024 6025 function __rest(s, e) { 6026 var t = {}; 6027 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 6028 t[p] = s[p]; 6029 if (s != null && typeof Object.getOwnPropertySymbols === "function") 6030 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 6031 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 6032 t[p[i]] = s[p[i]]; 6033 } 6034 return t; 6035 } 6036 6037 function __decorate(decorators, target, key, desc) { 6038 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6039 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 6040 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6041 return c > 3 && r && Object.defineProperty(target, key, r), r; 6042 } 6043 6044 function __param(paramIndex, decorator) { 6045 return function (target, key) { decorator(target, key, paramIndex); } 6046 } 6047 6048 function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 6049 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 6050 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 6051 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 6052 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6053 var _, done = false; 6054 for (var i = decorators.length - 1; i >= 0; i--) { 6055 var context = {}; 6056 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 6057 for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 6058 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 6059 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 6060 if (kind === "accessor") { 6061 if (result === void 0) continue; 6062 if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 6063 if (_ = accept(result.get)) descriptor.get = _; 6064 if (_ = accept(result.set)) descriptor.set = _; 6065 if (_ = accept(result.init)) initializers.unshift(_); 6066 } 6067 else if (_ = accept(result)) { 6068 if (kind === "field") initializers.unshift(_); 6069 else descriptor[key] = _; 6070 } 6071 } 6072 if (target) Object.defineProperty(target, contextIn.name, descriptor); 6073 done = true; 6074 }; 6075 6076 function __runInitializers(thisArg, initializers, value) { 6077 var useValue = arguments.length > 2; 6078 for (var i = 0; i < initializers.length; i++) { 6079 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 6080 } 6081 return useValue ? value : void 0; 6082 }; 6083 6084 function __propKey(x) { 6085 return typeof x === "symbol" ? x : "".concat(x); 6086 }; 6087 6088 function __setFunctionName(f, name, prefix) { 6089 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; 6090 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); 6091 }; 6092 6093 function __metadata(metadataKey, metadataValue) { 6094 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 6095 } 6096 6097 function __awaiter(thisArg, _arguments, P, generator) { 6098 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 6099 return new (P || (P = Promise))(function (resolve, reject) { 6100 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6101 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6102 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 6103 step((generator = generator.apply(thisArg, _arguments || [])).next()); 6104 }); 6105 } 6106 6107 function __generator(thisArg, body) { 6108 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); 6109 return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 6110 function verb(n) { return function (v) { return step([n, v]); }; } 6111 function step(op) { 6112 if (f) throw new TypeError("Generator is already executing."); 6113 while (g && (g = 0, op[0] && (_ = 0)), _) try { 6114 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 6115 if (y = 0, t) op = [op[0] & 2, t.value]; 6116 switch (op[0]) { 6117 case 0: case 1: t = op; break; 6118 case 4: _.label++; return { value: op[1], done: false }; 6119 case 5: _.label++; y = op[1]; op = [0]; continue; 6120 case 7: op = _.ops.pop(); _.trys.pop(); continue; 6121 default: 6122 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 6123 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 6124 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 6125 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 6126 if (t[2]) _.ops.pop(); 6127 _.trys.pop(); continue; 6128 } 6129 op = body.call(thisArg, _); 6130 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 6131 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 6132 } 6133 } 6134 6135 var __createBinding = Object.create ? (function(o, m, k, k2) { 6136 if (k2 === undefined) k2 = k; 6137 var desc = Object.getOwnPropertyDescriptor(m, k); 6138 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6139 desc = { enumerable: true, get: function() { return m[k]; } }; 6140 } 6141 Object.defineProperty(o, k2, desc); 6142 }) : (function(o, m, k, k2) { 6143 if (k2 === undefined) k2 = k; 6144 o[k2] = m[k]; 6145 }); 6146 6147 function __exportStar(m, o) { 6148 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 6149 } 6150 6151 function __values(o) { 6152 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 6153 if (m) return m.call(o); 6154 if (o && typeof o.length === "number") return { 6155 next: function () { 6156 if (o && i >= o.length) o = void 0; 6157 return { value: o && o[i++], done: !o }; 6158 } 6159 }; 6160 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 6161 } 6162 6163 function __read(o, n) { 6164 var m = typeof Symbol === "function" && o[Symbol.iterator]; 6165 if (!m) return o; 6166 var i = m.call(o), r, ar = [], e; 6167 try { 6168 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 6169 } 6170 catch (error) { e = { error: error }; } 6171 finally { 6172 try { 6173 if (r && !r.done && (m = i["return"])) m.call(i); 6174 } 6175 finally { if (e) throw e.error; } 6176 } 6177 return ar; 6178 } 6179 6180 /** @deprecated */ 6181 function __spread() { 6182 for (var ar = [], i = 0; i < arguments.length; i++) 6183 ar = ar.concat(__read(arguments[i])); 6184 return ar; 6185 } 6186 6187 /** @deprecated */ 6188 function __spreadArrays() { 6189 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 6190 for (var r = Array(s), k = 0, i = 0; i < il; i++) 6191 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 6192 r[k] = a[j]; 6193 return r; 6194 } 6195 6196 function __spreadArray(to, from, pack) { 6197 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 6198 if (ar || !(i in from)) { 6199 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 6200 ar[i] = from[i]; 6201 } 6202 } 6203 return to.concat(ar || Array.prototype.slice.call(from)); 6204 } 6205 6206 function __await(v) { 6207 return this instanceof __await ? (this.v = v, this) : new __await(v); 6208 } 6209 6210 function __asyncGenerator(thisArg, _arguments, generator) { 6211 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6212 var g = generator.apply(thisArg, _arguments || []), i, q = []; 6213 return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; 6214 function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } 6215 function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } 6216 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 6217 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 6218 function fulfill(value) { resume("next", value); } 6219 function reject(value) { resume("throw", value); } 6220 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 6221 } 6222 6223 function __asyncDelegator(o) { 6224 var i, p; 6225 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 6226 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } 6227 } 6228 6229 function __asyncValues(o) { 6230 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6231 var m = o[Symbol.asyncIterator], i; 6232 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); 6233 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } 6234 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 6235 } 6236 6237 function __makeTemplateObject(cooked, raw) { 6238 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 6239 return cooked; 6240 }; 6241 6242 var __setModuleDefault = Object.create ? (function(o, v) { 6243 Object.defineProperty(o, "default", { enumerable: true, value: v }); 6244 }) : function(o, v) { 6245 o["default"] = v; 6246 }; 6247 6248 function __importStar(mod) { 6249 if (mod && mod.__esModule) return mod; 6250 var result = {}; 6251 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 6252 __setModuleDefault(result, mod); 6253 return result; 6254 } 6255 6256 function __importDefault(mod) { 6257 return (mod && mod.__esModule) ? mod : { default: mod }; 6258 } 6259 6260 function __classPrivateFieldGet(receiver, state, kind, f) { 6261 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 6262 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"); 6263 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 6264 } 6265 6266 function __classPrivateFieldSet(receiver, state, value, kind, f) { 6267 if (kind === "m") throw new TypeError("Private method is not writable"); 6268 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 6269 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"); 6270 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 6271 } 6272 6273 function __classPrivateFieldIn(state, receiver) { 6274 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); 6275 return typeof state === "function" ? receiver === state : state.has(receiver); 6276 } 6277 6278 function __addDisposableResource(env, value, async) { 6279 if (value !== null && value !== void 0) { 6280 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 6281 var dispose, inner; 6282 if (async) { 6283 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 6284 dispose = value[Symbol.asyncDispose]; 6285 } 6286 if (dispose === void 0) { 6287 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 6288 dispose = value[Symbol.dispose]; 6289 if (async) inner = dispose; 6290 } 6291 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 6292 if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; 6293 env.stack.push({ value: value, dispose: dispose, async: async }); 6294 } 6295 else if (async) { 6296 env.stack.push({ async: true }); 6297 } 6298 return value; 6299 } 6300 6301 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 6302 var e = new Error(message); 6303 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 6304 }; 6305 6306 function __disposeResources(env) { 6307 function fail(e) { 6308 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 6309 env.hasError = true; 6310 } 6311 var r, s = 0; 6312 function next() { 6313 while (r = env.stack.pop()) { 6314 try { 6315 if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); 6316 if (r.dispose) { 6317 var result = r.dispose.call(r.value); 6318 if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 6319 } 6320 else s |= 1; 6321 } 6322 catch (e) { 6323 fail(e); 6324 } 6325 } 6326 if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); 6327 if (env.hasError) throw env.error; 6328 } 6329 return next(); 6330 } 6331 6332 /* harmony default export */ const tslib_es6 = ({ 6333 __extends, 6334 __assign, 6335 __rest, 6336 __decorate, 6337 __param, 6338 __metadata, 6339 __awaiter, 6340 __generator, 6341 __createBinding, 6342 __exportStar, 6343 __values, 6344 __read, 6345 __spread, 6346 __spreadArrays, 6347 __spreadArray, 6348 __await, 6349 __asyncGenerator, 6350 __asyncDelegator, 6351 __asyncValues, 6352 __makeTemplateObject, 6353 __importStar, 6354 __importDefault, 6355 __classPrivateFieldGet, 6356 __classPrivateFieldSet, 6357 __classPrivateFieldIn, 6358 __addDisposableResource, 6359 __disposeResources, 6360 }); 6361 6362 ;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js 6363 /** 6364 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 6365 */ 6366 var SUPPORTED_LOCALE = { 6367 tr: { 6368 regexp: /\u0130|\u0049|\u0049\u0307/g, 6369 map: { 6370 İ: "\u0069", 6371 I: "\u0131", 6372 İ: "\u0069", 6373 }, 6374 }, 6375 az: { 6376 regexp: /\u0130/g, 6377 map: { 6378 İ: "\u0069", 6379 I: "\u0131", 6380 İ: "\u0069", 6381 }, 6382 }, 6383 lt: { 6384 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 6385 map: { 6386 I: "\u0069\u0307", 6387 J: "\u006A\u0307", 6388 Į: "\u012F\u0307", 6389 Ì: "\u0069\u0307\u0300", 6390 Í: "\u0069\u0307\u0301", 6391 Ĩ: "\u0069\u0307\u0303", 6392 }, 6393 }, 6394 }; 6395 /** 6396 * Localized lower case. 6397 */ 6398 function localeLowerCase(str, locale) { 6399 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 6400 if (lang) 6401 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 6402 return lowerCase(str); 6403 } 6404 /** 6405 * Lower case as a function. 6406 */ 6407 function lowerCase(str) { 6408 return str.toLowerCase(); 6409 } 6410 6411 ;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js 6412 6413 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 6414 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 6415 // Remove all non-word characters. 6416 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 6417 /** 6418 * Normalize the string into something other libraries can manipulate easier. 6419 */ 6420 function noCase(input, options) { 6421 if (options === void 0) { options = {}; } 6422 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; 6423 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 6424 var start = 0; 6425 var end = result.length; 6426 // Trim the delimiter from around the output string. 6427 while (result.charAt(start) === "\0") 6428 start++; 6429 while (result.charAt(end - 1) === "\0") 6430 end--; 6431 // Transform each token independently. 6432 return result.slice(start, end).split("\0").map(transform).join(delimiter); 6433 } 6434 /** 6435 * Replace `re` in the input string with the replacement value. 6436 */ 6437 function replace(input, re, value) { 6438 if (re instanceof RegExp) 6439 return input.replace(re, value); 6440 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 6441 } 6442 6443 ;// CONCATENATED MODULE: ./node_modules/pascal-case/dist.es2015/index.js 6444 6445 6446 function pascalCaseTransform(input, index) { 6447 var firstChar = input.charAt(0); 6448 var lowerChars = input.substr(1).toLowerCase(); 6449 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 6450 return "_" + firstChar + lowerChars; 6451 } 6452 return "" + firstChar.toUpperCase() + lowerChars; 6453 } 6454 function dist_es2015_pascalCaseTransformMerge(input) { 6455 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase(); 6456 } 6457 function pascalCase(input, options) { 6458 if (options === void 0) { options = {}; } 6459 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 6460 } 6461 6462 ;// CONCATENATED MODULE: ./node_modules/camel-case/dist.es2015/index.js 6463 6464 6465 function camelCaseTransform(input, index) { 6466 if (index === 0) 6467 return input.toLowerCase(); 6468 return pascalCaseTransform(input, index); 6469 } 6470 function camelCaseTransformMerge(input, index) { 6471 if (index === 0) 6472 return input.toLowerCase(); 6473 return pascalCaseTransformMerge(input); 6474 } 6475 function camelCase(input, options) { 6476 if (options === void 0) { options = {}; } 6477 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 6478 } 6479 6480 ;// CONCATENATED MODULE: external ["wp","i18n"] 6481 const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 6482 ;// CONCATENATED MODULE: ./node_modules/colord/index.mjs 6483 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()})}; 6484 6485 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs 6486 /* 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"])} 6487 6488 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs 6489 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}} 6490 6491 ;// CONCATENATED MODULE: external ["wp","element"] 6492 const external_wp_element_namespaceObject = window["wp"]["element"]; 6493 ;// CONCATENATED MODULE: external ["wp","dom"] 6494 const external_wp_dom_namespaceObject = window["wp"]["dom"]; 6495 ;// CONCATENATED MODULE: external ["wp","richText"] 6496 const external_wp_richText_namespaceObject = window["wp"]["richText"]; 6497 ;// CONCATENATED MODULE: external ["wp","deprecated"] 6498 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 6499 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 6500 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/constants.js 6501 const BLOCK_ICON_DEFAULT = 'block-default'; 6502 6503 /** 6504 * Array of valid keys in a block type settings deprecation object. 6505 * 6506 * @type {string[]} 6507 */ 6508 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 6509 const __EXPERIMENTAL_STYLE_PROPERTY = { 6510 // Kept for back-compatibility purposes. 6511 '--wp--style--color--link': { 6512 value: ['color', 'link'], 6513 support: ['color', 'link'] 6514 }, 6515 aspectRatio: { 6516 value: ['dimensions', 'aspectRatio'], 6517 support: ['dimensions', 'aspectRatio'], 6518 useEngine: true 6519 }, 6520 background: { 6521 value: ['color', 'gradient'], 6522 support: ['color', 'gradients'], 6523 useEngine: true 6524 }, 6525 backgroundColor: { 6526 value: ['color', 'background'], 6527 support: ['color', 'background'], 6528 requiresOptOut: true, 6529 useEngine: true 6530 }, 6531 backgroundImage: { 6532 value: ['background', 'backgroundImage'], 6533 support: ['background', 'backgroundImage'], 6534 useEngine: true 6535 }, 6536 backgroundRepeat: { 6537 value: ['background', 'backgroundRepeat'], 6538 support: ['background', 'backgroundRepeat'], 6539 useEngine: true 6540 }, 6541 backgroundSize: { 6542 value: ['background', 'backgroundSize'], 6543 support: ['background', 'backgroundSize'], 6544 useEngine: true 6545 }, 6546 backgroundPosition: { 6547 value: ['background', 'backgroundPosition'], 6548 support: ['background', 'backgroundPosition'], 6549 useEngine: true 6550 }, 6551 borderColor: { 6552 value: ['border', 'color'], 6553 support: ['__experimentalBorder', 'color'], 6554 useEngine: true 6555 }, 6556 borderRadius: { 6557 value: ['border', 'radius'], 6558 support: ['__experimentalBorder', 'radius'], 6559 properties: { 6560 borderTopLeftRadius: 'topLeft', 6561 borderTopRightRadius: 'topRight', 6562 borderBottomLeftRadius: 'bottomLeft', 6563 borderBottomRightRadius: 'bottomRight' 6564 }, 6565 useEngine: true 6566 }, 6567 borderStyle: { 6568 value: ['border', 'style'], 6569 support: ['__experimentalBorder', 'style'], 6570 useEngine: true 6571 }, 6572 borderWidth: { 6573 value: ['border', 'width'], 6574 support: ['__experimentalBorder', 'width'], 6575 useEngine: true 6576 }, 6577 borderTopColor: { 6578 value: ['border', 'top', 'color'], 6579 support: ['__experimentalBorder', 'color'], 6580 useEngine: true 6581 }, 6582 borderTopStyle: { 6583 value: ['border', 'top', 'style'], 6584 support: ['__experimentalBorder', 'style'], 6585 useEngine: true 6586 }, 6587 borderTopWidth: { 6588 value: ['border', 'top', 'width'], 6589 support: ['__experimentalBorder', 'width'], 6590 useEngine: true 6591 }, 6592 borderRightColor: { 6593 value: ['border', 'right', 'color'], 6594 support: ['__experimentalBorder', 'color'], 6595 useEngine: true 6596 }, 6597 borderRightStyle: { 6598 value: ['border', 'right', 'style'], 6599 support: ['__experimentalBorder', 'style'], 6600 useEngine: true 6601 }, 6602 borderRightWidth: { 6603 value: ['border', 'right', 'width'], 6604 support: ['__experimentalBorder', 'width'], 6605 useEngine: true 6606 }, 6607 borderBottomColor: { 6608 value: ['border', 'bottom', 'color'], 6609 support: ['__experimentalBorder', 'color'], 6610 useEngine: true 6611 }, 6612 borderBottomStyle: { 6613 value: ['border', 'bottom', 'style'], 6614 support: ['__experimentalBorder', 'style'], 6615 useEngine: true 6616 }, 6617 borderBottomWidth: { 6618 value: ['border', 'bottom', 'width'], 6619 support: ['__experimentalBorder', 'width'], 6620 useEngine: true 6621 }, 6622 borderLeftColor: { 6623 value: ['border', 'left', 'color'], 6624 support: ['__experimentalBorder', 'color'], 6625 useEngine: true 6626 }, 6627 borderLeftStyle: { 6628 value: ['border', 'left', 'style'], 6629 support: ['__experimentalBorder', 'style'], 6630 useEngine: true 6631 }, 6632 borderLeftWidth: { 6633 value: ['border', 'left', 'width'], 6634 support: ['__experimentalBorder', 'width'], 6635 useEngine: true 6636 }, 6637 color: { 6638 value: ['color', 'text'], 6639 support: ['color', 'text'], 6640 requiresOptOut: true, 6641 useEngine: true 6642 }, 6643 columnCount: { 6644 value: ['typography', 'textColumns'], 6645 support: ['typography', 'textColumns'], 6646 useEngine: true 6647 }, 6648 filter: { 6649 value: ['filter', 'duotone'], 6650 support: ['filter', 'duotone'] 6651 }, 6652 linkColor: { 6653 value: ['elements', 'link', 'color', 'text'], 6654 support: ['color', 'link'] 6655 }, 6656 captionColor: { 6657 value: ['elements', 'caption', 'color', 'text'], 6658 support: ['color', 'caption'] 6659 }, 6660 buttonColor: { 6661 value: ['elements', 'button', 'color', 'text'], 6662 support: ['color', 'button'] 6663 }, 6664 buttonBackgroundColor: { 6665 value: ['elements', 'button', 'color', 'background'], 6666 support: ['color', 'button'] 6667 }, 6668 headingColor: { 6669 value: ['elements', 'heading', 'color', 'text'], 6670 support: ['color', 'heading'] 6671 }, 6672 headingBackgroundColor: { 6673 value: ['elements', 'heading', 'color', 'background'], 6674 support: ['color', 'heading'] 6675 }, 6676 fontFamily: { 6677 value: ['typography', 'fontFamily'], 6678 support: ['typography', '__experimentalFontFamily'], 6679 useEngine: true 6680 }, 6681 fontSize: { 6682 value: ['typography', 'fontSize'], 6683 support: ['typography', 'fontSize'], 6684 useEngine: true 6685 }, 6686 fontStyle: { 6687 value: ['typography', 'fontStyle'], 6688 support: ['typography', '__experimentalFontStyle'], 6689 useEngine: true 6690 }, 6691 fontWeight: { 6692 value: ['typography', 'fontWeight'], 6693 support: ['typography', '__experimentalFontWeight'], 6694 useEngine: true 6695 }, 6696 lineHeight: { 6697 value: ['typography', 'lineHeight'], 6698 support: ['typography', 'lineHeight'], 6699 useEngine: true 6700 }, 6701 margin: { 6702 value: ['spacing', 'margin'], 6703 support: ['spacing', 'margin'], 6704 properties: { 6705 marginTop: 'top', 6706 marginRight: 'right', 6707 marginBottom: 'bottom', 6708 marginLeft: 'left' 6709 }, 6710 useEngine: true 6711 }, 6712 minHeight: { 6713 value: ['dimensions', 'minHeight'], 6714 support: ['dimensions', 'minHeight'], 6715 useEngine: true 6716 }, 6717 padding: { 6718 value: ['spacing', 'padding'], 6719 support: ['spacing', 'padding'], 6720 properties: { 6721 paddingTop: 'top', 6722 paddingRight: 'right', 6723 paddingBottom: 'bottom', 6724 paddingLeft: 'left' 6725 }, 6726 useEngine: true 6727 }, 6728 textAlign: { 6729 value: ['typography', 'textAlign'], 6730 support: ['typography', 'textAlign'], 6731 useEngine: false 6732 }, 6733 textDecoration: { 6734 value: ['typography', 'textDecoration'], 6735 support: ['typography', '__experimentalTextDecoration'], 6736 useEngine: true 6737 }, 6738 textTransform: { 6739 value: ['typography', 'textTransform'], 6740 support: ['typography', '__experimentalTextTransform'], 6741 useEngine: true 6742 }, 6743 letterSpacing: { 6744 value: ['typography', 'letterSpacing'], 6745 support: ['typography', '__experimentalLetterSpacing'], 6746 useEngine: true 6747 }, 6748 writingMode: { 6749 value: ['typography', 'writingMode'], 6750 support: ['typography', '__experimentalWritingMode'], 6751 useEngine: true 6752 }, 6753 '--wp--style--root--padding': { 6754 value: ['spacing', 'padding'], 6755 support: ['spacing', 'padding'], 6756 properties: { 6757 '--wp--style--root--padding-top': 'top', 6758 '--wp--style--root--padding-right': 'right', 6759 '--wp--style--root--padding-bottom': 'bottom', 6760 '--wp--style--root--padding-left': 'left' 6761 }, 6762 rootOnly: true 6763 } 6764 }; 6765 const __EXPERIMENTAL_ELEMENTS = { 6766 link: 'a:where(:not(.wp-element-button))', 6767 heading: 'h1, h2, h3, h4, h5, h6', 6768 h1: 'h1', 6769 h2: 'h2', 6770 h3: 'h3', 6771 h4: 'h4', 6772 h5: 'h5', 6773 h6: 'h6', 6774 button: '.wp-element-button, .wp-block-button__link', 6775 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', 6776 cite: 'cite' 6777 }; 6778 6779 // These paths may have three origins, custom, theme, and default, 6780 // and are expected to override other origins with custom, theme, 6781 // and default priority. 6782 const __EXPERIMENTAL_PATHS_WITH_OVERRIDE = { 6783 'color.duotone': true, 6784 'color.gradients': true, 6785 'color.palette': true, 6786 'dimensions.aspectRatios': true, 6787 'typography.fontSizes': true, 6788 'spacing.spacingSizes': true 6789 }; 6790 6791 ;// CONCATENATED MODULE: external ["wp","warning"] 6792 const external_wp_warning_namespaceObject = window["wp"]["warning"]; 6793 var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject); 6794 ;// CONCATENATED MODULE: external ["wp","privateApis"] 6795 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 6796 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/lock-unlock.js 6797 /** 6798 * WordPress dependencies 6799 */ 6800 6801 const { 6802 lock, 6803 unlock 6804 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/blocks'); 6805 6806 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/registration.js 6807 /** 6808 * WordPress dependencies 6809 */ 6810 6811 6812 6813 6814 /** 6815 * Internal dependencies 6816 */ 6817 const i18nBlockSchema = { 6818 title: "block title", 6819 description: "block description", 6820 keywords: ["block keyword"], 6821 styles: [{ 6822 label: "block style label" 6823 }], 6824 variations: [{ 6825 title: "block variation title", 6826 description: "block variation description", 6827 keywords: ["block variation keyword"] 6828 }] 6829 }; 6830 6831 6832 6833 /** 6834 * An icon type definition. One of a Dashicon slug, an element, 6835 * or a component. 6836 * 6837 * @typedef {(string|Element|Component)} WPIcon 6838 * 6839 * @see https://developer.wordpress.org/resource/dashicons/ 6840 */ 6841 6842 /** 6843 * Render behavior of a block type icon; one of a Dashicon slug, an element, 6844 * or a component. 6845 * 6846 * @typedef {WPIcon} WPBlockTypeIconRender 6847 */ 6848 6849 /** 6850 * An object describing a normalized block type icon. 6851 * 6852 * @typedef {Object} WPBlockTypeIconDescriptor 6853 * 6854 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 6855 * one of a Dashicon slug, an 6856 * element, or a component. 6857 * @property {string} background Optimal background hex string 6858 * color when displaying icon. 6859 * @property {string} foreground Optimal foreground hex string 6860 * color when displaying icon. 6861 * @property {string} shadowColor Optimal shadow hex string 6862 * color when displaying icon. 6863 */ 6864 6865 /** 6866 * Value to use to render the icon for a block type in an editor interface, 6867 * either a Dashicon slug, an element, a component, or an object describing 6868 * the icon. 6869 * 6870 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 6871 */ 6872 6873 /** 6874 * Named block variation scopes. 6875 * 6876 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 6877 */ 6878 6879 /** 6880 * An object describing a variation defined for the block type. 6881 * 6882 * @typedef {Object} WPBlockVariation 6883 * 6884 * @property {string} name The unique and machine-readable name. 6885 * @property {string} title A human-readable variation title. 6886 * @property {string} [description] A detailed variation description. 6887 * @property {string} [category] Block type category classification, 6888 * used in search interfaces to arrange 6889 * block types by category. 6890 * @property {WPIcon} [icon] An icon helping to visualize the variation. 6891 * @property {boolean} [isDefault] Indicates whether the current variation is 6892 * the default one. Defaults to `false`. 6893 * @property {Object} [attributes] Values which override block attributes. 6894 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 6895 * @property {Object} [example] Example provides structured data for 6896 * the block preview. You can set to 6897 * `undefined` to disable the preview shown 6898 * for the block type. 6899 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 6900 * is applicable. When not provided, it 6901 * assumes all available scopes. 6902 * @property {string[]} [keywords] An array of terms (which can be translated) 6903 * that help users discover the variation 6904 * while searching. 6905 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 6906 * Function that accepts a block's attributes and the 6907 * variation's attributes and determines if a variation is active. 6908 * This function doesn't try to find a match dynamically based 6909 * on all block's attributes, as in many cases some attributes are irrelevant. 6910 * An example would be for `embed` block where we only care 6911 * about `providerNameSlug` attribute's value. 6912 * We can also use a `string[]` to tell which attributes 6913 * should be compared as a shorthand. Each attributes will 6914 * be matched and the variation will be active if all of them are matching. 6915 */ 6916 6917 /** 6918 * Defined behavior of a block type. 6919 * 6920 * @typedef {Object} WPBlockType 6921 * 6922 * @property {string} name Block type's namespaced name. 6923 * @property {string} title Human-readable block type label. 6924 * @property {string} [description] A detailed block type description. 6925 * @property {string} [category] Block type category classification, 6926 * used in search interfaces to arrange 6927 * block types by category. 6928 * @property {WPBlockTypeIcon} [icon] Block type icon. 6929 * @property {string[]} [keywords] Additional keywords to produce block 6930 * type as result in search interfaces. 6931 * @property {Object} [attributes] Block type attributes. 6932 * @property {Component} [save] Optional component describing 6933 * serialized markup structure of a 6934 * block type. 6935 * @property {Component} edit Component rendering an element to 6936 * manipulate the attributes of a block 6937 * in the context of an editor. 6938 * @property {WPBlockVariation[]} [variations] The list of block variations. 6939 * @property {Object} [example] Example provides structured data for 6940 * the block preview. When not defined 6941 * then no preview is shown. 6942 */ 6943 6944 function isObject(object) { 6945 return object !== null && typeof object === 'object'; 6946 } 6947 6948 /** 6949 * Sets the server side block definition of blocks. 6950 * 6951 * Ignored from documentation due to being marked as unstable. 6952 * 6953 * @ignore 6954 * 6955 * @param {Object} definitions Server-side block definitions 6956 */ 6957 // eslint-disable-next-line camelcase 6958 function unstable__bootstrapServerSideBlockDefinitions(definitions) { 6959 const { 6960 addBootstrappedBlockType 6961 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 6962 for (const [name, blockType] of Object.entries(definitions)) { 6963 addBootstrappedBlockType(name, blockType); 6964 } 6965 } 6966 6967 /** 6968 * Gets block settings from metadata loaded from `block.json` file 6969 * 6970 * @param {Object} metadata Block metadata loaded from `block.json`. 6971 * @param {string} metadata.textdomain Textdomain to use with translations. 6972 * 6973 * @return {Object} Block settings. 6974 */ 6975 function getBlockSettingsFromMetadata({ 6976 textdomain, 6977 ...metadata 6978 }) { 6979 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations', 'blockHooks', 'allowedBlocks']; 6980 const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key))); 6981 if (textdomain) { 6982 Object.keys(i18nBlockSchema).forEach(key => { 6983 if (!settings[key]) { 6984 return; 6985 } 6986 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 6987 }); 6988 } 6989 return settings; 6990 } 6991 6992 /** 6993 * Registers a new block provided a unique name and an object defining its 6994 * behavior. Once registered, the block is made available as an option to any 6995 * editor interface where blocks are implemented. 6996 * 6997 * For more in-depth information on registering a custom block see the 6998 * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). 6999 * 7000 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 7001 * @param {Object} settings Block settings. 7002 * 7003 * @example 7004 * ```js 7005 * import { __ } from '@wordpress/i18n'; 7006 * import { registerBlockType } from '@wordpress/blocks' 7007 * 7008 * registerBlockType( 'namespace/block-name', { 7009 * title: __( 'My First Block' ), 7010 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7011 * save: () => <div>Hello from the saved content!</div>, 7012 * } ); 7013 * ``` 7014 * 7015 * @return {WPBlockType | undefined} The block, if it has been successfully registered; 7016 * otherwise `undefined`. 7017 */ 7018 function registerBlockType(blockNameOrMetadata, settings) { 7019 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 7020 if (typeof name !== 'string') { 7021 true ? external_wp_warning_default()('Block names must be strings.') : 0; 7022 return; 7023 } 7024 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 7025 true ? external_wp_warning_default()('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block') : 0; 7026 return; 7027 } 7028 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) { 7029 true ? external_wp_warning_default()('Block "' + name + '" is already registered.') : 0; 7030 return; 7031 } 7032 const { 7033 addBootstrappedBlockType, 7034 addUnprocessedBlockType 7035 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 7036 if (isObject(blockNameOrMetadata)) { 7037 const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata); 7038 addBootstrappedBlockType(name, metadata); 7039 } 7040 addUnprocessedBlockType(name, settings); 7041 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7042 } 7043 7044 /** 7045 * Translates block settings provided with metadata using the i18n schema. 7046 * 7047 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 7048 * @param {string|string[]|Object[]} settingValue Value for the block setting. 7049 * @param {string} textdomain Textdomain to use with translations. 7050 * 7051 * @return {string|string[]|Object[]} Translated setting. 7052 */ 7053 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 7054 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') { 7055 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 7056 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain); 7057 } 7058 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) { 7059 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 7060 } 7061 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) { 7062 return Object.keys(settingValue).reduce((accumulator, key) => { 7063 if (!i18nSchema[key]) { 7064 accumulator[key] = settingValue[key]; 7065 return accumulator; 7066 } 7067 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 7068 return accumulator; 7069 }, {}); 7070 } 7071 return settingValue; 7072 } 7073 7074 /** 7075 * Registers a new block collection to group blocks in the same namespace in the inserter. 7076 * 7077 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 7078 * @param {Object} settings The block collection settings. 7079 * @param {string} settings.title The title to display in the block inserter. 7080 * @param {Object} [settings.icon] The icon to display in the block inserter. 7081 * 7082 * @example 7083 * ```js 7084 * import { __ } from '@wordpress/i18n'; 7085 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks'; 7086 * 7087 * // Register the collection. 7088 * registerBlockCollection( 'my-collection', { 7089 * title: __( 'Custom Collection' ), 7090 * } ); 7091 * 7092 * // Register a block in the same namespace to add it to the collection. 7093 * registerBlockType( 'my-collection/block-name', { 7094 * title: __( 'My First Block' ), 7095 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7096 * save: () => <div>'Hello from the saved content!</div>, 7097 * } ); 7098 * ``` 7099 */ 7100 function registerBlockCollection(namespace, { 7101 title, 7102 icon 7103 }) { 7104 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon); 7105 } 7106 7107 /** 7108 * Unregisters a block collection 7109 * 7110 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 7111 * 7112 * @example 7113 * ```js 7114 * import { unregisterBlockCollection } from '@wordpress/blocks'; 7115 * 7116 * unregisterBlockCollection( 'my-collection' ); 7117 * ``` 7118 */ 7119 function unregisterBlockCollection(namespace) { 7120 dispatch(blocksStore).removeBlockCollection(namespace); 7121 } 7122 7123 /** 7124 * Unregisters a block. 7125 * 7126 * @param {string} name Block name. 7127 * 7128 * @example 7129 * ```js 7130 * import { __ } from '@wordpress/i18n'; 7131 * import { unregisterBlockType } from '@wordpress/blocks'; 7132 * 7133 * const ExampleComponent = () => { 7134 * return ( 7135 * <Button 7136 * onClick={ () => 7137 * unregisterBlockType( 'my-collection/block-name' ) 7138 * } 7139 * > 7140 * { __( 'Unregister my custom block.' ) } 7141 * </Button> 7142 * ); 7143 * }; 7144 * ``` 7145 * 7146 * @return {WPBlockType | undefined} The previous block value, if it has been successfully 7147 * unregistered; otherwise `undefined`. 7148 */ 7149 function unregisterBlockType(name) { 7150 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7151 if (!oldBlock) { 7152 true ? external_wp_warning_default()('Block "' + name + '" is not registered.') : 0; 7153 return; 7154 } 7155 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name); 7156 return oldBlock; 7157 } 7158 7159 /** 7160 * Assigns name of block for handling non-block content. 7161 * 7162 * @param {string} blockName Block name. 7163 */ 7164 function setFreeformContentHandlerName(blockName) { 7165 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName); 7166 } 7167 7168 /** 7169 * Retrieves name of block handling non-block content, or undefined if no 7170 * handler has been defined. 7171 * 7172 * @return {?string} Block name. 7173 */ 7174 function getFreeformContentHandlerName() { 7175 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName(); 7176 } 7177 7178 /** 7179 * Retrieves name of block used for handling grouping interactions. 7180 * 7181 * @return {?string} Block name. 7182 */ 7183 function getGroupingBlockName() { 7184 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName(); 7185 } 7186 7187 /** 7188 * Assigns name of block handling unregistered block types. 7189 * 7190 * @param {string} blockName Block name. 7191 */ 7192 function setUnregisteredTypeHandlerName(blockName) { 7193 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName); 7194 } 7195 7196 /** 7197 * Retrieves name of block handling unregistered block types, or undefined if no 7198 * handler has been defined. 7199 * 7200 * @return {?string} Block name. 7201 */ 7202 function getUnregisteredTypeHandlerName() { 7203 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName(); 7204 } 7205 7206 /** 7207 * Assigns the default block name. 7208 * 7209 * @param {string} name Block name. 7210 * 7211 * @example 7212 * ```js 7213 * import { setDefaultBlockName } from '@wordpress/blocks'; 7214 * 7215 * const ExampleComponent = () => { 7216 * 7217 * return ( 7218 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }> 7219 * { __( 'Set the default block to Heading' ) } 7220 * </Button> 7221 * ); 7222 * }; 7223 * ``` 7224 */ 7225 function setDefaultBlockName(name) { 7226 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name); 7227 } 7228 7229 /** 7230 * Assigns name of block for handling block grouping interactions. 7231 * 7232 * This function lets you select a different block to group other blocks in instead of the 7233 * default `core/group` block. This function must be used in a component or when the DOM is fully 7234 * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/ 7235 * 7236 * @param {string} name Block name. 7237 * 7238 * @example 7239 * ```js 7240 * import { setGroupingBlockName } from '@wordpress/blocks'; 7241 * 7242 * const ExampleComponent = () => { 7243 * 7244 * return ( 7245 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }> 7246 * { __( 'Wrap in columns' ) } 7247 * </Button> 7248 * ); 7249 * }; 7250 * ``` 7251 */ 7252 function setGroupingBlockName(name) { 7253 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name); 7254 } 7255 7256 /** 7257 * Retrieves the default block name. 7258 * 7259 * @return {?string} Block name. 7260 */ 7261 function getDefaultBlockName() { 7262 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName(); 7263 } 7264 7265 /** 7266 * Returns a registered block type. 7267 * 7268 * @param {string} name Block name. 7269 * 7270 * @return {?Object} Block type. 7271 */ 7272 function getBlockType(name) { 7273 return (0,external_wp_data_namespaceObject.select)(store)?.getBlockType(name); 7274 } 7275 7276 /** 7277 * Returns all registered blocks. 7278 * 7279 * @return {Array} Block settings. 7280 */ 7281 function getBlockTypes() { 7282 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes(); 7283 } 7284 7285 /** 7286 * Returns the block support value for a feature, if defined. 7287 * 7288 * @param {(string|Object)} nameOrType Block name or type object 7289 * @param {string} feature Feature to retrieve 7290 * @param {*} defaultSupports Default value to return if not 7291 * explicitly defined 7292 * 7293 * @return {?*} Block support value 7294 */ 7295 function getBlockSupport(nameOrType, feature, defaultSupports) { 7296 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports); 7297 } 7298 7299 /** 7300 * Returns true if the block defines support for a feature, or false otherwise. 7301 * 7302 * @param {(string|Object)} nameOrType Block name or type object. 7303 * @param {string} feature Feature to test. 7304 * @param {boolean} defaultSupports Whether feature is supported by 7305 * default if not explicitly defined. 7306 * 7307 * @return {boolean} Whether block supports feature. 7308 */ 7309 function hasBlockSupport(nameOrType, feature, defaultSupports) { 7310 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports); 7311 } 7312 7313 /** 7314 * Determines whether or not the given block is a reusable block. This is a 7315 * special block type that is used to point to a global block stored via the 7316 * API. 7317 * 7318 * @param {Object} blockOrType Block or Block Type to test. 7319 * 7320 * @return {boolean} Whether the given block is a reusable block. 7321 */ 7322 function isReusableBlock(blockOrType) { 7323 return blockOrType?.name === 'core/block'; 7324 } 7325 7326 /** 7327 * Determines whether or not the given block is a template part. This is a 7328 * special block type that allows composing a page template out of reusable 7329 * design elements. 7330 * 7331 * @param {Object} blockOrType Block or Block Type to test. 7332 * 7333 * @return {boolean} Whether the given block is a template part. 7334 */ 7335 function isTemplatePart(blockOrType) { 7336 return blockOrType?.name === 'core/template-part'; 7337 } 7338 7339 /** 7340 * Returns an array with the child blocks of a given block. 7341 * 7342 * @param {string} blockName Name of block (example: “latest-posts”). 7343 * 7344 * @return {Array} Array of child block names. 7345 */ 7346 const getChildBlockNames = blockName => { 7347 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName); 7348 }; 7349 7350 /** 7351 * Returns a boolean indicating if a block has child blocks or not. 7352 * 7353 * @param {string} blockName Name of block (example: “latest-posts”). 7354 * 7355 * @return {boolean} True if a block contains child blocks and false otherwise. 7356 */ 7357 const hasChildBlocks = blockName => { 7358 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName); 7359 }; 7360 7361 /** 7362 * Returns a boolean indicating if a block has at least one child block with inserter support. 7363 * 7364 * @param {string} blockName Block type name. 7365 * 7366 * @return {boolean} True if a block contains at least one child blocks with inserter support 7367 * and false otherwise. 7368 */ 7369 const hasChildBlocksWithInserterSupport = blockName => { 7370 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName); 7371 }; 7372 7373 /** 7374 * Registers a new block style for the given block types. 7375 * 7376 * For more information on connecting the styles with CSS 7377 * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). 7378 * 7379 * @param {string|Array} blockNames Name of blocks e.g. “core/latest-posts” or `["core/group", "core/columns"]`. 7380 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 7381 * 7382 * @example 7383 * ```js 7384 * import { __ } from '@wordpress/i18n'; 7385 * import { registerBlockStyle } from '@wordpress/blocks'; 7386 * import { Button } from '@wordpress/components'; 7387 * 7388 * 7389 * const ExampleComponent = () => { 7390 * return ( 7391 * <Button 7392 * onClick={ () => { 7393 * registerBlockStyle( 'core/quote', { 7394 * name: 'fancy-quote', 7395 * label: __( 'Fancy Quote' ), 7396 * } ); 7397 * } } 7398 * > 7399 * { __( 'Add a new block style for core/quote' ) } 7400 * </Button> 7401 * ); 7402 * }; 7403 * ``` 7404 */ 7405 const registerBlockStyle = (blockNames, styleVariation) => { 7406 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockNames, styleVariation); 7407 }; 7408 7409 /** 7410 * Unregisters a block style for the given block. 7411 * 7412 * @param {string} blockName Name of block (example: “core/latest-posts”). 7413 * @param {string} styleVariationName Name of class applied to the block. 7414 * 7415 * @example 7416 * ```js 7417 * import { __ } from '@wordpress/i18n'; 7418 * import { unregisterBlockStyle } from '@wordpress/blocks'; 7419 * import { Button } from '@wordpress/components'; 7420 * 7421 * const ExampleComponent = () => { 7422 * return ( 7423 * <Button 7424 * onClick={ () => { 7425 * unregisterBlockStyle( 'core/quote', 'plain' ); 7426 * } } 7427 * > 7428 * { __( 'Remove the "Plain" block style for core/quote' ) } 7429 * </Button> 7430 * ); 7431 * }; 7432 * ``` 7433 */ 7434 const unregisterBlockStyle = (blockName, styleVariationName) => { 7435 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName); 7436 }; 7437 7438 /** 7439 * Returns an array with the variations of a given block type. 7440 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 7441 * 7442 * @ignore 7443 * 7444 * @param {string} blockName Name of block (example: “core/columns”). 7445 * @param {WPBlockVariationScope} [scope] Block variation scope name. 7446 * 7447 * @return {(WPBlockVariation[]|void)} Block variations. 7448 */ 7449 const getBlockVariations = (blockName, scope) => { 7450 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope); 7451 }; 7452 7453 /** 7454 * Registers a new block variation for the given block type. 7455 * 7456 * For more information on block variations see 7457 * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). 7458 * 7459 * @param {string} blockName Name of the block (example: “core/columns”). 7460 * @param {WPBlockVariation} variation Object describing a block variation. 7461 * 7462 * @example 7463 * ```js 7464 * import { __ } from '@wordpress/i18n'; 7465 * import { registerBlockVariation } from '@wordpress/blocks'; 7466 * import { Button } from '@wordpress/components'; 7467 * 7468 * const ExampleComponent = () => { 7469 * return ( 7470 * <Button 7471 * onClick={ () => { 7472 * registerBlockVariation( 'core/embed', { 7473 * name: 'custom', 7474 * title: __( 'My Custom Embed' ), 7475 * attributes: { providerNameSlug: 'custom' }, 7476 * } ); 7477 * } } 7478 * > 7479 * __( 'Add a custom variation for core/embed' ) } 7480 * </Button> 7481 * ); 7482 * }; 7483 * ``` 7484 */ 7485 const registerBlockVariation = (blockName, variation) => { 7486 if (typeof variation.name !== 'string') { 7487 true ? external_wp_warning_default()('Variation names must be unique strings.') : 0; 7488 } 7489 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation); 7490 }; 7491 7492 /** 7493 * Unregisters a block variation defined for the given block type. 7494 * 7495 * @param {string} blockName Name of the block (example: “core/columns”). 7496 * @param {string} variationName Name of the variation defined for the block. 7497 * 7498 * @example 7499 * ```js 7500 * import { __ } from '@wordpress/i18n'; 7501 * import { unregisterBlockVariation } from '@wordpress/blocks'; 7502 * import { Button } from '@wordpress/components'; 7503 * 7504 * const ExampleComponent = () => { 7505 * return ( 7506 * <Button 7507 * onClick={ () => { 7508 * unregisterBlockVariation( 'core/embed', 'youtube' ); 7509 * } } 7510 * > 7511 * { __( 'Remove the YouTube variation from core/embed' ) } 7512 * </Button> 7513 * ); 7514 * }; 7515 * ``` 7516 */ 7517 const unregisterBlockVariation = (blockName, variationName) => { 7518 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName); 7519 }; 7520 7521 /** 7522 * Registers a new block bindings source with an object defining its 7523 * behavior. Once registered, the source is available to be connected 7524 * to the supported block attributes. 7525 * 7526 * @param {Object} source Properties of the source to be registered. 7527 * @param {string} source.name The unique and machine-readable name. 7528 * @param {string} [source.label] Human-readable label. Optional when it is defined in the server. 7529 * @param {Array} [source.usesContext] Optional array of context needed by the source only in the editor. 7530 * @param {Function} [source.getValues] Optional function to get the values from the source. 7531 * @param {Function} [source.setValues] Optional function to update multiple values connected to the source. 7532 * @param {Function} [source.canUserEditValue] Optional function to determine if the user can edit the value. 7533 * 7534 * @example 7535 * ```js 7536 * import { _x } from '@wordpress/i18n'; 7537 * import { registerBlockBindingsSource } from '@wordpress/blocks' 7538 * 7539 * registerBlockBindingsSource( { 7540 * name: 'plugin/my-custom-source', 7541 * label: _x( 'My Custom Source', 'block bindings source' ), 7542 * usesContext: [ 'postType' ], 7543 * getValues: getSourceValues, 7544 * setValues: updateMyCustomValuesInBatch, 7545 * canUserEditValue: () => true, 7546 * } ); 7547 * ``` 7548 */ 7549 const registerBlockBindingsSource = source => { 7550 const { 7551 name, 7552 label, 7553 usesContext, 7554 getValues, 7555 setValues, 7556 canUserEditValue, 7557 getFieldsList 7558 } = source; 7559 const existingSource = unlock((0,external_wp_data_namespaceObject.select)(store)).getBlockBindingsSource(name); 7560 7561 /* 7562 * Check if the source has been already registered on the client. 7563 * If any property expected to be "client-only" is defined, return a warning. 7564 */ 7565 const serverProps = ['label', 'usesContext']; 7566 for (const prop in existingSource) { 7567 if (!serverProps.includes(prop) && existingSource[prop]) { 7568 true ? external_wp_warning_default()('Block bindings source "' + name + '" is already registered.') : 0; 7569 return; 7570 } 7571 } 7572 7573 // Check the `name` property is correct. 7574 if (!name) { 7575 true ? external_wp_warning_default()('Block bindings source must contain a name.') : 0; 7576 return; 7577 } 7578 if (typeof name !== 'string') { 7579 true ? external_wp_warning_default()('Block bindings source name must be a string.') : 0; 7580 return; 7581 } 7582 if (/[A-Z]+/.test(name)) { 7583 true ? external_wp_warning_default()('Block bindings source name must not contain uppercase characters.') : 0; 7584 return; 7585 } 7586 if (!/^[a-z0-9/-]+$/.test(name)) { 7587 true ? external_wp_warning_default()('Block bindings source name must contain only valid characters: lowercase characters, hyphens, or digits. Example: my-plugin/my-custom-source.') : 0; 7588 return; 7589 } 7590 if (!/^[a-z0-9-]+\/[a-z0-9-]+$/.test(name)) { 7591 true ? external_wp_warning_default()('Block bindings source name must contain a namespace and valid characters. Example: my-plugin/my-custom-source.') : 0; 7592 return; 7593 } 7594 7595 // Check the `label` property is correct. 7596 7597 if (!label && !existingSource?.label) { 7598 true ? external_wp_warning_default()('Block bindings source must contain a label.') : 0; 7599 return; 7600 } 7601 if (label && typeof label !== 'string') { 7602 true ? external_wp_warning_default()('Block bindings source label must be a string.') : 0; 7603 return; 7604 } 7605 if (label && existingSource?.label && label !== existingSource?.label) { 7606 true ? external_wp_warning_default()('Block bindings "' + name + '" source label was overriden.') : 0; 7607 } 7608 7609 // Check the `usesContext` property is correct. 7610 if (usesContext && !Array.isArray(usesContext)) { 7611 true ? external_wp_warning_default()('Block bindings source usesContext must be an array.') : 0; 7612 return; 7613 } 7614 7615 // Check the `getValues` property is correct. 7616 if (getValues && typeof getValues !== 'function') { 7617 true ? external_wp_warning_default()('Block bindings source getValues must be a function.') : 0; 7618 return; 7619 } 7620 7621 // Check the `setValues` property is correct. 7622 if (setValues && typeof setValues !== 'function') { 7623 true ? external_wp_warning_default()('Block bindings source setValues must be a function.') : 0; 7624 return; 7625 } 7626 7627 // Check the `canUserEditValue` property is correct. 7628 if (canUserEditValue && typeof canUserEditValue !== 'function') { 7629 true ? external_wp_warning_default()('Block bindings source canUserEditValue must be a function.') : 0; 7630 return; 7631 } 7632 7633 // Check the `getFieldsList` property is correct. 7634 if (getFieldsList && typeof getFieldsList !== 'function') { 7635 // eslint-disable-next-line no-console 7636 true ? external_wp_warning_default()('Block bindings source getFieldsList must be a function.') : 0; 7637 return; 7638 } 7639 return unlock((0,external_wp_data_namespaceObject.dispatch)(store)).addBlockBindingsSource(source); 7640 }; 7641 7642 /** 7643 * Unregisters a block bindings source by providing its name. 7644 * 7645 * @param {string} name The name of the block bindings source to unregister. 7646 * 7647 * @example 7648 * ```js 7649 * import { unregisterBlockBindingsSource } from '@wordpress/blocks'; 7650 * 7651 * unregisterBlockBindingsSource( 'plugin/my-custom-source' ); 7652 * ``` 7653 */ 7654 function unregisterBlockBindingsSource(name) { 7655 const oldSource = getBlockBindingsSource(name); 7656 if (!oldSource) { 7657 true ? external_wp_warning_default()('Block bindings source "' + name + '" is not registered.') : 0; 7658 return; 7659 } 7660 unlock((0,external_wp_data_namespaceObject.dispatch)(store)).removeBlockBindingsSource(name); 7661 } 7662 7663 /** 7664 * Returns a registered block bindings source by its name. 7665 * 7666 * @param {string} name Block bindings source name. 7667 * 7668 * @return {?Object} Block bindings source. 7669 */ 7670 function getBlockBindingsSource(name) { 7671 return unlock((0,external_wp_data_namespaceObject.select)(store)).getBlockBindingsSource(name); 7672 } 7673 7674 /** 7675 * Returns all registered block bindings sources. 7676 * 7677 * @return {Array} Block bindings sources. 7678 */ 7679 function getBlockBindingsSources() { 7680 return unlock((0,external_wp_data_namespaceObject.select)(store)).getAllBlockBindingsSources(); 7681 } 7682 7683 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/utils.js 7684 /** 7685 * External dependencies 7686 */ 7687 7688 7689 7690 7691 /** 7692 * WordPress dependencies 7693 */ 7694 7695 7696 7697 7698 7699 7700 /** 7701 * Internal dependencies 7702 */ 7703 7704 7705 k([names, a11y]); 7706 7707 /** 7708 * Array of icon colors containing a color to be used if the icon color 7709 * was not explicitly set but the icon background color was. 7710 * 7711 * @type {Object} 7712 */ 7713 const ICON_COLORS = ['#191e23', '#f8f9f9']; 7714 7715 /** 7716 * Determines whether the block's attribute is equal to the default attribute 7717 * which means the attribute is unmodified. 7718 * @param {Object} attributeDefinition The attribute's definition of the block type. 7719 * @param {*} value The attribute's value. 7720 * @return {boolean} Whether the attribute is unmodified. 7721 */ 7722 function isUnmodifiedAttribute(attributeDefinition, value) { 7723 // Every attribute that has a default must match the default. 7724 if (attributeDefinition.hasOwnProperty('default')) { 7725 return value === attributeDefinition.default; 7726 } 7727 7728 // The rich text type is a bit different from the rest because it 7729 // has an implicit default value of an empty RichTextData instance, 7730 // so check the length of the value. 7731 if (attributeDefinition.type === 'rich-text') { 7732 return !value?.length; 7733 } 7734 7735 // Every attribute that doesn't have a default should be undefined. 7736 return value === undefined; 7737 } 7738 7739 /** 7740 * Determines whether the block's attributes are equal to the default attributes 7741 * which means the block is unmodified. 7742 * 7743 * @param {WPBlock} block Block Object 7744 * 7745 * @return {boolean} Whether the block is an unmodified block. 7746 */ 7747 function isUnmodifiedBlock(block) { 7748 var _getBlockType$attribu; 7749 return Object.entries((_getBlockType$attribu = getBlockType(block.name)?.attributes) !== null && _getBlockType$attribu !== void 0 ? _getBlockType$attribu : {}).every(([key, definition]) => { 7750 const value = block.attributes[key]; 7751 return isUnmodifiedAttribute(definition, value); 7752 }); 7753 } 7754 7755 /** 7756 * Determines whether the block is a default block and its attributes are equal 7757 * to the default attributes which means the block is unmodified. 7758 * 7759 * @param {WPBlock} block Block Object 7760 * 7761 * @return {boolean} Whether the block is an unmodified default block. 7762 */ 7763 function isUnmodifiedDefaultBlock(block) { 7764 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block); 7765 } 7766 7767 /** 7768 * Determines whether the block content is unmodified. A block content is 7769 * considered unmodified if all the attributes that have a role of 'content' 7770 * are equal to the default attributes (or undefined). 7771 * If the block does not have any attributes with a role of 'content', it 7772 * will be considered unmodified if all the attributes are equal to the default 7773 * attributes (or undefined). 7774 * 7775 * @param {WPBlock} block Block Object 7776 * @return {boolean} Whether the block content is unmodified. 7777 */ 7778 function isUnmodifiedBlockContent(block) { 7779 const contentAttributes = getBlockAttributesNamesByRole(block.name, 'content'); 7780 if (contentAttributes.length === 0) { 7781 return isUnmodifiedBlock(block); 7782 } 7783 return contentAttributes.every(key => { 7784 const definition = getBlockType(block.name)?.attributes[key]; 7785 const value = block.attributes[key]; 7786 return isUnmodifiedAttribute(definition, value); 7787 }); 7788 } 7789 7790 /** 7791 * Function that checks if the parameter is a valid icon. 7792 * 7793 * @param {*} icon Parameter to be checked. 7794 * 7795 * @return {boolean} True if the parameter is a valid icon and false otherwise. 7796 */ 7797 7798 function isValidIcon(icon) { 7799 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component); 7800 } 7801 7802 /** 7803 * Function that receives an icon as set by the blocks during the registration 7804 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 7805 * in the codebase. 7806 * 7807 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 7808 * one of a Dashicon slug, an element, or a 7809 * component. 7810 * 7811 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 7812 */ 7813 function normalizeIconObject(icon) { 7814 icon = icon || BLOCK_ICON_DEFAULT; 7815 if (isValidIcon(icon)) { 7816 return { 7817 src: icon 7818 }; 7819 } 7820 if ('background' in icon) { 7821 const colordBgColor = w(icon.background); 7822 const getColorContrast = iconColor => colordBgColor.contrast(iconColor); 7823 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast)); 7824 return { 7825 ...icon, 7826 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast), 7827 shadowColor: colordBgColor.alpha(0.3).toRgbString() 7828 }; 7829 } 7830 return icon; 7831 } 7832 7833 /** 7834 * Normalizes block type passed as param. When string is passed then 7835 * it converts it to the matching block type object. 7836 * It passes the original object otherwise. 7837 * 7838 * @param {string|Object} blockTypeOrName Block type or name. 7839 * 7840 * @return {?Object} Block type. 7841 */ 7842 function normalizeBlockType(blockTypeOrName) { 7843 if (typeof blockTypeOrName === 'string') { 7844 return getBlockType(blockTypeOrName); 7845 } 7846 return blockTypeOrName; 7847 } 7848 7849 /** 7850 * Get the label for the block, usually this is either the block title, 7851 * or the value of the block's `label` function when that's specified. 7852 * 7853 * @param {Object} blockType The block type. 7854 * @param {Object} attributes The values of the block's attributes. 7855 * @param {Object} context The intended use for the label. 7856 * 7857 * @return {string} The block label. 7858 */ 7859 function getBlockLabel(blockType, attributes, context = 'visual') { 7860 const { 7861 __experimentalLabel: getLabel, 7862 title 7863 } = blockType; 7864 const label = getLabel && getLabel(attributes, { 7865 context 7866 }); 7867 if (!label) { 7868 return title; 7869 } 7870 if (label.toPlainText) { 7871 return label.toPlainText(); 7872 } 7873 7874 // Strip any HTML (i.e. RichText formatting) before returning. 7875 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label); 7876 } 7877 7878 /** 7879 * Get a label for the block for use by screenreaders, this is more descriptive 7880 * than the visual label and includes the block title and the value of the 7881 * `getLabel` function if it's specified. 7882 * 7883 * @param {?Object} blockType The block type. 7884 * @param {Object} attributes The values of the block's attributes. 7885 * @param {?number} position The position of the block in the block list. 7886 * @param {string} [direction='vertical'] The direction of the block layout. 7887 * 7888 * @return {string} The block label. 7889 */ 7890 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') { 7891 // `title` is already localized, `label` is a user-supplied value. 7892 const title = blockType?.title; 7893 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : ''; 7894 const hasPosition = position !== undefined; 7895 7896 // getBlockLabel returns the block title as a fallback when there's no label, 7897 // if it did return the title, this function needs to avoid adding the 7898 // title twice within the accessible label. Use this `hasLabel` boolean to 7899 // handle that. 7900 const hasLabel = label && label !== title; 7901 if (hasPosition && direction === 'vertical') { 7902 if (hasLabel) { 7903 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 7904 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label); 7905 } 7906 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. */ 7907 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position); 7908 } else if (hasPosition && direction === 'horizontal') { 7909 if (hasLabel) { 7910 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 7911 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label); 7912 } 7913 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. */ 7914 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position); 7915 } 7916 if (hasLabel) { 7917 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %1: The block title. %2: The block label. */ 7918 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label); 7919 } 7920 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %s: The block title. */ 7921 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title); 7922 } 7923 function getDefault(attributeSchema) { 7924 if (attributeSchema.default !== undefined) { 7925 return attributeSchema.default; 7926 } 7927 if (attributeSchema.type === 'rich-text') { 7928 return new external_wp_richText_namespaceObject.RichTextData(); 7929 } 7930 } 7931 7932 /** 7933 * Ensure attributes contains only values defined by block type, and merge 7934 * default values for missing attributes. 7935 * 7936 * @param {string} name The block's name. 7937 * @param {Object} attributes The block's attributes. 7938 * @return {Object} The sanitized attributes. 7939 */ 7940 function __experimentalSanitizeBlockAttributes(name, attributes) { 7941 // Get the type definition associated with a registered block. 7942 const blockType = getBlockType(name); 7943 if (undefined === blockType) { 7944 throw new Error(`Block type '$name}' is not registered.`); 7945 } 7946 return Object.entries(blockType.attributes).reduce((accumulator, [key, schema]) => { 7947 const value = attributes[key]; 7948 if (undefined !== value) { 7949 if (schema.type === 'rich-text') { 7950 if (value instanceof external_wp_richText_namespaceObject.RichTextData) { 7951 accumulator[key] = value; 7952 } else if (typeof value === 'string') { 7953 accumulator[key] = external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value); 7954 } 7955 } else if (schema.type === 'string' && value instanceof external_wp_richText_namespaceObject.RichTextData) { 7956 accumulator[key] = value.toHTMLString(); 7957 } else { 7958 accumulator[key] = value; 7959 } 7960 } else { 7961 const _default = getDefault(schema); 7962 if (undefined !== _default) { 7963 accumulator[key] = _default; 7964 } 7965 } 7966 if (['node', 'children'].indexOf(schema.source) !== -1) { 7967 // Ensure value passed is always an array, which we're expecting in 7968 // the RichText component to handle the deprecated value. 7969 if (typeof accumulator[key] === 'string') { 7970 accumulator[key] = [accumulator[key]]; 7971 } else if (!Array.isArray(accumulator[key])) { 7972 accumulator[key] = []; 7973 } 7974 } 7975 return accumulator; 7976 }, {}); 7977 } 7978 7979 /** 7980 * Filter block attributes by `role` and return their names. 7981 * 7982 * @param {string} name Block attribute's name. 7983 * @param {string} role The role of a block attribute. 7984 * 7985 * @return {string[]} The attribute names that have the provided role. 7986 */ 7987 function getBlockAttributesNamesByRole(name, role) { 7988 const attributes = getBlockType(name)?.attributes; 7989 if (!attributes) { 7990 return []; 7991 } 7992 const attributesNames = Object.keys(attributes); 7993 if (!role) { 7994 return attributesNames; 7995 } 7996 return attributesNames.filter(attributeName => { 7997 const attribute = attributes[attributeName]; 7998 if (attribute?.role === role) { 7999 return true; 8000 } 8001 if (attribute?.__experimentalRole === role) { 8002 external_wp_deprecated_default()('__experimentalRole attribute', { 8003 since: '6.7', 8004 version: '6.8', 8005 alternative: 'role attribute', 8006 hint: `Check the block.json of the $name} block.` 8007 }); 8008 return true; 8009 } 8010 return false; 8011 }); 8012 } 8013 const __experimentalGetBlockAttributesNamesByRole = (...args) => { 8014 external_wp_deprecated_default()('__experimentalGetBlockAttributesNamesByRole', { 8015 since: '6.7', 8016 version: '6.8', 8017 alternative: 'getBlockAttributesNamesByRole' 8018 }); 8019 return getBlockAttributesNamesByRole(...args); 8020 }; 8021 8022 /** 8023 * Return a new object with the specified keys omitted. 8024 * 8025 * @param {Object} object Original object. 8026 * @param {Array} keys Keys to be omitted. 8027 * 8028 * @return {Object} Object with omitted keys. 8029 */ 8030 function omit(object, keys) { 8031 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 8032 } 8033 8034 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/reducer.js 8035 /** 8036 * External dependencies 8037 */ 8038 8039 8040 /** 8041 * WordPress dependencies 8042 */ 8043 8044 8045 8046 /** 8047 * Internal dependencies 8048 */ 8049 8050 8051 /** 8052 * @typedef {Object} WPBlockCategory 8053 * 8054 * @property {string} slug Unique category slug. 8055 * @property {string} title Category label, for display in user interface. 8056 */ 8057 8058 /** 8059 * Default set of categories. 8060 * 8061 * @type {WPBlockCategory[]} 8062 */ 8063 const DEFAULT_CATEGORIES = [{ 8064 slug: 'text', 8065 title: (0,external_wp_i18n_namespaceObject.__)('Text') 8066 }, { 8067 slug: 'media', 8068 title: (0,external_wp_i18n_namespaceObject.__)('Media') 8069 }, { 8070 slug: 'design', 8071 title: (0,external_wp_i18n_namespaceObject.__)('Design') 8072 }, { 8073 slug: 'widgets', 8074 title: (0,external_wp_i18n_namespaceObject.__)('Widgets') 8075 }, { 8076 slug: 'theme', 8077 title: (0,external_wp_i18n_namespaceObject.__)('Theme') 8078 }, { 8079 slug: 'embed', 8080 title: (0,external_wp_i18n_namespaceObject.__)('Embeds') 8081 }, { 8082 slug: 'reusable', 8083 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks') 8084 }]; 8085 8086 // Key block types by their name. 8087 function keyBlockTypesByName(types) { 8088 return types.reduce((newBlockTypes, block) => ({ 8089 ...newBlockTypes, 8090 [block.name]: block 8091 }), {}); 8092 } 8093 8094 // Filter items to ensure they're unique by their name. 8095 function getUniqueItemsByName(items) { 8096 return items.reduce((acc, currentItem) => { 8097 if (!acc.some(item => item.name === currentItem.name)) { 8098 acc.push(currentItem); 8099 } 8100 return acc; 8101 }, []); 8102 } 8103 function bootstrappedBlockTypes(state = {}, action) { 8104 switch (action.type) { 8105 case 'ADD_BOOTSTRAPPED_BLOCK_TYPE': 8106 const { 8107 name, 8108 blockType 8109 } = action; 8110 const serverDefinition = state[name]; 8111 let newDefinition; 8112 // Don't overwrite if already set. It covers the case when metadata 8113 // was initialized from the server. 8114 if (serverDefinition) { 8115 // The `blockHooks` prop is not yet included in the server provided 8116 // definitions and needs to be polyfilled. This can be removed when the 8117 // minimum supported WordPress is >= 6.4. 8118 if (serverDefinition.blockHooks === undefined && blockType.blockHooks) { 8119 newDefinition = { 8120 ...serverDefinition, 8121 ...newDefinition, 8122 blockHooks: blockType.blockHooks 8123 }; 8124 } 8125 8126 // The `allowedBlocks` prop is not yet included in the server provided 8127 // definitions and needs to be polyfilled. This can be removed when the 8128 // minimum supported WordPress is >= 6.5. 8129 if (serverDefinition.allowedBlocks === undefined && blockType.allowedBlocks) { 8130 newDefinition = { 8131 ...serverDefinition, 8132 ...newDefinition, 8133 allowedBlocks: blockType.allowedBlocks 8134 }; 8135 } 8136 } else { 8137 newDefinition = Object.fromEntries(Object.entries(blockType).filter(([, value]) => value !== null && value !== undefined).map(([key, value]) => [camelCase(key), value])); 8138 newDefinition.name = name; 8139 } 8140 if (newDefinition) { 8141 return { 8142 ...state, 8143 [name]: newDefinition 8144 }; 8145 } 8146 return state; 8147 case 'REMOVE_BLOCK_TYPES': 8148 return omit(state, action.names); 8149 } 8150 return state; 8151 } 8152 8153 /** 8154 * Reducer managing the unprocessed block types in a form passed when registering the by block. 8155 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters 8156 * get added or removed. 8157 * 8158 * @param {Object} state Current state. 8159 * @param {Object} action Dispatched action. 8160 * 8161 * @return {Object} Updated state. 8162 */ 8163 function unprocessedBlockTypes(state = {}, action) { 8164 switch (action.type) { 8165 case 'ADD_UNPROCESSED_BLOCK_TYPE': 8166 return { 8167 ...state, 8168 [action.name]: action.blockType 8169 }; 8170 case 'REMOVE_BLOCK_TYPES': 8171 return omit(state, action.names); 8172 } 8173 return state; 8174 } 8175 8176 /** 8177 * Reducer managing the processed block types with all filters applied. 8178 * The state is derived from the `unprocessedBlockTypes` reducer. 8179 * 8180 * @param {Object} state Current state. 8181 * @param {Object} action Dispatched action. 8182 * 8183 * @return {Object} Updated state. 8184 */ 8185 function blockTypes(state = {}, action) { 8186 switch (action.type) { 8187 case 'ADD_BLOCK_TYPES': 8188 return { 8189 ...state, 8190 ...keyBlockTypesByName(action.blockTypes) 8191 }; 8192 case 'REMOVE_BLOCK_TYPES': 8193 return omit(state, action.names); 8194 } 8195 return state; 8196 } 8197 8198 /** 8199 * Reducer managing the block styles. 8200 * 8201 * @param {Object} state Current state. 8202 * @param {Object} action Dispatched action. 8203 * 8204 * @return {Object} Updated state. 8205 */ 8206 function blockStyles(state = {}, action) { 8207 var _state$action$blockNa; 8208 switch (action.type) { 8209 case 'ADD_BLOCK_TYPES': 8210 return { 8211 ...state, 8212 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8213 var _blockType$styles, _state$blockType$name; 8214 return [name, getUniqueItemsByName([...((_blockType$styles = blockType.styles) !== null && _blockType$styles !== void 0 ? _blockType$styles : []).map(style => ({ 8215 ...style, 8216 source: 'block' 8217 })), ...((_state$blockType$name = state[blockType.name]) !== null && _state$blockType$name !== void 0 ? _state$blockType$name : []).filter(({ 8218 source 8219 }) => 'block' !== source)])]; 8220 })) 8221 }; 8222 case 'ADD_BLOCK_STYLES': 8223 const updatedStyles = {}; 8224 action.blockNames.forEach(blockName => { 8225 var _state$blockName; 8226 updatedStyles[blockName] = getUniqueItemsByName([...((_state$blockName = state[blockName]) !== null && _state$blockName !== void 0 ? _state$blockName : []), ...action.styles]); 8227 }); 8228 return { 8229 ...state, 8230 ...updatedStyles 8231 }; 8232 case 'REMOVE_BLOCK_STYLES': 8233 return { 8234 ...state, 8235 [action.blockName]: ((_state$action$blockNa = state[action.blockName]) !== null && _state$action$blockNa !== void 0 ? _state$action$blockNa : []).filter(style => action.styleNames.indexOf(style.name) === -1) 8236 }; 8237 } 8238 return state; 8239 } 8240 8241 /** 8242 * Reducer managing the block variations. 8243 * 8244 * @param {Object} state Current state. 8245 * @param {Object} action Dispatched action. 8246 * 8247 * @return {Object} Updated state. 8248 */ 8249 function blockVariations(state = {}, action) { 8250 var _state$action$blockNa2, _state$action$blockNa3; 8251 switch (action.type) { 8252 case 'ADD_BLOCK_TYPES': 8253 return { 8254 ...state, 8255 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8256 var _blockType$variations, _state$blockType$name2; 8257 return [name, getUniqueItemsByName([...((_blockType$variations = blockType.variations) !== null && _blockType$variations !== void 0 ? _blockType$variations : []).map(variation => ({ 8258 ...variation, 8259 source: 'block' 8260 })), ...((_state$blockType$name2 = state[blockType.name]) !== null && _state$blockType$name2 !== void 0 ? _state$blockType$name2 : []).filter(({ 8261 source 8262 }) => 'block' !== source)])]; 8263 })) 8264 }; 8265 case 'ADD_BLOCK_VARIATIONS': 8266 return { 8267 ...state, 8268 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa2 = state[action.blockName]) !== null && _state$action$blockNa2 !== void 0 ? _state$action$blockNa2 : []), ...action.variations]) 8269 }; 8270 case 'REMOVE_BLOCK_VARIATIONS': 8271 return { 8272 ...state, 8273 [action.blockName]: ((_state$action$blockNa3 = state[action.blockName]) !== null && _state$action$blockNa3 !== void 0 ? _state$action$blockNa3 : []).filter(variation => action.variationNames.indexOf(variation.name) === -1) 8274 }; 8275 } 8276 return state; 8277 } 8278 8279 /** 8280 * Higher-order Reducer creating a reducer keeping track of given block name. 8281 * 8282 * @param {string} setActionType Action type. 8283 * 8284 * @return {Function} Reducer. 8285 */ 8286 function createBlockNameSetterReducer(setActionType) { 8287 return (state = null, action) => { 8288 switch (action.type) { 8289 case 'REMOVE_BLOCK_TYPES': 8290 if (action.names.indexOf(state) !== -1) { 8291 return null; 8292 } 8293 return state; 8294 case setActionType: 8295 return action.name || null; 8296 } 8297 return state; 8298 }; 8299 } 8300 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 8301 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 8302 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 8303 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 8304 8305 /** 8306 * Reducer managing the categories 8307 * 8308 * @param {WPBlockCategory[]} state Current state. 8309 * @param {Object} action Dispatched action. 8310 * 8311 * @return {WPBlockCategory[]} Updated state. 8312 */ 8313 function categories(state = DEFAULT_CATEGORIES, action) { 8314 switch (action.type) { 8315 case 'SET_CATEGORIES': 8316 // Ensure, that categories are unique by slug. 8317 const uniqueCategories = new Map(); 8318 (action.categories || []).forEach(category => { 8319 uniqueCategories.set(category.slug, category); 8320 }); 8321 return [...uniqueCategories.values()]; 8322 case 'UPDATE_CATEGORY': 8323 { 8324 if (!action.category || !Object.keys(action.category).length) { 8325 return state; 8326 } 8327 const categoryToChange = state.find(({ 8328 slug 8329 }) => slug === action.slug); 8330 if (categoryToChange) { 8331 return state.map(category => { 8332 if (category.slug === action.slug) { 8333 return { 8334 ...category, 8335 ...action.category 8336 }; 8337 } 8338 return category; 8339 }); 8340 } 8341 } 8342 } 8343 return state; 8344 } 8345 function collections(state = {}, action) { 8346 switch (action.type) { 8347 case 'ADD_BLOCK_COLLECTION': 8348 return { 8349 ...state, 8350 [action.namespace]: { 8351 title: action.title, 8352 icon: action.icon 8353 } 8354 }; 8355 case 'REMOVE_BLOCK_COLLECTION': 8356 return omit(state, action.namespace); 8357 } 8358 return state; 8359 } 8360 8361 /** 8362 * Merges usesContext with existing values, potentially defined in the server registration. 8363 * 8364 * @param {string[]} existingUsesContext Existing `usesContext`. 8365 * @param {string[]} newUsesContext Newly added `usesContext`. 8366 * @return {string[]|undefined} Merged `usesContext`. 8367 */ 8368 function getMergedUsesContext(existingUsesContext = [], newUsesContext = []) { 8369 const mergedArrays = Array.from(new Set(existingUsesContext.concat(newUsesContext))); 8370 return mergedArrays.length > 0 ? mergedArrays : undefined; 8371 } 8372 function blockBindingsSources(state = {}, action) { 8373 switch (action.type) { 8374 case 'ADD_BLOCK_BINDINGS_SOURCE': 8375 // Only open this API in Gutenberg and for `core/post-meta` for the moment. 8376 let getFieldsList; 8377 if (false) {} else if (action.name === 'core/post-meta') { 8378 getFieldsList = action.getFieldsList; 8379 } 8380 return { 8381 ...state, 8382 [action.name]: { 8383 label: action.label || state[action.name]?.label, 8384 usesContext: getMergedUsesContext(state[action.name]?.usesContext, action.usesContext), 8385 getValues: action.getValues, 8386 setValues: action.setValues, 8387 // Only set `canUserEditValue` if `setValues` is also defined. 8388 canUserEditValue: action.setValues && action.canUserEditValue, 8389 getFieldsList 8390 } 8391 }; 8392 case 'REMOVE_BLOCK_BINDINGS_SOURCE': 8393 return omit(state, action.name); 8394 } 8395 return state; 8396 } 8397 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ 8398 bootstrappedBlockTypes, 8399 unprocessedBlockTypes, 8400 blockTypes, 8401 blockStyles, 8402 blockVariations, 8403 defaultBlockName, 8404 freeformFallbackBlockName, 8405 unregisteredFallbackBlockName, 8406 groupingBlockName, 8407 categories, 8408 collections, 8409 blockBindingsSources 8410 })); 8411 8412 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js 8413 var remove_accents = __webpack_require__(9681); 8414 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 8415 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/utils.js 8416 /** 8417 * Helper util to return a value from a certain path of the object. 8418 * Path is specified as either: 8419 * - a string of properties, separated by dots, for example: "x.y". 8420 * - an array of properties, for example `[ 'x', 'y' ]`. 8421 * You can also specify a default value in case the result is nullish. 8422 * 8423 * @param {Object} object Input object. 8424 * @param {string|Array} path Path to the object property. 8425 * @param {*} defaultValue Default value if the value at the specified path is nullish. 8426 * @return {*} Value of the object property at the specified path. 8427 */ 8428 const getValueFromObjectPath = (object, path, defaultValue) => { 8429 var _value; 8430 const normalizedPath = Array.isArray(path) ? path : path.split('.'); 8431 let value = object; 8432 normalizedPath.forEach(fieldName => { 8433 value = value?.[fieldName]; 8434 }); 8435 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 8436 }; 8437 function utils_isObject(candidate) { 8438 return typeof candidate === 'object' && candidate.constructor === Object && candidate !== null; 8439 } 8440 8441 /** 8442 * Determine whether a set of object properties matches a given object. 8443 * 8444 * Given an object of block attributes and an object of variation attributes, 8445 * this function checks recursively whether all the variation attributes are 8446 * present in the block attributes object. 8447 * 8448 * @param {Object} blockAttributes The object to inspect. 8449 * @param {Object} variationAttributes The object of property values to match. 8450 * @return {boolean} Whether the block attributes match the variation attributes. 8451 */ 8452 function matchesAttributes(blockAttributes, variationAttributes) { 8453 if (utils_isObject(blockAttributes) && utils_isObject(variationAttributes)) { 8454 return Object.entries(variationAttributes).every(([key, value]) => matchesAttributes(blockAttributes?.[key], value)); 8455 } 8456 return blockAttributes === variationAttributes; 8457 } 8458 8459 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 8460 /** 8461 * WordPress dependencies 8462 */ 8463 8464 8465 8466 /** 8467 * Internal dependencies 8468 */ 8469 8470 8471 8472 const ROOT_BLOCK_SUPPORTS = ['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'padding', 'contentSize', 'wideSize', 'blockGap', 'textDecoration', 'textTransform', 'letterSpacing']; 8473 8474 /** 8475 * Filters the list of supported styles for a given element. 8476 * 8477 * @param {string[]} blockSupports list of supported styles. 8478 * @param {string|undefined} name block name. 8479 * @param {string|undefined} element element name. 8480 * 8481 * @return {string[]} filtered list of supported styles. 8482 */ 8483 function filterElementBlockSupports(blockSupports, name, element) { 8484 return blockSupports.filter(support => { 8485 if (support === 'fontSize' && element === 'heading') { 8486 return false; 8487 } 8488 8489 // This is only available for links 8490 if (support === 'textDecoration' && !name && element !== 'link') { 8491 return false; 8492 } 8493 8494 // This is only available for heading, button, caption and text 8495 if (support === 'textTransform' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 8496 return false; 8497 } 8498 8499 // This is only available for heading, button, caption and text 8500 if (support === 'letterSpacing' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 8501 return false; 8502 } 8503 8504 // Text columns is only available for blocks. 8505 if (support === 'textColumns' && !name) { 8506 return false; 8507 } 8508 return true; 8509 }); 8510 } 8511 8512 /** 8513 * Returns the list of supported styles for a given block name and element. 8514 */ 8515 const getSupportedStyles = (0,external_wp_data_namespaceObject.createSelector)((state, name, element) => { 8516 if (!name) { 8517 return filterElementBlockSupports(ROOT_BLOCK_SUPPORTS, name, element); 8518 } 8519 const blockType = selectors_getBlockType(state, name); 8520 if (!blockType) { 8521 return []; 8522 } 8523 const supportKeys = []; 8524 8525 // Check for blockGap support. 8526 // Block spacing support doesn't map directly to a single style property, so needs to be handled separately. 8527 if (blockType?.supports?.spacing?.blockGap) { 8528 supportKeys.push('blockGap'); 8529 } 8530 8531 // check for shadow support 8532 if (blockType?.supports?.shadow) { 8533 supportKeys.push('shadow'); 8534 } 8535 Object.keys(__EXPERIMENTAL_STYLE_PROPERTY).forEach(styleName => { 8536 if (!__EXPERIMENTAL_STYLE_PROPERTY[styleName].support) { 8537 return; 8538 } 8539 8540 // Opting out means that, for certain support keys like background color, 8541 // blocks have to explicitly set the support value false. If the key is 8542 // unset, we still enable it. 8543 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].requiresOptOut) { 8544 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].support[0] in blockType.supports && getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support) !== false) { 8545 supportKeys.push(styleName); 8546 return; 8547 } 8548 } 8549 if (getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support, false)) { 8550 supportKeys.push(styleName); 8551 } 8552 }); 8553 return filterElementBlockSupports(supportKeys, name, element); 8554 }, (state, name) => [state.blockTypes[name]]); 8555 8556 /** 8557 * Returns the bootstrapped block type metadata for a give block name. 8558 * 8559 * @param {Object} state Data state. 8560 * @param {string} name Block name. 8561 * 8562 * @return {Object} Bootstrapped block type metadata for a block. 8563 */ 8564 function getBootstrappedBlockType(state, name) { 8565 return state.bootstrappedBlockTypes[name]; 8566 } 8567 8568 /** 8569 * Returns all the unprocessed (before applying the `registerBlockType` filter) 8570 * block type settings as passed during block registration. 8571 * 8572 * @param {Object} state Data state. 8573 * 8574 * @return {Array} Unprocessed block type settings for all blocks. 8575 */ 8576 function getUnprocessedBlockTypes(state) { 8577 return state.unprocessedBlockTypes; 8578 } 8579 8580 /** 8581 * Returns all the block bindings sources registered. 8582 * 8583 * @param {Object} state Data state. 8584 * 8585 * @return {Object} All the registered sources and their properties. 8586 */ 8587 function getAllBlockBindingsSources(state) { 8588 return state.blockBindingsSources; 8589 } 8590 8591 /** 8592 * Returns a specific block bindings source. 8593 * 8594 * @param {Object} state Data state. 8595 * @param {string} sourceName Name of the source to get. 8596 * 8597 * @return {Object} The specific block binding source and its properties. 8598 */ 8599 function private_selectors_getBlockBindingsSource(state, sourceName) { 8600 return state.blockBindingsSources[sourceName]; 8601 } 8602 8603 /** 8604 * Determines if any of the block type's attributes have 8605 * the content role attribute. 8606 * 8607 * @param {Object} state Data state. 8608 * @param {string} blockTypeName Block type name. 8609 * @return {boolean} Whether block type has content role attribute. 8610 */ 8611 const hasContentRoleAttribute = (state, blockTypeName) => { 8612 const blockType = selectors_getBlockType(state, blockTypeName); 8613 if (!blockType) { 8614 return false; 8615 } 8616 return Object.values(blockType.attributes).some(({ 8617 role, 8618 __experimentalRole 8619 }) => { 8620 if (role === 'content') { 8621 return true; 8622 } 8623 if (__experimentalRole === 'content') { 8624 external_wp_deprecated_default()('__experimentalRole attribute', { 8625 since: '6.7', 8626 version: '6.8', 8627 alternative: 'role attribute', 8628 hint: `Check the block.json of the $blockTypeName} block.` 8629 }); 8630 return true; 8631 } 8632 return false; 8633 }); 8634 }; 8635 8636 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 8637 /** 8638 * External dependencies 8639 */ 8640 8641 8642 /** 8643 * WordPress dependencies 8644 */ 8645 8646 8647 8648 8649 /** 8650 * Internal dependencies 8651 */ 8652 8653 8654 8655 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 8656 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 8657 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 8658 8659 /** 8660 * Given a block name or block type object, returns the corresponding 8661 * normalized block type object. 8662 * 8663 * @param {Object} state Blocks state. 8664 * @param {(string|Object)} nameOrType Block name or type object 8665 * 8666 * @return {Object} Block type object. 8667 */ 8668 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType; 8669 8670 /** 8671 * Returns all the available block types. 8672 * 8673 * @param {Object} state Data state. 8674 * 8675 * @example 8676 * ```js 8677 * import { store as blocksStore } from '@wordpress/blocks'; 8678 * import { useSelect } from '@wordpress/data'; 8679 * 8680 * const ExampleComponent = () => { 8681 * const blockTypes = useSelect( 8682 * ( select ) => select( blocksStore ).getBlockTypes(), 8683 * [] 8684 * ); 8685 * 8686 * return ( 8687 * <ul> 8688 * { blockTypes.map( ( block ) => ( 8689 * <li key={ block.name }>{ block.title }</li> 8690 * ) ) } 8691 * </ul> 8692 * ); 8693 * }; 8694 * ``` 8695 * 8696 * @return {Array} Block Types. 8697 */ 8698 const selectors_getBlockTypes = (0,external_wp_data_namespaceObject.createSelector)(state => Object.values(state.blockTypes), state => [state.blockTypes]); 8699 8700 /** 8701 * Returns a block type by name. 8702 * 8703 * @param {Object} state Data state. 8704 * @param {string} name Block type name. 8705 * 8706 * @example 8707 * ```js 8708 * import { store as blocksStore } from '@wordpress/blocks'; 8709 * import { useSelect } from '@wordpress/data'; 8710 * 8711 * const ExampleComponent = () => { 8712 * const paragraphBlock = useSelect( ( select ) => 8713 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ), 8714 * [] 8715 * ); 8716 * 8717 * return ( 8718 * <ul> 8719 * { paragraphBlock && 8720 * Object.entries( paragraphBlock.supports ).map( 8721 * ( blockSupportsEntry ) => { 8722 * const [ propertyName, value ] = blockSupportsEntry; 8723 * return ( 8724 * <li 8725 * key={ propertyName } 8726 * >{ `${ propertyName } : ${ value }` }</li> 8727 * ); 8728 * } 8729 * ) } 8730 * </ul> 8731 * ); 8732 * }; 8733 * ``` 8734 * 8735 * @return {Object?} Block Type. 8736 */ 8737 function selectors_getBlockType(state, name) { 8738 return state.blockTypes[name]; 8739 } 8740 8741 /** 8742 * Returns block styles by block name. 8743 * 8744 * @param {Object} state Data state. 8745 * @param {string} name Block type name. 8746 * 8747 * @example 8748 * ```js 8749 * import { store as blocksStore } from '@wordpress/blocks'; 8750 * import { useSelect } from '@wordpress/data'; 8751 * 8752 * const ExampleComponent = () => { 8753 * const buttonBlockStyles = useSelect( ( select ) => 8754 * select( blocksStore ).getBlockStyles( 'core/button' ), 8755 * [] 8756 * ); 8757 * 8758 * return ( 8759 * <ul> 8760 * { buttonBlockStyles && 8761 * buttonBlockStyles.map( ( style ) => ( 8762 * <li key={ style.name }>{ style.label }</li> 8763 * ) ) } 8764 * </ul> 8765 * ); 8766 * }; 8767 * ``` 8768 * 8769 * @return {Array?} Block Styles. 8770 */ 8771 function getBlockStyles(state, name) { 8772 return state.blockStyles[name]; 8773 } 8774 8775 /** 8776 * Returns block variations by block name. 8777 * 8778 * @param {Object} state Data state. 8779 * @param {string} blockName Block type name. 8780 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8781 * 8782 * @example 8783 * ```js 8784 * import { store as blocksStore } from '@wordpress/blocks'; 8785 * import { useSelect } from '@wordpress/data'; 8786 * 8787 * const ExampleComponent = () => { 8788 * const socialLinkVariations = useSelect( ( select ) => 8789 * select( blocksStore ).getBlockVariations( 'core/social-link' ), 8790 * [] 8791 * ); 8792 * 8793 * return ( 8794 * <ul> 8795 * { socialLinkVariations && 8796 * socialLinkVariations.map( ( variation ) => ( 8797 * <li key={ variation.name }>{ variation.title }</li> 8798 * ) ) } 8799 * </ul> 8800 * ); 8801 * }; 8802 * ``` 8803 * 8804 * @return {(WPBlockVariation[]|void)} Block variations. 8805 */ 8806 const selectors_getBlockVariations = (0,external_wp_data_namespaceObject.createSelector)((state, blockName, scope) => { 8807 const variations = state.blockVariations[blockName]; 8808 if (!variations || !scope) { 8809 return variations; 8810 } 8811 return variations.filter(variation => { 8812 // For backward compatibility reasons, variation's scope defaults to 8813 // `block` and `inserter` when not set. 8814 return (variation.scope || ['block', 'inserter']).includes(scope); 8815 }); 8816 }, (state, blockName) => [state.blockVariations[blockName]]); 8817 8818 /** 8819 * Returns the active block variation for a given block based on its attributes. 8820 * Variations are determined by their `isActive` property. 8821 * Which is either an array of block attribute keys or a function. 8822 * 8823 * In case of an array of block attribute keys, the `attributes` are compared 8824 * to the variation's attributes using strict equality check. 8825 * 8826 * In case of function type, the function should accept a block's attributes 8827 * and the variation's attributes and determines if a variation is active. 8828 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 8829 * 8830 * @param {Object} state Data state. 8831 * @param {string} blockName Name of block (example: “core/columns”). 8832 * @param {Object} attributes Block attributes used to determine active variation. 8833 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8834 * 8835 * @example 8836 * ```js 8837 * import { __ } from '@wordpress/i18n'; 8838 * import { store as blocksStore } from '@wordpress/blocks'; 8839 * import { store as blockEditorStore } from '@wordpress/block-editor'; 8840 * import { useSelect } from '@wordpress/data'; 8841 * 8842 * const ExampleComponent = () => { 8843 * // This example assumes that a core/embed block is the first block in the Block Editor. 8844 * const activeBlockVariation = useSelect( ( select ) => { 8845 * // Retrieve the list of blocks. 8846 * const [ firstBlock ] = select( blockEditorStore ).getBlocks() 8847 * 8848 * // Return the active block variation for the first block. 8849 * return select( blocksStore ).getActiveBlockVariation( 8850 * firstBlock.name, 8851 * firstBlock.attributes 8852 * ); 8853 * }, [] ); 8854 * 8855 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? ( 8856 * <p>{ __( 'Spotify variation' ) }</p> 8857 * ) : ( 8858 * <p>{ __( 'Other variation' ) }</p> 8859 * ); 8860 * }; 8861 * ``` 8862 * 8863 * @return {(WPBlockVariation|undefined)} Active block variation. 8864 */ 8865 function getActiveBlockVariation(state, blockName, attributes, scope) { 8866 const variations = selectors_getBlockVariations(state, blockName, scope); 8867 if (!variations) { 8868 return variations; 8869 } 8870 const blockType = selectors_getBlockType(state, blockName); 8871 const attributeKeys = Object.keys(blockType?.attributes || {}); 8872 let match; 8873 let maxMatchedAttributes = 0; 8874 for (const variation of variations) { 8875 if (Array.isArray(variation.isActive)) { 8876 const definedAttributes = variation.isActive.filter(attribute => { 8877 // We support nested attribute paths, e.g. `layout.type`. 8878 // In this case, we need to check if the part before the 8879 // first dot is a known attribute. 8880 const topLevelAttribute = attribute.split('.')[0]; 8881 return attributeKeys.includes(topLevelAttribute); 8882 }); 8883 const definedAttributesLength = definedAttributes.length; 8884 if (definedAttributesLength === 0) { 8885 continue; 8886 } 8887 const isMatch = definedAttributes.every(attribute => { 8888 const variationAttributeValue = getValueFromObjectPath(variation.attributes, attribute); 8889 if (variationAttributeValue === undefined) { 8890 return false; 8891 } 8892 let blockAttributeValue = getValueFromObjectPath(attributes, attribute); 8893 if (blockAttributeValue instanceof external_wp_richText_namespaceObject.RichTextData) { 8894 blockAttributeValue = blockAttributeValue.toHTMLString(); 8895 } 8896 return matchesAttributes(blockAttributeValue, variationAttributeValue); 8897 }); 8898 if (isMatch && definedAttributesLength > maxMatchedAttributes) { 8899 match = variation; 8900 maxMatchedAttributes = definedAttributesLength; 8901 } 8902 } else if (variation.isActive?.(attributes, variation.attributes)) { 8903 // If isActive is a function, we cannot know how many attributes it matches. 8904 // This means that we cannot compare the specificity of our matches, 8905 // and simply return the best match we have found. 8906 return match || variation; 8907 } 8908 } 8909 return match; 8910 } 8911 8912 /** 8913 * Returns the default block variation for the given block type. 8914 * When there are multiple variations annotated as the default one, 8915 * the last added item is picked. This simplifies registering overrides. 8916 * When there is no default variation set, it returns the first item. 8917 * 8918 * @param {Object} state Data state. 8919 * @param {string} blockName Block type name. 8920 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8921 * 8922 * @example 8923 * ```js 8924 * import { __, sprintf } from '@wordpress/i18n'; 8925 * import { store as blocksStore } from '@wordpress/blocks'; 8926 * import { useSelect } from '@wordpress/data'; 8927 * 8928 * const ExampleComponent = () => { 8929 * const defaultEmbedBlockVariation = useSelect( ( select ) => 8930 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ), 8931 * [] 8932 * ); 8933 * 8934 * return ( 8935 * defaultEmbedBlockVariation && ( 8936 * <p> 8937 * { sprintf( 8938 * __( 'core/embed default variation: %s' ), 8939 * defaultEmbedBlockVariation.title 8940 * ) } 8941 * </p> 8942 * ) 8943 * ); 8944 * }; 8945 * ``` 8946 * 8947 * @return {?WPBlockVariation} The default block variation. 8948 */ 8949 function getDefaultBlockVariation(state, blockName, scope) { 8950 const variations = selectors_getBlockVariations(state, blockName, scope); 8951 const defaultVariation = [...variations].reverse().find(({ 8952 isDefault 8953 }) => !!isDefault); 8954 return defaultVariation || variations[0]; 8955 } 8956 8957 /** 8958 * Returns all the available block categories. 8959 * 8960 * @param {Object} state Data state. 8961 * 8962 * @example 8963 * ```js 8964 * import { store as blocksStore } from '@wordpress/blocks'; 8965 * import { useSelect, } from '@wordpress/data'; 8966 * 8967 * const ExampleComponent = () => { 8968 * const blockCategories = useSelect( ( select ) => 8969 * select( blocksStore ).getCategories(), 8970 * [] 8971 * ); 8972 * 8973 * return ( 8974 * <ul> 8975 * { blockCategories.map( ( category ) => ( 8976 * <li key={ category.slug }>{ category.title }</li> 8977 * ) ) } 8978 * </ul> 8979 * ); 8980 * }; 8981 * ``` 8982 * 8983 * @return {WPBlockCategory[]} Categories list. 8984 */ 8985 function getCategories(state) { 8986 return state.categories; 8987 } 8988 8989 /** 8990 * Returns all the available collections. 8991 * 8992 * @param {Object} state Data state. 8993 * 8994 * @example 8995 * ```js 8996 * import { store as blocksStore } from '@wordpress/blocks'; 8997 * import { useSelect } from '@wordpress/data'; 8998 * 8999 * const ExampleComponent = () => { 9000 * const blockCollections = useSelect( ( select ) => 9001 * select( blocksStore ).getCollections(), 9002 * [] 9003 * ); 9004 * 9005 * return ( 9006 * <ul> 9007 * { Object.values( blockCollections ).length > 0 && 9008 * Object.values( blockCollections ).map( ( collection ) => ( 9009 * <li key={ collection.title }>{ collection.title }</li> 9010 * ) ) } 9011 * </ul> 9012 * ); 9013 * }; 9014 * ``` 9015 * 9016 * @return {Object} Collections list. 9017 */ 9018 function getCollections(state) { 9019 return state.collections; 9020 } 9021 9022 /** 9023 * Returns the name of the default block name. 9024 * 9025 * @param {Object} state Data state. 9026 * 9027 * @example 9028 * ```js 9029 * import { __, sprintf } from '@wordpress/i18n'; 9030 * import { store as blocksStore } from '@wordpress/blocks'; 9031 * import { useSelect } from '@wordpress/data'; 9032 * 9033 * const ExampleComponent = () => { 9034 * const defaultBlockName = useSelect( ( select ) => 9035 * select( blocksStore ).getDefaultBlockName(), 9036 * [] 9037 * ); 9038 * 9039 * return ( 9040 * defaultBlockName && ( 9041 * <p> 9042 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) } 9043 * </p> 9044 * ) 9045 * ); 9046 * }; 9047 * ``` 9048 * 9049 * @return {string?} Default block name. 9050 */ 9051 function selectors_getDefaultBlockName(state) { 9052 return state.defaultBlockName; 9053 } 9054 9055 /** 9056 * Returns the name of the block for handling non-block content. 9057 * 9058 * @param {Object} state Data state. 9059 * 9060 * @example 9061 * ```js 9062 * import { __, sprintf } from '@wordpress/i18n'; 9063 * import { store as blocksStore } from '@wordpress/blocks'; 9064 * import { useSelect } from '@wordpress/data'; 9065 * 9066 * const ExampleComponent = () => { 9067 * const freeformFallbackBlockName = useSelect( ( select ) => 9068 * select( blocksStore ).getFreeformFallbackBlockName(), 9069 * [] 9070 * ); 9071 * 9072 * return ( 9073 * freeformFallbackBlockName && ( 9074 * <p> 9075 * { sprintf( __( 9076 * 'Freeform fallback block name: %s' ), 9077 * freeformFallbackBlockName 9078 * ) } 9079 * </p> 9080 * ) 9081 * ); 9082 * }; 9083 * ``` 9084 * 9085 * @return {string?} Name of the block for handling non-block content. 9086 */ 9087 function getFreeformFallbackBlockName(state) { 9088 return state.freeformFallbackBlockName; 9089 } 9090 9091 /** 9092 * Returns the name of the block for handling unregistered blocks. 9093 * 9094 * @param {Object} state Data state. 9095 * 9096 * @example 9097 * ```js 9098 * import { __, sprintf } from '@wordpress/i18n'; 9099 * import { store as blocksStore } from '@wordpress/blocks'; 9100 * import { useSelect } from '@wordpress/data'; 9101 * 9102 * const ExampleComponent = () => { 9103 * const unregisteredFallbackBlockName = useSelect( ( select ) => 9104 * select( blocksStore ).getUnregisteredFallbackBlockName(), 9105 * [] 9106 * ); 9107 * 9108 * return ( 9109 * unregisteredFallbackBlockName && ( 9110 * <p> 9111 * { sprintf( __( 9112 * 'Unregistered fallback block name: %s' ), 9113 * unregisteredFallbackBlockName 9114 * ) } 9115 * </p> 9116 * ) 9117 * ); 9118 * }; 9119 * ``` 9120 * 9121 * @return {string?} Name of the block for handling unregistered blocks. 9122 */ 9123 function getUnregisteredFallbackBlockName(state) { 9124 return state.unregisteredFallbackBlockName; 9125 } 9126 9127 /** 9128 * Returns the name of the block for handling the grouping of blocks. 9129 * 9130 * @param {Object} state Data state. 9131 * 9132 * @example 9133 * ```js 9134 * import { __, sprintf } from '@wordpress/i18n'; 9135 * import { store as blocksStore } from '@wordpress/blocks'; 9136 * import { useSelect } from '@wordpress/data'; 9137 * 9138 * const ExampleComponent = () => { 9139 * const groupingBlockName = useSelect( ( select ) => 9140 * select( blocksStore ).getGroupingBlockName(), 9141 * [] 9142 * ); 9143 * 9144 * return ( 9145 * groupingBlockName && ( 9146 * <p> 9147 * { sprintf( 9148 * __( 'Default grouping block name: %s' ), 9149 * groupingBlockName 9150 * ) } 9151 * </p> 9152 * ) 9153 * ); 9154 * }; 9155 * ``` 9156 * 9157 * @return {string?} Name of the block for handling the grouping of blocks. 9158 */ 9159 function selectors_getGroupingBlockName(state) { 9160 return state.groupingBlockName; 9161 } 9162 9163 /** 9164 * Returns an array with the child blocks of a given block. 9165 * 9166 * @param {Object} state Data state. 9167 * @param {string} blockName Block type name. 9168 * 9169 * @example 9170 * ```js 9171 * import { store as blocksStore } from '@wordpress/blocks'; 9172 * import { useSelect } from '@wordpress/data'; 9173 * 9174 * const ExampleComponent = () => { 9175 * const childBlockNames = useSelect( ( select ) => 9176 * select( blocksStore ).getChildBlockNames( 'core/navigation' ), 9177 * [] 9178 * ); 9179 * 9180 * return ( 9181 * <ul> 9182 * { childBlockNames && 9183 * childBlockNames.map( ( child ) => ( 9184 * <li key={ child }>{ child }</li> 9185 * ) ) } 9186 * </ul> 9187 * ); 9188 * }; 9189 * ``` 9190 * 9191 * @return {Array} Array of child block names. 9192 */ 9193 const selectors_getChildBlockNames = (0,external_wp_data_namespaceObject.createSelector)((state, blockName) => { 9194 return selectors_getBlockTypes(state).filter(blockType => { 9195 return blockType.parent?.includes(blockName); 9196 }).map(({ 9197 name 9198 }) => name); 9199 }, state => [state.blockTypes]); 9200 9201 /** 9202 * Returns the block support value for a feature, if defined. 9203 * 9204 * @param {Object} state Data state. 9205 * @param {(string|Object)} nameOrType Block name or type object 9206 * @param {Array|string} feature Feature to retrieve 9207 * @param {*} defaultSupports Default value to return if not 9208 * explicitly defined 9209 * 9210 * @example 9211 * ```js 9212 * import { __, sprintf } from '@wordpress/i18n'; 9213 * import { store as blocksStore } from '@wordpress/blocks'; 9214 * import { useSelect } from '@wordpress/data'; 9215 * 9216 * const ExampleComponent = () => { 9217 * const paragraphBlockSupportValue = useSelect( ( select ) => 9218 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ), 9219 * [] 9220 * ); 9221 * 9222 * return ( 9223 * <p> 9224 * { sprintf( 9225 * __( 'core/paragraph supports.anchor value: %s' ), 9226 * paragraphBlockSupportValue 9227 * ) } 9228 * </p> 9229 * ); 9230 * }; 9231 * ``` 9232 * 9233 * @return {?*} Block support value 9234 */ 9235 const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 9236 const blockType = getNormalizedBlockType(state, nameOrType); 9237 if (!blockType?.supports) { 9238 return defaultSupports; 9239 } 9240 return getValueFromObjectPath(blockType.supports, feature, defaultSupports); 9241 }; 9242 9243 /** 9244 * Returns true if the block defines support for a feature, or false otherwise. 9245 * 9246 * @param {Object} state Data state. 9247 * @param {(string|Object)} nameOrType Block name or type object. 9248 * @param {string} feature Feature to test. 9249 * @param {boolean} defaultSupports Whether feature is supported by 9250 * default if not explicitly defined. 9251 * 9252 * @example 9253 * ```js 9254 * import { __, sprintf } from '@wordpress/i18n'; 9255 * import { store as blocksStore } from '@wordpress/blocks'; 9256 * import { useSelect } from '@wordpress/data'; 9257 * 9258 * const ExampleComponent = () => { 9259 * const paragraphBlockSupportClassName = useSelect( ( select ) => 9260 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ), 9261 * [] 9262 * ); 9263 * 9264 * return ( 9265 * <p> 9266 * { sprintf( 9267 * __( 'core/paragraph supports custom class name?: %s' ), 9268 * paragraphBlockSupportClassName 9269 * ) } 9270 * /p> 9271 * ); 9272 * }; 9273 * ``` 9274 * 9275 * @return {boolean} Whether block supports feature. 9276 */ 9277 function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupports) { 9278 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports); 9279 } 9280 9281 /** 9282 * Normalizes a search term string: removes accents, converts to lowercase, removes extra whitespace. 9283 * 9284 * @param {string|null|undefined} term Search term to normalize. 9285 * @return {string} Normalized search term. 9286 */ 9287 function getNormalizedSearchTerm(term) { 9288 return remove_accents_default()(term !== null && term !== void 0 ? term : '').toLowerCase().trim(); 9289 } 9290 9291 /** 9292 * Returns true if the block type by the given name or object value matches a 9293 * search term, or false otherwise. 9294 * 9295 * @param {Object} state Blocks state. 9296 * @param {(string|Object)} nameOrType Block name or type object. 9297 * @param {string} searchTerm Search term by which to filter. 9298 * 9299 * @example 9300 * ```js 9301 * import { __, sprintf } from '@wordpress/i18n'; 9302 * import { store as blocksStore } from '@wordpress/blocks'; 9303 * import { useSelect } from '@wordpress/data'; 9304 * 9305 * const ExampleComponent = () => { 9306 * const termFound = useSelect( 9307 * ( select ) => 9308 * select( blocksStore ).isMatchingSearchTerm( 9309 * 'core/navigation', 9310 * 'theme' 9311 * ), 9312 * [] 9313 * ); 9314 * 9315 * return ( 9316 * <p> 9317 * { sprintf( 9318 * __( 9319 * 'Search term was found in the title, keywords, category or description in block.json: %s' 9320 * ), 9321 * termFound 9322 * ) } 9323 * </p> 9324 * ); 9325 * }; 9326 * ``` 9327 * 9328 * @return {Object[]} Whether block type matches search term. 9329 */ 9330 function isMatchingSearchTerm(state, nameOrType, searchTerm = '') { 9331 const blockType = getNormalizedBlockType(state, nameOrType); 9332 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 9333 const isSearchMatch = candidate => getNormalizedSearchTerm(candidate).includes(normalizedSearchTerm); 9334 return isSearchMatch(blockType.title) || blockType.keywords?.some(isSearchMatch) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description); 9335 } 9336 9337 /** 9338 * Returns a boolean indicating if a block has child blocks or not. 9339 * 9340 * @param {Object} state Data state. 9341 * @param {string} blockName Block type name. 9342 * 9343 * @example 9344 * ```js 9345 * import { __, sprintf } from '@wordpress/i18n'; 9346 * import { store as blocksStore } from '@wordpress/blocks'; 9347 * import { useSelect } from '@wordpress/data'; 9348 * 9349 * const ExampleComponent = () => { 9350 * const navigationBlockHasChildBlocks = useSelect( ( select ) => 9351 * select( blocksStore ).hasChildBlocks( 'core/navigation' ), 9352 * [] 9353 * ); 9354 * 9355 * return ( 9356 * <p> 9357 * { sprintf( 9358 * __( 'core/navigation has child blocks: %s' ), 9359 * navigationBlockHasChildBlocks 9360 * ) } 9361 * </p> 9362 * ); 9363 * }; 9364 * ``` 9365 * 9366 * @return {boolean} True if a block contains child blocks and false otherwise. 9367 */ 9368 const selectors_hasChildBlocks = (state, blockName) => { 9369 return selectors_getChildBlockNames(state, blockName).length > 0; 9370 }; 9371 9372 /** 9373 * Returns a boolean indicating if a block has at least one child block with inserter support. 9374 * 9375 * @param {Object} state Data state. 9376 * @param {string} blockName Block type name. 9377 * 9378 * @example 9379 * ```js 9380 * import { __, sprintf } from '@wordpress/i18n'; 9381 * import { store as blocksStore } from '@wordpress/blocks'; 9382 * import { useSelect } from '@wordpress/data'; 9383 * 9384 * const ExampleComponent = () => { 9385 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) => 9386 * select( blocksStore ).hasChildBlocksWithInserterSupport( 9387 * 'core/navigation' 9388 * ), 9389 * [] 9390 * ); 9391 * 9392 * return ( 9393 * <p> 9394 * { sprintf( 9395 * __( 'core/navigation has child blocks with inserter support: %s' ), 9396 * navigationBlockHasChildBlocksWithInserterSupport 9397 * ) } 9398 * </p> 9399 * ); 9400 * }; 9401 * ``` 9402 * 9403 * @return {boolean} True if a block contains at least one child blocks with inserter support 9404 * and false otherwise. 9405 */ 9406 const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => { 9407 return selectors_getChildBlockNames(state, blockName).some(childBlockName => { 9408 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true); 9409 }); 9410 }; 9411 const __experimentalHasContentRoleAttribute = (...args) => { 9412 external_wp_deprecated_default()('__experimentalHasContentRoleAttribute', { 9413 since: '6.7', 9414 version: '6.8', 9415 hint: 'This is a private selector.' 9416 }); 9417 return hasContentRoleAttribute(...args); 9418 }; 9419 9420 ;// CONCATENATED MODULE: ./node_modules/is-plain-object/dist/is-plain-object.mjs 9421 /*! 9422 * is-plain-object <https://github.com/jonschlinkert/is-plain-object> 9423 * 9424 * Copyright (c) 2014-2017, Jon Schlinkert. 9425 * Released under the MIT License. 9426 */ 9427 9428 function is_plain_object_isObject(o) { 9429 return Object.prototype.toString.call(o) === '[object Object]'; 9430 } 9431 9432 function isPlainObject(o) { 9433 var ctor,prot; 9434 9435 if (is_plain_object_isObject(o) === false) return false; 9436 9437 // If has modified constructor 9438 ctor = o.constructor; 9439 if (ctor === undefined) return true; 9440 9441 // If has modified prototype 9442 prot = ctor.prototype; 9443 if (is_plain_object_isObject(prot) === false) return false; 9444 9445 // If constructor does not have an Object-specific method 9446 if (prot.hasOwnProperty('isPrototypeOf') === false) { 9447 return false; 9448 } 9449 9450 // Most likely a plain Object 9451 return true; 9452 } 9453 9454 9455 9456 // EXTERNAL MODULE: ./node_modules/react-is/index.js 9457 var react_is = __webpack_require__(8529); 9458 ;// CONCATENATED MODULE: external ["wp","hooks"] 9459 const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 9460 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/process-block-type.js 9461 /** 9462 * External dependencies 9463 */ 9464 9465 9466 9467 /** 9468 * WordPress dependencies 9469 */ 9470 9471 9472 9473 9474 /** 9475 * Internal dependencies 9476 */ 9477 9478 9479 9480 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9481 9482 /** 9483 * Mapping of legacy category slugs to their latest normal values, used to 9484 * accommodate updates of the default set of block categories. 9485 * 9486 * @type {Record<string,string>} 9487 */ 9488 const LEGACY_CATEGORY_MAPPING = { 9489 common: 'text', 9490 formatting: 'text', 9491 layout: 'design' 9492 }; 9493 9494 /** 9495 * Merge block variations bootstrapped from the server and client. 9496 * 9497 * When a variation is registered in both places, its properties are merged. 9498 * 9499 * @param {Array} bootstrappedVariations - A block type variations from the server. 9500 * @param {Array} clientVariations - A block type variations from the client. 9501 * @return {Array} The merged array of block variations. 9502 */ 9503 function mergeBlockVariations(bootstrappedVariations = [], clientVariations = []) { 9504 const result = [...bootstrappedVariations]; 9505 clientVariations.forEach(clientVariation => { 9506 const index = result.findIndex(bootstrappedVariation => bootstrappedVariation.name === clientVariation.name); 9507 if (index !== -1) { 9508 result[index] = { 9509 ...result[index], 9510 ...clientVariation 9511 }; 9512 } else { 9513 result.push(clientVariation); 9514 } 9515 }); 9516 return result; 9517 } 9518 9519 /** 9520 * Takes the unprocessed block type settings, merges them with block type metadata 9521 * and applies all the existing filters for the registered block type. 9522 * Next, it validates all the settings and performs additional processing to the block type definition. 9523 * 9524 * @param {string} name Block name. 9525 * @param {WPBlockType} blockSettings Unprocessed block type settings. 9526 * 9527 * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. 9528 */ 9529 const processBlockType = (name, blockSettings) => ({ 9530 select 9531 }) => { 9532 const bootstrappedBlockType = select.getBootstrappedBlockType(name); 9533 const blockType = { 9534 name, 9535 icon: BLOCK_ICON_DEFAULT, 9536 keywords: [], 9537 attributes: {}, 9538 providesContext: {}, 9539 usesContext: [], 9540 selectors: {}, 9541 supports: {}, 9542 styles: [], 9543 blockHooks: {}, 9544 save: () => null, 9545 ...bootstrappedBlockType, 9546 ...blockSettings, 9547 // blockType.variations can be defined as a filePath. 9548 variations: mergeBlockVariations(Array.isArray(bootstrappedBlockType?.variations) ? bootstrappedBlockType.variations : [], Array.isArray(blockSettings?.variations) ? blockSettings.variations : []) 9549 }; 9550 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', blockType, name, null); 9551 if (settings.description && typeof settings.description !== 'string') { 9552 external_wp_deprecated_default()('Declaring non-string block descriptions', { 9553 since: '6.2' 9554 }); 9555 } 9556 if (settings.deprecated) { 9557 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( 9558 // Only keep valid deprecation keys. 9559 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', 9560 // Merge deprecation keys with pre-filter settings 9561 // so that filters that depend on specific keys being 9562 // present don't fail. 9563 { 9564 // Omit deprecation keys here so that deprecations 9565 // can opt out of specific keys like "supports". 9566 ...omit(blockType, DEPRECATED_ENTRY_KEYS), 9567 ...deprecation 9568 }, blockType.name, deprecation)).filter(([key]) => DEPRECATED_ENTRY_KEYS.includes(key)))); 9569 } 9570 if (!isPlainObject(settings)) { 9571 true ? external_wp_warning_default()('Block settings must be a valid object.') : 0; 9572 return; 9573 } 9574 if (typeof settings.save !== 'function') { 9575 true ? external_wp_warning_default()('The "save" property must be a valid function.') : 0; 9576 return; 9577 } 9578 if ('edit' in settings && !(0,react_is.isValidElementType)(settings.edit)) { 9579 true ? external_wp_warning_default()('The "edit" property must be a valid component.') : 0; 9580 return; 9581 } 9582 9583 // Canonicalize legacy categories to equivalent fallback. 9584 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 9585 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 9586 } 9587 if ('category' in settings && !select.getCategories().some(({ 9588 slug 9589 }) => slug === settings.category)) { 9590 true ? external_wp_warning_default()('The block "' + name + '" is registered with an invalid category "' + settings.category + '".') : 0; 9591 delete settings.category; 9592 } 9593 if (!('title' in settings) || settings.title === '') { 9594 true ? external_wp_warning_default()('The block "' + name + '" must have a title.') : 0; 9595 return; 9596 } 9597 if (typeof settings.title !== 'string') { 9598 true ? external_wp_warning_default()('Block titles must be strings.') : 0; 9599 return; 9600 } 9601 settings.icon = normalizeIconObject(settings.icon); 9602 if (!isValidIcon(settings.icon.src)) { 9603 true ? external_wp_warning_default()('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional') : 0; 9604 return; 9605 } 9606 return settings; 9607 }; 9608 9609 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/actions.js 9610 /** 9611 * WordPress dependencies 9612 */ 9613 9614 9615 /** 9616 * Internal dependencies 9617 */ 9618 9619 9620 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 9621 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9622 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 9623 9624 /** 9625 * Returns an action object used in signalling that block types have been added. 9626 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks. 9627 * 9628 * @ignore 9629 * 9630 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added. 9631 * 9632 * 9633 * @return {Object} Action object. 9634 */ 9635 function addBlockTypes(blockTypes) { 9636 return { 9637 type: 'ADD_BLOCK_TYPES', 9638 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes] 9639 }; 9640 } 9641 9642 /** 9643 * Signals that all block types should be computed again. 9644 * It uses stored unprocessed block types and all the most recent list of registered filters. 9645 * 9646 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 9647 * 1. Filter A. 9648 * 2. Block B. 9649 * 3. Block C. 9650 * 4. Filter D. 9651 * 5. Filter E. 9652 * 6. Block F. 9653 * 7. Filter G. 9654 * In this scenario some filters would not get applied for all blocks because they are registered too late. 9655 */ 9656 function reapplyBlockTypeFilters() { 9657 return ({ 9658 dispatch, 9659 select 9660 }) => { 9661 const processedBlockTypes = []; 9662 for (const [name, settings] of Object.entries(select.getUnprocessedBlockTypes())) { 9663 const result = dispatch(processBlockType(name, settings)); 9664 if (result) { 9665 processedBlockTypes.push(result); 9666 } 9667 } 9668 if (!processedBlockTypes.length) { 9669 return; 9670 } 9671 dispatch.addBlockTypes(processedBlockTypes); 9672 }; 9673 } 9674 function __experimentalReapplyBlockFilters() { 9675 external_wp_deprecated_default()('wp.data.dispatch( "core/blocks" ).__experimentalReapplyBlockFilters', { 9676 since: '6.4', 9677 alternative: 'reapplyBlockFilters' 9678 }); 9679 return reapplyBlockTypeFilters(); 9680 } 9681 9682 /** 9683 * Returns an action object used to remove a registered block type. 9684 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks. 9685 * 9686 * @ignore 9687 * 9688 * @param {string|string[]} names Block name or array of block names to be removed. 9689 * 9690 * 9691 * @return {Object} Action object. 9692 */ 9693 function removeBlockTypes(names) { 9694 return { 9695 type: 'REMOVE_BLOCK_TYPES', 9696 names: Array.isArray(names) ? names : [names] 9697 }; 9698 } 9699 9700 /** 9701 * Returns an action object used in signalling that new block styles have been added. 9702 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks. 9703 * 9704 * @param {string|Array} blockNames Block names to register new styles for. 9705 * @param {Array|Object} styles Block style object or array of block style objects. 9706 * 9707 * @ignore 9708 * 9709 * @return {Object} Action object. 9710 */ 9711 function addBlockStyles(blockNames, styles) { 9712 return { 9713 type: 'ADD_BLOCK_STYLES', 9714 styles: Array.isArray(styles) ? styles : [styles], 9715 blockNames: Array.isArray(blockNames) ? blockNames : [blockNames] 9716 }; 9717 } 9718 9719 /** 9720 * Returns an action object used in signalling that block styles have been removed. 9721 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks. 9722 * 9723 * @ignore 9724 * 9725 * @param {string} blockName Block name. 9726 * @param {Array|string} styleNames Block style names or array of block style names. 9727 * 9728 * @return {Object} Action object. 9729 */ 9730 function removeBlockStyles(blockName, styleNames) { 9731 return { 9732 type: 'REMOVE_BLOCK_STYLES', 9733 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames], 9734 blockName 9735 }; 9736 } 9737 9738 /** 9739 * Returns an action object used in signalling that new block variations have been added. 9740 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks. 9741 * 9742 * @ignore 9743 * 9744 * @param {string} blockName Block name. 9745 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 9746 * 9747 * @return {Object} Action object. 9748 */ 9749 function addBlockVariations(blockName, variations) { 9750 return { 9751 type: 'ADD_BLOCK_VARIATIONS', 9752 variations: Array.isArray(variations) ? variations : [variations], 9753 blockName 9754 }; 9755 } 9756 9757 /** 9758 * Returns an action object used in signalling that block variations have been removed. 9759 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks. 9760 * 9761 * @ignore 9762 * 9763 * @param {string} blockName Block name. 9764 * @param {string|string[]} variationNames Block variation names. 9765 * 9766 * @return {Object} Action object. 9767 */ 9768 function removeBlockVariations(blockName, variationNames) { 9769 return { 9770 type: 'REMOVE_BLOCK_VARIATIONS', 9771 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames], 9772 blockName 9773 }; 9774 } 9775 9776 /** 9777 * Returns an action object used to set the default block name. 9778 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks. 9779 * 9780 * @ignore 9781 * 9782 * @param {string} name Block name. 9783 * 9784 * @return {Object} Action object. 9785 */ 9786 function actions_setDefaultBlockName(name) { 9787 return { 9788 type: 'SET_DEFAULT_BLOCK_NAME', 9789 name 9790 }; 9791 } 9792 9793 /** 9794 * Returns an action object used to set the name of the block used as a fallback 9795 * for non-block content. 9796 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks. 9797 * 9798 * @ignore 9799 * 9800 * @param {string} name Block name. 9801 * 9802 * @return {Object} Action object. 9803 */ 9804 function setFreeformFallbackBlockName(name) { 9805 return { 9806 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 9807 name 9808 }; 9809 } 9810 9811 /** 9812 * Returns an action object used to set the name of the block used as a fallback 9813 * for unregistered blocks. 9814 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks. 9815 * 9816 * @ignore 9817 * 9818 * @param {string} name Block name. 9819 * 9820 * @return {Object} Action object. 9821 */ 9822 function setUnregisteredFallbackBlockName(name) { 9823 return { 9824 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 9825 name 9826 }; 9827 } 9828 9829 /** 9830 * Returns an action object used to set the name of the block used 9831 * when grouping other blocks 9832 * eg: in "Group/Ungroup" interactions 9833 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks. 9834 * 9835 * @ignore 9836 * 9837 * @param {string} name Block name. 9838 * 9839 * @return {Object} Action object. 9840 */ 9841 function actions_setGroupingBlockName(name) { 9842 return { 9843 type: 'SET_GROUPING_BLOCK_NAME', 9844 name 9845 }; 9846 } 9847 9848 /** 9849 * Returns an action object used to set block categories. 9850 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks. 9851 * 9852 * @ignore 9853 * 9854 * @param {WPBlockCategory[]} categories Block categories. 9855 * 9856 * @return {Object} Action object. 9857 */ 9858 function setCategories(categories) { 9859 return { 9860 type: 'SET_CATEGORIES', 9861 categories 9862 }; 9863 } 9864 9865 /** 9866 * Returns an action object used to update a category. 9867 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks. 9868 * 9869 * @ignore 9870 * 9871 * @param {string} slug Block category slug. 9872 * @param {Object} category Object containing the category properties that should be updated. 9873 * 9874 * @return {Object} Action object. 9875 */ 9876 function updateCategory(slug, category) { 9877 return { 9878 type: 'UPDATE_CATEGORY', 9879 slug, 9880 category 9881 }; 9882 } 9883 9884 /** 9885 * Returns an action object used to add block collections 9886 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks. 9887 * 9888 * @ignore 9889 * 9890 * @param {string} namespace The namespace of the blocks to put in the collection 9891 * @param {string} title The title to display in the block inserter 9892 * @param {Object} icon (optional) The icon to display in the block inserter 9893 * 9894 * @return {Object} Action object. 9895 */ 9896 function addBlockCollection(namespace, title, icon) { 9897 return { 9898 type: 'ADD_BLOCK_COLLECTION', 9899 namespace, 9900 title, 9901 icon 9902 }; 9903 } 9904 9905 /** 9906 * Returns an action object used to remove block collections 9907 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks. 9908 * 9909 * @ignore 9910 * 9911 * @param {string} namespace The namespace of the blocks to put in the collection 9912 * 9913 * @return {Object} Action object. 9914 */ 9915 function removeBlockCollection(namespace) { 9916 return { 9917 type: 'REMOVE_BLOCK_COLLECTION', 9918 namespace 9919 }; 9920 } 9921 9922 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 9923 /** 9924 * Internal dependencies 9925 */ 9926 9927 9928 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9929 9930 /** 9931 * Add bootstrapped block type metadata to the store. These metadata usually come from 9932 * the `block.json` file and are either statically boostrapped from the server, or 9933 * passed as the `metadata` parameter to the `registerBlockType` function. 9934 * 9935 * @param {string} name Block name. 9936 * @param {WPBlockType} blockType Block type metadata. 9937 */ 9938 function addBootstrappedBlockType(name, blockType) { 9939 return { 9940 type: 'ADD_BOOTSTRAPPED_BLOCK_TYPE', 9941 name, 9942 blockType 9943 }; 9944 } 9945 9946 /** 9947 * Add unprocessed block type settings to the store. These data are passed as the 9948 * `settings` parameter to the client-side `registerBlockType` function. 9949 * 9950 * @param {string} name Block name. 9951 * @param {WPBlockType} blockType Unprocessed block type settings. 9952 */ 9953 function addUnprocessedBlockType(name, blockType) { 9954 return ({ 9955 dispatch 9956 }) => { 9957 dispatch({ 9958 type: 'ADD_UNPROCESSED_BLOCK_TYPE', 9959 name, 9960 blockType 9961 }); 9962 const processedBlockType = dispatch(processBlockType(name, blockType)); 9963 if (!processedBlockType) { 9964 return; 9965 } 9966 dispatch.addBlockTypes(processedBlockType); 9967 }; 9968 } 9969 9970 /** 9971 * Adds new block bindings source. 9972 * 9973 * @param {string} source Name of the source to register. 9974 */ 9975 function addBlockBindingsSource(source) { 9976 return { 9977 type: 'ADD_BLOCK_BINDINGS_SOURCE', 9978 name: source.name, 9979 label: source.label, 9980 usesContext: source.usesContext, 9981 getValues: source.getValues, 9982 setValues: source.setValues, 9983 canUserEditValue: source.canUserEditValue, 9984 getFieldsList: source.getFieldsList 9985 }; 9986 } 9987 9988 /** 9989 * Removes existing block bindings source. 9990 * 9991 * @param {string} name Name of the source to remove. 9992 */ 9993 function removeBlockBindingsSource(name) { 9994 return { 9995 type: 'REMOVE_BLOCK_BINDINGS_SOURCE', 9996 name 9997 }; 9998 } 9999 10000 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/constants.js 10001 const STORE_NAME = 'core/blocks'; 10002 10003 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/index.js 10004 /** 10005 * WordPress dependencies 10006 */ 10007 10008 10009 /** 10010 * Internal dependencies 10011 */ 10012 10013 10014 10015 10016 10017 10018 10019 10020 /** 10021 * Store definition for the blocks namespace. 10022 * 10023 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 10024 * 10025 * @type {Object} 10026 */ 10027 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 10028 reducer: reducer, 10029 selectors: selectors_namespaceObject, 10030 actions: actions_namespaceObject 10031 }); 10032 (0,external_wp_data_namespaceObject.register)(store); 10033 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 10034 unlock(store).registerPrivateActions(private_actions_namespaceObject); 10035 10036 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/native.js 10037 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); 10038 /* harmony default export */ const esm_browser_native = ({ 10039 randomUUID 10040 }); 10041 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js 10042 // Unique ID creation requires a high quality random # generator. In the browser we therefore 10043 // require the crypto API and do not support built-in fallback to lower quality random number 10044 // generators (like Math.random()). 10045 let getRandomValues; 10046 const rnds8 = new Uint8Array(16); 10047 function rng() { 10048 // lazy load so that environments that need to polyfill have a chance to do so 10049 if (!getRandomValues) { 10050 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. 10051 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); 10052 10053 if (!getRandomValues) { 10054 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 10055 } 10056 } 10057 10058 return getRandomValues(rnds8); 10059 } 10060 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js 10061 10062 /** 10063 * Convert array of 16 byte values to UUID string format of the form: 10064 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 10065 */ 10066 10067 const byteToHex = []; 10068 10069 for (let i = 0; i < 256; ++i) { 10070 byteToHex.push((i + 0x100).toString(16).slice(1)); 10071 } 10072 10073 function unsafeStringify(arr, offset = 0) { 10074 // Note: Be careful editing this code! It's been tuned for performance 10075 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 10076 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]]; 10077 } 10078 10079 function stringify(arr, offset = 0) { 10080 const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one 10081 // of the following: 10082 // - One or more input array values don't map to a hex octet (leading to 10083 // "undefined" in the uuid) 10084 // - Invalid input values for the RFC `version` or `variant` fields 10085 10086 if (!validate(uuid)) { 10087 throw TypeError('Stringified UUID is invalid'); 10088 } 10089 10090 return uuid; 10091 } 10092 10093 /* harmony default export */ const esm_browser_stringify = ((/* unused pure expression or super */ null && (stringify))); 10094 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js 10095 10096 10097 10098 10099 function v4(options, buf, offset) { 10100 if (esm_browser_native.randomUUID && !buf && !options) { 10101 return esm_browser_native.randomUUID(); 10102 } 10103 10104 options = options || {}; 10105 const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 10106 10107 rnds[6] = rnds[6] & 0x0f | 0x40; 10108 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 10109 10110 if (buf) { 10111 offset = offset || 0; 10112 10113 for (let i = 0; i < 16; ++i) { 10114 buf[offset + i] = rnds[i]; 10115 } 10116 10117 return buf; 10118 } 10119 10120 return unsafeStringify(rnds); 10121 } 10122 10123 /* harmony default export */ const esm_browser_v4 = (v4); 10124 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/factory.js 10125 /** 10126 * External dependencies 10127 */ 10128 10129 10130 /** 10131 * WordPress dependencies 10132 */ 10133 10134 10135 /** 10136 * Internal dependencies 10137 */ 10138 10139 10140 10141 /** 10142 * Returns a block object given its type and attributes. 10143 * 10144 * @param {string} name Block name. 10145 * @param {Object} attributes Block attributes. 10146 * @param {?Array} innerBlocks Nested blocks. 10147 * 10148 * @return {Object} Block object. 10149 */ 10150 function createBlock(name, attributes = {}, innerBlocks = []) { 10151 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 10152 const clientId = esm_browser_v4(); 10153 10154 // Blocks are stored with a unique ID, the assigned type name, the block 10155 // attributes, and their inner blocks. 10156 return { 10157 clientId, 10158 name, 10159 isValid: true, 10160 attributes: sanitizedAttributes, 10161 innerBlocks 10162 }; 10163 } 10164 10165 /** 10166 * Given an array of InnerBlocks templates or Block Objects, 10167 * returns an array of created Blocks from them. 10168 * It handles the case of having InnerBlocks as Blocks by 10169 * converting them to the proper format to continue recursively. 10170 * 10171 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 10172 * 10173 * @return {Object[]} Array of Block objects. 10174 */ 10175 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) { 10176 return innerBlocksOrTemplate.map(innerBlock => { 10177 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 10178 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 10179 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 10180 }); 10181 } 10182 10183 /** 10184 * Given a block object, returns a copy of the block object while sanitizing its attributes, 10185 * optionally merging new attributes and/or replacing its inner blocks. 10186 * 10187 * @param {Object} block Block instance. 10188 * @param {Object} mergeAttributes Block attributes. 10189 * @param {?Array} newInnerBlocks Nested blocks. 10190 * 10191 * @return {Object} A cloned block. 10192 */ 10193 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) { 10194 const clientId = esm_browser_v4(); 10195 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { 10196 ...block.attributes, 10197 ...mergeAttributes 10198 }); 10199 return { 10200 ...block, 10201 clientId, 10202 attributes: sanitizedAttributes, 10203 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 10204 }; 10205 } 10206 10207 /** 10208 * Given a block object, returns a copy of the block object, 10209 * optionally merging new attributes and/or replacing its inner blocks. 10210 * 10211 * @param {Object} block Block instance. 10212 * @param {Object} mergeAttributes Block attributes. 10213 * @param {?Array} newInnerBlocks Nested blocks. 10214 * 10215 * @return {Object} A cloned block. 10216 */ 10217 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) { 10218 const clientId = esm_browser_v4(); 10219 return { 10220 ...block, 10221 clientId, 10222 attributes: { 10223 ...block.attributes, 10224 ...mergeAttributes 10225 }, 10226 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 10227 }; 10228 } 10229 10230 /** 10231 * Returns a boolean indicating whether a transform is possible based on 10232 * various bits of context. 10233 * 10234 * @param {Object} transform The transform object to validate. 10235 * @param {string} direction Is this a 'from' or 'to' transform. 10236 * @param {Array} blocks The blocks to transform from. 10237 * 10238 * @return {boolean} Is the transform possible? 10239 */ 10240 const isPossibleTransformForSource = (transform, direction, blocks) => { 10241 if (!blocks.length) { 10242 return false; 10243 } 10244 10245 // If multiple blocks are selected, only multi block transforms 10246 // or wildcard transforms are allowed. 10247 const isMultiBlock = blocks.length > 1; 10248 const firstBlockName = blocks[0].name; 10249 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 10250 if (!isValidForMultiBlocks) { 10251 return false; 10252 } 10253 10254 // Check non-wildcard transforms to ensure that transform is valid 10255 // for a block selection of multiple blocks of different types. 10256 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) { 10257 return false; 10258 } 10259 10260 // Only consider 'block' type transforms as valid. 10261 const isBlockType = transform.type === 'block'; 10262 if (!isBlockType) { 10263 return false; 10264 } 10265 10266 // Check if the transform's block name matches the source block (or is a wildcard) 10267 // only if this is a transform 'from'. 10268 const sourceBlock = blocks[0]; 10269 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 10270 if (!hasMatchingName) { 10271 return false; 10272 } 10273 10274 // Don't allow single Grouping blocks to be transformed into 10275 // a Grouping block. 10276 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 10277 return false; 10278 } 10279 10280 // If the transform has a `isMatch` function specified, check that it returns true. 10281 if (!maybeCheckTransformIsMatch(transform, blocks)) { 10282 return false; 10283 } 10284 return true; 10285 }; 10286 10287 /** 10288 * Returns block types that the 'blocks' can be transformed into, based on 10289 * 'from' transforms on other blocks. 10290 * 10291 * @param {Array} blocks The blocks to transform from. 10292 * 10293 * @return {Array} Block types that the blocks can be transformed into. 10294 */ 10295 const getBlockTypesForPossibleFromTransforms = blocks => { 10296 if (!blocks.length) { 10297 return []; 10298 } 10299 const allBlockTypes = getBlockTypes(); 10300 10301 // filter all blocks to find those with a 'from' transform. 10302 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => { 10303 const fromTransforms = getBlockTransforms('from', blockType.name); 10304 return !!findTransform(fromTransforms, transform => { 10305 return isPossibleTransformForSource(transform, 'from', blocks); 10306 }); 10307 }); 10308 return blockTypesWithPossibleFromTransforms; 10309 }; 10310 10311 /** 10312 * Returns block types that the 'blocks' can be transformed into, based on 10313 * the source block's own 'to' transforms. 10314 * 10315 * @param {Array} blocks The blocks to transform from. 10316 * 10317 * @return {Array} Block types that the source can be transformed into. 10318 */ 10319 const getBlockTypesForPossibleToTransforms = blocks => { 10320 if (!blocks.length) { 10321 return []; 10322 } 10323 const sourceBlock = blocks[0]; 10324 const blockType = getBlockType(sourceBlock.name); 10325 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; 10326 10327 // filter all 'to' transforms to find those that are possible. 10328 const possibleTransforms = transformsTo.filter(transform => { 10329 return transform && isPossibleTransformForSource(transform, 'to', blocks); 10330 }); 10331 10332 // Build a list of block names using the possible 'to' transforms. 10333 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat(); 10334 10335 // Map block names to block types. 10336 return blockNames.map(getBlockType); 10337 }; 10338 10339 /** 10340 * Determines whether transform is a "block" type 10341 * and if so whether it is a "wildcard" transform 10342 * ie: targets "any" block type 10343 * 10344 * @param {Object} t the Block transform object 10345 * 10346 * @return {boolean} whether transform is a wildcard transform 10347 */ 10348 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 10349 10350 /** 10351 * Determines whether the given Block is the core Block which 10352 * acts as a container Block for other Blocks as part of the 10353 * Grouping mechanics 10354 * 10355 * @param {string} name the name of the Block to test against 10356 * 10357 * @return {boolean} whether or not the Block is the container Block type 10358 */ 10359 const isContainerGroupBlock = name => name === getGroupingBlockName(); 10360 10361 /** 10362 * Returns an array of block types that the set of blocks received as argument 10363 * can be transformed into. 10364 * 10365 * @param {Array} blocks Blocks array. 10366 * 10367 * @return {Array} Block types that the blocks argument can be transformed to. 10368 */ 10369 function getPossibleBlockTransformations(blocks) { 10370 if (!blocks.length) { 10371 return []; 10372 } 10373 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 10374 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 10375 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])]; 10376 } 10377 10378 /** 10379 * Given an array of transforms, returns the highest-priority transform where 10380 * the predicate function returns a truthy value. A higher-priority transform 10381 * is one with a lower priority value (i.e. first in priority order). Returns 10382 * null if the transforms set is empty or the predicate function returns a 10383 * falsey value for all entries. 10384 * 10385 * @param {Object[]} transforms Transforms to search. 10386 * @param {Function} predicate Function returning true on matching transform. 10387 * 10388 * @return {?Object} Highest-priority transform candidate. 10389 */ 10390 function findTransform(transforms, predicate) { 10391 // The hooks library already has built-in mechanisms for managing priority 10392 // queue, so leverage via locally-defined instance. 10393 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)(); 10394 for (let i = 0; i < transforms.length; i++) { 10395 const candidate = transforms[i]; 10396 if (predicate(candidate)) { 10397 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 10398 } 10399 } 10400 10401 // Filter name is arbitrarily chosen but consistent with above aggregation. 10402 return hooks.applyFilters('transform', null); 10403 } 10404 10405 /** 10406 * Returns normal block transforms for a given transform direction, optionally 10407 * for a specific block by name, or an empty array if there are no transforms. 10408 * If no block name is provided, returns transforms for all blocks. A normal 10409 * transform object includes `blockName` as a property. 10410 * 10411 * @param {string} direction Transform direction ("to", "from"). 10412 * @param {string|Object} blockTypeOrName Block type or name. 10413 * 10414 * @return {Array} Block transforms for direction. 10415 */ 10416 function getBlockTransforms(direction, blockTypeOrName) { 10417 // When retrieving transforms for all block types, recurse into self. 10418 if (blockTypeOrName === undefined) { 10419 return getBlockTypes().map(({ 10420 name 10421 }) => getBlockTransforms(direction, name)).flat(); 10422 } 10423 10424 // Validate that block type exists and has array of direction. 10425 const blockType = normalizeBlockType(blockTypeOrName); 10426 const { 10427 name: blockName, 10428 transforms 10429 } = blockType || {}; 10430 if (!transforms || !Array.isArray(transforms[direction])) { 10431 return []; 10432 } 10433 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 10434 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => { 10435 if (t.type === 'raw') { 10436 return true; 10437 } 10438 if (t.type === 'prefix') { 10439 return true; 10440 } 10441 if (!t.blocks || !t.blocks.length) { 10442 return false; 10443 } 10444 if (isWildcardBlockTransform(t)) { 10445 return true; 10446 } 10447 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 10448 }) : transforms[direction]; 10449 10450 // Map transforms to normal form. 10451 return filteredTransforms.map(transform => ({ 10452 ...transform, 10453 blockName, 10454 usingMobileTransformations 10455 })); 10456 } 10457 10458 /** 10459 * Checks that a given transforms isMatch method passes for given source blocks. 10460 * 10461 * @param {Object} transform A transform object. 10462 * @param {Array} blocks Blocks array. 10463 * 10464 * @return {boolean} True if given blocks are a match for the transform. 10465 */ 10466 function maybeCheckTransformIsMatch(transform, blocks) { 10467 if (typeof transform.isMatch !== 'function') { 10468 return true; 10469 } 10470 const sourceBlock = blocks[0]; 10471 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 10472 const block = transform.isMultiBlock ? blocks : sourceBlock; 10473 return transform.isMatch(attributes, block); 10474 } 10475 10476 /** 10477 * Switch one or more blocks into one or more blocks of the new block type. 10478 * 10479 * @param {Array|Object} blocks Blocks array or block object. 10480 * @param {string} name Block name. 10481 * 10482 * @return {?Array} Array of blocks or null. 10483 */ 10484 function switchToBlockType(blocks, name) { 10485 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10486 const isMultiBlock = blocksArray.length > 1; 10487 const firstBlock = blocksArray[0]; 10488 const sourceName = firstBlock.name; 10489 10490 // Find the right transformation by giving priority to the "to" 10491 // transformation. 10492 const transformationsFrom = getBlockTransforms('from', name); 10493 const transformationsTo = getBlockTransforms('to', sourceName); 10494 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)); 10495 10496 // Stop if there is no valid transformation. 10497 if (!transformation) { 10498 return null; 10499 } 10500 let transformationResults; 10501 if (transformation.isMultiBlock) { 10502 if ('__experimentalConvert' in transformation) { 10503 transformationResults = transformation.__experimentalConvert(blocksArray); 10504 } else { 10505 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 10506 } 10507 } else if ('__experimentalConvert' in transformation) { 10508 transformationResults = transformation.__experimentalConvert(firstBlock); 10509 } else { 10510 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 10511 } 10512 10513 // Ensure that the transformation function returned an object or an array 10514 // of objects. 10515 if (transformationResults === null || typeof transformationResults !== 'object') { 10516 return null; 10517 } 10518 10519 // If the transformation function returned a single object, we want to work 10520 // with an array instead. 10521 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults]; 10522 10523 // Ensure that every block object returned by the transformation has a 10524 // valid block type. 10525 if (transformationResults.some(result => !getBlockType(result.name))) { 10526 return null; 10527 } 10528 const hasSwitchedBlock = transformationResults.some(result => result.name === name); 10529 10530 // Ensure that at least one block object returned by the transformation has 10531 // the expected "destination" block type. 10532 if (!hasSwitchedBlock) { 10533 return null; 10534 } 10535 const ret = transformationResults.map((result, index, results) => { 10536 /** 10537 * Filters an individual transform result from block transformation. 10538 * All of the original blocks are passed, since transformations are 10539 * many-to-many, not one-to-one. 10540 * 10541 * @param {Object} transformedBlock The transformed block. 10542 * @param {Object[]} blocks Original blocks transformed. 10543 * @param {Object[]} index Index of the transformed block on the array of results. 10544 * @param {Object[]} results An array all the blocks that resulted from the transformation. 10545 */ 10546 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results); 10547 }); 10548 return ret; 10549 } 10550 10551 /** 10552 * Create a block object from the example API. 10553 * 10554 * @param {string} name 10555 * @param {Object} example 10556 * 10557 * @return {Object} block. 10558 */ 10559 const getBlockFromExample = (name, example) => { 10560 try { 10561 var _example$innerBlocks; 10562 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 10563 } catch { 10564 return createBlock('core/missing', { 10565 originalName: name, 10566 originalContent: '', 10567 originalUndelimitedContent: '' 10568 }); 10569 } 10570 }; 10571 10572 ;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"] 10573 const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 10574 ;// CONCATENATED MODULE: external ["wp","autop"] 10575 const external_wp_autop_namespaceObject = window["wp"]["autop"]; 10576 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"] 10577 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 10578 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 10579 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/serialize-raw-block.js 10580 /** 10581 * Internal dependencies 10582 */ 10583 10584 10585 /** 10586 * @typedef {Object} Options Serialization options. 10587 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. 10588 */ 10589 10590 /** @typedef {import("./").WPRawBlock} WPRawBlock */ 10591 10592 /** 10593 * Serializes a block node into the native HTML-comment-powered block format. 10594 * CAVEAT: This function is intended for re-serializing blocks as parsed by 10595 * valid parsers and skips any validation steps. This is NOT a generic 10596 * serialization function for in-memory blocks. For most purposes, see the 10597 * following functions available in the `@wordpress/blocks` package: 10598 * 10599 * @see serializeBlock 10600 * @see serialize 10601 * 10602 * For more on the format of block nodes as returned by valid parsers: 10603 * 10604 * @see `@wordpress/block-serialization-default-parser` package 10605 * @see `@wordpress/block-serialization-spec-parser` package 10606 * 10607 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. 10608 * @param {Options} [options={}] Serialization options. 10609 * 10610 * @return {string} An HTML string representing a block. 10611 */ 10612 function serializeRawBlock(rawBlock, options = {}) { 10613 const { 10614 isCommentDelimited = true 10615 } = options; 10616 const { 10617 blockName, 10618 attrs = {}, 10619 innerBlocks = [], 10620 innerContent = [] 10621 } = rawBlock; 10622 let childIndex = 0; 10623 const content = innerContent.map(item => 10624 // `null` denotes a nested block, otherwise we have an HTML fragment. 10625 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 10626 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 10627 } 10628 10629 ;// CONCATENATED MODULE: external "ReactJSXRuntime" 10630 const external_ReactJSXRuntime_namespaceObject = window["ReactJSXRuntime"]; 10631 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/serializer.js 10632 /** 10633 * WordPress dependencies 10634 */ 10635 10636 10637 10638 10639 10640 10641 /** 10642 * Internal dependencies 10643 */ 10644 10645 10646 10647 10648 /** @typedef {import('./parser').WPBlock} WPBlock */ 10649 10650 /** 10651 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 10652 * 10653 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 10654 */ 10655 10656 /** 10657 * Returns the block's default classname from its name. 10658 * 10659 * @param {string} blockName The block name. 10660 * 10661 * @return {string} The block's default class. 10662 */ 10663 10664 function getBlockDefaultClassName(blockName) { 10665 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 10666 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10667 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10668 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName); 10669 } 10670 10671 /** 10672 * Returns the block's default menu item classname from its name. 10673 * 10674 * @param {string} blockName The block name. 10675 * 10676 * @return {string} The block's default menu item class. 10677 */ 10678 function getBlockMenuDefaultClassName(blockName) { 10679 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 10680 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10681 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10682 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName); 10683 } 10684 const blockPropsProvider = {}; 10685 const innerBlocksPropsProvider = {}; 10686 10687 /** 10688 * Call within a save function to get the props for the block wrapper. 10689 * 10690 * @param {Object} props Optional. Props to pass to the element. 10691 */ 10692 function getBlockProps(props = {}) { 10693 const { 10694 blockType, 10695 attributes 10696 } = blockPropsProvider; 10697 return getBlockProps.skipFilters ? props : (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10698 ...props 10699 }, blockType, attributes); 10700 } 10701 10702 /** 10703 * Call within a save function to get the props for the inner blocks wrapper. 10704 * 10705 * @param {Object} props Optional. Props to pass to the element. 10706 */ 10707 function getInnerBlocksProps(props = {}) { 10708 const { 10709 innerBlocks 10710 } = innerBlocksPropsProvider; 10711 // Allow a different component to be passed to getSaveElement to handle 10712 // inner blocks, bypassing the default serialisation. 10713 if (!Array.isArray(innerBlocks)) { 10714 return { 10715 ...props, 10716 children: innerBlocks 10717 }; 10718 } 10719 // Value is an array of blocks, so defer to block serializer. 10720 const html = serialize(innerBlocks, { 10721 isInnerBlocks: true 10722 }); 10723 // Use special-cased raw HTML tag to avoid default escaping. 10724 const children = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.RawHTML, { 10725 children: html 10726 }); 10727 return { 10728 ...props, 10729 children 10730 }; 10731 } 10732 10733 /** 10734 * Given a block type containing a save render implementation and attributes, returns the 10735 * enhanced element to be saved or string when raw HTML expected. 10736 * 10737 * @param {string|Object} blockTypeOrName Block type or name. 10738 * @param {Object} attributes Block attributes. 10739 * @param {?Array} innerBlocks Nested blocks. 10740 * 10741 * @return {Object|string} Save element or raw HTML string. 10742 */ 10743 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) { 10744 const blockType = normalizeBlockType(blockTypeOrName); 10745 if (!blockType?.save) { 10746 return null; 10747 } 10748 let { 10749 save 10750 } = blockType; 10751 10752 // Component classes are unsupported for save since serialization must 10753 // occur synchronously. For improved interoperability with higher-order 10754 // components which often return component class, emulate basic support. 10755 if (save.prototype instanceof external_wp_element_namespaceObject.Component) { 10756 const instance = new save({ 10757 attributes 10758 }); 10759 save = instance.render.bind(instance); 10760 } 10761 blockPropsProvider.blockType = blockType; 10762 blockPropsProvider.attributes = attributes; 10763 innerBlocksPropsProvider.innerBlocks = innerBlocks; 10764 let element = save({ 10765 attributes, 10766 innerBlocks 10767 }); 10768 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) { 10769 /** 10770 * Filters the props applied to the block save result element. 10771 * 10772 * @param {Object} props Props applied to save element. 10773 * @param {WPBlock} blockType Block type definition. 10774 * @param {Object} attributes Block attributes. 10775 */ 10776 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10777 ...element.props 10778 }, blockType, attributes); 10779 if (!external_wp_isShallowEqual_default()(props, element.props)) { 10780 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props); 10781 } 10782 } 10783 10784 /** 10785 * Filters the save result of a block during serialization. 10786 * 10787 * @param {Element} element Block save result. 10788 * @param {WPBlock} blockType Block type definition. 10789 * @param {Object} attributes Block attributes. 10790 */ 10791 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes); 10792 } 10793 10794 /** 10795 * Given a block type containing a save render implementation and attributes, returns the 10796 * static markup to be saved. 10797 * 10798 * @param {string|Object} blockTypeOrName Block type or name. 10799 * @param {Object} attributes Block attributes. 10800 * @param {?Array} innerBlocks Nested blocks. 10801 * 10802 * @return {string} Save content. 10803 */ 10804 function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 10805 const blockType = normalizeBlockType(blockTypeOrName); 10806 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks)); 10807 } 10808 10809 /** 10810 * Returns attributes which are to be saved and serialized into the block 10811 * comment delimiter. 10812 * 10813 * When a block exists in memory it contains as its attributes both those 10814 * parsed the block comment delimiter _and_ those which matched from the 10815 * contents of the block. 10816 * 10817 * This function returns only those attributes which are needed to persist and 10818 * which cannot be matched from the block content. 10819 * 10820 * @param {Object<string,*>} blockType Block type. 10821 * @param {Object<string,*>} attributes Attributes from in-memory block data. 10822 * 10823 * @return {Object<string,*>} Subset of attributes for comment serialization. 10824 */ 10825 function getCommentAttributes(blockType, attributes) { 10826 var _blockType$attributes; 10827 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).reduce((accumulator, [key, attributeSchema]) => { 10828 const value = attributes[key]; 10829 // Ignore undefined values. 10830 if (undefined === value) { 10831 return accumulator; 10832 } 10833 10834 // Ignore all attributes but the ones with an "undefined" source 10835 // "undefined" source refers to attributes saved in the block comment. 10836 if (attributeSchema.source !== undefined) { 10837 return accumulator; 10838 } 10839 10840 // Ignore all local attributes 10841 if (attributeSchema.role === 'local') { 10842 return accumulator; 10843 } 10844 if (attributeSchema.__experimentalRole === 'local') { 10845 external_wp_deprecated_default()('__experimentalRole attribute', { 10846 since: '6.7', 10847 version: '6.8', 10848 alternative: 'role attribute', 10849 hint: `Check the block.json of the $blockType?.name} block.` 10850 }); 10851 return accumulator; 10852 } 10853 10854 // Ignore default value. 10855 if ('default' in attributeSchema && JSON.stringify(attributeSchema.default) === JSON.stringify(value)) { 10856 return accumulator; 10857 } 10858 10859 // Otherwise, include in comment set. 10860 accumulator[key] = value; 10861 return accumulator; 10862 }, {}); 10863 } 10864 10865 /** 10866 * Given an attributes object, returns a string in the serialized attributes 10867 * format prepared for post content. 10868 * 10869 * @param {Object} attributes Attributes object. 10870 * 10871 * @return {string} Serialized attributes. 10872 */ 10873 function serializeAttributes(attributes) { 10874 return JSON.stringify(attributes) 10875 // Don't break HTML comments. 10876 .replace(/--/g, '\\u002d\\u002d') 10877 10878 // Don't break non-standard-compliant tools. 10879 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') 10880 10881 // Bypass server stripslashes behavior which would unescape stringify's 10882 // escaping of quotation mark. 10883 // 10884 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 10885 .replace(/\\"/g, '\\u0022'); 10886 } 10887 10888 /** 10889 * Given a block object, returns the Block's Inner HTML markup. 10890 * 10891 * @param {Object} block Block instance. 10892 * 10893 * @return {string} HTML. 10894 */ 10895 function getBlockInnerHTML(block) { 10896 // If block was parsed as invalid or encounters an error while generating 10897 // save content, use original content instead to avoid content loss. If a 10898 // block contains nested content, exempt it from this condition because we 10899 // otherwise have no access to its original content and content loss would 10900 // still occur. 10901 let saveContent = block.originalContent; 10902 if (block.isValid || block.innerBlocks.length) { 10903 try { 10904 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 10905 } catch (error) {} 10906 } 10907 return saveContent; 10908 } 10909 10910 /** 10911 * Returns the content of a block, including comment delimiters. 10912 * 10913 * @param {string} rawBlockName Block name. 10914 * @param {Object} attributes Block attributes. 10915 * @param {string} content Block save content. 10916 * 10917 * @return {string} Comment-delimited block content. 10918 */ 10919 function getCommentDelimitedContent(rawBlockName, attributes, content) { 10920 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : ''; 10921 10922 // Strip core blocks of their namespace prefix. 10923 const blockName = rawBlockName?.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName; 10924 10925 // @todo make the `wp:` prefix potentially configurable. 10926 10927 if (!content) { 10928 return `<!-- wp:$blockName} $serializedAttributes}/-->`; 10929 } 10930 return `<!-- wp:$blockName} $serializedAttributes}-->\n` + content + `\n<!-- /wp:$blockName} -->`; 10931 } 10932 10933 /** 10934 * Returns the content of a block, including comment delimiters, determining 10935 * serialized attributes and content form from the current state of the block. 10936 * 10937 * @param {WPBlock} block Block instance. 10938 * @param {WPBlockSerializationOptions} options Serialization options. 10939 * 10940 * @return {string} Serialized block. 10941 */ 10942 function serializeBlock(block, { 10943 isInnerBlocks = false 10944 } = {}) { 10945 if (!block.isValid && block.__unstableBlockSource) { 10946 return serializeRawBlock(block.__unstableBlockSource); 10947 } 10948 const blockName = block.name; 10949 const saveContent = getBlockInnerHTML(block); 10950 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 10951 return saveContent; 10952 } 10953 const blockType = getBlockType(blockName); 10954 if (!blockType) { 10955 return saveContent; 10956 } 10957 const saveAttributes = getCommentAttributes(blockType, block.attributes); 10958 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 10959 } 10960 function __unstableSerializeAndClean(blocks) { 10961 // A single unmodified default block is assumed to 10962 // be equivalent to an empty post. 10963 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 10964 blocks = []; 10965 } 10966 let content = serialize(blocks); 10967 10968 // For compatibility, treat a post consisting of a 10969 // single freeform block as legacy content and apply 10970 // pre-block-editor removep'd content formatting. 10971 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName() && blocks[0].name === 'core/freeform') { 10972 content = (0,external_wp_autop_namespaceObject.removep)(content); 10973 } 10974 return content; 10975 } 10976 10977 /** 10978 * Takes a block or set of blocks and returns the serialized post content. 10979 * 10980 * @param {Array} blocks Block(s) to serialize. 10981 * @param {WPBlockSerializationOptions} options Serialization options. 10982 * 10983 * @return {string} The post content. 10984 */ 10985 function serialize(blocks, options) { 10986 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10987 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n'); 10988 } 10989 10990 ;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js 10991 /** 10992 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 10993 * do not edit 10994 */ 10995 var namedCharRefs = { 10996 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" 10997 }; 10998 10999 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 11000 var CHARCODE = /^#([0-9]+)$/; 11001 var NAMED = /^([A-Za-z0-9]+)$/; 11002 var EntityParser = /** @class */ (function () { 11003 function EntityParser(named) { 11004 this.named = named; 11005 } 11006 EntityParser.prototype.parse = function (entity) { 11007 if (!entity) { 11008 return; 11009 } 11010 var matches = entity.match(HEXCHARCODE); 11011 if (matches) { 11012 return String.fromCharCode(parseInt(matches[1], 16)); 11013 } 11014 matches = entity.match(CHARCODE); 11015 if (matches) { 11016 return String.fromCharCode(parseInt(matches[1], 10)); 11017 } 11018 matches = entity.match(NAMED); 11019 if (matches) { 11020 return this.named[matches[1]]; 11021 } 11022 }; 11023 return EntityParser; 11024 }()); 11025 11026 var WSP = /[\t\n\f ]/; 11027 var ALPHA = /[A-Za-z]/; 11028 var CRLF = /\r\n?/g; 11029 function isSpace(char) { 11030 return WSP.test(char); 11031 } 11032 function isAlpha(char) { 11033 return ALPHA.test(char); 11034 } 11035 function preprocessInput(input) { 11036 return input.replace(CRLF, '\n'); 11037 } 11038 11039 var EventedTokenizer = /** @class */ (function () { 11040 function EventedTokenizer(delegate, entityParser, mode) { 11041 if (mode === void 0) { mode = 'precompile'; } 11042 this.delegate = delegate; 11043 this.entityParser = entityParser; 11044 this.mode = mode; 11045 this.state = "beforeData" /* beforeData */; 11046 this.line = -1; 11047 this.column = -1; 11048 this.input = ''; 11049 this.index = -1; 11050 this.tagNameBuffer = ''; 11051 this.states = { 11052 beforeData: function () { 11053 var char = this.peek(); 11054 if (char === '<' && !this.isIgnoredEndTag()) { 11055 this.transitionTo("tagOpen" /* tagOpen */); 11056 this.markTagStart(); 11057 this.consume(); 11058 } 11059 else { 11060 if (this.mode === 'precompile' && char === '\n') { 11061 var tag = this.tagNameBuffer.toLowerCase(); 11062 if (tag === 'pre' || tag === 'textarea') { 11063 this.consume(); 11064 } 11065 } 11066 this.transitionTo("data" /* data */); 11067 this.delegate.beginData(); 11068 } 11069 }, 11070 data: function () { 11071 var char = this.peek(); 11072 var tag = this.tagNameBuffer; 11073 if (char === '<' && !this.isIgnoredEndTag()) { 11074 this.delegate.finishData(); 11075 this.transitionTo("tagOpen" /* tagOpen */); 11076 this.markTagStart(); 11077 this.consume(); 11078 } 11079 else if (char === '&' && tag !== 'script' && tag !== 'style') { 11080 this.consume(); 11081 this.delegate.appendToData(this.consumeCharRef() || '&'); 11082 } 11083 else { 11084 this.consume(); 11085 this.delegate.appendToData(char); 11086 } 11087 }, 11088 tagOpen: function () { 11089 var char = this.consume(); 11090 if (char === '!') { 11091 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 11092 } 11093 else if (char === '/') { 11094 this.transitionTo("endTagOpen" /* endTagOpen */); 11095 } 11096 else if (char === '@' || char === ':' || isAlpha(char)) { 11097 this.transitionTo("tagName" /* tagName */); 11098 this.tagNameBuffer = ''; 11099 this.delegate.beginStartTag(); 11100 this.appendToTagName(char); 11101 } 11102 }, 11103 markupDeclarationOpen: function () { 11104 var char = this.consume(); 11105 if (char === '-' && this.peek() === '-') { 11106 this.consume(); 11107 this.transitionTo("commentStart" /* commentStart */); 11108 this.delegate.beginComment(); 11109 } 11110 else { 11111 var maybeDoctype = char.toUpperCase() + this.input.substring(this.index, this.index + 6).toUpperCase(); 11112 if (maybeDoctype === 'DOCTYPE') { 11113 this.consume(); 11114 this.consume(); 11115 this.consume(); 11116 this.consume(); 11117 this.consume(); 11118 this.consume(); 11119 this.transitionTo("doctype" /* doctype */); 11120 if (this.delegate.beginDoctype) 11121 this.delegate.beginDoctype(); 11122 } 11123 } 11124 }, 11125 doctype: function () { 11126 var char = this.consume(); 11127 if (isSpace(char)) { 11128 this.transitionTo("beforeDoctypeName" /* beforeDoctypeName */); 11129 } 11130 }, 11131 beforeDoctypeName: function () { 11132 var char = this.consume(); 11133 if (isSpace(char)) { 11134 return; 11135 } 11136 else { 11137 this.transitionTo("doctypeName" /* doctypeName */); 11138 if (this.delegate.appendToDoctypeName) 11139 this.delegate.appendToDoctypeName(char.toLowerCase()); 11140 } 11141 }, 11142 doctypeName: function () { 11143 var char = this.consume(); 11144 if (isSpace(char)) { 11145 this.transitionTo("afterDoctypeName" /* afterDoctypeName */); 11146 } 11147 else if (char === '>') { 11148 if (this.delegate.endDoctype) 11149 this.delegate.endDoctype(); 11150 this.transitionTo("beforeData" /* beforeData */); 11151 } 11152 else { 11153 if (this.delegate.appendToDoctypeName) 11154 this.delegate.appendToDoctypeName(char.toLowerCase()); 11155 } 11156 }, 11157 afterDoctypeName: function () { 11158 var char = this.consume(); 11159 if (isSpace(char)) { 11160 return; 11161 } 11162 else if (char === '>') { 11163 if (this.delegate.endDoctype) 11164 this.delegate.endDoctype(); 11165 this.transitionTo("beforeData" /* beforeData */); 11166 } 11167 else { 11168 var nextSixChars = char.toUpperCase() + this.input.substring(this.index, this.index + 5).toUpperCase(); 11169 var isPublic = nextSixChars.toUpperCase() === 'PUBLIC'; 11170 var isSystem = nextSixChars.toUpperCase() === 'SYSTEM'; 11171 if (isPublic || isSystem) { 11172 this.consume(); 11173 this.consume(); 11174 this.consume(); 11175 this.consume(); 11176 this.consume(); 11177 this.consume(); 11178 } 11179 if (isPublic) { 11180 this.transitionTo("afterDoctypePublicKeyword" /* afterDoctypePublicKeyword */); 11181 } 11182 else if (isSystem) { 11183 this.transitionTo("afterDoctypeSystemKeyword" /* afterDoctypeSystemKeyword */); 11184 } 11185 } 11186 }, 11187 afterDoctypePublicKeyword: function () { 11188 var char = this.peek(); 11189 if (isSpace(char)) { 11190 this.transitionTo("beforeDoctypePublicIdentifier" /* beforeDoctypePublicIdentifier */); 11191 this.consume(); 11192 } 11193 else if (char === '"') { 11194 this.transitionTo("doctypePublicIdentifierDoubleQuoted" /* doctypePublicIdentifierDoubleQuoted */); 11195 this.consume(); 11196 } 11197 else if (char === "'") { 11198 this.transitionTo("doctypePublicIdentifierSingleQuoted" /* doctypePublicIdentifierSingleQuoted */); 11199 this.consume(); 11200 } 11201 else if (char === '>') { 11202 this.consume(); 11203 if (this.delegate.endDoctype) 11204 this.delegate.endDoctype(); 11205 this.transitionTo("beforeData" /* beforeData */); 11206 } 11207 }, 11208 doctypePublicIdentifierDoubleQuoted: function () { 11209 var char = this.consume(); 11210 if (char === '"') { 11211 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11212 } 11213 else if (char === '>') { 11214 if (this.delegate.endDoctype) 11215 this.delegate.endDoctype(); 11216 this.transitionTo("beforeData" /* beforeData */); 11217 } 11218 else { 11219 if (this.delegate.appendToDoctypePublicIdentifier) 11220 this.delegate.appendToDoctypePublicIdentifier(char); 11221 } 11222 }, 11223 doctypePublicIdentifierSingleQuoted: function () { 11224 var char = this.consume(); 11225 if (char === "'") { 11226 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11227 } 11228 else if (char === '>') { 11229 if (this.delegate.endDoctype) 11230 this.delegate.endDoctype(); 11231 this.transitionTo("beforeData" /* beforeData */); 11232 } 11233 else { 11234 if (this.delegate.appendToDoctypePublicIdentifier) 11235 this.delegate.appendToDoctypePublicIdentifier(char); 11236 } 11237 }, 11238 afterDoctypePublicIdentifier: function () { 11239 var char = this.consume(); 11240 if (isSpace(char)) { 11241 this.transitionTo("betweenDoctypePublicAndSystemIdentifiers" /* betweenDoctypePublicAndSystemIdentifiers */); 11242 } 11243 else if (char === '>') { 11244 if (this.delegate.endDoctype) 11245 this.delegate.endDoctype(); 11246 this.transitionTo("beforeData" /* beforeData */); 11247 } 11248 else if (char === '"') { 11249 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11250 } 11251 else if (char === "'") { 11252 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11253 } 11254 }, 11255 betweenDoctypePublicAndSystemIdentifiers: function () { 11256 var char = this.consume(); 11257 if (isSpace(char)) { 11258 return; 11259 } 11260 else if (char === '>') { 11261 if (this.delegate.endDoctype) 11262 this.delegate.endDoctype(); 11263 this.transitionTo("beforeData" /* beforeData */); 11264 } 11265 else if (char === '"') { 11266 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11267 } 11268 else if (char === "'") { 11269 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11270 } 11271 }, 11272 doctypeSystemIdentifierDoubleQuoted: function () { 11273 var char = this.consume(); 11274 if (char === '"') { 11275 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11276 } 11277 else if (char === '>') { 11278 if (this.delegate.endDoctype) 11279 this.delegate.endDoctype(); 11280 this.transitionTo("beforeData" /* beforeData */); 11281 } 11282 else { 11283 if (this.delegate.appendToDoctypeSystemIdentifier) 11284 this.delegate.appendToDoctypeSystemIdentifier(char); 11285 } 11286 }, 11287 doctypeSystemIdentifierSingleQuoted: function () { 11288 var char = this.consume(); 11289 if (char === "'") { 11290 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11291 } 11292 else if (char === '>') { 11293 if (this.delegate.endDoctype) 11294 this.delegate.endDoctype(); 11295 this.transitionTo("beforeData" /* beforeData */); 11296 } 11297 else { 11298 if (this.delegate.appendToDoctypeSystemIdentifier) 11299 this.delegate.appendToDoctypeSystemIdentifier(char); 11300 } 11301 }, 11302 afterDoctypeSystemIdentifier: function () { 11303 var char = this.consume(); 11304 if (isSpace(char)) { 11305 return; 11306 } 11307 else if (char === '>') { 11308 if (this.delegate.endDoctype) 11309 this.delegate.endDoctype(); 11310 this.transitionTo("beforeData" /* beforeData */); 11311 } 11312 }, 11313 commentStart: function () { 11314 var char = this.consume(); 11315 if (char === '-') { 11316 this.transitionTo("commentStartDash" /* commentStartDash */); 11317 } 11318 else if (char === '>') { 11319 this.delegate.finishComment(); 11320 this.transitionTo("beforeData" /* beforeData */); 11321 } 11322 else { 11323 this.delegate.appendToCommentData(char); 11324 this.transitionTo("comment" /* comment */); 11325 } 11326 }, 11327 commentStartDash: function () { 11328 var char = this.consume(); 11329 if (char === '-') { 11330 this.transitionTo("commentEnd" /* commentEnd */); 11331 } 11332 else if (char === '>') { 11333 this.delegate.finishComment(); 11334 this.transitionTo("beforeData" /* beforeData */); 11335 } 11336 else { 11337 this.delegate.appendToCommentData('-'); 11338 this.transitionTo("comment" /* comment */); 11339 } 11340 }, 11341 comment: function () { 11342 var char = this.consume(); 11343 if (char === '-') { 11344 this.transitionTo("commentEndDash" /* commentEndDash */); 11345 } 11346 else { 11347 this.delegate.appendToCommentData(char); 11348 } 11349 }, 11350 commentEndDash: function () { 11351 var char = this.consume(); 11352 if (char === '-') { 11353 this.transitionTo("commentEnd" /* commentEnd */); 11354 } 11355 else { 11356 this.delegate.appendToCommentData('-' + char); 11357 this.transitionTo("comment" /* comment */); 11358 } 11359 }, 11360 commentEnd: function () { 11361 var char = this.consume(); 11362 if (char === '>') { 11363 this.delegate.finishComment(); 11364 this.transitionTo("beforeData" /* beforeData */); 11365 } 11366 else { 11367 this.delegate.appendToCommentData('--' + char); 11368 this.transitionTo("comment" /* comment */); 11369 } 11370 }, 11371 tagName: function () { 11372 var char = this.consume(); 11373 if (isSpace(char)) { 11374 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11375 } 11376 else if (char === '/') { 11377 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11378 } 11379 else if (char === '>') { 11380 this.delegate.finishTag(); 11381 this.transitionTo("beforeData" /* beforeData */); 11382 } 11383 else { 11384 this.appendToTagName(char); 11385 } 11386 }, 11387 endTagName: function () { 11388 var char = this.consume(); 11389 if (isSpace(char)) { 11390 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11391 this.tagNameBuffer = ''; 11392 } 11393 else if (char === '/') { 11394 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11395 this.tagNameBuffer = ''; 11396 } 11397 else if (char === '>') { 11398 this.delegate.finishTag(); 11399 this.transitionTo("beforeData" /* beforeData */); 11400 this.tagNameBuffer = ''; 11401 } 11402 else { 11403 this.appendToTagName(char); 11404 } 11405 }, 11406 beforeAttributeName: function () { 11407 var char = this.peek(); 11408 if (isSpace(char)) { 11409 this.consume(); 11410 return; 11411 } 11412 else if (char === '/') { 11413 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11414 this.consume(); 11415 } 11416 else if (char === '>') { 11417 this.consume(); 11418 this.delegate.finishTag(); 11419 this.transitionTo("beforeData" /* beforeData */); 11420 } 11421 else if (char === '=') { 11422 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 11423 this.transitionTo("attributeName" /* attributeName */); 11424 this.delegate.beginAttribute(); 11425 this.consume(); 11426 this.delegate.appendToAttributeName(char); 11427 } 11428 else { 11429 this.transitionTo("attributeName" /* attributeName */); 11430 this.delegate.beginAttribute(); 11431 } 11432 }, 11433 attributeName: function () { 11434 var char = this.peek(); 11435 if (isSpace(char)) { 11436 this.transitionTo("afterAttributeName" /* afterAttributeName */); 11437 this.consume(); 11438 } 11439 else if (char === '/') { 11440 this.delegate.beginAttributeValue(false); 11441 this.delegate.finishAttributeValue(); 11442 this.consume(); 11443 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11444 } 11445 else if (char === '=') { 11446 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11447 this.consume(); 11448 } 11449 else if (char === '>') { 11450 this.delegate.beginAttributeValue(false); 11451 this.delegate.finishAttributeValue(); 11452 this.consume(); 11453 this.delegate.finishTag(); 11454 this.transitionTo("beforeData" /* beforeData */); 11455 } 11456 else if (char === '"' || char === "'" || char === '<') { 11457 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 11458 this.consume(); 11459 this.delegate.appendToAttributeName(char); 11460 } 11461 else { 11462 this.consume(); 11463 this.delegate.appendToAttributeName(char); 11464 } 11465 }, 11466 afterAttributeName: function () { 11467 var char = this.peek(); 11468 if (isSpace(char)) { 11469 this.consume(); 11470 return; 11471 } 11472 else if (char === '/') { 11473 this.delegate.beginAttributeValue(false); 11474 this.delegate.finishAttributeValue(); 11475 this.consume(); 11476 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11477 } 11478 else if (char === '=') { 11479 this.consume(); 11480 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11481 } 11482 else if (char === '>') { 11483 this.delegate.beginAttributeValue(false); 11484 this.delegate.finishAttributeValue(); 11485 this.consume(); 11486 this.delegate.finishTag(); 11487 this.transitionTo("beforeData" /* beforeData */); 11488 } 11489 else { 11490 this.delegate.beginAttributeValue(false); 11491 this.delegate.finishAttributeValue(); 11492 this.transitionTo("attributeName" /* attributeName */); 11493 this.delegate.beginAttribute(); 11494 this.consume(); 11495 this.delegate.appendToAttributeName(char); 11496 } 11497 }, 11498 beforeAttributeValue: function () { 11499 var char = this.peek(); 11500 if (isSpace(char)) { 11501 this.consume(); 11502 } 11503 else if (char === '"') { 11504 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 11505 this.delegate.beginAttributeValue(true); 11506 this.consume(); 11507 } 11508 else if (char === "'") { 11509 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 11510 this.delegate.beginAttributeValue(true); 11511 this.consume(); 11512 } 11513 else if (char === '>') { 11514 this.delegate.beginAttributeValue(false); 11515 this.delegate.finishAttributeValue(); 11516 this.consume(); 11517 this.delegate.finishTag(); 11518 this.transitionTo("beforeData" /* beforeData */); 11519 } 11520 else { 11521 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 11522 this.delegate.beginAttributeValue(false); 11523 this.consume(); 11524 this.delegate.appendToAttributeValue(char); 11525 } 11526 }, 11527 attributeValueDoubleQuoted: function () { 11528 var char = this.consume(); 11529 if (char === '"') { 11530 this.delegate.finishAttributeValue(); 11531 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11532 } 11533 else if (char === '&') { 11534 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11535 } 11536 else { 11537 this.delegate.appendToAttributeValue(char); 11538 } 11539 }, 11540 attributeValueSingleQuoted: function () { 11541 var char = this.consume(); 11542 if (char === "'") { 11543 this.delegate.finishAttributeValue(); 11544 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11545 } 11546 else if (char === '&') { 11547 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11548 } 11549 else { 11550 this.delegate.appendToAttributeValue(char); 11551 } 11552 }, 11553 attributeValueUnquoted: function () { 11554 var char = this.peek(); 11555 if (isSpace(char)) { 11556 this.delegate.finishAttributeValue(); 11557 this.consume(); 11558 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11559 } 11560 else if (char === '/') { 11561 this.delegate.finishAttributeValue(); 11562 this.consume(); 11563 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11564 } 11565 else if (char === '&') { 11566 this.consume(); 11567 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11568 } 11569 else if (char === '>') { 11570 this.delegate.finishAttributeValue(); 11571 this.consume(); 11572 this.delegate.finishTag(); 11573 this.transitionTo("beforeData" /* beforeData */); 11574 } 11575 else { 11576 this.consume(); 11577 this.delegate.appendToAttributeValue(char); 11578 } 11579 }, 11580 afterAttributeValueQuoted: function () { 11581 var char = this.peek(); 11582 if (isSpace(char)) { 11583 this.consume(); 11584 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11585 } 11586 else if (char === '/') { 11587 this.consume(); 11588 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11589 } 11590 else if (char === '>') { 11591 this.consume(); 11592 this.delegate.finishTag(); 11593 this.transitionTo("beforeData" /* beforeData */); 11594 } 11595 else { 11596 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11597 } 11598 }, 11599 selfClosingStartTag: function () { 11600 var char = this.peek(); 11601 if (char === '>') { 11602 this.consume(); 11603 this.delegate.markTagAsSelfClosing(); 11604 this.delegate.finishTag(); 11605 this.transitionTo("beforeData" /* beforeData */); 11606 } 11607 else { 11608 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11609 } 11610 }, 11611 endTagOpen: function () { 11612 var char = this.consume(); 11613 if (char === '@' || char === ':' || isAlpha(char)) { 11614 this.transitionTo("endTagName" /* endTagName */); 11615 this.tagNameBuffer = ''; 11616 this.delegate.beginEndTag(); 11617 this.appendToTagName(char); 11618 } 11619 } 11620 }; 11621 this.reset(); 11622 } 11623 EventedTokenizer.prototype.reset = function () { 11624 this.transitionTo("beforeData" /* beforeData */); 11625 this.input = ''; 11626 this.tagNameBuffer = ''; 11627 this.index = 0; 11628 this.line = 1; 11629 this.column = 0; 11630 this.delegate.reset(); 11631 }; 11632 EventedTokenizer.prototype.transitionTo = function (state) { 11633 this.state = state; 11634 }; 11635 EventedTokenizer.prototype.tokenize = function (input) { 11636 this.reset(); 11637 this.tokenizePart(input); 11638 this.tokenizeEOF(); 11639 }; 11640 EventedTokenizer.prototype.tokenizePart = function (input) { 11641 this.input += preprocessInput(input); 11642 while (this.index < this.input.length) { 11643 var handler = this.states[this.state]; 11644 if (handler !== undefined) { 11645 handler.call(this); 11646 } 11647 else { 11648 throw new Error("unhandled state " + this.state); 11649 } 11650 } 11651 }; 11652 EventedTokenizer.prototype.tokenizeEOF = function () { 11653 this.flushData(); 11654 }; 11655 EventedTokenizer.prototype.flushData = function () { 11656 if (this.state === 'data') { 11657 this.delegate.finishData(); 11658 this.transitionTo("beforeData" /* beforeData */); 11659 } 11660 }; 11661 EventedTokenizer.prototype.peek = function () { 11662 return this.input.charAt(this.index); 11663 }; 11664 EventedTokenizer.prototype.consume = function () { 11665 var char = this.peek(); 11666 this.index++; 11667 if (char === '\n') { 11668 this.line++; 11669 this.column = 0; 11670 } 11671 else { 11672 this.column++; 11673 } 11674 return char; 11675 }; 11676 EventedTokenizer.prototype.consumeCharRef = function () { 11677 var endIndex = this.input.indexOf(';', this.index); 11678 if (endIndex === -1) { 11679 return; 11680 } 11681 var entity = this.input.slice(this.index, endIndex); 11682 var chars = this.entityParser.parse(entity); 11683 if (chars) { 11684 var count = entity.length; 11685 // consume the entity chars 11686 while (count) { 11687 this.consume(); 11688 count--; 11689 } 11690 // consume the `;` 11691 this.consume(); 11692 return chars; 11693 } 11694 }; 11695 EventedTokenizer.prototype.markTagStart = function () { 11696 this.delegate.tagOpen(); 11697 }; 11698 EventedTokenizer.prototype.appendToTagName = function (char) { 11699 this.tagNameBuffer += char; 11700 this.delegate.appendToTagName(char); 11701 }; 11702 EventedTokenizer.prototype.isIgnoredEndTag = function () { 11703 var tag = this.tagNameBuffer; 11704 return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') || 11705 (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') || 11706 (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>'); 11707 }; 11708 return EventedTokenizer; 11709 }()); 11710 11711 var Tokenizer = /** @class */ (function () { 11712 function Tokenizer(entityParser, options) { 11713 if (options === void 0) { options = {}; } 11714 this.options = options; 11715 this.token = null; 11716 this.startLine = 1; 11717 this.startColumn = 0; 11718 this.tokens = []; 11719 this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); 11720 this._currentAttribute = undefined; 11721 } 11722 Tokenizer.prototype.tokenize = function (input) { 11723 this.tokens = []; 11724 this.tokenizer.tokenize(input); 11725 return this.tokens; 11726 }; 11727 Tokenizer.prototype.tokenizePart = function (input) { 11728 this.tokens = []; 11729 this.tokenizer.tokenizePart(input); 11730 return this.tokens; 11731 }; 11732 Tokenizer.prototype.tokenizeEOF = function () { 11733 this.tokens = []; 11734 this.tokenizer.tokenizeEOF(); 11735 return this.tokens[0]; 11736 }; 11737 Tokenizer.prototype.reset = function () { 11738 this.token = null; 11739 this.startLine = 1; 11740 this.startColumn = 0; 11741 }; 11742 Tokenizer.prototype.current = function () { 11743 var token = this.token; 11744 if (token === null) { 11745 throw new Error('token was unexpectedly null'); 11746 } 11747 if (arguments.length === 0) { 11748 return token; 11749 } 11750 for (var i = 0; i < arguments.length; i++) { 11751 if (token.type === arguments[i]) { 11752 return token; 11753 } 11754 } 11755 throw new Error("token type was unexpectedly " + token.type); 11756 }; 11757 Tokenizer.prototype.push = function (token) { 11758 this.token = token; 11759 this.tokens.push(token); 11760 }; 11761 Tokenizer.prototype.currentAttribute = function () { 11762 return this._currentAttribute; 11763 }; 11764 Tokenizer.prototype.addLocInfo = function () { 11765 if (this.options.loc) { 11766 this.current().loc = { 11767 start: { 11768 line: this.startLine, 11769 column: this.startColumn 11770 }, 11771 end: { 11772 line: this.tokenizer.line, 11773 column: this.tokenizer.column 11774 } 11775 }; 11776 } 11777 this.startLine = this.tokenizer.line; 11778 this.startColumn = this.tokenizer.column; 11779 }; 11780 // Data 11781 Tokenizer.prototype.beginDoctype = function () { 11782 this.push({ 11783 type: "Doctype" /* Doctype */, 11784 name: '', 11785 }); 11786 }; 11787 Tokenizer.prototype.appendToDoctypeName = function (char) { 11788 this.current("Doctype" /* Doctype */).name += char; 11789 }; 11790 Tokenizer.prototype.appendToDoctypePublicIdentifier = function (char) { 11791 var doctype = this.current("Doctype" /* Doctype */); 11792 if (doctype.publicIdentifier === undefined) { 11793 doctype.publicIdentifier = char; 11794 } 11795 else { 11796 doctype.publicIdentifier += char; 11797 } 11798 }; 11799 Tokenizer.prototype.appendToDoctypeSystemIdentifier = function (char) { 11800 var doctype = this.current("Doctype" /* Doctype */); 11801 if (doctype.systemIdentifier === undefined) { 11802 doctype.systemIdentifier = char; 11803 } 11804 else { 11805 doctype.systemIdentifier += char; 11806 } 11807 }; 11808 Tokenizer.prototype.endDoctype = function () { 11809 this.addLocInfo(); 11810 }; 11811 Tokenizer.prototype.beginData = function () { 11812 this.push({ 11813 type: "Chars" /* Chars */, 11814 chars: '' 11815 }); 11816 }; 11817 Tokenizer.prototype.appendToData = function (char) { 11818 this.current("Chars" /* Chars */).chars += char; 11819 }; 11820 Tokenizer.prototype.finishData = function () { 11821 this.addLocInfo(); 11822 }; 11823 // Comment 11824 Tokenizer.prototype.beginComment = function () { 11825 this.push({ 11826 type: "Comment" /* Comment */, 11827 chars: '' 11828 }); 11829 }; 11830 Tokenizer.prototype.appendToCommentData = function (char) { 11831 this.current("Comment" /* Comment */).chars += char; 11832 }; 11833 Tokenizer.prototype.finishComment = function () { 11834 this.addLocInfo(); 11835 }; 11836 // Tags - basic 11837 Tokenizer.prototype.tagOpen = function () { }; 11838 Tokenizer.prototype.beginStartTag = function () { 11839 this.push({ 11840 type: "StartTag" /* StartTag */, 11841 tagName: '', 11842 attributes: [], 11843 selfClosing: false 11844 }); 11845 }; 11846 Tokenizer.prototype.beginEndTag = function () { 11847 this.push({ 11848 type: "EndTag" /* EndTag */, 11849 tagName: '' 11850 }); 11851 }; 11852 Tokenizer.prototype.finishTag = function () { 11853 this.addLocInfo(); 11854 }; 11855 Tokenizer.prototype.markTagAsSelfClosing = function () { 11856 this.current("StartTag" /* StartTag */).selfClosing = true; 11857 }; 11858 // Tags - name 11859 Tokenizer.prototype.appendToTagName = function (char) { 11860 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 11861 }; 11862 // Tags - attributes 11863 Tokenizer.prototype.beginAttribute = function () { 11864 this._currentAttribute = ['', '', false]; 11865 }; 11866 Tokenizer.prototype.appendToAttributeName = function (char) { 11867 this.currentAttribute()[0] += char; 11868 }; 11869 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 11870 this.currentAttribute()[2] = isQuoted; 11871 }; 11872 Tokenizer.prototype.appendToAttributeValue = function (char) { 11873 this.currentAttribute()[1] += char; 11874 }; 11875 Tokenizer.prototype.finishAttributeValue = function () { 11876 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 11877 }; 11878 Tokenizer.prototype.reportSyntaxError = function (message) { 11879 this.current().syntaxError = message; 11880 }; 11881 return Tokenizer; 11882 }()); 11883 11884 function tokenize(input, options) { 11885 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 11886 return tokenizer.tokenize(input); 11887 } 11888 11889 11890 11891 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 11892 var es6 = __webpack_require__(7734); 11893 var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 11894 ;// CONCATENATED MODULE: external ["wp","htmlEntities"] 11895 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 11896 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js 11897 /** 11898 * @typedef LoggerItem 11899 * @property {Function} log Which logger recorded the message 11900 * @property {Array<any>} args White arguments were supplied to the logger 11901 */ 11902 11903 function createLogger() { 11904 /** 11905 * Creates a log handler with block validation prefix. 11906 * 11907 * @param {Function} logger Original logger function. 11908 * 11909 * @return {Function} Augmented logger function. 11910 */ 11911 function createLogHandler(logger) { 11912 let log = (message, ...args) => logger('Block validation: ' + message, ...args); 11913 11914 // In test environments, pre-process string substitutions to improve 11915 // readability of error messages. We'd prefer to avoid pulling in this 11916 // dependency in runtime environments, and it can be dropped by a combo 11917 // of Webpack env substitution + UglifyJS dead code elimination. 11918 if (false) {} 11919 return log; 11920 } 11921 return { 11922 // eslint-disable-next-line no-console 11923 error: createLogHandler(console.error), 11924 // eslint-disable-next-line no-console 11925 warning: createLogHandler(console.warn), 11926 getItems() { 11927 return []; 11928 } 11929 }; 11930 } 11931 function createQueuedLogger() { 11932 /** 11933 * The list of enqueued log actions to print. 11934 * 11935 * @type {Array<LoggerItem>} 11936 */ 11937 const queue = []; 11938 const logger = createLogger(); 11939 return { 11940 error(...args) { 11941 queue.push({ 11942 log: logger.error, 11943 args 11944 }); 11945 }, 11946 warning(...args) { 11947 queue.push({ 11948 log: logger.warning, 11949 args 11950 }); 11951 }, 11952 getItems() { 11953 return queue; 11954 } 11955 }; 11956 } 11957 11958 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/index.js 11959 /** 11960 * External dependencies 11961 */ 11962 11963 11964 11965 /** 11966 * WordPress dependencies 11967 */ 11968 11969 11970 11971 /** 11972 * Internal dependencies 11973 */ 11974 11975 11976 11977 11978 11979 /** @typedef {import('../parser').WPBlock} WPBlock */ 11980 /** @typedef {import('../registration').WPBlockType} WPBlockType */ 11981 /** @typedef {import('./logger').LoggerItem} LoggerItem */ 11982 11983 const identity = x => x; 11984 11985 /** 11986 * Globally matches any consecutive whitespace 11987 * 11988 * @type {RegExp} 11989 */ 11990 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 11991 11992 /** 11993 * Matches a string containing only whitespace 11994 * 11995 * @type {RegExp} 11996 */ 11997 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 11998 11999 /** 12000 * Matches a CSS URL type value 12001 * 12002 * @type {RegExp} 12003 */ 12004 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 12005 12006 /** 12007 * Boolean attributes are attributes whose presence as being assigned is 12008 * meaningful, even if only empty. 12009 * 12010 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 12011 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 12012 * 12013 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 12014 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 12015 * .reduce( ( result, tr ) => Object.assign( result, { 12016 * [ tr.firstChild.textContent.trim() ]: true 12017 * } ), {} ) ).sort(); 12018 * 12019 * @type {Array} 12020 */ 12021 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']; 12022 12023 /** 12024 * Enumerated attributes are attributes which must be of a specific value form. 12025 * Like boolean attributes, these are meaningful if specified, even if not of a 12026 * valid enumerated value. 12027 * 12028 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 12029 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 12030 * 12031 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 12032 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 12033 * .reduce( ( result, tr ) => Object.assign( result, { 12034 * [ tr.firstChild.textContent.trim() ]: true 12035 * } ), {} ) ).sort(); 12036 * 12037 * @type {Array} 12038 */ 12039 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']; 12040 12041 /** 12042 * Meaningful attributes are those who cannot be safely ignored when omitted in 12043 * one HTML markup string and not another. 12044 * 12045 * @type {Array} 12046 */ 12047 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 12048 12049 /** 12050 * Array of functions which receive a text string on which to apply normalizing 12051 * behavior for consideration in text token equivalence, carefully ordered from 12052 * least-to-most expensive operations. 12053 * 12054 * @type {Array} 12055 */ 12056 const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace]; 12057 12058 /** 12059 * Regular expression matching a named character reference. In lieu of bundling 12060 * a full set of references, the pattern covers the minimal necessary to test 12061 * positively against the full set. 12062 * 12063 * "The ampersand must be followed by one of the names given in the named 12064 * character references section, using the same case." 12065 * 12066 * Tested aginst "12.5 Named character references": 12067 * 12068 * ``` 12069 * const references = Array.from( document.querySelectorAll( 12070 * '#named-character-references-table tr[id^=entity-] td:first-child' 12071 * ) ).map( ( code ) => code.textContent ) 12072 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 12073 * ``` 12074 * 12075 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12076 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 12077 * 12078 * @type {RegExp} 12079 */ 12080 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 12081 12082 /** 12083 * Regular expression matching a decimal character reference. 12084 * 12085 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 12086 * followed by one or more ASCII digits, representing a base-ten integer" 12087 * 12088 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12089 * 12090 * @type {RegExp} 12091 */ 12092 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 12093 12094 /** 12095 * Regular expression matching a hexadecimal character reference. 12096 * 12097 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 12098 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 12099 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 12100 * one or more ASCII hex digits, representing a hexadecimal integer" 12101 * 12102 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12103 * 12104 * @type {RegExp} 12105 */ 12106 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 12107 12108 /** 12109 * Returns true if the given string is a valid character reference segment, or 12110 * false otherwise. The text should be stripped of `&` and `;` demarcations. 12111 * 12112 * @param {string} text Text to test. 12113 * 12114 * @return {boolean} Whether text is valid character reference. 12115 */ 12116 function isValidCharacterReference(text) { 12117 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 12118 } 12119 12120 /** 12121 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the 12122 * implementation of `decodeEntities` from `html-entities`, in order to avoid 12123 * bundling a massive named character reference. 12124 * 12125 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 12126 */ 12127 class DecodeEntityParser { 12128 /** 12129 * Returns a substitute string for an entity string sequence between `&` 12130 * and `;`, or undefined if no substitution should occur. 12131 * 12132 * @param {string} entity Entity fragment discovered in HTML. 12133 * 12134 * @return {string | undefined} Entity substitute value. 12135 */ 12136 parse(entity) { 12137 if (isValidCharacterReference(entity)) { 12138 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';'); 12139 } 12140 } 12141 } 12142 12143 /** 12144 * Given a specified string, returns an array of strings split by consecutive 12145 * whitespace, ignoring leading or trailing whitespace. 12146 * 12147 * @param {string} text Original text. 12148 * 12149 * @return {string[]} Text pieces split on whitespace. 12150 */ 12151 function getTextPiecesSplitOnWhitespace(text) { 12152 return text.trim().split(REGEXP_WHITESPACE); 12153 } 12154 12155 /** 12156 * Given a specified string, returns a new trimmed string where all consecutive 12157 * whitespace is collapsed to a single space. 12158 * 12159 * @param {string} text Original text. 12160 * 12161 * @return {string} Trimmed text with consecutive whitespace collapsed. 12162 */ 12163 function getTextWithCollapsedWhitespace(text) { 12164 // This is an overly simplified whitespace comparison. The specification is 12165 // more prescriptive of whitespace behavior in inline and block contexts. 12166 // 12167 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33 12168 return getTextPiecesSplitOnWhitespace(text).join(' '); 12169 } 12170 12171 /** 12172 * Returns attribute pairs of the given StartTag token, including only pairs 12173 * where the value is non-empty or the attribute is a boolean attribute, an 12174 * enumerated attribute, or a custom data- attribute. 12175 * 12176 * @see MEANINGFUL_ATTRIBUTES 12177 * 12178 * @param {Object} token StartTag token. 12179 * 12180 * @return {Array[]} Attribute pairs. 12181 */ 12182 function getMeaningfulAttributePairs(token) { 12183 return token.attributes.filter(pair => { 12184 const [key, value] = pair; 12185 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key); 12186 }); 12187 } 12188 12189 /** 12190 * Returns true if two text tokens (with `chars` property) are equivalent, or 12191 * false otherwise. 12192 * 12193 * @param {Object} actual Actual token. 12194 * @param {Object} expected Expected token. 12195 * @param {Object} logger Validation logger object. 12196 * 12197 * @return {boolean} Whether two text tokens are equivalent. 12198 */ 12199 function isEquivalentTextTokens(actual, expected, logger = createLogger()) { 12200 // This function is intentionally written as syntactically "ugly" as a hot 12201 // path optimization. Text is progressively normalized in order from least- 12202 // to-most operationally expensive, until the earliest point at which text 12203 // can be confidently inferred as being equal. 12204 let actualChars = actual.chars; 12205 let expectedChars = expected.chars; 12206 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 12207 const normalize = TEXT_NORMALIZATIONS[i]; 12208 actualChars = normalize(actualChars); 12209 expectedChars = normalize(expectedChars); 12210 if (actualChars === expectedChars) { 12211 return true; 12212 } 12213 } 12214 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 12215 return false; 12216 } 12217 12218 /** 12219 * Given a CSS length value, returns a normalized CSS length value for strict equality 12220 * comparison. 12221 * 12222 * @param {string} value CSS length value. 12223 * 12224 * @return {string} Normalized CSS length value. 12225 */ 12226 function getNormalizedLength(value) { 12227 if (0 === parseFloat(value)) { 12228 return '0'; 12229 } 12230 // Normalize strings with floats to always include a leading zero. 12231 if (value.indexOf('.') === 0) { 12232 return '0' + value; 12233 } 12234 return value; 12235 } 12236 12237 /** 12238 * Given a style value, returns a normalized style value for strict equality 12239 * comparison. 12240 * 12241 * @param {string} value Style value. 12242 * 12243 * @return {string} Normalized style value. 12244 */ 12245 function getNormalizedStyleValue(value) { 12246 const textPieces = getTextPiecesSplitOnWhitespace(value); 12247 const normalizedPieces = textPieces.map(getNormalizedLength); 12248 const result = normalizedPieces.join(' '); 12249 return result 12250 // Normalize URL type to omit whitespace or quotes. 12251 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 12252 } 12253 12254 /** 12255 * Given a style attribute string, returns an object of style properties. 12256 * 12257 * @param {string} text Style attribute. 12258 * 12259 * @return {Object} Style properties. 12260 */ 12261 function getStyleProperties(text) { 12262 const pairs = text 12263 // Trim ending semicolon (avoid including in split) 12264 .replace(/;?\s*$/, '') 12265 // Split on property assignment. 12266 .split(';') 12267 // For each property assignment... 12268 .map(style => { 12269 // ...split further into key-value pairs. 12270 const [key, ...valueParts] = style.split(':'); 12271 const value = valueParts.join(':'); 12272 return [key.trim(), getNormalizedStyleValue(value.trim())]; 12273 }); 12274 return Object.fromEntries(pairs); 12275 } 12276 12277 /** 12278 * Attribute-specific equality handlers 12279 * 12280 * @type {Object} 12281 */ 12282 const isEqualAttributesOfName = { 12283 class: (actual, expected) => { 12284 // Class matches if members are the same, even if out of order or 12285 // superfluous whitespace between. 12286 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace); 12287 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c)); 12288 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c)); 12289 return actualDiff.length === 0 && expectedDiff.length === 0; 12290 }, 12291 style: (actual, expected) => { 12292 return es6_default()(...[actual, expected].map(getStyleProperties)); 12293 }, 12294 // For each boolean attribute, mere presence of attribute in both is enough 12295 // to assume equivalence. 12296 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true])) 12297 }; 12298 12299 /** 12300 * Given two sets of attribute tuples, returns true if the attribute sets are 12301 * equivalent. 12302 * 12303 * @param {Array[]} actual Actual attributes tuples. 12304 * @param {Array[]} expected Expected attributes tuples. 12305 * @param {Object} logger Validation logger object. 12306 * 12307 * @return {boolean} Whether attributes are equivalent. 12308 */ 12309 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) { 12310 // Attributes is tokenized as tuples. Their lengths should match. This also 12311 // avoids us needing to check both attributes sets, since if A has any keys 12312 // which do not exist in B, we know the sets to be different. 12313 if (actual.length !== expected.length) { 12314 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 12315 return false; 12316 } 12317 12318 // Attributes are not guaranteed to occur in the same order. For validating 12319 // actual attributes, first convert the set of expected attribute values to 12320 // an object, for lookup by key. 12321 const expectedAttributes = {}; 12322 for (let i = 0; i < expected.length; i++) { 12323 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 12324 } 12325 for (let i = 0; i < actual.length; i++) { 12326 const [name, actualValue] = actual[i]; 12327 const nameLower = name.toLowerCase(); 12328 12329 // As noted above, if missing member in B, assume different. 12330 if (!expectedAttributes.hasOwnProperty(nameLower)) { 12331 logger.warning('Encountered unexpected attribute `%s`.', name); 12332 return false; 12333 } 12334 const expectedValue = expectedAttributes[nameLower]; 12335 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 12336 if (isEqualAttributes) { 12337 // Defer custom attribute equality handling. 12338 if (!isEqualAttributes(actualValue, expectedValue)) { 12339 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12340 return false; 12341 } 12342 } else if (actualValue !== expectedValue) { 12343 // Otherwise strict inequality should bail. 12344 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12345 return false; 12346 } 12347 } 12348 return true; 12349 } 12350 12351 /** 12352 * Token-type-specific equality handlers 12353 * 12354 * @type {Object} 12355 */ 12356 const isEqualTokensOfType = { 12357 StartTag: (actual, expected, logger = createLogger()) => { 12358 if (actual.tagName !== expected.tagName && 12359 // Optimization: Use short-circuit evaluation to defer case- 12360 // insensitive check on the assumption that the majority case will 12361 // have exactly equal tag names. 12362 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 12363 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 12364 return false; 12365 } 12366 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 12367 }, 12368 Chars: isEquivalentTextTokens, 12369 Comment: isEquivalentTextTokens 12370 }; 12371 12372 /** 12373 * Given an array of tokens, returns the first token which is not purely 12374 * whitespace. 12375 * 12376 * Mutates the tokens array. 12377 * 12378 * @param {Object[]} tokens Set of tokens to search. 12379 * 12380 * @return {Object | undefined} Next non-whitespace token. 12381 */ 12382 function getNextNonWhitespaceToken(tokens) { 12383 let token; 12384 while (token = tokens.shift()) { 12385 if (token.type !== 'Chars') { 12386 return token; 12387 } 12388 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 12389 return token; 12390 } 12391 } 12392 } 12393 12394 /** 12395 * Tokenize an HTML string, gracefully handling any errors thrown during 12396 * underlying tokenization. 12397 * 12398 * @param {string} html HTML string to tokenize. 12399 * @param {Object} logger Validation logger object. 12400 * 12401 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 12402 */ 12403 function getHTMLTokens(html, logger = createLogger()) { 12404 try { 12405 return new Tokenizer(new DecodeEntityParser()).tokenize(html); 12406 } catch (e) { 12407 logger.warning('Malformed HTML detected: %s', html); 12408 } 12409 return null; 12410 } 12411 12412 /** 12413 * Returns true if the next HTML token closes the current token. 12414 * 12415 * @param {Object} currentToken Current token to compare with. 12416 * @param {Object|undefined} nextToken Next token to compare against. 12417 * 12418 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 12419 */ 12420 function isClosedByToken(currentToken, nextToken) { 12421 // Ensure this is a self closed token. 12422 if (!currentToken.selfClosing) { 12423 return false; 12424 } 12425 12426 // Check token names and determine if nextToken is the closing tag for currentToken. 12427 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 12428 return true; 12429 } 12430 return false; 12431 } 12432 12433 /** 12434 * Returns true if the given HTML strings are effectively equivalent, or 12435 * false otherwise. Invalid HTML is not considered equivalent, even if the 12436 * strings directly match. 12437 * 12438 * @param {string} actual Actual HTML string. 12439 * @param {string} expected Expected HTML string. 12440 * @param {Object} logger Validation logger object. 12441 * 12442 * @return {boolean} Whether HTML strings are equivalent. 12443 */ 12444 function isEquivalentHTML(actual, expected, logger = createLogger()) { 12445 // Short-circuit if markup is identical. 12446 if (actual === expected) { 12447 return true; 12448 } 12449 12450 // Tokenize input content and reserialized save content. 12451 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); 12452 12453 // If either is malformed then stop comparing - the strings are not equivalent. 12454 if (!actualTokens || !expectedTokens) { 12455 return false; 12456 } 12457 let actualToken, expectedToken; 12458 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 12459 expectedToken = getNextNonWhitespaceToken(expectedTokens); 12460 12461 // Inequal if exhausted all expected tokens. 12462 if (!expectedToken) { 12463 logger.warning('Expected end of content, instead saw %o.', actualToken); 12464 return false; 12465 } 12466 12467 // Inequal if next non-whitespace token of each set are not same type. 12468 if (actualToken.type !== expectedToken.type) { 12469 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 12470 return false; 12471 } 12472 12473 // Defer custom token type equality handling, otherwise continue and 12474 // assume as equal. 12475 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 12476 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 12477 return false; 12478 } 12479 12480 // Peek at the next tokens (actual and expected) to see if they close 12481 // a self-closing tag. 12482 if (isClosedByToken(actualToken, expectedTokens[0])) { 12483 // Consume the next expected token that closes the current actual 12484 // self-closing token. 12485 getNextNonWhitespaceToken(expectedTokens); 12486 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 12487 // Consume the next actual token that closes the current expected 12488 // self-closing token. 12489 getNextNonWhitespaceToken(actualTokens); 12490 } 12491 } 12492 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 12493 // If any non-whitespace tokens remain in expected token set, this 12494 // indicates inequality. 12495 logger.warning('Expected %o, instead saw end of content.', expectedToken); 12496 return false; 12497 } 12498 return true; 12499 } 12500 12501 /** 12502 * Returns an object with `isValid` property set to `true` if the parsed block 12503 * is valid given the input content. A block is considered valid if, when serialized 12504 * with assumed attributes, the content matches the original value. If block is 12505 * invalid, this function returns all validations issues as well. 12506 * 12507 * @param {string|Object} blockTypeOrName Block type. 12508 * @param {Object} attributes Parsed block attributes. 12509 * @param {string} originalBlockContent Original block content. 12510 * @param {Object} logger Validation logger object. 12511 * 12512 * @return {Object} Whether block is valid and contains validation messages. 12513 */ 12514 12515 /** 12516 * Returns an object with `isValid` property set to `true` if the parsed block 12517 * is valid given the input content. A block is considered valid if, when serialized 12518 * with assumed attributes, the content matches the original value. If block is 12519 * invalid, this function returns all validations issues as well. 12520 * 12521 * @param {WPBlock} block block object. 12522 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. 12523 * 12524 * @return {[boolean,Array<LoggerItem>]} validation results. 12525 */ 12526 function validateBlock(block, blockTypeOrName = block.name) { 12527 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); 12528 12529 // Shortcut to avoid costly validation. 12530 if (isFallbackBlock) { 12531 return [true, []]; 12532 } 12533 const logger = createQueuedLogger(); 12534 const blockType = normalizeBlockType(blockTypeOrName); 12535 let generatedBlockContent; 12536 try { 12537 generatedBlockContent = getSaveContent(blockType, block.attributes); 12538 } catch (error) { 12539 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 12540 return [false, logger.getItems()]; 12541 } 12542 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger); 12543 if (!isValid) { 12544 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); 12545 } 12546 return [isValid, logger.getItems()]; 12547 } 12548 12549 /** 12550 * Returns true if the parsed block is valid given the input content. A block 12551 * is considered valid if, when serialized with assumed attributes, the content 12552 * matches the original value. 12553 * 12554 * Logs to console in development environments when invalid. 12555 * 12556 * @deprecated Use validateBlock instead to avoid data loss. 12557 * 12558 * @param {string|Object} blockTypeOrName Block type. 12559 * @param {Object} attributes Parsed block attributes. 12560 * @param {string} originalBlockContent Original block content. 12561 * 12562 * @return {boolean} Whether block is valid. 12563 */ 12564 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 12565 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', { 12566 since: '12.6', 12567 plugin: 'Gutenberg', 12568 alternative: 'validateBlock' 12569 }); 12570 const blockType = normalizeBlockType(blockTypeOrName); 12571 const block = { 12572 name: blockType.name, 12573 attributes, 12574 innerBlocks: [], 12575 originalContent: originalBlockContent 12576 }; 12577 const [isValid] = validateBlock(block, blockType); 12578 return isValid; 12579 } 12580 12581 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/convert-legacy-block.js 12582 /** 12583 * Convert legacy blocks to their canonical form. This function is used 12584 * both in the parser level for previous content and to convert such blocks 12585 * used in Custom Post Types templates. 12586 * 12587 * @param {string} name The block's name 12588 * @param {Object} attributes The block's attributes 12589 * 12590 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found 12591 */ 12592 function convertLegacyBlockNameAndAttributes(name, attributes) { 12593 const newAttributes = { 12594 ...attributes 12595 }; 12596 // Convert 'core/cover-image' block in existing content to 'core/cover'. 12597 if ('core/cover-image' === name) { 12598 name = 'core/cover'; 12599 } 12600 12601 // Convert 'core/text' blocks in existing content to 'core/paragraph'. 12602 if ('core/text' === name || 'core/cover-text' === name) { 12603 name = 'core/paragraph'; 12604 } 12605 12606 // Convert derivative blocks such as 'core/social-link-wordpress' to the 12607 // canonical form 'core/social-link'. 12608 if (name && name.indexOf('core/social-link-') === 0) { 12609 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 12610 newAttributes.service = name.substring(17); 12611 name = 'core/social-link'; 12612 } 12613 12614 // Convert derivative blocks such as 'core-embed/instagram' to the 12615 // canonical form 'core/embed'. 12616 if (name && name.indexOf('core-embed/') === 0) { 12617 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 12618 const providerSlug = name.substring(11); 12619 const deprecated = { 12620 speaker: 'speaker-deck', 12621 polldaddy: 'crowdsignal' 12622 }; 12623 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; 12624 // This is needed as the `responsive` attribute was passed 12625 // in a different way before the refactoring to block variations. 12626 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 12627 newAttributes.responsive = true; 12628 } 12629 name = 'core/embed'; 12630 } 12631 12632 // Convert Post Comment blocks in existing content to Comment blocks. 12633 // TODO: Remove these checks when WordPress 6.0 is released. 12634 if (name === 'core/post-comment-author') { 12635 name = 'core/comment-author-name'; 12636 } 12637 if (name === 'core/post-comment-content') { 12638 name = 'core/comment-content'; 12639 } 12640 if (name === 'core/post-comment-date') { 12641 name = 'core/comment-date'; 12642 } 12643 if (name === 'core/comments-query-loop') { 12644 name = 'core/comments'; 12645 const { 12646 className = '' 12647 } = newAttributes; 12648 if (!className.includes('wp-block-comments-query-loop')) { 12649 newAttributes.className = ['wp-block-comments-query-loop', className].join(' '); 12650 } 12651 // Note that we also had to add a deprecation to the block in order 12652 // for the ID change to work. 12653 } 12654 if (name === 'core/post-comments') { 12655 name = 'core/comments'; 12656 newAttributes.legacy = true; 12657 } 12658 12659 // Column count was stored as a string from WP 6.3-6.6. Convert it to a number. 12660 if (attributes.layout?.type === 'grid' && typeof attributes.layout?.columnCount === 'string') { 12661 newAttributes.layout = { 12662 ...newAttributes.layout, 12663 columnCount: parseInt(attributes.layout.columnCount, 10) 12664 }; 12665 } 12666 12667 // Column span and row span were stored as strings in WP 6.6. Convert them to numbers. 12668 if (typeof attributes.style?.layout?.columnSpan === 'string') { 12669 const columnSpanNumber = parseInt(attributes.style.layout.columnSpan, 10); 12670 newAttributes.style = { 12671 ...newAttributes.style, 12672 layout: { 12673 ...newAttributes.style.layout, 12674 columnSpan: isNaN(columnSpanNumber) ? undefined : columnSpanNumber 12675 } 12676 }; 12677 } 12678 if (typeof attributes.style?.layout?.rowSpan === 'string') { 12679 const rowSpanNumber = parseInt(attributes.style.layout.rowSpan, 10); 12680 newAttributes.style = { 12681 ...newAttributes.style, 12682 layout: { 12683 ...newAttributes.style.layout, 12684 rowSpan: isNaN(rowSpanNumber) ? undefined : rowSpanNumber 12685 } 12686 }; 12687 } 12688 12689 // The following code is only relevant for the Gutenberg plugin. 12690 // It's a stand-alone if statement for dead-code elimination. 12691 if (false) {} 12692 return [name, newAttributes]; 12693 } 12694 12695 ;// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js 12696 /** 12697 * Given object and string of dot-delimited path segments, returns value at 12698 * path or undefined if path cannot be resolved. 12699 * 12700 * @param {Object} object Lookup object 12701 * @param {string} path Path to resolve 12702 * @return {?*} Resolved value 12703 */ 12704 function getPath(object, path) { 12705 var segments = path.split('.'); 12706 var segment; 12707 12708 while (segment = segments.shift()) { 12709 if (!(segment in object)) { 12710 return; 12711 } 12712 12713 object = object[segment]; 12714 } 12715 12716 return object; 12717 } 12718 ;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js 12719 /** 12720 * Internal dependencies 12721 */ 12722 12723 /** 12724 * Function returning a DOM document created by `createHTMLDocument`. The same 12725 * document is returned between invocations. 12726 * 12727 * @return {Document} DOM document. 12728 */ 12729 12730 var getDocument = function () { 12731 var doc; 12732 return function () { 12733 if (!doc) { 12734 doc = document.implementation.createHTMLDocument(''); 12735 } 12736 12737 return doc; 12738 }; 12739 }(); 12740 /** 12741 * Given a markup string or DOM element, creates an object aligning with the 12742 * shape of the matchers object, or the value returned by the matcher. 12743 * 12744 * @param {(string|Element)} source Source content 12745 * @param {(Object|Function)} matchers Matcher function or object of matchers 12746 * @return {(Object|*)} Matched value(s), shaped by object 12747 */ 12748 12749 12750 function parse(source, matchers) { 12751 if (!matchers) { 12752 return; 12753 } // Coerce to element 12754 12755 12756 if ('string' === typeof source) { 12757 var doc = getDocument(); 12758 doc.body.innerHTML = source; 12759 source = doc.body; 12760 } // Return singular value 12761 12762 12763 if ('function' === typeof matchers) { 12764 return matchers(source); 12765 } // Bail if we can't handle matchers 12766 12767 12768 if (Object !== matchers.constructor) { 12769 return; 12770 } // Shape result by matcher object 12771 12772 12773 return Object.keys(matchers).reduce(function (memo, key) { 12774 memo[key] = parse(source, matchers[key]); 12775 return memo; 12776 }, {}); 12777 } 12778 /** 12779 * Generates a function which matches node of type selector, returning an 12780 * attribute by property if the attribute exists. If no selector is passed, 12781 * returns property of the query element. 12782 * 12783 * @param {?string} selector Optional selector 12784 * @param {string} name Property name 12785 * @return {*} Property value 12786 */ 12787 12788 function prop(selector, name) { 12789 if (1 === arguments.length) { 12790 name = selector; 12791 selector = undefined; 12792 } 12793 12794 return function (node) { 12795 var match = node; 12796 12797 if (selector) { 12798 match = node.querySelector(selector); 12799 } 12800 12801 if (match) { 12802 return getPath(match, name); 12803 } 12804 }; 12805 } 12806 /** 12807 * Generates a function which matches node of type selector, returning an 12808 * attribute by name if the attribute exists. If no selector is passed, 12809 * returns attribute of the query element. 12810 * 12811 * @param {?string} selector Optional selector 12812 * @param {string} name Attribute name 12813 * @return {?string} Attribute value 12814 */ 12815 12816 function attr(selector, name) { 12817 if (1 === arguments.length) { 12818 name = selector; 12819 selector = undefined; 12820 } 12821 12822 return function (node) { 12823 var attributes = prop(selector, 'attributes')(node); 12824 12825 if (attributes && attributes.hasOwnProperty(name)) { 12826 return attributes[name].value; 12827 } 12828 }; 12829 } 12830 /** 12831 * Convenience for `prop( selector, 'innerHTML' )`. 12832 * 12833 * @see prop() 12834 * 12835 * @param {?string} selector Optional selector 12836 * @return {string} Inner HTML 12837 */ 12838 12839 function html(selector) { 12840 return prop(selector, 'innerHTML'); 12841 } 12842 /** 12843 * Convenience for `prop( selector, 'textContent' )`. 12844 * 12845 * @see prop() 12846 * 12847 * @param {?string} selector Optional selector 12848 * @return {string} Text content 12849 */ 12850 12851 function es_text(selector) { 12852 return prop(selector, 'textContent'); 12853 } 12854 /** 12855 * Creates a new matching context by first finding elements matching selector 12856 * using querySelectorAll before then running another `parse` on `matchers` 12857 * scoped to the matched elements. 12858 * 12859 * @see parse() 12860 * 12861 * @param {string} selector Selector to match 12862 * @param {(Object|Function)} matchers Matcher function or object of matchers 12863 * @return {Array.<*,Object>} Array of matched value(s) 12864 */ 12865 12866 function query(selector, matchers) { 12867 return function (node) { 12868 var matches = node.querySelectorAll(selector); 12869 return [].map.call(matches, function (match) { 12870 return parse(match, matchers); 12871 }); 12872 }; 12873 } 12874 ;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js 12875 /** 12876 * Memize options object. 12877 * 12878 * @typedef MemizeOptions 12879 * 12880 * @property {number} [maxSize] Maximum size of the cache. 12881 */ 12882 12883 /** 12884 * Internal cache entry. 12885 * 12886 * @typedef MemizeCacheNode 12887 * 12888 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 12889 * @property {?MemizeCacheNode|undefined} [next] Next node. 12890 * @property {Array<*>} args Function arguments for cache 12891 * entry. 12892 * @property {*} val Function result. 12893 */ 12894 12895 /** 12896 * Properties of the enhanced function for controlling cache. 12897 * 12898 * @typedef MemizeMemoizedFunction 12899 * 12900 * @property {()=>void} clear Clear the cache. 12901 */ 12902 12903 /** 12904 * Accepts a function to be memoized, and returns a new memoized function, with 12905 * optional options. 12906 * 12907 * @template {(...args: any[]) => any} F 12908 * 12909 * @param {F} fn Function to memoize. 12910 * @param {MemizeOptions} [options] Options object. 12911 * 12912 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 12913 */ 12914 function memize(fn, options) { 12915 var size = 0; 12916 12917 /** @type {?MemizeCacheNode|undefined} */ 12918 var head; 12919 12920 /** @type {?MemizeCacheNode|undefined} */ 12921 var tail; 12922 12923 options = options || {}; 12924 12925 function memoized(/* ...args */) { 12926 var node = head, 12927 len = arguments.length, 12928 args, 12929 i; 12930 12931 searchCache: while (node) { 12932 // Perform a shallow equality test to confirm that whether the node 12933 // under test is a candidate for the arguments passed. Two arrays 12934 // are shallowly equal if their length matches and each entry is 12935 // strictly equal between the two sets. Avoid abstracting to a 12936 // function which could incur an arguments leaking deoptimization. 12937 12938 // Check whether node arguments match arguments length 12939 if (node.args.length !== arguments.length) { 12940 node = node.next; 12941 continue; 12942 } 12943 12944 // Check whether node arguments match arguments values 12945 for (i = 0; i < len; i++) { 12946 if (node.args[i] !== arguments[i]) { 12947 node = node.next; 12948 continue searchCache; 12949 } 12950 } 12951 12952 // At this point we can assume we've found a match 12953 12954 // Surface matched node to head if not already 12955 if (node !== head) { 12956 // As tail, shift to previous. Must only shift if not also 12957 // head, since if both head and tail, there is no previous. 12958 if (node === tail) { 12959 tail = node.prev; 12960 } 12961 12962 // Adjust siblings to point to each other. If node was tail, 12963 // this also handles new tail's empty `next` assignment. 12964 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 12965 if (node.next) { 12966 node.next.prev = node.prev; 12967 } 12968 12969 node.next = head; 12970 node.prev = null; 12971 /** @type {MemizeCacheNode} */ (head).prev = node; 12972 head = node; 12973 } 12974 12975 // Return immediately 12976 return node.val; 12977 } 12978 12979 // No cached value found. Continue to insertion phase: 12980 12981 // Create a copy of arguments (avoid leaking deoptimization) 12982 args = new Array(len); 12983 for (i = 0; i < len; i++) { 12984 args[i] = arguments[i]; 12985 } 12986 12987 node = { 12988 args: args, 12989 12990 // Generate the result from original function 12991 val: fn.apply(null, args), 12992 }; 12993 12994 // Don't need to check whether node is already head, since it would 12995 // have been returned above already if it was 12996 12997 // Shift existing head down list 12998 if (head) { 12999 head.prev = node; 13000 node.next = head; 13001 } else { 13002 // If no head, follows that there's no tail (at initial or reset) 13003 tail = node; 13004 } 13005 13006 // Trim tail if we're reached max size and are pending cache insertion 13007 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 13008 tail = /** @type {MemizeCacheNode} */ (tail).prev; 13009 /** @type {MemizeCacheNode} */ (tail).next = null; 13010 } else { 13011 size++; 13012 } 13013 13014 head = node; 13015 13016 return node.val; 13017 } 13018 13019 memoized.clear = function () { 13020 head = null; 13021 tail = null; 13022 size = 0; 13023 }; 13024 13025 // Ignore reason: There's not a clear solution to create an intersection of 13026 // the function with additional properties, where the goal is to retain the 13027 // function signature of the incoming argument and add control properties 13028 // on the return value. 13029 13030 // @ts-ignore 13031 return memoized; 13032 } 13033 13034 13035 13036 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/matchers.js 13037 /** 13038 * External dependencies 13039 */ 13040 13041 13042 /** 13043 * WordPress dependencies 13044 */ 13045 13046 13047 /** 13048 * Internal dependencies 13049 */ 13050 13051 13052 function matchers_html(selector, multilineTag) { 13053 return domNode => { 13054 let match = domNode; 13055 if (selector) { 13056 match = domNode.querySelector(selector); 13057 } 13058 if (!match) { 13059 return ''; 13060 } 13061 if (multilineTag) { 13062 let value = ''; 13063 const length = match.children.length; 13064 for (let index = 0; index < length; index++) { 13065 const child = match.children[index]; 13066 if (child.nodeName.toLowerCase() !== multilineTag) { 13067 continue; 13068 } 13069 value += child.outerHTML; 13070 } 13071 return value; 13072 } 13073 return match.innerHTML; 13074 }; 13075 } 13076 const richText = (selector, preserveWhiteSpace) => el => { 13077 const target = selector ? el.querySelector(selector) : el; 13078 return target ? external_wp_richText_namespaceObject.RichTextData.fromHTMLElement(target, { 13079 preserveWhiteSpace 13080 }) : external_wp_richText_namespaceObject.RichTextData.empty(); 13081 }; 13082 13083 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/node.js 13084 /** 13085 * WordPress dependencies 13086 */ 13087 13088 13089 /** 13090 * Internal dependencies 13091 */ 13092 13093 13094 /** 13095 * A representation of a single node within a block's rich text value. If 13096 * representing a text node, the value is simply a string of the node value. 13097 * As representing an element node, it is an object of: 13098 * 13099 * 1. `type` (string): Tag name. 13100 * 2. `props` (object): Attributes and children array of WPBlockNode. 13101 * 13102 * @typedef {string|Object} WPBlockNode 13103 */ 13104 13105 /** 13106 * Given a single node and a node type (e.g. `'br'`), returns true if the node 13107 * corresponds to that type, false otherwise. 13108 * 13109 * @param {WPBlockNode} node Block node to test 13110 * @param {string} type Node to type to test against. 13111 * 13112 * @return {boolean} Whether node is of intended type. 13113 */ 13114 function isNodeOfType(node, type) { 13115 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', { 13116 since: '6.1', 13117 version: '6.3', 13118 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13119 }); 13120 return node && node.type === type; 13121 } 13122 13123 /** 13124 * Given an object implementing the NamedNodeMap interface, returns a plain 13125 * object equivalent value of name, value key-value pairs. 13126 * 13127 * @see https://dom.spec.whatwg.org/#interface-namednodemap 13128 * 13129 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 13130 * 13131 * @return {Object} Object equivalent value of NamedNodeMap. 13132 */ 13133 function getNamedNodeMapAsObject(nodeMap) { 13134 const result = {}; 13135 for (let i = 0; i < nodeMap.length; i++) { 13136 const { 13137 name, 13138 value 13139 } = nodeMap[i]; 13140 result[name] = value; 13141 } 13142 return result; 13143 } 13144 13145 /** 13146 * Given a DOM Element or Text node, returns an equivalent block node. Throws 13147 * if passed any node type other than element or text. 13148 * 13149 * @throws {TypeError} If non-element/text node is passed. 13150 * 13151 * @param {Node} domNode DOM node to convert. 13152 * 13153 * @return {WPBlockNode} Block node equivalent to DOM node. 13154 */ 13155 function fromDOM(domNode) { 13156 external_wp_deprecated_default()('wp.blocks.node.fromDOM', { 13157 since: '6.1', 13158 version: '6.3', 13159 alternative: 'wp.richText.create', 13160 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13161 }); 13162 if (domNode.nodeType === domNode.TEXT_NODE) { 13163 return domNode.nodeValue; 13164 } 13165 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 13166 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 13167 } 13168 return { 13169 type: domNode.nodeName.toLowerCase(), 13170 props: { 13171 ...getNamedNodeMapAsObject(domNode.attributes), 13172 children: children_fromDOM(domNode.childNodes) 13173 } 13174 }; 13175 } 13176 13177 /** 13178 * Given a block node, returns its HTML string representation. 13179 * 13180 * @param {WPBlockNode} node Block node to convert to string. 13181 * 13182 * @return {string} String HTML representation of block node. 13183 */ 13184 function toHTML(node) { 13185 external_wp_deprecated_default()('wp.blocks.node.toHTML', { 13186 since: '6.1', 13187 version: '6.3', 13188 alternative: 'wp.richText.toHTMLString', 13189 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13190 }); 13191 return children_toHTML([node]); 13192 } 13193 13194 /** 13195 * Given a selector, returns an hpq matcher generating a WPBlockNode value 13196 * matching the selector result. 13197 * 13198 * @param {string} selector DOM selector. 13199 * 13200 * @return {Function} hpq matcher. 13201 */ 13202 function matcher(selector) { 13203 external_wp_deprecated_default()('wp.blocks.node.matcher', { 13204 since: '6.1', 13205 version: '6.3', 13206 alternative: 'html source', 13207 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13208 }); 13209 return domNode => { 13210 let match = domNode; 13211 if (selector) { 13212 match = domNode.querySelector(selector); 13213 } 13214 try { 13215 return fromDOM(match); 13216 } catch (error) { 13217 return null; 13218 } 13219 }; 13220 } 13221 13222 /** 13223 * Object of utility functions used in managing block attribute values of 13224 * source `node`. 13225 * 13226 * @see https://github.com/WordPress/gutenberg/pull/10439 13227 * 13228 * @deprecated since 4.0. The `node` source should not be used, and can be 13229 * replaced by the `html` source. 13230 * 13231 * @private 13232 */ 13233 /* harmony default export */ const node = ({ 13234 isNodeOfType, 13235 fromDOM, 13236 toHTML, 13237 matcher 13238 }); 13239 13240 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/children.js 13241 /** 13242 * WordPress dependencies 13243 */ 13244 13245 13246 13247 /** 13248 * Internal dependencies 13249 */ 13250 13251 13252 /** 13253 * A representation of a block's rich text value. 13254 * 13255 * @typedef {WPBlockNode[]} WPBlockChildren 13256 */ 13257 13258 /** 13259 * Given block children, returns a serialize-capable WordPress element. 13260 * 13261 * @param {WPBlockChildren} children Block children object to convert. 13262 * 13263 * @return {Element} A serialize-capable element. 13264 */ 13265 function getSerializeCapableElement(children) { 13266 // The fact that block children are compatible with the element serializer is 13267 // merely an implementation detail that currently serves to be true, but 13268 // should not be mistaken as being a guarantee on the external API. The 13269 // public API only offers guarantees to work with strings (toHTML) and DOM 13270 // elements (fromDOM), and should provide utilities to manipulate the value 13271 // rather than expect consumers to inspect or construct its shape (concat). 13272 return children; 13273 } 13274 13275 /** 13276 * Given block children, returns an array of block nodes. 13277 * 13278 * @param {WPBlockChildren} children Block children object to convert. 13279 * 13280 * @return {Array<WPBlockNode>} An array of individual block nodes. 13281 */ 13282 function getChildrenArray(children) { 13283 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', { 13284 since: '6.1', 13285 version: '6.3', 13286 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13287 }); 13288 13289 // The fact that block children are compatible with the element serializer 13290 // is merely an implementation detail that currently serves to be true, but 13291 // should not be mistaken as being a guarantee on the external API. 13292 return children; 13293 } 13294 13295 /** 13296 * Given two or more block nodes, returns a new block node representing a 13297 * concatenation of its values. 13298 * 13299 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 13300 * 13301 * @return {WPBlockChildren} Concatenated block node. 13302 */ 13303 function concat(...blockNodes) { 13304 external_wp_deprecated_default()('wp.blocks.children.concat', { 13305 since: '6.1', 13306 version: '6.3', 13307 alternative: 'wp.richText.concat', 13308 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13309 }); 13310 const result = []; 13311 for (let i = 0; i < blockNodes.length; i++) { 13312 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]]; 13313 for (let j = 0; j < blockNode.length; j++) { 13314 const child = blockNode[j]; 13315 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 13316 if (canConcatToPreviousString) { 13317 result[result.length - 1] += child; 13318 } else { 13319 result.push(child); 13320 } 13321 } 13322 } 13323 return result; 13324 } 13325 13326 /** 13327 * Given an iterable set of DOM nodes, returns equivalent block children. 13328 * Ignores any non-element/text nodes included in set. 13329 * 13330 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 13331 * 13332 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 13333 */ 13334 function children_fromDOM(domNodes) { 13335 external_wp_deprecated_default()('wp.blocks.children.fromDOM', { 13336 since: '6.1', 13337 version: '6.3', 13338 alternative: 'wp.richText.create', 13339 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13340 }); 13341 const result = []; 13342 for (let i = 0; i < domNodes.length; i++) { 13343 try { 13344 result.push(fromDOM(domNodes[i])); 13345 } catch (error) { 13346 // Simply ignore if DOM node could not be converted. 13347 } 13348 } 13349 return result; 13350 } 13351 13352 /** 13353 * Given a block node, returns its HTML string representation. 13354 * 13355 * @param {WPBlockChildren} children Block node(s) to convert to string. 13356 * 13357 * @return {string} String HTML representation of block node. 13358 */ 13359 function children_toHTML(children) { 13360 external_wp_deprecated_default()('wp.blocks.children.toHTML', { 13361 since: '6.1', 13362 version: '6.3', 13363 alternative: 'wp.richText.toHTMLString', 13364 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13365 }); 13366 const element = getSerializeCapableElement(children); 13367 return (0,external_wp_element_namespaceObject.renderToString)(element); 13368 } 13369 13370 /** 13371 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 13372 * matching the selector result. 13373 * 13374 * @param {string} selector DOM selector. 13375 * 13376 * @return {Function} hpq matcher. 13377 */ 13378 function children_matcher(selector) { 13379 external_wp_deprecated_default()('wp.blocks.children.matcher', { 13380 since: '6.1', 13381 version: '6.3', 13382 alternative: 'html source', 13383 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13384 }); 13385 return domNode => { 13386 let match = domNode; 13387 if (selector) { 13388 match = domNode.querySelector(selector); 13389 } 13390 if (match) { 13391 return children_fromDOM(match.childNodes); 13392 } 13393 return []; 13394 }; 13395 } 13396 13397 /** 13398 * Object of utility functions used in managing block attribute values of 13399 * source `children`. 13400 * 13401 * @see https://github.com/WordPress/gutenberg/pull/10439 13402 * 13403 * @deprecated since 4.0. The `children` source should not be used, and can be 13404 * replaced by the `html` source. 13405 * 13406 * @private 13407 */ 13408 /* harmony default export */ const children = ({ 13409 concat, 13410 getChildrenArray, 13411 fromDOM: children_fromDOM, 13412 toHTML: children_toHTML, 13413 matcher: children_matcher 13414 }); 13415 13416 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/get-block-attributes.js 13417 /** 13418 * External dependencies 13419 */ 13420 13421 13422 13423 /** 13424 * WordPress dependencies 13425 */ 13426 13427 13428 13429 /** 13430 * Internal dependencies 13431 */ 13432 13433 13434 13435 /** 13436 * Higher-order hpq matcher which enhances an attribute matcher to return true 13437 * or false depending on whether the original matcher returns undefined. This 13438 * is useful for boolean attributes (e.g. disabled) whose attribute values may 13439 * be technically falsey (empty string), though their mere presence should be 13440 * enough to infer as true. 13441 * 13442 * @param {Function} matcher Original hpq matcher. 13443 * 13444 * @return {Function} Enhanced hpq matcher. 13445 */ 13446 const toBooleanAttributeMatcher = matcher => value => matcher(value) !== undefined; 13447 13448 /** 13449 * Returns true if value is of the given JSON schema type, or false otherwise. 13450 * 13451 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13452 * 13453 * @param {*} value Value to test. 13454 * @param {string} type Type to test. 13455 * 13456 * @return {boolean} Whether value is of type. 13457 */ 13458 function isOfType(value, type) { 13459 switch (type) { 13460 case 'rich-text': 13461 return value instanceof external_wp_richText_namespaceObject.RichTextData; 13462 case 'string': 13463 return typeof value === 'string'; 13464 case 'boolean': 13465 return typeof value === 'boolean'; 13466 case 'object': 13467 return !!value && value.constructor === Object; 13468 case 'null': 13469 return value === null; 13470 case 'array': 13471 return Array.isArray(value); 13472 case 'integer': 13473 case 'number': 13474 return typeof value === 'number'; 13475 } 13476 return true; 13477 } 13478 13479 /** 13480 * Returns true if value is of an array of given JSON schema types, or false 13481 * otherwise. 13482 * 13483 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13484 * 13485 * @param {*} value Value to test. 13486 * @param {string[]} types Types to test. 13487 * 13488 * @return {boolean} Whether value is of types. 13489 */ 13490 function isOfTypes(value, types) { 13491 return types.some(type => isOfType(value, type)); 13492 } 13493 13494 /** 13495 * Given an attribute key, an attribute's schema, a block's raw content and the 13496 * commentAttributes returns the attribute value depending on its source 13497 * definition of the given attribute key. 13498 * 13499 * @param {string} attributeKey Attribute key. 13500 * @param {Object} attributeSchema Attribute's schema. 13501 * @param {Node} innerDOM Parsed DOM of block's inner HTML. 13502 * @param {Object} commentAttributes Block's comment attributes. 13503 * @param {string} innerHTML Raw HTML from block node's innerHTML property. 13504 * 13505 * @return {*} Attribute value. 13506 */ 13507 function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) { 13508 let value; 13509 switch (attributeSchema.source) { 13510 // An undefined source means that it's an attribute serialized to the 13511 // block's "comment". 13512 case undefined: 13513 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 13514 break; 13515 // raw source means that it's the original raw block content. 13516 case 'raw': 13517 value = innerHTML; 13518 break; 13519 case 'attribute': 13520 case 'property': 13521 case 'html': 13522 case 'text': 13523 case 'rich-text': 13524 case 'children': 13525 case 'node': 13526 case 'query': 13527 case 'tag': 13528 value = parseWithAttributeSchema(innerDOM, attributeSchema); 13529 break; 13530 } 13531 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) { 13532 // Reject the value if it is not valid. Reverting to the undefined 13533 // value ensures the default is respected, if applicable. 13534 value = undefined; 13535 } 13536 if (value === undefined) { 13537 value = getDefault(attributeSchema); 13538 } 13539 return value; 13540 } 13541 13542 /** 13543 * Returns true if value is valid per the given block attribute schema type 13544 * definition, or false otherwise. 13545 * 13546 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 13547 * 13548 * @param {*} value Value to test. 13549 * @param {?(Array<string>|string)} type Block attribute schema type. 13550 * 13551 * @return {boolean} Whether value is valid. 13552 */ 13553 function isValidByType(value, type) { 13554 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]); 13555 } 13556 13557 /** 13558 * Returns true if value is valid per the given block attribute schema enum 13559 * definition, or false otherwise. 13560 * 13561 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 13562 * 13563 * @param {*} value Value to test. 13564 * @param {?Array} enumSet Block attribute schema enum. 13565 * 13566 * @return {boolean} Whether value is valid. 13567 */ 13568 function isValidByEnum(value, enumSet) { 13569 return !Array.isArray(enumSet) || enumSet.includes(value); 13570 } 13571 13572 /** 13573 * Returns an hpq matcher given a source object. 13574 * 13575 * @param {Object} sourceConfig Attribute Source object. 13576 * 13577 * @return {Function} A hpq Matcher. 13578 */ 13579 const matcherFromSource = memize(sourceConfig => { 13580 switch (sourceConfig.source) { 13581 case 'attribute': 13582 { 13583 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 13584 if (sourceConfig.type === 'boolean') { 13585 matcher = toBooleanAttributeMatcher(matcher); 13586 } 13587 return matcher; 13588 } 13589 case 'html': 13590 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 13591 case 'text': 13592 return es_text(sourceConfig.selector); 13593 case 'rich-text': 13594 return richText(sourceConfig.selector, sourceConfig.__unstablePreserveWhiteSpace); 13595 case 'children': 13596 return children_matcher(sourceConfig.selector); 13597 case 'node': 13598 return matcher(sourceConfig.selector); 13599 case 'query': 13600 const subMatchers = Object.fromEntries(Object.entries(sourceConfig.query).map(([key, subSourceConfig]) => [key, matcherFromSource(subSourceConfig)])); 13601 return query(sourceConfig.selector, subMatchers); 13602 case 'tag': 13603 { 13604 const matcher = prop(sourceConfig.selector, 'nodeName'); 13605 return domNode => matcher(domNode)?.toLowerCase(); 13606 } 13607 default: 13608 // eslint-disable-next-line no-console 13609 console.error(`Unknown source type "$sourceConfig.source}"`); 13610 } 13611 }); 13612 13613 /** 13614 * Parse a HTML string into DOM tree. 13615 * 13616 * @param {string|Node} innerHTML HTML string or already parsed DOM node. 13617 * 13618 * @return {Node} Parsed DOM node. 13619 */ 13620 function parseHtml(innerHTML) { 13621 return parse(innerHTML, h => h); 13622 } 13623 13624 /** 13625 * Given a block's raw content and an attribute's schema returns the attribute's 13626 * value depending on its source. 13627 * 13628 * @param {string|Node} innerHTML Block's raw content. 13629 * @param {Object} attributeSchema Attribute's schema. 13630 * 13631 * @return {*} Attribute value. 13632 */ 13633 function parseWithAttributeSchema(innerHTML, attributeSchema) { 13634 return matcherFromSource(attributeSchema)(parseHtml(innerHTML)); 13635 } 13636 13637 /** 13638 * Returns the block attributes of a registered block node given its type. 13639 * 13640 * @param {string|Object} blockTypeOrName Block type or name. 13641 * @param {string|Node} innerHTML Raw block content. 13642 * @param {?Object} attributes Known block attributes (from delimiters). 13643 * 13644 * @return {Object} All block attributes. 13645 */ 13646 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) { 13647 var _blockType$attributes; 13648 const doc = parseHtml(innerHTML); 13649 const blockType = normalizeBlockType(blockTypeOrName); 13650 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)])); 13651 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 13652 } 13653 13654 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/fix-custom-classname.js 13655 /** 13656 * Internal dependencies 13657 */ 13658 13659 13660 13661 const CLASS_ATTR_SCHEMA = { 13662 type: 'string', 13663 source: 'attribute', 13664 selector: '[data-custom-class-name] > *', 13665 attribute: 'class' 13666 }; 13667 13668 /** 13669 * Given an HTML string, returns an array of class names assigned to the root 13670 * element in the markup. 13671 * 13672 * @param {string} innerHTML Markup string from which to extract classes. 13673 * 13674 * @return {string[]} Array of class names assigned to the root element. 13675 */ 13676 function getHTMLRootElementClasses(innerHTML) { 13677 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>$innerHTML}</div>`, CLASS_ATTR_SCHEMA); 13678 return parsed ? parsed.trim().split(/\s+/) : []; 13679 } 13680 13681 /** 13682 * Given a parsed set of block attributes, if the block supports custom class 13683 * names and an unknown class (per the block's serialization behavior) is 13684 * found, the unknown classes are treated as custom classes. This prevents the 13685 * block from being considered as invalid. 13686 * 13687 * @param {Object} blockAttributes Original block attributes. 13688 * @param {Object} blockType Block type settings. 13689 * @param {string} innerHTML Original block markup. 13690 * 13691 * @return {Object} Filtered block attributes. 13692 */ 13693 function fixCustomClassname(blockAttributes, blockType, innerHTML) { 13694 if (!hasBlockSupport(blockType, 'customClassName', true)) { 13695 return blockAttributes; 13696 } 13697 const modifiedBlockAttributes = { 13698 ...blockAttributes 13699 }; 13700 // To determine difference, serialize block given the known set of 13701 // attributes, with the exception of `className`. This will determine 13702 // the default set of classes. From there, any difference in innerHTML 13703 // can be considered as custom classes. 13704 const { 13705 className: omittedClassName, 13706 ...attributesSansClassName 13707 } = modifiedBlockAttributes; 13708 const serialized = getSaveContent(blockType, attributesSansClassName); 13709 const defaultClasses = getHTMLRootElementClasses(serialized); 13710 const actualClasses = getHTMLRootElementClasses(innerHTML); 13711 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className)); 13712 if (customClasses.length) { 13713 modifiedBlockAttributes.className = customClasses.join(' '); 13714 } else if (serialized) { 13715 delete modifiedBlockAttributes.className; 13716 } 13717 return modifiedBlockAttributes; 13718 } 13719 13720 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/apply-built-in-validation-fixes.js 13721 /** 13722 * Internal dependencies 13723 */ 13724 13725 13726 /** 13727 * Attempts to fix block invalidation by applying build-in validation fixes 13728 * like moving all extra classNames to the className attribute. 13729 * 13730 * @param {WPBlock} block block object. 13731 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13732 * can be inferred from the block name, 13733 * but it's here for performance reasons. 13734 * 13735 * @return {WPBlock} Fixed block object 13736 */ 13737 function applyBuiltInValidationFixes(block, blockType) { 13738 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent); 13739 return { 13740 ...block, 13741 attributes: updatedBlockAttributes 13742 }; 13743 } 13744 13745 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/apply-block-deprecated-versions.js 13746 /** 13747 * Internal dependencies 13748 */ 13749 13750 13751 13752 13753 13754 13755 /** 13756 * Function that takes no arguments and always returns false. 13757 * 13758 * @return {boolean} Always returns false. 13759 */ 13760 function stubFalse() { 13761 return false; 13762 } 13763 13764 /** 13765 * Given a block object, returns a new copy of the block with any applicable 13766 * deprecated migrations applied, or the original block if it was both valid 13767 * and no eligible migrations exist. 13768 * 13769 * @param {import(".").WPBlock} block Parsed and invalid block object. 13770 * @param {import(".").WPRawBlock} rawBlock Raw block object. 13771 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13772 * can be inferred from the block name, 13773 * but it's here for performance reasons. 13774 * 13775 * @return {import(".").WPBlock} Migrated block object. 13776 */ 13777 function applyBlockDeprecatedVersions(block, rawBlock, blockType) { 13778 const parsedAttributes = rawBlock.attrs; 13779 const { 13780 deprecated: deprecatedDefinitions 13781 } = blockType; 13782 // Bail early if there are no registered deprecations to be handled. 13783 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 13784 return block; 13785 } 13786 13787 // By design, blocks lack any sort of version tracking. Instead, to process 13788 // outdated content the system operates a queue out of all the defined 13789 // attribute shapes and tries each definition until the input produces a 13790 // valid result. This mechanism seeks to avoid polluting the user-space with 13791 // machine-specific code. An invalid block is thus a block that could not be 13792 // matched successfully with any of the registered deprecation definitions. 13793 for (let i = 0; i < deprecatedDefinitions.length; i++) { 13794 // A block can opt into a migration even if the block is valid by 13795 // defining `isEligible` on its deprecation. If the block is both valid 13796 // and does not opt to migrate, skip. 13797 const { 13798 isEligible = stubFalse 13799 } = deprecatedDefinitions[i]; 13800 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks, { 13801 blockNode: rawBlock, 13802 block 13803 })) { 13804 continue; 13805 } 13806 13807 // Block type properties which could impact either serialization or 13808 // parsing are not considered in the deprecated block type by default, 13809 // and must be explicitly provided. 13810 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 13811 let migratedBlock = { 13812 ...block, 13813 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes) 13814 }; 13815 13816 // Ignore the deprecation if it produces a block which is not valid. 13817 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13818 13819 // If the migrated block is not valid initially, try the built-in fixes. 13820 if (!isValid) { 13821 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType); 13822 [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13823 } 13824 13825 // An invalid block does not imply incorrect HTML but the fact block 13826 // source information could be lost on re-serialization. 13827 if (!isValid) { 13828 continue; 13829 } 13830 let migratedInnerBlocks = migratedBlock.innerBlocks; 13831 let migratedAttributes = migratedBlock.attributes; 13832 13833 // A block may provide custom behavior to assign new attributes and/or 13834 // inner blocks. 13835 const { 13836 migrate 13837 } = deprecatedBlockType; 13838 if (migrate) { 13839 let migrated = migrate(migratedAttributes, block.innerBlocks); 13840 if (!Array.isArray(migrated)) { 13841 migrated = [migrated]; 13842 } 13843 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated; 13844 } 13845 block = { 13846 ...block, 13847 attributes: migratedAttributes, 13848 innerBlocks: migratedInnerBlocks, 13849 isValid: true, 13850 validationIssues: [] 13851 }; 13852 } 13853 return block; 13854 } 13855 13856 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/index.js 13857 /** 13858 * WordPress dependencies 13859 */ 13860 13861 13862 13863 /** 13864 * Internal dependencies 13865 */ 13866 13867 13868 13869 13870 13871 13872 13873 13874 13875 13876 /** 13877 * The raw structure of a block includes its attributes, inner 13878 * blocks, and inner HTML. It is important to distinguish inner blocks from 13879 * the HTML content of the block as only the latter is relevant for block 13880 * validation and edit operations. 13881 * 13882 * @typedef WPRawBlock 13883 * 13884 * @property {string=} blockName Block name 13885 * @property {Object=} attrs Block raw or comment attributes. 13886 * @property {string} innerHTML HTML content of the block. 13887 * @property {(string|null)[]} innerContent Content without inner blocks. 13888 * @property {WPRawBlock[]} innerBlocks Inner Blocks. 13889 */ 13890 13891 /** 13892 * Fully parsed block object. 13893 * 13894 * @typedef WPBlock 13895 * 13896 * @property {string} name Block name 13897 * @property {Object} attributes Block raw or comment attributes. 13898 * @property {WPBlock[]} innerBlocks Inner Blocks. 13899 * @property {string} originalContent Original content of the block before validation fixes. 13900 * @property {boolean} isValid Whether the block is valid. 13901 * @property {Object[]} validationIssues Validation issues. 13902 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. 13903 */ 13904 13905 /** 13906 * @typedef {Object} ParseOptions 13907 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. 13908 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content. 13909 */ 13910 13911 /** 13912 * Convert legacy blocks to their canonical form. This function is used 13913 * both in the parser level for previous content and to convert such blocks 13914 * used in Custom Post Types templates. 13915 * 13916 * @param {WPRawBlock} rawBlock 13917 * 13918 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found 13919 */ 13920 function convertLegacyBlocks(rawBlock) { 13921 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs); 13922 return { 13923 ...rawBlock, 13924 blockName: correctName, 13925 attrs: correctedAttributes 13926 }; 13927 } 13928 13929 /** 13930 * Normalize the raw block by applying the fallback block name if none given, 13931 * sanitize the parsed HTML... 13932 * 13933 * @param {WPRawBlock} rawBlock The raw block object. 13934 * @param {ParseOptions?} options Extra options for handling block parsing. 13935 * 13936 * @return {WPRawBlock} The normalized block object. 13937 */ 13938 function normalizeRawBlock(rawBlock, options) { 13939 const fallbackBlockName = getFreeformContentHandlerName(); 13940 13941 // If the grammar parsing don't produce any block name, use the freeform block. 13942 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName(); 13943 const rawAttributes = rawBlock.attrs || {}; 13944 const rawInnerBlocks = rawBlock.innerBlocks || []; 13945 let rawInnerHTML = rawBlock.innerHTML.trim(); 13946 13947 // Fallback content may be upgraded from classic content expecting implicit 13948 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 13949 // meaning there are no negative consequences to repeated autop calls. 13950 if (rawBlockName === fallbackBlockName && rawBlockName === 'core/freeform' && !options?.__unstableSkipAutop) { 13951 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim(); 13952 } 13953 return { 13954 ...rawBlock, 13955 blockName: rawBlockName, 13956 attrs: rawAttributes, 13957 innerHTML: rawInnerHTML, 13958 innerBlocks: rawInnerBlocks 13959 }; 13960 } 13961 13962 /** 13963 * Uses the "unregistered blockType" to create a block object. 13964 * 13965 * @param {WPRawBlock} rawBlock block. 13966 * 13967 * @return {WPRawBlock} The unregistered block object. 13968 */ 13969 function createMissingBlockType(rawBlock) { 13970 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); 13971 13972 // Preserve undelimited content for use by the unregistered type 13973 // handler. A block node's `innerHTML` isn't enough, as that field only 13974 // carries the block's own HTML and not its nested blocks. 13975 const originalUndelimitedContent = serializeRawBlock(rawBlock, { 13976 isCommentDelimited: false 13977 }); 13978 13979 // Preserve full block content for use by the unregistered type 13980 // handler, block boundaries included. 13981 const originalContent = serializeRawBlock(rawBlock, { 13982 isCommentDelimited: true 13983 }); 13984 return { 13985 blockName: unregisteredFallbackBlock, 13986 attrs: { 13987 originalName: rawBlock.blockName, 13988 originalContent, 13989 originalUndelimitedContent 13990 }, 13991 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML, 13992 innerBlocks: rawBlock.innerBlocks, 13993 innerContent: rawBlock.innerContent 13994 }; 13995 } 13996 13997 /** 13998 * Validates a block and wraps with validation meta. 13999 * 14000 * The name here is regrettable but `validateBlock` is already taken. 14001 * 14002 * @param {WPBlock} unvalidatedBlock 14003 * @param {import('../registration').WPBlockType} blockType 14004 * @return {WPBlock} validated block, with auto-fixes if initially invalid 14005 */ 14006 function applyBlockValidation(unvalidatedBlock, blockType) { 14007 // Attempt to validate the block. 14008 const [isValid] = validateBlock(unvalidatedBlock, blockType); 14009 if (isValid) { 14010 return { 14011 ...unvalidatedBlock, 14012 isValid, 14013 validationIssues: [] 14014 }; 14015 } 14016 14017 // If the block is invalid, attempt some built-in fixes 14018 // like custom classNames handling. 14019 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); 14020 // Attempt to validate the block once again after the built-in fixes. 14021 const [isFixedValid, validationIssues] = validateBlock(fixedBlock, blockType); 14022 return { 14023 ...fixedBlock, 14024 isValid: isFixedValid, 14025 validationIssues 14026 }; 14027 } 14028 14029 /** 14030 * Given a raw block returned by grammar parsing, returns a fully parsed block. 14031 * 14032 * @param {WPRawBlock} rawBlock The raw block object. 14033 * @param {ParseOptions} options Extra options for handling block parsing. 14034 * 14035 * @return {WPBlock | undefined} Fully parsed block. 14036 */ 14037 function parseRawBlock(rawBlock, options) { 14038 let normalizedBlock = normalizeRawBlock(rawBlock, options); 14039 14040 // During the lifecycle of the project, we renamed some old blocks 14041 // and transformed others to new blocks. To avoid breaking existing content, 14042 // we added this function to properly parse the old content. 14043 normalizedBlock = convertLegacyBlocks(normalizedBlock); 14044 14045 // Try finding the type for known block name. 14046 let blockType = getBlockType(normalizedBlock.blockName); 14047 14048 // If not blockType is found for the specified name, fallback to the "unregistedBlockType". 14049 if (!blockType) { 14050 normalizedBlock = createMissingBlockType(normalizedBlock); 14051 blockType = getBlockType(normalizedBlock.blockName); 14052 } 14053 14054 // If it's an empty freeform block or there's no blockType (no missing block handler) 14055 // Then, just ignore the block. 14056 // It might be a good idea to throw a warning here. 14057 // TODO: I'm unsure about the unregisteredFallbackBlock check, 14058 // it might ignore some dynamic unregistered third party blocks wrongly. 14059 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName(); 14060 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) { 14061 return; 14062 } 14063 14064 // Parse inner blocks recursively. 14065 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) 14066 // See https://github.com/WordPress/gutenberg/pull/17164. 14067 .filter(innerBlock => !!innerBlock); 14068 14069 // Get the fully parsed block. 14070 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks); 14071 parsedBlock.originalContent = normalizedBlock.innerHTML; 14072 const validatedBlock = applyBlockValidation(parsedBlock, blockType); 14073 const { 14074 validationIssues 14075 } = validatedBlock; 14076 14077 // Run the block deprecation and migrations. 14078 // This is performed on both invalid and valid blocks because 14079 // migration using the `migrate` functions should run even 14080 // if the output is deemed valid. 14081 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType); 14082 if (!updatedBlock.isValid) { 14083 // Preserve the original unprocessed version of the block 14084 // that we received (no fixes, no deprecations) so that 14085 // we can save it as close to exactly the same way as 14086 // we loaded it. This is important to avoid corruption 14087 // and data loss caused by block implementations trying 14088 // to process data that isn't fully recognized. 14089 updatedBlock.__unstableBlockSource = rawBlock; 14090 } 14091 if (!validatedBlock.isValid && updatedBlock.isValid && !options?.__unstableSkipMigrationLogs) { 14092 /* eslint-disable no-console */ 14093 console.groupCollapsed('Updated Block: %s', blockType.name); 14094 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); 14095 console.groupEnd(); 14096 /* eslint-enable no-console */ 14097 } else if (!validatedBlock.isValid && !updatedBlock.isValid) { 14098 validationIssues.forEach(({ 14099 log, 14100 args 14101 }) => log(...args)); 14102 } 14103 return updatedBlock; 14104 } 14105 14106 /** 14107 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 14108 * defined through a parsing expression grammar to take advantage of the regular 14109 * cadence provided by block delimiters -- composed syntactically through HTML 14110 * comments -- which, given a general HTML document as an input, returns a block 14111 * list array representation. 14112 * 14113 * This is a recursive-descent parser that scans linearly once through the input 14114 * document. Instead of directly recursing it utilizes a trampoline mechanism to 14115 * prevent stack overflow. This initial pass is mainly interested in separating 14116 * and isolating the blocks serialized in the document and manifestly not in the 14117 * content within the blocks. 14118 * 14119 * @see 14120 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 14121 * 14122 * @param {string} content The post content. 14123 * @param {ParseOptions} options Extra options for handling block parsing. 14124 * 14125 * @return {Array} Block list. 14126 */ 14127 function parser_parse(content, options) { 14128 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => { 14129 const block = parseRawBlock(rawBlock, options); 14130 if (block) { 14131 accumulator.push(block); 14132 } 14133 return accumulator; 14134 }, []); 14135 } 14136 14137 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js 14138 /** 14139 * Internal dependencies 14140 */ 14141 14142 function getRawTransforms() { 14143 return getBlockTransforms('from').filter(({ 14144 type 14145 }) => type === 'raw').map(transform => { 14146 return transform.isMatch ? transform : { 14147 ...transform, 14148 isMatch: node => transform.selector && node.matches(transform.selector) 14149 }; 14150 }); 14151 } 14152 14153 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js 14154 /** 14155 * WordPress dependencies 14156 */ 14157 14158 14159 /** 14160 * Internal dependencies 14161 */ 14162 14163 14164 14165 14166 14167 /** 14168 * Converts HTML directly to blocks. Looks for a matching transform for each 14169 * top-level tag. The HTML should be filtered to not have any text between 14170 * top-level tags and formatted in a way that blocks can handle the HTML. 14171 * 14172 * @param {string} html HTML to convert. 14173 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler 14174 * or pasteHandler. 14175 * 14176 * @return {Array} An array of blocks. 14177 */ 14178 function htmlToBlocks(html, handler) { 14179 const doc = document.implementation.createHTMLDocument(''); 14180 doc.body.innerHTML = html; 14181 return Array.from(doc.body.children).flatMap(node => { 14182 const rawTransform = findTransform(getRawTransforms(), ({ 14183 isMatch 14184 }) => isMatch(node)); 14185 if (!rawTransform) { 14186 // Until the HTML block is supported in the native version, we'll parse it 14187 // instead of creating the block to generate it as an unsupported block. 14188 if (external_wp_element_namespaceObject.Platform.isNative) { 14189 return parser_parse(`<!-- wp:html -->$node.outerHTML}<!-- /wp:html -->`); 14190 } 14191 return createBlock( 14192 // Should not be hardcoded. 14193 'core/html', getBlockAttributes('core/html', node.outerHTML)); 14194 } 14195 const { 14196 transform, 14197 blockName 14198 } = rawTransform; 14199 if (transform) { 14200 const block = transform(node, handler); 14201 if (node.hasAttribute('class')) { 14202 block.attributes.className = node.getAttribute('class'); 14203 } 14204 return block; 14205 } 14206 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 14207 }); 14208 } 14209 14210 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js 14211 /** 14212 * WordPress dependencies 14213 */ 14214 14215 function normaliseBlocks(HTML, options = {}) { 14216 const decuDoc = document.implementation.createHTMLDocument(''); 14217 const accuDoc = document.implementation.createHTMLDocument(''); 14218 const decu = decuDoc.body; 14219 const accu = accuDoc.body; 14220 decu.innerHTML = HTML; 14221 while (decu.firstChild) { 14222 const node = decu.firstChild; 14223 14224 // Text nodes: wrap in a paragraph, or append to previous. 14225 if (node.nodeType === node.TEXT_NODE) { 14226 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 14227 decu.removeChild(node); 14228 } else { 14229 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14230 accu.appendChild(accuDoc.createElement('P')); 14231 } 14232 accu.lastChild.appendChild(node); 14233 } 14234 // Element nodes. 14235 } else if (node.nodeType === node.ELEMENT_NODE) { 14236 // BR nodes: create a new paragraph on double, or append to previous. 14237 if (node.nodeName === 'BR') { 14238 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 14239 accu.appendChild(accuDoc.createElement('P')); 14240 decu.removeChild(node.nextSibling); 14241 } 14242 14243 // Don't append to an empty paragraph. 14244 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 14245 accu.lastChild.appendChild(node); 14246 } else { 14247 decu.removeChild(node); 14248 } 14249 } else if (node.nodeName === 'P') { 14250 // Only append non-empty paragraph nodes. 14251 if ((0,external_wp_dom_namespaceObject.isEmpty)(node) && !options.raw) { 14252 decu.removeChild(node); 14253 } else { 14254 accu.appendChild(node); 14255 } 14256 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) { 14257 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14258 accu.appendChild(accuDoc.createElement('P')); 14259 } 14260 accu.lastChild.appendChild(node); 14261 } else { 14262 accu.appendChild(node); 14263 } 14264 } else { 14265 decu.removeChild(node); 14266 } 14267 } 14268 return accu.innerHTML; 14269 } 14270 14271 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js 14272 /** 14273 * WordPress dependencies 14274 */ 14275 14276 14277 /** 14278 * Looks for `<!--nextpage-->` and `<!--more-->` comments and 14279 * replaces them with a custom element representing a future block. 14280 * 14281 * The custom element is a way to bypass the rest of the `raw-handling` 14282 * transforms, which would eliminate other kinds of node with which to carry 14283 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 14284 * 14285 * The custom element is then expected to be recognized by any registered 14286 * block's `raw` transform. 14287 * 14288 * @param {Node} node The node to be processed. 14289 * @param {Document} doc The document of the node. 14290 * @return {void} 14291 */ 14292 function specialCommentConverter(node, doc) { 14293 if (node.nodeType !== node.COMMENT_NODE) { 14294 return; 14295 } 14296 if (node.nodeValue !== 'nextpage' && node.nodeValue.indexOf('more') !== 0) { 14297 return; 14298 } 14299 const block = special_comment_converter_createBlock(node, doc); 14300 14301 // If our `<!--more-->` comment is in the middle of a paragraph, we should 14302 // split the paragraph in two and insert the more block in between. If it's 14303 // inside an empty paragraph, we should still move it out of the paragraph 14304 // and remove the paragraph. If there's no paragraph, fall back to simply 14305 // replacing the comment. 14306 if (!node.parentNode || node.parentNode.nodeName !== 'P') { 14307 (0,external_wp_dom_namespaceObject.replace)(node, block); 14308 } else { 14309 const childNodes = Array.from(node.parentNode.childNodes); 14310 const nodeIndex = childNodes.indexOf(node); 14311 const wrapperNode = node.parentNode.parentNode || doc.body; 14312 const paragraphBuilder = (acc, child) => { 14313 if (!acc) { 14314 acc = doc.createElement('p'); 14315 } 14316 acc.appendChild(child); 14317 return acc; 14318 }; 14319 14320 // Split the original parent node and insert our more block 14321 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), block, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEach(element => element && wrapperNode.insertBefore(element, node.parentNode)); 14322 14323 // Remove the old parent paragraph 14324 (0,external_wp_dom_namespaceObject.remove)(node.parentNode); 14325 } 14326 } 14327 function special_comment_converter_createBlock(commentNode, doc) { 14328 if (commentNode.nodeValue === 'nextpage') { 14329 return createNextpage(doc); 14330 } 14331 14332 // Grab any custom text in the comment. 14333 const customText = commentNode.nodeValue.slice(4).trim(); 14334 14335 /* 14336 * When a `<!--more-->` comment is found, we need to look for any 14337 * `<!--noteaser-->` sibling, but it may not be a direct sibling 14338 * (whitespace typically lies in between) 14339 */ 14340 let sibling = commentNode; 14341 let noTeaser = false; 14342 while (sibling = sibling.nextSibling) { 14343 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 14344 noTeaser = true; 14345 (0,external_wp_dom_namespaceObject.remove)(sibling); 14346 break; 14347 } 14348 } 14349 return createMore(customText, noTeaser, doc); 14350 } 14351 function createMore(customText, noTeaser, doc) { 14352 const node = doc.createElement('wp-block'); 14353 node.dataset.block = 'core/more'; 14354 if (customText) { 14355 node.dataset.customText = customText; 14356 } 14357 if (noTeaser) { 14358 // "Boolean" data attribute. 14359 node.dataset.noTeaser = ''; 14360 } 14361 return node; 14362 } 14363 function createNextpage(doc) { 14364 const node = doc.createElement('wp-block'); 14365 node.dataset.block = 'core/nextpage'; 14366 return node; 14367 } 14368 14369 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/list-reducer.js 14370 /** 14371 * WordPress dependencies 14372 */ 14373 14374 function isList(node) { 14375 return node.nodeName === 'OL' || node.nodeName === 'UL'; 14376 } 14377 function shallowTextContent(element) { 14378 return Array.from(element.childNodes).map(({ 14379 nodeValue = '' 14380 }) => nodeValue).join(''); 14381 } 14382 function listReducer(node) { 14383 if (!isList(node)) { 14384 return; 14385 } 14386 const list = node; 14387 const prevElement = node.previousElementSibling; 14388 14389 // Merge with previous list if: 14390 // * There is a previous list of the same type. 14391 // * There is only one list item. 14392 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 14393 // Move all child nodes, including any text nodes, if any. 14394 while (list.firstChild) { 14395 prevElement.appendChild(list.firstChild); 14396 } 14397 list.parentNode.removeChild(list); 14398 } 14399 const parentElement = node.parentNode; 14400 14401 // Nested list with empty parent item. 14402 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 14403 const parentListItem = parentElement; 14404 const prevListItem = parentListItem.previousElementSibling; 14405 const parentList = parentListItem.parentNode; 14406 if (prevListItem) { 14407 prevListItem.appendChild(list); 14408 parentList.removeChild(parentListItem); 14409 } 14410 } 14411 14412 // Invalid: OL/UL > OL/UL. 14413 if (parentElement && isList(parentElement)) { 14414 const prevListItem = node.previousElementSibling; 14415 if (prevListItem) { 14416 prevListItem.appendChild(node); 14417 } else { 14418 (0,external_wp_dom_namespaceObject.unwrap)(node); 14419 } 14420 } 14421 } 14422 14423 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/blockquote-normaliser.js 14424 /** 14425 * Internal dependencies 14426 */ 14427 14428 function blockquoteNormaliser(options) { 14429 return node => { 14430 if (node.nodeName !== 'BLOCKQUOTE') { 14431 return; 14432 } 14433 node.innerHTML = normaliseBlocks(node.innerHTML, options); 14434 }; 14435 } 14436 14437 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/figure-content-reducer.js 14438 /** 14439 * WordPress dependencies 14440 */ 14441 14442 14443 /** 14444 * Whether or not the given node is figure content. 14445 * 14446 * @param {Node} node The node to check. 14447 * @param {Object} schema The schema to use. 14448 * 14449 * @return {boolean} True if figure content, false if not. 14450 */ 14451 function isFigureContent(node, schema) { 14452 var _schema$figure$childr; 14453 const tag = node.nodeName.toLowerCase(); 14454 14455 // We are looking for tags that can be a child of the figure tag, excluding 14456 // `figcaption` and any phrasing content. 14457 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14458 return false; 14459 } 14460 return tag in ((_schema$figure$childr = schema?.figure?.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {}); 14461 } 14462 14463 /** 14464 * Whether or not the given node can have an anchor. 14465 * 14466 * @param {Node} node The node to check. 14467 * @param {Object} schema The schema to use. 14468 * 14469 * @return {boolean} True if it can, false if not. 14470 */ 14471 function canHaveAnchor(node, schema) { 14472 var _schema$figure$childr2; 14473 const tag = node.nodeName.toLowerCase(); 14474 return tag in ((_schema$figure$childr2 = schema?.figure?.children?.a?.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {}); 14475 } 14476 14477 /** 14478 * Wraps the given element in a figure element. 14479 * 14480 * @param {Element} element The element to wrap. 14481 * @param {Element} beforeElement The element before which to place the figure. 14482 */ 14483 function wrapFigureContent(element, beforeElement = element) { 14484 const figure = element.ownerDocument.createElement('figure'); 14485 beforeElement.parentNode.insertBefore(figure, beforeElement); 14486 figure.appendChild(element); 14487 } 14488 14489 /** 14490 * This filter takes figure content out of paragraphs, wraps it in a figure 14491 * element, and moves any anchors with it if needed. 14492 * 14493 * @param {Node} node The node to filter. 14494 * @param {Document} doc The document of the node. 14495 * @param {Object} schema The schema to use. 14496 * 14497 * @return {void} 14498 */ 14499 function figureContentReducer(node, doc, schema) { 14500 if (!isFigureContent(node, schema)) { 14501 return; 14502 } 14503 let nodeToInsert = node; 14504 const parentNode = node.parentNode; 14505 14506 // If the figure content can have an anchor and its parent is an anchor with 14507 // only the figure content, take the anchor out instead of just the content. 14508 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 14509 nodeToInsert = node.parentNode; 14510 } 14511 const wrapper = nodeToInsert.closest('p,div'); 14512 14513 // If wrapped in a paragraph or div, only extract if it's aligned or if 14514 // there is no text content. 14515 // Otherwise, if directly at the root, wrap in a figure element. 14516 if (wrapper) { 14517 // In jsdom-jscore, 'node.classList' can be undefined. 14518 // In this case, default to extract as it offers a better UI experience on mobile. 14519 if (!node.classList) { 14520 wrapFigureContent(nodeToInsert, wrapper); 14521 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 14522 wrapFigureContent(nodeToInsert, wrapper); 14523 } 14524 } else { 14525 wrapFigureContent(nodeToInsert); 14526 } 14527 } 14528 14529 ;// CONCATENATED MODULE: external ["wp","shortcode"] 14530 const external_wp_shortcode_namespaceObject = window["wp"]["shortcode"]; 14531 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/shortcode-converter.js 14532 /** 14533 * WordPress dependencies 14534 */ 14535 14536 14537 /** 14538 * Internal dependencies 14539 */ 14540 14541 14542 14543 14544 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14545 const beforeLineRegexp = /(\n|<p>)\s*$/; 14546 const afterLineRegexp = /^\s*(\n|<\/p>)/; 14547 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) { 14548 // Get all matches. 14549 const transformsFrom = getBlockTransforms('from'); 14550 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))); 14551 if (!transformation) { 14552 return [HTML]; 14553 } 14554 const transformTags = castArray(transformation.tag); 14555 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)); 14556 let match; 14557 const previousIndex = lastIndex; 14558 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) { 14559 lastIndex = match.index + match.content.length; 14560 const beforeHTML = HTML.substr(0, match.index); 14561 const afterHTML = HTML.substr(lastIndex); 14562 14563 // If the shortcode content does not contain HTML and the shortcode is 14564 // not on a new line (or in paragraph from Markdown converter), 14565 // consider the shortcode as inline text, and thus skip conversion for 14566 // this segment. 14567 if (!match.shortcode.content?.includes('<') && !(beforeLineRegexp.test(beforeHTML) && afterLineRegexp.test(afterHTML))) { 14568 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 14569 } 14570 14571 // If a transformation's `isMatch` predicate fails for the inbound 14572 // shortcode, try again by excluding the current block type. 14573 // 14574 // This is the only call to `segmentHTMLToShortcodeBlock` that should 14575 // ever carry over `excludedBlockNames`. Other calls in the module 14576 // should skip that argument as a way to reset the exclusion state, so 14577 // that one `isMatch` fail in an HTML fragment doesn't prevent any 14578 // valid matches in subsequent fragments. 14579 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 14580 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 14581 } 14582 let blocks = []; 14583 if (typeof transformation.transform === 'function') { 14584 // Passing all of `match` as second argument is intentionally broad 14585 // but shouldn't be too relied upon. 14586 // 14587 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14588 blocks = [].concat(transformation.transform(match.shortcode.attrs, match)); 14589 14590 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14591 blocks = blocks.map(block => { 14592 block.originalContent = match.shortcode.content; 14593 return applyBuiltInValidationFixes(block, getBlockType(block.name)); 14594 }); 14595 } else { 14596 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(([, schema]) => schema.shortcode) 14597 // Passing all of `match` as second argument is intentionally broad 14598 // but shouldn't be too relied upon. 14599 // 14600 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14601 .map(([key, schema]) => [key, schema.shortcode(match.shortcode.attrs, match)])); 14602 const blockType = getBlockType(transformation.blockName); 14603 if (!blockType) { 14604 return [HTML]; 14605 } 14606 const transformationBlockType = { 14607 ...blockType, 14608 attributes: transformation.attributes 14609 }; 14610 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); 14611 14612 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14613 block.originalContent = match.shortcode.content; 14614 block = applyBuiltInValidationFixes(block, transformationBlockType); 14615 blocks = [block]; 14616 } 14617 return [...segmentHTMLToShortcodeBlock(beforeHTML.replace(beforeLineRegexp, '')), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML.replace(afterLineRegexp, ''))]; 14618 } 14619 return [HTML]; 14620 } 14621 /* harmony default export */ const shortcode_converter = (segmentHTMLToShortcodeBlock); 14622 14623 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/utils.js 14624 /** 14625 * WordPress dependencies 14626 */ 14627 14628 14629 /** 14630 * Internal dependencies 14631 */ 14632 14633 14634 function getBlockContentSchemaFromTransforms(transforms, context) { 14635 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14636 const schemaArgs = { 14637 phrasingContentSchema, 14638 isPaste: context === 'paste' 14639 }; 14640 const schemas = transforms.map(({ 14641 isMatch, 14642 blockName, 14643 schema 14644 }) => { 14645 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor'); 14646 schema = typeof schema === 'function' ? schema(schemaArgs) : schema; 14647 14648 // If the block does not has anchor support and the transform does not 14649 // provides an isMatch we can return the schema right away. 14650 if (!hasAnchorSupport && !isMatch) { 14651 return schema; 14652 } 14653 if (!schema) { 14654 return {}; 14655 } 14656 return Object.fromEntries(Object.entries(schema).map(([key, value]) => { 14657 let attributes = value.attributes || []; 14658 // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 14659 if (hasAnchorSupport) { 14660 attributes = [...attributes, 'id']; 14661 } 14662 return [key, { 14663 ...value, 14664 attributes, 14665 isMatch: isMatch ? isMatch : undefined 14666 }]; 14667 })); 14668 }); 14669 function mergeTagNameSchemaProperties(objValue, srcValue, key) { 14670 switch (key) { 14671 case 'children': 14672 { 14673 if (objValue === '*' || srcValue === '*') { 14674 return '*'; 14675 } 14676 return { 14677 ...objValue, 14678 ...srcValue 14679 }; 14680 } 14681 case 'attributes': 14682 case 'require': 14683 { 14684 return [...(objValue || []), ...(srcValue || [])]; 14685 } 14686 case 'isMatch': 14687 { 14688 // If one of the values being merge is undefined (matches everything), 14689 // the result of the merge will be undefined. 14690 if (!objValue || !srcValue) { 14691 return undefined; 14692 } 14693 // When merging two isMatch functions, the result is a new function 14694 // that returns if one of the source functions returns true. 14695 return (...args) => { 14696 return objValue(...args) || srcValue(...args); 14697 }; 14698 } 14699 } 14700 } 14701 14702 // A tagName schema is an object with children, attributes, require, and 14703 // isMatch properties. 14704 function mergeTagNameSchemas(a, b) { 14705 for (const key in b) { 14706 a[key] = a[key] ? mergeTagNameSchemaProperties(a[key], b[key], key) : { 14707 ...b[key] 14708 }; 14709 } 14710 return a; 14711 } 14712 14713 // A schema is an object with tagName schemas by tag name. 14714 function mergeSchemas(a, b) { 14715 for (const key in b) { 14716 a[key] = a[key] ? mergeTagNameSchemas(a[key], b[key]) : { 14717 ...b[key] 14718 }; 14719 } 14720 return a; 14721 } 14722 return schemas.reduce(mergeSchemas, {}); 14723 } 14724 14725 /** 14726 * Gets the block content schema, which is extracted and merged from all 14727 * registered blocks with raw transfroms. 14728 * 14729 * @param {string} context Set to "paste" when in paste context, where the 14730 * schema is more strict. 14731 * 14732 * @return {Object} A complete block content schema. 14733 */ 14734 function getBlockContentSchema(context) { 14735 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 14736 } 14737 14738 /** 14739 * Checks whether HTML can be considered plain text. That is, it does not contain 14740 * any elements that are not line breaks. 14741 * 14742 * @param {string} HTML The HTML to check. 14743 * 14744 * @return {boolean} Whether the HTML can be considered plain text. 14745 */ 14746 function isPlain(HTML) { 14747 return !/<(?!br[ />])/i.test(HTML); 14748 } 14749 14750 /** 14751 * Given node filters, deeply filters and mutates a NodeList. 14752 * 14753 * @param {NodeList} nodeList The nodeList to filter. 14754 * @param {Array} filters An array of functions that can mutate with the provided node. 14755 * @param {Document} doc The document of the nodeList. 14756 * @param {Object} schema The schema to use. 14757 */ 14758 function deepFilterNodeList(nodeList, filters, doc, schema) { 14759 Array.from(nodeList).forEach(node => { 14760 deepFilterNodeList(node.childNodes, filters, doc, schema); 14761 filters.forEach(item => { 14762 // Make sure the node is still attached to the document. 14763 if (!doc.contains(node)) { 14764 return; 14765 } 14766 item(node, doc, schema); 14767 }); 14768 }); 14769 } 14770 14771 /** 14772 * Given node filters, deeply filters HTML tags. 14773 * Filters from the deepest nodes to the top. 14774 * 14775 * @param {string} HTML The HTML to filter. 14776 * @param {Array} filters An array of functions that can mutate with the provided node. 14777 * @param {Object} schema The schema to use. 14778 * 14779 * @return {string} The filtered HTML. 14780 */ 14781 function deepFilterHTML(HTML, filters = [], schema) { 14782 const doc = document.implementation.createHTMLDocument(''); 14783 doc.body.innerHTML = HTML; 14784 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 14785 return doc.body.innerHTML; 14786 } 14787 14788 /** 14789 * Gets a sibling within text-level context. 14790 * 14791 * @param {Element} node The subject node. 14792 * @param {string} which "next" or "previous". 14793 */ 14794 function getSibling(node, which) { 14795 const sibling = node[`$which}Sibling`]; 14796 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) { 14797 return sibling; 14798 } 14799 const { 14800 parentNode 14801 } = node; 14802 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) { 14803 return; 14804 } 14805 return getSibling(parentNode, which); 14806 } 14807 14808 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/index.js 14809 /** 14810 * WordPress dependencies 14811 */ 14812 14813 14814 14815 /** 14816 * Internal dependencies 14817 */ 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 14828 function deprecatedGetPhrasingContentSchema(context) { 14829 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 14830 since: '5.6', 14831 alternative: 'wp.dom.getPhrasingContentSchema' 14832 }); 14833 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14834 } 14835 14836 /** 14837 * Converts an HTML string to known blocks. 14838 * 14839 * @param {Object} $1 14840 * @param {string} $1.HTML The HTML to convert. 14841 * 14842 * @return {Array} A list of blocks. 14843 */ 14844 function rawHandler({ 14845 HTML = '' 14846 }) { 14847 // If we detect block delimiters, parse entirely as blocks. 14848 if (HTML.indexOf('<!-- wp:') !== -1) { 14849 const parseResult = parser_parse(HTML); 14850 const isSingleFreeFormBlock = parseResult.length === 1 && parseResult[0].name === 'core/freeform'; 14851 if (!isSingleFreeFormBlock) { 14852 return parseResult; 14853 } 14854 } 14855 14856 // An array of HTML strings and block objects. The blocks replace matched 14857 // shortcodes. 14858 const pieces = shortcode_converter(HTML); 14859 const blockContentSchema = getBlockContentSchema(); 14860 return pieces.map(piece => { 14861 // Already a block from shortcode. 14862 if (typeof piece !== 'string') { 14863 return piece; 14864 } 14865 14866 // These filters are essential for some blocks to be able to transform 14867 // from raw HTML. These filters move around some content or add 14868 // additional tags, they do not remove any content. 14869 const filters = [ 14870 // Needed to adjust invalid lists. 14871 listReducer, 14872 // Needed to create more and nextpage blocks. 14873 specialCommentConverter, 14874 // Needed to create media blocks. 14875 figureContentReducer, 14876 // Needed to create the quote block, which cannot handle text 14877 // without wrapper paragraphs. 14878 blockquoteNormaliser({ 14879 raw: true 14880 })]; 14881 piece = deepFilterHTML(piece, filters, blockContentSchema); 14882 piece = normaliseBlocks(piece, { 14883 raw: true 14884 }); 14885 return htmlToBlocks(piece, rawHandler); 14886 }).flat().filter(Boolean); 14887 } 14888 14889 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js 14890 /** 14891 * WordPress dependencies 14892 */ 14893 14894 14895 /** 14896 * Looks for comments, and removes them. 14897 * 14898 * @param {Node} node The node to be processed. 14899 * @return {void} 14900 */ 14901 function commentRemover(node) { 14902 if (node.nodeType === node.COMMENT_NODE) { 14903 (0,external_wp_dom_namespaceObject.remove)(node); 14904 } 14905 } 14906 14907 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js 14908 /** 14909 * WordPress dependencies 14910 */ 14911 14912 14913 /** 14914 * Checks if the given node should be considered inline content, optionally 14915 * depending on a context tag. 14916 * 14917 * @param {Node} node Node name. 14918 * @param {string} contextTag Tag name. 14919 * 14920 * @return {boolean} True if the node is inline content, false if nohe. 14921 */ 14922 function isInline(node, contextTag) { 14923 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14924 return true; 14925 } 14926 if (!contextTag) { 14927 return false; 14928 } 14929 const tag = node.nodeName.toLowerCase(); 14930 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 14931 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0); 14932 } 14933 function deepCheck(nodes, contextTag) { 14934 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 14935 } 14936 function isDoubleBR(node) { 14937 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 14938 } 14939 function isInlineContent(HTML, contextTag) { 14940 const doc = document.implementation.createHTMLDocument(''); 14941 doc.body.innerHTML = HTML; 14942 const nodes = Array.from(doc.body.children); 14943 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 14944 } 14945 14946 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 14947 /** 14948 * WordPress dependencies 14949 */ 14950 14951 function phrasingContentReducer(node, doc) { 14952 // In jsdom-jscore, 'node.style' can be null. 14953 // TODO: Explore fixing this by patching jsdom-jscore. 14954 if (node.nodeName === 'SPAN' && node.style) { 14955 const { 14956 fontWeight, 14957 fontStyle, 14958 textDecorationLine, 14959 textDecoration, 14960 verticalAlign 14961 } = node.style; 14962 if (fontWeight === 'bold' || fontWeight === '700') { 14963 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node); 14964 } 14965 if (fontStyle === 'italic') { 14966 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node); 14967 } 14968 14969 // Some DOM implementations (Safari, JSDom) don't support 14970 // style.textDecorationLine, so we check style.textDecoration as a 14971 // fallback. 14972 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) { 14973 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node); 14974 } 14975 if (verticalAlign === 'super') { 14976 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node); 14977 } else if (verticalAlign === 'sub') { 14978 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node); 14979 } 14980 } else if (node.nodeName === 'B') { 14981 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong'); 14982 } else if (node.nodeName === 'I') { 14983 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em'); 14984 } else if (node.nodeName === 'A') { 14985 // In jsdom-jscore, 'node.target' can be null. 14986 // TODO: Explore fixing this by patching jsdom-jscore. 14987 if (node.target && node.target.toLowerCase() === '_blank') { 14988 node.rel = 'noreferrer noopener'; 14989 } else { 14990 node.removeAttribute('target'); 14991 node.removeAttribute('rel'); 14992 } 14993 14994 // Saves anchor elements name attribute as id 14995 if (node.name && !node.id) { 14996 node.id = node.name; 14997 } 14998 14999 // Keeps id only if there is an internal link pointing to it 15000 if (node.id && !node.ownerDocument.querySelector(`[href="#$node.id}"]`)) { 15001 node.removeAttribute('id'); 15002 } 15003 } 15004 } 15005 15006 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js 15007 function headRemover(node) { 15008 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 15009 return; 15010 } 15011 node.parentNode.removeChild(node); 15012 } 15013 15014 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-ignore.js 15015 /** 15016 * Looks for comments, and removes them. 15017 * 15018 * @param {Node} node The node to be processed. 15019 * @return {void} 15020 */ 15021 function msListIgnore(node) { 15022 if (node.nodeType !== node.ELEMENT_NODE) { 15023 return; 15024 } 15025 const style = node.getAttribute('style'); 15026 if (!style || !style.includes('mso-list')) { 15027 return; 15028 } 15029 const rules = style.split(';').reduce((acc, rule) => { 15030 const [key, value] = rule.split(':'); 15031 if (key && value) { 15032 acc[key.trim().toLowerCase()] = value.trim().toLowerCase(); 15033 } 15034 return acc; 15035 }, {}); 15036 if (rules['mso-list'] === 'ignore') { 15037 node.remove(); 15038 } 15039 } 15040 15041 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js 15042 /** 15043 * Internal dependencies 15044 */ 15045 15046 15047 function ms_list_converter_isList(node) { 15048 return node.nodeName === 'OL' || node.nodeName === 'UL'; 15049 } 15050 function msListConverter(node, doc) { 15051 if (node.nodeName !== 'P') { 15052 return; 15053 } 15054 const style = node.getAttribute('style'); 15055 if (!style || !style.includes('mso-list')) { 15056 return; 15057 } 15058 const prevNode = node.previousElementSibling; 15059 15060 // Add new list if no previous. 15061 if (!prevNode || !ms_list_converter_isList(prevNode)) { 15062 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 15063 const type = node.textContent.trim().slice(0, 1); 15064 const isNumeric = /[1iIaA]/.test(type); 15065 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 15066 if (isNumeric) { 15067 newListNode.setAttribute('type', type); 15068 } 15069 node.parentNode.insertBefore(newListNode, node); 15070 } 15071 const listNode = node.previousElementSibling; 15072 const listType = listNode.nodeName; 15073 const listItem = doc.createElement('li'); 15074 let receivingNode = listNode; 15075 15076 // Add content. 15077 listItem.innerHTML = deepFilterHTML(node.innerHTML, [msListIgnore]); 15078 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 15079 let level = matches ? parseInt(matches[1], 10) - 1 || 0 : 0; 15080 15081 // Change pointer depending on indentation level. 15082 while (level--) { 15083 receivingNode = receivingNode.lastChild || receivingNode; 15084 15085 // If it's a list, move pointer to the last item. 15086 if (ms_list_converter_isList(receivingNode)) { 15087 receivingNode = receivingNode.lastChild || receivingNode; 15088 } 15089 } 15090 15091 // Make sure we append to a list. 15092 if (!ms_list_converter_isList(receivingNode)) { 15093 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 15094 } 15095 15096 // Append the list item to the list. 15097 receivingNode.appendChild(listItem); 15098 15099 // Remove the wrapper paragraph. 15100 node.parentNode.removeChild(node); 15101 } 15102 15103 ;// CONCATENATED MODULE: external ["wp","blob"] 15104 const external_wp_blob_namespaceObject = window["wp"]["blob"]; 15105 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/image-corrector.js 15106 /* wp:polyfill */ 15107 /** 15108 * WordPress dependencies 15109 */ 15110 15111 function imageCorrector(node) { 15112 if (node.nodeName !== 'IMG') { 15113 return; 15114 } 15115 if (node.src.indexOf('file:') === 0) { 15116 node.src = ''; 15117 } 15118 15119 // This piece cannot be tested outside a browser env. 15120 if (node.src.indexOf('data:') === 0) { 15121 const [properties, data] = node.src.split(','); 15122 const [type] = properties.slice(5).split(';'); 15123 if (!data || !type) { 15124 node.src = ''; 15125 return; 15126 } 15127 let decoded; 15128 15129 // Can throw DOMException! 15130 try { 15131 decoded = atob(data); 15132 } catch (e) { 15133 node.src = ''; 15134 return; 15135 } 15136 const uint8Array = new Uint8Array(decoded.length); 15137 for (let i = 0; i < uint8Array.length; i++) { 15138 uint8Array[i] = decoded.charCodeAt(i); 15139 } 15140 const name = type.replace('/', '.'); 15141 const file = new window.File([uint8Array], name, { 15142 type 15143 }); 15144 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 15145 } 15146 15147 // Remove trackers and hardly visible images. 15148 if (node.height === 1 || node.width === 1) { 15149 node.parentNode.removeChild(node); 15150 } 15151 } 15152 15153 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/div-normaliser.js 15154 /** 15155 * Internal dependencies 15156 */ 15157 15158 function divNormaliser(node) { 15159 if (node.nodeName !== 'DIV') { 15160 return; 15161 } 15162 node.innerHTML = normaliseBlocks(node.innerHTML); 15163 } 15164 15165 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 15166 var showdown = __webpack_require__(1030); 15167 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 15168 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/markdown-converter.js 15169 /** 15170 * External dependencies 15171 */ 15172 15173 15174 // Reuse the same showdown converter. 15175 const converter = new (showdown_default()).Converter({ 15176 noHeaderId: true, 15177 tables: true, 15178 literalMidWordUnderscores: true, 15179 omitExtraWLInCodeBlocks: true, 15180 simpleLineBreaks: true, 15181 strikethrough: true 15182 }); 15183 15184 /** 15185 * Corrects the Slack Markdown variant of the code block. 15186 * If uncorrected, it will be converted to inline code. 15187 * 15188 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks 15189 * 15190 * @param {string} text The potential Markdown text to correct. 15191 * 15192 * @return {string} The corrected Markdown. 15193 */ 15194 function slackMarkdownVariantCorrector(text) { 15195 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `$p1}\n$p2}\n$p3}`); 15196 } 15197 function bulletsToAsterisks(text) { 15198 return text.replace(/(^|\n)•( +)/g, '$1*$2'); 15199 } 15200 15201 /** 15202 * Converts a piece of text into HTML based on any Markdown present. 15203 * Also decodes any encoded HTML. 15204 * 15205 * @param {string} text The plain text to convert. 15206 * 15207 * @return {string} HTML. 15208 */ 15209 function markdownConverter(text) { 15210 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text))); 15211 } 15212 15213 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/iframe-remover.js 15214 /** 15215 * Removes iframes. 15216 * 15217 * @param {Node} node The node to check. 15218 * 15219 * @return {void} 15220 */ 15221 function iframeRemover(node) { 15222 if (node.nodeName === 'IFRAME') { 15223 const text = node.ownerDocument.createTextNode(node.src); 15224 node.parentNode.replaceChild(text, node); 15225 } 15226 } 15227 15228 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 15229 /** 15230 * WordPress dependencies 15231 */ 15232 15233 function googleDocsUIdRemover(node) { 15234 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 15235 return; 15236 } 15237 15238 // Google Docs sometimes wraps the content in a B tag. We don't want to keep 15239 // this. 15240 if (node.tagName === 'B') { 15241 (0,external_wp_dom_namespaceObject.unwrap)(node); 15242 } else { 15243 node.removeAttribute('id'); 15244 } 15245 } 15246 15247 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-formatting-remover.js 15248 /** 15249 * Internal dependencies 15250 */ 15251 15252 function isFormattingSpace(character) { 15253 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 15254 } 15255 15256 /** 15257 * Removes spacing that formats HTML. 15258 * 15259 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 15260 * 15261 * @param {Node} node The node to be processed. 15262 * @return {void} 15263 */ 15264 function htmlFormattingRemover(node) { 15265 if (node.nodeType !== node.TEXT_NODE) { 15266 return; 15267 } 15268 15269 // Ignore pre content. Note that this does not use Element#closest due to 15270 // a combination of (a) node may not be Element and (b) node.parentElement 15271 // does not have full support in all browsers (Internet Exporer). 15272 // 15273 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 15274 15275 /** @type {Node?} */ 15276 let parent = node; 15277 while (parent = parent.parentNode) { 15278 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 15279 return; 15280 } 15281 } 15282 15283 // First, replace any sequence of HTML formatting space with a single space. 15284 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); 15285 15286 // Remove the leading space if the text element is at the start of a block, 15287 // is preceded by a line break element, or has a space in the previous 15288 // node. 15289 if (newData[0] === ' ') { 15290 const previousSibling = getSibling(node, 'previous'); 15291 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 15292 newData = newData.slice(1); 15293 } 15294 } 15295 15296 // Remove the trailing space if the text element is at the end of a block, 15297 // is succeded by a line break element, or has a space in the next text 15298 // node. 15299 if (newData[newData.length - 1] === ' ') { 15300 const nextSibling = getSibling(node, 'next'); 15301 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 15302 newData = newData.slice(0, -1); 15303 } 15304 } 15305 15306 // If there's no data left, remove the node, so `previousSibling` stays 15307 // accurate. Otherwise, update the node data. 15308 if (!newData) { 15309 node.parentNode.removeChild(node); 15310 } else { 15311 node.data = newData; 15312 } 15313 } 15314 15315 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/br-remover.js 15316 /** 15317 * Internal dependencies 15318 */ 15319 15320 15321 /** 15322 * Removes trailing br elements from text-level content. 15323 * 15324 * @param {Element} node Node to check. 15325 */ 15326 function brRemover(node) { 15327 if (node.nodeName !== 'BR') { 15328 return; 15329 } 15330 if (getSibling(node, 'next')) { 15331 return; 15332 } 15333 node.parentNode.removeChild(node); 15334 } 15335 15336 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 15337 /** 15338 * Removes empty paragraph elements. 15339 * 15340 * @param {Element} node Node to check. 15341 */ 15342 function emptyParagraphRemover(node) { 15343 if (node.nodeName !== 'P') { 15344 return; 15345 } 15346 if (node.hasChildNodes()) { 15347 return; 15348 } 15349 node.parentNode.removeChild(node); 15350 } 15351 15352 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js 15353 /** 15354 * Replaces Slack paragraph markup with a double line break (later converted to 15355 * a proper paragraph). 15356 * 15357 * @param {Element} node Node to check. 15358 */ 15359 function slackParagraphCorrector(node) { 15360 if (node.nodeName !== 'SPAN') { 15361 return; 15362 } 15363 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') { 15364 return; 15365 } 15366 const { 15367 parentNode 15368 } = node; 15369 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15370 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15371 parentNode.removeChild(node); 15372 } 15373 15374 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/paste-handler.js 15375 /** 15376 * WordPress dependencies 15377 */ 15378 15379 15380 /** 15381 * Internal dependencies 15382 */ 15383 15384 15385 15386 15387 15388 15389 15390 15391 15392 15393 15394 15395 15396 15397 15398 15399 15400 15401 15402 15403 15404 15405 15406 15407 15408 15409 const log = (...args) => window?.console?.log?.(...args); 15410 15411 /** 15412 * Filters HTML to only contain phrasing content. 15413 * 15414 * @param {string} HTML The HTML to filter. 15415 * 15416 * @return {string} HTML only containing phrasing content. 15417 */ 15418 function filterInlineHTML(HTML) { 15419 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, msListIgnore, phrasingContentReducer, commentRemover]); 15420 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), { 15421 inline: true 15422 }); 15423 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 15424 15425 // Allows us to ask for this information when we get a report. 15426 log('Processed inline HTML:\n\n', HTML); 15427 return HTML; 15428 } 15429 15430 /** 15431 * Converts an HTML string to known blocks. Strips everything else. 15432 * 15433 * @param {Object} options 15434 * @param {string} [options.HTML] The HTML to convert. 15435 * @param {string} [options.plainText] Plain text version. 15436 * @param {string} [options.mode] Handle content as blocks or inline content. 15437 * * 'AUTO': Decide based on the content passed. 15438 * * 'INLINE': Always handle as inline content, and return string. 15439 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 15440 * @param {Array} [options.tagName] The tag into which content will be inserted. 15441 * 15442 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 15443 */ 15444 function pasteHandler({ 15445 HTML = '', 15446 plainText = '', 15447 mode = 'AUTO', 15448 tagName 15449 }) { 15450 // First of all, strip any meta tags. 15451 HTML = HTML.replace(/<meta[^>]+>/g, ''); 15452 // Strip Windows markers. 15453 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 15454 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); 15455 15456 // If we detect block delimiters in HTML, parse entirely as blocks. 15457 if (mode !== 'INLINE') { 15458 // Check plain text if there is no HTML. 15459 const content = HTML ? HTML : plainText; 15460 if (content.indexOf('<!-- wp:') !== -1) { 15461 const parseResult = parser_parse(content); 15462 const isSingleFreeFormBlock = parseResult.length === 1 && parseResult[0].name === 'core/freeform'; 15463 if (!isSingleFreeFormBlock) { 15464 return parseResult; 15465 } 15466 } 15467 } 15468 15469 // Normalize unicode to use composed characters. 15470 // Not normalizing the content will only affect older browsers and won't 15471 // entirely break the app. 15472 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 15473 // See: https://core.trac.wordpress.org/ticket/30130 15474 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 15475 if (String.prototype.normalize) { 15476 HTML = HTML.normalize(); 15477 } 15478 15479 // Must be run before checking if it's inline content. 15480 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]); 15481 15482 // Consider plain text if: 15483 // * There is a plain text version. 15484 // * There is no HTML version, or it has no formatting. 15485 const isPlainText = plainText && (!HTML || isPlain(HTML)); 15486 15487 // Parse Markdown (and encoded HTML) if it's considered plain text. 15488 if (isPlainText) { 15489 HTML = plainText; 15490 15491 // The markdown converter (Showdown) trims whitespace. 15492 if (!/^\s+$/.test(plainText)) { 15493 HTML = markdownConverter(HTML); 15494 } 15495 } 15496 15497 // An array of HTML strings and block objects. The blocks replace matched 15498 // shortcodes. 15499 const pieces = shortcode_converter(HTML); 15500 15501 // The call to shortcodeConverter will always return more than one element 15502 // if shortcodes are matched. The reason is when shortcodes are matched 15503 // empty HTML strings are included. 15504 const hasShortcodes = pieces.length > 1; 15505 if (isPlainText && !hasShortcodes) { 15506 // Switch to inline mode if: 15507 // * The current mode is AUTO. 15508 // * The original plain text had no line breaks. 15509 // * The original plain text was not an HTML paragraph. 15510 // * The converted text is just a paragraph. 15511 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 15512 mode = 'INLINE'; 15513 } 15514 } 15515 if (mode === 'INLINE') { 15516 return filterInlineHTML(HTML); 15517 } 15518 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 15519 return filterInlineHTML(HTML); 15520 } 15521 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'); 15522 const blockContentSchema = getBlockContentSchema('paste'); 15523 const blocks = pieces.map(piece => { 15524 // Already a block from shortcode. 15525 if (typeof piece !== 'string') { 15526 return piece; 15527 } 15528 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser(), divNormaliser]; 15529 const schema = { 15530 ...blockContentSchema, 15531 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 15532 ...phrasingContentSchema 15533 }; 15534 piece = deepFilterHTML(piece, filters, blockContentSchema); 15535 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema); 15536 piece = normaliseBlocks(piece); 15537 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); 15538 15539 // Allows us to ask for this information when we get a report. 15540 log('Processed HTML piece:\n\n', piece); 15541 return htmlToBlocks(piece, pasteHandler); 15542 }).flat().filter(Boolean); 15543 15544 // If we're allowed to return inline content, and there is only one 15545 // inlineable block, and the original plain text content does not have any 15546 // line breaks, then treat it as inline paste. 15547 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 15548 const trimRegex = /^[\n]+|[\n]+$/g; 15549 // Don't catch line breaks at the start or end. 15550 const trimmedPlainText = plainText.replace(trimRegex, ''); 15551 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 15552 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema).replace(trimRegex, ''); 15553 } 15554 } 15555 return blocks; 15556 } 15557 15558 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/categories.js 15559 /** 15560 * WordPress dependencies 15561 */ 15562 15563 15564 /** 15565 * Internal dependencies 15566 */ 15567 15568 15569 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 15570 15571 /** 15572 * Returns all the block categories. 15573 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 15574 * 15575 * @ignore 15576 * 15577 * @return {WPBlockCategory[]} Block categories. 15578 */ 15579 function categories_getCategories() { 15580 return (0,external_wp_data_namespaceObject.select)(store).getCategories(); 15581 } 15582 15583 /** 15584 * Sets the block categories. 15585 * 15586 * @param {WPBlockCategory[]} categories Block categories. 15587 * 15588 * @example 15589 * ```js 15590 * import { __ } from '@wordpress/i18n'; 15591 * import { store as blocksStore, setCategories } from '@wordpress/blocks'; 15592 * import { useSelect } from '@wordpress/data'; 15593 * import { Button } from '@wordpress/components'; 15594 * 15595 * const ExampleComponent = () => { 15596 * // Retrieve the list of current categories. 15597 * const blockCategories = useSelect( 15598 * ( select ) => select( blocksStore ).getCategories(), 15599 * [] 15600 * ); 15601 * 15602 * return ( 15603 * <Button 15604 * onClick={ () => { 15605 * // Add a custom category to the existing list. 15606 * setCategories( [ 15607 * ...blockCategories, 15608 * { title: 'Custom Category', slug: 'custom-category' }, 15609 * ] ); 15610 * } } 15611 * > 15612 * { __( 'Add a new custom block category' ) } 15613 * </Button> 15614 * ); 15615 * }; 15616 * ``` 15617 */ 15618 function categories_setCategories(categories) { 15619 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories); 15620 } 15621 15622 /** 15623 * Updates a category. 15624 * 15625 * @param {string} slug Block category slug. 15626 * @param {WPBlockCategory} category Object containing the category properties 15627 * that should be updated. 15628 * 15629 * @example 15630 * ```js 15631 * import { __ } from '@wordpress/i18n'; 15632 * import { updateCategory } from '@wordpress/blocks'; 15633 * import { Button } from '@wordpress/components'; 15634 * 15635 * const ExampleComponent = () => { 15636 * return ( 15637 * <Button 15638 * onClick={ () => { 15639 * updateCategory( 'text', { title: __( 'Written Word' ) } ); 15640 * } } 15641 * > 15642 * { __( 'Update Text category title' ) } 15643 * </Button> 15644 * ) ; 15645 * }; 15646 * ``` 15647 */ 15648 function categories_updateCategory(slug, category) { 15649 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category); 15650 } 15651 15652 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/templates.js 15653 /** 15654 * WordPress dependencies 15655 */ 15656 15657 15658 /** 15659 * Internal dependencies 15660 */ 15661 15662 15663 15664 15665 /** 15666 * Checks whether a list of blocks matches a template by comparing the block names. 15667 * 15668 * @param {Array} blocks Block list. 15669 * @param {Array} template Block template. 15670 * 15671 * @return {boolean} Whether the list of blocks matches a templates. 15672 */ 15673 function doBlocksMatchTemplate(blocks = [], template = []) { 15674 return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => { 15675 const block = blocks[index]; 15676 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 15677 }); 15678 } 15679 const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html'; 15680 const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query'; 15681 function normalizeAttributes(schema, values) { 15682 if (!values) { 15683 return {}; 15684 } 15685 return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)])); 15686 } 15687 function normalizeAttribute(definition, value) { 15688 if (isHTMLAttribute(definition) && Array.isArray(value)) { 15689 // Introduce a deprecated call at this point 15690 // When we're confident that "children" format should be removed from the templates. 15691 15692 return (0,external_wp_element_namespaceObject.renderToString)(value); 15693 } 15694 if (isQueryAttribute(definition) && value) { 15695 return value.map(subValues => { 15696 return normalizeAttributes(definition.query, subValues); 15697 }); 15698 } 15699 return value; 15700 } 15701 15702 /** 15703 * Synchronize a block list with a block template. 15704 * 15705 * Synchronizing a block list with a block template means that we loop over the blocks 15706 * keep the block as is if it matches the block at the same position in the template 15707 * (If it has the same name) and if doesn't match, we create a new block based on the template. 15708 * Extra blocks not present in the template are removed. 15709 * 15710 * @param {Array} blocks Block list. 15711 * @param {Array} template Block template. 15712 * 15713 * @return {Array} Updated Block list. 15714 */ 15715 function synchronizeBlocksWithTemplate(blocks = [], template) { 15716 // If no template is provided, return blocks unmodified. 15717 if (!template) { 15718 return blocks; 15719 } 15720 return template.map(([name, attributes, innerBlocksTemplate], index) => { 15721 var _blockType$attributes; 15722 const block = blocks[index]; 15723 if (block && block.name === name) { 15724 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 15725 return { 15726 ...block, 15727 innerBlocks 15728 }; 15729 } 15730 15731 // To support old templates that were using the "children" format 15732 // for the attributes using "html" strings now, we normalize the template attributes 15733 // before creating the blocks. 15734 15735 const blockType = getBlockType(name); 15736 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes); 15737 let [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); 15738 15739 // If a Block is undefined at this point, use the core/missing block as 15740 // a placeholder for a better user experience. 15741 if (undefined === getBlockType(blockName)) { 15742 blockAttributes = { 15743 originalName: name, 15744 originalContent: '', 15745 originalUndelimitedContent: '' 15746 }; 15747 blockName = 'core/missing'; 15748 } 15749 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 15750 }); 15751 } 15752 15753 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/index.js 15754 /** 15755 * Internal dependencies 15756 */ 15757 15758 15759 15760 // The blocktype is the most important concept within the block API. It defines 15761 // all aspects of the block configuration and its interfaces, including `edit` 15762 // and `save`. The transforms specification allows converting one blocktype to 15763 // another through formulas defined by either the source or the destination. 15764 // Switching a blocktype is to be considered a one-way operation implying a 15765 // transformation in the opposite way has to be handled explicitly. 15766 15767 15768 // The block tree is composed of a collection of block nodes. Blocks contained 15769 // within other blocks are called inner blocks. An important design 15770 // consideration is that inner blocks are -- conceptually -- not part of the 15771 // territory established by the parent block that contains them. 15772 // 15773 // This has multiple practical implications: when parsing, we can safely dispose 15774 // of any block boundary found within a block from the innerHTML property when 15775 // transfering to state. Not doing so would have a compounding effect on memory 15776 // and uncertainty over the source of truth. This can be illustrated in how, 15777 // given a tree of `n` nested blocks, the entry node would have to contain the 15778 // actual content of each block while each subsequent block node in the state 15779 // tree would replicate the entire chain `n-1`, meaning the extreme end node 15780 // would have been replicated `n` times as the tree is traversed and would 15781 // generate uncertainty as to which one is to hold the current value of the 15782 // block. For composition, it also means inner blocks can effectively be child 15783 // components whose mechanisms can be shielded from the `edit` implementation 15784 // and just passed along. 15785 15786 15787 15788 15789 // While block transformations account for a specific surface of the API, there 15790 // are also raw transformations which handle arbitrary sources not made out of 15791 // blocks but producing block basaed on various heursitics. This includes 15792 // pasting rich text or HTML data. 15793 15794 15795 // The process of serialization aims to deflate the internal memory of the block 15796 // editor and its state representation back into an HTML valid string. This 15797 // process restores the document integrity and inserts invisible delimiters 15798 // around each block with HTML comment boundaries which can contain any extra 15799 // attributes needed to operate with the block later on. 15800 15801 15802 // Validation is the process of comparing a block source with its output before 15803 // there is any user input or interaction with a block. When this operation 15804 // fails -- for whatever reason -- the block is to be considered invalid. As 15805 // part of validating a block the system will attempt to run the source against 15806 // any provided deprecation definitions. 15807 // 15808 // Worth emphasizing that validation is not a case of whether the markup is 15809 // merely HTML spec-compliant but about how the editor knows to create such 15810 // markup and that its inability to create an identical result can be a strong 15811 // indicator of potential data loss (the invalidation is then a protective 15812 // measure). 15813 // 15814 // The invalidation process can also be deconstructed in phases: 1) validate the 15815 // block exists; 2) validate the source matches the output; 3) validate the 15816 // source matches deprecated outputs; 4) work through the significance of 15817 // differences. These are stacked in a way that favors performance and optimizes 15818 // for the majority of cases. That is to say, the evaluation logic can become 15819 // more sophisticated the further down it goes in the process as the cost is 15820 // accounted for. The first logic checks have to be extremely efficient since 15821 // they will be run for all valid and invalid blocks alike. However, once a 15822 // block is detected as invalid -- failing the three first steps -- it is 15823 // adequate to spend more time determining validity before throwing a conflict. 15824 15825 15826 15827 // Blocks are inherently indifferent about where the data they operate with ends 15828 // up being saved. For example, all blocks can have a static and dynamic aspect 15829 // to them depending on the needs. The static nature of a block is the `save()` 15830 // definition that is meant to be serialized into HTML and which can be left 15831 // void. Any block can also register a `render_callback` on the server, which 15832 // makes its output dynamic either in part or in its totality. 15833 // 15834 // Child blocks are defined as a relationship that builds on top of the inner 15835 // blocks mechanism. A child block is a block node of a particular type that can 15836 // only exist within the inner block boundaries of a specific parent type. This 15837 // allows block authors to compose specific blocks that are not meant to be used 15838 // outside of a specified parent block context. Thus, child blocks extend the 15839 // concept of inner blocks to support a more direct relationship between sets of 15840 // blocks. The addition of parent–child would be a subset of the inner block 15841 // functionality under the premise that certain blocks only make sense as 15842 // children of another block. 15843 15844 15845 15846 // Templates are, in a general sense, a basic collection of block nodes with any 15847 // given set of predefined attributes that are supplied as the initial state of 15848 // an inner blocks group. These nodes can, in turn, contain any number of nested 15849 // blocks within their definition. Templates allow both to specify a default 15850 // state for an editor session or a default set of blocks for any inner block 15851 // implementation within a specific block. 15852 15853 15854 15855 15856 const privateApis = {}; 15857 lock(privateApis, { 15858 isUnmodifiedBlockContent: isUnmodifiedBlockContent 15859 }); 15860 15861 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/deprecated.js 15862 /** 15863 * WordPress dependencies 15864 */ 15865 15866 15867 /** 15868 * A Higher Order Component used to inject BlockContent using context to the 15869 * wrapped component. 15870 * 15871 * @deprecated 15872 * 15873 * @param {Component} OriginalComponent The component to enhance. 15874 * @return {Component} The same component. 15875 */ 15876 function withBlockContentContext(OriginalComponent) { 15877 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', { 15878 since: '6.1' 15879 }); 15880 return OriginalComponent; 15881 } 15882 15883 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/index.js 15884 // A "block" is the abstract term used to describe units of markup that, 15885 // when composed together, form the content or layout of a page. 15886 // The API for blocks is exposed via `wp.blocks`. 15887 // 15888 // Supported blocks are registered by calling `registerBlockType`. Once registered, 15889 // the block is made available as an option to the editor interface. 15890 // 15891 // Blocks are inferred from the HTML source of a post through a parsing mechanism 15892 // and then stored as objects in state, from which it is then rendered for editing. 15893 15894 15895 15896 15897 15898 })(); 15899 15900 (window.wp = window.wp || {}).blocks = __webpack_exports__; 15901 /******/ })() 15902 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |