blocks.js (494305B)
1 this["wp"] = this["wp"] || {}; this["wp"]["blocks"] = 2 /******/ (function(modules) { // webpackBootstrap 3 /******/ // The module cache 4 /******/ var installedModules = {}; 5 /******/ 6 /******/ // The require function 7 /******/ function __webpack_require__(moduleId) { 8 /******/ 9 /******/ // Check if module is in cache 10 /******/ if(installedModules[moduleId]) { 11 /******/ return installedModules[moduleId].exports; 12 /******/ } 13 /******/ // Create a new module (and put it into the cache) 14 /******/ var module = installedModules[moduleId] = { 15 /******/ i: moduleId, 16 /******/ l: false, 17 /******/ exports: {} 18 /******/ }; 19 /******/ 20 /******/ // Execute the module function 21 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 22 /******/ 23 /******/ // Flag the module as loaded 24 /******/ module.l = true; 25 /******/ 26 /******/ // Return the exports of the module 27 /******/ return module.exports; 28 /******/ } 29 /******/ 30 /******/ 31 /******/ // expose the modules object (__webpack_modules__) 32 /******/ __webpack_require__.m = modules; 33 /******/ 34 /******/ // expose the module cache 35 /******/ __webpack_require__.c = installedModules; 36 /******/ 37 /******/ // define getter function for harmony exports 38 /******/ __webpack_require__.d = function(exports, name, getter) { 39 /******/ if(!__webpack_require__.o(exports, name)) { 40 /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 41 /******/ } 42 /******/ }; 43 /******/ 44 /******/ // define __esModule on exports 45 /******/ __webpack_require__.r = function(exports) { 46 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 47 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 48 /******/ } 49 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 50 /******/ }; 51 /******/ 52 /******/ // create a fake namespace object 53 /******/ // mode & 1: value is a module id, require it 54 /******/ // mode & 2: merge all properties of value into the ns 55 /******/ // mode & 4: return value when already ns object 56 /******/ // mode & 8|1: behave like require 57 /******/ __webpack_require__.t = function(value, mode) { 58 /******/ if(mode & 1) value = __webpack_require__(value); 59 /******/ if(mode & 8) return value; 60 /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 61 /******/ var ns = Object.create(null); 62 /******/ __webpack_require__.r(ns); 63 /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 64 /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 65 /******/ return ns; 66 /******/ }; 67 /******/ 68 /******/ // getDefaultExport function for compatibility with non-harmony modules 69 /******/ __webpack_require__.n = function(module) { 70 /******/ var getter = module && module.__esModule ? 71 /******/ function getDefault() { return module['default']; } : 72 /******/ function getModuleExports() { return module; }; 73 /******/ __webpack_require__.d(getter, 'a', getter); 74 /******/ return getter; 75 /******/ }; 76 /******/ 77 /******/ // Object.prototype.hasOwnProperty.call 78 /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 79 /******/ 80 /******/ // __webpack_public_path__ 81 /******/ __webpack_require__.p = ""; 82 /******/ 83 /******/ 84 /******/ // Load entry module and return exports 85 /******/ return __webpack_require__(__webpack_require__.s = "0ATp"); 86 /******/ }) 87 /************************************************************************/ 88 /******/ ({ 89 90 /***/ "//Lo": 91 /***/ (function(module, __webpack_exports__, __webpack_require__) { 92 93 "use strict"; 94 /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("GRId"); 95 /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__); 96 /* harmony import */ var _wordpress_primitives__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("Tqx9"); 97 /* harmony import */ var _wordpress_primitives__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_primitives__WEBPACK_IMPORTED_MODULE_1__); 98 99 100 /** 101 * WordPress dependencies 102 */ 103 104 const blockDefault = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_primitives__WEBPACK_IMPORTED_MODULE_1__["SVG"], { 105 xmlns: "http://www.w3.org/2000/svg", 106 viewBox: "0 0 24 24" 107 }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_primitives__WEBPACK_IMPORTED_MODULE_1__["Path"], { 108 d: "M19 8h-1V6h-5v2h-2V6H6v2H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-8c0-1.1-.9-2-2-2zm.5 10c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5v-8c0-.3.2-.5.5-.5h14c.3 0 .5.2.5.5v8z" 109 })); 110 /* harmony default export */ __webpack_exports__["a"] = (blockDefault); 111 112 113 /***/ }), 114 115 /***/ "0ATp": 116 /***/ (function(module, __webpack_exports__, __webpack_require__) { 117 118 "use strict"; 119 // ESM COMPAT FLAG 120 __webpack_require__.r(__webpack_exports__); 121 122 // EXPORTS 123 __webpack_require__.d(__webpack_exports__, "store", function() { return /* reexport */ store; }); 124 __webpack_require__.d(__webpack_exports__, "createBlock", function() { return /* reexport */ createBlock; }); 125 __webpack_require__.d(__webpack_exports__, "createBlocksFromInnerBlocksTemplate", function() { return /* reexport */ createBlocksFromInnerBlocksTemplate; }); 126 __webpack_require__.d(__webpack_exports__, "cloneBlock", function() { return /* reexport */ cloneBlock; }); 127 __webpack_require__.d(__webpack_exports__, "__experimentalCloneSanitizedBlock", function() { return /* reexport */ __experimentalCloneSanitizedBlock; }); 128 __webpack_require__.d(__webpack_exports__, "getPossibleBlockTransformations", function() { return /* reexport */ getPossibleBlockTransformations; }); 129 __webpack_require__.d(__webpack_exports__, "switchToBlockType", function() { return /* reexport */ switchToBlockType; }); 130 __webpack_require__.d(__webpack_exports__, "getBlockTransforms", function() { return /* reexport */ getBlockTransforms; }); 131 __webpack_require__.d(__webpack_exports__, "findTransform", function() { return /* reexport */ findTransform; }); 132 __webpack_require__.d(__webpack_exports__, "getBlockFromExample", function() { return /* reexport */ getBlockFromExample; }); 133 __webpack_require__.d(__webpack_exports__, "parse", function() { return /* reexport */ parser; }); 134 __webpack_require__.d(__webpack_exports__, "getBlockAttributes", function() { return /* reexport */ getBlockAttributes; }); 135 __webpack_require__.d(__webpack_exports__, "parseWithAttributeSchema", function() { return /* reexport */ parseWithAttributeSchema; }); 136 __webpack_require__.d(__webpack_exports__, "pasteHandler", function() { return /* reexport */ pasteHandler; }); 137 __webpack_require__.d(__webpack_exports__, "rawHandler", function() { return /* reexport */ rawHandler; }); 138 __webpack_require__.d(__webpack_exports__, "getPhrasingContentSchema", function() { return /* reexport */ deprecatedGetPhrasingContentSchema; }); 139 __webpack_require__.d(__webpack_exports__, "serialize", function() { return /* reexport */ serialize; }); 140 __webpack_require__.d(__webpack_exports__, "getBlockContent", function() { return /* reexport */ getBlockInnerHTML; }); 141 __webpack_require__.d(__webpack_exports__, "getBlockDefaultClassName", function() { return /* reexport */ getBlockDefaultClassName; }); 142 __webpack_require__.d(__webpack_exports__, "getBlockMenuDefaultClassName", function() { return /* reexport */ getBlockMenuDefaultClassName; }); 143 __webpack_require__.d(__webpack_exports__, "getSaveElement", function() { return /* reexport */ getSaveElement; }); 144 __webpack_require__.d(__webpack_exports__, "getSaveContent", function() { return /* reexport */ getSaveContent; }); 145 __webpack_require__.d(__webpack_exports__, "__unstableGetBlockProps", function() { return /* reexport */ getBlockProps; }); 146 __webpack_require__.d(__webpack_exports__, "__unstableSerializeAndClean", function() { return /* reexport */ __unstableSerializeAndClean; }); 147 __webpack_require__.d(__webpack_exports__, "isValidBlockContent", function() { return /* reexport */ isValidBlockContent; }); 148 __webpack_require__.d(__webpack_exports__, "getCategories", function() { return /* reexport */ categories_getCategories; }); 149 __webpack_require__.d(__webpack_exports__, "setCategories", function() { return /* reexport */ categories_setCategories; }); 150 __webpack_require__.d(__webpack_exports__, "updateCategory", function() { return /* reexport */ categories_updateCategory; }); 151 __webpack_require__.d(__webpack_exports__, "registerBlockType", function() { return /* reexport */ registerBlockType; }); 152 __webpack_require__.d(__webpack_exports__, "registerBlockTypeFromMetadata", function() { return /* reexport */ registerBlockTypeFromMetadata; }); 153 __webpack_require__.d(__webpack_exports__, "registerBlockCollection", function() { return /* reexport */ registerBlockCollection; }); 154 __webpack_require__.d(__webpack_exports__, "unregisterBlockType", function() { return /* reexport */ unregisterBlockType; }); 155 __webpack_require__.d(__webpack_exports__, "setFreeformContentHandlerName", function() { return /* reexport */ setFreeformContentHandlerName; }); 156 __webpack_require__.d(__webpack_exports__, "getFreeformContentHandlerName", function() { return /* reexport */ getFreeformContentHandlerName; }); 157 __webpack_require__.d(__webpack_exports__, "setUnregisteredTypeHandlerName", function() { return /* reexport */ setUnregisteredTypeHandlerName; }); 158 __webpack_require__.d(__webpack_exports__, "getUnregisteredTypeHandlerName", function() { return /* reexport */ getUnregisteredTypeHandlerName; }); 159 __webpack_require__.d(__webpack_exports__, "setDefaultBlockName", function() { return /* reexport */ registration_setDefaultBlockName; }); 160 __webpack_require__.d(__webpack_exports__, "getDefaultBlockName", function() { return /* reexport */ registration_getDefaultBlockName; }); 161 __webpack_require__.d(__webpack_exports__, "setGroupingBlockName", function() { return /* reexport */ registration_setGroupingBlockName; }); 162 __webpack_require__.d(__webpack_exports__, "getGroupingBlockName", function() { return /* reexport */ registration_getGroupingBlockName; }); 163 __webpack_require__.d(__webpack_exports__, "getBlockType", function() { return /* reexport */ registration_getBlockType; }); 164 __webpack_require__.d(__webpack_exports__, "getBlockTypes", function() { return /* reexport */ registration_getBlockTypes; }); 165 __webpack_require__.d(__webpack_exports__, "getBlockSupport", function() { return /* reexport */ registration_getBlockSupport; }); 166 __webpack_require__.d(__webpack_exports__, "hasBlockSupport", function() { return /* reexport */ registration_hasBlockSupport; }); 167 __webpack_require__.d(__webpack_exports__, "getBlockVariations", function() { return /* reexport */ registration_getBlockVariations; }); 168 __webpack_require__.d(__webpack_exports__, "isReusableBlock", function() { return /* reexport */ isReusableBlock; }); 169 __webpack_require__.d(__webpack_exports__, "isTemplatePart", function() { return /* reexport */ isTemplatePart; }); 170 __webpack_require__.d(__webpack_exports__, "getChildBlockNames", function() { return /* reexport */ registration_getChildBlockNames; }); 171 __webpack_require__.d(__webpack_exports__, "hasChildBlocks", function() { return /* reexport */ registration_hasChildBlocks; }); 172 __webpack_require__.d(__webpack_exports__, "hasChildBlocksWithInserterSupport", function() { return /* reexport */ registration_hasChildBlocksWithInserterSupport; }); 173 __webpack_require__.d(__webpack_exports__, "unstable__bootstrapServerSideBlockDefinitions", function() { return /* reexport */ unstable__bootstrapServerSideBlockDefinitions; }); 174 __webpack_require__.d(__webpack_exports__, "registerBlockStyle", function() { return /* reexport */ registerBlockStyle; }); 175 __webpack_require__.d(__webpack_exports__, "unregisterBlockStyle", function() { return /* reexport */ unregisterBlockStyle; }); 176 __webpack_require__.d(__webpack_exports__, "registerBlockVariation", function() { return /* reexport */ registerBlockVariation; }); 177 __webpack_require__.d(__webpack_exports__, "unregisterBlockVariation", function() { return /* reexport */ unregisterBlockVariation; }); 178 __webpack_require__.d(__webpack_exports__, "isUnmodifiedDefaultBlock", function() { return /* reexport */ isUnmodifiedDefaultBlock; }); 179 __webpack_require__.d(__webpack_exports__, "normalizeIconObject", function() { return /* reexport */ normalizeIconObject; }); 180 __webpack_require__.d(__webpack_exports__, "isValidIcon", function() { return /* reexport */ isValidIcon; }); 181 __webpack_require__.d(__webpack_exports__, "__experimentalGetBlockLabel", function() { return /* reexport */ getBlockLabel; }); 182 __webpack_require__.d(__webpack_exports__, "__experimentalGetAccessibleBlockLabel", function() { return /* reexport */ getAccessibleBlockLabel; }); 183 __webpack_require__.d(__webpack_exports__, "__experimentalSanitizeBlockAttributes", function() { return /* reexport */ __experimentalSanitizeBlockAttributes; }); 184 __webpack_require__.d(__webpack_exports__, "__experimentalGetBlockAttributesNamesByRole", function() { return /* reexport */ __experimentalGetBlockAttributesNamesByRole; }); 185 __webpack_require__.d(__webpack_exports__, "doBlocksMatchTemplate", function() { return /* reexport */ doBlocksMatchTemplate; }); 186 __webpack_require__.d(__webpack_exports__, "synchronizeBlocksWithTemplate", function() { return /* reexport */ synchronizeBlocksWithTemplate; }); 187 __webpack_require__.d(__webpack_exports__, "children", function() { return /* reexport */ api_children; }); 188 __webpack_require__.d(__webpack_exports__, "node", function() { return /* reexport */ api_node; }); 189 __webpack_require__.d(__webpack_exports__, "__EXPERIMENTAL_STYLE_PROPERTY", function() { return /* reexport */ __EXPERIMENTAL_STYLE_PROPERTY; }); 190 __webpack_require__.d(__webpack_exports__, "__EXPERIMENTAL_ELEMENTS", function() { return /* reexport */ __EXPERIMENTAL_ELEMENTS; }); 191 __webpack_require__.d(__webpack_exports__, "withBlockContentContext", function() { return /* reexport */ withBlockContentContext; }); 192 193 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 194 var selectors_namespaceObject = {}; 195 __webpack_require__.r(selectors_namespaceObject); 196 __webpack_require__.d(selectors_namespaceObject, "getBlockTypes", function() { return getBlockTypes; }); 197 __webpack_require__.d(selectors_namespaceObject, "getBlockType", function() { return getBlockType; }); 198 __webpack_require__.d(selectors_namespaceObject, "getBlockStyles", function() { return getBlockStyles; }); 199 __webpack_require__.d(selectors_namespaceObject, "getBlockVariations", function() { return getBlockVariations; }); 200 __webpack_require__.d(selectors_namespaceObject, "getActiveBlockVariation", function() { return getActiveBlockVariation; }); 201 __webpack_require__.d(selectors_namespaceObject, "getDefaultBlockVariation", function() { return getDefaultBlockVariation; }); 202 __webpack_require__.d(selectors_namespaceObject, "getCategories", function() { return getCategories; }); 203 __webpack_require__.d(selectors_namespaceObject, "getCollections", function() { return getCollections; }); 204 __webpack_require__.d(selectors_namespaceObject, "getDefaultBlockName", function() { return getDefaultBlockName; }); 205 __webpack_require__.d(selectors_namespaceObject, "getFreeformFallbackBlockName", function() { return getFreeformFallbackBlockName; }); 206 __webpack_require__.d(selectors_namespaceObject, "getUnregisteredFallbackBlockName", function() { return getUnregisteredFallbackBlockName; }); 207 __webpack_require__.d(selectors_namespaceObject, "getGroupingBlockName", function() { return getGroupingBlockName; }); 208 __webpack_require__.d(selectors_namespaceObject, "getChildBlockNames", function() { return getChildBlockNames; }); 209 __webpack_require__.d(selectors_namespaceObject, "getBlockSupport", function() { return getBlockSupport; }); 210 __webpack_require__.d(selectors_namespaceObject, "hasBlockSupport", function() { return hasBlockSupport; }); 211 __webpack_require__.d(selectors_namespaceObject, "isMatchingSearchTerm", function() { return isMatchingSearchTerm; }); 212 __webpack_require__.d(selectors_namespaceObject, "hasChildBlocks", function() { return hasChildBlocks; }); 213 __webpack_require__.d(selectors_namespaceObject, "hasChildBlocksWithInserterSupport", function() { return hasChildBlocksWithInserterSupport; }); 214 215 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/actions.js 216 var actions_namespaceObject = {}; 217 __webpack_require__.r(actions_namespaceObject); 218 __webpack_require__.d(actions_namespaceObject, "addBlockTypes", function() { return addBlockTypes; }); 219 __webpack_require__.d(actions_namespaceObject, "removeBlockTypes", function() { return removeBlockTypes; }); 220 __webpack_require__.d(actions_namespaceObject, "addBlockStyles", function() { return addBlockStyles; }); 221 __webpack_require__.d(actions_namespaceObject, "removeBlockStyles", function() { return removeBlockStyles; }); 222 __webpack_require__.d(actions_namespaceObject, "addBlockVariations", function() { return addBlockVariations; }); 223 __webpack_require__.d(actions_namespaceObject, "removeBlockVariations", function() { return removeBlockVariations; }); 224 __webpack_require__.d(actions_namespaceObject, "setDefaultBlockName", function() { return setDefaultBlockName; }); 225 __webpack_require__.d(actions_namespaceObject, "setFreeformFallbackBlockName", function() { return setFreeformFallbackBlockName; }); 226 __webpack_require__.d(actions_namespaceObject, "setUnregisteredFallbackBlockName", function() { return setUnregisteredFallbackBlockName; }); 227 __webpack_require__.d(actions_namespaceObject, "setGroupingBlockName", function() { return setGroupingBlockName; }); 228 __webpack_require__.d(actions_namespaceObject, "setCategories", function() { return setCategories; }); 229 __webpack_require__.d(actions_namespaceObject, "updateCategory", function() { return updateCategory; }); 230 __webpack_require__.d(actions_namespaceObject, "addBlockCollection", function() { return addBlockCollection; }); 231 __webpack_require__.d(actions_namespaceObject, "removeBlockCollection", function() { return removeBlockCollection; }); 232 233 // EXTERNAL MODULE: external ["wp","data"] 234 var external_wp_data_ = __webpack_require__("1ZqX"); 235 236 // EXTERNAL MODULE: external "lodash" 237 var external_lodash_ = __webpack_require__("YLtl"); 238 239 // EXTERNAL MODULE: external ["wp","i18n"] 240 var external_wp_i18n_ = __webpack_require__("l3Sj"); 241 242 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/reducer.js 243 /** 244 * External dependencies 245 */ 246 247 /** 248 * WordPress dependencies 249 */ 250 251 252 253 /** 254 * @typedef {Object} WPBlockCategory 255 * 256 * @property {string} slug Unique category slug. 257 * @property {string} title Category label, for display in user interface. 258 */ 259 260 /** 261 * Default set of categories. 262 * 263 * @type {WPBlockCategory[]} 264 */ 265 266 const DEFAULT_CATEGORIES = [{ 267 slug: 'text', 268 title: Object(external_wp_i18n_["__"])('Text') 269 }, { 270 slug: 'media', 271 title: Object(external_wp_i18n_["__"])('Media') 272 }, { 273 slug: 'design', 274 title: Object(external_wp_i18n_["__"])('Design') 275 }, { 276 slug: 'widgets', 277 title: Object(external_wp_i18n_["__"])('Widgets') 278 }, { 279 slug: 'theme', 280 title: Object(external_wp_i18n_["__"])('Theme') 281 }, { 282 slug: 'embed', 283 title: Object(external_wp_i18n_["__"])('Embeds') 284 }, { 285 slug: 'reusable', 286 title: Object(external_wp_i18n_["__"])('Reusable blocks') 287 }]; 288 /** 289 * Reducer managing the block types 290 * 291 * @param {Object} state Current state. 292 * @param {Object} action Dispatched action. 293 * 294 * @return {Object} Updated state. 295 */ 296 297 function reducer_blockTypes(state = {}, action) { 298 switch (action.type) { 299 case 'ADD_BLOCK_TYPES': 300 return { ...state, 301 ...Object(external_lodash_["keyBy"])(Object(external_lodash_["map"])(action.blockTypes, blockType => Object(external_lodash_["omit"])(blockType, 'styles ')), 'name') 302 }; 303 304 case 'REMOVE_BLOCK_TYPES': 305 return Object(external_lodash_["omit"])(state, action.names); 306 } 307 308 return state; 309 } 310 /** 311 * Reducer managing the block style variations. 312 * 313 * @param {Object} state Current state. 314 * @param {Object} action Dispatched action. 315 * 316 * @return {Object} Updated state. 317 */ 318 319 function blockStyles(state = {}, action) { 320 switch (action.type) { 321 case 'ADD_BLOCK_TYPES': 322 return { ...state, 323 ...Object(external_lodash_["mapValues"])(Object(external_lodash_["keyBy"])(action.blockTypes, 'name'), blockType => { 324 return Object(external_lodash_["uniqBy"])([...Object(external_lodash_["get"])(blockType, ['styles'], []), ...Object(external_lodash_["get"])(state, [blockType.name], [])], style => style.name); 325 }) 326 }; 327 328 case 'ADD_BLOCK_STYLES': 329 return { ...state, 330 [action.blockName]: Object(external_lodash_["uniqBy"])([...Object(external_lodash_["get"])(state, [action.blockName], []), ...action.styles], style => style.name) 331 }; 332 333 case 'REMOVE_BLOCK_STYLES': 334 return { ...state, 335 [action.blockName]: Object(external_lodash_["filter"])(Object(external_lodash_["get"])(state, [action.blockName], []), style => action.styleNames.indexOf(style.name) === -1) 336 }; 337 } 338 339 return state; 340 } 341 /** 342 * Reducer managing the block variations. 343 * 344 * @param {Object} state Current state. 345 * @param {Object} action Dispatched action. 346 * 347 * @return {Object} Updated state. 348 */ 349 350 function blockVariations(state = {}, action) { 351 switch (action.type) { 352 case 'ADD_BLOCK_TYPES': 353 return { ...state, 354 ...Object(external_lodash_["mapValues"])(Object(external_lodash_["keyBy"])(action.blockTypes, 'name'), blockType => { 355 return Object(external_lodash_["uniqBy"])([...Object(external_lodash_["get"])(blockType, ['variations'], []), ...Object(external_lodash_["get"])(state, [blockType.name], [])], variation => variation.name); 356 }) 357 }; 358 359 case 'ADD_BLOCK_VARIATIONS': 360 return { ...state, 361 [action.blockName]: Object(external_lodash_["uniqBy"])([...Object(external_lodash_["get"])(state, [action.blockName], []), ...action.variations], variation => variation.name) 362 }; 363 364 case 'REMOVE_BLOCK_VARIATIONS': 365 return { ...state, 366 [action.blockName]: Object(external_lodash_["filter"])(Object(external_lodash_["get"])(state, [action.blockName], []), variation => action.variationNames.indexOf(variation.name) === -1) 367 }; 368 } 369 370 return state; 371 } 372 /** 373 * Higher-order Reducer creating a reducer keeping track of given block name. 374 * 375 * @param {string} setActionType Action type. 376 * 377 * @return {Function} Reducer. 378 */ 379 380 function createBlockNameSetterReducer(setActionType) { 381 return (state = null, action) => { 382 switch (action.type) { 383 case 'REMOVE_BLOCK_TYPES': 384 if (action.names.indexOf(state) !== -1) { 385 return null; 386 } 387 388 return state; 389 390 case setActionType: 391 return action.name || null; 392 } 393 394 return state; 395 }; 396 } 397 const reducer_defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 398 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 399 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 400 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 401 /** 402 * Reducer managing the categories 403 * 404 * @param {WPBlockCategory[]} state Current state. 405 * @param {Object} action Dispatched action. 406 * 407 * @return {WPBlockCategory[]} Updated state. 408 */ 409 410 function reducer_categories(state = DEFAULT_CATEGORIES, action) { 411 switch (action.type) { 412 case 'SET_CATEGORIES': 413 return action.categories || []; 414 415 case 'UPDATE_CATEGORY': 416 { 417 if (!action.category || Object(external_lodash_["isEmpty"])(action.category)) { 418 return state; 419 } 420 421 const categoryToChange = Object(external_lodash_["find"])(state, ['slug', action.slug]); 422 423 if (categoryToChange) { 424 return Object(external_lodash_["map"])(state, category => { 425 if (category.slug === action.slug) { 426 return { ...category, 427 ...action.category 428 }; 429 } 430 431 return category; 432 }); 433 } 434 } 435 } 436 437 return state; 438 } 439 function collections(state = {}, action) { 440 switch (action.type) { 441 case 'ADD_BLOCK_COLLECTION': 442 return { ...state, 443 [action.namespace]: { 444 title: action.title, 445 icon: action.icon 446 } 447 }; 448 449 case 'REMOVE_BLOCK_COLLECTION': 450 return Object(external_lodash_["omit"])(state, action.namespace); 451 } 452 453 return state; 454 } 455 /* harmony default export */ var reducer = (Object(external_wp_data_["combineReducers"])({ 456 blockTypes: reducer_blockTypes, 457 blockStyles, 458 blockVariations, 459 defaultBlockName: reducer_defaultBlockName, 460 freeformFallbackBlockName, 461 unregisteredFallbackBlockName, 462 groupingBlockName, 463 categories: reducer_categories, 464 collections 465 })); 466 467 // EXTERNAL MODULE: ./node_modules/rememo/es/rememo.js 468 var rememo = __webpack_require__("pPDe"); 469 470 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 471 /** 472 * External dependencies 473 */ 474 475 476 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 477 478 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 479 480 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 481 482 /** 483 * Given a block name or block type object, returns the corresponding 484 * normalized block type object. 485 * 486 * @param {Object} state Blocks state. 487 * @param {(string|Object)} nameOrType Block name or type object 488 * 489 * @return {Object} Block type object. 490 */ 491 492 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? getBlockType(state, nameOrType) : nameOrType; 493 /** 494 * Returns all the available block types. 495 * 496 * @param {Object} state Data state. 497 * 498 * @return {Array} Block Types. 499 */ 500 501 502 const getBlockTypes = Object(rememo["a" /* default */])(state => { 503 return Object.values(state.blockTypes).map(blockType => { 504 return { ...blockType, 505 variations: getBlockVariations(state, blockType.name) 506 }; 507 }); 508 }, state => [state.blockTypes, state.blockVariations]); 509 /** 510 * Returns a block type by name. 511 * 512 * @param {Object} state Data state. 513 * @param {string} name Block type name. 514 * 515 * @return {Object?} Block Type. 516 */ 517 518 function getBlockType(state, name) { 519 return state.blockTypes[name]; 520 } 521 /** 522 * Returns block styles by block name. 523 * 524 * @param {Object} state Data state. 525 * @param {string} name Block type name. 526 * 527 * @return {Array?} Block Styles. 528 */ 529 530 function getBlockStyles(state, name) { 531 return state.blockStyles[name]; 532 } 533 /** 534 * Returns block variations by block name. 535 * 536 * @param {Object} state Data state. 537 * @param {string} blockName Block type name. 538 * @param {WPBlockVariationScope} [scope] Block variation scope name. 539 * 540 * @return {(WPBlockVariation[]|void)} Block variations. 541 */ 542 543 const getBlockVariations = Object(rememo["a" /* default */])((state, blockName, scope) => { 544 const variations = state.blockVariations[blockName]; 545 546 if (!variations || !scope) { 547 return variations; 548 } 549 550 return variations.filter(variation => { 551 // For backward compatibility reasons, variation's scope defaults to 552 // `block` and `inserter` when not set. 553 return (variation.scope || ['block', 'inserter']).includes(scope); 554 }); 555 }, (state, blockName) => [state.blockVariations[blockName]]); 556 /** 557 * Returns the active block variation for a given block based on its attributes. 558 * Variations are determined by their `isActive` property. 559 * Which is either an array of block attribute keys or a function. 560 * 561 * In case of an array of block attribute keys, the `attributes` are compared 562 * to the variation's attributes using strict equality check. 563 * 564 * In case of function type, the function should accept a block's attributes 565 * and the variation's attributes and determines if a variation is active. 566 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 567 * 568 * @param {Object} state Data state. 569 * @param {string} blockName Name of block (example: “core/columns”). 570 * @param {Object} attributes Block attributes used to determine active variation. 571 * @param {WPBlockVariationScope} [scope] Block variation scope name. 572 * 573 * @return {(WPBlockVariation|undefined)} Active block variation. 574 */ 575 576 function getActiveBlockVariation(state, blockName, attributes, scope) { 577 const variations = getBlockVariations(state, blockName, scope); 578 const match = variations === null || variations === void 0 ? void 0 : variations.find(variation => { 579 var _variation$isActive; 580 581 if (Array.isArray(variation.isActive)) { 582 const blockType = getBlockType(state, blockName); 583 const attributeKeys = Object.keys(blockType.attributes || {}); 584 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute)); 585 586 if (definedAttributes.length === 0) { 587 return false; 588 } 589 590 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]); 591 } 592 593 return (_variation$isActive = variation.isActive) === null || _variation$isActive === void 0 ? void 0 : _variation$isActive.call(variation, attributes, variation.attributes); 594 }); 595 return match; 596 } 597 /** 598 * Returns the default block variation for the given block type. 599 * When there are multiple variations annotated as the default one, 600 * the last added item is picked. This simplifies registering overrides. 601 * When there is no default variation set, it returns the first item. 602 * 603 * @param {Object} state Data state. 604 * @param {string} blockName Block type name. 605 * @param {WPBlockVariationScope} [scope] Block variation scope name. 606 * 607 * @return {?WPBlockVariation} The default block variation. 608 */ 609 610 function getDefaultBlockVariation(state, blockName, scope) { 611 const variations = getBlockVariations(state, blockName, scope); 612 return Object(external_lodash_["findLast"])(variations, 'isDefault') || Object(external_lodash_["first"])(variations); 613 } 614 /** 615 * Returns all the available categories. 616 * 617 * @param {Object} state Data state. 618 * 619 * @return {WPBlockCategory[]} Categories list. 620 */ 621 622 function getCategories(state) { 623 return state.categories; 624 } 625 /** 626 * Returns all the available collections. 627 * 628 * @param {Object} state Data state. 629 * 630 * @return {Object} Collections list. 631 */ 632 633 function getCollections(state) { 634 return state.collections; 635 } 636 /** 637 * Returns the name of the default block name. 638 * 639 * @param {Object} state Data state. 640 * 641 * @return {string?} Default block name. 642 */ 643 644 function getDefaultBlockName(state) { 645 return state.defaultBlockName; 646 } 647 /** 648 * Returns the name of the block for handling non-block content. 649 * 650 * @param {Object} state Data state. 651 * 652 * @return {string?} Name of the block for handling non-block content. 653 */ 654 655 function getFreeformFallbackBlockName(state) { 656 return state.freeformFallbackBlockName; 657 } 658 /** 659 * Returns the name of the block for handling unregistered blocks. 660 * 661 * @param {Object} state Data state. 662 * 663 * @return {string?} Name of the block for handling unregistered blocks. 664 */ 665 666 function getUnregisteredFallbackBlockName(state) { 667 return state.unregisteredFallbackBlockName; 668 } 669 /** 670 * Returns the name of the block for handling unregistered blocks. 671 * 672 * @param {Object} state Data state. 673 * 674 * @return {string?} Name of the block for handling unregistered blocks. 675 */ 676 677 function getGroupingBlockName(state) { 678 return state.groupingBlockName; 679 } 680 /** 681 * Returns an array with the child blocks of a given block. 682 * 683 * @param {Object} state Data state. 684 * @param {string} blockName Block type name. 685 * 686 * @return {Array} Array of child block names. 687 */ 688 689 const getChildBlockNames = Object(rememo["a" /* default */])((state, blockName) => { 690 return Object(external_lodash_["map"])(Object(external_lodash_["filter"])(state.blockTypes, blockType => { 691 return Object(external_lodash_["includes"])(blockType.parent, blockName); 692 }), ({ 693 name 694 }) => name); 695 }, state => [state.blockTypes]); 696 /** 697 * Returns the block support value for a feature, if defined. 698 * 699 * @param {Object} state Data state. 700 * @param {(string|Object)} nameOrType Block name or type object 701 * @param {string} feature Feature to retrieve 702 * @param {*} defaultSupports Default value to return if not 703 * explicitly defined 704 * 705 * @return {?*} Block support value 706 */ 707 708 const getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 709 const blockType = getNormalizedBlockType(state, nameOrType); 710 return Object(external_lodash_["get"])(blockType, ['supports', ...feature.split('.')], defaultSupports); 711 }; 712 /** 713 * Returns true if the block defines support for a feature, or false otherwise. 714 * 715 * @param {Object} state Data state. 716 * @param {(string|Object)} nameOrType Block name or type object. 717 * @param {string} feature Feature to test. 718 * @param {boolean} defaultSupports Whether feature is supported by 719 * default if not explicitly defined. 720 * 721 * @return {boolean} Whether block supports feature. 722 */ 723 724 function hasBlockSupport(state, nameOrType, feature, defaultSupports) { 725 return !!getBlockSupport(state, nameOrType, feature, defaultSupports); 726 } 727 /** 728 * Returns true if the block type by the given name or object value matches a 729 * search term, or false otherwise. 730 * 731 * @param {Object} state Blocks state. 732 * @param {(string|Object)} nameOrType Block name or type object. 733 * @param {string} searchTerm Search term by which to filter. 734 * 735 * @return {Object[]} Whether block type matches search term. 736 */ 737 738 function isMatchingSearchTerm(state, nameOrType, searchTerm) { 739 const blockType = getNormalizedBlockType(state, nameOrType); 740 const getNormalizedSearchTerm = Object(external_lodash_["flow"])([// Disregard diacritics. 741 // Input: "média" 742 external_lodash_["deburr"], // Lowercase. 743 // Input: "MEDIA" 744 term => term.toLowerCase(), // Strip leading and trailing whitespace. 745 // Input: " media " 746 term => term.trim()]); 747 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 748 const isSearchMatch = Object(external_lodash_["flow"])([getNormalizedSearchTerm, normalizedCandidate => Object(external_lodash_["includes"])(normalizedCandidate, normalizedSearchTerm)]); 749 return isSearchMatch(blockType.title) || Object(external_lodash_["some"])(blockType.keywords, isSearchMatch) || isSearchMatch(blockType.category); 750 } 751 /** 752 * Returns a boolean indicating if a block has child blocks or not. 753 * 754 * @param {Object} state Data state. 755 * @param {string} blockName Block type name. 756 * 757 * @return {boolean} True if a block contains child blocks and false otherwise. 758 */ 759 760 const hasChildBlocks = (state, blockName) => { 761 return getChildBlockNames(state, blockName).length > 0; 762 }; 763 /** 764 * Returns a boolean indicating if a block has at least one child block with inserter support. 765 * 766 * @param {Object} state Data state. 767 * @param {string} blockName Block type name. 768 * 769 * @return {boolean} True if a block contains at least one child blocks with inserter support 770 * and false otherwise. 771 */ 772 773 const hasChildBlocksWithInserterSupport = (state, blockName) => { 774 return Object(external_lodash_["some"])(getChildBlockNames(state, blockName), childBlockName => { 775 return hasBlockSupport(state, childBlockName, 'inserter', true); 776 }); 777 }; 778 779 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/actions.js 780 /** 781 * External dependencies 782 */ 783 784 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 785 786 /** 787 * Returns an action object used in signalling that block types have been added. 788 * 789 * @param {Array|Object} blockTypes Block types received. 790 * 791 * @return {Object} Action object. 792 */ 793 794 function addBlockTypes(blockTypes) { 795 return { 796 type: 'ADD_BLOCK_TYPES', 797 blockTypes: Object(external_lodash_["castArray"])(blockTypes) 798 }; 799 } 800 /** 801 * Returns an action object used to remove a registered block type. 802 * 803 * @param {string|Array} names Block name. 804 * 805 * @return {Object} Action object. 806 */ 807 808 function removeBlockTypes(names) { 809 return { 810 type: 'REMOVE_BLOCK_TYPES', 811 names: Object(external_lodash_["castArray"])(names) 812 }; 813 } 814 /** 815 * Returns an action object used in signalling that new block styles have been added. 816 * 817 * @param {string} blockName Block name. 818 * @param {Array|Object} styles Block styles. 819 * 820 * @return {Object} Action object. 821 */ 822 823 function addBlockStyles(blockName, styles) { 824 return { 825 type: 'ADD_BLOCK_STYLES', 826 styles: Object(external_lodash_["castArray"])(styles), 827 blockName 828 }; 829 } 830 /** 831 * Returns an action object used in signalling that block styles have been removed. 832 * 833 * @param {string} blockName Block name. 834 * @param {Array|string} styleNames Block style names. 835 * 836 * @return {Object} Action object. 837 */ 838 839 function removeBlockStyles(blockName, styleNames) { 840 return { 841 type: 'REMOVE_BLOCK_STYLES', 842 styleNames: Object(external_lodash_["castArray"])(styleNames), 843 blockName 844 }; 845 } 846 /** 847 * Returns an action object used in signalling that new block variations have been added. 848 * 849 * @param {string} blockName Block name. 850 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 851 * 852 * @return {Object} Action object. 853 */ 854 855 function addBlockVariations(blockName, variations) { 856 return { 857 type: 'ADD_BLOCK_VARIATIONS', 858 variations: Object(external_lodash_["castArray"])(variations), 859 blockName 860 }; 861 } 862 /** 863 * Returns an action object used in signalling that block variations have been removed. 864 * 865 * @param {string} blockName Block name. 866 * @param {string|string[]} variationNames Block variation names. 867 * 868 * @return {Object} Action object. 869 */ 870 871 function removeBlockVariations(blockName, variationNames) { 872 return { 873 type: 'REMOVE_BLOCK_VARIATIONS', 874 variationNames: Object(external_lodash_["castArray"])(variationNames), 875 blockName 876 }; 877 } 878 /** 879 * Returns an action object used to set the default block name. 880 * 881 * @param {string} name Block name. 882 * 883 * @return {Object} Action object. 884 */ 885 886 function setDefaultBlockName(name) { 887 return { 888 type: 'SET_DEFAULT_BLOCK_NAME', 889 name 890 }; 891 } 892 /** 893 * Returns an action object used to set the name of the block used as a fallback 894 * for non-block content. 895 * 896 * @param {string} name Block name. 897 * 898 * @return {Object} Action object. 899 */ 900 901 function setFreeformFallbackBlockName(name) { 902 return { 903 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 904 name 905 }; 906 } 907 /** 908 * Returns an action object used to set the name of the block used as a fallback 909 * for unregistered blocks. 910 * 911 * @param {string} name Block name. 912 * 913 * @return {Object} Action object. 914 */ 915 916 function setUnregisteredFallbackBlockName(name) { 917 return { 918 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 919 name 920 }; 921 } 922 /** 923 * Returns an action object used to set the name of the block used 924 * when grouping other blocks 925 * eg: in "Group/Ungroup" interactions 926 * 927 * @param {string} name Block name. 928 * 929 * @return {Object} Action object. 930 */ 931 932 function setGroupingBlockName(name) { 933 return { 934 type: 'SET_GROUPING_BLOCK_NAME', 935 name 936 }; 937 } 938 /** 939 * Returns an action object used to set block categories. 940 * 941 * @param {Object[]} categories Block categories. 942 * 943 * @return {Object} Action object. 944 */ 945 946 function setCategories(categories) { 947 return { 948 type: 'SET_CATEGORIES', 949 categories 950 }; 951 } 952 /** 953 * Returns an action object used to update a category. 954 * 955 * @param {string} slug Block category slug. 956 * @param {Object} category Object containing the category properties that should be updated. 957 * 958 * @return {Object} Action object. 959 */ 960 961 function updateCategory(slug, category) { 962 return { 963 type: 'UPDATE_CATEGORY', 964 slug, 965 category 966 }; 967 } 968 /** 969 * Returns an action object used to add block collections 970 * 971 * @param {string} namespace The namespace of the blocks to put in the collection 972 * @param {string} title The title to display in the block inserter 973 * @param {Object} icon (optional) The icon to display in the block inserter 974 * 975 * @return {Object} Action object. 976 */ 977 978 function addBlockCollection(namespace, title, icon) { 979 return { 980 type: 'ADD_BLOCK_COLLECTION', 981 namespace, 982 title, 983 icon 984 }; 985 } 986 /** 987 * Returns an action object used to remove block collections 988 * 989 * @param {string} namespace The namespace of the blocks to put in the collection 990 * 991 * @return {Object} Action object. 992 */ 993 994 function removeBlockCollection(namespace) { 995 return { 996 type: 'REMOVE_BLOCK_COLLECTION', 997 namespace 998 }; 999 } 1000 1001 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/constants.js 1002 const STORE_NAME = 'core/blocks'; 1003 1004 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/index.js 1005 /** 1006 * WordPress dependencies 1007 */ 1008 1009 /** 1010 * Internal dependencies 1011 */ 1012 1013 1014 1015 1016 1017 /** 1018 * Store definition for the blocks namespace. 1019 * 1020 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 1021 * 1022 * @type {Object} 1023 */ 1024 1025 const store = Object(external_wp_data_["createReduxStore"])(STORE_NAME, { 1026 reducer: reducer, 1027 selectors: selectors_namespaceObject, 1028 actions: actions_namespaceObject 1029 }); 1030 Object(external_wp_data_["register"])(store); 1031 1032 // EXTERNAL MODULE: ./node_modules/uuid/dist/esm-browser/v4.js + 4 modules 1033 var v4 = __webpack_require__("7Cbv"); 1034 1035 // EXTERNAL MODULE: external ["wp","hooks"] 1036 var external_wp_hooks_ = __webpack_require__("g56x"); 1037 1038 // EXTERNAL MODULE: external ["wp","deprecated"] 1039 var external_wp_deprecated_ = __webpack_require__("NMb1"); 1040 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_); 1041 1042 // EXTERNAL MODULE: ./node_modules/@wordpress/icons/build-module/library/block-default.js 1043 var block_default = __webpack_require__("//Lo"); 1044 1045 // EXTERNAL MODULE: ./node_modules/tinycolor2/tinycolor.js 1046 var tinycolor = __webpack_require__("Zss7"); 1047 var tinycolor_default = /*#__PURE__*/__webpack_require__.n(tinycolor); 1048 1049 // EXTERNAL MODULE: external ["wp","element"] 1050 var external_wp_element_ = __webpack_require__("GRId"); 1051 1052 // EXTERNAL MODULE: external ["wp","dom"] 1053 var external_wp_dom_ = __webpack_require__("1CF3"); 1054 1055 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/utils.js 1056 /** 1057 * External dependencies 1058 */ 1059 1060 1061 /** 1062 * WordPress dependencies 1063 */ 1064 1065 1066 1067 1068 /** 1069 * Internal dependencies 1070 */ 1071 1072 1073 1074 /** 1075 * Array of icon colors containing a color to be used if the icon color 1076 * was not explicitly set but the icon background color was. 1077 * 1078 * @type {Object} 1079 */ 1080 1081 const ICON_COLORS = ['#191e23', '#f8f9f9']; 1082 /** 1083 * Determines whether the block is a default block 1084 * and its attributes are equal to the default attributes 1085 * which means the block is unmodified. 1086 * 1087 * @param {WPBlock} block Block Object 1088 * 1089 * @return {boolean} Whether the block is an unmodified default block 1090 */ 1091 1092 function isUnmodifiedDefaultBlock(block) { 1093 const defaultBlockName = registration_getDefaultBlockName(); 1094 1095 if (block.name !== defaultBlockName) { 1096 return false; 1097 } // Cache a created default block if no cache exists or the default block 1098 // name changed. 1099 1100 1101 if (!isUnmodifiedDefaultBlock.block || isUnmodifiedDefaultBlock.block.name !== defaultBlockName) { 1102 isUnmodifiedDefaultBlock.block = createBlock(defaultBlockName); 1103 } 1104 1105 const newDefaultBlock = isUnmodifiedDefaultBlock.block; 1106 const blockType = registration_getBlockType(defaultBlockName); 1107 return Object(external_lodash_["every"])(blockType.attributes, (value, key) => newDefaultBlock.attributes[key] === block.attributes[key]); 1108 } 1109 /** 1110 * Function that checks if the parameter is a valid icon. 1111 * 1112 * @param {*} icon Parameter to be checked. 1113 * 1114 * @return {boolean} True if the parameter is a valid icon and false otherwise. 1115 */ 1116 1117 function isValidIcon(icon) { 1118 return !!icon && (Object(external_lodash_["isString"])(icon) || Object(external_wp_element_["isValidElement"])(icon) || Object(external_lodash_["isFunction"])(icon) || icon instanceof external_wp_element_["Component"]); 1119 } 1120 /** 1121 * Function that receives an icon as set by the blocks during the registration 1122 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 1123 * in the codebase. 1124 * 1125 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 1126 * one of a Dashicon slug, an element, or a 1127 * component. 1128 * 1129 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 1130 */ 1131 1132 function normalizeIconObject(icon) { 1133 if (isValidIcon(icon)) { 1134 return { 1135 src: icon 1136 }; 1137 } 1138 1139 if (Object(external_lodash_["has"])(icon, ['background'])) { 1140 const tinyBgColor = tinycolor_default()(icon.background); 1141 return { ...icon, 1142 foreground: icon.foreground ? icon.foreground : Object(tinycolor["mostReadable"])(tinyBgColor, ICON_COLORS, { 1143 includeFallbackColors: true, 1144 level: 'AA', 1145 size: 'large' 1146 }).toHexString(), 1147 shadowColor: tinyBgColor.setAlpha(0.3).toRgbString() 1148 }; 1149 } 1150 1151 return icon; 1152 } 1153 /** 1154 * Normalizes block type passed as param. When string is passed then 1155 * it converts it to the matching block type object. 1156 * It passes the original object otherwise. 1157 * 1158 * @param {string|Object} blockTypeOrName Block type or name. 1159 * 1160 * @return {?Object} Block type. 1161 */ 1162 1163 function normalizeBlockType(blockTypeOrName) { 1164 if (Object(external_lodash_["isString"])(blockTypeOrName)) { 1165 return registration_getBlockType(blockTypeOrName); 1166 } 1167 1168 return blockTypeOrName; 1169 } 1170 /** 1171 * Get the label for the block, usually this is either the block title, 1172 * or the value of the block's `label` function when that's specified. 1173 * 1174 * @param {Object} blockType The block type. 1175 * @param {Object} attributes The values of the block's attributes. 1176 * @param {Object} context The intended use for the label. 1177 * 1178 * @return {string} The block label. 1179 */ 1180 1181 function getBlockLabel(blockType, attributes, context = 'visual') { 1182 const { 1183 __experimentalLabel: getLabel, 1184 title 1185 } = blockType; 1186 const label = getLabel && getLabel(attributes, { 1187 context 1188 }); 1189 1190 if (!label) { 1191 return title; 1192 } // Strip any HTML (i.e. RichText formatting) before returning. 1193 1194 1195 return Object(external_wp_dom_["__unstableStripHTML"])(label); 1196 } 1197 /** 1198 * Get a label for the block for use by screenreaders, this is more descriptive 1199 * than the visual label and includes the block title and the value of the 1200 * `getLabel` function if it's specified. 1201 * 1202 * @param {Object} blockType The block type. 1203 * @param {Object} attributes The values of the block's attributes. 1204 * @param {?number} position The position of the block in the block list. 1205 * @param {string} [direction='vertical'] The direction of the block layout. 1206 * 1207 * @return {string} The block label. 1208 */ 1209 1210 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') { 1211 // `title` is already localized, `label` is a user-supplied value. 1212 const { 1213 title 1214 } = blockType; 1215 const label = getBlockLabel(blockType, attributes, 'accessibility'); 1216 const hasPosition = position !== undefined; // getBlockLabel returns the block title as a fallback when there's no label, 1217 // if it did return the title, this function needs to avoid adding the 1218 // title twice within the accessible label. Use this `hasLabel` boolean to 1219 // handle that. 1220 1221 const hasLabel = label && label !== title; 1222 1223 if (hasPosition && direction === 'vertical') { 1224 if (hasLabel) { 1225 return Object(external_wp_i18n_["sprintf"])( 1226 /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 1227 Object(external_wp_i18n_["__"])('%1$s Block. Row %2$d. %3$s'), title, position, label); 1228 } 1229 1230 return Object(external_wp_i18n_["sprintf"])( 1231 /* translators: accessibility text. 1: The block title. 2: The block row number. */ 1232 Object(external_wp_i18n_["__"])('%1$s Block. Row %2$d'), title, position); 1233 } else if (hasPosition && direction === 'horizontal') { 1234 if (hasLabel) { 1235 return Object(external_wp_i18n_["sprintf"])( 1236 /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 1237 Object(external_wp_i18n_["__"])('%1$s Block. Column %2$d. %3$s'), title, position, label); 1238 } 1239 1240 return Object(external_wp_i18n_["sprintf"])( 1241 /* translators: accessibility text. 1: The block title. 2: The block column number. */ 1242 Object(external_wp_i18n_["__"])('%1$s Block. Column %2$d'), title, position); 1243 } 1244 1245 if (hasLabel) { 1246 return Object(external_wp_i18n_["sprintf"])( 1247 /* translators: accessibility text. %1: The block title. %2: The block label. */ 1248 Object(external_wp_i18n_["__"])('%1$s Block. %2$s'), title, label); 1249 } 1250 1251 return Object(external_wp_i18n_["sprintf"])( 1252 /* translators: accessibility text. %s: The block title. */ 1253 Object(external_wp_i18n_["__"])('%s Block'), title); 1254 } 1255 /** 1256 * Ensure attributes contains only values defined by block type, and merge 1257 * default values for missing attributes. 1258 * 1259 * @param {string} name The block's name. 1260 * @param {Object} attributes The block's attributes. 1261 * @return {Object} The sanitized attributes. 1262 */ 1263 1264 function __experimentalSanitizeBlockAttributes(name, attributes) { 1265 // Get the type definition associated with a registered block. 1266 const blockType = registration_getBlockType(name); 1267 1268 if (undefined === blockType) { 1269 throw new Error(`Block type '${name}' is not registered.`); 1270 } 1271 1272 return Object(external_lodash_["reduce"])(blockType.attributes, (accumulator, schema, key) => { 1273 const value = attributes[key]; 1274 1275 if (undefined !== value) { 1276 accumulator[key] = value; 1277 } else if (schema.hasOwnProperty('default')) { 1278 accumulator[key] = schema.default; 1279 } 1280 1281 if (['node', 'children'].indexOf(schema.source) !== -1) { 1282 // Ensure value passed is always an array, which we're expecting in 1283 // the RichText component to handle the deprecated value. 1284 if (typeof accumulator[key] === 'string') { 1285 accumulator[key] = [accumulator[key]]; 1286 } else if (!Array.isArray(accumulator[key])) { 1287 accumulator[key] = []; 1288 } 1289 } 1290 1291 return accumulator; 1292 }, {}); 1293 } 1294 /** 1295 * Filter block attributes by `role` and return their names. 1296 * 1297 * @param {string} name Block attribute's name. 1298 * @param {string} role The role of a block attribute. 1299 * 1300 * @return {string[]} The attribute names that have the provided role. 1301 */ 1302 1303 function __experimentalGetBlockAttributesNamesByRole(name, role) { 1304 var _getBlockType; 1305 1306 const attributes = (_getBlockType = registration_getBlockType(name)) === null || _getBlockType === void 0 ? void 0 : _getBlockType.attributes; 1307 if (!attributes) return []; 1308 const attributesNames = Object.keys(attributes); 1309 if (!role) return attributesNames; 1310 return attributesNames.filter(attributeName => { 1311 var _attributes$attribute; 1312 1313 return ((_attributes$attribute = attributes[attributeName]) === null || _attributes$attribute === void 0 ? void 0 : _attributes$attribute.__experimentalRole) === role; 1314 }); 1315 } 1316 1317 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/constants.js 1318 /** 1319 * Array of valid keys in a block type settings deprecation object. 1320 * 1321 * @type {string[]} 1322 */ 1323 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 1324 const __EXPERIMENTAL_STYLE_PROPERTY = { 1325 //kept for back-compatibility purposes. 1326 '--wp--style--color--link': { 1327 value: ['color', 'link'], 1328 support: ['color', 'link'] 1329 }, 1330 background: { 1331 value: ['color', 'gradient'], 1332 support: ['color', 'gradients'] 1333 }, 1334 backgroundColor: { 1335 value: ['color', 'background'], 1336 support: ['color'] 1337 }, 1338 borderColor: { 1339 value: ['border', 'color'], 1340 support: ['__experimentalBorder', 'color'] 1341 }, 1342 borderRadius: { 1343 value: ['border', 'radius'], 1344 support: ['__experimentalBorder', 'radius'] 1345 }, 1346 borderStyle: { 1347 value: ['border', 'style'], 1348 support: ['__experimentalBorder', 'style'] 1349 }, 1350 borderWidth: { 1351 value: ['border', 'width'], 1352 support: ['__experimentalBorder', 'width'] 1353 }, 1354 color: { 1355 value: ['color', 'text'], 1356 support: ['color'] 1357 }, 1358 linkColor: { 1359 value: ['elements', 'link', 'color', 'text'], 1360 support: ['color', 'link'] 1361 }, 1362 fontFamily: { 1363 value: ['typography', 'fontFamily'], 1364 support: ['typography', '__experimentalFontFamily'] 1365 }, 1366 fontSize: { 1367 value: ['typography', 'fontSize'], 1368 support: ['typography', 'fontSize'] 1369 }, 1370 fontStyle: { 1371 value: ['typography', 'fontStyle'], 1372 support: ['typography', '__experimentalFontStyle'] 1373 }, 1374 fontWeight: { 1375 value: ['typography', 'fontWeight'], 1376 support: ['typography', '__experimentalFontWeight'] 1377 }, 1378 lineHeight: { 1379 value: ['typography', 'lineHeight'], 1380 support: ['typography', 'lineHeight'] 1381 }, 1382 margin: { 1383 value: ['spacing', 'margin'], 1384 support: ['spacing', 'margin'], 1385 properties: ['top', 'right', 'bottom', 'left'] 1386 }, 1387 padding: { 1388 value: ['spacing', 'padding'], 1389 support: ['spacing', 'padding'], 1390 properties: ['top', 'right', 'bottom', 'left'] 1391 }, 1392 textDecoration: { 1393 value: ['typography', 'textDecoration'], 1394 support: ['typography', '__experimentalTextDecoration'] 1395 }, 1396 textTransform: { 1397 value: ['typography', 'textTransform'], 1398 support: ['typography', '__experimentalTextTransform'] 1399 } 1400 }; 1401 const __EXPERIMENTAL_ELEMENTS = { 1402 link: 'a', 1403 h1: 'h1', 1404 h2: 'h2', 1405 h3: 'h3', 1406 h4: 'h4', 1407 h5: 'h5', 1408 h6: 'h6' 1409 }; 1410 1411 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/registration.js 1412 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ 1413 1414 /** 1415 * External dependencies 1416 */ 1417 1418 /** 1419 * WordPress dependencies 1420 */ 1421 1422 1423 1424 1425 1426 1427 /** 1428 * Internal dependencies 1429 */ 1430 1431 const i18nBlockSchema = { 1432 title: "block title", 1433 description: "block description", 1434 keywords: ["block keyword"], 1435 styles: [{ 1436 label: "block style label" 1437 }], 1438 variations: [{ 1439 title: "block variation title", 1440 description: "block variation description", 1441 keywords: ["block variation keyword"] 1442 }] 1443 }; 1444 1445 1446 1447 /** 1448 * An icon type definition. One of a Dashicon slug, an element, 1449 * or a component. 1450 * 1451 * @typedef {(string|WPElement|WPComponent)} WPIcon 1452 * 1453 * @see https://developer.wordpress.org/resource/dashicons/ 1454 */ 1455 1456 /** 1457 * Render behavior of a block type icon; one of a Dashicon slug, an element, 1458 * or a component. 1459 * 1460 * @typedef {WPIcon} WPBlockTypeIconRender 1461 */ 1462 1463 /** 1464 * An object describing a normalized block type icon. 1465 * 1466 * @typedef {Object} WPBlockTypeIconDescriptor 1467 * 1468 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 1469 * one of a Dashicon slug, an 1470 * element, or a component. 1471 * @property {string} background Optimal background hex string 1472 * color when displaying icon. 1473 * @property {string} foreground Optimal foreground hex string 1474 * color when displaying icon. 1475 * @property {string} shadowColor Optimal shadow hex string 1476 * color when displaying icon. 1477 */ 1478 1479 /** 1480 * Value to use to render the icon for a block type in an editor interface, 1481 * either a Dashicon slug, an element, a component, or an object describing 1482 * the icon. 1483 * 1484 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 1485 */ 1486 1487 /** 1488 * Named block variation scopes. 1489 * 1490 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 1491 */ 1492 1493 /** 1494 * An object describing a variation defined for the block type. 1495 * 1496 * @typedef {Object} WPBlockVariation 1497 * 1498 * @property {string} name The unique and machine-readable name. 1499 * @property {string} title A human-readable variation title. 1500 * @property {string} [description] A detailed variation description. 1501 * @property {string} [category] Block type category classification, 1502 * used in search interfaces to arrange 1503 * block types by category. 1504 * @property {WPIcon} [icon] An icon helping to visualize the variation. 1505 * @property {boolean} [isDefault] Indicates whether the current variation is 1506 * the default one. Defaults to `false`. 1507 * @property {Object} [attributes] Values which override block attributes. 1508 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 1509 * @property {Object} [example] Example provides structured data for 1510 * the block preview. You can set to 1511 * `undefined` to disable the preview shown 1512 * for the block type. 1513 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 1514 * is applicable. When not provided, it 1515 * assumes all available scopes. 1516 * @property {string[]} [keywords] An array of terms (which can be translated) 1517 * that help users discover the variation 1518 * while searching. 1519 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 1520 * Function that accepts a block's attributes and the 1521 * variation's attributes and determines if a variation is active. 1522 * This function doesn't try to find a match dynamically based 1523 * on all block's attributes, as in many cases some attributes are irrelevant. 1524 * An example would be for `embed` block where we only care 1525 * about `providerNameSlug` attribute's value. 1526 * We can also use a `string[]` to tell which attributes 1527 * should be compared as a shorthand. Each attributes will 1528 * be matched and the variation will be active if all of them are matching. 1529 */ 1530 1531 /** 1532 * Defined behavior of a block type. 1533 * 1534 * @typedef {Object} WPBlock 1535 * 1536 * @property {string} name Block type's namespaced name. 1537 * @property {string} title Human-readable block type label. 1538 * @property {string} [description] A detailed block type description. 1539 * @property {string} [category] Block type category classification, 1540 * used in search interfaces to arrange 1541 * block types by category. 1542 * @property {WPBlockTypeIcon} [icon] Block type icon. 1543 * @property {string[]} [keywords] Additional keywords to produce block 1544 * type as result in search interfaces. 1545 * @property {Object} [attributes] Block type attributes. 1546 * @property {WPComponent} [save] Optional component describing 1547 * serialized markup structure of a 1548 * block type. 1549 * @property {WPComponent} edit Component rendering an element to 1550 * manipulate the attributes of a block 1551 * in the context of an editor. 1552 * @property {WPBlockVariation[]} [variations] The list of block variations. 1553 * @property {Object} [example] Example provides structured data for 1554 * the block preview. When not defined 1555 * then no preview is shown. 1556 */ 1557 1558 /** 1559 * Mapping of legacy category slugs to their latest normal values, used to 1560 * accommodate updates of the default set of block categories. 1561 * 1562 * @type {Record<string,string>} 1563 */ 1564 1565 const LEGACY_CATEGORY_MAPPING = { 1566 common: 'text', 1567 formatting: 'text', 1568 layout: 'design' 1569 }; 1570 const serverSideBlockDefinitions = {}; 1571 /** 1572 * Sets the server side block definition of blocks. 1573 * 1574 * @param {Object} definitions Server-side block definitions 1575 */ 1576 // eslint-disable-next-line camelcase 1577 1578 function unstable__bootstrapServerSideBlockDefinitions(definitions) { 1579 for (const blockName of Object.keys(definitions)) { 1580 // Don't overwrite if already set. It covers the case when metadata 1581 // was initialized from the server. 1582 if (serverSideBlockDefinitions[blockName]) { 1583 // We still need to polyfill `apiVersion` for WordPress version 1584 // lower than 5.7. If it isn't present in the definition shared 1585 // from the server, we try to fallback to the definition passed. 1586 // @see https://github.com/WordPress/gutenberg/pull/29279 1587 if (serverSideBlockDefinitions[blockName].apiVersion === undefined && definitions[blockName].apiVersion) { 1588 serverSideBlockDefinitions[blockName].apiVersion = definitions[blockName].apiVersion; 1589 } 1590 1591 continue; 1592 } 1593 1594 serverSideBlockDefinitions[blockName] = Object(external_lodash_["mapKeys"])(Object(external_lodash_["pickBy"])(definitions[blockName], value => !Object(external_lodash_["isNil"])(value)), (value, key) => Object(external_lodash_["camelCase"])(key)); 1595 } 1596 } 1597 /** 1598 * Gets block settings from metadata loaded from `block.json` file. 1599 * 1600 * @param {Object} metadata Block metadata loaded from `block.json`. 1601 * @param {string} metadata.textdomain Textdomain to use with translations. 1602 * 1603 * @return {Object} Block settings. 1604 */ 1605 1606 function getBlockSettingsFromMetadata({ 1607 textdomain, 1608 ...metadata 1609 }) { 1610 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'supports', 'styles', 'example', 'variations']; 1611 const settings = Object(external_lodash_["pick"])(metadata, allowedFields); 1612 1613 if (textdomain) { 1614 Object.keys(i18nBlockSchema).forEach(key => { 1615 if (!settings[key]) { 1616 return; 1617 } 1618 1619 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 1620 }); 1621 } 1622 1623 return settings; 1624 } 1625 /** 1626 * Registers a new block provided a unique name and an object defining its 1627 * behavior. Once registered, the block is made available as an option to any 1628 * editor interface where blocks are implemented. 1629 * 1630 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 1631 * @param {Object} settings Block settings. 1632 * 1633 * @return {?WPBlock} The block, if it has been successfully registered; 1634 * otherwise `undefined`. 1635 */ 1636 1637 1638 function registerBlockType(blockNameOrMetadata, settings) { 1639 const name = Object(external_lodash_["isObject"])(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 1640 1641 if (typeof name !== 'string') { 1642 console.error('Block names must be strings.'); 1643 return; 1644 } 1645 1646 if (Object(external_lodash_["isObject"])(blockNameOrMetadata)) { 1647 unstable__bootstrapServerSideBlockDefinitions({ 1648 [name]: getBlockSettingsFromMetadata(blockNameOrMetadata) 1649 }); 1650 } 1651 1652 settings = { 1653 name, 1654 icon: block_default["a" /* default */], 1655 keywords: [], 1656 attributes: {}, 1657 providesContext: {}, 1658 usesContext: [], 1659 supports: {}, 1660 styles: [], 1661 save: () => null, 1662 ...(serverSideBlockDefinitions === null || serverSideBlockDefinitions === void 0 ? void 0 : serverSideBlockDefinitions[name]), 1663 ...settings 1664 }; 1665 1666 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 1667 console.error('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block'); 1668 return; 1669 } 1670 1671 if (Object(external_wp_data_["select"])(store).getBlockType(name)) { 1672 console.error('Block "' + name + '" is already registered.'); 1673 return; 1674 } 1675 1676 const preFilterSettings = { ...settings 1677 }; 1678 settings = Object(external_wp_hooks_["applyFilters"])('blocks.registerBlockType', settings, name); 1679 1680 if (settings.deprecated) { 1681 settings.deprecated = settings.deprecated.map(deprecation => Object(external_lodash_["pick"])( // Only keep valid deprecation keys. 1682 Object(external_wp_hooks_["applyFilters"])('blocks.registerBlockType', // Merge deprecation keys with pre-filter settings 1683 // so that filters that depend on specific keys being 1684 // present don't fail. 1685 { // Omit deprecation keys here so that deprecations 1686 // can opt out of specific keys like "supports". 1687 ...Object(external_lodash_["omit"])(preFilterSettings, DEPRECATED_ENTRY_KEYS), 1688 ...deprecation 1689 }, name), DEPRECATED_ENTRY_KEYS)); 1690 } 1691 1692 if (!Object(external_lodash_["isPlainObject"])(settings)) { 1693 console.error('Block settings must be a valid object.'); 1694 return; 1695 } 1696 1697 if (!Object(external_lodash_["isFunction"])(settings.save)) { 1698 console.error('The "save" property must be a valid function.'); 1699 return; 1700 } 1701 1702 if ('edit' in settings && !Object(external_lodash_["isFunction"])(settings.edit)) { 1703 console.error('The "edit" property must be a valid function.'); 1704 return; 1705 } // Canonicalize legacy categories to equivalent fallback. 1706 1707 1708 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 1709 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 1710 } 1711 1712 if ('category' in settings && !Object(external_lodash_["some"])(Object(external_wp_data_["select"])(store).getCategories(), { 1713 slug: settings.category 1714 })) { 1715 console.warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".'); 1716 delete settings.category; 1717 } 1718 1719 if (!('title' in settings) || settings.title === '') { 1720 console.error('The block "' + name + '" must have a title.'); 1721 return; 1722 } 1723 1724 if (typeof settings.title !== 'string') { 1725 console.error('Block titles must be strings.'); 1726 return; 1727 } 1728 1729 settings.icon = normalizeIconObject(settings.icon); 1730 1731 if (!isValidIcon(settings.icon.src)) { 1732 console.error('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional'); 1733 return; 1734 } 1735 1736 Object(external_wp_data_["dispatch"])(store).addBlockTypes(settings); 1737 return settings; 1738 } 1739 /** 1740 * Translates block settings provided with metadata using the i18n schema. 1741 * 1742 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 1743 * @param {string|string[]|Object[]} settingValue Value for the block setting. 1744 * @param {string} textdomain Textdomain to use with translations. 1745 * 1746 * @return {string|string[]|Object[]} Translated setting. 1747 */ 1748 1749 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 1750 if (Object(external_lodash_["isString"])(i18nSchema) && Object(external_lodash_["isString"])(settingValue)) { 1751 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 1752 return Object(external_wp_i18n_["_x"])(settingValue, i18nSchema, textdomain); 1753 } 1754 1755 if (Object(external_lodash_["isArray"])(i18nSchema) && !Object(external_lodash_["isEmpty"])(i18nSchema) && Object(external_lodash_["isArray"])(settingValue)) { 1756 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 1757 } 1758 1759 if (Object(external_lodash_["isObject"])(i18nSchema) && !Object(external_lodash_["isEmpty"])(i18nSchema) && Object(external_lodash_["isObject"])(settingValue)) { 1760 return Object.keys(settingValue).reduce((accumulator, key) => { 1761 if (!i18nSchema[key]) { 1762 accumulator[key] = settingValue[key]; 1763 return accumulator; 1764 } 1765 1766 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 1767 return accumulator; 1768 }, {}); 1769 } 1770 1771 return settingValue; 1772 } 1773 /** 1774 * Registers a new block provided from metadata stored in `block.json` file. 1775 * 1776 * @deprecated Use `registerBlockType` instead. 1777 * 1778 * @param {Object} metadata Block metadata loaded from `block.json`. 1779 * @param {Object} additionalSettings Additional block settings. 1780 * 1781 * @return {?WPBlock} The block, if it has been successfully registered; 1782 * otherwise `undefined`. 1783 */ 1784 1785 1786 function registerBlockTypeFromMetadata(metadata, additionalSettings) { 1787 external_wp_deprecated_default()('wp.blocks.registerBlockTypeFromMetadata', { 1788 since: '10.7', 1789 plugin: 'Gutenberg', 1790 alternative: 'wp.blocks.registerBlockType', 1791 version: '11.0' 1792 }); 1793 return registerBlockType(metadata, additionalSettings); 1794 } 1795 /** 1796 * Registers a new block collection to group blocks in the same namespace in the inserter. 1797 * 1798 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 1799 * @param {Object} settings The block collection settings. 1800 * @param {string} settings.title The title to display in the block inserter. 1801 * @param {Object} [settings.icon] The icon to display in the block inserter. 1802 */ 1803 1804 function registerBlockCollection(namespace, { 1805 title, 1806 icon 1807 }) { 1808 Object(external_wp_data_["dispatch"])(store).addBlockCollection(namespace, title, icon); 1809 } 1810 /** 1811 * Unregisters a block collection 1812 * 1813 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 1814 * 1815 */ 1816 1817 function unregisterBlockCollection(namespace) { 1818 Object(external_wp_data_["dispatch"])(store).removeBlockCollection(namespace); 1819 } 1820 /** 1821 * Unregisters a block. 1822 * 1823 * @param {string} name Block name. 1824 * 1825 * @return {?WPBlock} The previous block value, if it has been successfully 1826 * unregistered; otherwise `undefined`. 1827 */ 1828 1829 function unregisterBlockType(name) { 1830 const oldBlock = Object(external_wp_data_["select"])(store).getBlockType(name); 1831 1832 if (!oldBlock) { 1833 console.error('Block "' + name + '" is not registered.'); 1834 return; 1835 } 1836 1837 Object(external_wp_data_["dispatch"])(store).removeBlockTypes(name); 1838 return oldBlock; 1839 } 1840 /** 1841 * Assigns name of block for handling non-block content. 1842 * 1843 * @param {string} blockName Block name. 1844 */ 1845 1846 function setFreeformContentHandlerName(blockName) { 1847 Object(external_wp_data_["dispatch"])(store).setFreeformFallbackBlockName(blockName); 1848 } 1849 /** 1850 * Retrieves name of block handling non-block content, or undefined if no 1851 * handler has been defined. 1852 * 1853 * @return {?string} Block name. 1854 */ 1855 1856 function getFreeformContentHandlerName() { 1857 return Object(external_wp_data_["select"])(store).getFreeformFallbackBlockName(); 1858 } 1859 /** 1860 * Retrieves name of block used for handling grouping interactions. 1861 * 1862 * @return {?string} Block name. 1863 */ 1864 1865 function registration_getGroupingBlockName() { 1866 return Object(external_wp_data_["select"])(store).getGroupingBlockName(); 1867 } 1868 /** 1869 * Assigns name of block handling unregistered block types. 1870 * 1871 * @param {string} blockName Block name. 1872 */ 1873 1874 function setUnregisteredTypeHandlerName(blockName) { 1875 Object(external_wp_data_["dispatch"])(store).setUnregisteredFallbackBlockName(blockName); 1876 } 1877 /** 1878 * Retrieves name of block handling unregistered block types, or undefined if no 1879 * handler has been defined. 1880 * 1881 * @return {?string} Block name. 1882 */ 1883 1884 function getUnregisteredTypeHandlerName() { 1885 return Object(external_wp_data_["select"])(store).getUnregisteredFallbackBlockName(); 1886 } 1887 /** 1888 * Assigns the default block name. 1889 * 1890 * @param {string} name Block name. 1891 */ 1892 1893 function registration_setDefaultBlockName(name) { 1894 Object(external_wp_data_["dispatch"])(store).setDefaultBlockName(name); 1895 } 1896 /** 1897 * Assigns name of block for handling block grouping interactions. 1898 * 1899 * @param {string} name Block name. 1900 */ 1901 1902 function registration_setGroupingBlockName(name) { 1903 Object(external_wp_data_["dispatch"])(store).setGroupingBlockName(name); 1904 } 1905 /** 1906 * Retrieves the default block name. 1907 * 1908 * @return {?string} Block name. 1909 */ 1910 1911 function registration_getDefaultBlockName() { 1912 return Object(external_wp_data_["select"])(store).getDefaultBlockName(); 1913 } 1914 /** 1915 * Returns a registered block type. 1916 * 1917 * @param {string} name Block name. 1918 * 1919 * @return {?Object} Block type. 1920 */ 1921 1922 function registration_getBlockType(name) { 1923 return Object(external_wp_data_["select"])(store).getBlockType(name); 1924 } 1925 /** 1926 * Returns all registered blocks. 1927 * 1928 * @return {Array} Block settings. 1929 */ 1930 1931 function registration_getBlockTypes() { 1932 return Object(external_wp_data_["select"])(store).getBlockTypes(); 1933 } 1934 /** 1935 * Returns the block support value for a feature, if defined. 1936 * 1937 * @param {(string|Object)} nameOrType Block name or type object 1938 * @param {string} feature Feature to retrieve 1939 * @param {*} defaultSupports Default value to return if not 1940 * explicitly defined 1941 * 1942 * @return {?*} Block support value 1943 */ 1944 1945 function registration_getBlockSupport(nameOrType, feature, defaultSupports) { 1946 return Object(external_wp_data_["select"])(store).getBlockSupport(nameOrType, feature, defaultSupports); 1947 } 1948 /** 1949 * Returns true if the block defines support for a feature, or false otherwise. 1950 * 1951 * @param {(string|Object)} nameOrType Block name or type object. 1952 * @param {string} feature Feature to test. 1953 * @param {boolean} defaultSupports Whether feature is supported by 1954 * default if not explicitly defined. 1955 * 1956 * @return {boolean} Whether block supports feature. 1957 */ 1958 1959 function registration_hasBlockSupport(nameOrType, feature, defaultSupports) { 1960 return Object(external_wp_data_["select"])(store).hasBlockSupport(nameOrType, feature, defaultSupports); 1961 } 1962 /** 1963 * Determines whether or not the given block is a reusable block. This is a 1964 * special block type that is used to point to a global block stored via the 1965 * API. 1966 * 1967 * @param {Object} blockOrType Block or Block Type to test. 1968 * 1969 * @return {boolean} Whether the given block is a reusable block. 1970 */ 1971 1972 function isReusableBlock(blockOrType) { 1973 return blockOrType.name === 'core/block'; 1974 } 1975 /** 1976 * Determines whether or not the given block is a template part. This is a 1977 * special block type that allows composing a page template out of reusable 1978 * design elements. 1979 * 1980 * @param {Object} blockOrType Block or Block Type to test. 1981 * 1982 * @return {boolean} Whether the given block is a template part. 1983 */ 1984 1985 function isTemplatePart(blockOrType) { 1986 return blockOrType.name === 'core/template-part'; 1987 } 1988 /** 1989 * Returns an array with the child blocks of a given block. 1990 * 1991 * @param {string} blockName Name of block (example: “latest-posts”). 1992 * 1993 * @return {Array} Array of child block names. 1994 */ 1995 1996 const registration_getChildBlockNames = blockName => { 1997 return Object(external_wp_data_["select"])(store).getChildBlockNames(blockName); 1998 }; 1999 /** 2000 * Returns a boolean indicating if a block has child blocks or not. 2001 * 2002 * @param {string} blockName Name of block (example: “latest-posts”). 2003 * 2004 * @return {boolean} True if a block contains child blocks and false otherwise. 2005 */ 2006 2007 const registration_hasChildBlocks = blockName => { 2008 return Object(external_wp_data_["select"])(store).hasChildBlocks(blockName); 2009 }; 2010 /** 2011 * Returns a boolean indicating if a block has at least one child block with inserter support. 2012 * 2013 * @param {string} blockName Block type name. 2014 * 2015 * @return {boolean} True if a block contains at least one child blocks with inserter support 2016 * and false otherwise. 2017 */ 2018 2019 const registration_hasChildBlocksWithInserterSupport = blockName => { 2020 return Object(external_wp_data_["select"])(store).hasChildBlocksWithInserterSupport(blockName); 2021 }; 2022 /** 2023 * Registers a new block style variation for the given block. 2024 * 2025 * @param {string} blockName Name of block (example: “core/latest-posts”). 2026 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 2027 */ 2028 2029 const registerBlockStyle = (blockName, styleVariation) => { 2030 Object(external_wp_data_["dispatch"])(store).addBlockStyles(blockName, styleVariation); 2031 }; 2032 /** 2033 * Unregisters a block style variation for the given block. 2034 * 2035 * @param {string} blockName Name of block (example: “core/latest-posts”). 2036 * @param {string} styleVariationName Name of class applied to the block. 2037 */ 2038 2039 const unregisterBlockStyle = (blockName, styleVariationName) => { 2040 Object(external_wp_data_["dispatch"])(store).removeBlockStyles(blockName, styleVariationName); 2041 }; 2042 /** 2043 * Returns an array with the variations of a given block type. 2044 * 2045 * @param {string} blockName Name of block (example: “core/columns”). 2046 * @param {WPBlockVariationScope} [scope] Block variation scope name. 2047 * 2048 * @return {(WPBlockVariation[]|void)} Block variations. 2049 */ 2050 2051 const registration_getBlockVariations = (blockName, scope) => { 2052 return Object(external_wp_data_["select"])(store).getBlockVariations(blockName, scope); 2053 }; 2054 /** 2055 * Registers a new block variation for the given block type. 2056 * 2057 * @param {string} blockName Name of the block (example: “core/columns”). 2058 * @param {WPBlockVariation} variation Object describing a block variation. 2059 */ 2060 2061 const registerBlockVariation = (blockName, variation) => { 2062 Object(external_wp_data_["dispatch"])(store).addBlockVariations(blockName, variation); 2063 }; 2064 /** 2065 * Unregisters a block variation defined for the given block type. 2066 * 2067 * @param {string} blockName Name of the block (example: “core/columns”). 2068 * @param {string} variationName Name of the variation defined for the block. 2069 */ 2070 2071 const unregisterBlockVariation = (blockName, variationName) => { 2072 Object(external_wp_data_["dispatch"])(store).removeBlockVariations(blockName, variationName); 2073 }; 2074 2075 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/factory.js 2076 /** 2077 * External dependencies 2078 */ 2079 2080 2081 /** 2082 * WordPress dependencies 2083 */ 2084 2085 2086 /** 2087 * Internal dependencies 2088 */ 2089 2090 2091 2092 /** 2093 * Returns a block object given its type and attributes. 2094 * 2095 * @param {string} name Block name. 2096 * @param {Object} attributes Block attributes. 2097 * @param {?Array} innerBlocks Nested blocks. 2098 * 2099 * @return {Object} Block object. 2100 */ 2101 2102 function createBlock(name, attributes = {}, innerBlocks = []) { 2103 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 2104 2105 const clientId = Object(v4["a" /* default */])(); // Blocks are stored with a unique ID, the assigned type name, the block 2106 // attributes, and their inner blocks. 2107 2108 return { 2109 clientId, 2110 name, 2111 isValid: true, 2112 attributes: sanitizedAttributes, 2113 innerBlocks 2114 }; 2115 } 2116 /** 2117 * Given an array of InnerBlocks templates or Block Objects, 2118 * returns an array of created Blocks from them. 2119 * It handles the case of having InnerBlocks as Blocks by 2120 * converting them to the proper format to continue recursively. 2121 * 2122 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 2123 * 2124 * @return {Object[]} Array of Block objects. 2125 */ 2126 2127 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) { 2128 return innerBlocksOrTemplate.map(innerBlock => { 2129 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 2130 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 2131 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 2132 }); 2133 } 2134 /** 2135 * Given a block object, returns a copy of the block object while sanitizing its attributes, 2136 * optionally merging new attributes and/or replacing its inner blocks. 2137 * 2138 * @param {Object} block Block instance. 2139 * @param {Object} mergeAttributes Block attributes. 2140 * @param {?Array} newInnerBlocks Nested blocks. 2141 * 2142 * @return {Object} A cloned block. 2143 */ 2144 2145 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) { 2146 const clientId = Object(v4["a" /* default */])(); 2147 2148 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { ...block.attributes, 2149 ...mergeAttributes 2150 }); 2151 2152 return { ...block, 2153 clientId, 2154 attributes: sanitizedAttributes, 2155 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 2156 }; 2157 } 2158 /** 2159 * Given a block object, returns a copy of the block object, 2160 * optionally merging new attributes and/or replacing its inner blocks. 2161 * 2162 * @param {Object} block Block instance. 2163 * @param {Object} mergeAttributes Block attributes. 2164 * @param {?Array} newInnerBlocks Nested blocks. 2165 * 2166 * @return {Object} A cloned block. 2167 */ 2168 2169 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) { 2170 const clientId = Object(v4["a" /* default */])(); 2171 return { ...block, 2172 clientId, 2173 attributes: { ...block.attributes, 2174 ...mergeAttributes 2175 }, 2176 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 2177 }; 2178 } 2179 /** 2180 * Returns a boolean indicating whether a transform is possible based on 2181 * various bits of context. 2182 * 2183 * @param {Object} transform The transform object to validate. 2184 * @param {string} direction Is this a 'from' or 'to' transform. 2185 * @param {Array} blocks The blocks to transform from. 2186 * 2187 * @return {boolean} Is the transform possible? 2188 */ 2189 2190 const isPossibleTransformForSource = (transform, direction, blocks) => { 2191 if (Object(external_lodash_["isEmpty"])(blocks)) { 2192 return false; 2193 } // If multiple blocks are selected, only multi block transforms 2194 // or wildcard transforms are allowed. 2195 2196 2197 const isMultiBlock = blocks.length > 1; 2198 const firstBlockName = Object(external_lodash_["first"])(blocks).name; 2199 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 2200 2201 if (!isValidForMultiBlocks) { 2202 return false; 2203 } // Check non-wildcard transforms to ensure that transform is valid 2204 // for a block selection of multiple blocks of different types 2205 2206 2207 if (!isWildcardBlockTransform(transform) && !Object(external_lodash_["every"])(blocks, { 2208 name: firstBlockName 2209 })) { 2210 return false; 2211 } // Only consider 'block' type transforms as valid. 2212 2213 2214 const isBlockType = transform.type === 'block'; 2215 2216 if (!isBlockType) { 2217 return false; 2218 } // Check if the transform's block name matches the source block (or is a wildcard) 2219 // only if this is a transform 'from'. 2220 2221 2222 const sourceBlock = Object(external_lodash_["first"])(blocks); 2223 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 2224 2225 if (!hasMatchingName) { 2226 return false; 2227 } // Don't allow single Grouping blocks to be transformed into 2228 // a Grouping block. 2229 2230 2231 if (!isMultiBlock && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 2232 return false; 2233 } // If the transform has a `isMatch` function specified, check that it returns true. 2234 2235 2236 if (Object(external_lodash_["isFunction"])(transform.isMatch)) { 2237 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 2238 2239 if (!transform.isMatch(attributes)) { 2240 return false; 2241 } 2242 } 2243 2244 if (transform.usingMobileTransformations && isWildcardBlockTransform(transform) && !isContainerGroupBlock(sourceBlock.name)) { 2245 return false; 2246 } 2247 2248 return true; 2249 }; 2250 /** 2251 * Returns block types that the 'blocks' can be transformed into, based on 2252 * 'from' transforms on other blocks. 2253 * 2254 * @param {Array} blocks The blocks to transform from. 2255 * 2256 * @return {Array} Block types that the blocks can be transformed into. 2257 */ 2258 2259 2260 const getBlockTypesForPossibleFromTransforms = blocks => { 2261 if (Object(external_lodash_["isEmpty"])(blocks)) { 2262 return []; 2263 } 2264 2265 const allBlockTypes = registration_getBlockTypes(); // filter all blocks to find those with a 'from' transform. 2266 2267 const blockTypesWithPossibleFromTransforms = Object(external_lodash_["filter"])(allBlockTypes, blockType => { 2268 const fromTransforms = getBlockTransforms('from', blockType.name); 2269 return !!findTransform(fromTransforms, transform => { 2270 return isPossibleTransformForSource(transform, 'from', blocks); 2271 }); 2272 }); 2273 return blockTypesWithPossibleFromTransforms; 2274 }; 2275 /** 2276 * Returns block types that the 'blocks' can be transformed into, based on 2277 * the source block's own 'to' transforms. 2278 * 2279 * @param {Array} blocks The blocks to transform from. 2280 * 2281 * @return {Array} Block types that the source can be transformed into. 2282 */ 2283 2284 2285 const getBlockTypesForPossibleToTransforms = blocks => { 2286 if (Object(external_lodash_["isEmpty"])(blocks)) { 2287 return []; 2288 } 2289 2290 const sourceBlock = Object(external_lodash_["first"])(blocks); 2291 const blockType = registration_getBlockType(sourceBlock.name); 2292 const transformsTo = getBlockTransforms('to', blockType.name); // filter all 'to' transforms to find those that are possible. 2293 2294 const possibleTransforms = Object(external_lodash_["filter"])(transformsTo, transform => { 2295 return transform && isPossibleTransformForSource(transform, 'to', blocks); 2296 }); // Build a list of block names using the possible 'to' transforms. 2297 2298 const blockNames = Object(external_lodash_["flatMap"])(possibleTransforms, transformation => transformation.blocks); // Map block names to block types. 2299 2300 return blockNames.map(name => registration_getBlockType(name)); 2301 }; 2302 /** 2303 * Determines whether transform is a "block" type 2304 * and if so whether it is a "wildcard" transform 2305 * ie: targets "any" block type 2306 * 2307 * @param {Object} t the Block transform object 2308 * 2309 * @return {boolean} whether transform is a wildcard transform 2310 */ 2311 2312 2313 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 2314 /** 2315 * Determines whether the given Block is the core Block which 2316 * acts as a container Block for other Blocks as part of the 2317 * Grouping mechanics 2318 * 2319 * @param {string} name the name of the Block to test against 2320 * 2321 * @return {boolean} whether or not the Block is the container Block type 2322 */ 2323 2324 const isContainerGroupBlock = name => name === registration_getGroupingBlockName(); 2325 /** 2326 * Returns an array of block types that the set of blocks received as argument 2327 * can be transformed into. 2328 * 2329 * @param {Array} blocks Blocks array. 2330 * 2331 * @return {Array} Block types that the blocks argument can be transformed to. 2332 */ 2333 2334 function getPossibleBlockTransformations(blocks) { 2335 if (Object(external_lodash_["isEmpty"])(blocks)) { 2336 return []; 2337 } 2338 2339 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 2340 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 2341 return Object(external_lodash_["uniq"])([...blockTypesForFromTransforms, ...blockTypesForToTransforms]); 2342 } 2343 /** 2344 * Given an array of transforms, returns the highest-priority transform where 2345 * the predicate function returns a truthy value. A higher-priority transform 2346 * is one with a lower priority value (i.e. first in priority order). Returns 2347 * null if the transforms set is empty or the predicate function returns a 2348 * falsey value for all entries. 2349 * 2350 * @param {Object[]} transforms Transforms to search. 2351 * @param {Function} predicate Function returning true on matching transform. 2352 * 2353 * @return {?Object} Highest-priority transform candidate. 2354 */ 2355 2356 function findTransform(transforms, predicate) { 2357 // The hooks library already has built-in mechanisms for managing priority 2358 // queue, so leverage via locally-defined instance. 2359 const hooks = Object(external_wp_hooks_["createHooks"])(); 2360 2361 for (let i = 0; i < transforms.length; i++) { 2362 const candidate = transforms[i]; 2363 2364 if (predicate(candidate)) { 2365 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 2366 } 2367 } // Filter name is arbitrarily chosen but consistent with above aggregation. 2368 2369 2370 return hooks.applyFilters('transform', null); 2371 } 2372 /** 2373 * Returns normal block transforms for a given transform direction, optionally 2374 * for a specific block by name, or an empty array if there are no transforms. 2375 * If no block name is provided, returns transforms for all blocks. A normal 2376 * transform object includes `blockName` as a property. 2377 * 2378 * @param {string} direction Transform direction ("to", "from"). 2379 * @param {string|Object} blockTypeOrName Block type or name. 2380 * 2381 * @return {Array} Block transforms for direction. 2382 */ 2383 2384 function getBlockTransforms(direction, blockTypeOrName) { 2385 // When retrieving transforms for all block types, recurse into self. 2386 if (blockTypeOrName === undefined) { 2387 return Object(external_lodash_["flatMap"])(registration_getBlockTypes(), ({ 2388 name 2389 }) => getBlockTransforms(direction, name)); 2390 } // Validate that block type exists and has array of direction. 2391 2392 2393 const blockType = normalizeBlockType(blockTypeOrName); 2394 const { 2395 name: blockName, 2396 transforms 2397 } = blockType || {}; 2398 2399 if (!transforms || !Array.isArray(transforms[direction])) { 2400 return []; 2401 } 2402 2403 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 2404 const filteredTransforms = usingMobileTransformations ? Object(external_lodash_["filter"])(transforms[direction], t => { 2405 if (t.type === 'raw') { 2406 return true; 2407 } 2408 2409 if (!t.blocks || !t.blocks.length) { 2410 return false; 2411 } 2412 2413 if (isWildcardBlockTransform(t)) { 2414 return true; 2415 } 2416 2417 return Object(external_lodash_["every"])(t.blocks, transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 2418 }) : transforms[direction]; // Map transforms to normal form. 2419 2420 return filteredTransforms.map(transform => ({ ...transform, 2421 blockName, 2422 usingMobileTransformations 2423 })); 2424 } 2425 /** 2426 * Switch one or more blocks into one or more blocks of the new block type. 2427 * 2428 * @param {Array|Object} blocks Blocks array or block object. 2429 * @param {string} name Block name. 2430 * 2431 * @return {?Array} Array of blocks or null. 2432 */ 2433 2434 function switchToBlockType(blocks, name) { 2435 const blocksArray = Object(external_lodash_["castArray"])(blocks); 2436 const isMultiBlock = blocksArray.length > 1; 2437 const firstBlock = blocksArray[0]; 2438 const sourceName = firstBlock.name; // Find the right transformation by giving priority to the "to" 2439 // transformation. 2440 2441 const transformationsFrom = getBlockTransforms('from', name); 2442 const transformationsTo = getBlockTransforms('to', sourceName); 2443 const transformation = findTransform(transformationsTo, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(name) !== -1) && (!isMultiBlock || t.isMultiBlock)) || findTransform(transformationsFrom, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(sourceName) !== -1) && (!isMultiBlock || t.isMultiBlock)); // Stop if there is no valid transformation. 2444 2445 if (!transformation) { 2446 return null; 2447 } 2448 2449 let transformationResults; 2450 2451 if (transformation.isMultiBlock) { 2452 if (Object(external_lodash_["has"])(transformation, '__experimentalConvert')) { 2453 transformationResults = transformation.__experimentalConvert(blocksArray); 2454 } else { 2455 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 2456 } 2457 } else if (Object(external_lodash_["has"])(transformation, '__experimentalConvert')) { 2458 transformationResults = transformation.__experimentalConvert(firstBlock); 2459 } else { 2460 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 2461 } // Ensure that the transformation function returned an object or an array 2462 // of objects. 2463 2464 2465 if (!Object(external_lodash_["isObjectLike"])(transformationResults)) { 2466 return null; 2467 } // If the transformation function returned a single object, we want to work 2468 // with an array instead. 2469 2470 2471 transformationResults = Object(external_lodash_["castArray"])(transformationResults); // Ensure that every block object returned by the transformation has a 2472 // valid block type. 2473 2474 if (transformationResults.some(result => !registration_getBlockType(result.name))) { 2475 return null; 2476 } 2477 2478 const hasSwitchedBlock = Object(external_lodash_["some"])(transformationResults, result => result.name === name); // Ensure that at least one block object returned by the transformation has 2479 // the expected "destination" block type. 2480 2481 if (!hasSwitchedBlock) { 2482 return null; 2483 } 2484 2485 const ret = transformationResults.map(result => { 2486 /** 2487 * Filters an individual transform result from block transformation. 2488 * All of the original blocks are passed, since transformations are 2489 * many-to-many, not one-to-one. 2490 * 2491 * @param {Object} transformedBlock The transformed block. 2492 * @param {Object[]} blocks Original blocks transformed. 2493 */ 2494 return Object(external_wp_hooks_["applyFilters"])('blocks.switchToBlockType.transformedBlock', result, blocks); 2495 }); 2496 return ret; 2497 } 2498 /** 2499 * Create a block object from the example API. 2500 * 2501 * @param {string} name 2502 * @param {Object} example 2503 * 2504 * @return {Object} block. 2505 */ 2506 2507 const getBlockFromExample = (name, example) => { 2508 return createBlock(name, example.attributes, Object(external_lodash_["map"])(example.innerBlocks, innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 2509 }; 2510 2511 // CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js 2512 /** 2513 * Given object and string of dot-delimited path segments, returns value at 2514 * path or undefined if path cannot be resolved. 2515 * 2516 * @param {Object} object Lookup object 2517 * @param {string} path Path to resolve 2518 * @return {?*} Resolved value 2519 */ 2520 function getPath(object, path) { 2521 var segments = path.split('.'); 2522 var segment; 2523 2524 while (segment = segments.shift()) { 2525 if (!(segment in object)) { 2526 return; 2527 } 2528 2529 object = object[segment]; 2530 } 2531 2532 return object; 2533 } 2534 // CONCATENATED MODULE: ./node_modules/hpq/es/index.js 2535 /** 2536 * Internal dependencies 2537 */ 2538 2539 /** 2540 * Function returning a DOM document created by `createHTMLDocument`. The same 2541 * document is returned between invocations. 2542 * 2543 * @return {Document} DOM document. 2544 */ 2545 2546 var getDocument = function () { 2547 var doc; 2548 return function () { 2549 if (!doc) { 2550 doc = document.implementation.createHTMLDocument(''); 2551 } 2552 2553 return doc; 2554 }; 2555 }(); 2556 /** 2557 * Given a markup string or DOM element, creates an object aligning with the 2558 * shape of the matchers object, or the value returned by the matcher. 2559 * 2560 * @param {(string|Element)} source Source content 2561 * @param {(Object|Function)} matchers Matcher function or object of matchers 2562 * @return {(Object|*)} Matched value(s), shaped by object 2563 */ 2564 2565 2566 function parse(source, matchers) { 2567 if (!matchers) { 2568 return; 2569 } // Coerce to element 2570 2571 2572 if ('string' === typeof source) { 2573 var doc = getDocument(); 2574 doc.body.innerHTML = source; 2575 source = doc.body; 2576 } // Return singular value 2577 2578 2579 if ('function' === typeof matchers) { 2580 return matchers(source); 2581 } // Bail if we can't handle matchers 2582 2583 2584 if (Object !== matchers.constructor) { 2585 return; 2586 } // Shape result by matcher object 2587 2588 2589 return Object.keys(matchers).reduce(function (memo, key) { 2590 memo[key] = parse(source, matchers[key]); 2591 return memo; 2592 }, {}); 2593 } 2594 /** 2595 * Generates a function which matches node of type selector, returning an 2596 * attribute by property if the attribute exists. If no selector is passed, 2597 * returns property of the query element. 2598 * 2599 * @param {?string} selector Optional selector 2600 * @param {string} name Property name 2601 * @return {*} Property value 2602 */ 2603 2604 function prop(selector, name) { 2605 if (1 === arguments.length) { 2606 name = selector; 2607 selector = undefined; 2608 } 2609 2610 return function (node) { 2611 var match = node; 2612 2613 if (selector) { 2614 match = node.querySelector(selector); 2615 } 2616 2617 if (match) { 2618 return getPath(match, name); 2619 } 2620 }; 2621 } 2622 /** 2623 * Generates a function which matches node of type selector, returning an 2624 * attribute by name if the attribute exists. If no selector is passed, 2625 * returns attribute of the query element. 2626 * 2627 * @param {?string} selector Optional selector 2628 * @param {string} name Attribute name 2629 * @return {?string} Attribute value 2630 */ 2631 2632 function attr(selector, name) { 2633 if (1 === arguments.length) { 2634 name = selector; 2635 selector = undefined; 2636 } 2637 2638 return function (node) { 2639 var attributes = prop(selector, 'attributes')(node); 2640 2641 if (attributes && attributes.hasOwnProperty(name)) { 2642 return attributes[name].value; 2643 } 2644 }; 2645 } 2646 /** 2647 * Convenience for `prop( selector, 'innerHTML' )`. 2648 * 2649 * @see prop() 2650 * 2651 * @param {?string} selector Optional selector 2652 * @return {string} Inner HTML 2653 */ 2654 2655 function es_html(selector) { 2656 return prop(selector, 'innerHTML'); 2657 } 2658 /** 2659 * Convenience for `prop( selector, 'textContent' )`. 2660 * 2661 * @see prop() 2662 * 2663 * @param {?string} selector Optional selector 2664 * @return {string} Text content 2665 */ 2666 2667 function es_text(selector) { 2668 return prop(selector, 'textContent'); 2669 } 2670 /** 2671 * Creates a new matching context by first finding elements matching selector 2672 * using querySelectorAll before then running another `parse` on `matchers` 2673 * scoped to the matched elements. 2674 * 2675 * @see parse() 2676 * 2677 * @param {string} selector Selector to match 2678 * @param {(Object|Function)} matchers Matcher function or object of matchers 2679 * @return {Array.<*,Object>} Array of matched value(s) 2680 */ 2681 2682 function query(selector, matchers) { 2683 return function (node) { 2684 var matches = node.querySelectorAll(selector); 2685 return [].map.call(matches, function (match) { 2686 return parse(match, matchers); 2687 }); 2688 }; 2689 } 2690 // EXTERNAL MODULE: external ["wp","autop"] 2691 var external_wp_autop_ = __webpack_require__("UuzZ"); 2692 2693 // EXTERNAL MODULE: external ["wp","blockSerializationDefaultParser"] 2694 var external_wp_blockSerializationDefaultParser_ = __webpack_require__("ouCq"); 2695 2696 // CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js 2697 /** 2698 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 2699 * do not edit 2700 */ 2701 var namedCharRefs = { 2702 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" 2703 }; 2704 2705 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 2706 var CHARCODE = /^#([0-9]+)$/; 2707 var NAMED = /^([A-Za-z0-9]+)$/; 2708 var EntityParser = /** @class */ (function () { 2709 function EntityParser(named) { 2710 this.named = named; 2711 } 2712 EntityParser.prototype.parse = function (entity) { 2713 if (!entity) { 2714 return; 2715 } 2716 var matches = entity.match(HEXCHARCODE); 2717 if (matches) { 2718 return String.fromCharCode(parseInt(matches[1], 16)); 2719 } 2720 matches = entity.match(CHARCODE); 2721 if (matches) { 2722 return String.fromCharCode(parseInt(matches[1], 10)); 2723 } 2724 matches = entity.match(NAMED); 2725 if (matches) { 2726 return this.named[matches[1]]; 2727 } 2728 }; 2729 return EntityParser; 2730 }()); 2731 2732 var WSP = /[\t\n\f ]/; 2733 var ALPHA = /[A-Za-z]/; 2734 var CRLF = /\r\n?/g; 2735 function isSpace(char) { 2736 return WSP.test(char); 2737 } 2738 function isAlpha(char) { 2739 return ALPHA.test(char); 2740 } 2741 function preprocessInput(input) { 2742 return input.replace(CRLF, '\n'); 2743 } 2744 2745 var EventedTokenizer = /** @class */ (function () { 2746 function EventedTokenizer(delegate, entityParser, mode) { 2747 if (mode === void 0) { mode = 'precompile'; } 2748 this.delegate = delegate; 2749 this.entityParser = entityParser; 2750 this.mode = mode; 2751 this.state = "beforeData" /* beforeData */; 2752 this.line = -1; 2753 this.column = -1; 2754 this.input = ''; 2755 this.index = -1; 2756 this.tagNameBuffer = ''; 2757 this.states = { 2758 beforeData: function () { 2759 var char = this.peek(); 2760 if (char === '<' && !this.isIgnoredEndTag()) { 2761 this.transitionTo("tagOpen" /* tagOpen */); 2762 this.markTagStart(); 2763 this.consume(); 2764 } 2765 else { 2766 if (this.mode === 'precompile' && char === '\n') { 2767 var tag = this.tagNameBuffer.toLowerCase(); 2768 if (tag === 'pre' || tag === 'textarea') { 2769 this.consume(); 2770 } 2771 } 2772 this.transitionTo("data" /* data */); 2773 this.delegate.beginData(); 2774 } 2775 }, 2776 data: function () { 2777 var char = this.peek(); 2778 var tag = this.tagNameBuffer; 2779 if (char === '<' && !this.isIgnoredEndTag()) { 2780 this.delegate.finishData(); 2781 this.transitionTo("tagOpen" /* tagOpen */); 2782 this.markTagStart(); 2783 this.consume(); 2784 } 2785 else if (char === '&' && tag !== 'script' && tag !== 'style') { 2786 this.consume(); 2787 this.delegate.appendToData(this.consumeCharRef() || '&'); 2788 } 2789 else { 2790 this.consume(); 2791 this.delegate.appendToData(char); 2792 } 2793 }, 2794 tagOpen: function () { 2795 var char = this.consume(); 2796 if (char === '!') { 2797 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 2798 } 2799 else if (char === '/') { 2800 this.transitionTo("endTagOpen" /* endTagOpen */); 2801 } 2802 else if (char === '@' || char === ':' || isAlpha(char)) { 2803 this.transitionTo("tagName" /* tagName */); 2804 this.tagNameBuffer = ''; 2805 this.delegate.beginStartTag(); 2806 this.appendToTagName(char); 2807 } 2808 }, 2809 markupDeclarationOpen: function () { 2810 var char = this.consume(); 2811 if (char === '-' && this.peek() === '-') { 2812 this.consume(); 2813 this.transitionTo("commentStart" /* commentStart */); 2814 this.delegate.beginComment(); 2815 } 2816 else { 2817 var maybeDoctype = char.toUpperCase() + this.input.substring(this.index, this.index + 6).toUpperCase(); 2818 if (maybeDoctype === 'DOCTYPE') { 2819 this.consume(); 2820 this.consume(); 2821 this.consume(); 2822 this.consume(); 2823 this.consume(); 2824 this.consume(); 2825 this.transitionTo("doctype" /* doctype */); 2826 if (this.delegate.beginDoctype) 2827 this.delegate.beginDoctype(); 2828 } 2829 } 2830 }, 2831 doctype: function () { 2832 var char = this.consume(); 2833 if (isSpace(char)) { 2834 this.transitionTo("beforeDoctypeName" /* beforeDoctypeName */); 2835 } 2836 }, 2837 beforeDoctypeName: function () { 2838 var char = this.consume(); 2839 if (isSpace(char)) { 2840 return; 2841 } 2842 else { 2843 this.transitionTo("doctypeName" /* doctypeName */); 2844 if (this.delegate.appendToDoctypeName) 2845 this.delegate.appendToDoctypeName(char.toLowerCase()); 2846 } 2847 }, 2848 doctypeName: function () { 2849 var char = this.consume(); 2850 if (isSpace(char)) { 2851 this.transitionTo("afterDoctypeName" /* afterDoctypeName */); 2852 } 2853 else if (char === '>') { 2854 if (this.delegate.endDoctype) 2855 this.delegate.endDoctype(); 2856 this.transitionTo("beforeData" /* beforeData */); 2857 } 2858 else { 2859 if (this.delegate.appendToDoctypeName) 2860 this.delegate.appendToDoctypeName(char.toLowerCase()); 2861 } 2862 }, 2863 afterDoctypeName: function () { 2864 var char = this.consume(); 2865 if (isSpace(char)) { 2866 return; 2867 } 2868 else if (char === '>') { 2869 if (this.delegate.endDoctype) 2870 this.delegate.endDoctype(); 2871 this.transitionTo("beforeData" /* beforeData */); 2872 } 2873 else { 2874 var nextSixChars = char.toUpperCase() + this.input.substring(this.index, this.index + 5).toUpperCase(); 2875 var isPublic = nextSixChars.toUpperCase() === 'PUBLIC'; 2876 var isSystem = nextSixChars.toUpperCase() === 'SYSTEM'; 2877 if (isPublic || isSystem) { 2878 this.consume(); 2879 this.consume(); 2880 this.consume(); 2881 this.consume(); 2882 this.consume(); 2883 this.consume(); 2884 } 2885 if (isPublic) { 2886 this.transitionTo("afterDoctypePublicKeyword" /* afterDoctypePublicKeyword */); 2887 } 2888 else if (isSystem) { 2889 this.transitionTo("afterDoctypeSystemKeyword" /* afterDoctypeSystemKeyword */); 2890 } 2891 } 2892 }, 2893 afterDoctypePublicKeyword: function () { 2894 var char = this.peek(); 2895 if (isSpace(char)) { 2896 this.transitionTo("beforeDoctypePublicIdentifier" /* beforeDoctypePublicIdentifier */); 2897 this.consume(); 2898 } 2899 else if (char === '"') { 2900 this.transitionTo("doctypePublicIdentifierDoubleQuoted" /* doctypePublicIdentifierDoubleQuoted */); 2901 this.consume(); 2902 } 2903 else if (char === "'") { 2904 this.transitionTo("doctypePublicIdentifierSingleQuoted" /* doctypePublicIdentifierSingleQuoted */); 2905 this.consume(); 2906 } 2907 else if (char === '>') { 2908 this.consume(); 2909 if (this.delegate.endDoctype) 2910 this.delegate.endDoctype(); 2911 this.transitionTo("beforeData" /* beforeData */); 2912 } 2913 }, 2914 doctypePublicIdentifierDoubleQuoted: function () { 2915 var char = this.consume(); 2916 if (char === '"') { 2917 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 2918 } 2919 else if (char === '>') { 2920 if (this.delegate.endDoctype) 2921 this.delegate.endDoctype(); 2922 this.transitionTo("beforeData" /* beforeData */); 2923 } 2924 else { 2925 if (this.delegate.appendToDoctypePublicIdentifier) 2926 this.delegate.appendToDoctypePublicIdentifier(char); 2927 } 2928 }, 2929 doctypePublicIdentifierSingleQuoted: function () { 2930 var char = this.consume(); 2931 if (char === "'") { 2932 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 2933 } 2934 else if (char === '>') { 2935 if (this.delegate.endDoctype) 2936 this.delegate.endDoctype(); 2937 this.transitionTo("beforeData" /* beforeData */); 2938 } 2939 else { 2940 if (this.delegate.appendToDoctypePublicIdentifier) 2941 this.delegate.appendToDoctypePublicIdentifier(char); 2942 } 2943 }, 2944 afterDoctypePublicIdentifier: function () { 2945 var char = this.consume(); 2946 if (isSpace(char)) { 2947 this.transitionTo("betweenDoctypePublicAndSystemIdentifiers" /* betweenDoctypePublicAndSystemIdentifiers */); 2948 } 2949 else if (char === '>') { 2950 if (this.delegate.endDoctype) 2951 this.delegate.endDoctype(); 2952 this.transitionTo("beforeData" /* beforeData */); 2953 } 2954 else if (char === '"') { 2955 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 2956 } 2957 else if (char === "'") { 2958 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 2959 } 2960 }, 2961 betweenDoctypePublicAndSystemIdentifiers: function () { 2962 var char = this.consume(); 2963 if (isSpace(char)) { 2964 return; 2965 } 2966 else if (char === '>') { 2967 if (this.delegate.endDoctype) 2968 this.delegate.endDoctype(); 2969 this.transitionTo("beforeData" /* beforeData */); 2970 } 2971 else if (char === '"') { 2972 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 2973 } 2974 else if (char === "'") { 2975 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 2976 } 2977 }, 2978 doctypeSystemIdentifierDoubleQuoted: function () { 2979 var char = this.consume(); 2980 if (char === '"') { 2981 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 2982 } 2983 else if (char === '>') { 2984 if (this.delegate.endDoctype) 2985 this.delegate.endDoctype(); 2986 this.transitionTo("beforeData" /* beforeData */); 2987 } 2988 else { 2989 if (this.delegate.appendToDoctypeSystemIdentifier) 2990 this.delegate.appendToDoctypeSystemIdentifier(char); 2991 } 2992 }, 2993 doctypeSystemIdentifierSingleQuoted: function () { 2994 var char = this.consume(); 2995 if (char === "'") { 2996 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 2997 } 2998 else if (char === '>') { 2999 if (this.delegate.endDoctype) 3000 this.delegate.endDoctype(); 3001 this.transitionTo("beforeData" /* beforeData */); 3002 } 3003 else { 3004 if (this.delegate.appendToDoctypeSystemIdentifier) 3005 this.delegate.appendToDoctypeSystemIdentifier(char); 3006 } 3007 }, 3008 afterDoctypeSystemIdentifier: function () { 3009 var char = this.consume(); 3010 if (isSpace(char)) { 3011 return; 3012 } 3013 else if (char === '>') { 3014 if (this.delegate.endDoctype) 3015 this.delegate.endDoctype(); 3016 this.transitionTo("beforeData" /* beforeData */); 3017 } 3018 }, 3019 commentStart: function () { 3020 var char = this.consume(); 3021 if (char === '-') { 3022 this.transitionTo("commentStartDash" /* commentStartDash */); 3023 } 3024 else if (char === '>') { 3025 this.delegate.finishComment(); 3026 this.transitionTo("beforeData" /* beforeData */); 3027 } 3028 else { 3029 this.delegate.appendToCommentData(char); 3030 this.transitionTo("comment" /* comment */); 3031 } 3032 }, 3033 commentStartDash: function () { 3034 var char = this.consume(); 3035 if (char === '-') { 3036 this.transitionTo("commentEnd" /* commentEnd */); 3037 } 3038 else if (char === '>') { 3039 this.delegate.finishComment(); 3040 this.transitionTo("beforeData" /* beforeData */); 3041 } 3042 else { 3043 this.delegate.appendToCommentData('-'); 3044 this.transitionTo("comment" /* comment */); 3045 } 3046 }, 3047 comment: function () { 3048 var char = this.consume(); 3049 if (char === '-') { 3050 this.transitionTo("commentEndDash" /* commentEndDash */); 3051 } 3052 else { 3053 this.delegate.appendToCommentData(char); 3054 } 3055 }, 3056 commentEndDash: function () { 3057 var char = this.consume(); 3058 if (char === '-') { 3059 this.transitionTo("commentEnd" /* commentEnd */); 3060 } 3061 else { 3062 this.delegate.appendToCommentData('-' + char); 3063 this.transitionTo("comment" /* comment */); 3064 } 3065 }, 3066 commentEnd: function () { 3067 var char = this.consume(); 3068 if (char === '>') { 3069 this.delegate.finishComment(); 3070 this.transitionTo("beforeData" /* beforeData */); 3071 } 3072 else { 3073 this.delegate.appendToCommentData('--' + char); 3074 this.transitionTo("comment" /* comment */); 3075 } 3076 }, 3077 tagName: function () { 3078 var char = this.consume(); 3079 if (isSpace(char)) { 3080 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 3081 } 3082 else if (char === '/') { 3083 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3084 } 3085 else if (char === '>') { 3086 this.delegate.finishTag(); 3087 this.transitionTo("beforeData" /* beforeData */); 3088 } 3089 else { 3090 this.appendToTagName(char); 3091 } 3092 }, 3093 endTagName: function () { 3094 var char = this.consume(); 3095 if (isSpace(char)) { 3096 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 3097 this.tagNameBuffer = ''; 3098 } 3099 else if (char === '/') { 3100 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3101 this.tagNameBuffer = ''; 3102 } 3103 else if (char === '>') { 3104 this.delegate.finishTag(); 3105 this.transitionTo("beforeData" /* beforeData */); 3106 this.tagNameBuffer = ''; 3107 } 3108 else { 3109 this.appendToTagName(char); 3110 } 3111 }, 3112 beforeAttributeName: function () { 3113 var char = this.peek(); 3114 if (isSpace(char)) { 3115 this.consume(); 3116 return; 3117 } 3118 else if (char === '/') { 3119 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3120 this.consume(); 3121 } 3122 else if (char === '>') { 3123 this.consume(); 3124 this.delegate.finishTag(); 3125 this.transitionTo("beforeData" /* beforeData */); 3126 } 3127 else if (char === '=') { 3128 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 3129 this.transitionTo("attributeName" /* attributeName */); 3130 this.delegate.beginAttribute(); 3131 this.consume(); 3132 this.delegate.appendToAttributeName(char); 3133 } 3134 else { 3135 this.transitionTo("attributeName" /* attributeName */); 3136 this.delegate.beginAttribute(); 3137 } 3138 }, 3139 attributeName: function () { 3140 var char = this.peek(); 3141 if (isSpace(char)) { 3142 this.transitionTo("afterAttributeName" /* afterAttributeName */); 3143 this.consume(); 3144 } 3145 else if (char === '/') { 3146 this.delegate.beginAttributeValue(false); 3147 this.delegate.finishAttributeValue(); 3148 this.consume(); 3149 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3150 } 3151 else if (char === '=') { 3152 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 3153 this.consume(); 3154 } 3155 else if (char === '>') { 3156 this.delegate.beginAttributeValue(false); 3157 this.delegate.finishAttributeValue(); 3158 this.consume(); 3159 this.delegate.finishTag(); 3160 this.transitionTo("beforeData" /* beforeData */); 3161 } 3162 else if (char === '"' || char === "'" || char === '<') { 3163 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 3164 this.consume(); 3165 this.delegate.appendToAttributeName(char); 3166 } 3167 else { 3168 this.consume(); 3169 this.delegate.appendToAttributeName(char); 3170 } 3171 }, 3172 afterAttributeName: function () { 3173 var char = this.peek(); 3174 if (isSpace(char)) { 3175 this.consume(); 3176 return; 3177 } 3178 else if (char === '/') { 3179 this.delegate.beginAttributeValue(false); 3180 this.delegate.finishAttributeValue(); 3181 this.consume(); 3182 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3183 } 3184 else if (char === '=') { 3185 this.consume(); 3186 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 3187 } 3188 else if (char === '>') { 3189 this.delegate.beginAttributeValue(false); 3190 this.delegate.finishAttributeValue(); 3191 this.consume(); 3192 this.delegate.finishTag(); 3193 this.transitionTo("beforeData" /* beforeData */); 3194 } 3195 else { 3196 this.delegate.beginAttributeValue(false); 3197 this.delegate.finishAttributeValue(); 3198 this.transitionTo("attributeName" /* attributeName */); 3199 this.delegate.beginAttribute(); 3200 this.consume(); 3201 this.delegate.appendToAttributeName(char); 3202 } 3203 }, 3204 beforeAttributeValue: function () { 3205 var char = this.peek(); 3206 if (isSpace(char)) { 3207 this.consume(); 3208 } 3209 else if (char === '"') { 3210 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 3211 this.delegate.beginAttributeValue(true); 3212 this.consume(); 3213 } 3214 else if (char === "'") { 3215 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 3216 this.delegate.beginAttributeValue(true); 3217 this.consume(); 3218 } 3219 else if (char === '>') { 3220 this.delegate.beginAttributeValue(false); 3221 this.delegate.finishAttributeValue(); 3222 this.consume(); 3223 this.delegate.finishTag(); 3224 this.transitionTo("beforeData" /* beforeData */); 3225 } 3226 else { 3227 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 3228 this.delegate.beginAttributeValue(false); 3229 this.consume(); 3230 this.delegate.appendToAttributeValue(char); 3231 } 3232 }, 3233 attributeValueDoubleQuoted: function () { 3234 var char = this.consume(); 3235 if (char === '"') { 3236 this.delegate.finishAttributeValue(); 3237 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 3238 } 3239 else if (char === '&') { 3240 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 3241 } 3242 else { 3243 this.delegate.appendToAttributeValue(char); 3244 } 3245 }, 3246 attributeValueSingleQuoted: function () { 3247 var char = this.consume(); 3248 if (char === "'") { 3249 this.delegate.finishAttributeValue(); 3250 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 3251 } 3252 else if (char === '&') { 3253 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 3254 } 3255 else { 3256 this.delegate.appendToAttributeValue(char); 3257 } 3258 }, 3259 attributeValueUnquoted: function () { 3260 var char = this.peek(); 3261 if (isSpace(char)) { 3262 this.delegate.finishAttributeValue(); 3263 this.consume(); 3264 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 3265 } 3266 else if (char === '/') { 3267 this.delegate.finishAttributeValue(); 3268 this.consume(); 3269 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3270 } 3271 else if (char === '&') { 3272 this.consume(); 3273 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 3274 } 3275 else if (char === '>') { 3276 this.delegate.finishAttributeValue(); 3277 this.consume(); 3278 this.delegate.finishTag(); 3279 this.transitionTo("beforeData" /* beforeData */); 3280 } 3281 else { 3282 this.consume(); 3283 this.delegate.appendToAttributeValue(char); 3284 } 3285 }, 3286 afterAttributeValueQuoted: function () { 3287 var char = this.peek(); 3288 if (isSpace(char)) { 3289 this.consume(); 3290 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 3291 } 3292 else if (char === '/') { 3293 this.consume(); 3294 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 3295 } 3296 else if (char === '>') { 3297 this.consume(); 3298 this.delegate.finishTag(); 3299 this.transitionTo("beforeData" /* beforeData */); 3300 } 3301 else { 3302 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 3303 } 3304 }, 3305 selfClosingStartTag: function () { 3306 var char = this.peek(); 3307 if (char === '>') { 3308 this.consume(); 3309 this.delegate.markTagAsSelfClosing(); 3310 this.delegate.finishTag(); 3311 this.transitionTo("beforeData" /* beforeData */); 3312 } 3313 else { 3314 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 3315 } 3316 }, 3317 endTagOpen: function () { 3318 var char = this.consume(); 3319 if (char === '@' || char === ':' || isAlpha(char)) { 3320 this.transitionTo("endTagName" /* endTagName */); 3321 this.tagNameBuffer = ''; 3322 this.delegate.beginEndTag(); 3323 this.appendToTagName(char); 3324 } 3325 } 3326 }; 3327 this.reset(); 3328 } 3329 EventedTokenizer.prototype.reset = function () { 3330 this.transitionTo("beforeData" /* beforeData */); 3331 this.input = ''; 3332 this.tagNameBuffer = ''; 3333 this.index = 0; 3334 this.line = 1; 3335 this.column = 0; 3336 this.delegate.reset(); 3337 }; 3338 EventedTokenizer.prototype.transitionTo = function (state) { 3339 this.state = state; 3340 }; 3341 EventedTokenizer.prototype.tokenize = function (input) { 3342 this.reset(); 3343 this.tokenizePart(input); 3344 this.tokenizeEOF(); 3345 }; 3346 EventedTokenizer.prototype.tokenizePart = function (input) { 3347 this.input += preprocessInput(input); 3348 while (this.index < this.input.length) { 3349 var handler = this.states[this.state]; 3350 if (handler !== undefined) { 3351 handler.call(this); 3352 } 3353 else { 3354 throw new Error("unhandled state " + this.state); 3355 } 3356 } 3357 }; 3358 EventedTokenizer.prototype.tokenizeEOF = function () { 3359 this.flushData(); 3360 }; 3361 EventedTokenizer.prototype.flushData = function () { 3362 if (this.state === 'data') { 3363 this.delegate.finishData(); 3364 this.transitionTo("beforeData" /* beforeData */); 3365 } 3366 }; 3367 EventedTokenizer.prototype.peek = function () { 3368 return this.input.charAt(this.index); 3369 }; 3370 EventedTokenizer.prototype.consume = function () { 3371 var char = this.peek(); 3372 this.index++; 3373 if (char === '\n') { 3374 this.line++; 3375 this.column = 0; 3376 } 3377 else { 3378 this.column++; 3379 } 3380 return char; 3381 }; 3382 EventedTokenizer.prototype.consumeCharRef = function () { 3383 var endIndex = this.input.indexOf(';', this.index); 3384 if (endIndex === -1) { 3385 return; 3386 } 3387 var entity = this.input.slice(this.index, endIndex); 3388 var chars = this.entityParser.parse(entity); 3389 if (chars) { 3390 var count = entity.length; 3391 // consume the entity chars 3392 while (count) { 3393 this.consume(); 3394 count--; 3395 } 3396 // consume the `;` 3397 this.consume(); 3398 return chars; 3399 } 3400 }; 3401 EventedTokenizer.prototype.markTagStart = function () { 3402 this.delegate.tagOpen(); 3403 }; 3404 EventedTokenizer.prototype.appendToTagName = function (char) { 3405 this.tagNameBuffer += char; 3406 this.delegate.appendToTagName(char); 3407 }; 3408 EventedTokenizer.prototype.isIgnoredEndTag = function () { 3409 var tag = this.tagNameBuffer; 3410 return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') || 3411 (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') || 3412 (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>'); 3413 }; 3414 return EventedTokenizer; 3415 }()); 3416 3417 var Tokenizer = /** @class */ (function () { 3418 function Tokenizer(entityParser, options) { 3419 if (options === void 0) { options = {}; } 3420 this.options = options; 3421 this.token = null; 3422 this.startLine = 1; 3423 this.startColumn = 0; 3424 this.tokens = []; 3425 this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); 3426 this._currentAttribute = undefined; 3427 } 3428 Tokenizer.prototype.tokenize = function (input) { 3429 this.tokens = []; 3430 this.tokenizer.tokenize(input); 3431 return this.tokens; 3432 }; 3433 Tokenizer.prototype.tokenizePart = function (input) { 3434 this.tokens = []; 3435 this.tokenizer.tokenizePart(input); 3436 return this.tokens; 3437 }; 3438 Tokenizer.prototype.tokenizeEOF = function () { 3439 this.tokens = []; 3440 this.tokenizer.tokenizeEOF(); 3441 return this.tokens[0]; 3442 }; 3443 Tokenizer.prototype.reset = function () { 3444 this.token = null; 3445 this.startLine = 1; 3446 this.startColumn = 0; 3447 }; 3448 Tokenizer.prototype.current = function () { 3449 var token = this.token; 3450 if (token === null) { 3451 throw new Error('token was unexpectedly null'); 3452 } 3453 if (arguments.length === 0) { 3454 return token; 3455 } 3456 for (var i = 0; i < arguments.length; i++) { 3457 if (token.type === arguments[i]) { 3458 return token; 3459 } 3460 } 3461 throw new Error("token type was unexpectedly " + token.type); 3462 }; 3463 Tokenizer.prototype.push = function (token) { 3464 this.token = token; 3465 this.tokens.push(token); 3466 }; 3467 Tokenizer.prototype.currentAttribute = function () { 3468 return this._currentAttribute; 3469 }; 3470 Tokenizer.prototype.addLocInfo = function () { 3471 if (this.options.loc) { 3472 this.current().loc = { 3473 start: { 3474 line: this.startLine, 3475 column: this.startColumn 3476 }, 3477 end: { 3478 line: this.tokenizer.line, 3479 column: this.tokenizer.column 3480 } 3481 }; 3482 } 3483 this.startLine = this.tokenizer.line; 3484 this.startColumn = this.tokenizer.column; 3485 }; 3486 // Data 3487 Tokenizer.prototype.beginDoctype = function () { 3488 this.push({ 3489 type: "Doctype" /* Doctype */, 3490 name: '', 3491 }); 3492 }; 3493 Tokenizer.prototype.appendToDoctypeName = function (char) { 3494 this.current("Doctype" /* Doctype */).name += char; 3495 }; 3496 Tokenizer.prototype.appendToDoctypePublicIdentifier = function (char) { 3497 var doctype = this.current("Doctype" /* Doctype */); 3498 if (doctype.publicIdentifier === undefined) { 3499 doctype.publicIdentifier = char; 3500 } 3501 else { 3502 doctype.publicIdentifier += char; 3503 } 3504 }; 3505 Tokenizer.prototype.appendToDoctypeSystemIdentifier = function (char) { 3506 var doctype = this.current("Doctype" /* Doctype */); 3507 if (doctype.systemIdentifier === undefined) { 3508 doctype.systemIdentifier = char; 3509 } 3510 else { 3511 doctype.systemIdentifier += char; 3512 } 3513 }; 3514 Tokenizer.prototype.endDoctype = function () { 3515 this.addLocInfo(); 3516 }; 3517 Tokenizer.prototype.beginData = function () { 3518 this.push({ 3519 type: "Chars" /* Chars */, 3520 chars: '' 3521 }); 3522 }; 3523 Tokenizer.prototype.appendToData = function (char) { 3524 this.current("Chars" /* Chars */).chars += char; 3525 }; 3526 Tokenizer.prototype.finishData = function () { 3527 this.addLocInfo(); 3528 }; 3529 // Comment 3530 Tokenizer.prototype.beginComment = function () { 3531 this.push({ 3532 type: "Comment" /* Comment */, 3533 chars: '' 3534 }); 3535 }; 3536 Tokenizer.prototype.appendToCommentData = function (char) { 3537 this.current("Comment" /* Comment */).chars += char; 3538 }; 3539 Tokenizer.prototype.finishComment = function () { 3540 this.addLocInfo(); 3541 }; 3542 // Tags - basic 3543 Tokenizer.prototype.tagOpen = function () { }; 3544 Tokenizer.prototype.beginStartTag = function () { 3545 this.push({ 3546 type: "StartTag" /* StartTag */, 3547 tagName: '', 3548 attributes: [], 3549 selfClosing: false 3550 }); 3551 }; 3552 Tokenizer.prototype.beginEndTag = function () { 3553 this.push({ 3554 type: "EndTag" /* EndTag */, 3555 tagName: '' 3556 }); 3557 }; 3558 Tokenizer.prototype.finishTag = function () { 3559 this.addLocInfo(); 3560 }; 3561 Tokenizer.prototype.markTagAsSelfClosing = function () { 3562 this.current("StartTag" /* StartTag */).selfClosing = true; 3563 }; 3564 // Tags - name 3565 Tokenizer.prototype.appendToTagName = function (char) { 3566 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 3567 }; 3568 // Tags - attributes 3569 Tokenizer.prototype.beginAttribute = function () { 3570 this._currentAttribute = ['', '', false]; 3571 }; 3572 Tokenizer.prototype.appendToAttributeName = function (char) { 3573 this.currentAttribute()[0] += char; 3574 }; 3575 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 3576 this.currentAttribute()[2] = isQuoted; 3577 }; 3578 Tokenizer.prototype.appendToAttributeValue = function (char) { 3579 this.currentAttribute()[1] += char; 3580 }; 3581 Tokenizer.prototype.finishAttributeValue = function () { 3582 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 3583 }; 3584 Tokenizer.prototype.reportSyntaxError = function (message) { 3585 this.current().syntaxError = message; 3586 }; 3587 return Tokenizer; 3588 }()); 3589 3590 function tokenize(input, options) { 3591 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 3592 return tokenizer.tokenize(input); 3593 } 3594 3595 3596 3597 // EXTERNAL MODULE: external ["wp","htmlEntities"] 3598 var external_wp_htmlEntities_ = __webpack_require__("rmEH"); 3599 3600 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js 3601 function createLogger() { 3602 /** 3603 * Creates a log handler with block validation prefix. 3604 * 3605 * @param {Function} logger Original logger function. 3606 * 3607 * @return {Function} Augmented logger function. 3608 */ 3609 function createLogHandler(logger) { 3610 let log = (message, ...args) => logger('Block validation: ' + message, ...args); // In test environments, pre-process string substitutions to improve 3611 // readability of error messages. We'd prefer to avoid pulling in this 3612 // dependency in runtime environments, and it can be dropped by a combo 3613 // of Webpack env substitution + UglifyJS dead code elimination. 3614 3615 3616 if (false) {} 3617 3618 return log; 3619 } 3620 3621 return { 3622 // eslint-disable-next-line no-console 3623 error: createLogHandler(console.error), 3624 // eslint-disable-next-line no-console 3625 warning: createLogHandler(console.warn), 3626 3627 getItems() { 3628 return []; 3629 } 3630 3631 }; 3632 } 3633 function createQueuedLogger() { 3634 /** 3635 * The list of enqueued log actions to print. 3636 * 3637 * @type {Array} 3638 */ 3639 const queue = []; 3640 const logger = createLogger(); 3641 return { 3642 error(...args) { 3643 queue.push({ 3644 log: logger.error, 3645 args 3646 }); 3647 }, 3648 3649 warning(...args) { 3650 queue.push({ 3651 log: logger.warning, 3652 args 3653 }); 3654 }, 3655 3656 getItems() { 3657 return queue; 3658 } 3659 3660 }; 3661 } 3662 3663 // EXTERNAL MODULE: external ["wp","isShallowEqual"] 3664 var external_wp_isShallowEqual_ = __webpack_require__("rl8x"); 3665 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_); 3666 3667 // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js 3668 var esm_extends = __webpack_require__("wx14"); 3669 3670 // EXTERNAL MODULE: external ["wp","compose"] 3671 var external_wp_compose_ = __webpack_require__("K9lf"); 3672 3673 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/block-content-provider/index.js 3674 3675 3676 3677 /** 3678 * WordPress dependencies 3679 */ 3680 3681 3682 /** 3683 * Internal dependencies 3684 */ 3685 3686 3687 const { 3688 Consumer, 3689 Provider 3690 } = Object(external_wp_element_["createContext"])(() => {}); 3691 /** 3692 * An internal block component used in block content serialization to inject 3693 * nested block content within the `save` implementation of the ancestor 3694 * component in which it is nested. The component provides a pre-bound 3695 * `BlockContent` component via context, which is used by the developer-facing 3696 * `InnerBlocks.Content` component to render block content. 3697 * 3698 * @example 3699 * 3700 * ```jsx 3701 * <BlockContentProvider innerBlocks={ innerBlocks }> 3702 * { blockSaveElement } 3703 * </BlockContentProvider> 3704 * ``` 3705 * 3706 * @param {Object} props Component props. 3707 * @param {WPElement} props.children Block save result. 3708 * @param {Array} props.innerBlocks Block(s) to serialize. 3709 * 3710 * @return {WPComponent} Element with BlockContent injected via context. 3711 */ 3712 3713 const BlockContentProvider = ({ 3714 children, 3715 innerBlocks 3716 }) => { 3717 const BlockContent = () => { 3718 // Value is an array of blocks, so defer to block serializer 3719 const html = serialize(innerBlocks, { 3720 isInnerBlocks: true 3721 }); // Use special-cased raw HTML tag to avoid default escaping 3722 3723 return Object(external_wp_element_["createElement"])(external_wp_element_["RawHTML"], null, html); 3724 }; 3725 3726 return Object(external_wp_element_["createElement"])(Provider, { 3727 value: BlockContent 3728 }, children); 3729 }; 3730 /** 3731 * A Higher Order Component used to inject BlockContent using context to the 3732 * wrapped component. 3733 * 3734 * @return {WPComponent} Enhanced component with injected BlockContent as prop. 3735 */ 3736 3737 3738 const withBlockContentContext = Object(external_wp_compose_["createHigherOrderComponent"])(OriginalComponent => { 3739 return props => Object(external_wp_element_["createElement"])(Consumer, null, context => Object(external_wp_element_["createElement"])(OriginalComponent, Object(esm_extends["a" /* default */])({}, props, { 3740 BlockContent: context 3741 }))); 3742 }, 'withBlockContentContext'); 3743 /* harmony default export */ var block_content_provider = (BlockContentProvider); 3744 3745 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/serializer.js 3746 3747 3748 /** 3749 * External dependencies 3750 */ 3751 3752 /** 3753 * WordPress dependencies 3754 */ 3755 3756 3757 3758 3759 3760 /** 3761 * Internal dependencies 3762 */ 3763 3764 3765 3766 3767 /** 3768 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 3769 * 3770 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 3771 */ 3772 3773 /** 3774 * Returns the block's default classname from its name. 3775 * 3776 * @param {string} blockName The block name. 3777 * 3778 * @return {string} The block's default class. 3779 */ 3780 3781 function getBlockDefaultClassName(blockName) { 3782 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 3783 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 3784 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 3785 return Object(external_wp_hooks_["applyFilters"])('blocks.getBlockDefaultClassName', className, blockName); 3786 } 3787 /** 3788 * Returns the block's default menu item classname from its name. 3789 * 3790 * @param {string} blockName The block name. 3791 * 3792 * @return {string} The block's default menu item class. 3793 */ 3794 3795 function getBlockMenuDefaultClassName(blockName) { 3796 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 3797 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 3798 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 3799 return Object(external_wp_hooks_["applyFilters"])('blocks.getBlockMenuDefaultClassName', className, blockName); 3800 } 3801 const blockPropsProvider = {}; 3802 /** 3803 * Call within a save function to get the props for the block wrapper. 3804 * 3805 * @param {Object} props Optional. Props to pass to the element. 3806 */ 3807 3808 function getBlockProps(props = {}) { 3809 const { 3810 blockType, 3811 attributes 3812 } = blockPropsProvider; 3813 return Object(external_wp_hooks_["applyFilters"])('blocks.getSaveContent.extraProps', { ...props 3814 }, blockType, attributes); 3815 } 3816 /** 3817 * Given a block type containing a save render implementation and attributes, returns the 3818 * enhanced element to be saved or string when raw HTML expected. 3819 * 3820 * @param {string|Object} blockTypeOrName Block type or name. 3821 * @param {Object} attributes Block attributes. 3822 * @param {?Array} innerBlocks Nested blocks. 3823 * 3824 * @return {Object|string} Save element or raw HTML string. 3825 */ 3826 3827 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) { 3828 const blockType = normalizeBlockType(blockTypeOrName); 3829 let { 3830 save 3831 } = blockType; // Component classes are unsupported for save since serialization must 3832 // occur synchronously. For improved interoperability with higher-order 3833 // components which often return component class, emulate basic support. 3834 3835 if (save.prototype instanceof external_wp_element_["Component"]) { 3836 const instance = new save({ 3837 attributes 3838 }); 3839 save = instance.render.bind(instance); 3840 } 3841 3842 blockPropsProvider.blockType = blockType; 3843 blockPropsProvider.attributes = attributes; 3844 let element = save({ 3845 attributes, 3846 innerBlocks 3847 }); 3848 const hasLightBlockWrapper = blockType.apiVersion > 1 || registration_hasBlockSupport(blockType, 'lightBlockWrapper', false); 3849 3850 if (Object(external_lodash_["isObject"])(element) && Object(external_wp_hooks_["hasFilter"])('blocks.getSaveContent.extraProps') && !hasLightBlockWrapper) { 3851 /** 3852 * Filters the props applied to the block save result element. 3853 * 3854 * @param {Object} props Props applied to save element. 3855 * @param {WPBlock} blockType Block type definition. 3856 * @param {Object} attributes Block attributes. 3857 */ 3858 const props = Object(external_wp_hooks_["applyFilters"])('blocks.getSaveContent.extraProps', { ...element.props 3859 }, blockType, attributes); 3860 3861 if (!external_wp_isShallowEqual_default()(props, element.props)) { 3862 element = Object(external_wp_element_["cloneElement"])(element, props); 3863 } 3864 } 3865 /** 3866 * Filters the save result of a block during serialization. 3867 * 3868 * @param {WPElement} element Block save result. 3869 * @param {WPBlock} blockType Block type definition. 3870 * @param {Object} attributes Block attributes. 3871 */ 3872 3873 3874 element = Object(external_wp_hooks_["applyFilters"])('blocks.getSaveElement', element, blockType, attributes); 3875 return Object(external_wp_element_["createElement"])(block_content_provider, { 3876 innerBlocks: innerBlocks 3877 }, element); 3878 } 3879 /** 3880 * Given a block type containing a save render implementation and attributes, returns the 3881 * static markup to be saved. 3882 * 3883 * @param {string|Object} blockTypeOrName Block type or name. 3884 * @param {Object} attributes Block attributes. 3885 * @param {?Array} innerBlocks Nested blocks. 3886 * 3887 * @return {string} Save content. 3888 */ 3889 3890 function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 3891 const blockType = normalizeBlockType(blockTypeOrName); 3892 return Object(external_wp_element_["renderToString"])(getSaveElement(blockType, attributes, innerBlocks)); 3893 } 3894 /** 3895 * Returns attributes which are to be saved and serialized into the block 3896 * comment delimiter. 3897 * 3898 * When a block exists in memory it contains as its attributes both those 3899 * parsed the block comment delimiter _and_ those which matched from the 3900 * contents of the block. 3901 * 3902 * This function returns only those attributes which are needed to persist and 3903 * which cannot be matched from the block content. 3904 * 3905 * @param {Object<string,*>} blockType Block type. 3906 * @param {Object<string,*>} attributes Attributes from in-memory block data. 3907 * 3908 * @return {Object<string,*>} Subset of attributes for comment serialization. 3909 */ 3910 3911 function getCommentAttributes(blockType, attributes) { 3912 return Object(external_lodash_["reduce"])(blockType.attributes, (accumulator, attributeSchema, key) => { 3913 const value = attributes[key]; // Ignore undefined values. 3914 3915 if (undefined === value) { 3916 return accumulator; 3917 } // Ignore all attributes but the ones with an "undefined" source 3918 // "undefined" source refers to attributes saved in the block comment. 3919 3920 3921 if (attributeSchema.source !== undefined) { 3922 return accumulator; 3923 } // Ignore default value. 3924 3925 3926 if ('default' in attributeSchema && attributeSchema.default === value) { 3927 return accumulator; 3928 } // Otherwise, include in comment set. 3929 3930 3931 accumulator[key] = value; 3932 return accumulator; 3933 }, {}); 3934 } 3935 /** 3936 * Given an attributes object, returns a string in the serialized attributes 3937 * format prepared for post content. 3938 * 3939 * @param {Object} attributes Attributes object. 3940 * 3941 * @return {string} Serialized attributes. 3942 */ 3943 3944 function serializeAttributes(attributes) { 3945 return JSON.stringify(attributes) // Don't break HTML comments. 3946 .replace(/--/g, '\\u002d\\u002d') // Don't break non-standard-compliant tools. 3947 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') // Bypass server stripslashes behavior which would unescape stringify's 3948 // escaping of quotation mark. 3949 // 3950 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 3951 .replace(/\\"/g, '\\u0022'); 3952 } 3953 /** 3954 * Given a block object, returns the Block's Inner HTML markup. 3955 * 3956 * @param {Object} block Block instance. 3957 * 3958 * @return {string} HTML. 3959 */ 3960 3961 function getBlockInnerHTML(block) { 3962 // If block was parsed as invalid or encounters an error while generating 3963 // save content, use original content instead to avoid content loss. If a 3964 // block contains nested content, exempt it from this condition because we 3965 // otherwise have no access to its original content and content loss would 3966 // still occur. 3967 let saveContent = block.originalContent; 3968 3969 if (block.isValid || block.innerBlocks.length) { 3970 try { 3971 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 3972 } catch (error) {} 3973 } 3974 3975 return saveContent; 3976 } 3977 /** 3978 * Returns the content of a block, including comment delimiters. 3979 * 3980 * @param {string} rawBlockName Block name. 3981 * @param {Object} attributes Block attributes. 3982 * @param {string} content Block save content. 3983 * 3984 * @return {string} Comment-delimited block content. 3985 */ 3986 3987 function getCommentDelimitedContent(rawBlockName, attributes, content) { 3988 const serializedAttributes = !Object(external_lodash_["isEmpty"])(attributes) ? serializeAttributes(attributes) + ' ' : ''; // Strip core blocks of their namespace prefix. 3989 3990 const blockName = Object(external_lodash_["startsWith"])(rawBlockName, 'core/') ? rawBlockName.slice(5) : rawBlockName; // @todo make the `wp:` prefix potentially configurable. 3991 3992 if (!content) { 3993 return `<!-- wp:${blockName} ${serializedAttributes}/-->`; 3994 } 3995 3996 return `<!-- wp:${blockName} ${serializedAttributes}-->\n` + content + `\n<!-- /wp:${blockName} -->`; 3997 } 3998 /** 3999 * Returns the content of a block, including comment delimiters, determining 4000 * serialized attributes and content form from the current state of the block. 4001 * 4002 * @param {Object} block Block instance. 4003 * @param {WPBlockSerializationOptions} options Serialization options. 4004 * 4005 * @return {string} Serialized block. 4006 */ 4007 4008 function serializeBlock(block, { 4009 isInnerBlocks = false 4010 } = {}) { 4011 const blockName = block.name; 4012 const saveContent = getBlockInnerHTML(block); 4013 4014 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 4015 return saveContent; 4016 } 4017 4018 const blockType = registration_getBlockType(blockName); 4019 const saveAttributes = getCommentAttributes(blockType, block.attributes); 4020 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 4021 } 4022 function __unstableSerializeAndClean(blocks) { 4023 // A single unmodified default block is assumed to 4024 // be equivalent to an empty post. 4025 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 4026 blocks = []; 4027 } 4028 4029 let content = serialize(blocks); // For compatibility, treat a post consisting of a 4030 // single freeform block as legacy content and apply 4031 // pre-block-editor removep'd content formatting. 4032 4033 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName()) { 4034 content = Object(external_wp_autop_["removep"])(content); 4035 } 4036 4037 return content; 4038 } 4039 /** 4040 * Takes a block or set of blocks and returns the serialized post content. 4041 * 4042 * @param {Array} blocks Block(s) to serialize. 4043 * @param {WPBlockSerializationOptions} options Serialization options. 4044 * 4045 * @return {string} The post content. 4046 */ 4047 4048 function serialize(blocks, options) { 4049 return Object(external_lodash_["castArray"])(blocks).map(block => serializeBlock(block, options)).join('\n\n'); 4050 } 4051 4052 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/index.js 4053 /** 4054 * External dependencies 4055 */ 4056 4057 4058 /** 4059 * WordPress dependencies 4060 */ 4061 4062 4063 /** 4064 * Internal dependencies 4065 */ 4066 4067 4068 4069 4070 /** 4071 * Globally matches any consecutive whitespace 4072 * 4073 * @type {RegExp} 4074 */ 4075 4076 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 4077 /** 4078 * Matches a string containing only whitespace 4079 * 4080 * @type {RegExp} 4081 */ 4082 4083 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 4084 /** 4085 * Matches a CSS URL type value 4086 * 4087 * @type {RegExp} 4088 */ 4089 4090 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 4091 /** 4092 * Boolean attributes are attributes whose presence as being assigned is 4093 * meaningful, even if only empty. 4094 * 4095 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 4096 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 4097 * 4098 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 4099 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 4100 * .reduce( ( result, tr ) => Object.assign( result, { 4101 * [ tr.firstChild.textContent.trim() ]: true 4102 * } ), {} ) ).sort(); 4103 * 4104 * @type {Array} 4105 */ 4106 4107 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']; 4108 /** 4109 * Enumerated attributes are attributes which must be of a specific value form. 4110 * Like boolean attributes, these are meaningful if specified, even if not of a 4111 * valid enumerated value. 4112 * 4113 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 4114 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 4115 * 4116 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 4117 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 4118 * .reduce( ( result, tr ) => Object.assign( result, { 4119 * [ tr.firstChild.textContent.trim() ]: true 4120 * } ), {} ) ).sort(); 4121 * 4122 * @type {Array} 4123 */ 4124 4125 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']; 4126 /** 4127 * Meaningful attributes are those who cannot be safely ignored when omitted in 4128 * one HTML markup string and not another. 4129 * 4130 * @type {Array} 4131 */ 4132 4133 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 4134 /** 4135 * Array of functions which receive a text string on which to apply normalizing 4136 * behavior for consideration in text token equivalence, carefully ordered from 4137 * least-to-most expensive operations. 4138 * 4139 * @type {Array} 4140 */ 4141 4142 const TEXT_NORMALIZATIONS = [external_lodash_["identity"], getTextWithCollapsedWhitespace]; 4143 /** 4144 * Regular expression matching a named character reference. In lieu of bundling 4145 * a full set of references, the pattern covers the minimal necessary to test 4146 * positively against the full set. 4147 * 4148 * "The ampersand must be followed by one of the names given in the named 4149 * character references section, using the same case." 4150 * 4151 * Tested aginst "12.5 Named character references": 4152 * 4153 * ``` 4154 * const references = Array.from( document.querySelectorAll( 4155 * '#named-character-references-table tr[id^=entity-] td:first-child' 4156 * ) ).map( ( code ) => code.textContent ) 4157 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 4158 * ``` 4159 * 4160 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 4161 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 4162 * 4163 * @type {RegExp} 4164 */ 4165 4166 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 4167 /** 4168 * Regular expression matching a decimal character reference. 4169 * 4170 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 4171 * followed by one or more ASCII digits, representing a base-ten integer" 4172 * 4173 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 4174 * 4175 * @type {RegExp} 4176 */ 4177 4178 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 4179 /** 4180 * Regular expression matching a hexadecimal character reference. 4181 * 4182 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 4183 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 4184 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 4185 * one or more ASCII hex digits, representing a hexadecimal integer" 4186 * 4187 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 4188 * 4189 * @type {RegExp} 4190 */ 4191 4192 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 4193 /** 4194 * Returns true if the given string is a valid character reference segment, or 4195 * false otherwise. The text should be stripped of `&` and `;` demarcations. 4196 * 4197 * @param {string} text Text to test. 4198 * 4199 * @return {boolean} Whether text is valid character reference. 4200 */ 4201 4202 function isValidCharacterReference(text) { 4203 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 4204 } 4205 /** 4206 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the 4207 * implementation of `decodeEntities` from `html-entities`, in order to avoid 4208 * bundling a massive named character reference. 4209 * 4210 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 4211 */ 4212 4213 class validation_DecodeEntityParser { 4214 /** 4215 * Returns a substitute string for an entity string sequence between `&` 4216 * and `;`, or undefined if no substitution should occur. 4217 * 4218 * @param {string} entity Entity fragment discovered in HTML. 4219 * 4220 * @return {?string} Entity substitute value. 4221 */ 4222 parse(entity) { 4223 if (isValidCharacterReference(entity)) { 4224 return Object(external_wp_htmlEntities_["decodeEntities"])('&' + entity + ';'); 4225 } 4226 } 4227 4228 } 4229 /** 4230 * Given a specified string, returns an array of strings split by consecutive 4231 * whitespace, ignoring leading or trailing whitespace. 4232 * 4233 * @param {string} text Original text. 4234 * 4235 * @return {string[]} Text pieces split on whitespace. 4236 */ 4237 4238 function getTextPiecesSplitOnWhitespace(text) { 4239 return text.trim().split(REGEXP_WHITESPACE); 4240 } 4241 /** 4242 * Given a specified string, returns a new trimmed string where all consecutive 4243 * whitespace is collapsed to a single space. 4244 * 4245 * @param {string} text Original text. 4246 * 4247 * @return {string} Trimmed text with consecutive whitespace collapsed. 4248 */ 4249 4250 function getTextWithCollapsedWhitespace(text) { 4251 // This is an overly simplified whitespace comparison. The specification is 4252 // more prescriptive of whitespace behavior in inline and block contexts. 4253 // 4254 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33 4255 return getTextPiecesSplitOnWhitespace(text).join(' '); 4256 } 4257 /** 4258 * Returns attribute pairs of the given StartTag token, including only pairs 4259 * where the value is non-empty or the attribute is a boolean attribute, an 4260 * enumerated attribute, or a custom data- attribute. 4261 * 4262 * @see MEANINGFUL_ATTRIBUTES 4263 * 4264 * @param {Object} token StartTag token. 4265 * 4266 * @return {Array[]} Attribute pairs. 4267 */ 4268 4269 function getMeaningfulAttributePairs(token) { 4270 return token.attributes.filter(pair => { 4271 const [key, value] = pair; 4272 return value || key.indexOf('data-') === 0 || Object(external_lodash_["includes"])(MEANINGFUL_ATTRIBUTES, key); 4273 }); 4274 } 4275 /** 4276 * Returns true if two text tokens (with `chars` property) are equivalent, or 4277 * false otherwise. 4278 * 4279 * @param {Object} actual Actual token. 4280 * @param {Object} expected Expected token. 4281 * @param {Object} logger Validation logger object. 4282 * 4283 * @return {boolean} Whether two text tokens are equivalent. 4284 */ 4285 4286 function isEquivalentTextTokens(actual, expected, logger = createLogger()) { 4287 // This function is intentionally written as syntactically "ugly" as a hot 4288 // path optimization. Text is progressively normalized in order from least- 4289 // to-most operationally expensive, until the earliest point at which text 4290 // can be confidently inferred as being equal. 4291 let actualChars = actual.chars; 4292 let expectedChars = expected.chars; 4293 4294 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 4295 const normalize = TEXT_NORMALIZATIONS[i]; 4296 actualChars = normalize(actualChars); 4297 expectedChars = normalize(expectedChars); 4298 4299 if (actualChars === expectedChars) { 4300 return true; 4301 } 4302 } 4303 4304 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 4305 return false; 4306 } 4307 /** 4308 * Given a CSS length value, returns a normalized CSS length value for strict equality 4309 * comparison. 4310 * 4311 * @param {string} value CSS length value. 4312 * 4313 * @return {string} Normalized CSS length value. 4314 */ 4315 4316 function getNormalizedLength(value) { 4317 return 0 === parseFloat(value) ? '0' : value; 4318 } 4319 /** 4320 * Given a style value, returns a normalized style value for strict equality 4321 * comparison. 4322 * 4323 * @param {string} value Style value. 4324 * 4325 * @return {string} Normalized style value. 4326 */ 4327 4328 function getNormalizedStyleValue(value) { 4329 const textPieces = getTextPiecesSplitOnWhitespace(value); 4330 const normalizedPieces = textPieces.map(getNormalizedLength); 4331 const result = normalizedPieces.join(' '); 4332 return result // Normalize URL type to omit whitespace or quotes 4333 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 4334 } 4335 /** 4336 * Given a style attribute string, returns an object of style properties. 4337 * 4338 * @param {string} text Style attribute. 4339 * 4340 * @return {Object} Style properties. 4341 */ 4342 4343 function getStyleProperties(text) { 4344 const pairs = text // Trim ending semicolon (avoid including in split) 4345 .replace(/;?\s*$/, '') // Split on property assignment 4346 .split(';') // For each property assignment... 4347 .map(style => { 4348 // ...split further into key-value pairs 4349 const [key, ...valueParts] = style.split(':'); 4350 const value = valueParts.join(':'); 4351 return [key.trim(), getNormalizedStyleValue(value.trim())]; 4352 }); 4353 return Object(external_lodash_["fromPairs"])(pairs); 4354 } 4355 /** 4356 * Attribute-specific equality handlers 4357 * 4358 * @type {Object} 4359 */ 4360 4361 const isEqualAttributesOfName = { 4362 class: (actual, expected) => { 4363 // Class matches if members are the same, even if out of order or 4364 // superfluous whitespace between. 4365 return !Object(external_lodash_["xor"])(...[actual, expected].map(getTextPiecesSplitOnWhitespace)).length; 4366 }, 4367 style: (actual, expected) => { 4368 return Object(external_lodash_["isEqual"])(...[actual, expected].map(getStyleProperties)); 4369 }, 4370 // For each boolean attribute, mere presence of attribute in both is enough 4371 // to assume equivalence. 4372 ...Object(external_lodash_["fromPairs"])(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, external_lodash_["stubTrue"]])) 4373 }; 4374 /** 4375 * Given two sets of attribute tuples, returns true if the attribute sets are 4376 * equivalent. 4377 * 4378 * @param {Array[]} actual Actual attributes tuples. 4379 * @param {Array[]} expected Expected attributes tuples. 4380 * @param {Object} logger Validation logger object. 4381 * 4382 * @return {boolean} Whether attributes are equivalent. 4383 */ 4384 4385 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) { 4386 // Attributes is tokenized as tuples. Their lengths should match. This also 4387 // avoids us needing to check both attributes sets, since if A has any keys 4388 // which do not exist in B, we know the sets to be different. 4389 if (actual.length !== expected.length) { 4390 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 4391 return false; 4392 } // Attributes are not guaranteed to occur in the same order. For validating 4393 // actual attributes, first convert the set of expected attribute values to 4394 // an object, for lookup by key. 4395 4396 4397 const expectedAttributes = {}; 4398 4399 for (let i = 0; i < expected.length; i++) { 4400 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 4401 } 4402 4403 for (let i = 0; i < actual.length; i++) { 4404 const [name, actualValue] = actual[i]; 4405 const nameLower = name.toLowerCase(); // As noted above, if missing member in B, assume different 4406 4407 if (!expectedAttributes.hasOwnProperty(nameLower)) { 4408 logger.warning('Encountered unexpected attribute `%s`.', name); 4409 return false; 4410 } 4411 4412 const expectedValue = expectedAttributes[nameLower]; 4413 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 4414 4415 if (isEqualAttributes) { 4416 // Defer custom attribute equality handling 4417 if (!isEqualAttributes(actualValue, expectedValue)) { 4418 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 4419 return false; 4420 } 4421 } else if (actualValue !== expectedValue) { 4422 // Otherwise strict inequality should bail 4423 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 4424 return false; 4425 } 4426 } 4427 4428 return true; 4429 } 4430 /** 4431 * Token-type-specific equality handlers 4432 * 4433 * @type {Object} 4434 */ 4435 4436 const isEqualTokensOfType = { 4437 StartTag: (actual, expected, logger = createLogger()) => { 4438 if (actual.tagName !== expected.tagName && // Optimization: Use short-circuit evaluation to defer case- 4439 // insensitive check on the assumption that the majority case will 4440 // have exactly equal tag names. 4441 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 4442 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 4443 return false; 4444 } 4445 4446 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 4447 }, 4448 Chars: isEquivalentTextTokens, 4449 Comment: isEquivalentTextTokens 4450 }; 4451 /** 4452 * Given an array of tokens, returns the first token which is not purely 4453 * whitespace. 4454 * 4455 * Mutates the tokens array. 4456 * 4457 * @param {Object[]} tokens Set of tokens to search. 4458 * 4459 * @return {Object} Next non-whitespace token. 4460 */ 4461 4462 function getNextNonWhitespaceToken(tokens) { 4463 let token; 4464 4465 while (token = tokens.shift()) { 4466 if (token.type !== 'Chars') { 4467 return token; 4468 } 4469 4470 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 4471 return token; 4472 } 4473 } 4474 } 4475 /** 4476 * Tokenize an HTML string, gracefully handling any errors thrown during 4477 * underlying tokenization. 4478 * 4479 * @param {string} html HTML string to tokenize. 4480 * @param {Object} logger Validation logger object. 4481 * 4482 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 4483 */ 4484 4485 function getHTMLTokens(html, logger = createLogger()) { 4486 try { 4487 return new Tokenizer(new validation_DecodeEntityParser()).tokenize(html); 4488 } catch (e) { 4489 logger.warning('Malformed HTML detected: %s', html); 4490 } 4491 4492 return null; 4493 } 4494 /** 4495 * Returns true if the next HTML token closes the current token. 4496 * 4497 * @param {Object} currentToken Current token to compare with. 4498 * @param {Object|undefined} nextToken Next token to compare against. 4499 * 4500 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 4501 */ 4502 4503 4504 function isClosedByToken(currentToken, nextToken) { 4505 // Ensure this is a self closed token 4506 if (!currentToken.selfClosing) { 4507 return false; 4508 } // Check token names and determine if nextToken is the closing tag for currentToken 4509 4510 4511 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 4512 return true; 4513 } 4514 4515 return false; 4516 } 4517 /** 4518 * Returns true if the given HTML strings are effectively equivalent, or 4519 * false otherwise. Invalid HTML is not considered equivalent, even if the 4520 * strings directly match. 4521 * 4522 * @param {string} actual Actual HTML string. 4523 * @param {string} expected Expected HTML string. 4524 * @param {Object} logger Validation logger object. 4525 * 4526 * @return {boolean} Whether HTML strings are equivalent. 4527 */ 4528 4529 function isEquivalentHTML(actual, expected, logger = createLogger()) { 4530 // Short-circuit if markup is identical. 4531 if (actual === expected) { 4532 return true; 4533 } // Tokenize input content and reserialized save content 4534 4535 4536 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); // If either is malformed then stop comparing - the strings are not equivalent 4537 4538 if (!actualTokens || !expectedTokens) { 4539 return false; 4540 } 4541 4542 let actualToken, expectedToken; 4543 4544 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 4545 expectedToken = getNextNonWhitespaceToken(expectedTokens); // Inequal if exhausted all expected tokens 4546 4547 if (!expectedToken) { 4548 logger.warning('Expected end of content, instead saw %o.', actualToken); 4549 return false; 4550 } // Inequal if next non-whitespace token of each set are not same type 4551 4552 4553 if (actualToken.type !== expectedToken.type) { 4554 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 4555 return false; 4556 } // Defer custom token type equality handling, otherwise continue and 4557 // assume as equal 4558 4559 4560 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 4561 4562 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 4563 return false; 4564 } // Peek at the next tokens (actual and expected) to see if they close 4565 // a self-closing tag 4566 4567 4568 if (isClosedByToken(actualToken, expectedTokens[0])) { 4569 // Consume the next expected token that closes the current actual 4570 // self-closing token 4571 getNextNonWhitespaceToken(expectedTokens); 4572 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 4573 // Consume the next actual token that closes the current expected 4574 // self-closing token 4575 getNextNonWhitespaceToken(actualTokens); 4576 } 4577 } 4578 4579 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 4580 // If any non-whitespace tokens remain in expected token set, this 4581 // indicates inequality 4582 logger.warning('Expected %o, instead saw end of content.', expectedToken); 4583 return false; 4584 } 4585 4586 return true; 4587 } 4588 /** 4589 * Returns an object with `isValid` property set to `true` if the parsed block 4590 * is valid given the input content. A block is considered valid if, when serialized 4591 * with assumed attributes, the content matches the original value. If block is 4592 * invalid, this function returns all validations issues as well. 4593 * 4594 * @param {string|Object} blockTypeOrName Block type. 4595 * @param {Object} attributes Parsed block attributes. 4596 * @param {string} originalBlockContent Original block content. 4597 * @param {Object} logger Validation logger object. 4598 * 4599 * @return {Object} Whether block is valid and contains validation messages. 4600 */ 4601 4602 function getBlockContentValidationResult(blockTypeOrName, attributes, originalBlockContent, logger = createQueuedLogger()) { 4603 const blockType = normalizeBlockType(blockTypeOrName); 4604 let generatedBlockContent; 4605 4606 try { 4607 generatedBlockContent = getSaveContent(blockType, attributes); 4608 } catch (error) { 4609 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 4610 return { 4611 isValid: false, 4612 validationIssues: logger.getItems() 4613 }; 4614 } 4615 4616 const isValid = isEquivalentHTML(originalBlockContent, generatedBlockContent, logger); 4617 4618 if (!isValid) { 4619 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, originalBlockContent); 4620 } 4621 4622 return { 4623 isValid, 4624 validationIssues: logger.getItems() 4625 }; 4626 } 4627 /** 4628 * Returns true if the parsed block is valid given the input content. A block 4629 * is considered valid if, when serialized with assumed attributes, the content 4630 * matches the original value. 4631 * 4632 * Logs to console in development environments when invalid. 4633 * 4634 * @param {string|Object} blockTypeOrName Block type. 4635 * @param {Object} attributes Parsed block attributes. 4636 * @param {string} originalBlockContent Original block content. 4637 * 4638 * @return {boolean} Whether block is valid. 4639 */ 4640 4641 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 4642 const { 4643 isValid 4644 } = getBlockContentValidationResult(blockTypeOrName, attributes, originalBlockContent, createLogger()); 4645 return isValid; 4646 } 4647 4648 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/matchers.js 4649 /** 4650 * External dependencies 4651 */ 4652 4653 /** 4654 * Internal dependencies 4655 */ 4656 4657 4658 4659 function matchers_html(selector, multilineTag) { 4660 return domNode => { 4661 let match = domNode; 4662 4663 if (selector) { 4664 match = domNode.querySelector(selector); 4665 } 4666 4667 if (!match) { 4668 return ''; 4669 } 4670 4671 if (multilineTag) { 4672 let value = ''; 4673 const length = match.children.length; 4674 4675 for (let index = 0; index < length; index++) { 4676 const child = match.children[index]; 4677 4678 if (child.nodeName.toLowerCase() !== multilineTag) { 4679 continue; 4680 } 4681 4682 value += child.outerHTML; 4683 } 4684 4685 return value; 4686 } 4687 4688 return match.innerHTML; 4689 }; 4690 } 4691 4692 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/node.js 4693 /** 4694 * Internal dependencies 4695 */ 4696 4697 /** 4698 * A representation of a single node within a block's rich text value. If 4699 * representing a text node, the value is simply a string of the node value. 4700 * As representing an element node, it is an object of: 4701 * 4702 * 1. `type` (string): Tag name. 4703 * 2. `props` (object): Attributes and children array of WPBlockNode. 4704 * 4705 * @typedef {string|Object} WPBlockNode 4706 */ 4707 4708 /** 4709 * Given a single node and a node type (e.g. `'br'`), returns true if the node 4710 * corresponds to that type, false otherwise. 4711 * 4712 * @param {WPBlockNode} node Block node to test 4713 * @param {string} type Node to type to test against. 4714 * 4715 * @return {boolean} Whether node is of intended type. 4716 */ 4717 4718 function isNodeOfType(node, type) { 4719 return node && node.type === type; 4720 } 4721 /** 4722 * Given an object implementing the NamedNodeMap interface, returns a plain 4723 * object equivalent value of name, value key-value pairs. 4724 * 4725 * @see https://dom.spec.whatwg.org/#interface-namednodemap 4726 * 4727 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 4728 * 4729 * @return {Object} Object equivalent value of NamedNodeMap. 4730 */ 4731 4732 4733 function getNamedNodeMapAsObject(nodeMap) { 4734 const result = {}; 4735 4736 for (let i = 0; i < nodeMap.length; i++) { 4737 const { 4738 name, 4739 value 4740 } = nodeMap[i]; 4741 result[name] = value; 4742 } 4743 4744 return result; 4745 } 4746 /** 4747 * Given a DOM Element or Text node, returns an equivalent block node. Throws 4748 * if passed any node type other than element or text. 4749 * 4750 * @throws {TypeError} If non-element/text node is passed. 4751 * 4752 * @param {Node} domNode DOM node to convert. 4753 * 4754 * @return {WPBlockNode} Block node equivalent to DOM node. 4755 */ 4756 4757 function fromDOM(domNode) { 4758 if (domNode.nodeType === domNode.TEXT_NODE) { 4759 return domNode.nodeValue; 4760 } 4761 4762 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 4763 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 4764 } 4765 4766 return { 4767 type: domNode.nodeName.toLowerCase(), 4768 props: { ...getNamedNodeMapAsObject(domNode.attributes), 4769 children: children_fromDOM(domNode.childNodes) 4770 } 4771 }; 4772 } 4773 /** 4774 * Given a block node, returns its HTML string representation. 4775 * 4776 * @param {WPBlockNode} node Block node to convert to string. 4777 * 4778 * @return {string} String HTML representation of block node. 4779 */ 4780 4781 function toHTML(node) { 4782 return children_toHTML([node]); 4783 } 4784 /** 4785 * Given a selector, returns an hpq matcher generating a WPBlockNode value 4786 * matching the selector result. 4787 * 4788 * @param {string} selector DOM selector. 4789 * 4790 * @return {Function} hpq matcher. 4791 */ 4792 4793 function node_matcher(selector) { 4794 return domNode => { 4795 let match = domNode; 4796 4797 if (selector) { 4798 match = domNode.querySelector(selector); 4799 } 4800 4801 try { 4802 return fromDOM(match); 4803 } catch (error) { 4804 return null; 4805 } 4806 }; 4807 } 4808 /** 4809 * Object of utility functions used in managing block attribute values of 4810 * source `node`. 4811 * 4812 * @see https://github.com/WordPress/gutenberg/pull/10439 4813 * 4814 * @deprecated since 4.0. The `node` source should not be used, and can be 4815 * replaced by the `html` source. 4816 * 4817 * @private 4818 */ 4819 4820 /* harmony default export */ var api_node = ({ 4821 isNodeOfType, 4822 fromDOM, 4823 toHTML, 4824 matcher: node_matcher 4825 }); 4826 4827 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/children.js 4828 /** 4829 * External dependencies 4830 */ 4831 4832 /** 4833 * WordPress dependencies 4834 */ 4835 4836 4837 /** 4838 * Internal dependencies 4839 */ 4840 4841 4842 /** 4843 * A representation of a block's rich text value. 4844 * 4845 * @typedef {WPBlockNode[]} WPBlockChildren 4846 */ 4847 4848 /** 4849 * Given block children, returns a serialize-capable WordPress element. 4850 * 4851 * @param {WPBlockChildren} children Block children object to convert. 4852 * 4853 * @return {WPElement} A serialize-capable element. 4854 */ 4855 4856 function getSerializeCapableElement(children) { 4857 // The fact that block children are compatible with the element serializer is 4858 // merely an implementation detail that currently serves to be true, but 4859 // should not be mistaken as being a guarantee on the external API. The 4860 // public API only offers guarantees to work with strings (toHTML) and DOM 4861 // elements (fromDOM), and should provide utilities to manipulate the value 4862 // rather than expect consumers to inspect or construct its shape (concat). 4863 return children; 4864 } 4865 /** 4866 * Given block children, returns an array of block nodes. 4867 * 4868 * @param {WPBlockChildren} children Block children object to convert. 4869 * 4870 * @return {Array<WPBlockNode>} An array of individual block nodes. 4871 */ 4872 4873 function getChildrenArray(children) { 4874 // The fact that block children are compatible with the element serializer 4875 // is merely an implementation detail that currently serves to be true, but 4876 // should not be mistaken as being a guarantee on the external API. 4877 return children; 4878 } 4879 /** 4880 * Given two or more block nodes, returns a new block node representing a 4881 * concatenation of its values. 4882 * 4883 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 4884 * 4885 * @return {WPBlockChildren} Concatenated block node. 4886 */ 4887 4888 4889 function concat(...blockNodes) { 4890 const result = []; 4891 4892 for (let i = 0; i < blockNodes.length; i++) { 4893 const blockNode = Object(external_lodash_["castArray"])(blockNodes[i]); 4894 4895 for (let j = 0; j < blockNode.length; j++) { 4896 const child = blockNode[j]; 4897 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 4898 4899 if (canConcatToPreviousString) { 4900 result[result.length - 1] += child; 4901 } else { 4902 result.push(child); 4903 } 4904 } 4905 } 4906 4907 return result; 4908 } 4909 /** 4910 * Given an iterable set of DOM nodes, returns equivalent block children. 4911 * Ignores any non-element/text nodes included in set. 4912 * 4913 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 4914 * 4915 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 4916 */ 4917 4918 function children_fromDOM(domNodes) { 4919 const result = []; 4920 4921 for (let i = 0; i < domNodes.length; i++) { 4922 try { 4923 result.push(fromDOM(domNodes[i])); 4924 } catch (error) {// Simply ignore if DOM node could not be converted. 4925 } 4926 } 4927 4928 return result; 4929 } 4930 /** 4931 * Given a block node, returns its HTML string representation. 4932 * 4933 * @param {WPBlockChildren} children Block node(s) to convert to string. 4934 * 4935 * @return {string} String HTML representation of block node. 4936 */ 4937 4938 function children_toHTML(children) { 4939 const element = getSerializeCapableElement(children); 4940 return Object(external_wp_element_["renderToString"])(element); 4941 } 4942 /** 4943 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 4944 * matching the selector result. 4945 * 4946 * @param {string} selector DOM selector. 4947 * 4948 * @return {Function} hpq matcher. 4949 */ 4950 4951 function children_matcher(selector) { 4952 return domNode => { 4953 let match = domNode; 4954 4955 if (selector) { 4956 match = domNode.querySelector(selector); 4957 } 4958 4959 if (match) { 4960 return children_fromDOM(match.childNodes); 4961 } 4962 4963 return []; 4964 }; 4965 } 4966 /** 4967 * Object of utility functions used in managing block attribute values of 4968 * source `children`. 4969 * 4970 * @see https://github.com/WordPress/gutenberg/pull/10439 4971 * 4972 * @deprecated since 4.0. The `children` source should not be used, and can be 4973 * replaced by the `html` source. 4974 * 4975 * @private 4976 */ 4977 4978 /* harmony default export */ var api_children = ({ 4979 concat, 4980 getChildrenArray, 4981 fromDOM: children_fromDOM, 4982 toHTML: children_toHTML, 4983 matcher: children_matcher 4984 }); 4985 4986 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser.js 4987 /** 4988 * External dependencies 4989 */ 4990 4991 4992 /** 4993 * WordPress dependencies 4994 */ 4995 4996 4997 4998 4999 /** 5000 * Internal dependencies 5001 */ 5002 5003 5004 5005 5006 5007 5008 5009 5010 /** 5011 * Sources which are guaranteed to return a string value. 5012 * 5013 * @type {Set} 5014 */ 5015 5016 const STRING_SOURCES = new Set(['attribute', 'html', 'text', 'tag']); 5017 /** 5018 * Higher-order hpq matcher which enhances an attribute matcher to return true 5019 * or false depending on whether the original matcher returns undefined. This 5020 * is useful for boolean attributes (e.g. disabled) whose attribute values may 5021 * be technically falsey (empty string), though their mere presence should be 5022 * enough to infer as true. 5023 * 5024 * @param {Function} matcher Original hpq matcher. 5025 * 5026 * @return {Function} Enhanced hpq matcher. 5027 */ 5028 5029 const toBooleanAttributeMatcher = matcher => Object(external_lodash_["flow"])([matcher, // Expected values from `attr( 'disabled' )`: 5030 // 5031 // <input> 5032 // - Value: `undefined` 5033 // - Transformed: `false` 5034 // 5035 // <input disabled> 5036 // - Value: `''` 5037 // - Transformed: `true` 5038 // 5039 // <input disabled="disabled"> 5040 // - Value: `'disabled'` 5041 // - Transformed: `true` 5042 value => value !== undefined]); 5043 /** 5044 * Returns true if value is of the given JSON schema type, or false otherwise. 5045 * 5046 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 5047 * 5048 * @param {*} value Value to test. 5049 * @param {string} type Type to test. 5050 * 5051 * @return {boolean} Whether value is of type. 5052 */ 5053 5054 function isOfType(value, type) { 5055 switch (type) { 5056 case 'string': 5057 return typeof value === 'string'; 5058 5059 case 'boolean': 5060 return typeof value === 'boolean'; 5061 5062 case 'object': 5063 return !!value && value.constructor === Object; 5064 5065 case 'null': 5066 return value === null; 5067 5068 case 'array': 5069 return Array.isArray(value); 5070 5071 case 'integer': 5072 case 'number': 5073 return typeof value === 'number'; 5074 } 5075 5076 return true; 5077 } 5078 /** 5079 * Returns true if value is of an array of given JSON schema types, or false 5080 * otherwise. 5081 * 5082 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 5083 * 5084 * @param {*} value Value to test. 5085 * @param {string[]} types Types to test. 5086 * 5087 * @return {boolean} Whether value is of types. 5088 */ 5089 5090 function isOfTypes(value, types) { 5091 return types.some(type => isOfType(value, type)); 5092 } 5093 /** 5094 * Returns true if value is valid per the given block attribute schema type 5095 * definition, or false otherwise. 5096 * 5097 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 5098 * 5099 * @param {*} value Value to test. 5100 * @param {?(Array<string>|string)} type Block attribute schema type. 5101 * 5102 * @return {boolean} Whether value is valid. 5103 */ 5104 5105 function isValidByType(value, type) { 5106 return type === undefined || isOfTypes(value, Object(external_lodash_["castArray"])(type)); 5107 } 5108 /** 5109 * Returns true if value is valid per the given block attribute schema enum 5110 * definition, or false otherwise. 5111 * 5112 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 5113 * 5114 * @param {*} value Value to test. 5115 * @param {?Array} enumSet Block attribute schema enum. 5116 * 5117 * @return {boolean} Whether value is valid. 5118 */ 5119 5120 function isValidByEnum(value, enumSet) { 5121 return !Array.isArray(enumSet) || enumSet.includes(value); 5122 } 5123 /** 5124 * Returns true if the given attribute schema describes a value which may be 5125 * an ambiguous string. 5126 * 5127 * Some sources are ambiguously serialized as strings, for which value casting 5128 * is enabled. This is only possible when a singular type is assigned to the 5129 * attribute schema, since the string ambiguity makes it impossible to know the 5130 * correct type of multiple to which to cast. 5131 * 5132 * @param {Object} attributeSchema Attribute's schema. 5133 * 5134 * @return {boolean} Whether attribute schema defines an ambiguous string 5135 * source. 5136 */ 5137 5138 function isAmbiguousStringSource(attributeSchema) { 5139 const { 5140 source, 5141 type 5142 } = attributeSchema; 5143 const isStringSource = STRING_SOURCES.has(source); 5144 const isSingleType = typeof type === 'string'; 5145 return isStringSource && isSingleType; 5146 } 5147 /** 5148 * Returns an hpq matcher given a source object. 5149 * 5150 * @param {Object} sourceConfig Attribute Source object. 5151 * 5152 * @return {Function} A hpq Matcher. 5153 */ 5154 5155 function matcherFromSource(sourceConfig) { 5156 switch (sourceConfig.source) { 5157 case 'attribute': 5158 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 5159 5160 if (sourceConfig.type === 'boolean') { 5161 matcher = toBooleanAttributeMatcher(matcher); 5162 } 5163 5164 return matcher; 5165 5166 case 'html': 5167 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 5168 5169 case 'text': 5170 return es_text(sourceConfig.selector); 5171 5172 case 'children': 5173 return children_matcher(sourceConfig.selector); 5174 5175 case 'node': 5176 return node_matcher(sourceConfig.selector); 5177 5178 case 'query': 5179 const subMatchers = Object(external_lodash_["mapValues"])(sourceConfig.query, matcherFromSource); 5180 return query(sourceConfig.selector, subMatchers); 5181 5182 case 'tag': 5183 return Object(external_lodash_["flow"])([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]); 5184 5185 default: 5186 // eslint-disable-next-line no-console 5187 console.error(`Unknown source type "${sourceConfig.source}"`); 5188 } 5189 } 5190 /** 5191 * Given a block's raw content and an attribute's schema returns the attribute's 5192 * value depending on its source. 5193 * 5194 * @param {string} innerHTML Block's raw content. 5195 * @param {Object} attributeSchema Attribute's schema. 5196 * 5197 * @return {*} Attribute value. 5198 */ 5199 5200 function parseWithAttributeSchema(innerHTML, attributeSchema) { 5201 return parse(innerHTML, matcherFromSource(attributeSchema)); 5202 } 5203 /** 5204 * Given an attribute key, an attribute's schema, a block's raw content and the 5205 * commentAttributes returns the attribute value depending on its source 5206 * definition of the given attribute key. 5207 * 5208 * @param {string} attributeKey Attribute key. 5209 * @param {Object} attributeSchema Attribute's schema. 5210 * @param {string} innerHTML Block's raw content. 5211 * @param {Object} commentAttributes Block's comment attributes. 5212 * 5213 * @return {*} Attribute value. 5214 */ 5215 5216 function getBlockAttribute(attributeKey, attributeSchema, innerHTML, commentAttributes) { 5217 const { 5218 type, 5219 enum: enumSet 5220 } = attributeSchema; 5221 let value; 5222 5223 switch (attributeSchema.source) { 5224 // An undefined source means that it's an attribute serialized to the 5225 // block's "comment". 5226 case undefined: 5227 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 5228 break; 5229 5230 case 'attribute': 5231 case 'property': 5232 case 'html': 5233 case 'text': 5234 case 'children': 5235 case 'node': 5236 case 'query': 5237 case 'tag': 5238 value = parseWithAttributeSchema(innerHTML, attributeSchema); 5239 break; 5240 } 5241 5242 if (!isValidByType(value, type) || !isValidByEnum(value, enumSet)) { 5243 // Reject the value if it is not valid. Reverting to the undefined 5244 // value ensures the default is respected, if applicable. 5245 value = undefined; 5246 } 5247 5248 if (value === undefined) { 5249 return attributeSchema.default; 5250 } 5251 5252 return value; 5253 } 5254 /** 5255 * Returns the block attributes of a registered block node given its type. 5256 * 5257 * @param {string|Object} blockTypeOrName Block type or name. 5258 * @param {string} innerHTML Raw block content. 5259 * @param {?Object} attributes Known block attributes (from delimiters). 5260 * 5261 * @return {Object} All block attributes. 5262 */ 5263 5264 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) { 5265 const blockType = normalizeBlockType(blockTypeOrName); 5266 const blockAttributes = Object(external_lodash_["mapValues"])(blockType.attributes, (attributeSchema, attributeKey) => { 5267 return getBlockAttribute(attributeKey, attributeSchema, innerHTML, attributes); 5268 }); 5269 return Object(external_wp_hooks_["applyFilters"])('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 5270 } 5271 /** 5272 * Given a block object, returns a new copy of the block with any applicable 5273 * deprecated migrations applied, or the original block if it was both valid 5274 * and no eligible migrations exist. 5275 * 5276 * @param {WPBlock} block Original block object. 5277 * @param {Object} parsedAttributes Attributes as parsed from the initial 5278 * block markup. 5279 * 5280 * @return {WPBlock} Migrated block object. 5281 */ 5282 5283 function getMigratedBlock(block, parsedAttributes) { 5284 const blockType = registration_getBlockType(block.name); 5285 const { 5286 deprecated: deprecatedDefinitions 5287 } = blockType; // Bail early if there are no registered deprecations to be handled. 5288 5289 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 5290 return block; 5291 } 5292 5293 const { 5294 originalContent, 5295 innerBlocks 5296 } = block; // By design, blocks lack any sort of version tracking. Instead, to process 5297 // outdated content the system operates a queue out of all the defined 5298 // attribute shapes and tries each definition until the input produces a 5299 // valid result. This mechanism seeks to avoid polluting the user-space with 5300 // machine-specific code. An invalid block is thus a block that could not be 5301 // matched successfully with any of the registered deprecation definitions. 5302 5303 for (let i = 0; i < deprecatedDefinitions.length; i++) { 5304 // A block can opt into a migration even if the block is valid by 5305 // defining `isEligible` on its deprecation. If the block is both valid 5306 // and does not opt to migrate, skip. 5307 const { 5308 isEligible = external_lodash_["stubFalse"] 5309 } = deprecatedDefinitions[i]; 5310 5311 if (block.isValid && !isEligible(parsedAttributes, innerBlocks)) { 5312 continue; 5313 } // Block type properties which could impact either serialization or 5314 // parsing are not considered in the deprecated block type by default, 5315 // and must be explicitly provided. 5316 5317 5318 const deprecatedBlockType = Object.assign(Object(external_lodash_["omit"])(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 5319 let migratedAttributes = getBlockAttributes(deprecatedBlockType, originalContent, parsedAttributes); // Ignore the deprecation if it produces a block which is not valid. 5320 5321 const { 5322 isValid, 5323 validationIssues 5324 } = getBlockContentValidationResult(deprecatedBlockType, migratedAttributes, originalContent); // An invalid block does not imply incorrect HTML but the fact block 5325 // source information could be lost on reserialization. 5326 5327 if (!isValid) { 5328 block = { ...block, 5329 validationIssues: [...Object(external_lodash_["get"])(block, 'validationIssues', []), ...validationIssues] 5330 }; 5331 continue; 5332 } 5333 5334 let migratedInnerBlocks = innerBlocks; // A block may provide custom behavior to assign new attributes and/or 5335 // inner blocks. 5336 5337 const { 5338 migrate 5339 } = deprecatedBlockType; 5340 5341 if (migrate) { 5342 [migratedAttributes = parsedAttributes, migratedInnerBlocks = innerBlocks] = Object(external_lodash_["castArray"])(migrate(migratedAttributes, innerBlocks)); 5343 } 5344 5345 block = { ...block, 5346 attributes: migratedAttributes, 5347 innerBlocks: migratedInnerBlocks, 5348 isValid: true 5349 }; 5350 } 5351 5352 return block; 5353 } 5354 /** 5355 * Convert legacy blocks to their canonical form. This function is used 5356 * both in the parser level for previous content and to convert such blocks 5357 * used in Custom Post Types templates. 5358 * 5359 * @param {string} name The block's name 5360 * @param {Object} attributes The block's attributes 5361 * 5362 * @return {Object} The block's name and attributes, changed accordingly if a match was found 5363 */ 5364 5365 function convertLegacyBlocks(name, attributes) { 5366 const newAttributes = { ...attributes 5367 }; // Convert 'core/cover-image' block in existing content to 'core/cover'. 5368 5369 if ('core/cover-image' === name) { 5370 name = 'core/cover'; 5371 } // Convert 'core/text' blocks in existing content to 'core/paragraph'. 5372 5373 5374 if ('core/text' === name || 'core/cover-text' === name) { 5375 name = 'core/paragraph'; 5376 } // Convert derivative blocks such as 'core/social-link-wordpress' to the 5377 // canonical form 'core/social-link'. 5378 5379 5380 if (name && name.indexOf('core/social-link-') === 0) { 5381 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 5382 newAttributes.service = name.substring(17); 5383 name = 'core/social-link'; 5384 } // Convert derivative blocks such as 'core-embed/instagram' to the 5385 // canonical form 'core/embed'. 5386 5387 5388 if (name && name.indexOf('core-embed/') === 0) { 5389 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 5390 const providerSlug = name.substring(11); 5391 const deprecated = { 5392 speaker: 'speaker-deck', 5393 polldaddy: 'crowdsignal' 5394 }; 5395 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; // this is needed as the `responsive` attribute was passed 5396 // in a different way before the refactoring to block variations 5397 5398 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 5399 newAttributes.responsive = true; 5400 } 5401 5402 name = 'core/embed'; 5403 } // Convert 'core/query-loop' blocks in existing content to 'core/post-template'. 5404 // TODO: Remove this check when WordPress 5.9 is released. 5405 5406 5407 if (name === 'core/query-loop') { 5408 name = 'core/post-template'; 5409 } 5410 5411 return { 5412 name, 5413 attributes: newAttributes 5414 }; 5415 } 5416 /** 5417 * Creates a block with fallback to the unknown type handler. 5418 * 5419 * @param {Object} blockNode Parsed block node. 5420 * 5421 * @return {?Object} An initialized block object (if possible). 5422 */ 5423 5424 function createBlockWithFallback(blockNode) { 5425 const { 5426 blockName: originalName 5427 } = blockNode; // The fundamental structure of a blocktype includes its attributes, inner 5428 // blocks, and inner HTML. It is important to distinguish inner blocks from 5429 // the HTML content of the block as only the latter is relevant for block 5430 // validation and edit operations. 5431 5432 let { 5433 attrs: attributes, 5434 innerBlocks = [], 5435 innerHTML 5436 } = blockNode; 5437 const { 5438 innerContent 5439 } = blockNode; // Blocks that don't have a registered handler are considered freeform. 5440 5441 const freeformContentFallbackBlock = getFreeformContentHandlerName(); 5442 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || freeformContentFallbackBlock; 5443 attributes = attributes || {}; // Trim content to avoid creation of intermediary freeform segments. 5444 5445 innerHTML = innerHTML.trim(); // Use type from block content if available. Otherwise, default to the 5446 // freeform content fallback. 5447 5448 let name = originalName || freeformContentFallbackBlock; 5449 ({ 5450 name, 5451 attributes 5452 } = convertLegacyBlocks(name, attributes)); // Fallback content may be upgraded from classic content expecting implicit 5453 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 5454 // meaning there are no negative consequences to repeated autop calls. 5455 5456 if (name === freeformContentFallbackBlock) { 5457 innerHTML = Object(external_wp_autop_["autop"])(innerHTML).trim(); 5458 } // Try finding the type for known block name, else fall back again. 5459 5460 5461 let blockType = registration_getBlockType(name); 5462 5463 if (!blockType) { 5464 // Since the constituents of the block node are extracted at the start 5465 // of the present function, construct a new object rather than reuse 5466 // `blockNode`. 5467 const reconstitutedBlockNode = { 5468 attrs: attributes, 5469 blockName: originalName, 5470 innerBlocks, 5471 innerContent 5472 }; // Preserve undelimited content for use by the unregistered type 5473 // handler. A block node's `innerHTML` isn't enough, as that field only 5474 // carries the block's own HTML and not its nested blocks. 5475 5476 const originalUndelimitedContent = serializeBlockNode(reconstitutedBlockNode, { 5477 isCommentDelimited: false 5478 }); // Preserve full block content for use by the unregistered type 5479 // handler, block boundaries included. 5480 5481 const originalContent = serializeBlockNode(reconstitutedBlockNode, { 5482 isCommentDelimited: true 5483 }); // If detected as a block which is not registered, preserve comment 5484 // delimiters in content of unregistered type handler. 5485 5486 if (name) { 5487 innerHTML = originalContent; 5488 } 5489 5490 name = unregisteredFallbackBlock; 5491 attributes = { 5492 originalName, 5493 originalContent, 5494 originalUndelimitedContent 5495 }; 5496 blockType = registration_getBlockType(name); 5497 } // Coerce inner blocks from parsed form to canonical form. 5498 5499 5500 innerBlocks = innerBlocks.map(createBlockWithFallback); // Remove `undefined` innerBlocks. 5501 // 5502 // This is a temporary fix to prevent unrecoverable TypeErrors when handling unexpectedly 5503 // empty freeform block nodes. See https://github.com/WordPress/gutenberg/pull/17164. 5504 5505 innerBlocks = innerBlocks.filter(innerBlock => innerBlock); 5506 const isFallbackBlock = name === freeformContentFallbackBlock || name === unregisteredFallbackBlock; // Include in set only if type was determined. 5507 5508 if (!blockType || !innerHTML && isFallbackBlock) { 5509 return; 5510 } 5511 5512 let block = createBlock(name, getBlockAttributes(blockType, innerHTML, attributes), innerBlocks); // Block validation assumes an idempotent operation from source block to serialized block 5513 // provided there are no changes in attributes. The validation procedure thus compares the 5514 // provided source value with the serialized output before there are any modifications to 5515 // the block. When both match, the block is marked as valid. 5516 5517 if (!isFallbackBlock) { 5518 const { 5519 isValid, 5520 validationIssues 5521 } = getBlockContentValidationResult(blockType, block.attributes, innerHTML); 5522 block.isValid = isValid; 5523 block.validationIssues = validationIssues; 5524 } // Preserve original content for future use in case the block is parsed 5525 // as invalid, or future serialization attempt results in an error. 5526 5527 5528 block.originalContent = block.originalContent || innerHTML; // Ensure all necessary migrations are applied to the block. 5529 5530 block = getMigratedBlock(block, attributes); 5531 5532 if (block.validationIssues && block.validationIssues.length > 0) { 5533 if (block.isValid) { 5534 // eslint-disable-next-line no-console 5535 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, block.attributes), block.originalContent); 5536 } else { 5537 block.validationIssues.forEach(({ 5538 log, 5539 args 5540 }) => log(...args)); 5541 } 5542 } 5543 5544 return block; 5545 } 5546 /** 5547 * Serializes a block node into the native HTML-comment-powered block format. 5548 * CAVEAT: This function is intended for reserializing blocks as parsed by 5549 * valid parsers and skips any validation steps. This is NOT a generic 5550 * serialization function for in-memory blocks. For most purposes, see the 5551 * following functions available in the `@wordpress/blocks` package: 5552 * 5553 * @see serializeBlock 5554 * @see serialize 5555 * 5556 * For more on the format of block nodes as returned by valid parsers: 5557 * 5558 * @see `@wordpress/block-serialization-default-parser` package 5559 * @see `@wordpress/block-serialization-spec-parser` package 5560 * 5561 * @param {Object} blockNode A block node as returned by a valid parser. 5562 * @param {?Object} options Serialization options. 5563 * @param {?boolean} options.isCommentDelimited Whether to output HTML comments around blocks. 5564 * 5565 * @return {string} An HTML string representing a block. 5566 */ 5567 5568 function serializeBlockNode(blockNode, options = {}) { 5569 const { 5570 isCommentDelimited = true 5571 } = options; 5572 const { 5573 blockName, 5574 attrs = {}, 5575 innerBlocks = [], 5576 innerContent = [] 5577 } = blockNode; 5578 let childIndex = 0; 5579 const content = innerContent.map(item => // `null` denotes a nested block, otherwise we have an HTML fragment. 5580 item !== null ? item : serializeBlockNode(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 5581 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 5582 } 5583 /** 5584 * Creates a parse implementation for the post content which returns a list of blocks. 5585 * 5586 * @param {Function} parseImplementation Parse implementation. 5587 * 5588 * @return {Function} An implementation which parses the post content. 5589 */ 5590 5591 const createParse = parseImplementation => content => parseImplementation(content).reduce((accumulator, blockNode) => { 5592 const block = createBlockWithFallback(blockNode); 5593 5594 if (block) { 5595 accumulator.push(block); 5596 } 5597 5598 return accumulator; 5599 }, []); 5600 /** 5601 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 5602 * defined through a parsing expression grammar to take advantage of the regular 5603 * cadence provided by block delimiters -- composed syntactically through HTML 5604 * comments -- which, given a general HTML document as an input, returns a block 5605 * list array representation. 5606 * 5607 * This is a recursive-descent parser that scans linearly once through the input 5608 * document. Instead of directly recursing it utilizes a trampoline mechanism to 5609 * prevent stack overflow. This initial pass is mainly interested in separating 5610 * and isolating the blocks serialized in the document and manifestly not in the 5611 * content within the blocks. 5612 * 5613 * @see 5614 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 5615 * 5616 * @param {string} content The post content. 5617 * 5618 * @return {Array} Block list. 5619 */ 5620 5621 5622 const parseWithGrammar = createParse(external_wp_blockSerializationDefaultParser_["parse"]); 5623 /* harmony default export */ var parser = (parseWithGrammar); 5624 5625 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js 5626 /** 5627 * External dependencies 5628 */ 5629 5630 /** 5631 * Internal dependencies 5632 */ 5633 5634 5635 function getRawTransforms() { 5636 return Object(external_lodash_["filter"])(getBlockTransforms('from'), { 5637 type: 'raw' 5638 }).map(transform => { 5639 return transform.isMatch ? transform : { ...transform, 5640 isMatch: node => transform.selector && node.matches(transform.selector) 5641 }; 5642 }); 5643 } 5644 5645 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js 5646 /** 5647 * Internal dependencies 5648 */ 5649 5650 5651 5652 /** 5653 * Converts HTML directly to blocks. Looks for a matching transform for each 5654 * top-level tag. The HTML should be filtered to not have any text between 5655 * top-level tags and formatted in a way that blocks can handle the HTML. 5656 * 5657 * @param {string} html HTML to convert. 5658 * 5659 * @return {Array} An array of blocks. 5660 */ 5661 5662 function htmlToBlocks(html) { 5663 const doc = document.implementation.createHTMLDocument(''); 5664 doc.body.innerHTML = html; 5665 return Array.from(doc.body.children).flatMap(node => { 5666 const rawTransform = findTransform(getRawTransforms(), ({ 5667 isMatch 5668 }) => isMatch(node)); 5669 5670 if (!rawTransform) { 5671 return createBlock( // Should not be hardcoded. 5672 'core/html', getBlockAttributes('core/html', node.outerHTML)); 5673 } 5674 5675 const { 5676 transform, 5677 blockName 5678 } = rawTransform; 5679 5680 if (transform) { 5681 return transform(node); 5682 } 5683 5684 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 5685 }); 5686 } 5687 5688 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js 5689 /** 5690 * WordPress dependencies 5691 */ 5692 5693 function normaliseBlocks(HTML) { 5694 const decuDoc = document.implementation.createHTMLDocument(''); 5695 const accuDoc = document.implementation.createHTMLDocument(''); 5696 const decu = decuDoc.body; 5697 const accu = accuDoc.body; 5698 decu.innerHTML = HTML; 5699 5700 while (decu.firstChild) { 5701 const node = decu.firstChild; // Text nodes: wrap in a paragraph, or append to previous. 5702 5703 if (node.nodeType === node.TEXT_NODE) { 5704 if (Object(external_wp_dom_["isEmpty"])(node)) { 5705 decu.removeChild(node); 5706 } else { 5707 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 5708 accu.appendChild(accuDoc.createElement('P')); 5709 } 5710 5711 accu.lastChild.appendChild(node); 5712 } // Element nodes. 5713 5714 } else if (node.nodeType === node.ELEMENT_NODE) { 5715 // BR nodes: create a new paragraph on double, or append to previous. 5716 if (node.nodeName === 'BR') { 5717 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 5718 accu.appendChild(accuDoc.createElement('P')); 5719 decu.removeChild(node.nextSibling); 5720 } // Don't append to an empty paragraph. 5721 5722 5723 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 5724 accu.lastChild.appendChild(node); 5725 } else { 5726 decu.removeChild(node); 5727 } 5728 } else if (node.nodeName === 'P') { 5729 // Only append non-empty paragraph nodes. 5730 if (Object(external_wp_dom_["isEmpty"])(node)) { 5731 decu.removeChild(node); 5732 } else { 5733 accu.appendChild(node); 5734 } 5735 } else if (Object(external_wp_dom_["isPhrasingContent"])(node)) { 5736 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 5737 accu.appendChild(accuDoc.createElement('P')); 5738 } 5739 5740 accu.lastChild.appendChild(node); 5741 } else { 5742 accu.appendChild(node); 5743 } 5744 } else { 5745 decu.removeChild(node); 5746 } 5747 } 5748 5749 return accu.innerHTML; 5750 } 5751 5752 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js 5753 /** 5754 * WordPress dependencies 5755 */ 5756 5757 /** 5758 * Looks for `<!--nextpage-->` and `<!--more-->` comments, as well as the 5759 * `<!--more Some text-->` variant and its `<!--noteaser-->` companion, 5760 * and replaces them with a custom element representing a future block. 5761 * 5762 * The custom element is a way to bypass the rest of the `raw-handling` 5763 * transforms, which would eliminate other kinds of node with which to carry 5764 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 5765 * 5766 * The custom element is then expected to be recognized by any registered 5767 * block's `raw` transform. 5768 * 5769 * @param {Node} node The node to be processed. 5770 * @param {Document} doc The document of the node. 5771 * @return {void} 5772 */ 5773 5774 function specialCommentConverter(node, doc) { 5775 if (node.nodeType !== node.COMMENT_NODE) { 5776 return; 5777 } 5778 5779 if (node.nodeValue === 'nextpage') { 5780 Object(external_wp_dom_["replace"])(node, createNextpage(doc)); 5781 return; 5782 } 5783 5784 if (node.nodeValue.indexOf('more') === 0) { 5785 // Grab any custom text in the comment. 5786 const customText = node.nodeValue.slice(4).trim(); 5787 /* 5788 * When a `<!--more-->` comment is found, we need to look for any 5789 * `<!--noteaser-->` sibling, but it may not be a direct sibling 5790 * (whitespace typically lies in between) 5791 */ 5792 5793 let sibling = node; 5794 let noTeaser = false; 5795 5796 while (sibling = sibling.nextSibling) { 5797 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 5798 noTeaser = true; 5799 Object(external_wp_dom_["remove"])(sibling); 5800 break; 5801 } 5802 } 5803 5804 Object(external_wp_dom_["replace"])(node, createMore(customText, noTeaser, doc)); 5805 } 5806 } 5807 5808 function createMore(customText, noTeaser, doc) { 5809 const node = doc.createElement('wp-block'); 5810 node.dataset.block = 'core/more'; 5811 5812 if (customText) { 5813 node.dataset.customText = customText; 5814 } 5815 5816 if (noTeaser) { 5817 // "Boolean" data attribute 5818 node.dataset.noTeaser = ''; 5819 } 5820 5821 return node; 5822 } 5823 5824 function createNextpage(doc) { 5825 const node = doc.createElement('wp-block'); 5826 node.dataset.block = 'core/nextpage'; 5827 return node; 5828 } 5829 5830 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js 5831 /** 5832 * WordPress dependencies 5833 */ 5834 5835 /** 5836 * Looks for comments, and removes them. 5837 * 5838 * @param {Node} node The node to be processed. 5839 * @return {void} 5840 */ 5841 5842 function commentRemover(node) { 5843 if (node.nodeType === node.COMMENT_NODE) { 5844 Object(external_wp_dom_["remove"])(node); 5845 } 5846 } 5847 5848 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js 5849 /** 5850 * External dependencies 5851 */ 5852 5853 /** 5854 * WordPress dependencies 5855 */ 5856 5857 5858 /** 5859 * Checks if the given node should be considered inline content, optionally 5860 * depending on a context tag. 5861 * 5862 * @param {Node} node Node name. 5863 * @param {string} contextTag Tag name. 5864 * 5865 * @return {boolean} True if the node is inline content, false if nohe. 5866 */ 5867 5868 function isInline(node, contextTag) { 5869 if (Object(external_wp_dom_["isTextContent"])(node)) { 5870 return true; 5871 } 5872 5873 if (!contextTag) { 5874 return false; 5875 } 5876 5877 const tag = node.nodeName.toLowerCase(); 5878 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 5879 return inlineAllowedTagGroups.some(tagGroup => Object(external_lodash_["difference"])([tag, contextTag], tagGroup).length === 0); 5880 } 5881 5882 function deepCheck(nodes, contextTag) { 5883 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 5884 } 5885 5886 function isDoubleBR(node) { 5887 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 5888 } 5889 5890 function isInlineContent(HTML, contextTag) { 5891 const doc = document.implementation.createHTMLDocument(''); 5892 doc.body.innerHTML = HTML; 5893 const nodes = Array.from(doc.body.children); 5894 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 5895 } 5896 5897 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 5898 /** 5899 * External dependencies 5900 */ 5901 5902 /** 5903 * WordPress dependencies 5904 */ 5905 5906 5907 function phrasingContentReducer(node, doc) { 5908 // In jsdom-jscore, 'node.style' can be null. 5909 // TODO: Explore fixing this by patching jsdom-jscore. 5910 if (node.nodeName === 'SPAN' && node.style) { 5911 const { 5912 fontWeight, 5913 fontStyle, 5914 textDecorationLine, 5915 textDecoration, 5916 verticalAlign 5917 } = node.style; 5918 5919 if (fontWeight === 'bold' || fontWeight === '700') { 5920 Object(external_wp_dom_["wrap"])(doc.createElement('strong'), node); 5921 } 5922 5923 if (fontStyle === 'italic') { 5924 Object(external_wp_dom_["wrap"])(doc.createElement('em'), node); 5925 } // Some DOM implementations (Safari, JSDom) don't support 5926 // style.textDecorationLine, so we check style.textDecoration as a 5927 // fallback. 5928 5929 5930 if (textDecorationLine === 'line-through' || Object(external_lodash_["includes"])(textDecoration, 'line-through')) { 5931 Object(external_wp_dom_["wrap"])(doc.createElement('s'), node); 5932 } 5933 5934 if (verticalAlign === 'super') { 5935 Object(external_wp_dom_["wrap"])(doc.createElement('sup'), node); 5936 } else if (verticalAlign === 'sub') { 5937 Object(external_wp_dom_["wrap"])(doc.createElement('sub'), node); 5938 } 5939 } else if (node.nodeName === 'B') { 5940 node = Object(external_wp_dom_["replaceTag"])(node, 'strong'); 5941 } else if (node.nodeName === 'I') { 5942 node = Object(external_wp_dom_["replaceTag"])(node, 'em'); 5943 } else if (node.nodeName === 'A') { 5944 // In jsdom-jscore, 'node.target' can be null. 5945 // TODO: Explore fixing this by patching jsdom-jscore. 5946 if (node.target && node.target.toLowerCase() === '_blank') { 5947 node.rel = 'noreferrer noopener'; 5948 } else { 5949 node.removeAttribute('target'); 5950 node.removeAttribute('rel'); 5951 } 5952 } 5953 } 5954 5955 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js 5956 function headRemover(node) { 5957 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 5958 return; 5959 } 5960 5961 node.parentNode.removeChild(node); 5962 } 5963 5964 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js 5965 /** 5966 * Browser dependencies 5967 */ 5968 const { 5969 parseInt: ms_list_converter_parseInt 5970 } = window; 5971 5972 function isList(node) { 5973 return node.nodeName === 'OL' || node.nodeName === 'UL'; 5974 } 5975 5976 function msListConverter(node, doc) { 5977 if (node.nodeName !== 'P') { 5978 return; 5979 } 5980 5981 const style = node.getAttribute('style'); 5982 5983 if (!style) { 5984 return; 5985 } // Quick check. 5986 5987 5988 if (style.indexOf('mso-list') === -1) { 5989 return; 5990 } 5991 5992 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 5993 5994 if (!matches) { 5995 return; 5996 } 5997 5998 let level = ms_list_converter_parseInt(matches[1], 10) - 1 || 0; 5999 const prevNode = node.previousElementSibling; // Add new list if no previous. 6000 6001 if (!prevNode || !isList(prevNode)) { 6002 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 6003 const type = node.textContent.trim().slice(0, 1); 6004 const isNumeric = /[1iIaA]/.test(type); 6005 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 6006 6007 if (isNumeric) { 6008 newListNode.setAttribute('type', type); 6009 } 6010 6011 node.parentNode.insertBefore(newListNode, node); 6012 } 6013 6014 const listNode = node.previousElementSibling; 6015 const listType = listNode.nodeName; 6016 const listItem = doc.createElement('li'); 6017 let receivingNode = listNode; // Remove the first span with list info. 6018 6019 node.removeChild(node.firstElementChild); // Add content. 6020 6021 while (node.firstChild) { 6022 listItem.appendChild(node.firstChild); 6023 } // Change pointer depending on indentation level. 6024 6025 6026 while (level--) { 6027 receivingNode = receivingNode.lastElementChild || receivingNode; // If it's a list, move pointer to the last item. 6028 6029 if (isList(receivingNode)) { 6030 receivingNode = receivingNode.lastElementChild || receivingNode; 6031 } 6032 } // Make sure we append to a list. 6033 6034 6035 if (!isList(receivingNode)) { 6036 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 6037 } // Append the list item to the list. 6038 6039 6040 receivingNode.appendChild(listItem); // Remove the wrapper paragraph. 6041 6042 node.parentNode.removeChild(node); 6043 } 6044 6045 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/list-reducer.js 6046 /** 6047 * WordPress dependencies 6048 */ 6049 6050 6051 function list_reducer_isList(node) { 6052 return node.nodeName === 'OL' || node.nodeName === 'UL'; 6053 } 6054 6055 function shallowTextContent(element) { 6056 return Array.from(element.childNodes).map(({ 6057 nodeValue = '' 6058 }) => nodeValue).join(''); 6059 } 6060 6061 function listReducer(node) { 6062 if (!list_reducer_isList(node)) { 6063 return; 6064 } 6065 6066 const list = node; 6067 const prevElement = node.previousElementSibling; // Merge with previous list if: 6068 // * There is a previous list of the same type. 6069 // * There is only one list item. 6070 6071 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 6072 // Move all child nodes, including any text nodes, if any. 6073 while (list.firstChild) { 6074 prevElement.appendChild(list.firstChild); 6075 } 6076 6077 list.parentNode.removeChild(list); 6078 } 6079 6080 const parentElement = node.parentNode; // Nested list with empty parent item. 6081 6082 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 6083 const parentListItem = parentElement; 6084 const prevListItem = parentListItem.previousElementSibling; 6085 const parentList = parentListItem.parentNode; 6086 6087 if (prevListItem) { 6088 prevListItem.appendChild(list); 6089 parentList.removeChild(parentListItem); 6090 } else { 6091 parentList.parentNode.insertBefore(list, parentList); 6092 parentList.parentNode.removeChild(parentList); 6093 } 6094 } // Invalid: OL/UL > OL/UL. 6095 6096 6097 if (parentElement && list_reducer_isList(parentElement)) { 6098 const prevListItem = node.previousElementSibling; 6099 6100 if (prevListItem) { 6101 prevListItem.appendChild(node); 6102 } else { 6103 Object(external_wp_dom_["unwrap"])(node); 6104 } 6105 } 6106 } 6107 6108 // EXTERNAL MODULE: external ["wp","blob"] 6109 var external_wp_blob_ = __webpack_require__("xTGt"); 6110 6111 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/image-corrector.js 6112 /** 6113 * WordPress dependencies 6114 */ 6115 6116 /** 6117 * Browser dependencies 6118 */ 6119 6120 const { 6121 atob, 6122 File 6123 } = window; 6124 function imageCorrector(node) { 6125 if (node.nodeName !== 'IMG') { 6126 return; 6127 } 6128 6129 if (node.src.indexOf('file:') === 0) { 6130 node.src = ''; 6131 } // This piece cannot be tested outside a browser env. 6132 6133 6134 if (node.src.indexOf('data:') === 0) { 6135 const [properties, data] = node.src.split(','); 6136 const [type] = properties.slice(5).split(';'); 6137 6138 if (!data || !type) { 6139 node.src = ''; 6140 return; 6141 } 6142 6143 let decoded; // Can throw DOMException! 6144 6145 try { 6146 decoded = atob(data); 6147 } catch (e) { 6148 node.src = ''; 6149 return; 6150 } 6151 6152 const uint8Array = new Uint8Array(decoded.length); 6153 6154 for (let i = 0; i < uint8Array.length; i++) { 6155 uint8Array[i] = decoded.charCodeAt(i); 6156 } 6157 6158 const name = type.replace('/', '.'); 6159 const file = new File([uint8Array], name, { 6160 type 6161 }); 6162 node.src = Object(external_wp_blob_["createBlobURL"])(file); 6163 } // Remove trackers and hardly visible images. 6164 6165 6166 if (node.height === 1 || node.width === 1) { 6167 node.parentNode.removeChild(node); 6168 } 6169 } 6170 6171 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/blockquote-normaliser.js 6172 /** 6173 * Internal dependencies 6174 */ 6175 6176 function blockquoteNormaliser(node) { 6177 if (node.nodeName !== 'BLOCKQUOTE') { 6178 return; 6179 } 6180 6181 node.innerHTML = normaliseBlocks(node.innerHTML); 6182 } 6183 6184 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/figure-content-reducer.js 6185 /** 6186 * External dependencies 6187 */ 6188 6189 /** 6190 * WordPress dependencies 6191 */ 6192 6193 6194 /** 6195 * Whether or not the given node is figure content. 6196 * 6197 * @param {Node} node The node to check. 6198 * @param {Object} schema The schema to use. 6199 * 6200 * @return {boolean} True if figure content, false if not. 6201 */ 6202 6203 function isFigureContent(node, schema) { 6204 const tag = node.nodeName.toLowerCase(); // We are looking for tags that can be a child of the figure tag, excluding 6205 // `figcaption` and any phrasing content. 6206 6207 if (tag === 'figcaption' || Object(external_wp_dom_["isTextContent"])(node)) { 6208 return false; 6209 } 6210 6211 return Object(external_lodash_["has"])(schema, ['figure', 'children', tag]); 6212 } 6213 /** 6214 * Whether or not the given node can have an anchor. 6215 * 6216 * @param {Node} node The node to check. 6217 * @param {Object} schema The schema to use. 6218 * 6219 * @return {boolean} True if it can, false if not. 6220 */ 6221 6222 6223 function canHaveAnchor(node, schema) { 6224 const tag = node.nodeName.toLowerCase(); 6225 return Object(external_lodash_["has"])(schema, ['figure', 'children', 'a', 'children', tag]); 6226 } 6227 /** 6228 * Wraps the given element in a figure element. 6229 * 6230 * @param {Element} element The element to wrap. 6231 * @param {Element} beforeElement The element before which to place the figure. 6232 */ 6233 6234 6235 function wrapFigureContent(element, beforeElement = element) { 6236 const figure = element.ownerDocument.createElement('figure'); 6237 beforeElement.parentNode.insertBefore(figure, beforeElement); 6238 figure.appendChild(element); 6239 } 6240 /** 6241 * This filter takes figure content out of paragraphs, wraps it in a figure 6242 * element, and moves any anchors with it if needed. 6243 * 6244 * @param {Node} node The node to filter. 6245 * @param {Document} doc The document of the node. 6246 * @param {Object} schema The schema to use. 6247 * 6248 * @return {void} 6249 */ 6250 6251 6252 function figureContentReducer(node, doc, schema) { 6253 if (!isFigureContent(node, schema)) { 6254 return; 6255 } 6256 6257 let nodeToInsert = node; 6258 const parentNode = node.parentNode; // If the figure content can have an anchor and its parent is an anchor with 6259 // only the figure content, take the anchor out instead of just the content. 6260 6261 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 6262 nodeToInsert = node.parentNode; 6263 } 6264 6265 const wrapper = nodeToInsert.closest('p,div'); // If wrapped in a paragraph or div, only extract if it's aligned or if 6266 // there is no text content. 6267 // Otherwise, if directly at the root, wrap in a figure element. 6268 6269 if (wrapper) { 6270 // In jsdom-jscore, 'node.classList' can be undefined. 6271 // In this case, default to extract as it offers a better UI experience on mobile. 6272 if (!node.classList) { 6273 wrapFigureContent(nodeToInsert, wrapper); 6274 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 6275 wrapFigureContent(nodeToInsert, wrapper); 6276 } 6277 } else if (nodeToInsert.parentNode.nodeName === 'BODY') { 6278 wrapFigureContent(nodeToInsert); 6279 } 6280 } 6281 6282 // EXTERNAL MODULE: external ["wp","shortcode"] 6283 var external_wp_shortcode_ = __webpack_require__("SVSp"); 6284 6285 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/shortcode-converter.js 6286 /** 6287 * External dependencies 6288 */ 6289 6290 /** 6291 * WordPress dependencies 6292 */ 6293 6294 6295 /** 6296 * Internal dependencies 6297 */ 6298 6299 6300 6301 6302 6303 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) { 6304 // Get all matches. 6305 const transformsFrom = getBlockTransforms('from'); 6306 const transformation = findTransform(transformsFrom, transform => excludedBlockNames.indexOf(transform.blockName) === -1 && transform.type === 'shortcode' && Object(external_lodash_["some"])(Object(external_lodash_["castArray"])(transform.tag), tag => Object(external_wp_shortcode_["regexp"])(tag).test(HTML))); 6307 6308 if (!transformation) { 6309 return [HTML]; 6310 } 6311 6312 const transformTags = Object(external_lodash_["castArray"])(transformation.tag); 6313 const transformTag = Object(external_lodash_["find"])(transformTags, tag => Object(external_wp_shortcode_["regexp"])(tag).test(HTML)); 6314 let match; 6315 const previousIndex = lastIndex; 6316 6317 if (match = Object(external_wp_shortcode_["next"])(transformTag, HTML, lastIndex)) { 6318 lastIndex = match.index + match.content.length; 6319 const beforeHTML = HTML.substr(0, match.index); 6320 const afterHTML = HTML.substr(lastIndex); // If the shortcode content does not contain HTML and the shortcode is 6321 // not on a new line (or in paragraph from Markdown converter), 6322 // consider the shortcode as inline text, and thus skip conversion for 6323 // this segment. 6324 6325 if (!Object(external_lodash_["includes"])(match.shortcode.content || '', '<') && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) { 6326 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 6327 } // If a transformation's `isMatch` predicate fails for the inbound 6328 // shortcode, try again by excluding the current block type. 6329 // 6330 // This is the only call to `segmentHTMLToShortcodeBlock` that should 6331 // ever carry over `excludedBlockNames`. Other calls in the module 6332 // should skip that argument as a way to reset the exclusion state, so 6333 // that one `isMatch` fail in an HTML fragment doesn't prevent any 6334 // valid matches in subsequent fragments. 6335 6336 6337 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 6338 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 6339 } 6340 6341 const attributes = Object(external_lodash_["mapValues"])(Object(external_lodash_["pickBy"])(transformation.attributes, schema => schema.shortcode), // Passing all of `match` as second argument is intentionally broad 6342 // but shouldn't be too relied upon. 6343 // 6344 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 6345 schema => schema.shortcode(match.shortcode.attrs, match)); 6346 const block = createBlock(transformation.blockName, getBlockAttributes({ ...registration_getBlockType(transformation.blockName), 6347 attributes: transformation.attributes 6348 }, match.shortcode.content, attributes)); 6349 return [...segmentHTMLToShortcodeBlock(beforeHTML), block, ...segmentHTMLToShortcodeBlock(afterHTML)]; 6350 } 6351 6352 return [HTML]; 6353 } 6354 6355 /* harmony default export */ var shortcode_converter = (segmentHTMLToShortcodeBlock); 6356 6357 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 6358 var showdown = __webpack_require__("M55E"); 6359 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 6360 6361 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/markdown-converter.js 6362 /** 6363 * External dependencies 6364 */ 6365 // Reuse the same showdown converter. 6366 6367 const converter = new showdown_default.a.Converter({ 6368 noHeaderId: true, 6369 tables: true, 6370 literalMidWordUnderscores: true, 6371 omitExtraWLInCodeBlocks: true, 6372 simpleLineBreaks: true, 6373 strikethrough: true 6374 }); 6375 /** 6376 * Corrects the Slack Markdown variant of the code block. 6377 * If uncorrected, it will be converted to inline code. 6378 * 6379 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks 6380 * 6381 * @param {string} text The potential Markdown text to correct. 6382 * 6383 * @return {string} The corrected Markdown. 6384 */ 6385 6386 function slackMarkdownVariantCorrector(text) { 6387 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `${p1}\n${p2}\n${p3}`); 6388 } 6389 /** 6390 * Converts a piece of text into HTML based on any Markdown present. 6391 * Also decodes any encoded HTML. 6392 * 6393 * @param {string} text The plain text to convert. 6394 * 6395 * @return {string} HTML. 6396 */ 6397 6398 6399 function markdownConverter(text) { 6400 return converter.makeHtml(slackMarkdownVariantCorrector(text)); 6401 } 6402 6403 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/iframe-remover.js 6404 /** 6405 * Removes iframes. 6406 * 6407 * @param {Node} node The node to check. 6408 * 6409 * @return {void} 6410 */ 6411 function iframeRemover(node) { 6412 if (node.nodeName === 'IFRAME') { 6413 const text = node.ownerDocument.createTextNode(node.src); 6414 node.parentNode.replaceChild(text, node); 6415 } 6416 } 6417 6418 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 6419 /** 6420 * WordPress dependencies 6421 */ 6422 6423 function googleDocsUIdRemover(node) { 6424 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 6425 return; 6426 } 6427 6428 Object(external_wp_dom_["unwrap"])(node); 6429 } 6430 6431 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/utils.js 6432 /** 6433 * External dependencies 6434 */ 6435 6436 /** 6437 * WordPress dependencies 6438 */ 6439 6440 6441 /** 6442 * Internal dependencies 6443 */ 6444 6445 6446 6447 function getBlockContentSchemaFromTransforms(transforms, context) { 6448 const phrasingContentSchema = Object(external_wp_dom_["getPhrasingContentSchema"])(context); 6449 const schemaArgs = { 6450 phrasingContentSchema, 6451 isPaste: context === 'paste' 6452 }; 6453 const schemas = transforms.map(({ 6454 isMatch, 6455 blockName, 6456 schema 6457 }) => { 6458 const hasAnchorSupport = registration_hasBlockSupport(blockName, 'anchor'); 6459 schema = Object(external_lodash_["isFunction"])(schema) ? schema(schemaArgs) : schema; // If the block does not has anchor support and the transform does not 6460 // provides an isMatch we can return the schema right away. 6461 6462 if (!hasAnchorSupport && !isMatch) { 6463 return schema; 6464 } 6465 6466 return Object(external_lodash_["mapValues"])(schema, value => { 6467 let attributes = value.attributes || []; // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 6468 6469 if (hasAnchorSupport) { 6470 attributes = [...attributes, 'id']; 6471 } 6472 6473 return { ...value, 6474 attributes, 6475 isMatch: isMatch ? isMatch : undefined 6476 }; 6477 }); 6478 }); 6479 return Object(external_lodash_["mergeWith"])({}, ...schemas, (objValue, srcValue, key) => { 6480 switch (key) { 6481 case 'children': 6482 { 6483 if (objValue === '*' || srcValue === '*') { 6484 return '*'; 6485 } 6486 6487 return { ...objValue, 6488 ...srcValue 6489 }; 6490 } 6491 6492 case 'attributes': 6493 case 'require': 6494 { 6495 return [...(objValue || []), ...(srcValue || [])]; 6496 } 6497 6498 case 'isMatch': 6499 { 6500 // If one of the values being merge is undefined (matches everything), 6501 // the result of the merge will be undefined. 6502 if (!objValue || !srcValue) { 6503 return undefined; 6504 } // When merging two isMatch functions, the result is a new function 6505 // that returns if one of the source functions returns true. 6506 6507 6508 return (...args) => { 6509 return objValue(...args) || srcValue(...args); 6510 }; 6511 } 6512 } 6513 }); 6514 } 6515 /** 6516 * Gets the block content schema, which is extracted and merged from all 6517 * registered blocks with raw transfroms. 6518 * 6519 * @param {string} context Set to "paste" when in paste context, where the 6520 * schema is more strict. 6521 * 6522 * @return {Object} A complete block content schema. 6523 */ 6524 6525 function getBlockContentSchema(context) { 6526 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 6527 } 6528 /** 6529 * Checks whether HTML can be considered plain text. That is, it does not contain 6530 * any elements that are not line breaks. 6531 * 6532 * @param {string} HTML The HTML to check. 6533 * 6534 * @return {boolean} Whether the HTML can be considered plain text. 6535 */ 6536 6537 function isPlain(HTML) { 6538 return !/<(?!br[ />])/i.test(HTML); 6539 } 6540 /** 6541 * Given node filters, deeply filters and mutates a NodeList. 6542 * 6543 * @param {NodeList} nodeList The nodeList to filter. 6544 * @param {Array} filters An array of functions that can mutate with the provided node. 6545 * @param {Document} doc The document of the nodeList. 6546 * @param {Object} schema The schema to use. 6547 */ 6548 6549 function deepFilterNodeList(nodeList, filters, doc, schema) { 6550 Array.from(nodeList).forEach(node => { 6551 deepFilterNodeList(node.childNodes, filters, doc, schema); 6552 filters.forEach(item => { 6553 // Make sure the node is still attached to the document. 6554 if (!doc.contains(node)) { 6555 return; 6556 } 6557 6558 item(node, doc, schema); 6559 }); 6560 }); 6561 } 6562 /** 6563 * Given node filters, deeply filters HTML tags. 6564 * Filters from the deepest nodes to the top. 6565 * 6566 * @param {string} HTML The HTML to filter. 6567 * @param {Array} filters An array of functions that can mutate with the provided node. 6568 * @param {Object} schema The schema to use. 6569 * 6570 * @return {string} The filtered HTML. 6571 */ 6572 6573 function deepFilterHTML(HTML, filters = [], schema) { 6574 const doc = document.implementation.createHTMLDocument(''); 6575 doc.body.innerHTML = HTML; 6576 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 6577 return doc.body.innerHTML; 6578 } 6579 /** 6580 * Gets a sibling within text-level context. 6581 * 6582 * @param {Element} node The subject node. 6583 * @param {string} which "next" or "previous". 6584 */ 6585 6586 function getSibling(node, which) { 6587 const sibling = node[`${which}Sibling`]; 6588 6589 if (sibling && Object(external_wp_dom_["isPhrasingContent"])(sibling)) { 6590 return sibling; 6591 } 6592 6593 const { 6594 parentNode 6595 } = node; 6596 6597 if (!parentNode || !Object(external_wp_dom_["isPhrasingContent"])(parentNode)) { 6598 return; 6599 } 6600 6601 return getSibling(parentNode, which); 6602 } 6603 6604 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-formatting-remover.js 6605 /** 6606 * Internal dependencies 6607 */ 6608 6609 6610 function isFormattingSpace(character) { 6611 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 6612 } 6613 /** 6614 * Removes spacing that formats HTML. 6615 * 6616 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 6617 * 6618 * @param {Node} node The node to be processed. 6619 * @return {void} 6620 */ 6621 6622 6623 function htmlFormattingRemover(node) { 6624 if (node.nodeType !== node.TEXT_NODE) { 6625 return; 6626 } // Ignore pre content. Note that this does not use Element#closest due to 6627 // a combination of (a) node may not be Element and (b) node.parentElement 6628 // does not have full support in all browsers (Internet Exporer). 6629 // 6630 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 6631 6632 /** @type {Node?} */ 6633 6634 6635 let parent = node; 6636 6637 while (parent = parent.parentNode) { 6638 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 6639 return; 6640 } 6641 } // First, replace any sequence of HTML formatting space with a single space. 6642 6643 6644 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); // Remove the leading space if the text element is at the start of a block, 6645 // is preceded by a line break element, or has a space in the previous 6646 // node. 6647 6648 if (newData[0] === ' ') { 6649 const previousSibling = getSibling(node, 'previous'); 6650 6651 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 6652 newData = newData.slice(1); 6653 } 6654 } // Remove the trailing space if the text element is at the end of a block, 6655 // is succeded by a line break element, or has a space in the next text 6656 // node. 6657 6658 6659 if (newData[newData.length - 1] === ' ') { 6660 const nextSibling = getSibling(node, 'next'); 6661 6662 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 6663 newData = newData.slice(0, -1); 6664 } 6665 } // If there's no data left, remove the node, so `previousSibling` stays 6666 // accurate. Otherwise, update the node data. 6667 6668 6669 if (!newData) { 6670 node.parentNode.removeChild(node); 6671 } else { 6672 node.data = newData; 6673 } 6674 } 6675 6676 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/br-remover.js 6677 /** 6678 * Internal dependencies 6679 */ 6680 6681 /** 6682 * Removes trailing br elements from text-level content. 6683 * 6684 * @param {Element} node Node to check. 6685 */ 6686 6687 function brRemover(node) { 6688 if (node.nodeName !== 'BR') { 6689 return; 6690 } 6691 6692 if (getSibling(node, 'next')) { 6693 return; 6694 } 6695 6696 node.parentNode.removeChild(node); 6697 } 6698 6699 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 6700 /** 6701 * Removes empty paragraph elements. 6702 * 6703 * @param {Element} node Node to check. 6704 */ 6705 function emptyParagraphRemover(node) { 6706 if (node.nodeName !== 'P') { 6707 return; 6708 } 6709 6710 if (node.hasChildNodes()) { 6711 return; 6712 } 6713 6714 node.parentNode.removeChild(node); 6715 } 6716 6717 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/paste-handler.js 6718 /** 6719 * External dependencies 6720 */ 6721 6722 /** 6723 * WordPress dependencies 6724 */ 6725 6726 6727 /** 6728 * Internal dependencies 6729 */ 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 /** 6755 * Browser dependencies 6756 */ 6757 6758 const { 6759 console: paste_handler_console 6760 } = window; 6761 /** 6762 * Filters HTML to only contain phrasing content. 6763 * 6764 * @param {string} HTML The HTML to filter. 6765 * @param {boolean} preserveWhiteSpace Whether or not to preserve consequent white space. 6766 * 6767 * @return {string} HTML only containing phrasing content. 6768 */ 6769 6770 function filterInlineHTML(HTML, preserveWhiteSpace) { 6771 HTML = deepFilterHTML(HTML, [googleDocsUIdRemover, phrasingContentReducer, commentRemover]); 6772 HTML = Object(external_wp_dom_["removeInvalidHTML"])(HTML, Object(external_wp_dom_["getPhrasingContentSchema"])('paste'), { 6773 inline: true 6774 }); 6775 6776 if (!preserveWhiteSpace) { 6777 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 6778 } // Allows us to ask for this information when we get a report. 6779 6780 6781 paste_handler_console.log('Processed inline HTML:\n\n', HTML); 6782 return HTML; 6783 } 6784 /** 6785 * Converts an HTML string to known blocks. Strips everything else. 6786 * 6787 * @param {Object} options 6788 * @param {string} [options.HTML] The HTML to convert. 6789 * @param {string} [options.plainText] Plain text version. 6790 * @param {string} [options.mode] Handle content as blocks or inline content. 6791 * * 'AUTO': Decide based on the content passed. 6792 * * 'INLINE': Always handle as inline content, and return string. 6793 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 6794 * @param {Array} [options.tagName] The tag into which content will be inserted. 6795 * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space. 6796 * 6797 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 6798 */ 6799 6800 6801 function pasteHandler({ 6802 HTML = '', 6803 plainText = '', 6804 mode = 'AUTO', 6805 tagName, 6806 preserveWhiteSpace 6807 }) { 6808 // First of all, strip any meta tags. 6809 HTML = HTML.replace(/<meta[^>]+>/g, ''); // Strip Windows markers. 6810 6811 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 6812 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); // If we detect block delimiters in HTML, parse entirely as blocks. 6813 6814 if (mode !== 'INLINE') { 6815 // Check plain text if there is no HTML. 6816 const content = HTML ? HTML : plainText; 6817 6818 if (content.indexOf('<!-- wp:') !== -1) { 6819 return parseWithGrammar(content); 6820 } 6821 } // Normalize unicode to use composed characters. 6822 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory. 6823 // Not normalizing the content will only affect older browsers and won't 6824 // entirely break the app. 6825 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 6826 // See: https://core.trac.wordpress.org/ticket/30130 6827 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 6828 6829 6830 if (String.prototype.normalize) { 6831 HTML = HTML.normalize(); 6832 } // Parse Markdown (and encoded HTML) if: 6833 // * There is a plain text version. 6834 // * There is no HTML version, or it has no formatting. 6835 6836 6837 if (plainText && (!HTML || isPlain(HTML))) { 6838 HTML = plainText; // The markdown converter (Showdown) trims whitespace. 6839 6840 if (!/^\s+$/.test(plainText)) { 6841 HTML = markdownConverter(HTML); 6842 } // Switch to inline mode if: 6843 // * The current mode is AUTO. 6844 // * The original plain text had no line breaks. 6845 // * The original plain text was not an HTML paragraph. 6846 // * The converted text is just a paragraph. 6847 6848 6849 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 6850 mode = 'INLINE'; 6851 } 6852 } 6853 6854 if (mode === 'INLINE') { 6855 return filterInlineHTML(HTML, preserveWhiteSpace); 6856 } // An array of HTML strings and block objects. The blocks replace matched 6857 // shortcodes. 6858 6859 6860 const pieces = shortcode_converter(HTML); // The call to shortcodeConverter will always return more than one element 6861 // if shortcodes are matched. The reason is when shortcodes are matched 6862 // empty HTML strings are included. 6863 6864 const hasShortcodes = pieces.length > 1; 6865 6866 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 6867 return filterInlineHTML(HTML, preserveWhiteSpace); 6868 } 6869 6870 const phrasingContentSchema = Object(external_wp_dom_["getPhrasingContentSchema"])('paste'); 6871 const blockContentSchema = getBlockContentSchema('paste'); 6872 const blocks = Object(external_lodash_["compact"])(Object(external_lodash_["flatMap"])(pieces, piece => { 6873 // Already a block from shortcode. 6874 if (typeof piece !== 'string') { 6875 return piece; 6876 } 6877 6878 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser]; 6879 const schema = { ...blockContentSchema, 6880 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 6881 ...phrasingContentSchema 6882 }; 6883 piece = deepFilterHTML(piece, filters, blockContentSchema); 6884 piece = Object(external_wp_dom_["removeInvalidHTML"])(piece, schema); 6885 piece = normaliseBlocks(piece); 6886 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); // Allows us to ask for this information when we get a report. 6887 6888 paste_handler_console.log('Processed HTML piece:\n\n', piece); 6889 return htmlToBlocks(piece); 6890 })); // If we're allowed to return inline content, and there is only one 6891 // inlineable block, and the original plain text content does not have any 6892 // line breaks, then treat it as inline paste. 6893 6894 if (mode === 'AUTO' && blocks.length === 1 && registration_hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 6895 // Don't catch line breaks at the start or end. 6896 const trimmedPlainText = plainText.replace(/^[\n]+|[\n]+$/g, ''); 6897 6898 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 6899 return Object(external_wp_dom_["removeInvalidHTML"])(getBlockInnerHTML(blocks[0]), phrasingContentSchema); 6900 } 6901 } 6902 6903 return blocks; 6904 } 6905 6906 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/index.js 6907 /** 6908 * External dependencies 6909 */ 6910 6911 /** 6912 * WordPress dependencies 6913 */ 6914 6915 6916 6917 /** 6918 * Internal dependencies 6919 */ 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 function deprecatedGetPhrasingContentSchema(context) { 6932 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 6933 since: '5.6', 6934 alternative: 'wp.dom.getPhrasingContentSchema' 6935 }); 6936 return Object(external_wp_dom_["getPhrasingContentSchema"])(context); 6937 } 6938 /** 6939 * Converts an HTML string to known blocks. 6940 * 6941 * @param {Object} $1 6942 * @param {string} $1.HTML The HTML to convert. 6943 * 6944 * @return {Array} A list of blocks. 6945 */ 6946 6947 function rawHandler({ 6948 HTML = '' 6949 }) { 6950 // If we detect block delimiters, parse entirely as blocks. 6951 if (HTML.indexOf('<!-- wp:') !== -1) { 6952 return parseWithGrammar(HTML); 6953 } // An array of HTML strings and block objects. The blocks replace matched 6954 // shortcodes. 6955 6956 6957 const pieces = shortcode_converter(HTML); 6958 const blockContentSchema = getBlockContentSchema(); 6959 return Object(external_lodash_["compact"])(Object(external_lodash_["flatMap"])(pieces, piece => { 6960 // Already a block from shortcode. 6961 if (typeof piece !== 'string') { 6962 return piece; 6963 } // These filters are essential for some blocks to be able to transform 6964 // from raw HTML. These filters move around some content or add 6965 // additional tags, they do not remove any content. 6966 6967 6968 const filters = [// Needed to adjust invalid lists. 6969 listReducer, // Needed to create more and nextpage blocks. 6970 specialCommentConverter, // Needed to create media blocks. 6971 figureContentReducer, // Needed to create the quote block, which cannot handle text 6972 // without wrapper paragraphs. 6973 blockquoteNormaliser]; 6974 piece = deepFilterHTML(piece, filters, blockContentSchema); 6975 piece = normaliseBlocks(piece); 6976 return htmlToBlocks(piece); 6977 })); 6978 } 6979 6980 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/categories.js 6981 /** 6982 * WordPress dependencies 6983 */ 6984 6985 /** 6986 * Internal dependencies 6987 */ 6988 6989 6990 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 6991 6992 /** 6993 * Returns all the block categories. 6994 * 6995 * @return {WPBlockCategory[]} Block categories. 6996 */ 6997 6998 function categories_getCategories() { 6999 return Object(external_wp_data_["select"])(store).getCategories(); 7000 } 7001 /** 7002 * Sets the block categories. 7003 * 7004 * @param {WPBlockCategory[]} categories Block categories. 7005 */ 7006 7007 function categories_setCategories(categories) { 7008 Object(external_wp_data_["dispatch"])(store).setCategories(categories); 7009 } 7010 /** 7011 * Updates a category. 7012 * 7013 * @param {string} slug Block category slug. 7014 * @param {WPBlockCategory} category Object containing the category properties 7015 * that should be updated. 7016 */ 7017 7018 function categories_updateCategory(slug, category) { 7019 Object(external_wp_data_["dispatch"])(store).updateCategory(slug, category); 7020 } 7021 7022 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/templates.js 7023 /** 7024 * External dependencies 7025 */ 7026 7027 /** 7028 * WordPress dependencies 7029 */ 7030 7031 7032 /** 7033 * Internal dependencies 7034 */ 7035 7036 7037 7038 7039 /** 7040 * Checks whether a list of blocks matches a template by comparing the block names. 7041 * 7042 * @param {Array} blocks Block list. 7043 * @param {Array} template Block template. 7044 * 7045 * @return {boolean} Whether the list of blocks matches a templates 7046 */ 7047 7048 function doBlocksMatchTemplate(blocks = [], template = []) { 7049 return blocks.length === template.length && Object(external_lodash_["every"])(template, ([name,, innerBlocksTemplate], index) => { 7050 const block = blocks[index]; 7051 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 7052 }); 7053 } 7054 /** 7055 * Synchronize a block list with a block template. 7056 * 7057 * Synchronizing a block list with a block template means that we loop over the blocks 7058 * keep the block as is if it matches the block at the same position in the template 7059 * (If it has the same name) and if doesn't match, we create a new block based on the template. 7060 * Extra blocks not present in the template are removed. 7061 * 7062 * @param {Array} blocks Block list. 7063 * @param {Array} template Block template. 7064 * 7065 * @return {Array} Updated Block list. 7066 */ 7067 7068 function synchronizeBlocksWithTemplate(blocks = [], template) { 7069 // If no template is provided, return blocks unmodified. 7070 if (!template) { 7071 return blocks; 7072 } 7073 7074 return Object(external_lodash_["map"])(template, ([name, attributes, innerBlocksTemplate], index) => { 7075 const block = blocks[index]; 7076 7077 if (block && block.name === name) { 7078 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 7079 return { ...block, 7080 innerBlocks 7081 }; 7082 } // To support old templates that were using the "children" format 7083 // for the attributes using "html" strings now, we normalize the template attributes 7084 // before creating the blocks. 7085 7086 7087 const blockType = registration_getBlockType(name); 7088 7089 const isHTMLAttribute = attributeDefinition => Object(external_lodash_["get"])(attributeDefinition, ['source']) === 'html'; 7090 7091 const isQueryAttribute = attributeDefinition => Object(external_lodash_["get"])(attributeDefinition, ['source']) === 'query'; 7092 7093 const normalizeAttributes = (schema, values) => { 7094 return Object(external_lodash_["mapValues"])(values, (value, key) => { 7095 return normalizeAttribute(schema[key], value); 7096 }); 7097 }; 7098 7099 const normalizeAttribute = (definition, value) => { 7100 if (isHTMLAttribute(definition) && Object(external_lodash_["isArray"])(value)) { 7101 // Introduce a deprecated call at this point 7102 // When we're confident that "children" format should be removed from the templates. 7103 return Object(external_wp_element_["renderToString"])(value); 7104 } 7105 7106 if (isQueryAttribute(definition) && value) { 7107 return value.map(subValues => { 7108 return normalizeAttributes(definition.query, subValues); 7109 }); 7110 } 7111 7112 return value; 7113 }; 7114 7115 const normalizedAttributes = normalizeAttributes(Object(external_lodash_["get"])(blockType, ['attributes'], {}), attributes); 7116 const { 7117 name: blockName, 7118 attributes: blockAttributes 7119 } = convertLegacyBlocks(name, normalizedAttributes); 7120 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 7121 }); 7122 } 7123 7124 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/index.js 7125 // The blocktype is the most important concept within the block API. It defines 7126 // all aspects of the block configuration and its interfaces, including `edit` 7127 // and `save`. The transforms specification allows converting one blocktype to 7128 // another through formulas defined by either the source or the destination. 7129 // Switching a blocktype is to be considered a one-way operation implying a 7130 // transformation in the opposite way has to be handled explicitly. 7131 // The block tree is composed of a collection of block nodes. Blocks contained 7132 // within other blocks are called inner blocks. An important design 7133 // consideration is that inner blocks are -- conceptually -- not part of the 7134 // territory established by the parent block that contains them. 7135 // 7136 // This has multiple practical implications: when parsing, we can safely dispose 7137 // of any block boundary found within a block from the innerHTML property when 7138 // transfering to state. Not doing so would have a compounding effect on memory 7139 // and uncertainty over the source of truth. This can be illustrated in how, 7140 // given a tree of `n` nested blocks, the entry node would have to contain the 7141 // actual content of each block while each subsequent block node in the state 7142 // tree would replicate the entire chain `n-1`, meaning the extreme end node 7143 // would have been replicated `n` times as the tree is traversed and would 7144 // generate uncertainty as to which one is to hold the current value of the 7145 // block. For composition, it also means inner blocks can effectively be child 7146 // components whose mechanisms can be shielded from the `edit` implementation 7147 // and just passed along. 7148 7149 // While block transformations account for a specific surface of the API, there 7150 // are also raw transformations which handle arbitrary sources not made out of 7151 // blocks but producing block basaed on various heursitics. This includes 7152 // pasting rich text or HTML data. 7153 7154 // The process of serialization aims to deflate the internal memory of the block 7155 // editor and its state representation back into an HTML valid string. This 7156 // process restores the document integrity and inserts invisible delimiters 7157 // around each block with HTML comment boundaries which can contain any extra 7158 // attributes needed to operate with the block later on. 7159 7160 // Validation is the process of comparing a block source with its output before 7161 // there is any user input or interaction with a block. When this operation 7162 // fails -- for whatever reason -- the block is to be considered invalid. As 7163 // part of validating a block the system will attempt to run the source against 7164 // any provided deprecation definitions. 7165 // 7166 // Worth emphasizing that validation is not a case of whether the markup is 7167 // merely HTML spec-compliant but about how the editor knows to create such 7168 // markup and that its inability to create an identical result can be a strong 7169 // indicator of potential data loss (the invalidation is then a protective 7170 // measure). 7171 // 7172 // The invalidation process can also be deconstructed in phases: 1) validate the 7173 // block exists; 2) validate the source matches the output; 3) validate the 7174 // source matches deprecated outputs; 4) work through the significance of 7175 // differences. These are stacked in a way that favors performance and optimizes 7176 // for the majority of cases. That is to say, the evaluation logic can become 7177 // more sophisticated the further down it goes in the process as the cost is 7178 // accounted for. The first logic checks have to be extremely efficient since 7179 // they will be run for all valid and invalid blocks alike. However, once a 7180 // block is detected as invalid -- failing the three first steps -- it is 7181 // adequate to spend more time determining validity before throwing a conflict. 7182 7183 7184 // Blocks are inherently indifferent about where the data they operate with ends 7185 // up being saved. For example, all blocks can have a static and dynamic aspect 7186 // to them depending on the needs. The static nature of a block is the `save()` 7187 // definition that is meant to be serialized into HTML and which can be left 7188 // void. Any block can also register a `render_callback` on the server, which 7189 // makes its output dynamic either in part or in its totality. 7190 // 7191 // Child blocks are defined as a relationship that builds on top of the inner 7192 // blocks mechanism. A child block is a block node of a particular type that can 7193 // only exist within the inner block boundaries of a specific parent type. This 7194 // allows block authors to compose specific blocks that are not meant to be used 7195 // outside of a specified parent block context. Thus, child blocks extend the 7196 // concept of inner blocks to support a more direct relationship between sets of 7197 // blocks. The addition of parent–child would be a subset of the inner block 7198 // functionality under the premise that certain blocks only make sense as 7199 // children of another block. 7200 7201 7202 // Templates are, in a general sense, a basic collection of block nodes with any 7203 // given set of predefined attributes that are supplied as the initial state of 7204 // an inner blocks group. These nodes can, in turn, contain any number of nested 7205 // blocks within their definition. Templates allow both to specify a default 7206 // state for an editor session or a default set of blocks for any inner block 7207 // implementation within a specific block. 7208 7209 7210 7211 7212 7213 7214 // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/index.js 7215 // A "block" is the abstract term used to describe units of markup that, 7216 // when composed together, form the content or layout of a page. 7217 // The API for blocks is exposed via `wp.blocks`. 7218 // 7219 // Supported blocks are registered by calling `registerBlockType`. Once registered, 7220 // the block is made available as an option to the editor interface. 7221 // 7222 // Blocks are inferred from the HTML source of a post through a parsing mechanism 7223 // and then stored as objects in state, from which it is then rendered for editing. 7224 7225 7226 7227 7228 7229 /***/ }), 7230 7231 /***/ "1CF3": 7232 /***/ (function(module, exports) { 7233 7234 (function() { module.exports = window["wp"]["dom"]; }()); 7235 7236 /***/ }), 7237 7238 /***/ "1ZqX": 7239 /***/ (function(module, exports) { 7240 7241 (function() { module.exports = window["wp"]["data"]; }()); 7242 7243 /***/ }), 7244 7245 /***/ "7Cbv": 7246 /***/ (function(module, __webpack_exports__, __webpack_require__) { 7247 7248 "use strict"; 7249 7250 // CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js 7251 // Unique ID creation requires a high quality random # generator. In the browser we therefore 7252 // require the crypto API and do not support built-in fallback to lower quality random number 7253 // generators (like Math.random()). 7254 var getRandomValues; 7255 var rnds8 = new Uint8Array(16); 7256 function rng() { 7257 // lazy load so that environments that need to polyfill have a chance to do so 7258 if (!getRandomValues) { 7259 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also, 7260 // find the complete implementation of crypto (msCrypto) on IE11. 7261 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto); 7262 7263 if (!getRandomValues) { 7264 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 7265 } 7266 } 7267 7268 return getRandomValues(rnds8); 7269 } 7270 // CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js 7271 /* harmony default export */ var regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i); 7272 // CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js 7273 7274 7275 function validate(uuid) { 7276 return typeof uuid === 'string' && regex.test(uuid); 7277 } 7278 7279 /* harmony default export */ var esm_browser_validate = (validate); 7280 // CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js 7281 7282 /** 7283 * Convert array of 16 byte values to UUID string format of the form: 7284 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 7285 */ 7286 7287 var byteToHex = []; 7288 7289 for (var stringify_i = 0; stringify_i < 256; ++stringify_i) { 7290 byteToHex.push((stringify_i + 0x100).toString(16).substr(1)); 7291 } 7292 7293 function stringify(arr) { 7294 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 7295 // Note: Be careful editing this code! It's been tuned for performance 7296 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 7297 var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one 7298 // of the following: 7299 // - One or more input array values don't map to a hex octet (leading to 7300 // "undefined" in the uuid) 7301 // - Invalid input values for the RFC `version` or `variant` fields 7302 7303 if (!esm_browser_validate(uuid)) { 7304 throw TypeError('Stringified UUID is invalid'); 7305 } 7306 7307 return uuid; 7308 } 7309 7310 /* harmony default export */ var esm_browser_stringify = (stringify); 7311 // CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js 7312 7313 7314 7315 function v4(options, buf, offset) { 7316 options = options || {}; 7317 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 7318 7319 rnds[6] = rnds[6] & 0x0f | 0x40; 7320 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 7321 7322 if (buf) { 7323 offset = offset || 0; 7324 7325 for (var i = 0; i < 16; ++i) { 7326 buf[offset + i] = rnds[i]; 7327 } 7328 7329 return buf; 7330 } 7331 7332 return esm_browser_stringify(rnds); 7333 } 7334 7335 /* harmony default export */ var esm_browser_v4 = __webpack_exports__["a"] = (v4); 7336 7337 /***/ }), 7338 7339 /***/ "GRId": 7340 /***/ (function(module, exports) { 7341 7342 (function() { module.exports = window["wp"]["element"]; }()); 7343 7344 /***/ }), 7345 7346 /***/ "K9lf": 7347 /***/ (function(module, exports) { 7348 7349 (function() { module.exports = window["wp"]["compose"]; }()); 7350 7351 /***/ }), 7352 7353 /***/ "M55E": 7354 /***/ (function(module, exports, __webpack_require__) { 7355 7356 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */ 7357 (function(){ 7358 /** 7359 * Created by Tivie on 13-07-2015. 7360 */ 7361 7362 function getDefaultOpts (simple) { 7363 'use strict'; 7364 7365 var defaultOptions = { 7366 omitExtraWLInCodeBlocks: { 7367 defaultValue: false, 7368 describe: 'Omit the default extra whiteline added to code blocks', 7369 type: 'boolean' 7370 }, 7371 noHeaderId: { 7372 defaultValue: false, 7373 describe: 'Turn on/off generated header id', 7374 type: 'boolean' 7375 }, 7376 prefixHeaderId: { 7377 defaultValue: false, 7378 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', 7379 type: 'string' 7380 }, 7381 rawPrefixHeaderId: { 7382 defaultValue: false, 7383 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)', 7384 type: 'boolean' 7385 }, 7386 ghCompatibleHeaderId: { 7387 defaultValue: false, 7388 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)', 7389 type: 'boolean' 7390 }, 7391 rawHeaderId: { 7392 defaultValue: false, 7393 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids', 7394 type: 'boolean' 7395 }, 7396 headerLevelStart: { 7397 defaultValue: false, 7398 describe: 'The header blocks level start', 7399 type: 'integer' 7400 }, 7401 parseImgDimensions: { 7402 defaultValue: false, 7403 describe: 'Turn on/off image dimension parsing', 7404 type: 'boolean' 7405 }, 7406 simplifiedAutoLink: { 7407 defaultValue: false, 7408 describe: 'Turn on/off GFM autolink style', 7409 type: 'boolean' 7410 }, 7411 excludeTrailingPunctuationFromURLs: { 7412 defaultValue: false, 7413 describe: 'Excludes trailing punctuation from links generated with autoLinking', 7414 type: 'boolean' 7415 }, 7416 literalMidWordUnderscores: { 7417 defaultValue: false, 7418 describe: 'Parse midword underscores as literal underscores', 7419 type: 'boolean' 7420 }, 7421 literalMidWordAsterisks: { 7422 defaultValue: false, 7423 describe: 'Parse midword asterisks as literal asterisks', 7424 type: 'boolean' 7425 }, 7426 strikethrough: { 7427 defaultValue: false, 7428 describe: 'Turn on/off strikethrough support', 7429 type: 'boolean' 7430 }, 7431 tables: { 7432 defaultValue: false, 7433 describe: 'Turn on/off tables support', 7434 type: 'boolean' 7435 }, 7436 tablesHeaderId: { 7437 defaultValue: false, 7438 describe: 'Add an id to table headers', 7439 type: 'boolean' 7440 }, 7441 ghCodeBlocks: { 7442 defaultValue: true, 7443 describe: 'Turn on/off GFM fenced code blocks support', 7444 type: 'boolean' 7445 }, 7446 tasklists: { 7447 defaultValue: false, 7448 describe: 'Turn on/off GFM tasklist support', 7449 type: 'boolean' 7450 }, 7451 smoothLivePreview: { 7452 defaultValue: false, 7453 describe: 'Prevents weird effects in live previews due to incomplete input', 7454 type: 'boolean' 7455 }, 7456 smartIndentationFix: { 7457 defaultValue: false, 7458 description: 'Tries to smartly fix indentation in es6 strings', 7459 type: 'boolean' 7460 }, 7461 disableForced4SpacesIndentedSublists: { 7462 defaultValue: false, 7463 description: 'Disables the requirement of indenting nested sublists by 4 spaces', 7464 type: 'boolean' 7465 }, 7466 simpleLineBreaks: { 7467 defaultValue: false, 7468 description: 'Parses simple line breaks as <br> (GFM Style)', 7469 type: 'boolean' 7470 }, 7471 requireSpaceBeforeHeadingText: { 7472 defaultValue: false, 7473 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)', 7474 type: 'boolean' 7475 }, 7476 ghMentions: { 7477 defaultValue: false, 7478 description: 'Enables github @mentions', 7479 type: 'boolean' 7480 }, 7481 ghMentionsLink: { 7482 defaultValue: 'https://github.com/{u}', 7483 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.', 7484 type: 'string' 7485 }, 7486 encodeEmails: { 7487 defaultValue: true, 7488 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities', 7489 type: 'boolean' 7490 }, 7491 openLinksInNewWindow: { 7492 defaultValue: false, 7493 description: 'Open all links in new windows', 7494 type: 'boolean' 7495 }, 7496 backslashEscapesHTMLTags: { 7497 defaultValue: false, 7498 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>', 7499 type: 'boolean' 7500 }, 7501 emoji: { 7502 defaultValue: false, 7503 description: 'Enable emoji support. Ex: `this is a :smile: emoji`', 7504 type: 'boolean' 7505 }, 7506 underline: { 7507 defaultValue: false, 7508 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>`', 7509 type: 'boolean' 7510 }, 7511 completeHTMLDocument: { 7512 defaultValue: false, 7513 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags', 7514 type: 'boolean' 7515 }, 7516 metadata: { 7517 defaultValue: false, 7518 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).', 7519 type: 'boolean' 7520 }, 7521 splitAdjacentBlockquotes: { 7522 defaultValue: false, 7523 description: 'Split adjacent blockquote blocks', 7524 type: 'boolean' 7525 } 7526 }; 7527 if (simple === false) { 7528 return JSON.parse(JSON.stringify(defaultOptions)); 7529 } 7530 var ret = {}; 7531 for (var opt in defaultOptions) { 7532 if (defaultOptions.hasOwnProperty(opt)) { 7533 ret[opt] = defaultOptions[opt].defaultValue; 7534 } 7535 } 7536 return ret; 7537 } 7538 7539 function allOptionsOn () { 7540 'use strict'; 7541 var options = getDefaultOpts(true), 7542 ret = {}; 7543 for (var opt in options) { 7544 if (options.hasOwnProperty(opt)) { 7545 ret[opt] = true; 7546 } 7547 } 7548 return ret; 7549 } 7550 7551 /** 7552 * Created by Tivie on 06-01-2015. 7553 */ 7554 7555 // Private properties 7556 var showdown = {}, 7557 parsers = {}, 7558 extensions = {}, 7559 globalOptions = getDefaultOpts(true), 7560 setFlavor = 'vanilla', 7561 flavor = { 7562 github: { 7563 omitExtraWLInCodeBlocks: true, 7564 simplifiedAutoLink: true, 7565 excludeTrailingPunctuationFromURLs: true, 7566 literalMidWordUnderscores: true, 7567 strikethrough: true, 7568 tables: true, 7569 tablesHeaderId: true, 7570 ghCodeBlocks: true, 7571 tasklists: true, 7572 disableForced4SpacesIndentedSublists: true, 7573 simpleLineBreaks: true, 7574 requireSpaceBeforeHeadingText: true, 7575 ghCompatibleHeaderId: true, 7576 ghMentions: true, 7577 backslashEscapesHTMLTags: true, 7578 emoji: true, 7579 splitAdjacentBlockquotes: true 7580 }, 7581 original: { 7582 noHeaderId: true, 7583 ghCodeBlocks: false 7584 }, 7585 ghost: { 7586 omitExtraWLInCodeBlocks: true, 7587 parseImgDimensions: true, 7588 simplifiedAutoLink: true, 7589 excludeTrailingPunctuationFromURLs: true, 7590 literalMidWordUnderscores: true, 7591 strikethrough: true, 7592 tables: true, 7593 tablesHeaderId: true, 7594 ghCodeBlocks: true, 7595 tasklists: true, 7596 smoothLivePreview: true, 7597 simpleLineBreaks: true, 7598 requireSpaceBeforeHeadingText: true, 7599 ghMentions: false, 7600 encodeEmails: true 7601 }, 7602 vanilla: getDefaultOpts(true), 7603 allOn: allOptionsOn() 7604 }; 7605 7606 /** 7607 * helper namespace 7608 * @type {{}} 7609 */ 7610 showdown.helper = {}; 7611 7612 /** 7613 * TODO LEGACY SUPPORT CODE 7614 * @type {{}} 7615 */ 7616 showdown.extensions = {}; 7617 7618 /** 7619 * Set a global option 7620 * @static 7621 * @param {string} key 7622 * @param {*} value 7623 * @returns {showdown} 7624 */ 7625 showdown.setOption = function (key, value) { 7626 'use strict'; 7627 globalOptions[key] = value; 7628 return this; 7629 }; 7630 7631 /** 7632 * Get a global option 7633 * @static 7634 * @param {string} key 7635 * @returns {*} 7636 */ 7637 showdown.getOption = function (key) { 7638 'use strict'; 7639 return globalOptions[key]; 7640 }; 7641 7642 /** 7643 * Get the global options 7644 * @static 7645 * @returns {{}} 7646 */ 7647 showdown.getOptions = function () { 7648 'use strict'; 7649 return globalOptions; 7650 }; 7651 7652 /** 7653 * Reset global options to the default values 7654 * @static 7655 */ 7656 showdown.resetOptions = function () { 7657 'use strict'; 7658 globalOptions = getDefaultOpts(true); 7659 }; 7660 7661 /** 7662 * Set the flavor showdown should use as default 7663 * @param {string} name 7664 */ 7665 showdown.setFlavor = function (name) { 7666 'use strict'; 7667 if (!flavor.hasOwnProperty(name)) { 7668 throw Error(name + ' flavor was not found'); 7669 } 7670 showdown.resetOptions(); 7671 var preset = flavor[name]; 7672 setFlavor = name; 7673 for (var option in preset) { 7674 if (preset.hasOwnProperty(option)) { 7675 globalOptions[option] = preset[option]; 7676 } 7677 } 7678 }; 7679 7680 /** 7681 * Get the currently set flavor 7682 * @returns {string} 7683 */ 7684 showdown.getFlavor = function () { 7685 'use strict'; 7686 return setFlavor; 7687 }; 7688 7689 /** 7690 * Get the options of a specified flavor. Returns undefined if the flavor was not found 7691 * @param {string} name Name of the flavor 7692 * @returns {{}|undefined} 7693 */ 7694 showdown.getFlavorOptions = function (name) { 7695 'use strict'; 7696 if (flavor.hasOwnProperty(name)) { 7697 return flavor[name]; 7698 } 7699 }; 7700 7701 /** 7702 * Get the default options 7703 * @static 7704 * @param {boolean} [simple=true] 7705 * @returns {{}} 7706 */ 7707 showdown.getDefaultOptions = function (simple) { 7708 'use strict'; 7709 return getDefaultOpts(simple); 7710 }; 7711 7712 /** 7713 * Get or set a subParser 7714 * 7715 * subParser(name) - Get a registered subParser 7716 * subParser(name, func) - Register a subParser 7717 * @static 7718 * @param {string} name 7719 * @param {function} [func] 7720 * @returns {*} 7721 */ 7722 showdown.subParser = function (name, func) { 7723 'use strict'; 7724 if (showdown.helper.isString(name)) { 7725 if (typeof func !== 'undefined') { 7726 parsers[name] = func; 7727 } else { 7728 if (parsers.hasOwnProperty(name)) { 7729 return parsers[name]; 7730 } else { 7731 throw Error('SubParser named ' + name + ' not registered!'); 7732 } 7733 } 7734 } 7735 }; 7736 7737 /** 7738 * Gets or registers an extension 7739 * @static 7740 * @param {string} name 7741 * @param {object|function=} ext 7742 * @returns {*} 7743 */ 7744 showdown.extension = function (name, ext) { 7745 'use strict'; 7746 7747 if (!showdown.helper.isString(name)) { 7748 throw Error('Extension \'name\' must be a string'); 7749 } 7750 7751 name = showdown.helper.stdExtName(name); 7752 7753 // Getter 7754 if (showdown.helper.isUndefined(ext)) { 7755 if (!extensions.hasOwnProperty(name)) { 7756 throw Error('Extension named ' + name + ' is not registered!'); 7757 } 7758 return extensions[name]; 7759 7760 // Setter 7761 } else { 7762 // Expand extension if it's wrapped in a function 7763 if (typeof ext === 'function') { 7764 ext = ext(); 7765 } 7766 7767 // Ensure extension is an array 7768 if (!showdown.helper.isArray(ext)) { 7769 ext = [ext]; 7770 } 7771 7772 var validExtension = validate(ext, name); 7773 7774 if (validExtension.valid) { 7775 extensions[name] = ext; 7776 } else { 7777 throw Error(validExtension.error); 7778 } 7779 } 7780 }; 7781 7782 /** 7783 * Gets all extensions registered 7784 * @returns {{}} 7785 */ 7786 showdown.getAllExtensions = function () { 7787 'use strict'; 7788 return extensions; 7789 }; 7790 7791 /** 7792 * Remove an extension 7793 * @param {string} name 7794 */ 7795 showdown.removeExtension = function (name) { 7796 'use strict'; 7797 delete extensions[name]; 7798 }; 7799 7800 /** 7801 * Removes all extensions 7802 */ 7803 showdown.resetExtensions = function () { 7804 'use strict'; 7805 extensions = {}; 7806 }; 7807 7808 /** 7809 * Validate extension 7810 * @param {array} extension 7811 * @param {string} name 7812 * @returns {{valid: boolean, error: string}} 7813 */ 7814 function validate (extension, name) { 7815 'use strict'; 7816 7817 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', 7818 ret = { 7819 valid: true, 7820 error: '' 7821 }; 7822 7823 if (!showdown.helper.isArray(extension)) { 7824 extension = [extension]; 7825 } 7826 7827 for (var i = 0; i < extension.length; ++i) { 7828 var baseMsg = errMsg + ' sub-extension ' + i + ': ', 7829 ext = extension[i]; 7830 if (typeof ext !== 'object') { 7831 ret.valid = false; 7832 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; 7833 return ret; 7834 } 7835 7836 if (!showdown.helper.isString(ext.type)) { 7837 ret.valid = false; 7838 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; 7839 return ret; 7840 } 7841 7842 var type = ext.type = ext.type.toLowerCase(); 7843 7844 // normalize extension type 7845 if (type === 'language') { 7846 type = ext.type = 'lang'; 7847 } 7848 7849 if (type === 'html') { 7850 type = ext.type = 'output'; 7851 } 7852 7853 if (type !== 'lang' && type !== 'output' && type !== 'listener') { 7854 ret.valid = false; 7855 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; 7856 return ret; 7857 } 7858 7859 if (type === 'listener') { 7860 if (showdown.helper.isUndefined(ext.listeners)) { 7861 ret.valid = false; 7862 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; 7863 return ret; 7864 } 7865 } else { 7866 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { 7867 ret.valid = false; 7868 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; 7869 return ret; 7870 } 7871 } 7872 7873 if (ext.listeners) { 7874 if (typeof ext.listeners !== 'object') { 7875 ret.valid = false; 7876 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; 7877 return ret; 7878 } 7879 for (var ln in ext.listeners) { 7880 if (ext.listeners.hasOwnProperty(ln)) { 7881 if (typeof ext.listeners[ln] !== 'function') { 7882 ret.valid = false; 7883 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + 7884 ' must be a function but ' + typeof ext.listeners[ln] + ' given'; 7885 return ret; 7886 } 7887 } 7888 } 7889 } 7890 7891 if (ext.filter) { 7892 if (typeof ext.filter !== 'function') { 7893 ret.valid = false; 7894 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; 7895 return ret; 7896 } 7897 } else if (ext.regex) { 7898 if (showdown.helper.isString(ext.regex)) { 7899 ext.regex = new RegExp(ext.regex, 'g'); 7900 } 7901 if (!(ext.regex instanceof RegExp)) { 7902 ret.valid = false; 7903 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; 7904 return ret; 7905 } 7906 if (showdown.helper.isUndefined(ext.replace)) { 7907 ret.valid = false; 7908 ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; 7909 return ret; 7910 } 7911 } 7912 } 7913 return ret; 7914 } 7915 7916 /** 7917 * Validate extension 7918 * @param {object} ext 7919 * @returns {boolean} 7920 */ 7921 showdown.validateExtension = function (ext) { 7922 'use strict'; 7923 7924 var validateExtension = validate(ext, null); 7925 if (!validateExtension.valid) { 7926 console.warn(validateExtension.error); 7927 return false; 7928 } 7929 return true; 7930 }; 7931 7932 /** 7933 * showdownjs helper functions 7934 */ 7935 7936 if (!showdown.hasOwnProperty('helper')) { 7937 showdown.helper = {}; 7938 } 7939 7940 /** 7941 * Check if var is string 7942 * @static 7943 * @param {string} a 7944 * @returns {boolean} 7945 */ 7946 showdown.helper.isString = function (a) { 7947 'use strict'; 7948 return (typeof a === 'string' || a instanceof String); 7949 }; 7950 7951 /** 7952 * Check if var is a function 7953 * @static 7954 * @param {*} a 7955 * @returns {boolean} 7956 */ 7957 showdown.helper.isFunction = function (a) { 7958 'use strict'; 7959 var getType = {}; 7960 return a && getType.toString.call(a) === '[object Function]'; 7961 }; 7962 7963 /** 7964 * isArray helper function 7965 * @static 7966 * @param {*} a 7967 * @returns {boolean} 7968 */ 7969 showdown.helper.isArray = function (a) { 7970 'use strict'; 7971 return Array.isArray(a); 7972 }; 7973 7974 /** 7975 * Check if value is undefined 7976 * @static 7977 * @param {*} value The value to check. 7978 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. 7979 */ 7980 showdown.helper.isUndefined = function (value) { 7981 'use strict'; 7982 return typeof value === 'undefined'; 7983 }; 7984 7985 /** 7986 * ForEach helper function 7987 * Iterates over Arrays and Objects (own properties only) 7988 * @static 7989 * @param {*} obj 7990 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object 7991 */ 7992 showdown.helper.forEach = function (obj, callback) { 7993 'use strict'; 7994 // check if obj is defined 7995 if (showdown.helper.isUndefined(obj)) { 7996 throw new Error('obj param is required'); 7997 } 7998 7999 if (showdown.helper.isUndefined(callback)) { 8000 throw new Error('callback param is required'); 8001 } 8002 8003 if (!showdown.helper.isFunction(callback)) { 8004 throw new Error('callback param must be a function/closure'); 8005 } 8006 8007 if (typeof obj.forEach === 'function') { 8008 obj.forEach(callback); 8009 } else if (showdown.helper.isArray(obj)) { 8010 for (var i = 0; i < obj.length; i++) { 8011 callback(obj[i], i, obj); 8012 } 8013 } else if (typeof (obj) === 'object') { 8014 for (var prop in obj) { 8015 if (obj.hasOwnProperty(prop)) { 8016 callback(obj[prop], prop, obj); 8017 } 8018 } 8019 } else { 8020 throw new Error('obj does not seem to be an array or an iterable object'); 8021 } 8022 }; 8023 8024 /** 8025 * Standardidize extension name 8026 * @static 8027 * @param {string} s extension name 8028 * @returns {string} 8029 */ 8030 showdown.helper.stdExtName = function (s) { 8031 'use strict'; 8032 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase(); 8033 }; 8034 8035 function escapeCharactersCallback (wholeMatch, m1) { 8036 'use strict'; 8037 var charCodeToEscape = m1.charCodeAt(0); 8038 return '¨E' + charCodeToEscape + 'E'; 8039 } 8040 8041 /** 8042 * Callback used to escape characters when passing through String.replace 8043 * @static 8044 * @param {string} wholeMatch 8045 * @param {string} m1 8046 * @returns {string} 8047 */ 8048 showdown.helper.escapeCharactersCallback = escapeCharactersCallback; 8049 8050 /** 8051 * Escape characters in a string 8052 * @static 8053 * @param {string} text 8054 * @param {string} charsToEscape 8055 * @param {boolean} afterBackslash 8056 * @returns {XML|string|void|*} 8057 */ 8058 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) { 8059 'use strict'; 8060 // First we have to escape the escape characters so that 8061 // we can build a character class out of them 8062 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; 8063 8064 if (afterBackslash) { 8065 regexString = '\\\\' + regexString; 8066 } 8067 8068 var regex = new RegExp(regexString, 'g'); 8069 text = text.replace(regex, escapeCharactersCallback); 8070 8071 return text; 8072 }; 8073 8074 /** 8075 * Unescape HTML entities 8076 * @param txt 8077 * @returns {string} 8078 */ 8079 showdown.helper.unescapeHTMLEntities = function (txt) { 8080 'use strict'; 8081 8082 return txt 8083 .replace(/"/g, '"') 8084 .replace(/</g, '<') 8085 .replace(/>/g, '>') 8086 .replace(/&/g, '&'); 8087 }; 8088 8089 var rgxFindMatchPos = function (str, left, right, flags) { 8090 'use strict'; 8091 var f = flags || '', 8092 g = f.indexOf('g') > -1, 8093 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), 8094 l = new RegExp(left, f.replace(/g/g, '')), 8095 pos = [], 8096 t, s, m, start, end; 8097 8098 do { 8099 t = 0; 8100 while ((m = x.exec(str))) { 8101 if (l.test(m[0])) { 8102 if (!(t++)) { 8103 s = x.lastIndex; 8104 start = s - m[0].length; 8105 } 8106 } else if (t) { 8107 if (!--t) { 8108 end = m.index + m[0].length; 8109 var obj = { 8110 left: {start: start, end: s}, 8111 match: {start: s, end: m.index}, 8112 right: {start: m.index, end: end}, 8113 wholeMatch: {start: start, end: end} 8114 }; 8115 pos.push(obj); 8116 if (!g) { 8117 return pos; 8118 } 8119 } 8120 } 8121 } 8122 } while (t && (x.lastIndex = s)); 8123 8124 return pos; 8125 }; 8126 8127 /** 8128 * matchRecursiveRegExp 8129 * 8130 * (c) 2007 Steven Levithan <stevenlevithan.com> 8131 * MIT License 8132 * 8133 * Accepts a string to search, a left and right format delimiter 8134 * as regex patterns, and optional regex flags. Returns an array 8135 * of matches, allowing nested instances of left/right delimiters. 8136 * Use the "g" flag to return all matches, otherwise only the 8137 * first is returned. Be careful to ensure that the left and 8138 * right format delimiters produce mutually exclusive matches. 8139 * Backreferences are not supported within the right delimiter 8140 * due to how it is internally combined with the left delimiter. 8141 * When matching strings whose format delimiters are unbalanced 8142 * to the left or right, the output is intentionally as a 8143 * conventional regex library with recursion support would 8144 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using 8145 * "<" and ">" as the delimiters (both strings contain a single, 8146 * balanced instance of "<x>"). 8147 * 8148 * examples: 8149 * matchRecursiveRegExp("test", "\\(", "\\)") 8150 * returns: [] 8151 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") 8152 * returns: ["t<<e>><s>", ""] 8153 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") 8154 * returns: ["test"] 8155 */ 8156 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { 8157 'use strict'; 8158 8159 var matchPos = rgxFindMatchPos (str, left, right, flags), 8160 results = []; 8161 8162 for (var i = 0; i < matchPos.length; ++i) { 8163 results.push([ 8164 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 8165 str.slice(matchPos[i].match.start, matchPos[i].match.end), 8166 str.slice(matchPos[i].left.start, matchPos[i].left.end), 8167 str.slice(matchPos[i].right.start, matchPos[i].right.end) 8168 ]); 8169 } 8170 return results; 8171 }; 8172 8173 /** 8174 * 8175 * @param {string} str 8176 * @param {string|function} replacement 8177 * @param {string} left 8178 * @param {string} right 8179 * @param {string} flags 8180 * @returns {string} 8181 */ 8182 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { 8183 'use strict'; 8184 8185 if (!showdown.helper.isFunction(replacement)) { 8186 var repStr = replacement; 8187 replacement = function () { 8188 return repStr; 8189 }; 8190 } 8191 8192 var matchPos = rgxFindMatchPos(str, left, right, flags), 8193 finalStr = str, 8194 lng = matchPos.length; 8195 8196 if (lng > 0) { 8197 var bits = []; 8198 if (matchPos[0].wholeMatch.start !== 0) { 8199 bits.push(str.slice(0, matchPos[0].wholeMatch.start)); 8200 } 8201 for (var i = 0; i < lng; ++i) { 8202 bits.push( 8203 replacement( 8204 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 8205 str.slice(matchPos[i].match.start, matchPos[i].match.end), 8206 str.slice(matchPos[i].left.start, matchPos[i].left.end), 8207 str.slice(matchPos[i].right.start, matchPos[i].right.end) 8208 ) 8209 ); 8210 if (i < lng - 1) { 8211 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); 8212 } 8213 } 8214 if (matchPos[lng - 1].wholeMatch.end < str.length) { 8215 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); 8216 } 8217 finalStr = bits.join(''); 8218 } 8219 return finalStr; 8220 }; 8221 8222 /** 8223 * Returns the index within the passed String object of the first occurrence of the specified regex, 8224 * starting the search at fromIndex. Returns -1 if the value is not found. 8225 * 8226 * @param {string} str string to search 8227 * @param {RegExp} regex Regular expression to search 8228 * @param {int} [fromIndex = 0] Index to start the search 8229 * @returns {Number} 8230 * @throws InvalidArgumentError 8231 */ 8232 showdown.helper.regexIndexOf = function (str, regex, fromIndex) { 8233 'use strict'; 8234 if (!showdown.helper.isString(str)) { 8235 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 8236 } 8237 if (regex instanceof RegExp === false) { 8238 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp'; 8239 } 8240 var indexOf = str.substring(fromIndex || 0).search(regex); 8241 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf; 8242 }; 8243 8244 /** 8245 * Splits the passed string object at the defined index, and returns an array composed of the two substrings 8246 * @param {string} str string to split 8247 * @param {int} index index to split string at 8248 * @returns {[string,string]} 8249 * @throws InvalidArgumentError 8250 */ 8251 showdown.helper.splitAtIndex = function (str, index) { 8252 'use strict'; 8253 if (!showdown.helper.isString(str)) { 8254 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 8255 } 8256 return [str.substring(0, index), str.substring(index)]; 8257 }; 8258 8259 /** 8260 * Obfuscate an e-mail address through the use of Character Entities, 8261 * transforming ASCII characters into their equivalent decimal or hex entities. 8262 * 8263 * Since it has a random component, subsequent calls to this function produce different results 8264 * 8265 * @param {string} mail 8266 * @returns {string} 8267 */ 8268 showdown.helper.encodeEmailAddress = function (mail) { 8269 'use strict'; 8270 var encode = [ 8271 function (ch) { 8272 return '&#' + ch.charCodeAt(0) + ';'; 8273 }, 8274 function (ch) { 8275 return '&#x' + ch.charCodeAt(0).toString(16) + ';'; 8276 }, 8277 function (ch) { 8278 return ch; 8279 } 8280 ]; 8281 8282 mail = mail.replace(/./g, function (ch) { 8283 if (ch === '@') { 8284 // this *must* be encoded. I insist. 8285 ch = encode[Math.floor(Math.random() * 2)](ch); 8286 } else { 8287 var r = Math.random(); 8288 // roughly 10% raw, 45% hex, 45% dec 8289 ch = ( 8290 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) 8291 ); 8292 } 8293 return ch; 8294 }); 8295 8296 return mail; 8297 }; 8298 8299 /** 8300 * 8301 * @param str 8302 * @param targetLength 8303 * @param padString 8304 * @returns {string} 8305 */ 8306 showdown.helper.padEnd = function padEnd (str, targetLength, padString) { 8307 'use strict'; 8308 /*jshint bitwise: false*/ 8309 // eslint-disable-next-line space-infix-ops 8310 targetLength = targetLength>>0; //floor if number or convert non-number to 0; 8311 /*jshint bitwise: true*/ 8312 padString = String(padString || ' '); 8313 if (str.length > targetLength) { 8314 return String(str); 8315 } else { 8316 targetLength = targetLength - str.length; 8317 if (targetLength > padString.length) { 8318 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 8319 } 8320 return String(str) + padString.slice(0,targetLength); 8321 } 8322 }; 8323 8324 /** 8325 * POLYFILLS 8326 */ 8327 // use this instead of builtin is undefined for IE8 compatibility 8328 if (typeof console === 'undefined') { 8329 console = { 8330 warn: function (msg) { 8331 'use strict'; 8332 alert(msg); 8333 }, 8334 log: function (msg) { 8335 'use strict'; 8336 alert(msg); 8337 }, 8338 error: function (msg) { 8339 'use strict'; 8340 throw msg; 8341 } 8342 }; 8343 } 8344 8345 /** 8346 * Common regexes. 8347 * We declare some common regexes to improve performance 8348 */ 8349 showdown.helper.regexes = { 8350 asteriskDashAndColon: /([*_:~])/g 8351 }; 8352 8353 /** 8354 * EMOJIS LIST 8355 */ 8356 showdown.helper.emojis = { 8357 '+1':'\ud83d\udc4d', 8358 '-1':'\ud83d\udc4e', 8359 '100':'\ud83d\udcaf', 8360 '1234':'\ud83d\udd22', 8361 '1st_place_medal':'\ud83e\udd47', 8362 '2nd_place_medal':'\ud83e\udd48', 8363 '3rd_place_medal':'\ud83e\udd49', 8364 '8ball':'\ud83c\udfb1', 8365 'a':'\ud83c\udd70\ufe0f', 8366 'ab':'\ud83c\udd8e', 8367 'abc':'\ud83d\udd24', 8368 'abcd':'\ud83d\udd21', 8369 'accept':'\ud83c\ude51', 8370 'aerial_tramway':'\ud83d\udea1', 8371 'airplane':'\u2708\ufe0f', 8372 'alarm_clock':'\u23f0', 8373 'alembic':'\u2697\ufe0f', 8374 'alien':'\ud83d\udc7d', 8375 'ambulance':'\ud83d\ude91', 8376 'amphora':'\ud83c\udffa', 8377 'anchor':'\u2693\ufe0f', 8378 'angel':'\ud83d\udc7c', 8379 'anger':'\ud83d\udca2', 8380 'angry':'\ud83d\ude20', 8381 'anguished':'\ud83d\ude27', 8382 'ant':'\ud83d\udc1c', 8383 'apple':'\ud83c\udf4e', 8384 'aquarius':'\u2652\ufe0f', 8385 'aries':'\u2648\ufe0f', 8386 'arrow_backward':'\u25c0\ufe0f', 8387 'arrow_double_down':'\u23ec', 8388 'arrow_double_up':'\u23eb', 8389 'arrow_down':'\u2b07\ufe0f', 8390 'arrow_down_small':'\ud83d\udd3d', 8391 'arrow_forward':'\u25b6\ufe0f', 8392 'arrow_heading_down':'\u2935\ufe0f', 8393 'arrow_heading_up':'\u2934\ufe0f', 8394 'arrow_left':'\u2b05\ufe0f', 8395 'arrow_lower_left':'\u2199\ufe0f', 8396 'arrow_lower_right':'\u2198\ufe0f', 8397 'arrow_right':'\u27a1\ufe0f', 8398 'arrow_right_hook':'\u21aa\ufe0f', 8399 'arrow_up':'\u2b06\ufe0f', 8400 'arrow_up_down':'\u2195\ufe0f', 8401 'arrow_up_small':'\ud83d\udd3c', 8402 'arrow_upper_left':'\u2196\ufe0f', 8403 'arrow_upper_right':'\u2197\ufe0f', 8404 'arrows_clockwise':'\ud83d\udd03', 8405 'arrows_counterclockwise':'\ud83d\udd04', 8406 'art':'\ud83c\udfa8', 8407 'articulated_lorry':'\ud83d\ude9b', 8408 'artificial_satellite':'\ud83d\udef0', 8409 'astonished':'\ud83d\ude32', 8410 'athletic_shoe':'\ud83d\udc5f', 8411 'atm':'\ud83c\udfe7', 8412 'atom_symbol':'\u269b\ufe0f', 8413 'avocado':'\ud83e\udd51', 8414 'b':'\ud83c\udd71\ufe0f', 8415 'baby':'\ud83d\udc76', 8416 'baby_bottle':'\ud83c\udf7c', 8417 'baby_chick':'\ud83d\udc24', 8418 'baby_symbol':'\ud83d\udebc', 8419 'back':'\ud83d\udd19', 8420 'bacon':'\ud83e\udd53', 8421 'badminton':'\ud83c\udff8', 8422 'baggage_claim':'\ud83d\udec4', 8423 'baguette_bread':'\ud83e\udd56', 8424 'balance_scale':'\u2696\ufe0f', 8425 'balloon':'\ud83c\udf88', 8426 'ballot_box':'\ud83d\uddf3', 8427 'ballot_box_with_check':'\u2611\ufe0f', 8428 'bamboo':'\ud83c\udf8d', 8429 'banana':'\ud83c\udf4c', 8430 'bangbang':'\u203c\ufe0f', 8431 'bank':'\ud83c\udfe6', 8432 'bar_chart':'\ud83d\udcca', 8433 'barber':'\ud83d\udc88', 8434 'baseball':'\u26be\ufe0f', 8435 'basketball':'\ud83c\udfc0', 8436 'basketball_man':'\u26f9\ufe0f', 8437 'basketball_woman':'\u26f9\ufe0f‍\u2640\ufe0f', 8438 'bat':'\ud83e\udd87', 8439 'bath':'\ud83d\udec0', 8440 'bathtub':'\ud83d\udec1', 8441 'battery':'\ud83d\udd0b', 8442 'beach_umbrella':'\ud83c\udfd6', 8443 'bear':'\ud83d\udc3b', 8444 'bed':'\ud83d\udecf', 8445 'bee':'\ud83d\udc1d', 8446 'beer':'\ud83c\udf7a', 8447 'beers':'\ud83c\udf7b', 8448 'beetle':'\ud83d\udc1e', 8449 'beginner':'\ud83d\udd30', 8450 'bell':'\ud83d\udd14', 8451 'bellhop_bell':'\ud83d\udece', 8452 'bento':'\ud83c\udf71', 8453 'biking_man':'\ud83d\udeb4', 8454 'bike':'\ud83d\udeb2', 8455 'biking_woman':'\ud83d\udeb4‍\u2640\ufe0f', 8456 'bikini':'\ud83d\udc59', 8457 'biohazard':'\u2623\ufe0f', 8458 'bird':'\ud83d\udc26', 8459 'birthday':'\ud83c\udf82', 8460 'black_circle':'\u26ab\ufe0f', 8461 'black_flag':'\ud83c\udff4', 8462 'black_heart':'\ud83d\udda4', 8463 'black_joker':'\ud83c\udccf', 8464 'black_large_square':'\u2b1b\ufe0f', 8465 'black_medium_small_square':'\u25fe\ufe0f', 8466 'black_medium_square':'\u25fc\ufe0f', 8467 'black_nib':'\u2712\ufe0f', 8468 'black_small_square':'\u25aa\ufe0f', 8469 'black_square_button':'\ud83d\udd32', 8470 'blonde_man':'\ud83d\udc71', 8471 'blonde_woman':'\ud83d\udc71‍\u2640\ufe0f', 8472 'blossom':'\ud83c\udf3c', 8473 'blowfish':'\ud83d\udc21', 8474 'blue_book':'\ud83d\udcd8', 8475 'blue_car':'\ud83d\ude99', 8476 'blue_heart':'\ud83d\udc99', 8477 'blush':'\ud83d\ude0a', 8478 'boar':'\ud83d\udc17', 8479 'boat':'\u26f5\ufe0f', 8480 'bomb':'\ud83d\udca3', 8481 'book':'\ud83d\udcd6', 8482 'bookmark':'\ud83d\udd16', 8483 'bookmark_tabs':'\ud83d\udcd1', 8484 'books':'\ud83d\udcda', 8485 'boom':'\ud83d\udca5', 8486 'boot':'\ud83d\udc62', 8487 'bouquet':'\ud83d\udc90', 8488 'bowing_man':'\ud83d\ude47', 8489 'bow_and_arrow':'\ud83c\udff9', 8490 'bowing_woman':'\ud83d\ude47‍\u2640\ufe0f', 8491 'bowling':'\ud83c\udfb3', 8492 'boxing_glove':'\ud83e\udd4a', 8493 'boy':'\ud83d\udc66', 8494 'bread':'\ud83c\udf5e', 8495 'bride_with_veil':'\ud83d\udc70', 8496 'bridge_at_night':'\ud83c\udf09', 8497 'briefcase':'\ud83d\udcbc', 8498 'broken_heart':'\ud83d\udc94', 8499 'bug':'\ud83d\udc1b', 8500 'building_construction':'\ud83c\udfd7', 8501 'bulb':'\ud83d\udca1', 8502 'bullettrain_front':'\ud83d\ude85', 8503 'bullettrain_side':'\ud83d\ude84', 8504 'burrito':'\ud83c\udf2f', 8505 'bus':'\ud83d\ude8c', 8506 'business_suit_levitating':'\ud83d\udd74', 8507 'busstop':'\ud83d\ude8f', 8508 'bust_in_silhouette':'\ud83d\udc64', 8509 'busts_in_silhouette':'\ud83d\udc65', 8510 'butterfly':'\ud83e\udd8b', 8511 'cactus':'\ud83c\udf35', 8512 'cake':'\ud83c\udf70', 8513 'calendar':'\ud83d\udcc6', 8514 'call_me_hand':'\ud83e\udd19', 8515 'calling':'\ud83d\udcf2', 8516 'camel':'\ud83d\udc2b', 8517 'camera':'\ud83d\udcf7', 8518 'camera_flash':'\ud83d\udcf8', 8519 'camping':'\ud83c\udfd5', 8520 'cancer':'\u264b\ufe0f', 8521 'candle':'\ud83d\udd6f', 8522 'candy':'\ud83c\udf6c', 8523 'canoe':'\ud83d\udef6', 8524 'capital_abcd':'\ud83d\udd20', 8525 'capricorn':'\u2651\ufe0f', 8526 'car':'\ud83d\ude97', 8527 'card_file_box':'\ud83d\uddc3', 8528 'card_index':'\ud83d\udcc7', 8529 'card_index_dividers':'\ud83d\uddc2', 8530 'carousel_horse':'\ud83c\udfa0', 8531 'carrot':'\ud83e\udd55', 8532 'cat':'\ud83d\udc31', 8533 'cat2':'\ud83d\udc08', 8534 'cd':'\ud83d\udcbf', 8535 'chains':'\u26d3', 8536 'champagne':'\ud83c\udf7e', 8537 'chart':'\ud83d\udcb9', 8538 'chart_with_downwards_trend':'\ud83d\udcc9', 8539 'chart_with_upwards_trend':'\ud83d\udcc8', 8540 'checkered_flag':'\ud83c\udfc1', 8541 'cheese':'\ud83e\uddc0', 8542 'cherries':'\ud83c\udf52', 8543 'cherry_blossom':'\ud83c\udf38', 8544 'chestnut':'\ud83c\udf30', 8545 'chicken':'\ud83d\udc14', 8546 'children_crossing':'\ud83d\udeb8', 8547 'chipmunk':'\ud83d\udc3f', 8548 'chocolate_bar':'\ud83c\udf6b', 8549 'christmas_tree':'\ud83c\udf84', 8550 'church':'\u26ea\ufe0f', 8551 'cinema':'\ud83c\udfa6', 8552 'circus_tent':'\ud83c\udfaa', 8553 'city_sunrise':'\ud83c\udf07', 8554 'city_sunset':'\ud83c\udf06', 8555 'cityscape':'\ud83c\udfd9', 8556 'cl':'\ud83c\udd91', 8557 'clamp':'\ud83d\udddc', 8558 'clap':'\ud83d\udc4f', 8559 'clapper':'\ud83c\udfac', 8560 'classical_building':'\ud83c\udfdb', 8561 'clinking_glasses':'\ud83e\udd42', 8562 'clipboard':'\ud83d\udccb', 8563 'clock1':'\ud83d\udd50', 8564 'clock10':'\ud83d\udd59', 8565 'clock1030':'\ud83d\udd65', 8566 'clock11':'\ud83d\udd5a', 8567 'clock1130':'\ud83d\udd66', 8568 'clock12':'\ud83d\udd5b', 8569 'clock1230':'\ud83d\udd67', 8570 'clock130':'\ud83d\udd5c', 8571 'clock2':'\ud83d\udd51', 8572 'clock230':'\ud83d\udd5d', 8573 'clock3':'\ud83d\udd52', 8574 'clock330':'\ud83d\udd5e', 8575 'clock4':'\ud83d\udd53', 8576 'clock430':'\ud83d\udd5f', 8577 'clock5':'\ud83d\udd54', 8578 'clock530':'\ud83d\udd60', 8579 'clock6':'\ud83d\udd55', 8580 'clock630':'\ud83d\udd61', 8581 'clock7':'\ud83d\udd56', 8582 'clock730':'\ud83d\udd62', 8583 'clock8':'\ud83d\udd57', 8584 'clock830':'\ud83d\udd63', 8585 'clock9':'\ud83d\udd58', 8586 'clock930':'\ud83d\udd64', 8587 'closed_book':'\ud83d\udcd5', 8588 'closed_lock_with_key':'\ud83d\udd10', 8589 'closed_umbrella':'\ud83c\udf02', 8590 'cloud':'\u2601\ufe0f', 8591 'cloud_with_lightning':'\ud83c\udf29', 8592 'cloud_with_lightning_and_rain':'\u26c8', 8593 'cloud_with_rain':'\ud83c\udf27', 8594 'cloud_with_snow':'\ud83c\udf28', 8595 'clown_face':'\ud83e\udd21', 8596 'clubs':'\u2663\ufe0f', 8597 'cocktail':'\ud83c\udf78', 8598 'coffee':'\u2615\ufe0f', 8599 'coffin':'\u26b0\ufe0f', 8600 'cold_sweat':'\ud83d\ude30', 8601 'comet':'\u2604\ufe0f', 8602 'computer':'\ud83d\udcbb', 8603 'computer_mouse':'\ud83d\uddb1', 8604 'confetti_ball':'\ud83c\udf8a', 8605 'confounded':'\ud83d\ude16', 8606 'confused':'\ud83d\ude15', 8607 'congratulations':'\u3297\ufe0f', 8608 'construction':'\ud83d\udea7', 8609 'construction_worker_man':'\ud83d\udc77', 8610 'construction_worker_woman':'\ud83d\udc77‍\u2640\ufe0f', 8611 'control_knobs':'\ud83c\udf9b', 8612 'convenience_store':'\ud83c\udfea', 8613 'cookie':'\ud83c\udf6a', 8614 'cool':'\ud83c\udd92', 8615 'policeman':'\ud83d\udc6e', 8616 'copyright':'\u00a9\ufe0f', 8617 'corn':'\ud83c\udf3d', 8618 'couch_and_lamp':'\ud83d\udecb', 8619 'couple':'\ud83d\udc6b', 8620 'couple_with_heart_woman_man':'\ud83d\udc91', 8621 'couple_with_heart_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc68', 8622 'couple_with_heart_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc69', 8623 'couplekiss_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc68', 8624 'couplekiss_man_woman':'\ud83d\udc8f', 8625 'couplekiss_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc69', 8626 'cow':'\ud83d\udc2e', 8627 'cow2':'\ud83d\udc04', 8628 'cowboy_hat_face':'\ud83e\udd20', 8629 'crab':'\ud83e\udd80', 8630 'crayon':'\ud83d\udd8d', 8631 'credit_card':'\ud83d\udcb3', 8632 'crescent_moon':'\ud83c\udf19', 8633 'cricket':'\ud83c\udfcf', 8634 'crocodile':'\ud83d\udc0a', 8635 'croissant':'\ud83e\udd50', 8636 'crossed_fingers':'\ud83e\udd1e', 8637 'crossed_flags':'\ud83c\udf8c', 8638 'crossed_swords':'\u2694\ufe0f', 8639 'crown':'\ud83d\udc51', 8640 'cry':'\ud83d\ude22', 8641 'crying_cat_face':'\ud83d\ude3f', 8642 'crystal_ball':'\ud83d\udd2e', 8643 'cucumber':'\ud83e\udd52', 8644 'cupid':'\ud83d\udc98', 8645 'curly_loop':'\u27b0', 8646 'currency_exchange':'\ud83d\udcb1', 8647 'curry':'\ud83c\udf5b', 8648 'custard':'\ud83c\udf6e', 8649 'customs':'\ud83d\udec3', 8650 'cyclone':'\ud83c\udf00', 8651 'dagger':'\ud83d\udde1', 8652 'dancer':'\ud83d\udc83', 8653 'dancing_women':'\ud83d\udc6f', 8654 'dancing_men':'\ud83d\udc6f‍\u2642\ufe0f', 8655 'dango':'\ud83c\udf61', 8656 'dark_sunglasses':'\ud83d\udd76', 8657 'dart':'\ud83c\udfaf', 8658 'dash':'\ud83d\udca8', 8659 'date':'\ud83d\udcc5', 8660 'deciduous_tree':'\ud83c\udf33', 8661 'deer':'\ud83e\udd8c', 8662 'department_store':'\ud83c\udfec', 8663 'derelict_house':'\ud83c\udfda', 8664 'desert':'\ud83c\udfdc', 8665 'desert_island':'\ud83c\udfdd', 8666 'desktop_computer':'\ud83d\udda5', 8667 'male_detective':'\ud83d\udd75\ufe0f', 8668 'diamond_shape_with_a_dot_inside':'\ud83d\udca0', 8669 'diamonds':'\u2666\ufe0f', 8670 'disappointed':'\ud83d\ude1e', 8671 'disappointed_relieved':'\ud83d\ude25', 8672 'dizzy':'\ud83d\udcab', 8673 'dizzy_face':'\ud83d\ude35', 8674 'do_not_litter':'\ud83d\udeaf', 8675 'dog':'\ud83d\udc36', 8676 'dog2':'\ud83d\udc15', 8677 'dollar':'\ud83d\udcb5', 8678 'dolls':'\ud83c\udf8e', 8679 'dolphin':'\ud83d\udc2c', 8680 'door':'\ud83d\udeaa', 8681 'doughnut':'\ud83c\udf69', 8682 'dove':'\ud83d\udd4a', 8683 'dragon':'\ud83d\udc09', 8684 'dragon_face':'\ud83d\udc32', 8685 'dress':'\ud83d\udc57', 8686 'dromedary_camel':'\ud83d\udc2a', 8687 'drooling_face':'\ud83e\udd24', 8688 'droplet':'\ud83d\udca7', 8689 'drum':'\ud83e\udd41', 8690 'duck':'\ud83e\udd86', 8691 'dvd':'\ud83d\udcc0', 8692 'e-mail':'\ud83d\udce7', 8693 'eagle':'\ud83e\udd85', 8694 'ear':'\ud83d\udc42', 8695 'ear_of_rice':'\ud83c\udf3e', 8696 'earth_africa':'\ud83c\udf0d', 8697 'earth_americas':'\ud83c\udf0e', 8698 'earth_asia':'\ud83c\udf0f', 8699 'egg':'\ud83e\udd5a', 8700 'eggplant':'\ud83c\udf46', 8701 'eight_pointed_black_star':'\u2734\ufe0f', 8702 'eight_spoked_asterisk':'\u2733\ufe0f', 8703 'electric_plug':'\ud83d\udd0c', 8704 'elephant':'\ud83d\udc18', 8705 'email':'\u2709\ufe0f', 8706 'end':'\ud83d\udd1a', 8707 'envelope_with_arrow':'\ud83d\udce9', 8708 'euro':'\ud83d\udcb6', 8709 'european_castle':'\ud83c\udff0', 8710 'european_post_office':'\ud83c\udfe4', 8711 'evergreen_tree':'\ud83c\udf32', 8712 'exclamation':'\u2757\ufe0f', 8713 'expressionless':'\ud83d\ude11', 8714 'eye':'\ud83d\udc41', 8715 'eye_speech_bubble':'\ud83d\udc41‍\ud83d\udde8', 8716 'eyeglasses':'\ud83d\udc53', 8717 'eyes':'\ud83d\udc40', 8718 'face_with_head_bandage':'\ud83e\udd15', 8719 'face_with_thermometer':'\ud83e\udd12', 8720 'fist_oncoming':'\ud83d\udc4a', 8721 'factory':'\ud83c\udfed', 8722 'fallen_leaf':'\ud83c\udf42', 8723 'family_man_woman_boy':'\ud83d\udc6a', 8724 'family_man_boy':'\ud83d\udc68‍\ud83d\udc66', 8725 'family_man_boy_boy':'\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 8726 'family_man_girl':'\ud83d\udc68‍\ud83d\udc67', 8727 'family_man_girl_boy':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 8728 'family_man_girl_girl':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 8729 'family_man_man_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66', 8730 'family_man_man_boy_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 8731 'family_man_man_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67', 8732 'family_man_man_girl_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 8733 'family_man_man_girl_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 8734 'family_man_woman_boy_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 8735 'family_man_woman_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67', 8736 'family_man_woman_girl_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 8737 'family_man_woman_girl_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 8738 'family_woman_boy':'\ud83d\udc69‍\ud83d\udc66', 8739 'family_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 8740 'family_woman_girl':'\ud83d\udc69‍\ud83d\udc67', 8741 'family_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 8742 'family_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 8743 'family_woman_woman_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66', 8744 'family_woman_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 8745 'family_woman_woman_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67', 8746 'family_woman_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 8747 'family_woman_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 8748 'fast_forward':'\u23e9', 8749 'fax':'\ud83d\udce0', 8750 'fearful':'\ud83d\ude28', 8751 'feet':'\ud83d\udc3e', 8752 'female_detective':'\ud83d\udd75\ufe0f‍\u2640\ufe0f', 8753 'ferris_wheel':'\ud83c\udfa1', 8754 'ferry':'\u26f4', 8755 'field_hockey':'\ud83c\udfd1', 8756 'file_cabinet':'\ud83d\uddc4', 8757 'file_folder':'\ud83d\udcc1', 8758 'film_projector':'\ud83d\udcfd', 8759 'film_strip':'\ud83c\udf9e', 8760 'fire':'\ud83d\udd25', 8761 'fire_engine':'\ud83d\ude92', 8762 'fireworks':'\ud83c\udf86', 8763 'first_quarter_moon':'\ud83c\udf13', 8764 'first_quarter_moon_with_face':'\ud83c\udf1b', 8765 'fish':'\ud83d\udc1f', 8766 'fish_cake':'\ud83c\udf65', 8767 'fishing_pole_and_fish':'\ud83c\udfa3', 8768 'fist_raised':'\u270a', 8769 'fist_left':'\ud83e\udd1b', 8770 'fist_right':'\ud83e\udd1c', 8771 'flags':'\ud83c\udf8f', 8772 'flashlight':'\ud83d\udd26', 8773 'fleur_de_lis':'\u269c\ufe0f', 8774 'flight_arrival':'\ud83d\udeec', 8775 'flight_departure':'\ud83d\udeeb', 8776 'floppy_disk':'\ud83d\udcbe', 8777 'flower_playing_cards':'\ud83c\udfb4', 8778 'flushed':'\ud83d\ude33', 8779 'fog':'\ud83c\udf2b', 8780 'foggy':'\ud83c\udf01', 8781 'football':'\ud83c\udfc8', 8782 'footprints':'\ud83d\udc63', 8783 'fork_and_knife':'\ud83c\udf74', 8784 'fountain':'\u26f2\ufe0f', 8785 'fountain_pen':'\ud83d\udd8b', 8786 'four_leaf_clover':'\ud83c\udf40', 8787 'fox_face':'\ud83e\udd8a', 8788 'framed_picture':'\ud83d\uddbc', 8789 'free':'\ud83c\udd93', 8790 'fried_egg':'\ud83c\udf73', 8791 'fried_shrimp':'\ud83c\udf64', 8792 'fries':'\ud83c\udf5f', 8793 'frog':'\ud83d\udc38', 8794 'frowning':'\ud83d\ude26', 8795 'frowning_face':'\u2639\ufe0f', 8796 'frowning_man':'\ud83d\ude4d‍\u2642\ufe0f', 8797 'frowning_woman':'\ud83d\ude4d', 8798 'middle_finger':'\ud83d\udd95', 8799 'fuelpump':'\u26fd\ufe0f', 8800 'full_moon':'\ud83c\udf15', 8801 'full_moon_with_face':'\ud83c\udf1d', 8802 'funeral_urn':'\u26b1\ufe0f', 8803 'game_die':'\ud83c\udfb2', 8804 'gear':'\u2699\ufe0f', 8805 'gem':'\ud83d\udc8e', 8806 'gemini':'\u264a\ufe0f', 8807 'ghost':'\ud83d\udc7b', 8808 'gift':'\ud83c\udf81', 8809 'gift_heart':'\ud83d\udc9d', 8810 'girl':'\ud83d\udc67', 8811 'globe_with_meridians':'\ud83c\udf10', 8812 'goal_net':'\ud83e\udd45', 8813 'goat':'\ud83d\udc10', 8814 'golf':'\u26f3\ufe0f', 8815 'golfing_man':'\ud83c\udfcc\ufe0f', 8816 'golfing_woman':'\ud83c\udfcc\ufe0f‍\u2640\ufe0f', 8817 'gorilla':'\ud83e\udd8d', 8818 'grapes':'\ud83c\udf47', 8819 'green_apple':'\ud83c\udf4f', 8820 'green_book':'\ud83d\udcd7', 8821 'green_heart':'\ud83d\udc9a', 8822 'green_salad':'\ud83e\udd57', 8823 'grey_exclamation':'\u2755', 8824 'grey_question':'\u2754', 8825 'grimacing':'\ud83d\ude2c', 8826 'grin':'\ud83d\ude01', 8827 'grinning':'\ud83d\ude00', 8828 'guardsman':'\ud83d\udc82', 8829 'guardswoman':'\ud83d\udc82‍\u2640\ufe0f', 8830 'guitar':'\ud83c\udfb8', 8831 'gun':'\ud83d\udd2b', 8832 'haircut_woman':'\ud83d\udc87', 8833 'haircut_man':'\ud83d\udc87‍\u2642\ufe0f', 8834 'hamburger':'\ud83c\udf54', 8835 'hammer':'\ud83d\udd28', 8836 'hammer_and_pick':'\u2692', 8837 'hammer_and_wrench':'\ud83d\udee0', 8838 'hamster':'\ud83d\udc39', 8839 'hand':'\u270b', 8840 'handbag':'\ud83d\udc5c', 8841 'handshake':'\ud83e\udd1d', 8842 'hankey':'\ud83d\udca9', 8843 'hatched_chick':'\ud83d\udc25', 8844 'hatching_chick':'\ud83d\udc23', 8845 'headphones':'\ud83c\udfa7', 8846 'hear_no_evil':'\ud83d\ude49', 8847 'heart':'\u2764\ufe0f', 8848 'heart_decoration':'\ud83d\udc9f', 8849 'heart_eyes':'\ud83d\ude0d', 8850 'heart_eyes_cat':'\ud83d\ude3b', 8851 'heartbeat':'\ud83d\udc93', 8852 'heartpulse':'\ud83d\udc97', 8853 'hearts':'\u2665\ufe0f', 8854 'heavy_check_mark':'\u2714\ufe0f', 8855 'heavy_division_sign':'\u2797', 8856 'heavy_dollar_sign':'\ud83d\udcb2', 8857 'heavy_heart_exclamation':'\u2763\ufe0f', 8858 'heavy_minus_sign':'\u2796', 8859 'heavy_multiplication_x':'\u2716\ufe0f', 8860 'heavy_plus_sign':'\u2795', 8861 'helicopter':'\ud83d\ude81', 8862 'herb':'\ud83c\udf3f', 8863 'hibiscus':'\ud83c\udf3a', 8864 'high_brightness':'\ud83d\udd06', 8865 'high_heel':'\ud83d\udc60', 8866 'hocho':'\ud83d\udd2a', 8867 'hole':'\ud83d\udd73', 8868 'honey_pot':'\ud83c\udf6f', 8869 'horse':'\ud83d\udc34', 8870 'horse_racing':'\ud83c\udfc7', 8871 'hospital':'\ud83c\udfe5', 8872 'hot_pepper':'\ud83c\udf36', 8873 'hotdog':'\ud83c\udf2d', 8874 'hotel':'\ud83c\udfe8', 8875 'hotsprings':'\u2668\ufe0f', 8876 'hourglass':'\u231b\ufe0f', 8877 'hourglass_flowing_sand':'\u23f3', 8878 'house':'\ud83c\udfe0', 8879 'house_with_garden':'\ud83c\udfe1', 8880 'houses':'\ud83c\udfd8', 8881 'hugs':'\ud83e\udd17', 8882 'hushed':'\ud83d\ude2f', 8883 'ice_cream':'\ud83c\udf68', 8884 'ice_hockey':'\ud83c\udfd2', 8885 'ice_skate':'\u26f8', 8886 'icecream':'\ud83c\udf66', 8887 'id':'\ud83c\udd94', 8888 'ideograph_advantage':'\ud83c\ude50', 8889 'imp':'\ud83d\udc7f', 8890 'inbox_tray':'\ud83d\udce5', 8891 'incoming_envelope':'\ud83d\udce8', 8892 'tipping_hand_woman':'\ud83d\udc81', 8893 'information_source':'\u2139\ufe0f', 8894 'innocent':'\ud83d\ude07', 8895 'interrobang':'\u2049\ufe0f', 8896 'iphone':'\ud83d\udcf1', 8897 'izakaya_lantern':'\ud83c\udfee', 8898 'jack_o_lantern':'\ud83c\udf83', 8899 'japan':'\ud83d\uddfe', 8900 'japanese_castle':'\ud83c\udfef', 8901 'japanese_goblin':'\ud83d\udc7a', 8902 'japanese_ogre':'\ud83d\udc79', 8903 'jeans':'\ud83d\udc56', 8904 'joy':'\ud83d\ude02', 8905 'joy_cat':'\ud83d\ude39', 8906 'joystick':'\ud83d\udd79', 8907 'kaaba':'\ud83d\udd4b', 8908 'key':'\ud83d\udd11', 8909 'keyboard':'\u2328\ufe0f', 8910 'keycap_ten':'\ud83d\udd1f', 8911 'kick_scooter':'\ud83d\udef4', 8912 'kimono':'\ud83d\udc58', 8913 'kiss':'\ud83d\udc8b', 8914 'kissing':'\ud83d\ude17', 8915 'kissing_cat':'\ud83d\ude3d', 8916 'kissing_closed_eyes':'\ud83d\ude1a', 8917 'kissing_heart':'\ud83d\ude18', 8918 'kissing_smiling_eyes':'\ud83d\ude19', 8919 'kiwi_fruit':'\ud83e\udd5d', 8920 'koala':'\ud83d\udc28', 8921 'koko':'\ud83c\ude01', 8922 'label':'\ud83c\udff7', 8923 'large_blue_circle':'\ud83d\udd35', 8924 'large_blue_diamond':'\ud83d\udd37', 8925 'large_orange_diamond':'\ud83d\udd36', 8926 'last_quarter_moon':'\ud83c\udf17', 8927 'last_quarter_moon_with_face':'\ud83c\udf1c', 8928 'latin_cross':'\u271d\ufe0f', 8929 'laughing':'\ud83d\ude06', 8930 'leaves':'\ud83c\udf43', 8931 'ledger':'\ud83d\udcd2', 8932 'left_luggage':'\ud83d\udec5', 8933 'left_right_arrow':'\u2194\ufe0f', 8934 'leftwards_arrow_with_hook':'\u21a9\ufe0f', 8935 'lemon':'\ud83c\udf4b', 8936 'leo':'\u264c\ufe0f', 8937 'leopard':'\ud83d\udc06', 8938 'level_slider':'\ud83c\udf9a', 8939 'libra':'\u264e\ufe0f', 8940 'light_rail':'\ud83d\ude88', 8941 'link':'\ud83d\udd17', 8942 'lion':'\ud83e\udd81', 8943 'lips':'\ud83d\udc44', 8944 'lipstick':'\ud83d\udc84', 8945 'lizard':'\ud83e\udd8e', 8946 'lock':'\ud83d\udd12', 8947 'lock_with_ink_pen':'\ud83d\udd0f', 8948 'lollipop':'\ud83c\udf6d', 8949 'loop':'\u27bf', 8950 'loud_sound':'\ud83d\udd0a', 8951 'loudspeaker':'\ud83d\udce2', 8952 'love_hotel':'\ud83c\udfe9', 8953 'love_letter':'\ud83d\udc8c', 8954 'low_brightness':'\ud83d\udd05', 8955 'lying_face':'\ud83e\udd25', 8956 'm':'\u24c2\ufe0f', 8957 'mag':'\ud83d\udd0d', 8958 'mag_right':'\ud83d\udd0e', 8959 'mahjong':'\ud83c\udc04\ufe0f', 8960 'mailbox':'\ud83d\udceb', 8961 'mailbox_closed':'\ud83d\udcea', 8962 'mailbox_with_mail':'\ud83d\udcec', 8963 'mailbox_with_no_mail':'\ud83d\udced', 8964 'man':'\ud83d\udc68', 8965 'man_artist':'\ud83d\udc68‍\ud83c\udfa8', 8966 'man_astronaut':'\ud83d\udc68‍\ud83d\ude80', 8967 'man_cartwheeling':'\ud83e\udd38‍\u2642\ufe0f', 8968 'man_cook':'\ud83d\udc68‍\ud83c\udf73', 8969 'man_dancing':'\ud83d\udd7a', 8970 'man_facepalming':'\ud83e\udd26‍\u2642\ufe0f', 8971 'man_factory_worker':'\ud83d\udc68‍\ud83c\udfed', 8972 'man_farmer':'\ud83d\udc68‍\ud83c\udf3e', 8973 'man_firefighter':'\ud83d\udc68‍\ud83d\ude92', 8974 'man_health_worker':'\ud83d\udc68‍\u2695\ufe0f', 8975 'man_in_tuxedo':'\ud83e\udd35', 8976 'man_judge':'\ud83d\udc68‍\u2696\ufe0f', 8977 'man_juggling':'\ud83e\udd39‍\u2642\ufe0f', 8978 'man_mechanic':'\ud83d\udc68‍\ud83d\udd27', 8979 'man_office_worker':'\ud83d\udc68‍\ud83d\udcbc', 8980 'man_pilot':'\ud83d\udc68‍\u2708\ufe0f', 8981 'man_playing_handball':'\ud83e\udd3e‍\u2642\ufe0f', 8982 'man_playing_water_polo':'\ud83e\udd3d‍\u2642\ufe0f', 8983 'man_scientist':'\ud83d\udc68‍\ud83d\udd2c', 8984 'man_shrugging':'\ud83e\udd37‍\u2642\ufe0f', 8985 'man_singer':'\ud83d\udc68‍\ud83c\udfa4', 8986 'man_student':'\ud83d\udc68‍\ud83c\udf93', 8987 'man_teacher':'\ud83d\udc68‍\ud83c\udfeb', 8988 'man_technologist':'\ud83d\udc68‍\ud83d\udcbb', 8989 'man_with_gua_pi_mao':'\ud83d\udc72', 8990 'man_with_turban':'\ud83d\udc73', 8991 'tangerine':'\ud83c\udf4a', 8992 'mans_shoe':'\ud83d\udc5e', 8993 'mantelpiece_clock':'\ud83d\udd70', 8994 'maple_leaf':'\ud83c\udf41', 8995 'martial_arts_uniform':'\ud83e\udd4b', 8996 'mask':'\ud83d\ude37', 8997 'massage_woman':'\ud83d\udc86', 8998 'massage_man':'\ud83d\udc86‍\u2642\ufe0f', 8999 'meat_on_bone':'\ud83c\udf56', 9000 'medal_military':'\ud83c\udf96', 9001 'medal_sports':'\ud83c\udfc5', 9002 'mega':'\ud83d\udce3', 9003 'melon':'\ud83c\udf48', 9004 'memo':'\ud83d\udcdd', 9005 'men_wrestling':'\ud83e\udd3c‍\u2642\ufe0f', 9006 'menorah':'\ud83d\udd4e', 9007 'mens':'\ud83d\udeb9', 9008 'metal':'\ud83e\udd18', 9009 'metro':'\ud83d\ude87', 9010 'microphone':'\ud83c\udfa4', 9011 'microscope':'\ud83d\udd2c', 9012 'milk_glass':'\ud83e\udd5b', 9013 'milky_way':'\ud83c\udf0c', 9014 'minibus':'\ud83d\ude90', 9015 'minidisc':'\ud83d\udcbd', 9016 'mobile_phone_off':'\ud83d\udcf4', 9017 'money_mouth_face':'\ud83e\udd11', 9018 'money_with_wings':'\ud83d\udcb8', 9019 'moneybag':'\ud83d\udcb0', 9020 'monkey':'\ud83d\udc12', 9021 'monkey_face':'\ud83d\udc35', 9022 'monorail':'\ud83d\ude9d', 9023 'moon':'\ud83c\udf14', 9024 'mortar_board':'\ud83c\udf93', 9025 'mosque':'\ud83d\udd4c', 9026 'motor_boat':'\ud83d\udee5', 9027 'motor_scooter':'\ud83d\udef5', 9028 'motorcycle':'\ud83c\udfcd', 9029 'motorway':'\ud83d\udee3', 9030 'mount_fuji':'\ud83d\uddfb', 9031 'mountain':'\u26f0', 9032 'mountain_biking_man':'\ud83d\udeb5', 9033 'mountain_biking_woman':'\ud83d\udeb5‍\u2640\ufe0f', 9034 'mountain_cableway':'\ud83d\udea0', 9035 'mountain_railway':'\ud83d\ude9e', 9036 'mountain_snow':'\ud83c\udfd4', 9037 'mouse':'\ud83d\udc2d', 9038 'mouse2':'\ud83d\udc01', 9039 'movie_camera':'\ud83c\udfa5', 9040 'moyai':'\ud83d\uddff', 9041 'mrs_claus':'\ud83e\udd36', 9042 'muscle':'\ud83d\udcaa', 9043 'mushroom':'\ud83c\udf44', 9044 'musical_keyboard':'\ud83c\udfb9', 9045 'musical_note':'\ud83c\udfb5', 9046 'musical_score':'\ud83c\udfbc', 9047 'mute':'\ud83d\udd07', 9048 'nail_care':'\ud83d\udc85', 9049 'name_badge':'\ud83d\udcdb', 9050 'national_park':'\ud83c\udfde', 9051 'nauseated_face':'\ud83e\udd22', 9052 'necktie':'\ud83d\udc54', 9053 'negative_squared_cross_mark':'\u274e', 9054 'nerd_face':'\ud83e\udd13', 9055 'neutral_face':'\ud83d\ude10', 9056 'new':'\ud83c\udd95', 9057 'new_moon':'\ud83c\udf11', 9058 'new_moon_with_face':'\ud83c\udf1a', 9059 'newspaper':'\ud83d\udcf0', 9060 'newspaper_roll':'\ud83d\uddde', 9061 'next_track_button':'\u23ed', 9062 'ng':'\ud83c\udd96', 9063 'no_good_man':'\ud83d\ude45‍\u2642\ufe0f', 9064 'no_good_woman':'\ud83d\ude45', 9065 'night_with_stars':'\ud83c\udf03', 9066 'no_bell':'\ud83d\udd15', 9067 'no_bicycles':'\ud83d\udeb3', 9068 'no_entry':'\u26d4\ufe0f', 9069 'no_entry_sign':'\ud83d\udeab', 9070 'no_mobile_phones':'\ud83d\udcf5', 9071 'no_mouth':'\ud83d\ude36', 9072 'no_pedestrians':'\ud83d\udeb7', 9073 'no_smoking':'\ud83d\udead', 9074 'non-potable_water':'\ud83d\udeb1', 9075 'nose':'\ud83d\udc43', 9076 'notebook':'\ud83d\udcd3', 9077 'notebook_with_decorative_cover':'\ud83d\udcd4', 9078 'notes':'\ud83c\udfb6', 9079 'nut_and_bolt':'\ud83d\udd29', 9080 'o':'\u2b55\ufe0f', 9081 'o2':'\ud83c\udd7e\ufe0f', 9082 'ocean':'\ud83c\udf0a', 9083 'octopus':'\ud83d\udc19', 9084 'oden':'\ud83c\udf62', 9085 'office':'\ud83c\udfe2', 9086 'oil_drum':'\ud83d\udee2', 9087 'ok':'\ud83c\udd97', 9088 'ok_hand':'\ud83d\udc4c', 9089 'ok_man':'\ud83d\ude46‍\u2642\ufe0f', 9090 'ok_woman':'\ud83d\ude46', 9091 'old_key':'\ud83d\udddd', 9092 'older_man':'\ud83d\udc74', 9093 'older_woman':'\ud83d\udc75', 9094 'om':'\ud83d\udd49', 9095 'on':'\ud83d\udd1b', 9096 'oncoming_automobile':'\ud83d\ude98', 9097 'oncoming_bus':'\ud83d\ude8d', 9098 'oncoming_police_car':'\ud83d\ude94', 9099 'oncoming_taxi':'\ud83d\ude96', 9100 'open_file_folder':'\ud83d\udcc2', 9101 'open_hands':'\ud83d\udc50', 9102 'open_mouth':'\ud83d\ude2e', 9103 'open_umbrella':'\u2602\ufe0f', 9104 'ophiuchus':'\u26ce', 9105 'orange_book':'\ud83d\udcd9', 9106 'orthodox_cross':'\u2626\ufe0f', 9107 'outbox_tray':'\ud83d\udce4', 9108 'owl':'\ud83e\udd89', 9109 'ox':'\ud83d\udc02', 9110 'package':'\ud83d\udce6', 9111 'page_facing_up':'\ud83d\udcc4', 9112 'page_with_curl':'\ud83d\udcc3', 9113 'pager':'\ud83d\udcdf', 9114 'paintbrush':'\ud83d\udd8c', 9115 'palm_tree':'\ud83c\udf34', 9116 'pancakes':'\ud83e\udd5e', 9117 'panda_face':'\ud83d\udc3c', 9118 'paperclip':'\ud83d\udcce', 9119 'paperclips':'\ud83d\udd87', 9120 'parasol_on_ground':'\u26f1', 9121 'parking':'\ud83c\udd7f\ufe0f', 9122 'part_alternation_mark':'\u303d\ufe0f', 9123 'partly_sunny':'\u26c5\ufe0f', 9124 'passenger_ship':'\ud83d\udef3', 9125 'passport_control':'\ud83d\udec2', 9126 'pause_button':'\u23f8', 9127 'peace_symbol':'\u262e\ufe0f', 9128 'peach':'\ud83c\udf51', 9129 'peanuts':'\ud83e\udd5c', 9130 'pear':'\ud83c\udf50', 9131 'pen':'\ud83d\udd8a', 9132 'pencil2':'\u270f\ufe0f', 9133 'penguin':'\ud83d\udc27', 9134 'pensive':'\ud83d\ude14', 9135 'performing_arts':'\ud83c\udfad', 9136 'persevere':'\ud83d\ude23', 9137 'person_fencing':'\ud83e\udd3a', 9138 'pouting_woman':'\ud83d\ude4e', 9139 'phone':'\u260e\ufe0f', 9140 'pick':'\u26cf', 9141 'pig':'\ud83d\udc37', 9142 'pig2':'\ud83d\udc16', 9143 'pig_nose':'\ud83d\udc3d', 9144 'pill':'\ud83d\udc8a', 9145 'pineapple':'\ud83c\udf4d', 9146 'ping_pong':'\ud83c\udfd3', 9147 'pisces':'\u2653\ufe0f', 9148 'pizza':'\ud83c\udf55', 9149 'place_of_worship':'\ud83d\uded0', 9150 'plate_with_cutlery':'\ud83c\udf7d', 9151 'play_or_pause_button':'\u23ef', 9152 'point_down':'\ud83d\udc47', 9153 'point_left':'\ud83d\udc48', 9154 'point_right':'\ud83d\udc49', 9155 'point_up':'\u261d\ufe0f', 9156 'point_up_2':'\ud83d\udc46', 9157 'police_car':'\ud83d\ude93', 9158 'policewoman':'\ud83d\udc6e‍\u2640\ufe0f', 9159 'poodle':'\ud83d\udc29', 9160 'popcorn':'\ud83c\udf7f', 9161 'post_office':'\ud83c\udfe3', 9162 'postal_horn':'\ud83d\udcef', 9163 'postbox':'\ud83d\udcee', 9164 'potable_water':'\ud83d\udeb0', 9165 'potato':'\ud83e\udd54', 9166 'pouch':'\ud83d\udc5d', 9167 'poultry_leg':'\ud83c\udf57', 9168 'pound':'\ud83d\udcb7', 9169 'rage':'\ud83d\ude21', 9170 'pouting_cat':'\ud83d\ude3e', 9171 'pouting_man':'\ud83d\ude4e‍\u2642\ufe0f', 9172 'pray':'\ud83d\ude4f', 9173 'prayer_beads':'\ud83d\udcff', 9174 'pregnant_woman':'\ud83e\udd30', 9175 'previous_track_button':'\u23ee', 9176 'prince':'\ud83e\udd34', 9177 'princess':'\ud83d\udc78', 9178 'printer':'\ud83d\udda8', 9179 'purple_heart':'\ud83d\udc9c', 9180 'purse':'\ud83d\udc5b', 9181 'pushpin':'\ud83d\udccc', 9182 'put_litter_in_its_place':'\ud83d\udeae', 9183 'question':'\u2753', 9184 'rabbit':'\ud83d\udc30', 9185 'rabbit2':'\ud83d\udc07', 9186 'racehorse':'\ud83d\udc0e', 9187 'racing_car':'\ud83c\udfce', 9188 'radio':'\ud83d\udcfb', 9189 'radio_button':'\ud83d\udd18', 9190 'radioactive':'\u2622\ufe0f', 9191 'railway_car':'\ud83d\ude83', 9192 'railway_track':'\ud83d\udee4', 9193 'rainbow':'\ud83c\udf08', 9194 'rainbow_flag':'\ud83c\udff3\ufe0f‍\ud83c\udf08', 9195 'raised_back_of_hand':'\ud83e\udd1a', 9196 'raised_hand_with_fingers_splayed':'\ud83d\udd90', 9197 'raised_hands':'\ud83d\ude4c', 9198 'raising_hand_woman':'\ud83d\ude4b', 9199 'raising_hand_man':'\ud83d\ude4b‍\u2642\ufe0f', 9200 'ram':'\ud83d\udc0f', 9201 'ramen':'\ud83c\udf5c', 9202 'rat':'\ud83d\udc00', 9203 'record_button':'\u23fa', 9204 'recycle':'\u267b\ufe0f', 9205 'red_circle':'\ud83d\udd34', 9206 'registered':'\u00ae\ufe0f', 9207 'relaxed':'\u263a\ufe0f', 9208 'relieved':'\ud83d\ude0c', 9209 'reminder_ribbon':'\ud83c\udf97', 9210 'repeat':'\ud83d\udd01', 9211 'repeat_one':'\ud83d\udd02', 9212 'rescue_worker_helmet':'\u26d1', 9213 'restroom':'\ud83d\udebb', 9214 'revolving_hearts':'\ud83d\udc9e', 9215 'rewind':'\u23ea', 9216 'rhinoceros':'\ud83e\udd8f', 9217 'ribbon':'\ud83c\udf80', 9218 'rice':'\ud83c\udf5a', 9219 'rice_ball':'\ud83c\udf59', 9220 'rice_cracker':'\ud83c\udf58', 9221 'rice_scene':'\ud83c\udf91', 9222 'right_anger_bubble':'\ud83d\uddef', 9223 'ring':'\ud83d\udc8d', 9224 'robot':'\ud83e\udd16', 9225 'rocket':'\ud83d\ude80', 9226 'rofl':'\ud83e\udd23', 9227 'roll_eyes':'\ud83d\ude44', 9228 'roller_coaster':'\ud83c\udfa2', 9229 'rooster':'\ud83d\udc13', 9230 'rose':'\ud83c\udf39', 9231 'rosette':'\ud83c\udff5', 9232 'rotating_light':'\ud83d\udea8', 9233 'round_pushpin':'\ud83d\udccd', 9234 'rowing_man':'\ud83d\udea3', 9235 'rowing_woman':'\ud83d\udea3‍\u2640\ufe0f', 9236 'rugby_football':'\ud83c\udfc9', 9237 'running_man':'\ud83c\udfc3', 9238 'running_shirt_with_sash':'\ud83c\udfbd', 9239 'running_woman':'\ud83c\udfc3‍\u2640\ufe0f', 9240 'sa':'\ud83c\ude02\ufe0f', 9241 'sagittarius':'\u2650\ufe0f', 9242 'sake':'\ud83c\udf76', 9243 'sandal':'\ud83d\udc61', 9244 'santa':'\ud83c\udf85', 9245 'satellite':'\ud83d\udce1', 9246 'saxophone':'\ud83c\udfb7', 9247 'school':'\ud83c\udfeb', 9248 'school_satchel':'\ud83c\udf92', 9249 'scissors':'\u2702\ufe0f', 9250 'scorpion':'\ud83e\udd82', 9251 'scorpius':'\u264f\ufe0f', 9252 'scream':'\ud83d\ude31', 9253 'scream_cat':'\ud83d\ude40', 9254 'scroll':'\ud83d\udcdc', 9255 'seat':'\ud83d\udcba', 9256 'secret':'\u3299\ufe0f', 9257 'see_no_evil':'\ud83d\ude48', 9258 'seedling':'\ud83c\udf31', 9259 'selfie':'\ud83e\udd33', 9260 'shallow_pan_of_food':'\ud83e\udd58', 9261 'shamrock':'\u2618\ufe0f', 9262 'shark':'\ud83e\udd88', 9263 'shaved_ice':'\ud83c\udf67', 9264 'sheep':'\ud83d\udc11', 9265 'shell':'\ud83d\udc1a', 9266 'shield':'\ud83d\udee1', 9267 'shinto_shrine':'\u26e9', 9268 'ship':'\ud83d\udea2', 9269 'shirt':'\ud83d\udc55', 9270 'shopping':'\ud83d\udecd', 9271 'shopping_cart':'\ud83d\uded2', 9272 'shower':'\ud83d\udebf', 9273 'shrimp':'\ud83e\udd90', 9274 'signal_strength':'\ud83d\udcf6', 9275 'six_pointed_star':'\ud83d\udd2f', 9276 'ski':'\ud83c\udfbf', 9277 'skier':'\u26f7', 9278 'skull':'\ud83d\udc80', 9279 'skull_and_crossbones':'\u2620\ufe0f', 9280 'sleeping':'\ud83d\ude34', 9281 'sleeping_bed':'\ud83d\udecc', 9282 'sleepy':'\ud83d\ude2a', 9283 'slightly_frowning_face':'\ud83d\ude41', 9284 'slightly_smiling_face':'\ud83d\ude42', 9285 'slot_machine':'\ud83c\udfb0', 9286 'small_airplane':'\ud83d\udee9', 9287 'small_blue_diamond':'\ud83d\udd39', 9288 'small_orange_diamond':'\ud83d\udd38', 9289 'small_red_triangle':'\ud83d\udd3a', 9290 'small_red_triangle_down':'\ud83d\udd3b', 9291 'smile':'\ud83d\ude04', 9292 'smile_cat':'\ud83d\ude38', 9293 'smiley':'\ud83d\ude03', 9294 'smiley_cat':'\ud83d\ude3a', 9295 'smiling_imp':'\ud83d\ude08', 9296 'smirk':'\ud83d\ude0f', 9297 'smirk_cat':'\ud83d\ude3c', 9298 'smoking':'\ud83d\udeac', 9299 'snail':'\ud83d\udc0c', 9300 'snake':'\ud83d\udc0d', 9301 'sneezing_face':'\ud83e\udd27', 9302 'snowboarder':'\ud83c\udfc2', 9303 'snowflake':'\u2744\ufe0f', 9304 'snowman':'\u26c4\ufe0f', 9305 'snowman_with_snow':'\u2603\ufe0f', 9306 'sob':'\ud83d\ude2d', 9307 'soccer':'\u26bd\ufe0f', 9308 'soon':'\ud83d\udd1c', 9309 'sos':'\ud83c\udd98', 9310 'sound':'\ud83d\udd09', 9311 'space_invader':'\ud83d\udc7e', 9312 'spades':'\u2660\ufe0f', 9313 'spaghetti':'\ud83c\udf5d', 9314 'sparkle':'\u2747\ufe0f', 9315 'sparkler':'\ud83c\udf87', 9316 'sparkles':'\u2728', 9317 'sparkling_heart':'\ud83d\udc96', 9318 'speak_no_evil':'\ud83d\ude4a', 9319 'speaker':'\ud83d\udd08', 9320 'speaking_head':'\ud83d\udde3', 9321 'speech_balloon':'\ud83d\udcac', 9322 'speedboat':'\ud83d\udea4', 9323 'spider':'\ud83d\udd77', 9324 'spider_web':'\ud83d\udd78', 9325 'spiral_calendar':'\ud83d\uddd3', 9326 'spiral_notepad':'\ud83d\uddd2', 9327 'spoon':'\ud83e\udd44', 9328 'squid':'\ud83e\udd91', 9329 'stadium':'\ud83c\udfdf', 9330 'star':'\u2b50\ufe0f', 9331 'star2':'\ud83c\udf1f', 9332 'star_and_crescent':'\u262a\ufe0f', 9333 'star_of_david':'\u2721\ufe0f', 9334 'stars':'\ud83c\udf20', 9335 'station':'\ud83d\ude89', 9336 'statue_of_liberty':'\ud83d\uddfd', 9337 'steam_locomotive':'\ud83d\ude82', 9338 'stew':'\ud83c\udf72', 9339 'stop_button':'\u23f9', 9340 'stop_sign':'\ud83d\uded1', 9341 'stopwatch':'\u23f1', 9342 'straight_ruler':'\ud83d\udccf', 9343 'strawberry':'\ud83c\udf53', 9344 'stuck_out_tongue':'\ud83d\ude1b', 9345 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d', 9346 'stuck_out_tongue_winking_eye':'\ud83d\ude1c', 9347 'studio_microphone':'\ud83c\udf99', 9348 'stuffed_flatbread':'\ud83e\udd59', 9349 'sun_behind_large_cloud':'\ud83c\udf25', 9350 'sun_behind_rain_cloud':'\ud83c\udf26', 9351 'sun_behind_small_cloud':'\ud83c\udf24', 9352 'sun_with_face':'\ud83c\udf1e', 9353 'sunflower':'\ud83c\udf3b', 9354 'sunglasses':'\ud83d\ude0e', 9355 'sunny':'\u2600\ufe0f', 9356 'sunrise':'\ud83c\udf05', 9357 'sunrise_over_mountains':'\ud83c\udf04', 9358 'surfing_man':'\ud83c\udfc4', 9359 'surfing_woman':'\ud83c\udfc4‍\u2640\ufe0f', 9360 'sushi':'\ud83c\udf63', 9361 'suspension_railway':'\ud83d\ude9f', 9362 'sweat':'\ud83d\ude13', 9363 'sweat_drops':'\ud83d\udca6', 9364 'sweat_smile':'\ud83d\ude05', 9365 'sweet_potato':'\ud83c\udf60', 9366 'swimming_man':'\ud83c\udfca', 9367 'swimming_woman':'\ud83c\udfca‍\u2640\ufe0f', 9368 'symbols':'\ud83d\udd23', 9369 'synagogue':'\ud83d\udd4d', 9370 'syringe':'\ud83d\udc89', 9371 'taco':'\ud83c\udf2e', 9372 'tada':'\ud83c\udf89', 9373 'tanabata_tree':'\ud83c\udf8b', 9374 'taurus':'\u2649\ufe0f', 9375 'taxi':'\ud83d\ude95', 9376 'tea':'\ud83c\udf75', 9377 'telephone_receiver':'\ud83d\udcde', 9378 'telescope':'\ud83d\udd2d', 9379 'tennis':'\ud83c\udfbe', 9380 'tent':'\u26fa\ufe0f', 9381 'thermometer':'\ud83c\udf21', 9382 'thinking':'\ud83e\udd14', 9383 'thought_balloon':'\ud83d\udcad', 9384 'ticket':'\ud83c\udfab', 9385 'tickets':'\ud83c\udf9f', 9386 'tiger':'\ud83d\udc2f', 9387 'tiger2':'\ud83d\udc05', 9388 'timer_clock':'\u23f2', 9389 'tipping_hand_man':'\ud83d\udc81‍\u2642\ufe0f', 9390 'tired_face':'\ud83d\ude2b', 9391 'tm':'\u2122\ufe0f', 9392 'toilet':'\ud83d\udebd', 9393 'tokyo_tower':'\ud83d\uddfc', 9394 'tomato':'\ud83c\udf45', 9395 'tongue':'\ud83d\udc45', 9396 'top':'\ud83d\udd1d', 9397 'tophat':'\ud83c\udfa9', 9398 'tornado':'\ud83c\udf2a', 9399 'trackball':'\ud83d\uddb2', 9400 'tractor':'\ud83d\ude9c', 9401 'traffic_light':'\ud83d\udea5', 9402 'train':'\ud83d\ude8b', 9403 'train2':'\ud83d\ude86', 9404 'tram':'\ud83d\ude8a', 9405 'triangular_flag_on_post':'\ud83d\udea9', 9406 'triangular_ruler':'\ud83d\udcd0', 9407 'trident':'\ud83d\udd31', 9408 'triumph':'\ud83d\ude24', 9409 'trolleybus':'\ud83d\ude8e', 9410 'trophy':'\ud83c\udfc6', 9411 'tropical_drink':'\ud83c\udf79', 9412 'tropical_fish':'\ud83d\udc20', 9413 'truck':'\ud83d\ude9a', 9414 'trumpet':'\ud83c\udfba', 9415 'tulip':'\ud83c\udf37', 9416 'tumbler_glass':'\ud83e\udd43', 9417 'turkey':'\ud83e\udd83', 9418 'turtle':'\ud83d\udc22', 9419 'tv':'\ud83d\udcfa', 9420 'twisted_rightwards_arrows':'\ud83d\udd00', 9421 'two_hearts':'\ud83d\udc95', 9422 'two_men_holding_hands':'\ud83d\udc6c', 9423 'two_women_holding_hands':'\ud83d\udc6d', 9424 'u5272':'\ud83c\ude39', 9425 'u5408':'\ud83c\ude34', 9426 'u55b6':'\ud83c\ude3a', 9427 'u6307':'\ud83c\ude2f\ufe0f', 9428 'u6708':'\ud83c\ude37\ufe0f', 9429 'u6709':'\ud83c\ude36', 9430 'u6e80':'\ud83c\ude35', 9431 'u7121':'\ud83c\ude1a\ufe0f', 9432 'u7533':'\ud83c\ude38', 9433 'u7981':'\ud83c\ude32', 9434 'u7a7a':'\ud83c\ude33', 9435 'umbrella':'\u2614\ufe0f', 9436 'unamused':'\ud83d\ude12', 9437 'underage':'\ud83d\udd1e', 9438 'unicorn':'\ud83e\udd84', 9439 'unlock':'\ud83d\udd13', 9440 'up':'\ud83c\udd99', 9441 'upside_down_face':'\ud83d\ude43', 9442 'v':'\u270c\ufe0f', 9443 'vertical_traffic_light':'\ud83d\udea6', 9444 'vhs':'\ud83d\udcfc', 9445 'vibration_mode':'\ud83d\udcf3', 9446 'video_camera':'\ud83d\udcf9', 9447 'video_game':'\ud83c\udfae', 9448 'violin':'\ud83c\udfbb', 9449 'virgo':'\u264d\ufe0f', 9450 'volcano':'\ud83c\udf0b', 9451 'volleyball':'\ud83c\udfd0', 9452 'vs':'\ud83c\udd9a', 9453 'vulcan_salute':'\ud83d\udd96', 9454 'walking_man':'\ud83d\udeb6', 9455 'walking_woman':'\ud83d\udeb6‍\u2640\ufe0f', 9456 'waning_crescent_moon':'\ud83c\udf18', 9457 'waning_gibbous_moon':'\ud83c\udf16', 9458 'warning':'\u26a0\ufe0f', 9459 'wastebasket':'\ud83d\uddd1', 9460 'watch':'\u231a\ufe0f', 9461 'water_buffalo':'\ud83d\udc03', 9462 'watermelon':'\ud83c\udf49', 9463 'wave':'\ud83d\udc4b', 9464 'wavy_dash':'\u3030\ufe0f', 9465 'waxing_crescent_moon':'\ud83c\udf12', 9466 'wc':'\ud83d\udebe', 9467 'weary':'\ud83d\ude29', 9468 'wedding':'\ud83d\udc92', 9469 'weight_lifting_man':'\ud83c\udfcb\ufe0f', 9470 'weight_lifting_woman':'\ud83c\udfcb\ufe0f‍\u2640\ufe0f', 9471 'whale':'\ud83d\udc33', 9472 'whale2':'\ud83d\udc0b', 9473 'wheel_of_dharma':'\u2638\ufe0f', 9474 'wheelchair':'\u267f\ufe0f', 9475 'white_check_mark':'\u2705', 9476 'white_circle':'\u26aa\ufe0f', 9477 'white_flag':'\ud83c\udff3\ufe0f', 9478 'white_flower':'\ud83d\udcae', 9479 'white_large_square':'\u2b1c\ufe0f', 9480 'white_medium_small_square':'\u25fd\ufe0f', 9481 'white_medium_square':'\u25fb\ufe0f', 9482 'white_small_square':'\u25ab\ufe0f', 9483 'white_square_button':'\ud83d\udd33', 9484 'wilted_flower':'\ud83e\udd40', 9485 'wind_chime':'\ud83c\udf90', 9486 'wind_face':'\ud83c\udf2c', 9487 'wine_glass':'\ud83c\udf77', 9488 'wink':'\ud83d\ude09', 9489 'wolf':'\ud83d\udc3a', 9490 'woman':'\ud83d\udc69', 9491 'woman_artist':'\ud83d\udc69‍\ud83c\udfa8', 9492 'woman_astronaut':'\ud83d\udc69‍\ud83d\ude80', 9493 'woman_cartwheeling':'\ud83e\udd38‍\u2640\ufe0f', 9494 'woman_cook':'\ud83d\udc69‍\ud83c\udf73', 9495 'woman_facepalming':'\ud83e\udd26‍\u2640\ufe0f', 9496 'woman_factory_worker':'\ud83d\udc69‍\ud83c\udfed', 9497 'woman_farmer':'\ud83d\udc69‍\ud83c\udf3e', 9498 'woman_firefighter':'\ud83d\udc69‍\ud83d\ude92', 9499 'woman_health_worker':'\ud83d\udc69‍\u2695\ufe0f', 9500 'woman_judge':'\ud83d\udc69‍\u2696\ufe0f', 9501 'woman_juggling':'\ud83e\udd39‍\u2640\ufe0f', 9502 'woman_mechanic':'\ud83d\udc69‍\ud83d\udd27', 9503 'woman_office_worker':'\ud83d\udc69‍\ud83d\udcbc', 9504 'woman_pilot':'\ud83d\udc69‍\u2708\ufe0f', 9505 'woman_playing_handball':'\ud83e\udd3e‍\u2640\ufe0f', 9506 'woman_playing_water_polo':'\ud83e\udd3d‍\u2640\ufe0f', 9507 'woman_scientist':'\ud83d\udc69‍\ud83d\udd2c', 9508 'woman_shrugging':'\ud83e\udd37‍\u2640\ufe0f', 9509 'woman_singer':'\ud83d\udc69‍\ud83c\udfa4', 9510 'woman_student':'\ud83d\udc69‍\ud83c\udf93', 9511 'woman_teacher':'\ud83d\udc69‍\ud83c\udfeb', 9512 'woman_technologist':'\ud83d\udc69‍\ud83d\udcbb', 9513 'woman_with_turban':'\ud83d\udc73‍\u2640\ufe0f', 9514 'womans_clothes':'\ud83d\udc5a', 9515 'womans_hat':'\ud83d\udc52', 9516 'women_wrestling':'\ud83e\udd3c‍\u2640\ufe0f', 9517 'womens':'\ud83d\udeba', 9518 'world_map':'\ud83d\uddfa', 9519 'worried':'\ud83d\ude1f', 9520 'wrench':'\ud83d\udd27', 9521 'writing_hand':'\u270d\ufe0f', 9522 'x':'\u274c', 9523 'yellow_heart':'\ud83d\udc9b', 9524 'yen':'\ud83d\udcb4', 9525 'yin_yang':'\u262f\ufe0f', 9526 'yum':'\ud83d\ude0b', 9527 'zap':'\u26a1\ufe0f', 9528 'zipper_mouth_face':'\ud83e\udd10', 9529 'zzz':'\ud83d\udca4', 9530 9531 /* special emojis :P */ 9532 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">', 9533 '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>' 9534 }; 9535 9536 /** 9537 * Created by Estevao on 31-05-2015. 9538 */ 9539 9540 /** 9541 * Showdown Converter class 9542 * @class 9543 * @param {object} [converterOptions] 9544 * @returns {Converter} 9545 */ 9546 showdown.Converter = function (converterOptions) { 9547 'use strict'; 9548 9549 var 9550 /** 9551 * Options used by this converter 9552 * @private 9553 * @type {{}} 9554 */ 9555 options = {}, 9556 9557 /** 9558 * Language extensions used by this converter 9559 * @private 9560 * @type {Array} 9561 */ 9562 langExtensions = [], 9563 9564 /** 9565 * Output modifiers extensions used by this converter 9566 * @private 9567 * @type {Array} 9568 */ 9569 outputModifiers = [], 9570 9571 /** 9572 * Event listeners 9573 * @private 9574 * @type {{}} 9575 */ 9576 listeners = {}, 9577 9578 /** 9579 * The flavor set in this converter 9580 */ 9581 setConvFlavor = setFlavor, 9582 9583 /** 9584 * Metadata of the document 9585 * @type {{parsed: {}, raw: string, format: string}} 9586 */ 9587 metadata = { 9588 parsed: {}, 9589 raw: '', 9590 format: '' 9591 }; 9592 9593 _constructor(); 9594 9595 /** 9596 * Converter constructor 9597 * @private 9598 */ 9599 function _constructor () { 9600 converterOptions = converterOptions || {}; 9601 9602 for (var gOpt in globalOptions) { 9603 if (globalOptions.hasOwnProperty(gOpt)) { 9604 options[gOpt] = globalOptions[gOpt]; 9605 } 9606 } 9607 9608 // Merge options 9609 if (typeof converterOptions === 'object') { 9610 for (var opt in converterOptions) { 9611 if (converterOptions.hasOwnProperty(opt)) { 9612 options[opt] = converterOptions[opt]; 9613 } 9614 } 9615 } else { 9616 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + 9617 ' was passed instead.'); 9618 } 9619 9620 if (options.extensions) { 9621 showdown.helper.forEach(options.extensions, _parseExtension); 9622 } 9623 } 9624 9625 /** 9626 * Parse extension 9627 * @param {*} ext 9628 * @param {string} [name=''] 9629 * @private 9630 */ 9631 function _parseExtension (ext, name) { 9632 9633 name = name || null; 9634 // If it's a string, the extension was previously loaded 9635 if (showdown.helper.isString(ext)) { 9636 ext = showdown.helper.stdExtName(ext); 9637 name = ext; 9638 9639 // LEGACY_SUPPORT CODE 9640 if (showdown.extensions[ext]) { 9641 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + 9642 'Please inform the developer that the extension should be updated!'); 9643 legacyExtensionLoading(showdown.extensions[ext], ext); 9644 return; 9645 // END LEGACY SUPPORT CODE 9646 9647 } else if (!showdown.helper.isUndefined(extensions[ext])) { 9648 ext = extensions[ext]; 9649 9650 } else { 9651 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); 9652 } 9653 } 9654 9655 if (typeof ext === 'function') { 9656 ext = ext(); 9657 } 9658 9659 if (!showdown.helper.isArray(ext)) { 9660 ext = [ext]; 9661 } 9662 9663 var validExt = validate(ext, name); 9664 if (!validExt.valid) { 9665 throw Error(validExt.error); 9666 } 9667 9668 for (var i = 0; i < ext.length; ++i) { 9669 switch (ext[i].type) { 9670 9671 case 'lang': 9672 langExtensions.push(ext[i]); 9673 break; 9674 9675 case 'output': 9676 outputModifiers.push(ext[i]); 9677 break; 9678 } 9679 if (ext[i].hasOwnProperty('listeners')) { 9680 for (var ln in ext[i].listeners) { 9681 if (ext[i].listeners.hasOwnProperty(ln)) { 9682 listen(ln, ext[i].listeners[ln]); 9683 } 9684 } 9685 } 9686 } 9687 9688 } 9689 9690 /** 9691 * LEGACY_SUPPORT 9692 * @param {*} ext 9693 * @param {string} name 9694 */ 9695 function legacyExtensionLoading (ext, name) { 9696 if (typeof ext === 'function') { 9697 ext = ext(new showdown.Converter()); 9698 } 9699 if (!showdown.helper.isArray(ext)) { 9700 ext = [ext]; 9701 } 9702 var valid = validate(ext, name); 9703 9704 if (!valid.valid) { 9705 throw Error(valid.error); 9706 } 9707 9708 for (var i = 0; i < ext.length; ++i) { 9709 switch (ext[i].type) { 9710 case 'lang': 9711 langExtensions.push(ext[i]); 9712 break; 9713 case 'output': 9714 outputModifiers.push(ext[i]); 9715 break; 9716 default:// should never reach here 9717 throw Error('Extension loader error: Type unrecognized!!!'); 9718 } 9719 } 9720 } 9721 9722 /** 9723 * Listen to an event 9724 * @param {string} name 9725 * @param {function} callback 9726 */ 9727 function listen (name, callback) { 9728 if (!showdown.helper.isString(name)) { 9729 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); 9730 } 9731 9732 if (typeof callback !== 'function') { 9733 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); 9734 } 9735 9736 if (!listeners.hasOwnProperty(name)) { 9737 listeners[name] = []; 9738 } 9739 listeners[name].push(callback); 9740 } 9741 9742 function rTrimInputText (text) { 9743 var rsp = text.match(/^\s*/)[0].length, 9744 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); 9745 return text.replace(rgx, ''); 9746 } 9747 9748 /** 9749 * Dispatch an event 9750 * @private 9751 * @param {string} evtName Event name 9752 * @param {string} text Text 9753 * @param {{}} options Converter Options 9754 * @param {{}} globals 9755 * @returns {string} 9756 */ 9757 this._dispatch = function dispatch (evtName, text, options, globals) { 9758 if (listeners.hasOwnProperty(evtName)) { 9759 for (var ei = 0; ei < listeners[evtName].length; ++ei) { 9760 var nText = listeners[evtName][ei](evtName, text, this, options, globals); 9761 if (nText && typeof nText !== 'undefined') { 9762 text = nText; 9763 } 9764 } 9765 } 9766 return text; 9767 }; 9768 9769 /** 9770 * Listen to an event 9771 * @param {string} name 9772 * @param {function} callback 9773 * @returns {showdown.Converter} 9774 */ 9775 this.listen = function (name, callback) { 9776 listen(name, callback); 9777 return this; 9778 }; 9779 9780 /** 9781 * Converts a markdown string into HTML 9782 * @param {string} text 9783 * @returns {*} 9784 */ 9785 this.makeHtml = function (text) { 9786 //check if text is not falsy 9787 if (!text) { 9788 return text; 9789 } 9790 9791 var globals = { 9792 gHtmlBlocks: [], 9793 gHtmlMdBlocks: [], 9794 gHtmlSpans: [], 9795 gUrls: {}, 9796 gTitles: {}, 9797 gDimensions: {}, 9798 gListLevel: 0, 9799 hashLinkCounts: {}, 9800 langExtensions: langExtensions, 9801 outputModifiers: outputModifiers, 9802 converter: this, 9803 ghCodeBlocks: [], 9804 metadata: { 9805 parsed: {}, 9806 raw: '', 9807 format: '' 9808 } 9809 }; 9810 9811 // This lets us use ¨ trema as an escape char to avoid md5 hashes 9812 // The choice of character is arbitrary; anything that isn't 9813 // magic in Markdown will work. 9814 text = text.replace(/¨/g, '¨T'); 9815 9816 // Replace $ with ¨D 9817 // RegExp interprets $ as a special character 9818 // when it's in a replacement string 9819 text = text.replace(/\$/g, '¨D'); 9820 9821 // Standardize line endings 9822 text = text.replace(/\r\n/g, '\n'); // DOS to Unix 9823 text = text.replace(/\r/g, '\n'); // Mac to Unix 9824 9825 // Stardardize line spaces 9826 text = text.replace(/\u00A0/g, ' '); 9827 9828 if (options.smartIndentationFix) { 9829 text = rTrimInputText(text); 9830 } 9831 9832 // Make sure text begins and ends with a couple of newlines: 9833 text = '\n\n' + text + '\n\n'; 9834 9835 // detab 9836 text = showdown.subParser('detab')(text, options, globals); 9837 9838 /** 9839 * Strip any lines consisting only of spaces and tabs. 9840 * This makes subsequent regexs easier to write, because we can 9841 * match consecutive blank lines with /\n+/ instead of something 9842 * contorted like /[ \t]*\n+/ 9843 */ 9844 text = text.replace(/^[ \t]+$/mg, ''); 9845 9846 //run languageExtensions 9847 showdown.helper.forEach(langExtensions, function (ext) { 9848 text = showdown.subParser('runExtension')(ext, text, options, globals); 9849 }); 9850 9851 // run the sub parsers 9852 text = showdown.subParser('metadata')(text, options, globals); 9853 text = showdown.subParser('hashPreCodeTags')(text, options, globals); 9854 text = showdown.subParser('githubCodeBlocks')(text, options, globals); 9855 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 9856 text = showdown.subParser('hashCodeTags')(text, options, globals); 9857 text = showdown.subParser('stripLinkDefinitions')(text, options, globals); 9858 text = showdown.subParser('blockGamut')(text, options, globals); 9859 text = showdown.subParser('unhashHTMLSpans')(text, options, globals); 9860 text = showdown.subParser('unescapeSpecialChars')(text, options, globals); 9861 9862 // attacklab: Restore dollar signs 9863 text = text.replace(/¨D/g, '$$'); 9864 9865 // attacklab: Restore tremas 9866 text = text.replace(/¨T/g, '¨'); 9867 9868 // render a complete html document instead of a partial if the option is enabled 9869 text = showdown.subParser('completeHTMLDocument')(text, options, globals); 9870 9871 // Run output modifiers 9872 showdown.helper.forEach(outputModifiers, function (ext) { 9873 text = showdown.subParser('runExtension')(ext, text, options, globals); 9874 }); 9875 9876 // update metadata 9877 metadata = globals.metadata; 9878 return text; 9879 }; 9880 9881 /** 9882 * Converts an HTML string into a markdown string 9883 * @param src 9884 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used. 9885 * @returns {string} 9886 */ 9887 this.makeMarkdown = this.makeMd = function (src, HTMLParser) { 9888 9889 // replace \r\n with \n 9890 src = src.replace(/\r\n/g, '\n'); 9891 src = src.replace(/\r/g, '\n'); // old macs 9892 9893 // due to an edge case, we need to find this: > < 9894 // to prevent removing of non silent white spaces 9895 // ex: <em>this is</em> <strong>sparta</strong> 9896 src = src.replace(/>[ \t]+</, '>¨NBSP;<'); 9897 9898 if (!HTMLParser) { 9899 if (window && window.document) { 9900 HTMLParser = window.document; 9901 } else { 9902 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'); 9903 } 9904 } 9905 9906 var doc = HTMLParser.createElement('div'); 9907 doc.innerHTML = src; 9908 9909 var globals = { 9910 preList: substitutePreCodeTags(doc) 9911 }; 9912 9913 // remove all newlines and collapse spaces 9914 clean(doc); 9915 9916 // some stuff, like accidental reference links must now be escaped 9917 // TODO 9918 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/); 9919 9920 var nodes = doc.childNodes, 9921 mdDoc = ''; 9922 9923 for (var i = 0; i < nodes.length; i++) { 9924 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals); 9925 } 9926 9927 function clean (node) { 9928 for (var n = 0; n < node.childNodes.length; ++n) { 9929 var child = node.childNodes[n]; 9930 if (child.nodeType === 3) { 9931 if (!/\S/.test(child.nodeValue)) { 9932 node.removeChild(child); 9933 --n; 9934 } else { 9935 child.nodeValue = child.nodeValue.split('\n').join(' '); 9936 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1'); 9937 } 9938 } else if (child.nodeType === 1) { 9939 clean(child); 9940 } 9941 } 9942 } 9943 9944 // find all pre tags and replace contents with placeholder 9945 // we need this so that we can remove all indentation from html 9946 // to ease up parsing 9947 function substitutePreCodeTags (doc) { 9948 9949 var pres = doc.querySelectorAll('pre'), 9950 presPH = []; 9951 9952 for (var i = 0; i < pres.length; ++i) { 9953 9954 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') { 9955 var content = pres[i].firstChild.innerHTML.trim(), 9956 language = pres[i].firstChild.getAttribute('data-language') || ''; 9957 9958 // if data-language attribute is not defined, then we look for class language-* 9959 if (language === '') { 9960 var classes = pres[i].firstChild.className.split(' '); 9961 for (var c = 0; c < classes.length; ++c) { 9962 var matches = classes[c].match(/^language-(.+)$/); 9963 if (matches !== null) { 9964 language = matches[1]; 9965 break; 9966 } 9967 } 9968 } 9969 9970 // unescape html entities in content 9971 content = showdown.helper.unescapeHTMLEntities(content); 9972 9973 presPH.push(content); 9974 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>'; 9975 } else { 9976 presPH.push(pres[i].innerHTML); 9977 pres[i].innerHTML = ''; 9978 pres[i].setAttribute('prenum', i.toString()); 9979 } 9980 } 9981 return presPH; 9982 } 9983 9984 return mdDoc; 9985 }; 9986 9987 /** 9988 * Set an option of this Converter instance 9989 * @param {string} key 9990 * @param {*} value 9991 */ 9992 this.setOption = function (key, value) { 9993 options[key] = value; 9994 }; 9995 9996 /** 9997 * Get the option of this Converter instance 9998 * @param {string} key 9999 * @returns {*} 10000 */ 10001 this.getOption = function (key) { 10002 return options[key]; 10003 }; 10004 10005 /** 10006 * Get the options of this Converter instance 10007 * @returns {{}} 10008 */ 10009 this.getOptions = function () { 10010 return options; 10011 }; 10012 10013 /** 10014 * Add extension to THIS converter 10015 * @param {{}} extension 10016 * @param {string} [name=null] 10017 */ 10018 this.addExtension = function (extension, name) { 10019 name = name || null; 10020 _parseExtension(extension, name); 10021 }; 10022 10023 /** 10024 * Use a global registered extension with THIS converter 10025 * @param {string} extensionName Name of the previously registered extension 10026 */ 10027 this.useExtension = function (extensionName) { 10028 _parseExtension(extensionName); 10029 }; 10030 10031 /** 10032 * Set the flavor THIS converter should use 10033 * @param {string} name 10034 */ 10035 this.setFlavor = function (name) { 10036 if (!flavor.hasOwnProperty(name)) { 10037 throw Error(name + ' flavor was not found'); 10038 } 10039 var preset = flavor[name]; 10040 setConvFlavor = name; 10041 for (var option in preset) { 10042 if (preset.hasOwnProperty(option)) { 10043 options[option] = preset[option]; 10044 } 10045 } 10046 }; 10047 10048 /** 10049 * Get the currently set flavor of this converter 10050 * @returns {string} 10051 */ 10052 this.getFlavor = function () { 10053 return setConvFlavor; 10054 }; 10055 10056 /** 10057 * Remove an extension from THIS converter. 10058 * Note: This is a costly operation. It's better to initialize a new converter 10059 * and specify the extensions you wish to use 10060 * @param {Array} extension 10061 */ 10062 this.removeExtension = function (extension) { 10063 if (!showdown.helper.isArray(extension)) { 10064 extension = [extension]; 10065 } 10066 for (var a = 0; a < extension.length; ++a) { 10067 var ext = extension[a]; 10068 for (var i = 0; i < langExtensions.length; ++i) { 10069 if (langExtensions[i] === ext) { 10070 langExtensions[i].splice(i, 1); 10071 } 10072 } 10073 for (var ii = 0; ii < outputModifiers.length; ++i) { 10074 if (outputModifiers[ii] === ext) { 10075 outputModifiers[ii].splice(i, 1); 10076 } 10077 } 10078 } 10079 }; 10080 10081 /** 10082 * Get all extension of THIS converter 10083 * @returns {{language: Array, output: Array}} 10084 */ 10085 this.getAllExtensions = function () { 10086 return { 10087 language: langExtensions, 10088 output: outputModifiers 10089 }; 10090 }; 10091 10092 /** 10093 * Get the metadata of the previously parsed document 10094 * @param raw 10095 * @returns {string|{}} 10096 */ 10097 this.getMetadata = function (raw) { 10098 if (raw) { 10099 return metadata.raw; 10100 } else { 10101 return metadata.parsed; 10102 } 10103 }; 10104 10105 /** 10106 * Get the metadata format of the previously parsed document 10107 * @returns {string} 10108 */ 10109 this.getMetadataFormat = function () { 10110 return metadata.format; 10111 }; 10112 10113 /** 10114 * Private: set a single key, value metadata pair 10115 * @param {string} key 10116 * @param {string} value 10117 */ 10118 this._setMetadataPair = function (key, value) { 10119 metadata.parsed[key] = value; 10120 }; 10121 10122 /** 10123 * Private: set metadata format 10124 * @param {string} format 10125 */ 10126 this._setMetadataFormat = function (format) { 10127 metadata.format = format; 10128 }; 10129 10130 /** 10131 * Private: set metadata raw text 10132 * @param {string} raw 10133 */ 10134 this._setMetadataRaw = function (raw) { 10135 metadata.raw = raw; 10136 }; 10137 }; 10138 10139 /** 10140 * Turn Markdown link shortcuts into XHTML <a> tags. 10141 */ 10142 showdown.subParser('anchors', function (text, options, globals) { 10143 'use strict'; 10144 10145 text = globals.converter._dispatch('anchors.before', text, options, globals); 10146 10147 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { 10148 if (showdown.helper.isUndefined(title)) { 10149 title = ''; 10150 } 10151 linkId = linkId.toLowerCase(); 10152 10153 // Special case for explicit empty url 10154 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 10155 url = ''; 10156 } else if (!url) { 10157 if (!linkId) { 10158 // lower-case and turn embedded newlines into spaces 10159 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); 10160 } 10161 url = '#' + linkId; 10162 10163 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { 10164 url = globals.gUrls[linkId]; 10165 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { 10166 title = globals.gTitles[linkId]; 10167 } 10168 } else { 10169 return wholeMatch; 10170 } 10171 } 10172 10173 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance 10174 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 10175 10176 var result = '<a href="' + url + '"'; 10177 10178 if (title !== '' && title !== null) { 10179 title = title.replace(/"/g, '"'); 10180 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance 10181 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 10182 result += ' title="' + title + '"'; 10183 } 10184 10185 // optionLinksInNewWindow only applies 10186 // to external links. Hash links (#) open in same page 10187 if (options.openLinksInNewWindow && !/^#/.test(url)) { 10188 // escaped _ 10189 result += ' rel="noopener noreferrer" target="¨E95Eblank"'; 10190 } 10191 10192 result += '>' + linkText + '</a>'; 10193 10194 return result; 10195 }; 10196 10197 // First, handle reference-style links: [link text] [id] 10198 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); 10199 10200 // Next, inline-style links: [link text](url "optional title") 10201 // cases with crazy urls like ./image/cat1).png 10202 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 10203 writeAnchorTag); 10204 10205 // normal cases 10206 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 10207 writeAnchorTag); 10208 10209 // handle reference-style shortcuts: [link text] 10210 // These must come last in case you've also got [link test][1] 10211 // or [link test](/foo) 10212 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); 10213 10214 // Lastly handle GithubMentions if option is enabled 10215 if (options.ghMentions) { 10216 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) { 10217 if (escape === '\\') { 10218 return st + mentions; 10219 } 10220 10221 //check if options.ghMentionsLink is a string 10222 if (!showdown.helper.isString(options.ghMentionsLink)) { 10223 throw new Error('ghMentionsLink option must be a string'); 10224 } 10225 var lnk = options.ghMentionsLink.replace(/\{u}/g, username), 10226 target = ''; 10227 if (options.openLinksInNewWindow) { 10228 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 10229 } 10230 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>'; 10231 }); 10232 } 10233 10234 text = globals.converter._dispatch('anchors.after', text, options, globals); 10235 return text; 10236 }); 10237 10238 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] 10239 10240 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, 10241 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, 10242 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, 10243 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi, 10244 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 10245 10246 replaceLink = function (options) { 10247 'use strict'; 10248 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) { 10249 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 10250 var lnkTxt = link, 10251 append = '', 10252 target = '', 10253 lmc = leadingMagicChars || '', 10254 tmc = trailingMagicChars || ''; 10255 if (/^www\./i.test(link)) { 10256 link = link.replace(/^www\./i, 'http://www.'); 10257 } 10258 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) { 10259 append = trailingPunctuation; 10260 } 10261 if (options.openLinksInNewWindow) { 10262 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 10263 } 10264 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc; 10265 }; 10266 }, 10267 10268 replaceMail = function (options, globals) { 10269 'use strict'; 10270 return function (wholeMatch, b, mail) { 10271 var href = 'mailto:'; 10272 b = b || ''; 10273 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals); 10274 if (options.encodeEmails) { 10275 href = showdown.helper.encodeEmailAddress(href + mail); 10276 mail = showdown.helper.encodeEmailAddress(mail); 10277 } else { 10278 href = href + mail; 10279 } 10280 return b + '<a href="' + href + '">' + mail + '</a>'; 10281 }; 10282 }; 10283 10284 showdown.subParser('autoLinks', function (text, options, globals) { 10285 'use strict'; 10286 10287 text = globals.converter._dispatch('autoLinks.before', text, options, globals); 10288 10289 text = text.replace(delimUrlRegex, replaceLink(options)); 10290 text = text.replace(delimMailRegex, replaceMail(options, globals)); 10291 10292 text = globals.converter._dispatch('autoLinks.after', text, options, globals); 10293 10294 return text; 10295 }); 10296 10297 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) { 10298 'use strict'; 10299 10300 if (!options.simplifiedAutoLink) { 10301 return text; 10302 } 10303 10304 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals); 10305 10306 if (options.excludeTrailingPunctuationFromURLs) { 10307 text = text.replace(simpleURLRegex2, replaceLink(options)); 10308 } else { 10309 text = text.replace(simpleURLRegex, replaceLink(options)); 10310 } 10311 text = text.replace(simpleMailRegex, replaceMail(options, globals)); 10312 10313 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals); 10314 10315 return text; 10316 }); 10317 10318 /** 10319 * These are all the transformations that form block-level 10320 * tags like paragraphs, headers, and list items. 10321 */ 10322 showdown.subParser('blockGamut', function (text, options, globals) { 10323 'use strict'; 10324 10325 text = globals.converter._dispatch('blockGamut.before', text, options, globals); 10326 10327 // we parse blockquotes first so that we can have headings and hrs 10328 // inside blockquotes 10329 text = showdown.subParser('blockQuotes')(text, options, globals); 10330 text = showdown.subParser('headers')(text, options, globals); 10331 10332 // Do Horizontal Rules: 10333 text = showdown.subParser('horizontalRule')(text, options, globals); 10334 10335 text = showdown.subParser('lists')(text, options, globals); 10336 text = showdown.subParser('codeBlocks')(text, options, globals); 10337 text = showdown.subParser('tables')(text, options, globals); 10338 10339 // We already ran _HashHTMLBlocks() before, in Markdown(), but that 10340 // was to escape raw HTML in the original Markdown source. This time, 10341 // we're escaping the markup we've just created, so that we don't wrap 10342 // <p> tags around block-level tags. 10343 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 10344 text = showdown.subParser('paragraphs')(text, options, globals); 10345 10346 text = globals.converter._dispatch('blockGamut.after', text, options, globals); 10347 10348 return text; 10349 }); 10350 10351 showdown.subParser('blockQuotes', function (text, options, globals) { 10352 'use strict'; 10353 10354 text = globals.converter._dispatch('blockQuotes.before', text, options, globals); 10355 10356 // add a couple extra lines after the text and endtext mark 10357 text = text + '\n\n'; 10358 10359 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm; 10360 10361 if (options.splitAdjacentBlockquotes) { 10362 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm; 10363 } 10364 10365 text = text.replace(rgx, function (bq) { 10366 // attacklab: hack around Konqueror 3.5.4 bug: 10367 // "----------bug".replace(/^-/g,"") == "bug" 10368 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting 10369 10370 // attacklab: clean up hack 10371 bq = bq.replace(/¨0/g, ''); 10372 10373 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines 10374 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); 10375 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse 10376 10377 bq = bq.replace(/(^|\n)/g, '$1 '); 10378 // These leading spaces screw with <pre> content, so we need to fix that: 10379 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { 10380 var pre = m1; 10381 // attacklab: hack around Konqueror 3.5.4 bug: 10382 pre = pre.replace(/^ /mg, '¨0'); 10383 pre = pre.replace(/¨0/g, ''); 10384 return pre; 10385 }); 10386 10387 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); 10388 }); 10389 10390 text = globals.converter._dispatch('blockQuotes.after', text, options, globals); 10391 return text; 10392 }); 10393 10394 /** 10395 * Process Markdown `<pre><code>` blocks. 10396 */ 10397 showdown.subParser('codeBlocks', function (text, options, globals) { 10398 'use strict'; 10399 10400 text = globals.converter._dispatch('codeBlocks.before', text, options, globals); 10401 10402 // sentinel workarounds for lack of \A and \Z, safari\khtml bug 10403 text += '¨0'; 10404 10405 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g; 10406 text = text.replace(pattern, function (wholeMatch, m1, m2) { 10407 var codeblock = m1, 10408 nextChar = m2, 10409 end = '\n'; 10410 10411 codeblock = showdown.subParser('outdent')(codeblock, options, globals); 10412 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 10413 codeblock = showdown.subParser('detab')(codeblock, options, globals); 10414 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 10415 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines 10416 10417 if (options.omitExtraWLInCodeBlocks) { 10418 end = ''; 10419 } 10420 10421 codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; 10422 10423 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; 10424 }); 10425 10426 // strip sentinel 10427 text = text.replace(/¨0/, ''); 10428 10429 text = globals.converter._dispatch('codeBlocks.after', text, options, globals); 10430 return text; 10431 }); 10432 10433 /** 10434 * 10435 * * Backtick quotes are used for <code></code> spans. 10436 * 10437 * * You can use multiple backticks as the delimiters if you want to 10438 * include literal backticks in the code span. So, this input: 10439 * 10440 * Just type ``foo `bar` baz`` at the prompt. 10441 * 10442 * Will translate to: 10443 * 10444 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> 10445 * 10446 * There's no arbitrary limit to the number of backticks you 10447 * can use as delimters. If you need three consecutive backticks 10448 * in your code, use four for delimiters, etc. 10449 * 10450 * * You can use spaces to get literal backticks at the edges: 10451 * 10452 * ... type `` `bar` `` ... 10453 * 10454 * Turns to: 10455 * 10456 * ... type <code>`bar`</code> ... 10457 */ 10458 showdown.subParser('codeSpans', function (text, options, globals) { 10459 'use strict'; 10460 10461 text = globals.converter._dispatch('codeSpans.before', text, options, globals); 10462 10463 if (typeof text === 'undefined') { 10464 text = ''; 10465 } 10466 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, 10467 function (wholeMatch, m1, m2, m3) { 10468 var c = m3; 10469 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace 10470 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace 10471 c = showdown.subParser('encodeCode')(c, options, globals); 10472 c = m1 + '<code>' + c + '</code>'; 10473 c = showdown.subParser('hashHTMLSpans')(c, options, globals); 10474 return c; 10475 } 10476 ); 10477 10478 text = globals.converter._dispatch('codeSpans.after', text, options, globals); 10479 return text; 10480 }); 10481 10482 /** 10483 * Create a full HTML document from the processed markdown 10484 */ 10485 showdown.subParser('completeHTMLDocument', function (text, options, globals) { 10486 'use strict'; 10487 10488 if (!options.completeHTMLDocument) { 10489 return text; 10490 } 10491 10492 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals); 10493 10494 var doctype = 'html', 10495 doctypeParsed = '<!DOCTYPE HTML>\n', 10496 title = '', 10497 charset = '<meta charset="utf-8">\n', 10498 lang = '', 10499 metadata = ''; 10500 10501 if (typeof globals.metadata.parsed.doctype !== 'undefined') { 10502 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n'; 10503 doctype = globals.metadata.parsed.doctype.toString().toLowerCase(); 10504 if (doctype === 'html' || doctype === 'html5') { 10505 charset = '<meta charset="utf-8">'; 10506 } 10507 } 10508 10509 for (var meta in globals.metadata.parsed) { 10510 if (globals.metadata.parsed.hasOwnProperty(meta)) { 10511 switch (meta.toLowerCase()) { 10512 case 'doctype': 10513 break; 10514 10515 case 'title': 10516 title = '<title>' + globals.metadata.parsed.title + '</title>\n'; 10517 break; 10518 10519 case 'charset': 10520 if (doctype === 'html' || doctype === 'html5') { 10521 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n'; 10522 } else { 10523 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n'; 10524 } 10525 break; 10526 10527 case 'language': 10528 case 'lang': 10529 lang = ' lang="' + globals.metadata.parsed[meta] + '"'; 10530 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 10531 break; 10532 10533 default: 10534 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 10535 } 10536 } 10537 } 10538 10539 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>'; 10540 10541 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals); 10542 return text; 10543 }); 10544 10545 /** 10546 * Convert all tabs to spaces 10547 */ 10548 showdown.subParser('detab', function (text, options, globals) { 10549 'use strict'; 10550 text = globals.converter._dispatch('detab.before', text, options, globals); 10551 10552 // expand first n-1 tabs 10553 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width 10554 10555 // replace the nth with two sentinels 10556 text = text.replace(/\t/g, '¨A¨B'); 10557 10558 // use the sentinel to anchor our regex so it doesn't explode 10559 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) { 10560 var leadingText = m1, 10561 numSpaces = 4 - leadingText.length % 4; // g_tab_width 10562 10563 // there *must* be a better way to do this: 10564 for (var i = 0; i < numSpaces; i++) { 10565 leadingText += ' '; 10566 } 10567 10568 return leadingText; 10569 }); 10570 10571 // clean up sentinels 10572 text = text.replace(/¨A/g, ' '); // g_tab_width 10573 text = text.replace(/¨B/g, ''); 10574 10575 text = globals.converter._dispatch('detab.after', text, options, globals); 10576 return text; 10577 }); 10578 10579 showdown.subParser('ellipsis', function (text, options, globals) { 10580 'use strict'; 10581 10582 text = globals.converter._dispatch('ellipsis.before', text, options, globals); 10583 10584 text = text.replace(/\.\.\./g, '…'); 10585 10586 text = globals.converter._dispatch('ellipsis.after', text, options, globals); 10587 10588 return text; 10589 }); 10590 10591 /** 10592 * Turn emoji codes into emojis 10593 * 10594 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis 10595 */ 10596 showdown.subParser('emoji', function (text, options, globals) { 10597 'use strict'; 10598 10599 if (!options.emoji) { 10600 return text; 10601 } 10602 10603 text = globals.converter._dispatch('emoji.before', text, options, globals); 10604 10605 var emojiRgx = /:([\S]+?):/g; 10606 10607 text = text.replace(emojiRgx, function (wm, emojiCode) { 10608 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) { 10609 return showdown.helper.emojis[emojiCode]; 10610 } 10611 return wm; 10612 }); 10613 10614 text = globals.converter._dispatch('emoji.after', text, options, globals); 10615 10616 return text; 10617 }); 10618 10619 /** 10620 * Smart processing for ampersands and angle brackets that need to be encoded. 10621 */ 10622 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) { 10623 'use strict'; 10624 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals); 10625 10626 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: 10627 // http://bumppo.net/projects/amputator/ 10628 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); 10629 10630 // Encode naked <'s 10631 text = text.replace(/<(?![a-z\/?$!])/gi, '<'); 10632 10633 // Encode < 10634 text = text.replace(/</g, '<'); 10635 10636 // Encode > 10637 text = text.replace(/>/g, '>'); 10638 10639 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals); 10640 return text; 10641 }); 10642 10643 /** 10644 * Returns the string, with after processing the following backslash escape sequences. 10645 * 10646 * attacklab: The polite way to do this is with the new escapeCharacters() function: 10647 * 10648 * text = escapeCharacters(text,"\\",true); 10649 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); 10650 * 10651 * ...but we're sidestepping its use of the (slow) RegExp constructor 10652 * as an optimization for Firefox. This function gets called a LOT. 10653 */ 10654 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) { 10655 'use strict'; 10656 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals); 10657 10658 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); 10659 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback); 10660 10661 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals); 10662 return text; 10663 }); 10664 10665 /** 10666 * Encode/escape certain characters inside Markdown code runs. 10667 * The point is that in code, these characters are literals, 10668 * and lose their special Markdown meanings. 10669 */ 10670 showdown.subParser('encodeCode', function (text, options, globals) { 10671 'use strict'; 10672 10673 text = globals.converter._dispatch('encodeCode.before', text, options, globals); 10674 10675 // Encode all ampersands; HTML entities are not 10676 // entities within a Markdown code span. 10677 text = text 10678 .replace(/&/g, '&') 10679 // Do the angle bracket song and dance: 10680 .replace(/</g, '<') 10681 .replace(/>/g, '>') 10682 // Now, escape characters that are magic in Markdown: 10683 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback); 10684 10685 text = globals.converter._dispatch('encodeCode.after', text, options, globals); 10686 return text; 10687 }); 10688 10689 /** 10690 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they 10691 * don't conflict with their use in Markdown for code, italics and strong. 10692 */ 10693 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) { 10694 'use strict'; 10695 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals); 10696 10697 // Build a regex to find HTML tags. 10698 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, 10699 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi; 10700 10701 text = text.replace(tags, function (wholeMatch) { 10702 return wholeMatch 10703 .replace(/(.)<\/?code>(?=.)/g, '$1`') 10704 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 10705 }); 10706 10707 text = text.replace(comments, function (wholeMatch) { 10708 return wholeMatch 10709 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 10710 }); 10711 10712 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals); 10713 return text; 10714 }); 10715 10716 /** 10717 * Handle github codeblocks prior to running HashHTML so that 10718 * HTML contained within the codeblock gets escaped properly 10719 * Example: 10720 * ```ruby 10721 * def hello_world(x) 10722 * puts "Hello, #{x}" 10723 * end 10724 * ``` 10725 */ 10726 showdown.subParser('githubCodeBlocks', function (text, options, globals) { 10727 'use strict'; 10728 10729 // early exit if option is not enabled 10730 if (!options.ghCodeBlocks) { 10731 return text; 10732 } 10733 10734 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); 10735 10736 text += '¨0'; 10737 10738 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) { 10739 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; 10740 10741 // First parse the github code block 10742 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 10743 codeblock = showdown.subParser('detab')(codeblock, options, globals); 10744 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 10745 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace 10746 10747 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; 10748 10749 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); 10750 10751 // Since GHCodeblocks can be false positives, we need to 10752 // store the primitive text and the parsed text in a global var, 10753 // and then return a token 10754 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 10755 }); 10756 10757 // attacklab: strip sentinel 10758 text = text.replace(/¨0/, ''); 10759 10760 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); 10761 }); 10762 10763 showdown.subParser('hashBlock', function (text, options, globals) { 10764 'use strict'; 10765 text = globals.converter._dispatch('hashBlock.before', text, options, globals); 10766 text = text.replace(/(^\n+|\n+$)/g, ''); 10767 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; 10768 text = globals.converter._dispatch('hashBlock.after', text, options, globals); 10769 return text; 10770 }); 10771 10772 /** 10773 * Hash and escape <code> elements that should not be parsed as markdown 10774 */ 10775 showdown.subParser('hashCodeTags', function (text, options, globals) { 10776 'use strict'; 10777 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals); 10778 10779 var repFunc = function (wholeMatch, match, left, right) { 10780 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 10781 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C'; 10782 }; 10783 10784 // Hash naked <code> 10785 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim'); 10786 10787 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals); 10788 return text; 10789 }); 10790 10791 showdown.subParser('hashElement', function (text, options, globals) { 10792 'use strict'; 10793 10794 return function (wholeMatch, m1) { 10795 var blockText = m1; 10796 10797 // Undo double lines 10798 blockText = blockText.replace(/\n\n/g, '\n'); 10799 blockText = blockText.replace(/^\n/, ''); 10800 10801 // strip trailing blank lines 10802 blockText = blockText.replace(/\n+$/g, ''); 10803 10804 // Replace the element text with a marker ("¨KxK" where x is its key) 10805 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; 10806 10807 return blockText; 10808 }; 10809 }); 10810 10811 showdown.subParser('hashHTMLBlocks', function (text, options, globals) { 10812 'use strict'; 10813 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals); 10814 10815 var blockTags = [ 10816 'pre', 10817 'div', 10818 'h1', 10819 'h2', 10820 'h3', 10821 'h4', 10822 'h5', 10823 'h6', 10824 'blockquote', 10825 'table', 10826 'dl', 10827 'ol', 10828 'ul', 10829 'script', 10830 'noscript', 10831 'form', 10832 'fieldset', 10833 'iframe', 10834 'math', 10835 'style', 10836 'section', 10837 'header', 10838 'footer', 10839 'nav', 10840 'article', 10841 'aside', 10842 'address', 10843 'audio', 10844 'canvas', 10845 'figure', 10846 'hgroup', 10847 'output', 10848 'video', 10849 'p' 10850 ], 10851 repFunc = function (wholeMatch, match, left, right) { 10852 var txt = wholeMatch; 10853 // check if this html element is marked as markdown 10854 // if so, it's contents should be parsed as markdown 10855 if (left.search(/\bmarkdown\b/) !== -1) { 10856 txt = left + globals.converter.makeHtml(match) + right; 10857 } 10858 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 10859 }; 10860 10861 if (options.backslashEscapesHTMLTags) { 10862 // encode backslash escaped HTML tags 10863 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) { 10864 return '<' + inside + '>'; 10865 }); 10866 } 10867 10868 // hash HTML Blocks 10869 for (var i = 0; i < blockTags.length; ++i) { 10870 10871 var opTagPos, 10872 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'), 10873 patLeft = '<' + blockTags[i] + '\\b[^>]*>', 10874 patRight = '</' + blockTags[i] + '>'; 10875 // 1. Look for the first position of the first opening HTML tag in the text 10876 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) { 10877 10878 // if the HTML tag is \ escaped, we need to escape it and break 10879 10880 10881 //2. Split the text in that position 10882 var subTexts = showdown.helper.splitAtIndex(text, opTagPos), 10883 //3. Match recursively 10884 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im'); 10885 10886 // prevent an infinite loop 10887 if (newSubText1 === subTexts[1]) { 10888 break; 10889 } 10890 text = subTexts[0].concat(newSubText1); 10891 } 10892 } 10893 // HR SPECIAL CASE 10894 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, 10895 showdown.subParser('hashElement')(text, options, globals)); 10896 10897 // Special case for standalone HTML comments 10898 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) { 10899 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 10900 }, '^ {0,3}<!--', '-->', 'gm'); 10901 10902 // PHP and ASP-style processor instructions (<?...?> and <%...%>) 10903 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, 10904 showdown.subParser('hashElement')(text, options, globals)); 10905 10906 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals); 10907 return text; 10908 }); 10909 10910 /** 10911 * Hash span elements that should not be parsed as markdown 10912 */ 10913 showdown.subParser('hashHTMLSpans', function (text, options, globals) { 10914 'use strict'; 10915 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals); 10916 10917 function hashHTMLSpan (html) { 10918 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C'; 10919 } 10920 10921 // Hash Self Closing tags 10922 text = text.replace(/<[^>]+?\/>/gi, function (wm) { 10923 return hashHTMLSpan(wm); 10924 }); 10925 10926 // Hash tags without properties 10927 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) { 10928 return hashHTMLSpan(wm); 10929 }); 10930 10931 // Hash tags with properties 10932 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) { 10933 return hashHTMLSpan(wm); 10934 }); 10935 10936 // Hash self closing tags without /> 10937 text = text.replace(/<[^>]+?>/gi, function (wm) { 10938 return hashHTMLSpan(wm); 10939 }); 10940 10941 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/ 10942 10943 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals); 10944 return text; 10945 }); 10946 10947 /** 10948 * Unhash HTML spans 10949 */ 10950 showdown.subParser('unhashHTMLSpans', function (text, options, globals) { 10951 'use strict'; 10952 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); 10953 10954 for (var i = 0; i < globals.gHtmlSpans.length; ++i) { 10955 var repText = globals.gHtmlSpans[i], 10956 // limiter to prevent infinite loop (assume 10 as limit for recurse) 10957 limit = 0; 10958 10959 while (/¨C(\d+)C/.test(repText)) { 10960 var num = RegExp.$1; 10961 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); 10962 if (limit === 10) { 10963 console.error('maximum nesting of 10 spans reached!!!'); 10964 break; 10965 } 10966 ++limit; 10967 } 10968 text = text.replace('¨C' + i + 'C', repText); 10969 } 10970 10971 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); 10972 return text; 10973 }); 10974 10975 /** 10976 * Hash and escape <pre><code> elements that should not be parsed as markdown 10977 */ 10978 showdown.subParser('hashPreCodeTags', function (text, options, globals) { 10979 'use strict'; 10980 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals); 10981 10982 var repFunc = function (wholeMatch, match, left, right) { 10983 // encode html entities 10984 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 10985 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 10986 }; 10987 10988 // Hash <pre><code> 10989 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim'); 10990 10991 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals); 10992 return text; 10993 }); 10994 10995 showdown.subParser('headers', function (text, options, globals) { 10996 'use strict'; 10997 10998 text = globals.converter._dispatch('headers.before', text, options, globals); 10999 11000 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), 11001 11002 // Set text-style headers: 11003 // Header 1 11004 // ======== 11005 // 11006 // Header 2 11007 // -------- 11008 // 11009 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, 11010 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; 11011 11012 text = text.replace(setextRegexH1, function (wholeMatch, m1) { 11013 11014 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 11015 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 11016 hLevel = headerLevelStart, 11017 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 11018 return showdown.subParser('hashBlock')(hashBlock, options, globals); 11019 }); 11020 11021 text = text.replace(setextRegexH2, function (matchFound, m1) { 11022 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 11023 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 11024 hLevel = headerLevelStart + 1, 11025 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 11026 return showdown.subParser('hashBlock')(hashBlock, options, globals); 11027 }); 11028 11029 // atx-style headers: 11030 // # Header 1 11031 // ## Header 2 11032 // ## Header 2 with closing hashes ## 11033 // ... 11034 // ###### Header 6 11035 // 11036 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm; 11037 11038 text = text.replace(atxStyle, function (wholeMatch, m1, m2) { 11039 var hText = m2; 11040 if (options.customizedHeaderId) { 11041 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, ''); 11042 } 11043 11044 var span = showdown.subParser('spanGamut')(hText, options, globals), 11045 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', 11046 hLevel = headerLevelStart - 1 + m1.length, 11047 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; 11048 11049 return showdown.subParser('hashBlock')(header, options, globals); 11050 }); 11051 11052 function headerId (m) { 11053 var title, 11054 prefix; 11055 11056 // It is separate from other options to allow combining prefix and customized 11057 if (options.customizedHeaderId) { 11058 var match = m.match(/\{([^{]+?)}\s*$/); 11059 if (match && match[1]) { 11060 m = match[1]; 11061 } 11062 } 11063 11064 title = m; 11065 11066 // Prefix id to prevent causing inadvertent pre-existing style matches. 11067 if (showdown.helper.isString(options.prefixHeaderId)) { 11068 prefix = options.prefixHeaderId; 11069 } else if (options.prefixHeaderId === true) { 11070 prefix = 'section-'; 11071 } else { 11072 prefix = ''; 11073 } 11074 11075 if (!options.rawPrefixHeaderId) { 11076 title = prefix + title; 11077 } 11078 11079 if (options.ghCompatibleHeaderId) { 11080 title = title 11081 .replace(/ /g, '-') 11082 // replace previously escaped chars (&, ¨ and $) 11083 .replace(/&/g, '') 11084 .replace(/¨T/g, '') 11085 .replace(/¨D/g, '') 11086 // replace rest of the chars (&~$ are repeated as they might have been escaped) 11087 // borrowed from github's redcarpet (some they should produce similar results) 11088 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '') 11089 .toLowerCase(); 11090 } else if (options.rawHeaderId) { 11091 title = title 11092 .replace(/ /g, '-') 11093 // replace previously escaped chars (&, ¨ and $) 11094 .replace(/&/g, '&') 11095 .replace(/¨T/g, '¨') 11096 .replace(/¨D/g, '$') 11097 // replace " and ' 11098 .replace(/["']/g, '-') 11099 .toLowerCase(); 11100 } else { 11101 title = title 11102 .replace(/[^\w]/g, '') 11103 .toLowerCase(); 11104 } 11105 11106 if (options.rawPrefixHeaderId) { 11107 title = prefix + title; 11108 } 11109 11110 if (globals.hashLinkCounts[title]) { 11111 title = title + '-' + (globals.hashLinkCounts[title]++); 11112 } else { 11113 globals.hashLinkCounts[title] = 1; 11114 } 11115 return title; 11116 } 11117 11118 text = globals.converter._dispatch('headers.after', text, options, globals); 11119 return text; 11120 }); 11121 11122 /** 11123 * Turn Markdown link shortcuts into XHTML <a> tags. 11124 */ 11125 showdown.subParser('horizontalRule', function (text, options, globals) { 11126 'use strict'; 11127 text = globals.converter._dispatch('horizontalRule.before', text, options, globals); 11128 11129 var key = showdown.subParser('hashBlock')('<hr />', options, globals); 11130 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key); 11131 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key); 11132 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key); 11133 11134 text = globals.converter._dispatch('horizontalRule.after', text, options, globals); 11135 return text; 11136 }); 11137 11138 /** 11139 * Turn Markdown image shortcuts into <img> tags. 11140 */ 11141 showdown.subParser('images', function (text, options, globals) { 11142 'use strict'; 11143 11144 text = globals.converter._dispatch('images.before', text, options, globals); 11145 11146 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, 11147 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, 11148 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, 11149 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, 11150 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; 11151 11152 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) { 11153 url = url.replace(/\s/g, ''); 11154 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title); 11155 } 11156 11157 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { 11158 11159 var gUrls = globals.gUrls, 11160 gTitles = globals.gTitles, 11161 gDims = globals.gDimensions; 11162 11163 linkId = linkId.toLowerCase(); 11164 11165 if (!title) { 11166 title = ''; 11167 } 11168 // Special case for explicit empty url 11169 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 11170 url = ''; 11171 11172 } else if (url === '' || url === null) { 11173 if (linkId === '' || linkId === null) { 11174 // lower-case and turn embedded newlines into spaces 11175 linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); 11176 } 11177 url = '#' + linkId; 11178 11179 if (!showdown.helper.isUndefined(gUrls[linkId])) { 11180 url = gUrls[linkId]; 11181 if (!showdown.helper.isUndefined(gTitles[linkId])) { 11182 title = gTitles[linkId]; 11183 } 11184 if (!showdown.helper.isUndefined(gDims[linkId])) { 11185 width = gDims[linkId].width; 11186 height = gDims[linkId].height; 11187 } 11188 } else { 11189 return wholeMatch; 11190 } 11191 } 11192 11193 altText = altText 11194 .replace(/"/g, '"') 11195 //altText = showdown.helper.escapeCharacters(altText, '*_', false); 11196 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 11197 //url = showdown.helper.escapeCharacters(url, '*_', false); 11198 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 11199 var result = '<img src="' + url + '" alt="' + altText + '"'; 11200 11201 if (title && showdown.helper.isString(title)) { 11202 title = title 11203 .replace(/"/g, '"') 11204 //title = showdown.helper.escapeCharacters(title, '*_', false); 11205 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 11206 result += ' title="' + title + '"'; 11207 } 11208 11209 if (width && height) { 11210 width = (width === '*') ? 'auto' : width; 11211 height = (height === '*') ? 'auto' : height; 11212 11213 result += ' width="' + width + '"'; 11214 result += ' height="' + height + '"'; 11215 } 11216 11217 result += ' />'; 11218 11219 return result; 11220 } 11221 11222 // First, handle reference-style labeled images: ![alt text][id] 11223 text = text.replace(referenceRegExp, writeImageTag); 11224 11225 // Next, handle inline images:  11226 11227 // base64 encoded images 11228 text = text.replace(base64RegExp, writeImageTagBase64); 11229 11230 // cases with crazy urls like ./image/cat1).png 11231 text = text.replace(crazyRegExp, writeImageTag); 11232 11233 // normal cases 11234 text = text.replace(inlineRegExp, writeImageTag); 11235 11236 // handle reference-style shortcuts: ![img text] 11237 text = text.replace(refShortcutRegExp, writeImageTag); 11238 11239 text = globals.converter._dispatch('images.after', text, options, globals); 11240 return text; 11241 }); 11242 11243 showdown.subParser('italicsAndBold', function (text, options, globals) { 11244 'use strict'; 11245 11246 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); 11247 11248 // it's faster to have 3 separate regexes for each case than have just one 11249 // because of backtracing, in some cases, it could lead to an exponential effect 11250 // called "catastrophic backtrace". Ominous! 11251 11252 function parseInside (txt, left, right) { 11253 /* 11254 if (options.simplifiedAutoLink) { 11255 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 11256 } 11257 */ 11258 return left + txt + right; 11259 } 11260 11261 // Parse underscores 11262 if (options.literalMidWordUnderscores) { 11263 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 11264 return parseInside (txt, '<strong><em>', '</em></strong>'); 11265 }); 11266 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 11267 return parseInside (txt, '<strong>', '</strong>'); 11268 }); 11269 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { 11270 return parseInside (txt, '<em>', '</em>'); 11271 }); 11272 } else { 11273 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 11274 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 11275 }); 11276 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 11277 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 11278 }); 11279 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { 11280 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) 11281 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 11282 }); 11283 } 11284 11285 // Now parse asterisks 11286 if (options.literalMidWordAsterisks) { 11287 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) { 11288 return parseInside (txt, lead + '<strong><em>', '</em></strong>'); 11289 }); 11290 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) { 11291 return parseInside (txt, lead + '<strong>', '</strong>'); 11292 }); 11293 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) { 11294 return parseInside (txt, lead + '<em>', '</em>'); 11295 }); 11296 } else { 11297 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) { 11298 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 11299 }); 11300 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) { 11301 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 11302 }); 11303 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) { 11304 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it) 11305 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 11306 }); 11307 } 11308 11309 11310 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); 11311 return text; 11312 }); 11313 11314 /** 11315 * Form HTML ordered (numbered) and unordered (bulleted) lists. 11316 */ 11317 showdown.subParser('lists', function (text, options, globals) { 11318 'use strict'; 11319 11320 /** 11321 * Process the contents of a single ordered or unordered list, splitting it 11322 * into individual list items. 11323 * @param {string} listStr 11324 * @param {boolean} trimTrailing 11325 * @returns {string} 11326 */ 11327 function processListItems (listStr, trimTrailing) { 11328 // The $g_list_level global keeps track of when we're inside a list. 11329 // Each time we enter a list, we increment it; when we leave a list, 11330 // we decrement. If it's zero, we're not in a list anymore. 11331 // 11332 // We do this because when we're not inside a list, we want to treat 11333 // something like this: 11334 // 11335 // I recommend upgrading to version 11336 // 8. Oops, now this line is treated 11337 // as a sub-list. 11338 // 11339 // As a single paragraph, despite the fact that the second line starts 11340 // with a digit-period-space sequence. 11341 // 11342 // Whereas when we're inside a list (or sub-list), that line will be 11343 // treated as the start of a sub-list. What a kludge, huh? This is 11344 // an aspect of Markdown's syntax that's hard to parse perfectly 11345 // without resorting to mind-reading. Perhaps the solution is to 11346 // change the syntax rules such that sub-lists must start with a 11347 // starting cardinal number; e.g. "1." or "a.". 11348 globals.gListLevel++; 11349 11350 // trim trailing blank lines: 11351 listStr = listStr.replace(/\n{2,}$/, '\n'); 11352 11353 // attacklab: add sentinel to emulate \z 11354 listStr += '¨0'; 11355 11356 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, 11357 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr)); 11358 11359 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation, 11360 // which is a syntax breaking change 11361 // activating this option reverts to old behavior 11362 if (options.disableForced4SpacesIndentedSublists) { 11363 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm; 11364 } 11365 11366 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { 11367 checked = (checked && checked.trim() !== ''); 11368 11369 var item = showdown.subParser('outdent')(m4, options, globals), 11370 bulletStyle = ''; 11371 11372 // Support for github tasklists 11373 if (taskbtn && options.tasklists) { 11374 bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; 11375 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { 11376 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; 11377 if (checked) { 11378 otp += ' checked'; 11379 } 11380 otp += '>'; 11381 return otp; 11382 }); 11383 } 11384 11385 // ISSUE #312 11386 // This input: - - - a 11387 // causes trouble to the parser, since it interprets it as: 11388 // <ul><li><li><li>a</li></li></li></ul> 11389 // instead of: 11390 // <ul><li>- - a</li></ul> 11391 // So, to prevent it, we will put a marker (¨A)in the beginning of the line 11392 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser 11393 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) { 11394 return '¨A' + wm2; 11395 }); 11396 11397 // m1 - Leading line or 11398 // Has a double return (multi paragraph) or 11399 // Has sublist 11400 if (m1 || (item.search(/\n{2,}/) > -1)) { 11401 item = showdown.subParser('githubCodeBlocks')(item, options, globals); 11402 item = showdown.subParser('blockGamut')(item, options, globals); 11403 } else { 11404 // Recursion for sub-lists: 11405 item = showdown.subParser('lists')(item, options, globals); 11406 item = item.replace(/\n$/, ''); // chomp(item) 11407 item = showdown.subParser('hashHTMLBlocks')(item, options, globals); 11408 11409 // Colapse double linebreaks 11410 item = item.replace(/\n\n+/g, '\n\n'); 11411 if (isParagraphed) { 11412 item = showdown.subParser('paragraphs')(item, options, globals); 11413 } else { 11414 item = showdown.subParser('spanGamut')(item, options, globals); 11415 } 11416 } 11417 11418 // now we need to remove the marker (¨A) 11419 item = item.replace('¨A', ''); 11420 // we can finally wrap the line in list item tags 11421 item = '<li' + bulletStyle + '>' + item + '</li>\n'; 11422 11423 return item; 11424 }); 11425 11426 // attacklab: strip sentinel 11427 listStr = listStr.replace(/¨0/g, ''); 11428 11429 globals.gListLevel--; 11430 11431 if (trimTrailing) { 11432 listStr = listStr.replace(/\s+$/, ''); 11433 } 11434 11435 return listStr; 11436 } 11437 11438 function styleStartNumber (list, listType) { 11439 // check if ol and starts by a number different than 1 11440 if (listType === 'ol') { 11441 var res = list.match(/^ *(\d+)\./); 11442 if (res && res[1] !== '1') { 11443 return ' start="' + res[1] + '"'; 11444 } 11445 } 11446 return ''; 11447 } 11448 11449 /** 11450 * Check and parse consecutive lists (better fix for issue #142) 11451 * @param {string} list 11452 * @param {string} listType 11453 * @param {boolean} trimTrailing 11454 * @returns {string} 11455 */ 11456 function parseConsecutiveLists (list, listType, trimTrailing) { 11457 // check if we caught 2 or more consecutive lists by mistake 11458 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa 11459 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, 11460 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, 11461 counterRxg = (listType === 'ul') ? olRgx : ulRgx, 11462 result = ''; 11463 11464 if (list.search(counterRxg) !== -1) { 11465 (function parseCL (txt) { 11466 var pos = txt.search(counterRxg), 11467 style = styleStartNumber(list, listType); 11468 if (pos !== -1) { 11469 // slice 11470 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n'; 11471 11472 // invert counterType and listType 11473 listType = (listType === 'ul') ? 'ol' : 'ul'; 11474 counterRxg = (listType === 'ul') ? olRgx : ulRgx; 11475 11476 //recurse 11477 parseCL(txt.slice(pos)); 11478 } else { 11479 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n'; 11480 } 11481 })(list); 11482 } else { 11483 var style = styleStartNumber(list, listType); 11484 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n'; 11485 } 11486 11487 return result; 11488 } 11489 11490 /** Start of list parsing **/ 11491 text = globals.converter._dispatch('lists.before', text, options, globals); 11492 // add sentinel to hack around khtml/safari bug: 11493 // http://bugs.webkit.org/show_bug.cgi?id=11231 11494 text += '¨0'; 11495 11496 if (globals.gListLevel) { 11497 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 11498 function (wholeMatch, list, m2) { 11499 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 11500 return parseConsecutiveLists(list, listType, true); 11501 } 11502 ); 11503 } else { 11504 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 11505 function (wholeMatch, m1, list, m3) { 11506 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 11507 return parseConsecutiveLists(list, listType, false); 11508 } 11509 ); 11510 } 11511 11512 // strip sentinel 11513 text = text.replace(/¨0/, ''); 11514 text = globals.converter._dispatch('lists.after', text, options, globals); 11515 return text; 11516 }); 11517 11518 /** 11519 * Parse metadata at the top of the document 11520 */ 11521 showdown.subParser('metadata', function (text, options, globals) { 11522 'use strict'; 11523 11524 if (!options.metadata) { 11525 return text; 11526 } 11527 11528 text = globals.converter._dispatch('metadata.before', text, options, globals); 11529 11530 function parseMetadataContents (content) { 11531 // raw is raw so it's not changed in any way 11532 globals.metadata.raw = content; 11533 11534 // escape chars forbidden in html attributes 11535 // double quotes 11536 content = content 11537 // ampersand first 11538 .replace(/&/g, '&') 11539 // double quotes 11540 .replace(/"/g, '"'); 11541 11542 content = content.replace(/\n {4}/g, ' '); 11543 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) { 11544 globals.metadata.parsed[key] = value; 11545 return ''; 11546 }); 11547 } 11548 11549 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) { 11550 parseMetadataContents(content); 11551 return '¨M'; 11552 }); 11553 11554 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) { 11555 if (format) { 11556 globals.metadata.format = format; 11557 } 11558 parseMetadataContents(content); 11559 return '¨M'; 11560 }); 11561 11562 text = text.replace(/¨M/g, ''); 11563 11564 text = globals.converter._dispatch('metadata.after', text, options, globals); 11565 return text; 11566 }); 11567 11568 /** 11569 * Remove one level of line-leading tabs or spaces 11570 */ 11571 showdown.subParser('outdent', function (text, options, globals) { 11572 'use strict'; 11573 text = globals.converter._dispatch('outdent.before', text, options, globals); 11574 11575 // attacklab: hack around Konqueror 3.5.4 bug: 11576 // "----------bug".replace(/^-/g,"") == "bug" 11577 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width 11578 11579 // attacklab: clean up hack 11580 text = text.replace(/¨0/g, ''); 11581 11582 text = globals.converter._dispatch('outdent.after', text, options, globals); 11583 return text; 11584 }); 11585 11586 /** 11587 * 11588 */ 11589 showdown.subParser('paragraphs', function (text, options, globals) { 11590 'use strict'; 11591 11592 text = globals.converter._dispatch('paragraphs.before', text, options, globals); 11593 // Strip leading and trailing lines: 11594 text = text.replace(/^\n+/g, ''); 11595 text = text.replace(/\n+$/g, ''); 11596 11597 var grafs = text.split(/\n{2,}/g), 11598 grafsOut = [], 11599 end = grafs.length; // Wrap <p> tags 11600 11601 for (var i = 0; i < end; i++) { 11602 var str = grafs[i]; 11603 // if this is an HTML marker, copy it 11604 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) { 11605 grafsOut.push(str); 11606 11607 // test for presence of characters to prevent empty lines being parsed 11608 // as paragraphs (resulting in undesired extra empty paragraphs) 11609 } else if (str.search(/\S/) >= 0) { 11610 str = showdown.subParser('spanGamut')(str, options, globals); 11611 str = str.replace(/^([ \t]*)/g, '<p>'); 11612 str += '</p>'; 11613 grafsOut.push(str); 11614 } 11615 } 11616 11617 /** Unhashify HTML blocks */ 11618 end = grafsOut.length; 11619 for (i = 0; i < end; i++) { 11620 var blockText = '', 11621 grafsOutIt = grafsOut[i], 11622 codeFlag = false; 11623 // if this is a marker for an html block... 11624 // use RegExp.test instead of string.search because of QML bug 11625 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { 11626 var delim = RegExp.$1, 11627 num = RegExp.$2; 11628 11629 if (delim === 'K') { 11630 blockText = globals.gHtmlBlocks[num]; 11631 } else { 11632 // we need to check if ghBlock is a false positive 11633 if (codeFlag) { 11634 // use encoded version of all text 11635 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals); 11636 } else { 11637 blockText = globals.ghCodeBlocks[num].codeblock; 11638 } 11639 } 11640 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs 11641 11642 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); 11643 // Check if grafsOutIt is a pre->code 11644 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { 11645 codeFlag = true; 11646 } 11647 } 11648 grafsOut[i] = grafsOutIt; 11649 } 11650 text = grafsOut.join('\n'); 11651 // Strip leading and trailing lines: 11652 text = text.replace(/^\n+/g, ''); 11653 text = text.replace(/\n+$/g, ''); 11654 return globals.converter._dispatch('paragraphs.after', text, options, globals); 11655 }); 11656 11657 /** 11658 * Run extension 11659 */ 11660 showdown.subParser('runExtension', function (ext, text, options, globals) { 11661 'use strict'; 11662 11663 if (ext.filter) { 11664 text = ext.filter(text, globals.converter, options); 11665 11666 } else if (ext.regex) { 11667 // TODO remove this when old extension loading mechanism is deprecated 11668 var re = ext.regex; 11669 if (!(re instanceof RegExp)) { 11670 re = new RegExp(re, 'g'); 11671 } 11672 text = text.replace(re, ext.replace); 11673 } 11674 11675 return text; 11676 }); 11677 11678 /** 11679 * These are all the transformations that occur *within* block-level 11680 * tags like paragraphs, headers, and list items. 11681 */ 11682 showdown.subParser('spanGamut', function (text, options, globals) { 11683 'use strict'; 11684 11685 text = globals.converter._dispatch('spanGamut.before', text, options, globals); 11686 text = showdown.subParser('codeSpans')(text, options, globals); 11687 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); 11688 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); 11689 11690 // Process anchor and image tags. Images must come first, 11691 // because ![foo][f] looks like an anchor. 11692 text = showdown.subParser('images')(text, options, globals); 11693 text = showdown.subParser('anchors')(text, options, globals); 11694 11695 // Make links out of things like `<http://example.com/>` 11696 // Must come after anchors, because you can use < and > 11697 // delimiters in inline links like [this](<url>). 11698 text = showdown.subParser('autoLinks')(text, options, globals); 11699 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals); 11700 text = showdown.subParser('emoji')(text, options, globals); 11701 text = showdown.subParser('underline')(text, options, globals); 11702 text = showdown.subParser('italicsAndBold')(text, options, globals); 11703 text = showdown.subParser('strikethrough')(text, options, globals); 11704 text = showdown.subParser('ellipsis')(text, options, globals); 11705 11706 // we need to hash HTML tags inside spans 11707 text = showdown.subParser('hashHTMLSpans')(text, options, globals); 11708 11709 // now we encode amps and angles 11710 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); 11711 11712 // Do hard breaks 11713 if (options.simpleLineBreaks) { 11714 // GFM style hard breaks 11715 // only add line breaks if the text does not contain a block (special case for lists) 11716 if (!/\n\n¨K/.test(text)) { 11717 text = text.replace(/\n+/g, '<br />\n'); 11718 } 11719 } else { 11720 // Vanilla hard breaks 11721 text = text.replace(/ +\n/g, '<br />\n'); 11722 } 11723 11724 text = globals.converter._dispatch('spanGamut.after', text, options, globals); 11725 return text; 11726 }); 11727 11728 showdown.subParser('strikethrough', function (text, options, globals) { 11729 'use strict'; 11730 11731 function parseInside (txt) { 11732 if (options.simplifiedAutoLink) { 11733 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 11734 } 11735 return '<del>' + txt + '</del>'; 11736 } 11737 11738 if (options.strikethrough) { 11739 text = globals.converter._dispatch('strikethrough.before', text, options, globals); 11740 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); }); 11741 text = globals.converter._dispatch('strikethrough.after', text, options, globals); 11742 } 11743 11744 return text; 11745 }); 11746 11747 /** 11748 * Strips link definitions from text, stores the URLs and titles in 11749 * hash references. 11750 * Link defs are in the form: ^[id]: url "optional title" 11751 */ 11752 showdown.subParser('stripLinkDefinitions', function (text, options, globals) { 11753 'use strict'; 11754 11755 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, 11756 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; 11757 11758 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug 11759 text += '¨0'; 11760 11761 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) { 11762 linkId = linkId.toLowerCase(); 11763 if (url.match(/^data:.+?\/.+?;base64,/)) { 11764 // remove newlines 11765 globals.gUrls[linkId] = url.replace(/\s/g, ''); 11766 } else { 11767 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive 11768 } 11769 11770 if (blankLines) { 11771 // Oops, found blank lines, so it's not a title. 11772 // Put back the parenthetical statement we stole. 11773 return blankLines + title; 11774 11775 } else { 11776 if (title) { 11777 globals.gTitles[linkId] = title.replace(/"|'/g, '"'); 11778 } 11779 if (options.parseImgDimensions && width && height) { 11780 globals.gDimensions[linkId] = { 11781 width: width, 11782 height: height 11783 }; 11784 } 11785 } 11786 // Completely remove the definition from the text 11787 return ''; 11788 }; 11789 11790 // first we try to find base64 link references 11791 text = text.replace(base64Regex, replaceFunc); 11792 11793 text = text.replace(regex, replaceFunc); 11794 11795 // attacklab: strip sentinel 11796 text = text.replace(/¨0/, ''); 11797 11798 return text; 11799 }); 11800 11801 showdown.subParser('tables', function (text, options, globals) { 11802 'use strict'; 11803 11804 if (!options.tables) { 11805 return text; 11806 } 11807 11808 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, 11809 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm; 11810 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm; 11811 11812 function parseStyles (sLine) { 11813 if (/^:[ \t]*--*$/.test(sLine)) { 11814 return ' style="text-align:left;"'; 11815 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { 11816 return ' style="text-align:right;"'; 11817 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { 11818 return ' style="text-align:center;"'; 11819 } else { 11820 return ''; 11821 } 11822 } 11823 11824 function parseHeaders (header, style) { 11825 var id = ''; 11826 header = header.trim(); 11827 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility 11828 if (options.tablesHeaderId || options.tableHeaderId) { 11829 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; 11830 } 11831 header = showdown.subParser('spanGamut')(header, options, globals); 11832 11833 return '<th' + id + style + '>' + header + '</th>\n'; 11834 } 11835 11836 function parseCells (cell, style) { 11837 var subText = showdown.subParser('spanGamut')(cell, options, globals); 11838 return '<td' + style + '>' + subText + '</td>\n'; 11839 } 11840 11841 function buildTable (headers, cells) { 11842 var tb = '<table>\n<thead>\n<tr>\n', 11843 tblLgn = headers.length; 11844 11845 for (var i = 0; i < tblLgn; ++i) { 11846 tb += headers[i]; 11847 } 11848 tb += '</tr>\n</thead>\n<tbody>\n'; 11849 11850 for (i = 0; i < cells.length; ++i) { 11851 tb += '<tr>\n'; 11852 for (var ii = 0; ii < tblLgn; ++ii) { 11853 tb += cells[i][ii]; 11854 } 11855 tb += '</tr>\n'; 11856 } 11857 tb += '</tbody>\n</table>\n'; 11858 return tb; 11859 } 11860 11861 function parseTable (rawTable) { 11862 var i, tableLines = rawTable.split('\n'); 11863 11864 for (i = 0; i < tableLines.length; ++i) { 11865 // strip wrong first and last column if wrapped tables are used 11866 if (/^ {0,3}\|/.test(tableLines[i])) { 11867 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); 11868 } 11869 if (/\|[ \t]*$/.test(tableLines[i])) { 11870 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); 11871 } 11872 // parse code spans first, but we only support one line code spans 11873 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals); 11874 } 11875 11876 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), 11877 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), 11878 rawCells = [], 11879 headers = [], 11880 styles = [], 11881 cells = []; 11882 11883 tableLines.shift(); 11884 tableLines.shift(); 11885 11886 for (i = 0; i < tableLines.length; ++i) { 11887 if (tableLines[i].trim() === '') { 11888 continue; 11889 } 11890 rawCells.push( 11891 tableLines[i] 11892 .split('|') 11893 .map(function (s) { 11894 return s.trim(); 11895 }) 11896 ); 11897 } 11898 11899 if (rawHeaders.length < rawStyles.length) { 11900 return rawTable; 11901 } 11902 11903 for (i = 0; i < rawStyles.length; ++i) { 11904 styles.push(parseStyles(rawStyles[i])); 11905 } 11906 11907 for (i = 0; i < rawHeaders.length; ++i) { 11908 if (showdown.helper.isUndefined(styles[i])) { 11909 styles[i] = ''; 11910 } 11911 headers.push(parseHeaders(rawHeaders[i], styles[i])); 11912 } 11913 11914 for (i = 0; i < rawCells.length; ++i) { 11915 var row = []; 11916 for (var ii = 0; ii < headers.length; ++ii) { 11917 if (showdown.helper.isUndefined(rawCells[i][ii])) { 11918 11919 } 11920 row.push(parseCells(rawCells[i][ii], styles[ii])); 11921 } 11922 cells.push(row); 11923 } 11924 11925 return buildTable(headers, cells); 11926 } 11927 11928 text = globals.converter._dispatch('tables.before', text, options, globals); 11929 11930 // find escaped pipe characters 11931 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback); 11932 11933 // parse multi column tables 11934 text = text.replace(tableRgx, parseTable); 11935 11936 // parse one column tables 11937 text = text.replace(singeColTblRgx, parseTable); 11938 11939 text = globals.converter._dispatch('tables.after', text, options, globals); 11940 11941 return text; 11942 }); 11943 11944 showdown.subParser('underline', function (text, options, globals) { 11945 'use strict'; 11946 11947 if (!options.underline) { 11948 return text; 11949 } 11950 11951 text = globals.converter._dispatch('underline.before', text, options, globals); 11952 11953 if (options.literalMidWordUnderscores) { 11954 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 11955 return '<u>' + txt + '</u>'; 11956 }); 11957 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 11958 return '<u>' + txt + '</u>'; 11959 }); 11960 } else { 11961 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 11962 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 11963 }); 11964 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 11965 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 11966 }); 11967 } 11968 11969 // escape remaining underscores to prevent them being parsed by italic and bold 11970 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback); 11971 11972 text = globals.converter._dispatch('underline.after', text, options, globals); 11973 11974 return text; 11975 }); 11976 11977 /** 11978 * Swap back in all the special characters we've hidden. 11979 */ 11980 showdown.subParser('unescapeSpecialChars', function (text, options, globals) { 11981 'use strict'; 11982 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals); 11983 11984 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) { 11985 var charCodeToReplace = parseInt(m1); 11986 return String.fromCharCode(charCodeToReplace); 11987 }); 11988 11989 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals); 11990 return text; 11991 }); 11992 11993 showdown.subParser('makeMarkdown.blockquote', function (node, globals) { 11994 'use strict'; 11995 11996 var txt = ''; 11997 if (node.hasChildNodes()) { 11998 var children = node.childNodes, 11999 childrenLength = children.length; 12000 12001 for (var i = 0; i < childrenLength; ++i) { 12002 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals); 12003 12004 if (innerTxt === '') { 12005 continue; 12006 } 12007 txt += innerTxt; 12008 } 12009 } 12010 // cleanup 12011 txt = txt.trim(); 12012 txt = '> ' + txt.split('\n').join('\n> '); 12013 return txt; 12014 }); 12015 12016 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) { 12017 'use strict'; 12018 12019 var lang = node.getAttribute('language'), 12020 num = node.getAttribute('precodenum'); 12021 return '```' + lang + '\n' + globals.preList[num] + '\n```'; 12022 }); 12023 12024 showdown.subParser('makeMarkdown.codeSpan', function (node) { 12025 'use strict'; 12026 12027 return '`' + node.innerHTML + '`'; 12028 }); 12029 12030 showdown.subParser('makeMarkdown.emphasis', function (node, globals) { 12031 'use strict'; 12032 12033 var txt = ''; 12034 if (node.hasChildNodes()) { 12035 txt += '*'; 12036 var children = node.childNodes, 12037 childrenLength = children.length; 12038 for (var i = 0; i < childrenLength; ++i) { 12039 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12040 } 12041 txt += '*'; 12042 } 12043 return txt; 12044 }); 12045 12046 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) { 12047 'use strict'; 12048 12049 var headerMark = new Array(headerLevel + 1).join('#'), 12050 txt = ''; 12051 12052 if (node.hasChildNodes()) { 12053 txt = headerMark + ' '; 12054 var children = node.childNodes, 12055 childrenLength = children.length; 12056 12057 for (var i = 0; i < childrenLength; ++i) { 12058 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12059 } 12060 } 12061 return txt; 12062 }); 12063 12064 showdown.subParser('makeMarkdown.hr', function () { 12065 'use strict'; 12066 12067 return '---'; 12068 }); 12069 12070 showdown.subParser('makeMarkdown.image', function (node) { 12071 'use strict'; 12072 12073 var txt = ''; 12074 if (node.hasAttribute('src')) { 12075 txt += ' + '>'; 12077 if (node.hasAttribute('width') && node.hasAttribute('height')) { 12078 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height'); 12079 } 12080 12081 if (node.hasAttribute('title')) { 12082 txt += ' "' + node.getAttribute('title') + '"'; 12083 } 12084 txt += ')'; 12085 } 12086 return txt; 12087 }); 12088 12089 showdown.subParser('makeMarkdown.links', function (node, globals) { 12090 'use strict'; 12091 12092 var txt = ''; 12093 if (node.hasChildNodes() && node.hasAttribute('href')) { 12094 var children = node.childNodes, 12095 childrenLength = children.length; 12096 txt = '['; 12097 for (var i = 0; i < childrenLength; ++i) { 12098 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12099 } 12100 txt += ']('; 12101 txt += '<' + node.getAttribute('href') + '>'; 12102 if (node.hasAttribute('title')) { 12103 txt += ' "' + node.getAttribute('title') + '"'; 12104 } 12105 txt += ')'; 12106 } 12107 return txt; 12108 }); 12109 12110 showdown.subParser('makeMarkdown.list', function (node, globals, type) { 12111 'use strict'; 12112 12113 var txt = ''; 12114 if (!node.hasChildNodes()) { 12115 return ''; 12116 } 12117 var listItems = node.childNodes, 12118 listItemsLenght = listItems.length, 12119 listNum = node.getAttribute('start') || 1; 12120 12121 for (var i = 0; i < listItemsLenght; ++i) { 12122 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') { 12123 continue; 12124 } 12125 12126 // define the bullet to use in list 12127 var bullet = ''; 12128 if (type === 'ol') { 12129 bullet = listNum.toString() + '. '; 12130 } else { 12131 bullet = '- '; 12132 } 12133 12134 // parse list item 12135 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals); 12136 ++listNum; 12137 } 12138 12139 // add comment at the end to prevent consecutive lists to be parsed as one 12140 txt += '\n<!-- -->\n'; 12141 return txt.trim(); 12142 }); 12143 12144 showdown.subParser('makeMarkdown.listItem', function (node, globals) { 12145 'use strict'; 12146 12147 var listItemTxt = ''; 12148 12149 var children = node.childNodes, 12150 childrenLenght = children.length; 12151 12152 for (var i = 0; i < childrenLenght; ++i) { 12153 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12154 } 12155 // if it's only one liner, we need to add a newline at the end 12156 if (!/\n$/.test(listItemTxt)) { 12157 listItemTxt += '\n'; 12158 } else { 12159 // it's multiparagraph, so we need to indent 12160 listItemTxt = listItemTxt 12161 .split('\n') 12162 .join('\n ') 12163 .replace(/^ {4}$/gm, '') 12164 .replace(/\n\n+/g, '\n\n'); 12165 } 12166 12167 return listItemTxt; 12168 }); 12169 12170 12171 12172 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) { 12173 'use strict'; 12174 12175 spansOnly = spansOnly || false; 12176 12177 var txt = ''; 12178 12179 // edge case of text without wrapper paragraph 12180 if (node.nodeType === 3) { 12181 return showdown.subParser('makeMarkdown.txt')(node, globals); 12182 } 12183 12184 // HTML comment 12185 if (node.nodeType === 8) { 12186 return '<!--' + node.data + '-->\n\n'; 12187 } 12188 12189 // process only node elements 12190 if (node.nodeType !== 1) { 12191 return ''; 12192 } 12193 12194 var tagName = node.tagName.toLowerCase(); 12195 12196 switch (tagName) { 12197 12198 // 12199 // BLOCKS 12200 // 12201 case 'h1': 12202 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; } 12203 break; 12204 case 'h2': 12205 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; } 12206 break; 12207 case 'h3': 12208 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; } 12209 break; 12210 case 'h4': 12211 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; } 12212 break; 12213 case 'h5': 12214 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; } 12215 break; 12216 case 'h6': 12217 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; } 12218 break; 12219 12220 case 'p': 12221 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; } 12222 break; 12223 12224 case 'blockquote': 12225 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; } 12226 break; 12227 12228 case 'hr': 12229 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; } 12230 break; 12231 12232 case 'ol': 12233 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; } 12234 break; 12235 12236 case 'ul': 12237 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; } 12238 break; 12239 12240 case 'precode': 12241 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; } 12242 break; 12243 12244 case 'pre': 12245 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; } 12246 break; 12247 12248 case 'table': 12249 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; } 12250 break; 12251 12252 // 12253 // SPANS 12254 // 12255 case 'code': 12256 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals); 12257 break; 12258 12259 case 'em': 12260 case 'i': 12261 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals); 12262 break; 12263 12264 case 'strong': 12265 case 'b': 12266 txt = showdown.subParser('makeMarkdown.strong')(node, globals); 12267 break; 12268 12269 case 'del': 12270 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals); 12271 break; 12272 12273 case 'a': 12274 txt = showdown.subParser('makeMarkdown.links')(node, globals); 12275 break; 12276 12277 case 'img': 12278 txt = showdown.subParser('makeMarkdown.image')(node, globals); 12279 break; 12280 12281 default: 12282 txt = node.outerHTML + '\n\n'; 12283 } 12284 12285 // common normalization 12286 // TODO eventually 12287 12288 return txt; 12289 }); 12290 12291 showdown.subParser('makeMarkdown.paragraph', function (node, globals) { 12292 'use strict'; 12293 12294 var txt = ''; 12295 if (node.hasChildNodes()) { 12296 var children = node.childNodes, 12297 childrenLength = children.length; 12298 for (var i = 0; i < childrenLength; ++i) { 12299 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12300 } 12301 } 12302 12303 // some text normalization 12304 txt = txt.trim(); 12305 12306 return txt; 12307 }); 12308 12309 showdown.subParser('makeMarkdown.pre', function (node, globals) { 12310 'use strict'; 12311 12312 var num = node.getAttribute('prenum'); 12313 return '<pre>' + globals.preList[num] + '</pre>'; 12314 }); 12315 12316 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { 12317 'use strict'; 12318 12319 var txt = ''; 12320 if (node.hasChildNodes()) { 12321 txt += '~~'; 12322 var children = node.childNodes, 12323 childrenLength = children.length; 12324 for (var i = 0; i < childrenLength; ++i) { 12325 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12326 } 12327 txt += '~~'; 12328 } 12329 return txt; 12330 }); 12331 12332 showdown.subParser('makeMarkdown.strong', function (node, globals) { 12333 'use strict'; 12334 12335 var txt = ''; 12336 if (node.hasChildNodes()) { 12337 txt += '**'; 12338 var children = node.childNodes, 12339 childrenLength = children.length; 12340 for (var i = 0; i < childrenLength; ++i) { 12341 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 12342 } 12343 txt += '**'; 12344 } 12345 return txt; 12346 }); 12347 12348 showdown.subParser('makeMarkdown.table', function (node, globals) { 12349 'use strict'; 12350 12351 var txt = '', 12352 tableArray = [[], []], 12353 headings = node.querySelectorAll('thead>tr>th'), 12354 rows = node.querySelectorAll('tbody>tr'), 12355 i, ii; 12356 for (i = 0; i < headings.length; ++i) { 12357 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals), 12358 allign = '---'; 12359 12360 if (headings[i].hasAttribute('style')) { 12361 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, ''); 12362 switch (style) { 12363 case 'text-align:left;': 12364 allign = ':---'; 12365 break; 12366 case 'text-align:right;': 12367 allign = '---:'; 12368 break; 12369 case 'text-align:center;': 12370 allign = ':---:'; 12371 break; 12372 } 12373 } 12374 tableArray[0][i] = headContent.trim(); 12375 tableArray[1][i] = allign; 12376 } 12377 12378 for (i = 0; i < rows.length; ++i) { 12379 var r = tableArray.push([]) - 1, 12380 cols = rows[i].getElementsByTagName('td'); 12381 12382 for (ii = 0; ii < headings.length; ++ii) { 12383 var cellContent = ' '; 12384 if (typeof cols[ii] !== 'undefined') { 12385 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals); 12386 } 12387 tableArray[r].push(cellContent); 12388 } 12389 } 12390 12391 var cellSpacesCount = 3; 12392 for (i = 0; i < tableArray.length; ++i) { 12393 for (ii = 0; ii < tableArray[i].length; ++ii) { 12394 var strLen = tableArray[i][ii].length; 12395 if (strLen > cellSpacesCount) { 12396 cellSpacesCount = strLen; 12397 } 12398 } 12399 } 12400 12401 for (i = 0; i < tableArray.length; ++i) { 12402 for (ii = 0; ii < tableArray[i].length; ++ii) { 12403 if (i === 1) { 12404 if (tableArray[i][ii].slice(-1) === ':') { 12405 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':'; 12406 } else { 12407 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-'); 12408 } 12409 } else { 12410 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount); 12411 } 12412 } 12413 txt += '| ' + tableArray[i].join(' | ') + ' |\n'; 12414 } 12415 12416 return txt.trim(); 12417 }); 12418 12419 showdown.subParser('makeMarkdown.tableCell', function (node, globals) { 12420 'use strict'; 12421 12422 var txt = ''; 12423 if (!node.hasChildNodes()) { 12424 return ''; 12425 } 12426 var children = node.childNodes, 12427 childrenLength = children.length; 12428 12429 for (var i = 0; i < childrenLength; ++i) { 12430 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true); 12431 } 12432 return txt.trim(); 12433 }); 12434 12435 showdown.subParser('makeMarkdown.txt', function (node) { 12436 'use strict'; 12437 12438 var txt = node.nodeValue; 12439 12440 // multiple spaces are collapsed 12441 txt = txt.replace(/ +/g, ' '); 12442 12443 // replace the custom ¨NBSP; with a space 12444 txt = txt.replace(/¨NBSP;/g, ' '); 12445 12446 // ", <, > and & should replace escaped html entities 12447 txt = showdown.helper.unescapeHTMLEntities(txt); 12448 12449 // escape markdown magic characters 12450 // emphasis, strong and strikethrough - can appear everywhere 12451 // we also escape pipe (|) because of tables 12452 // and escape ` because of code blocks and spans 12453 txt = txt.replace(/([*_~|`])/g, '\\$1'); 12454 12455 // escape > because of blockquotes 12456 txt = txt.replace(/^(\s*)>/g, '\\$1>'); 12457 12458 // hash character, only troublesome at the beginning of a line because of headers 12459 txt = txt.replace(/^#/gm, '\\#'); 12460 12461 // horizontal rules 12462 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3'); 12463 12464 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer 12465 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.'); 12466 12467 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped) 12468 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2'); 12469 12470 // images and links, ] followed by ( is problematic, so we escape it 12471 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\('); 12472 12473 // reference URIs must also be escaped 12474 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:'); 12475 12476 return txt; 12477 }); 12478 12479 var root = this; 12480 12481 // AMD Loader 12482 if (true) { 12483 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { 12484 'use strict'; 12485 return showdown; 12486 }).call(exports, __webpack_require__, exports, module), 12487 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 12488 12489 // CommonJS/nodeJS Loader 12490 } else {} 12491 }).call(this); 12492 12493 12494 12495 12496 /***/ }), 12497 12498 /***/ "NMb1": 12499 /***/ (function(module, exports) { 12500 12501 (function() { module.exports = window["wp"]["deprecated"]; }()); 12502 12503 /***/ }), 12504 12505 /***/ "SVSp": 12506 /***/ (function(module, exports) { 12507 12508 (function() { module.exports = window["wp"]["shortcode"]; }()); 12509 12510 /***/ }), 12511 12512 /***/ "Tqx9": 12513 /***/ (function(module, exports) { 12514 12515 (function() { module.exports = window["wp"]["primitives"]; }()); 12516 12517 /***/ }), 12518 12519 /***/ "UuzZ": 12520 /***/ (function(module, exports) { 12521 12522 (function() { module.exports = window["wp"]["autop"]; }()); 12523 12524 /***/ }), 12525 12526 /***/ "YLtl": 12527 /***/ (function(module, exports) { 12528 12529 (function() { module.exports = window["lodash"]; }()); 12530 12531 /***/ }), 12532 12533 /***/ "Zss7": 12534 /***/ (function(module, exports, __webpack_require__) { 12535 12536 var __WEBPACK_AMD_DEFINE_RESULT__;// TinyColor v1.4.2 12537 // https://github.com/bgrins/TinyColor 12538 // Brian Grinstead, MIT License 12539 12540 (function(Math) { 12541 12542 var trimLeft = /^\s+/, 12543 trimRight = /\s+$/, 12544 tinyCounter = 0, 12545 mathRound = Math.round, 12546 mathMin = Math.min, 12547 mathMax = Math.max, 12548 mathRandom = Math.random; 12549 12550 function tinycolor (color, opts) { 12551 12552 color = (color) ? color : ''; 12553 opts = opts || { }; 12554 12555 // If input is already a tinycolor, return itself 12556 if (color instanceof tinycolor) { 12557 return color; 12558 } 12559 // If we are called as a function, call using new instead 12560 if (!(this instanceof tinycolor)) { 12561 return new tinycolor(color, opts); 12562 } 12563 12564 var rgb = inputToRGB(color); 12565 this._originalInput = color, 12566 this._r = rgb.r, 12567 this._g = rgb.g, 12568 this._b = rgb.b, 12569 this._a = rgb.a, 12570 this._roundA = mathRound(100*this._a) / 100, 12571 this._format = opts.format || rgb.format; 12572 this._gradientType = opts.gradientType; 12573 12574 // Don't let the range of [0,255] come back in [0,1]. 12575 // Potentially lose a little bit of precision here, but will fix issues where 12576 // .5 gets interpreted as half of the total, instead of half of 1 12577 // If it was supposed to be 128, this was already taken care of by `inputToRgb` 12578 if (this._r < 1) { this._r = mathRound(this._r); } 12579 if (this._g < 1) { this._g = mathRound(this._g); } 12580 if (this._b < 1) { this._b = mathRound(this._b); } 12581 12582 this._ok = rgb.ok; 12583 this._tc_id = tinyCounter++; 12584 } 12585 12586 tinycolor.prototype = { 12587 isDark: function() { 12588 return this.getBrightness() < 128; 12589 }, 12590 isLight: function() { 12591 return !this.isDark(); 12592 }, 12593 isValid: function() { 12594 return this._ok; 12595 }, 12596 getOriginalInput: function() { 12597 return this._originalInput; 12598 }, 12599 getFormat: function() { 12600 return this._format; 12601 }, 12602 getAlpha: function() { 12603 return this._a; 12604 }, 12605 getBrightness: function() { 12606 //http://www.w3.org/TR/AERT#color-contrast 12607 var rgb = this.toRgb(); 12608 return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; 12609 }, 12610 getLuminance: function() { 12611 //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef 12612 var rgb = this.toRgb(); 12613 var RsRGB, GsRGB, BsRGB, R, G, B; 12614 RsRGB = rgb.r/255; 12615 GsRGB = rgb.g/255; 12616 BsRGB = rgb.b/255; 12617 12618 if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);} 12619 if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);} 12620 if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);} 12621 return (0.2126 * R) + (0.7152 * G) + (0.0722 * B); 12622 }, 12623 setAlpha: function(value) { 12624 this._a = boundAlpha(value); 12625 this._roundA = mathRound(100*this._a) / 100; 12626 return this; 12627 }, 12628 toHsv: function() { 12629 var hsv = rgbToHsv(this._r, this._g, this._b); 12630 return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a }; 12631 }, 12632 toHsvString: function() { 12633 var hsv = rgbToHsv(this._r, this._g, this._b); 12634 var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); 12635 return (this._a == 1) ? 12636 "hsv(" + h + ", " + s + "%, " + v + "%)" : 12637 "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")"; 12638 }, 12639 toHsl: function() { 12640 var hsl = rgbToHsl(this._r, this._g, this._b); 12641 return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a }; 12642 }, 12643 toHslString: function() { 12644 var hsl = rgbToHsl(this._r, this._g, this._b); 12645 var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); 12646 return (this._a == 1) ? 12647 "hsl(" + h + ", " + s + "%, " + l + "%)" : 12648 "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")"; 12649 }, 12650 toHex: function(allow3Char) { 12651 return rgbToHex(this._r, this._g, this._b, allow3Char); 12652 }, 12653 toHexString: function(allow3Char) { 12654 return '#' + this.toHex(allow3Char); 12655 }, 12656 toHex8: function(allow4Char) { 12657 return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); 12658 }, 12659 toHex8String: function(allow4Char) { 12660 return '#' + this.toHex8(allow4Char); 12661 }, 12662 toRgb: function() { 12663 return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a }; 12664 }, 12665 toRgbString: function() { 12666 return (this._a == 1) ? 12667 "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" : 12668 "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")"; 12669 }, 12670 toPercentageRgb: function() { 12671 return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a }; 12672 }, 12673 toPercentageRgbString: function() { 12674 return (this._a == 1) ? 12675 "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" : 12676 "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; 12677 }, 12678 toName: function() { 12679 if (this._a === 0) { 12680 return "transparent"; 12681 } 12682 12683 if (this._a < 1) { 12684 return false; 12685 } 12686 12687 return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; 12688 }, 12689 toFilter: function(secondColor) { 12690 var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a); 12691 var secondHex8String = hex8String; 12692 var gradientType = this._gradientType ? "GradientType = 1, " : ""; 12693 12694 if (secondColor) { 12695 var s = tinycolor(secondColor); 12696 secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a); 12697 } 12698 12699 return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")"; 12700 }, 12701 toString: function(format) { 12702 var formatSet = !!format; 12703 format = format || this._format; 12704 12705 var formattedString = false; 12706 var hasAlpha = this._a < 1 && this._a >= 0; 12707 var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name"); 12708 12709 if (needsAlphaFormat) { 12710 // Special case for "transparent", all other non-alpha formats 12711 // will return rgba when there is transparency. 12712 if (format === "name" && this._a === 0) { 12713 return this.toName(); 12714 } 12715 return this.toRgbString(); 12716 } 12717 if (format === "rgb") { 12718 formattedString = this.toRgbString(); 12719 } 12720 if (format === "prgb") { 12721 formattedString = this.toPercentageRgbString(); 12722 } 12723 if (format === "hex" || format === "hex6") { 12724 formattedString = this.toHexString(); 12725 } 12726 if (format === "hex3") { 12727 formattedString = this.toHexString(true); 12728 } 12729 if (format === "hex4") { 12730 formattedString = this.toHex8String(true); 12731 } 12732 if (format === "hex8") { 12733 formattedString = this.toHex8String(); 12734 } 12735 if (format === "name") { 12736 formattedString = this.toName(); 12737 } 12738 if (format === "hsl") { 12739 formattedString = this.toHslString(); 12740 } 12741 if (format === "hsv") { 12742 formattedString = this.toHsvString(); 12743 } 12744 12745 return formattedString || this.toHexString(); 12746 }, 12747 clone: function() { 12748 return tinycolor(this.toString()); 12749 }, 12750 12751 _applyModification: function(fn, args) { 12752 var color = fn.apply(null, [this].concat([].slice.call(args))); 12753 this._r = color._r; 12754 this._g = color._g; 12755 this._b = color._b; 12756 this.setAlpha(color._a); 12757 return this; 12758 }, 12759 lighten: function() { 12760 return this._applyModification(lighten, arguments); 12761 }, 12762 brighten: function() { 12763 return this._applyModification(brighten, arguments); 12764 }, 12765 darken: function() { 12766 return this._applyModification(darken, arguments); 12767 }, 12768 desaturate: function() { 12769 return this._applyModification(desaturate, arguments); 12770 }, 12771 saturate: function() { 12772 return this._applyModification(saturate, arguments); 12773 }, 12774 greyscale: function() { 12775 return this._applyModification(greyscale, arguments); 12776 }, 12777 spin: function() { 12778 return this._applyModification(spin, arguments); 12779 }, 12780 12781 _applyCombination: function(fn, args) { 12782 return fn.apply(null, [this].concat([].slice.call(args))); 12783 }, 12784 analogous: function() { 12785 return this._applyCombination(analogous, arguments); 12786 }, 12787 complement: function() { 12788 return this._applyCombination(complement, arguments); 12789 }, 12790 monochromatic: function() { 12791 return this._applyCombination(monochromatic, arguments); 12792 }, 12793 splitcomplement: function() { 12794 return this._applyCombination(splitcomplement, arguments); 12795 }, 12796 triad: function() { 12797 return this._applyCombination(triad, arguments); 12798 }, 12799 tetrad: function() { 12800 return this._applyCombination(tetrad, arguments); 12801 } 12802 }; 12803 12804 // If input is an object, force 1 into "1.0" to handle ratios properly 12805 // String input requires "1.0" as input, so 1 will be treated as 1 12806 tinycolor.fromRatio = function(color, opts) { 12807 if (typeof color == "object") { 12808 var newColor = {}; 12809 for (var i in color) { 12810 if (color.hasOwnProperty(i)) { 12811 if (i === "a") { 12812 newColor[i] = color[i]; 12813 } 12814 else { 12815 newColor[i] = convertToPercentage(color[i]); 12816 } 12817 } 12818 } 12819 color = newColor; 12820 } 12821 12822 return tinycolor(color, opts); 12823 }; 12824 12825 // Given a string or object, convert that input to RGB 12826 // Possible string inputs: 12827 // 12828 // "red" 12829 // "#f00" or "f00" 12830 // "#ff0000" or "ff0000" 12831 // "#ff000000" or "ff000000" 12832 // "rgb 255 0 0" or "rgb (255, 0, 0)" 12833 // "rgb 1.0 0 0" or "rgb (1, 0, 0)" 12834 // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" 12835 // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" 12836 // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" 12837 // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" 12838 // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" 12839 // 12840 function inputToRGB(color) { 12841 12842 var rgb = { r: 0, g: 0, b: 0 }; 12843 var a = 1; 12844 var s = null; 12845 var v = null; 12846 var l = null; 12847 var ok = false; 12848 var format = false; 12849 12850 if (typeof color == "string") { 12851 color = stringInputToObject(color); 12852 } 12853 12854 if (typeof color == "object") { 12855 if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { 12856 rgb = rgbToRgb(color.r, color.g, color.b); 12857 ok = true; 12858 format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; 12859 } 12860 else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { 12861 s = convertToPercentage(color.s); 12862 v = convertToPercentage(color.v); 12863 rgb = hsvToRgb(color.h, s, v); 12864 ok = true; 12865 format = "hsv"; 12866 } 12867 else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { 12868 s = convertToPercentage(color.s); 12869 l = convertToPercentage(color.l); 12870 rgb = hslToRgb(color.h, s, l); 12871 ok = true; 12872 format = "hsl"; 12873 } 12874 12875 if (color.hasOwnProperty("a")) { 12876 a = color.a; 12877 } 12878 } 12879 12880 a = boundAlpha(a); 12881 12882 return { 12883 ok: ok, 12884 format: color.format || format, 12885 r: mathMin(255, mathMax(rgb.r, 0)), 12886 g: mathMin(255, mathMax(rgb.g, 0)), 12887 b: mathMin(255, mathMax(rgb.b, 0)), 12888 a: a 12889 }; 12890 } 12891 12892 12893 // Conversion Functions 12894 // -------------------- 12895 12896 // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from: 12897 // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript> 12898 12899 // `rgbToRgb` 12900 // Handle bounds / percentage checking to conform to CSS color spec 12901 // <http://www.w3.org/TR/css3-color/> 12902 // *Assumes:* r, g, b in [0, 255] or [0, 1] 12903 // *Returns:* { r, g, b } in [0, 255] 12904 function rgbToRgb(r, g, b){ 12905 return { 12906 r: bound01(r, 255) * 255, 12907 g: bound01(g, 255) * 255, 12908 b: bound01(b, 255) * 255 12909 }; 12910 } 12911 12912 // `rgbToHsl` 12913 // Converts an RGB color value to HSL. 12914 // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] 12915 // *Returns:* { h, s, l } in [0,1] 12916 function rgbToHsl(r, g, b) { 12917 12918 r = bound01(r, 255); 12919 g = bound01(g, 255); 12920 b = bound01(b, 255); 12921 12922 var max = mathMax(r, g, b), min = mathMin(r, g, b); 12923 var h, s, l = (max + min) / 2; 12924 12925 if(max == min) { 12926 h = s = 0; // achromatic 12927 } 12928 else { 12929 var d = max - min; 12930 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 12931 switch(max) { 12932 case r: h = (g - b) / d + (g < b ? 6 : 0); break; 12933 case g: h = (b - r) / d + 2; break; 12934 case b: h = (r - g) / d + 4; break; 12935 } 12936 12937 h /= 6; 12938 } 12939 12940 return { h: h, s: s, l: l }; 12941 } 12942 12943 // `hslToRgb` 12944 // Converts an HSL color value to RGB. 12945 // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] 12946 // *Returns:* { r, g, b } in the set [0, 255] 12947 function hslToRgb(h, s, l) { 12948 var r, g, b; 12949 12950 h = bound01(h, 360); 12951 s = bound01(s, 100); 12952 l = bound01(l, 100); 12953 12954 function hue2rgb(p, q, t) { 12955 if(t < 0) t += 1; 12956 if(t > 1) t -= 1; 12957 if(t < 1/6) return p + (q - p) * 6 * t; 12958 if(t < 1/2) return q; 12959 if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; 12960 return p; 12961 } 12962 12963 if(s === 0) { 12964 r = g = b = l; // achromatic 12965 } 12966 else { 12967 var q = l < 0.5 ? l * (1 + s) : l + s - l * s; 12968 var p = 2 * l - q; 12969 r = hue2rgb(p, q, h + 1/3); 12970 g = hue2rgb(p, q, h); 12971 b = hue2rgb(p, q, h - 1/3); 12972 } 12973 12974 return { r: r * 255, g: g * 255, b: b * 255 }; 12975 } 12976 12977 // `rgbToHsv` 12978 // Converts an RGB color value to HSV 12979 // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] 12980 // *Returns:* { h, s, v } in [0,1] 12981 function rgbToHsv(r, g, b) { 12982 12983 r = bound01(r, 255); 12984 g = bound01(g, 255); 12985 b = bound01(b, 255); 12986 12987 var max = mathMax(r, g, b), min = mathMin(r, g, b); 12988 var h, s, v = max; 12989 12990 var d = max - min; 12991 s = max === 0 ? 0 : d / max; 12992 12993 if(max == min) { 12994 h = 0; // achromatic 12995 } 12996 else { 12997 switch(max) { 12998 case r: h = (g - b) / d + (g < b ? 6 : 0); break; 12999 case g: h = (b - r) / d + 2; break; 13000 case b: h = (r - g) / d + 4; break; 13001 } 13002 h /= 6; 13003 } 13004 return { h: h, s: s, v: v }; 13005 } 13006 13007 // `hsvToRgb` 13008 // Converts an HSV color value to RGB. 13009 // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] 13010 // *Returns:* { r, g, b } in the set [0, 255] 13011 function hsvToRgb(h, s, v) { 13012 13013 h = bound01(h, 360) * 6; 13014 s = bound01(s, 100); 13015 v = bound01(v, 100); 13016 13017 var i = Math.floor(h), 13018 f = h - i, 13019 p = v * (1 - s), 13020 q = v * (1 - f * s), 13021 t = v * (1 - (1 - f) * s), 13022 mod = i % 6, 13023 r = [v, q, p, p, t, v][mod], 13024 g = [t, v, v, q, p, p][mod], 13025 b = [p, p, t, v, v, q][mod]; 13026 13027 return { r: r * 255, g: g * 255, b: b * 255 }; 13028 } 13029 13030 // `rgbToHex` 13031 // Converts an RGB color to hex 13032 // Assumes r, g, and b are contained in the set [0, 255] 13033 // Returns a 3 or 6 character hex 13034 function rgbToHex(r, g, b, allow3Char) { 13035 13036 var hex = [ 13037 pad2(mathRound(r).toString(16)), 13038 pad2(mathRound(g).toString(16)), 13039 pad2(mathRound(b).toString(16)) 13040 ]; 13041 13042 // Return a 3 character hex if possible 13043 if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { 13044 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); 13045 } 13046 13047 return hex.join(""); 13048 } 13049 13050 // `rgbaToHex` 13051 // Converts an RGBA color plus alpha transparency to hex 13052 // Assumes r, g, b are contained in the set [0, 255] and 13053 // a in [0, 1]. Returns a 4 or 8 character rgba hex 13054 function rgbaToHex(r, g, b, a, allow4Char) { 13055 13056 var hex = [ 13057 pad2(mathRound(r).toString(16)), 13058 pad2(mathRound(g).toString(16)), 13059 pad2(mathRound(b).toString(16)), 13060 pad2(convertDecimalToHex(a)) 13061 ]; 13062 13063 // Return a 4 character hex if possible 13064 if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { 13065 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); 13066 } 13067 13068 return hex.join(""); 13069 } 13070 13071 // `rgbaToArgbHex` 13072 // Converts an RGBA color to an ARGB Hex8 string 13073 // Rarely used, but required for "toFilter()" 13074 function rgbaToArgbHex(r, g, b, a) { 13075 13076 var hex = [ 13077 pad2(convertDecimalToHex(a)), 13078 pad2(mathRound(r).toString(16)), 13079 pad2(mathRound(g).toString(16)), 13080 pad2(mathRound(b).toString(16)) 13081 ]; 13082 13083 return hex.join(""); 13084 } 13085 13086 // `equals` 13087 // Can be called with any tinycolor input 13088 tinycolor.equals = function (color1, color2) { 13089 if (!color1 || !color2) { return false; } 13090 return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); 13091 }; 13092 13093 tinycolor.random = function() { 13094 return tinycolor.fromRatio({ 13095 r: mathRandom(), 13096 g: mathRandom(), 13097 b: mathRandom() 13098 }); 13099 }; 13100 13101 13102 // Modification Functions 13103 // ---------------------- 13104 // Thanks to less.js for some of the basics here 13105 // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js> 13106 13107 function desaturate(color, amount) { 13108 amount = (amount === 0) ? 0 : (amount || 10); 13109 var hsl = tinycolor(color).toHsl(); 13110 hsl.s -= amount / 100; 13111 hsl.s = clamp01(hsl.s); 13112 return tinycolor(hsl); 13113 } 13114 13115 function saturate(color, amount) { 13116 amount = (amount === 0) ? 0 : (amount || 10); 13117 var hsl = tinycolor(color).toHsl(); 13118 hsl.s += amount / 100; 13119 hsl.s = clamp01(hsl.s); 13120 return tinycolor(hsl); 13121 } 13122 13123 function greyscale(color) { 13124 return tinycolor(color).desaturate(100); 13125 } 13126 13127 function lighten (color, amount) { 13128 amount = (amount === 0) ? 0 : (amount || 10); 13129 var hsl = tinycolor(color).toHsl(); 13130 hsl.l += amount / 100; 13131 hsl.l = clamp01(hsl.l); 13132 return tinycolor(hsl); 13133 } 13134 13135 function brighten(color, amount) { 13136 amount = (amount === 0) ? 0 : (amount || 10); 13137 var rgb = tinycolor(color).toRgb(); 13138 rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100)))); 13139 rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100)))); 13140 rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100)))); 13141 return tinycolor(rgb); 13142 } 13143 13144 function darken (color, amount) { 13145 amount = (amount === 0) ? 0 : (amount || 10); 13146 var hsl = tinycolor(color).toHsl(); 13147 hsl.l -= amount / 100; 13148 hsl.l = clamp01(hsl.l); 13149 return tinycolor(hsl); 13150 } 13151 13152 // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. 13153 // Values outside of this range will be wrapped into this range. 13154 function spin(color, amount) { 13155 var hsl = tinycolor(color).toHsl(); 13156 var hue = (hsl.h + amount) % 360; 13157 hsl.h = hue < 0 ? 360 + hue : hue; 13158 return tinycolor(hsl); 13159 } 13160 13161 // Combination Functions 13162 // --------------------- 13163 // Thanks to jQuery xColor for some of the ideas behind these 13164 // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js> 13165 13166 function complement(color) { 13167 var hsl = tinycolor(color).toHsl(); 13168 hsl.h = (hsl.h + 180) % 360; 13169 return tinycolor(hsl); 13170 } 13171 13172 function triad(color) { 13173 var hsl = tinycolor(color).toHsl(); 13174 var h = hsl.h; 13175 return [ 13176 tinycolor(color), 13177 tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), 13178 tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) 13179 ]; 13180 } 13181 13182 function tetrad(color) { 13183 var hsl = tinycolor(color).toHsl(); 13184 var h = hsl.h; 13185 return [ 13186 tinycolor(color), 13187 tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), 13188 tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), 13189 tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) 13190 ]; 13191 } 13192 13193 function splitcomplement(color) { 13194 var hsl = tinycolor(color).toHsl(); 13195 var h = hsl.h; 13196 return [ 13197 tinycolor(color), 13198 tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}), 13199 tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l}) 13200 ]; 13201 } 13202 13203 function analogous(color, results, slices) { 13204 results = results || 6; 13205 slices = slices || 30; 13206 13207 var hsl = tinycolor(color).toHsl(); 13208 var part = 360 / slices; 13209 var ret = [tinycolor(color)]; 13210 13211 for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { 13212 hsl.h = (hsl.h + part) % 360; 13213 ret.push(tinycolor(hsl)); 13214 } 13215 return ret; 13216 } 13217 13218 function monochromatic(color, results) { 13219 results = results || 6; 13220 var hsv = tinycolor(color).toHsv(); 13221 var h = hsv.h, s = hsv.s, v = hsv.v; 13222 var ret = []; 13223 var modification = 1 / results; 13224 13225 while (results--) { 13226 ret.push(tinycolor({ h: h, s: s, v: v})); 13227 v = (v + modification) % 1; 13228 } 13229 13230 return ret; 13231 } 13232 13233 // Utility Functions 13234 // --------------------- 13235 13236 tinycolor.mix = function(color1, color2, amount) { 13237 amount = (amount === 0) ? 0 : (amount || 50); 13238 13239 var rgb1 = tinycolor(color1).toRgb(); 13240 var rgb2 = tinycolor(color2).toRgb(); 13241 13242 var p = amount / 100; 13243 13244 var rgba = { 13245 r: ((rgb2.r - rgb1.r) * p) + rgb1.r, 13246 g: ((rgb2.g - rgb1.g) * p) + rgb1.g, 13247 b: ((rgb2.b - rgb1.b) * p) + rgb1.b, 13248 a: ((rgb2.a - rgb1.a) * p) + rgb1.a 13249 }; 13250 13251 return tinycolor(rgba); 13252 }; 13253 13254 13255 // Readability Functions 13256 // --------------------- 13257 // <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2) 13258 13259 // `contrast` 13260 // Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2) 13261 tinycolor.readability = function(color1, color2) { 13262 var c1 = tinycolor(color1); 13263 var c2 = tinycolor(color2); 13264 return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05); 13265 }; 13266 13267 // `isReadable` 13268 // Ensure that foreground and background color combinations meet WCAG2 guidelines. 13269 // The third argument is an optional Object. 13270 // the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA'; 13271 // the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'. 13272 // If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}. 13273 13274 // *Example* 13275 // tinycolor.isReadable("#000", "#111") => false 13276 // tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false 13277 tinycolor.isReadable = function(color1, color2, wcag2) { 13278 var readability = tinycolor.readability(color1, color2); 13279 var wcag2Parms, out; 13280 13281 out = false; 13282 13283 wcag2Parms = validateWCAG2Parms(wcag2); 13284 switch (wcag2Parms.level + wcag2Parms.size) { 13285 case "AAsmall": 13286 case "AAAlarge": 13287 out = readability >= 4.5; 13288 break; 13289 case "AAlarge": 13290 out = readability >= 3; 13291 break; 13292 case "AAAsmall": 13293 out = readability >= 7; 13294 break; 13295 } 13296 return out; 13297 13298 }; 13299 13300 // `mostReadable` 13301 // Given a base color and a list of possible foreground or background 13302 // colors for that base, returns the most readable color. 13303 // Optionally returns Black or White if the most readable color is unreadable. 13304 // *Example* 13305 // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" 13306 // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" 13307 // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" 13308 // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" 13309 tinycolor.mostReadable = function(baseColor, colorList, args) { 13310 var bestColor = null; 13311 var bestScore = 0; 13312 var readability; 13313 var includeFallbackColors, level, size ; 13314 args = args || {}; 13315 includeFallbackColors = args.includeFallbackColors ; 13316 level = args.level; 13317 size = args.size; 13318 13319 for (var i= 0; i < colorList.length ; i++) { 13320 readability = tinycolor.readability(baseColor, colorList[i]); 13321 if (readability > bestScore) { 13322 bestScore = readability; 13323 bestColor = tinycolor(colorList[i]); 13324 } 13325 } 13326 13327 if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) { 13328 return bestColor; 13329 } 13330 else { 13331 args.includeFallbackColors=false; 13332 return tinycolor.mostReadable(baseColor,["#fff", "#000"],args); 13333 } 13334 }; 13335 13336 13337 // Big List of Colors 13338 // ------------------ 13339 // <http://www.w3.org/TR/css3-color/#svg-color> 13340 var names = tinycolor.names = { 13341 aliceblue: "f0f8ff", 13342 antiquewhite: "faebd7", 13343 aqua: "0ff", 13344 aquamarine: "7fffd4", 13345 azure: "f0ffff", 13346 beige: "f5f5dc", 13347 bisque: "ffe4c4", 13348 black: "000", 13349 blanchedalmond: "ffebcd", 13350 blue: "00f", 13351 blueviolet: "8a2be2", 13352 brown: "a52a2a", 13353 burlywood: "deb887", 13354 burntsienna: "ea7e5d", 13355 cadetblue: "5f9ea0", 13356 chartreuse: "7fff00", 13357 chocolate: "d2691e", 13358 coral: "ff7f50", 13359 cornflowerblue: "6495ed", 13360 cornsilk: "fff8dc", 13361 crimson: "dc143c", 13362 cyan: "0ff", 13363 darkblue: "00008b", 13364 darkcyan: "008b8b", 13365 darkgoldenrod: "b8860b", 13366 darkgray: "a9a9a9", 13367 darkgreen: "006400", 13368 darkgrey: "a9a9a9", 13369 darkkhaki: "bdb76b", 13370 darkmagenta: "8b008b", 13371 darkolivegreen: "556b2f", 13372 darkorange: "ff8c00", 13373 darkorchid: "9932cc", 13374 darkred: "8b0000", 13375 darksalmon: "e9967a", 13376 darkseagreen: "8fbc8f", 13377 darkslateblue: "483d8b", 13378 darkslategray: "2f4f4f", 13379 darkslategrey: "2f4f4f", 13380 darkturquoise: "00ced1", 13381 darkviolet: "9400d3", 13382 deeppink: "ff1493", 13383 deepskyblue: "00bfff", 13384 dimgray: "696969", 13385 dimgrey: "696969", 13386 dodgerblue: "1e90ff", 13387 firebrick: "b22222", 13388 floralwhite: "fffaf0", 13389 forestgreen: "228b22", 13390 fuchsia: "f0f", 13391 gainsboro: "dcdcdc", 13392 ghostwhite: "f8f8ff", 13393 gold: "ffd700", 13394 goldenrod: "daa520", 13395 gray: "808080", 13396 green: "008000", 13397 greenyellow: "adff2f", 13398 grey: "808080", 13399 honeydew: "f0fff0", 13400 hotpink: "ff69b4", 13401 indianred: "cd5c5c", 13402 indigo: "4b0082", 13403 ivory: "fffff0", 13404 khaki: "f0e68c", 13405 lavender: "e6e6fa", 13406 lavenderblush: "fff0f5", 13407 lawngreen: "7cfc00", 13408 lemonchiffon: "fffacd", 13409 lightblue: "add8e6", 13410 lightcoral: "f08080", 13411 lightcyan: "e0ffff", 13412 lightgoldenrodyellow: "fafad2", 13413 lightgray: "d3d3d3", 13414 lightgreen: "90ee90", 13415 lightgrey: "d3d3d3", 13416 lightpink: "ffb6c1", 13417 lightsalmon: "ffa07a", 13418 lightseagreen: "20b2aa", 13419 lightskyblue: "87cefa", 13420 lightslategray: "789", 13421 lightslategrey: "789", 13422 lightsteelblue: "b0c4de", 13423 lightyellow: "ffffe0", 13424 lime: "0f0", 13425 limegreen: "32cd32", 13426 linen: "faf0e6", 13427 magenta: "f0f", 13428 maroon: "800000", 13429 mediumaquamarine: "66cdaa", 13430 mediumblue: "0000cd", 13431 mediumorchid: "ba55d3", 13432 mediumpurple: "9370db", 13433 mediumseagreen: "3cb371", 13434 mediumslateblue: "7b68ee", 13435 mediumspringgreen: "00fa9a", 13436 mediumturquoise: "48d1cc", 13437 mediumvioletred: "c71585", 13438 midnightblue: "191970", 13439 mintcream: "f5fffa", 13440 mistyrose: "ffe4e1", 13441 moccasin: "ffe4b5", 13442 navajowhite: "ffdead", 13443 navy: "000080", 13444 oldlace: "fdf5e6", 13445 olive: "808000", 13446 olivedrab: "6b8e23", 13447 orange: "ffa500", 13448 orangered: "ff4500", 13449 orchid: "da70d6", 13450 palegoldenrod: "eee8aa", 13451 palegreen: "98fb98", 13452 paleturquoise: "afeeee", 13453 palevioletred: "db7093", 13454 papayawhip: "ffefd5", 13455 peachpuff: "ffdab9", 13456 peru: "cd853f", 13457 pink: "ffc0cb", 13458 plum: "dda0dd", 13459 powderblue: "b0e0e6", 13460 purple: "800080", 13461 rebeccapurple: "663399", 13462 red: "f00", 13463 rosybrown: "bc8f8f", 13464 royalblue: "4169e1", 13465 saddlebrown: "8b4513", 13466 salmon: "fa8072", 13467 sandybrown: "f4a460", 13468 seagreen: "2e8b57", 13469 seashell: "fff5ee", 13470 sienna: "a0522d", 13471 silver: "c0c0c0", 13472 skyblue: "87ceeb", 13473 slateblue: "6a5acd", 13474 slategray: "708090", 13475 slategrey: "708090", 13476 snow: "fffafa", 13477 springgreen: "00ff7f", 13478 steelblue: "4682b4", 13479 tan: "d2b48c", 13480 teal: "008080", 13481 thistle: "d8bfd8", 13482 tomato: "ff6347", 13483 turquoise: "40e0d0", 13484 violet: "ee82ee", 13485 wheat: "f5deb3", 13486 white: "fff", 13487 whitesmoke: "f5f5f5", 13488 yellow: "ff0", 13489 yellowgreen: "9acd32" 13490 }; 13491 13492 // Make it easy to access colors via `hexNames[hex]` 13493 var hexNames = tinycolor.hexNames = flip(names); 13494 13495 13496 // Utilities 13497 // --------- 13498 13499 // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }` 13500 function flip(o) { 13501 var flipped = { }; 13502 for (var i in o) { 13503 if (o.hasOwnProperty(i)) { 13504 flipped[o[i]] = i; 13505 } 13506 } 13507 return flipped; 13508 } 13509 13510 // Return a valid alpha value [0,1] with all invalid values being set to 1 13511 function boundAlpha(a) { 13512 a = parseFloat(a); 13513 13514 if (isNaN(a) || a < 0 || a > 1) { 13515 a = 1; 13516 } 13517 13518 return a; 13519 } 13520 13521 // Take input from [0, n] and return it as [0, 1] 13522 function bound01(n, max) { 13523 if (isOnePointZero(n)) { n = "100%"; } 13524 13525 var processPercent = isPercentage(n); 13526 n = mathMin(max, mathMax(0, parseFloat(n))); 13527 13528 // Automatically convert percentage into number 13529 if (processPercent) { 13530 n = parseInt(n * max, 10) / 100; 13531 } 13532 13533 // Handle floating point rounding errors 13534 if ((Math.abs(n - max) < 0.000001)) { 13535 return 1; 13536 } 13537 13538 // Convert into [0, 1] range if it isn't already 13539 return (n % max) / parseFloat(max); 13540 } 13541 13542 // Force a number between 0 and 1 13543 function clamp01(val) { 13544 return mathMin(1, mathMax(0, val)); 13545 } 13546 13547 // Parse a base-16 hex value into a base-10 integer 13548 function parseIntFromHex(val) { 13549 return parseInt(val, 16); 13550 } 13551 13552 // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 13553 // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0> 13554 function isOnePointZero(n) { 13555 return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; 13556 } 13557 13558 // Check to see if string passed in is a percentage 13559 function isPercentage(n) { 13560 return typeof n === "string" && n.indexOf('%') != -1; 13561 } 13562 13563 // Force a hex value to have 2 characters 13564 function pad2(c) { 13565 return c.length == 1 ? '0' + c : '' + c; 13566 } 13567 13568 // Replace a decimal with it's percentage value 13569 function convertToPercentage(n) { 13570 if (n <= 1) { 13571 n = (n * 100) + "%"; 13572 } 13573 13574 return n; 13575 } 13576 13577 // Converts a decimal to a hex value 13578 function convertDecimalToHex(d) { 13579 return Math.round(parseFloat(d) * 255).toString(16); 13580 } 13581 // Converts a hex value to a decimal 13582 function convertHexToDecimal(h) { 13583 return (parseIntFromHex(h) / 255); 13584 } 13585 13586 var matchers = (function() { 13587 13588 // <http://www.w3.org/TR/css3-values/#integers> 13589 var CSS_INTEGER = "[-\\+]?\\d+%?"; 13590 13591 // <http://www.w3.org/TR/css3-values/#number-value> 13592 var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; 13593 13594 // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. 13595 var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; 13596 13597 // Actual matching. 13598 // Parentheses and commas are optional, but not required. 13599 // Whitespace can take the place of commas or opening paren 13600 var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; 13601 var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; 13602 13603 return { 13604 CSS_UNIT: new RegExp(CSS_UNIT), 13605 rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), 13606 rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), 13607 hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), 13608 hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), 13609 hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), 13610 hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), 13611 hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, 13612 hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, 13613 hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, 13614 hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ 13615 }; 13616 })(); 13617 13618 // `isValidCSSUnit` 13619 // Take in a single string / number and check to see if it looks like a CSS unit 13620 // (see `matchers` above for definition). 13621 function isValidCSSUnit(color) { 13622 return !!matchers.CSS_UNIT.exec(color); 13623 } 13624 13625 // `stringInputToObject` 13626 // Permissive string parsing. Take in a number of formats, and output an object 13627 // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}` 13628 function stringInputToObject(color) { 13629 13630 color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase(); 13631 var named = false; 13632 if (names[color]) { 13633 color = names[color]; 13634 named = true; 13635 } 13636 else if (color == 'transparent') { 13637 return { r: 0, g: 0, b: 0, a: 0, format: "name" }; 13638 } 13639 13640 // Try to match string input using regular expressions. 13641 // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] 13642 // Just return an object and let the conversion functions handle that. 13643 // This way the result will be the same whether the tinycolor is initialized with string or object. 13644 var match; 13645 if ((match = matchers.rgb.exec(color))) { 13646 return { r: match[1], g: match[2], b: match[3] }; 13647 } 13648 if ((match = matchers.rgba.exec(color))) { 13649 return { r: match[1], g: match[2], b: match[3], a: match[4] }; 13650 } 13651 if ((match = matchers.hsl.exec(color))) { 13652 return { h: match[1], s: match[2], l: match[3] }; 13653 } 13654 if ((match = matchers.hsla.exec(color))) { 13655 return { h: match[1], s: match[2], l: match[3], a: match[4] }; 13656 } 13657 if ((match = matchers.hsv.exec(color))) { 13658 return { h: match[1], s: match[2], v: match[3] }; 13659 } 13660 if ((match = matchers.hsva.exec(color))) { 13661 return { h: match[1], s: match[2], v: match[3], a: match[4] }; 13662 } 13663 if ((match = matchers.hex8.exec(color))) { 13664 return { 13665 r: parseIntFromHex(match[1]), 13666 g: parseIntFromHex(match[2]), 13667 b: parseIntFromHex(match[3]), 13668 a: convertHexToDecimal(match[4]), 13669 format: named ? "name" : "hex8" 13670 }; 13671 } 13672 if ((match = matchers.hex6.exec(color))) { 13673 return { 13674 r: parseIntFromHex(match[1]), 13675 g: parseIntFromHex(match[2]), 13676 b: parseIntFromHex(match[3]), 13677 format: named ? "name" : "hex" 13678 }; 13679 } 13680 if ((match = matchers.hex4.exec(color))) { 13681 return { 13682 r: parseIntFromHex(match[1] + '' + match[1]), 13683 g: parseIntFromHex(match[2] + '' + match[2]), 13684 b: parseIntFromHex(match[3] + '' + match[3]), 13685 a: convertHexToDecimal(match[4] + '' + match[4]), 13686 format: named ? "name" : "hex8" 13687 }; 13688 } 13689 if ((match = matchers.hex3.exec(color))) { 13690 return { 13691 r: parseIntFromHex(match[1] + '' + match[1]), 13692 g: parseIntFromHex(match[2] + '' + match[2]), 13693 b: parseIntFromHex(match[3] + '' + match[3]), 13694 format: named ? "name" : "hex" 13695 }; 13696 } 13697 13698 return false; 13699 } 13700 13701 function validateWCAG2Parms(parms) { 13702 // return valid WCAG2 parms for isReadable. 13703 // If input parms are invalid, return {"level":"AA", "size":"small"} 13704 var level, size; 13705 parms = parms || {"level":"AA", "size":"small"}; 13706 level = (parms.level || "AA").toUpperCase(); 13707 size = (parms.size || "small").toLowerCase(); 13708 if (level !== "AA" && level !== "AAA") { 13709 level = "AA"; 13710 } 13711 if (size !== "small" && size !== "large") { 13712 size = "small"; 13713 } 13714 return {"level":level, "size":size}; 13715 } 13716 13717 // Node: Export function 13718 if ( true && module.exports) { 13719 module.exports = tinycolor; 13720 } 13721 // AMD/requirejs: Define the module 13722 else if (true) { 13723 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {return tinycolor;}).call(exports, __webpack_require__, exports, module), 13724 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 13725 } 13726 // Browser: Expose to window 13727 else {} 13728 13729 })(Math); 13730 13731 13732 /***/ }), 13733 13734 /***/ "g56x": 13735 /***/ (function(module, exports) { 13736 13737 (function() { module.exports = window["wp"]["hooks"]; }()); 13738 13739 /***/ }), 13740 13741 /***/ "l3Sj": 13742 /***/ (function(module, exports) { 13743 13744 (function() { module.exports = window["wp"]["i18n"]; }()); 13745 13746 /***/ }), 13747 13748 /***/ "ouCq": 13749 /***/ (function(module, exports) { 13750 13751 (function() { module.exports = window["wp"]["blockSerializationDefaultParser"]; }()); 13752 13753 /***/ }), 13754 13755 /***/ "pPDe": 13756 /***/ (function(module, __webpack_exports__, __webpack_require__) { 13757 13758 "use strict"; 13759 13760 13761 var LEAF_KEY, hasWeakMap; 13762 13763 /** 13764 * Arbitrary value used as key for referencing cache object in WeakMap tree. 13765 * 13766 * @type {Object} 13767 */ 13768 LEAF_KEY = {}; 13769 13770 /** 13771 * Whether environment supports WeakMap. 13772 * 13773 * @type {boolean} 13774 */ 13775 hasWeakMap = typeof WeakMap !== 'undefined'; 13776 13777 /** 13778 * Returns the first argument as the sole entry in an array. 13779 * 13780 * @param {*} value Value to return. 13781 * 13782 * @return {Array} Value returned as entry in array. 13783 */ 13784 function arrayOf( value ) { 13785 return [ value ]; 13786 } 13787 13788 /** 13789 * Returns true if the value passed is object-like, or false otherwise. A value 13790 * is object-like if it can support property assignment, e.g. object or array. 13791 * 13792 * @param {*} value Value to test. 13793 * 13794 * @return {boolean} Whether value is object-like. 13795 */ 13796 function isObjectLike( value ) { 13797 return !! value && 'object' === typeof value; 13798 } 13799 13800 /** 13801 * Creates and returns a new cache object. 13802 * 13803 * @return {Object} Cache object. 13804 */ 13805 function createCache() { 13806 var cache = { 13807 clear: function() { 13808 cache.head = null; 13809 }, 13810 }; 13811 13812 return cache; 13813 } 13814 13815 /** 13816 * Returns true if entries within the two arrays are strictly equal by 13817 * reference from a starting index. 13818 * 13819 * @param {Array} a First array. 13820 * @param {Array} b Second array. 13821 * @param {number} fromIndex Index from which to start comparison. 13822 * 13823 * @return {boolean} Whether arrays are shallowly equal. 13824 */ 13825 function isShallowEqual( a, b, fromIndex ) { 13826 var i; 13827 13828 if ( a.length !== b.length ) { 13829 return false; 13830 } 13831 13832 for ( i = fromIndex; i < a.length; i++ ) { 13833 if ( a[ i ] !== b[ i ] ) { 13834 return false; 13835 } 13836 } 13837 13838 return true; 13839 } 13840 13841 /** 13842 * Returns a memoized selector function. The getDependants function argument is 13843 * called before the memoized selector and is expected to return an immutable 13844 * reference or array of references on which the selector depends for computing 13845 * its own return value. The memoize cache is preserved only as long as those 13846 * dependant references remain the same. If getDependants returns a different 13847 * reference(s), the cache is cleared and the selector value regenerated. 13848 * 13849 * @param {Function} selector Selector function. 13850 * @param {Function} getDependants Dependant getter returning an immutable 13851 * reference or array of reference used in 13852 * cache bust consideration. 13853 * 13854 * @return {Function} Memoized selector. 13855 */ 13856 /* harmony default export */ __webpack_exports__["a"] = (function( selector, getDependants ) { 13857 var rootCache, getCache; 13858 13859 // Use object source as dependant if getter not provided 13860 if ( ! getDependants ) { 13861 getDependants = arrayOf; 13862 } 13863 13864 /** 13865 * Returns the root cache. If WeakMap is supported, this is assigned to the 13866 * root WeakMap cache set, otherwise it is a shared instance of the default 13867 * cache object. 13868 * 13869 * @return {(WeakMap|Object)} Root cache object. 13870 */ 13871 function getRootCache() { 13872 return rootCache; 13873 } 13874 13875 /** 13876 * Returns the cache for a given dependants array. When possible, a WeakMap 13877 * will be used to create a unique cache for each set of dependants. This 13878 * is feasible due to the nature of WeakMap in allowing garbage collection 13879 * to occur on entries where the key object is no longer referenced. Since 13880 * WeakMap requires the key to be an object, this is only possible when the 13881 * dependant is object-like. The root cache is created as a hierarchy where 13882 * each top-level key is the first entry in a dependants set, the value a 13883 * WeakMap where each key is the next dependant, and so on. This continues 13884 * so long as the dependants are object-like. If no dependants are object- 13885 * like, then the cache is shared across all invocations. 13886 * 13887 * @see isObjectLike 13888 * 13889 * @param {Array} dependants Selector dependants. 13890 * 13891 * @return {Object} Cache object. 13892 */ 13893 function getWeakMapCache( dependants ) { 13894 var caches = rootCache, 13895 isUniqueByDependants = true, 13896 i, dependant, map, cache; 13897 13898 for ( i = 0; i < dependants.length; i++ ) { 13899 dependant = dependants[ i ]; 13900 13901 // Can only compose WeakMap from object-like key. 13902 if ( ! isObjectLike( dependant ) ) { 13903 isUniqueByDependants = false; 13904 break; 13905 } 13906 13907 // Does current segment of cache already have a WeakMap? 13908 if ( caches.has( dependant ) ) { 13909 // Traverse into nested WeakMap. 13910 caches = caches.get( dependant ); 13911 } else { 13912 // Create, set, and traverse into a new one. 13913 map = new WeakMap(); 13914 caches.set( dependant, map ); 13915 caches = map; 13916 } 13917 } 13918 13919 // We use an arbitrary (but consistent) object as key for the last item 13920 // in the WeakMap to serve as our running cache. 13921 if ( ! caches.has( LEAF_KEY ) ) { 13922 cache = createCache(); 13923 cache.isUniqueByDependants = isUniqueByDependants; 13924 caches.set( LEAF_KEY, cache ); 13925 } 13926 13927 return caches.get( LEAF_KEY ); 13928 } 13929 13930 // Assign cache handler by availability of WeakMap 13931 getCache = hasWeakMap ? getWeakMapCache : getRootCache; 13932 13933 /** 13934 * Resets root memoization cache. 13935 */ 13936 function clear() { 13937 rootCache = hasWeakMap ? new WeakMap() : createCache(); 13938 } 13939 13940 // eslint-disable-next-line jsdoc/check-param-names 13941 /** 13942 * The augmented selector call, considering first whether dependants have 13943 * changed before passing it to underlying memoize function. 13944 * 13945 * @param {Object} source Source object for derivation. 13946 * @param {...*} extraArgs Additional arguments to pass to selector. 13947 * 13948 * @return {*} Selector result. 13949 */ 13950 function callSelector( /* source, ...extraArgs */ ) { 13951 var len = arguments.length, 13952 cache, node, i, args, dependants; 13953 13954 // Create copy of arguments (avoid leaking deoptimization). 13955 args = new Array( len ); 13956 for ( i = 0; i < len; i++ ) { 13957 args[ i ] = arguments[ i ]; 13958 } 13959 13960 dependants = getDependants.apply( null, args ); 13961 cache = getCache( dependants ); 13962 13963 // If not guaranteed uniqueness by dependants (primitive type or lack 13964 // of WeakMap support), shallow compare against last dependants and, if 13965 // references have changed, destroy cache to recalculate result. 13966 if ( ! cache.isUniqueByDependants ) { 13967 if ( cache.lastDependants && ! isShallowEqual( dependants, cache.lastDependants, 0 ) ) { 13968 cache.clear(); 13969 } 13970 13971 cache.lastDependants = dependants; 13972 } 13973 13974 node = cache.head; 13975 while ( node ) { 13976 // Check whether node arguments match arguments 13977 if ( ! isShallowEqual( node.args, args, 1 ) ) { 13978 node = node.next; 13979 continue; 13980 } 13981 13982 // At this point we can assume we've found a match 13983 13984 // Surface matched node to head if not already 13985 if ( node !== cache.head ) { 13986 // Adjust siblings to point to each other. 13987 node.prev.next = node.next; 13988 if ( node.next ) { 13989 node.next.prev = node.prev; 13990 } 13991 13992 node.next = cache.head; 13993 node.prev = null; 13994 cache.head.prev = node; 13995 cache.head = node; 13996 } 13997 13998 // Return immediately 13999 return node.val; 14000 } 14001 14002 // No cached value found. Continue to insertion phase: 14003 14004 node = { 14005 // Generate the result from original function 14006 val: selector.apply( null, args ), 14007 }; 14008 14009 // Avoid including the source object in the cache. 14010 args[ 0 ] = null; 14011 node.args = args; 14012 14013 // Don't need to check whether node is already head, since it would 14014 // have been returned above already if it was 14015 14016 // Shift existing head down list 14017 if ( cache.head ) { 14018 cache.head.prev = node; 14019 node.next = cache.head; 14020 } 14021 14022 cache.head = node; 14023 14024 return node.val; 14025 } 14026 14027 callSelector.getDependants = getDependants; 14028 callSelector.clear = clear; 14029 clear(); 14030 14031 return callSelector; 14032 }); 14033 14034 14035 /***/ }), 14036 14037 /***/ "rl8x": 14038 /***/ (function(module, exports) { 14039 14040 (function() { module.exports = window["wp"]["isShallowEqual"]; }()); 14041 14042 /***/ }), 14043 14044 /***/ "rmEH": 14045 /***/ (function(module, exports) { 14046 14047 (function() { module.exports = window["wp"]["htmlEntities"]; }()); 14048 14049 /***/ }), 14050 14051 /***/ "wx14": 14052 /***/ (function(module, __webpack_exports__, __webpack_require__) { 14053 14054 "use strict"; 14055 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _extends; }); 14056 function _extends() { 14057 _extends = Object.assign || function (target) { 14058 for (var i = 1; i < arguments.length; i++) { 14059 var source = arguments[i]; 14060 14061 for (var key in source) { 14062 if (Object.prototype.hasOwnProperty.call(source, key)) { 14063 target[key] = source[key]; 14064 } 14065 } 14066 } 14067 14068 return target; 14069 }; 14070 14071 return _extends.apply(this, arguments); 14072 } 14073 14074 /***/ }), 14075 14076 /***/ "xTGt": 14077 /***/ (function(module, exports) { 14078 14079 (function() { module.exports = window["wp"]["blob"]; }()); 14080 14081 /***/ }) 14082 14083 /******/ });